@pawlogic/dl 0.11.11 → 0.11.12
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/dl.mjs +1 -1
- package/ilands.mjs +1 -1
- package/package.json +1 -1
package/dl.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import e,{mkdirSync as t,writeFileSync as i,chmodSync as n,existsSync as o,readFileSync as r,rmSync as a}from"node:fs";import s,{join as l,resolve as c,isAbsolute as d,dirname as u,extname as p}from"node:path";import{fileURLToPath as m}from"node:url";import h from"node:events";import f,{spawn as g,execFileSync as v,spawnSync as y}from"node:child_process";import b from"node:process";import{randomBytes as _,createHash as w,randomUUID as k}from"node:crypto";import{createServer as x}from"node:http";import*as S from"node:os";import{homedir as E}from"node:os";import{readFile as O,mkdir as T,writeFile as A}from"node:fs/promises";function $(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var N,j,C={},I={},R={};function q(){if(N)return R;N=1;class e extends Error{constructor(e,t,i){super(i),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=t,this.exitCode=e,this.nestedError=void 0}}return R.CommanderError=e,R.InvalidArgumentError=class extends e{constructor(e){super(1,"commander.invalidArgument",e),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}},R}function P(){if(j)return I;j=1;const{InvalidArgumentError:e}=q();return I.Argument=class{constructor(e,t){switch(this.description=t||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,e[0]){case"<":this.required=!0,this._name=e.slice(1,-1);break;case"[":this.required=!1,this._name=e.slice(1,-1);break;default:this.required=!0,this._name=e}this._name.length>3&&"..."===this._name.slice(-3)&&(this.variadic=!0,this._name=this._name.slice(0,-3))}name(){return this._name}_concatValue(e,t){return t!==this.defaultValue&&Array.isArray(t)?t.concat(e):[e]}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}argParser(e){return this.parseArg=e,this}choices(t){return this.argChoices=t.slice(),this.parseArg=(t,i)=>{if(!this.argChoices.includes(t))throw new e(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._concatValue(t,i):t},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}},I.humanReadableArgName=function(e){const t=e.name()+(!0===e.variadic?"...":"");return e.required?"<"+t+">":"["+t+"]"},I}var L,z={},M={};function U(){if(L)return M;L=1;const{humanReadableArgName:e}=P();return M.Help=class{constructor(){this.helpWidth=void 0,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}visibleCommands(e){const t=e.commands.filter(e=>!e._hidden),i=e._getHelpCommand();return i&&!i._hidden&&t.push(i),this.sortSubcommands&&t.sort((e,t)=>e.name().localeCompare(t.name())),t}compareOptions(e,t){const i=e=>e.short?e.short.replace(/^-/,""):e.long.replace(/^--/,"");return i(e).localeCompare(i(t))}visibleOptions(e){const t=e.options.filter(e=>!e.hidden),i=e._getHelpOption();if(i&&!i.hidden){const n=i.short&&e._findOption(i.short),o=i.long&&e._findOption(i.long);n||o?i.long&&!o?t.push(e.createOption(i.long,i.description)):i.short&&!n&&t.push(e.createOption(i.short,i.description)):t.push(i)}return this.sortOptions&&t.sort(this.compareOptions),t}visibleGlobalOptions(e){if(!this.showGlobalOptions)return[];const t=[];for(let i=e.parent;i;i=i.parent){const e=i.options.filter(e=>!e.hidden);t.push(...e)}return this.sortOptions&&t.sort(this.compareOptions),t}visibleArguments(e){return e._argsDescription&&e.registeredArguments.forEach(t=>{t.description=t.description||e._argsDescription[t.name()]||""}),e.registeredArguments.find(e=>e.description)?e.registeredArguments:[]}subcommandTerm(t){const i=t.registeredArguments.map(t=>e(t)).join(" ");return t._name+(t._aliases[0]?"|"+t._aliases[0]:"")+(t.options.length?" [options]":"")+(i?" "+i:"")}optionTerm(e){return e.flags}argumentTerm(e){return e.name()}longestSubcommandTermLength(e,t){return t.visibleCommands(e).reduce((e,i)=>Math.max(e,t.subcommandTerm(i).length),0)}longestOptionTermLength(e,t){return t.visibleOptions(e).reduce((e,i)=>Math.max(e,t.optionTerm(i).length),0)}longestGlobalOptionTermLength(e,t){return t.visibleGlobalOptions(e).reduce((e,i)=>Math.max(e,t.optionTerm(i).length),0)}longestArgumentTermLength(e,t){return t.visibleArguments(e).reduce((e,i)=>Math.max(e,t.argumentTerm(i).length),0)}commandUsage(e){let t=e._name;e._aliases[0]&&(t=t+"|"+e._aliases[0]);let i="";for(let t=e.parent;t;t=t.parent)i=t.name()+" "+i;return i+t+" "+e.usage()}commandDescription(e){return e.description()}subcommandDescription(e){return e.summary()||e.description()}optionDescription(e){const t=[];return e.argChoices&&t.push(`choices: ${e.argChoices.map(e=>JSON.stringify(e)).join(", ")}`),void 0!==e.defaultValue&&(e.required||e.optional||e.isBoolean()&&"boolean"==typeof e.defaultValue)&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),void 0!==e.presetArg&&e.optional&&t.push(`preset: ${JSON.stringify(e.presetArg)}`),void 0!==e.envVar&&t.push(`env: ${e.envVar}`),t.length>0?`${e.description} (${t.join(", ")})`:e.description}argumentDescription(e){const t=[];if(e.argChoices&&t.push(`choices: ${e.argChoices.map(e=>JSON.stringify(e)).join(", ")}`),void 0!==e.defaultValue&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),t.length>0){const i=`(${t.join(", ")})`;return e.description?`${e.description} ${i}`:i}return e.description}formatHelp(e,t){const i=t.padWidth(e,t),n=t.helpWidth||80;function o(e,o){if(o){const r=`${e.padEnd(i+2)}${o}`;return t.wrap(r,n-2,i+2)}return e}function r(e){return e.join("\n").replace(/^/gm," ".repeat(2))}let a=[`Usage: ${t.commandUsage(e)}`,""];const s=t.commandDescription(e);s.length>0&&(a=a.concat([t.wrap(s,n,0),""]));const l=t.visibleArguments(e).map(e=>o(t.argumentTerm(e),t.argumentDescription(e)));l.length>0&&(a=a.concat(["Arguments:",r(l),""]));const c=t.visibleOptions(e).map(e=>o(t.optionTerm(e),t.optionDescription(e)));if(c.length>0&&(a=a.concat(["Options:",r(c),""])),this.showGlobalOptions){const i=t.visibleGlobalOptions(e).map(e=>o(t.optionTerm(e),t.optionDescription(e)));i.length>0&&(a=a.concat(["Global Options:",r(i),""]))}const d=t.visibleCommands(e).map(e=>o(t.subcommandTerm(e),t.subcommandDescription(e)));return d.length>0&&(a=a.concat(["Commands:",r(d),""])),a.join("\n")}padWidth(e,t){return Math.max(t.longestOptionTermLength(e,t),t.longestGlobalOptionTermLength(e,t),t.longestSubcommandTermLength(e,t),t.longestArgumentTermLength(e,t))}wrap(e,t,i,n=40){const o=new RegExp("[\\n][ \\f\\t\\v - \ufeff]+");if(e.match(o))return e;const r=t-i;if(r<n)return e;const a=e.slice(0,i),s=e.slice(i).replace("\r\n","\n"),l=" ".repeat(i),c="\\s",d=new RegExp(`\n|.{1,${r-1}}([${c}]|$)|[^${c}]+?([${c}]|$)`,"g");return a+(s.match(d)||[]).map((e,t)=>"\n"===e?"":(t>0?l:"")+e.trimEnd()).join("\n")}},M}var F,D={};function H(){if(F)return D;F=1;const{InvalidArgumentError:e}=q();return D.Option=class{constructor(e,t){this.flags=e,this.description=t||"",this.required=e.includes("<"),this.optional=e.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test(e),this.mandatory=!1;const i=function(e){let t,i;const n=e.split(/[ |,]+/);return n.length>1&&!/^[[<]/.test(n[1])&&(t=n.shift()),i=n.shift(),!t&&/^-[^-]$/.test(i)&&(t=i,i=void 0),{shortFlag:t,longFlag:i}}(e);this.short=i.shortFlag,this.long=i.longFlag,this.negate=!1,this.long&&(this.negate=this.long.startsWith("--no-")),this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}preset(e){return this.presetArg=e,this}conflicts(e){return this.conflictsWith=this.conflictsWith.concat(e),this}implies(e){let t=e;return"string"==typeof e&&(t={[e]:!0}),this.implied=Object.assign(this.implied||{},t),this}env(e){return this.envVar=e,this}argParser(e){return this.parseArg=e,this}makeOptionMandatory(e=!0){return this.mandatory=!!e,this}hideHelp(e=!0){return this.hidden=!!e,this}_concatValue(e,t){return t!==this.defaultValue&&Array.isArray(t)?t.concat(e):[e]}choices(t){return this.argChoices=t.slice(),this.parseArg=(t,i)=>{if(!this.argChoices.includes(t))throw new e(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._concatValue(t,i):t},this}name(){return this.long?this.long.replace(/^--/,""):this.short.replace(/^-/,"")}attributeName(){return this.name().replace(/^no-/,"").split("-").reduce((e,t)=>e+t[0].toUpperCase()+t.slice(1))}is(e){return this.short===e||this.long===e}isBoolean(){return!this.required&&!this.optional&&!this.negate}},D.DualOptions=class{constructor(e){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,e.forEach(e=>{e.negate?this.negativeOptions.set(e.attributeName(),e):this.positiveOptions.set(e.attributeName(),e)}),this.negativeOptions.forEach((e,t)=>{this.positiveOptions.has(t)&&this.dualOptions.add(t)})}valueFromOption(e,t){const i=t.attributeName();if(!this.dualOptions.has(i))return!0;const n=this.negativeOptions.get(i).presetArg,o=void 0!==n&&n;return t.negate===(o===e)}},D}var B,V,J,K={};function G(){return B||(B=1,K.suggestSimilar=function(e,t){if(!t||0===t.length)return"";t=Array.from(new Set(t));const i=e.startsWith("--");i&&(e=e.slice(2),t=t.map(e=>e.slice(2)));let n=[],o=3;return t.forEach(t=>{if(t.length<=1)return;const i=function(e,t){if(Math.abs(e.length-t.length)>3)return Math.max(e.length,t.length);const i=[];for(let t=0;t<=e.length;t++)i[t]=[t];for(let e=0;e<=t.length;e++)i[0][e]=e;for(let n=1;n<=t.length;n++)for(let o=1;o<=e.length;o++){let r=1;r=e[o-1]===t[n-1]?0:1,i[o][n]=Math.min(i[o-1][n]+1,i[o][n-1]+1,i[o-1][n-1]+r),o>1&&n>1&&e[o-1]===t[n-2]&&e[o-2]===t[n-1]&&(i[o][n]=Math.min(i[o][n],i[o-2][n-2]+1))}return i[e.length][t.length]}(e,t),r=Math.max(e.length,t.length);(r-i)/r>.4&&(i<o?(o=i,n=[t]):i===o&&n.push(t))}),n.sort((e,t)=>e.localeCompare(t)),i&&(n=n.map(e=>`--${e}`)),n.length>1?`\n(Did you mean one of ${n.join(", ")}?)`:1===n.length?`\n(Did you mean ${n[0]}?)`:""}),K}var Y=function(){if(J)return C;J=1;const{Argument:t}=P(),{Command:i}=function(){if(V)return z;V=1;const t=h.EventEmitter,i=f,n=s,o=e,r=b,{Argument:a,humanReadableArgName:l}=P(),{CommanderError:c}=q(),{Help:d}=U(),{Option:u,DualOptions:p}=H(),{suggestSimilar:m}=G();class g extends t{constructor(e){super(),this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!0,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=e||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._outputConfiguration={writeOut:e=>r.stdout.write(e),writeErr:e=>r.stderr.write(e),getOutHelpWidth:()=>r.stdout.isTTY?r.stdout.columns:void 0,getErrHelpWidth:()=>r.stderr.isTTY?r.stderr.columns:void 0,outputError:(e,t)=>t(e)},this._hidden=!1,this._helpOption=void 0,this._addImplicitHelpCommand=void 0,this._helpCommand=void 0,this._helpConfiguration={}}copyInheritedSettings(e){return this._outputConfiguration=e._outputConfiguration,this._helpOption=e._helpOption,this._helpCommand=e._helpCommand,this._helpConfiguration=e._helpConfiguration,this._exitCallback=e._exitCallback,this._storeOptionsAsProperties=e._storeOptionsAsProperties,this._combineFlagAndOptionalValue=e._combineFlagAndOptionalValue,this._allowExcessArguments=e._allowExcessArguments,this._enablePositionalOptions=e._enablePositionalOptions,this._showHelpAfterError=e._showHelpAfterError,this._showSuggestionAfterError=e._showSuggestionAfterError,this}_getCommandAndAncestors(){const e=[];for(let t=this;t;t=t.parent)e.push(t);return e}command(e,t,i){let n=t,o=i;"object"==typeof n&&null!==n&&(o=n,n=null),o=o||{};const[,r,a]=e.match(/([^ ]+) *(.*)/),s=this.createCommand(r);return n&&(s.description(n),s._executableHandler=!0),o.isDefault&&(this._defaultCommandName=s._name),s._hidden=!(!o.noHelp&&!o.hidden),s._executableFile=o.executableFile||null,a&&s.arguments(a),this._registerCommand(s),s.parent=this,s.copyInheritedSettings(this),n?this:s}createCommand(e){return new g(e)}createHelp(){return Object.assign(new d,this.configureHelp())}configureHelp(e){return void 0===e?this._helpConfiguration:(this._helpConfiguration=e,this)}configureOutput(e){return void 0===e?this._outputConfiguration:(Object.assign(this._outputConfiguration,e),this)}showHelpAfterError(e=!0){return"string"!=typeof e&&(e=!!e),this._showHelpAfterError=e,this}showSuggestionAfterError(e=!0){return this._showSuggestionAfterError=!!e,this}addCommand(e,t){if(!e._name)throw new Error("Command passed to .addCommand() must have a name\n- specify the name in Command constructor or using .name()");return(t=t||{}).isDefault&&(this._defaultCommandName=e._name),(t.noHelp||t.hidden)&&(e._hidden=!0),this._registerCommand(e),e.parent=this,e._checkForBrokenPassThrough(),this}createArgument(e,t){return new a(e,t)}argument(e,t,i,n){const o=this.createArgument(e,t);return"function"==typeof i?o.default(n).argParser(i):o.default(i),this.addArgument(o),this}arguments(e){return e.trim().split(/ +/).forEach(e=>{this.argument(e)}),this}addArgument(e){const t=this.registeredArguments.slice(-1)[0];if(t&&t.variadic)throw new Error(`only the last argument can be variadic '${t.name()}'`);if(e.required&&void 0!==e.defaultValue&&void 0===e.parseArg)throw new Error(`a default value for a required argument is never used: '${e.name()}'`);return this.registeredArguments.push(e),this}helpCommand(e,t){if("boolean"==typeof e)return this._addImplicitHelpCommand=e,this;e=e??"help [command]";const[,i,n]=e.match(/([^ ]+) *(.*)/),o=t??"display help for command",r=this.createCommand(i);return r.helpOption(!1),n&&r.arguments(n),o&&r.description(o),this._addImplicitHelpCommand=!0,this._helpCommand=r,this}addHelpCommand(e,t){return"object"!=typeof e?(this.helpCommand(e,t),this):(this._addImplicitHelpCommand=!0,this._helpCommand=e,this)}_getHelpCommand(){return this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"))?(void 0===this._helpCommand&&this.helpCommand(void 0,void 0),this._helpCommand):null}hook(e,t){const i=["preSubcommand","preAction","postAction"];if(!i.includes(e))throw new Error(`Unexpected value for event passed to hook : '${e}'.\nExpecting one of '${i.join("', '")}'`);return this._lifeCycleHooks[e]?this._lifeCycleHooks[e].push(t):this._lifeCycleHooks[e]=[t],this}exitOverride(e){return this._exitCallback=e||(e=>{if("commander.executeSubCommandAsync"!==e.code)throw e}),this}_exit(e,t,i){this._exitCallback&&this._exitCallback(new c(e,t,i)),r.exit(e)}action(e){return this._actionHandler=t=>{const i=this.registeredArguments.length,n=t.slice(0,i);return this._storeOptionsAsProperties?n[i]=this:n[i]=this.opts(),n.push(this),e.apply(this,n)},this}createOption(e,t){return new u(e,t)}_callParseArg(e,t,i,n){try{return e.parseArg(t,i)}catch(e){if("commander.invalidArgument"===e.code){const t=`${n} ${e.message}`;this.error(t,{exitCode:e.exitCode,code:e.code})}throw e}}_registerOption(e){const t=e.short&&this._findOption(e.short)||e.long&&this._findOption(e.long);if(t){const i=e.long&&this._findOption(e.long)?e.long:e.short;throw new Error(`Cannot add option '${e.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${i}'\n- already used by option '${t.flags}'`)}this.options.push(e)}_registerCommand(e){const t=e=>[e.name()].concat(e.aliases()),i=t(e).find(e=>this._findCommand(e));if(i){const n=t(this._findCommand(i)).join("|"),o=t(e).join("|");throw new Error(`cannot add command '${o}' as already have command '${n}'`)}this.commands.push(e)}addOption(e){this._registerOption(e);const t=e.name(),i=e.attributeName();if(e.negate){const t=e.long.replace(/^--no-/,"--");this._findOption(t)||this.setOptionValueWithSource(i,void 0===e.defaultValue||e.defaultValue,"default")}else void 0!==e.defaultValue&&this.setOptionValueWithSource(i,e.defaultValue,"default");const n=(t,n,o)=>{null==t&&void 0!==e.presetArg&&(t=e.presetArg);const r=this.getOptionValue(i);null!==t&&e.parseArg?t=this._callParseArg(e,t,r,n):null!==t&&e.variadic&&(t=e._concatValue(t,r)),null==t&&(t=!e.negate&&(!(!e.isBoolean()&&!e.optional)||"")),this.setOptionValueWithSource(i,t,o)};return this.on("option:"+t,t=>{const i=`error: option '${e.flags}' argument '${t}' is invalid.`;n(t,i,"cli")}),e.envVar&&this.on("optionEnv:"+t,t=>{const i=`error: option '${e.flags}' value '${t}' from env '${e.envVar}' is invalid.`;n(t,i,"env")}),this}_optionEx(e,t,i,n,o){if("object"==typeof t&&t instanceof u)throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");const r=this.createOption(t,i);if(r.makeOptionMandatory(!!e.mandatory),"function"==typeof n)r.default(o).argParser(n);else if(n instanceof RegExp){const e=n;n=(t,i)=>{const n=e.exec(t);return n?n[0]:i},r.default(o).argParser(n)}else r.default(n);return this.addOption(r)}option(e,t,i,n){return this._optionEx({},e,t,i,n)}requiredOption(e,t,i,n){return this._optionEx({mandatory:!0},e,t,i,n)}combineFlagAndOptionalValue(e=!0){return this._combineFlagAndOptionalValue=!!e,this}allowUnknownOption(e=!0){return this._allowUnknownOption=!!e,this}allowExcessArguments(e=!0){return this._allowExcessArguments=!!e,this}enablePositionalOptions(e=!0){return this._enablePositionalOptions=!!e,this}passThroughOptions(e=!0){return this._passThroughOptions=!!e,this._checkForBrokenPassThrough(),this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions)throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}storeOptionsAsProperties(e=!0){if(this.options.length)throw new Error("call .storeOptionsAsProperties() before adding options");if(Object.keys(this._optionValues).length)throw new Error("call .storeOptionsAsProperties() before setting option values");return this._storeOptionsAsProperties=!!e,this}getOptionValue(e){return this._storeOptionsAsProperties?this[e]:this._optionValues[e]}setOptionValue(e,t){return this.setOptionValueWithSource(e,t,void 0)}setOptionValueWithSource(e,t,i){return this._storeOptionsAsProperties?this[e]=t:this._optionValues[e]=t,this._optionValueSources[e]=i,this}getOptionValueSource(e){return this._optionValueSources[e]}getOptionValueSourceWithGlobals(e){let t;return this._getCommandAndAncestors().forEach(i=>{void 0!==i.getOptionValueSource(e)&&(t=i.getOptionValueSource(e))}),t}_prepareUserArgs(e,t){if(void 0!==e&&!Array.isArray(e))throw new Error("first parameter to parse must be array or undefined");if(t=t||{},void 0===e&&void 0===t.from){r.versions?.electron&&(t.from="electron");const e=r.execArgv??[];(e.includes("-e")||e.includes("--eval")||e.includes("-p")||e.includes("--print"))&&(t.from="eval")}let i;switch(void 0===e&&(e=r.argv),this.rawArgs=e.slice(),t.from){case void 0:case"node":this._scriptPath=e[1],i=e.slice(2);break;case"electron":r.defaultApp?(this._scriptPath=e[1],i=e.slice(2)):i=e.slice(1);break;case"user":i=e.slice(0);break;case"eval":i=e.slice(1);break;default:throw new Error(`unexpected parse option { from: '${t.from}' }`)}return!this._name&&this._scriptPath&&this.nameFromFilename(this._scriptPath),this._name=this._name||"program",i}parse(e,t){const i=this._prepareUserArgs(e,t);return this._parseCommand([],i),this}async parseAsync(e,t){const i=this._prepareUserArgs(e,t);return await this._parseCommand([],i),this}_executeSubCommand(e,t){t=t.slice();let a=!1;const s=[".js",".ts",".tsx",".mjs",".cjs"];function l(e,t){const i=n.resolve(e,t);if(o.existsSync(i))return i;if(s.includes(n.extname(t)))return;const r=s.find(e=>o.existsSync(`${i}${e}`));return r?`${i}${r}`:void 0}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let d,u=e._executableFile||`${this._name}-${e._name}`,p=this._executableDir||"";if(this._scriptPath){let e;try{e=o.realpathSync(this._scriptPath)}catch(t){e=this._scriptPath}p=n.resolve(n.dirname(e),p)}if(p){let t=l(p,u);if(!t&&!e._executableFile&&this._scriptPath){const i=n.basename(this._scriptPath,n.extname(this._scriptPath));i!==this._name&&(t=l(p,`${i}-${e._name}`))}u=t||u}a=s.includes(n.extname(u)),"win32"!==r.platform?a?(t.unshift(u),t=v(r.execArgv).concat(t),d=i.spawn(r.argv[0],t,{stdio:"inherit"})):d=i.spawn(u,t,{stdio:"inherit"}):(t.unshift(u),t=v(r.execArgv).concat(t),d=i.spawn(r.execPath,t,{stdio:"inherit"})),d.killed||["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach(e=>{r.on(e,()=>{!1===d.killed&&null===d.exitCode&&d.kill(e)})});const m=this._exitCallback;d.on("close",e=>{e=e??1,m?m(new c(e,"commander.executeSubCommandAsync","(close)")):r.exit(e)}),d.on("error",t=>{if("ENOENT"===t.code){const t=p?`searched for local subcommand relative to directory '${p}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",i=`'${u}' does not exist\n - if '${e._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead\n - if the default executable name is not suitable, use the executableFile option to supply a custom name or path\n - ${t}`;throw new Error(i)}if("EACCES"===t.code)throw new Error(`'${u}' not executable`);if(m){const e=new c(1,"commander.executeSubCommandAsync","(error)");e.nestedError=t,m(e)}else r.exit(1)}),this.runningCommand=d}_dispatchSubcommand(e,t,i){const n=this._findCommand(e);let o;return n||this.help({error:!0}),o=this._chainOrCallSubCommandHook(o,n,"preSubcommand"),o=this._chainOrCall(o,()=>{if(!n._executableHandler)return n._parseCommand(t,i);this._executeSubCommand(n,t.concat(i))}),o}_dispatchHelpCommand(e){e||this.help();const t=this._findCommand(e);return t&&!t._executableHandler&&t.help(),this._dispatchSubcommand(e,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){this.registeredArguments.forEach((e,t)=>{e.required&&null==this.args[t]&&this.missingArgument(e.name())}),this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic||this.args.length>this.registeredArguments.length&&this._excessArguments(this.args)}_processArguments(){const e=(e,t,i)=>{let n=t;if(null!==t&&e.parseArg){const o=`error: command-argument value '${t}' is invalid for argument '${e.name()}'.`;n=this._callParseArg(e,t,i,o)}return n};this._checkNumberOfArguments();const t=[];this.registeredArguments.forEach((i,n)=>{let o=i.defaultValue;i.variadic?n<this.args.length?(o=this.args.slice(n),i.parseArg&&(o=o.reduce((t,n)=>e(i,n,t),i.defaultValue))):void 0===o&&(o=[]):n<this.args.length&&(o=this.args[n],i.parseArg&&(o=e(i,o,i.defaultValue))),t[n]=o}),this.processedArgs=t}_chainOrCall(e,t){return e&&e.then&&"function"==typeof e.then?e.then(()=>t()):t()}_chainOrCallHooks(e,t){let i=e;const n=[];return this._getCommandAndAncestors().reverse().filter(e=>void 0!==e._lifeCycleHooks[t]).forEach(e=>{e._lifeCycleHooks[t].forEach(t=>{n.push({hookedCommand:e,callback:t})})}),"postAction"===t&&n.reverse(),n.forEach(e=>{i=this._chainOrCall(i,()=>e.callback(e.hookedCommand,this))}),i}_chainOrCallSubCommandHook(e,t,i){let n=e;return void 0!==this._lifeCycleHooks[i]&&this._lifeCycleHooks[i].forEach(e=>{n=this._chainOrCall(n,()=>e(this,t))}),n}_parseCommand(e,t){const i=this.parseOptions(t);if(this._parseOptionsEnv(),this._parseOptionsImplied(),e=e.concat(i.operands),t=i.unknown,this.args=e.concat(t),e&&this._findCommand(e[0]))return this._dispatchSubcommand(e[0],e.slice(1),t);if(this._getHelpCommand()&&e[0]===this._getHelpCommand().name())return this._dispatchHelpCommand(e[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(t),this._dispatchSubcommand(this._defaultCommandName,e,t);!this.commands.length||0!==this.args.length||this._actionHandler||this._defaultCommandName||this.help({error:!0}),this._outputHelpIfRequested(i.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();const n=()=>{i.unknown.length>0&&this.unknownOption(i.unknown[0])},o=`command:${this.name()}`;if(this._actionHandler){let i;return n(),this._processArguments(),i=this._chainOrCallHooks(i,"preAction"),i=this._chainOrCall(i,()=>this._actionHandler(this.processedArgs)),this.parent&&(i=this._chainOrCall(i,()=>{this.parent.emit(o,e,t)})),i=this._chainOrCallHooks(i,"postAction"),i}if(this.parent&&this.parent.listenerCount(o))n(),this._processArguments(),this.parent.emit(o,e,t);else if(e.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",e,t);this.listenerCount("command:*")?this.emit("command:*",e,t):this.commands.length?this.unknownCommand():(n(),this._processArguments())}else this.commands.length?(n(),this.help({error:!0})):(n(),this._processArguments())}_findCommand(e){if(e)return this.commands.find(t=>t._name===e||t._aliases.includes(e))}_findOption(e){return this.options.find(t=>t.is(e))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach(e=>{e.options.forEach(t=>{t.mandatory&&void 0===e.getOptionValue(t.attributeName())&&e.missingMandatoryOptionValue(t)})})}_checkForConflictingLocalOptions(){const e=this.options.filter(e=>{const t=e.attributeName();return void 0!==this.getOptionValue(t)&&"default"!==this.getOptionValueSource(t)}),t=e.filter(e=>e.conflictsWith.length>0);t.forEach(t=>{const i=e.find(e=>t.conflictsWith.includes(e.attributeName()));i&&this._conflictingOption(t,i)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach(e=>{e._checkForConflictingLocalOptions()})}parseOptions(e){const t=[],i=[];let n=t;const o=e.slice();function r(e){return e.length>1&&"-"===e[0]}let a=null;for(;o.length;){const e=o.shift();if("--"===e){n===i&&n.push(e),n.push(...o);break}if(!a||r(e)){if(a=null,r(e)){const t=this._findOption(e);if(t){if(t.required){const e=o.shift();void 0===e&&this.optionMissingArgument(t),this.emit(`option:${t.name()}`,e)}else if(t.optional){let e=null;o.length>0&&!r(o[0])&&(e=o.shift()),this.emit(`option:${t.name()}`,e)}else this.emit(`option:${t.name()}`);a=t.variadic?t:null;continue}}if(e.length>2&&"-"===e[0]&&"-"!==e[1]){const t=this._findOption(`-${e[1]}`);if(t){t.required||t.optional&&this._combineFlagAndOptionalValue?this.emit(`option:${t.name()}`,e.slice(2)):(this.emit(`option:${t.name()}`),o.unshift(`-${e.slice(2)}`));continue}}if(/^--[^=]+=/.test(e)){const t=e.indexOf("="),i=this._findOption(e.slice(0,t));if(i&&(i.required||i.optional)){this.emit(`option:${i.name()}`,e.slice(t+1));continue}}if(r(e)&&(n=i),(this._enablePositionalOptions||this._passThroughOptions)&&0===t.length&&0===i.length){if(this._findCommand(e)){t.push(e),o.length>0&&i.push(...o);break}if(this._getHelpCommand()&&e===this._getHelpCommand().name()){t.push(e),o.length>0&&t.push(...o);break}if(this._defaultCommandName){i.push(e),o.length>0&&i.push(...o);break}}if(this._passThroughOptions){n.push(e),o.length>0&&n.push(...o);break}n.push(e)}else this.emit(`option:${a.name()}`,e)}return{operands:t,unknown:i}}opts(){if(this._storeOptionsAsProperties){const e={},t=this.options.length;for(let i=0;i<t;i++){const t=this.options[i].attributeName();e[t]=t===this._versionOptionName?this._version:this[t]}return e}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce((e,t)=>Object.assign(e,t.opts()),{})}error(e,t){this._outputConfiguration.outputError(`${e}\n`,this._outputConfiguration.writeErr),"string"==typeof this._showHelpAfterError?this._outputConfiguration.writeErr(`${this._showHelpAfterError}\n`):this._showHelpAfterError&&(this._outputConfiguration.writeErr("\n"),this.outputHelp({error:!0}));const i=t||{},n=i.exitCode||1,o=i.code||"commander.error";this._exit(n,o,e)}_parseOptionsEnv(){this.options.forEach(e=>{if(e.envVar&&e.envVar in r.env){const t=e.attributeName();(void 0===this.getOptionValue(t)||["default","config","env"].includes(this.getOptionValueSource(t)))&&(e.required||e.optional?this.emit(`optionEnv:${e.name()}`,r.env[e.envVar]):this.emit(`optionEnv:${e.name()}`))}})}_parseOptionsImplied(){const e=new p(this.options),t=e=>void 0!==this.getOptionValue(e)&&!["default","implied"].includes(this.getOptionValueSource(e));this.options.filter(i=>void 0!==i.implied&&t(i.attributeName())&&e.valueFromOption(this.getOptionValue(i.attributeName()),i)).forEach(e=>{Object.keys(e.implied).filter(e=>!t(e)).forEach(t=>{this.setOptionValueWithSource(t,e.implied[t],"implied")})})}missingArgument(e){const t=`error: missing required argument '${e}'`;this.error(t,{code:"commander.missingArgument"})}optionMissingArgument(e){const t=`error: option '${e.flags}' argument missing`;this.error(t,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(e){const t=`error: required option '${e.flags}' not specified`;this.error(t,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(e,t){const i=e=>{const t=e.attributeName(),i=this.getOptionValue(t),n=this.options.find(e=>e.negate&&t===e.attributeName()),o=this.options.find(e=>!e.negate&&t===e.attributeName());return n&&(void 0===n.presetArg&&!1===i||void 0!==n.presetArg&&i===n.presetArg)?n:o||e},n=e=>{const t=i(e),n=t.attributeName();return"env"===this.getOptionValueSource(n)?`environment variable '${t.envVar}'`:`option '${t.flags}'`},o=`error: ${n(e)} cannot be used with ${n(t)}`;this.error(o,{code:"commander.conflictingOption"})}unknownOption(e){if(this._allowUnknownOption)return;let t="";if(e.startsWith("--")&&this._showSuggestionAfterError){let i=[],n=this;do{const e=n.createHelp().visibleOptions(n).filter(e=>e.long).map(e=>e.long);i=i.concat(e),n=n.parent}while(n&&!n._enablePositionalOptions);t=m(e,i)}const i=`error: unknown option '${e}'${t}`;this.error(i,{code:"commander.unknownOption"})}_excessArguments(e){if(this._allowExcessArguments)return;const t=this.registeredArguments.length,i=1===t?"":"s",n=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${t} argument${i} but got ${e.length}.`;this.error(n,{code:"commander.excessArguments"})}unknownCommand(){const e=this.args[0];let t="";if(this._showSuggestionAfterError){const i=[];this.createHelp().visibleCommands(this).forEach(e=>{i.push(e.name()),e.alias()&&i.push(e.alias())}),t=m(e,i)}const i=`error: unknown command '${e}'${t}`;this.error(i,{code:"commander.unknownCommand"})}version(e,t,i){if(void 0===e)return this._version;this._version=e,t=t||"-V, --version",i=i||"output the version number";const n=this.createOption(t,i);return this._versionOptionName=n.attributeName(),this._registerOption(n),this.on("option:"+n.name(),()=>{this._outputConfiguration.writeOut(`${e}\n`),this._exit(0,"commander.version",e)}),this}description(e,t){return void 0===e&&void 0===t?this._description:(this._description=e,t&&(this._argsDescription=t),this)}summary(e){return void 0===e?this._summary:(this._summary=e,this)}alias(e){if(void 0===e)return this._aliases[0];let t=this;if(0!==this.commands.length&&this.commands[this.commands.length-1]._executableHandler&&(t=this.commands[this.commands.length-1]),e===t._name)throw new Error("Command alias can't be the same as its name");const i=this.parent?._findCommand(e);if(i){const t=[i.name()].concat(i.aliases()).join("|");throw new Error(`cannot add alias '${e}' to command '${this.name()}' as already have command '${t}'`)}return t._aliases.push(e),this}aliases(e){return void 0===e?this._aliases:(e.forEach(e=>this.alias(e)),this)}usage(e){if(void 0===e){if(this._usage)return this._usage;const e=this.registeredArguments.map(e=>l(e));return[].concat(this.options.length||null!==this._helpOption?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?e:[]).join(" ")}return this._usage=e,this}name(e){return void 0===e?this._name:(this._name=e,this)}nameFromFilename(e){return this._name=n.basename(e,n.extname(e)),this}executableDir(e){return void 0===e?this._executableDir:(this._executableDir=e,this)}helpInformation(e){const t=this.createHelp();return void 0===t.helpWidth&&(t.helpWidth=e&&e.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth()),t.formatHelp(this,t)}_getHelpContext(e){const t={error:!!(e=e||{}).error};let i;return i=t.error?e=>this._outputConfiguration.writeErr(e):e=>this._outputConfiguration.writeOut(e),t.write=e.write||i,t.command=this,t}outputHelp(e){let t;"function"==typeof e&&(t=e,e=void 0);const i=this._getHelpContext(e);this._getCommandAndAncestors().reverse().forEach(e=>e.emit("beforeAllHelp",i)),this.emit("beforeHelp",i);let n=this.helpInformation(i);if(t&&(n=t(n),"string"!=typeof n&&!Buffer.isBuffer(n)))throw new Error("outputHelp callback must return a string or a Buffer");i.write(n),this._getHelpOption()?.long&&this.emit(this._getHelpOption().long),this.emit("afterHelp",i),this._getCommandAndAncestors().forEach(e=>e.emit("afterAllHelp",i))}helpOption(e,t){return"boolean"==typeof e?(this._helpOption=e?this._helpOption??void 0:null,this):(e=e??"-h, --help",t=t??"display help for command",this._helpOption=this.createOption(e,t),this)}_getHelpOption(){return void 0===this._helpOption&&this.helpOption(void 0,void 0),this._helpOption}addHelpOption(e){return this._helpOption=e,this}help(e){this.outputHelp(e);let t=r.exitCode||0;0===t&&e&&"function"!=typeof e&&e.error&&(t=1),this._exit(t,"commander.help","(outputHelp)")}addHelpText(e,t){const i=["beforeAll","before","after","afterAll"];if(!i.includes(e))throw new Error(`Unexpected value for position to addHelpText.\nExpecting one of '${i.join("', '")}'`);const n=`${e}Help`;return this.on(n,e=>{let i;i="function"==typeof t?t({error:e.error,command:e.command}):t,i&&e.write(`${i}\n`)}),this}_outputHelpIfRequested(e){const t=this._getHelpOption();t&&e.find(e=>t.is(e))&&(this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)"))}}function v(e){return e.map(e=>{if(!e.startsWith("--inspect"))return e;let t,i,n="127.0.0.1",o="9229";return null!==(i=e.match(/^(--inspect(-brk)?)$/))?t=i[1]:null!==(i=e.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))?(t=i[1],/^\d+$/.test(i[3])?o=i[3]:n=i[3]):null!==(i=e.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))&&(t=i[1],n=i[3],o=i[4]),t&&"0"!==o?`${t}=${n}:${parseInt(o)+1}`:e})}return z.Command=g,z}(),{CommanderError:n,InvalidArgumentError:o}=q(),{Help:r}=U(),{Option:a}=H();return C.program=new i,C.createCommand=e=>new i(e),C.createOption=(e,t)=>new a(e,t),C.createArgument=(e,i)=>new t(e,i),C.Command=i,C.Option=a,C.Argument=t,C.Help=r,C.CommanderError=n,C.InvalidArgumentError=o,C.InvalidOptionArgumentError=o,C}(),W=$(Y);const{program:Z,createCommand:X,createArgument:Q,createOption:ee,CommanderError:te,InvalidArgumentError:ie,InvalidOptionArgumentError:ne,Command:oe,Argument:re,Option:ae,Help:se}=W;function le(e,t,i){function n(i,n){if(i._zod||Object.defineProperty(i,"_zod",{value:{def:n,constr:a,traits:new Set},enumerable:!1}),i._zod.traits.has(e))return;i._zod.traits.add(e),t(i,n);const o=a.prototype,r=Object.keys(o);for(let e=0;e<r.length;e++){const t=r[e];t in i||(i[t]=o[t].bind(i))}}const o=i?.Parent??Object;class r extends o{}function a(e){var t;const o=i?.Parent?new r:this;n(o,e),(t=o._zod).deferred??(t.deferred=[]);for(const e of o._zod.deferred)e();return o}return Object.defineProperty(r,"name",{value:e}),Object.defineProperty(a,"init",{value:n}),Object.defineProperty(a,Symbol.hasInstance,{value:t=>!!(i?.Parent&&t instanceof i.Parent)||t?._zod?.traits?.has(e)}),Object.defineProperty(a,"name",{value:e}),a}class ce extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class de extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name="ZodEncodeError"}}const ue={};function pe(e){return ue}function me(e){const t=Object.values(e).filter(e=>"number"==typeof e);return Object.entries(e).filter(([e,i])=>-1===t.indexOf(+e)).map(([e,t])=>t)}function he(e,t){return"bigint"==typeof t?t.toString():t}function fe(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function ge(e){return null==e}function ve(e){const t=e.startsWith("^")?1:0,i=e.endsWith("$")?e.length-1:e.length;return e.slice(t,i)}const ye=Symbol("evaluating");function be(e,t,i){let n;Object.defineProperty(e,t,{get(){if(n!==ye)return void 0===n&&(n=ye,n=i()),n},set(i){Object.defineProperty(e,t,{value:i})},configurable:!0})}function _e(e,t,i){Object.defineProperty(e,t,{value:i,writable:!0,enumerable:!0,configurable:!0})}function we(...e){const t={};for(const i of e){const e=Object.getOwnPropertyDescriptors(i);Object.assign(t,e)}return Object.defineProperties({},t)}function ke(e){return JSON.stringify(e)}const xe="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function Se(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}const Ee=fe(()=>{if("undefined"!=typeof navigator&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch(e){return!1}});function Oe(e){if(!1===Se(e))return!1;const t=e.constructor;if(void 0===t)return!0;if("function"!=typeof t)return!0;const i=t.prototype;return!1!==Se(i)&&!1!==Object.prototype.hasOwnProperty.call(i,"isPrototypeOf")}function Te(e){return Oe(e)?{...e}:Array.isArray(e)?[...e]:e}const Ae=new Set(["string","number","symbol"]);function $e(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ne(e,t,i){const n=new e._zod.constr(t??e._zod.def);return t&&!i?.parent||(n._zod.parent=e),n}function je(e){const t=e;if(!t)return{};if("string"==typeof t)return{error:()=>t};if(void 0!==t?.message){if(void 0!==t?.error)throw new Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,"string"==typeof t.error?{...t,error:()=>t.error}:t}const Ce={safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-34028234663852886e22,34028234663852886e22],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]};function Ie(e,t=0){if(!0===e.aborted)return!0;for(let i=t;i<e.issues.length;i++)if(!0!==e.issues[i]?.continue)return!0;return!1}function Re(e,t){return t.map(t=>{var i;return(i=t).path??(i.path=[]),t.path.unshift(e),t})}function qe(e){return"string"==typeof e?e:e?.message}function Pe(e,t,i){const n={...e,path:e.path??[]};if(!e.message){const o=qe(e.inst?._zod.def?.error?.(e))??qe(t?.error?.(e))??qe(i.customError?.(e))??qe(i.localeError?.(e))??"Invalid input";n.message=o}return delete n.inst,delete n.continue,t?.reportInput||delete n.input,n}function Le(e){return Array.isArray(e)?"array":"string"==typeof e?"string":"unknown"}function ze(...e){const[t,i,n]=e;return"string"==typeof t?{message:t,code:"custom",input:i,inst:n}:{...t}}const Me=(e,t)=>{e.name="$ZodError",Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),e.message=JSON.stringify(t,he,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},Ue=le("$ZodError",Me),Fe=le("$ZodError",Me,{Parent:Error}),De=e=>(t,i,n,o)=>{const r=n?Object.assign(n,{async:!1}):{async:!1},a=t._zod.run({value:i,issues:[]},r);if(a instanceof Promise)throw new ce;if(a.issues.length){const t=new(o?.Err??e)(a.issues.map(e=>Pe(e,r,pe())));throw xe(t,o?.callee),t}return a.value},He=e=>async(t,i,n,o)=>{const r=n?Object.assign(n,{async:!0}):{async:!0};let a=t._zod.run({value:i,issues:[]},r);if(a instanceof Promise&&(a=await a),a.issues.length){const t=new(o?.Err??e)(a.issues.map(e=>Pe(e,r,pe())));throw xe(t,o?.callee),t}return a.value},Be=e=>(t,i,n)=>{const o=n?{...n,async:!1}:{async:!1},r=t._zod.run({value:i,issues:[]},o);if(r instanceof Promise)throw new ce;return r.issues.length?{success:!1,error:new(e??Ue)(r.issues.map(e=>Pe(e,o,pe())))}:{success:!0,data:r.value}},Ve=Be(Fe),Je=e=>async(t,i,n)=>{const o=n?Object.assign(n,{async:!0}):{async:!0};let r=t._zod.run({value:i,issues:[]},o);return r instanceof Promise&&(r=await r),r.issues.length?{success:!1,error:new e(r.issues.map(e=>Pe(e,o,pe())))}:{success:!0,data:r.value}},Ke=Je(Fe),Ge=e=>(t,i,n)=>{const o=n?Object.assign(n,{direction:"backward"}):{direction:"backward"};return De(e)(t,i,o)},Ye=e=>(t,i,n)=>De(e)(t,i,n),We=e=>async(t,i,n)=>{const o=n?Object.assign(n,{direction:"backward"}):{direction:"backward"};return He(e)(t,i,o)},Ze=e=>async(t,i,n)=>He(e)(t,i,n),Xe=e=>(t,i,n)=>{const o=n?Object.assign(n,{direction:"backward"}):{direction:"backward"};return Be(e)(t,i,o)},Qe=e=>(t,i,n)=>Be(e)(t,i,n),et=e=>async(t,i,n)=>{const o=n?Object.assign(n,{direction:"backward"}):{direction:"backward"};return Je(e)(t,i,o)},tt=e=>async(t,i,n)=>Je(e)(t,i,n),it=/^[cC][^\s-]{8,}$/,nt=/^[0-9a-z]+$/,ot=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,rt=/^[0-9a-vA-V]{20}$/,at=/^[A-Za-z0-9]{27}$/,st=/^[a-zA-Z0-9_-]{21}$/,lt=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,ct=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,dt=e=>e?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,ut=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,pt=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,mt=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,ht=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,ft=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,gt=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,vt=/^[A-Za-z0-9_-]*$/,yt=/^\+[1-9]\d{6,14}$/,bt="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))",_t=new RegExp(`^${bt}$`);function wt(e){const t="(?:[01]\\d|2[0-3]):[0-5]\\d";return"number"==typeof e.precision?-1===e.precision?`${t}`:0===e.precision?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}const kt=/^-?\d+$/,xt=/^-?\d+(?:\.\d+)?$/,St=/^(?:true|false)$/i,Et=/^[^A-Z]*$/,Ot=/^[^a-z]*$/,Tt=le("$ZodCheck",(e,t)=>{var i;e._zod??(e._zod={}),e._zod.def=t,(i=e._zod).onattach??(i.onattach=[])}),At={number:"number",bigint:"bigint",object:"date"},$t=le("$ZodCheckLessThan",(e,t)=>{Tt.init(e,t);const i=At[typeof t.value];e._zod.onattach.push(e=>{const i=e._zod.bag,n=(t.inclusive?i.maximum:i.exclusiveMaximum)??Number.POSITIVE_INFINITY;t.value<n&&(t.inclusive?i.maximum=t.value:i.exclusiveMaximum=t.value)}),e._zod.check=n=>{(t.inclusive?n.value<=t.value:n.value<t.value)||n.issues.push({origin:i,code:"too_big",maximum:"object"==typeof t.value?t.value.getTime():t.value,input:n.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),Nt=le("$ZodCheckGreaterThan",(e,t)=>{Tt.init(e,t);const i=At[typeof t.value];e._zod.onattach.push(e=>{const i=e._zod.bag,n=(t.inclusive?i.minimum:i.exclusiveMinimum)??Number.NEGATIVE_INFINITY;t.value>n&&(t.inclusive?i.minimum=t.value:i.exclusiveMinimum=t.value)}),e._zod.check=n=>{(t.inclusive?n.value>=t.value:n.value>t.value)||n.issues.push({origin:i,code:"too_small",minimum:"object"==typeof t.value?t.value.getTime():t.value,input:n.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),jt=le("$ZodCheckMultipleOf",(e,t)=>{Tt.init(e,t),e._zod.onattach.push(e=>{var i;(i=e._zod.bag).multipleOf??(i.multipleOf=t.value)}),e._zod.check=i=>{if(typeof i.value!=typeof t.value)throw new Error("Cannot mix number and bigint in multiple_of check.");("bigint"==typeof i.value?i.value%t.value===BigInt(0):0===function(e,t){const i=(e.toString().split(".")[1]||"").length,n=t.toString();let o=(n.split(".")[1]||"").length;if(0===o&&/\d?e-\d?/.test(n)){const e=n.match(/\d?e-(\d?)/);e?.[1]&&(o=Number.parseInt(e[1]))}const r=i>o?i:o;return Number.parseInt(e.toFixed(r).replace(".",""))%Number.parseInt(t.toFixed(r).replace(".",""))/10**r}(i.value,t.value))||i.issues.push({origin:typeof i.value,code:"not_multiple_of",divisor:t.value,input:i.value,inst:e,continue:!t.abort})}}),Ct=le("$ZodCheckNumberFormat",(e,t)=>{Tt.init(e,t),t.format=t.format||"float64";const i=t.format?.includes("int"),n=i?"int":"number",[o,r]=Ce[t.format];e._zod.onattach.push(e=>{const n=e._zod.bag;n.format=t.format,n.minimum=o,n.maximum=r,i&&(n.pattern=kt)}),e._zod.check=a=>{const s=a.value;if(i){if(!Number.isInteger(s))return void a.issues.push({expected:n,format:t.format,code:"invalid_type",continue:!1,input:s,inst:e});if(!Number.isSafeInteger(s))return void(s>0?a.issues.push({input:s,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:n,inclusive:!0,continue:!t.abort}):a.issues.push({input:s,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:n,inclusive:!0,continue:!t.abort}))}s<o&&a.issues.push({origin:"number",input:s,code:"too_small",minimum:o,inclusive:!0,inst:e,continue:!t.abort}),s>r&&a.issues.push({origin:"number",input:s,code:"too_big",maximum:r,inclusive:!0,inst:e,continue:!t.abort})}}),It=le("$ZodCheckMaxLength",(e,t)=>{var i;Tt.init(e,t),(i=e._zod.def).when??(i.when=e=>{const t=e.value;return!ge(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const i=e._zod.bag.maximum??Number.POSITIVE_INFINITY;t.maximum<i&&(e._zod.bag.maximum=t.maximum)}),e._zod.check=i=>{const n=i.value;if(n.length<=t.maximum)return;const o=Le(n);i.issues.push({origin:o,code:"too_big",maximum:t.maximum,inclusive:!0,input:n,inst:e,continue:!t.abort})}}),Rt=le("$ZodCheckMinLength",(e,t)=>{var i;Tt.init(e,t),(i=e._zod.def).when??(i.when=e=>{const t=e.value;return!ge(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const i=e._zod.bag.minimum??Number.NEGATIVE_INFINITY;t.minimum>i&&(e._zod.bag.minimum=t.minimum)}),e._zod.check=i=>{const n=i.value;if(n.length>=t.minimum)return;const o=Le(n);i.issues.push({origin:o,code:"too_small",minimum:t.minimum,inclusive:!0,input:n,inst:e,continue:!t.abort})}}),qt=le("$ZodCheckLengthEquals",(e,t)=>{var i;Tt.init(e,t),(i=e._zod.def).when??(i.when=e=>{const t=e.value;return!ge(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const i=e._zod.bag;i.minimum=t.length,i.maximum=t.length,i.length=t.length}),e._zod.check=i=>{const n=i.value,o=n.length;if(o===t.length)return;const r=Le(n),a=o>t.length;i.issues.push({origin:r,...a?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:i.value,inst:e,continue:!t.abort})}}),Pt=le("$ZodCheckStringFormat",(e,t)=>{var i,n;Tt.init(e,t),e._zod.onattach.push(e=>{const i=e._zod.bag;i.format=t.format,t.pattern&&(i.patterns??(i.patterns=new Set),i.patterns.add(t.pattern))}),t.pattern?(i=e._zod).check??(i.check=i=>{t.pattern.lastIndex=0,t.pattern.test(i.value)||i.issues.push({origin:"string",code:"invalid_format",format:t.format,input:i.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(n=e._zod).check??(n.check=()=>{})}),Lt=le("$ZodCheckRegex",(e,t)=>{Pt.init(e,t),e._zod.check=i=>{t.pattern.lastIndex=0,t.pattern.test(i.value)||i.issues.push({origin:"string",code:"invalid_format",format:"regex",input:i.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),zt=le("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=Et),Pt.init(e,t)}),Mt=le("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=Ot),Pt.init(e,t)}),Ut=le("$ZodCheckIncludes",(e,t)=>{Tt.init(e,t);const i=$e(t.includes),n=new RegExp("number"==typeof t.position?`^.{${t.position}}${i}`:i);t.pattern=n,e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(n)}),e._zod.check=i=>{i.value.includes(t.includes,t.position)||i.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:i.value,inst:e,continue:!t.abort})}}),Ft=le("$ZodCheckStartsWith",(e,t)=>{Tt.init(e,t);const i=new RegExp(`^${$e(t.prefix)}.*`);t.pattern??(t.pattern=i),e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(i)}),e._zod.check=i=>{i.value.startsWith(t.prefix)||i.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:i.value,inst:e,continue:!t.abort})}}),Dt=le("$ZodCheckEndsWith",(e,t)=>{Tt.init(e,t);const i=new RegExp(`.*${$e(t.suffix)}$`);t.pattern??(t.pattern=i),e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(i)}),e._zod.check=i=>{i.value.endsWith(t.suffix)||i.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:i.value,inst:e,continue:!t.abort})}}),Ht=le("$ZodCheckOverwrite",(e,t)=>{Tt.init(e,t),e._zod.check=e=>{e.value=t.tx(e.value)}});class Bt{constructor(e=[]){this.content=[],this.indent=0,this&&(this.args=e)}indented(e){this.indent+=1,e(this),this.indent-=1}write(e){if("function"==typeof e)return e(this,{execution:"sync"}),void e(this,{execution:"async"});const t=e.split("\n").filter(e=>e),i=Math.min(...t.map(e=>e.length-e.trimStart().length)),n=t.map(e=>e.slice(i)).map(e=>" ".repeat(2*this.indent)+e);for(const e of n)this.content.push(e)}compile(){const e=Function,t=this?.args;return new e(...t,[...(this?.content??[""]).map(e=>` ${e}`)].join("\n"))}}const Vt={major:4,minor:3,patch:6},Jt=le("$ZodType",(e,t)=>{var i;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=Vt;const n=[...e._zod.def.checks??[]];e._zod.traits.has("$ZodCheck")&&n.unshift(e);for(const t of n)for(const i of t._zod.onattach)i(e);if(0===n.length)(i=e._zod).deferred??(i.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{const t=(e,t,i)=>{let n,o=Ie(e);for(const r of t){if(r._zod.def.when){if(!r._zod.def.when(e))continue}else if(o)continue;const t=e.issues.length,a=r._zod.check(e);if(a instanceof Promise&&!1===i?.async)throw new ce;if(n||a instanceof Promise)n=(n??Promise.resolve()).then(async()=>{await a,e.issues.length!==t&&(o||(o=Ie(e,t)))});else{if(e.issues.length===t)continue;o||(o=Ie(e,t))}}return n?n.then(()=>e):e},i=(i,o,r)=>{if(Ie(i))return i.aborted=!0,i;const a=t(o,n,r);if(a instanceof Promise){if(!1===r.async)throw new ce;return a.then(t=>e._zod.parse(t,r))}return e._zod.parse(a,r)};e._zod.run=(o,r)=>{if(r.skipChecks)return e._zod.parse(o,r);if("backward"===r.direction){const t=e._zod.parse({value:o.value,issues:[]},{...r,skipChecks:!0});return t instanceof Promise?t.then(e=>i(e,o,r)):i(t,o,r)}const a=e._zod.parse(o,r);if(a instanceof Promise){if(!1===r.async)throw new ce;return a.then(e=>t(e,n,r))}return t(a,n,r)}}be(e,"~standard",()=>({validate:t=>{try{const i=Ve(e,t);return i.success?{value:i.data}:{issues:i.error?.issues}}catch(i){return Ke(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:"zod",version:1}))}),Kt=le("$ZodString",(e,t)=>{var i;Jt.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??(i=e._zod.bag,new RegExp(`^${i?`[\\s\\S]{${i?.minimum??0},${i?.maximum??""}}`:"[\\s\\S]*"}$`)),e._zod.parse=(i,n)=>{if(t.coerce)try{i.value=String(i.value)}catch(n){}return"string"==typeof i.value||i.issues.push({expected:"string",code:"invalid_type",input:i.value,inst:e}),i}}),Gt=le("$ZodStringFormat",(e,t)=>{Pt.init(e,t),Kt.init(e,t)}),Yt=le("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=ct),Gt.init(e,t)}),Wt=le("$ZodUUID",(e,t)=>{if(t.version){const e={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[t.version];if(void 0===e)throw new Error(`Invalid UUID version: "${t.version}"`);t.pattern??(t.pattern=dt(e))}else t.pattern??(t.pattern=dt());Gt.init(e,t)}),Zt=le("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=ut),Gt.init(e,t)}),Xt=le("$ZodURL",(e,t)=>{Gt.init(e,t),e._zod.check=i=>{try{const n=i.value.trim(),o=new URL(n);return t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(o.hostname)||i.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:t.hostname.source,input:i.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(o.protocol.endsWith(":")?o.protocol.slice(0,-1):o.protocol)||i.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:t.protocol.source,input:i.value,inst:e,continue:!t.abort})),void(t.normalize?i.value=o.href:i.value=n)}catch(n){i.issues.push({code:"invalid_format",format:"url",input:i.value,inst:e,continue:!t.abort})}}}),Qt=le("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),Gt.init(e,t)}),ei=le("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=st),Gt.init(e,t)}),ti=le("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=it),Gt.init(e,t)}),ii=le("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=nt),Gt.init(e,t)}),ni=le("$ZodULID",(e,t)=>{t.pattern??(t.pattern=ot),Gt.init(e,t)}),oi=le("$ZodXID",(e,t)=>{t.pattern??(t.pattern=rt),Gt.init(e,t)}),ri=le("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=at),Gt.init(e,t)}),ai=le("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=function(e){const t=wt({precision:e.precision}),i=["Z"];e.local&&i.push(""),e.offset&&i.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");const n=`${t}(?:${i.join("|")})`;return new RegExp(`^${bt}T(?:${n})$`)}(t)),Gt.init(e,t)}),si=le("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=_t),Gt.init(e,t)}),li=le("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=new RegExp(`^${wt(t)}$`)),Gt.init(e,t)}),ci=le("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=lt),Gt.init(e,t)}),di=le("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=pt),Gt.init(e,t),e._zod.bag.format="ipv4"}),ui=le("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=mt),Gt.init(e,t),e._zod.bag.format="ipv6",e._zod.check=i=>{try{new URL(`http://[${i.value}]`)}catch{i.issues.push({code:"invalid_format",format:"ipv6",input:i.value,inst:e,continue:!t.abort})}}}),pi=le("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=ht),Gt.init(e,t)}),mi=le("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=ft),Gt.init(e,t),e._zod.check=i=>{const n=i.value.split("/");try{if(2!==n.length)throw new Error;const[e,t]=n;if(!t)throw new Error;const i=Number(t);if(`${i}`!==t)throw new Error;if(i<0||i>128)throw new Error;new URL(`http://[${e}]`)}catch{i.issues.push({code:"invalid_format",format:"cidrv6",input:i.value,inst:e,continue:!t.abort})}}});function hi(e){if(""===e)return!0;if(e.length%4!=0)return!1;try{return atob(e),!0}catch{return!1}}const fi=le("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=gt),Gt.init(e,t),e._zod.bag.contentEncoding="base64",e._zod.check=i=>{hi(i.value)||i.issues.push({code:"invalid_format",format:"base64",input:i.value,inst:e,continue:!t.abort})}}),gi=le("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=vt),Gt.init(e,t),e._zod.bag.contentEncoding="base64url",e._zod.check=i=>{(function(e){if(!vt.test(e))return!1;const t=e.replace(/[-_]/g,e=>"-"===e?"+":"/");return hi(t.padEnd(4*Math.ceil(t.length/4),"="))})(i.value)||i.issues.push({code:"invalid_format",format:"base64url",input:i.value,inst:e,continue:!t.abort})}}),vi=le("$ZodE164",(e,t)=>{t.pattern??(t.pattern=yt),Gt.init(e,t)}),yi=le("$ZodJWT",(e,t)=>{Gt.init(e,t),e._zod.check=i=>{(function(e,t=null){try{const i=e.split(".");if(3!==i.length)return!1;const[n]=i;if(!n)return!1;const o=JSON.parse(atob(n));return!("typ"in o&&"JWT"!==o?.typ||!o.alg||t&&(!("alg"in o)||o.alg!==t))}catch{return!1}})(i.value,t.alg)||i.issues.push({code:"invalid_format",format:"jwt",input:i.value,inst:e,continue:!t.abort})}}),bi=le("$ZodNumber",(e,t)=>{Jt.init(e,t),e._zod.pattern=e._zod.bag.pattern??xt,e._zod.parse=(i,n)=>{if(t.coerce)try{i.value=Number(i.value)}catch(e){}const o=i.value;if("number"==typeof o&&!Number.isNaN(o)&&Number.isFinite(o))return i;const r="number"==typeof o?Number.isNaN(o)?"NaN":Number.isFinite(o)?void 0:"Infinity":void 0;return i.issues.push({expected:"number",code:"invalid_type",input:o,inst:e,...r?{received:r}:{}}),i}}),_i=le("$ZodNumberFormat",(e,t)=>{Ct.init(e,t),bi.init(e,t)}),wi=le("$ZodBoolean",(e,t)=>{Jt.init(e,t),e._zod.pattern=St,e._zod.parse=(i,n)=>{if(t.coerce)try{i.value=Boolean(i.value)}catch(e){}const o=i.value;return"boolean"==typeof o||i.issues.push({expected:"boolean",code:"invalid_type",input:o,inst:e}),i}}),ki=le("$ZodUnknown",(e,t)=>{Jt.init(e,t),e._zod.parse=e=>e}),xi=le("$ZodNever",(e,t)=>{Jt.init(e,t),e._zod.parse=(t,i)=>(t.issues.push({expected:"never",code:"invalid_type",input:t.value,inst:e}),t)});function Si(e,t,i){e.issues.length&&t.issues.push(...Re(i,e.issues)),t.value[i]=e.value}const Ei=le("$ZodArray",(e,t)=>{Jt.init(e,t),e._zod.parse=(i,n)=>{const o=i.value;if(!Array.isArray(o))return i.issues.push({expected:"array",code:"invalid_type",input:o,inst:e}),i;i.value=Array(o.length);const r=[];for(let e=0;e<o.length;e++){const a=o[e],s=t.element._zod.run({value:a,issues:[]},n);s instanceof Promise?r.push(s.then(t=>Si(t,i,e))):Si(s,i,e)}return r.length?Promise.all(r).then(()=>i):i}});function Oi(e,t,i,n,o){if(e.issues.length){if(o&&!(i in n))return;t.issues.push(...Re(i,e.issues))}void 0===e.value?i in n&&(t.value[i]=void 0):t.value[i]=e.value}function Ti(e){const t=Object.keys(e.shape);for(const i of t)if(!e.shape?.[i]?._zod?.traits?.has("$ZodType"))throw new Error(`Invalid element at key "${i}": expected a Zod schema`);const i=(n=e.shape,Object.keys(n).filter(e=>"optional"===n[e]._zod.optin&&"optional"===n[e]._zod.optout));var n;return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(i)}}function Ai(e,t,i,n,o,r){const a=[],s=o.keySet,l=o.catchall._zod,c=l.def.type,d="optional"===l.optout;for(const o in t){if(s.has(o))continue;if("never"===c){a.push(o);continue}const r=l.run({value:t[o],issues:[]},n);r instanceof Promise?e.push(r.then(e=>Oi(e,i,o,t,d))):Oi(r,i,o,t,d)}return a.length&&i.issues.push({code:"unrecognized_keys",keys:a,input:t,inst:r}),e.length?Promise.all(e).then(()=>i):i}const $i=le("$ZodObject",(e,t)=>{Jt.init(e,t);const i=Object.getOwnPropertyDescriptor(t,"shape");if(!i?.get){const e=t.shape;Object.defineProperty(t,"shape",{get:()=>{const i={...e};return Object.defineProperty(t,"shape",{value:i}),i}})}const n=fe(()=>Ti(t));be(e._zod,"propValues",()=>{const e=t.shape,i={};for(const t in e){const n=e[t]._zod;if(n.values){i[t]??(i[t]=new Set);for(const e of n.values)i[t].add(e)}}return i});const o=Se,r=t.catchall;let a;e._zod.parse=(t,i)=>{a??(a=n.value);const s=t.value;if(!o(s))return t.issues.push({expected:"object",code:"invalid_type",input:s,inst:e}),t;t.value={};const l=[],c=a.shape;for(const e of a.keys){const n=c[e],o="optional"===n._zod.optout,r=n._zod.run({value:s[e],issues:[]},i);r instanceof Promise?l.push(r.then(i=>Oi(i,t,e,s,o))):Oi(r,t,e,s,o)}return r?Ai(l,s,t,i,n.value,e):l.length?Promise.all(l).then(()=>t):t}}),Ni=le("$ZodObjectJIT",(e,t)=>{$i.init(e,t);const i=e._zod.parse,n=fe(()=>Ti(t));let o;const r=Se,a=!ue.jitless,s=a&&Ee.value,l=t.catchall;let c;e._zod.parse=(d,u)=>{c??(c=n.value);const p=d.value;return r(p)?a&&s&&!1===u?.async&&!0!==u.jitless?(o||(o=(e=>{const t=new Bt(["shape","payload","ctx"]),i=n.value,o=e=>{const t=ke(e);return`shape[${t}]._zod.run({ value: input[${t}], issues: [] }, ctx)`};t.write("const input = payload.value;");const r=Object.create(null);let a=0;for(const e of i.keys)r[e]="key_"+a++;t.write("const newResult = {};");for(const n of i.keys){const i=r[n],a=ke(n),s=e[n],l="optional"===s?._zod?.optout;t.write(`const ${i} = ${o(n)};`),l?t.write(`\n if (${i}.issues.length) {\n if (${a} in input) {\n payload.issues = payload.issues.concat(${i}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${a}, ...iss.path] : [${a}]\n })));\n }\n }\n \n if (${i}.value === undefined) {\n if (${a} in input) {\n newResult[${a}] = undefined;\n }\n } else {\n newResult[${a}] = ${i}.value;\n }\n \n `):t.write(`\n if (${i}.issues.length) {\n payload.issues = payload.issues.concat(${i}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${a}, ...iss.path] : [${a}]\n })));\n }\n \n if (${i}.value === undefined) {\n if (${a} in input) {\n newResult[${a}] = undefined;\n }\n } else {\n newResult[${a}] = ${i}.value;\n }\n \n `)}t.write("payload.value = newResult;"),t.write("return payload;");const s=t.compile();return(t,i)=>s(e,t,i)})(t.shape)),d=o(d,u),l?Ai([],p,d,u,c,e):d):i(d,u):(d.issues.push({expected:"object",code:"invalid_type",input:p,inst:e}),d)}});function ji(e,t,i,n){for(const i of e)if(0===i.issues.length)return t.value=i.value,t;const o=e.filter(e=>!Ie(e));return 1===o.length?(t.value=o[0].value,o[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:i,errors:e.map(e=>e.issues.map(e=>Pe(e,n,pe())))}),t)}const Ci=le("$ZodUnion",(e,t)=>{Jt.init(e,t),be(e._zod,"optin",()=>t.options.some(e=>"optional"===e._zod.optin)?"optional":void 0),be(e._zod,"optout",()=>t.options.some(e=>"optional"===e._zod.optout)?"optional":void 0),be(e._zod,"values",()=>{if(t.options.every(e=>e._zod.values))return new Set(t.options.flatMap(e=>Array.from(e._zod.values)))}),be(e._zod,"pattern",()=>{if(t.options.every(e=>e._zod.pattern)){const e=t.options.map(e=>e._zod.pattern);return new RegExp(`^(${e.map(e=>ve(e.source)).join("|")})$`)}});const i=1===t.options.length,n=t.options[0]._zod.run;e._zod.parse=(o,r)=>{if(i)return n(o,r);let a=!1;const s=[];for(const e of t.options){const t=e._zod.run({value:o.value,issues:[]},r);if(t instanceof Promise)s.push(t),a=!0;else{if(0===t.issues.length)return t;s.push(t)}}return a?Promise.all(s).then(t=>ji(t,o,e,r)):ji(s,o,e,r)}}),Ii=le("$ZodIntersection",(e,t)=>{Jt.init(e,t),e._zod.parse=(e,i)=>{const n=e.value,o=t.left._zod.run({value:n,issues:[]},i),r=t.right._zod.run({value:n,issues:[]},i);return o instanceof Promise||r instanceof Promise?Promise.all([o,r]).then(([t,i])=>qi(e,t,i)):qi(e,o,r)}});function Ri(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e===+t)return{valid:!0,data:e};if(Oe(e)&&Oe(t)){const i=Object.keys(t),n=Object.keys(e).filter(e=>-1!==i.indexOf(e)),o={...e,...t};for(const i of n){const n=Ri(e[i],t[i]);if(!n.valid)return{valid:!1,mergeErrorPath:[i,...n.mergeErrorPath]};o[i]=n.data}return{valid:!0,data:o}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const i=[];for(let n=0;n<e.length;n++){const o=Ri(e[n],t[n]);if(!o.valid)return{valid:!1,mergeErrorPath:[n,...o.mergeErrorPath]};i.push(o.data)}return{valid:!0,data:i}}return{valid:!1,mergeErrorPath:[]}}function qi(e,t,i){const n=new Map;let o;for(const i of t.issues)if("unrecognized_keys"===i.code){o??(o=i);for(const e of i.keys)n.has(e)||n.set(e,{}),n.get(e).l=!0}else e.issues.push(i);for(const t of i.issues)if("unrecognized_keys"===t.code)for(const e of t.keys)n.has(e)||n.set(e,{}),n.get(e).r=!0;else e.issues.push(t);const r=[...n].filter(([,e])=>e.l&&e.r).map(([e])=>e);if(r.length&&o&&e.issues.push({...o,keys:r}),Ie(e))return e;const a=Ri(t.value,i.value);if(!a.valid)throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(a.mergeErrorPath)}`);return e.value=a.data,e}const Pi=le("$ZodEnum",(e,t)=>{Jt.init(e,t);const i=me(t.entries),n=new Set(i);e._zod.values=n,e._zod.pattern=new RegExp(`^(${i.filter(e=>Ae.has(typeof e)).map(e=>"string"==typeof e?$e(e):e.toString()).join("|")})$`),e._zod.parse=(t,o)=>{const r=t.value;return n.has(r)||t.issues.push({code:"invalid_value",values:i,input:r,inst:e}),t}}),Li=le("$ZodTransform",(e,t)=>{Jt.init(e,t),e._zod.parse=(i,n)=>{if("backward"===n.direction)throw new de(e.constructor.name);const o=t.transform(i.value,i);if(n.async)return(o instanceof Promise?o:Promise.resolve(o)).then(e=>(i.value=e,i));if(o instanceof Promise)throw new ce;return i.value=o,i}});function zi(e,t){return e.issues.length&&void 0===t?{issues:[],value:void 0}:e}const Mi=le("$ZodOptional",(e,t)=>{Jt.init(e,t),e._zod.optin="optional",e._zod.optout="optional",be(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),be(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${ve(e.source)})?$`):void 0}),e._zod.parse=(e,i)=>{if("optional"===t.innerType._zod.optin){const n=t.innerType._zod.run(e,i);return n instanceof Promise?n.then(t=>zi(t,e.value)):zi(n,e.value)}return void 0===e.value?e:t.innerType._zod.run(e,i)}}),Ui=le("$ZodExactOptional",(e,t)=>{Mi.init(e,t),be(e._zod,"values",()=>t.innerType._zod.values),be(e._zod,"pattern",()=>t.innerType._zod.pattern),e._zod.parse=(e,i)=>t.innerType._zod.run(e,i)}),Fi=le("$ZodNullable",(e,t)=>{Jt.init(e,t),be(e._zod,"optin",()=>t.innerType._zod.optin),be(e._zod,"optout",()=>t.innerType._zod.optout),be(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${ve(e.source)}|null)$`):void 0}),be(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(e,i)=>null===e.value?e:t.innerType._zod.run(e,i)}),Di=le("$ZodDefault",(e,t)=>{Jt.init(e,t),e._zod.optin="optional",be(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,i)=>{if("backward"===i.direction)return t.innerType._zod.run(e,i);if(void 0===e.value)return e.value=t.defaultValue,e;const n=t.innerType._zod.run(e,i);return n instanceof Promise?n.then(e=>Hi(e,t)):Hi(n,t)}});function Hi(e,t){return void 0===e.value&&(e.value=t.defaultValue),e}const Bi=le("$ZodPrefault",(e,t)=>{Jt.init(e,t),e._zod.optin="optional",be(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,i)=>("backward"===i.direction||void 0===e.value&&(e.value=t.defaultValue),t.innerType._zod.run(e,i))}),Vi=le("$ZodNonOptional",(e,t)=>{Jt.init(e,t),be(e._zod,"values",()=>{const e=t.innerType._zod.values;return e?new Set([...e].filter(e=>void 0!==e)):void 0}),e._zod.parse=(i,n)=>{const o=t.innerType._zod.run(i,n);return o instanceof Promise?o.then(t=>Ji(t,e)):Ji(o,e)}});function Ji(e,t){return e.issues.length||void 0!==e.value||e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const Ki=le("$ZodCatch",(e,t)=>{Jt.init(e,t),be(e._zod,"optin",()=>t.innerType._zod.optin),be(e._zod,"optout",()=>t.innerType._zod.optout),be(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,i)=>{if("backward"===i.direction)return t.innerType._zod.run(e,i);const n=t.innerType._zod.run(e,i);return n instanceof Promise?n.then(n=>(e.value=n.value,n.issues.length&&(e.value=t.catchValue({...e,error:{issues:n.issues.map(e=>Pe(e,i,pe()))},input:e.value}),e.issues=[]),e)):(e.value=n.value,n.issues.length&&(e.value=t.catchValue({...e,error:{issues:n.issues.map(e=>Pe(e,i,pe()))},input:e.value}),e.issues=[]),e)}}),Gi=le("$ZodPipe",(e,t)=>{Jt.init(e,t),be(e._zod,"values",()=>t.in._zod.values),be(e._zod,"optin",()=>t.in._zod.optin),be(e._zod,"optout",()=>t.out._zod.optout),be(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(e,i)=>{if("backward"===i.direction){const n=t.out._zod.run(e,i);return n instanceof Promise?n.then(e=>Yi(e,t.in,i)):Yi(n,t.in,i)}const n=t.in._zod.run(e,i);return n instanceof Promise?n.then(e=>Yi(e,t.out,i)):Yi(n,t.out,i)}});function Yi(e,t,i){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},i)}const Wi=le("$ZodReadonly",(e,t)=>{Jt.init(e,t),be(e._zod,"propValues",()=>t.innerType._zod.propValues),be(e._zod,"values",()=>t.innerType._zod.values),be(e._zod,"optin",()=>t.innerType?._zod?.optin),be(e._zod,"optout",()=>t.innerType?._zod?.optout),e._zod.parse=(e,i)=>{if("backward"===i.direction)return t.innerType._zod.run(e,i);const n=t.innerType._zod.run(e,i);return n instanceof Promise?n.then(Zi):Zi(n)}});function Zi(e){return e.value=Object.freeze(e.value),e}const Xi=le("$ZodCustom",(e,t)=>{Tt.init(e,t),Jt.init(e,t),e._zod.parse=(e,t)=>e,e._zod.check=i=>{const n=i.value,o=t.fn(n);if(o instanceof Promise)return o.then(t=>Qi(t,i,n,e));Qi(o,i,n,e)}});function Qi(e,t,i,n){if(!e){const e={code:"custom",input:i,inst:n,path:[...n._zod.def.path??[]],continue:!n._zod.def.abort};n._zod.def.params&&(e.params=n._zod.def.params),t.issues.push(ze(e))}}var en;(en=globalThis).__zod_globalRegistry??(en.__zod_globalRegistry=new class{constructor(){this._map=new WeakMap,this._idmap=new Map}add(e,...t){const i=t[0];return this._map.set(e,i),i&&"object"==typeof i&&"id"in i&&this._idmap.set(i.id,e),this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(e){const t=this._map.get(e);return t&&"object"==typeof t&&"id"in t&&this._idmap.delete(t.id),this._map.delete(e),this}get(e){const t=e._zod.parent;if(t){const i={...this.get(t)??{}};delete i.id;const n={...i,...this._map.get(e)};return Object.keys(n).length?n:void 0}return this._map.get(e)}has(e){return this._map.has(e)}});const tn=globalThis.__zod_globalRegistry;function nn(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...je(t)})}function on(e,t){return new $t({check:"less_than",...je(t),value:e,inclusive:!1})}function rn(e,t){return new $t({check:"less_than",...je(t),value:e,inclusive:!0})}function an(e,t){return new Nt({check:"greater_than",...je(t),value:e,inclusive:!1})}function sn(e,t){return new Nt({check:"greater_than",...je(t),value:e,inclusive:!0})}function ln(e,t){return new jt({check:"multiple_of",...je(t),value:e})}function cn(e,t){return new It({check:"max_length",...je(t),maximum:e})}function dn(e,t){return new Rt({check:"min_length",...je(t),minimum:e})}function un(e,t){return new qt({check:"length_equals",...je(t),length:e})}function pn(e){return new Ht({check:"overwrite",tx:e})}function mn(e){let t=e?.target??"draft-2020-12";return"draft-4"===t&&(t="draft-04"),"draft-7"===t&&(t="draft-07"),{processors:e.processors??{},metadataRegistry:e?.metadata??tn,target:t,unrepresentable:e?.unrepresentable??"throw",override:e?.override??(()=>{}),io:e?.io??"output",counter:0,seen:new Map,cycles:e?.cycles??"ref",reused:e?.reused??"inline",external:e?.external??void 0}}function hn(e,t,i={path:[],schemaPath:[]}){var n;const o=e._zod.def,r=t.seen.get(e);if(r)return r.count++,i.schemaPath.includes(e)&&(r.cycle=i.path),r.schema;const a={schema:{},count:1,cycle:void 0,path:i.path};t.seen.set(e,a);const s=e._zod.toJSONSchema?.();if(s)a.schema=s;else{const n={...i,schemaPath:[...i.schemaPath,e],path:i.path};if(e._zod.processJSONSchema)e._zod.processJSONSchema(t,a.schema,n);else{const i=a.schema,r=t.processors[o.type];if(!r)throw new Error(`[toJSONSchema]: Non-representable type encountered: ${o.type}`);r(e,t,i,n)}const r=e._zod.parent;r&&(a.ref||(a.ref=r),hn(r,t,n),t.seen.get(r).isParent=!0)}const l=t.metadataRegistry.get(e);return l&&Object.assign(a.schema,l),"input"===t.io&&vn(e)&&(delete a.schema.examples,delete a.schema.default),"input"===t.io&&a.schema._prefault&&((n=a.schema).default??(n.default=a.schema._prefault)),delete a.schema._prefault,t.seen.get(e).schema}function fn(e,t){const i=e.seen.get(t);if(!i)throw new Error("Unprocessed schema. This is a bug in Zod.");const n=new Map;for(const t of e.seen.entries()){const i=e.metadataRegistry.get(t[0])?.id;if(i){const e=n.get(i);if(e&&e!==t[0])throw new Error(`Duplicate schema id "${i}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);n.set(i,t[0])}}const o=t=>{if(t[1].schema.$ref)return;const n=t[1],{ref:o,defId:r}=(t=>{const n="draft-2020-12"===e.target?"$defs":"definitions";if(e.external){const i=e.external.registry.get(t[0])?.id,o=e.external.uri??(e=>e);if(i)return{ref:o(i)};const r=t[1].defId??t[1].schema.id??"schema"+e.counter++;return t[1].defId=r,{defId:r,ref:`${o("__shared")}#/${n}/${r}`}}if(t[1]===i)return{ref:"#"};const o=`#/${n}/`,r=t[1].schema.id??"__schema"+e.counter++;return{defId:r,ref:o+r}})(t);n.def={...n.schema},r&&(n.defId=r);const a=n.schema;for(const e in a)delete a[e];a.$ref=o};if("throw"===e.cycles)for(const t of e.seen.entries()){const e=t[1];if(e.cycle)throw new Error(`Cycle detected: #/${e.cycle?.join("/")}/<root>\n\nSet the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`)}for(const i of e.seen.entries()){const n=i[1];if(t===i[0]){o(i);continue}if(e.external){const n=e.external.registry.get(i[0])?.id;if(t!==i[0]&&n){o(i);continue}}const r=e.metadataRegistry.get(i[0])?.id;(r||n.cycle||n.count>1&&"ref"===e.reused)&&o(i)}}function gn(e,t){const i=e.seen.get(t);if(!i)throw new Error("Unprocessed schema. This is a bug in Zod.");const n=t=>{const i=e.seen.get(t);if(null===i.ref)return;const o=i.def??i.schema,r={...o},a=i.ref;if(i.ref=null,a){n(a);const i=e.seen.get(a),s=i.schema;if(!s.$ref||"draft-07"!==e.target&&"draft-04"!==e.target&&"openapi-3.0"!==e.target?Object.assign(o,s):(o.allOf=o.allOf??[],o.allOf.push(s)),Object.assign(o,r),t._zod.parent===a)for(const e in o)"$ref"!==e&&"allOf"!==e&&(e in r||delete o[e]);if(s.$ref&&i.def)for(const e in o)"$ref"!==e&&"allOf"!==e&&e in i.def&&JSON.stringify(o[e])===JSON.stringify(i.def[e])&&delete o[e]}const s=t._zod.parent;if(s&&s!==a){n(s);const t=e.seen.get(s);if(t?.schema.$ref&&(o.$ref=t.schema.$ref,t.def))for(const e in o)"$ref"!==e&&"allOf"!==e&&e in t.def&&JSON.stringify(o[e])===JSON.stringify(t.def[e])&&delete o[e]}e.override({zodSchema:t,jsonSchema:o,path:i.path??[]})};for(const t of[...e.seen.entries()].reverse())n(t[0]);const o={};if("draft-2020-12"===e.target?o.$schema="https://json-schema.org/draft/2020-12/schema":"draft-07"===e.target?o.$schema="http://json-schema.org/draft-07/schema#":"draft-04"===e.target?o.$schema="http://json-schema.org/draft-04/schema#":e.target,e.external?.uri){const i=e.external.registry.get(t)?.id;if(!i)throw new Error("Schema is missing an `id` property");o.$id=e.external.uri(i)}Object.assign(o,i.def??i.schema);const r=e.external?.defs??{};for(const t of e.seen.entries()){const e=t[1];e.def&&e.defId&&(r[e.defId]=e.def)}e.external||Object.keys(r).length>0&&("draft-2020-12"===e.target?o.$defs=r:o.definitions=r);try{const i=JSON.parse(JSON.stringify(o));return Object.defineProperty(i,"~standard",{value:{...t["~standard"],jsonSchema:{input:yn(t,"input",e.processors),output:yn(t,"output",e.processors)}},enumerable:!1,writable:!1}),i}catch(e){throw new Error("Error converting schema to JSON.")}}function vn(e,t){const i=t??{seen:new Set};if(i.seen.has(e))return!1;i.seen.add(e);const n=e._zod.def;if("transform"===n.type)return!0;if("array"===n.type)return vn(n.element,i);if("set"===n.type)return vn(n.valueType,i);if("lazy"===n.type)return vn(n.getter(),i);if("promise"===n.type||"optional"===n.type||"nonoptional"===n.type||"nullable"===n.type||"readonly"===n.type||"default"===n.type||"prefault"===n.type)return vn(n.innerType,i);if("intersection"===n.type)return vn(n.left,i)||vn(n.right,i);if("record"===n.type||"map"===n.type)return vn(n.keyType,i)||vn(n.valueType,i);if("pipe"===n.type)return vn(n.in,i)||vn(n.out,i);if("object"===n.type){for(const e in n.shape)if(vn(n.shape[e],i))return!0;return!1}if("union"===n.type){for(const e of n.options)if(vn(e,i))return!0;return!1}if("tuple"===n.type){for(const e of n.items)if(vn(e,i))return!0;return!(!n.rest||!vn(n.rest,i))}return!1}const yn=(e,t,i={})=>n=>{const{libraryOptions:o,target:r}=n??{},a=mn({...o??{},target:r,io:t,processors:i});return hn(e,a),fn(a,e),gn(a,e)},bn={guid:"uuid",url:"uri",datetime:"date-time",json_string:"json-string",regex:""},_n=(e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType},wn=le("ZodISODateTime",(e,t)=>{ai.init(e,t),Dn.init(e,t)});const kn=le("ZodISODate",(e,t)=>{si.init(e,t),Dn.init(e,t)});const xn=le("ZodISOTime",(e,t)=>{li.init(e,t),Dn.init(e,t)});const Sn=le("ZodISODuration",(e,t)=>{ci.init(e,t),Dn.init(e,t)});const En=le("ZodError",(e,t)=>{Ue.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:t=>function(e,t=e=>e.message){const i={_errors:[]},n=e=>{for(const o of e.issues)if("invalid_union"===o.code&&o.errors.length)o.errors.map(e=>n({issues:e}));else if("invalid_key"===o.code)n({issues:o.issues});else if("invalid_element"===o.code)n({issues:o.issues});else if(0===o.path.length)i._errors.push(t(o));else{let e=i,n=0;for(;n<o.path.length;){const i=o.path[n];n===o.path.length-1?(e[i]=e[i]||{_errors:[]},e[i]._errors.push(t(o))):e[i]=e[i]||{_errors:[]},e=e[i],n++}}};return n(e),i}(e,t)},flatten:{value:t=>function(e,t=e=>e.message){const i={},n=[];for(const o of e.issues)o.path.length>0?(i[o.path[0]]=i[o.path[0]]||[],i[o.path[0]].push(t(o))):n.push(t(o));return{formErrors:n,fieldErrors:i}}(e,t)},addIssue:{value:t=>{e.issues.push(t),e.message=JSON.stringify(e.issues,he,2)}},addIssues:{value:t=>{e.issues.push(...t),e.message=JSON.stringify(e.issues,he,2)}},isEmpty:{get:()=>0===e.issues.length}})},{Parent:Error}),On=De(En),Tn=He(En),An=Be(En),$n=Je(En),Nn=Ge(En),jn=Ye(En),Cn=We(En),In=Ze(En),Rn=Xe(En),qn=Qe(En),Pn=et(En),Ln=tt(En),zn=le("ZodType",(e,t)=>(Jt.init(e,t),Object.assign(e["~standard"],{jsonSchema:{input:yn(e,"input"),output:yn(e,"output")}}),e.toJSONSchema=((e,t={})=>i=>{const n=mn({...i,processors:t});return hn(e,n),fn(n,e),gn(n,e)})(e,{}),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...i)=>e.clone(we(t,{checks:[...t.checks??[],...i.map(e=>"function"==typeof e?{_zod:{check:e,def:{check:"custom"},onattach:[]}}:e)]}),{parent:!0}),e.with=e.check,e.clone=(t,i)=>Ne(e,t,i),e.brand=()=>e,e.register=(t,i)=>(t.add(e,i),e),e.parse=(t,i)=>On(e,t,i,{callee:e.parse}),e.safeParse=(t,i)=>An(e,t,i),e.parseAsync=async(t,i)=>Tn(e,t,i,{callee:e.parseAsync}),e.safeParseAsync=async(t,i)=>$n(e,t,i),e.spa=e.safeParseAsync,e.encode=(t,i)=>Nn(e,t,i),e.decode=(t,i)=>jn(e,t,i),e.encodeAsync=async(t,i)=>Cn(e,t,i),e.decodeAsync=async(t,i)=>In(e,t,i),e.safeEncode=(t,i)=>Rn(e,t,i),e.safeDecode=(t,i)=>qn(e,t,i),e.safeEncodeAsync=async(t,i)=>Pn(e,t,i),e.safeDecodeAsync=async(t,i)=>Ln(e,t,i),e.refine=(t,i)=>e.check(function(e,t={}){return function(e,t,i){return new Uo({type:"custom",check:"custom",fn:t,...je(i)})}(0,e,t)}(t,i)),e.superRefine=t=>e.check(function(e){const t=function(e){const t=new Tt({check:"custom",...je(void 0)});return t._zod.check=e,t}(i=>(i.addIssue=e=>{if("string"==typeof e)i.issues.push(ze(e,i.value,t._zod.def));else{const n=e;n.fatal&&(n.continue=!1),n.code??(n.code="custom"),n.input??(n.input=i.value),n.inst??(n.inst=t),n.continue??(n.continue=!t._zod.def.abort),i.issues.push(ze(n))}},e(i.value,i)));return t}(t)),e.overwrite=t=>e.check(pn(t)),e.optional=()=>$o(e),e.exactOptional=()=>new No({type:"optional",innerType:e}),e.nullable=()=>Co(e),e.nullish=()=>$o(Co(e)),e.nonoptional=t=>function(e,t){return new qo({type:"nonoptional",innerType:e,...je(t)})}(e,t),e.array=()=>bo(e),e.or=t=>xo([e,t]),e.and=t=>new So({type:"intersection",left:e,right:t}),e.transform=t=>zo(e,new To({type:"transform",transform:t})),e.default=t=>{return i=t,new Io({type:"default",innerType:e,get defaultValue(){return"function"==typeof i?i():Te(i)}});var i},e.prefault=t=>{return i=t,new Ro({type:"prefault",innerType:e,get defaultValue(){return"function"==typeof i?i():Te(i)}});var i},e.catch=t=>{return new Po({type:"catch",innerType:e,catchValue:"function"==typeof(i=t)?i:()=>i});var i},e.pipe=t=>zo(e,t),e.readonly=()=>new Mo({type:"readonly",innerType:e}),e.describe=t=>{const i=e.clone();return tn.add(i,{description:t}),i},Object.defineProperty(e,"description",{get:()=>tn.get(e)?.description,configurable:!0}),e.meta=(...t)=>{if(0===t.length)return tn.get(e);const i=e.clone();return tn.add(i,t[0]),i},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e.apply=t=>t(e),e)),Mn=le("_ZodString",(e,t)=>{Kt.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i)=>{const n=i;n.type="string";const{minimum:o,maximum:r,format:a,patterns:s,contentEncoding:l}=e._zod.bag;if("number"==typeof o&&(n.minLength=o),"number"==typeof r&&(n.maxLength=r),a&&(n.format=bn[a]??a,""===n.format&&delete n.format,"time"===a&&delete n.format),l&&(n.contentEncoding=l),s&&s.size>0){const e=[...s];1===e.length?n.pattern=e[0].source:e.length>1&&(n.allOf=[...e.map(e=>({..."draft-07"===t.target||"draft-04"===t.target||"openapi-3.0"===t.target?{type:"string"}:{},pattern:e.source}))])}})(e,t,i);const i=e._zod.bag;e.format=i.format??null,e.minLength=i.minimum??null,e.maxLength=i.maximum??null,e.regex=(...t)=>e.check(function(e,t){return new Lt({check:"string_format",format:"regex",...je(t),pattern:e})}(...t)),e.includes=(...t)=>e.check(function(e,t){return new Ut({check:"string_format",format:"includes",...je(t),includes:e})}(...t)),e.startsWith=(...t)=>e.check(function(e,t){return new Ft({check:"string_format",format:"starts_with",...je(t),prefix:e})}(...t)),e.endsWith=(...t)=>e.check(function(e,t){return new Dt({check:"string_format",format:"ends_with",...je(t),suffix:e})}(...t)),e.min=(...t)=>e.check(dn(...t)),e.max=(...t)=>e.check(cn(...t)),e.length=(...t)=>e.check(un(...t)),e.nonempty=(...t)=>e.check(dn(1,...t)),e.lowercase=t=>e.check(function(e){return new zt({check:"string_format",format:"lowercase",...je(e)})}(t)),e.uppercase=t=>e.check(function(e){return new Mt({check:"string_format",format:"uppercase",...je(e)})}(t)),e.trim=()=>e.check(pn(e=>e.trim())),e.normalize=(...t)=>e.check(function(e){return pn(t=>t.normalize(e))}(...t)),e.toLowerCase=()=>e.check(pn(e=>e.toLowerCase())),e.toUpperCase=()=>e.check(pn(e=>e.toUpperCase())),e.slugify=()=>e.check(pn(e=>function(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}(e)))}),Un=le("ZodString",(e,t)=>{Kt.init(e,t),Mn.init(e,t),e.email=t=>e.check(function(e,t){return new Hn({type:"string",format:"email",check:"string_format",abort:!1,...je(t)})}(0,t)),e.url=t=>e.check(function(e,t){return new Jn({type:"string",format:"url",check:"string_format",abort:!1,...je(t)})}(0,t)),e.jwt=t=>e.check(function(e,t){return new so({type:"string",format:"jwt",check:"string_format",abort:!1,...je(t)})}(0,t)),e.emoji=t=>e.check(function(e,t){return new Kn({type:"string",format:"emoji",check:"string_format",abort:!1,...je(t)})}(0,t)),e.guid=t=>e.check(nn(Bn,t)),e.uuid=t=>e.check(function(e,t){return new Vn({type:"string",format:"uuid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.uuidv4=t=>e.check(function(e,t){return new Vn({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...je(t)})}(0,t)),e.uuidv6=t=>e.check(function(e,t){return new Vn({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...je(t)})}(0,t)),e.uuidv7=t=>e.check(function(e,t){return new Vn({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...je(t)})}(0,t)),e.nanoid=t=>e.check(function(e,t){return new Gn({type:"string",format:"nanoid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.guid=t=>e.check(nn(Bn,t)),e.cuid=t=>e.check(function(e,t){return new Yn({type:"string",format:"cuid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.cuid2=t=>e.check(function(e,t){return new Wn({type:"string",format:"cuid2",check:"string_format",abort:!1,...je(t)})}(0,t)),e.ulid=t=>e.check(function(e,t){return new Zn({type:"string",format:"ulid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.base64=t=>e.check(function(e,t){return new oo({type:"string",format:"base64",check:"string_format",abort:!1,...je(t)})}(0,t)),e.base64url=t=>e.check(function(e,t){return new ro({type:"string",format:"base64url",check:"string_format",abort:!1,...je(t)})}(0,t)),e.xid=t=>e.check(function(e,t){return new Xn({type:"string",format:"xid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.ksuid=t=>e.check(function(e,t){return new Qn({type:"string",format:"ksuid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.ipv4=t=>e.check(function(e,t){return new eo({type:"string",format:"ipv4",check:"string_format",abort:!1,...je(t)})}(0,t)),e.ipv6=t=>e.check(function(e,t){return new to({type:"string",format:"ipv6",check:"string_format",abort:!1,...je(t)})}(0,t)),e.cidrv4=t=>e.check(function(e,t){return new io({type:"string",format:"cidrv4",check:"string_format",abort:!1,...je(t)})}(0,t)),e.cidrv6=t=>e.check(function(e,t){return new no({type:"string",format:"cidrv6",check:"string_format",abort:!1,...je(t)})}(0,t)),e.e164=t=>e.check(function(e,t){return new ao({type:"string",format:"e164",check:"string_format",abort:!1,...je(t)})}(0,t)),e.datetime=t=>e.check(function(e){return function(e,t){return new wn({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...je(t)})}(0,e)}(t)),e.date=t=>e.check(function(e){return function(e,t){return new kn({type:"string",format:"date",check:"string_format",...je(t)})}(0,e)}(t)),e.time=t=>e.check(function(e){return function(e,t){return new xn({type:"string",format:"time",check:"string_format",precision:null,...je(t)})}(0,e)}(t)),e.duration=t=>e.check(function(e){return function(e,t){return new Sn({type:"string",format:"duration",check:"string_format",...je(t)})}(0,e)}(t))});function Fn(e){return function(e,t){return new Un({type:"string",...je(t)})}(0,e)}const Dn=le("ZodStringFormat",(e,t)=>{Gt.init(e,t),Mn.init(e,t)}),Hn=le("ZodEmail",(e,t)=>{Zt.init(e,t),Dn.init(e,t)}),Bn=le("ZodGUID",(e,t)=>{Yt.init(e,t),Dn.init(e,t)}),Vn=le("ZodUUID",(e,t)=>{Wt.init(e,t),Dn.init(e,t)}),Jn=le("ZodURL",(e,t)=>{Xt.init(e,t),Dn.init(e,t)}),Kn=le("ZodEmoji",(e,t)=>{Qt.init(e,t),Dn.init(e,t)}),Gn=le("ZodNanoID",(e,t)=>{ei.init(e,t),Dn.init(e,t)}),Yn=le("ZodCUID",(e,t)=>{ti.init(e,t),Dn.init(e,t)}),Wn=le("ZodCUID2",(e,t)=>{ii.init(e,t),Dn.init(e,t)}),Zn=le("ZodULID",(e,t)=>{ni.init(e,t),Dn.init(e,t)}),Xn=le("ZodXID",(e,t)=>{oi.init(e,t),Dn.init(e,t)}),Qn=le("ZodKSUID",(e,t)=>{ri.init(e,t),Dn.init(e,t)}),eo=le("ZodIPv4",(e,t)=>{di.init(e,t),Dn.init(e,t)}),to=le("ZodIPv6",(e,t)=>{ui.init(e,t),Dn.init(e,t)}),io=le("ZodCIDRv4",(e,t)=>{pi.init(e,t),Dn.init(e,t)}),no=le("ZodCIDRv6",(e,t)=>{mi.init(e,t),Dn.init(e,t)}),oo=le("ZodBase64",(e,t)=>{fi.init(e,t),Dn.init(e,t)}),ro=le("ZodBase64URL",(e,t)=>{gi.init(e,t),Dn.init(e,t)}),ao=le("ZodE164",(e,t)=>{vi.init(e,t),Dn.init(e,t)}),so=le("ZodJWT",(e,t)=>{yi.init(e,t),Dn.init(e,t)}),lo=le("ZodNumber",(e,t)=>{bi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i)=>{const n=i,{minimum:o,maximum:r,format:a,multipleOf:s,exclusiveMaximum:l,exclusiveMinimum:c}=e._zod.bag;"string"==typeof a&&a.includes("int")?n.type="integer":n.type="number","number"==typeof c&&("draft-04"===t.target||"openapi-3.0"===t.target?(n.minimum=c,n.exclusiveMinimum=!0):n.exclusiveMinimum=c),"number"==typeof o&&(n.minimum=o,"number"==typeof c&&"draft-04"!==t.target&&(c>=o?delete n.minimum:delete n.exclusiveMinimum)),"number"==typeof l&&("draft-04"===t.target||"openapi-3.0"===t.target?(n.maximum=l,n.exclusiveMaximum=!0):n.exclusiveMaximum=l),"number"==typeof r&&(n.maximum=r,"number"==typeof l&&"draft-04"!==t.target&&(l<=r?delete n.maximum:delete n.exclusiveMaximum)),"number"==typeof s&&(n.multipleOf=s)})(e,t,i),e.gt=(t,i)=>e.check(an(t,i)),e.gte=(t,i)=>e.check(sn(t,i)),e.min=(t,i)=>e.check(sn(t,i)),e.lt=(t,i)=>e.check(on(t,i)),e.lte=(t,i)=>e.check(rn(t,i)),e.max=(t,i)=>e.check(rn(t,i)),e.int=t=>e.check(po(t)),e.safe=t=>e.check(po(t)),e.positive=t=>e.check(an(0,t)),e.nonnegative=t=>e.check(sn(0,t)),e.negative=t=>e.check(on(0,t)),e.nonpositive=t=>e.check(rn(0,t)),e.multipleOf=(t,i)=>e.check(ln(t,i)),e.step=(t,i)=>e.check(ln(t,i)),e.finite=()=>e;const i=e._zod.bag;e.minValue=Math.max(i.minimum??Number.NEGATIVE_INFINITY,i.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,e.maxValue=Math.min(i.maximum??Number.POSITIVE_INFINITY,i.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,e.isInt=(i.format??"").includes("int")||Number.isSafeInteger(i.multipleOf??.5),e.isFinite=!0,e.format=i.format??null});function co(e){return function(e,t){return new lo({type:"number",checks:[],...je(t)})}(0,e)}const uo=le("ZodNumberFormat",(e,t)=>{_i.init(e,t),lo.init(e,t)});function po(e){return function(e,t){return new uo({type:"number",check:"number_format",abort:!1,format:"safeint",...je(t)})}(0,e)}const mo=le("ZodBoolean",(e,t)=>{wi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>((e,t,i)=>{i.type="boolean"})(0,0,t)});function ho(e){return function(e,t){return new mo({type:"boolean",...je(t)})}(0,e)}const fo=le("ZodUnknown",(e,t)=>{ki.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>{}});function go(){return new fo({type:"unknown"})}const vo=le("ZodNever",(e,t)=>{xi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>((e,t,i)=>{i.not={}})(0,0,t)});const yo=le("ZodArray",(e,t)=>{Ei.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=i,r=e._zod.def,{minimum:a,maximum:s}=e._zod.bag;"number"==typeof a&&(o.minItems=a),"number"==typeof s&&(o.maxItems=s),o.type="array",o.items=hn(r.element,t,{...n,path:[...n.path,"items"]})})(e,t,i,n),e.element=t.element,e.min=(t,i)=>e.check(dn(t,i)),e.nonempty=t=>e.check(dn(1,t)),e.max=(t,i)=>e.check(cn(t,i)),e.length=(t,i)=>e.check(un(t,i)),e.unwrap=()=>e.element});function bo(e,t){return function(e,t,i){return new yo({type:"array",element:t,...je(i)})}(0,e,t)}const _o=le("ZodObject",(e,t)=>{Ni.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=i,r=e._zod.def;o.type="object",o.properties={};const a=r.shape;for(const e in a)o.properties[e]=hn(a[e],t,{...n,path:[...n.path,"properties",e]});const s=new Set(Object.keys(a)),l=new Set([...s].filter(e=>{const i=r.shape[e]._zod;return"input"===t.io?void 0===i.optin:void 0===i.optout}));l.size>0&&(o.required=Array.from(l)),"never"===r.catchall?._zod.def.type?o.additionalProperties=!1:r.catchall?r.catchall&&(o.additionalProperties=hn(r.catchall,t,{...n,path:[...n.path,"additionalProperties"]})):"output"===t.io&&(o.additionalProperties=!1)})(e,t,i,n),be(e,"shape",()=>t.shape),e.keyof=()=>Oo(Object.keys(e._zod.def.shape)),e.catchall=t=>e.clone({...e._zod.def,catchall:t}),e.passthrough=()=>e.clone({...e._zod.def,catchall:go()}),e.loose=()=>e.clone({...e._zod.def,catchall:go()}),e.strict=()=>{return e.clone({...e._zod.def,catchall:function(e,t){return new vo({type:"never",...je(t)})}(0,t)});var t},e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=t=>function(e,t){if(!Oe(t))throw new Error("Invalid input to extend: expected a plain object");const i=e._zod.def.checks;if(i&&i.length>0){const i=e._zod.def.shape;for(const e in t)if(void 0!==Object.getOwnPropertyDescriptor(i,e))throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}const n=we(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t};return _e(this,"shape",i),i}});return Ne(e,n)}(e,t),e.safeExtend=t=>function(e,t){if(!Oe(t))throw new Error("Invalid input to safeExtend: expected a plain object");const i=we(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t};return _e(this,"shape",i),i}});return Ne(e,i)}(e,t),e.merge=t=>function(e,t){const i=we(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t._zod.def.shape};return _e(this,"shape",i),i},get catchall(){return t._zod.def.catchall},checks:[]});return Ne(e,i)}(e,t),e.pick=t=>function(e,t){const i=e._zod.def,n=i.checks;if(n&&n.length>0)throw new Error(".pick() cannot be used on object schemas containing refinements");return Ne(e,we(e._zod.def,{get shape(){const e={};for(const n in t){if(!(n in i.shape))throw new Error(`Unrecognized key: "${n}"`);t[n]&&(e[n]=i.shape[n])}return _e(this,"shape",e),e},checks:[]}))}(e,t),e.omit=t=>function(e,t){const i=e._zod.def,n=i.checks;if(n&&n.length>0)throw new Error(".omit() cannot be used on object schemas containing refinements");const o=we(e._zod.def,{get shape(){const n={...e._zod.def.shape};for(const e in t){if(!(e in i.shape))throw new Error(`Unrecognized key: "${e}"`);t[e]&&delete n[e]}return _e(this,"shape",n),n},checks:[]});return Ne(e,o)}(e,t),e.partial=(...t)=>function(e,t,i){const n=t._zod.def.checks;if(n&&n.length>0)throw new Error(".partial() cannot be used on object schemas containing refinements");const o=we(t._zod.def,{get shape(){const n=t._zod.def.shape,o={...n};if(i)for(const t in i){if(!(t in n))throw new Error(`Unrecognized key: "${t}"`);i[t]&&(o[t]=e?new e({type:"optional",innerType:n[t]}):n[t])}else for(const t in n)o[t]=e?new e({type:"optional",innerType:n[t]}):n[t];return _e(this,"shape",o),o},checks:[]});return Ne(t,o)}(Ao,e,t[0]),e.required=(...t)=>function(e,t,i){const n=we(t._zod.def,{get shape(){const n=t._zod.def.shape,o={...n};if(i)for(const t in i){if(!(t in o))throw new Error(`Unrecognized key: "${t}"`);i[t]&&(o[t]=new e({type:"nonoptional",innerType:n[t]}))}else for(const t in n)o[t]=new e({type:"nonoptional",innerType:n[t]});return _e(this,"shape",o),o}});return Ne(t,n)}(qo,e,t[0])});function wo(e,t){const i={type:"object",shape:e??{},...je(t)};return new _o(i)}const ko=le("ZodUnion",(e,t)=>{Ci.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def,r=!1===o.inclusive,a=o.options.map((e,i)=>hn(e,t,{...n,path:[...n.path,r?"oneOf":"anyOf",i]}));r?i.oneOf=a:i.anyOf=a})(e,t,i,n),e.options=t.options});function xo(e,t){return new ko({type:"union",options:e,...je(t)})}const So=le("ZodIntersection",(e,t)=>{Ii.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def,r=hn(o.left,t,{...n,path:[...n.path,"allOf",0]}),a=hn(o.right,t,{...n,path:[...n.path,"allOf",1]}),s=e=>"allOf"in e&&1===Object.keys(e).length,l=[...s(r)?r.allOf:[r],...s(a)?a.allOf:[a]];i.allOf=l})(e,t,i,n)}),Eo=le("ZodEnum",(e,t)=>{Pi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i)=>{const n=me(e._zod.def.entries);n.every(e=>"number"==typeof e)&&(i.type="number"),n.every(e=>"string"==typeof e)&&(i.type="string"),i.enum=n})(e,0,i),e.enum=t.entries,e.options=Object.values(t.entries);const i=new Set(Object.keys(t.entries));e.extract=(e,n)=>{const o={};for(const n of e){if(!i.has(n))throw new Error(`Key ${n} not found in enum`);o[n]=t.entries[n]}return new Eo({...t,checks:[],...je(n),entries:o})},e.exclude=(e,n)=>{const o={...t.entries};for(const t of e){if(!i.has(t))throw new Error(`Key ${t} not found in enum`);delete o[t]}return new Eo({...t,checks:[],...je(n),entries:o})}});function Oo(e,t){const i=Array.isArray(e)?Object.fromEntries(e.map(e=>[e,e])):e;return new Eo({type:"enum",entries:i,...je(t)})}const To=le("ZodTransform",(e,t)=>{Li.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>((e,t)=>{if("throw"===t.unrepresentable)throw new Error("Transforms cannot be represented in JSON Schema")})(0,e),e._zod.parse=(i,n)=>{if("backward"===n.direction)throw new de(e.constructor.name);i.addIssue=n=>{if("string"==typeof n)i.issues.push(ze(n,i.value,t));else{const t=n;t.fatal&&(t.continue=!1),t.code??(t.code="custom"),t.input??(t.input=i.value),t.inst??(t.inst=e),i.issues.push(ze(t))}};const o=t.transform(i.value,i);return o instanceof Promise?o.then(e=>(i.value=e,i)):(i.value=o,i)}}),Ao=le("ZodOptional",(e,t)=>{Mi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>_n(e,t,0,n),e.unwrap=()=>e._zod.def.innerType});function $o(e){return new Ao({type:"optional",innerType:e})}const No=le("ZodExactOptional",(e,t)=>{Ui.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>_n(e,t,0,n),e.unwrap=()=>e._zod.def.innerType}),jo=le("ZodNullable",(e,t)=>{Fi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def,r=hn(o.innerType,t,n),a=t.seen.get(e);"openapi-3.0"===t.target?(a.ref=o.innerType,i.nullable=!0):i.anyOf=[r,{type:"null"}]})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType});function Co(e){return new jo({type:"nullable",innerType:e})}const Io=le("ZodDefault",(e,t)=>{Di.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType,i.default=JSON.parse(JSON.stringify(o.defaultValue))})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap}),Ro=le("ZodPrefault",(e,t)=>{Bi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType,"input"===t.io&&(i._prefault=JSON.parse(JSON.stringify(o.defaultValue)))})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType}),qo=le("ZodNonOptional",(e,t)=>{Vi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType})(e,t,0,n),e.unwrap=()=>e._zod.def.innerType}),Po=le("ZodCatch",(e,t)=>{Ki.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;let r;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType;try{r=o.catchValue(void 0)}catch{throw new Error("Dynamic catch values are not supported in JSON Schema")}i.default=r})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap}),Lo=le("ZodPipe",(e,t)=>{Gi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def,r="input"===t.io?"transform"===o.in._zod.def.type?o.out:o.in:o.out;hn(r,t,n),t.seen.get(e).ref=r})(e,t,0,n),e.in=t.in,e.out=t.out});function zo(e,t){return new Lo({type:"pipe",in:e,out:t})}const Mo=le("ZodReadonly",(e,t)=>{Wi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType,i.readOnly=!0})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType}),Uo=le("ZodCustom",(e,t)=>{Xi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>((e,t)=>{if("throw"===t.unrepresentable)throw new Error("Custom types cannot be represented in JSON Schema")})(0,e)}),Fo=Oo(["none","generic_character","real_person","known_ip","realistic_animal","illustrated_human"]).optional().describe("Internal safety hint; stripped before submit."),Do=xo([Fn(),bo(Fn())]),Ho=wo({service:Oo(["banana-pro","banana-2","seedream","seedream-5-lte","gpt-image-2"]),prompt:Fn(),aspect_ratio:Oo(["1:1","3:4","4:3","16:9","9:16","3:2","2:3","21:9"]).optional(),image_size:Oo(["1K","2K"]).optional(),img_url:Do.optional(),image:Do.optional(),image_urls:bo(Fn()).optional(),size:Fn().optional(),model:Fn().optional(),vendor:Fn().optional(),nsfw_checker:ho().optional()}),Bo=Ho.omit({img_url:!0,image:!0,image_urls:!0}),Vo=Ho,Jo=wo({service:Oo(["dli2v3","dlim2v","dlai2v","dlai2v_pro","dlai2v_pro_multiframe","happyhorse-1-0-i2v","happyhorse-1-0-r2v","happyhorse-1-0-video-edit","seedance-1-5","seedance-2-0","seedance-2-0-fast","seedance-2-0-mini","kling3.0","kling-o3-ref2v","kling-o3-pro-ref2v","kling-o3-v2v","kling-o3-pro-v2v","grok-imagine-1.5","gemini-omni-video","longcat-avatar-1-5"]),prompt:Fn(),duration:co().int().optional(),aspect_ratio:Fn().optional(),image_url:Fn().optional(),last_frame_url:Fn().optional(),urls:bo(Fn()).optional(),resolution:Fn().optional(),generate_audio:ho().optional(),mode:Oo(["fun","normal","spicy"]).optional(),draft:ho().optional(),seed:co().int().optional(),keyframes:bo(go()).optional(),quality_preset:Oo(["fast","high","ultra"]).optional(),width:co().int().optional(),height:co().int().optional(),sound:ho().optional(),negative_prompt:Fn().optional(),cfg_scale:co().optional(),end_image_url:Fn().optional(),image_urls:bo(Fn()).optional(),reference_audio_url:Fn().optional(),audio_url:Fn().optional(),ref_video_url:Fn().optional(),video_url:Fn().optional(),video_start:co().optional(),video_ends:co().optional(),video_urls:bo(Fn()).optional(),ark_asset_ids:bo(Fn()).optional(),_reference_subject_type:Fo,elements:bo(go()).optional(),camera_fixed:ho().optional(),audio_setting:Oo(["auto","origin"]).optional()}),Ko=wo({service:Oo(["dlai2v","longcat-avatar","dlai2v_pro","dlai2v_pro_multiframe"]),image_url:Fn().optional(),audio_url:Fn(),prompt:Fn().optional(),quality_preset:Oo(["fast","high","ultra"]).optional(),width:co().int().optional(),height:co().int().optional(),seed:co().int().min(0).optional(),resolution:Oo(["480p","720p","1080p"]).optional(),duration:co().int().min(1).optional(),keyframes:bo(go()).optional()}),Go=wo({service:Oo(["dreamactor","kling3.0-motion"]),video_url:Fn(),image_url:Fn().optional(),image_urls:bo(Fn()).optional(),image_base64:Fn().optional(),cut_first_second:ho().optional(),character_orientation:Oo(["image","video"]).optional(),keep_original_sound:ho().optional(),tier:Oo(["pro","std"]).optional(),prompt:Fn().optional(),negative_prompt:Fn().optional(),duration:co().int().min(1).optional()}).refine(e=>1==(e.image_url?1:0)+(e.image_urls&&e.image_urls.length>0?1:0)+(e.image_base64?1:0),{message:"exactly one of image_url / image_urls / image_base64 is required",path:["image_url"]}),Yo=wo({service:Oo(["suno-v5","suno-v5_5","minimax"]),prompt:Fn(),title:Fn().optional(),tags:Fn().optional(),negative_tags:Fn().optional(),custom:ho().optional(),instrumental:ho().optional(),vocal_gender:Oo(["Male","Female"]).optional()}),Wo=wo({service:Oo(["elevenlabs-sound"]),text:Fn(),duration_seconds:co().min(.5).max(30).optional(),prompt_influence:co().min(0).max(1).optional(),loop:ho().optional(),output_format:Oo(["mp3_44100_128","mp3_44100_192","mp3_44100_96","mp3_44100_64","mp3_44100_32","mp3_22050_32"]).optional()}),Zo=wo({service:Oo(["minimax-tts","voxcpm"]),text:Fn(),audio_url:Fn().optional(),control:Fn().optional(),model:Oo(["speech-2.8-hd","speech-2.8-turbo","speech-2.6-hd","speech-2.6-turbo"]).optional(),voice_id:Fn().optional(),speed:co().min(.5).max(2).optional(),vol:co().optional(),pitch:co().int().min(-12).max(12).optional(),emotion:Oo(["happy","sad","angry","calm","whisper"]).optional(),language_boost:Fn().optional(),format:Oo(["mp3","pcm","flac","wav"]).optional(),sample_rate:co().int().refine(e=>[8e3,16e3,22050,24e3,32e3,44100].includes(e),"sample_rate must be one of: 8000, 16000, 22050, 24000, 32000, 44100").optional(),bitrate:co().int().refine(e=>[32e3,64e3,128e3,256e3].includes(e),"bitrate must be one of: 32000, 64000, 128000, 256000").optional()}),Xo=wo({audio_url:Fn().describe("Publicly readable audio URL."),transcript_text:Fn().optional().describe("Known transcript text. When set, ASR recognition is skipped and the service only timestamps this text."),language:Fn().optional().describe("Language hint such as auto, en, zh, ja, es."),word_timestamps:ho().optional().describe("Return full text, segments, and word-level timestamps in addition to srt_content."),vad_filter:ho().optional().describe("Enable stable-ts VAD during timestamp alignment."),denoise_audio:ho().optional().describe("Enable Demucs denoising / vocal separation; ASR defaults this to true."),max_segment_duration:co().min(1).max(30).optional().describe("Maximum subtitle segment duration in seconds.")}),Qo=wo({style_id:Fn().optional(),fill_color:Fn().optional(),border_color:Fn().optional(),font_id:Fn().optional(),font_weight:Oo(["normal","bold"]).optional(),shadow:wo({color:Fn().optional(),opacity:co().min(0).max(1).optional()}).optional(),position:Oo(["top","bottom"]).optional(),position_value:co().min(0).max(.5).optional(),font_size:Oo(["sm","md","lg"]).optional(),font_size_px:co().int().min(12).max(72).optional()}),er=wo({video_url:Fn(),srt_content:Fn(),caption:Qo.optional().describe("JSON object controlling caption style. font_size_px wins over font_size."),task_id:Fn().optional()}),tr=wo({audio_url:Fn(),beat_method:Fn().optional(),analysis_types:bo(Fn()).optional()}),ir=wo({video_url:Fn(),threshold:co().min(0).max(1).optional(),output_format:Oo(["boundaries","shots","full"]).optional()}),nr=wo({url:Fn(),format:Oo(["auto","video","audio"]).optional(),video_quality:Oo(["best","2160","1440","1080","720","480","360"]).optional(),audio_format:Oo(["best","mp3","ogg","wav","opus"]).optional(),filename_pattern:Fn().optional()}),or=wo({latitude:co(),longitude:co(),heading:co().min(0).max(360).optional(),pitch:co().min(-90).max(90).optional(),fov:co().min(1).max(120).optional()}),rr=wo({latitude:co(),longitude:co()}),ar=wo({address:Fn().optional(),latitude:co().optional(),longitude:co().optional()}),sr=wo({query:Fn(),latitude:co(),longitude:co(),radius:co().int().min(100).max(5e4).optional()}),lr=wo({photo_reference:Fn(),max_width:co().int().min(1).max(4800).optional()}),cr=wo({latitude:co(),longitude:co(),zoom:co().int().min(0).max(21).optional(),size:Fn().optional(),maptype:Fn().optional()}),dr={generate_image:Ho,generate_video:Jo,lipsync:Ko,motion_control:Go,generate_music:Yo,generate_sound:Wo,generate_tts:Zo,generate_tts_elevenlabs:Zo,generate_tts_dialogue:Zo,transcribe:Xo,render_caption:er,analyze_beats:tr,detect_shots:ir,download_media:nr,streetview_image:or,streetview_metadata:rr,geocode:ar,places_search:sr,place_photo:lr,static_map:cr},ur={name:"generate_image",provider:"api_layer",description:"Generate an image via api-layer. Supports: banana-2 (= nano-banana-2, Imagen4 4K, newest generation — materially faster AND higher quality than banana-pro; default first choice within the banana family), banana-pro (= nano-banana-pro, Imagen3 series up to 2K, older / slower / cheaper — use only when cost-saving is explicit), seedream (Asian aesthetic), seedream-5-lte (next-gen), gpt-image-2 (highest text-in-image fidelity and instruction-following edits; supports multi-image i2i up to 16 refs).",zodSchema:dr.generate_image,token_cost:100,artifact_slot:"generated_image",is_async:!0,timeout:300},pr={name:"generate_video",provider:"api_layer",description:"Generate a video via api-layer. Services: dli2v3 (Veo 3.1), dlim2v (Grok), dlai2v (LTX 2), dlai2v_pro (LTX 2 Pro = LTX 2.3 multi-frame workflow on RunPod; single image_url + duration auto-wrapped into keyframes[0] in api-layer router), dlai2v_pro_multiframe (LTX 2.3 真·多帧变体, 2-4 帧关键帧引导视频生成: 必须传 keyframes=[{image_url, frame_ratio?, weight?}] (2-4 帧) + audio_url; frame_ratio 0.0-1.0 表示该帧在视频中的相对时间位置(不传按数量等分 [0,1] / [0,0.5,1] / [0,0.33,0.67,1]); weight 0.0-1.0 (默认 0.4) 控制 guide 强度; aspect_ratio 16:9/9:16/1:1, resolution 强制 720p), happyhorse-1-0-i2v (Alibaba HappyHorse single first-frame i2v), happyhorse-1-0-r2v (Alibaba HappyHorse 1-9 reference images → video), happyhorse-1-0-video-edit (Alibaba HappyHorse video edit with 0-5 reference images), seedance-1-5, seedance-2-0, seedance-2-0-fast, seedance-2-0-mini (Seedance 2.0 lowest-cost 480p/720p, 5-12s), kling3.0, kling-o3-ref2v, kling-o3-pro-ref2v, kling-o3-v2v (Kling O3 Std video-edit / video-to-video: 输入视频 + prompt 编辑画面,可选 image_urls / elements 作辅助参考), kling-o3-pro-v2v (同 v2v 的 Pro 版,质量更高), gemini-omni-video, grok-imagine-1.5, longcat-avatar-1-5. Prompt placeholders: @imageN → image_urls[N-1], @audioN → reference_audio_url, @videoN → ref_video_url, @assetN → ark_asset_ids[N-1] (all 1-indexed).",zodSchema:dr.generate_video,strip_before_submit:["_reference_subject_type"],token_cost:400,artifact_slot:"generated_video",is_async:!0,timeout:300},mr={name:"lipsync",provider:"api_layer",description:"Lip-sync via api-layer. Services: dlai2v (LTX 2), longcat-avatar, dlai2v_pro (LTX 2 Pro = LTX 2.3 multi-frame workflow on RunPod), dlai2v_pro_multiframe (LTX 2.3 真·多帧变体, 2-4 帧关键帧+音频驱动: 必须传 keyframes=[{image_url, frame_ratio?, weight?}] (2-4) + audio_url; frame_ratio 0.0-1.0 时间位置, weight 默认 0.4, aspect_ratio 16:9/9:16/1:1, resolution 强制 720p). dlai2v_pro auto-wraps single image_url into keyframes[0] in api-layer router.",zodSchema:dr.lipsync,token_cost:350,artifact_slot:"lipsync_video",is_async:!0,timeout:300},hr={name:"motion_control",provider:"api_layer",description:"Transfer motion/pose from source video onto target character. Services: dreamactor, kling3.0-motion.",zodSchema:dr.motion_control,token_cost:400,artifact_slot:"motion_video",is_async:!0,timeout:300},fr={name:"generate_music",provider:"api_layer",description:"Generate music via api-layer. Services: suno-v5, suno-v5_5, minimax.",zodSchema:dr.generate_music,token_cost:300,artifact_slot:"music_candidate",is_async:!0,timeout:600},gr={name:"generate_sound",provider:"api_layer",description:"Generate a short sound effect via api-layer (ElevenLabs Sound Effects v2, 0.5–30s). For SFX / Foley / ambient / short loops — not full songs (use generate_music for that).",zodSchema:dr.generate_sound,token_cost:50,artifact_slot:"sound_effect",is_async:!0,timeout:60},vr={name:"generate_tts",provider:"api_layer",description:"Generate speech via api-layer TTS. Services: minimax-tts, voxcpm (self-hosted custom voice sample / authorized reference cloning).",zodSchema:dr.generate_tts,token_cost:80,artifact_slot:"tts_audio",is_async:!0,timeout:120},yr={...vr,name:"generate_tts_elevenlabs",zodSchema:dr.generate_tts_elevenlabs,description:"Back-compat alias for generate_tts (routed to api-layer /tts/submit)."},br={...vr,name:"generate_tts_dialogue",zodSchema:dr.generate_tts_dialogue,description:"Back-compat alias for generate_tts (routed to api-layer /tts/submit)."},_r={name:"transcribe",provider:"asr",description:"Transcribe audio to text.",zodSchema:dr.transcribe,default_params:{word_timestamps:!1},strip_before_submit:["model_size"],token_cost:50,artifact_slot:"audio_transcription",is_async:!0,timeout:30},wr={name:"render_caption",provider:"caption_render",description:"Burn SRT captions into a video and return the captioned video URL.",zodSchema:dr.render_caption,token_cost:50,artifact_slot:"captioned_video",is_async:!1,timeout:600},kr={name:"analyze_beats",provider:"audio_analyzer",description:"Analyze beat structure of an audio file.",zodSchema:dr.analyze_beats,token_cost:25,artifact_slot:"beat_analysis",is_async:!1,timeout:900},xr={name:"detect_shots",provider:"shot_analysis",description:"Detect shot boundaries using TransNetV2.",zodSchema:dr.detect_shots,token_cost:30,artifact_slot:"shot_analysis",is_async:!1,timeout:120},Sr={name:"download_media",provider:"media_downloader",description:"Download a video/audio/image from TikTok / Instagram / Twitter / Bilibili / etc. and re-upload to CDN. Returns a persistent public URL. Limits: <=500MB, 30 RPM. YouTube currently unsupported (anti-bot block).",zodSchema:dr.download_media,token_cost:30,artifact_slot:"downloaded_media",is_async:!1,timeout:120},Er={name:"streetview_image",provider:"geo",description:"Street-level image at coordinates; auto-routes provider (Google / AMap / Panoramax).",zodSchema:dr.streetview_image,token_cost:5,artifact_slot:"streetview_image",is_async:!1,timeout:30},Or={name:"streetview_metadata",provider:"geo",description:"Check street view coverage at coordinates. Returns coverage status. Low cost — call before streetview_image.",zodSchema:dr.streetview_metadata,token_cost:1,is_async:!1,timeout:10},Tr={name:"geocode",provider:"geo",description:"Forward (address→coords) or reverse (coords→address) geocoding.",zodSchema:dr.geocode,token_cost:2,is_async:!1,timeout:10},Ar={name:"places_search",provider:"geo",description:"Search places/POIs near coordinates by keyword.",zodSchema:dr.places_search,token_cost:10,is_async:!1,timeout:15},$r={name:"place_photo",provider:"geo",description:"Fetch a photo by its photo_reference returned from places_search.",zodSchema:dr.place_photo,token_cost:5,artifact_slot:"place_photo",is_async:!1,timeout:15},Nr={name:"static_map",provider:"geo",description:"Bird's-eye view map image at coordinates with optional markers.",zodSchema:dr.static_map,token_cost:3,artifact_slot:"static_map",is_async:!1,timeout:15},jr=Object.freeze({generate_image:ur,generate_video:pr,lipsync:mr,motion_control:hr,generate_music:fr,generate_sound:gr,generate_tts:vr,generate_tts_elevenlabs:yr,generate_tts_dialogue:br,transcribe:_r,render_caption:wr,analyze_beats:kr,detect_shots:xr,download_media:Sr,streetview_image:Er,streetview_metadata:Or,geocode:Tr,places_search:Ar,place_photo:$r,static_map:Nr});function Cr(e){return jr[e]}const Ir=[{flag:"--print-schema",description:"emit JSON schema for this verb's single + batch shape"},{flag:"--echo-parsed",description:"echo canonicalised input on stderr (debug)"},{flag:"--dry-run",description:"validate, quote, and render approval preview without submitting vendor work"},{flag:"--help",description:"show this help"}],Rr=[{code:"E_SCHEMA",when:"missing/invalid flag value",recovery:"run `dl <verb> --print-schema` to see the expected shape"},{code:"E_BACKEND",when:"backend returned a failure",recovery:"inspect the `data` field on stderr; usually quota / unreachable URL / asset missing"}];function qr(e){const t=[` --${e.flag.padEnd(20)} ${function(e){switch(e.kind){case"string":return"<string>";case"integer":return"<integer>";case"number":return"<number>";case"boolean":return"(boolean flag)";case"array":return e.itemKind?`<${e.itemKind}> (repeatable)`:"<value> (repeatable)";case"object":return"<see --<name>-file>";default:return"<value>"}}(e)}`];if(e.description&&t.push(` ${" ".repeat(22)} ${e.description}`),e.enum&&t.push(` ${" ".repeat(22)} one of: ${e.enum.join(", ")}`),void 0!==e.minimum||void 0!==e.maximum){const i=[void 0!==e.minimum?`>= ${e.minimum}`:"",void 0!==e.maximum?`<= ${e.maximum}`:""].filter(Boolean).join(", ");t.push(` ${" ".repeat(22)} ${i}`)}return void 0!==e.default&&t.push(` ${" ".repeat(22)} default: ${JSON.stringify(e.default)}`),e.internal&&!e.description?.toLowerCase().includes("strip")&&t.push(` ${" ".repeat(22)} (internal hint, stripped before submit)`),t}function Pr(e,t,i){if(i)return function(e,t,i){const n=t.services.find(e=>e.service===i);if(!n){const n=t.services.map(e=>e.service).join(" | ");return[`Unknown service '${i}'.`,`Known services for \`dl ${e}\`: ${n}`,`Run \`dl ${e} model -h\` for the ranking + decision logic.`].join("\n")}const o=[];o.push(`SERVICE: ${n.service}${n.label?` — ${n.label}`:""}`),n.tier&&o.push(` Tier: ${n.tier}`),n.bestFor&&o.push(` Best for: ${n.bestFor}`);const r=[];if(n.quality&&r.push(`Quality ${n.quality}`),n.speed&&r.push(`Speed ${n.speed}`),n.cost&&r.push(`Cost ${n.cost}`),r.length>0&&o.push(` ${r.join(" · ")}`),o.push(""),n.description&&n.description.length>0){o.push("DESCRIPTION");for(const e of n.description)o.push(` ${e}`);o.push("")}if(n.promptTips&&n.promptTips.length>0){o.push("PROMPT TIPS (model-specific)");for(const e of n.promptTips)o.push(` - ${e}`);o.push("")}if(n.constraints&&n.constraints.length>0){o.push("CONSTRAINTS");for(const e of n.constraints)o.push(` - ${e}`);o.push("")}if(n.flagSubset&&n.flagSubset.length>0){o.push("FLAG SUBSET (for this service — full schema via `--print-schema`)");for(const e of n.flagSubset)o.push(` --${e}`);o.push("")}if(o.push("PROMPT LANGUAGE"),o.push(" - Write the prompt in the user's original language; do NOT translate it (e.g. Chinese → English) unless the user explicitly asks or this model requires a specific language."),o.push(" - The example commands below show structure / placeholders only — not prompt language or wording. Do not copy their phrasing or language onto the user's prompt."),o.push(""),n.examples&&n.examples.length>0)for(const e of n.examples){o.push(`EXAMPLE — ${e.caption}`);for(const t of e.command.split("\n"))o.push(` ${t}`);o.push("")}for(;o.length>0&&""===o[o.length-1];)o.pop();return o.join("\n")}(e,t,i);const n=[];if(n.push("TOPIC: model — service selection & per-service call shape",""),t.rankingSummary&&t.rankingSummary.length>0){for(const e of t.rankingSummary)n.push(e);n.push("")}if(t.services.length>0){n.push("SERVICES");for(const e of t.services){const t=` ${e.service.padEnd(20)} ${e.tier??""}`.trimEnd();n.push(t),e.bestFor&&n.push(` Best for: ${e.bestFor}`);const i=[];e.quality&&i.push(`Quality ${e.quality}`),e.speed&&i.push(`Speed ${e.speed}`),e.cost&&i.push(`Cost ${e.cost}`),i.length>0&&n.push(` ${i.join(" · ")}`),n.push("")}}if(t.decisionLogic&&t.decisionLogic.length>0){n.push("DECISION LOGIC (按优先级)");const e=Math.max(...t.decisionLogic.map(e=>e.when.length));for(const i of t.decisionLogic)n.push(` ${i.when.padEnd(e)} → ${i.pick}`);n.push("")}n.push("LEARN MORE");const o=t.services.map(e=>e.service).join(" | ");for(n.push(` dl ${e} model <service> per-service flag subset + prompt tips + example`),n.push(` <service> ∈ { ${o} }`);n.length>0&&""===n[n.length-1];)n.pop();return n.join("\n")}function Lr(e,t,i=!1){const n=[];if(n.push("TOPIC: preflight — decisions you must make before the first call",""),t.intro&&n.push(t.intro,""),t.decisions.length>0&&(n.push("DECISIONS"),t.decisions.forEach((e,t)=>{n.push(` ${t+1}. ${e.name}`);for(const t of e.description.split("\n"))n.push(` ${t}`)}),n.push("")),t.notes&&t.notes.length>0){n.push("NOTES");for(const e of t.notes)n.push(` - ${e}`);n.push("")}for(i&&n.push("SEE ALSO",` dl ${e} model -h — service selection (decision #1 usually)`);n.length>0&&""===n[n.length-1];)n.pop();return n.join("\n")}function zr(e,t){const i=[];i.push("TOPIC: policy — user-facing communication rules + payment-package gate",""),t.intro&&i.push(t.intro,"");for(const e of t.rules){i.push(e.title);for(const t of e.body)i.push(` ${t}`);i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Mr(e,t){const i=[];i.push("TOPIC: composition — how upstream / sibling skills consume this verb's output",""),t.intro&&i.push(t.intro,"");for(const e of t.integrations){i.push(`WHEN CALLED FROM: ${e.skill}`);for(const t of e.rule)i.push(` ${t}`);i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Ur(e,t){const i=[];if(i.push("TOPIC: async — detach-by-default protocol + result shape",""),t.intro&&t.intro.length>0){for(const e of t.intro)i.push(e);i.push("")}if(t.resultShape&&t.resultShape.length>0){i.push("RESULT SHAPE (delivered via [async-callback])");for(const e of t.resultShape)i.push(` ${e}`);i.push("")}if(t.notes&&t.notes.length>0){i.push("NOTES");for(const e of t.notes)i.push(` - ${e}`);i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Fr(e,t){const i=[];if(i.push("TOPIC: publish — handing the result off to publish_content / downstream artifact",""),t.intro&&t.intro.length>0){for(const e of t.intro)i.push(e);i.push("")}if(t.fields&&t.fields.length>0){i.push("PUBLISH_CONTENT FIELD MAPPING");const e=Math.max(...t.fields.map(e=>e.name.length));for(const n of t.fields)i.push(` ${n.name.padEnd(e)} ${n.value}`);i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Dr(e,t){const i=[];i.push("TOPIC: examples — copy-paste-ready calls per scenario","");for(const e of t.examples){i.push(`EXAMPLE — ${e.caption}`);for(const t of e.command.split("\n"))i.push(` ${t}`);i.push("")}if(t.notExamples&&t.notExamples.length>0){i.push("NOT AN EXAMPLE (these all fail)");for(const e of t.notExamples){i.push(` # ❌ ${e.whyItFails}`);for(const t of e.command.split("\n"))i.push(` ${t}`);i.push("")}}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Hr(e,t){const i=[];i.push("TOPIC: errors — failure codes + recovery breadcrumbs","");const n=t.errors??Rr;if(n.length>0){i.push("CODES");for(const e of n)i.push(` ${e.code}`),i.push(` when: ${e.when}`),e.recovery&&i.push(` recovery: ${e.recovery}`),i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Br(e,t){const i=function(){const e=function(e){if(!e)return null;try{const t=JSON.parse(e);return"object"!=typeof t||null===t||Array.isArray(t)?null:t}catch{return null}}(process.env.PI_AGENT_CONTEXT),t={};return Vr(t,"user_id",e?.user_id??process.env.PI_USER_ID),Vr(t,"prompt_id",e?.prompt_id??process.env.PI_PROMPT_ID),Vr(t,"tool_call_id",e?.tool_call_id??process.env.PI_TOOL_CALL_ID),Vr(t,"sub_agent_id",e?.sub_agent_id??process.env.PI_SUB_AGENT_ID),Vr(t,"user_unique_name",e?.user_unique_name??process.env.PI_USER_UNIQUE_NAME),Vr(t,"user_tier",e?.user_tier??process.env.PI_USER_TIER),t}();return{quote:e,trace:{project_id:t.projectId,job_ref:t.jobRef,command:e.command,action:e.action,mode:t.mode,...void 0!==t.batchIndex?{batch_index:t.batchIndex}:{},...t.jobKey?{job_key:t.jobKey}:{},...i}}}function Vr(e,t,i){if("string"!=typeof i)return;const n=i.trim();n&&(e[t]=n)}class Jr extends Error{hint;constructor(e,t){super(e),this.hint=t,this.name="ProxyClientError"}}class Kr extends Error{hint;constructor(e,t){super(e),this.hint=t,this.name="ByoaOauthError"}}function Gr(e){return e.toString("base64url")}function Yr(e){return e.replace(/\/+$/,"")}async function Wr(e,t,i){const n=await i(e,{method:"POST",headers:{"content-type":"application/x-www-form-urlencoded"},body:new URLSearchParams(t).toString()}),o=await n.text();if(!n.ok)throw new Kr(`token endpoint returned ${n.status}: ${o.slice(0,300)}`,"the OAuth client may be misconfigured — check --client-id / --issuer");const r=JSON.parse(o);if("object"!=typeof r||null===r||"string"!=typeof r.access_token)throw new Kr("token endpoint returned a malformed response (no access_token)");return r}const Zr="ai.ilands.cli",Xr="byoa";function Qr(e=process.env){const t=(e.ILANDS_CONFIG_DIR??"").trim();if(t)return t;if("win32"===process.platform){const t=(e.APPDATA??"").trim();if(t)return l(t,"ilands")}const i=(e.HOME??"").trim()||E();return l(i,".ilands")}function ea(e=process.env){return l(Qr(e),"credentials")}function ta(e){try{return v("win32"===process.platform?"where":"which",[e],{stdio:"ignore"}),!0}catch{return!1}}function ia(e){return"file"===(e.ILANDS_CRED_STORE??"").trim()?"file":"darwin"===process.platform?"keychain":"linux"===process.platform&&ta("secret-tool")?"secret-tool":"file"}function na(e){try{const t=JSON.parse(e);if("object"!=typeof t||null===t)return null;const i=t;return 1!==i.version||"string"!=typeof i.issuer||"string"!=typeof i.client_id||"string"!=typeof i.access_token||"number"!=typeof i.expires_at||"object"!=typeof i.user||null===i.user?null:t}catch{return null}}function oa(e){const t=ea(e);if(!o(t))return null;try{return na(r(t,"utf-8"))}catch{return null}}function ra(){try{return na(v("security",["find-generic-password","-s",Zr,"-a",Xr,"-w"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim())}catch{return null}}function aa(){try{v("security",["delete-generic-password","-s",Zr,"-a",Xr],{stdio:"ignore"})}catch{}}function sa(){try{return na(v("secret-tool",["lookup","service",Zr,"account",Xr],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim())}catch{return null}}function la(){try{v("secret-tool",["clear","service",Zr,"account",Xr],{stdio:"ignore"})}catch{}}function ca(e=process.env){switch(ia(e)){case"keychain":return ra()??oa(e);case"secret-tool":return sa()??oa(e);default:return oa(e)}}function da(e,t){return null!==e&&e.access_token===t.access_token&&e.user.id===t.user.id}function ua(e,o=process.env){switch(ia(o)){case"keychain":if(function(e){try{return aa(),v("security",["add-generic-password","-s",Zr,"-a",Xr,"-w",JSON.stringify(e)],{stdio:"ignore"}),!0}catch{return!1}}(e)&&da(ra(),e))return"keychain";aa();break;case"secret-tool":if(function(e){try{return v("secret-tool",["store","--label","ilands CLI","service",Zr,"account",Xr],{input:JSON.stringify(e),stdio:["pipe","ignore","ignore"]}),!0}catch{return!1}}(e)&&da(sa(),e))return"secret-tool";la()}return function(e,o){const r=Qr(e);t(r,{recursive:!0,mode:448});const a=ea(e);i(a,`${JSON.stringify(o,null,2)}\n`,{mode:384});try{n(a,384)}catch{}}(o,e),"file"}const pa="https://ilands-edge-router-staging.bitter-fog-5f6d.workers.dev",ma="byoa";function ha(e=process.env){return fa((e.ILANDS_BYOA_CALLBACK_BASE_URL??"").trim()||"https://callback-server-z4umynwjcq-an.a.run.app")}function fa(e){return e.replace(/\/+$/,"")}function ga(){return Math.floor(Date.now()/1e3)}function va(e,t){const i=(t.ILANDS_GATEWAY_URL??"").trim();return fa(e?.gateway_url||i||pa)}function ya(e=process.env){const t=[],i=!!(e.CALLBACK_SERVER_URL??"").trim()&&!!(e.DL_PROXY_TOKEN??"").trim(),n=!!(e.ILANDS_SANDBOX_RPC_URL??"").trim()&&!!(e.ILANDS_SANDBOX_TOKEN??"").trim();return i&&t.push("dl"),n&&t.push("ilands"),{sandbox:t.length>0,flavors:t}}async function ba(e=process.env,t=fetch){const i=(e.CALLBACK_SERVER_URL??"").trim(),n=(e.DL_PROXY_TOKEN??"").trim();if(i&&n)return{mode:"sandbox",baseUrl:`${fa(i)}/sandbox-rpc/dl`,token:n,projectId:(e.PI_PROJECT_ID??"").trim()};if(i||n)throw new Jr((i?"DL_PROXY_TOKEN":"CALLBACK_SERVER_URL")+" not set in sandbox env","this dl binary is the sandbox flavor; it only works when hono-pi-e2b injects DL_PROXY_TOKEN + CALLBACK_SERVER_URL via commands.run envs.");const o=await async function(e=process.env,t=fetch){const i=ca(e);if(!i)return null;if(i.expires_at-ga()>30)return i;if(!i.refresh_token)throw new Jr("byoa access token expired and no refresh token is stored","run `ilands login` (or `dl login`) again");let n;try{n=await async function(e){return Wr(`${Yr(e.issuer)}/oauth/token`,{grant_type:"refresh_token",refresh_token:e.refreshToken,client_id:e.clientId},e.fetchImpl??fetch)}({issuer:i.issuer,clientId:i.client_id,refreshToken:i.refresh_token,fetchImpl:t})}catch(e){const t=e instanceof Error?e.message:String(e);throw new Jr(`byoa token refresh failed: ${t}`,"run `ilands login` (or `dl login`) again")}const o={...i,access_token:n.access_token,...n.refresh_token?{refresh_token:n.refresh_token}:{},expires_at:ga()+(n.expires_in??3600)};return ua(o,e),o}(e,t);if(o)return{mode:"byoa",baseUrl:`${va(o,e)}/byoa/dl`,token:o.access_token,projectId:"byoa"};throw new Jr("no dl credentials: neither sandbox env nor a byoa login was found","run `ilands login` (or `dl login`) to use dl with your ilands account; sandbox mode needs CALLBACK_SERVER_URL + DL_PROXY_TOKEN.")}function _a(e){switch(e){case"E_BACKEND":case"E_INSUFFICIENT_CREDITS":case"E_COMMAND_NOT_OFFERED":case"E_NO_PERMISSION":return 1;default:return 2}}class wa extends Error{code;hint;extra;constructor(e,t,i,n){super(t),this.code=e,this.hint=i,this.extra=n}}function ka(e,t){if(e===t)return 0;if(!e.length)return t.length;if(!t.length)return e.length;const i=e.length,n=t.length;let o=Array(n+1).fill(0).map((e,t)=>t),r=Array(n+1).fill(0);for(let a=1;a<=i;a++){r[0]=a;for(let i=1;i<=n;i++){const n=e.charCodeAt(a-1)===t.charCodeAt(i-1)?0:1;r[i]=Math.min(r[i-1]+1,o[i]+1,o[i-1]+n)}[o,r]=[r,o]}return o[n]}function xa(e,t){if(!t.length)return;let i=t[0],n=ka(e,i);for(let o=1;o<t.length;o++){const r=ka(e,t[o]);r<n&&(n=r,i=t[o])}return n<=Math.max(3,Math.floor(e.length/3))?i:void 0}class Sa extends Error{status;bodyText;url;constructor(e,t,i,n){super(e),this.status=t,this.bodyText=i,this.url=n}}async function Ea(e,t={}){const i=t.method??"GET",n={"content-type":"application/json",...t.headers??{}},o=void 0===t.body?void 0:"string"==typeof t.body?t.body:JSON.stringify(t.body),r=t.timeoutMs??3e4,a=(t.retries??0)+1;let s=null;for(let t=1;t<=a;t++){const l=new AbortController,c=setTimeout(()=>l.abort(),r);try{const r=await fetch(e,{method:i,headers:n,body:o,signal:l.signal}),c=await r.text();if(!r.ok){if(402===r.status){const e=Ta(c);if(e)throw new wa("E_INSUFFICIENT_CREDITS",e.message,"充值后重试;本次请求没有提交到上游供应商。",{billing_error:"INSUFFICIENT_CREDITS",...void 0!==e.balance?{balance:e.balance}:{},...void 0!==e.required?{required:e.required}:{}})}if(403===r.status){const e=Aa(c);if(e)throw new wa("command_not_offered"===e.reason?"E_COMMAND_NOT_OFFERED":"E_NO_PERMISSION",e.message,e.hint,{reason:e.reason})}if(r.status>=500&&t<a){s=new Sa(`http ${r.status}`,r.status,c,e);continue}throw new Sa(`http ${r.status}: ${Oa(c,500)}`,r.status,c,e)}if(0===c.length)return;try{return JSON.parse(c)}catch{return c}}catch(e){if(e instanceof Sa)throw e;if(s=e,t>=a)break}finally{clearTimeout(c)}}throw s instanceof Error?s:new Error(String(s))}function Oa(e,t){return e.length>t?`${e.slice(0,t)}…`:e}function Ta(e){const t=$a(e);if(!t)return null;const i="detail"in t?t.detail:t,n=Na(i)?i:t,o=Ca(n,"code"),r=Ca(n,"error");if("E_INSUFFICIENT_CREDITS"!==o&&"INSUFFICIENT_CREDITS"!==r&&(void 0===n.balance||void 0===n.required))return null;const a=ja(n,"balance"),s=ja(n,"required"),l=Ca(n,"message")??("string"==typeof i&&""!==i.trim()?i.trim():function(e,t){return void 0!==e&&void 0!==t?`余额不足: 当前 ${e} credits, 需 ${t}。请充值后重试。`:"余额不足。请充值后重试。"}(a,s));return{message:l,...void 0!==a?{balance:a}:{},...void 0!==s?{required:s}:{}}}function Aa(e){const t=$a(e);if(!t)return null;const i=Na(t.error)?t.error:t,n=Ca(i,"reason")??Ca(i,"code");return"command_not_offered"!==n&&"no_permission"!==n?null:{reason:n,message:Ca(i,"message")??("command_not_offered"===n?"this command is not offered in byoa (login) mode":"your account's role does not allow this command"),hint:Ca(i,"hint")}}function $a(e){if(""===e.trim())return null;try{const t=JSON.parse(e);return Na(t)?t:null}catch{return null}}function Na(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function ja(e,t){const i=e[t];return"number"==typeof i&&Number.isFinite(i)?i:void 0}function Ca(e,t){const i=e[t];return"string"==typeof i&&""!==i.trim()?i.trim():void 0}const Ia="X-DL-Billing";function Ra(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function qa(e,t,i){const n=Ra(i);n&&(e[t]=n)}function Pa(e){const t={},i=Ra(process.env.TRACEPARENT),n=Ra(process.env.TRACESTATE);return qa(t,"traceparent",i),qa(t,"x-pi-traceparent",i),qa(t,"tracestate",n),qa(t,"x-pi-tracestate",n),qa(t,"x-dl-command","dl"),qa(t,"x-dl-subcommand",e.billing?.quote.command??function(){for(const e of process.argv.slice(2)){const t=Ra(e);if(t&&!t.startsWith("-"))return t}}()),qa(t,"x-dl-action",e.billing?.quote.action),qa(t,"x-dl-event",e.billing?.quote.event),qa(t,"x-dl-service",function(e){if("object"==typeof e&&null!==e&&!Array.isArray(e))return Ra(e.service)}(e.body)??function(e){const t=e?.details.service;return Ra(t)}(e.billing?.quote)??e.prefix),qa(t,"x-dl-job-ref",e.billing?.jobRef),t}function La(e,t){if(!t)throw new Jr("PI_PROJECT_ID not set in sandbox env","this dl binary is the sandbox flavor; it only works when hono-pi-e2b injects DL_PROXY_TOKEN + CALLBACK_SERVER_URL via commands.run envs.");return{_dl_billing:Br(e.quote,{projectId:t,jobRef:e.jobRef,mode:e.trace?.mode??"single",...void 0!==e.trace?.batchIndex?{batchIndex:e.trace.batchIndex}:{},...e.trace?.jobKey?{jobKey:e.trace.jobKey}:{}})}}function za(e,t){if(!e.billing)return{};const i=Buffer.from(JSON.stringify(La(e.billing,t)),"utf-8").toString("base64url");return{[Ia]:i}}async function Ma(e){const t=await ba(),i=await Ea(`${t.baseUrl}/billing/charge`,{method:"POST",headers:{Authorization:`Bearer ${t.token}`,...Pa({billing:e})},body:La(e,t.projectId),timeoutMs:1e4,retries:0});if(!i.receipt)throw new Jr("gateway returned malformed dl billing charge response");return i.receipt}async function Ua(e){const t=await ba();await Ea(`${t.baseUrl}/billing/refund`,{method:"POST",headers:{Authorization:`Bearer ${t.token}`,...Pa({billing:e})},body:{...La(e,t.projectId),reason:e.reason,...e.chargeId?{charge_id:e.chargeId}:{}},timeoutMs:1e4,retries:0})}function Fa(e,t,i){const n=i.replace(/^\/+/,"").replace(/\/+$/,"");return n?`${e.baseUrl}/${t}/${n}`:`${e.baseUrl}/${t}`}async function Da(e,t,i,n={}){const o=await ba();return Ea(Fa(o,e,t),{method:n.method??"POST",headers:{Authorization:`Bearer ${o.token}`,...n.headers??{},...Pa({billing:n.billing,body:i,prefix:e}),...za(n,o.projectId)},body:i,timeoutMs:n.timeoutMs??3e4,retries:n.retries??0})}async function Ha(e,t,i,n={}){const o=await ba(),r=Object.entries(i).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&"),a=Fa(o,e,t);return Ea(r?`${a}?${r}`:a,{method:"GET",headers:{Authorization:`Bearer ${o.token}`,...n.headers??{},...Pa({billing:n.billing,prefix:e}),...za(n,o.projectId)},timeoutMs:n.timeoutMs??3e4,retries:n.retries??0})}class Ba extends Error{action;errors;constructor(e,t,i){super(e),this.action=t,this.errors=i,this.name="ActionValidationError"}}const Va={generate_music:{path:"/api/agent/music/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_video:{path:"/api/agent/video/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_image:{path:"/api/agent/image/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_sound:{path:"/api/agent/sound/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_tts:{path:"/api/agent/tts/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_tts_elevenlabs:{path:"/api/agent/tts/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_tts_dialogue:{path:"/api/agent/tts/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},lipsync:{path:"/api/agent/video/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},motion_control:{path:"/api/agent/video/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},detect_shots:{path:"/api/v1/shot-analysis/analyze",baseEnv:"SHOT_ANALYSIS_BASE_URL",auth:"x-api-key",authEnv:"SHOT_ANALYSIS_API_KEY"},transcribe:{path:"/api/agent/asr/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},render_caption:{path:"/api/v1/caption/render",baseEnv:"CAPTION_RENDER_BASE_URL",auth:"x-api-key",authEnv:"CAPTION_RENDER_API_KEY"},analyze_beats:{path:"/analyze",baseEnv:"AUDIO_ANALYZER_BASE_URL",auth:"x-api-key",authEnv:"AUDIO_ANALYZER_API_KEY"},download_media:{path:"/api/v1/media-download/download",baseEnv:"MEDIA_DOWNLOAD_BASE_URL",auth:"x-api-key",authEnv:"MEDIA_DOWNLOAD_API_KEY"},streetview_image:{path:"/api/v1/streetview/image",gatewayPrefix:"geo",auth:"x-api-key"},streetview_metadata:{path:"/api/v1/streetview/metadata",gatewayPrefix:"geo",auth:"x-api-key"},geocode:{path:"/api/v1/geocode",gatewayPrefix:"geo",auth:"x-api-key"},places_search:{path:"/api/v1/places/search",gatewayPrefix:"geo",auth:"x-api-key"},place_photo:{path:"/api/v1/places/photo",gatewayPrefix:"geo",auth:"x-api-key"},static_map:{path:"/api/v1/maps/static",gatewayPrefix:"geo",auth:"x-api-key"}};function Ja(e){const t=Va[e];if(!t)throw new Error(`unknown action: ${e}`);return t}function Ka(e){const t=Va[e];return void 0!==t&&"x-api-key"===t.auth}const Ga={ASR_BASE_URL:"asr",AUDIO_ANALYZER_BASE_URL:"audio-analyzer",CAPTION_RENDER_BASE_URL:"caption-render",SHOT_ANALYSIS_BASE_URL:"shot-analysis",MEDIA_DOWNLOAD_BASE_URL:"media-download"};function Ya(e){const t=(process.env.PI_PROJECT_ID??"").trim();if(t)return t;throw new Jr("callback"===e?"PI_PROJECT_ID not set — required for callback URL routing under callback-resume v2":"PI_PROJECT_ID not set — required for dl billing trace","hono-pi-e2b injects PI_PROJECT_ID on every commands.run; set it manually in LOCAL_SANDBOX dev")}function Wa(e,t,i){return t.billing?{...e,_dl_billing:Br(t.billing,{projectId:i.projectId,jobRef:i.jobRef,mode:t.billingTrace?.mode??"single",...void 0!==t.billingTrace?.batchIndex?{batchIndex:t.billingTrace.batchIndex}:{},...t.billingTrace?.jobKey?{jobKey:t.billingTrace.jobKey}:{}})}:e}async function Za(e,t,i,n={}){const o=Ja(e);!function(e,t){const i=Cr(e);if(!i)return;const n=i.zodSchema.safeParse(t);if(!n.success){const t=n.error.issues,i=t.map(e=>`${e.path.join(".")||"<root>"} ${e.message}`.trim()).join("; ");throw new Ba(`params invalid for ${e}: ${i}`,e,t)}}(e,t);const r=Cr(e),a=r?function(e,t){if(!e.strip_before_submit||0===e.strip_before_submit.length)return t;const i={...t};for(const t of e.strip_before_submit)delete i[t];return i}(r,function(e,t){const i={...t};for(const[t,n]of Object.entries(e.default_params??{}))void 0===i[t]&&(i[t]=n);return i}(r,t)):t,{prefix:s,tail:l}=function(e){const t=Ja(e),i=t.path.replace(/^\/+/,"");if("bearer"===t.auth)return{prefix:"media/submit",tail:i};if(t.gatewayPrefix)return{prefix:t.gatewayPrefix,tail:i};const n=t.baseEnv?Ga[t.baseEnv]:void 0;if(!n)throw new Error(`no sandbox-rpc prefix for ${e} (baseEnv=${t.baseEnv??"unset"})`);return{prefix:n,tail:i}}(e),c=(process.env.CALLBACK_SERVER_URL??"").replace(/\/+$/,""),d=!!c,u=d?c:ha(process.env),p="bearer"===o.auth?(()=>{const e=d?Ya("callback"):ma,{service:t,...o}=a;return Wa({service:t,callback_url:`${u}/callback/${encodeURIComponent(e)}/${i}`,params:o},n,{projectId:e,jobRef:i})})():Wa(a,n,{projectId:n.billing?d?Ya("billing"):ma:"",jobRef:i}),m=1e3*(r?.timeout??120);return{...await Da(s,l,p,{timeoutMs:"bearer"===o.auth?Math.max(m,12e4):m,retries:1}),job_ref:i}}function Xa(e){return e.replace(/^_+/,"").replace(/_/g,"-")}function Qa(e){return e.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function es(e){return e._def??{}}function ts(e){return es(e).type}function is(e){let t,i=e,n=!0,o=0;for(;o++<16;){const e=es(i),o=e.type;if("optional"!==o&&"nullable"!==o){if("default"!==o)break;if(n=!1,t="function"==typeof e.defaultValue?e.defaultValue():e.defaultValue,!e.innerType)break;i=e.innerType}else{if(n=!1,!e.innerType)break;i=e.innerType}}return{inner:i,required:n,default:t}}function ns(e){return e.def??e._zod?.def}function os(e){const t=es(e).checks;if(!t)return!1;for(const e of t){const t=ns(e);if("number_format"===t?.check&&"safeint"===t.format)return!0}return!1}function rs(e,t){const i=e.startsWith("_"),n=Xa(e),{inner:o,required:r,default:a}=is(t),s=ts(o),l={flag:n,jsonName:e,kind:"string",required:r,internal:i,default:a,description:t.description};switch(s){case"string":return l;case"number":{const{minimum:e,maximum:t}=function(e){const t=es(e).checks;if(!t)return{};const i={};for(const e of t){const t=ns(e);t&&("greater_than"===t.check&&"number"==typeof t.value&&(i.minimum=t.value),"less_than"===t.check&&"number"==typeof t.value&&(i.maximum=t.value))}return i}(o);return{...l,kind:os(o)?"integer":"number",minimum:e,maximum:t}}case"boolean":return{...l,kind:"boolean"};case"enum":{const e=es(o).entries??{},t=Object.keys(e);return{...l,enum:t}}case"literal":{const e=es(o),t=e.values?.[0]??e.value;return{...l,enum:[String(t)]}}case"array":{const e=es(o).element;return{...l,kind:"array",itemKind:as(e)}}case"union":{const e=es(o).options??[],t=e.some(e=>function(e){return"string"===e||"number"===e||"boolean"===e}(ts(is(e).inner))),i=e.find(e=>"array"===ts(is(e).inner));if(t&&i){const e=es(is(i).inner).element;return{...l,kind:"array",itemKind:as(e),scalarOrArray:!0}}return{...l,kind:"object"}}default:return{...l,kind:"object"}}}function as(e){if(!e)return;const t=ts(is(e).inner);return"string"===t?"string":"number"===t?os(is(e).inner)?"integer":"number":"boolean"===t?"boolean":void 0}function ss(e,t){switch(e.kind){case"integer":{const e=Number(t);return Number.isFinite(e)?Math.trunc(e):t}case"number":{const e=Number(t);return Number.isFinite(e)?e:t}case"boolean":return Boolean(t);case"array":{const i=(Array.isArray(t)?t:[t]).map(t=>function(e,t){if("integer"===e){const e=Number(t);return Number.isFinite(e)?Math.trunc(e):t}if("number"===e){const e=Number(t);return Number.isFinite(e)?e:t}return"boolean"===e?Boolean(t):t}(e.itemKind,t));return e.scalarOrArray&&1===i.length?i[0]:i}default:if("object"===e.kind&&"string"==typeof t)try{return JSON.parse(t)}catch{return t}return t}}async function ls(e,t){if("-"===e)try{const e=await async function(){if(process.stdin.isTTY)throw new wa("E_FILE_MISSING","`--*-file=-` requested stdin but stdin is a TTY (nothing piped in)","pipe a file via stdin, e.g. `cat params.json | dl ... --params-file=-`, or pass a file path",{stdin_is_tty:!0});const e=[];for await(const t of process.stdin)e.push("string"==typeof t?Buffer.from(t):t);return Buffer.concat(e).toString("utf8")}();if(0===e.length)throw new wa("E_FILE_MISSING",`${t}=- received empty stdin`,`pipe non-empty content into \`${t}=-\`, or pass a file path`,{source:"<stdin>"});return{label:"<stdin>",raw:e}}catch(e){if(e instanceof wa)throw e;const i=e instanceof Error?e.message:String(e);throw new wa("E_FILE_MISSING",`failed to read stdin for ${t}: ${i}`,void 0,{source:"<stdin>"})}const i=c(e);try{return{label:i,raw:await O(i,"utf8")}}catch(n){const o=n instanceof Error?n.message:String(n);throw new wa("E_FILE_MISSING",`${t}: cannot read file at ${i} (${o})`,`check the path is reachable from cwd; cwd=${process.cwd()}; if the file is meant to be on stdin pass \`${t}=-\``,{flag:t,given:e,resolved:i,cwd:process.cwd()})}}function cs(e,t){try{return JSON.parse(e.raw)}catch(i){const n=i instanceof Error?i.message:String(i),o=/position (\d+)/.exec(n),r=o?Number(o[1]):-1,a=r>=0?function(e,t){const i=e.slice(0,Math.max(0,t)),n=e.split("\n"),o=i.split("\n").length-1,r=t-(i.lastIndexOf("\n")+1),a=Math.max(0,o-1),s=Math.min(n.length,o+2),l=n.slice(a,s).map((e,t)=>`${a+t===o?">":" "} ${(a+t+1).toString().padStart(3," ")}: ${e}`).join("\n");return{line:o+1,column:r+1,snippet:l}}(e.raw,r):void 0;throw new wa("E_FILE_PARSE",`${t} (${e.label}): JSON parse failed (${n})`,"check for missing/extra commas, unbalanced braces, or single quotes — JSON requires double quotes",{flag:t,source:e.label,...a?{line:a.line,column:a.column,snippet:a.snippet}:{}})}}async function ds(e,t){const i=await ls(e,t),n=cs(i,t);if(!Array.isArray(n))throw new wa("E_SCHEMA",`${t} (${i.label}): expected JSON array, got ${fs(n)}`,'rewrite the file to start with `[`. Example: [{"job_key":"a","params":{}}]',{flag:t,source:i.label,got:fs(n),expected:"JSON array"});return{source:i,data:n}}function us(e,t){const i={label:"inline",raw:e},n=cs(i,t);if(!Array.isArray(n))throw new wa("E_SCHEMA",`${t}: expected JSON array, got ${fs(n)}`,`pass an inline JSON array. Example: ${t} '[{"job_key":"a","params":{}}]'`,{flag:t,got:fs(n),expected:"JSON array"});return{source:i,data:n}}function ps(e){throw new wa("E_SCHEMA",`${e.inline} and ${e.file} are mutually exclusive`,`prefer ${e.inline} (inline); file/stdin content is invisible to the billing extension / dl adapter`,{inline_flag:e.inline,file_flag:e.file})}async function ms(e,t,i){const n="string"==typeof e&&""!==e,o="string"==typeof t&&""!==t;return n&&o&&ps(i),n?function(e,t){const i={label:"inline",raw:e},n=cs(i,t);if(null===n||"object"!=typeof n||Array.isArray(n))throw new wa("E_SCHEMA",`${t}: expected JSON object, got ${fs(n)}`,`pass an inline JSON object. Example: ${t} '{"key":"value"}'`,{flag:t,got:fs(n),expected:"JSON object"});return{source:i,data:n}}(e,i.inline):o?async function(e,t){const i=await ls(e,t),n=cs(i,t);if(null===n||"object"!=typeof n||Array.isArray(n))throw new wa("E_SCHEMA",`${t} (${i.label}): expected JSON object, got ${fs(n)}`,'rewrite the file to start with `{`. Example: {"key":"value"}',{flag:t,source:i.label,got:fs(n),expected:"JSON object"});return{source:i,data:n}}(t,i.file):void 0}async function hs(e,t,i){const n="string"==typeof e&&""!==e,o="string"==typeof t&&""!==t;if(n&&o&&ps(i),n){if(""===e.trim())throw new wa("E_SCHEMA",`${i.inline}: expected non-empty text, got empty input`,`pass the text content as an inline string to ${i.inline}`,{flag:i.inline,expected:"non-empty text"});return{label:"inline",raw:e}}if(o)return async function(e,t){const i=await ls(e,t);if(""===i.raw.trim())throw new wa("E_SCHEMA",`${t} (${i.label}): expected non-empty text, got empty input`,`pipe or write the long-text content into ${t}; an empty file is never a valid value`,{flag:t,source:i.label,expected:"non-empty text"});return i}(t,i.file)}function fs(e){if(null===e)return"null";if(Array.isArray(e))return"array";const t=typeof e;return"object"===t?"object":t}function gs(e){process.stdout.write(`${JSON.stringify(e)}\n`),process.exit(0)}function vs(e,t,i){const n={ok:!1,code:"E_BACKEND",error:e,message:e,...t?{hint:t}:{},...i??{}};process.stderr.write(`${JSON.stringify(n)}\n`),process.exit(1)}function ys(e,t,i,n){const o={ok:!1,code:e,error:t,message:t,...i?{hint:i}:{},...n??{}};process.stderr.write(`${JSON.stringify(o)}\n`),process.exit(_a(e))}function bs(e){ys(e.code,e.message,e.hint,e.extra)}function _s(e,t){if("1"!==process.env.DL_ECHO_PARSED)return;const i=JSON.stringify({echo:"parsed",...e});process.stderr.write(`${i}\n`)}function ws(e){const t=JSON.stringify({event:"submitted",...e});process.stderr.write(`${t}\n`)}class ks extends Error{constructor(e){super(e),this.name="JsonPointerError"}}const xs="@file:";function Ss(e){return"string"==typeof e&&e.startsWith(xs)}function Es(e,t){if(!e.startsWith(xs))throw new wa("E_SCHEMA",`不是 @file: 语法:${e}`,"正确格式:@file:/abs/path.json#/json/pointer",{flag:t.flag});const i=e.slice(6),n=i.indexOf("#");if(n<0)throw new wa("E_SCHEMA",`${t.flag} 缺少 JSON Pointer(# 之后的部分):${e}`,"@file: 必须带 #/some/pointer 才能定位到具体字段,避免误读入整个文件",{flag:t.flag});const o=i.slice(0,n),a=i.slice(n+1);if(!o)throw new wa("E_SCHEMA",`${t.flag} 路径为空:${e}`,void 0,{flag:t.flag});if(!d(o))throw new wa("E_SCHEMA",`${t.flag} 路径必须是绝对路径:${o}`,"避免 cwd 歧义。可在 shell 里用 $PWD/相对路径 转成绝对路径",{flag:t.flag});let s,l,c;try{s=r(o,"utf8")}catch(e){const i=e instanceof Error?e.message:String(e);throw new wa("E_FILE_MISSING",`${t.flag} 读取文件失败:${o}(${i})`,void 0,{flag:t.flag,path:o})}try{l=JSON.parse(s)}catch(e){const i=e instanceof Error?e.message:String(e);throw new wa("E_FILE_PARSE",`${t.flag} 不是合法 JSON:${o}(${i})`,void 0,{flag:t.flag,path:o})}try{c=function(e,t){const i=function(e){if(""===e)return[];if(!e.startsWith("/"))throw new ks(`JSON Pointer 必须以 "/" 开头(或为空字符串表示根节点):${e}`);return e.slice(1).split("/").map(e=>e.replace(/~1/g,"/").replace(/~0/g,"~"))}(t);let n=e;const o=[];for(const e of i){if(o.push(e),null==n)throw new ks(`JSON Pointer 无法定位:/${o.join("/")}(中途遇到 ${null===n?"null":"undefined"})`);if(Array.isArray(n)){if(!/^\d+$/.test(e))throw new ks(`JSON Pointer 数组段必须是非负整数:/${o.join("/")}(实际:${JSON.stringify(e)})`);const t=Number(e);if(t>=n.length)throw new ks(`JSON Pointer 数组越界:/${o.join("/")}(长度 ${n.length})`);n=n[t];continue}if("object"==typeof n){const t=n;if(!Object.hasOwn(t,e))throw new ks(`JSON Pointer 字段不存在:/${o.join("/")}`);n=t[e];continue}throw new ks(`JSON Pointer 无法在标量上继续下钻:/${o.join("/")}(当前类型 ${typeof n})`)}return n}(l,a.startsWith("/")?a:`/${a}`)}catch(e){if(e instanceof ks)throw new wa("E_SCHEMA",`${t.flag} ${e.message}`,void 0,{flag:t.flag,path:o,pointer:a});throw e}if(t.requireString&&"string"!=typeof c)throw new wa("E_SCHEMA",`${t.flag} JSON Pointer 命中的值不是字符串:${a}(实际类型:${Array.isArray(c)?"array":typeof c})`,void 0,{flag:t.flag,path:o,pointer:a});return c}function Os(e,t){if(!e.startsWith(xs))throw new wa("E_SCHEMA",`不是 @file: 语法:${e}`,"正确格式:@file:/abs/path.txt",{flag:t.flag});const i=e.slice(6);if(i.indexOf("#")>=0){const i=Es(e,{flag:t.flag,requireString:!0});if("string"==typeof i)return i;throw new wa("E_SCHEMA",`${t.flag} JSON Pointer 命中的值不是字符串`,void 0,{flag:t.flag})}const n=i;if(!n)throw new wa("E_SCHEMA",`${t.flag} 路径为空:${e}`,void 0,{flag:t.flag});if(!d(n))throw new wa("E_SCHEMA",`${t.flag} 路径必须是绝对路径:${n}`,"避免 cwd 歧义。可在 shell 里用 $PWD/相对路径 转成绝对路径",{flag:t.flag});try{return r(n,"utf8")}catch(e){const i=e instanceof Error?e.message:String(e);throw new wa("E_FILE_MISSING",`${t.flag} 读取文件失败:${n}(${i})`,void 0,{flag:t.flag,path:n})}}function Ts(e){return Ss(e.prompt)?{...e,prompt:Os(e.prompt,{flag:"--prompt"})}:e}function As(e,t){const i=Array.isArray(e)?e:e.issues,n=t.maxErrors??5,o=function(e){const t={invalid_type:0,required:0,invalid_value:1,invalid_enum_value:1,invalid_string:2,too_small:3,too_big:3,unrecognized_keys:4,invalid_union:5,custom:6};return[...e].sort((e,i)=>{const n=t[e.code]??99,o=t[i.code]??99;return n!==o?n-o:$s(Ns(e.path)).localeCompare($s(Ns(i.path)))})}(i).slice(0,n);return o.map(e=>function(e,t){switch(e.code){case"invalid_type":return function(e,t){const i=e,n=Ns(e.path),o=i.received??function(e){if(!e)return;const t=/received\s+(\S+?)\b/.exec(e);return t?.[1]}(e.message),r=void 0===o?js(t.input??t.jobs,n):void 0,a=o??function(e){if(null===e)return"null";if(void 0===e)return"undefined";if(Array.isArray(e))return"array";const t=typeof e;if("number"===t&&Number.isNaN(e))return"nan";if("object"===t){const t=e.constructor;return t&&t!==Object&&"string"==typeof t.name&&t.name.length>0?t.name:"object"}return t}(r),s="undefined"===o||void 0===o&&void 0===r,l=Cs(n,t);return s?{code:"E_SCHEMA",message:`${l.prefix} is required`,expected:Is(t.flags,Rs(Ns(e.path)))??i.expected,got:void 0,instance_path:l.instance_path,mode:t.mode,verb:t.verb,job_index:l.job_index,job_key:l.job_key,flag:l.flag,hint:`run \`dl ${t.verb} --print-schema\` to see all required fields`}:{code:"E_SCHEMA",message:`${l.prefix}: expected ${i.expected??"<unknown>"}, got ${a??"<unknown>"}`,expected:i.expected,got:a,instance_path:l.instance_path,mode:t.mode,verb:t.verb,job_index:l.job_index,job_key:l.job_key,flag:l.flag,hint:`run \`dl ${t.verb} --print-schema\` to see expected types`}}(e,t);case"invalid_value":case"invalid_enum_value":return function(e,t){const i=e,n=(i.values??[]).map(e=>String(e)),o=i.received??js(t.input??t.jobs,Ns(e.path)),r=Cs(Ns(e.path),t),a="string"==typeof o?xa(o,n):void 0;return{code:"E_SCHEMA",message:a?`${r.prefix}: expected one of {${n.join("|")}}, got ${JSON.stringify(o)} (did you mean ${JSON.stringify(a)}?)`:`${r.prefix}: expected one of {${n.join("|")}}, got ${JSON.stringify(o)}`,expected:`enum {${n.join("|")}}`,got:o,instance_path:r.instance_path,mode:t.mode,verb:t.verb,job_index:r.job_index,job_key:r.job_key,flag:r.flag,hint:a?"re-run with the suggested value":`run \`dl ${t.verb} --print-schema\` for the full enum`}}(e,t);case"too_small":case"too_big":return function(e,t){const i=e,n=Cs(Ns(e.path),t),o="too_small"===e.code?"at least":"at most",r="too_small"===e.code?i.minimum:i.maximum,a="string"===i.type?" chars":"";return{code:"E_SCHEMA",message:`${n.prefix}: expected ${o} ${r}${a}, got ${qs(i.received)}`,expected:`${o} ${r}${a}`,got:i.received,instance_path:n.instance_path,mode:t.mode,verb:t.verb,job_index:n.job_index,job_key:n.job_key,flag:n.flag,hint:`adjust ${n.prefix} so it satisfies the bound`}}(e,t);case"unrecognized_keys":return function(e,t){const i=e,n=i.keys?.[0]??"<unknown>",o=t.flags.map(e=>e.jsonName),r=xa(n,o),a=Cs(Ns(e.path),t,n),s=`--${Xa(n)}`,l=r?`--${Xa(r)}`:void 0;return{code:"E_SCHEMA",message:l?`${s} is not a valid flag (did you mean ${l}?)`:`${s} is not a valid flag`,expected:`one of: ${o.map(e=>`--${Xa(e)}`).join(", ")}`,got:n,instance_path:a.instance_path,mode:t.mode,verb:t.verb,job_index:a.job_index,job_key:a.job_key,flag:s,hint:l?`re-run with ${l}`:`run \`dl ${t.verb} --help\` for the full flag list`}}(e,t);case"invalid_union":return function(e,t){const i=Cs(Ns(e.path),t);return{code:"E_SCHEMA",message:`${i.prefix}: must satisfy one of the conditional shapes (e.g. provide image_url OR image_base64, not both/neither)`,expected:"one-of constraint",got:void 0,instance_path:i.instance_path,mode:t.mode,verb:t.verb,job_index:i.job_index,job_key:i.job_key,flag:i.flag,hint:`run \`dl ${t.verb} --print-schema\` for the conditional required-field combinations`}}(e,t);case"custom":return function(e,t){const i=Cs(Ns(e.path),t);return{code:"E_SCHEMA",message:`${i.prefix}: ${e.message??"validation failed"}`,expected:void 0,got:void 0,instance_path:i.instance_path,mode:t.mode,verb:t.verb,job_index:i.job_index,job_key:i.job_key,flag:i.flag,hint:`run \`dl ${t.verb} --print-schema\` for the schema`}}(e,t);default:return function(e,t){const i=Cs(Ns(e.path),t);return{code:"E_SCHEMA",message:`${i.prefix}: ${e.message??"validation failed"}`,expected:void 0,got:void 0,instance_path:i.instance_path,mode:t.mode,verb:t.verb,job_index:i.job_index,job_key:i.job_key,flag:i.flag,hint:`run \`dl ${t.verb} --print-schema\` for the schema`}}(e,t)}}(e,t))}function $s(e){return 0===e.length?"":`/${e.join("/")}`}function Ns(e){return e.map(e=>"symbol"==typeof e?e.toString():e)}function js(e,t){let i=e;for(const e of t){if(null==i||"object"!=typeof i)return;i=i[e]}return i}function Cs(e,t,i){const n=void 0!==i?[...e,i]:[...e],o=0===n.length?"":`/${n.join("/")}`;if("single"===t.mode){const t=i??e[e.length-1],n="string"==typeof t?`--${Xa(t)}`:void 0;return{instance_path:o,flag:n,job_index:void 0,job_key:void 0,prefix:n??"<root>"}}const r="number"==typeof e[0]?e[0]:void 0,a=(void 0!==i?[...e.slice(1),i]:e.slice(1)).map(String),s=void 0!==r&&t.jobs?t.jobs[r]:void 0;return{instance_path:o,flag:void 0,job_index:r,job_key:s&&"string"==typeof s.job_key?s.job_key:void 0,prefix:void 0===r?"--jobs-file":a.length>0?`--jobs-file[${r}].${a.join(".")}`:`--jobs-file[${r}]`}}function Is(e,t){if(!t)return;const i=e.find(e=>e.jsonName===t);return i?i.enum?`enum {${i.enum.join("|")}}`:i.kind:void 0}function Rs(e){const t=e[e.length-1];return"string"==typeof t?t:void 0}function qs(e){if(null===e)return"null";if(void 0===e)return"undefined";if(Array.isArray(e))return"array";const t=typeof e;return"object"===t?"object":"string"===t?JSON.stringify(e):String(e)}function Ps(e,t){const i=function(e){const{inner:t}=is(e);if("object"!==ts(t))return[];const i=es(t).shape??{},n=[];for(const[e,t]of Object.entries(i))n.push(rs(e,t));return n}(t.schema),n={verb:t.verb,description:t.description,whenToUse:t.whenToUse,whenNotToUse:t.whenNotToUse,flags:i,supportsBatch:t.supportsBatch,examples:t.examples,notExamples:t.notExamples,outputSingle:t.outputSingle,outputBatch:t.outputBatch,errors:t.errors,notes:t.notes,extraFlags:t.extraFlags?.map(e=>({flag:e.spec.split(/\s+/)[0],description:e.description,...e.enum?{enum:e.enum}:{}})),modelTopic:t.modelTopic,preflightTopic:t.preflightTopic,policyTopic:t.policyTopic,compositionTopic:t.compositionTopic,asyncTopic:t.asyncTopic,publishTopic:t.publishTopic},o=function(e){const t=[],i=!!(e.modelTopic||e.preflightTopic||e.policyTopic||e.compositionTopic||e.asyncTopic||e.publishTopic);if(t.push("DESCRIPTION",` ${e.description}`,""),e.whenToUse.length>0){t.push("WHEN TO USE");for(const i of e.whenToUse)t.push(` - ${i}`);t.push("")}if(e.whenNotToUse&&e.whenNotToUse.length>0){t.push("WHEN NOT TO USE");for(const i of e.whenNotToUse)t.push(` - ${i}`);t.push("")}if(e.notes&&e.notes.length>0){t.push("NOTES");for(const i of e.notes)t.push(` - ${i}`);t.push("")}if(i){const i=function(e,t){if(!(t.modelTopic||t.preflightTopic||t.policyTopic||t.compositionTopic||t.asyncTopic||t.publishTopic))return[];const i=[];t.modelTopic&&i.push({topic:"model",oneLiner:"service ranking + per-service call shape + decision logic"}),t.preflightTopic&&i.push({topic:"preflight",oneLiner:"decisions you must make before the first call"}),t.policyTopic&&i.push({topic:"policy",oneLiner:"user-facing communication rules + payment-package gate"}),t.compositionTopic&&i.push({topic:"composition",oneLiner:"how upstream / sibling skills consume this output"}),t.asyncTopic&&i.push({topic:"async",oneLiner:"detach-by-default protocol + result shape"}),t.publishTopic&&i.push({topic:"publish",oneLiner:"handing the result off to publish_content"}),i.push({topic:"examples",oneLiner:"copy-paste-ready calls per scenario"}),i.push({topic:"errors",oneLiner:"failure codes + recovery breadcrumbs"});const n=["LEARN MORE (drill down for the specific decision you face)"];for(const t of i)n.push(` dl ${e} ${t.topic.padEnd(11)} -h — ${t.oneLiner}`);return n}(e.verb,e);if(i.length>0){for(const e of i)t.push(e);t.push("")}}const n=e.flags.filter(e=>e.required),o=e.flags.filter(e=>!e.required);if(n.length>0){t.push("REQUIRED");for(const e of n)t.push(...qr(e));t.push("")}if(o.length>0||e.extraFlags&&e.extraFlags.length>0){t.push("OPTIONAL");for(const e of o)t.push(...qr(e));for(const i of e.extraFlags??[])t.push(` ${i.flag.padEnd(22)} ${i.description}`),i.enum&&t.push(` one of: ${i.enum.join(", ")}`);t.push("")}e.supportsBatch&&(t.push("BATCH MODE (mutually exclusive with the per-job scalar flags above)"),t.push(" --jobs <inline-json> RECOMMENDED. JSON array of {job_key, ...same fields as scalars above}"," passed as an inline string. Lets the LLM-side billing extension"," preflight charge the full batch cost (= N × per-action cost) so"," insufficient-credits requests block before vendor is touched.",' Usage: --jobs "$(cat /workspace/jobs.json)" — or pass JSON directly.'," --jobs-file <path|-> LEGACY. JSON array via file path; `-` reads stdin. Billing extension"," cannot see the file content, so falls back to per-job best-effort"," charging — users with low balance can partially get free vendor work."," Prefer --jobs unless the JSON is too large for argv (uncommon)."),t.push(""));const r=e.utility??Ir;t.push("UTILITY");for(const e of r)t.push(` ${e.flag.padEnd(22)} ${e.description}`);if(t.push(""),!i){for(const i of e.examples){t.push(`EXAMPLE — ${i.caption}`);for(const e of i.command.split("\n"))t.push(` ${e}`);t.push("")}if(e.notExamples&&e.notExamples.length>0){t.push("NOT AN EXAMPLE (these all fail)");for(const i of e.notExamples){t.push(` # ❌ ${i.whyItFails}`);for(const e of i.command.split("\n"))t.push(` ${e}`);t.push("")}}}if(e.outputSingle){t.push("OUTPUT (single, success)");for(const i of e.outputSingle.split("\n"))t.push(` ${i}`);t.push("")}if(e.outputBatch&&e.supportsBatch){t.push("OUTPUT (batch, success)");for(const i of e.outputBatch.split("\n"))t.push(` ${i}`);t.push("")}if(!i){const i=e.errors??Rr;if(i.length>0){t.push("ERRORS");for(const e of i){const i=e.recovery?` — ${e.recovery}`:"";t.push(` ${e.code.padEnd(11)} ${e.when}${i}`)}}}for(;t.length>0&&""===t[t.length-1];)t.pop();return t.join("\n")}(n),r=e.command(t.verb).description(t.description);r.configureHelp({formatHelp:()=>o}),function(e,t,i){const n=t.verb;if(t.modelTopic){const i=t.modelTopic,o=e.command("model [service]").description("service ranking + decision logic; pass <service> for per-service profile");o.configureHelp({formatHelp:()=>Pr(n,i)}),o.action(e=>{console.log(Pr(n,i,e)),process.exit(0)})}if(t.preflightTopic){const i=t.preflightTopic,o=!!t.modelTopic,r=e.command("preflight").description("decisions you must make before the first call");r.configureHelp({formatHelp:()=>Lr(n,i,o)}),r.action(()=>{console.log(Lr(n,i,o)),process.exit(0)})}if(t.policyTopic){const i=t.policyTopic,n=e.command("policy").description("user-facing communication rules + payment-package gate");n.configureHelp({formatHelp:()=>zr(0,i)}),n.action(()=>{console.log(zr(0,i)),process.exit(0)})}if(t.compositionTopic){const i=t.compositionTopic,n=e.command("composition").description("how upstream / sibling skills consume this output");n.configureHelp({formatHelp:()=>Mr(0,i)}),n.action(()=>{console.log(Mr(0,i)),process.exit(0)})}if(t.asyncTopic){const i=t.asyncTopic,n=e.command("async").description("detach-by-default protocol + result shape");n.configureHelp({formatHelp:()=>Ur(0,i)}),n.action(()=>{console.log(Ur(0,i)),process.exit(0)})}if(t.publishTopic){const i=t.publishTopic,n=e.command("publish").description("handing the result off to publish_content");n.configureHelp({formatHelp:()=>Fr(0,i)}),n.action(()=>{console.log(Fr(0,i)),process.exit(0)})}if(!!(t.modelTopic||t.preflightTopic||t.policyTopic||t.compositionTopic||t.asyncTopic||t.publishTopic)){if(t.examples.length>0||t.notExamples&&t.notExamples.length>0){const t=e.command("examples").description("copy-paste-ready calls per scenario");t.configureHelp({formatHelp:()=>Dr(0,i)}),t.action(()=>{console.log(Dr(0,i)),process.exit(0)})}const n=e.command("errors").description("failure codes + recovery breadcrumbs");n.configureHelp({formatHelp:()=>Hr(0,i)}),n.action(()=>{console.log(Hr(0,i)),process.exit(0)})}}(r,t,n);const a=function(e){const t=[e.name()];let i=e.parent;for(;i&&i.parent;)t.unshift(i.name()),i=i.parent;return t.join(" ")}(r);for(const e of i)Ls(r,e);if(t.extraFlags)for(const e of t.extraFlags)void 0!==e.default?r.option(e.spec,e.description,e.default):r.option(e.spec,e.description);t.supportsBatch&&(r.option("--jobs <inline-json>","BATCH MODE (recommended): JSON array of {job_key, ...same fields as scalars above} as an inline string; lets pi-extension preflight charge the full batch cost"),r.option("--jobs-file <path|->","BATCH MODE (legacy): JSON array via file path; `-` reads stdin. Prefer --jobs because the LLM-side billing extension cannot count jobs from a file path and must fall back to per-job best-effort charging.")),r.option("--print-schema","emit JSON schema for this verb's single + batch shape and exit"),r.option("--echo-parsed","echo canonicalised input on stderr (debug)"),r.option("--dry-run","validate, quote, and render approval preview without submitting vendor work or requiring user approval"),r.option("--quote","emit the credit quote for this command and exit without submitting vendor work"),r.action(async e=>{const n=e;n.printSchema&&function(e,t,i){const n={};for(const e of t)e.required&&(n[e.flag]=Ms(e));const o=e.extraFlags?.map(e=>({flag:e.spec.split(/\s+/)[0],type:"string",required:!1,...e.enum?{enum:e.enum}:{},...void 0!==e.default?{default:e.default}:{}}))??[],r={ok:!0,verb:i,single:{scalars:[...t.map(e=>({flag:`--${e.flag}`,type:e.kind,required:e.required,...e.enum?{enum:e.enum}:{},...void 0!==e.minimum?{minimum:e.minimum}:{},...void 0!==e.maximum?{maximum:e.maximum}:{},...void 0!==e.default?{default:e.default}:{},...e.internal?{internal:!0,note:"stripped before submit"}:{}})),...o],example:n},batch:e.supportsBatch?{shape:"array<object>",item_required:["job_key",...t.filter(e=>e.required).map(e=>e.jsonName)],example:[{job_key:"job_0",...Us(t)}]}:null};process.stdout.write(`${JSON.stringify(r,null,2)}\n`),process.exit(0)}(t,i,a),!0===n.dryRun&&!0===n.quote&&ys("E_SCHEMA","--dry-run and --quote are mutually exclusive","use --dry-run for agent-facing validation/preview, or --quote for runtime approval pricing.",{verb:a});const o="string"==typeof n.jobs&&""!==n.jobs,r="string"==typeof n.jobsFile&&""!==n.jobsFile,s=o||r,l=function(e,t){for(const i of e){const e=t[zs(i.flag)];if(void 0!==e&&("boolean"!=typeof e||!1!==e))return!0}return!1}(i,n);o&&r&&ys("E_SCHEMA","--jobs and --jobs-file are mutually exclusive","pick one batch input mode; --jobs is preferred so the billing extension can preflight charge the full batch cost.",{verb:a}),s&&l&&ys("E_SCHEMA","batch flag is mutually exclusive with the per-job scalar flags",`pick one mode: pass a job array via --jobs '<inline-json>' (or --jobs-file=path) OR pass scalar flags directly. Run \`dl ${a} --print-schema\` to see both shapes.`,{verb:a});try{s?await async function(e,t,i,n){const o="string"==typeof i.jobs&&""!==i.jobs,r=o?"--jobs":"--jobs-file",{data:a}=o?us(String(i.jobs),"--jobs"):await ds(String(i.jobsFile),"--jobs-file");if(!o){const e=String(i.jobsFile),t="-"===e?"<path/to/jobs.json>":e;process.stderr.write(`[dl] DEPRECATED: --jobs-file=${e} prevents the billing extension from sizing the batch, so insufficient-credit requests can only be reconciled after vendor submit (partial free work possible). Switch to --jobs '<inline-json>'.\n[dl] Migration: dl ${n} --jobs "$(cat ${t})"\n[dl] See: dl ${n} -h (BATCH MODE section).\n`)}0===a.length&&ys("E_SCHEMA",`${r} must be a non-empty JSON array`,`run \`dl ${n} --print-schema\` for the batch shape`,{verb:n,flag:r});const s=[],l=[];for(let i=0;i<a.length;i++){try{a[i]=Ts(a[i]),e.transformParams&&(a[i]=e.transformParams(a[i],{mode:"batch"}))}catch(e){if(e instanceof wa){s.push({code:"custom",path:[i],message:e.message});continue}throw e}if(e.strictBatchParams){const e=Ds(a[i],t);if(e.length>0){s.push({code:"unrecognized_keys",keys:e,path:[i],message:`Unrecognized key${1===e.length?"":"s"}: ${e.join(", ")}`});continue}}const n=e.schema.safeParse(a[i]);if(n.success){const t=a[i],o="string"==typeof t.job_key?t.job_key:`job_${i}`;if(e.preflight)try{e.preflight(n.data)}catch(e){if(!(e instanceof wa))throw e;s.push({code:"custom",path:[i],message:e.message});continue}l.push({jobKey:o,params:n.data})}else for(const e of n.error.issues)s.push({...e,path:[i,...e.path]})}if(s.length>0){const e=As(s,{verb:n,flags:t,mode:"batch",jobs:a,input:a}),i=e[0];ys("E_SCHEMA",i.message,i.hint,{verb:i.verb,instance_path:i.instance_path,expected:i.expected,got:i.got,...void 0!==i.job_index?{job_index:i.job_index}:{},...i.job_key?{job_key:i.job_key}:{},...e.length>1?{details:e.slice(1)}:{}})}const c=e.resolveActionName?e.resolveActionName(i):e.actionName,d=l.map((i,o)=>{try{const r=Fs(e,i.params,{fullVerb:n,flags:t,mode:"batch",input:i.params,command:n,action:c,jobIndex:o,jobKey:i.jobKey}),a=e.approvalPreview?.(i.params,{mode:"batch",verb:n,action:c});return{...i,billing:r,...a?{approvalPreview:a}:{}}}catch(e){throw e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_index:o,job_key:i.jobKey}),e}});_s({command:n,mode:"batch",jobs:a}),!0===i.quote&&function(e,t,i){const n=i.map((t,i)=>(t.billing||Bs(e),{index:i,jobKey:t.jobKey,...t.billing})),o=Hs(e,i);gs({ok:!0,mode:"batch",source:"dl",action:t,totalCredits:n.reduce((e,t)=>e+t.credits,0),items:n,...o?{approvalPreview:o}:{}})}(n,c,d),!0===i.dryRun&&function(e,t){const i=t.map((e,t)=>({index:t,jobKey:e.jobKey,params:e.params,...e.billing?{billing:e.billing}:{}})),n=Hs("dry-run",t);gs({ok:!0,mode:"batch",source:"dl",dryRun:!0,action:e,totalCredits:t.reduce((e,t)=>e+(t.billing?.credits??0),0),jobs:i,...n?{approvalPreview:n}:{}})}(c,d.map(e=>({jobKey:e.jobKey,params:e.params,billing:e.billing,...e.approvalPreview?{approvalPreview:e.approvalPreview}:{}})));const u=await Promise.all(d.map(async(e,t)=>{const i=e.params,n=k(),o=e.billing;try{const r=await Za(c,i,n,{billing:o,billingTrace:{mode:"batch",batchIndex:t,jobKey:e.jobKey}});ws({action:c,job_ref:n,mode:"batch",job_key:e.jobKey,index:t});const{job_ref:a,...s}=r;return Ka(c)?{job_key:e.jobKey,index:t,job_ref:n,...o?{billing:o}:{},...s}:{job_key:e.jobKey,index:t,job_ref:n,status:"pending",...o?{billing:o}:{},...s}}catch(i){if(i instanceof wa)return{job_key:e.jobKey,index:t,job_ref:n,status:"failed",code:i.code,error:i.message,message:i.message,...i.hint?{hint:i.hint}:{},...i.extra??{}};const o=i instanceof Error?i.message:String(i);return{job_key:e.jobKey,index:t,job_ref:n,status:"failed",error:o}}})),p=u.some(e=>"failed"===e.status),m={ok:!p,action:c,results:u};u.some(e=>"E_INSUFFICIENT_CREDITS"===e.code)&&ys("E_INSUFFICIENT_CREDITS","one or more batch jobs failed because credits are insufficient","Top up credits and retry; jobs with status=failed were not submitted to upstream vendors.",m),p&&vs("one or more batch jobs failed","inspect .results[].status",m),gs(m)}(t,i,n,a):await async function(e,t,i,n){let o=function(e,t){const i={};for(const n of e){const e=t[Qa(n.flag)];void 0!==e&&(i[n.jsonName]=ss(n,e))}return i}(t,i);try{o=Ts(o),e.transformParams&&(o=e.transformParams(o,{opts:i,mode:"single"}))}catch(e){throw e instanceof wa&&bs(e),e}const r=e.schema.safeParse(o);if(!r.success){const e=As(r.error,{verb:n,flags:t,mode:"single",input:o}),i=e[0];ys("E_SCHEMA",i.message,i.hint,{verb:i.verb,instance_path:i.instance_path,expected:i.expected,got:i.got,...i.flag?{flag:i.flag}:{},...e.length>1?{details:e.slice(1)}:{}})}if(e.preflight)try{e.preflight(r.data)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:n,mode:"single",params:r.data});const a=k(),s=e.resolveActionName?e.resolveActionName(i):e.actionName,l=Fs(e,r.data,{fullVerb:n,flags:t,mode:"single",input:r.data,command:n,action:s});if(!0===i.quote){const t=e.approvalPreview?.(r.data,{opts:i,mode:"single",verb:n,action:s});!function(e,t,i,n){i||Bs(e),gs({ok:!0,mode:"single",source:"dl",action:t,totalCredits:i.credits,items:[i],...n?{approvalPreview:n}:{}})}(n,s,l,t)}if(!0===i.dryRun){const t=e.approvalPreview?.(r.data,{opts:i,mode:"single",verb:n,action:s});!function(e,t,i,n){gs({ok:!0,mode:"single",source:"dl",dryRun:!0,action:e,params:t,...i?{billing:i}:{},...n?{approvalPreview:n}:{}})}(s,r.data,l,t)}try{const t=r.data,n=await Za(s,t,a,{billing:l,billingTrace:{mode:"single"}}),o=e.transformResult?e.transformResult(n,{params:r.data,opts:i,mode:"single"}):n;ws({action:s,job_ref:a,mode:"single"}),Ka(s)&&gs({ok:!0,...o,...l?{billing:l}:{}}),gs({ok:!0,status:"pending",...o,...l?{billing:l}:{}})}catch(t){t instanceof Ba&&ys("E_SCHEMA",t.message,`run \`dl ${n} --print-schema\` for required fields`,{verb:n,details:t.errors}),t instanceof wa&&ys(t.code,t.message,t.hint,{...t.extra??{},job_ref:a,action:e.actionName}),vs(t instanceof Error?t.message:String(t),void 0,{job_ref:a,action:e.actionName})}}(t,i,n,a)}catch(e){throw e instanceof wa&&bs(e),e}})}function Ls(e,t){const i=`--${t.flag}`,n=function(e){const t=[];return t.push(e.required?"REQUIRED":"optional"),e.enum&&t.push(`one of: ${e.enum.join(", ")}`),void 0===e.minimum&&void 0===e.maximum||t.push([void 0!==e.minimum?`>= ${e.minimum}`:void 0,void 0!==e.maximum?`<= ${e.maximum}`:void 0].filter(Boolean).join(", ")),e.description&&t.push(e.description),t.join(" — ")}(t);switch(t.kind){case"boolean":return void e.option(i,n);case"array":return void e.option(`${i} <${t.itemKind??"value"}>`,`${n}; repeatable`,(e,t=[])=>[...t,e]);case"integer":case"number":return void e.option(`${i} <n>`,n,e=>Number(e));default:e.option(`${i} <value>`,n)}}function zs(e){return e.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function Ms(e){if(e.enum&&e.enum.length>0)return e.enum[0];switch(e.kind){case"boolean":return!1;case"integer":case"number":return 0;case"array":return[];default:return"<value>"}}function Us(e){const t={};for(const i of e)i.required&&(t[i.jsonName]=Ms(i));return t}function Fs(e,t,i){if(!e.billing)return null;const n=e.billing.select(t),o=e.billing.schema.safeParse(n);if(!o.success){const e=As(o.error,{verb:i.fullVerb,flags:i.flags,mode:i.mode,input:i.input}),t=e[0];ys("E_SCHEMA",`billing schema validation failed: ${t.message}`,t.hint,{verb:t.verb,instance_path:t.instance_path,expected:t.expected,got:t.got,...t.flag?{flag:t.flag}:{},...void 0!==i.jobIndex?{job_index:i.jobIndex}:{},...i.jobKey?{job_key:i.jobKey}:{},...e.length>1?{details:e.slice(1)}:{}})}return e.billing.quote(o.data,{command:i.command,action:i.action})}function Ds(e,t){if("object"!=typeof e||null===e||Array.isArray(e))return[];const i=new Set(["job_key",...t.map(e=>e.jsonName)]);return Object.keys(e).filter(e=>!i.has(e))}function Hs(e,t){const i=t.filter(e=>e.approvalPreview);if(0!==i.length)return{kind:"batch",title:`${e} batch`,summary:`${t.length} jobs`,sections:i.flatMap((e,t)=>{const i=e.approvalPreview;if(!i)return[];const n=e.jobKey||`job_${t}`;return i.sections.map(e=>{const t="title"in e&&e.title?`[${n}] ${e.title}`:`[${n}]`;return{...e,title:t}})})}}function Bs(e){ys("E_SCHEMA",`dl ${e} --quote is only supported for billable actions`,"remove --quote or use a billable command that defines pricing",{verb:e})}const Vs="for media (video/image/audio) use the upload_file tool and store the returned URL inside a JSON artifact; if this really is text, pass --content-type application/json or text/plain";function Js(e,t){const i=e.resolve?.(t)??e,n={};for(const e of i.scalars)e.required&&(n[e.name]=Gs(e));const o={};for(const e of i.files)o[e.name]=JSON.parse(Ks(e));process.stdout.write(`${JSON.stringify({ok:!0,command:i.command,summary:i.summary,scalars:i.scalars,files:i.files,example:{scalars:n,files:o}},null,2)}\n`),process.exit(0)}function Ks(e){if("text"===e.kind)return JSON.stringify(e.example);try{return JSON.parse(e.example),e.example}catch{return"array"===e.kind?"[]":"{}"}}function Gs(e){if(e.enum&&e.enum.length>0)return e.enum[0];switch(e.type){case"boolean":return!1;case"integer":case"number":return 0;default:return"<value>"}}const Ys=/^https?:\/\//i,Ws=/https?:\/\/[^\s"'<>]+/gi;function Zs(e,t="$"){const i=[];return Xs(e,t,i),i}function Xs(e,t,i){if(null!=e)if("string"!=typeof e){if(Array.isArray(e))for(let n=0;n<e.length;n++)Xs(e[n],`${t}[${n}]`,i);else if("object"==typeof e)for(const[n,o]of Object.entries(e))Xs(o,`${t}.${n}`,i)}else Ys.test(e)&&i.push({path:t,url:e})}function Qs(e){let t=e;for(;t.length>0;){const e=t[t.length-1];if(!e)break;if(".,;:!?".includes(e))t=t.slice(0,-1);else if(")"===e&&el(t,"(")<el(t,")"))t=t.slice(0,-1);else if("]"===e&&el(t,"[")<el(t,"]"))t=t.slice(0,-1);else{if(!("}"===e&&el(t,"{")<el(t,"}")))break;t=t.slice(0,-1)}}return t}function el(e,t){let i=0;for(const n of e)n===t&&i++;return i}async function tl(e,t,i,n,o){const r=n+1;let a;for(let n=1;n<=r;n++)try{const s=await t(e,{method:"HEAD",signal:AbortSignal.timeout(i)});if(s.status>=200&&s.status<400)return{status:s.status};if(s.status>=400&&s.status<500)return{status:s.status};if(a=`http ${s.status}`,n<r){await il(o);continue}return{status:s.status,reason:a}}catch(e){if(a=e instanceof Error?e.message:String(e),n<r){await il(o);continue}return{status:0,reason:a}}return{status:0,reason:a}}function il(e){return new Promise(t=>setTimeout(t,e))}async function nl(e,t){try{return await Da("artifact",e,t,{timeoutMs:3e4,retries:0})}catch(e){if(e instanceof Jr&&vs(e.message,e.hint),e instanceof Sa){const t=function(e){if(e)try{const t=JSON.parse(e);if(t&&!1===t.ok&&"string"==typeof t.error)return t}catch{}}(e.bodyText);if(t)return t}throw e}}function ol(e){if(e.ok)return e;"E_SCHEMA"===e.code&&ys("E_SCHEMA",e.error,e.hint,void 0!==e.details?{details:e.details}:void 0),vs(e.error,e.hint,void 0!==e.details?{details:e.details}:void 0)}function rl(e){const{ok:t,...i}=e;return i}function al(e,t,i){const n={};for(const i of t)i in e&&(n[i]=e[i]);return i&&"content"in e&&(n.content=e.content),n}async function sl(e,t){if(t||0===e.length)return;const i=await async function(e,t={}){const i=t.concurrency??20,n=t.timeoutMs??3e3,o=t.retries??1,r=t.retryDelayMs??500,a=t.fetchImpl??globalThis.fetch,s=new Map;for(const{url:t,path:i}of e){const e=s.get(t);e?e.push(i):s.set(t,[i])}const l=Array.from(s.keys()),c=new Map;let d=0;const u=Math.min(i,l.length);await Promise.all(Array.from({length:u},()=>(async()=>{for(;;){const e=d++;if(e>=l.length)return;const t=l[e];c.set(t,await tl(t,a,n,o,r))}})()));const p=[];for(const e of l){const{status:t,reason:i}=c.get(e)??{status:0};if(!(t>=200&&t<400))for(const n of s.get(e)??[])p.push({path:n,url:e,status:t,...i?{reason:i}:{}})}return p}(e);0!==i.length&&ys("E_URL_UNREACHABLE",function(e){if(0===e.length)return"";const t=e[0],i=1===e.length?"URL is":"URLs are",n=e.length>1?` (${e.length-1} more in details.failures)`:"";return`${e.length} ${i} unreachable${n}: path=${t.path} status=${t.status} url=${t.url}`}(i),"One or more artifact URLs are not reachable by HEAD. Fix each URL at details.failures[].path and retry. Use --skip-url-check only for offline fixtures or intentional non-public URLs.",{failures:i,count:i.length})}function ll(e,t){let i;d(e)||ys("E_SCHEMA",`--contract must be an absolute path, got ${e}`,"skill resource references resolve to absolute paths at tool-call time; pass that absolute path here.",{flag:"--contract",given:e});try{i=JSON.parse(r(e,"utf8"))}catch(t){ys("E_FILE_PARSE",`failed to read --contract ${e}: ${t instanceof Error?t.message:String(t)}`,void 0,{flag:"--contract",given:e})}const n=(i.slots??{})[t],o={},a=c(u(e),".."),s=new Set;n?.schema_ref&&s.add(n.schema_ref);for(const e of s){const t=d(e)?e:c(a,e);try{o[e]=JSON.parse(r(t,"utf8"))}catch(i){ys("E_FILE_PARSE",`failed to read schema_ref ${e} (resolved ${t}): ${i instanceof Error?i.message:String(i)}`,void 0,{schema_ref:e})}}return{contract:i,schemas:o}}function cl(e){return`${JSON.stringify(e)}\n`}async function dl(e,t){const i=ya(t);if(i.sandbox)return{exitCode:0,stdout:cl({ok:!0,logged_in:!0,mode:"sandbox",sandbox_flavors:i.flavors,hint:"already authenticated with sandbox-injected credentials; `login` is a no-op here. byoa login is only for running dl/ilands on your own machine."})};const n=function(e){const t={},i=new Set,n=new Set(["--client-id","--issuer","--gateway","--timeout-seconds"]),o=new Set(["--no-browser"]);for(let r=0;r<e.length;r++){const a=e[r];if(void 0===a)break;const s=a.indexOf("="),l=s>=0?a.slice(0,s):a;if(o.has(l)){if(s>=0)return{error:`${l} does not take a value`};i.add(l);continue}if(!n.has(l))return{error:`unknown flag: ${l}`};const c=s>=0?a.slice(s+1):e[++r];if(void 0===c)return{error:`${l} requires a value`};t[l]=c}return{values:t,booleans:i}}(e);if("error"in n)return{exitCode:2,stderr:cl({ok:!1,code:"E_UNKNOWN_OPTION",message:n.error})};const o=n.values["--client-id"]?.trim()||(t.ILANDS_OAUTH_CLIENT_ID??"").trim()||"fIQZIN6q7FhwiF4z",r=n.values["--issuer"]?.trim()||(t.ILANDS_OAUTH_ISSUER??"").trim()||"https://clerk.ilands.ai",a=n.values["--gateway"]?.trim()||(t.ILANDS_GATEWAY_URL??"").trim()||void 0,s=Number(n.values["--timeout-seconds"]??""),l=n.booleans.has("--no-browser");try{const e=await async function(e){const{verifier:t,challenge:i}=function(){const e=Gr(_(48));return{verifier:e,challenge:Gr(w("sha256").update(e).digest())}}(),n=Gr(_(16)),o=e.timeoutMs??18e4,{server:r,redirectUri:a,result:s}=await function(e,t){return new Promise((i,n)=>{let o=null,r=null;const a=new Promise((e,t)=>{o=e,r=t}),s=x((t,i)=>{const n=new URL(t.url??"/","http://127.0.0.1");if("/callback"!==n.pathname)return void i.writeHead(404).end("not found");const a=n.searchParams.get("error"),s=n.searchParams.get("code"),l=n.searchParams.get("state"),c=(e,t)=>{i.writeHead(e,{"content-type":"text/html; charset=utf-8"}).end(t)};return a?(c(200,"<h3>Login failed — you can close this window.</h3>"),void r?.(new Kr(`authorization was denied: ${a}`))):s&&l===e?(c(200,"<h3>✅ Logged in to ilands — you can close this window.</h3>"),void o?.({code:s})):(c(400,"<h3>Invalid callback — you can close this window.</h3>"),void r?.(new Kr("callback missing code or state mismatch")))});setTimeout(()=>{r?.(new Kr(`login timed out after ${Math.round(t/1e3)}s`))},t).unref(),s.on("error",n),s.listen(0,"127.0.0.1",()=>{const e=s.address();i({server:s,redirectUri:`http://127.0.0.1:${e.port}/callback`,result:a})})})}(n,o);try{const o=function(e){const t=new URLSearchParams({response_type:"code",client_id:e.clientId,redirect_uri:e.redirectUri,scope:"profile email offline_access",state:e.state,code_challenge:e.challenge,code_challenge_method:"S256"});return`${Yr(e.issuer)}/oauth/authorize?${t.toString()}`}({issuer:e.issuer,clientId:e.clientId,redirectUri:a,challenge:i,state:n});e.onAuthorizeUrl?await e.onAuthorizeUrl(o):function(e){try{const[t,i]="darwin"===process.platform?["open",[e]]:"win32"===process.platform?["cmd",["/c","start","",e]]:["xdg-open",[e]];return g(t,i,{stdio:"ignore",detached:!0}).unref(),!0}catch{return!1}}(o)||process.stderr.write(`open this URL in your browser to continue:\n${o}\n`);const{code:r}=await s,l=await async function(e){return Wr(`${Yr(e.issuer)}/oauth/token`,{grant_type:"authorization_code",code:e.code,redirect_uri:e.redirectUri,client_id:e.clientId,code_verifier:e.verifier},e.fetchImpl??fetch)}({issuer:e.issuer,clientId:e.clientId,code:r,redirectUri:a,verifier:t,fetchImpl:e.fetchImpl}),c=await async function(e){const t=e.fetchImpl??fetch,i=await t(`${Yr(e.issuer)}/oauth/userinfo`,{headers:{Authorization:`Bearer ${e.accessToken}`}});if(!i.ok)throw new Kr(`userinfo endpoint returned ${i.status}`);const n=await i.json(),o="string"==typeof n.user_id&&n.user_id||"string"==typeof n.sub&&n.sub||"";if(!o)throw new Kr("userinfo response has no user id (sub/user_id)");const r="string"==typeof n.name&&n.name.trim()||[n.given_name,n.family_name].filter(e=>"string"==typeof e&&!!e.trim()).join(" ")||void 0,a="string"==typeof n.email&&n.email.trim()?n.email:void 0;return{id:o,...r?{name:r}:{},...a?{email:a}:{}}}({issuer:e.issuer,accessToken:l.access_token,fetchImpl:e.fetchImpl});return{version:1,issuer:Yr(e.issuer),client_id:e.clientId,access_token:l.access_token,...l.refresh_token?{refresh_token:l.refresh_token}:{},expires_at:Math.floor(Date.now()/1e3)+(l.expires_in??3600),user:c,...e.gatewayUrl?{gateway_url:Yr(e.gatewayUrl)}:{}}}finally{r.close()}}({issuer:r,clientId:o,...a?{gatewayUrl:a}:{},...Number.isFinite(s)&&s>0?{timeoutMs:1e3*s}:{},...l?{onAuthorizeUrl:e=>{process.stderr.write(`open this URL in your browser to continue:\n${e}\n`)}}:{}}),i=ua(e,t);return{exitCode:0,stdout:cl({ok:!0,logged_in:!0,user:e.user,issuer:e.issuer,gateway_url:e.gateway_url??pa,access_token_expires_at:e.expires_at,credential_store:i,hint:"both `ilands` and `dl` now use this login (shared credential store)."})}}catch(e){const t=e instanceof Error?e.message:String(e),i=e instanceof Error&&"hint"in e?e.hint:void 0;return{exitCode:1,stderr:cl({ok:!1,code:"E_BACKEND",message:`login failed: ${t}`,...i?{hint:i}:{}})}}}function ul(e){e.stdout&&process.stdout.write(e.stdout),e.stderr&&process.stderr.write(e.stderr),process.exit(e.exitCode)}const pl=wo({});function ml(e,t){return{source:"dl",event:"shot_detect",credits:50,command:t.command,action:t.action??"detect_shots",details:{rule:"detect-shots.fixed"}}}const hl=wo({});function fl(e,t){return{source:"dl",event:"download_media",credits:5,command:t.command,action:t.action??"download_media",details:{rule:"download-media.fixed"}}}wo({mode:Oo(["text","markdown","raw"])});const gl=Ho.pick({service:!0}),vl={"banana-pro":150,"banana-2":100,seedream:50,"seedream-5-lte":50,"gpt-image-2":75};function yl(e,t){const i=e.service||"seedream";return{source:"dl",event:"image_generate",credits:vl[i],command:t.command,action:t.action??"generate_image",details:{service:e.service,billable_service:i,rule:"generate-image.service.fixed"}}}const bl=Yo.pick({service:!0}),_l={"suno-v5":100,"suno-v5_5":100,minimax:200};function wl(e,t){return{source:"dl",event:"music_generate",credits:_l[e.service],command:t.command,action:t.action??"generate_music",details:{service:e.service,billable_service:e.service,rule:"generate-music.service.fixed"}}}const kl=Zo.pick({text:!0,service:!0});function xl(e,t){const i=e.text.length>0?e.text.length:100;return{source:"dl",event:"tts_generate",credits:Math.max(1,Math.ceil(i/40)),command:t.command,action:t.action??"generate_tts",details:{service:e.service,text_length:e.text.length,billable_characters:i,chars_per_credit:40,rule:"generate-tts.text-length"}}}const Sl="dlim2v",El=Jo.pick({service:!0,duration:!0,resolution:!0}),Ol={"seedance-2-0":{"480p":70,"720p":150,"1080p":360,"4k":720},"seedance-2-0-fast":{"480p":55,"720p":120,"1080p":null,"4k":null},"seedance-2-0-mini":{"480p":35,"720p":75,"1080p":null,"4k":null},"kling-o3-ref2v":{"480p":50,"720p":120,"1080p":300},"kling-o3-pro-ref2v":{"480p":65,"720p":130,"1080p":240},"kling-o3-v2v":{"480p":50,"720p":100,"1080p":300},"kling-o3-pro-v2v":{"480p":65,"720p":130,"1080p":240},"seedance-1-5":{"720p":60,"1080p":120},dli2v3:{_default:30,"720p":30,"1080p":60},dlai2v_pro:{"720p":70,"1080p":200},dlai2v_pro_multiframe:{"720p":70,"1080p":200},"kling3.0":{"720p":100,"1080p":200},dlai2v:{_default:50},dlim2v:{_default:50},"happyhorse-1-0-i2v":{_default:150},"happyhorse-1-0-r2v":{_default:150},"happyhorse-1-0-video-edit":{_default:150},"gemini-omni-video":{"480p":null,"720p":50,"1080p":150,"4k":300},"grok-imagine-1.5":{"480p":50,"720p":80},"longcat-avatar-1-5":{_default:100}};function Tl(e,t){const{billableService:i,pricedResolution:n,rate:o}=function(e,t){const i=Ol[e]??Ol[Sl],n=Ol[e]?e:Sl,o=function(e){const t=e?.trim().toLowerCase();return"480p"===t||"720p"===t||"1080p"===t||"4k"===t?t:null}(t);if(o){const e=i?.[o];if(void 0!==e)return{billableService:n,pricedResolution:o,rate:Al(e,n,o)}}return void 0!==i?._default?{billableService:n,pricedResolution:"_default",rate:Al(i._default,n,"_default")}:void 0!==i?.["720p"]?{billableService:n,pricedResolution:"720p",rate:Al(i["720p"],n,"720p")}:{billableService:Sl,pricedResolution:"_default",rate:50}}(e.service,e.resolution),r=function(e,t){if("number"!=typeof t||!Number.isFinite(t)||t<=0)return 8;if("seedance-2-0-mini"===e&&(t<5||t>12))throw new wa("E_SCHEMA","--duration must be between 5 and 12 for seedance-2-0-mini","Seedance 2.0 Mini supports 5-12s for text-to-video. Pick an integer duration in that range, then trim the final segment after generation if needed.",{service:e,flag:"--duration"});return t}(e.service,e.duration);return{source:"dl",event:"video_generate",credits:Math.ceil(o*r),command:t.command,action:t.action??"generate_video",details:{service:e.service,billable_service:i,resolution:e.resolution,priced_resolution:n,duration_seconds:e.duration,billable_duration_seconds:r,rate_credits_per_second:o,rule:"generate-video.service-resolution.duration"}}}function Al(e,t,i){if(null!==e)return e;throw new wa("E_SCHEMA",`generate-video pricing is not defined for service '${t}' at '${i}'`,"Pick a priced service/resolution from docs/billing/billing-pricing.md before submitting the job.",{service:t,resolution:i,pricing_status:"unpriced"})}const $l=wo({mode:Oo(["forward","reverse"])});function Nl(e,t){return{source:"dl",event:"geocode",credits:5,command:t.command,action:t.action??"geocode",details:{rule:"geocode.fixed",mode:e.mode}}}wo({});const jl=Ko.pick({service:!0,duration:!0,resolution:!0}),Cl={dlai2v_pro:{"720p":70,"1080p":200},dlai2v_pro_multiframe:{"720p":70,"1080p":200},dlai2v:{_default:null},"longcat-avatar":{_default:100}};function Il(e,t){const{pricedResolution:i,rate:n}=function(e,t){const i=Cl[e],n=function(e){const t=e?.trim().toLowerCase();return"480p"===t||"720p"===t||"1080p"===t?t:null}(t);if(n){const t=i?.[n];if(void 0!==t)return{pricedResolution:n,rate:Rl(t,e,n)}}return void 0!==i?._default?{pricedResolution:"_default",rate:Rl(i._default,e,"_default")}:void 0!==i?.["720p"]?{pricedResolution:"720p",rate:Rl(i["720p"],e,"720p")}:{pricedResolution:"_default",rate:190}}(e.service,e.resolution),o=function(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?e:8}(e.duration);return{source:"dl",event:"lipsync_generate",credits:Math.ceil(n*o),command:t.command,action:t.action??"lipsync",details:{service:e.service,resolution:e.resolution,priced_resolution:i,duration_seconds:e.duration,billable_duration_seconds:o,rate_credits_per_second:n,rule:"lipsync.service-resolution.duration"}}}function Rl(e,t,i){if(null!==e)return e;throw new wa("E_SCHEMA",`lipsync pricing is not defined for service '${t}' at '${i}'`,"Pick a priced service/resolution from docs/billing/billing-pricing.md before submitting the job.",{service:t,resolution:i,pricing_status:"unpriced"})}const ql=wo({service:Oo(["dreamactor","kling3.0-motion"]),tier:Oo(["pro","std"]).optional(),duration:co().int().min(1).optional()});function Pl(e,t){const{pricedTier:i,rate:n}=(r=e.service,a=e.tier,"dreamactor"===r?{pricedTier:"_default",rate:60}:"kling3.0-motion"===r?"std"===a?{pricedTier:"std",rate:100}:{pricedTier:"pro",rate:200}:{pricedTier:"_default",rate:100}),o=function(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?e:10}(e.duration);var r,a;return{source:"dl",event:"motion_control_generate",credits:Math.ceil(n*o),command:t.command,action:t.action??"motion_control",details:{service:e.service,tier:e.tier,priced_tier:i,duration_seconds:e.duration,billable_duration_seconds:o,rate_credits_per_second:n,rule:"motion-control.service-tier.duration"}}}const Ll=wo({});function zl(e,t){return{source:"dl",event:"places",credits:20,command:t.command,action:t.action??"place_photo",details:{rule:"places.fixed",subcommand:"photo"}}}const Ml=wo({});function Ul(e,t){return{source:"dl",event:"places",credits:20,command:t.command,action:t.action??"places_search",details:{rule:"places.fixed",subcommand:"search"}}}wo({});const Fl=wo({});function Dl(e,t){return{source:"dl",event:"render_caption",credits:50,command:t.command,action:t.action??"render_caption",details:{rule:"render-caption.fixed"}}}wo({provider:Oo(["baidu","baidu-image","serper","tavily","brave"])});const Hl=wo({});function Bl(e,t){return{source:"dl",event:"static_map",credits:5,command:t.command,action:t.action??"static_map",details:{rule:"static-map.fixed"}}}wo({provider:Fn().min(1),native_id:Fn().min(1)}),wo({type:Oo(["image","video"]),mode:Oo(["fallback","fanout"]),limit:co().int().min(1).max(30),providers:bo(Fn().min(1)).min(1)});const Vl=wo({});function Jl(e,t){return{source:"dl",event:"streetview",credits:10,command:t.command,action:t.action??"streetview_image",details:{rule:"streetview.fixed",subcommand:"image"}}}const Kl=wo({});function Gl(e,t){return{source:"dl",event:"streetview",credits:10,command:t.command,action:t.action??"streetview_metadata",details:{rule:"streetview.fixed",subcommand:"metadata"}}}const Yl=wo({});function Wl(e,t){return{source:"dl",event:"audio_transcribe",credits:50,command:t.command,action:t.action??"transcribe",details:{rule:"transcribe.fixed"}}}const Zl=["text","markdown","raw"];function Xl(e){const t=Number(e);if(!Number.isFinite(t)||!Number.isInteger(t)||t<7e3||t>12e4)throw new Error(`--timeout-ms must be an integer between 7000 and 120000, got ${e}`);return t}function Ql(e,t){const i=e[t];return"string"==typeof i&&""!==i.trim()?i.trim():void 0}const ec="按特征选路由: ffprobe / -c copy / 简单 trim 用本地 ffmpeg; -c:v 重编码 / filter_complex / 输入 >2min 走 dl ffmpeg; >5min 编码加 --async 走 callback。";function tc(e){return e?`${e}; ${ec}`:ec}const ic=["img_url","image","image_urls"];function nc(e){return Array.isArray(e)?e.length>0:"string"==typeof e?e.trim().length>0:null!=e}function oc(e){const t=ic.filter(t=>nc(e[t]));if(t.length>0)throw new wa("E_SCHEMA","`generate-image-prompt` does not accept reference image fields.","Use `dl generate-image-ref` when a source/reference image is required.",{fields:t});return e}function rc(e){if(!function(e){return ic.some(t=>nc(e[t]))}(e))throw new wa("E_SCHEMA","`generate-image-ref` requires at least one reference image.","Pass `--img-url` or `--image-urls`; use `dl generate-image-prompt` for prompt-only generation.",{required_one_of:ic})}function ac(e){return"string"==typeof e&&e.trim().length>0?[e]:Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.trim().length>0):[]}function sc(e,t,i){const n="ref"===i;Ps(e,{verb:t,actionName:"generate_image",schema:n?Vo:Bo,billing:{schema:gl,select:e=>({service:e.service}),quote:yl},preflight:n?rc:void 0,transformParams:n?void 0:oc,approvalPreview:e=>function(e,t){const i=(n=[...ac(t.img_url),...ac(t.image),...ac(t.image_urls)],[...new Set(n)]);var n;const o=[];"string"==typeof t.service&&o.push({label:"Service",value:t.service}),"string"==typeof t.aspect_ratio&&o.push({label:"Aspect ratio",value:t.aspect_ratio});const r="string"==typeof t.image_size?t.image_size:t.size;return"string"==typeof r&&o.push({label:"Image size",value:r}),{kind:"generate_image",title:"ref"===e?"Image generation with references":"Image generation",sections:[{type:"text",title:"Prompt",value:"string"==typeof t.prompt?t.prompt:"",display:"prewrap"},...i.length>0?[{type:"media",title:"Reference images",items:i.map((e,t)=>({kind:"image",url:e,label:`Reference ${t+1}`}))}]:[],...o.length>0?[{type:"kv",title:"Details",items:o}]:[]]}}(i,e),strictBatchParams:!0,supportsBatch:!0,description:n?"Generate or edit a still image from required source/reference image URL(s).":"Generate a still image from a text prompt only; reference image inputs are rejected.",notes:n?["`--img-url` (repeatable) is the canonical i2i input; `--image-urls` is its array-form alias.","`--image` is a legacy alias for `--img-url` — prefer `--img-url` in new calls."]:["This command is prompt-only and does not expose reference image flags.","If the task says use/keep/match a photo, same person, likeness, outfit, style image, or source image, use `dl generate-image-ref` instead."],whenToUse:n?["You need to edit an existing image (i2i)","You need a character reference sheet, likeness, outfit transfer, style/scene composition, or any output grounded in uploaded/source images","Multi-reference composition — pass `--img-url` repeatedly or use `--image-urls`"]:["You need a still image from text only","No user/source/reference image is part of the generation contract","Multi-aspect-ratio fan-out for prompt-only jobs"],whenNotToUse:n?["You need a prompt-only image with no source/reference images — use `dl generate-image-prompt`","You need a video — use `dl generate-video`","You need style-reference search before generating — use `dl knowledge search --domain=visual_style` first"]:["The user said use this picture/photo/image, make it look like me, keep the same person, match this outfit, or preserve identity/likeness — use `dl generate-image-ref`","You need a video — use `dl generate-video`","You need style-reference search before generating — use `dl knowledge search --domain=visual_style` first"],examples:[{caption:"single, banana-2 (newest in banana family, faster + better)",command:'dl generate-image-prompt \\\n --service=banana-2 \\\n --prompt="a corgi astronaut floating above earth, cinematic light" \\\n --aspect-ratio=16:9 \\\n --image-size=2K'},{caption:"i2i with multiple reference images",command:'dl generate-image-ref \\\n --service=gpt-image-2 \\\n --prompt="merge: subject from img1 in the setting of img2" \\\n --img-url="https://1.png" \\\n --img-url="https://2.png"'},{caption:"batch via stdin",command:'cat <<EOF | dl generate-image-prompt --jobs-file=-\n[\n {"job_key":"keyframe_01","service":"banana-2","prompt":"opening shot, dawn","aspect_ratio":"16:9"},\n {"job_key":"keyframe_02","service":"banana-2","prompt":"crescendo, fireworks","aspect_ratio":"16:9"}\n]\nEOF'}],notExamples:[{command:'dl generate-image-prompt --params=\'{"service":"banana-pro"}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"url":"https://storage.../image.png","width":1920,"height":1080}}',outputBatch:'{"ok":true,"action":"generate_image","results":[\n {"job_key":"keyframe_01","job_ref":"<uuid>","status":"pending"},\n ...\n]} // batch is non-blocking; each completed job is pushed back to the session via [async-callback]',modelTopic:{rankingSummary:["Overall quality ranking (strongest to weakest): gpt-image-2 > banana-2 > banana-pro > seedream-5-lte / seedream.",'Higher rank does NOT mean "better in every scenario" — it means "stronger on the combined axes of','photorealism + text rendering + instruction following + multi-image composition". For specific scenarios pick by the SERVICES table + DECISION LOGIC below.',"Service-name ↔ model-name mapping: banana-pro = nano-banana-pro (Imagen3 series, older / cheaper / slower), banana-2 = nano-banana-2 (Imagen4 4K, newest generation — materially faster AND higher quality than banana-pro; default first choice within the banana family)."],services:[{service:"gpt-image-2",label:"OpenAI GPT-Image-2",tier:"🥇 #1 Overall strongest",bestFor:"Overall strongest. The only reliable choice for precise text rendering, the only instruction-driven editor, and the only multi-image compositor (up to 16 reference images). Expensive and slow — use only when these exclusive capabilities are needed",quality:"Very High",speed:"10s-2min",cost:"high",description:["OpenAI GPT-Image-2 is exposed through the api-layer. Overall quality is strongest + 3 exclusive capabilities (","text rendering / instruction edit / multi-image composition, up to 16 refs).","The api-layer auto-routes to the backend that precisely honors the passed field: passing","`aspect_ratio` routes to a backend that natively honors `aspect_ratio`; passing a `size` pixel string","(`1024*1536`) triggers a backend that precisely honors `size`. Callers do not pick the vendor manually."],promptTips:['To render text you must use quotes: `the word "HELLO" in chrome letters` — this is one of the few models that can render text reliably','For edits, use the "keep X, change Y" framing rather than just describing the target','For multi-image composition, number them in prose: "the subject in image 1", "the background in image 2"',"Prefer full natural-language descriptions, not keyword soup","When using a `search-visual-style` hit as style ref: take the `prompt_gpt` field (gpt-image-2 specific variant), not `prompt` — `prompt` is for other services (banana / seedream etc.)."],constraints:["Expensive + slow (10s-2min); only use when you need the 3 exclusive capabilities","At most 16 reference images (via --image-urls)"],flagSubset:["service","prompt","img-url","image-urls","aspect-ratio","size","nsfw-checker"],examples:[{caption:"text-in-image",command:`dl ${t} --service=gpt-image-2 \\\n --prompt='A minimalist poster: the bold word "KAIROS" centered, off-white paper background, subtle grain, Helvetica Bold'`},{caption:"multi-image edit",command:'dl generate-image-ref --service=gpt-image-2 \\\n --prompt="Place the product from image 1 onto the desk in image 2, match the lighting of image 2" \\\n --image-urls=https://.../product.jpg \\\n --image-urls=https://.../scene.jpg'}]},{service:"banana-2",label:"Imagen4 4K (nano-banana-2) — newest, faster + stronger than banana-pro",tier:"🥈 #2",bestFor:"Overall quality runner-up to gpt-image-2 AND faster + higher quality than banana-pro. Imagen4 4K (nano-banana-2), the newest generation in the banana family. Default first choice within the banana family unless explicit cost-saving",quality:"Very High",speed:"10-60s (materially faster than banana-pro)",cost:"high",description:["Google Imagen4 4K family (nano-banana-2). The newest banana generation: BOTH faster AND clearly stronger overall","quality than banana-pro (Imagen3). Cost is higher than banana-pro but typically worth it given the speed + quality","win. Use this as the default within the banana family; drop to banana-pro only when cost-saving is explicit."],flagSubset:["service","prompt","aspect-ratio","image-size","img-url"],examples:[{caption:"single, banana-2 (newest, faster + better)",command:`dl ${t} --service=banana-2 \\\n --prompt="cinematic photo: a mountaineer at dawn on a glacier, ultra-detailed" \\\n --aspect-ratio=3:4 \\\n --image-size=2K`}]},{service:"banana-pro",label:"Imagen3 2K (nano-banana-pro) — older, cheaper, slower",tier:"🥉 #3",bestFor:"Imagen3 family (nano-banana-pro), up to 2K. One generation OLDER than banana-2: cheaper but slower and lower quality. Drop to this tier only when cost-saving is explicit",quality:"High",speed:"30s-3min (slower than banana-2)",cost:"low",description:["Google Imagen3 family (nano-banana-pro). The cheap-and-slow version of banana-2 — one generation older,","both slower and one quality tier below. Pick it only when cost-saving is explicit; banana-2 is the default","banana choice otherwise."],flagSubset:["service","prompt","aspect-ratio","image-size","img-url"],examples:[{caption:"single, banana-pro (cost-saving fallback)",command:`dl ${t} --service=banana-pro \\\n --prompt="a corgi astronaut floating above earth, cinematic light" \\\n --aspect-ratio=16:9 \\\n --image-size=2K`}]},{service:"seedream-5-lte",label:"ByteDance Seedream 5.0",tier:"4",bestFor:"Below the 3 overall tiers above. ByteDance Seedream 5.0, fast (10-30s), usable for general scenarios but overall not as strong as the banana family",quality:"Very High",speed:"10-30s",cost:"low",description:["ByteDance Seedream 5.0. Fast and cheap, overall below the banana family but renders in 10-30s."],flagSubset:["service","prompt","model","size","image"],examples:[{caption:"single, seedream-5-lte",command:`dl ${t} --service=seedream-5-lte \\\n --prompt="风格化插画:一只穿越赛博朋克城市的猫" \\\n --size=1:1`}]},{service:"seedream",label:"Seedream 4.5",tier:"5",bestFor:"Weakest overall tier. Seedream 4.5 — historically strong on Asian aesthetic / Asian-face portraits / marketing imagery, but overall quality is below the four above",quality:"High",speed:"10-30s",cost:"low",description:["ByteDance Seedream 4.5. Historically strong on Asian aesthetic / Asian-face portraits / Chinese marketing imagery;","overall quality is below the top 4 tiers but performs more reliably in these specialized scenarios."],flagSubset:["service","prompt","model","size","image"],examples:[{caption:"single, seedream",command:`dl ${t} --service=seedream \\\n --prompt="温暖光感的亚洲女性肖像,中景,白底" \\\n --model=seedream-4-5-251128 \\\n --size=3:4`}]}],decisionLogic:[{when:"No special user requirements / default case",pick:"gpt-image-2 (overall strongest, first choice)"},{when:"gpt-image-2 is too expensive / too slow and you don't need its exclusive capabilities",pick:"banana-2 (overall runner-up, Imagen4 4K / nano-banana-2, newest banana generation)"},{when:"Must render text — logo / tagline / UI text",pick:"gpt-image-2 (exclusively reliable)"},{when:'Must do instruction-driven edits ("keep the person, swap background to...")',pick:"gpt-image-2 (exclusive)"},{when:"Must do multi-image composition (place an object from image A into the scene of image B)",pick:"gpt-image-2 (exclusive, 16 refs)"},{when:"Explicit 4K / high-resolution / strong photorealism need, and no need for gpt-image-2 exclusives",pick:"banana-2"},{when:"Explicit cost-saving / general scenario can accept one generation lower",pick:"banana-pro (cheap version, Imagen3 2K / nano-banana-pro)"},{when:"Specialized Asian-face portraits / Chinese marketing imagery",pick:"seedream (historical strength)"},{when:"Need a fast preview (10-30s)",pick:"seedream-5-lte or seedream"}]},preflightTopic:{intro:`Before the first \`dl ${t}\` call, the following four decisions must be explicit (for the per-service flag shape see \`dl ${t} model <service>\` — positional; \`model -h <service>\` short-circuits to the overview):`,decisions:[{name:"Service / model family",description:`Which service to use. Decide per the SERVICES table + DECISION LOGIC in \`dl ${t} model -h\` (overview), or \`dl ${t} model <service>\` (per-service profile).`},{name:"Aspect ratio / size dimension",description:`Ratio / pixel string / resolution tier use different fields across services (the FLAG SUBSET in \`dl ${t} model <service>\`\nexposes them explicitly); you only need to decide the target ratio + target resolution tier, leave the field mapping to --help.`},{name:"Reference-input plan",description:"Whether reference images are needed, which URLs go in, and whether you need multi-reference / instruction-driven\nedit / multi-image composition (only the latter two are reliable on gpt-image-2)."},{name:"Generation count / budget sensitivity",description:"Single image or batch, batch cap, and whether the user asked for a lower-cost service."}],notes:["If cost-sensitive or unsure about service choice, read `pricing-and-policies-dramaland-faq/SKILL.md` for a planning estimate before locking the package parameters","Do not submit until all four decisions are explicit — switching service later requires confirming the changed generation parameters"]},policyTopic:{intro:"Two classes of hard rules: external communication must not leak internal details (rule 1 below); generation parameters must be explicit before submit (rule 2 below).",rules:[{title:"1. ⚠ User-Facing Communication Rule — do not leak internal details",body:["Never surface internal infrastructure details to the end user:"," - any vendor / backend internal name"," - any USD / RMB price figure"," - any internal model code name (e.g. `nano-banana-pro`, `seedream-4-5-251128`)"," - any internal trace identifier: job_id / task_id / request_id /"," prompt_id / raw_task_id / or any other UUID / hex-form ID string"," (these are for debug, appear in the raw JSON returned by dl CLI; do not repeat them to the user)","","Applies to: generation-parameter ask cards / chat narration / progress messages / any user-visible string.","","When confirming generation parameters with the user, summarize **only**:"," - the service name (e.g. banana-pro, banana-2, gpt-image-2, seedream)"," - the user-meaningful constraint the user actually asked for"," (aspect ratio, count, edit vs. new, etc.)",' - the action ("Generate", "Edit")',"","✅ Good:",' - "确认生成一张 9:16 比例的图片(GPT-Image-2)?"',' - "Confirm: generate 1 image at 9:16 with gpt-image-2?"',"","❌ Bad (leaks internal info):",' - "将使用 GPT-Image-2 + Wavespeed 供应商,预计约 $0.10/张,确认开始生成吗?"',' - "Will route via internal_vendor_name (~$0.10), confirm?"',"","Do not put credit amounts, balances, spend, refunds, or billing approval into ask cards.","The app shows the exact credit cost and asks for confirmation immediately before the actual","generation starts. The pricing skill is only for budget planning estimates."]},{title:"2. Production Package Rule — do not call before parameters are explicit",body:["This verb's service / model family, aspect ratio / size, generation count (including","batch range), and reference image plan are all components of the generation package.",`Do not call \`dl ${t}\` before those parameters are explicit.`,"","Within the same parameter package you can batch-generate — do not block per-image.","Only re-ask when the package changes (switching service, changing size / ratio, increasing count,","fallback, regeneration, or replacing key inputs). Ask about the changed creative / technical","choice only, not credit consumption."]}]},compositionTopic:{intro:"This atomic skill only produces URLs; artifact / canvas registration and other downstream responsibilities are not this verb's job.",integrations:[{skill:"music-video reference-pack workflow",rule:["Keep every returned candidate URL in the upstream","`reference_list.ref_img_urls` array and choose `selected_url`","explicitly instead of discarding alternates."]},{skill:"full-song MV segment production",rule:["Image generation may also be used for segment-specific lip-sync","keyframe stills. Those stills should combine the segment's selected","character, location, and prop references into a front-facing","performance image that can drive lip-sync.","","Preserve the returned URLs in the downstream segment metadata or","generation notes so the lip-sync input can be audited. When a","composition workflow requires these stills, generate them before","the lip-sync call; do not let the raw character reference sheet","become the final lip-sync input."]},{skill:"right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs `dl artifact write` or `patch-json pi_media_log` on your behalf —","that is the composition layer's job. The upstream workflow (visual-production / music-video","composition) is responsible for placing the returned URL into its own artifact slot","(`reference_list.ref_img_urls` / `storyboard.references` etc.)."]}]},asyncTopic:{intro:[`\`dl ${t}\` by default returns { job_ref, status: "pending" } and exits immediately — do not poll.`,"Results are injected into the current session as `[async-callback] job=<ref>` text; during that window you can make","other tool calls, or simply end the turn and let the session sit idle until the callback arrives.","",'Only run `dl poll` separately when "the next step strictly requires the result"; the dl subcommand itself no longer supports',"`--wait` blocking."],resultShape:['{ "url": "https://storage.googleapis.com/.../image.png" }'],notes:["The URL field is the atomic skill's sole product handed up to the upper layer","The upstream workflow is responsible for placing this URL into its own artifact slot; the atomic skill no longer registers canvas on your behalf","⚠ This URL already lives on our GCS — feed it directly to downstream tools / artifacts; do NOT pass to upload_file (would re-host an identical blob under a different URL)."]},publishTopic:{intro:["After producing your image URL(s), call `publish_content` with","`presentation_family='text_image'` and the explicit media fields.",'See "Publishing Your Work / text_image" in your creation playbook for',"the full field mapping template."],fields:[{name:"presentation_family",value:"'text_image'"},{name:"media_urls.images[]",value:"<returned image URLs (preserve all candidates)>"},{name:"thumbnail_url",value:"media_urls.images[0]"},{name:"delivery_format",value:"'image'"},{name:"experience_format",value:"'passive_media'"}]}})}const lc=["minimax","elevenlabs","elevenlabs-dialogue","voxcpm"],cc={minimax:"generate_tts",elevenlabs:"generate_tts_elevenlabs","elevenlabs-dialogue":"generate_tts_dialogue",voxcpm:"generate_tts"};function dc(e){return"string"==typeof e&&e.trim().length>0?[e]:Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.trim().length>0):[]}function uc(e){return[...new Set(e)]}function pc(e){return"string"==typeof e&&e.trim().length>0?e:void 0}function mc(e,t,i,n){("string"==typeof i&&i.trim().length>0||"number"==typeof i&&Number.isFinite(i)||"boolean"==typeof i&&(i||n?.includeFalse))&&e.push({label:t,value:i})}function hc(e,t){return t.length>0?{type:"media",title:e,items:[...t]}:void 0}function fc(e,t){return t.length>0?{type:"kv",title:e,items:[...t]}:void 0}function gc(e,t){const i=pc(t);return i?{type:"text",title:e,value:i,display:"prewrap"}:void 0}function vc(e,t,i){return t.map((t,n)=>({kind:e,url:t,label:`${i} ${n+1}`}))}function yc(e){return Array.isArray(e)?e.flatMap((e,t)=>{const i=_c(e);if(!i)return[];const n=pc(i.image_url);if(!n)return[];const o=bc(i.frame_position)??bc(i.frame_ratio);return[{kind:"image",url:n,label:o?`Keyframe ${t+1} (${o})`:`Keyframe ${t+1}`}]}):[]}function bc(e){return"string"==typeof e&&e.trim().length>0?e:"number"==typeof e&&Number.isFinite(e)?String(e):void 0}function _c(e){if("string"==typeof e)try{return _c(JSON.parse(e))}catch{return}if("object"==typeof e&&null!==e&&!Array.isArray(e))return e}const wc="--refs-from";function kc(e){return null==e?[]:Array.isArray(e)?e.filter(e=>"string"==typeof e):"string"==typeof e?[e]:[]}function xc(e){const t=new Set,i=[];for(const n of e)t.has(n)||(t.add(n),i.push(n));return i}function Sc(e){return"seedance-2-0"===e||"seedance-2-0-fast"===e||"seedance-2-0-mini"===e}function Ec(e,t){vs(`dl ${e} is not implemented on pi yet`,t)}const Oc=["sfx","stinger","bgm","amb","audio_any","visual_style","voice","writing_plot","writing_character","writing_payoff","writing_conflict","writing_hook","writing_any","meme"],Tc=["elevenlabs","minimax"],Ac=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function $c(){const e=JSON.stringify({event:"hint",code:"ASYNC_DETACH",message:"dl poll is single-shot — never call it in a bash loop. Bash has a ~5min hard cap and the sandbox is reclaimed on inactivity, so wait loops die as 'sandbox not running' or 'terminated' before the callback arrives. End your turn; the callback re-spawns a fresh sandbox with [async-callback] when ready."});process.stderr.write(`${e}\n`)}const Nc=65536,jc="DL_BEGIN",Cc="DL_END";const Ic=["baidu","baidu-image","serper","tavily","brave"],Rc=new Set(["pd","pw","pm","py"]),qc=["web","image","video"],Pc=4194304;function Lc(e,t){return Math.min(t??10,{web:50,image:30,video:10}[e])}async function zc(e){const t=e.extra?.image;if(void 0!==t){if("string"!=typeof t||""===t.trim())throw new wa("E_SCHEMA","--params-file image must be a non-empty base64 string",void 0,{flag:"--params-file",expected:"object with image:string"});return t}if(!e.imageFile)throw new wa("E_SCHEMA","--image-file is required for provider=baidu-image",'pass a jpg/png file path, or pass {"image":"<base64>"} through --params-file',{flag:"--image-file",provider:"baidu-image"});const i=c(e.imageFile);let n;try{n=await O(i)}catch(t){const n=t instanceof Error?t.message:String(t);throw new wa("E_FILE_MISSING",`--image-file: cannot read file at ${i} (${n})`,"make sure the path exists in the sandbox",{flag:"--image-file",given:e.imageFile,resolved:i,cwd:process.cwd()})}if(0===n.byteLength)throw new wa("E_SCHEMA",`--image-file (${i}): expected non-empty jpg/png image`,void 0,{flag:"--image-file",resolved:i});if(n.byteLength>Pc)throw new wa("E_SCHEMA",`--image-file (${i}): image must be <= 4MB before base64 encoding`,void 0,{flag:"--image-file",resolved:i,max_bytes:Pc,bytes:n.byteLength});return n.toString("base64")}async function Mc(e,t,i){if("baidu"===e)return async function(e,t){const i=t.resourceType??"web",n={messages:[{role:"user",content:e}],search_source:"baidu_search_v2",resource_type_filter:[{type:i,top_k:Lc(i,t.k)}]};if(t.freshness){const e={pw:"week",pm:"month",py:"year"}[t.freshness];if(!e)throw new Error("--freshness=pd is not supported by baidu; use pw|pm|py or provider=brave");n.search_recency_filter=e}return t.extra&&Object.assign(n,t.extra),((await Da("search/baidu","v2/ai_search/web_search",n,{timeoutMs:2e4,retries:1,...t.billing?{billing:{jobRef:t.billing.jobRef,quote:t.billing.quote}}:{}})).references??[]).slice(0,t.k??10).map(e=>{const t=e.image?.width??e.video?.width,i=e.image?.height??e.video?.height;return{title:e.title??e.web_anchor??"",url:e.url??e.video?.url??e.image?.url??"",snippet:e.snippet??e.content??"",...e.date?{publishedAt:e.date}:{},...e.website?{source:e.website}:{},...e.type?{type:e.type}:{},...e.image?.url?{imageUrl:e.image.url}:{},...e.video?.url?{videoUrl:e.video.url}:{},...e.video?.hover_pic?{thumbnailUrl:e.video.hover_pic}:{},...void 0!==t?{width:t}:{},...void 0!==i?{height:i}:{},...void 0!==e.video?.duration?{duration:e.video.duration}:{},...void 0!==e.video?.size?{size:e.video.size}:{}}})}(t,i);if("baidu-image"===e)return async function(e){const t={image:await zc(e),count:Math.min(e.k??10,50)};if(e.extra)for(const[i,n]of Object.entries(e.extra))"image"!==i&&(t[i]=n);const i=await Da("search/baidu-image","v2/tools/image_similar_info",t,{timeoutMs:2e4,retries:1,...e.billing?{billing:{jobRef:e.billing.jobRef,quote:e.billing.quote}}:{}}),n=i.result?.res_data?.result_page;return(i.result?.res_data?.res_items??[]).slice(0,e.k??10).map(e=>({title:e.title??"",url:e.fromurl??e.detail_page??e.objurl??"",snippet:e.site_name??"",..."string"==typeof e.update_time||"number"==typeof e.update_time?{publishedAt:String(e.update_time)}:{},...e.site_name?{source:e.site_name}:{},...e.objurl?{imageUrl:e.objurl}:{},...e.result_page??n?{resultPage:e.result_page??n}:{},..."number"==typeof e.sim_level?{similarityLevel:e.sim_level}:{},...e.item_cate?{category:e.item_cate}:{},...void 0!==e.width?{width:e.width}:{},...void 0!==e.height?{height:e.height}:{}}))}(i);if("serper"===e)return async function(e,t){const i={q:e,num:t.k??10};if(t.country&&(i.gl=t.country),t.freshness){const e={pd:"qdr:d",pw:"qdr:w",pm:"qdr:m",py:"qdr:y"};i.tbs=e[t.freshness]??i.tbs}return t.extra&&Object.assign(i,t.extra),((await Da("search/serper","search",i,{timeoutMs:2e4,retries:1,...t.billing?{billing:{jobRef:t.billing.jobRef,quote:t.billing.quote}}:{}})).organic??[]).slice(0,t.k??10).map(e=>({title:e.title??"",url:e.link??"",snippet:e.snippet??"",...e.date?{publishedAt:e.date}:{},...e.source?{source:e.source}:{}}))}(t,i);if("tavily"===e)return async function(e,t){const i={query:e,max_results:t.k??10,search_depth:"basic"};if(t.freshness){const e={pd:"day",pw:"week",pm:"month",py:"year"};i.time_range=e[t.freshness]??i.time_range}return t.extra&&Object.assign(i,t.extra),((await Da("search/tavily","search",i,{timeoutMs:2e4,retries:1,...t.billing?{billing:{jobRef:t.billing.jobRef,quote:t.billing.quote}}:{}})).results??[]).slice(0,t.k??10).map(e=>({title:e.title??"",url:e.url??"",snippet:e.content??"",...e.published_date?{publishedAt:e.published_date}:{}}))}(t,i);if("brave"===e)return async function(e,t){const i={q:e,count:String(t.k??10)};if(t.country&&(i.country=t.country),t.freshness&&(i.freshness=t.freshness),t.extra)for(const[e,n]of Object.entries(t.extra))"string"!=typeof n&&"number"!=typeof n&&"boolean"!=typeof n||(i[e]=String(n));const n=await Ha("search/brave","res/v1/web/search",i,{timeoutMs:2e4,retries:1,headers:{Accept:"application/json"},...t.billing?{billing:{jobRef:t.billing.jobRef,quote:t.billing.quote}}:{}});return(n.web?.results??[]).slice(0,t.k??10).map(e=>({title:e.title??"",url:e.url??"",snippet:e.description??"",...e.age?{publishedAt:e.age}:{}}))}(t,i);throw new Error(`unsupported provider: ${e}`)}const Uc="acac8c8",Fc="@pawlogic/dl",Dc="/home/user/.local";async function Hc(e){const t=(process.env.CALLBACK_SERVER_URL??"").trim().replace(/\/+$/,""),i=(process.env.DL_PROXY_TOKEN??"").trim();if(!t||!i)return;const n="latest"===e.distTag||"staging"===e.distTag?e.distTag:"unknown",o=e=>{const t=(process.env[e]??"").trim();return t&&/^[A-Za-z0-9_-]+$/.test(t)?t:null},r=o("PI_PROJECT_ID"),a=o("PI_MODE"),s=o("PI_USER_TIER"),l=o("PI_USER_ID"),c=o("PI_PROMPT_ID"),d=o("PI_TOOL_CALL_ID"),u=(process.env.HOSTNAME??S.hostname()??"").trim(),p=u&&/^[A-Za-z0-9_-]+$/.test(u)?u:null,m=new AbortController,h=setTimeout(()=>m.abort(),2e3);try{await fetch(`${t}/sandbox-rpc/dl/selfupdate-event`,{method:"POST",signal:m.signal,headers:{"content-type":"application/json",authorization:`Bearer ${i}`},body:JSON.stringify({trigger:e.trigger,dist_tag:n,outcome:e.outcome,duration_ms:e.durationMs,installed_version:e.installedVersion,build_short_sha:e.buildShortSha,project_id:r,mode:a,user_tier:s,user_id:l,prompt_id:c,tool_call_id:d,sandbox_id:p})})}catch{}finally{clearTimeout(h)}}async function Bc(){const e=(process.env.CALLBACK_SERVER_URL??"").trim().replace(/\/+$/,"");if(!e)return null;const t=await async function(e){const t=new AbortController,i=setTimeout(()=>t.abort(),5e3);try{const i=await fetch(e,{signal:t.signal});return i.ok?(await i.text()).trim():null}catch{return null}finally{clearTimeout(i)}}(`${e}/health`);if(!t)return null;try{const e=JSON.parse(t),i=e.build_short_sha?.trim();return i&&/^[a-f0-9]{7}$/i.test(i)?i.slice(0,7):null}catch{return null}}function Vc(){for(const e of[`${Dc}/lib/node_modules/${Fc}/package.json`,`${Dc}/lib/node_modules/${Fc.replace("@pawlogic/","")}/package.json`])try{if(!o(e))continue;const t=JSON.parse(r(e,"utf8"));if("string"==typeof t.version&&t.version.trim())return t.version}catch{}try{const e=u(m(import.meta.url));for(const t of["../package.json","../../package.json","../../../package.json"]){const i=c(e,t);if(!o(i))continue;const n=JSON.parse(r(i,"utf8"));if(n.name===Fc&&"string"==typeof n.version)return n.version}}catch{}return null}async function Jc(){const e=(process.env.DL_NPM_DIST_TAG??"").trim()||null;return{dl_build_short_sha:Uc,dl_build_full_sha:"acac8c806e70c7f193f9d4aff1cf26af5ff788b7",npm_dist_tag:e,npm_installed_version:Vc(),callback_server_url:(process.env.CALLBACK_SERVER_URL??"").trim()||null,callback_build_short_sha:await Bc(),updated:!1,skipped_reason:null}}function Kc(e,t){const i=t.replace(/^\/+/,"");var n;n={use_tool:"read",skill:e,relative_path:i,hint:`Call the \`read\` tool with path \`dirname(<location of skill "${e}" in <available_skills>>) + "/${i}"\`.`},process.stdout.write(`${JSON.stringify({ok:!0,...n})}\n`),process.exit(0)}const Gc="/workspace/.stock-media",Yc=209715200,Wc=/^([a-z0-9_-]+):([a-zA-Z0-9_.-]+)$/,Zc=new Map([["image/jpeg","jpg"],["image/jpg","jpg"],["image/png","png"],["image/webp","webp"],["image/gif","gif"],["image/avif","avif"],["video/mp4","mp4"],["video/quicktime","mov"],["video/webm","webm"],["video/x-matroska","mkv"]]);class Xc extends Error{hint;constructor(e,t){super(e),this.hint=t,this.name="StockDownloadError"}}function Qc(e,t){const i=e&&e.length>0?e:t;return d(i)||vs(`--to must be an absolute path; got "${i}"`,"use an absolute /workspace/... path"),i.startsWith("/workspace/")||"/workspace"===i||vs(`--to must be under /workspace/; got "${i}"`,"stock-media downloads only target sandbox /workspace."),i}const ed={name:"openverse",supports:{image:!0,video:!1},async search(e){if("image"!==e.type)return[];const t={q:e.query,page_size:String(e.perProviderLimit)};"landscape"===e.orientation?t.aspect_ratio="wide":"portrait"===e.orientation?t.aspect_ratio="tall":"square"===e.orientation&&(t.aspect_ratio="square"),void 0!==e.minWidth&&(t.size="large");let i=((await Ha("stock-media/openverse","v1/images",t)).results??[]).map(e=>{const t=function(e,t,i){const n=e.toUpperCase(),o=t??"4.0";return{license:"CC0"===n?"CC0 1.0 (Public Domain)":`CC ${n} ${o}`,license_url:i??("CC0"===n?"https://creativecommons.org/publicdomain/zero/1.0/":`https://creativecommons.org/licenses/${e.toLowerCase()}/${o}/`),attribution_required:"CC0"!==n}}(e.license,e.license_version,e.license_url),i=e.creator??"Unknown";return{asset_id:`openverse:${e.id}`,provider:"openverse",type:"image",preview_url:e.thumbnail,download_url:e.url,dimensions:{width:e.width,height:e.height},duration:null,tags:(e.tags??[]).map(e=>e.name).filter(Boolean),author:i,author_url:e.creator_url??"",license:t.license,license_url:t.license_url,attribution_required:t.attribution_required,attribution_text:(n={title:e.title,creator:e.creator,license:t.license},`${n.title?`"${n.title}"`:"Image"}${n.creator?` by ${n.creator}`:""} (${n.license}) via Openverse`),source_url:e.foreign_landing_url??e.url};var n});return void 0!==e.minWidth&&(i=i.filter(t=>t.dimensions.width>=e.minWidth)),i}},td="Pexels License",id="https://www.pexels.com/license/";function nd(e,t){const i=e.filter(e=>"video/mp4"===e.file_type),n=i.length>0?i:e,o=t?n.filter(e=>e.width>=t):n;return(o.length>0?o:n).slice().sort((e,t)=>t.width-e.width)[0]??null}const od="Pixabay Content License",rd="https://pixabay.com/service/license-summary/";function ad(e){return e.split(",").map(e=>e.trim()).filter(e=>e.length>0)}function sd(e,t){const i=[e.large,e.medium,e.small,e.tiny].filter(e=>!!e&&!!e.url);if(0===i.length)return null;const n=t?i.filter(e=>e.width>=t):i;return(n.length>0?n:i).slice().sort((e,t)=>t.width-e.width)[0]??null}const ld={pexels:{name:"pexels",supports:{image:!0,video:!0},async search(e){const t={query:e.query,per_page:String(e.perProviderLimit)};if(e.orientation&&(t.orientation=e.orientation),"image"===e.type){let i=((await Ha("stock-media/pexels","v1/search",t)).photos??[]).map(e=>{const t=e.alt?e.alt.split(/[,\s]+/).filter(e=>e.length>1):[];return{asset_id:`pexels:${e.id}`,provider:"pexels",type:"image",preview_url:e.src.medium??e.src.small??e.src.tiny??e.src.original,download_url:e.src.original,dimensions:{width:e.width,height:e.height},duration:null,tags:t,author:e.photographer,author_url:e.photographer_url,license:td,license_url:id,attribution_required:!1,attribution_text:`Photo by ${e.photographer} on Pexels`,source_url:e.url}});return e.minWidth&&(i=i.filter(t=>t.dimensions.width>=e.minWidth)),i}let i=function(e,t){const i=e.videos??[],n=[];for(const e of i){const i=nd(e.video_files,t);i&&n.push({asset_id:`pexels:${e.id}`,provider:"pexels",type:"video",preview_url:e.image,download_url:i.link,dimensions:{width:i.width,height:i.height},duration:e.duration,tags:e.tags??[],author:e.user.name,author_url:e.user.url,license:td,license_url:id,attribution_required:!1,attribution_text:`Video by ${e.user.name} on Pexels`,source_url:e.url})}return n}(await Ha("stock-media/pexels","videos/search",t),e.minWidth);return void 0!==e.durationMin&&(i=i.filter(t=>(t.duration??0)>=e.durationMin)),void 0!==e.durationMax&&(i=i.filter(t=>(t.duration??0)<=e.durationMax)),i}},pixabay:{name:"pixabay",supports:{image:!0,video:!0},async search(e){const t={q:e.query,per_page:String(e.perProviderLimit)};if("landscape"===e.orientation?t.orientation="horizontal":"portrait"===e.orientation&&(t.orientation="vertical"),"image"===e.type)return t.image_type="photo",void 0!==e.minWidth&&(t.min_width=String(e.minWidth)),((await Ha("stock-media/pixabay","api",t)).hits??[]).map(e=>({asset_id:`pixabay:${e.id}`,provider:"pixabay",type:"image",preview_url:e.webformatURL??e.previewURL,download_url:e.largeImageURL??e.webformatURL,dimensions:{width:e.imageWidth,height:e.imageHeight},duration:null,tags:ad(e.tags),author:e.user,author_url:`https://pixabay.com/users/${encodeURIComponent(e.user)}/`,license:od,license_url:rd,attribution_required:!1,attribution_text:`Image by ${e.user} on Pixabay`,source_url:e.pageURL}));let i=function(e,t){const i=e.hits??[],n=[];for(const e of i){const i=sd(e.videos,t);i&&n.push({asset_id:`pixabay:${e.id}`,provider:"pixabay",type:"video",preview_url:e.picture_id?`https://i.vimeocdn.com/video/${e.picture_id}_640x360.jpg`:e.userImageURL,download_url:i.url,dimensions:{width:i.width,height:i.height},duration:e.duration,tags:ad(e.tags),author:e.user,author_url:`https://pixabay.com/users/${encodeURIComponent(e.user)}/`,license:od,license_url:rd,attribution_required:!1,attribution_text:`Video by ${e.user} on Pixabay`,source_url:e.pageURL})}return n}(await Ha("stock-media/pixabay","api/videos",t),e.minWidth);return void 0!==e.durationMin&&(i=i.filter(t=>(t.duration??0)>=e.durationMin)),void 0!==e.durationMax&&(i=i.filter(t=>(t.duration??0)<=e.durationMax)),i}},openverse:ed},cd=["pexels","pixabay","openverse"],dd=new Set(["landscape","portrait","square"]),ud=new Set(["image","video"]),pd=["fallback","fanout"];function md(e,t,i){const n=Number(e);return(!Number.isFinite(n)||!Number.isInteger(n)||n<1||n>i)&&vs(`${t} must be a positive integer ≤ ${i}; got ${e}`),n}function hd(e,t){const i=Number(e);return(!Number.isFinite(i)||i<0)&&vs(`${t} must be a non-negative number; got ${e}`),i}function fd(e,t){return t instanceof Sa?{provider:e,status:t.status,reason:`${t.status}: ${t.message}`}:t instanceof Jr?{provider:e,reason:`proxy-client: ${t.message}${t.hint?` (${t.hint})`:""}`}:t instanceof Error?{provider:e,reason:t.message}:{provider:e,reason:String(t)}}function gd(e,t){const i=[],n=new Set,o=e.map(()=>0);let r=e.filter(e=>e.length>0).length;for(;i.length<t&&r>0;){r=0;for(let a=0;a<e.length;a++){const s=e[a];if(o[a]<s.length){const e=s[o[a]];if(o[a]+=1,!n.has(e.asset_id)&&(n.add(e.asset_id),i.push(e),i.length>=t))break;o[a]<s.length&&(r+=1)}}}return i}const vd=(e,t)=>ld[e].search(t);async function yd(e){try{await Ua({jobRef:e.jobRef,quote:e.quote,reason:e.reason,chargeId:e.receipt.charge_id})}catch(t){process.stderr.write(`${JSON.stringify({level:"warn",event:"dl_billing_refund_failed",job_ref:e.jobRef,reason:e.reason,error:t instanceof Error?t.message:String(t)})}\n`)}}function bd(e,t){const i={};for(const t of["job_ref","task_id","data"])void 0!==e[t]&&(i[t]=e[t]);return void 0!==e.error&&null!==e.error&&(i.error=e.error),i}const _d=new oe;_d.name("dl").description(["DramaLand CLI","","Generation:"," lipsync transcribe generate-image-prompt generate-image-ref generate-video generate-music generate-sound generate-lyrics"," generate-tts analyze-beats render-caption motion-control detect-shots download-media","","Geo:"," geocode streetview <command> places <command> static-map","","Pipelines:"," ffmpeg remotion poll search stock <command> fetch","","Local:"," self-update script <command> skill <command>","","Resources:"," artifact <command> asset <command> knowledge <command>","","Batch: pass --jobs '<inline-json>' per verb (recommended; --jobs-file is legacy).","Run `dl <command> --help` for the full per-command shape.","","Output: JSON on stdout when ok, JSON {ok:false,code,error,hint?} on stderr on failure.","Codes: E_FILE_MISSING / E_FILE_PARSE / E_SCHEMA / E_UNKNOWN_OPTION (exit 2)"," E_INSUFFICIENT_CREDITS / E_BACKEND (exit 1)"].join("\n")).version(function(){try{const e=u(m(import.meta.url));for(const t of["./package.json","../package.json","../../package.json"])try{const i=JSON.parse(r(c(e,t),"utf8"));if("string"==typeof i.version&&i.version.trim())return`${i.version} (build ${Uc})`}catch{}}catch{}return`unknown (build ${Uc})`}()),function(e){e.command("login").description("Log in with your ilands account for local (non-sandbox) use — opens the browser (Clerk OAuth). No-op inside the hosted sandbox (credentials are already injected). Shared with the `ilands` bin.").option("--client-id <id>","OAuth client id (default: ILANDS_OAUTH_CLIENT_ID)").option("--issuer <url>","OAuth issuer (default: https://clerk.ilands.ai)").option("--gateway <url>","BYOA gateway base URL (stored with the login)").option("--timeout-seconds <n>","how long to wait for the browser callback (default 180)").option("--no-browser","print the authorize URL instead of opening a browser").action(async e=>{const t=[];e.clientId&&t.push(`--client-id=${e.clientId}`),e.issuer&&t.push(`--issuer=${e.issuer}`),e.gateway&&t.push(`--gateway=${e.gateway}`),e.timeoutSeconds&&t.push(`--timeout-seconds=${e.timeoutSeconds}`),!1===e.browser&&t.push("--no-browser"),ul(await dl(t,process.env))}),e.command("logout").description("Clear the stored local ilands login (both `dl` and `ilands`). No-op inside the hosted sandbox.").action(async()=>{ul(await async function(e,t){if(ya(t).sandbox)return{exitCode:0,stdout:cl({ok:!0,logged_out:!1,mode:"sandbox",hint:"running with sandbox-injected credentials; there is no byoa login to clear here."})};const i=null!==ca(t);return function(e=process.env){"darwin"===process.platform&&aa(),"linux"===process.platform&&ta("secret-tool")&&la(),function(e){try{a(ea(e),{force:!0})}catch{}}(e)}(t),{exitCode:0,stdout:cl({ok:!0,logged_in:!1,cleared:i})}}(0,process.env))}),e.command("whoami").description("Show the current credential mode (sandbox / byoa login / none).").action(async()=>{ul(await async function(e,t){const i=ya(t);if(i.sandbox)return{exitCode:0,stdout:cl({ok:!0,mode:"sandbox",sandbox_flavors:i.flavors,hint:"running with sandbox-injected credentials; byoa login is not used here."})};const n=ca(t);if(!n)return{exitCode:1,stderr:cl({ok:!1,logged_in:!1,message:"not logged in",hint:"run `ilands login` (or `dl login`)"})};const o=Math.floor(Date.now()/1e3);return{exitCode:0,stdout:cl({ok:!0,mode:"byoa",logged_in:!0,user:n.user,issuer:n.issuer,gateway_url:va(n,t),access_token_expires_at:n.expires_at,access_token_expired:n.expires_at<=o,has_refresh_token:!!n.refresh_token})}}(0,process.env))})}(_d),function(e){e.command("self-update").description("Reinstall @pawlogic/dl from npmjs.com. Shows dl build SHA vs live callback-server build SHA.").addHelpText("after",["","Sandbox 内部 dl 由 npm install -g --prefix=/home/user/.local @pawlogic/dl@<tag> 装出。","沙箱 wrapper `/usr/local/bin/dl` 每次调用前跑 dl-npm-update.sh(TTL 300s)。本命令绕开 TTL。","","DL_NPM_DIST_TAG env 由 template bake 时按 alias 注入:"," prod (pi-sandbox-dl) → latest"," staging (pi-sandbox-dl-staging) → staging"," PR preview (pi-sandbox-dl-pr-N) → 空 → 本命令 no-op,沙箱 dl 锁版","","CALLBACK_SERVER_URL 用于通过 GET /health 对账 dl ↔ callback-server 是否同 SHA。","","Flags:"," --check 不装,只打印当前状态 JSON"," --force 绕过 TTL 强制重装(默认行为也是绕过)"].join("\n")).option("--check","只打状态 JSON,不联 registry").option("--force","绕过 300s TTL 缓存(CLI 默认就绕)").action(async e=>{const t=e.check?await Jc():await async function(e={}){const t=await Jc(),i=e.force?"cli_force":"cli";if(!t.npm_dist_tag)return t.skipped_reason="DL_NPM_DIST_TAG unset (PR preview / local — no npm self-update)",await Hc({trigger:i,distTag:t.npm_dist_tag,outcome:"no_tag",durationMs:null,installedVersion:t.npm_installed_version,buildShortSha:"unknown"!==t.dl_build_short_sha?t.dl_build_short_sha:null}),t;const n=Date.now();let o="ok";try{const e=y("npm",["install","-g",`--prefix=${Dc}`,"--silent","--no-audit","--no-fund","--no-update-notifier","--force",`${Fc}@${t.npm_dist_tag}`],{env:{...process.env,HOME:"/home/user"},stdio:"pipe",timeout:3e4});if(0!==e.status)return t.skipped_reason=`npm install exit=${e.status??"signal"}: ${(e.stderr??Buffer.from("")).toString("utf8").slice(0,200)}`,o="SIGTERM"===e.signal?"timeout":"npm_fail",await Hc({trigger:i,distTag:t.npm_dist_tag,outcome:o,durationMs:Date.now()-n,installedVersion:t.npm_installed_version,buildShortSha:"unknown"!==t.dl_build_short_sha?t.dl_build_short_sha:null}),t}catch(e){return t.skipped_reason=`npm install threw: ${String(e).slice(0,200)}`,await Hc({trigger:i,distTag:t.npm_dist_tag,outcome:"npm_fail",durationMs:Date.now()-n,installedVersion:t.npm_installed_version,buildShortSha:"unknown"!==t.dl_build_short_sha?t.dl_build_short_sha:null}),t}try{v("sh",["-c","printf '%s' \"$(date +%s)\" > /tmp/dl-npm-checkedat"],{stdio:"ignore"})}catch{}try{v("ln",["-sf","/usr/local/bin/dl",`${Dc}/bin/dl`],{stdio:"ignore"})}catch{}return t.npm_installed_version=Vc(),t.updated=!0,t.skipped_reason=null,await Hc({trigger:i,distTag:t.npm_dist_tag,outcome:o,durationMs:Date.now()-n,installedVersion:t.npm_installed_version,buildShortSha:"unknown"!==t.dl_build_short_sha?t.dl_build_short_sha:null}),t}({force:e.force}),i="unknown"!==t.dl_build_short_sha&&null!==t.callback_build_short_sha&&t.dl_build_short_sha===t.callback_build_short_sha;gs({ok:!0,...t,build_short_sha_aligned_with_callback:i,hint:i?null:"dl build SHA 跟 live callback-server 的 build SHA 对不齐 —— 可能需要 staging-deploy(staging) 或 prod-deploy(latest) 把 dl 推到同一个 commit"})})}(_d),function(e){e.command("script").description("Local python3 sandbox — ulimit CPU seconds / 64 KiB output.").command("exec").description(["Run a python3 transform. --inputs-file keys are injected as top-level variables;","assign to `result` to return a value.",""," --script-file=<path|-> python source; `-` reads stdin (preferred for one-off scripts)."," --inputs-file=<path|-> JSON object whose keys become globals; `-` reads stdin.","","Example (script via stdin, inputs from disk):"," cat <<'PY' | dl script exec --script-file=- --inputs-file=/workspace/inputs.json --timeout=5"," result = sum(items)"," PY"].join("\n")).option("--script <text>",'RECOMMENDED: python source inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --script "$(cat script.py)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --script-file.').option("--script-file <path|->",'LEGACY: python source via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --script "$(cat file)". Use --script-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--inputs <inline-json>",'RECOMMENDED: JSON object whose keys become globals, inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --inputs "$(cat inputs.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --inputs-file.').option("--inputs-file <path|->",'LEGACY: JSON object whose keys become globals, via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --inputs "$(cat file)". Use --inputs-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--timeout <s>","CPU seconds (1–5, default 5)",e=>Number(e)).option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").action(async e=>{e.printSchema&&Js({command:"dl script exec",summary:"Run a python3 transform in the local sandbox; assign `result` to return a value.",scalars:[{name:"timeout",type:"integer",required:!1,description:"CPU seconds (1–5, default 5)"},{name:"script",type:"string",required:!1,description:"RECOMMENDED inline python source (required: pass this or --script-file)"},{name:"inputs",type:"string",required:!1,description:"RECOMMENDED inline JSON object whose keys become globals (sibling of --inputs-file)"}],files:[{name:"script-file",required:!1,kind:"text",description:"LEGACY: python source via file/stdin (prefer --script inline)",example:"result = sum(items)\n"},{name:"inputs-file",required:!1,kind:"object",description:"LEGACY: JSON object of globals via file/stdin (prefer --inputs inline)",example:'{"items":[1,2,3]}'}]});let t,i,n="",o={};e.script||e.scriptFile||ys("E_SCHEMA","--script is required (pass the python source inline, or use --script-file for the legacy file/stdin path)","run `dl script exec --print-schema` to see the expected shape",{flag:"--script"});try{const r=await hs(e.script?String(e.script):void 0,e.scriptFile?String(e.scriptFile):void 0,{inline:"--script",file:"--script-file"});r&&(n=r.raw,t=r.label);const a=await ms(e.inputs?String(e.inputs):void 0,e.inputsFile?String(e.inputsFile):void 0,{inline:"--inputs",file:"--inputs-file"});a&&(o=a.data,i=a.source.label)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:"script exec",script_source:t??null,inputs:o,inputs_source:i??null});const r=void 0!==e.timeout?Number(e.timeout):void 0,a=await async function(e,t={},i={}){const n=Date.now(),o=Math.max(1,Math.min(i.timeoutSeconds??5,5)),r=1e3*(o+1),a=`ulimit -t ${o} 2>/dev/null; ulimit -v 65536 2>/dev/null; exec python3 -I -c "$PY_SCRIPT"`,s={PY_SCRIPT:["import json as __dl_json","import sys as __dl_sys","__dl_inputs_raw = __dl_sys.stdin.read()","__dl_inputs = __dl_json.loads(__dl_inputs_raw) if __dl_inputs_raw else {}","for __dl_k, __dl_v in __dl_inputs.items():"," globals()[__dl_k] = __dl_v","__dl_input_keys = set(__dl_inputs.keys())","# --- user script ---",e,"# --- end user script ---","__dl_result = globals().get('result')","__dl_outputs = {}","for __dl_k, __dl_v in list(globals().items()):"," if __dl_k.startswith('_') or __dl_k == 'result':"," continue"," if __dl_k in __dl_input_keys:"," continue"," if __dl_k in ('json','sys') or callable(__dl_v) or isinstance(__dl_v, type):"," continue"," try:"," __dl_json.dumps(__dl_v, default=str)"," except Exception:"," continue"," __dl_outputs[__dl_k] = __dl_v",`__dl_sys.stdout.write(${JSON.stringify(jc)} + __dl_json.dumps({'result': __dl_result, 'output_variables': __dl_outputs}, default=str) + ${JSON.stringify(Cc)} + '\\n')`].join("\n"),LANG:"C.UTF-8",PATH:process.env.PATH??"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},l=g("/bin/sh",["-c",a],{env:s,stdio:["pipe","pipe","pipe"]});let c="",d="",u=0,p=0;l.stdout.on("data",e=>{if(u>=Nc)return;const t=Nc-u,i=e.length>t?e.subarray(0,t):e;c+=i.toString("utf8"),u+=i.length}),l.stderr.on("data",e=>{if(p>=Nc)return;const t=Nc-p,i=e.length>t?e.subarray(0,t):e;d+=i.toString("utf8"),p+=i.length}),l.stdin.write(JSON.stringify(t)),l.stdin.end();let m=!1;const h=setTimeout(()=>{m=!0,l.kill("SIGKILL")},r+6e3-6e3+6e3),f=await new Promise(e=>{l.on("close",(t,i)=>e({code:t??-1,signal:i}))});clearTimeout(h);const v=Date.now()-n,y=Buffer.byteLength(e,"utf8"),b=m||"SIGKILL"===f.signal||"SIGXCPU"===f.signal||137===f.code||152===f.code;let _,w={},k=c;const x=c.lastIndexOf(jc),S=c.lastIndexOf(Cc);if(-1!==x&&-1!==S&&S>x){const e=c.slice(x+10,S);try{const t=JSON.parse(e);_=t.result,w=t.output_variables??{},k=c.slice(0,x)}catch{}}return b?{success:!1,result:null,output_variables:{},error:`script timed out (CPU limit ${o}s)`,stdout:k,stderr:d,duration_ms:v,script_size_bytes:y,timed_out:!0,exit_code:f.code}:0!==f.code?{success:!1,result:null,output_variables:{},error:d.trim().slice(-500)||`script exited with code ${f.code}`,stdout:k,stderr:d,duration_ms:v,script_size_bytes:y,timed_out:!1,exit_code:f.code}:{success:!0,result:_,output_variables:w,error:null,stdout:k,stderr:d,duration_ms:v,script_size_bytes:y,timed_out:!1,exit_code:f.code}}(n,o,{timeoutSeconds:r});a.success||vs(a.error??`script exited with code ${a.exit_code}`,void 0,{stdout:a.stdout,stderr:a.stderr,exit_code:a.exit_code,duration_ms:a.duration_ms,script_size_bytes:a.script_size_bytes,timed_out:a.timed_out}),gs({ok:!0,success:!0,result:a.result,output_variables:a.output_variables,error:null,duration_ms:a.duration_ms,script_size_bytes:a.script_size_bytes,stdout:a.stdout,stderr:a.stderr})})}(_d),function(e){const t=e.command("skill").description("Return a pointer the model hands to the built-in `read` tool; no file I/O happens here.");t.command("read").description("Return a `read`-tool pointer for this skill's `SKILL.md`.").requiredOption("--name <name>","skill name (matches `<name>` in `<available_skills>`)").action(e=>{Kc(String(e.name),"SKILL.md")}),t.command("resource").description("Return a `read`-tool pointer for a file inside a skill's directory.").option("--skill <name>","skill name (matches `<name>` in `<available_skills>`)").option("--name <name>","legacy alias of --skill (kept for back-compat with older skill md)").requiredOption("--path <path>","path inside the skill's directory, relative to the skill root").action(e=>{const t=String(e.skill??e.name??"");t||vs("either --skill or --name is required","e.g. dl skill resource --skill=video-breakdown --path=resources/analysis_system_prompt.txt"),Kc(t,String(e.path))});for(const e of["activate","compile","draft-create","draft-update","fork","publish","search","validate"])t.command(e,{hidden:!0}).description("skill authoring command — NOT implemented on Pi").allowUnknownOption(!0).action(()=>Ec(`skill ${e}`,"skill authoring commands (activate/compile/draft-*/fork/publish/search/validate) are iLands-runtime-only. On Pi, read a skill file with the built-in `read` tool using `dirname(<location>) + <relative-path>`."))._hidden=!0}(_d),function(e){const t=e.command("artifact").description("Versioned slot store for skill artifacts (drafts, validation, canonical promotion).").addHelpText("after",["","Storage layout per project:"," slots/<slot> + versions/<n> — drafts, latest version pointer."," canonical/<slot> — promoted, immutable."," receipts/<autoId> — finalize / promote event stream.","","Status: draft → verified (finalize) → stale (upstream changed)"," any → invalidated (terminal)."].join("\n"));t.command("list").description("List every slot header in the current session.").option("--quiet","emit only {ok,count,slots:[{slot,status,currentVersion}]}").action(async e=>{try{const t=(ol(await nl("list",{})).slots??[]).map(t=>({slot:t.slotName,status:t.status,currentVersion:t.currentVersion,contentType:t.contentType,...e.quiet?{}:{updatedAt:t.updatedAt},...e.quiet?{}:t.inputFence?{inputFence:t.inputFence}:{}}));gs({ok:!0,count:t.length,slots:t})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("read").description("Read a slot version (default: current).").requiredOption("--slot <name>").option("--version <n>","version number (default: header.currentVersion)",e=>parseInt(e,10)).option("--quiet","omit metadata, return content only").action(async e=>{try{const t=ol(await nl("read",{slot:String(e.slot),...void 0!==e.version?{version:e.version}:{}})),i=t.header,n=t.version;n||vs(`slot has no version content: ${e.slot}`),e.quiet&&gs({ok:!0,content:n.content}),gs({ok:!0,slot:i?.slotName,version:n.version,content:n.content,contentType:n.contentType,changeType:n.changeType,contentHash:n.contentHash,status:n.status,createdAt:n.createdAt,currentVersion:i?.currentVersion,headerStatus:i?.status,...n.changeSummary?{changeSummary:n.changeSummary}:{},...n.inputFence?{inputFence:n.inputFence}:{}})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("write").description("Write a new version of a slot. Resets status to draft.").addHelpText("after",["","`--contract` is OPTIONAL. Without it, write is best-effort: JSON parse +","state-machine checks only. With it, the slot's `schema_ref` is run through","ajv in RELAXED mode (every `additionalProperties: false` in the schema is","flipped to `true` before compile, so extra domain fields are accepted","while `required` / `type` / `enum` / `minLength` still apply). Pass","`--strict-schema` to use the contract schema exactly as written.","Content-type mismatches with the contract downgrade to warnings.","","Example (stdin):"," cat <<EOF | dl artifact write --slot=music_candidate --content-type=application/json --content-file=-",' {"service":"banana-pro","prompt":"a cat in a hat"}'," EOF"].join("\n")).option("--slot <name>").option("--content <text>",'RECOMMENDED: content body inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --content "$(cat body.json)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --content-file.').option("--content-file <path|->",'LEGACY: content body as raw text (JSON for application/json) via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --content "$(cat file)". Use --content-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--contract <path>","absolute path to artifact_contract.json (optional)").option("--strict-schema","validate against the contract schema as-written (default: relaxed — `additionalProperties: false` is flipped to `true`)").option("--content-type <ct>","MIME type","application/json").option("--change-summary <text>","human-readable summary of the write").option("--dry-run","validate but do not persist").option("--include-content","include the full written content in the response (default: omitted)").option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").option("--skip-url-check","skip URL reachability preflight for JSON content").action(async e=>{e.printSchema&&Js({command:"dl artifact write",summary:"Write a new version of a slot.",scalars:[{name:"slot",type:"string",required:!0,description:"slot name"},{name:"content-type",type:"string",required:!1,description:"MIME (default application/json)"},{name:"contract",type:"string",required:!1,description:"absolute path to artifact_contract.json (optional)"},{name:"strict-schema",type:"boolean",required:!1,description:"validate against contract schema as-written (default: relaxed)"},{name:"change-summary",type:"string",required:!1,description:""},{name:"dry-run",type:"boolean",required:!1,description:""},{name:"include-content",type:"boolean",required:!1,description:"include full written content in response (default: omitted)"},{name:"skip-url-check",type:"boolean",required:!1,description:"skip URL reachability preflight for JSON content"},{name:"content",type:"string",required:!1,description:"RECOMMENDED inline raw-text content body (required: pass this or --content-file)"}],files:[{name:"content-file",required:!1,kind:"text",description:"LEGACY: content body via file/stdin (prefer --content inline)",example:'{"service":"banana-pro","prompt":"a cat"}'}]}),e.slot||ys("E_SCHEMA","--slot is required","run `dl artifact write --print-schema` for the expected shape",{flag:"--slot"}),e.content||e.contentFile||ys("E_SCHEMA","--content is required (pass the content inline, or use --content-file for the legacy file/stdin path)","run `dl artifact write --print-schema` to see the expected shape",{flag:"--content"});{const i=function(e){const t=e.split(";")[0]?.trim().toLowerCase()??"";return!(!t||"application/json"!==t&&!t.startsWith("text/")&&!t.endsWith("+json")&&!t.endsWith("+xml")&&"application/xml"!==t&&"application/yaml"!==t&&"application/x-yaml"!==t)}(t=String(e.contentType))?null:{message:`artifact content-type "${t}" is not text/JSON — artifact slots store text only`,hint:Vs,extra:{contentType:t}};i&&ys("E_SCHEMA",i.message,i.hint,i.extra)}var t;let i,n="";try{const t=await hs(e.content?String(e.content):void 0,e.contentFile?String(e.contentFile):void 0,{inline:"--content",file:"--content-file"});t&&(n=t.raw,i=t.label)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:"artifact write",slot:String(e.slot),content_source:i??null,content_bytes:Buffer.byteLength(n,"utf8")});{const e=function(e){return function(e){return/[\u0000\uFFFD]/.test(e)}(e)?{message:"artifact content contains binary bytes (NUL or U+FFFD replacement chars) — looks like a binary file read as text",hint:Vs,extra:{reason:"binary-content"}}:null}(n);e&&ys("E_SCHEMA",e.message,e.hint,e.extra)}if(!e.skipUrlCheck&&String(e.contentType).includes("json")){let e;try{e=JSON.parse(n)}catch{e=void 0}void 0!==e&&await sl(Zs(e),!1)}const o=e.contract?ll(String(e.contract),String(e.slot)):void 0;try{gs({ok:!0,...al(rl(ol(await nl("write",{slot:String(e.slot),content:n,contentType:String(e.contentType),...o?{contract:o.contract,schemas:o.schemas}:{},...e.strictSchema?{strictSchema:!0}:{},...e.changeSummary?{changeSummary:String(e.changeSummary)}:{},...e.dryRun?{dryRun:!0}:{}}))),["slotName","version","status","contentHash","warnings"],!!e.includeContent)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("patch").description("Text patch: unique find+replace. Writes a new version (changeType=patch).").requiredOption("--slot <name>").requiredOption("--from <string>","exact substring to replace (must match exactly once)").requiredOption("--to <string>","replacement string").option("--change-summary <text>").option("--dry-run","report what would change, do not persist").option("--include-content","include full patched content in response (default: omitted)").option("--skip-url-check","skip URL reachability preflight for --to text").action(async e=>{await sl(function(e){const t=new Set,i=[];for(const n of e.matchAll(Ws)){const e=Qs(n[0]);e&&!t.has(e)&&(t.add(e),i.push({path:"$.to",url:e}))}return i}(String(e.to)),!!e.skipUrlCheck);try{gs({ok:!0,...al(rl(ol(await nl("patch",{slot:String(e.slot),from:String(e.from),to:String(e.to),...e.changeSummary?{changeSummary:String(e.changeSummary)}:{},...e.dryRun?{dryRun:!0}:{}}))),["slotName","version","status","contentHash"],!!e.includeContent)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("patch-json").description("Atomic JSONPath-lite patch on a slot's JSON content (set/merge/append/delete).").addHelpText("after",["","`--operations-file` is a JSON array of `{path, op, value?}` entries."," path — JSONPath-lite: dot/bracket access only (`a.b.c[2]`); no filters / wildcards"," op — one of: set | merge | append | delete"," value — required for set/merge/append; omitted for delete","","Example (stdin):"," cat <<EOF | dl artifact patch-json --slot=storyboard --operations-file=-",' [{"path":"segments[0].text","op":"set","value":"hi"}]'," EOF"].join("\n")).option("--slot <name>").option("--operations <inline-json>",'RECOMMENDED: JSON array of {path,op,value?} inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --operations "$(cat ops.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --operations-file.').option("--operations-file <path|->",'LEGACY: JSON array of {path,op,value?} via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --operations "$(cat file)". Use --operations-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--change-summary <text>").option("--dry-run","report op count, do not persist").option("--include-content","include full patched content in response (default: omitted)").option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").option("--skip-url-check","skip URL reachability preflight for operations[].value").action(async e=>{e.printSchema&&Js({command:"dl artifact patch-json",summary:"Atomic JSONPath-lite patch on a slot's JSON content.",scalars:[{name:"slot",type:"string",required:!0,description:"slot name"},{name:"change-summary",type:"string",required:!1,description:""},{name:"dry-run",type:"boolean",required:!1,description:""},{name:"include-content",type:"boolean",required:!1,description:"include full patched content in response (default: omitted)"},{name:"skip-url-check",type:"boolean",required:!1,description:"skip URL reachability preflight for operations[].value"},{name:"operations",type:"string",required:!1,description:"RECOMMENDED inline JSON array of {path,op,value?} (required: pass this or --operations-file)"}],files:[{name:"operations-file",required:!1,kind:"array",description:"LEGACY: array of {path,op,value?} via file/stdin (prefer --operations inline)",example:'[{"path":"segments[0].text","op":"set","value":"hi"}]'}]}),e.slot||ys("E_SCHEMA","--slot is required","run `dl artifact patch-json --print-schema` for the expected shape",{flag:"--slot"}),e.operations||e.operationsFile||ys("E_SCHEMA","--operations is required (pass the JSON array inline, or use --operations-file for the legacy file/stdin path)","run `dl artifact patch-json --print-schema` to see the expected shape",{flag:"--operations"});let t,i=[];try{const n=await async function(e,t,i){const n="string"==typeof e&&""!==e,o="string"==typeof t&&""!==t;return n&&o&&ps(i),n?us(e,i.inline):o?ds(t,i.file):void 0}(e.operations?String(e.operations):void 0,e.operationsFile?String(e.operationsFile):void 0,{inline:"--operations",file:"--operations-file"});n&&(i=n.data,t=n.source.label)}catch(e){throw e instanceof wa&&bs(e),e}if(0===i.length&&ys("E_SCHEMA","--operations must be a non-empty JSON array",void 0,{flag:"--operations"}),_s({command:"artifact patch-json",slot:String(e.slot),operations:i,operations_source:t??null}),!e.skipUrlCheck){const e=[];for(let t=0;t<i.length;t++){const n=i[t].value;if(void 0!==n)for(const i of Zs(n,`$.operations[${t}].value`))e.push(i)}await sl(e,!1)}try{gs({ok:!0,...al(rl(ol(await nl("patch-json",{slot:String(e.slot),operations:i,...e.changeSummary?{changeSummary:String(e.changeSummary)}:{},...e.dryRun?{dryRun:!0}:{}}))),["slotName","version","status","contentHash"],!!e.includeContent)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("diff").description("Line-level diff between two versions of a slot (default: current vs. current-1).").requiredOption("--slot <name>").option("--from <n>","older version",e=>parseInt(e,10)).option("--to <n>","newer version (default: current)",e=>parseInt(e,10)).option("--quiet","just return patch string").action(async e=>{try{const t=ol(await nl("read",{slot:String(e.slot)})).header;t||vs(`slot not found: ${e.slot}`);const i=Number(t?.currentVersion??1),n=e.to??i,o=e.from??Math.max(1,n-1);o===n&&gs({ok:!0,slot:e.slot,from:o,to:n,unchanged:!0,diff:""});const[r,a]=await Promise.all([nl("read",{slot:String(e.slot),version:o}),nl("read",{slot:String(e.slot),version:n})]),s=ol(r),l=ol(a),c=function(e,t){const i=e.split("\n"),n=t.split("\n"),o=i.length,r=n.length,a=Array.from({length:o+1},()=>new Array(r+1).fill(0));for(let e=0;e<o;e++)for(let t=0;t<r;t++)a[e+1][t+1]=i[e]===n[t]?a[e][t]+1:Math.max(a[e+1][t],a[e][t+1]);const s=[];let l=o,c=r;for(;l>0&&c>0;)i[l-1]===n[c-1]?(s.push({type:"ctx",line:i[l-1]}),l--,c--):a[l][c-1]>=a[l-1][c]?(s.push({type:"add",line:n[c-1]}),c--):(s.push({type:"del",line:i[l-1]}),l--);for(;l>0;)s.push({type:"del",line:i[l-1]}),l--;for(;c>0;)s.push({type:"add",line:n[c-1]}),c--;return s.reverse()}(String(s.version?.content??""),String(l.version?.content??"")),d=function(e){return e.map(e=>"add"===e.type?`+${e.line}`:"del"===e.type?`-${e.line}`:` ${e.line}`).join("\n")}(c);e.quiet&&gs({ok:!0,diff:d}),gs({ok:!0,slot:e.slot,from:o,to:n,added:c.filter(e=>"add"===e.type).length,deleted:c.filter(e=>"del"===e.type).length,diff:d})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("validate").description("Run contract validation without changing state. Returns issues + warnings + staleness.").addHelpText("after",["","`--contract` is OPTIONAL. Without it, only state-machine + emptiness +","staleness checks run. With it, schema is validated in RELAXED mode unless","`--strict-schema` is passed (see `dl artifact write --help`)."].join("\n")).requiredOption("--slot <name>").option("--contract <path>","absolute path to artifact_contract.json (optional)").option("--strict-schema","validate against the contract schema as-written (default: relaxed)").option("--quiet").action(async e=>{try{const t=e.contract?ll(String(e.contract),String(e.slot)):void 0,i=ol(await nl("validate",{slot:String(e.slot),...t?{contract:t.contract,schemas:t.schemas}:{},...e.strictSchema?{strictSchema:!0}:{}}));e.quiet&&gs({ok:!0,verified:i.verified,isStale:i.isStale,issueCount:Array.isArray(i.issues)?i.issues.length:0}),gs({ok:!0,...rl(i)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("fork").description("Copy the latest version of --source into --target as a new draft (changeType=fork).").requiredOption("--source <name>").requiredOption("--target <name>").option("--dry-run").option("--include-content","include full forked content in response (default: omitted)").action(async e=>{try{gs({ok:!0,...al(rl(ol(await nl("fork",{source:String(e.source),target:String(e.target),...e.dryRun?{dryRun:!0}:{}}))),["slotName","version","changeType"],!!e.includeContent)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("finalize").description("Verify slot against its contract. mode=verify_and_promote also flips draft→verified, writes canonical, emits receipt.").addHelpText("after",["","`--contract` is OPTIONAL. Without it, only state-machine + emptiness +","staleness checks run; the slot still flips to `verified` (or promotes","in `verify_and_promote` mode). With it, schema validates in RELAXED mode","unless `--strict-schema` is passed (see `dl artifact write --help`)."].join("\n")).requiredOption("--slot <name>").option("--contract <path>","absolute path to artifact_contract.json (optional)").option("--strict-schema","validate against the contract schema as-written (default: relaxed)").option("--mode <mode>","verify | verify_and_promote","verify").option("--dry-run","never promote, even if mode=verify_and_promote").option("--include-content","include full finalized content in response (default: omitted)").action(async e=>{["verify","verify_and_promote"].includes(String(e.mode))||vs(`unsupported mode: ${e.mode}`,'use "verify" or "verify_and_promote".');try{const t=e.contract?ll(String(e.contract),String(e.slot)):void 0,i=e.dryRun?"verify":String(e.mode);gs({ok:!0,...al(rl(ol(await nl("finalize",{slot:String(e.slot),mode:i,...t?{contract:t.contract,schemas:t.schemas}:{},...e.strictSchema?{strictSchema:!0}:{}}))),["slotName","version","verified","promoted","status","canonicalId"],!!e.includeContent),...e.dryRun?{dryRun:!0}:{}})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("select").description("NOT implemented — use `artifact finalize --mode=verify_and_promote` to lock a canonical version.").requiredOption("--slot <name>").option("--quiet").action(()=>{vs("dl artifact select is not implemented on pi","pi does not model active variants; use `artifact finalize --mode=verify_and_promote` to lock a canonical version instead.")})._hidden=!0,t.command("canonical").description("Read the canonical (promoted) snapshot of a slot, if any.").requiredOption("--slot <name>").option("--quiet").action(async e=>{try{const t=ol(await nl("canonical",{slot:String(e.slot)})).canonical??null;t||vs(`no canonical promotion for slot: ${e.slot}`),e.quiet&&gs({ok:!0,content:t.content,contentHash:t.contentHash}),gs({ok:!0,...t})}catch(e){vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){const t=e.command("asset").description("Register / fetch media assets (groups + assets) for downstream generate-* verbs.");t.command("register").description("Create an asset group and register one Image / Video / Audio asset under it; the server assigns the real group_id.").requiredOption("--group-id <name>","human-readable group NAME (despite the flag's spelling — server assigns the real id)").requiredOption("--name <name>").requiredOption("--url <url>").requiredOption("--asset-type <type>","one of: Image / Video / Audio (iLands capitalization)").option("--project-name <name>","default project","default").addHelpText("after",'\n\nSeedance asset usage:\n - Video assets are supported by dl asset register. Use --asset-type=Video for .mp4 / video URLs.\n - For Seedance 2.0 generate-video, a registered video asset must be passed by asset id:\n --ark-asset-ids=<asset_id> and reference it in the prompt as @assetN.\n - Do not also pass the same registered video URL via --ref-video-url; that raw URL flag is for unregistered video references.\n\nExamples:\n dl asset register --group-id=healthfood-girl --name=tiktok-healthfood-ref \\\n --url="https://example.com/ref.mp4" --asset-type=Video\n\n dl generate-video --service=seedance-2-0 \\\n --prompt="follow @asset1 as the reference video rhythm, no BGM" \\\n --duration=6 --aspect-ratio=9:16 --resolution=720p \\\n --ark-asset-ids=asset_xxx').action(async e=>{try{const t=await async function(e){return Da("media/register-asset","api/asset/create-group",{name:e.name,project_name:e.project_name??"default",...e.description?{description:e.description}:{}},{timeoutMs:3e4,retries:1})}({name:String(e.groupId),project_name:String(e.projectName??"default")}),i=t.group_id??t.data?.Result?.Id??"";i||vs("create-group returned no group_id",void 0,{response:t});const n=await async function(e){return Da("media/register-asset","api/asset/create",e,{timeoutMs:3e4,retries:1})}({group_id:i,name:String(e.name),url:String(e.url),asset_type:String(e.assetType)});gs({ok:!0,group:{group_id:i,name:e.groupId},asset:n})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("get").description("Fetch a single asset by id.").requiredOption("--id <id>").action(async e=>{try{gs({ok:!0,asset:await async function(e){return Da("media/get-asset","api/asset/get",{id:e},{timeoutMs:3e4,retries:1})}(String(e.id))})}catch(e){vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){const t=e.command("knowledge").description("Knowledge-base search across domain libraries (sfx, bgm, visual_style, voice, writing, meme).");t.command("search").description("Search a knowledge domain; returns `data` plus domain metadata and CDN URLs.").addHelpText("after",["","Domains: sfx, stinger, bgm, amb, audio_any, visual_style, voice,"," writing_plot/character/payoff/conflict/hook/any, meme.","","`--provider` (voice-only): filter to a specific TTS provider —"," `elevenlabs` (high-quality English, audio tags) or `minimax` (CN+EN).",' Equivalent to adding `{"vendor":"<v>"}` to --filters-file but'," surfaces in --help / --print-schema for easier agent discovery.","","Example (stdin):",' cat <<EOF | dl knowledge search --domain=voice --query="deep narrator" --filters-file=-',' {"language":"EN","gender":"Male"}'," EOF","","Example (provider filter):",' dl knowledge search --domain=voice --provider=elevenlabs --query="warm narrator"'].join("\n")).requiredOption("--domain <name>",`one of: ${Oc.join(", ")}`).requiredOption("--query <q>").option("--kind <tag>","domain-specific shape filter (e.g. meme: ready|template)").option("--provider <name>",`(voice domain only) filter to a TTS provider: ${Tc.join(" | ")}`).option("--k <n>","max hits (default 10)",e=>{const t=Number(e);if(!Number.isFinite(t)||!Number.isInteger(t)||t<1||t>100)throw new Error(`--k invalid: ${e}`);return t}).option("--filters <inline-json>",'RECOMMENDED: domain-specific filters inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --filters "$(cat filters.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --filters-file.').option("--filters-file <path|->",'LEGACY: domain-specific filters JSON object via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --filters "$(cat file)". Use --filters-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--print-schema","print scalar+file schema and exit").action(async e=>{e.printSchema&&Js({command:"dl knowledge search",summary:"Knowledge-base search for domain-specific asset libraries.",scalars:[{name:"domain",type:"string",required:!0,description:"asset library domain",enum:Oc},{name:"query",type:"string",required:!0,description:"search query"},{name:"kind",type:"string",required:!1,description:"domain-specific shape filter (e.g. meme: ready|template)"},{name:"provider",type:"string",required:!1,description:"voice-domain only: filter by TTS provider (elevenlabs | minimax)",enum:Tc},{name:"k",type:"integer",required:!1,description:"max hits (default 10, max 100)"},{name:"filters",type:"string",required:!1,description:"RECOMMENDED inline JSON object of domain-specific filters (sibling of --filters-file)"}],files:[{name:"filters-file",required:!1,kind:"object",description:"LEGACY: domain-specific filters (prefer --filters inline)",example:'{"language":"EN","gender":"Female","vendor":"elevenlabs"}'}]});const t=String(e.domain);Oc.includes(t)||vs(`--domain must be one of ${Oc.join(", ")}; got ${t}`);const i=String(e.query),n=Math.min(e.k??10,20),o=e.kind?String(e.kind):void 0,r=e.provider?String(e.provider):void 0;r&&(Tc.includes(r)||vs(`--provider must be one of ${Tc.join(", ")}; got ${r}`),"voice"!==t&&vs(`--provider is only valid with --domain=voice; got --domain=${t}`,"drop --provider, or switch --domain=voice if you meant to search voices."));let a={};try{const t=await ms(e.filters?String(e.filters):void 0,e.filtersFile?String(e.filtersFile):void 0,{inline:"--filters",file:"--filters-file"});t&&(a=t.data)}catch(e){throw e instanceof wa&&bs(e),e}if("voice"===t&&"provider"in a){const{provider:e,...t}=a;a={...t,..."vendor"in t?{}:{vendor:e}}}const s={...a,...o?{kind:o}:{},...r?{vendor:r}:{}},l={domain:t,query:i,limit:n};Object.keys(s).length>0&&(l.filters=s);try{const e=await Da("knowledge","api/v1/knowledge/search",l,{timeoutMs:3e4,retries:1}),o=Array.isArray(e.data)?e.data:[],r=e.meta&&"object"==typeof e.meta?e.meta:{domain:t,query:i,limit:n,count:o.length};gs({ok:!0,domain:t,query:i,...e,data:o,meta:r,hits:o})}catch(e){if(e instanceof Jr&&vs(e.message,e.hint),e instanceof Sa){const t=function(e){let t;try{t=JSON.parse(e)}catch{return}if(!t||"object"!=typeof t)return;const i=t.error;if(!i||"object"!=typeof i)return;const n=i.message;return"string"==typeof n&&n.length>0?n:void 0}(e.bodyText),i=e.status>=400&&e.status<500;vs(`knowledge search failed (http ${e.status})${t?`: ${t}`:""}`,i?"fix request filters; run `dl knowledge search --print-schema` for the expected shape":"check backend reachability",{status:e.status,body:e.bodyText.slice(0,500)})}vs(e instanceof Error?e.message:String(e))}});for(const e of["agent-profile","context-find","context-write","materials","platform","trending","web","web-read"])t.command(e).description("iLands-runtime-only knowledge verb — NOT implemented on pi").allowUnknownOption(!0).action(()=>Ec(`knowledge ${e}`,"iLands-runtime-only knowledge verb — on Pi, use `dl search` / `dl web-fetch` / `dl artifact write` as appropriate."))._hidden=!0}(_d),function(e){Ps(e,{verb:"lipsync",actionName:"lipsync",schema:Ko,billing:{schema:jl,select:e=>({service:e.service,duration:e.duration,resolution:e.resolution}),quote:Il},approvalPreview:e=>function(e){const t=[...vc("image","string"==typeof e.image_url?[e.image_url]:[],"Face image"),...yc(e.keyframes)],i=vc("audio","string"==typeof e.audio_url?[e.audio_url]:[],"Driving audio"),n=[];return mc(n,"Service",e.service),mc(n,"Resolution",e.resolution),mc(n,"Quality",e.quality_preset),"number"==typeof e.width&&"number"==typeof e.height&&n.push({label:"Dimensions",value:`${e.width}x${e.height}`}),mc(n,"Seed",e.seed),mc(n,"Billing duration",e.duration),{kind:"lipsync",title:"Lip-sync video",summary:"string"==typeof e.service?e.service:void 0,sections:[gc("Prompt",e.prompt),hc("Face / keyframes",t),hc("Driving audio",i),fc("Details",n)].filter(e=>void 0!==e)}}(e),supportsBatch:!0,description:"Generate a talking-head video where a character's lips sync to a driving audio track. Submits one job (or N via --jobs-file) and returns {job_ref, status:'pending'}; the rendered video URL arrives via [async-callback].",notes:["Preferred default service: `dlai2v_pro` (LTX 2 Pro / LTX 2.3 multi-frame).","Use `dlai2v` (LTX 2 baseline) when you need explicit --width / --height / --seed / --quality-preset control.","`--audio-url` determines lipsync duration. Do not pass --duration to control output length; if present, duration is billing-only and vendor does not read it.","","LTX 2 family (`dlai2v_pro` / `dlai2v`) prompt template — every prompt must contain all three:",' 1. Subject is speaking/singing (e.g. "the character speaks naturally with perfect lip synchronization")'," 2. Character action description (head nods, hands, shoulders, breathing, gaze, …)",' 3. Camera movement description (e.g. "Dolly in", "slow push in", "static medium close-up")',"Reference template:",' --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods'," and tilts, hands resting gently or making small conversational gestures, relaxed",' shoulders, natural breathing motion, high quality, natural lighting, Dolly in"',"","## Multi-keyframe mode (--keyframes, dlai2v / dlai2v_pro / dlai2v_pro_multiframe only)","--image-url and --keyframes are mutually exclusive. --image-url = single reference image","(api-layer auto-wraps it into keyframes[0]). --keyframes = 1-5 explicit keyframe images","for richer camera movement — the model interpolates animation between keyframes + audio-driven lip sync.","",'Each --keyframes value is a JSON object: {"image_url":"...","frame_position":"first|middle|last"}'," - frame_position controls where in the timeline the keyframe anchors"," - All keyframe images must be the same character and same aspect ratio"," - Typical MV workflow: generate a 2×2 grid image (same character, 4 poses) via dl generate-image-ref when source/reference images exist, otherwise dl generate-image-prompt,"," ffmpeg crop into 4 panels, pass as 4 keyframes → rich camera movement + pose transitions","","Constraints: --keyframes only works with dlai2v / dlai2v_pro / dlai2v_pro_multiframe","(preflight rejects other services); 1-5 keyframes for dlai2v / dlai2v_pro,","2-4 keyframes for dlai2v_pro_multiframe; do NOT pass both --image-url and --keyframes.","","## dlai2v_pro_multiframe (LTX 2.3 真·多帧变体)","真正的多帧关键帧引导视频生成(不是单帧 wrap)。必须用 --keyframes (2-4 帧);","每帧支持 {image_url (必填), frame_ratio? (0.0-1.0 时间位置), weight? (0.0-1.0 强度, 默认 0.4)}。","frame_ratio 不传则按数量等分: 2帧=[0,1] / 3帧=[0,0.5,1] / 4帧=[0,0.33,0.67,1]。","api-layer 按 keyframes 数量自动 router 到 mutiframe_{2f,3f,4f} workflow。","--aspect-ratio 支持 16:9/9:16/1:1;resolution 强制 720p (不可改);","不支持显式 --width / --height / --resolution。"],whenToUse:["You have a face image + audio and want a video of the face speaking","Multi-segment lipsync (split the song / dialogue into beats and fan out via --jobs-file)"],whenNotToUse:["You only need text → speech (no face) — use `dl generate-tts`","You need a music track — use `dl generate-music`","You need a talking head from scratch with no audio: not supported on Pi"],examples:[{caption:"single, the common case — dlai2v_pro with the LTX-family prompt template",command:'dl lipsync \\\n --service=dlai2v_pro \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods and tilts, hands resting gently or making small conversational gestures, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"'},{caption:"single, dlai2v (LTX 2 baseline) when you need width/height/seed control",command:'dl lipsync \\\n --service=dlai2v \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="the singer performs the chorus line with perfect lip synchronization, subtle head nods, hands lightly gripping the mic, relaxed shoulders, natural breathing between phrases, high quality, natural lighting, slow dolly in" \\\n --quality-preset=high \\\n --width=1280 \\\n --height=736'},{caption:"multi-keyframe (4 poses from a 2×2 grid crop) — richer camera movement",command:'dl lipsync \\\n --service=dlai2v_pro \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf_top_left.png","frame_position":"first"}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf_top_right.png","frame_position":"middle"}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf_bottom_left.png","frame_position":"middle"}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf_bottom_right.png","frame_position":"last"}\' \\\n --audio-url="https://cdn.example.com/segment.mp3" \\\n --prompt="A person sings expressively with perfect lip synchronization, dynamic head movement, confident posture shifts, high quality, natural lighting, slow dolly in"'},{caption:"batch via stdin (parallel fan-out)",command:'cat <<EOF | dl lipsync --jobs-file=-\n[\n {"job_key":"seg_001","service":"dlai2v_pro","image_url":"https://1.png","audio_url":"https://1.mp3","prompt":"A person speaks naturally with perfect lip synchronization, subtle head nods and tilts, hands resting gently, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"},\n {"job_key":"seg_002","service":"dlai2v","image_url":"https://2.png","audio_url":"https://2.mp3","prompt":"A person sings clearly with perfect lip synchronization, subtle head nods, relaxed shoulders, natural breathing motion, high quality, natural lighting, static medium close-up"}\n]\nEOF'},{caption:"batch with multi-keyframe job",command:'cat <<EOF | dl lipsync --jobs-file=-\n[\n {"job_key":"seg_001","service":"dlai2v_pro","image_url":"https://face.png","audio_url":"https://1.mp3","prompt":"A person speaks naturally with perfect lip synchronization, subtle head nods, hands resting gently, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"},\n {"job_key":"seg_002","service":"dlai2v_pro","keyframes":[{"image_url":"https://kf1.png","frame_position":"first"},{"image_url":"https://kf2.png","frame_position":"middle"},{"image_url":"https://kf3.png","frame_position":"last"}],"audio_url":"https://2.mp3","prompt":"A person sings expressively with perfect lip synchronization, dynamic head movement, confident posture, high quality, natural lighting, slow push in"}\n]\nEOF'}],notExamples:[{command:'dl lipsync --params=\'{"service":"dlai2v","image_url":"...","audio_url":"..."}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"},{command:"dl lipsync --image-url=... --audio-url=... --jobs-file=batch.json",whyItFails:"scalar flags + --jobs-file are mutually exclusive; raises E_SCHEMA"},{command:"dl lipsync --service=dlai2v_pro --image-url=... --keyframes='...' --audio-url=...",whyItFails:"--image-url and --keyframes are mutually exclusive; preflight rejects. Use one or the other."}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"url":"https://storage.../video.mp4","duration_ms":3200}}',outputBatch:'{"ok":true,"action":"lipsync","results":[\n {"job_key":"seg_001","job_ref":"<uuid>","status":"pending"},\n ...\n]} // batch is non-blocking; each completed job is pushed back to the session via [async-callback]',preflight:e=>{const t=String(e.service??""),i="string"==typeof e.image_url&&""!==e.image_url,n=Array.isArray(e.keyframes)&&e.keyframes.length>0;if(!i&&!n)throw new wa("E_SCHEMA","either --image-url or --keyframes is required","provide a face image via --image-url, or multiple keyframes via --keyframes",{verb:"lipsync",service:t});if(i&&n)throw new wa("E_SCHEMA","--image-url and --keyframes are mutually exclusive","use --image-url for single-image lipsync, or --keyframes for multi-keyframe lipsync (1-5 frames); do not pass both",{verb:"lipsync",service:t});if(n&&"dlai2v"!==t&&"dlai2v_pro"!==t&&"dlai2v_pro_multiframe"!==t)throw new wa("E_SCHEMA",`--keyframes is only supported for dlai2v / dlai2v_pro / dlai2v_pro_multiframe, not ${t}`,"use --image-url instead, or switch --service to dlai2v / dlai2v_pro / dlai2v_pro_multiframe for multi-keyframe lipsync",{flag:"--keyframes",verb:"lipsync",service:t});if("dlai2v_pro_multiframe"===t){if(!n)throw new wa("E_SCHEMA","dlai2v_pro_multiframe requires --keyframes (2-4 frames); --image-url alone is not supported","pass 2-4 --keyframes flags; if you only have 1 image, use --service=dlai2v_pro instead",{verb:"lipsync",service:t});const i=e.keyframes.length;if(i<2||i>4)throw new wa("E_SCHEMA",`dlai2v_pro_multiframe requires 2-4 keyframes, got ${i}`,"adjust to 2/3/4 keyframes; api-layer routes to mutiframe_{2f,3f,4f} workflow by count",{flag:"--keyframes",verb:"lipsync",service:t})}if(n&&e.keyframes.length>5)throw new wa("E_SCHEMA",`--keyframes accepts 1-5 frames, got ${e.keyframes.length}`,"reduce to at most 5 keyframe images",{flag:"--keyframes",verb:"lipsync",service:t})},modelTopic:{rankingSummary:["Overall ranking (strongest → weakest) + recommended default:"," 🥇 dlai2v_pro LTX 2 Pro / LTX 2.3 multi-frame — **preferred default for new lipsync work**"," 🥈 dlai2v LTX 2 baseline — when you need explicit width/height/seed/quality-preset control"," 🥉 longcat-avatar Longer audio + simple setup, weaker resolution control"],services:[{service:"dlai2v_pro",label:"LTX 2 Pro (LTX 2.3 multi-frame)",tier:"🥇 Preferred default",bestFor:"Default choice for new lipsync work. LTX-2's successor multi-frame workflow; scene-style prompt (subject + action + camera) + face still + audio",quality:"Very High",speed:"2-5min",cost:"mid",description:["LTX 2 Pro, routes to the LTX-2.3 multi-frame workflow.","","Two input modes:"," Mode 1 (single image): --image-url — api-layer auto-wraps into keyframes[0]."," Mode 2 (multi-keyframe): --keyframes (1-5 frames) — explicit keyframe images for richer"," camera movement. Model interpolates between keyframes + audio-driven lip sync.",' Each keyframe: {"image_url":"...","frame_position":"first|middle|last"}'," Typical workflow: generate 2×2 grid (same character, 4 poses), ffmpeg crop → 4 keyframes.","","--image-url and --keyframes are mutually exclusive."],promptTips:["⚠ LTX family prompt template — all three segments required:"," 1. Subject is speaking/singing (explicitly say the character is *speaking* or *singing* with perfect lip sync)"," 2. Character action (head nods/tilts / gaze / hands / shoulders / breathing)"," 3. Camera movement (Dolly in / slow push in / static medium close-up; static must also be stated explicitly)","Append a quality / lighting tail: 'high quality, natural lighting'","","Reference template:",' "A person speaks naturally with perfect lip synchronization, subtle'," head nods and tilts, hands resting gently or making small conversational"," gestures, relaxed shoulders, natural breathing motion, high quality,",' natural lighting, Dolly in"'],flagSubset:["service","image-url","audio-url","prompt","keyframes"],constraints:["⚠ dlai2v_pro accepts a **strict subset** of flags — do NOT copy a dlai2v example and just swap the service name"," Invalid: --quality-preset / --width / --height / --resolution / --seed"," Invalid: --ark-asset-ids / --reference-subject-type (not part of the lipsync surface)"," Invalid: --duration (audio_url determines the output duration)"," Passing them is silently ignored (the multi-frame workflow uses fixed output dimensions)","--keyframes: 1-5 frames, mutually exclusive with --image-url","audio_url ≤ 100MB & ≤ 20s","audio formats: mp3 / wav / ogg / flac / m4a / aac / webm"],examples:[{caption:"single, dlai2v_pro default (LTX 2 Pro)",command:'dl lipsync --service=dlai2v_pro \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods and tilts, hands resting gently or making small conversational gestures, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"'}]},{service:"dlai2v",label:"LTX 2 baseline (Multimodal)",tier:"🥈 When you need width/height/seed control",bestFor:"You need explicit --width / --height / --seed / --quality-preset control (dlai2v_pro's fixed-dimension multi-frame does not expose these)",quality:"Very High",speed:"2-5min",cost:"mid",description:["LTX 2 baseline. Prompt template is the same as dlai2v_pro (subject speaking + character action + camera move).","Also supports --keyframes (1-5 frames) for multi-keyframe mode, same as dlai2v_pro."],promptTips:["Same three-segment template as dlai2v_pro","--quality-preset='ultra' gives the best lip sync but is slower"],flagSubset:["service","image-url","audio-url","prompt","quality-preset","width","height","seed","keyframes"],constraints:["audio ≤ 19s & ≤ 50MB","--keyframes: 1-5 frames, mutually exclusive with --image-url","Do NOT pass --duration to control output length; audio_url determines the lipsync length"],examples:[{caption:"dlai2v with explicit width/height/seed",command:'dl lipsync --service=dlai2v \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods, hands resting gently, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in" \\\n --quality-preset=high --width=1280 --height=736 --seed=42'}]},{service:"longcat-avatar",label:"LongCat Avatar",tier:"Long audio + simple",bestFor:"Longer audio + simple parameter setup",quality:"High",speed:"1-3min",cost:"low",description:["LongCat Avatar. Handles longer audio with relatively simple parameters, but resolution control is weaker."],promptTips:["Relatively permissive — 'a person speaking' will run; the LTX-family three-segment template still produces better results"],flagSubset:["service","image-url","audio-url","prompt","resolution","seed"],constraints:["Few resolution options (mainly 480p); no fine-grained width/height control","Do NOT pass --duration; audio_url determines output length"],examples:[{caption:"longcat-avatar simple setup",command:'dl lipsync --service=longcat-avatar \\\n --image-url=https://... --audio-url=https://... \\\n --prompt="a person speaking" --resolution=480p --seed=42'}]}],decisionLogic:[{when:"Default / unsure / new lipsync work",pick:"dlai2v_pro (LTX 2 Pro, preferred default)"},{when:"Need explicit --width / --height / --seed / --quality-preset control",pick:"dlai2v (LTX 2 baseline)"},{when:"Longer audio + simple parameters (< control needs)",pick:"longcat-avatar"}]},preflightTopic:{intro:"Confirm these 5 items before the first dl lipsync call (MV segment workflow adds a 6th):",decisions:[{name:"Service / model",description:"Pick a supported lipsync service (dlai2v_pro default / dlai2v / dlai2v_pro_multiframe / longcat-avatar).\nDetermines prompt template shape + flag subset + audio duration cap."},{name:"Driving duration",description:"Whether audio length is within the selected service cap (dlai2v_pro ≤ 20s / dlai2v ≤ 19s; check the selected service profile for other caps).\n`--audio-url` determines the request duration; do not use --duration to control output length.\nIf the intended final segment is shorter than 3s, trim the driving audio upstream or trim padded output afterward;\nlonger than the service cap MUST be split upstream. **Driving audio is canonical** — do NOT crop / pad /\nstretch / integer-round it to match vendor duration. If the vendor outputs padded video, trim back\nto exact storyboard / audio duration."},{name:"Resolution package",description:"480p / 720p / explicit width-height (depends on service). dlai2v_pro does NOT accept resolution / width / height (fixed dim);\ndlai2v accepts width / height / quality-preset."},{name:"Face / reference plan",description:"Decide the face image source: real-looking human portrait / generated performance still / registered asset bundle.\n**MV segment workflow**: for the LTX family, do NOT use a raw character reference sheet directly;\nuse dl generate-image-ref to produce a segment-specific performance still first when source/reference images exist —\nfront-facing / mouth clearly visible / matching the segment's scene / lighting / wardrobe / props."}],notes:["Cost-sensitive / service / resolution unclear → read pricing-and-policies-dramaland-faq/SKILL.md first","Batch lipsync goes through --jobs-file; do not block per segment. Do NOT flatten nested jobs[].params"]},policyTopic:{intro:"Six categories of hard rules: User-facing isolation / Package gate / LTX prompt template / URL hygiene / MV duration & still / Fallback ladder.",rules:[{title:"1. User-Facing Communication — never leak internal details",body:["Vendor / pricing / internal model code (LTX-2.3 multi-frame workflow / Seedance 2.0 Pro) /","trace id must NOT surface to the user. User-facing summary only mentions: service alias","(LTX / Seedance / LongCat) + character / duration + action (lip-sync / lip-sync video)."]},{title:"2. Production Package Gate — never call before authorization",body:["service / model / driving duration / resolution / width-height / job count (including batch","segment range) / face / reference plan / audio source plan are all components of the paid","package authorization. Do not call before the package is authorized; once authorized, batch","within the package. Only re-ask on package overflow (service switch / duration change /","resolution change / quantity increment / swap of a key input / fallback / paid regeneration)."]},{title:"3. LTX-family Prompt Template Discipline (dlai2v_pro / dlai2v)",body:["LTX 2 family prompt MUST contain all three segments:"," (1) Subject speaking/singing (explicitly say the character is *speaking* or *singing* with perfect lip sync)"," (2) Character action (head nods / tilts / gaze / hands / shoulders / breathing)"," (3) Camera movement (Dolly in / slow push in / static medium close-up; static must be stated explicitly)","","Append a quality / lighting tail: 'high quality, natural lighting'.","","❌ Bad — 'a person speaking' (too vague; the model improvises)","✅ Good — see the reference template in the dlai2v_pro service profile"]},{title:"4. URL Hygiene — public HTTPS / never fabricate storage URLs",body:["All media URLs (image_url / audio_url) MUST be real publicly reachable HTTPS URLs. Legitimate sources:"," - dl generate-image-prompt / dl generate-image-ref / generate-tts / generate-music submit results (GCS storage URLs)"," - URLs uploaded by the user or provided in the conversation"," - URLs returned by platform queries like dl content list","","NEVER fabricate storage URLs / guess domains / invent paths. Need a face image → run dl generate-image-ref first when source/reference images exist, otherwise dl generate-image-prompt;","need audio → run dl generate-tts or generate-music first."]},{title:"5. MV Segment Duration & Keyframe Boundary",body:["**Driving audio is canonical**: do NOT crop / pad / stretch / integer-round audio to match","vendor duration, and do NOT pass --duration. If the vendor outputs padded video, ffmpeg trim back to the exact","storyboard / audio duration.","","Intended final segment shorter than 3s → request at least the vendor minimum, then trim back;","longer than 15-20s → MUST split upstream — do not feed it all at once.","","LTX family MUST NOT use a raw character design / reference sheet directly as image_url.","Use dl generate-image-ref to produce a segment-specific performance still when source/reference images exist — front-facing /","mouth clearly visible / matching the segment's scene / lighting / wardrobe / props."]},{title:"6. Fallback Ladder",body:["When this verb produces jitter / mouth drift / gaze drift / character drift / moderation block, in order:","","1. Retry once (transient network / quota jitter usually clears)","2. Swap within supported LTX-family modes: dlai2v_pro ↔ dlai2v, or switch between single image and keyframes","3. Re-pick the face still: performance still not sharp enough / not front-facing enough →"," regenerate a segment-specific still via image-generation","4. Edit the prompt: LTX-family three segments incomplete → fill in","5. Split segments: audio too long / model's segment handling capped → split upstream"]}]},compositionTopic:{intro:"This atomic skill only produces a lipsync video URL; artifact / canvas / publish_content downstream responsibilities are not in this verb's scope.",integrations:[{skill:"generate-tts / generate-music (audio source)",rule:["audio_url sources: dl generate-tts (dialogue / narration) or dl generate-music (song / vocal track).","Confirm ownership before feeding raw user-uploaded audio; never fabricate a GCS URL.","Do not use duration to control output length; audio_url determines the requested length."]},{skill:"generate-image-ref (face / performance still source)",rule:["image_url source: dl generate-image-ref producing a segment-specific performance still when source/reference images exist.","MV segment workflow: do NOT use a raw character design directly as the lipsync image_url;","generate a segment-specific still first (front-facing / mouth clearly visible / matching scene)."]},{skill:"Right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs dl artifact write / patch-json on pi_media_log on its caller's behalf — that is the composition layer's job."]},{skill:"publish_content (final delivery)",rule:["Hand the lipsync output video URL to publish_content with presentation_family='video'","(see the publish subtopic for details)."]}]},asyncTopic:{intro:["dl lipsync returns { job_ref, status: 'pending' } and exits immediately by default — do NOT poll.","The result is injected into the session as [async-callback] job=<ref> text; typical wait is 1-5 minutes.","If the next step must have the result (e.g. immediately feeding ffmpeg) → query separately with","dl poll --job-ref=<ref>; dl subcommands themselves no longer support --wait blocking (removed in #294)."],resultShape:['{ "url": "https://storage.googleapis.com/.../video.mp4", "original_url": "...", "vendor": "..." }',"vendor / original_url / other internal metadata fields MUST NOT be exposed to the user"],notes:["⚠ Do NOT write a bash poll loop (while sleep + dl poll) — forbidden by the agent runtime async rules (#389)","Batch lipsync goes through --jobs-file; each job's completion is pushed back independently via [async-callback]","⚠ The returned URL already lives on our GCS — feed it directly to downstream tools / artifacts; do NOT pass to upload_file."]},publishTopic:{intro:["After producing the lipsync video URL, call publish_content with presentation_family='video' +","explicit media fields. See 'Publishing Your Work / video' in the creation playbook for the full field map."],fields:[{name:"presentation_family",value:"'video'"},{name:"media_urls.video",value:"<lipsync output URL>"},{name:"delivery_format",value:"'video'"}]}})}(_d),function(e){Ps(e,{verb:"transcribe",actionName:"transcribe",schema:Xo,billing:{schema:Yl,select:()=>({}),quote:Wl},supportsBatch:!1,description:"Asynchronously transcribe audio to SRT subtitles. Returns {status:'pending', job_ref} immediately; the SRT lands via [async-callback] in a later turn.",notes:["Async by default — submit returns `{status:'pending', job_ref, data:{task_id}}`; do NOT wrap in `nohup ... &` / bash poll loop. End the turn and wait for `[async-callback] job=<ref>` to land.","`--language` accepts `auto` (detect) or any ISO-639-1 code (`en`, `zh`, `ja`, `es`, `fr`, …).","`--transcript-text` skips ASR recognition and aligns the provided text to the audio to produce SRT/timestamps.","`--word-timestamps` controls whether the callback payload includes full `text`/`segments`/`words` in addition to `srt_url`/`srt_content`.","`--model-size` is intentionally not supported; ASR uses the server-side Qwen3 + stable-ts pipeline."],whenToUse:["You have an audio URL and need SRT subtitles (single language or auto-detect)","Music-video phase 01 / shot-by-shot caption work that needs subtitle timing"],whenNotToUse:["You need beat / tempo analysis (use `dl analyze-beats` instead)","You need to download a remote video before transcribing — `dl transcribe` only accepts a public URL"],examples:[{caption:"auto-detect language, return SRT only when callback lands",command:'dl transcribe --audio-url="https://cdn.example.com/voice.mp3" --language=auto'},{caption:"request word timestamps in callback payload",command:'dl transcribe \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --language=en \\\n --word-timestamps'},{caption:"align an existing transcript without ASR recognition",command:'dl transcribe \\\n --audio-url="https://cdn.example.com/song.mp3" \\\n --transcript-text="Known lyric line. Next lyric line." \\\n --language=auto'}],notExamples:[{command:'nohup dl transcribe --audio-url="https://cdn.example.com/voice.mp3" --language=zh > /tmp/asr.json &',whyItFails:"transcribe is async — submit returns immediately and the result arrives as [async-callback] in a later turn. Backgrounding orphans the child when the sandbox is reclaimed and there is no job_ref to poll."},{command:'dl transcribe --audio-url="https://cdn.example.com/voice.mp3" --model-size=large-v3',whyItFails:"`--model-size` is no longer a valid CLI flag; model selection is server-side"},{command:'dl transcribe --params=\'{"audio_url":"...","language":"auto"}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"},{command:"dl transcribe --audio-url=face.mp3",whyItFails:"audio_url must be a fully-qualified public URL; raises E_BACKEND"}],outputSingle:'{"ok":true,"status":"pending","job_ref":"<uuid>","data":{"task_id":"ag:asr:qwen3-asr:<id>","status":"pending"}}',transformResult:bd,preflightTopic:{intro:"Confirm these 4 items before the first dl transcribe call:",decisions:[{name:"Audio URL is publicly reachable",description:"audio_url must be a publicly accessible URL (or platform-internal storage URL).\nFor private buckets (GCS / S3) sign the URL first. Local file paths / data: URIs are rejected."},{name:"Language hint",description:"--language=auto (default) works for most content; explicitly write the\nISO-639-1 code (en / zh / ja / es / fr) when the language is known — improves\nASR accuracy and speed."},{name:"Callback payload mode (pick one)",description:'Default callback payload: srt_content + srt_url only (token-thrifty, fits direct caption rendering).\n--word-timestamps: callback also includes text + segments + words (word-level timing,\n for MV beat alignment / lip-sync / by-word fine cut).\n--transcript-text="...": skips ASR recognition; ASR vendor only time-aligns the given text\n to the audio (use for user-supplied lyrics / pre-edited transcripts / alignment-after-other-ASR).'},{name:"Tuning (optional)",description:"--vad-filter: enables stable-ts VAD for cleaner segment splitting.\n--denoise-audio: ASR defaults to true (Demucs denoising / vocal separation); make explicit if you want.\n--max-segment-duration=5: readable upper bound per caption line in seconds; 5 is usually enough."}],notes:["Async by default — submit returns `{status:'pending', job_ref, data:{task_id}}` immediately; end the turn and wait for `[async-callback] job=<ref>`. See `dl transcribe async -h`.","Do NOT pass --model-size — it's not a valid CLI flag (server-side picks the pipeline)","Server-side budget is ~590s per identification (cold-start GPU + long denoised audio can hit this); pre-split very long audio if a single segment risks this limit"]},policyTopic:{intro:"Four hard rules: User-facing isolation / Package gate / Default callback trim / Server-side model selection.",rules:[{title:"1. User-Facing Communication — never leak internal details",body:["Vendor / internal pipeline (Qwen3-ASR / stable-ts / DTW) / trace id must NOT","surface to the end user. User-facing summary only mentions: action (transcribe /","caption / time-align) + language + duration."]},{title:"2. Production Package Gate — never call before authorization",body:["Audio source / target language / word-level need / downstream usage (caption render","vs beat sync vs alignment of known text) are all components of the paid production","package authorization. Do not call before the package is authorized; once authorized,","batch within the package by parallel `dl transcribe` calls (no `--jobs-file`; api-layer","already fan-outs jobs server-side). Only re-ask on package overflow (language switch /","adding word-level / adding text alignment / fallback / paid regeneration).","","Cost reference: 50 platform tokens / transcription, ~590s server-side ASR budget per identification."]},{title:"3. Default Callback Trim — word-timestamps controls the callback payload, not the CLI response",body:["The CLI `dl transcribe` response is always the submit acknowledgement:","`{ok:true, status:'pending', job_ref, data:{task_id}}`. The SRT lives in the","`[async-callback]` payload that lands in a later turn.","","By default the callback payload's `result` carries srt_content + srt_url only.","The text / segments / words fields are **intentionally dropped** from the callback","payload to save tokens. Only pass --word-timestamps when the caller explicitly","needs word-level timing (MV beat sync / lip-sync alignment / by-word fine cut).","Phase 01 storyboards typically need default SRT only; downstream caption renderers","(create-subtitles) also consume srt_content / srt_url directly."]},{title:"4. Server-side Model Selection — --model-size is NOT exposed",body:["The ASR pipeline is server-selected (Qwen3-ASR for text + stable-ts for","timestamps + DTW fallback for alignment). There is no --model-size CLI flag.","Passing it raises E_UNKNOWN_OPTION."]}]},compositionTopic:{intro:"transcribe is an atomic skill — it only produces SRT + optional word-level timing. Downstream caption rendering / beat cutting / alignment publishing are NOT this verb's responsibility.",integrations:[{skill:"create-subtitles (caption rendering)",rule:["The create-subtitles SOP consumes transcribe's callback `result.srt_url` / `srt_content`,","then runs dl render-caption / ffmpeg to burn subtitles. transcribe only","emits the SRT — styling / fonts / burn-in are not its job."]},{skill:"lipsync / hyperframes-cli (lip alignment / beat-driven animation)",rule:["Beat-driven animation / lip alignment workflow: transcribe --word-timestamps →","feed callback `result.words[]` to hyperframes-cli for beat anchoring, or feed","`result.segments[]` to dl lipsync as a prompt condition. These workflows explicitly","need word-level timing, so set --word-timestamps; default trimming drops these","fields from the callback payload."]},{skill:"publish_content (delivering the SRT file to the user)",rule:["If the final deliverable is a .srt file (no further downstream rendering),","go through publish_content's subtitle / transcript slot; see the publish-related","skill for details."]},{skill:"create-complex-music-video-from-music (audio_analysis artifact slot)",rule:["Persist post-fallback transcript to the `audio_analysis` slot via read-modify-write:","`dl artifact read` → set `transcription.text` / `srt_content` / `language` / `segments[]`","(preserve existing `beats` / `track`) → `dl artifact write --contract='<ARTIFACT_CONTRACT_PATH>'`.","Two separate Bash calls. Full procedure: skills/audio-transcription/SKILL.md."]}]},asyncTopic:{intro:["dl transcribe is async via the api-layer task queue (#395). Submit returns","`{ok:true, status:'pending', job_ref, data:{task_id}}` immediately and exits — **do NOT poll**.","The transcription result arrives later as `[async-callback] job=<ref>` user message that","re-enters the session in a new turn.","","End the turn after submit. Do NOT wrap the call in `nohup ... &`, do NOT poll in a","`sleep`/`for`/`while` loop, and do NOT call `dl poll` proactively — see customPrompt §9","for the async detach rules that govern all submit-style verbs."],resultShape:['// Callback payload\'s "result" object (default — srt only)','{ "success": true, "language": "en", "duration": 12.408,',' "srt_content": "1\\n00:00:00,000 --\x3e 00:00:02,500\\nFirst segment of speech.\\n",',' "srt_url": "https://storage.googleapis.com/dramaland-public/asr/srt/<date>/<hash>.srt",',' "alignment_method_used": "stable-ts", "alignment_quality": "high" }','// alignment_quality ∈ "high" | "medium" | "low" or absent — only "high" trustworthy (see Quality fallback note).',"",'// With --word-timestamps, the callback "result" also includes:','{ "text": "...", "segments": [{"id":0,"start":0.0,"end":2.5,"text":"..."}],',' "words": [{"word":"First","start":0.0,"end":0.4,"probability":0.98}] }'],notes:["⚠ Do NOT write a bash poll loop (while sleep + dl poll) — agent runtime async rules forbid it (#389)","Lost-callback escape hatch: if significantly more than the expected window (~5-60s short / longer for cold-start GPU / multi-minute audio) passes without `[async-callback]` landing, you may do exactly ONE single-shot `dl poll --job-ref=<ref>` — never in a loop. See customPrompt §9.","Batch fan-out: api-layer queues each transcribe submit independently — for multiple audios call `dl transcribe` in parallel; do NOT use `--jobs-file` (supportsBatch is false on this verb).","Quality fallback: when `result.alignment_quality` is `low` / `medium` / missing, word-level timing is unreliable. Call the built-in `understand_media` tool on the same audio to recover a clean transcript, then resubmit `dl transcribe --audio-url=<same> --transcript-text=<clean> --word-timestamps=true` to time-align via DTW. The second callback supersedes the first — do not mix segments across the two. Full procedure: skills/audio-transcription/SKILL.md → 'Low alignment_quality → understand_media fallback'."]},publishTopic:{intro:["transcribe atomic does NOT call publish_content directly. Its outputs","srt_content / srt_url usually feed downstream caption renderers","(create-subtitles / hyperframes-cli).","If the final deliverable is the SRT itself, map publish_content fields as:"],fields:[{name:"presentation_family",value:"'document' or 'caption-bundle' (per publish_content schema)"},{name:"media_urls.subtitle",value:"<srt_url>"},{name:"delivery_format",value:"'srt'"}]}})}(_d),function(e){sc(e,"generate-image-prompt","prompt"),sc(e,"generate-image-ref","ref"),function(e){e.command("generate-image",{hidden:!1}).allowUnknownOption(!0).allowExcessArguments(!0).description("Deprecated ambiguous image generation command. Use generate-image-prompt or generate-image-ref.").action(()=>{ys("E_DEPRECATED","`dl generate-image` is ambiguous and has been retired.","Use `dl generate-image-prompt` for prompt-only generation, or `dl generate-image-ref` when any source/reference image is required.",{replacements:["generate-image-prompt","generate-image-ref"]})})}(e)}(_d),function(e){Ps(e,{verb:"generate-video",actionName:"generate_video",schema:Jo,supportsBatch:!0,billing:{schema:El,select:e=>({service:e.service,duration:e.duration,resolution:e.resolution}),quote:Tl},approvalPreview:e=>function(e){const t=[...vc("image",dc(e.image_url),"Image input"),...vc("image",dc(e.image_urls),"Reference image"),...vc("image",dc(e.urls),"Reference URL"),...vc("image",dc(e.last_frame_url),"Last frame"),...vc("image",dc(e.end_image_url),"End frame"),...yc(e.keyframes),...(i=e.elements,Array.isArray(i)?i.flatMap((e,t)=>{const i=_c(e);if(!i)return[];const n=t+1,o=uc([...dc(i.url),...dc(i.image_url),...dc(i.frontal_image_url)]),r=dc(i.reference_image_urls);return[...o.map((e,t)=>({kind:"image",url:e,label:1===o.length?`Element ${n}`:`Element ${n}.${t+1}`})),...r.map((e,t)=>({kind:"image",url:e,label:`Element ${n} ref ${t+1}`}))]}):[])];var i;const n=[...vc("video",dc(e.video_url),"Source video"),...vc("video",dc(e.ref_video_url),"Reference video"),...vc("video",dc(e.video_urls),"Reference video")],o=[...vc("audio",dc(e.reference_audio_url),"Reference audio"),...vc("audio",dc(e.audio_url),"Driving audio")],r=uc(dc(e.ark_asset_ids)).map((e,t)=>({label:`Asset ${t+1}`,value:e})),a=[];mc(a,"Service",e.service),mc(a,"Duration",e.duration),mc(a,"Aspect ratio",e.aspect_ratio),mc(a,"Resolution",e.resolution),mc(a,"Mode",e.mode),mc(a,"Quality",e.quality_preset),mc(a,"Seed",e.seed),"number"==typeof e.width&&"number"==typeof e.height&&a.push({label:"Dimensions",value:`${e.width}x${e.height}`}),mc(a,"Generate audio",e.generate_audio),mc(a,"Sound",e.sound),mc(a,"Draft",e.draft),mc(a,"Camera fixed",e.camera_fixed),mc(a,"Audio setting",e.audio_setting),mc(a,"Reference subject",e._reference_subject_type),mc(a,"CFG scale",e.cfg_scale);const s=[pc(e.service),"number"==typeof e.duration?`${e.duration}s`:void 0].filter(e=>!!e).join(" · ");return{kind:"generate_video",title:"Video generation",...s?{summary:s}:{},sections:[gc("Prompt",e.prompt),gc("Negative prompt",e.negative_prompt),hc("Image / keyframe references",t),hc("Video references",n),hc("Audio references",o),fc("Asset references",r),fc("Details",a)].filter(e=>void 0!==e)}}(e),strictBatchParams:!0,description:"Generate a short video clip from a text prompt (optionally seeded with reference images / audio).",notes:["Prompt placeholders are 1-indexed and get substituted at submit time:"," @imageN → image_urls[N-1] @audioN → reference_audio_url"," @videoN → ref_video_url @assetN → ark_asset_ids[N-1]"," @assetN can point at a registered Image / Video / Audio asset; Seedance routes by asset type.","","--prompt supports loading from a JSON file:"," --prompt=@file:/abs/path.json#/json/pointer"," When prefixed with @file:, extract a string per RFC 6901 JSON Pointer as the prompt.","","--refs-from bulk-binds reference assets from a JSON file such as a storyboard:"," --refs-from=@file:/abs/storyboard.json#/segments/0/references"," The pointer must point at a [{element_id, url}, ...] array; element_id routes by prefix:"," image* → image_urls, asset* → ark_asset_ids,"," audio* → reference_audio_url, video* → ref_video_url."," If a video has already been registered as an asset, route it as asset* / @assetN, not video* / @videoN.","If Seedance audio output is moderation-blocked, retry with prompt text like 'no BGM' / 'no background music'; do not pass --generate-audio.","Seedance 2.0 分辨率:Pro(seedance-2-0)支持小写 480p / 720p / 1080p / 4k;Fast / Mini 仅支持 480p / 720p。"," 4K 成片必须使用 --service=seedance-2-0 --resolution=4k,价格为 720 credits/s。","","FEEDBACK-BASED GUARDRAILS — avoid the common expensive failures:"," 1. Short continuous video → prefer one Seedance clip; do NOT split only because the prompt has multiple visual beats."," 2. Identity-critical work (real face / selfie / actor / artist / fixed character) → choose a reference-consistent model first; weak reference-following models can produce random people."," 3. Real-looking human / known-IP with Seedance 2.0 → register assets first, then reference @assetN; do not rely on raw media URLs."," 4. Before submitting a segment, check whether a successful or pending job already exists; never resubmit unless the user explicitly asks for regeneration."," 5. Multi-segment / long-form workflows (N>=4 segments or >30s total) → run a sample wave first: 1-3 representative segments, show playable URLs, get explicit user OK before full batch."," 6. For multi-segment lip-sync workflows, use dl lipsync for the sample wave and prove one representative clip before committing a large batch."," 7. Fallback is allowed, but non-Seedance models need role-locked frames/keyframes first; do not pass --ark-asset-ids or @assetN to Veo/Grok/Kling.","","⚠ SEEDANCE 2.0 ASSET RULES (seedance-2-0 / seedance-2-0-fast / seedance-2-0-mini) — read before composing the call:"," 1. Real-person / known-IP media input MUST go through `dl asset register` first;"," passing a raw real-person media URL via --image-url / --image-urls / --ref-video-url is blocked by upstream policy."," 2. Once an image / video / audio is registered as an asset, reference it ONLY via --ark-asset-ids + @assetN"," in the prompt. Do NOT also pass that same media through --image-url / --image-urls / --ref-video-url —"," the two channels are mutually exclusive for the same media; double-passing wastes a ref"," slot and produces unpredictable routing on the vendor side."," 3. Set --reference-subject-type=real_person on real-person asset calls."," 4. Registered Video assets are supported; pass them as --ark-asset-ids + @assetN, not --ref-video-url + @videoN."," 5. --image-urls / --ref-video-url are reserved for non-registered scene / prop / video refs that are NOT real people."," 6. ARK r2v counts all reference_video inputs together and requires total reference-video duration <=15.2s."," Multiple video refs are allowed only when they are distinct and the combined duration is within the limit;"," never pass the same video twice as both --ark-asset-ids/@assetN and --ref-video-url/@videoN."," Full constraint list: `dl generate-video model seedance-2-0` (or `model seedance-2-0-fast` / `model seedance-2-0-mini`)."],whenToUse:["You need a short clip (2–10s) from a prompt","You need image-to-video (i2v) using the @imageN placeholders","Multi-segment storyboards with discrete scenes: split intentionally and fan out via --jobs-file"],whenNotToUse:["You need lip-sync — use `dl lipsync`","You need motion transfer between two videos — use `dl motion-control`","You need still images — use `dl generate-image-prompt` for prompt-only images or `dl generate-image-ref` when source/reference images are required"],examples:[{caption:"single, seedance-2-0",command:'dl generate-video \\\n --service=seedance-2-0 \\\n --prompt="a corgi astronaut floating, slow zoom in" \\\n --duration=5 \\\n --resolution=720p'},{caption:"i2v with reference frame",command:'dl generate-video \\\n --service=dli2v3 \\\n --prompt="@image1 starts moving forward into the snow" \\\n --image-urls="https://1.png" \\\n --duration=4'},{caption:"prompt + references from storyboard JSON",command:'dl generate-video \\\n --service=seedance-2-0 \\\n --prompt="@file:/abs/storyboard.json#/segments/0/detail/prompt" \\\n --refs-from="@file:/abs/storyboard.json#/segments/0/references" \\\n --duration=10 --resolution=720p'}],notExamples:[{command:'dl generate-video --params=\'{"service":"seedance-2-0","prompt":"..."}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"url":"https://storage.../video.mp4","duration_ms":5000}}',outputBatch:'{"ok":true,"action":"generate_video","results":[\n {"job_key":"scene_01","job_ref":"<uuid>","status":"pending"},\n ...\n]} // batch is non-blocking; each completed job is pushed back to the session via [async-callback]',extraFlags:[{spec:"--refs-from <ref>",description:"Bulk-bind reference assets: @file:PATH#POINTER, pointer must point at a [{element_id, url}, ...] array"}],transformParams:(e,t)=>{let i=e;if(Ss(i.prompt)){const e=Es(i.prompt,{flag:"--prompt",requireString:!0});i={...i,prompt:e}}if("single"===t.mode){const e=t.opts?.refsFrom;"string"==typeof e&&""!==e&&(i=function(e,t){const i={...e};if(t.image_urls.length>0){const e=kc(i.image_urls);i.image_urls=xc([...t.image_urls,...e])}if(t.ark_asset_ids.length>0){const e=kc(i.ark_asset_ids);i.ark_asset_ids=xc([...t.ark_asset_ids,...e])}return t.reference_audio_url&&void 0===i.reference_audio_url&&(i.reference_audio_url=t.reference_audio_url),t.ref_video_url&&void 0===i.ref_video_url&&(i.ref_video_url=t.ref_video_url),i}(i,function(e){if(!Ss(e))throw new wa("E_SCHEMA",`${wc} 仅支持 @file:PATH#POINTER 语法,收到:${e}`,"示例:--refs-from=@file:/abs/storyboard.json#/segments/0/references",{flag:wc});const t=Es(e,{flag:wc});if(!Array.isArray(t))throw new wa("E_SCHEMA",`${wc} JSON Pointer 命中的不是数组(实际类型:${typeof t})`,"references 应该是 [{element_id, url}, ...] 形式",{flag:wc});return function(e){const t={image_urls:[],ark_asset_ids:[]},i=[],n=[],o=[],r=[];if(e.forEach((e,t)=>{if(!e||"object"!=typeof e)throw new wa("E_SCHEMA",`${wc} references[${t}] 不是对象(实际:${null===e?"null":typeof e})`,void 0,{flag:wc});const a=e,s=a.element_id,l=a.url;if("string"!=typeof s||""===s)throw new wa("E_SCHEMA",`${wc} references[${t}].element_id 缺失或不是非空字符串`,void 0,{flag:wc});if("string"!=typeof l||""===l)throw new wa("E_SCHEMA",`${wc} references[${t}].url 缺失或不是非空字符串(element_id=${s})`,void 0,{flag:wc});const c=/^([a-z]+)(\d*)$/i.exec(s);if(!c)throw new wa("E_SCHEMA",`${wc} references[${t}].element_id 不符合 <prefix><N?> 规范:${s}`,"形如 image1 / asset2 / audio1 / video1",{flag:wc});const d=c[1].toLowerCase(),u=c[2],p=""===u?0:Number(u);switch(d){case"image":o.push({n:p,id:s,url:l});break;case"asset":r.push({n:p,id:s,url:l});break;case"audio":i.push({id:s,url:l});break;case"video":n.push({id:s,url:l});break;default:throw new wa("E_SCHEMA",`${wc} 未知的 element_id 前缀:${s}`,"支持:image / asset / audio / video(后缀数字可选,作为排序)",{flag:wc})}}),i.length>1)throw new wa("E_SCHEMA",`${wc} 最多只能有一个 audio* 引用(实际 ${i.length}:${i.map(e=>e.id).join(", ")})`,void 0,{flag:wc});if(n.length>1)throw new wa("E_SCHEMA",`${wc} 最多只能有一个 video* 引用(实际 ${n.length}:${n.map(e=>e.id).join(", ")})`,void 0,{flag:wc});return o.sort((e,t)=>e.n-t.n),r.sort((e,t)=>e.n-t.n),t.image_urls=o.map(e=>e.url),t.ark_asset_ids=r.map(e=>e.url),i[0]&&(t.reference_audio_url=i[0].url),n[0]&&(t.ref_video_url=n[0].url),t}(t)}(e)))}return i},preflight:e=>{const t=String(e.service??"");if(function(e,t){if(!Sc(t))return;if("seedance-2-0-mini"===t&&"number"==typeof e.duration&&(e.duration<5||e.duration>12))throw new wa("E_SCHEMA","--duration must be between 5 and 12 for seedance-2-0-mini","Seedance 2.0 Mini supports 5-12s for text-to-video. Pick an integer duration in that range, then trim the final segment after generation if needed.",{verb:"generate-video",service:t,flag:"--duration"});if("string"!=typeof e.resolution)return;const i="seedance-2-0"===t?["480p","720p","1080p","4k"]:["480p","720p"];if(!i.includes(e.resolution)){const e=i.join(", ");throw new wa("E_SCHEMA",`--resolution must be one of ${e} for ${t}`,"seedance-2-0"===t?"Seedance 2.0 Pro 支持 480p、720p、1080p 和 4k;请使用小写 4k。":"Seedance 2.0 Fast / Mini 仅支持 480p 和 720p;1080p 与 4k 会被拒绝且不计价。",{verb:"generate-video",service:t,flag:"--resolution"})}}(e,t),function(e,t){if(Sc(t))return;const i=Array.isArray(e.ark_asset_ids)&&e.ark_asset_ids.length>0,n="string"==typeof e.prompt?e.prompt:"",o=/@asset\d+\b/.test(n);if(i||o)throw new wa("E_SCHEMA",`Seedance asset references require --service=seedance-2-0, --service=seedance-2-0-fast, or --service=seedance-2-0-mini, not ${t}`,"Fallback is allowed, but rebuild the segment for the target model first: generate role-locked frame/keyframe images from the character reference, then pass those frames through --image-url / --image-urls / --keyframes as supported by that model. Do not pass --ark-asset-ids or @assetN to non-Seedance services.",{verb:"generate-video",service:t,expected:"seedance-2-0|seedance-2-0-fast|seedance-2-0-mini",flag:i?"--ark-asset-ids":"--prompt"})}(e,t),function(e,t){if("grok-imagine-1.5"!==t)return;const i="string"==typeof e.image_url&&""!==e.image_url.trim(),n=Array.isArray(e.image_urls)?e.image_urls.filter(e=>"string"==typeof e):[];if(!i)throw new wa("E_SCHEMA","--image-url is required for grok-imagine-1.5","Grok Imagine 1.5 is exposed through api-layer as a single-reference image-to-video service. Pass exactly one reference via --image-url.",{verb:"generate-video",service:t,flag:"--image-url"});if(n.length>0)throw new wa("E_SCHEMA","--image-urls is not supported for grok-imagine-1.5","Use --image-url for the single reference image. Do not pass multi-reference images to Grok Imagine 1.5.",{verb:"generate-video",service:t,flag:"--image-urls"});if("number"==typeof e.duration&&(e.duration<1||e.duration>15))throw new wa("E_SCHEMA","--duration must be between 1 and 15 for grok-imagine-1.5","Pick an integer duration from 1 to 15 seconds.",{verb:"generate-video",service:t,flag:"--duration"});if("string"==typeof e.resolution&&"480p"!==e.resolution&&"720p"!==e.resolution)throw new wa("E_SCHEMA","--resolution must be 480p or 720p for grok-imagine-1.5","Use --resolution=480p or --resolution=720p. Other tiers are not supported by the api-layer Grok 1.5 provider.",{verb:"generate-video",service:t,flag:"--resolution"});if("string"==typeof e.aspect_ratio&&!["auto","1:1","16:9","9:16","4:3","3:4","3:2","2:3"].includes(e.aspect_ratio))throw new wa("E_SCHEMA","--aspect-ratio is not supported for grok-imagine-1.5","Use one of: auto, 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3.",{verb:"generate-video",service:t,flag:"--aspect-ratio"})}(e,t),"dlai2v_pro"!==t&&"dlai2v_pro_multiframe"!==t)return;const i="string"==typeof e.image_url&&""!==e.image_url,n=Array.isArray(e.keyframes)&&e.keyframes.length>0;if("string"!=typeof e.audio_url||""===e.audio_url)throw new wa("E_SCHEMA",`--audio-url is required for ${t} (the LTX 2.3 workflow derives video length from the driving audio)`,"pass --audio-url=<driving audio>; output length follows the audio. Do NOT use --duration to control length (billing-only here)",{verb:"generate-video",service:t});if(!i&&!n)throw new wa("E_SCHEMA",`either --image-url or --keyframes is required for ${t}`,"provide a face/scene still via --image-url, or multiple keyframes via --keyframes",{verb:"generate-video",service:t});if(i&&n)throw new wa("E_SCHEMA","--image-url and --keyframes are mutually exclusive","use --image-url for a single still (api-layer wraps it into keyframes[0]), or --keyframes for explicit multi-frame guidance; not both",{verb:"generate-video",service:t});if("dlai2v_pro_multiframe"===t){if(!n)throw new wa("E_SCHEMA","dlai2v_pro_multiframe requires --keyframes (2-4 frames); --image-url alone is not supported","pass 2-4 --keyframes flags; if you only have 1 image, use --service=dlai2v_pro instead",{verb:"generate-video",service:t});const i=e.keyframes.length;if(i<2||i>4)throw new wa("E_SCHEMA",`dlai2v_pro_multiframe requires 2-4 keyframes, got ${i}`,"adjust to 2/3/4 keyframes; api-layer routes to mutiframe_{2f,3f,4f} workflow by count",{flag:"--keyframes",verb:"generate-video",service:t})}else if(n&&e.keyframes.length>5)throw new wa("E_SCHEMA",`--keyframes accepts 1-5 frames for dlai2v_pro, got ${e.keyframes.length}`,"reduce to at most 5 keyframe images, or switch to --service=dlai2v_pro_multiframe (2-4 frames)",{flag:"--keyframes",verb:"generate-video",service:t})},modelTopic:{rankingSummary:["Overall quality tiers (strongest to weakest):"," 🥇 Top tier: seedance-2-0 family (Pro + Fast + Mini)"," 🥈 Runner-up tier: happyhorse-1-0-* family (r2v / i2v / video-edit)"," 🥈 Unique-capability tier: kling-o3-pro-v2v / kling-o3-v2v (video-to-video editing — Kling-side alternative to happyhorse-1-0-video-edit)"," 🥉 Third tier: rest of kling-o3-* family (ref2v Pro / std) + kling3.0"," Below that: dli2v3 / dlim2v / seedance-1-5","","This ranking is overall quality (character consistency / camera stability / physical plausibility / duration cap);","it does NOT mean you should always pick the top tier — special scenarios (video edit / Chinese prompt /","multi-ref) have exclusive capabilities per family.","","Note: seedance-2-0-fast and seedance-2-0-mini are cheaper variants of the same generation/family with the same","field shape (auto-keyframe / multi-ref / audio coupling / video ref continuation). Fast remains the quality/cost","baseline; Mini is the lowest-cost Seedance 2.0 option for draft / preview and budget-sensitive MV segments.","","Separate category — audio-driven talking / singing video (lip-synced, output length = driving audio, --audio-url REQUIRED):"," dlai2v_pro (single still or 1-5 keyframes) / dlai2v_pro_multiframe (2-4 keyframes, richer movement)"," — same LTX-2.3 engine as the matching `dl lipsync` services; use whichever verb your pipeline composes through."," longcat-avatar-1-5 (self-hosted; very stable lip-sync but slow ~8-10min)."," These are NOT ranked against the t2v/i2v tiers above — they solve a different problem."],services:[{service:"seedance-2-0",label:"Seedance 2.0 Pro",tier:"🥇 Top tier (Pro)",bestFor:"Overall strongest quality. Character consistency + auto-keyframe + video ref / continuation + audio-coupled generation — the fullest feature set. Expensive and requires asset register (for real-looking human / IP scenarios you must first call dl asset register)",quality:"Very High",speed:"2-5min",cost:"high",description:["ByteDance Seedance 2.0 Pro. Currently strongest overall quality, fullest capability set:"," - auto-keyframe (auto-generates multiple keyframes)"," - multi-reference images (image_urls)"," - video ref / continuation (raw video via ref_video_url, registered video via ark_asset_ids + @assetN)"," - audio coupling (reference_audio_url + @audio1)"," - duration <=15s or -1 for auto"," - resolution 480p / 720p / 1080p / 4k(4k 仅 Pro;720 credits/s)"],promptTips:["Placeholders are 1-indexed: @imageN → image_urls[N-1] / @audioN → reference_audio_url / @videoN → ref_video_url / @assetN → ark_asset_ids[N-1]","Registered Image / Video / Audio assets all use @assetN; do not switch a registered video asset back to @videoN","For audio + image lip-sync scenarios use dl lipsync — do not force-fit them into generate-video","reference_audio_url must be ≤15s and cannot be the only reference on its own (must be paired with image_urls or ref_video_url)"],constraints:["Real-looking human / known-IP inputs must be passed through dl asset register first; after registration pass that source ref via --ark-asset-ids + @assetN only, never again via --image-urls + @imageN or --ref-video-url + @videoN","Registered Video assets are valid Seedance refs; pass the asset id through --ark-asset-ids and mention @assetN in the prompt","r2v reference-video limit: ARK requires the total duration of all reference_video inputs to be <=15.2s. Multiple video refs are allowed only when they are distinct and their combined duration stays within the limit; never pass the same video twice as both registered Video asset and raw --ref-video-url.","If generated/output audio triggers moderation, retry with prompt text such as 'no BGM' / 'no background music'; do not pass --generate-audio","Field-name trap: use ref_video_url (not video_url) / reference_audio_url (not audio_url) — get it wrong and the vendor silently drops the ref","duration 4-15s or -1 (auto); the Pi CLI currently requires integer — use ceil(intended) then ffmpeg trim","Read skills/video-generation/docs/seedance_reference_assets.md (real-looking human scenarios)"],flagSubset:["service","prompt","duration","aspect-ratio","resolution","image-urls","reference-audio-url","ref-video-url","ark-asset-ids","generate-audio","reference-subject-type"],examples:[{caption:"single, seedance-2-0 with @audio1 + image ref",command:'dl generate-video --service=seedance-2-0 \\\n --prompt="the character speaks @audio1 with clear articulation, @image1 sets the scene" \\\n --duration=8 --aspect-ratio=16:9 --resolution=720p \\\n --image-urls=https://.../keyframe.jpg \\\n --reference-audio-url=https://.../speech.mp3'},{caption:"real-looking human with asset register",command:'# Register asset first\ndl asset register --group-id=actor-jane --name=jane-headshot \\\n --url=https://.../actor.jpg --asset-type=Image\n# Then generate (use the real asset_id from the previous step\'s response)\ndl generate-video --service=seedance-2-0 \\\n --prompt="@asset1 walks through a cyberpunk street, no BGM" \\\n --duration=6 --resolution=720p \\\n --ark-asset-ids=asset_xxx \\\n --reference-subject-type=real_person'},{caption:"registered reference video asset",command:'# Register video asset first\ndl asset register --group-id=healthfood-girl --name=tiktok-healthfood-ref \\\n --url=https://.../reference.mp4 --asset-type=Video\n# Then generate (use the real asset_id from the previous step\'s response)\ndl generate-video --service=seedance-2-0 \\\n --prompt="follow @asset1 for camera structure and action rhythm, no BGM" \\\n --duration=6 --aspect-ratio=9:16 --resolution=720p \\\n --ark-asset-ids=asset_xxx'}]},{service:"seedance-2-0-fast",label:"Seedance 2.0 Fast",tier:"🥇 Top tier (Fast variant)",bestFor:"Same family and capabilities as Pro (auto-keyframe / multi-ref / audio coupling / video ref), just slightly lower quality than Pro, faster, and cheaper. Prefer this when Pro is too expensive or you only need a preview — do not drop to a lower-tier model instead",quality:"Very High",speed:"1-3min",cost:"mid",description:["The Fast variant of seedance-2-0. Same family and capability set, slightly lower quality / faster / cheaper.","For default scenarios with no special requirements → pick this; do not default to Pro and do not default to a lower-tier."],constraints:["Constraints are identical to seedance-2-0: real-looking human / IP and registered video refs must go through asset register and then asset-only for that source ref (do not also pass its URL in image_urls or ref_video_url); ARK r2v reference_video total duration <=15.2s; distinct multi-video refs are allowed, but do not pass the same video twice through asset + raw URL; ref_video_url / reference_audio_url field-name trap; duration 4-15s integer; audio moderation fallback is prompt text 'no BGM', not --generate-audio","分辨率仅支持 480p / 720p;不支持 1080p / 4k"],flagSubset:["service","prompt","duration","aspect-ratio","resolution","image-urls","reference-audio-url","ref-video-url","ark-asset-ids","generate-audio"],examples:[{caption:"single, seedance-2-0-fast (default first choice)",command:'dl generate-video --service=seedance-2-0-fast \\\n --prompt="a corgi astronaut floating, slow zoom in" \\\n --duration=5 --resolution=720p'}]},{service:"seedance-2-0-mini",label:"Seedance 2.0 Mini",tier:"🥇 Top tier family (Mini / lowest-cost Seedance 2.0)",bestFor:"Lowest-cost Seedance 2.0 family option. Use it as the default low-cost preview / MV non-lipsync workhorse when budget matters more than Pro/Fast quality. Prefer Fast or Pro for hero shots, identity-critical close-ups, or final high-quality passes.",quality:"High",speed:"1-3min",cost:"low",description:["Dreamina Seedance 2.0 Mini via BytePlus ARK. Same command shape as seedance-2-0 / fast.","Model: dreamina-seedance-2-0-mini-260615. Supports 480p / 720p, 5-12s text-to-video, 24fps, and one concurrent upstream task.","Credits: 35 credits/s at 480p, 75 credits/s at 720p. 1080p / 4k 均不支持且不计价。"],constraints:["Reference rules are identical to seedance-2-0: real-looking human / IP and registered video refs must go through asset register and then asset-only for that source ref; do not also pass its URL in image_urls or ref_video_url","r2v reference-video limit: ARK requires total reference_video duration <=15.2s. Distinct multi-video refs are allowed, but do not pass the same video twice through asset + raw URL.","Resolution 仅支持 480p / 720p;1080p / 4k 会被拒绝且不计价","Duration 5-12s for text-to-video; use integer duration and trim after generation if the final segment is shorter","Field-name trap: use ref_video_url (not video_url) / reference_audio_url (not audio_url)"],flagSubset:["service","prompt","duration","aspect-ratio","resolution","image-urls","reference-audio-url","ref-video-url","ark-asset-ids","generate-audio"],examples:[{caption:"single, seedance-2-0-mini low-cost preview",command:'dl generate-video --service=seedance-2-0-mini \\\n --prompt="a cinematic handheld shot of a quiet neon alley, no BGM" \\\n --duration=5 --resolution=720p --aspect-ratio=16:9'}]},{service:"happyhorse-1-0-r2v",label:"HappyHorse 1.0 R2V (Alibaba)",tier:"🥈 Runner-up tier",bestFor:"Overall runner-up to seedance. Made by Alibaba, strong on Chinese prompts. 1-9 ref multi-subject composition",quality:"High",speed:"2-5min",cost:"mid",description:["Alibaba HappyHorse 1.0 reference-to-video (multi-ref composition).","Markedly better on Chinese prompts than other families; 1-9 reference images for multi-subject composition."],constraints:["image_urls 1-9 images is REQUIRED; prompt is also REQUIRED","aspect_ratio only 16:9 / 9:16 / 3:4 / 4:3 / 1:1 (no adaptive / 21:9)","resolution uses uppercase: 720P / 1080P (lowercase 720p is rejected — the opposite of other families!)","duration integer 3-15s"],flagSubset:["service","prompt","image-urls","duration","aspect-ratio","resolution","seed"],examples:[{caption:"multi-character composition",command:'dl generate-video --service=happyhorse-1-0-r2v \\\n --prompt="两个人在花园相遇,午后柔光" \\\n --image-urls=https://1.png --image-urls=https://2.png \\\n --duration=5 --resolution=1080P --aspect-ratio=16:9'}]},{service:"happyhorse-1-0-i2v",label:"HappyHorse 1.0 I2V",tier:"🥈 Runner-up tier",bestFor:"HappyHorse family — use this for the single-first-frame i2v scenario",quality:"High",speed:"2-5min",cost:"mid",description:["HappyHorse 1.0 single-first-frame image-to-video. Same family but only accepts a single image_url (not image_urls)."],constraints:["image_url (singular) is REQUIRED","resolution uppercase: 720P / 1080P (default 1080P)","duration 3-15s integer (default 5)"],flagSubset:["service","prompt","image-url","duration","resolution","seed"],examples:[{caption:"single first-frame i2v",command:'dl generate-video --service=happyhorse-1-0-i2v \\\n --prompt="角色缓慢转身,镜头微微推近" \\\n --image-url=https://.../first-frame.jpg \\\n --duration=5 --resolution=1080P'}]},{service:"happyhorse-1-0-video-edit",label:"HappyHorse 1.0 Video Edit",tier:"🥈 Exclusive capability",bestFor:"HappyHorse family video-to-video edit. The only true video editor in the whole table (change style / change scene while preserving composition)",quality:"High",speed:"3-5min",cost:"mid",description:["HappyHorse video-to-video edit. **The only entry in the generate-video table** that supports true","video editing: input a video + 0-5 refs + prompt, output a new video with changed style / scene but preserved","composition."],constraints:["video_url (singular) is REQUIRED — this is the source video; the field name differs from seedance's ref_video_url and **cannot be interchanged**","image_urls 0-5 optional (repeatable flag)","audio_setting: auto (default, HappyHorse decides) or origin (preserves source audio) — does not accept a generate_audio bool","Output duration = input video duration, do not pass --duration","resolution uppercase: 720P / 1080P"],flagSubset:["service","prompt","video-url","image-urls","resolution","audio-setting","seed"],examples:[{caption:"video edit — change scene to dusk",command:'dl generate-video --service=happyhorse-1-0-video-edit \\\n --prompt="keep original composition, change scene to dusk city skyline" \\\n --video-url=https://.../source.mp4 \\\n --image-urls=https://.../style-ref.png \\\n --resolution=1080P --audio-setting=auto'}]},{service:"kling-o3-pro-ref2v",label:"Kling O3 Pro Ref2V",tier:"🥉 Third tier",bestFor:"Kuaishou Kling O3 high-spec. multi-reference + character elements + first/end frame. Overall behind happyhorse",quality:"High",speed:"3-5min",cost:"mid",description:["Kling O3 ref-to-video Pro. Supports first frame + end frame + multi-reference","+ structured JSON via --elements to control character / scene elements. Overall quality slightly","below happyhorse, but first/end frame control is the advantage."],constraints:["image_url is the first frame, optional (without it, text-to-video only)","end_image_url is the last frame","elements is structured JSON: {frontal_image_url, reference_image_urls[]}"],flagSubset:["service","prompt","image-url","end-image-url","image-urls","elements","duration","aspect-ratio"],examples:[{caption:"first + end frame control",command:'dl generate-video --service=kling-o3-pro-ref2v \\\n --prompt="smooth transition from morning to noon" \\\n --image-url=https://.../start.png \\\n --end-image-url=https://.../end.png \\\n --duration=5 --aspect-ratio=16:9'}]},{service:"kling-o3-ref2v",label:"Kling O3 Ref2V",tier:"🥉 Third tier",bestFor:"Kling O3 standard. Same as Pro but slightly lower quality / cheaper",quality:"High",speed:"2-5min",cost:"low",description:["Kling O3 standard. Same params as Pro, slightly lower quality and cheaper. Backup when Pro is too expensive."],constraints:["Parameters are the same as kling-o3-pro-ref2v"],flagSubset:["service","prompt","image-url","end-image-url","image-urls","elements","duration","aspect-ratio"]},{service:"kling-o3-pro-v2v",label:"Kling O3 Pro V2V (video-edit)",tier:"🥈 Unique capability",bestFor:"Kling O3 Pro **video editing**: input video + prompt to change the frame contents; optional image_urls / elements as auxiliary refs. Pro quality. Use as the Kling-side alternative to happyhorse-1-0-video-edit or as fallback when seedance-2-0 video ref / continuation is unavailable.",quality:"Very High",speed:"3-5min",cost:"mid-high",description:["Kling O3 Pro **V2V (video-to-video) editing**. Input an existing video, write a prompt","describing how to change the frame contents (re-style / change scene / preserve composition),","and the model edits the input video accordingly. Auxiliary references via image_urls (≤4)","or structured elements JSON. Output duration / aspect_ratio **match the input video** —","you must NOT pass --duration / --aspect-ratio.","","Business positioning: Kling-side alternative to `happyhorse-1-0-video-edit` (Alibaba","ecosystem). Also a video-edit fallback when seedance-2-0 video-ref continuation is","unavailable."],promptTips:["Prompt describes the **edit operation** (e.g., 'change style to anime', 'replace background with night city', 'preserve composition, change wardrobe to formal suit')","image_urls (≤4) act as style / element auxiliary refs, not first-frame anchors","elements is structured JSON for fine-grained element control (see --print-schema)"],flagSubset:["service","prompt","video-url","image-urls","elements","negative-prompt","cfg-scale"],constraints:["video_url REQUIRED","Output duration / aspect_ratio = input video's (do NOT pass --duration / --aspect-ratio — raises E_SCHEMA or is silently overridden)","image_urls ≤ 4 auxiliary refs (optional)","Same param contract as kling-o3-v2v; Pro is higher quality / slower / more expensive"],examples:[{caption:"v2v Pro — change scene to anime",command:'dl generate-video --service=kling-o3-pro-v2v \\\n --prompt="re-style the video into anime; preserve composition and motion" \\\n --video-url=https://.../source.mp4 \\\n --image-urls=https://.../style-ref.png \\\n --negative-prompt="blurry, low contrast" --cfg-scale=7'}]},{service:"kling-o3-v2v",label:"Kling O3 Std V2V (video-edit)",tier:"🥈 Unique capability",bestFor:"Kling O3 standard **video editing**. Same param contract as Pro v2v but slightly lower quality / cheaper / faster. The cheap alternative to happyhorse-1-0-video-edit / Pro v2v.",quality:"High",speed:"2-5min",cost:"mid",description:["Kling O3 standard V2V (video-edit). Same input contract as kling-o3-pro-v2v","(video_url + prompt + optional image_urls / elements / negative_prompt / cfg_scale).","Slightly lower quality, faster, cheaper. Use as the cheap variant of Pro v2v, or","the Kling-side cheap alternative to happyhorse-1-0-video-edit."],promptTips:["Same as kling-o3-pro-v2v: prompt describes the edit operation, not a new scene from scratch"],flagSubset:["service","prompt","video-url","image-urls","elements","negative-prompt","cfg-scale"],constraints:["Same as kling-o3-pro-v2v (video_url required, output duration / aspect_ratio match input, image_urls ≤ 4)"]},{service:"kling3.0",label:"Kling 3.0",tier:"🥉 Third tier",bestFor:"Kling legacy version, i2v + audio support",quality:"High",speed:"1-3min",cost:"low",description:["Kling 3.0 (legacy). Usable for simple i2v + audio scenarios; overall behind kling-o3-*."],constraints:["image_url REQUIRED (image-to-video only)","sound / cfg-scale / negative-prompt optional"],flagSubset:["service","prompt","image-url","duration","aspect-ratio","sound","negative-prompt","cfg-scale"],examples:[{caption:"Kling 3.0 i2v with sound",command:'dl generate-video --service=kling3.0 \\\n --prompt="character speaks calmly" \\\n --image-url=https://.../portrait.jpg \\\n --duration=10 --aspect-ratio=16:9 --sound'}]},{service:"dli2v3",label:"Veo 3.1 Fast",tier:"Below that",bestFor:"Google Veo 3.1 Fast variant, text/image-to-video. Overall behind all of the above",quality:"Mid",speed:"1-3min",cost:"low",description:["Google Veo 3.1 Fast. 1-3 reference images, overall quality is middling."],constraints:["image_url 1-3, optional; last_frame_url optional; duration auto"],flagSubset:["service","prompt","image-url","last-frame-url","aspect-ratio"],examples:[{caption:"Veo 3.1 with first frame",command:'dl generate-video --service=dli2v3 \\\n --prompt="@image1 starts moving forward into the snow" \\\n --image-urls=https://1.png --duration=4'}]},{service:"dlim2v",label:"Grok Imagine",tier:"Below that",bestFor:"xAI Grok. Creative / stylized / fun mode is the strong suit, overall quality is middling",quality:"Mid",speed:"1-3min",cost:"low",description:["xAI Grok Imagine. Creative / fun stylized is the signature; overall quality is middling."],constraints:["duration 6s or 10s","mode=normal (default)"],flagSubset:["service","prompt","image-url","duration","aspect-ratio","mode"]},{service:"seedance-1-5",label:"Seedance 1.5 Pro",tier:"Below that",bestFor:"seedance legacy (1.5, NOT the 2.0 family); only suited to draft previews (first+last frame control)",quality:"Mid",speed:"1-3min",cost:"low",description:["seedance 1.5 Pro (legacy family — not the same generation as 2.0). first frame + last frame control,","only suited to draft previews; quality is clearly below the 2.0 family."],constraints:["duration 4-12s","first/last frame URL optional; generate-audio optional"],flagSubset:["service","prompt","image-url","last-frame-url","duration","aspect-ratio","resolution","generate-audio","seed"]},{service:"grok-imagine-1.5",label:"Grok Imagine 1.5 (xAI)",tier:"Single-reference i2v",bestFor:"xAI Grok Imagine 1.5 image-to-video from a SINGLE reference image. Fast, creative / stylized motion. Keep the prompt about action / camera / mood — do NOT over-describe makeup or fine facial detail (over-specifying makeup degrades the result).",quality:"Mid-High",speed:"1-3min",cost:"low",description:["xAI Grok Imagine 1.5 (preview). Single-reference image-to-video — one reference image drives the clip."," - takes exactly ONE reference image (image_url); it is NOT a multi-ref model"," - duration 1-15s, resolution 480p / 720p"," - strong at creative / stylized motion"],promptTips:["Single reference image only — pass it via --image-url","Keep the prompt focused on motion / camera / mood; do NOT over-describe makeup or fine facial detail — over-specifying makeup makes results worse"],constraints:["image_url REQUIRED (image-to-video, single reference)","duration 1-15s; resolution 480p / 720p","aspect_ratio: auto / 1:1 / 16:9 / 9:16 / 4:3 / 3:4 / 3:2 / 2:3"],flagSubset:["service","prompt","image-url","duration","aspect-ratio","resolution"],examples:[{caption:"single-ref i2v",command:'dl generate-video --service=grok-imagine-1.5 \\\n --prompt="she turns toward the camera and smiles, soft cinematic light" \\\n --image-url=https://.../portrait.jpg \\\n --duration=6 --resolution=720p'}]},{service:"gemini-omni-video",label:"Gemini Omni Video (Google)",tier:"Exclusive capability (video editing)",bestFor:"Google Gemini Omni any-to-any video. Its standout strength is VIDEO EDITING — feed a source video + prompt and it re-works the clip impressively. Also does text-to-video and image-to-video (up to 7 reference images).",quality:"High",speed:"2-5min",cost:"mid",description:["Google Gemini Omni any-to-any multimodal video generation."," - **video editing is the killer feature**: pass a source video (--video-url) + prompt to re-edit it"," - also text-to-video and image-to-video (image_urls up to 7)"," - duration 4 / 6 / 8 / 10s; resolution 720p / 1080p / 4k; aspect 16:9 / 9:16"],promptTips:["For video editing pass the source clip via --video-url and describe the edit in the prompt","--video-start / --video-ends (seconds) optionally select a SUB-SEGMENT to edit (e.g. only 2–7s of a clip). Omit them to edit from the start; the provider caps the edited segment at 10s, so for sources longer than 10s pass an explicit ≤10s window","image_urls (≤7) act as reference subjects for generation"],constraints:["prompt REQUIRED","duration one of 4 / 6 / 8 / 10 (default 8); IGNORED when --video-url is provided — the edit follows the source segment","resolution 720p / 1080p / 4k (default 720p); aspect_ratio 16:9 / 9:16","image_urls ≤ 7 (optional); --video-url is the source for video editing (optional)","--video-start / --video-ends (seconds): OPTIONAL source segment; ends>start, (ends-start) ≤ 10s; omit → from 0 up to 10s (api-layer default, no probing needed)","editing real / recognizable people (incl. realistic digital-human avatars) may be rejected by the provider's prominent-people safety filter — not a flag issue; use a non-Google v2v service (kling-o3-v2v / happyhorse-1-0-video-edit) for those"],flagSubset:["service","prompt","duration","aspect-ratio","resolution","image-urls","video-url","video-start","video-ends","seed"],examples:[{caption:"video editing — re-work a whole source clip (add --video-start/--video-ends only to edit a sub-segment)",command:'dl generate-video --service=gemini-omni-video \\\n --prompt="restyle this clip into a rainy neon cyberpunk night, keep the subject\'s motion" \\\n --video-url=https://.../source.mp4 \\\n --resolution=720p'},{caption:"text-to-video",command:'dl generate-video --service=gemini-omni-video \\\n --prompt="a paper boat sailing down a sunlit street gutter, cinematic" \\\n --duration=8 --aspect-ratio=16:9 --resolution=720p'}]},{service:"longcat-avatar-1-5",label:"LongCat 1.5 (self-hosted)",tier:"Exclusive capability (audio-driven talking-head)",bestFor:"Audio-driven talking-head: one face image + one driving audio → a lip-synced video. Lip-sync is very stable — that is the reason to pick it; the trade-off is speed (noticeably slow, ~8-10min). Self-hosted on our own RunPod.",quality:"High (lip-sync stability)",speed:"8-10min (slow)",cost:"mid",description:["Self-hosted LongCat 1.5 audio-driven talking-head (distinct from the WaveSpeed longcat-avatar in `dl lipsync`).","Feeds a single face image + a driving audio and renders a lip-synced talking-head video."," - lip-sync is very stable — the strongest reason to pick it"," - output length follows the driving audio (do not pass --duration)"," - width / height default 1280x720 (pass both together to override)"," - noticeably slow (~8-10min); use it when lip-sync fidelity matters more than turnaround"],promptTips:["image_url is the face; audio_url is the driving speech — both REQUIRED","prompt is optional and only lightly steers the scene; the mouth is driven by the audio, not the prompt"],constraints:["image_url (face) REQUIRED","audio_url (driving audio, ≤20s) REQUIRED","output length = audio length; do NOT pass --duration","width / height optional but must be passed as a pair (default 1280x720)"],flagSubset:["service","prompt","image-url","audio-url","width","height"],examples:[{caption:"talking-head from face + audio",command:"dl generate-video --service=longcat-avatar-1-5 \\\n --image-url=https://.../face.jpg \\\n --audio-url=https://.../speech.mp3"}]},{service:"dlai2v_pro",label:"LTX 2 Pro (LTX 2.3 audio-driven)",tier:"Exclusive capability (audio-driven talking / singing video)",bestFor:"Audio-driven talking / singing video: one face/scene still (or 1-5 keyframes) + a driving audio → a lip-synced clip whose length follows the audio. Same engine as `dl lipsync --service=dlai2v_pro`; reach for it here when your pipeline composes through generate-video rather than the lipsync verb.",quality:"Very High",speed:"2-5min",cost:"mid",description:["LTX 2 Pro (routes to the LTX-2.3 audio workflow). **Audio-driven** — the ComfyUI","workflow derives video length from the driving audio, so --audio-url is REQUIRED.","","Two visual-input modes (mutually exclusive):"," Mode 1 (single still): --image-url — api-layer auto-wraps it into keyframes[0]."," Mode 2 (multi-keyframe): --keyframes (1-5 frames) for richer camera movement;",' each keyframe is {"image_url":"...","frame_position":"first|middle|last"}.',"","Output length = audio length; do NOT pass --duration to control length (--duration is","billing-only here, the vendor ignores it)."],promptTips:["⚠ LTX-family prompt template — all three segments required:"," 1. Subject is speaking/singing (explicitly say the character speaks/sings with perfect lip sync)"," 2. Character action (head nods/tilts / gaze / hands / shoulders / breathing)"," 3. Camera movement (Dolly in / slow push in / static medium close-up — state static explicitly)","Append a quality / lighting tail: 'high quality, natural lighting'"],flagSubset:["service","prompt","image-url","audio-url","keyframes","duration"],constraints:["--audio-url REQUIRED (drives output length); audio ≤ 20s & ≤ 100MB; mp3 / wav / ogg / flac / m4a / aac / webm","--image-url and --keyframes are mutually exclusive; --keyframes 1-5 frames","Do NOT pass --duration to control length (billing-only); width / height / resolution are fixed by the workflow","For the same single image + audio lip-sync need you can equally use `dl lipsync --service=dlai2v_pro` — identical engine"],examples:[{caption:"single still + driving audio (talking-head)",command:'dl generate-video --service=dlai2v_pro \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods and tilts, hands resting gently or making small conversational gestures, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"'}]},{service:"dlai2v_pro_multiframe",label:"LTX 2 Pro Multi-frame (LTX 2.3 真·多帧)",tier:"Exclusive capability (keyframe-guided audio-driven video)",bestFor:"True multi-keyframe (2-4) guided, audio-driven video: the model interpolates animation across the keyframes while lip-syncing to the driving audio — richer camera / pose movement than single-still dlai2v_pro. Same engine as `dl lipsync --service=dlai2v_pro_multiframe`.",quality:"Very High",speed:"2-5min",cost:"mid",description:["LTX 2.3 真·多帧变体(真正的多帧关键帧引导,不是单帧 wrap)。**Audio-driven** — audio","时长决定视频帧数,所以 --audio-url 必填;api-layer 按 keyframes 数量自动 router 到","mutiframe_{2f,3f,4f} workflow。","",'每帧 keyframe:{"image_url"(必填),"frame_ratio"?(0.0-1.0 时间位置),"weight"?(0.0-1.0 强度,默认 0.4)}。',"frame_ratio 不传则按帧数等分:2帧=[0,1] / 3帧=[0,0.5,1] / 4帧=[0,0.33,0.67,1]。","所有 keyframe 必须同一角色、同一画幅。"],promptTips:["Same LTX-family three-segment template as dlai2v_pro (subject speaking/singing + character action + camera move)"],flagSubset:["service","prompt","keyframes","audio-url","aspect-ratio","duration"],constraints:["--keyframes REQUIRED, 2-4 frames (api-layer routes to mutiframe_{2f,3f,4f} by count); --image-url alone not supported — use dlai2v_pro for a single still","--audio-url REQUIRED (drives output length / frame count)","--aspect-ratio 支持 16:9 / 9:16 / 1:1;resolution 强制 720p(不可改);不支持 --width / --height / --resolution","Do NOT pass --duration to control length (billing-only)"],examples:[{caption:"3 keyframes + driving audio",command:'dl generate-video --service=dlai2v_pro_multiframe \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf1.png","frame_ratio":0}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf2.png","frame_ratio":0.5}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf3.png","frame_ratio":1}\' \\\n --audio-url="https://cdn.example.com/segment.mp3" \\\n --aspect-ratio=9:16 \\\n --prompt="A person sings expressively with perfect lip synchronization, dynamic head movement, confident posture shifts, high quality, natural lighting, slow push in"'}]}],decisionLogic:[{when:"Default / no special requirement",pick:"seedance-2-0-mini for low-cost drafts / MV non-lipsync batches; seedance-2-0-fast when quality matters more"},{when:"Cost-sensitive but still wants Seedance 2.0 reference consistency",pick:"seedance-2-0-mini (lowest-cost Seedance 2.0 family option; 480p/720p only, 5-12s)"},{when:"Want the highest overall quality + need character consistency / video ref / audio coupling",pick:"seedance-2-0 (top-tier Pro, expensive)"},{when:"Real-looking human / known-IP actor",pick:"seedance-2-0 / seedance-2-0-fast / seedance-2-0-mini, **must first run dl asset register**"},{when:"Already registered a Seedance reference video asset",pick:"seedance-2-0 / seedance-2-0-fast / seedance-2-0-mini with --ark-asset-ids + @assetN, not --ref-video-url + @videoN"},{when:"Video editing (change style / change scene while preserving composition)",pick:"happyhorse-1-0-video-edit (Alibaba-side, Chinese-prompt-friendly) OR kling-o3-pro-v2v / kling-o3-v2v (Kling-side; also serves as fallback when happyhorse / seedance-2-0 video-ref is unavailable)"},{when:"Chinese prompt / Alibaba preference / 1-9 multi-subject refs",pick:"happyhorse-1-0-r2v or happyhorse-1-0-i2v"},{when:"multi-reference + character elements + first/end frame control",pick:"kling-o3-pro-ref2v (quality-priority) or kling-o3-ref2v (cheap)"},{when:"Quick draft preview",pick:"seedance-2-0-mini (cheapest Seedance 2.0) or seedance-2-0-fast (higher quality)"},{when:"Creative / fun stylized",pick:"dlim2v (Grok specialty)"},{when:"Single-reference creative i2v (one image → stylized motion)",pick:"grok-imagine-1.5 (xAI; single ref image, keep prompt off makeup / facial detail)"},{when:"Edit / re-work an existing video clip (any-to-any)",pick:"gemini-omni-video (Google; standout at re-editing a source video) — also see happyhorse-1-0-video-edit / kling-o3-pro-v2v"},{when:"Audio-driven talking-head / stable lip-sync",pick:"longcat-avatar-1-5 (self-hosted; very stable lip-sync, slow ~8-10min). For other lip-sync routes see dl lipsync"},{when:"Audio-driven talking / singing video from a single still (lip-synced, output = audio length)",pick:"dlai2v_pro (LTX 2 Pro, audio-driven; --image-url + --audio-url). Same engine as dl lipsync --service=dlai2v_pro"},{when:"Audio-driven video with 2-4 keyframe guidance (richer camera / pose movement, lip-synced)",pick:"dlai2v_pro_multiframe (LTX 2.3 multi-frame; 2-4 --keyframes + --audio-url). Same engine as dl lipsync --service=dlai2v_pro_multiframe"}]},preflightTopic:{intro:"Before the first dl generate-video call, these five decisions must be explicit (for the per-service flag shape see `dl generate-video model <service>` — positional; `model -h <service>` short-circuits to the overview):",decisions:[{name:"Service / model",description:"Which service to use. Decide per the SERVICES table + DECISION LOGIC in `dl generate-video model -h` (overview), or `dl generate-video model <service>` (per-service profile)."},{name:"Duration plan",description:"Provider's valid duration range + the trim-back plan if the final segment is shorter than the provider min.\nseedance-2-0 / fast currently require integer duration (4-15s); seedance-2-0-mini requires 5-12s — use ceil(intended) then ffmpeg trim;\nhappyhorse video-edit's duration auto-follows the source video — do not pass it."},{name:"Aspect ratio",description:"Target frame ratio. The allowed enum varies per service:\n seedance-2-0 supports adaptive / 16:9 / 4:3 / 1:1 / 3:4 / 9:16 / 21:9;\n happyhorse-r2v does not accept adaptive / 21:9, only 16:9 / 9:16 / 3:4 / 4:3 / 1:1."},{name:"Resolution package",description:"Resolution tier. Field-casing trap per service:\n seedance-2-0 Pro 使用小写 480p / 720p / 1080p / 4k;Fast / Mini 仅支持小写 480p / 720p;\n happyhorse-* uses **uppercase** 720P / 1080P (lowercase is rejected — opposite of seedance)."},{name:"Reference-input plan",description:"Which image / audio / video / asset will enter this call.\nReal-looking human / IP → Seedance 2.0 family must first go through dl asset register, then submit that source ref asset-only; do not also submit its URL.\nIf a video has already been registered as an asset, submit its asset id via --ark-asset-ids and use @assetN; do not submit the same URL via --ref-video-url.\nFor Seedance r2v, ARK counts all reference_video inputs together and requires total duration <=15.2s; multiple video refs are allowed only when they are distinct and fit the combined-duration limit."}],notes:["Seedance 2.0 family mandatory preflight: using a real-looking human but skipping asset register, or submitting the same source ref both as ark_asset_ids and raw image/video URL fields, causes upstream policy block or unpredictable result","Seedance r2v reference-video limit: ARK requires all reference_video inputs together to be <=15.2s; distinct multi-video refs are allowed, but do not pass the same video twice through registered asset + raw URL.","If Seedance generated/output audio is moderation-blocked, retry with prompt text 'no BGM' / 'no background music'; do not pass --generate-audio","If cost-sensitive or unsure about service choice, read pricing-and-policies-dramaland-faq/SKILL.md before locking the package"]},policyTopic:{intro:"Three classes of hard rules: external communication must not leak internal details; paid package must be authorized before submit; URLs must be real and accessible.",rules:[{title:"1. User-Facing Communication Rule — do not leak internal details",body:["Never surface vendor / backend internal name / USD/RMB price /","internal model code (seedance-2-0 vendor routing etc.) / trace identifier","(job_id / task_id / request_id / other UUIDs) to the end user.","","User-facing summary should mention **only**:"," - service name (seedance-2-0 / happyhorse-1-0-r2v / kling3.0 etc.)",' - user-meaningful constraint (duration, aspect, "edit" vs "generate" etc.)'," - action (generate / edit video)"]},{title:"2. Production Package Gate — do not call before paid authorization",body:["service / model, duration plan, aspect ratio, resolution, generation count (including batch","segment range), and image / audio / video / asset reference plan are all components of the system",'prompt-level "paid media production package authorization". Do not submit before authorization.',"","Within the same authorized package you can batch-generate — do not block per segment.","Only re-ask on package overflow (switching service / changing duration / changing resolution /","adding count / fallback / paid regeneration)."]},{title:"3. URL Hygiene — do not fabricate storage URLs",body:["All reference URLs (image / audio / video) must be real accessible HTTPS. Legal sources:"," - dl generate-image-prompt / dl generate-image-ref / dl generate-music / other submit results (GCS URLs)"," - URLs uploaded by the user or provided by the conversation context"," - URLs returned by dl content list or other platform queries","","NEVER fabricate or guess storage URLs. If a reference image is missing, generate it via dl","generate-image-prompt or generate-image-ref first; if audio is missing, generate it — do not invent domains / paths.","","Seedance 2.0 registered refs are stricter: after dl asset register, pass only","--ark-asset-ids + @assetN for that media; do not also submit its raw image/video URL.","For Seedance r2v, ARK requires total reference_video duration <=15.2s across all video refs.","Distinct multi-video refs are allowed; do not duplicate the same source through asset + raw URL.","If output audio is moderation-blocked, retry with prompt text 'no BGM' / 'no background music';","do not pass --generate-audio."]}]},compositionTopic:{intro:"This atomic skill only produces a video URL; artifact / canvas registration and other downstream responsibilities are not this verb's job.",integrations:[{skill:"full-song MV / multi-segment video workflow",rule:["Distinguish the storyboard's intended final segment duration from the provider request","duration. If the final segment is shorter than the provider min, request the provider min, then ffmpeg","trim back to the original intended length. Do not round up to a whole number / do not audio-retime to match provider duration.","","If the provider requires integer duration (seedance-2-0 currently does), use ceil(intended);","do not floor / do not nearest-integer round.","","If the segment already has resolved reference assets (reference_list) → pass those real","URLs / registered asset ids directly; do not rely on prompt text alone.","For Seedance real-looking human media, pass the registered asset id only and omit the same raw URL.","For Seedance video references, use registered asset ids for registered videos and raw URLs for unregistered videos; do not send the same source through both channels."]},{skill:"ffmpeg (probe / trim / concat / crop)",rule:["This verb only handles vendor generation, no ffmpeg work. For trim / concat / probe →","load the ffmpeg skill and use dl ffmpeg; do not install system ffmpeg in the sandbox."]},{skill:"right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs dl artifact write / patch-json pi_media_log on your behalf —","that is the composition layer's job. The upstream workflow (visual-production / music-video","composition) is responsible for placing the returned URL into its own artifact slot."]}]},asyncTopic:{intro:["dl generate-video by default returns { job_ref, status: 'pending' } and exits immediately — do not poll.","Results are injected into the current session as [async-callback] job=<ref> text; typical duration 1-5 minutes.","","Only run dl poll separately when 'the next step strictly requires the result' (e.g. immediately feeding ffmpeg)."],resultShape:['{ "url": "https://storage.googleapis.com/.../video.mp4",',' "original_url": "...",',' "vendor": "..." }'],notes:["The URL field is the atomic skill's sole product handed up to the upper layer","The vendor field is debug-only; per the user-facing communication policy, do not leak it to the user","⚠ This URL already lives on our GCS — feed it directly to downstream tools / artifacts; do NOT pass to upload_file (would re-host an identical blob under a different URL)."]},publishTopic:{intro:["After producing your video URL, call publish_content with","presentation_family='video' and the explicit media fields. See","'Publishing Your Work / video' in your creation playbook for the full","field mapping template."],fields:[{name:"presentation_family",value:"'video'"},{name:"media_urls.video",value:"<returned video URL>"},{name:"frameRatio",value:"<from your aspect_ratio decision>"},{name:"thumbnail_url",value:"<optional poster frame>"},{name:"duration_seconds",value:"<intended final, after ffmpeg trim>"},{name:"delivery_format",value:"'video'"},{name:"experience_format",value:"'passive_media'"}]}})}(_d),function(e){Ps(e,{verb:"generate-music",actionName:"generate_music",schema:Yo,billing:{schema:bl,select:e=>({service:e.service}),quote:wl},supportsBatch:!0,description:"Generate music from a required prompt; prompt is music direction unless --custom makes it lyrics.",notes:["Services: suno-v5, suno-v5_5, minimax.","`--prompt` is always required; there is no title/tags-only mode.","`--custom` changes prompt semantics: with --custom it is lyrics; otherwise it is music direction and Suno may write lyrics.","`--instrumental` requests no vocals; still pass --prompt as music direction and usually omit --custom.","`--vocal-gender` is capitalized: `Male` / `Female` (not lowercase) — backend is case-sensitive.","Need lyrics for `--custom` and the user did not provide any? Run `dl generate-lyrics --prompt=<brief>` first (returns 2-3 candidates with [Verse]/[Chorus] markers); only hand-write lyrics yourself when that command fails."],whenToUse:["You need a generated music track from a required music brief or explicit lyrics","You're producing a music-video reference track and want to fan out style variants via --jobs-file"],whenNotToUse:["You need spoken text — use `dl generate-tts`","You need beat positions of an existing audio file — use `dl analyze-beats`"],examples:[{caption:"suno-v5_5, model-written lyrics",command:'dl generate-music \\\n --service=suno-v5_5 \\\n --prompt="bright synth-pop anthem with retro arcade textures, energetic chorus, glossy modern mix" \\\n --title="Neon High Score" \\\n --tags="synth-pop, retro arcade, energetic, glossy chorus" \\\n --vocal-gender=Female'},{caption:"instrumental only",command:'dl generate-music \\\n --service=suno-v5_5 \\\n --prompt="wordless cinematic piano and warm string pads, slow emotional build, 72 BPM, clean mix" \\\n --title="After the Rain" \\\n --tags="instrumental, cinematic piano, warm strings, reflective, 72 BPM" \\\n --negative-tags="vocals, singing, lyrics, spoken word" \\\n --instrumental'},{caption:"custom lyrics",command:'dl generate-music \\\n --service=suno-v5_5 \\\n --prompt="[Verse] Neon streets are waking [Chorus] We rise above the static" \\\n --title="Above the Static" \\\n --tags="electropop, female vocal, uplifting chorus" \\\n --custom \\\n --vocal-gender=Female'}],notExamples:[{command:'dl generate-music --service=suno-v5_5 --title="After the Rain" --tags="instrumental, cinematic" --instrumental',whyItFails:"--prompt is required even for instrumental tracks; derive a brief from the title/tags instead"},{command:'dl generate-music --params=\'{"service":"suno-v5","prompt":"..."}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"url":"https://storage.../audio.mp3","duration_ms":120000}}',modelTopic:{rankingSummary:["Ranked by overall quality (head-to-head on the same song; earlier = stronger):"," 🥇 suno-v5_5 (2 tracks) — current strongest Suno; vocals / arrangement / mix all beat v5 and minimax;"," long structure (verse / chorus / bridge) is stable. **Default / preferred for final delivery.**"," 🥈 suno-v5 (2 tracks) — previous-generation Suno; clearly lower quality than v5_5, but still **significantly stronger than minimax**."," Fall back to it only when v5_5 is unavailable or when you want dual-service comparison candidates."," 🥉 minimax (1 track) — single-track fast generation; quality below both Suno tiers (more mechanical vocals),"," fastest single-track speed, lowest cost. **Only suitable as a stopgap BGM / placeholder / quick demo**; not recommended for final delivery."],services:[{service:"suno-v5_5",label:"Suno V5.5",tier:"🥇 Default / Strongest",bestFor:"Default / unsure / final delivery. Vocals, arrangement, and mix are all strongest; long structure is stable",quality:"Very High",speed:"1-3min",cost:"mid-high",description:["Suno V5.5, Pi's current strongest music service. Each generation returns **2 candidate tracks**","(MUST normalize them into music_candidate.content[] preserving all of them; finalize only after user pick)."],promptTips:["prompt semantics shift with --custom / --instrumental:"," No-vocal BGM: --instrumental + prompt = music direction (style / mood / arrangement /"," BPM / structure / use case); do NOT write lyrics; usually omit --custom"," Suno writes its own lyrics: omit --custom + omit --instrumental + prompt = music direction"," Custom lyrics: --custom + prompt = actual lyrics; STRONGLY recommended to use [Verse] /"," [Chorus] / [Bridge] / [Outro] structure markers","","title / tags are auxiliary controls only — they CANNOT replace prompt (prompt is always required).","For pure music, add --negative-tags='vocals, singing, lyrics, spoken word' to reinforce no-vocal."],flagSubset:["service","prompt","title","tags","negative-tags","custom","instrumental","vocal-gender"],constraints:["⚠ Always returns 2 tracks; evaluate and recommend the best, but MUST NOT use a track as the downstream music_url without user pick","--vocal-gender is case-sensitive: `Male` / `Female` (not lowercase)","No native duration parameter — express target duration via prompt + tags"],examples:[{caption:"suno-v5_5, Suno-written lyrics (default case)",command:'dl generate-music --service=suno-v5_5 \\\n --prompt="bright synth-pop anthem with retro arcade textures, energetic chorus, glossy modern mix" \\\n --title="Neon High Score" \\\n --tags="synth-pop, retro arcade, energetic, glossy chorus" \\\n --vocal-gender=Female'},{caption:"suno-v5_5, custom lyrics",command:'dl generate-music --service=suno-v5_5 \\\n --prompt="[Verse] Neon streets are waking [Chorus] We rise above the static" \\\n --title="Above the Static" \\\n --tags="electropop, female vocal, uplifting chorus" \\\n --custom --vocal-gender=Female'},{caption:"suno-v5_5, instrumental / no-vocal BGM",command:'dl generate-music --service=suno-v5_5 \\\n --prompt="wordless cinematic piano and warm string pads, slow emotional build, 72 BPM, clean mix for a reflective closing scene" \\\n --title="After the Rain" \\\n --tags="instrumental, cinematic piano, warm strings, reflective, 72 BPM" \\\n --negative-tags="vocals, singing, lyrics, spoken word" --instrumental'}]},{service:"suno-v5",label:"Suno V5",tier:"🥈 Runner-up",bestFor:"v5_5 unavailable, or you want v5_5 + v5 dual-service comparison candidates",quality:"High",speed:"1-3min",cost:"mid",description:["Suno V5, previous generation. Vocal nuance / harmonic layering / style fidelity are all clearly","below v5_5, but still **significantly stronger than minimax**. Also returns 2 tracks. Parameters /","semantics are identical to v5_5 — only the service name differs."],promptTips:["Same as suno-v5_5; the custom / instrumental triangle contract is identical"],flagSubset:["service","prompt","title","tags","negative-tags","custom","instrumental","vocal-gender"],constraints:["Same as suno-v5_5 (2 tracks / user pick required / vocal-gender casing)"]},{service:"minimax",label:"MiniMax Music",tier:"🥉 Stopgap placeholder",bestFor:"ONLY stopgap BGM / placeholder music / quick demo, or when the user explicitly asks for fast/cheap",quality:"Mid",speed:"30-90s",cost:"low",description:["MiniMax single-track fast generation. Quality is below both Suno tiers (more mechanical vocals,","weaker style control, flatter structure). Single track → single candidate (one entry in content[];","the selected fields can be set directly on the first write).","**Not recommended for final delivery.**"],promptTips:["Same custom / instrumental semantics as the Suno family"],flagSubset:["service","prompt","title","tags","negative-tags","custom","instrumental","vocal-gender"],constraints:["⚠ Single-track return — no head-to-head comparison candidate","minimax title is forwarded into params; the api-layer may echo it in the result (not guaranteed to reach the upstream API)"]}],decisionLogic:[{when:"Default / unsure / final delivery",pick:"suno-v5_5 (strongest quality)"},{when:"v5_5 having issues / want dual-service comparison candidates",pick:"add suno-v5 (do NOT fall straight to minimax)"},{when:"ONLY stopgap BGM / placeholder / quick demo, or user explicitly asks fast/cheap",pick:"minimax"},{when:"Need lyrics but user did not provide any",pick:"Call `dl generate-lyrics --prompt=<brief>` first (returns 2-3 candidates), pick one, then Any Suno service + custom: true. Fall back to agent-written lyrics or `custom: false` only when generate-lyrics is unavailable"},{when:"Let Suno write its own lyrics (no separate lyrics call)",pick:"Any Suno service + custom: false"},{when:"User has already provided complete lyrics",pick:"Any Suno service + custom: true + [Verse]/[Chorus] markers"},{when:"No-vocal BGM (no lyrics)",pick:"Any service + --instrumental + prompt = music direction"}]},preflightTopic:{intro:"Explicitly prepare the generation brief before the first dl generate-music call — if ANY of the 7 items below is undecided, do not start the call:",decisions:[{name:"Generation mode",description:"Net-new generation vs remix / continuation. **The current CLI only exposes net-new.**\nIf the request is remix / continuation and the runtime exposes no true remix controls, STOP and\nsurface the capability mismatch directly — do not disguise it as a normal generate call."},{name:"Instrumental vs vocal",description:"Decide whether to pass --instrumental. The prompt-writing rule follows from this choice."},{name:"Custom mode (decide explicitly, do not rely on default)",description:"--custom determines prompt semantics:\n --custom=true → prompt is the **actual lyrics**; use [Verse] / [Chorus] / [Bridge] structure markers\n --custom=false → prompt is **music direction**; Suno may write its own lyrics (unless --instrumental)\nDo not rely on defaults — make the decision explicit."},{name:"Lyrics strategy",description:'For a vocal track: are lyrics provided by the user / generated via `dl generate-lyrics` / written by the agent / left to Suno via non-custom mode?\n**Preferred order when the user did not hand over lyrics:**\n 1. Try `dl generate-lyrics --prompt="<short brief, ≤200 chars>"` first — returns 2-3 KIE-Suno lyric candidates with [Verse]/[Chorus] markers; pick one and feed it as `dl generate-music --custom --prompt=<lyrics>`.\n 2. If `dl generate-lyrics` returns E_BACKEND / sensitive-word block / timeout, fall back to writing lyrics yourself with explicit [Verse]/[Chorus]/[Bridge] structure markers.\n 3. Only let Suno auto-write lyrics (omit --custom) when neither route is available or the brief is too vague to land lyrics.\nA pure instrumental track MUST NOT include lyric text in the prompt and SHOULD NOT call generate-lyrics.'},{name:"Target duration",description:"Target seconds or duration band. The current generate_music CLI has NO native duration parameter,\nso this intent must be expressed via prompt / title / tags and reflected in the subsequent evaluation."},{name:"Style package",description:"title / tags / negative-tags / era / genre / energy / tempo feel / instrumentation /\nvocal-gender (when relevant) — all need to be decided before calling the service."},{name:"Service choice (decide only after the brief is fully clear)",description:"Choose service from the brief: default suno-v5_5 / add suno-v5 for dual candidates / minimax only for stopgap.\nCost-sensitive or unclear choice → read pricing-and-policies-dramaland-faq/SKILL.md first, then lock."}],notes:["Cost-sensitive / unclear service → read pricing-and-policies-dramaland-faq/SKILL.md first","Batch generation goes through --jobs-file (JSON array); do not block per item; escape multi-line lyrics with \\n inside JSON strings"]},policyTopic:{intro:"Five categories of hard rules: User-facing isolation / Package gate / **Prompt-Custom-Instrumental triangle contract** / **Artifact-Finalize Gate** / Fallback ladder.",rules:[{title:"1. User-Facing Communication — never leak internal details",body:["Vendor / pricing / internal model code (Suno V5.5 / Suno V5 / MiniMax) / trace id must NOT","surface to the user. User-facing summary only mentions: service alias (Suno / MiniMax) +","action (generate music / score / candidate songs) + candidate count."]},{title:"2. Production Package Gate — never call before authorization",body:["service / generation count / candidate count / instrumental / vocal / custom mode / lyrics","strategy / target duration / style package / source / brief plan are all components of the paid","package authorization. Do not call before authorization; once authorized, batch and normalize","candidates within the package — do not block per candidate. Only re-ask on package overflow","(service swap / candidate-count change / duration change / lyrics-strategy change / fallback /","paid regeneration)."]},{title:"3. Prompt / Custom / Instrumental Triangle Contract (#391)",body:["`prompt` is ALWAYS required; there is no 'title + tags only' generation mode.","","| Goal | Flags | prompt meaning |","|-----|-----|-------------|","| No-vocal BGM | --instrumental, usually OMIT --custom | **Music direction**: style / mood / arrangement / tempo / structure / scene. Do NOT write lyrics |","| Suno writes lyrics | OMIT --custom, OMIT --instrumental | **Music direction**; Suno V5.5 / V5 writes its own lyrics based on the brief |","| Custom lyrics | Pass --custom | **Actual lyrics**; recommended to use [Verse] / [Chorus] / [Bridge] / [Outro] structure markers |","","For pure music, add --negative-tags='vocals, singing, lyrics, spoken word' to reinforce the no-vocal constraint.","title and tags are auxiliary controls only — they CANNOT replace prompt.","If the user only provided title / tags, synthesize a short prompt from them first — do not omit prompt.","For multi-line lyrics, prefer --jobs-file and escape with \\n inside JSON strings; do not use literal heredoc newlines.","Need lyrics but the user did not provide any? Call `dl generate-lyrics --prompt=<short brief>` first (KIE Suno, returns 2-3 candidates with [Verse]/[Chorus] markers) and feed the chosen text into --custom. Only hand-write lyrics yourself when generate-lyrics fails."]},{title:"4. Artifact-Finalize Gate (music_candidate slot)",body:["Results from this verb MUST land in the music_candidate slot (new artifact protocol — pure","domain `data`, no UI fields). Landing flow:",""," 1. Read schemas/artifact_contract.json (in this skill's directory); record ARTIFACT_CONTRACT_PATH"," 2. Read schemas/music_candidate.schema.json + templates/music_candidate.minimum.json"," 3. Normalize the provider response into data.candidates[] — preserve ALL tracks;"," normalize tags 'pop, electronic' into the array ['pop', 'electronic']; each candidate"," includes a lyrics field (#306)"," 4. Single-track (minimax) → one entry; data.selected_candidate_index = 0 and"," data.selected_audio_url copied from candidates[0].audio_url on the first write"," 5. Multi-track (suno-v5 / suno-v5_5) → multiple entries in data.candidates[]; selected_* = null;"," MUST wait for user pick (media_choice ask rendered from candidates[]) before patch-json"," selected_candidate_index + selected_audio_url, then re-finalize","","⚠ Any artifact call failure → the slot does not exist; do NOT pretend it succeeded / do NOT keep using a temp file.","⚠ ARTIFACT-FINALIZE GATE requires user consent before finalize; do NOT finalize a multi-track candidate before pick."," selected_audio_url is only usable as the downstream music_url when the slot is verified + non-null."]},{title:"5. Fallback Ladder",body:["When this verb produces issues (insufficient quality / wrong style / moderation block / service unavailable), in order:","","1. Retry once (transient network / quota jitter usually clears)","2. Edit prompt: strengthen style brief; add negative-tags; fill missing [Verse]/[Chorus] structure markers","3. Swap service: v5_5 → add v5 head-to-head (do NOT fall straight to minimax)","4. Adjust mode switches: vocal-gender / instrumental / custom","5. Only fall back to minimax when the user explicitly asks for 'fast/cheap' or confirms it is a stopgap placeholder"]}]},compositionTopic:{intro:"This atomic skill mandatorily lands results in the music_candidate artifact slot; downstream (lipsync / analyze-beats / publish_content) consumes selected_audio_url (only after user pick + finalize).",integrations:[{skill:"dl artifact (music_candidate slot)",rule:["MANDATORY: after generation, normalize results into the music_candidate slot (Artifact protocol 0509)."," - Multi-track providers (suno-v5 / suno-v5_5) → preserve all candidates in content[];"," selected_* = null; wait for user pick before patch-json + re-finalize"," - Single-track provider (minimax) → wrapper selected_* can be set on the first write","See schemas/music_candidate.schema.json and the schemas/ + templates/ in this skill's directory."]},{skill:"dl lipsync (audio source for lipsync)",rule:["selected_audio_url can be used as lipsync --audio-url.","⚠ Only usable when the slot is verified + selected_audio_url is non-null; otherwise treat as not generated."]},{skill:"dl analyze-beats (beat / sync points)",rule:["MV beat sync: selected_audio_url → dl analyze-beats to extract beats + segmentation."]},{skill:"publish_content (final delivery)",rule:["publish_content presentation_family='text' + media_urls.audio=<url> +","delivery_format='audio' (the runtime does NOT auto-infer audio from presentation_family,","media_urls.audio MUST be written explicitly)."]}]},asyncTopic:{intro:["dl generate-music returns { job_ref, status: 'pending' } and exits immediately by default — do NOT poll.","The result is injected into the session as [async-callback] job=<ref> text; typical wait is 1-3 minutes (minimax 30-90s).","If the next step must have the result (immediately normalize into the artifact or feed lipsync) →","query separately with dl poll --job-ref=<ref>; dl subcommands themselves no longer support --wait blocking (#294)."],resultShape:["// suno-v5 / suno-v5_5 (2 tracks)",'{ "musics": [',' { "id": "<uuid>", "audio_url": "https://storage.../track1.mp3",',' "title": "...", "tags": "...", "prompt": "..." },',' { "id": "<uuid>", "audio_url": "https://storage.../track2.mp3", ... }'," ] }","// minimax (1 track)",'{ "audio_url": "https://storage.../track.mp3", "title": "...", ... }',"vendor / internal metadata fields MUST NOT be exposed to the user"],notes:["⚠ Do NOT write a bash poll loop (while sleep + dl poll) — forbidden by the agent runtime async rules (#389)","Batch goes through --jobs-file; each job's completion is pushed back independently via [async-callback]"]},publishTopic:{intro:["After producing audio_url, publish_content goes through the 'text' presentation_family (audio is not a standalone family).","The runtime does NOT auto-infer audio from presentation_family; media_urls.audio MUST be written explicitly."],fields:[{name:"presentation_family",value:"'text'"},{name:"media_urls.audio",value:"<selected_audio_url> (only available after user pick + slot verified)"},{name:"delivery_format",value:"'audio'"}]}})}(_d),function(e){Ps(e,{verb:"generate-sound",actionName:"generate_sound",schema:Wo,supportsBatch:!0,description:"Generate a short sound effect (SFX / Foley / ambient / short loop) from a text description. ElevenLabs Sound Effects v2, duration 0.5–30s.",notes:["Only service is `elevenlabs-sound` (single provider for now).","`--duration-seconds` hard cap is 30s (ElevenLabs v2 limit). Omit to let the model pick a duration.","`--loop` produces a seamlessly looping clip — only valid on v2 (the default model).","`--prompt-influence` controls how strictly the model follows the text (0–1, default 0.3 server-side).","For a full song with vocals or longer than 30s, use `dl generate-music` instead."],whenToUse:["You need a short cinematic SFX / Foley / ambient bed / UI sound / short loop","You want a looping background texture for a video or scene transition","Batch dispatch a set of SFX cues via --jobs-file (each job 0.5–30s)"],whenNotToUse:["You need a full music track with melody / vocals / structure — use `dl generate-music`","You need spoken text — use `dl generate-tts`","You need an audio file longer than 30 seconds — current SFX model caps at 30s"],examples:[{caption:"rain ambience, 10s",command:'dl generate-sound \\\n --service=elevenlabs-sound \\\n --text="steady rain on a tin roof, distant low thunder, no music" \\\n --duration-seconds=10'},{caption:"UI confirmation chime, seamless loop",command:'dl generate-sound \\\n --service=elevenlabs-sound \\\n --text="soft synthetic confirmation chime, two short notes, clean digital" \\\n --duration-seconds=2 \\\n --loop \\\n --prompt-influence=0.6'},{caption:"short emotional music bed (probe SFX model for short-music territory)",command:'dl generate-sound \\\n --service=elevenlabs-sound \\\n --text="dreamy romantic piano with soft strings, warm and intimate, slow tempo" \\\n --duration-seconds=15'}],notExamples:[{command:'dl generate-sound --service=elevenlabs-sound --text="..." --duration-seconds=60',whyItFails:"duration_seconds is capped at 30 by the ElevenLabs SFX v2 model; the schema rejects values > 30"},{command:'dl generate-sound --service=elevenlabs-sound --text="full pop song with vocals and chorus"',whyItFails:"This verb is short-SFX only; for vocal songs / longer compositions use `dl generate-music`"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"audio_url":"https://storage.../sound.mp3","duration_ms":10031,"format":"mp3","sample_rate":44100}}'})}(_d),function(e){e.command("generate-lyrics").description("Generate Suno-style song lyrics from a short brief (<=200 chars). Returns 2-3 candidates synchronously; pick one and feed to `dl generate-music --custom`.").addHelpText("after",["","WHEN TO USE"," - You're about to call `dl generate-music --custom` and need lyrics with [Verse]/[Chorus] markers."," - You want 2-3 lyric variants to choose from before committing to a music generation.","","WHEN NOT TO USE"," - The song is instrumental — skip lyrics entirely, pass `--instrumental` to generate-music."," - You already have lyrics from the user — pass them directly to `dl generate-music --custom --prompt=...`.","","PRESENT TO USER (after candidates return)"," The user must be able to READ the full lyrics before choosing — never offer titles alone."," Build ONE select-v1 ask: one option per candidate, where"," - label = the candidate title"," - description = a one-line hook/preview (e.g. the first lyric line)"," - detail = the candidate's FULL `text`, with [Verse]/[Chorus] line breaks kept"," The card renders detail collapsed with an expand toggle, so the user reads the full"," lyrics inline and picks in the same card. Add a text option like 「都不满意,重新写」."," No separate 'here are the lyrics' message is needed — detail carries the full text."," Example option:",' {"id":"coney","label":"Coney Island Kiss","description":"有 Rap 段 · 纽约场景感强","detail":"[Verse]\\n...\\n[Chorus]\\n..."}',"","FALLBACK"," - If this command fails (E_BACKEND / E_SENSITIVE / E_TIMEOUT), hand-write lyrics yourself with [Verse]/[Chorus] structure and continue to generate-music.","","OUTPUT",' {"ok":true,"data":{"task_id":"...","lyrics":[{"title":"...","text":"[Verse]...","status":"complete"}, ...]}}',"","Example:",' dl generate-lyrics --prompt="bittersweet synth-pop about leaving a small town at sunrise"'].join("\n")).requiredOption("--prompt <text>","REQUIRED — short brief describing the song (<=200 chars)").action(async e=>{const t=String(e.prompt??"").trim();t||vs("--prompt is required and must be non-empty"),t.length>200&&vs("--prompt must be <=200 characters (KIE limit)",`current length: ${t.length}`);try{const e=await Da("media/submit","api/forward/lyrics",{prompt:t},{timeoutMs:14e4,retries:0});e.success&&e.data?.lyrics||vs(e.error||"lyrics generation returned no candidates"),gs({ok:!0,data:e.data})}catch(e){e instanceof Jr&&vs(e.message,e.hint),vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){Ps(e,{verb:"analyze-beats",actionName:"analyze_beats",schema:tr,supportsBatch:!1,description:"Analyse beat structure of an audio file. Synchronous — returns the beat list directly.",notes:["`--beat-method` is one of: `madmom_rnn` (default), `librosa`. Override only when you have a specific reason."],whenToUse:["Music-video planning: you need beat positions to anchor segment boundaries","Tempo / downbeat estimation before scheduling cuts"],whenNotToUse:["You need a transcript — use `dl transcribe`","You need to generate music — use `dl generate-music`"],examples:[{caption:"default beat method",command:'dl analyze-beats --audio-url="https://cdn.example.com/song.mp3"'},{caption:"explicit librosa (faster but different output)",command:'dl analyze-beats \\\n --audio-url="https://cdn.example.com/song.mp3" \\\n --beat-method=librosa'}],notExamples:[{command:'dl analyze-beats --params=\'{"audio_url":"..."}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"}],outputSingle:'{"ok":true,"success":true,"beats":[{"position":1,"time":0.45,"strength":0.9}, ...]}'})}(_d),function(e){Ps(e,{verb:"render-caption",actionName:"render_caption",schema:er,billing:{schema:Fl,select:()=>({}),quote:Dl},supportsBatch:!1,description:"Burn SRT captions into a video. Synchronous — returns the captioned video URL directly.",notes:["`--caption` is a JSON object. Supported fields include fill_color, border_color, font_id, font_weight, shadow, position, position_value, font_size, and font_size_px.","`font_size_px` takes precedence over the `font_size` preset."],whenToUse:["You already have a video URL and SRT content and need a burned-caption video","The create-subtitles skill has generated SRT and the user requested embedded subtitles"],whenNotToUse:["You need ASR first — use `dl transcribe` or the create-subtitles skill","You only need an external SRT file — do not render captions"],examples:[{caption:"burn default-style captions",command:'dl render-caption \\\n --video-url="https://cdn.example.com/video.mp4" \\\n --srt-content="1\\n00:00:00,000 --\x3e 00:00:02,500\\nHello\\n" \\\n --caption=\'{"fill_color":"#FFFFFF","border_color":"#000000","font_id":"noto_sans","font_weight":"bold","position":"bottom","position_value":0.1,"font_size_px":36}\''}],notExamples:[{command:'dl render-caption --params=\'{"video_url":"..."}\'',whyItFails:"inline JSON via --params is removed; pass scalar flags directly"}],outputSingle:'{"ok":true,"success":true,"video_url":"https://.../captioned.mp4"}'})}(_d),function(e){Ps(e,{verb:"motion-control",actionName:"motion_control",schema:Go,billing:{schema:ql,select:e=>({service:e.service,tier:e.tier,duration:e.duration}),quote:Pl},supportsBatch:!0,description:"Transfer motion / pose from a source video onto one or more target characters (services: dreamactor, kling3.0-motion). dreamactor supports multi-person via --image-urls; kling3.0-motion is single-person only.",notes:["Provide exactly one of --image-url / --image-urls / --image-base64; supplying more than one (or none) raises E_SCHEMA.","`--image-urls` 是多人入口,**仅 dreamactor 支持**——传 N 个 URL,driving video 里就要有匹配的 N 个角色;kling3.0-motion 传 --image-urls 会被 vendor 拒绝。","`--duration=<seconds>` 是**计费专用**字段(整数,driving video 的秒数),vendor 不读。不传时计费按 10s 兜底,可能少扣 —— 请用 dl ffmpeg / 上传 metadata 拿到真实长度后传过来。"],whenToUse:["You have a reference performance video and a target character image","You need multi-character motion transfer (dreamactor + --image-urls)"],whenNotToUse:["You want a clip generated from scratch — use `dl generate-video`","You need lip-sync (not body motion) — use `dl lipsync`"],examples:[{caption:"single, dreamactor (--duration 整 driving video 秒数,计费用)",command:"dl motion-control --service=dreamactor --video-url=https://v.mp4 --image-url=https://char.png --duration=12"},{caption:"multi-person, dreamactor (N image_urls ↔ N 角色 in driving video)",command:"dl motion-control --service=dreamactor \\\n --video-url=https://.../two-people-dancing.mp4 \\\n --image-urls=https://.../alice.png \\\n --image-urls=https://.../bob.png \\\n --duration=12"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed","data":{"url":"https://...mp4"}}',modelTopic:{rankingSummary:["2 services: dreamactor (fast + simple) / kling3.0-motion (quality + orientation control)."],services:[{service:"dreamactor",label:"DreamActor M2.0 (BytePlus)",tier:"Fast + simple",bestFor:"Single- or multi-character pose / motion transfer from video to image(s)",quality:"High",speed:"1-3min",cost:"low",description:["BytePlus DreamActor M2.0. General motion transfer, fast and with simple parameters.","Supports multi-person: pass N reference images via --image-urls and the driving video should contain N matching characters."],constraints:["GCS URL → api-layer rewrites to CDN URL automatically (BytePlus cannot reach GCS directly)","Recommend cut_first_second=true to drop the first-second transition artifact","Multi-person via --image-urls: 数组里每个 URL 对应 driving video 里一个角色,数量需匹配"],flagSubset:["service","video-url","image-url","image-urls","image-base64","cut-first-second"],examples:[{caption:"single, dreamactor",command:"dl motion-control --service=dreamactor \\\n --video-url=https://.../driving.mp4 \\\n --image-url=https://.../character.png \\\n --cut-first-second"},{caption:"multi-person, dreamactor (image_urls 数组)",command:"dl motion-control --service=dreamactor \\\n --video-url=https://.../two-people-dancing.mp4 \\\n --image-urls=https://.../alice.png \\\n --image-urls=https://.../bob.png \\\n --cut-first-second"}]},{service:"kling3.0-motion",label:"Kling 3.0 Motion",tier:"High quality + control",bestFor:"High-quality motion transfer + orientation control + quality tier + negative prompt",quality:"Very High",speed:"2-5min",cost:"mid",description:["Kling 3.0 Motion. Higher quality, supports:"," - character_orientation control (image / video)"," - tier (std / pro quality)"," - negative_prompt / prompt guidance"],constraints:["character_orientation='image' → character orientation follows the image; 'video' → follows the driving video","tier='pro' is higher quality than 'std' but slower"],flagSubset:["service","video-url","image-url","image-base64","character-orientation","tier","prompt","negative-prompt","sound"],examples:[{caption:"kling3.0-motion high quality + orientation",command:"dl motion-control --service=kling3.0-motion \\\n --video-url=https://.../driving.mp4 \\\n --image-url=https://.../character.png \\\n --character-orientation=image --tier=pro"}]}],decisionLogic:[{when:"Simple motion transfer, fast",pick:"dreamactor"},{when:"Need character orientation control / quality tier / negative prompt",pick:"kling3.0-motion"}]},preflightTopic:{intro:"Confirm these 3 items before the first dl motion-control call:",decisions:[{name:"Service",description:"dreamactor (fast and simple) or kling3.0-motion (high quality + control)."},{name:"Driving video + target character image(s)",description:"Driving video source + character image source.\nvideo_url is always required. Image source: exactly one of --image-url (single, both services) / --image-urls (multi-person, dreamactor only) / --image-base64 (single, both services). Missing all three or supplying more than one raises E_SCHEMA."},{name:"kling3.0-motion-specific",description:"If choosing kling3.0-motion, decide up front: character_orientation (image / video) +\ntier (std / pro) + whether to include prompt / negative_prompt / sound."}]},policyTopic:{rules:[{title:"1. User-Facing Communication",body:["Do not leak vendor / price / internal model code. Only mention service name + action (motion transfer)."]},{title:"2. Production Package Gate",body:["service / tier / task count / source video plan / target image plan /","character_orientation / sound / prompt are all components of the paid-package authorization.","Do not call before authorization; only re-ask on package overflow (switching service / tier / adding count /","replacing key inputs / fallback / paid regeneration)."]}]},compositionTopic:{intro:"This atomic skill only produces a motion-controlled video URL; artifact / canvas registration and other downstream responsibilities are not this verb's job.",integrations:[{skill:"right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs dl artifact write / patch-json pi_media_log on your behalf — that is the composition layer's job."]}]},asyncTopic:{intro:["dl motion-control by default returns { job_ref, status: 'pending' } and exits immediately — do not poll.","Results are injected into the session as [async-callback] job=<ref> text; typical duration 1-5 minutes."],resultShape:['{ "url": "https://storage.googleapis.com/.../video.mp4", ... }'],notes:["The URL field is the atomic skill's sole product","vendor / internal metadata fields must not be leaked to the user"]},publishTopic:{intro:["After producing motion-controlled video URL, call publish_content with","presentation_family='video' + media fields."],fields:[{name:"presentation_family",value:"'video'"},{name:"media_urls.video",value:"<motion control output URL>"},{name:"delivery_format",value:"'video'"}]}})}(_d),function(e){Ps(e,{verb:"generate-tts",actionName:"generate_tts",schema:Zo,billing:{schema:kl,select:e=>({service:e.service,text:e.text}),quote:xl},supportsBatch:!0,description:"Generate speech audio from text. `--provider` picks the backend (minimax / elevenlabs / elevenlabs-dialogue / voxcpm).",whenToUse:["You need synthetic speech from text","Multi-line / multi-voice via --jobs-file","As the first step of a talking-head pipeline; pipe the resulting `audio_url` into `dl lipsync`","You need to create a voice sample from an authorized reference audio clip — use `--provider=voxcpm` with `--audio-url=<reference>`","You need a custom voice from a free-form voice description — use `--provider=voxcpm` without `--audio-url` and put the description in `--control`"],whenNotToUse:["You need a music track (vocals or instrumental) — use `dl generate-music`","You only need the lip-sync stage and already have the audio — use `dl lipsync` directly"],notes:["Per-provider routing is via `--provider` (extraFlag). The `--service` enum (minimax-tts / voxcpm) is selected to match the provider.","For minimax / elevenlabs / elevenlabs-dialogue, look up the voice id with `dl knowledge search --domain=voice --query=…`.","`--provider=voxcpm` does NOT use voice_id. Pass `--audio-url` (reference audio) to clone; omit it to synthesize from `--control` (voice description). See `dl generate-tts model voxcpm` for the full call shape."],examples:[{caption:"single, minimax (default)",command:'dl generate-tts --service=minimax-tts --text="Hello, world." --emotion=calm'},{caption:"elevenlabs single voice",command:'dl generate-tts --provider=elevenlabs --service=minimax-tts \\\n --voice-id=<elevenlabs_voice_id> --text="Hello, world." --speed=1'},{caption:"elevenlabs multi-voice dialogue",command:'dl generate-tts --provider=elevenlabs-dialogue --service=minimax-tts \\\n --text="Speaker turns…" --speed=1'},{caption:"voxcpm clone — clone a real person's voice from reference audio",command:'dl generate-tts --provider=voxcpm --service=voxcpm \\\n --audio-url=https://.../reference.m4a \\\n --text="要朗读的台词" --control="calm warm"'},{caption:"voxcpm prompt — synthesize from voice description (no reference audio)",command:'dl generate-tts --provider=voxcpm --service=voxcpm \\\n --text="要朗读的台词" --control="warm calm female narrator"'}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed","data":{"url":"https://...mp3"}}',extraFlags:[{spec:"--provider <name>",description:"backend route",default:"minimax",enum:lc}],resolveActionName:e=>{const t=String(e.provider??"minimax"),i=cc[t];if(!i)throw new Error(`unknown --provider: ${t}; expected one of ${lc.join(", ")}`);return i},modelTopic:{rankingSummary:["⚠ provider is selected via the `--provider` extraFlag. `--service` mirrors the chosen","provider (minimax-tts for the three platform providers; voxcpm for self-hosted voxcpm).","The four providers route to different backend actions / wire shapes:"," --provider=minimax → MiniMax TTS (default, multilingual + explicit pause control)"," --provider=elevenlabs → ElevenLabs single voice"," --provider=elevenlabs-dialogue → ElevenLabs multi-voice dialogue"," --provider=voxcpm → VoxCPM2 self-hosted (audio-reference voice cloning or description-based custom voice)"],services:[{service:"minimax",label:"MiniMax TTS",tier:"🥇 Default",bestFor:"Multilingual (Chinese / English / Japanese / etc.), explicit pause control, emotion control",quality:"High",speed:"30-60s",cost:"low",description:["MiniMax TTS, Pi's default provider.","Multilingual + emotion control via --emotion + <#X#> pause + language boost.","The voice library is searchable via dl knowledge search --domain=voice","(101 profiles: 40 Chinese + 61 English)."],promptTips:["Use native MiniMax markers only for deliberate pauses: <#X#> pause (X seconds, decimal); punctuation — long dashes / ... ellipsis are processed as natural short pauses","Keep --text to spoken words, punctuation, and pause markers; do not add inline emotion tags","Do not apply other TTS vendors' bracketed tags — MiniMax does not recognize them and reads them as literal characters","For code-mixed text, you must add --language-boost"],constraints:["voice_id must be found via dl knowledge search --domain=voice — do not rely on memory or fabricate","text length cap / model list / speed / vol / pitch / sample_rate / bitrate valid ranges all per --help"],flagSubset:["provider","service","text","voice-id","model","speed","vol","pitch","emotion","language-boost","format","sample-rate","bitrate"],examples:[{caption:"single, minimax default",command:'dl generate-tts --provider=minimax --service=minimax-tts \\\n --text="今天<#0.5#>真是个好天气,你看天上多蓝。" \\\n --voice-id=<voice_id> --emotion=calm --language-boost=auto'}]},{service:"elevenlabs",label:"ElevenLabs single voice",tier:"High-quality English / multilingual",bestFor:"ElevenLabs single voice. Higher quality, rich English / multilingual detail",quality:"Very High",speed:"30-60s",cost:"mid",description:["ElevenLabs single voice. Higher quality — suits scenarios that need the ElevenLabs distinctive voice library or","mixed Chinese-English / long-form narration.","","⚠ voice_id must be an ElevenLabs one, not MiniMax — use","dl knowledge search --domain=voice --query='<desc>' with filters to","pick a voice sourced from elevenlabs."],constraints:["voice_id must come from ElevenLabs — cannot use a MiniMax voice_id","--provider=elevenlabs (not --service)"],flagSubset:["provider","service","text","voice-id","model","speed"],examples:[{caption:"elevenlabs single voice",command:'dl generate-tts --provider=elevenlabs --service=minimax-tts \\\n --voice-id=<elevenlabs_voice_id> --text="Hello, world." --speed=1'}]},{service:"elevenlabs-dialogue",label:"ElevenLabs multi-voice dialogue",tier:"Multi-character dialogue",bestFor:"Multi-character dialogue synthesis (dialogue / interview / multi speaker turns)",quality:"Very High",speed:"1-2min",cost:"high",description:["ElevenLabs multi-voice dialogue. One call synthesizes dialogue across multiple speakers.","Usage differs from single voice — write text in multi-turn form and the vendor routes the voices itself."],constraints:["text must follow the vendor-expected multi-speaker format; run --print-schema for the exact schema"],flagSubset:["provider","service","text","speed"],examples:[{caption:"elevenlabs dialogue",command:'dl generate-tts --provider=elevenlabs-dialogue --service=minimax-tts \\\n --text="Speaker A: Hello.\\nSpeaker B: Hi there!" --speed=1'}]},{service:"voxcpm",label:"VoxCPM2 (self-hosted custom voice sample / authorized reference cloning)",tier:"Custom voice sample generator + authorized reference cloner",bestFor:"Create a custom voice sample from a free-form text description when no reference audio exists, or clone an authorized reference voice from one clean audio clip. Use this when MiniMax / ElevenLabs voice libraries don't cover the target voice and no reusable platform voice_id should be created.",quality:"Very High (clone fidelity scales with reference audio quality)",speed:"10-30s inference + 0-150s RunPod cold start",cost:"low (self-hosted, only pays RunPod GPU seconds)",description:["VoxCPM2 deployed on RunPod serverless (dramaland-ai-small). Use it for voice samples","that are represented by the returned audio URL plus prompt/reference metadata, not by","a reusable provider voice_id.","","Two internal modes, automatically chosen by api-layer from the `--audio-url` field:"," - voiceclone (audio_url present) → authorized reference audio + text → clone the audio's voice"," - voiceprompt (audio_url absent) → voice description + text → synthesize from description","","There is NO voice_id concept in voxcpm — voice identity is either the reference audio or","the textual description in --control."],promptTips:["`--audio-url` must be an authorized clean 3-30s clip of the target voice; clearer reference → better clone fidelity","`--control` semantics flip by mode:"," - clone mode (with --audio-url): emotion / style controls, e.g. `calm`, `excited`, `whisper`"," - prompt mode (without --audio-url): voice description, e.g. `warm calm female narrator`"," English short phrases work best either way","voxcpm reads text literally — MiniMax pause markers like <#X#> are NOT recognized; use punctuation for pauses instead"],constraints:["text length cap 4096 characters","reference audio max 50MB; content-type must be audio/* (video / image refused)","clone mode requires `--audio-url`; if you don't have a reference clip, omit `--audio-url` (auto-falls to prompt mode)","do NOT pass --voice-id / --emotion / --language-boost / etc. — those are minimax-specific and ignored here","cold start can add up to ~150s on first call; the api-layer's async submit/poll handles this transparently — don't add your own retries"],flagSubset:["provider","service","text","audio-url","control"],examples:[{caption:"voxcpm clone — clone the voice in a reference audio",command:'dl generate-tts --provider=voxcpm --service=voxcpm \\\n --audio-url=https://.../target-voice.m4a \\\n --text="要朗读的台词" --control="calm"'},{caption:"voxcpm prompt — no reference audio, synthesize from voice description",command:'dl generate-tts --provider=voxcpm --service=voxcpm \\\n --text="要朗读的台词" --control="warm calm female narrator"'}]}],decisionLogic:[{when:"Default / Chinese / pause markers + request-level emotion",pick:"--provider=minimax (default)"},{when:"Need the ElevenLabs voice library / higher English quality",pick:"--provider=elevenlabs"},{when:"Multi-speaker dialogue synthesis",pick:"--provider=elevenlabs-dialogue"},{when:"Need a VoxCPM voice sample from an authorized reference audio, with no reusable provider voice_id",pick:"--provider=voxcpm with --audio-url=<reference>"},{when:"Need a custom voice from a free-form text description, when no reference audio is available",pick:"--provider=voxcpm with --control='<voice description>' (no --audio-url)"}]},preflightTopic:{intro:"Confirm these 4 items before the first dl generate-tts call:",decisions:[{name:"Provider",description:"Which provider to use (minimax / elevenlabs / elevenlabs-dialogue / voxcpm). Decides the voice-identity mechanism + marker syntax + which flags are read.\n - minimax / elevenlabs / elevenlabs-dialogue → platform voice library (voice_id required)\n - voxcpm → no voice_id; supply --audio-url (clone) or --control (voice description)"},{name:"Voice identity",description:"For minimax / elevenlabs / elevenlabs-dialogue: search a voice_id via `dl knowledge search --domain=voice`\n(query is natural-language; filter fields / valid enums per `dl knowledge search --help`).\nFor voxcpm: either an `--audio-url` reference clip (clone) OR a textual `--control` voice description (prompt). voxcpm ignores voice_id."},{name:"Text preparation",description:"Prepare text per the chosen provider's marker syntax.\n - MiniMax: <#X#> pauses + standard punctuation for short pauses; set tone with --emotion instead of inline tags\n - voxcpm: plain text, no markers — punctuation only (markers are read literally)\n - elevenlabs / elevenlabs-dialogue: per ElevenLabs marker conventions (see model -h)"},{name:"Audio format",description:"format / sample_rate / bitrate — defaults are usually enough. Adjust only if downstream has special requirements (lipsync / concat). voxcpm's output format follows its handler default (mp3 / flac) and ignores these flags."}],notes:["If cost-sensitive → read pricing-and-policies-dramaland-faq/SKILL.md first","For batch generation use --jobs-file, do not block per item"]},policyTopic:{intro:"Five classes of hard rules: User-facing non-leak / Package gate / **Marker syntax discipline** / **TTS pronounceability discipline** / Failure fallback ladder.",rules:[{title:"1. User-Facing Communication — do not leak internal details",body:["vendor / price / internal model code / trace id must not be surfaced to the user.","User-facing summary only mentions: provider name (MiniMax / ElevenLabs) + character /","language + action (generate TTS / TTS dialogue)."]},{title:"2. Production Package Gate — do not call before paid authorization",body:["provider / model / voice_id / generation count / text segment range / text length / target","duration / audio format parameters / downstream usage are all components of the paid package authorization. Do not call before authorization;","within the same package you can batch; only re-ask on package overflow (switching model / voice / adding count /","changing format / fallback / paid regeneration)."]},{title:"3. MiniMax Marker syntax discipline (provider=minimax only)",body:["MiniMax marker syntax **must use native forms** — do not apply other TTS vendors' bracketed","tags (MiniMax does not recognize them and reads them as literal characters, producing noise).","Keep script text to spoken words, punctuation, and explicit pause markers; do not add inline emotion tags.","","### Pauses"," - <#X#>, X is seconds as a decimal (<#0.3#> / <#0.8#> / <#1.5#>)"," - Punctuation substitutes: long dashes (—) / ... ellipsis are processed naturally as short pauses","","### Emotion"," - Do not put inline emotion tags in --text"," - Per-request: attach --emotion=... (valid enum per --help)","","### Language hint"," - For code-mixed text, you must add --language-boost (valid values per --help)"]},{title:"4. TTS pronounceability discipline — hard constraint on the script side",body:["When writing the script, spell out complex numbers / currency / abbreviations / units / dates / ratios — **do not bet","on TTS getting them right on its own**. Simple integers (5 / 27 / 120) / bare 4-digit years (2024) / whole percentages","(50%) are usually OK; otherwise spell them out:",""," $1.4M → one point four million dollars"," 42.7% → forty-two point seven percent"," Q3 2024 → third quarter of twenty twenty-four"," 3:1 → three to one"," 42°F → forty-two degrees Fahrenheit"," ROI → R O I (spaces force letter-by-letter) or return on investment"," Chinese percent → 百分之四十二点七"," Chinese currency magnitude → 一点四亿美元 or 14 亿美元","","Mispronunciation can only be fixed by editing the caption — you cannot re-pronounce the audio — so **handle it at script time**."]},{title:"5. voxcpm input discipline (provider=voxcpm only)",body:["voxcpm reads text **literally**. Markers from other TTS vendors (MiniMax `<#X#>`, ElevenLabs","`[break]`, inline emotion tags) are NOT recognized and will be pronounced as","literal characters. Use plain text + punctuation for pauses.","","### Voice identity"," - Clone mode (with --audio-url): voice timbre comes from the reference audio; --control controls emotion / style (`calm` / `excited`)"," - Prompt mode (without --audio-url): voice timbre comes from the --control description (`warm calm female narrator`); English short phrases work best","","### Flags voxcpm ignores"," --voice-id / --emotion / --language-boost / --model / --sample-rate / --bitrate / --pitch / --vol"," (those are minimax-specific; voxcpm silently drops them)"]},{title:"6. Failure fallback ladder",body:["When this verb produces jitter / silence / clipping / content-moderation blocks, in order:","","1. Retry once (transient network / quota wobbles usually pass; voxcpm cold start can add ~150s)","2. Switch model / tune knobs: step within the model list listed by --help (high-quality vs fast)"," or tune speed / emotion / language_boost (minimax only)","3. Re-pick voice identity:"," - minimax / elevenlabs: pick another voice_id via dl knowledge search --domain=voice"," - voxcpm clone: try a cleaner / longer / different reference --audio-url"," - voxcpm prompt: refine --control description","4. Switch provider — esp. when MiniMax / ElevenLabs voice library cannot match the target voice:"," fall back to --provider=voxcpm with an authorized reference audio.","5. Fall back to script changes: too long / too dense markers / too many hard-to-pronounce expressions → shorten + dilute"," markers + convert un-spelled-out complex numbers / abbreviations into pronounceable form (see rule 4)"]}]},compositionTopic:{intro:"This atomic skill only produces an audio URL; artifact / canvas registration and other downstream responsibilities are not this verb's job.",integrations:[{skill:"Voice ID search (dl knowledge search --domain=voice) — minimax / elevenlabs only",rule:["MiniMax voice library has 101 profiles (40 CN + 61 EN). Search:"," dl knowledge search --domain=voice --query='<natural-language description>' \\",' --filters-file=- <<<\'{"language":"CN","gender":"Female"}\'',"","For specific filter fields / valid enums see dl knowledge search --help.","","For the ElevenLabs voice library, filter via --filters-file with 'provider': 'elevenlabs'.","","voxcpm does NOT use this knowledge base — its voice identity is either the reference","--audio-url (clone) or the --control description (prompt). Skip voice search entirely","when --provider=voxcpm."]},{skill:"downstream lipsync / video composition",rule:["The generated audio_url can be fed directly into:"," - dl lipsync --audio-url=... (seedance 2.0 ≤ 15s / dlai2v ≤ 19s, see lipsync model -h)"," - dl generate-video --reference-audio-url=... (seedance 2.0 same 15s cap)","","Target duration must be aligned with the downstream audio duration cap during the generate-tts stage."]},{skill:"right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs dl artifact write / patch-json pi_media_log on your behalf —","that is the composition layer's job."]}]},asyncTopic:{intro:["dl generate-tts by default returns { job_ref, status: 'pending' } and exits immediately — do not poll.","Results are injected into the session as [async-callback] job=<ref> text; typical duration 30s-2min.","","Only run dl poll separately when the next step strictly requires the result (immediately feeding lipsync / ffmpeg concat)."],resultShape:['{ "audio_url": "https://storage.googleapis.com/.../speech.mp3",',' "duration_ms": 3200,',' "format": "mp3",',' "usage_characters": 42 }'],notes:["audio_url is the atomic skill's sole product and can serve directly as a downstream reference_audio_url","vendor-internal metadata fields must not be leaked to the user"]},publishTopic:{intro:["After producing TTS audio URL, call publish_content with presentation_family='text',","media_urls.audio=<url>, delivery_format='audio'. The playbook 'Publishing Your Work /","text' template is the closest match; pass media_urls.audio explicitly (the runtime will not infer audio from","presentation_family)."],fields:[{name:"presentation_family",value:"'text'"},{name:"media_urls.audio",value:"<TTS audio URL>"},{name:"delivery_format",value:"'audio'"}]}})}(_d),function(e){Ps(e,{verb:"detect-shots",actionName:"detect_shots",schema:ir,billing:{schema:pl,select:()=>({}),quote:ml},supportsBatch:!1,description:"Detect shot boundaries via TransNetV2. Synchronous — returns the shot list directly.",whenToUse:["You need shot-level segmentation of a video for breakdown / analysis"],whenNotToUse:["You need a transcript of the video's audio — use `dl transcribe`","You need beat / tempo of the audio track — use `dl analyze-beats`"],examples:[{caption:"default threshold",command:"dl detect-shots --video-url=https://example.com/clip.mp4 --output-format=full"}],outputSingle:'{"ok":true,"success":true,"shots":[{"index":0,"start_time":0,"end_time":7.97,...}, ...]}'})}(_d),function(e){Ps(e,{verb:"download-media",actionName:"download_media",schema:nr,billing:{schema:hl,select:()=>({}),quote:fl},supportsBatch:!1,description:"Download social-media media (TikTok / Instagram / Twitter / Bilibili / …) and re-host on CDN.",notes:["Sources supported: TikTok, Instagram, Twitter/X, Bilibili, and most cobalt-supported sites.","YouTube is currently NOT supported. Limits: ≤500MB per asset, 30 requests/minute."],whenToUse:["You have a social-media URL and need a persistent CDN copy for downstream tools"],whenNotToUse:["The URL is a YouTube link — not supported; surface the limitation to the user instead","You only need to fetch+extract HTML/text — use `dl fetch`"],examples:[{caption:"auto format",command:"dl download-media --url=https://www.tiktok.com/@user/video/123 --format=auto"}],outputSingle:'{"ok":true,"success":true,"data":{"url":"https://storage.../media.mp4"}}',preflightTopic:{intro:"Confirm these 2 items before the first dl download-media call:",decisions:[{name:"Source platform",description:"Supported: TikTok / Instagram / Twitter / Bilibili / Reddit / Vimeo /\nSoundCloud / Twitch / Pinterest / Dailymotion / Loom / Rutube / Streamable.\n**YouTube is NOT supported** (anti-bot block) — if the user gives a YouTube link,\nsurface the limitation; do not retry blindly."},{name:"Format / quality",description:"--format=auto (default) / video / audio / image.\n--video-quality: default is usually enough; on large files + file_too_large error → lower\nquality and retry."}],notes:["≤500MB per file","30 req/min/instance (rate limit)","Synchronous call, no dl poll"]},policyTopic:{rules:[{title:"1. Error handling loop (full error-code table)",body:["When error_code is returned, handle per the table:",""," rate_limited → wait the hinted seconds and retry"," cobalt_unavailable → ~30s retry"," download_timeout → ~30s retry"," gcs_upload_failed → ~30s retry"," content_not_found → unrecoverable, tell the user the source is unreachable"," content_requires_auth → same as above (common for YouTube)"," content_geo_restricted → same as above"," content_age_restricted → same as above"," file_too_large → lower video_quality or --format=audio and retry"," local_processing_required → same as above"," platform_unsupported → unrecoverable, platform not supported"," internal_error / service_misconfigured → escalate (do not retry)"]},{title:"2. Warning handling",body:["warning_code: gcs_fallback → R2 upload failed, the URL is a temporary direct link that may expire."," If you need a persistent URL, re-run.","","warning_code: picker_first_only → the source has multiple items (e.g. Instagram carousel),"," only the first was taken. For others, the source URL must explicitly point to the specific item."]},{title:"3. YouTube hard-unsupported",body:["YouTube links are currently blocked by anti-bot and return content_requires_auth.","Do not retry blindly — tell the user that YouTube is not supported."]}]},compositionTopic:{intro:"The download result is a persistent CDN URL on our R2 — feed it directly into downstream verbs / artifacts. Do NOT pass to upload_file (it is already hosted by us).",integrations:[{skill:"downstream verbs using the downloaded URL",rule:["output_url is public + permanent and can be passed directly to:"," - dl generate-video --image-urls=... / --ref-video-url=..."," - dl lipsync --image-url=... / --audio-url=..."," - dl render-caption / dl ffmpeg, etc.","","If you hit warning_code: gcs_fallback, re-run first to get a stable URL before feeding downstream;","do not risk expiration."]}]},asyncTopic:{intro:["⚠ dl download-media is **synchronous** (supportsBatch=false). The response includes output_url","+ filename + content_type + file_size_bytes + source_platform and other fields.","Typical duration 5-15s (short clips) / up to 120s (large files)."],resultShape:['{ "ok": true, "success": true,',' "data": { "output_url": "https://public.ilands.ai/.../media.mp4",',' "filename": "...",',' "content_type": "video/mp4",',' "file_size_bytes": 12345678,',' "source_platform": "tiktok" } }']}})}(_d),function(e){Ps(e,{verb:"geocode",actionName:"geocode",schema:ar,billing:{schema:$l,select:e=>({mode:"string"==typeof e.address&&e.address.trim()?"forward":"reverse"}),quote:Nl},supportsBatch:!1,description:"Forward (address → coords) or reverse (coords → address) geocoding.",notes:["Pass exactly one of: `--address` (forward) OR `--latitude`+`--longitude` (reverse).","Provider auto-routes by region (Google globally, AMap inside China, Panoramax in France)."],whenToUse:["You need to look up coordinates for a place name, or a place name for coordinates"],whenNotToUse:["You need a list of POIs near a point — use `dl places search`"],examples:[{caption:"forward",command:'dl geocode --address="Tokyo Tower, Tokyo"'},{caption:"reverse",command:"dl geocode --latitude=35.6586 --longitude=139.7454"}],outputSingle:'{"ok":true,"success":true,"data":{...}}'})}(_d),function(e){const t=e.command("streetview").description("Street-level imagery and coverage info (Google / AMap / Panoramax).");Ps(t,{verb:"metadata",actionName:"streetview_metadata",schema:rr,billing:{schema:Kl,select:()=>({}),quote:Gl},supportsBatch:!1,description:"Check street-view coverage at coordinates. Low-cost — call before `dl streetview image`.",whenToUse:["You're about to fetch a streetview image but want to confirm coverage exists first"],examples:[{caption:"coverage probe",command:"dl streetview metadata --latitude=35.6586 --longitude=139.7454"}]}),Ps(t,{verb:"image",actionName:"streetview_image",schema:or,billing:{schema:Vl,select:()=>({}),quote:Jl},supportsBatch:!1,description:"Street-level image at coordinates; auto-routes provider (Google / AMap / Panoramax).",whenToUse:["You need a ground-level photo at known coordinates"],examples:[{caption:"with view direction",command:"dl streetview image --latitude=35.6586 --longitude=139.7454 --heading=90 --pitch=0 --fov=90"}]})}(_d),function(e){const t=e.command("places").description("Search places / POIs near coordinates and fetch their photos.");Ps(t,{verb:"search",actionName:"places_search",schema:sr,billing:{schema:Ml,select:()=>({}),quote:Ul},supportsBatch:!1,description:"Search places / POIs near coordinates by keyword.",whenToUse:["You need a list of places matching a keyword near a known location"],examples:[{caption:"ramen near Tokyo Tower",command:"dl places search --query=ramen --latitude=35.6586 --longitude=139.7454 --radius=500"}]}),Ps(t,{verb:"photo",actionName:"place_photo",schema:lr,billing:{schema:Ll,select:()=>({}),quote:zl},supportsBatch:!1,description:"Fetch a photo by photo_reference (returned from `dl places search`).",whenToUse:["You have a photo_reference token from places search and want to materialise the image"],examples:[{caption:"default size",command:"dl places photo --photo-reference=<token> --max-width=1600"}]})}(_d),function(e){Ps(e,{verb:"static-map",actionName:"static_map",schema:cr,billing:{schema:Hl,select:()=>({}),quote:Bl},supportsBatch:!1,description:"Bird's-eye view map image at coordinates with optional markers.",notes:["`--size` is `WIDTHxHEIGHT` in pixels (e.g. `600x400`); both must be positive integers."],whenToUse:["You need a static map tile centred on coordinates for embedding / reference"],whenNotToUse:["You need a street-level photo, not a top-down map — use `dl streetview image`","You need to search for POIs at the location — use `dl places search`"],examples:[{caption:"default",command:"dl static-map --latitude=35.6586 --longitude=139.7454 --zoom=15 --size=600x400"}],outputSingle:'{"ok":true,"success":true,"data":{"url":"https://storage.../map.png"}}'})}(_d),function(e){e.command("ffmpeg").description("Run raw ffmpeg / ffprobe in the remote ffmpeg sandbox. Synchronous by default (returns URL or probe JSON). Pass --async for long encodes — returns { status: 'pending', job_ref } and resumes via [async-callback].").addHelpText("after",["","Routing guidance:"," ffprobe / -c copy / 简单 trim 用本地 ffmpeg (秒级)。"," -c:v 重编码 / filter_complex / 输入 >2min 走 dl ffmpeg (同步, 默认)。"," >5min 编码 / MV 长任务 加 --async 走 callback (远程 sandbox 上限 1800s)。","","Sync mode (default):"," Polls until done or --timeout-ms expires. Default budget 10min;"," wrap with bash { timeout: N } to extend past the 5min sandbox cap.","","Async mode (--async):"," Returns { status: 'pending', job_ref } immediately. End the turn —"," result arrives as [async-callback] job=<ref> in a later turn."," Do NOT poll, do NOT re-submit, do NOT sleep/while wait.","","Example (sync, 默认):"," cat <<EOF | dl ffmpeg --command-file=- --input=src=https://…"," ffprobe -v quiet -print_format json -show_format -show_streams /input/src"," EOF","","Example (async, 长编码):"," cat <<EOF | dl ffmpeg --async --command-file=- --input=src=https://…"," ffmpeg -i /input/src -c:v libx264 -preset medium -crf 23 /output/out.mp4"," EOF"," # 命令立刻返回 pending; end turn 等 [async-callback]。"].join("\n")).option("--command <text>",'RECOMMENDED: ffmpeg/ffprobe command line inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --command "$(cat cmd.txt)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --command-file.').option("--command-file <path|->",'LEGACY: ffmpeg/ffprobe command line as raw text via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --command "$(cat file)". Use --command-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--input <name=url>","name=url for /input/{name}; pass multiple --input flags",(e,t={})=>{const i=e.indexOf("=");if(i<=0)throw new ie(`--input expects name=url, got ${e}`);return t[e.slice(0,i)]=e.slice(i+1),t},{}).option("--output-kind <tag>","classification tag echoed back in the response").option("--timeout <s>","sandbox-side timeout seconds (capped at 1800)",e=>Number(e)).option("--agent-id <n>","",e=>Number(e)).option("--async","async callback mode: return { status: 'pending', job_ref } immediately, resume via [async-callback]. Default is sync polling.").option("--timeout-ms <n>","[sync only] client polling budget (default 600000 = 10min)",e=>Number(e)).option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").action(async e=>{e.printSchema&&Js({command:"dl ffmpeg",summary:"Run raw ffmpeg / ffprobe in the remote sandbox. Synchronous by default (returns URL or probe JSON). Pass --async for long encodes — returns { status: 'pending', job_ref } and resumes via [async-callback].",scalars:[{name:"input",type:"string",required:!1,description:"name=url; repeatable; mounted as /input/<name>"},{name:"output-kind",type:"string",required:!1,description:"tag echoed back in response"},{name:"timeout",type:"integer",required:!1,description:"sandbox timeout seconds (capped at 1800)"},{name:"agent-id",type:"integer",required:!1,description:""},{name:"async",type:"boolean",required:!1,description:"async callback mode (default is sync polling)"},{name:"timeout-ms",type:"integer",required:!1,description:"[sync only] client polling budget (default 600000)"},{name:"command",type:"string",required:!1,description:"RECOMMENDED inline ffmpeg/ffprobe command line (required: pass this or --command-file)"}],files:[{name:"command-file",required:!1,kind:"text",description:"LEGACY: ffmpeg/ffprobe command line via file/stdin (prefer --command inline)",example:'ffmpeg -i /input/a -i /input/b -filter_complex "[0:v][1:v]overlay" /output/out.mp4'}]});let t,i="";try{const n=await hs(e.command?String(e.command):void 0,e.commandFile?String(e.commandFile):void 0,{inline:"--command",file:"--command-file"});n&&(i=n.raw.trim(),t=n.label)}catch(e){throw e instanceof wa&&bs(e),e}i||ys("E_SCHEMA","--command is required (pass the ffmpeg command inline, or use --command-file for the legacy file/stdin path)",tc("run `dl ffmpeg --print-schema` to see the expected shape"),{flag:"--command"});const n=e.input&&Object.keys(e.input).length>0?e.input:void 0,o=!0===e.async;_s({command:"ffmpeg",ffmpeg_command:i,inputs:n??null,source:t??null,mode:o?"async":"sync"});const r=k();try{let t;if(o&&(t=function(e){const t=(process.env.CALLBACK_SERVER_URL??"").replace(/\/+$/,"");if(!t)throw new Jr("CALLBACK_SERVER_URL not set — async ffmpeg submit needs it for the vendor callback target","hono-pi-e2b injects this on every commands.run; drop --async to use the default polling path, or set it manually in LOCAL_SANDBOX dev");const i=(process.env.PI_PROJECT_ID??"").trim();if(!i)throw new Jr("PI_PROJECT_ID not set — required for callback URL routing under callback-resume v2","hono-pi-e2b injects PI_PROJECT_ID on every commands.run; drop --async to use the default polling path, or set it manually in LOCAL_SANDBOX dev");return`${t}/callback/${encodeURIComponent(i)}/${e}`}(r)),await Da("ffmpeg-sandbox","cli",{job_id:r,command:i,...n?{inputs:n}:{},...void 0!==e.timeout?{timeout:Number(e.timeout)}:{},...void 0!==e.agentId?{agent_id:Number(e.agentId)}:{},...e.outputKind?{output_kind:String(e.outputKind)}:{},...t?{callback_url:t}:{}}),o)return ws({action:"ffmpeg",job_ref:r,mode:"single"}),void gs({ok:!0,status:"pending",job_ref:r,output_kind:e.outputKind??null});const a=await async function(e,t){const i=Date.now();for(;Date.now()-i<t;){const t=await Ha("ffmpeg-sandbox",`jobs/${e}`,{},{timeoutMs:3e4,retries:0});if("completed"===t.status)return t.data??t;if("failed"===t.status)throw new Error(`ffmpeg-sandbox: ${t.error??"failed"}`);await new Promise(e=>setTimeout(e,2e3))}throw new Error(`ffmpeg-sandbox: timeout after ${t}ms`)}(r,e.timeoutMs??6e5);gs({ok:!0,output_kind:e.outputKind??null,data:a})}catch(e){e instanceof Jr&&vs(e.message,tc(e.hint)),vs(e instanceof Error?e.message:String(e),ec)}})}(_d),function(e){e.command("remotion").description("Render a Remotion composition.").addHelpText("after",["","`--source-file` is the LOCAL path to a Component.tsx file readable at","runtime — dl reads it, ships the source through the gateway, and the","renderer compiles it server-side. No upload step required.","","Example (stdin for inputProps):"," cat <<EOF | dl remotion --source-file=/workspace/remotion/title_card.tsx \\"," --duration-in-frames=120 --fps=30 --width=1080 --height=1920 \\"," --input-props-file=-",' {"title":"Hello"}'," EOF"].join("\n")).option("--source <text>",'RECOMMENDED: Component.tsx source inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --source "$(cat title_card.tsx)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --source-file.').option("--source-file <path>",'LEGACY: local path to a Component.tsx file (read at submit time, shipped server-side). File content is invisible to the billing extension + dl adapter, so prefer --source "$(cat file)". Use --source-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--duration-in-frames <n>","",e=>Number(e)).option("--fps <n>","",e=>Number(e)).option("--width <n>","",e=>Number(e)).option("--height <n>","",e=>Number(e)).option("--composition-id <id>").option("--input-props <inline-json>",'RECOMMENDED: JSON inputProps inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --input-props "$(cat props.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --input-props-file.').option("--input-props-file <path|->",'LEGACY: JSON inputProps via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --input-props "$(cat file)". Use --input-props-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--agent-id <n>","",e=>Number(e)).option("--timeout-ms <n>","client polling budget (default 900000 = 15min)",e=>Number(e)).option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{let t,i,n,o;if(e.printSchema&&Js({command:"dl remotion",summary:"Render a Remotion composition.",scalars:[{name:"source",type:"string",required:!1,description:"RECOMMENDED inline Component.tsx source (required: pass this or --source-file)"},{name:"source-file",type:"string",required:!1,description:"LEGACY: absolute path to a Component.tsx (prefer --source inline)"},{name:"duration-in-frames",type:"integer",required:!0,description:""},{name:"fps",type:"integer",required:!1,description:""},{name:"width",type:"integer",required:!1,description:""},{name:"height",type:"integer",required:!1,description:""},{name:"composition-id",type:"string",required:!1,description:""},{name:"agent-id",type:"integer",required:!1,description:""},{name:"timeout-ms",type:"integer",required:!1,description:""},{name:"input-props",type:"string",required:!1,description:"RECOMMENDED inline JSON inputProps (sibling of --input-props-file)"}],files:[{name:"input-props-file",required:!1,kind:"object",description:"LEGACY: JSON inputProps via file/stdin (prefer --input-props inline)",example:'{"title":"Hello"}'}]}),e.source||e.sourceFile||ys("E_SCHEMA","--source is required (pass the Component.tsx inline, or use --source-file for the legacy file path)","pi skills should pass the component inline via --source, or an absolute path via --source-file",{flag:"--source"}),e.source&&e.sourceFile&&ys("E_SCHEMA","--source and --source-file are mutually exclusive","prefer --source (inline); file content is invisible to the billing extension / dl adapter",{inline_flag:"--source",file_flag:"--source-file"}),void 0===e.durationInFrames&&ys("E_SCHEMA","--duration-in-frames is required",void 0,{flag:"--duration-in-frames"}),e.source)t=String(e.source),i="inline";else{try{t=await O(String(e.sourceFile),"utf8")}catch(t){const i=t instanceof Error?t.message:String(t);ys("E_FILE_MISSING",`--source-file: cannot read ${e.sourceFile} (${i})`,"make sure the path exists in the sandbox",{flag:"--source-file",given:String(e.sourceFile)})}i=String(e.sourceFile)}t||ys("E_SCHEMA",e.source?"--source is empty":"--source-file is empty","pi skills should resolve the component via --source (inline) or an absolute --source-file path.",{flag:e.source?"--source":"--source-file"});try{const t=await ms(e.inputProps?String(e.inputProps):void 0,e.inputPropsFile?String(e.inputPropsFile):void 0,{inline:"--input-props",file:"--input-props-file"});t&&(n=t.data,o=t.source.label)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:"remotion",source_file:i,input_props:n??null,input_props_source:o??null});const r=k(),a={source:"dl",event:"remotion_render",credits:20,command:(s={command:"remotion",action:"remotion_render"}).command,action:s.action??"remotion_render",details:{rule:"remotion.fixed"}};var s;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"remotion_render",totalCredits:a.credits,items:[a]});const l={source_code:t,duration_in_frames:Number(e.durationInFrames),...e.compositionId?{composition_id:String(e.compositionId)}:{},...void 0!==e.fps?{fps:Number(e.fps)}:{},...void 0!==e.width?{width:Number(e.width)}:{},...void 0!==e.height?{height:Number(e.height)}:{},...n?{input_props:n}:{}};let c=!1;try{await Da("remotion","renders",{job_id:r,params:l,agent_id:e.agentId??0},{billing:{jobRef:r,quote:a}}),c=!0;const t=await async function(e,t){const i=Date.now();for(;Date.now()-i<t;){const t=await Ha("remotion",`renders/${e}`,{},{timeoutMs:3e4,retries:0});if("completed"===t.status)return t.data??t;if("failed"===t.status)throw new Error(`remotion: ${t.error??"failed"}`);await new Promise(e=>setTimeout(e,2e3))}throw new Error(`remotion: timeout after ${t}ms`)}(r,e.timeoutMs??9e5);gs({ok:!0,job_ref:r,data:t,billing:a})}catch(e){c&&await async function(e){try{await Ua({jobRef:e.jobRef,quote:e.quote,reason:e.reason})}catch(t){process.stderr.write(`${JSON.stringify({level:"warn",event:"dl_billing_refund_failed",job_ref:e.jobRef,reason:e.reason,error:t instanceof Error?t.message:String(t)})}\n`)}}({jobRef:r,quote:a,reason:"remotion_render_failed"}),e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:r}),e instanceof Jr&&vs(e.message,e.hint,{job_ref:r}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:r})}})}(_d),function(e){e.command("hyperframes").description("Render a HyperFrames HTML composition to MP4 (remote fallback path).").addHelpText("after",["","`--source-file` is the LOCAL path to a `.html` composition file —","dl reads it, ships the source through the gateway, and the renderer","runs hyperframes CLI server-side. No upload step required.","","Prefer local `npx hyperframes render` for short renders; use `dl","hyperframes` when sandbox CPU/memory limits are hit or the job is","large enough to want the GCS-uploaded output URL directly.","","Example (stdin for inputProps):"," cat <<EOF | dl hyperframes --source-file=/workspace/hf/title-card.html \\"," --duration-in-frames=120 --fps=30 --width=1080 --height=1920 \\"," --input-props-file=-",' {"title":"Hello"}'," EOF"].join("\n")).option("--source <text>",'RECOMMENDED: HTML composition source inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --source "$(cat title-card.html)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --source-file.').option("--source-file <path>",'LEGACY: local path to an HTML composition file (read at submit time, shipped server-side). File content is invisible to the billing extension + dl adapter, so prefer --source "$(cat file)". Use --source-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--duration-in-frames <n>","",e=>Number(e)).option("--fps <n>","",e=>Number(e)).option("--width <n>","",e=>Number(e)).option("--height <n>","",e=>Number(e)).option("--composition-id <id>").option("--input-props <inline-json>",'RECOMMENDED: JSON inputProps inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --input-props "$(cat props.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --input-props-file.').option("--input-props-file <path|->",'LEGACY: JSON inputProps via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --input-props "$(cat file)". Use --input-props-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--agent-id <n>","",e=>Number(e)).option("--timeout-ms <n>","client polling budget (default 900000 = 15min)",e=>Number(e)).option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{let t,i,n,o;if(e.printSchema&&Js({command:"dl hyperframes",summary:"Render a HyperFrames HTML composition to MP4 (remote fallback path).",scalars:[{name:"source",type:"string",required:!1,description:"RECOMMENDED inline HTML composition source (required: pass this or --source-file)"},{name:"source-file",type:"string",required:!1,description:"LEGACY: absolute path to a .html composition (prefer --source inline)"},{name:"duration-in-frames",type:"integer",required:!0,description:""},{name:"fps",type:"integer",required:!1,description:""},{name:"width",type:"integer",required:!1,description:""},{name:"height",type:"integer",required:!1,description:""},{name:"composition-id",type:"string",required:!1,description:""},{name:"agent-id",type:"integer",required:!1,description:""},{name:"timeout-ms",type:"integer",required:!1,description:""},{name:"input-props",type:"string",required:!1,description:"RECOMMENDED inline JSON inputProps (sibling of --input-props-file)"}],files:[{name:"input-props-file",required:!1,kind:"object",description:"LEGACY: JSON inputProps via file/stdin (prefer --input-props inline)",example:'{"title":"Hello"}'}]}),e.source||e.sourceFile||ys("E_SCHEMA","--source is required (pass the HTML composition inline, or use --source-file for the legacy file path)","pi skills should pass the composition inline via --source, or an absolute path via --source-file",{flag:"--source"}),e.source&&e.sourceFile&&ys("E_SCHEMA","--source and --source-file are mutually exclusive","prefer --source (inline); file content is invisible to the billing extension / dl adapter",{inline_flag:"--source",file_flag:"--source-file"}),void 0===e.durationInFrames&&ys("E_SCHEMA","--duration-in-frames is required",void 0,{flag:"--duration-in-frames"}),e.source)t=String(e.source),i="inline";else{try{t=await O(String(e.sourceFile),"utf8")}catch(t){const i=t instanceof Error?t.message:String(t);ys("E_FILE_MISSING",`--source-file: cannot read ${e.sourceFile} (${i})`,"make sure the path exists in the sandbox",{flag:"--source-file",given:String(e.sourceFile)})}i=String(e.sourceFile)}t||ys("E_SCHEMA",e.source?"--source is empty":"--source-file is empty","pi skills should resolve the composition via --source (inline) or an absolute --source-file path.",{flag:e.source?"--source":"--source-file"});try{const t=await ms(e.inputProps?String(e.inputProps):void 0,e.inputPropsFile?String(e.inputPropsFile):void 0,{inline:"--input-props",file:"--input-props-file"});t&&(n=t.data,o=t.source.label)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:"hyperframes",source_file:i,input_props:n??null,input_props_source:o??null});const r=k(),a={source:"dl",event:"hyperframes_render",credits:50,command:(s={command:"hyperframes",action:"hyperframes_render"}).command,action:s.action??"hyperframes_render",details:{rule:"hyperframes.fixed"}};var s;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"hyperframes_render",totalCredits:a.credits,items:[a]});const l={source_code:t,duration_in_frames:Number(e.durationInFrames),...e.compositionId?{composition_id:String(e.compositionId)}:{},...void 0!==e.fps?{fps:Number(e.fps)}:{},...void 0!==e.width?{width:Number(e.width)}:{},...void 0!==e.height?{height:Number(e.height)}:{},...n?{input_props:n}:{}};let c=!1;try{await Da("hyperframes","renders",{job_id:r,params:l,agent_id:e.agentId??0},{billing:{jobRef:r,quote:a}}),c=!0;const t=await async function(e,t){const i=Date.now();for(;Date.now()-i<t;){const t=await Ha("hyperframes",`renders/${e}`,{},{timeoutMs:3e4,retries:0});if("completed"===t.status)return t.data??t;if("failed"===t.status)throw new Error(`hyperframes: ${t.error??"failed"}`);await new Promise(e=>setTimeout(e,2e3))}throw new Error(`hyperframes: timeout after ${t}ms`)}(r,e.timeoutMs??9e5);gs({ok:!0,job_ref:r,data:t,billing:a})}catch(e){c&&await async function(e){try{await Ua({jobRef:e.jobRef,quote:e.quote,reason:e.reason})}catch(t){process.stderr.write(`${JSON.stringify({level:"warn",event:"dl_billing_refund_failed",job_ref:e.jobRef,reason:e.reason,error:t instanceof Error?t.message:String(t)})}\n`)}}({jobRef:r,quote:a,reason:"hyperframes_render_failed"}),e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:r}),e instanceof Jr&&vs(e.message,e.hint,{job_ref:r}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:r})}})}(_d),function(e){e.command("poll").description("Single one-shot status check for an async job by job_ref. Does NOT loop — call at most once; end your turn and let [async-callback] resume you when the job lands.").addHelpText("after",["","Output (success):",' {"ok":true,"job_ref":"<uuid>","status":"completed"|"failed"|"pending","data":{...}}',"","`status=pending` means the job exists but hasn't terminated yet. 404 from","the backend also maps to `pending` (job_ref not yet registered).","","DO NOT call this inside `sleep` / `for` / `while` loops to wait for a job to","finish. Bash commands have a ~5-minute cap, the sandbox is reclaimed on","inactivity, and the proxy token TTL tracks the command budget — any wait","loop will be killed before the callback fires. End the turn instead; the","vendor result arrives as a `[async-callback] job=<ref>` user message in a","later turn, re-spawning a fresh sandbox."].join("\n")).requiredOption("--job-ref <ref>","the job_ref returned by a previous async submit (e.g. dl generate-music)").action(async e=>{try{const t=String(e.jobRef).trim();Ac.test(t)||ys("E_SCHEMA","--job-ref must be the full UUID returned by the submit command","Do not use short prefixes like 2988ed2c; callback-server stores async job docs by the full job_ref.",{job_ref:t});const i=(process.env.CALLBACK_SERVER_URL??"").replace(/\/+$/,"")||ha(process.env),n=await fetch(`${i}/result/${encodeURIComponent(t)}`,{method:"GET",signal:AbortSignal.timeout(15e3)});n.ok||(404===n.status&&($c(),gs({ok:!0,job_ref:t,status:"pending"})),vs(`poll http ${n.status}`));const o=await n.json();"pending"===o.status&&$c(),gs({ok:!0,job_ref:t,...o})}catch(e){vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){e.command("search").description("External web search via Baidu / Serper / Tavily / Brave, plus Baidu similar-image search.").addHelpText("after",["","`--provider` is required; pick the adapter to use (no auto-fanout).","For Baidu image/video discovery, use `--provider=baidu --resource-type=image|video`.","For Baidu similar-image search, use `--provider=baidu-image --image-file=<jpg|png>`.","For URL fetch (not a query), use `dl fetch` instead.","","Example (stdin):",' cat <<EOF | dl search --query="cats" --provider=tavily --params-file=-',' {"safe":"strict"}'," EOF"].join("\n")).option("--query <q>","search query string").requiredOption("--provider <name>","search adapter: baidu|baidu-image|serper|tavily|brave").option("--k <n>","max hits (default 10, max 100)",e=>function(e,t,i=100){const n=Number(e);if(!Number.isFinite(n)||!Number.isInteger(n)||n<1||n>i)throw new Error(`${t} must be a positive integer ≤ ${i}, got ${e}`);return n}(e,"--k")).option("--resource-type <type>","baidu only: web|image|video (default web)").option("--image-file <path>","jpg/png file for provider=baidu-image").option("--country <cc>","ISO country hint (serper/brave only)").option("--freshness <win>","freshness window: pd (day) | pw (week) | pm (month) | py (year)").option("--params <inline-json>",'RECOMMENDED: adapter-specific extras inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --params "$(cat extras.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --params-file.').option("--params-file <path|->",'LEGACY: adapter-specific extras JSON object via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --params "$(cat file)". Use --params-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--print-schema","print scalar+file schema and exit").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{e.printSchema&&Js({command:"dl search",summary:"External web search via Baidu / Serper / Tavily / Brave, plus Baidu similar-image search.",scalars:[{name:"query",type:"string",required:!1,description:"search query (required except provider=baidu-image)"},{name:"provider",type:"string",required:!0,description:"baidu|baidu-image|serper|tavily|brave",enum:Ic},{name:"k",type:"integer",required:!1,description:"max hits (default 10, max 100)"},{name:"resource-type",type:"string",required:!1,description:"baidu only: web|image|video (default web)",enum:qc},{name:"image-file",type:"string",required:!1,description:"jpg/png path for provider=baidu-image"},{name:"country",type:"string",required:!1,description:"ISO country hint (serper/brave)"},{name:"freshness",type:"string",required:!1,description:"pd|pw|pm|py",enum:["pd","pw","pm","py"]},{name:"params",type:"string",required:!1,description:"RECOMMENDED inline JSON object of adapter-specific extras (sibling of --params-file)"}],files:[{name:"params-file",required:!1,kind:"object",description:"LEGACY: adapter-specific extras (prefer --params inline)",example:'{"safe":"strict"}'}]});const t=String(e.provider??"");let i;if(Ic.includes(t)||vs(`--provider must be one of ${Ic.join(", ")}; got ${t}`,"only baidu/baidu-image/serper/tavily/brave are wired; auto-fanout is not supported."),"baidu-image"===t||e.query||ys("E_SCHEMA","--query is required","pass --query for text search providers",{flag:"--query"}),e.resourceType){const t=String(e.resourceType);n=t,qc.includes(n)||ys("E_SCHEMA",`--resource-type must be web|image|video; got ${t}`,void 0,{flag:"--resource-type"}),i=t}var n;let o;i&&"baidu"!==t&&ys("E_SCHEMA","--resource-type is only supported with --provider=baidu",void 0,{flag:"--resource-type",provider:t}),e.freshness&&!Rc.has(String(e.freshness))&&vs(`--freshness must be pd|pw|pm|py; got ${e.freshness}`);try{const t=await ms(e.params?String(e.params):void 0,e.paramsFile?String(e.paramsFile):void 0,{inline:"--params",file:"--params-file"});t&&(o=t.data)}catch(e){throw e instanceof wa&&bs(e),e}const r=k(),a={source:"dl",event:"search",credits:10,command:(s={command:"search",action:"search"}).command,action:s.action??"search",details:{rule:"search.fixed",provider:{provider:t}.provider}};var s;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"search",totalCredits:a.credits,items:[a]});try{gs({ok:!0,job_ref:r,provider:t,hits:await Mc(t,e.query?String(e.query):"",{k:e.k,...i?{resourceType:i}:{},...e.imageFile?{imageFile:String(e.imageFile)}:{},...e.country?{country:String(e.country)}:{},...e.freshness?{freshness:e.freshness}:{},...o?{extra:o}:{},billing:{jobRef:r,quote:a}}),billing:a})}catch(e){e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:r}),e instanceof Jr&&vs(e.message,e.hint),vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){const t=e.command("stock").description("Search and download public stock media (Pexels / Pixabay / Openverse) for b-roll.");t.command("search").description("Sequential-fallback search across providers (Pexels → Pixabay → Openverse). Use --mode=fanout for parallel.").addHelpText("after",["","Modes:"," fallback (default) - calls Pexels -> Pixabay -> Openverse in order and stops once limit results are collected."," If one provider returns too few results, it falls through to the next; lowest API budget."," fanout - calls all enabled providers concurrently and merges for provider diversity."," Costs about 3x API budget; use only when cross-vendor diversity is required (rare queries).","","Provider selection:"," --providers defaults to all supports-current-type providers in default order."," Openverse is image-only; for --type=video it is auto-skipped."," Custom order: --providers=pixabay,pexels lets agent reorder fallback.","","Output: JSON { ok, job_ref, query, type, mode, results[], providers_queried, providers_failed[], billing }."," Fallback mode: providers_queried may be shorter than enabled when later providers are not needed."," Each result carries asset_id, download_url and full license metadata —"," pass them to `dl stock download` for the fetch.","","Examples:",' dl stock search --query="sunset beach" --type=image --limit=10',' dl stock search --query="city traffic" --type=video --duration-min=5 --duration-max=15',' dl stock search --query="rare landscape" --type=image --mode=fanout # needs diversity',' dl stock search --query="..." --providers=pixabay,pexels # custom order'].join("\n")).requiredOption("--query <q>","natural-language search query").requiredOption("--type <t>","image | video").option("--orientation <o>","landscape | portrait | square").option("--min-width <n>","minimum dimensions.width in px (filter post-normalize)",e=>md(e,"--min-width",1e5)).option("--duration-min <s>","minimum video duration in seconds (video only)",e=>hd(e,"--duration-min")).option("--duration-max <s>","maximum video duration in seconds (video only)",e=>hd(e,"--duration-max")).option("--limit <n>","max results to return (1..30, default 10)",e=>md(e,"--limit",30),10).option("--providers <list>",`csv of providers in custom order; default order: ${cd.join(", ")}`).option("--mode <m>",`search strategy: ${pd.join(" | ")} (default fallback saves API budget; use fanout only when diversity is required)`,"fallback").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{const t=String(e.type);ud.has(t)||vs(`--type must be image|video; got ${e.type}`),e.orientation&&!dd.has(String(e.orientation))&&vs(`--orientation must be landscape|portrait|square; got ${e.orientation}`);const i=String(e.mode);pd.includes(i)||vs(`--mode must be one of ${pd.join(", ")}; got ${e.mode}`);const n=e.limit??10,o=function(e,t){const i=e?e.split(",").map(e=>e.trim()).filter(Boolean):[...cd],n=[];for(const e of i){const i=ld[e];i||vs(`unknown stock provider: ${e}`,`supported providers: ${cd.join(", ")}`),("image"===t&&i.supports.image||"video"===t&&i.supports.video)&&n.push(e)}return 0===n.length&&vs(`no providers support type=${t}`,"try --providers=pexels,pixabay"),n}(e.providers?String(e.providers):void 0,t),r="fanout"===i?Math.max(1,Math.ceil(1.5*n/o.length)):n,a={query:String(e.query),type:t,orientation:e.orientation?String(e.orientation):void 0,minWidth:e.minWidth,durationMin:e.durationMin,durationMax:e.durationMax,perProviderLimit:r},s=k(),l={source:"dl",event:"stock_search",credits:5,command:(d={command:"stock search",action:"stock_search"}).command,action:d.action??"stock_search",details:{rule:"stock-search.fixed",type:(c={type:t,mode:i,limit:n,providers:o}).type,mode:c.mode,limit:c.limit,providers:c.providers}};var c,d;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"stock_search",totalCredits:l.credits,items:[l]});let u=null;try{u=await Ma({jobRef:s,quote:l});const{results:r,queried:c,failed:d}="fanout"===i?await async function(e,t,i,n=vd){const o=await Promise.allSettled(e.map(e=>n(e,t))),r=[],a=[];for(let t=0;t<e.length;t++){const i=o[t];"fulfilled"===i.status?r.push(i.value):(r.push([]),a.push(fd(e[t],i.reason)))}return{results:gd(r,i),queried:[...e],failed:a}}(o,a,n):await async function(e,t,i,n=vd){const o=[],r=new Set,a=[],s=[];for(const l of e){a.push(l);try{const e=await n(l,t);for(const t of e)if(!r.has(t.asset_id)&&(r.add(t.asset_id),o.push(t),o.length>=i))break}catch(e){s.push(fd(l,e))}if(o.length>=i)break}return{results:o.slice(0,i),queried:a,failed:s}}(o,a,n);0===r.length&&d.length>0&&d.length===c.length&&(await yd({jobRef:s,quote:l,receipt:u,reason:"stock_search_failed"}),vs(`all stock-media providers failed for "${e.query}"`,"check API keys / quota; see providers_failed for per-provider reason.",{job_ref:s,mode:i,providers_queried:c,providers_failed:d})),gs({ok:!0,job_ref:s,query:a.query,type:t,mode:i,results:r,providers_queried:c,providers_failed:d,billing:l})}catch(e){u&&await yd({jobRef:s,quote:l,receipt:u,reason:"stock_search_failed"}),e instanceof Jr&&vs(e.message,e.hint,{job_ref:s}),e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:s}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:s})}}),function(e){e.command("download").description("Fetch a stock-media asset (CDN URL from search result) into /workspace and echo full metadata.").addHelpText("after",["","Flow: callback-server handles billing-only charge/refund; dl directly fetches the public CDN URL."," The --metadata-json from your search result is passed through verbatim,"," so agents have everything to write credits / track usage later.","","Example:"," RESULT=$(dl stock search --query=cats --type=image --limit=1 | jq '.results[0]')"," dl stock download \\",' --asset-id="$(jq -r .asset_id <<<"$RESULT")" \\',' --url="$(jq -r .download_url <<<\\"$RESULT\\")" \\',' --metadata-json="$RESULT"'].join("\n")).requiredOption("--asset-id <id>","<provider>:<native_id> from a search result").requiredOption("--url <url>","direct CDN URL from search result's download_url").option("--to <path>",`absolute path under /workspace (default: ${Gc}/<provider>-<id>.<ext>)`).option("--metadata-json <json>","JSON-encoded metadata object from search result; echoed back in output for downstream credit-tracking").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{const{provider:t,nativeId:i}=function(e){const t=Wc.exec(e);return t||vs(`invalid --asset-id "${e}"`,"expected `<provider>:<native_id>`, e.g. pexels:12345 (from search results)."),{provider:t[1],nativeId:t[2]}}(String(e.assetId)),n=String(e.url);try{const e=new URL(n);"https:"!==e.protocol&&"http:"!==e.protocol&&vs(`--url must be http(s); got protocol ${e.protocol}`)}catch(e){throw"TypeError"===e.name&&vs(`--url is not a valid URL: ${n}`),e}const o=function(e){if(!e)return null;try{const t=JSON.parse(e);return("object"!=typeof t||null===t||Array.isArray(t))&&vs("--metadata-json must be a JSON object; got "+("object"==typeof t?"array/null":typeof t)),t}catch(e){vs(`--metadata-json failed to parse: ${e.message}`)}}(e.metadataJson),r=e.to?Qc(String(e.to),String(e.to)):void 0,a=k(),s={source:"dl",event:"stock_download",credits:5,command:(c={command:"stock download",action:"stock_download"}).command,action:c.action??"stock_download",details:{rule:"stock-download.fixed",provider:(l={provider:t,native_id:i}).provider,native_id:l.native_id}};var l,c;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"stock_download",totalCredits:s.credits,items:[s]});let d=null;try{d=await Ma({jobRef:a,quote:s});const{buf:e,contentType:l}=await async function(e){const t=new AbortController,i=setTimeout(()=>t.abort(),6e4);try{const i=await fetch(e,{signal:t.signal});if(!i.ok)throw new Xc(`download failed: HTTP ${i.status} from ${e}`);const n=i.headers.get("content-length");if(n&&Number(n)>Yc)throw new Xc(`download too large: ${n} bytes exceeds 209715200 cap`,"this looks like an unusually large asset; double-check the URL.");const o=await i.arrayBuffer();if(o.byteLength>Yc)throw new Xc(`download too large: ${o.byteLength} bytes exceeds 209715200 cap`,"this looks like an unusually large asset; double-check the URL.");return{buf:Buffer.from(o),contentType:i.headers.get("content-type")}}catch(t){if(t instanceof Xc)throw t;if("AbortError"===t.name)throw new Xc("download timed out after 60000ms",`url: ${e}`);throw new Xc(`download fetch error: ${t.message}`,`url: ${e}`)}finally{clearTimeout(i)}}(n),c=function(e,t){if(t){const e=t.split(";")[0]?.trim().toLowerCase();if(e&&Zc.has(e))return Zc.get(e)}try{const t=new URL(e),i=p(t.pathname).replace(/^\./,"").toLowerCase();if(i&&/^[a-z0-9]{2,5}$/.test(i))return i}catch{}return"bin"}(n,l),m=r??Qc(void 0,`${Gc}/${t}-${i}.${c}`);await T(u(m),{recursive:!0}),await A(m,e),gs({ok:!0,job_ref:a,asset_id:`${t}:${i}`,local_path:m,size_bytes:e.length,mime_type:l?.split(";")[0]?.trim()??null,metadata:o,billing:s})}catch(e){d&&await async function(e){try{await Ua({jobRef:e.jobRef,quote:e.quote,reason:e.reason,chargeId:e.receipt.charge_id})}catch(t){process.stderr.write(`${JSON.stringify({level:"warn",event:"dl_billing_refund_failed",job_ref:e.jobRef,reason:e.reason,error:t instanceof Error?t.message:String(t)})}\n`)}}({jobRef:a,quote:s,receipt:d,reason:"stock_download_failed"}),e instanceof Xc&&vs(e.message,e.hint,{job_ref:a}),e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:a}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:a})}})}(t)}(_d),function(e){e.command("fetch").description("Fetch a URL and emit extracted text / markdown / raw body (--mode). Non-2xx → error.").addHelpText("after",["","For a search query (not a URL), use `dl search`.","For social-media downloads (TikTok / IG / etc.), use `dl download-media`.","","Example:"," dl fetch --url=https://example.com --mode=markdown --max-bytes=1000000"].join("\n")).requiredOption("--url <url>").option("--mode <mode>","text|markdown|raw","text").option("--max-bytes <n>","max bytes to read (default 2000000, max 50000000)",e=>function(e,t,i){const n=Number(e);if(!Number.isFinite(n)||!Number.isInteger(n)||n<1||n>i)throw new Error(`--max-bytes must be a positive integer ≤ ${i}, got ${e}`);return n}(e,0,5e7)).option("--timeout-ms <n>","end-to-end timeout in ms (default 30000, min 7000, max 120000)",Xl).option("--user-agent <ua>","override UA header").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{const t=String(e.mode??"text");var i;i=t,Zl.includes(i)||vs(`--mode must be text|markdown|raw, got ${t}`);const n=k(),o=e.timeoutMs??3e4,r={source:"dl",event:"fetch",credits:5,command:(a={command:"fetch",action:"fetch"}).command,action:a.action??"fetch",details:{rule:"fetch.fixed",mode:{mode:t}.mode}};var a;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"fetch",totalCredits:r.credits,items:[r]});try{gs({ok:!0,job_ref:n,...await Da("web-fetch","",{url:String(e.url),mode:t,max_bytes:e.maxBytes??2e6,timeout_ms:o,...e.userAgent?{user_agent:String(e.userAgent)}:{}},{timeoutMs:o,retries:0,billing:{jobRef:n,quote:r}}),billing:r})}catch(e){if(e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:n}),e instanceof Sa){const t=function(e){const t=function(e){let t;try{t=JSON.parse(e)}catch{return null}if("object"!=typeof(i=t)||null===i||Array.isArray(i))return null;var i;const n=Ql(t,"error")??Ql(t,"message");return n?{message:n,errorCode:Ql(t,"error_code"),provider:Ql(t,"provider"),..."boolean"==typeof t.retryable?{retryable:t.retryable}:{}}:null}(e.bodyText),i=t?.errorCode,n="FIRECRAWL_RATE_LIMITED"===i?"Firecrawl 正在限流,请按 Retry-After 稍后重试。":"FIRECRAWL_QUOTA_EXHAUSTED"===i?"Firecrawl Cloud quota 已耗尽,请补充 quota 后重试。":!0===t?.retryable?"这是可重试的上游失败,请稍后重试。":void 0;return{message:t?.message??`fetch gateway returned HTTP ${e.status}`,...n?{hint:n}:{},extra:{http_status:e.status,...i?{error_code:i}:{},...t?.provider?{provider:t.provider}:{},...void 0!==t?.retryable?{retryable:t.retryable}:{}}}}(e);ys("E_BACKEND",t.message,t.hint,{...t.extra,job_ref:n})}e instanceof Jr&&vs(e.message,e.hint,{job_ref:n}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:n})}})}(_d),_d.configureHelp({subcommandTerm(e){const t=e.name(),i=e.commands.length>0,n=(e.registeredArguments??[]).length>0;return i?`${t} <command>`:n?`${t} ${e.usage()}`:`${t} [options]`}}),function(e){const t=e=>{e.exitOverride(),e.configureOutput({writeErr:()=>{},outputError:()=>{}}),e.commands.forEach(t)};t(e);const i=e.parseAsync.bind(e);e.parseAsync=async n=>{t(e);try{return await i(n)}catch(t){!function(e,t){const i=t,n=i?.code??"",o=i?.message??String(t??"");if("commander.unknownOption"===n){const t=function(e){const t=/unknown option ['`"]?([-a-zA-Z0-9_]+)['`"]?/.exec(e);return t?.[1]}(o)??"",i=function(e){const t=new Set,i=e=>{for(const i of e.options)i.long&&t.add(i.long),i.short&&t.add(i.short);for(const t of e.commands)i(t)};return i(e),[...t]}(e),n=t?xa(t,i):void 0,r=n&&n!==t?n:void 0;ys("E_UNKNOWN_OPTION",r?`unknown option \`${t}\` (did you mean \`${r}\`?)`:`unknown option \`${t||"<unknown>"}\``,"run the command with --help for the full flag list",{flag:t,...r?{suggestion:r}:{}})}"commander.unknownCommand"===n&&ys("E_UNKNOWN_OPTION",`unknown command: ${o}`,"run --help for the list of subcommands",{commander_code:n}),"commander.help"!==n&&"commander.helpDisplayed"!==n&&"commander.version"!==n||process.exit(0),"commander.missingMandatoryOptionValue"!==n&&"commander.missingArgument"!==n||ys("E_SCHEMA",o,"see --help; required scalar / argument is missing",{commander_code:n}),"commander.invalidOptionArgumentValue"!==n&&"commander.invalidArgument"!==n||ys("E_SCHEMA",o,"see --help for accepted values",{commander_code:n}),process.stderr.write(`${JSON.stringify({ok:!1,code:"E_BACKEND",error:o})}\n`),process.exit("number"==typeof i?.exitCode?i.exitCode:1)}(e,t)}}}(_d),_d.parseAsync(process.argv).catch(e=>{e instanceof wa&&(process.stderr.write(`${JSON.stringify({ok:!1,code:e.code,error:e.message,message:e.message,...e.hint?{hint:e.hint}:{},...e.extra??{}})}\n`),process.exit(_a(e.code)));const t=e instanceof Error?e.message:String(e),i=e instanceof Error&&"hint"in e&&"string"==typeof e.hint?e.hint:void 0;process.stderr.write(`${JSON.stringify({ok:!1,code:"E_BACKEND",error:t,...i?{hint:i}:{}})}\n`),process.exit(1)});
|
|
2
|
+
import e,{mkdirSync as t,writeFileSync as i,chmodSync as n,existsSync as o,readFileSync as r,rmSync as a}from"node:fs";import s,{join as l,resolve as c,isAbsolute as d,dirname as u,extname as p}from"node:path";import{fileURLToPath as m}from"node:url";import h from"node:events";import f,{spawn as g,execFileSync as v,spawnSync as y}from"node:child_process";import b from"node:process";import{randomBytes as _,createHash as w,randomUUID as k}from"node:crypto";import{createServer as x}from"node:http";import*as S from"node:os";import{homedir as E}from"node:os";import{readFile as O,mkdir as T,writeFile as A}from"node:fs/promises";function $(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var N,j,C={},I={},R={};function q(){if(N)return R;N=1;class e extends Error{constructor(e,t,i){super(i),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=t,this.exitCode=e,this.nestedError=void 0}}return R.CommanderError=e,R.InvalidArgumentError=class extends e{constructor(e){super(1,"commander.invalidArgument",e),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}},R}function P(){if(j)return I;j=1;const{InvalidArgumentError:e}=q();return I.Argument=class{constructor(e,t){switch(this.description=t||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,e[0]){case"<":this.required=!0,this._name=e.slice(1,-1);break;case"[":this.required=!1,this._name=e.slice(1,-1);break;default:this.required=!0,this._name=e}this._name.length>3&&"..."===this._name.slice(-3)&&(this.variadic=!0,this._name=this._name.slice(0,-3))}name(){return this._name}_concatValue(e,t){return t!==this.defaultValue&&Array.isArray(t)?t.concat(e):[e]}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}argParser(e){return this.parseArg=e,this}choices(t){return this.argChoices=t.slice(),this.parseArg=(t,i)=>{if(!this.argChoices.includes(t))throw new e(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._concatValue(t,i):t},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}},I.humanReadableArgName=function(e){const t=e.name()+(!0===e.variadic?"...":"");return e.required?"<"+t+">":"["+t+"]"},I}var L,z={},M={};function U(){if(L)return M;L=1;const{humanReadableArgName:e}=P();return M.Help=class{constructor(){this.helpWidth=void 0,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}visibleCommands(e){const t=e.commands.filter(e=>!e._hidden),i=e._getHelpCommand();return i&&!i._hidden&&t.push(i),this.sortSubcommands&&t.sort((e,t)=>e.name().localeCompare(t.name())),t}compareOptions(e,t){const i=e=>e.short?e.short.replace(/^-/,""):e.long.replace(/^--/,"");return i(e).localeCompare(i(t))}visibleOptions(e){const t=e.options.filter(e=>!e.hidden),i=e._getHelpOption();if(i&&!i.hidden){const n=i.short&&e._findOption(i.short),o=i.long&&e._findOption(i.long);n||o?i.long&&!o?t.push(e.createOption(i.long,i.description)):i.short&&!n&&t.push(e.createOption(i.short,i.description)):t.push(i)}return this.sortOptions&&t.sort(this.compareOptions),t}visibleGlobalOptions(e){if(!this.showGlobalOptions)return[];const t=[];for(let i=e.parent;i;i=i.parent){const e=i.options.filter(e=>!e.hidden);t.push(...e)}return this.sortOptions&&t.sort(this.compareOptions),t}visibleArguments(e){return e._argsDescription&&e.registeredArguments.forEach(t=>{t.description=t.description||e._argsDescription[t.name()]||""}),e.registeredArguments.find(e=>e.description)?e.registeredArguments:[]}subcommandTerm(t){const i=t.registeredArguments.map(t=>e(t)).join(" ");return t._name+(t._aliases[0]?"|"+t._aliases[0]:"")+(t.options.length?" [options]":"")+(i?" "+i:"")}optionTerm(e){return e.flags}argumentTerm(e){return e.name()}longestSubcommandTermLength(e,t){return t.visibleCommands(e).reduce((e,i)=>Math.max(e,t.subcommandTerm(i).length),0)}longestOptionTermLength(e,t){return t.visibleOptions(e).reduce((e,i)=>Math.max(e,t.optionTerm(i).length),0)}longestGlobalOptionTermLength(e,t){return t.visibleGlobalOptions(e).reduce((e,i)=>Math.max(e,t.optionTerm(i).length),0)}longestArgumentTermLength(e,t){return t.visibleArguments(e).reduce((e,i)=>Math.max(e,t.argumentTerm(i).length),0)}commandUsage(e){let t=e._name;e._aliases[0]&&(t=t+"|"+e._aliases[0]);let i="";for(let t=e.parent;t;t=t.parent)i=t.name()+" "+i;return i+t+" "+e.usage()}commandDescription(e){return e.description()}subcommandDescription(e){return e.summary()||e.description()}optionDescription(e){const t=[];return e.argChoices&&t.push(`choices: ${e.argChoices.map(e=>JSON.stringify(e)).join(", ")}`),void 0!==e.defaultValue&&(e.required||e.optional||e.isBoolean()&&"boolean"==typeof e.defaultValue)&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),void 0!==e.presetArg&&e.optional&&t.push(`preset: ${JSON.stringify(e.presetArg)}`),void 0!==e.envVar&&t.push(`env: ${e.envVar}`),t.length>0?`${e.description} (${t.join(", ")})`:e.description}argumentDescription(e){const t=[];if(e.argChoices&&t.push(`choices: ${e.argChoices.map(e=>JSON.stringify(e)).join(", ")}`),void 0!==e.defaultValue&&t.push(`default: ${e.defaultValueDescription||JSON.stringify(e.defaultValue)}`),t.length>0){const i=`(${t.join(", ")})`;return e.description?`${e.description} ${i}`:i}return e.description}formatHelp(e,t){const i=t.padWidth(e,t),n=t.helpWidth||80;function o(e,o){if(o){const r=`${e.padEnd(i+2)}${o}`;return t.wrap(r,n-2,i+2)}return e}function r(e){return e.join("\n").replace(/^/gm," ".repeat(2))}let a=[`Usage: ${t.commandUsage(e)}`,""];const s=t.commandDescription(e);s.length>0&&(a=a.concat([t.wrap(s,n,0),""]));const l=t.visibleArguments(e).map(e=>o(t.argumentTerm(e),t.argumentDescription(e)));l.length>0&&(a=a.concat(["Arguments:",r(l),""]));const c=t.visibleOptions(e).map(e=>o(t.optionTerm(e),t.optionDescription(e)));if(c.length>0&&(a=a.concat(["Options:",r(c),""])),this.showGlobalOptions){const i=t.visibleGlobalOptions(e).map(e=>o(t.optionTerm(e),t.optionDescription(e)));i.length>0&&(a=a.concat(["Global Options:",r(i),""]))}const d=t.visibleCommands(e).map(e=>o(t.subcommandTerm(e),t.subcommandDescription(e)));return d.length>0&&(a=a.concat(["Commands:",r(d),""])),a.join("\n")}padWidth(e,t){return Math.max(t.longestOptionTermLength(e,t),t.longestGlobalOptionTermLength(e,t),t.longestSubcommandTermLength(e,t),t.longestArgumentTermLength(e,t))}wrap(e,t,i,n=40){const o=new RegExp("[\\n][ \\f\\t\\v - \ufeff]+");if(e.match(o))return e;const r=t-i;if(r<n)return e;const a=e.slice(0,i),s=e.slice(i).replace("\r\n","\n"),l=" ".repeat(i),c="\\s",d=new RegExp(`\n|.{1,${r-1}}([${c}]|$)|[^${c}]+?([${c}]|$)`,"g");return a+(s.match(d)||[]).map((e,t)=>"\n"===e?"":(t>0?l:"")+e.trimEnd()).join("\n")}},M}var F,D={};function H(){if(F)return D;F=1;const{InvalidArgumentError:e}=q();return D.Option=class{constructor(e,t){this.flags=e,this.description=t||"",this.required=e.includes("<"),this.optional=e.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test(e),this.mandatory=!1;const i=function(e){let t,i;const n=e.split(/[ |,]+/);return n.length>1&&!/^[[<]/.test(n[1])&&(t=n.shift()),i=n.shift(),!t&&/^-[^-]$/.test(i)&&(t=i,i=void 0),{shortFlag:t,longFlag:i}}(e);this.short=i.shortFlag,this.long=i.longFlag,this.negate=!1,this.long&&(this.negate=this.long.startsWith("--no-")),this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0}default(e,t){return this.defaultValue=e,this.defaultValueDescription=t,this}preset(e){return this.presetArg=e,this}conflicts(e){return this.conflictsWith=this.conflictsWith.concat(e),this}implies(e){let t=e;return"string"==typeof e&&(t={[e]:!0}),this.implied=Object.assign(this.implied||{},t),this}env(e){return this.envVar=e,this}argParser(e){return this.parseArg=e,this}makeOptionMandatory(e=!0){return this.mandatory=!!e,this}hideHelp(e=!0){return this.hidden=!!e,this}_concatValue(e,t){return t!==this.defaultValue&&Array.isArray(t)?t.concat(e):[e]}choices(t){return this.argChoices=t.slice(),this.parseArg=(t,i)=>{if(!this.argChoices.includes(t))throw new e(`Allowed choices are ${this.argChoices.join(", ")}.`);return this.variadic?this._concatValue(t,i):t},this}name(){return this.long?this.long.replace(/^--/,""):this.short.replace(/^-/,"")}attributeName(){return this.name().replace(/^no-/,"").split("-").reduce((e,t)=>e+t[0].toUpperCase()+t.slice(1))}is(e){return this.short===e||this.long===e}isBoolean(){return!this.required&&!this.optional&&!this.negate}},D.DualOptions=class{constructor(e){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,e.forEach(e=>{e.negate?this.negativeOptions.set(e.attributeName(),e):this.positiveOptions.set(e.attributeName(),e)}),this.negativeOptions.forEach((e,t)=>{this.positiveOptions.has(t)&&this.dualOptions.add(t)})}valueFromOption(e,t){const i=t.attributeName();if(!this.dualOptions.has(i))return!0;const n=this.negativeOptions.get(i).presetArg,o=void 0!==n&&n;return t.negate===(o===e)}},D}var B,V,J,K={};function G(){return B||(B=1,K.suggestSimilar=function(e,t){if(!t||0===t.length)return"";t=Array.from(new Set(t));const i=e.startsWith("--");i&&(e=e.slice(2),t=t.map(e=>e.slice(2)));let n=[],o=3;return t.forEach(t=>{if(t.length<=1)return;const i=function(e,t){if(Math.abs(e.length-t.length)>3)return Math.max(e.length,t.length);const i=[];for(let t=0;t<=e.length;t++)i[t]=[t];for(let e=0;e<=t.length;e++)i[0][e]=e;for(let n=1;n<=t.length;n++)for(let o=1;o<=e.length;o++){let r=1;r=e[o-1]===t[n-1]?0:1,i[o][n]=Math.min(i[o-1][n]+1,i[o][n-1]+1,i[o-1][n-1]+r),o>1&&n>1&&e[o-1]===t[n-2]&&e[o-2]===t[n-1]&&(i[o][n]=Math.min(i[o][n],i[o-2][n-2]+1))}return i[e.length][t.length]}(e,t),r=Math.max(e.length,t.length);(r-i)/r>.4&&(i<o?(o=i,n=[t]):i===o&&n.push(t))}),n.sort((e,t)=>e.localeCompare(t)),i&&(n=n.map(e=>`--${e}`)),n.length>1?`\n(Did you mean one of ${n.join(", ")}?)`:1===n.length?`\n(Did you mean ${n[0]}?)`:""}),K}var Y=function(){if(J)return C;J=1;const{Argument:t}=P(),{Command:i}=function(){if(V)return z;V=1;const t=h.EventEmitter,i=f,n=s,o=e,r=b,{Argument:a,humanReadableArgName:l}=P(),{CommanderError:c}=q(),{Help:d}=U(),{Option:u,DualOptions:p}=H(),{suggestSimilar:m}=G();class g extends t{constructor(e){super(),this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!0,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=e||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._outputConfiguration={writeOut:e=>r.stdout.write(e),writeErr:e=>r.stderr.write(e),getOutHelpWidth:()=>r.stdout.isTTY?r.stdout.columns:void 0,getErrHelpWidth:()=>r.stderr.isTTY?r.stderr.columns:void 0,outputError:(e,t)=>t(e)},this._hidden=!1,this._helpOption=void 0,this._addImplicitHelpCommand=void 0,this._helpCommand=void 0,this._helpConfiguration={}}copyInheritedSettings(e){return this._outputConfiguration=e._outputConfiguration,this._helpOption=e._helpOption,this._helpCommand=e._helpCommand,this._helpConfiguration=e._helpConfiguration,this._exitCallback=e._exitCallback,this._storeOptionsAsProperties=e._storeOptionsAsProperties,this._combineFlagAndOptionalValue=e._combineFlagAndOptionalValue,this._allowExcessArguments=e._allowExcessArguments,this._enablePositionalOptions=e._enablePositionalOptions,this._showHelpAfterError=e._showHelpAfterError,this._showSuggestionAfterError=e._showSuggestionAfterError,this}_getCommandAndAncestors(){const e=[];for(let t=this;t;t=t.parent)e.push(t);return e}command(e,t,i){let n=t,o=i;"object"==typeof n&&null!==n&&(o=n,n=null),o=o||{};const[,r,a]=e.match(/([^ ]+) *(.*)/),s=this.createCommand(r);return n&&(s.description(n),s._executableHandler=!0),o.isDefault&&(this._defaultCommandName=s._name),s._hidden=!(!o.noHelp&&!o.hidden),s._executableFile=o.executableFile||null,a&&s.arguments(a),this._registerCommand(s),s.parent=this,s.copyInheritedSettings(this),n?this:s}createCommand(e){return new g(e)}createHelp(){return Object.assign(new d,this.configureHelp())}configureHelp(e){return void 0===e?this._helpConfiguration:(this._helpConfiguration=e,this)}configureOutput(e){return void 0===e?this._outputConfiguration:(Object.assign(this._outputConfiguration,e),this)}showHelpAfterError(e=!0){return"string"!=typeof e&&(e=!!e),this._showHelpAfterError=e,this}showSuggestionAfterError(e=!0){return this._showSuggestionAfterError=!!e,this}addCommand(e,t){if(!e._name)throw new Error("Command passed to .addCommand() must have a name\n- specify the name in Command constructor or using .name()");return(t=t||{}).isDefault&&(this._defaultCommandName=e._name),(t.noHelp||t.hidden)&&(e._hidden=!0),this._registerCommand(e),e.parent=this,e._checkForBrokenPassThrough(),this}createArgument(e,t){return new a(e,t)}argument(e,t,i,n){const o=this.createArgument(e,t);return"function"==typeof i?o.default(n).argParser(i):o.default(i),this.addArgument(o),this}arguments(e){return e.trim().split(/ +/).forEach(e=>{this.argument(e)}),this}addArgument(e){const t=this.registeredArguments.slice(-1)[0];if(t&&t.variadic)throw new Error(`only the last argument can be variadic '${t.name()}'`);if(e.required&&void 0!==e.defaultValue&&void 0===e.parseArg)throw new Error(`a default value for a required argument is never used: '${e.name()}'`);return this.registeredArguments.push(e),this}helpCommand(e,t){if("boolean"==typeof e)return this._addImplicitHelpCommand=e,this;e=e??"help [command]";const[,i,n]=e.match(/([^ ]+) *(.*)/),o=t??"display help for command",r=this.createCommand(i);return r.helpOption(!1),n&&r.arguments(n),o&&r.description(o),this._addImplicitHelpCommand=!0,this._helpCommand=r,this}addHelpCommand(e,t){return"object"!=typeof e?(this.helpCommand(e,t),this):(this._addImplicitHelpCommand=!0,this._helpCommand=e,this)}_getHelpCommand(){return this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"))?(void 0===this._helpCommand&&this.helpCommand(void 0,void 0),this._helpCommand):null}hook(e,t){const i=["preSubcommand","preAction","postAction"];if(!i.includes(e))throw new Error(`Unexpected value for event passed to hook : '${e}'.\nExpecting one of '${i.join("', '")}'`);return this._lifeCycleHooks[e]?this._lifeCycleHooks[e].push(t):this._lifeCycleHooks[e]=[t],this}exitOverride(e){return this._exitCallback=e||(e=>{if("commander.executeSubCommandAsync"!==e.code)throw e}),this}_exit(e,t,i){this._exitCallback&&this._exitCallback(new c(e,t,i)),r.exit(e)}action(e){return this._actionHandler=t=>{const i=this.registeredArguments.length,n=t.slice(0,i);return this._storeOptionsAsProperties?n[i]=this:n[i]=this.opts(),n.push(this),e.apply(this,n)},this}createOption(e,t){return new u(e,t)}_callParseArg(e,t,i,n){try{return e.parseArg(t,i)}catch(e){if("commander.invalidArgument"===e.code){const t=`${n} ${e.message}`;this.error(t,{exitCode:e.exitCode,code:e.code})}throw e}}_registerOption(e){const t=e.short&&this._findOption(e.short)||e.long&&this._findOption(e.long);if(t){const i=e.long&&this._findOption(e.long)?e.long:e.short;throw new Error(`Cannot add option '${e.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${i}'\n- already used by option '${t.flags}'`)}this.options.push(e)}_registerCommand(e){const t=e=>[e.name()].concat(e.aliases()),i=t(e).find(e=>this._findCommand(e));if(i){const n=t(this._findCommand(i)).join("|"),o=t(e).join("|");throw new Error(`cannot add command '${o}' as already have command '${n}'`)}this.commands.push(e)}addOption(e){this._registerOption(e);const t=e.name(),i=e.attributeName();if(e.negate){const t=e.long.replace(/^--no-/,"--");this._findOption(t)||this.setOptionValueWithSource(i,void 0===e.defaultValue||e.defaultValue,"default")}else void 0!==e.defaultValue&&this.setOptionValueWithSource(i,e.defaultValue,"default");const n=(t,n,o)=>{null==t&&void 0!==e.presetArg&&(t=e.presetArg);const r=this.getOptionValue(i);null!==t&&e.parseArg?t=this._callParseArg(e,t,r,n):null!==t&&e.variadic&&(t=e._concatValue(t,r)),null==t&&(t=!e.negate&&(!(!e.isBoolean()&&!e.optional)||"")),this.setOptionValueWithSource(i,t,o)};return this.on("option:"+t,t=>{const i=`error: option '${e.flags}' argument '${t}' is invalid.`;n(t,i,"cli")}),e.envVar&&this.on("optionEnv:"+t,t=>{const i=`error: option '${e.flags}' value '${t}' from env '${e.envVar}' is invalid.`;n(t,i,"env")}),this}_optionEx(e,t,i,n,o){if("object"==typeof t&&t instanceof u)throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");const r=this.createOption(t,i);if(r.makeOptionMandatory(!!e.mandatory),"function"==typeof n)r.default(o).argParser(n);else if(n instanceof RegExp){const e=n;n=(t,i)=>{const n=e.exec(t);return n?n[0]:i},r.default(o).argParser(n)}else r.default(n);return this.addOption(r)}option(e,t,i,n){return this._optionEx({},e,t,i,n)}requiredOption(e,t,i,n){return this._optionEx({mandatory:!0},e,t,i,n)}combineFlagAndOptionalValue(e=!0){return this._combineFlagAndOptionalValue=!!e,this}allowUnknownOption(e=!0){return this._allowUnknownOption=!!e,this}allowExcessArguments(e=!0){return this._allowExcessArguments=!!e,this}enablePositionalOptions(e=!0){return this._enablePositionalOptions=!!e,this}passThroughOptions(e=!0){return this._passThroughOptions=!!e,this._checkForBrokenPassThrough(),this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions)throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}storeOptionsAsProperties(e=!0){if(this.options.length)throw new Error("call .storeOptionsAsProperties() before adding options");if(Object.keys(this._optionValues).length)throw new Error("call .storeOptionsAsProperties() before setting option values");return this._storeOptionsAsProperties=!!e,this}getOptionValue(e){return this._storeOptionsAsProperties?this[e]:this._optionValues[e]}setOptionValue(e,t){return this.setOptionValueWithSource(e,t,void 0)}setOptionValueWithSource(e,t,i){return this._storeOptionsAsProperties?this[e]=t:this._optionValues[e]=t,this._optionValueSources[e]=i,this}getOptionValueSource(e){return this._optionValueSources[e]}getOptionValueSourceWithGlobals(e){let t;return this._getCommandAndAncestors().forEach(i=>{void 0!==i.getOptionValueSource(e)&&(t=i.getOptionValueSource(e))}),t}_prepareUserArgs(e,t){if(void 0!==e&&!Array.isArray(e))throw new Error("first parameter to parse must be array or undefined");if(t=t||{},void 0===e&&void 0===t.from){r.versions?.electron&&(t.from="electron");const e=r.execArgv??[];(e.includes("-e")||e.includes("--eval")||e.includes("-p")||e.includes("--print"))&&(t.from="eval")}let i;switch(void 0===e&&(e=r.argv),this.rawArgs=e.slice(),t.from){case void 0:case"node":this._scriptPath=e[1],i=e.slice(2);break;case"electron":r.defaultApp?(this._scriptPath=e[1],i=e.slice(2)):i=e.slice(1);break;case"user":i=e.slice(0);break;case"eval":i=e.slice(1);break;default:throw new Error(`unexpected parse option { from: '${t.from}' }`)}return!this._name&&this._scriptPath&&this.nameFromFilename(this._scriptPath),this._name=this._name||"program",i}parse(e,t){const i=this._prepareUserArgs(e,t);return this._parseCommand([],i),this}async parseAsync(e,t){const i=this._prepareUserArgs(e,t);return await this._parseCommand([],i),this}_executeSubCommand(e,t){t=t.slice();let a=!1;const s=[".js",".ts",".tsx",".mjs",".cjs"];function l(e,t){const i=n.resolve(e,t);if(o.existsSync(i))return i;if(s.includes(n.extname(t)))return;const r=s.find(e=>o.existsSync(`${i}${e}`));return r?`${i}${r}`:void 0}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let d,u=e._executableFile||`${this._name}-${e._name}`,p=this._executableDir||"";if(this._scriptPath){let e;try{e=o.realpathSync(this._scriptPath)}catch(t){e=this._scriptPath}p=n.resolve(n.dirname(e),p)}if(p){let t=l(p,u);if(!t&&!e._executableFile&&this._scriptPath){const i=n.basename(this._scriptPath,n.extname(this._scriptPath));i!==this._name&&(t=l(p,`${i}-${e._name}`))}u=t||u}a=s.includes(n.extname(u)),"win32"!==r.platform?a?(t.unshift(u),t=v(r.execArgv).concat(t),d=i.spawn(r.argv[0],t,{stdio:"inherit"})):d=i.spawn(u,t,{stdio:"inherit"}):(t.unshift(u),t=v(r.execArgv).concat(t),d=i.spawn(r.execPath,t,{stdio:"inherit"})),d.killed||["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach(e=>{r.on(e,()=>{!1===d.killed&&null===d.exitCode&&d.kill(e)})});const m=this._exitCallback;d.on("close",e=>{e=e??1,m?m(new c(e,"commander.executeSubCommandAsync","(close)")):r.exit(e)}),d.on("error",t=>{if("ENOENT"===t.code){const t=p?`searched for local subcommand relative to directory '${p}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",i=`'${u}' does not exist\n - if '${e._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead\n - if the default executable name is not suitable, use the executableFile option to supply a custom name or path\n - ${t}`;throw new Error(i)}if("EACCES"===t.code)throw new Error(`'${u}' not executable`);if(m){const e=new c(1,"commander.executeSubCommandAsync","(error)");e.nestedError=t,m(e)}else r.exit(1)}),this.runningCommand=d}_dispatchSubcommand(e,t,i){const n=this._findCommand(e);let o;return n||this.help({error:!0}),o=this._chainOrCallSubCommandHook(o,n,"preSubcommand"),o=this._chainOrCall(o,()=>{if(!n._executableHandler)return n._parseCommand(t,i);this._executeSubCommand(n,t.concat(i))}),o}_dispatchHelpCommand(e){e||this.help();const t=this._findCommand(e);return t&&!t._executableHandler&&t.help(),this._dispatchSubcommand(e,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){this.registeredArguments.forEach((e,t)=>{e.required&&null==this.args[t]&&this.missingArgument(e.name())}),this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic||this.args.length>this.registeredArguments.length&&this._excessArguments(this.args)}_processArguments(){const e=(e,t,i)=>{let n=t;if(null!==t&&e.parseArg){const o=`error: command-argument value '${t}' is invalid for argument '${e.name()}'.`;n=this._callParseArg(e,t,i,o)}return n};this._checkNumberOfArguments();const t=[];this.registeredArguments.forEach((i,n)=>{let o=i.defaultValue;i.variadic?n<this.args.length?(o=this.args.slice(n),i.parseArg&&(o=o.reduce((t,n)=>e(i,n,t),i.defaultValue))):void 0===o&&(o=[]):n<this.args.length&&(o=this.args[n],i.parseArg&&(o=e(i,o,i.defaultValue))),t[n]=o}),this.processedArgs=t}_chainOrCall(e,t){return e&&e.then&&"function"==typeof e.then?e.then(()=>t()):t()}_chainOrCallHooks(e,t){let i=e;const n=[];return this._getCommandAndAncestors().reverse().filter(e=>void 0!==e._lifeCycleHooks[t]).forEach(e=>{e._lifeCycleHooks[t].forEach(t=>{n.push({hookedCommand:e,callback:t})})}),"postAction"===t&&n.reverse(),n.forEach(e=>{i=this._chainOrCall(i,()=>e.callback(e.hookedCommand,this))}),i}_chainOrCallSubCommandHook(e,t,i){let n=e;return void 0!==this._lifeCycleHooks[i]&&this._lifeCycleHooks[i].forEach(e=>{n=this._chainOrCall(n,()=>e(this,t))}),n}_parseCommand(e,t){const i=this.parseOptions(t);if(this._parseOptionsEnv(),this._parseOptionsImplied(),e=e.concat(i.operands),t=i.unknown,this.args=e.concat(t),e&&this._findCommand(e[0]))return this._dispatchSubcommand(e[0],e.slice(1),t);if(this._getHelpCommand()&&e[0]===this._getHelpCommand().name())return this._dispatchHelpCommand(e[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(t),this._dispatchSubcommand(this._defaultCommandName,e,t);!this.commands.length||0!==this.args.length||this._actionHandler||this._defaultCommandName||this.help({error:!0}),this._outputHelpIfRequested(i.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();const n=()=>{i.unknown.length>0&&this.unknownOption(i.unknown[0])},o=`command:${this.name()}`;if(this._actionHandler){let i;return n(),this._processArguments(),i=this._chainOrCallHooks(i,"preAction"),i=this._chainOrCall(i,()=>this._actionHandler(this.processedArgs)),this.parent&&(i=this._chainOrCall(i,()=>{this.parent.emit(o,e,t)})),i=this._chainOrCallHooks(i,"postAction"),i}if(this.parent&&this.parent.listenerCount(o))n(),this._processArguments(),this.parent.emit(o,e,t);else if(e.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",e,t);this.listenerCount("command:*")?this.emit("command:*",e,t):this.commands.length?this.unknownCommand():(n(),this._processArguments())}else this.commands.length?(n(),this.help({error:!0})):(n(),this._processArguments())}_findCommand(e){if(e)return this.commands.find(t=>t._name===e||t._aliases.includes(e))}_findOption(e){return this.options.find(t=>t.is(e))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach(e=>{e.options.forEach(t=>{t.mandatory&&void 0===e.getOptionValue(t.attributeName())&&e.missingMandatoryOptionValue(t)})})}_checkForConflictingLocalOptions(){const e=this.options.filter(e=>{const t=e.attributeName();return void 0!==this.getOptionValue(t)&&"default"!==this.getOptionValueSource(t)}),t=e.filter(e=>e.conflictsWith.length>0);t.forEach(t=>{const i=e.find(e=>t.conflictsWith.includes(e.attributeName()));i&&this._conflictingOption(t,i)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach(e=>{e._checkForConflictingLocalOptions()})}parseOptions(e){const t=[],i=[];let n=t;const o=e.slice();function r(e){return e.length>1&&"-"===e[0]}let a=null;for(;o.length;){const e=o.shift();if("--"===e){n===i&&n.push(e),n.push(...o);break}if(!a||r(e)){if(a=null,r(e)){const t=this._findOption(e);if(t){if(t.required){const e=o.shift();void 0===e&&this.optionMissingArgument(t),this.emit(`option:${t.name()}`,e)}else if(t.optional){let e=null;o.length>0&&!r(o[0])&&(e=o.shift()),this.emit(`option:${t.name()}`,e)}else this.emit(`option:${t.name()}`);a=t.variadic?t:null;continue}}if(e.length>2&&"-"===e[0]&&"-"!==e[1]){const t=this._findOption(`-${e[1]}`);if(t){t.required||t.optional&&this._combineFlagAndOptionalValue?this.emit(`option:${t.name()}`,e.slice(2)):(this.emit(`option:${t.name()}`),o.unshift(`-${e.slice(2)}`));continue}}if(/^--[^=]+=/.test(e)){const t=e.indexOf("="),i=this._findOption(e.slice(0,t));if(i&&(i.required||i.optional)){this.emit(`option:${i.name()}`,e.slice(t+1));continue}}if(r(e)&&(n=i),(this._enablePositionalOptions||this._passThroughOptions)&&0===t.length&&0===i.length){if(this._findCommand(e)){t.push(e),o.length>0&&i.push(...o);break}if(this._getHelpCommand()&&e===this._getHelpCommand().name()){t.push(e),o.length>0&&t.push(...o);break}if(this._defaultCommandName){i.push(e),o.length>0&&i.push(...o);break}}if(this._passThroughOptions){n.push(e),o.length>0&&n.push(...o);break}n.push(e)}else this.emit(`option:${a.name()}`,e)}return{operands:t,unknown:i}}opts(){if(this._storeOptionsAsProperties){const e={},t=this.options.length;for(let i=0;i<t;i++){const t=this.options[i].attributeName();e[t]=t===this._versionOptionName?this._version:this[t]}return e}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce((e,t)=>Object.assign(e,t.opts()),{})}error(e,t){this._outputConfiguration.outputError(`${e}\n`,this._outputConfiguration.writeErr),"string"==typeof this._showHelpAfterError?this._outputConfiguration.writeErr(`${this._showHelpAfterError}\n`):this._showHelpAfterError&&(this._outputConfiguration.writeErr("\n"),this.outputHelp({error:!0}));const i=t||{},n=i.exitCode||1,o=i.code||"commander.error";this._exit(n,o,e)}_parseOptionsEnv(){this.options.forEach(e=>{if(e.envVar&&e.envVar in r.env){const t=e.attributeName();(void 0===this.getOptionValue(t)||["default","config","env"].includes(this.getOptionValueSource(t)))&&(e.required||e.optional?this.emit(`optionEnv:${e.name()}`,r.env[e.envVar]):this.emit(`optionEnv:${e.name()}`))}})}_parseOptionsImplied(){const e=new p(this.options),t=e=>void 0!==this.getOptionValue(e)&&!["default","implied"].includes(this.getOptionValueSource(e));this.options.filter(i=>void 0!==i.implied&&t(i.attributeName())&&e.valueFromOption(this.getOptionValue(i.attributeName()),i)).forEach(e=>{Object.keys(e.implied).filter(e=>!t(e)).forEach(t=>{this.setOptionValueWithSource(t,e.implied[t],"implied")})})}missingArgument(e){const t=`error: missing required argument '${e}'`;this.error(t,{code:"commander.missingArgument"})}optionMissingArgument(e){const t=`error: option '${e.flags}' argument missing`;this.error(t,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(e){const t=`error: required option '${e.flags}' not specified`;this.error(t,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(e,t){const i=e=>{const t=e.attributeName(),i=this.getOptionValue(t),n=this.options.find(e=>e.negate&&t===e.attributeName()),o=this.options.find(e=>!e.negate&&t===e.attributeName());return n&&(void 0===n.presetArg&&!1===i||void 0!==n.presetArg&&i===n.presetArg)?n:o||e},n=e=>{const t=i(e),n=t.attributeName();return"env"===this.getOptionValueSource(n)?`environment variable '${t.envVar}'`:`option '${t.flags}'`},o=`error: ${n(e)} cannot be used with ${n(t)}`;this.error(o,{code:"commander.conflictingOption"})}unknownOption(e){if(this._allowUnknownOption)return;let t="";if(e.startsWith("--")&&this._showSuggestionAfterError){let i=[],n=this;do{const e=n.createHelp().visibleOptions(n).filter(e=>e.long).map(e=>e.long);i=i.concat(e),n=n.parent}while(n&&!n._enablePositionalOptions);t=m(e,i)}const i=`error: unknown option '${e}'${t}`;this.error(i,{code:"commander.unknownOption"})}_excessArguments(e){if(this._allowExcessArguments)return;const t=this.registeredArguments.length,i=1===t?"":"s",n=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${t} argument${i} but got ${e.length}.`;this.error(n,{code:"commander.excessArguments"})}unknownCommand(){const e=this.args[0];let t="";if(this._showSuggestionAfterError){const i=[];this.createHelp().visibleCommands(this).forEach(e=>{i.push(e.name()),e.alias()&&i.push(e.alias())}),t=m(e,i)}const i=`error: unknown command '${e}'${t}`;this.error(i,{code:"commander.unknownCommand"})}version(e,t,i){if(void 0===e)return this._version;this._version=e,t=t||"-V, --version",i=i||"output the version number";const n=this.createOption(t,i);return this._versionOptionName=n.attributeName(),this._registerOption(n),this.on("option:"+n.name(),()=>{this._outputConfiguration.writeOut(`${e}\n`),this._exit(0,"commander.version",e)}),this}description(e,t){return void 0===e&&void 0===t?this._description:(this._description=e,t&&(this._argsDescription=t),this)}summary(e){return void 0===e?this._summary:(this._summary=e,this)}alias(e){if(void 0===e)return this._aliases[0];let t=this;if(0!==this.commands.length&&this.commands[this.commands.length-1]._executableHandler&&(t=this.commands[this.commands.length-1]),e===t._name)throw new Error("Command alias can't be the same as its name");const i=this.parent?._findCommand(e);if(i){const t=[i.name()].concat(i.aliases()).join("|");throw new Error(`cannot add alias '${e}' to command '${this.name()}' as already have command '${t}'`)}return t._aliases.push(e),this}aliases(e){return void 0===e?this._aliases:(e.forEach(e=>this.alias(e)),this)}usage(e){if(void 0===e){if(this._usage)return this._usage;const e=this.registeredArguments.map(e=>l(e));return[].concat(this.options.length||null!==this._helpOption?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?e:[]).join(" ")}return this._usage=e,this}name(e){return void 0===e?this._name:(this._name=e,this)}nameFromFilename(e){return this._name=n.basename(e,n.extname(e)),this}executableDir(e){return void 0===e?this._executableDir:(this._executableDir=e,this)}helpInformation(e){const t=this.createHelp();return void 0===t.helpWidth&&(t.helpWidth=e&&e.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth()),t.formatHelp(this,t)}_getHelpContext(e){const t={error:!!(e=e||{}).error};let i;return i=t.error?e=>this._outputConfiguration.writeErr(e):e=>this._outputConfiguration.writeOut(e),t.write=e.write||i,t.command=this,t}outputHelp(e){let t;"function"==typeof e&&(t=e,e=void 0);const i=this._getHelpContext(e);this._getCommandAndAncestors().reverse().forEach(e=>e.emit("beforeAllHelp",i)),this.emit("beforeHelp",i);let n=this.helpInformation(i);if(t&&(n=t(n),"string"!=typeof n&&!Buffer.isBuffer(n)))throw new Error("outputHelp callback must return a string or a Buffer");i.write(n),this._getHelpOption()?.long&&this.emit(this._getHelpOption().long),this.emit("afterHelp",i),this._getCommandAndAncestors().forEach(e=>e.emit("afterAllHelp",i))}helpOption(e,t){return"boolean"==typeof e?(this._helpOption=e?this._helpOption??void 0:null,this):(e=e??"-h, --help",t=t??"display help for command",this._helpOption=this.createOption(e,t),this)}_getHelpOption(){return void 0===this._helpOption&&this.helpOption(void 0,void 0),this._helpOption}addHelpOption(e){return this._helpOption=e,this}help(e){this.outputHelp(e);let t=r.exitCode||0;0===t&&e&&"function"!=typeof e&&e.error&&(t=1),this._exit(t,"commander.help","(outputHelp)")}addHelpText(e,t){const i=["beforeAll","before","after","afterAll"];if(!i.includes(e))throw new Error(`Unexpected value for position to addHelpText.\nExpecting one of '${i.join("', '")}'`);const n=`${e}Help`;return this.on(n,e=>{let i;i="function"==typeof t?t({error:e.error,command:e.command}):t,i&&e.write(`${i}\n`)}),this}_outputHelpIfRequested(e){const t=this._getHelpOption();t&&e.find(e=>t.is(e))&&(this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)"))}}function v(e){return e.map(e=>{if(!e.startsWith("--inspect"))return e;let t,i,n="127.0.0.1",o="9229";return null!==(i=e.match(/^(--inspect(-brk)?)$/))?t=i[1]:null!==(i=e.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))?(t=i[1],/^\d+$/.test(i[3])?o=i[3]:n=i[3]):null!==(i=e.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))&&(t=i[1],n=i[3],o=i[4]),t&&"0"!==o?`${t}=${n}:${parseInt(o)+1}`:e})}return z.Command=g,z}(),{CommanderError:n,InvalidArgumentError:o}=q(),{Help:r}=U(),{Option:a}=H();return C.program=new i,C.createCommand=e=>new i(e),C.createOption=(e,t)=>new a(e,t),C.createArgument=(e,i)=>new t(e,i),C.Command=i,C.Option=a,C.Argument=t,C.Help=r,C.CommanderError=n,C.InvalidArgumentError=o,C.InvalidOptionArgumentError=o,C}(),W=$(Y);const{program:Z,createCommand:X,createArgument:Q,createOption:ee,CommanderError:te,InvalidArgumentError:ie,InvalidOptionArgumentError:ne,Command:oe,Argument:re,Option:ae,Help:se}=W;function le(e,t,i){function n(i,n){if(i._zod||Object.defineProperty(i,"_zod",{value:{def:n,constr:a,traits:new Set},enumerable:!1}),i._zod.traits.has(e))return;i._zod.traits.add(e),t(i,n);const o=a.prototype,r=Object.keys(o);for(let e=0;e<r.length;e++){const t=r[e];t in i||(i[t]=o[t].bind(i))}}const o=i?.Parent??Object;class r extends o{}function a(e){var t;const o=i?.Parent?new r:this;n(o,e),(t=o._zod).deferred??(t.deferred=[]);for(const e of o._zod.deferred)e();return o}return Object.defineProperty(r,"name",{value:e}),Object.defineProperty(a,"init",{value:n}),Object.defineProperty(a,Symbol.hasInstance,{value:t=>!!(i?.Parent&&t instanceof i.Parent)||t?._zod?.traits?.has(e)}),Object.defineProperty(a,"name",{value:e}),a}class ce extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class de extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name="ZodEncodeError"}}const ue={};function pe(e){return ue}function me(e){const t=Object.values(e).filter(e=>"number"==typeof e);return Object.entries(e).filter(([e,i])=>-1===t.indexOf(+e)).map(([e,t])=>t)}function he(e,t){return"bigint"==typeof t?t.toString():t}function fe(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function ge(e){return null==e}function ve(e){const t=e.startsWith("^")?1:0,i=e.endsWith("$")?e.length-1:e.length;return e.slice(t,i)}const ye=Symbol("evaluating");function be(e,t,i){let n;Object.defineProperty(e,t,{get(){if(n!==ye)return void 0===n&&(n=ye,n=i()),n},set(i){Object.defineProperty(e,t,{value:i})},configurable:!0})}function _e(e,t,i){Object.defineProperty(e,t,{value:i,writable:!0,enumerable:!0,configurable:!0})}function we(...e){const t={};for(const i of e){const e=Object.getOwnPropertyDescriptors(i);Object.assign(t,e)}return Object.defineProperties({},t)}function ke(e){return JSON.stringify(e)}const xe="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function Se(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}const Ee=fe(()=>{if("undefined"!=typeof navigator&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch(e){return!1}});function Oe(e){if(!1===Se(e))return!1;const t=e.constructor;if(void 0===t)return!0;if("function"!=typeof t)return!0;const i=t.prototype;return!1!==Se(i)&&!1!==Object.prototype.hasOwnProperty.call(i,"isPrototypeOf")}function Te(e){return Oe(e)?{...e}:Array.isArray(e)?[...e]:e}const Ae=new Set(["string","number","symbol"]);function $e(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ne(e,t,i){const n=new e._zod.constr(t??e._zod.def);return t&&!i?.parent||(n._zod.parent=e),n}function je(e){const t=e;if(!t)return{};if("string"==typeof t)return{error:()=>t};if(void 0!==t?.message){if(void 0!==t?.error)throw new Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,"string"==typeof t.error?{...t,error:()=>t.error}:t}const Ce={safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-34028234663852886e22,34028234663852886e22],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]};function Ie(e,t=0){if(!0===e.aborted)return!0;for(let i=t;i<e.issues.length;i++)if(!0!==e.issues[i]?.continue)return!0;return!1}function Re(e,t){return t.map(t=>{var i;return(i=t).path??(i.path=[]),t.path.unshift(e),t})}function qe(e){return"string"==typeof e?e:e?.message}function Pe(e,t,i){const n={...e,path:e.path??[]};if(!e.message){const o=qe(e.inst?._zod.def?.error?.(e))??qe(t?.error?.(e))??qe(i.customError?.(e))??qe(i.localeError?.(e))??"Invalid input";n.message=o}return delete n.inst,delete n.continue,t?.reportInput||delete n.input,n}function Le(e){return Array.isArray(e)?"array":"string"==typeof e?"string":"unknown"}function ze(...e){const[t,i,n]=e;return"string"==typeof t?{message:t,code:"custom",input:i,inst:n}:{...t}}const Me=(e,t)=>{e.name="$ZodError",Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),e.message=JSON.stringify(t,he,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},Ue=le("$ZodError",Me),Fe=le("$ZodError",Me,{Parent:Error}),De=e=>(t,i,n,o)=>{const r=n?Object.assign(n,{async:!1}):{async:!1},a=t._zod.run({value:i,issues:[]},r);if(a instanceof Promise)throw new ce;if(a.issues.length){const t=new(o?.Err??e)(a.issues.map(e=>Pe(e,r,pe())));throw xe(t,o?.callee),t}return a.value},He=e=>async(t,i,n,o)=>{const r=n?Object.assign(n,{async:!0}):{async:!0};let a=t._zod.run({value:i,issues:[]},r);if(a instanceof Promise&&(a=await a),a.issues.length){const t=new(o?.Err??e)(a.issues.map(e=>Pe(e,r,pe())));throw xe(t,o?.callee),t}return a.value},Be=e=>(t,i,n)=>{const o=n?{...n,async:!1}:{async:!1},r=t._zod.run({value:i,issues:[]},o);if(r instanceof Promise)throw new ce;return r.issues.length?{success:!1,error:new(e??Ue)(r.issues.map(e=>Pe(e,o,pe())))}:{success:!0,data:r.value}},Ve=Be(Fe),Je=e=>async(t,i,n)=>{const o=n?Object.assign(n,{async:!0}):{async:!0};let r=t._zod.run({value:i,issues:[]},o);return r instanceof Promise&&(r=await r),r.issues.length?{success:!1,error:new e(r.issues.map(e=>Pe(e,o,pe())))}:{success:!0,data:r.value}},Ke=Je(Fe),Ge=e=>(t,i,n)=>{const o=n?Object.assign(n,{direction:"backward"}):{direction:"backward"};return De(e)(t,i,o)},Ye=e=>(t,i,n)=>De(e)(t,i,n),We=e=>async(t,i,n)=>{const o=n?Object.assign(n,{direction:"backward"}):{direction:"backward"};return He(e)(t,i,o)},Ze=e=>async(t,i,n)=>He(e)(t,i,n),Xe=e=>(t,i,n)=>{const o=n?Object.assign(n,{direction:"backward"}):{direction:"backward"};return Be(e)(t,i,o)},Qe=e=>(t,i,n)=>Be(e)(t,i,n),et=e=>async(t,i,n)=>{const o=n?Object.assign(n,{direction:"backward"}):{direction:"backward"};return Je(e)(t,i,o)},tt=e=>async(t,i,n)=>Je(e)(t,i,n),it=/^[cC][^\s-]{8,}$/,nt=/^[0-9a-z]+$/,ot=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,rt=/^[0-9a-vA-V]{20}$/,at=/^[A-Za-z0-9]{27}$/,st=/^[a-zA-Z0-9_-]{21}$/,lt=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,ct=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,dt=e=>e?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,ut=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,pt=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,mt=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,ht=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,ft=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,gt=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,vt=/^[A-Za-z0-9_-]*$/,yt=/^\+[1-9]\d{6,14}$/,bt="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))",_t=new RegExp(`^${bt}$`);function wt(e){const t="(?:[01]\\d|2[0-3]):[0-5]\\d";return"number"==typeof e.precision?-1===e.precision?`${t}`:0===e.precision?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}const kt=/^-?\d+$/,xt=/^-?\d+(?:\.\d+)?$/,St=/^(?:true|false)$/i,Et=/^[^A-Z]*$/,Ot=/^[^a-z]*$/,Tt=le("$ZodCheck",(e,t)=>{var i;e._zod??(e._zod={}),e._zod.def=t,(i=e._zod).onattach??(i.onattach=[])}),At={number:"number",bigint:"bigint",object:"date"},$t=le("$ZodCheckLessThan",(e,t)=>{Tt.init(e,t);const i=At[typeof t.value];e._zod.onattach.push(e=>{const i=e._zod.bag,n=(t.inclusive?i.maximum:i.exclusiveMaximum)??Number.POSITIVE_INFINITY;t.value<n&&(t.inclusive?i.maximum=t.value:i.exclusiveMaximum=t.value)}),e._zod.check=n=>{(t.inclusive?n.value<=t.value:n.value<t.value)||n.issues.push({origin:i,code:"too_big",maximum:"object"==typeof t.value?t.value.getTime():t.value,input:n.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),Nt=le("$ZodCheckGreaterThan",(e,t)=>{Tt.init(e,t);const i=At[typeof t.value];e._zod.onattach.push(e=>{const i=e._zod.bag,n=(t.inclusive?i.minimum:i.exclusiveMinimum)??Number.NEGATIVE_INFINITY;t.value>n&&(t.inclusive?i.minimum=t.value:i.exclusiveMinimum=t.value)}),e._zod.check=n=>{(t.inclusive?n.value>=t.value:n.value>t.value)||n.issues.push({origin:i,code:"too_small",minimum:"object"==typeof t.value?t.value.getTime():t.value,input:n.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),jt=le("$ZodCheckMultipleOf",(e,t)=>{Tt.init(e,t),e._zod.onattach.push(e=>{var i;(i=e._zod.bag).multipleOf??(i.multipleOf=t.value)}),e._zod.check=i=>{if(typeof i.value!=typeof t.value)throw new Error("Cannot mix number and bigint in multiple_of check.");("bigint"==typeof i.value?i.value%t.value===BigInt(0):0===function(e,t){const i=(e.toString().split(".")[1]||"").length,n=t.toString();let o=(n.split(".")[1]||"").length;if(0===o&&/\d?e-\d?/.test(n)){const e=n.match(/\d?e-(\d?)/);e?.[1]&&(o=Number.parseInt(e[1]))}const r=i>o?i:o;return Number.parseInt(e.toFixed(r).replace(".",""))%Number.parseInt(t.toFixed(r).replace(".",""))/10**r}(i.value,t.value))||i.issues.push({origin:typeof i.value,code:"not_multiple_of",divisor:t.value,input:i.value,inst:e,continue:!t.abort})}}),Ct=le("$ZodCheckNumberFormat",(e,t)=>{Tt.init(e,t),t.format=t.format||"float64";const i=t.format?.includes("int"),n=i?"int":"number",[o,r]=Ce[t.format];e._zod.onattach.push(e=>{const n=e._zod.bag;n.format=t.format,n.minimum=o,n.maximum=r,i&&(n.pattern=kt)}),e._zod.check=a=>{const s=a.value;if(i){if(!Number.isInteger(s))return void a.issues.push({expected:n,format:t.format,code:"invalid_type",continue:!1,input:s,inst:e});if(!Number.isSafeInteger(s))return void(s>0?a.issues.push({input:s,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:n,inclusive:!0,continue:!t.abort}):a.issues.push({input:s,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:n,inclusive:!0,continue:!t.abort}))}s<o&&a.issues.push({origin:"number",input:s,code:"too_small",minimum:o,inclusive:!0,inst:e,continue:!t.abort}),s>r&&a.issues.push({origin:"number",input:s,code:"too_big",maximum:r,inclusive:!0,inst:e,continue:!t.abort})}}),It=le("$ZodCheckMaxLength",(e,t)=>{var i;Tt.init(e,t),(i=e._zod.def).when??(i.when=e=>{const t=e.value;return!ge(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const i=e._zod.bag.maximum??Number.POSITIVE_INFINITY;t.maximum<i&&(e._zod.bag.maximum=t.maximum)}),e._zod.check=i=>{const n=i.value;if(n.length<=t.maximum)return;const o=Le(n);i.issues.push({origin:o,code:"too_big",maximum:t.maximum,inclusive:!0,input:n,inst:e,continue:!t.abort})}}),Rt=le("$ZodCheckMinLength",(e,t)=>{var i;Tt.init(e,t),(i=e._zod.def).when??(i.when=e=>{const t=e.value;return!ge(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const i=e._zod.bag.minimum??Number.NEGATIVE_INFINITY;t.minimum>i&&(e._zod.bag.minimum=t.minimum)}),e._zod.check=i=>{const n=i.value;if(n.length>=t.minimum)return;const o=Le(n);i.issues.push({origin:o,code:"too_small",minimum:t.minimum,inclusive:!0,input:n,inst:e,continue:!t.abort})}}),qt=le("$ZodCheckLengthEquals",(e,t)=>{var i;Tt.init(e,t),(i=e._zod.def).when??(i.when=e=>{const t=e.value;return!ge(t)&&void 0!==t.length}),e._zod.onattach.push(e=>{const i=e._zod.bag;i.minimum=t.length,i.maximum=t.length,i.length=t.length}),e._zod.check=i=>{const n=i.value,o=n.length;if(o===t.length)return;const r=Le(n),a=o>t.length;i.issues.push({origin:r,...a?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:i.value,inst:e,continue:!t.abort})}}),Pt=le("$ZodCheckStringFormat",(e,t)=>{var i,n;Tt.init(e,t),e._zod.onattach.push(e=>{const i=e._zod.bag;i.format=t.format,t.pattern&&(i.patterns??(i.patterns=new Set),i.patterns.add(t.pattern))}),t.pattern?(i=e._zod).check??(i.check=i=>{t.pattern.lastIndex=0,t.pattern.test(i.value)||i.issues.push({origin:"string",code:"invalid_format",format:t.format,input:i.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(n=e._zod).check??(n.check=()=>{})}),Lt=le("$ZodCheckRegex",(e,t)=>{Pt.init(e,t),e._zod.check=i=>{t.pattern.lastIndex=0,t.pattern.test(i.value)||i.issues.push({origin:"string",code:"invalid_format",format:"regex",input:i.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),zt=le("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=Et),Pt.init(e,t)}),Mt=le("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=Ot),Pt.init(e,t)}),Ut=le("$ZodCheckIncludes",(e,t)=>{Tt.init(e,t);const i=$e(t.includes),n=new RegExp("number"==typeof t.position?`^.{${t.position}}${i}`:i);t.pattern=n,e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(n)}),e._zod.check=i=>{i.value.includes(t.includes,t.position)||i.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:i.value,inst:e,continue:!t.abort})}}),Ft=le("$ZodCheckStartsWith",(e,t)=>{Tt.init(e,t);const i=new RegExp(`^${$e(t.prefix)}.*`);t.pattern??(t.pattern=i),e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(i)}),e._zod.check=i=>{i.value.startsWith(t.prefix)||i.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:i.value,inst:e,continue:!t.abort})}}),Dt=le("$ZodCheckEndsWith",(e,t)=>{Tt.init(e,t);const i=new RegExp(`.*${$e(t.suffix)}$`);t.pattern??(t.pattern=i),e._zod.onattach.push(e=>{const t=e._zod.bag;t.patterns??(t.patterns=new Set),t.patterns.add(i)}),e._zod.check=i=>{i.value.endsWith(t.suffix)||i.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:i.value,inst:e,continue:!t.abort})}}),Ht=le("$ZodCheckOverwrite",(e,t)=>{Tt.init(e,t),e._zod.check=e=>{e.value=t.tx(e.value)}});class Bt{constructor(e=[]){this.content=[],this.indent=0,this&&(this.args=e)}indented(e){this.indent+=1,e(this),this.indent-=1}write(e){if("function"==typeof e)return e(this,{execution:"sync"}),void e(this,{execution:"async"});const t=e.split("\n").filter(e=>e),i=Math.min(...t.map(e=>e.length-e.trimStart().length)),n=t.map(e=>e.slice(i)).map(e=>" ".repeat(2*this.indent)+e);for(const e of n)this.content.push(e)}compile(){const e=Function,t=this?.args;return new e(...t,[...(this?.content??[""]).map(e=>` ${e}`)].join("\n"))}}const Vt={major:4,minor:3,patch:6},Jt=le("$ZodType",(e,t)=>{var i;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=Vt;const n=[...e._zod.def.checks??[]];e._zod.traits.has("$ZodCheck")&&n.unshift(e);for(const t of n)for(const i of t._zod.onattach)i(e);if(0===n.length)(i=e._zod).deferred??(i.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{const t=(e,t,i)=>{let n,o=Ie(e);for(const r of t){if(r._zod.def.when){if(!r._zod.def.when(e))continue}else if(o)continue;const t=e.issues.length,a=r._zod.check(e);if(a instanceof Promise&&!1===i?.async)throw new ce;if(n||a instanceof Promise)n=(n??Promise.resolve()).then(async()=>{await a,e.issues.length!==t&&(o||(o=Ie(e,t)))});else{if(e.issues.length===t)continue;o||(o=Ie(e,t))}}return n?n.then(()=>e):e},i=(i,o,r)=>{if(Ie(i))return i.aborted=!0,i;const a=t(o,n,r);if(a instanceof Promise){if(!1===r.async)throw new ce;return a.then(t=>e._zod.parse(t,r))}return e._zod.parse(a,r)};e._zod.run=(o,r)=>{if(r.skipChecks)return e._zod.parse(o,r);if("backward"===r.direction){const t=e._zod.parse({value:o.value,issues:[]},{...r,skipChecks:!0});return t instanceof Promise?t.then(e=>i(e,o,r)):i(t,o,r)}const a=e._zod.parse(o,r);if(a instanceof Promise){if(!1===r.async)throw new ce;return a.then(e=>t(e,n,r))}return t(a,n,r)}}be(e,"~standard",()=>({validate:t=>{try{const i=Ve(e,t);return i.success?{value:i.data}:{issues:i.error?.issues}}catch(i){return Ke(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:"zod",version:1}))}),Kt=le("$ZodString",(e,t)=>{var i;Jt.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??(i=e._zod.bag,new RegExp(`^${i?`[\\s\\S]{${i?.minimum??0},${i?.maximum??""}}`:"[\\s\\S]*"}$`)),e._zod.parse=(i,n)=>{if(t.coerce)try{i.value=String(i.value)}catch(n){}return"string"==typeof i.value||i.issues.push({expected:"string",code:"invalid_type",input:i.value,inst:e}),i}}),Gt=le("$ZodStringFormat",(e,t)=>{Pt.init(e,t),Kt.init(e,t)}),Yt=le("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=ct),Gt.init(e,t)}),Wt=le("$ZodUUID",(e,t)=>{if(t.version){const e={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[t.version];if(void 0===e)throw new Error(`Invalid UUID version: "${t.version}"`);t.pattern??(t.pattern=dt(e))}else t.pattern??(t.pattern=dt());Gt.init(e,t)}),Zt=le("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=ut),Gt.init(e,t)}),Xt=le("$ZodURL",(e,t)=>{Gt.init(e,t),e._zod.check=i=>{try{const n=i.value.trim(),o=new URL(n);return t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(o.hostname)||i.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:t.hostname.source,input:i.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(o.protocol.endsWith(":")?o.protocol.slice(0,-1):o.protocol)||i.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:t.protocol.source,input:i.value,inst:e,continue:!t.abort})),void(t.normalize?i.value=o.href:i.value=n)}catch(n){i.issues.push({code:"invalid_format",format:"url",input:i.value,inst:e,continue:!t.abort})}}}),Qt=le("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=new RegExp("^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$","u")),Gt.init(e,t)}),ei=le("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=st),Gt.init(e,t)}),ti=le("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=it),Gt.init(e,t)}),ii=le("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=nt),Gt.init(e,t)}),ni=le("$ZodULID",(e,t)=>{t.pattern??(t.pattern=ot),Gt.init(e,t)}),oi=le("$ZodXID",(e,t)=>{t.pattern??(t.pattern=rt),Gt.init(e,t)}),ri=le("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=at),Gt.init(e,t)}),ai=le("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=function(e){const t=wt({precision:e.precision}),i=["Z"];e.local&&i.push(""),e.offset&&i.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");const n=`${t}(?:${i.join("|")})`;return new RegExp(`^${bt}T(?:${n})$`)}(t)),Gt.init(e,t)}),si=le("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=_t),Gt.init(e,t)}),li=le("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=new RegExp(`^${wt(t)}$`)),Gt.init(e,t)}),ci=le("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=lt),Gt.init(e,t)}),di=le("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=pt),Gt.init(e,t),e._zod.bag.format="ipv4"}),ui=le("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=mt),Gt.init(e,t),e._zod.bag.format="ipv6",e._zod.check=i=>{try{new URL(`http://[${i.value}]`)}catch{i.issues.push({code:"invalid_format",format:"ipv6",input:i.value,inst:e,continue:!t.abort})}}}),pi=le("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=ht),Gt.init(e,t)}),mi=le("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=ft),Gt.init(e,t),e._zod.check=i=>{const n=i.value.split("/");try{if(2!==n.length)throw new Error;const[e,t]=n;if(!t)throw new Error;const i=Number(t);if(`${i}`!==t)throw new Error;if(i<0||i>128)throw new Error;new URL(`http://[${e}]`)}catch{i.issues.push({code:"invalid_format",format:"cidrv6",input:i.value,inst:e,continue:!t.abort})}}});function hi(e){if(""===e)return!0;if(e.length%4!=0)return!1;try{return atob(e),!0}catch{return!1}}const fi=le("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=gt),Gt.init(e,t),e._zod.bag.contentEncoding="base64",e._zod.check=i=>{hi(i.value)||i.issues.push({code:"invalid_format",format:"base64",input:i.value,inst:e,continue:!t.abort})}}),gi=le("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=vt),Gt.init(e,t),e._zod.bag.contentEncoding="base64url",e._zod.check=i=>{(function(e){if(!vt.test(e))return!1;const t=e.replace(/[-_]/g,e=>"-"===e?"+":"/");return hi(t.padEnd(4*Math.ceil(t.length/4),"="))})(i.value)||i.issues.push({code:"invalid_format",format:"base64url",input:i.value,inst:e,continue:!t.abort})}}),vi=le("$ZodE164",(e,t)=>{t.pattern??(t.pattern=yt),Gt.init(e,t)}),yi=le("$ZodJWT",(e,t)=>{Gt.init(e,t),e._zod.check=i=>{(function(e,t=null){try{const i=e.split(".");if(3!==i.length)return!1;const[n]=i;if(!n)return!1;const o=JSON.parse(atob(n));return!("typ"in o&&"JWT"!==o?.typ||!o.alg||t&&(!("alg"in o)||o.alg!==t))}catch{return!1}})(i.value,t.alg)||i.issues.push({code:"invalid_format",format:"jwt",input:i.value,inst:e,continue:!t.abort})}}),bi=le("$ZodNumber",(e,t)=>{Jt.init(e,t),e._zod.pattern=e._zod.bag.pattern??xt,e._zod.parse=(i,n)=>{if(t.coerce)try{i.value=Number(i.value)}catch(e){}const o=i.value;if("number"==typeof o&&!Number.isNaN(o)&&Number.isFinite(o))return i;const r="number"==typeof o?Number.isNaN(o)?"NaN":Number.isFinite(o)?void 0:"Infinity":void 0;return i.issues.push({expected:"number",code:"invalid_type",input:o,inst:e,...r?{received:r}:{}}),i}}),_i=le("$ZodNumberFormat",(e,t)=>{Ct.init(e,t),bi.init(e,t)}),wi=le("$ZodBoolean",(e,t)=>{Jt.init(e,t),e._zod.pattern=St,e._zod.parse=(i,n)=>{if(t.coerce)try{i.value=Boolean(i.value)}catch(e){}const o=i.value;return"boolean"==typeof o||i.issues.push({expected:"boolean",code:"invalid_type",input:o,inst:e}),i}}),ki=le("$ZodUnknown",(e,t)=>{Jt.init(e,t),e._zod.parse=e=>e}),xi=le("$ZodNever",(e,t)=>{Jt.init(e,t),e._zod.parse=(t,i)=>(t.issues.push({expected:"never",code:"invalid_type",input:t.value,inst:e}),t)});function Si(e,t,i){e.issues.length&&t.issues.push(...Re(i,e.issues)),t.value[i]=e.value}const Ei=le("$ZodArray",(e,t)=>{Jt.init(e,t),e._zod.parse=(i,n)=>{const o=i.value;if(!Array.isArray(o))return i.issues.push({expected:"array",code:"invalid_type",input:o,inst:e}),i;i.value=Array(o.length);const r=[];for(let e=0;e<o.length;e++){const a=o[e],s=t.element._zod.run({value:a,issues:[]},n);s instanceof Promise?r.push(s.then(t=>Si(t,i,e))):Si(s,i,e)}return r.length?Promise.all(r).then(()=>i):i}});function Oi(e,t,i,n,o){if(e.issues.length){if(o&&!(i in n))return;t.issues.push(...Re(i,e.issues))}void 0===e.value?i in n&&(t.value[i]=void 0):t.value[i]=e.value}function Ti(e){const t=Object.keys(e.shape);for(const i of t)if(!e.shape?.[i]?._zod?.traits?.has("$ZodType"))throw new Error(`Invalid element at key "${i}": expected a Zod schema`);const i=(n=e.shape,Object.keys(n).filter(e=>"optional"===n[e]._zod.optin&&"optional"===n[e]._zod.optout));var n;return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(i)}}function Ai(e,t,i,n,o,r){const a=[],s=o.keySet,l=o.catchall._zod,c=l.def.type,d="optional"===l.optout;for(const o in t){if(s.has(o))continue;if("never"===c){a.push(o);continue}const r=l.run({value:t[o],issues:[]},n);r instanceof Promise?e.push(r.then(e=>Oi(e,i,o,t,d))):Oi(r,i,o,t,d)}return a.length&&i.issues.push({code:"unrecognized_keys",keys:a,input:t,inst:r}),e.length?Promise.all(e).then(()=>i):i}const $i=le("$ZodObject",(e,t)=>{Jt.init(e,t);const i=Object.getOwnPropertyDescriptor(t,"shape");if(!i?.get){const e=t.shape;Object.defineProperty(t,"shape",{get:()=>{const i={...e};return Object.defineProperty(t,"shape",{value:i}),i}})}const n=fe(()=>Ti(t));be(e._zod,"propValues",()=>{const e=t.shape,i={};for(const t in e){const n=e[t]._zod;if(n.values){i[t]??(i[t]=new Set);for(const e of n.values)i[t].add(e)}}return i});const o=Se,r=t.catchall;let a;e._zod.parse=(t,i)=>{a??(a=n.value);const s=t.value;if(!o(s))return t.issues.push({expected:"object",code:"invalid_type",input:s,inst:e}),t;t.value={};const l=[],c=a.shape;for(const e of a.keys){const n=c[e],o="optional"===n._zod.optout,r=n._zod.run({value:s[e],issues:[]},i);r instanceof Promise?l.push(r.then(i=>Oi(i,t,e,s,o))):Oi(r,t,e,s,o)}return r?Ai(l,s,t,i,n.value,e):l.length?Promise.all(l).then(()=>t):t}}),Ni=le("$ZodObjectJIT",(e,t)=>{$i.init(e,t);const i=e._zod.parse,n=fe(()=>Ti(t));let o;const r=Se,a=!ue.jitless,s=a&&Ee.value,l=t.catchall;let c;e._zod.parse=(d,u)=>{c??(c=n.value);const p=d.value;return r(p)?a&&s&&!1===u?.async&&!0!==u.jitless?(o||(o=(e=>{const t=new Bt(["shape","payload","ctx"]),i=n.value,o=e=>{const t=ke(e);return`shape[${t}]._zod.run({ value: input[${t}], issues: [] }, ctx)`};t.write("const input = payload.value;");const r=Object.create(null);let a=0;for(const e of i.keys)r[e]="key_"+a++;t.write("const newResult = {};");for(const n of i.keys){const i=r[n],a=ke(n),s=e[n],l="optional"===s?._zod?.optout;t.write(`const ${i} = ${o(n)};`),l?t.write(`\n if (${i}.issues.length) {\n if (${a} in input) {\n payload.issues = payload.issues.concat(${i}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${a}, ...iss.path] : [${a}]\n })));\n }\n }\n \n if (${i}.value === undefined) {\n if (${a} in input) {\n newResult[${a}] = undefined;\n }\n } else {\n newResult[${a}] = ${i}.value;\n }\n \n `):t.write(`\n if (${i}.issues.length) {\n payload.issues = payload.issues.concat(${i}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${a}, ...iss.path] : [${a}]\n })));\n }\n \n if (${i}.value === undefined) {\n if (${a} in input) {\n newResult[${a}] = undefined;\n }\n } else {\n newResult[${a}] = ${i}.value;\n }\n \n `)}t.write("payload.value = newResult;"),t.write("return payload;");const s=t.compile();return(t,i)=>s(e,t,i)})(t.shape)),d=o(d,u),l?Ai([],p,d,u,c,e):d):i(d,u):(d.issues.push({expected:"object",code:"invalid_type",input:p,inst:e}),d)}});function ji(e,t,i,n){for(const i of e)if(0===i.issues.length)return t.value=i.value,t;const o=e.filter(e=>!Ie(e));return 1===o.length?(t.value=o[0].value,o[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:i,errors:e.map(e=>e.issues.map(e=>Pe(e,n,pe())))}),t)}const Ci=le("$ZodUnion",(e,t)=>{Jt.init(e,t),be(e._zod,"optin",()=>t.options.some(e=>"optional"===e._zod.optin)?"optional":void 0),be(e._zod,"optout",()=>t.options.some(e=>"optional"===e._zod.optout)?"optional":void 0),be(e._zod,"values",()=>{if(t.options.every(e=>e._zod.values))return new Set(t.options.flatMap(e=>Array.from(e._zod.values)))}),be(e._zod,"pattern",()=>{if(t.options.every(e=>e._zod.pattern)){const e=t.options.map(e=>e._zod.pattern);return new RegExp(`^(${e.map(e=>ve(e.source)).join("|")})$`)}});const i=1===t.options.length,n=t.options[0]._zod.run;e._zod.parse=(o,r)=>{if(i)return n(o,r);let a=!1;const s=[];for(const e of t.options){const t=e._zod.run({value:o.value,issues:[]},r);if(t instanceof Promise)s.push(t),a=!0;else{if(0===t.issues.length)return t;s.push(t)}}return a?Promise.all(s).then(t=>ji(t,o,e,r)):ji(s,o,e,r)}}),Ii=le("$ZodIntersection",(e,t)=>{Jt.init(e,t),e._zod.parse=(e,i)=>{const n=e.value,o=t.left._zod.run({value:n,issues:[]},i),r=t.right._zod.run({value:n,issues:[]},i);return o instanceof Promise||r instanceof Promise?Promise.all([o,r]).then(([t,i])=>qi(e,t,i)):qi(e,o,r)}});function Ri(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e===+t)return{valid:!0,data:e};if(Oe(e)&&Oe(t)){const i=Object.keys(t),n=Object.keys(e).filter(e=>-1!==i.indexOf(e)),o={...e,...t};for(const i of n){const n=Ri(e[i],t[i]);if(!n.valid)return{valid:!1,mergeErrorPath:[i,...n.mergeErrorPath]};o[i]=n.data}return{valid:!0,data:o}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const i=[];for(let n=0;n<e.length;n++){const o=Ri(e[n],t[n]);if(!o.valid)return{valid:!1,mergeErrorPath:[n,...o.mergeErrorPath]};i.push(o.data)}return{valid:!0,data:i}}return{valid:!1,mergeErrorPath:[]}}function qi(e,t,i){const n=new Map;let o;for(const i of t.issues)if("unrecognized_keys"===i.code){o??(o=i);for(const e of i.keys)n.has(e)||n.set(e,{}),n.get(e).l=!0}else e.issues.push(i);for(const t of i.issues)if("unrecognized_keys"===t.code)for(const e of t.keys)n.has(e)||n.set(e,{}),n.get(e).r=!0;else e.issues.push(t);const r=[...n].filter(([,e])=>e.l&&e.r).map(([e])=>e);if(r.length&&o&&e.issues.push({...o,keys:r}),Ie(e))return e;const a=Ri(t.value,i.value);if(!a.valid)throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(a.mergeErrorPath)}`);return e.value=a.data,e}const Pi=le("$ZodEnum",(e,t)=>{Jt.init(e,t);const i=me(t.entries),n=new Set(i);e._zod.values=n,e._zod.pattern=new RegExp(`^(${i.filter(e=>Ae.has(typeof e)).map(e=>"string"==typeof e?$e(e):e.toString()).join("|")})$`),e._zod.parse=(t,o)=>{const r=t.value;return n.has(r)||t.issues.push({code:"invalid_value",values:i,input:r,inst:e}),t}}),Li=le("$ZodTransform",(e,t)=>{Jt.init(e,t),e._zod.parse=(i,n)=>{if("backward"===n.direction)throw new de(e.constructor.name);const o=t.transform(i.value,i);if(n.async)return(o instanceof Promise?o:Promise.resolve(o)).then(e=>(i.value=e,i));if(o instanceof Promise)throw new ce;return i.value=o,i}});function zi(e,t){return e.issues.length&&void 0===t?{issues:[],value:void 0}:e}const Mi=le("$ZodOptional",(e,t)=>{Jt.init(e,t),e._zod.optin="optional",e._zod.optout="optional",be(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),be(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${ve(e.source)})?$`):void 0}),e._zod.parse=(e,i)=>{if("optional"===t.innerType._zod.optin){const n=t.innerType._zod.run(e,i);return n instanceof Promise?n.then(t=>zi(t,e.value)):zi(n,e.value)}return void 0===e.value?e:t.innerType._zod.run(e,i)}}),Ui=le("$ZodExactOptional",(e,t)=>{Mi.init(e,t),be(e._zod,"values",()=>t.innerType._zod.values),be(e._zod,"pattern",()=>t.innerType._zod.pattern),e._zod.parse=(e,i)=>t.innerType._zod.run(e,i)}),Fi=le("$ZodNullable",(e,t)=>{Jt.init(e,t),be(e._zod,"optin",()=>t.innerType._zod.optin),be(e._zod,"optout",()=>t.innerType._zod.optout),be(e._zod,"pattern",()=>{const e=t.innerType._zod.pattern;return e?new RegExp(`^(${ve(e.source)}|null)$`):void 0}),be(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(e,i)=>null===e.value?e:t.innerType._zod.run(e,i)}),Di=le("$ZodDefault",(e,t)=>{Jt.init(e,t),e._zod.optin="optional",be(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,i)=>{if("backward"===i.direction)return t.innerType._zod.run(e,i);if(void 0===e.value)return e.value=t.defaultValue,e;const n=t.innerType._zod.run(e,i);return n instanceof Promise?n.then(e=>Hi(e,t)):Hi(n,t)}});function Hi(e,t){return void 0===e.value&&(e.value=t.defaultValue),e}const Bi=le("$ZodPrefault",(e,t)=>{Jt.init(e,t),e._zod.optin="optional",be(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,i)=>("backward"===i.direction||void 0===e.value&&(e.value=t.defaultValue),t.innerType._zod.run(e,i))}),Vi=le("$ZodNonOptional",(e,t)=>{Jt.init(e,t),be(e._zod,"values",()=>{const e=t.innerType._zod.values;return e?new Set([...e].filter(e=>void 0!==e)):void 0}),e._zod.parse=(i,n)=>{const o=t.innerType._zod.run(i,n);return o instanceof Promise?o.then(t=>Ji(t,e)):Ji(o,e)}});function Ji(e,t){return e.issues.length||void 0!==e.value||e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const Ki=le("$ZodCatch",(e,t)=>{Jt.init(e,t),be(e._zod,"optin",()=>t.innerType._zod.optin),be(e._zod,"optout",()=>t.innerType._zod.optout),be(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(e,i)=>{if("backward"===i.direction)return t.innerType._zod.run(e,i);const n=t.innerType._zod.run(e,i);return n instanceof Promise?n.then(n=>(e.value=n.value,n.issues.length&&(e.value=t.catchValue({...e,error:{issues:n.issues.map(e=>Pe(e,i,pe()))},input:e.value}),e.issues=[]),e)):(e.value=n.value,n.issues.length&&(e.value=t.catchValue({...e,error:{issues:n.issues.map(e=>Pe(e,i,pe()))},input:e.value}),e.issues=[]),e)}}),Gi=le("$ZodPipe",(e,t)=>{Jt.init(e,t),be(e._zod,"values",()=>t.in._zod.values),be(e._zod,"optin",()=>t.in._zod.optin),be(e._zod,"optout",()=>t.out._zod.optout),be(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(e,i)=>{if("backward"===i.direction){const n=t.out._zod.run(e,i);return n instanceof Promise?n.then(e=>Yi(e,t.in,i)):Yi(n,t.in,i)}const n=t.in._zod.run(e,i);return n instanceof Promise?n.then(e=>Yi(e,t.out,i)):Yi(n,t.out,i)}});function Yi(e,t,i){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},i)}const Wi=le("$ZodReadonly",(e,t)=>{Jt.init(e,t),be(e._zod,"propValues",()=>t.innerType._zod.propValues),be(e._zod,"values",()=>t.innerType._zod.values),be(e._zod,"optin",()=>t.innerType?._zod?.optin),be(e._zod,"optout",()=>t.innerType?._zod?.optout),e._zod.parse=(e,i)=>{if("backward"===i.direction)return t.innerType._zod.run(e,i);const n=t.innerType._zod.run(e,i);return n instanceof Promise?n.then(Zi):Zi(n)}});function Zi(e){return e.value=Object.freeze(e.value),e}const Xi=le("$ZodCustom",(e,t)=>{Tt.init(e,t),Jt.init(e,t),e._zod.parse=(e,t)=>e,e._zod.check=i=>{const n=i.value,o=t.fn(n);if(o instanceof Promise)return o.then(t=>Qi(t,i,n,e));Qi(o,i,n,e)}});function Qi(e,t,i,n){if(!e){const e={code:"custom",input:i,inst:n,path:[...n._zod.def.path??[]],continue:!n._zod.def.abort};n._zod.def.params&&(e.params=n._zod.def.params),t.issues.push(ze(e))}}var en;(en=globalThis).__zod_globalRegistry??(en.__zod_globalRegistry=new class{constructor(){this._map=new WeakMap,this._idmap=new Map}add(e,...t){const i=t[0];return this._map.set(e,i),i&&"object"==typeof i&&"id"in i&&this._idmap.set(i.id,e),this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(e){const t=this._map.get(e);return t&&"object"==typeof t&&"id"in t&&this._idmap.delete(t.id),this._map.delete(e),this}get(e){const t=e._zod.parent;if(t){const i={...this.get(t)??{}};delete i.id;const n={...i,...this._map.get(e)};return Object.keys(n).length?n:void 0}return this._map.get(e)}has(e){return this._map.has(e)}});const tn=globalThis.__zod_globalRegistry;function nn(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...je(t)})}function on(e,t){return new $t({check:"less_than",...je(t),value:e,inclusive:!1})}function rn(e,t){return new $t({check:"less_than",...je(t),value:e,inclusive:!0})}function an(e,t){return new Nt({check:"greater_than",...je(t),value:e,inclusive:!1})}function sn(e,t){return new Nt({check:"greater_than",...je(t),value:e,inclusive:!0})}function ln(e,t){return new jt({check:"multiple_of",...je(t),value:e})}function cn(e,t){return new It({check:"max_length",...je(t),maximum:e})}function dn(e,t){return new Rt({check:"min_length",...je(t),minimum:e})}function un(e,t){return new qt({check:"length_equals",...je(t),length:e})}function pn(e){return new Ht({check:"overwrite",tx:e})}function mn(e){let t=e?.target??"draft-2020-12";return"draft-4"===t&&(t="draft-04"),"draft-7"===t&&(t="draft-07"),{processors:e.processors??{},metadataRegistry:e?.metadata??tn,target:t,unrepresentable:e?.unrepresentable??"throw",override:e?.override??(()=>{}),io:e?.io??"output",counter:0,seen:new Map,cycles:e?.cycles??"ref",reused:e?.reused??"inline",external:e?.external??void 0}}function hn(e,t,i={path:[],schemaPath:[]}){var n;const o=e._zod.def,r=t.seen.get(e);if(r)return r.count++,i.schemaPath.includes(e)&&(r.cycle=i.path),r.schema;const a={schema:{},count:1,cycle:void 0,path:i.path};t.seen.set(e,a);const s=e._zod.toJSONSchema?.();if(s)a.schema=s;else{const n={...i,schemaPath:[...i.schemaPath,e],path:i.path};if(e._zod.processJSONSchema)e._zod.processJSONSchema(t,a.schema,n);else{const i=a.schema,r=t.processors[o.type];if(!r)throw new Error(`[toJSONSchema]: Non-representable type encountered: ${o.type}`);r(e,t,i,n)}const r=e._zod.parent;r&&(a.ref||(a.ref=r),hn(r,t,n),t.seen.get(r).isParent=!0)}const l=t.metadataRegistry.get(e);return l&&Object.assign(a.schema,l),"input"===t.io&&vn(e)&&(delete a.schema.examples,delete a.schema.default),"input"===t.io&&a.schema._prefault&&((n=a.schema).default??(n.default=a.schema._prefault)),delete a.schema._prefault,t.seen.get(e).schema}function fn(e,t){const i=e.seen.get(t);if(!i)throw new Error("Unprocessed schema. This is a bug in Zod.");const n=new Map;for(const t of e.seen.entries()){const i=e.metadataRegistry.get(t[0])?.id;if(i){const e=n.get(i);if(e&&e!==t[0])throw new Error(`Duplicate schema id "${i}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);n.set(i,t[0])}}const o=t=>{if(t[1].schema.$ref)return;const n=t[1],{ref:o,defId:r}=(t=>{const n="draft-2020-12"===e.target?"$defs":"definitions";if(e.external){const i=e.external.registry.get(t[0])?.id,o=e.external.uri??(e=>e);if(i)return{ref:o(i)};const r=t[1].defId??t[1].schema.id??"schema"+e.counter++;return t[1].defId=r,{defId:r,ref:`${o("__shared")}#/${n}/${r}`}}if(t[1]===i)return{ref:"#"};const o=`#/${n}/`,r=t[1].schema.id??"__schema"+e.counter++;return{defId:r,ref:o+r}})(t);n.def={...n.schema},r&&(n.defId=r);const a=n.schema;for(const e in a)delete a[e];a.$ref=o};if("throw"===e.cycles)for(const t of e.seen.entries()){const e=t[1];if(e.cycle)throw new Error(`Cycle detected: #/${e.cycle?.join("/")}/<root>\n\nSet the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`)}for(const i of e.seen.entries()){const n=i[1];if(t===i[0]){o(i);continue}if(e.external){const n=e.external.registry.get(i[0])?.id;if(t!==i[0]&&n){o(i);continue}}const r=e.metadataRegistry.get(i[0])?.id;(r||n.cycle||n.count>1&&"ref"===e.reused)&&o(i)}}function gn(e,t){const i=e.seen.get(t);if(!i)throw new Error("Unprocessed schema. This is a bug in Zod.");const n=t=>{const i=e.seen.get(t);if(null===i.ref)return;const o=i.def??i.schema,r={...o},a=i.ref;if(i.ref=null,a){n(a);const i=e.seen.get(a),s=i.schema;if(!s.$ref||"draft-07"!==e.target&&"draft-04"!==e.target&&"openapi-3.0"!==e.target?Object.assign(o,s):(o.allOf=o.allOf??[],o.allOf.push(s)),Object.assign(o,r),t._zod.parent===a)for(const e in o)"$ref"!==e&&"allOf"!==e&&(e in r||delete o[e]);if(s.$ref&&i.def)for(const e in o)"$ref"!==e&&"allOf"!==e&&e in i.def&&JSON.stringify(o[e])===JSON.stringify(i.def[e])&&delete o[e]}const s=t._zod.parent;if(s&&s!==a){n(s);const t=e.seen.get(s);if(t?.schema.$ref&&(o.$ref=t.schema.$ref,t.def))for(const e in o)"$ref"!==e&&"allOf"!==e&&e in t.def&&JSON.stringify(o[e])===JSON.stringify(t.def[e])&&delete o[e]}e.override({zodSchema:t,jsonSchema:o,path:i.path??[]})};for(const t of[...e.seen.entries()].reverse())n(t[0]);const o={};if("draft-2020-12"===e.target?o.$schema="https://json-schema.org/draft/2020-12/schema":"draft-07"===e.target?o.$schema="http://json-schema.org/draft-07/schema#":"draft-04"===e.target?o.$schema="http://json-schema.org/draft-04/schema#":e.target,e.external?.uri){const i=e.external.registry.get(t)?.id;if(!i)throw new Error("Schema is missing an `id` property");o.$id=e.external.uri(i)}Object.assign(o,i.def??i.schema);const r=e.external?.defs??{};for(const t of e.seen.entries()){const e=t[1];e.def&&e.defId&&(r[e.defId]=e.def)}e.external||Object.keys(r).length>0&&("draft-2020-12"===e.target?o.$defs=r:o.definitions=r);try{const i=JSON.parse(JSON.stringify(o));return Object.defineProperty(i,"~standard",{value:{...t["~standard"],jsonSchema:{input:yn(t,"input",e.processors),output:yn(t,"output",e.processors)}},enumerable:!1,writable:!1}),i}catch(e){throw new Error("Error converting schema to JSON.")}}function vn(e,t){const i=t??{seen:new Set};if(i.seen.has(e))return!1;i.seen.add(e);const n=e._zod.def;if("transform"===n.type)return!0;if("array"===n.type)return vn(n.element,i);if("set"===n.type)return vn(n.valueType,i);if("lazy"===n.type)return vn(n.getter(),i);if("promise"===n.type||"optional"===n.type||"nonoptional"===n.type||"nullable"===n.type||"readonly"===n.type||"default"===n.type||"prefault"===n.type)return vn(n.innerType,i);if("intersection"===n.type)return vn(n.left,i)||vn(n.right,i);if("record"===n.type||"map"===n.type)return vn(n.keyType,i)||vn(n.valueType,i);if("pipe"===n.type)return vn(n.in,i)||vn(n.out,i);if("object"===n.type){for(const e in n.shape)if(vn(n.shape[e],i))return!0;return!1}if("union"===n.type){for(const e of n.options)if(vn(e,i))return!0;return!1}if("tuple"===n.type){for(const e of n.items)if(vn(e,i))return!0;return!(!n.rest||!vn(n.rest,i))}return!1}const yn=(e,t,i={})=>n=>{const{libraryOptions:o,target:r}=n??{},a=mn({...o??{},target:r,io:t,processors:i});return hn(e,a),fn(a,e),gn(a,e)},bn={guid:"uuid",url:"uri",datetime:"date-time",json_string:"json-string",regex:""},_n=(e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType},wn=le("ZodISODateTime",(e,t)=>{ai.init(e,t),Dn.init(e,t)});const kn=le("ZodISODate",(e,t)=>{si.init(e,t),Dn.init(e,t)});const xn=le("ZodISOTime",(e,t)=>{li.init(e,t),Dn.init(e,t)});const Sn=le("ZodISODuration",(e,t)=>{ci.init(e,t),Dn.init(e,t)});const En=le("ZodError",(e,t)=>{Ue.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:t=>function(e,t=e=>e.message){const i={_errors:[]},n=e=>{for(const o of e.issues)if("invalid_union"===o.code&&o.errors.length)o.errors.map(e=>n({issues:e}));else if("invalid_key"===o.code)n({issues:o.issues});else if("invalid_element"===o.code)n({issues:o.issues});else if(0===o.path.length)i._errors.push(t(o));else{let e=i,n=0;for(;n<o.path.length;){const i=o.path[n];n===o.path.length-1?(e[i]=e[i]||{_errors:[]},e[i]._errors.push(t(o))):e[i]=e[i]||{_errors:[]},e=e[i],n++}}};return n(e),i}(e,t)},flatten:{value:t=>function(e,t=e=>e.message){const i={},n=[];for(const o of e.issues)o.path.length>0?(i[o.path[0]]=i[o.path[0]]||[],i[o.path[0]].push(t(o))):n.push(t(o));return{formErrors:n,fieldErrors:i}}(e,t)},addIssue:{value:t=>{e.issues.push(t),e.message=JSON.stringify(e.issues,he,2)}},addIssues:{value:t=>{e.issues.push(...t),e.message=JSON.stringify(e.issues,he,2)}},isEmpty:{get:()=>0===e.issues.length}})},{Parent:Error}),On=De(En),Tn=He(En),An=Be(En),$n=Je(En),Nn=Ge(En),jn=Ye(En),Cn=We(En),In=Ze(En),Rn=Xe(En),qn=Qe(En),Pn=et(En),Ln=tt(En),zn=le("ZodType",(e,t)=>(Jt.init(e,t),Object.assign(e["~standard"],{jsonSchema:{input:yn(e,"input"),output:yn(e,"output")}}),e.toJSONSchema=((e,t={})=>i=>{const n=mn({...i,processors:t});return hn(e,n),fn(n,e),gn(n,e)})(e,{}),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...i)=>e.clone(we(t,{checks:[...t.checks??[],...i.map(e=>"function"==typeof e?{_zod:{check:e,def:{check:"custom"},onattach:[]}}:e)]}),{parent:!0}),e.with=e.check,e.clone=(t,i)=>Ne(e,t,i),e.brand=()=>e,e.register=(t,i)=>(t.add(e,i),e),e.parse=(t,i)=>On(e,t,i,{callee:e.parse}),e.safeParse=(t,i)=>An(e,t,i),e.parseAsync=async(t,i)=>Tn(e,t,i,{callee:e.parseAsync}),e.safeParseAsync=async(t,i)=>$n(e,t,i),e.spa=e.safeParseAsync,e.encode=(t,i)=>Nn(e,t,i),e.decode=(t,i)=>jn(e,t,i),e.encodeAsync=async(t,i)=>Cn(e,t,i),e.decodeAsync=async(t,i)=>In(e,t,i),e.safeEncode=(t,i)=>Rn(e,t,i),e.safeDecode=(t,i)=>qn(e,t,i),e.safeEncodeAsync=async(t,i)=>Pn(e,t,i),e.safeDecodeAsync=async(t,i)=>Ln(e,t,i),e.refine=(t,i)=>e.check(function(e,t={}){return function(e,t,i){return new Uo({type:"custom",check:"custom",fn:t,...je(i)})}(0,e,t)}(t,i)),e.superRefine=t=>e.check(function(e){const t=function(e){const t=new Tt({check:"custom",...je(void 0)});return t._zod.check=e,t}(i=>(i.addIssue=e=>{if("string"==typeof e)i.issues.push(ze(e,i.value,t._zod.def));else{const n=e;n.fatal&&(n.continue=!1),n.code??(n.code="custom"),n.input??(n.input=i.value),n.inst??(n.inst=t),n.continue??(n.continue=!t._zod.def.abort),i.issues.push(ze(n))}},e(i.value,i)));return t}(t)),e.overwrite=t=>e.check(pn(t)),e.optional=()=>$o(e),e.exactOptional=()=>new No({type:"optional",innerType:e}),e.nullable=()=>Co(e),e.nullish=()=>$o(Co(e)),e.nonoptional=t=>function(e,t){return new qo({type:"nonoptional",innerType:e,...je(t)})}(e,t),e.array=()=>bo(e),e.or=t=>xo([e,t]),e.and=t=>new So({type:"intersection",left:e,right:t}),e.transform=t=>zo(e,new To({type:"transform",transform:t})),e.default=t=>{return i=t,new Io({type:"default",innerType:e,get defaultValue(){return"function"==typeof i?i():Te(i)}});var i},e.prefault=t=>{return i=t,new Ro({type:"prefault",innerType:e,get defaultValue(){return"function"==typeof i?i():Te(i)}});var i},e.catch=t=>{return new Po({type:"catch",innerType:e,catchValue:"function"==typeof(i=t)?i:()=>i});var i},e.pipe=t=>zo(e,t),e.readonly=()=>new Mo({type:"readonly",innerType:e}),e.describe=t=>{const i=e.clone();return tn.add(i,{description:t}),i},Object.defineProperty(e,"description",{get:()=>tn.get(e)?.description,configurable:!0}),e.meta=(...t)=>{if(0===t.length)return tn.get(e);const i=e.clone();return tn.add(i,t[0]),i},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e.apply=t=>t(e),e)),Mn=le("_ZodString",(e,t)=>{Kt.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i)=>{const n=i;n.type="string";const{minimum:o,maximum:r,format:a,patterns:s,contentEncoding:l}=e._zod.bag;if("number"==typeof o&&(n.minLength=o),"number"==typeof r&&(n.maxLength=r),a&&(n.format=bn[a]??a,""===n.format&&delete n.format,"time"===a&&delete n.format),l&&(n.contentEncoding=l),s&&s.size>0){const e=[...s];1===e.length?n.pattern=e[0].source:e.length>1&&(n.allOf=[...e.map(e=>({..."draft-07"===t.target||"draft-04"===t.target||"openapi-3.0"===t.target?{type:"string"}:{},pattern:e.source}))])}})(e,t,i);const i=e._zod.bag;e.format=i.format??null,e.minLength=i.minimum??null,e.maxLength=i.maximum??null,e.regex=(...t)=>e.check(function(e,t){return new Lt({check:"string_format",format:"regex",...je(t),pattern:e})}(...t)),e.includes=(...t)=>e.check(function(e,t){return new Ut({check:"string_format",format:"includes",...je(t),includes:e})}(...t)),e.startsWith=(...t)=>e.check(function(e,t){return new Ft({check:"string_format",format:"starts_with",...je(t),prefix:e})}(...t)),e.endsWith=(...t)=>e.check(function(e,t){return new Dt({check:"string_format",format:"ends_with",...je(t),suffix:e})}(...t)),e.min=(...t)=>e.check(dn(...t)),e.max=(...t)=>e.check(cn(...t)),e.length=(...t)=>e.check(un(...t)),e.nonempty=(...t)=>e.check(dn(1,...t)),e.lowercase=t=>e.check(function(e){return new zt({check:"string_format",format:"lowercase",...je(e)})}(t)),e.uppercase=t=>e.check(function(e){return new Mt({check:"string_format",format:"uppercase",...je(e)})}(t)),e.trim=()=>e.check(pn(e=>e.trim())),e.normalize=(...t)=>e.check(function(e){return pn(t=>t.normalize(e))}(...t)),e.toLowerCase=()=>e.check(pn(e=>e.toLowerCase())),e.toUpperCase=()=>e.check(pn(e=>e.toUpperCase())),e.slugify=()=>e.check(pn(e=>function(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}(e)))}),Un=le("ZodString",(e,t)=>{Kt.init(e,t),Mn.init(e,t),e.email=t=>e.check(function(e,t){return new Hn({type:"string",format:"email",check:"string_format",abort:!1,...je(t)})}(0,t)),e.url=t=>e.check(function(e,t){return new Jn({type:"string",format:"url",check:"string_format",abort:!1,...je(t)})}(0,t)),e.jwt=t=>e.check(function(e,t){return new so({type:"string",format:"jwt",check:"string_format",abort:!1,...je(t)})}(0,t)),e.emoji=t=>e.check(function(e,t){return new Kn({type:"string",format:"emoji",check:"string_format",abort:!1,...je(t)})}(0,t)),e.guid=t=>e.check(nn(Bn,t)),e.uuid=t=>e.check(function(e,t){return new Vn({type:"string",format:"uuid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.uuidv4=t=>e.check(function(e,t){return new Vn({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...je(t)})}(0,t)),e.uuidv6=t=>e.check(function(e,t){return new Vn({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...je(t)})}(0,t)),e.uuidv7=t=>e.check(function(e,t){return new Vn({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...je(t)})}(0,t)),e.nanoid=t=>e.check(function(e,t){return new Gn({type:"string",format:"nanoid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.guid=t=>e.check(nn(Bn,t)),e.cuid=t=>e.check(function(e,t){return new Yn({type:"string",format:"cuid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.cuid2=t=>e.check(function(e,t){return new Wn({type:"string",format:"cuid2",check:"string_format",abort:!1,...je(t)})}(0,t)),e.ulid=t=>e.check(function(e,t){return new Zn({type:"string",format:"ulid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.base64=t=>e.check(function(e,t){return new oo({type:"string",format:"base64",check:"string_format",abort:!1,...je(t)})}(0,t)),e.base64url=t=>e.check(function(e,t){return new ro({type:"string",format:"base64url",check:"string_format",abort:!1,...je(t)})}(0,t)),e.xid=t=>e.check(function(e,t){return new Xn({type:"string",format:"xid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.ksuid=t=>e.check(function(e,t){return new Qn({type:"string",format:"ksuid",check:"string_format",abort:!1,...je(t)})}(0,t)),e.ipv4=t=>e.check(function(e,t){return new eo({type:"string",format:"ipv4",check:"string_format",abort:!1,...je(t)})}(0,t)),e.ipv6=t=>e.check(function(e,t){return new to({type:"string",format:"ipv6",check:"string_format",abort:!1,...je(t)})}(0,t)),e.cidrv4=t=>e.check(function(e,t){return new io({type:"string",format:"cidrv4",check:"string_format",abort:!1,...je(t)})}(0,t)),e.cidrv6=t=>e.check(function(e,t){return new no({type:"string",format:"cidrv6",check:"string_format",abort:!1,...je(t)})}(0,t)),e.e164=t=>e.check(function(e,t){return new ao({type:"string",format:"e164",check:"string_format",abort:!1,...je(t)})}(0,t)),e.datetime=t=>e.check(function(e){return function(e,t){return new wn({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...je(t)})}(0,e)}(t)),e.date=t=>e.check(function(e){return function(e,t){return new kn({type:"string",format:"date",check:"string_format",...je(t)})}(0,e)}(t)),e.time=t=>e.check(function(e){return function(e,t){return new xn({type:"string",format:"time",check:"string_format",precision:null,...je(t)})}(0,e)}(t)),e.duration=t=>e.check(function(e){return function(e,t){return new Sn({type:"string",format:"duration",check:"string_format",...je(t)})}(0,e)}(t))});function Fn(e){return function(e,t){return new Un({type:"string",...je(t)})}(0,e)}const Dn=le("ZodStringFormat",(e,t)=>{Gt.init(e,t),Mn.init(e,t)}),Hn=le("ZodEmail",(e,t)=>{Zt.init(e,t),Dn.init(e,t)}),Bn=le("ZodGUID",(e,t)=>{Yt.init(e,t),Dn.init(e,t)}),Vn=le("ZodUUID",(e,t)=>{Wt.init(e,t),Dn.init(e,t)}),Jn=le("ZodURL",(e,t)=>{Xt.init(e,t),Dn.init(e,t)}),Kn=le("ZodEmoji",(e,t)=>{Qt.init(e,t),Dn.init(e,t)}),Gn=le("ZodNanoID",(e,t)=>{ei.init(e,t),Dn.init(e,t)}),Yn=le("ZodCUID",(e,t)=>{ti.init(e,t),Dn.init(e,t)}),Wn=le("ZodCUID2",(e,t)=>{ii.init(e,t),Dn.init(e,t)}),Zn=le("ZodULID",(e,t)=>{ni.init(e,t),Dn.init(e,t)}),Xn=le("ZodXID",(e,t)=>{oi.init(e,t),Dn.init(e,t)}),Qn=le("ZodKSUID",(e,t)=>{ri.init(e,t),Dn.init(e,t)}),eo=le("ZodIPv4",(e,t)=>{di.init(e,t),Dn.init(e,t)}),to=le("ZodIPv6",(e,t)=>{ui.init(e,t),Dn.init(e,t)}),io=le("ZodCIDRv4",(e,t)=>{pi.init(e,t),Dn.init(e,t)}),no=le("ZodCIDRv6",(e,t)=>{mi.init(e,t),Dn.init(e,t)}),oo=le("ZodBase64",(e,t)=>{fi.init(e,t),Dn.init(e,t)}),ro=le("ZodBase64URL",(e,t)=>{gi.init(e,t),Dn.init(e,t)}),ao=le("ZodE164",(e,t)=>{vi.init(e,t),Dn.init(e,t)}),so=le("ZodJWT",(e,t)=>{yi.init(e,t),Dn.init(e,t)}),lo=le("ZodNumber",(e,t)=>{bi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i)=>{const n=i,{minimum:o,maximum:r,format:a,multipleOf:s,exclusiveMaximum:l,exclusiveMinimum:c}=e._zod.bag;"string"==typeof a&&a.includes("int")?n.type="integer":n.type="number","number"==typeof c&&("draft-04"===t.target||"openapi-3.0"===t.target?(n.minimum=c,n.exclusiveMinimum=!0):n.exclusiveMinimum=c),"number"==typeof o&&(n.minimum=o,"number"==typeof c&&"draft-04"!==t.target&&(c>=o?delete n.minimum:delete n.exclusiveMinimum)),"number"==typeof l&&("draft-04"===t.target||"openapi-3.0"===t.target?(n.maximum=l,n.exclusiveMaximum=!0):n.exclusiveMaximum=l),"number"==typeof r&&(n.maximum=r,"number"==typeof l&&"draft-04"!==t.target&&(l<=r?delete n.maximum:delete n.exclusiveMaximum)),"number"==typeof s&&(n.multipleOf=s)})(e,t,i),e.gt=(t,i)=>e.check(an(t,i)),e.gte=(t,i)=>e.check(sn(t,i)),e.min=(t,i)=>e.check(sn(t,i)),e.lt=(t,i)=>e.check(on(t,i)),e.lte=(t,i)=>e.check(rn(t,i)),e.max=(t,i)=>e.check(rn(t,i)),e.int=t=>e.check(po(t)),e.safe=t=>e.check(po(t)),e.positive=t=>e.check(an(0,t)),e.nonnegative=t=>e.check(sn(0,t)),e.negative=t=>e.check(on(0,t)),e.nonpositive=t=>e.check(rn(0,t)),e.multipleOf=(t,i)=>e.check(ln(t,i)),e.step=(t,i)=>e.check(ln(t,i)),e.finite=()=>e;const i=e._zod.bag;e.minValue=Math.max(i.minimum??Number.NEGATIVE_INFINITY,i.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,e.maxValue=Math.min(i.maximum??Number.POSITIVE_INFINITY,i.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,e.isInt=(i.format??"").includes("int")||Number.isSafeInteger(i.multipleOf??.5),e.isFinite=!0,e.format=i.format??null});function co(e){return function(e,t){return new lo({type:"number",checks:[],...je(t)})}(0,e)}const uo=le("ZodNumberFormat",(e,t)=>{_i.init(e,t),lo.init(e,t)});function po(e){return function(e,t){return new uo({type:"number",check:"number_format",abort:!1,format:"safeint",...je(t)})}(0,e)}const mo=le("ZodBoolean",(e,t)=>{wi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>((e,t,i)=>{i.type="boolean"})(0,0,t)});function ho(e){return function(e,t){return new mo({type:"boolean",...je(t)})}(0,e)}const fo=le("ZodUnknown",(e,t)=>{ki.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>{}});function go(){return new fo({type:"unknown"})}const vo=le("ZodNever",(e,t)=>{xi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>((e,t,i)=>{i.not={}})(0,0,t)});const yo=le("ZodArray",(e,t)=>{Ei.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=i,r=e._zod.def,{minimum:a,maximum:s}=e._zod.bag;"number"==typeof a&&(o.minItems=a),"number"==typeof s&&(o.maxItems=s),o.type="array",o.items=hn(r.element,t,{...n,path:[...n.path,"items"]})})(e,t,i,n),e.element=t.element,e.min=(t,i)=>e.check(dn(t,i)),e.nonempty=t=>e.check(dn(1,t)),e.max=(t,i)=>e.check(cn(t,i)),e.length=(t,i)=>e.check(un(t,i)),e.unwrap=()=>e.element});function bo(e,t){return function(e,t,i){return new yo({type:"array",element:t,...je(i)})}(0,e,t)}const _o=le("ZodObject",(e,t)=>{Ni.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=i,r=e._zod.def;o.type="object",o.properties={};const a=r.shape;for(const e in a)o.properties[e]=hn(a[e],t,{...n,path:[...n.path,"properties",e]});const s=new Set(Object.keys(a)),l=new Set([...s].filter(e=>{const i=r.shape[e]._zod;return"input"===t.io?void 0===i.optin:void 0===i.optout}));l.size>0&&(o.required=Array.from(l)),"never"===r.catchall?._zod.def.type?o.additionalProperties=!1:r.catchall?r.catchall&&(o.additionalProperties=hn(r.catchall,t,{...n,path:[...n.path,"additionalProperties"]})):"output"===t.io&&(o.additionalProperties=!1)})(e,t,i,n),be(e,"shape",()=>t.shape),e.keyof=()=>Oo(Object.keys(e._zod.def.shape)),e.catchall=t=>e.clone({...e._zod.def,catchall:t}),e.passthrough=()=>e.clone({...e._zod.def,catchall:go()}),e.loose=()=>e.clone({...e._zod.def,catchall:go()}),e.strict=()=>{return e.clone({...e._zod.def,catchall:function(e,t){return new vo({type:"never",...je(t)})}(0,t)});var t},e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=t=>function(e,t){if(!Oe(t))throw new Error("Invalid input to extend: expected a plain object");const i=e._zod.def.checks;if(i&&i.length>0){const i=e._zod.def.shape;for(const e in t)if(void 0!==Object.getOwnPropertyDescriptor(i,e))throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}const n=we(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t};return _e(this,"shape",i),i}});return Ne(e,n)}(e,t),e.safeExtend=t=>function(e,t){if(!Oe(t))throw new Error("Invalid input to safeExtend: expected a plain object");const i=we(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t};return _e(this,"shape",i),i}});return Ne(e,i)}(e,t),e.merge=t=>function(e,t){const i=we(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t._zod.def.shape};return _e(this,"shape",i),i},get catchall(){return t._zod.def.catchall},checks:[]});return Ne(e,i)}(e,t),e.pick=t=>function(e,t){const i=e._zod.def,n=i.checks;if(n&&n.length>0)throw new Error(".pick() cannot be used on object schemas containing refinements");return Ne(e,we(e._zod.def,{get shape(){const e={};for(const n in t){if(!(n in i.shape))throw new Error(`Unrecognized key: "${n}"`);t[n]&&(e[n]=i.shape[n])}return _e(this,"shape",e),e},checks:[]}))}(e,t),e.omit=t=>function(e,t){const i=e._zod.def,n=i.checks;if(n&&n.length>0)throw new Error(".omit() cannot be used on object schemas containing refinements");const o=we(e._zod.def,{get shape(){const n={...e._zod.def.shape};for(const e in t){if(!(e in i.shape))throw new Error(`Unrecognized key: "${e}"`);t[e]&&delete n[e]}return _e(this,"shape",n),n},checks:[]});return Ne(e,o)}(e,t),e.partial=(...t)=>function(e,t,i){const n=t._zod.def.checks;if(n&&n.length>0)throw new Error(".partial() cannot be used on object schemas containing refinements");const o=we(t._zod.def,{get shape(){const n=t._zod.def.shape,o={...n};if(i)for(const t in i){if(!(t in n))throw new Error(`Unrecognized key: "${t}"`);i[t]&&(o[t]=e?new e({type:"optional",innerType:n[t]}):n[t])}else for(const t in n)o[t]=e?new e({type:"optional",innerType:n[t]}):n[t];return _e(this,"shape",o),o},checks:[]});return Ne(t,o)}(Ao,e,t[0]),e.required=(...t)=>function(e,t,i){const n=we(t._zod.def,{get shape(){const n=t._zod.def.shape,o={...n};if(i)for(const t in i){if(!(t in o))throw new Error(`Unrecognized key: "${t}"`);i[t]&&(o[t]=new e({type:"nonoptional",innerType:n[t]}))}else for(const t in n)o[t]=new e({type:"nonoptional",innerType:n[t]});return _e(this,"shape",o),o}});return Ne(t,n)}(qo,e,t[0])});function wo(e,t){const i={type:"object",shape:e??{},...je(t)};return new _o(i)}const ko=le("ZodUnion",(e,t)=>{Ci.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def,r=!1===o.inclusive,a=o.options.map((e,i)=>hn(e,t,{...n,path:[...n.path,r?"oneOf":"anyOf",i]}));r?i.oneOf=a:i.anyOf=a})(e,t,i,n),e.options=t.options});function xo(e,t){return new ko({type:"union",options:e,...je(t)})}const So=le("ZodIntersection",(e,t)=>{Ii.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def,r=hn(o.left,t,{...n,path:[...n.path,"allOf",0]}),a=hn(o.right,t,{...n,path:[...n.path,"allOf",1]}),s=e=>"allOf"in e&&1===Object.keys(e).length,l=[...s(r)?r.allOf:[r],...s(a)?a.allOf:[a]];i.allOf=l})(e,t,i,n)}),Eo=le("ZodEnum",(e,t)=>{Pi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i)=>{const n=me(e._zod.def.entries);n.every(e=>"number"==typeof e)&&(i.type="number"),n.every(e=>"string"==typeof e)&&(i.type="string"),i.enum=n})(e,0,i),e.enum=t.entries,e.options=Object.values(t.entries);const i=new Set(Object.keys(t.entries));e.extract=(e,n)=>{const o={};for(const n of e){if(!i.has(n))throw new Error(`Key ${n} not found in enum`);o[n]=t.entries[n]}return new Eo({...t,checks:[],...je(n),entries:o})},e.exclude=(e,n)=>{const o={...t.entries};for(const t of e){if(!i.has(t))throw new Error(`Key ${t} not found in enum`);delete o[t]}return new Eo({...t,checks:[],...je(n),entries:o})}});function Oo(e,t){const i=Array.isArray(e)?Object.fromEntries(e.map(e=>[e,e])):e;return new Eo({type:"enum",entries:i,...je(t)})}const To=le("ZodTransform",(e,t)=>{Li.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>((e,t)=>{if("throw"===t.unrepresentable)throw new Error("Transforms cannot be represented in JSON Schema")})(0,e),e._zod.parse=(i,n)=>{if("backward"===n.direction)throw new de(e.constructor.name);i.addIssue=n=>{if("string"==typeof n)i.issues.push(ze(n,i.value,t));else{const t=n;t.fatal&&(t.continue=!1),t.code??(t.code="custom"),t.input??(t.input=i.value),t.inst??(t.inst=e),i.issues.push(ze(t))}};const o=t.transform(i.value,i);return o instanceof Promise?o.then(e=>(i.value=e,i)):(i.value=o,i)}}),Ao=le("ZodOptional",(e,t)=>{Mi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>_n(e,t,0,n),e.unwrap=()=>e._zod.def.innerType});function $o(e){return new Ao({type:"optional",innerType:e})}const No=le("ZodExactOptional",(e,t)=>{Ui.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>_n(e,t,0,n),e.unwrap=()=>e._zod.def.innerType}),jo=le("ZodNullable",(e,t)=>{Fi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def,r=hn(o.innerType,t,n),a=t.seen.get(e);"openapi-3.0"===t.target?(a.ref=o.innerType,i.nullable=!0):i.anyOf=[r,{type:"null"}]})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType});function Co(e){return new jo({type:"nullable",innerType:e})}const Io=le("ZodDefault",(e,t)=>{Di.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType,i.default=JSON.parse(JSON.stringify(o.defaultValue))})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap}),Ro=le("ZodPrefault",(e,t)=>{Bi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType,"input"===t.io&&(i._prefault=JSON.parse(JSON.stringify(o.defaultValue)))})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType}),qo=le("ZodNonOptional",(e,t)=>{Vi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType})(e,t,0,n),e.unwrap=()=>e._zod.def.innerType}),Po=le("ZodCatch",(e,t)=>{Ki.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;let r;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType;try{r=o.catchValue(void 0)}catch{throw new Error("Dynamic catch values are not supported in JSON Schema")}i.default=r})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap}),Lo=le("ZodPipe",(e,t)=>{Gi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def,r="input"===t.io?"transform"===o.in._zod.def.type?o.out:o.in:o.out;hn(r,t,n),t.seen.get(e).ref=r})(e,t,0,n),e.in=t.in,e.out=t.out});function zo(e,t){return new Lo({type:"pipe",in:e,out:t})}const Mo=le("ZodReadonly",(e,t)=>{Wi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(t,i,n)=>((e,t,i,n)=>{const o=e._zod.def;hn(o.innerType,t,n),t.seen.get(e).ref=o.innerType,i.readOnly=!0})(e,t,i,n),e.unwrap=()=>e._zod.def.innerType}),Uo=le("ZodCustom",(e,t)=>{Xi.init(e,t),zn.init(e,t),e._zod.processJSONSchema=(e,t,i)=>((e,t)=>{if("throw"===t.unrepresentable)throw new Error("Custom types cannot be represented in JSON Schema")})(0,e)}),Fo=Oo(["none","generic_character","real_person","known_ip","realistic_animal","illustrated_human"]).optional().describe("Internal safety hint; stripped before submit."),Do=xo([Fn(),bo(Fn())]),Ho=wo({service:Oo(["banana-pro","banana-2","seedream","seedream-5-lte","gpt-image-2"]),prompt:Fn(),aspect_ratio:Oo(["1:1","3:4","4:3","16:9","9:16","3:2","2:3","21:9"]).optional(),image_size:Oo(["1K","2K"]).optional(),img_url:Do.optional(),image:Do.optional(),image_urls:bo(Fn()).optional(),size:Fn().optional(),model:Fn().optional(),vendor:Fn().optional(),nsfw_checker:ho().optional()}),Bo=Ho.omit({img_url:!0,image:!0,image_urls:!0}),Vo=Ho,Jo=wo({service:Oo(["dli2v3","dlim2v","dlai2v","dlai2v_pro","dlai2v_pro_multiframe","happyhorse-1-0-i2v","happyhorse-1-0-r2v","happyhorse-1-0-video-edit","seedance-1-5","seedance-2-0","seedance-2-0-fast","seedance-2-0-mini","kling3.0","kling-o3-ref2v","kling-o3-pro-ref2v","kling-o3-v2v","kling-o3-pro-v2v","grok-imagine-1.5","gemini-omni-video","longcat-avatar-1-5"]),prompt:Fn(),duration:co().int().optional(),aspect_ratio:Fn().optional(),image_url:Fn().optional(),last_frame_url:Fn().optional(),urls:bo(Fn()).optional(),resolution:Fn().optional(),generate_audio:ho().optional(),mode:Oo(["fun","normal","spicy"]).optional(),draft:ho().optional(),seed:co().int().optional(),keyframes:bo(go()).optional(),quality_preset:Oo(["fast","high","ultra"]).optional(),width:co().int().optional(),height:co().int().optional(),sound:ho().optional(),negative_prompt:Fn().optional(),cfg_scale:co().optional(),end_image_url:Fn().optional(),image_urls:bo(Fn()).optional(),reference_audio_url:Fn().optional(),audio_url:Fn().optional(),ref_video_url:Fn().optional(),video_url:Fn().optional(),video_start:co().optional(),video_ends:co().optional(),video_urls:bo(Fn()).optional(),ark_asset_ids:bo(Fn()).optional(),_reference_subject_type:Fo,elements:bo(go()).optional(),camera_fixed:ho().optional(),audio_setting:Oo(["auto","origin"]).optional()}),Ko=wo({service:Oo(["dlai2v","longcat-avatar","dlai2v_pro","dlai2v_pro_multiframe"]),image_url:Fn().optional(),audio_url:Fn(),prompt:Fn().optional(),quality_preset:Oo(["fast","high","ultra"]).optional(),width:co().int().optional(),height:co().int().optional(),seed:co().int().min(0).optional(),resolution:Oo(["480p","720p","1080p"]).optional(),duration:co().int().min(1).optional(),keyframes:bo(go()).optional()}),Go=wo({service:Oo(["dreamactor","kling3.0-motion"]),video_url:Fn(),image_url:Fn().optional(),image_urls:bo(Fn()).optional(),image_base64:Fn().optional(),cut_first_second:ho().optional(),character_orientation:Oo(["image","video"]).optional(),keep_original_sound:ho().optional(),tier:Oo(["pro","std"]).optional(),prompt:Fn().optional(),negative_prompt:Fn().optional(),duration:co().int().min(1).optional()}).refine(e=>1==(e.image_url?1:0)+(e.image_urls&&e.image_urls.length>0?1:0)+(e.image_base64?1:0),{message:"exactly one of image_url / image_urls / image_base64 is required",path:["image_url"]}),Yo=wo({service:Oo(["suno-v5","suno-v5_5","minimax"]),prompt:Fn(),title:Fn().optional(),tags:Fn().optional(),negative_tags:Fn().optional(),custom:ho().optional(),instrumental:ho().optional(),vocal_gender:Oo(["Male","Female"]).optional()}),Wo=wo({service:Oo(["elevenlabs-sound"]),text:Fn(),duration_seconds:co().min(.5).max(30).optional(),prompt_influence:co().min(0).max(1).optional(),loop:ho().optional(),output_format:Oo(["mp3_44100_128","mp3_44100_192","mp3_44100_96","mp3_44100_64","mp3_44100_32","mp3_22050_32"]).optional()}),Zo=wo({service:Oo(["minimax-tts","voxcpm"]),text:Fn(),audio_url:Fn().optional(),control:Fn().optional(),model:Oo(["speech-2.8-hd","speech-2.8-turbo","speech-2.6-hd","speech-2.6-turbo"]).optional(),voice_id:Fn().optional(),speed:co().min(.5).max(2).optional(),vol:co().optional(),pitch:co().int().min(-12).max(12).optional(),emotion:Oo(["happy","sad","angry","calm","whisper"]).optional(),language_boost:Fn().optional(),format:Oo(["mp3","pcm","flac","wav"]).optional(),sample_rate:co().int().refine(e=>[8e3,16e3,22050,24e3,32e3,44100].includes(e),"sample_rate must be one of: 8000, 16000, 22050, 24000, 32000, 44100").optional(),bitrate:co().int().refine(e=>[32e3,64e3,128e3,256e3].includes(e),"bitrate must be one of: 32000, 64000, 128000, 256000").optional()}),Xo=wo({audio_url:Fn().describe("Publicly readable audio URL."),transcript_text:Fn().optional().describe("Known transcript text. When set, ASR recognition is skipped and the service only timestamps this text."),language:Fn().optional().describe("Language hint such as auto, en, zh, ja, es."),word_timestamps:ho().optional().describe("Return full text, segments, and word-level timestamps in addition to srt_content."),vad_filter:ho().optional().describe("Enable stable-ts VAD during timestamp alignment."),denoise_audio:ho().optional().describe("Enable Demucs denoising / vocal separation; ASR defaults this to true."),max_segment_duration:co().min(1).max(30).optional().describe("Maximum subtitle segment duration in seconds.")}),Qo=wo({style_id:Fn().optional(),fill_color:Fn().optional(),border_color:Fn().optional(),font_id:Fn().optional(),font_weight:Oo(["normal","bold"]).optional(),shadow:wo({color:Fn().optional(),opacity:co().min(0).max(1).optional()}).optional(),position:Oo(["top","bottom"]).optional(),position_value:co().min(0).max(.5).optional(),font_size:Oo(["sm","md","lg"]).optional(),font_size_px:co().int().min(12).max(72).optional()}),er=wo({video_url:Fn(),srt_content:Fn(),caption:Qo.optional().describe("JSON object controlling caption style. font_size_px wins over font_size."),task_id:Fn().optional()}),tr=wo({audio_url:Fn(),beat_method:Fn().optional(),analysis_types:bo(Fn()).optional()}),ir=wo({video_url:Fn(),threshold:co().min(0).max(1).optional(),output_format:Oo(["boundaries","shots","full"]).optional()}),nr=wo({url:Fn(),format:Oo(["auto","video","audio"]).optional(),video_quality:Oo(["best","2160","1440","1080","720","480","360"]).optional(),audio_format:Oo(["best","mp3","ogg","wav","opus"]).optional(),filename_pattern:Fn().optional()}),or=wo({latitude:co(),longitude:co(),heading:co().min(0).max(360).optional(),pitch:co().min(-90).max(90).optional(),fov:co().min(1).max(120).optional()}),rr=wo({latitude:co(),longitude:co()}),ar=wo({address:Fn().optional(),latitude:co().optional(),longitude:co().optional()}),sr=wo({query:Fn(),latitude:co(),longitude:co(),radius:co().int().min(100).max(5e4).optional()}),lr=wo({photo_reference:Fn(),max_width:co().int().min(1).max(4800).optional()}),cr=wo({latitude:co(),longitude:co(),zoom:co().int().min(0).max(21).optional(),size:Fn().optional(),maptype:Fn().optional()}),dr={generate_image:Ho,generate_video:Jo,lipsync:Ko,motion_control:Go,generate_music:Yo,generate_sound:Wo,generate_tts:Zo,generate_tts_elevenlabs:Zo,generate_tts_dialogue:Zo,transcribe:Xo,render_caption:er,analyze_beats:tr,detect_shots:ir,download_media:nr,streetview_image:or,streetview_metadata:rr,geocode:ar,places_search:sr,place_photo:lr,static_map:cr},ur={name:"generate_image",provider:"api_layer",description:"Generate an image via api-layer. Supports: banana-2 (= nano-banana-2, Imagen4 4K, newest generation — materially faster AND higher quality than banana-pro; default first choice within the banana family), banana-pro (= nano-banana-pro, Imagen3 series up to 2K, older / slower / cheaper — use only when cost-saving is explicit), seedream (Asian aesthetic), seedream-5-lte (next-gen), gpt-image-2 (highest text-in-image fidelity and instruction-following edits; supports multi-image i2i up to 16 refs).",zodSchema:dr.generate_image,token_cost:100,artifact_slot:"generated_image",is_async:!0,timeout:300},pr={name:"generate_video",provider:"api_layer",description:"Generate a video via api-layer. Services: dli2v3 (Veo 3.1), dlim2v (Grok), dlai2v (LTX 2), dlai2v_pro (LTX 2 Pro = LTX 2.3 multi-frame workflow on RunPod; single image_url + duration auto-wrapped into keyframes[0] in api-layer router), dlai2v_pro_multiframe (LTX 2.3 真·多帧变体, 2-4 帧关键帧引导视频生成: 必须传 keyframes=[{image_url, frame_ratio?, weight?}] (2-4 帧) + audio_url; frame_ratio 0.0-1.0 表示该帧在视频中的相对时间位置(不传按数量等分 [0,1] / [0,0.5,1] / [0,0.33,0.67,1]); weight 0.0-1.0 (默认 0.4) 控制 guide 强度; aspect_ratio 16:9/9:16/1:1, resolution 强制 720p), happyhorse-1-0-i2v (Alibaba HappyHorse single first-frame i2v), happyhorse-1-0-r2v (Alibaba HappyHorse 1-9 reference images → video), happyhorse-1-0-video-edit (Alibaba HappyHorse video edit with 0-5 reference images), seedance-1-5, seedance-2-0, seedance-2-0-fast, seedance-2-0-mini (Seedance 2.0 lowest-cost 480p/720p, 5-12s), kling3.0, kling-o3-ref2v, kling-o3-pro-ref2v, kling-o3-v2v (Kling O3 Std video-edit / video-to-video: 输入视频 + prompt 编辑画面,可选 image_urls / elements 作辅助参考), kling-o3-pro-v2v (同 v2v 的 Pro 版,质量更高), gemini-omni-video, grok-imagine-1.5, longcat-avatar-1-5. Prompt placeholders: @imageN → image_urls[N-1], @audioN → reference_audio_url, @videoN → ref_video_url, @assetN → ark_asset_ids[N-1] (all 1-indexed).",zodSchema:dr.generate_video,strip_before_submit:["_reference_subject_type"],token_cost:400,artifact_slot:"generated_video",is_async:!0,timeout:300},mr={name:"lipsync",provider:"api_layer",description:"Lip-sync via api-layer. Services: dlai2v (LTX 2), longcat-avatar, dlai2v_pro (LTX 2 Pro = LTX 2.3 multi-frame workflow on RunPod), dlai2v_pro_multiframe (LTX 2.3 真·多帧变体, 2-4 帧关键帧+音频驱动: 必须传 keyframes=[{image_url, frame_ratio?, weight?}] (2-4) + audio_url; frame_ratio 0.0-1.0 时间位置, weight 默认 0.4, aspect_ratio 16:9/9:16/1:1, resolution 强制 720p). dlai2v_pro auto-wraps single image_url into keyframes[0] in api-layer router.",zodSchema:dr.lipsync,token_cost:350,artifact_slot:"lipsync_video",is_async:!0,timeout:300},hr={name:"motion_control",provider:"api_layer",description:"Transfer motion/pose from source video onto target character. Services: dreamactor, kling3.0-motion.",zodSchema:dr.motion_control,token_cost:400,artifact_slot:"motion_video",is_async:!0,timeout:300},fr={name:"generate_music",provider:"api_layer",description:"Generate music via api-layer. Services: suno-v5, suno-v5_5, minimax.",zodSchema:dr.generate_music,token_cost:300,artifact_slot:"music_candidate",is_async:!0,timeout:600},gr={name:"generate_sound",provider:"api_layer",description:"Generate a short sound effect via api-layer (ElevenLabs Sound Effects v2, 0.5–30s). For SFX / Foley / ambient / short loops — not full songs (use generate_music for that).",zodSchema:dr.generate_sound,token_cost:50,artifact_slot:"sound_effect",is_async:!0,timeout:60},vr={name:"generate_tts",provider:"api_layer",description:"Generate speech via api-layer TTS. Services: minimax-tts, voxcpm (self-hosted custom voice sample / authorized reference cloning).",zodSchema:dr.generate_tts,token_cost:80,artifact_slot:"tts_audio",is_async:!0,timeout:120},yr={...vr,name:"generate_tts_elevenlabs",zodSchema:dr.generate_tts_elevenlabs,description:"Back-compat alias for generate_tts (routed to api-layer /tts/submit)."},br={...vr,name:"generate_tts_dialogue",zodSchema:dr.generate_tts_dialogue,description:"Back-compat alias for generate_tts (routed to api-layer /tts/submit)."},_r={name:"transcribe",provider:"asr",description:"Transcribe audio to text.",zodSchema:dr.transcribe,default_params:{word_timestamps:!1},strip_before_submit:["model_size"],token_cost:50,artifact_slot:"audio_transcription",is_async:!0,timeout:30},wr={name:"render_caption",provider:"caption_render",description:"Burn SRT captions into a video and return the captioned video URL.",zodSchema:dr.render_caption,token_cost:50,artifact_slot:"captioned_video",is_async:!1,timeout:600},kr={name:"analyze_beats",provider:"audio_analyzer",description:"Analyze beat structure of an audio file.",zodSchema:dr.analyze_beats,token_cost:25,artifact_slot:"beat_analysis",is_async:!1,timeout:900},xr={name:"detect_shots",provider:"shot_analysis",description:"Detect shot boundaries using TransNetV2.",zodSchema:dr.detect_shots,token_cost:30,artifact_slot:"shot_analysis",is_async:!1,timeout:120},Sr={name:"download_media",provider:"media_downloader",description:"Download a video/audio/image from TikTok / Instagram / Twitter / Bilibili / etc. and re-upload to CDN. Returns a persistent public URL. Limits: <=500MB, 30 RPM. YouTube currently unsupported (anti-bot block).",zodSchema:dr.download_media,token_cost:30,artifact_slot:"downloaded_media",is_async:!1,timeout:120},Er={name:"streetview_image",provider:"geo",description:"Street-level image at coordinates; auto-routes provider (Google / AMap / Panoramax).",zodSchema:dr.streetview_image,token_cost:5,artifact_slot:"streetview_image",is_async:!1,timeout:30},Or={name:"streetview_metadata",provider:"geo",description:"Check street view coverage at coordinates. Returns coverage status. Low cost — call before streetview_image.",zodSchema:dr.streetview_metadata,token_cost:1,is_async:!1,timeout:10},Tr={name:"geocode",provider:"geo",description:"Forward (address→coords) or reverse (coords→address) geocoding.",zodSchema:dr.geocode,token_cost:2,is_async:!1,timeout:10},Ar={name:"places_search",provider:"geo",description:"Search places/POIs near coordinates by keyword.",zodSchema:dr.places_search,token_cost:10,is_async:!1,timeout:15},$r={name:"place_photo",provider:"geo",description:"Fetch a photo by its photo_reference returned from places_search.",zodSchema:dr.place_photo,token_cost:5,artifact_slot:"place_photo",is_async:!1,timeout:15},Nr={name:"static_map",provider:"geo",description:"Bird's-eye view map image at coordinates with optional markers.",zodSchema:dr.static_map,token_cost:3,artifact_slot:"static_map",is_async:!1,timeout:15},jr=Object.freeze({generate_image:ur,generate_video:pr,lipsync:mr,motion_control:hr,generate_music:fr,generate_sound:gr,generate_tts:vr,generate_tts_elevenlabs:yr,generate_tts_dialogue:br,transcribe:_r,render_caption:wr,analyze_beats:kr,detect_shots:xr,download_media:Sr,streetview_image:Er,streetview_metadata:Or,geocode:Tr,places_search:Ar,place_photo:$r,static_map:Nr});function Cr(e){return jr[e]}const Ir=[{flag:"--print-schema",description:"emit JSON schema for this verb's single + batch shape"},{flag:"--echo-parsed",description:"echo canonicalised input on stderr (debug)"},{flag:"--dry-run",description:"validate, quote, and render approval preview without submitting vendor work"},{flag:"--help",description:"show this help"}],Rr=[{code:"E_SCHEMA",when:"missing/invalid flag value",recovery:"run `dl <verb> --print-schema` to see the expected shape"},{code:"E_BACKEND",when:"backend returned a failure",recovery:"inspect the `data` field on stderr; usually quota / unreachable URL / asset missing"}];function qr(e){const t=[` --${e.flag.padEnd(20)} ${function(e){switch(e.kind){case"string":return"<string>";case"integer":return"<integer>";case"number":return"<number>";case"boolean":return"(boolean flag)";case"array":return e.itemKind?`<${e.itemKind}> (repeatable)`:"<value> (repeatable)";case"object":return"<see --<name>-file>";default:return"<value>"}}(e)}`];if(e.description&&t.push(` ${" ".repeat(22)} ${e.description}`),e.enum&&t.push(` ${" ".repeat(22)} one of: ${e.enum.join(", ")}`),void 0!==e.minimum||void 0!==e.maximum){const i=[void 0!==e.minimum?`>= ${e.minimum}`:"",void 0!==e.maximum?`<= ${e.maximum}`:""].filter(Boolean).join(", ");t.push(` ${" ".repeat(22)} ${i}`)}return void 0!==e.default&&t.push(` ${" ".repeat(22)} default: ${JSON.stringify(e.default)}`),e.internal&&!e.description?.toLowerCase().includes("strip")&&t.push(` ${" ".repeat(22)} (internal hint, stripped before submit)`),t}function Pr(e,t,i){if(i)return function(e,t,i){const n=t.services.find(e=>e.service===i);if(!n){const n=t.services.map(e=>e.service).join(" | ");return[`Unknown service '${i}'.`,`Known services for \`dl ${e}\`: ${n}`,`Run \`dl ${e} model -h\` for the ranking + decision logic.`].join("\n")}const o=[];o.push(`SERVICE: ${n.service}${n.label?` — ${n.label}`:""}`),n.tier&&o.push(` Tier: ${n.tier}`),n.bestFor&&o.push(` Best for: ${n.bestFor}`);const r=[];if(n.quality&&r.push(`Quality ${n.quality}`),n.speed&&r.push(`Speed ${n.speed}`),n.cost&&r.push(`Cost ${n.cost}`),r.length>0&&o.push(` ${r.join(" · ")}`),o.push(""),n.description&&n.description.length>0){o.push("DESCRIPTION");for(const e of n.description)o.push(` ${e}`);o.push("")}if(n.promptTips&&n.promptTips.length>0){o.push("PROMPT TIPS (model-specific)");for(const e of n.promptTips)o.push(` - ${e}`);o.push("")}if(n.constraints&&n.constraints.length>0){o.push("CONSTRAINTS");for(const e of n.constraints)o.push(` - ${e}`);o.push("")}if(n.flagSubset&&n.flagSubset.length>0){o.push("FLAG SUBSET (for this service — full schema via `--print-schema`)");for(const e of n.flagSubset)o.push(` --${e}`);o.push("")}if(o.push("PROMPT LANGUAGE"),o.push(" - Write the prompt in the user's original language; do NOT translate it (e.g. Chinese → English) unless the user explicitly asks or this model requires a specific language."),o.push(" - The example commands below show structure / placeholders only — not prompt language or wording. Do not copy their phrasing or language onto the user's prompt."),o.push(""),n.examples&&n.examples.length>0)for(const e of n.examples){o.push(`EXAMPLE — ${e.caption}`);for(const t of e.command.split("\n"))o.push(` ${t}`);o.push("")}for(;o.length>0&&""===o[o.length-1];)o.pop();return o.join("\n")}(e,t,i);const n=[];if(n.push("TOPIC: model — service selection & per-service call shape",""),t.rankingSummary&&t.rankingSummary.length>0){for(const e of t.rankingSummary)n.push(e);n.push("")}if(t.services.length>0){n.push("SERVICES");for(const e of t.services){const t=` ${e.service.padEnd(20)} ${e.tier??""}`.trimEnd();n.push(t),e.bestFor&&n.push(` Best for: ${e.bestFor}`);const i=[];e.quality&&i.push(`Quality ${e.quality}`),e.speed&&i.push(`Speed ${e.speed}`),e.cost&&i.push(`Cost ${e.cost}`),i.length>0&&n.push(` ${i.join(" · ")}`),n.push("")}}if(t.decisionLogic&&t.decisionLogic.length>0){n.push("DECISION LOGIC (按优先级)");const e=Math.max(...t.decisionLogic.map(e=>e.when.length));for(const i of t.decisionLogic)n.push(` ${i.when.padEnd(e)} → ${i.pick}`);n.push("")}n.push("LEARN MORE");const o=t.services.map(e=>e.service).join(" | ");for(n.push(` dl ${e} model <service> per-service flag subset + prompt tips + example`),n.push(` <service> ∈ { ${o} }`);n.length>0&&""===n[n.length-1];)n.pop();return n.join("\n")}function Lr(e,t,i=!1){const n=[];if(n.push("TOPIC: preflight — decisions you must make before the first call",""),t.intro&&n.push(t.intro,""),t.decisions.length>0&&(n.push("DECISIONS"),t.decisions.forEach((e,t)=>{n.push(` ${t+1}. ${e.name}`);for(const t of e.description.split("\n"))n.push(` ${t}`)}),n.push("")),t.notes&&t.notes.length>0){n.push("NOTES");for(const e of t.notes)n.push(` - ${e}`);n.push("")}for(i&&n.push("SEE ALSO",` dl ${e} model -h — service selection (decision #1 usually)`);n.length>0&&""===n[n.length-1];)n.pop();return n.join("\n")}function zr(e,t){const i=[];i.push("TOPIC: policy — user-facing communication rules + payment-package gate",""),t.intro&&i.push(t.intro,"");for(const e of t.rules){i.push(e.title);for(const t of e.body)i.push(` ${t}`);i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Mr(e,t){const i=[];i.push("TOPIC: composition — how upstream / sibling skills consume this verb's output",""),t.intro&&i.push(t.intro,"");for(const e of t.integrations){i.push(`WHEN CALLED FROM: ${e.skill}`);for(const t of e.rule)i.push(` ${t}`);i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Ur(e,t){const i=[];if(i.push("TOPIC: async — detach-by-default protocol + result shape",""),t.intro&&t.intro.length>0){for(const e of t.intro)i.push(e);i.push("")}if(t.resultShape&&t.resultShape.length>0){i.push("RESULT SHAPE (delivered via [async-callback])");for(const e of t.resultShape)i.push(` ${e}`);i.push("")}if(t.notes&&t.notes.length>0){i.push("NOTES");for(const e of t.notes)i.push(` - ${e}`);i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Fr(e,t){const i=[];if(i.push("TOPIC: publish — handing the result off to publish_content / downstream artifact",""),t.intro&&t.intro.length>0){for(const e of t.intro)i.push(e);i.push("")}if(t.fields&&t.fields.length>0){i.push("PUBLISH_CONTENT FIELD MAPPING");const e=Math.max(...t.fields.map(e=>e.name.length));for(const n of t.fields)i.push(` ${n.name.padEnd(e)} ${n.value}`);i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Dr(e,t){const i=[];i.push("TOPIC: examples — copy-paste-ready calls per scenario","");for(const e of t.examples){i.push(`EXAMPLE — ${e.caption}`);for(const t of e.command.split("\n"))i.push(` ${t}`);i.push("")}if(t.notExamples&&t.notExamples.length>0){i.push("NOT AN EXAMPLE (these all fail)");for(const e of t.notExamples){i.push(` # ❌ ${e.whyItFails}`);for(const t of e.command.split("\n"))i.push(` ${t}`);i.push("")}}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Hr(e,t){const i=[];i.push("TOPIC: errors — failure codes + recovery breadcrumbs","");const n=t.errors??Rr;if(n.length>0){i.push("CODES");for(const e of n)i.push(` ${e.code}`),i.push(` when: ${e.when}`),e.recovery&&i.push(` recovery: ${e.recovery}`),i.push("")}for(;i.length>0&&""===i[i.length-1];)i.pop();return i.join("\n")}function Br(e,t){const i=function(){const e=function(e){if(!e)return null;try{const t=JSON.parse(e);return"object"!=typeof t||null===t||Array.isArray(t)?null:t}catch{return null}}(process.env.PI_AGENT_CONTEXT),t={};return Vr(t,"user_id",e?.user_id??process.env.PI_USER_ID),Vr(t,"prompt_id",e?.prompt_id??process.env.PI_PROMPT_ID),Vr(t,"tool_call_id",e?.tool_call_id??process.env.PI_TOOL_CALL_ID),Vr(t,"sub_agent_id",e?.sub_agent_id??process.env.PI_SUB_AGENT_ID),Vr(t,"user_unique_name",e?.user_unique_name??process.env.PI_USER_UNIQUE_NAME),Vr(t,"user_tier",e?.user_tier??process.env.PI_USER_TIER),t}();return{quote:e,trace:{project_id:t.projectId,job_ref:t.jobRef,command:e.command,action:e.action,mode:t.mode,...void 0!==t.batchIndex?{batch_index:t.batchIndex}:{},...t.jobKey?{job_key:t.jobKey}:{},...i}}}function Vr(e,t,i){if("string"!=typeof i)return;const n=i.trim();n&&(e[t]=n)}class Jr extends Error{hint;constructor(e,t){super(e),this.hint=t,this.name="ProxyClientError"}}class Kr extends Error{hint;constructor(e,t){super(e),this.hint=t,this.name="ByoaOauthError"}}function Gr(e){return e.toString("base64url")}function Yr(e){return e.replace(/\/+$/,"")}async function Wr(e,t,i){const n=await i(e,{method:"POST",headers:{"content-type":"application/x-www-form-urlencoded"},body:new URLSearchParams(t).toString()}),o=await n.text();if(!n.ok)throw new Kr(`token endpoint returned ${n.status}: ${o.slice(0,300)}`,"the OAuth client may be misconfigured — check --client-id / --issuer");const r=JSON.parse(o);if("object"!=typeof r||null===r||"string"!=typeof r.access_token)throw new Kr("token endpoint returned a malformed response (no access_token)");return r}const Zr="ai.ilands.cli",Xr="byoa";function Qr(e=process.env){const t=(e.ILANDS_CONFIG_DIR??"").trim();if(t)return t;if("win32"===process.platform){const t=(e.APPDATA??"").trim();if(t)return l(t,"ilands")}const i=(e.HOME??"").trim()||E();return l(i,".ilands")}function ea(e=process.env){return l(Qr(e),"credentials")}function ta(e){try{return v("win32"===process.platform?"where":"which",[e],{stdio:"ignore"}),!0}catch{return!1}}function ia(e){return"file"===(e.ILANDS_CRED_STORE??"").trim()?"file":"darwin"===process.platform?"keychain":"linux"===process.platform&&ta("secret-tool")?"secret-tool":"file"}function na(e){try{const t=JSON.parse(e);if("object"!=typeof t||null===t)return null;const i=t;return 1!==i.version||"string"!=typeof i.issuer||"string"!=typeof i.client_id||"string"!=typeof i.access_token||"number"!=typeof i.expires_at||"object"!=typeof i.user||null===i.user?null:t}catch{return null}}function oa(e){const t=ea(e);if(!o(t))return null;try{return na(r(t,"utf-8"))}catch{return null}}function ra(){try{return na(v("security",["find-generic-password","-s",Zr,"-a",Xr,"-w"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim())}catch{return null}}function aa(){try{v("security",["delete-generic-password","-s",Zr,"-a",Xr],{stdio:"ignore"})}catch{}}function sa(){try{return na(v("secret-tool",["lookup","service",Zr,"account",Xr],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim())}catch{return null}}function la(){try{v("secret-tool",["clear","service",Zr,"account",Xr],{stdio:"ignore"})}catch{}}function ca(e=process.env){switch(ia(e)){case"keychain":return ra()??oa(e);case"secret-tool":return sa()??oa(e);default:return oa(e)}}function da(e,t){return null!==e&&e.access_token===t.access_token&&e.user.id===t.user.id}function ua(e,o=process.env){switch(ia(o)){case"keychain":if(function(e){try{return aa(),v("security",["add-generic-password","-s",Zr,"-a",Xr,"-w",JSON.stringify(e)],{stdio:"ignore"}),!0}catch{return!1}}(e)&&da(ra(),e))return"keychain";aa();break;case"secret-tool":if(function(e){try{return v("secret-tool",["store","--label","ilands CLI","service",Zr,"account",Xr],{input:JSON.stringify(e),stdio:["pipe","ignore","ignore"]}),!0}catch{return!1}}(e)&&da(sa(),e))return"secret-tool";la()}return function(e,o){const r=Qr(e);t(r,{recursive:!0,mode:448});const a=ea(e);i(a,`${JSON.stringify(o,null,2)}\n`,{mode:384});try{n(a,384)}catch{}}(o,e),"file"}const pa="https://ilands-edge-router-staging.bitter-fog-5f6d.workers.dev",ma="byoa";function ha(e=process.env){return fa((e.ILANDS_BYOA_CALLBACK_BASE_URL??"").trim()||"https://callback-server-z4umynwjcq-an.a.run.app")}function fa(e){return e.replace(/\/+$/,"")}function ga(){return Math.floor(Date.now()/1e3)}function va(e,t){const i=(t.ILANDS_GATEWAY_URL??"").trim();return fa(e?.gateway_url||i||pa)}function ya(e=process.env){const t=[],i=!!(e.CALLBACK_SERVER_URL??"").trim()&&!!(e.DL_PROXY_TOKEN??"").trim(),n=!!(e.ILANDS_SANDBOX_RPC_URL??"").trim()&&!!(e.ILANDS_SANDBOX_TOKEN??"").trim();return i&&t.push("dl"),n&&t.push("ilands"),{sandbox:t.length>0,flavors:t}}async function ba(e=process.env,t=fetch){const i=(e.CALLBACK_SERVER_URL??"").trim(),n=(e.DL_PROXY_TOKEN??"").trim();if(i&&n)return{mode:"sandbox",baseUrl:`${fa(i)}/sandbox-rpc/dl`,token:n,projectId:(e.PI_PROJECT_ID??"").trim()};if(i||n)throw new Jr((i?"DL_PROXY_TOKEN":"CALLBACK_SERVER_URL")+" not set in sandbox env","this dl binary is the sandbox flavor; it only works when hono-pi-e2b injects DL_PROXY_TOKEN + CALLBACK_SERVER_URL via commands.run envs.");const o=await async function(e=process.env,t=fetch){const i=ca(e);if(!i)return null;if(i.expires_at-ga()>30)return i;if(!i.refresh_token)throw new Jr("byoa access token expired and no refresh token is stored","run `ilands login` (or `dl login`) again");let n;try{n=await async function(e){return Wr(`${Yr(e.issuer)}/oauth/token`,{grant_type:"refresh_token",refresh_token:e.refreshToken,client_id:e.clientId},e.fetchImpl??fetch)}({issuer:i.issuer,clientId:i.client_id,refreshToken:i.refresh_token,fetchImpl:t})}catch(e){const t=e instanceof Error?e.message:String(e);throw new Jr(`byoa token refresh failed: ${t}`,"run `ilands login` (or `dl login`) again")}const o={...i,access_token:n.access_token,...n.refresh_token?{refresh_token:n.refresh_token}:{},expires_at:ga()+(n.expires_in??3600)};return ua(o,e),o}(e,t);if(o)return{mode:"byoa",baseUrl:`${va(o,e)}/byoa/dl`,token:o.access_token,projectId:"byoa"};throw new Jr("no dl credentials: neither sandbox env nor a byoa login was found","run `ilands login` (or `dl login`) to use dl with your ilands account; sandbox mode needs CALLBACK_SERVER_URL + DL_PROXY_TOKEN.")}function _a(e){switch(e){case"E_BACKEND":case"E_INSUFFICIENT_CREDITS":case"E_COMMAND_NOT_OFFERED":case"E_NO_PERMISSION":return 1;default:return 2}}class wa extends Error{code;hint;extra;constructor(e,t,i,n){super(t),this.code=e,this.hint=i,this.extra=n}}function ka(e,t){if(e===t)return 0;if(!e.length)return t.length;if(!t.length)return e.length;const i=e.length,n=t.length;let o=Array(n+1).fill(0).map((e,t)=>t),r=Array(n+1).fill(0);for(let a=1;a<=i;a++){r[0]=a;for(let i=1;i<=n;i++){const n=e.charCodeAt(a-1)===t.charCodeAt(i-1)?0:1;r[i]=Math.min(r[i-1]+1,o[i]+1,o[i-1]+n)}[o,r]=[r,o]}return o[n]}function xa(e,t){if(!t.length)return;let i=t[0],n=ka(e,i);for(let o=1;o<t.length;o++){const r=ka(e,t[o]);r<n&&(n=r,i=t[o])}return n<=Math.max(3,Math.floor(e.length/3))?i:void 0}class Sa extends Error{status;bodyText;url;constructor(e,t,i,n){super(e),this.status=t,this.bodyText=i,this.url=n}}async function Ea(e,t={}){const i=t.method??"GET",n={"content-type":"application/json",...t.headers??{}},o=void 0===t.body?void 0:"string"==typeof t.body?t.body:JSON.stringify(t.body),r=t.timeoutMs??3e4,a=(t.retries??0)+1;let s=null;for(let t=1;t<=a;t++){const l=new AbortController,c=setTimeout(()=>l.abort(),r);try{const r=await fetch(e,{method:i,headers:n,body:o,signal:l.signal}),c=await r.text();if(!r.ok){if(402===r.status){const e=Ta(c);if(e)throw new wa("E_INSUFFICIENT_CREDITS",e.message,"充值后重试;本次请求没有提交到上游供应商。",{billing_error:"INSUFFICIENT_CREDITS",...void 0!==e.balance?{balance:e.balance}:{},...void 0!==e.required?{required:e.required}:{}})}if(403===r.status){const e=Aa(c);if(e)throw new wa("command_not_offered"===e.reason?"E_COMMAND_NOT_OFFERED":"E_NO_PERMISSION",e.message,e.hint,{reason:e.reason})}if(r.status>=500&&t<a){s=new Sa(`http ${r.status}`,r.status,c,e);continue}throw new Sa(`http ${r.status}: ${Oa(c,500)}`,r.status,c,e)}if(0===c.length)return;try{return JSON.parse(c)}catch{return c}}catch(e){if(e instanceof Sa)throw e;if(s=e,t>=a)break}finally{clearTimeout(c)}}throw s instanceof Error?s:new Error(String(s))}function Oa(e,t){return e.length>t?`${e.slice(0,t)}…`:e}function Ta(e){const t=$a(e);if(!t)return null;const i="detail"in t?t.detail:t,n=Na(i)?i:t,o=Ca(n,"code"),r=Ca(n,"error");if("E_INSUFFICIENT_CREDITS"!==o&&"INSUFFICIENT_CREDITS"!==r&&(void 0===n.balance||void 0===n.required))return null;const a=ja(n,"balance"),s=ja(n,"required"),l=Ca(n,"message")??("string"==typeof i&&""!==i.trim()?i.trim():function(e,t){return void 0!==e&&void 0!==t?`余额不足: 当前 ${e} credits, 需 ${t}。请充值后重试。`:"余额不足。请充值后重试。"}(a,s));return{message:l,...void 0!==a?{balance:a}:{},...void 0!==s?{required:s}:{}}}function Aa(e){const t=$a(e);if(!t)return null;const i=Na(t.error)?t.error:t,n=Ca(i,"reason")??Ca(i,"code");return"command_not_offered"!==n&&"no_permission"!==n?null:{reason:n,message:Ca(i,"message")??("command_not_offered"===n?"this command is not offered in byoa (login) mode":"your account's role does not allow this command"),hint:Ca(i,"hint")}}function $a(e){if(""===e.trim())return null;try{const t=JSON.parse(e);return Na(t)?t:null}catch{return null}}function Na(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function ja(e,t){const i=e[t];return"number"==typeof i&&Number.isFinite(i)?i:void 0}function Ca(e,t){const i=e[t];return"string"==typeof i&&""!==i.trim()?i.trim():void 0}const Ia="X-DL-Billing";function Ra(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function qa(e,t,i){const n=Ra(i);n&&(e[t]=n)}function Pa(e){const t={},i=Ra(process.env.TRACEPARENT),n=Ra(process.env.TRACESTATE);return qa(t,"traceparent",i),qa(t,"x-pi-traceparent",i),qa(t,"tracestate",n),qa(t,"x-pi-tracestate",n),qa(t,"x-dl-command","dl"),qa(t,"x-dl-subcommand",e.billing?.quote.command??function(){for(const e of process.argv.slice(2)){const t=Ra(e);if(t&&!t.startsWith("-"))return t}}()),qa(t,"x-dl-action",e.billing?.quote.action),qa(t,"x-dl-event",e.billing?.quote.event),qa(t,"x-dl-service",function(e){if("object"==typeof e&&null!==e&&!Array.isArray(e))return Ra(e.service)}(e.body)??function(e){const t=e?.details.service;return Ra(t)}(e.billing?.quote)??e.prefix),qa(t,"x-dl-job-ref",e.billing?.jobRef),t}function La(e,t){if(!t)throw new Jr("PI_PROJECT_ID not set in sandbox env","this dl binary is the sandbox flavor; it only works when hono-pi-e2b injects DL_PROXY_TOKEN + CALLBACK_SERVER_URL via commands.run envs.");return{_dl_billing:Br(e.quote,{projectId:t,jobRef:e.jobRef,mode:e.trace?.mode??"single",...void 0!==e.trace?.batchIndex?{batchIndex:e.trace.batchIndex}:{},...e.trace?.jobKey?{jobKey:e.trace.jobKey}:{}})}}function za(e,t){if(!e.billing)return{};const i=Buffer.from(JSON.stringify(La(e.billing,t)),"utf-8").toString("base64url");return{[Ia]:i}}async function Ma(e){const t=await ba(),i=await Ea(`${t.baseUrl}/billing/charge`,{method:"POST",headers:{Authorization:`Bearer ${t.token}`,...Pa({billing:e})},body:La(e,t.projectId),timeoutMs:1e4,retries:0});if(!i.receipt)throw new Jr("gateway returned malformed dl billing charge response");return i.receipt}async function Ua(e){const t=await ba();await Ea(`${t.baseUrl}/billing/refund`,{method:"POST",headers:{Authorization:`Bearer ${t.token}`,...Pa({billing:e})},body:{...La(e,t.projectId),reason:e.reason,...e.chargeId?{charge_id:e.chargeId}:{}},timeoutMs:1e4,retries:0})}function Fa(e,t,i){const n=i.replace(/^\/+/,"").replace(/\/+$/,"");return n?`${e.baseUrl}/${t}/${n}`:`${e.baseUrl}/${t}`}async function Da(e,t,i,n={}){const o=await ba();return Ea(Fa(o,e,t),{method:n.method??"POST",headers:{Authorization:`Bearer ${o.token}`,...n.headers??{},...Pa({billing:n.billing,body:i,prefix:e}),...za(n,o.projectId)},body:i,timeoutMs:n.timeoutMs??3e4,retries:n.retries??0})}async function Ha(e,t,i,n={}){const o=await ba(),r=Object.entries(i).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).join("&"),a=Fa(o,e,t);return Ea(r?`${a}?${r}`:a,{method:"GET",headers:{Authorization:`Bearer ${o.token}`,...n.headers??{},...Pa({billing:n.billing,prefix:e}),...za(n,o.projectId)},timeoutMs:n.timeoutMs??3e4,retries:n.retries??0})}class Ba extends Error{action;errors;constructor(e,t,i){super(e),this.action=t,this.errors=i,this.name="ActionValidationError"}}const Va={generate_music:{path:"/api/agent/music/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_video:{path:"/api/agent/video/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_image:{path:"/api/agent/image/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_sound:{path:"/api/agent/sound/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_tts:{path:"/api/agent/tts/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_tts_elevenlabs:{path:"/api/agent/tts/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},generate_tts_dialogue:{path:"/api/agent/tts/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},lipsync:{path:"/api/agent/video/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},motion_control:{path:"/api/agent/video/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},detect_shots:{path:"/api/v1/shot-analysis/analyze",baseEnv:"SHOT_ANALYSIS_BASE_URL",auth:"x-api-key",authEnv:"SHOT_ANALYSIS_API_KEY"},transcribe:{path:"/api/agent/asr/submit",baseEnv:"API_LAYER_BASE_URL",auth:"bearer",authEnv:"API_LAYER_API_KEY"},render_caption:{path:"/api/v1/caption/render",baseEnv:"CAPTION_RENDER_BASE_URL",auth:"x-api-key",authEnv:"CAPTION_RENDER_API_KEY"},analyze_beats:{path:"/analyze",baseEnv:"AUDIO_ANALYZER_BASE_URL",auth:"x-api-key",authEnv:"AUDIO_ANALYZER_API_KEY"},download_media:{path:"/api/v1/media-download/download",baseEnv:"MEDIA_DOWNLOAD_BASE_URL",auth:"x-api-key",authEnv:"MEDIA_DOWNLOAD_API_KEY"},streetview_image:{path:"/api/v1/streetview/image",gatewayPrefix:"geo",auth:"x-api-key"},streetview_metadata:{path:"/api/v1/streetview/metadata",gatewayPrefix:"geo",auth:"x-api-key"},geocode:{path:"/api/v1/geocode",gatewayPrefix:"geo",auth:"x-api-key"},places_search:{path:"/api/v1/places/search",gatewayPrefix:"geo",auth:"x-api-key"},place_photo:{path:"/api/v1/places/photo",gatewayPrefix:"geo",auth:"x-api-key"},static_map:{path:"/api/v1/maps/static",gatewayPrefix:"geo",auth:"x-api-key"}};function Ja(e){const t=Va[e];if(!t)throw new Error(`unknown action: ${e}`);return t}function Ka(e){const t=Va[e];return void 0!==t&&"x-api-key"===t.auth}const Ga={ASR_BASE_URL:"asr",AUDIO_ANALYZER_BASE_URL:"audio-analyzer",CAPTION_RENDER_BASE_URL:"caption-render",SHOT_ANALYSIS_BASE_URL:"shot-analysis",MEDIA_DOWNLOAD_BASE_URL:"media-download"};function Ya(e){const t=(process.env.PI_PROJECT_ID??"").trim();if(t)return t;throw new Jr("callback"===e?"PI_PROJECT_ID not set — required for callback URL routing under callback-resume v2":"PI_PROJECT_ID not set — required for dl billing trace","hono-pi-e2b injects PI_PROJECT_ID on every commands.run; set it manually in LOCAL_SANDBOX dev")}function Wa(e,t,i){return t.billing?{...e,_dl_billing:Br(t.billing,{projectId:i.projectId,jobRef:i.jobRef,mode:t.billingTrace?.mode??"single",...void 0!==t.billingTrace?.batchIndex?{batchIndex:t.billingTrace.batchIndex}:{},...t.billingTrace?.jobKey?{jobKey:t.billingTrace.jobKey}:{}})}:e}async function Za(e,t,i,n={}){const o=Ja(e);!function(e,t){const i=Cr(e);if(!i)return;const n=i.zodSchema.safeParse(t);if(!n.success){const t=n.error.issues,i=t.map(e=>`${e.path.join(".")||"<root>"} ${e.message}`.trim()).join("; ");throw new Ba(`params invalid for ${e}: ${i}`,e,t)}}(e,t);const r=Cr(e),a=r?function(e,t){if(!e.strip_before_submit||0===e.strip_before_submit.length)return t;const i={...t};for(const t of e.strip_before_submit)delete i[t];return i}(r,function(e,t){const i={...t};for(const[t,n]of Object.entries(e.default_params??{}))void 0===i[t]&&(i[t]=n);return i}(r,t)):t,{prefix:s,tail:l}=function(e){const t=Ja(e),i=t.path.replace(/^\/+/,"");if("bearer"===t.auth)return{prefix:"media/submit",tail:i};if(t.gatewayPrefix)return{prefix:t.gatewayPrefix,tail:i};const n=t.baseEnv?Ga[t.baseEnv]:void 0;if(!n)throw new Error(`no sandbox-rpc prefix for ${e} (baseEnv=${t.baseEnv??"unset"})`);return{prefix:n,tail:i}}(e),c=(process.env.CALLBACK_SERVER_URL??"").replace(/\/+$/,""),d=!!c,u=d?c:ha(process.env),p="bearer"===o.auth?(()=>{const e=d?Ya("callback"):ma,{service:t,...o}=a;return Wa({service:t,callback_url:`${u}/callback/${encodeURIComponent(e)}/${i}`,params:o},n,{projectId:e,jobRef:i})})():Wa(a,n,{projectId:n.billing?d?Ya("billing"):ma:"",jobRef:i}),m=1e3*(r?.timeout??120);return{...await Da(s,l,p,{timeoutMs:"bearer"===o.auth?Math.max(m,12e4):m,retries:1}),job_ref:i}}function Xa(e){return e.replace(/^_+/,"").replace(/_/g,"-")}function Qa(e){return e.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function es(e){return e._def??{}}function ts(e){return es(e).type}function is(e){let t,i=e,n=!0,o=0;for(;o++<16;){const e=es(i),o=e.type;if("optional"!==o&&"nullable"!==o){if("default"!==o)break;if(n=!1,t="function"==typeof e.defaultValue?e.defaultValue():e.defaultValue,!e.innerType)break;i=e.innerType}else{if(n=!1,!e.innerType)break;i=e.innerType}}return{inner:i,required:n,default:t}}function ns(e){return e.def??e._zod?.def}function os(e){const t=es(e).checks;if(!t)return!1;for(const e of t){const t=ns(e);if("number_format"===t?.check&&"safeint"===t.format)return!0}return!1}function rs(e,t){const i=e.startsWith("_"),n=Xa(e),{inner:o,required:r,default:a}=is(t),s=ts(o),l={flag:n,jsonName:e,kind:"string",required:r,internal:i,default:a,description:t.description};switch(s){case"string":return l;case"number":{const{minimum:e,maximum:t}=function(e){const t=es(e).checks;if(!t)return{};const i={};for(const e of t){const t=ns(e);t&&("greater_than"===t.check&&"number"==typeof t.value&&(i.minimum=t.value),"less_than"===t.check&&"number"==typeof t.value&&(i.maximum=t.value))}return i}(o);return{...l,kind:os(o)?"integer":"number",minimum:e,maximum:t}}case"boolean":return{...l,kind:"boolean"};case"enum":{const e=es(o).entries??{},t=Object.keys(e);return{...l,enum:t}}case"literal":{const e=es(o),t=e.values?.[0]??e.value;return{...l,enum:[String(t)]}}case"array":{const e=es(o).element;return{...l,kind:"array",itemKind:as(e)}}case"union":{const e=es(o).options??[],t=e.some(e=>function(e){return"string"===e||"number"===e||"boolean"===e}(ts(is(e).inner))),i=e.find(e=>"array"===ts(is(e).inner));if(t&&i){const e=es(is(i).inner).element;return{...l,kind:"array",itemKind:as(e),scalarOrArray:!0}}return{...l,kind:"object"}}default:return{...l,kind:"object"}}}function as(e){if(!e)return;const t=ts(is(e).inner);return"string"===t?"string":"number"===t?os(is(e).inner)?"integer":"number":"boolean"===t?"boolean":void 0}function ss(e,t){switch(e.kind){case"integer":{const e=Number(t);return Number.isFinite(e)?Math.trunc(e):t}case"number":{const e=Number(t);return Number.isFinite(e)?e:t}case"boolean":return Boolean(t);case"array":{const i=(Array.isArray(t)?t:[t]).map(t=>function(e,t){if("integer"===e){const e=Number(t);return Number.isFinite(e)?Math.trunc(e):t}if("number"===e){const e=Number(t);return Number.isFinite(e)?e:t}return"boolean"===e?Boolean(t):t}(e.itemKind,t));return e.scalarOrArray&&1===i.length?i[0]:i}default:if("object"===e.kind&&"string"==typeof t)try{return JSON.parse(t)}catch{return t}return t}}async function ls(e,t){if("-"===e)try{const e=await async function(){if(process.stdin.isTTY)throw new wa("E_FILE_MISSING","`--*-file=-` requested stdin but stdin is a TTY (nothing piped in)","pipe a file via stdin, e.g. `cat params.json | dl ... --params-file=-`, or pass a file path",{stdin_is_tty:!0});const e=[];for await(const t of process.stdin)e.push("string"==typeof t?Buffer.from(t):t);return Buffer.concat(e).toString("utf8")}();if(0===e.length)throw new wa("E_FILE_MISSING",`${t}=- received empty stdin`,`pipe non-empty content into \`${t}=-\`, or pass a file path`,{source:"<stdin>"});return{label:"<stdin>",raw:e}}catch(e){if(e instanceof wa)throw e;const i=e instanceof Error?e.message:String(e);throw new wa("E_FILE_MISSING",`failed to read stdin for ${t}: ${i}`,void 0,{source:"<stdin>"})}const i=c(e);try{return{label:i,raw:await O(i,"utf8")}}catch(n){const o=n instanceof Error?n.message:String(n);throw new wa("E_FILE_MISSING",`${t}: cannot read file at ${i} (${o})`,`check the path is reachable from cwd; cwd=${process.cwd()}; if the file is meant to be on stdin pass \`${t}=-\``,{flag:t,given:e,resolved:i,cwd:process.cwd()})}}function cs(e,t){try{return JSON.parse(e.raw)}catch(i){const n=i instanceof Error?i.message:String(i),o=/position (\d+)/.exec(n),r=o?Number(o[1]):-1,a=r>=0?function(e,t){const i=e.slice(0,Math.max(0,t)),n=e.split("\n"),o=i.split("\n").length-1,r=t-(i.lastIndexOf("\n")+1),a=Math.max(0,o-1),s=Math.min(n.length,o+2),l=n.slice(a,s).map((e,t)=>`${a+t===o?">":" "} ${(a+t+1).toString().padStart(3," ")}: ${e}`).join("\n");return{line:o+1,column:r+1,snippet:l}}(e.raw,r):void 0;throw new wa("E_FILE_PARSE",`${t} (${e.label}): JSON parse failed (${n})`,"check for missing/extra commas, unbalanced braces, or single quotes — JSON requires double quotes",{flag:t,source:e.label,...a?{line:a.line,column:a.column,snippet:a.snippet}:{}})}}async function ds(e,t){const i=await ls(e,t),n=cs(i,t);if(!Array.isArray(n))throw new wa("E_SCHEMA",`${t} (${i.label}): expected JSON array, got ${fs(n)}`,'rewrite the file to start with `[`. Example: [{"job_key":"a","params":{}}]',{flag:t,source:i.label,got:fs(n),expected:"JSON array"});return{source:i,data:n}}function us(e,t){const i={label:"inline",raw:e},n=cs(i,t);if(!Array.isArray(n))throw new wa("E_SCHEMA",`${t}: expected JSON array, got ${fs(n)}`,`pass an inline JSON array. Example: ${t} '[{"job_key":"a","params":{}}]'`,{flag:t,got:fs(n),expected:"JSON array"});return{source:i,data:n}}function ps(e){throw new wa("E_SCHEMA",`${e.inline} and ${e.file} are mutually exclusive`,`prefer ${e.inline} (inline); file/stdin content is invisible to the billing extension / dl adapter`,{inline_flag:e.inline,file_flag:e.file})}async function ms(e,t,i){const n="string"==typeof e&&""!==e,o="string"==typeof t&&""!==t;return n&&o&&ps(i),n?function(e,t){const i={label:"inline",raw:e},n=cs(i,t);if(null===n||"object"!=typeof n||Array.isArray(n))throw new wa("E_SCHEMA",`${t}: expected JSON object, got ${fs(n)}`,`pass an inline JSON object. Example: ${t} '{"key":"value"}'`,{flag:t,got:fs(n),expected:"JSON object"});return{source:i,data:n}}(e,i.inline):o?async function(e,t){const i=await ls(e,t),n=cs(i,t);if(null===n||"object"!=typeof n||Array.isArray(n))throw new wa("E_SCHEMA",`${t} (${i.label}): expected JSON object, got ${fs(n)}`,'rewrite the file to start with `{`. Example: {"key":"value"}',{flag:t,source:i.label,got:fs(n),expected:"JSON object"});return{source:i,data:n}}(t,i.file):void 0}async function hs(e,t,i){const n="string"==typeof e&&""!==e,o="string"==typeof t&&""!==t;if(n&&o&&ps(i),n){if(""===e.trim())throw new wa("E_SCHEMA",`${i.inline}: expected non-empty text, got empty input`,`pass the text content as an inline string to ${i.inline}`,{flag:i.inline,expected:"non-empty text"});return{label:"inline",raw:e}}if(o)return async function(e,t){const i=await ls(e,t);if(""===i.raw.trim())throw new wa("E_SCHEMA",`${t} (${i.label}): expected non-empty text, got empty input`,`pipe or write the long-text content into ${t}; an empty file is never a valid value`,{flag:t,source:i.label,expected:"non-empty text"});return i}(t,i.file)}function fs(e){if(null===e)return"null";if(Array.isArray(e))return"array";const t=typeof e;return"object"===t?"object":t}function gs(e){process.stdout.write(`${JSON.stringify(e)}\n`),process.exit(0)}function vs(e,t,i){const n={ok:!1,code:"E_BACKEND",error:e,message:e,...t?{hint:t}:{},...i??{}};process.stderr.write(`${JSON.stringify(n)}\n`),process.exit(1)}function ys(e,t,i,n){const o={ok:!1,code:e,error:t,message:t,...i?{hint:i}:{},...n??{}};process.stderr.write(`${JSON.stringify(o)}\n`),process.exit(_a(e))}function bs(e){ys(e.code,e.message,e.hint,e.extra)}function _s(e,t){if("1"!==process.env.DL_ECHO_PARSED)return;const i=JSON.stringify({echo:"parsed",...e});process.stderr.write(`${i}\n`)}function ws(e){const t=JSON.stringify({event:"submitted",...e});process.stderr.write(`${t}\n`)}class ks extends Error{constructor(e){super(e),this.name="JsonPointerError"}}const xs="@file:";function Ss(e){return"string"==typeof e&&e.startsWith(xs)}function Es(e,t){if(!e.startsWith(xs))throw new wa("E_SCHEMA",`不是 @file: 语法:${e}`,"正确格式:@file:/abs/path.json#/json/pointer",{flag:t.flag});const i=e.slice(6),n=i.indexOf("#");if(n<0)throw new wa("E_SCHEMA",`${t.flag} 缺少 JSON Pointer(# 之后的部分):${e}`,"@file: 必须带 #/some/pointer 才能定位到具体字段,避免误读入整个文件",{flag:t.flag});const o=i.slice(0,n),a=i.slice(n+1);if(!o)throw new wa("E_SCHEMA",`${t.flag} 路径为空:${e}`,void 0,{flag:t.flag});if(!d(o))throw new wa("E_SCHEMA",`${t.flag} 路径必须是绝对路径:${o}`,"避免 cwd 歧义。可在 shell 里用 $PWD/相对路径 转成绝对路径",{flag:t.flag});let s,l,c;try{s=r(o,"utf8")}catch(e){const i=e instanceof Error?e.message:String(e);throw new wa("E_FILE_MISSING",`${t.flag} 读取文件失败:${o}(${i})`,void 0,{flag:t.flag,path:o})}try{l=JSON.parse(s)}catch(e){const i=e instanceof Error?e.message:String(e);throw new wa("E_FILE_PARSE",`${t.flag} 不是合法 JSON:${o}(${i})`,void 0,{flag:t.flag,path:o})}try{c=function(e,t){const i=function(e){if(""===e)return[];if(!e.startsWith("/"))throw new ks(`JSON Pointer 必须以 "/" 开头(或为空字符串表示根节点):${e}`);return e.slice(1).split("/").map(e=>e.replace(/~1/g,"/").replace(/~0/g,"~"))}(t);let n=e;const o=[];for(const e of i){if(o.push(e),null==n)throw new ks(`JSON Pointer 无法定位:/${o.join("/")}(中途遇到 ${null===n?"null":"undefined"})`);if(Array.isArray(n)){if(!/^\d+$/.test(e))throw new ks(`JSON Pointer 数组段必须是非负整数:/${o.join("/")}(实际:${JSON.stringify(e)})`);const t=Number(e);if(t>=n.length)throw new ks(`JSON Pointer 数组越界:/${o.join("/")}(长度 ${n.length})`);n=n[t];continue}if("object"==typeof n){const t=n;if(!Object.hasOwn(t,e))throw new ks(`JSON Pointer 字段不存在:/${o.join("/")}`);n=t[e];continue}throw new ks(`JSON Pointer 无法在标量上继续下钻:/${o.join("/")}(当前类型 ${typeof n})`)}return n}(l,a.startsWith("/")?a:`/${a}`)}catch(e){if(e instanceof ks)throw new wa("E_SCHEMA",`${t.flag} ${e.message}`,void 0,{flag:t.flag,path:o,pointer:a});throw e}if(t.requireString&&"string"!=typeof c)throw new wa("E_SCHEMA",`${t.flag} JSON Pointer 命中的值不是字符串:${a}(实际类型:${Array.isArray(c)?"array":typeof c})`,void 0,{flag:t.flag,path:o,pointer:a});return c}function Os(e,t){if(!e.startsWith(xs))throw new wa("E_SCHEMA",`不是 @file: 语法:${e}`,"正确格式:@file:/abs/path.txt",{flag:t.flag});const i=e.slice(6);if(i.indexOf("#")>=0){const i=Es(e,{flag:t.flag,requireString:!0});if("string"==typeof i)return i;throw new wa("E_SCHEMA",`${t.flag} JSON Pointer 命中的值不是字符串`,void 0,{flag:t.flag})}const n=i;if(!n)throw new wa("E_SCHEMA",`${t.flag} 路径为空:${e}`,void 0,{flag:t.flag});if(!d(n))throw new wa("E_SCHEMA",`${t.flag} 路径必须是绝对路径:${n}`,"避免 cwd 歧义。可在 shell 里用 $PWD/相对路径 转成绝对路径",{flag:t.flag});try{return r(n,"utf8")}catch(e){const i=e instanceof Error?e.message:String(e);throw new wa("E_FILE_MISSING",`${t.flag} 读取文件失败:${n}(${i})`,void 0,{flag:t.flag,path:n})}}function Ts(e){return Ss(e.prompt)?{...e,prompt:Os(e.prompt,{flag:"--prompt"})}:e}function As(e,t){const i=Array.isArray(e)?e:e.issues,n=t.maxErrors??5,o=function(e){const t={invalid_type:0,required:0,invalid_value:1,invalid_enum_value:1,invalid_string:2,too_small:3,too_big:3,unrecognized_keys:4,invalid_union:5,custom:6};return[...e].sort((e,i)=>{const n=t[e.code]??99,o=t[i.code]??99;return n!==o?n-o:$s(Ns(e.path)).localeCompare($s(Ns(i.path)))})}(i).slice(0,n);return o.map(e=>function(e,t){switch(e.code){case"invalid_type":return function(e,t){const i=e,n=Ns(e.path),o=i.received??function(e){if(!e)return;const t=/received\s+(\S+?)\b/.exec(e);return t?.[1]}(e.message),r=void 0===o?js(t.input??t.jobs,n):void 0,a=o??function(e){if(null===e)return"null";if(void 0===e)return"undefined";if(Array.isArray(e))return"array";const t=typeof e;if("number"===t&&Number.isNaN(e))return"nan";if("object"===t){const t=e.constructor;return t&&t!==Object&&"string"==typeof t.name&&t.name.length>0?t.name:"object"}return t}(r),s="undefined"===o||void 0===o&&void 0===r,l=Cs(n,t);return s?{code:"E_SCHEMA",message:`${l.prefix} is required`,expected:Is(t.flags,Rs(Ns(e.path)))??i.expected,got:void 0,instance_path:l.instance_path,mode:t.mode,verb:t.verb,job_index:l.job_index,job_key:l.job_key,flag:l.flag,hint:`run \`dl ${t.verb} --print-schema\` to see all required fields`}:{code:"E_SCHEMA",message:`${l.prefix}: expected ${i.expected??"<unknown>"}, got ${a??"<unknown>"}`,expected:i.expected,got:a,instance_path:l.instance_path,mode:t.mode,verb:t.verb,job_index:l.job_index,job_key:l.job_key,flag:l.flag,hint:`run \`dl ${t.verb} --print-schema\` to see expected types`}}(e,t);case"invalid_value":case"invalid_enum_value":return function(e,t){const i=e,n=(i.values??[]).map(e=>String(e)),o=i.received??js(t.input??t.jobs,Ns(e.path)),r=Cs(Ns(e.path),t),a="string"==typeof o?xa(o,n):void 0;return{code:"E_SCHEMA",message:a?`${r.prefix}: expected one of {${n.join("|")}}, got ${JSON.stringify(o)} (did you mean ${JSON.stringify(a)}?)`:`${r.prefix}: expected one of {${n.join("|")}}, got ${JSON.stringify(o)}`,expected:`enum {${n.join("|")}}`,got:o,instance_path:r.instance_path,mode:t.mode,verb:t.verb,job_index:r.job_index,job_key:r.job_key,flag:r.flag,hint:a?"re-run with the suggested value":`run \`dl ${t.verb} --print-schema\` for the full enum`}}(e,t);case"too_small":case"too_big":return function(e,t){const i=e,n=Cs(Ns(e.path),t),o="too_small"===e.code?"at least":"at most",r="too_small"===e.code?i.minimum:i.maximum,a="string"===i.type?" chars":"";return{code:"E_SCHEMA",message:`${n.prefix}: expected ${o} ${r}${a}, got ${qs(i.received)}`,expected:`${o} ${r}${a}`,got:i.received,instance_path:n.instance_path,mode:t.mode,verb:t.verb,job_index:n.job_index,job_key:n.job_key,flag:n.flag,hint:`adjust ${n.prefix} so it satisfies the bound`}}(e,t);case"unrecognized_keys":return function(e,t){const i=e,n=i.keys?.[0]??"<unknown>",o=t.flags.map(e=>e.jsonName),r=xa(n,o),a=Cs(Ns(e.path),t,n),s=`--${Xa(n)}`,l=r?`--${Xa(r)}`:void 0;return{code:"E_SCHEMA",message:l?`${s} is not a valid flag (did you mean ${l}?)`:`${s} is not a valid flag`,expected:`one of: ${o.map(e=>`--${Xa(e)}`).join(", ")}`,got:n,instance_path:a.instance_path,mode:t.mode,verb:t.verb,job_index:a.job_index,job_key:a.job_key,flag:s,hint:l?`re-run with ${l}`:`run \`dl ${t.verb} --help\` for the full flag list`}}(e,t);case"invalid_union":return function(e,t){const i=Cs(Ns(e.path),t);return{code:"E_SCHEMA",message:`${i.prefix}: must satisfy one of the conditional shapes (e.g. provide image_url OR image_base64, not both/neither)`,expected:"one-of constraint",got:void 0,instance_path:i.instance_path,mode:t.mode,verb:t.verb,job_index:i.job_index,job_key:i.job_key,flag:i.flag,hint:`run \`dl ${t.verb} --print-schema\` for the conditional required-field combinations`}}(e,t);case"custom":return function(e,t){const i=Cs(Ns(e.path),t);return{code:"E_SCHEMA",message:`${i.prefix}: ${e.message??"validation failed"}`,expected:void 0,got:void 0,instance_path:i.instance_path,mode:t.mode,verb:t.verb,job_index:i.job_index,job_key:i.job_key,flag:i.flag,hint:`run \`dl ${t.verb} --print-schema\` for the schema`}}(e,t);default:return function(e,t){const i=Cs(Ns(e.path),t);return{code:"E_SCHEMA",message:`${i.prefix}: ${e.message??"validation failed"}`,expected:void 0,got:void 0,instance_path:i.instance_path,mode:t.mode,verb:t.verb,job_index:i.job_index,job_key:i.job_key,flag:i.flag,hint:`run \`dl ${t.verb} --print-schema\` for the schema`}}(e,t)}}(e,t))}function $s(e){return 0===e.length?"":`/${e.join("/")}`}function Ns(e){return e.map(e=>"symbol"==typeof e?e.toString():e)}function js(e,t){let i=e;for(const e of t){if(null==i||"object"!=typeof i)return;i=i[e]}return i}function Cs(e,t,i){const n=void 0!==i?[...e,i]:[...e],o=0===n.length?"":`/${n.join("/")}`;if("single"===t.mode){const t=i??e[e.length-1],n="string"==typeof t?`--${Xa(t)}`:void 0;return{instance_path:o,flag:n,job_index:void 0,job_key:void 0,prefix:n??"<root>"}}const r="number"==typeof e[0]?e[0]:void 0,a=(void 0!==i?[...e.slice(1),i]:e.slice(1)).map(String),s=void 0!==r&&t.jobs?t.jobs[r]:void 0;return{instance_path:o,flag:void 0,job_index:r,job_key:s&&"string"==typeof s.job_key?s.job_key:void 0,prefix:void 0===r?"--jobs-file":a.length>0?`--jobs-file[${r}].${a.join(".")}`:`--jobs-file[${r}]`}}function Is(e,t){if(!t)return;const i=e.find(e=>e.jsonName===t);return i?i.enum?`enum {${i.enum.join("|")}}`:i.kind:void 0}function Rs(e){const t=e[e.length-1];return"string"==typeof t?t:void 0}function qs(e){if(null===e)return"null";if(void 0===e)return"undefined";if(Array.isArray(e))return"array";const t=typeof e;return"object"===t?"object":"string"===t?JSON.stringify(e):String(e)}function Ps(e,t){const i=function(e){const{inner:t}=is(e);if("object"!==ts(t))return[];const i=es(t).shape??{},n=[];for(const[e,t]of Object.entries(i))n.push(rs(e,t));return n}(t.schema),n={verb:t.verb,description:t.description,whenToUse:t.whenToUse,whenNotToUse:t.whenNotToUse,flags:i,supportsBatch:t.supportsBatch,examples:t.examples,notExamples:t.notExamples,outputSingle:t.outputSingle,outputBatch:t.outputBatch,errors:t.errors,notes:t.notes,extraFlags:t.extraFlags?.map(e=>({flag:e.spec.split(/\s+/)[0],description:e.description,...e.enum?{enum:e.enum}:{}})),modelTopic:t.modelTopic,preflightTopic:t.preflightTopic,policyTopic:t.policyTopic,compositionTopic:t.compositionTopic,asyncTopic:t.asyncTopic,publishTopic:t.publishTopic},o=function(e){const t=[],i=!!(e.modelTopic||e.preflightTopic||e.policyTopic||e.compositionTopic||e.asyncTopic||e.publishTopic);if(t.push("DESCRIPTION",` ${e.description}`,""),e.whenToUse.length>0){t.push("WHEN TO USE");for(const i of e.whenToUse)t.push(` - ${i}`);t.push("")}if(e.whenNotToUse&&e.whenNotToUse.length>0){t.push("WHEN NOT TO USE");for(const i of e.whenNotToUse)t.push(` - ${i}`);t.push("")}if(e.notes&&e.notes.length>0){t.push("NOTES");for(const i of e.notes)t.push(` - ${i}`);t.push("")}if(i){const i=function(e,t){if(!(t.modelTopic||t.preflightTopic||t.policyTopic||t.compositionTopic||t.asyncTopic||t.publishTopic))return[];const i=[];t.modelTopic&&i.push({topic:"model",oneLiner:"service ranking + per-service call shape + decision logic"}),t.preflightTopic&&i.push({topic:"preflight",oneLiner:"decisions you must make before the first call"}),t.policyTopic&&i.push({topic:"policy",oneLiner:"user-facing communication rules + payment-package gate"}),t.compositionTopic&&i.push({topic:"composition",oneLiner:"how upstream / sibling skills consume this output"}),t.asyncTopic&&i.push({topic:"async",oneLiner:"detach-by-default protocol + result shape"}),t.publishTopic&&i.push({topic:"publish",oneLiner:"handing the result off to publish_content"}),i.push({topic:"examples",oneLiner:"copy-paste-ready calls per scenario"}),i.push({topic:"errors",oneLiner:"failure codes + recovery breadcrumbs"});const n=["LEARN MORE (drill down for the specific decision you face)"];for(const t of i)n.push(` dl ${e} ${t.topic.padEnd(11)} -h — ${t.oneLiner}`);return n}(e.verb,e);if(i.length>0){for(const e of i)t.push(e);t.push("")}}const n=e.flags.filter(e=>e.required),o=e.flags.filter(e=>!e.required);if(n.length>0){t.push("REQUIRED");for(const e of n)t.push(...qr(e));t.push("")}if(o.length>0||e.extraFlags&&e.extraFlags.length>0){t.push("OPTIONAL");for(const e of o)t.push(...qr(e));for(const i of e.extraFlags??[])t.push(` ${i.flag.padEnd(22)} ${i.description}`),i.enum&&t.push(` one of: ${i.enum.join(", ")}`);t.push("")}e.supportsBatch&&(t.push("BATCH MODE (mutually exclusive with the per-job scalar flags above)"),t.push(" --jobs <inline-json> RECOMMENDED. JSON array of {job_key, ...same fields as scalars above}"," passed as an inline string. Lets the LLM-side billing extension"," preflight charge the full batch cost (= N × per-action cost) so"," insufficient-credits requests block before vendor is touched.",' Usage: --jobs "$(cat /workspace/jobs.json)" — or pass JSON directly.'," --jobs-file <path|-> LEGACY. JSON array via file path; `-` reads stdin. Billing extension"," cannot see the file content, so falls back to per-job best-effort"," charging — users with low balance can partially get free vendor work."," Prefer --jobs unless the JSON is too large for argv (uncommon)."),t.push(""));const r=e.utility??Ir;t.push("UTILITY");for(const e of r)t.push(` ${e.flag.padEnd(22)} ${e.description}`);if(t.push(""),!i){for(const i of e.examples){t.push(`EXAMPLE — ${i.caption}`);for(const e of i.command.split("\n"))t.push(` ${e}`);t.push("")}if(e.notExamples&&e.notExamples.length>0){t.push("NOT AN EXAMPLE (these all fail)");for(const i of e.notExamples){t.push(` # ❌ ${i.whyItFails}`);for(const e of i.command.split("\n"))t.push(` ${e}`);t.push("")}}}if(e.outputSingle){t.push("OUTPUT (single, success)");for(const i of e.outputSingle.split("\n"))t.push(` ${i}`);t.push("")}if(e.outputBatch&&e.supportsBatch){t.push("OUTPUT (batch, success)");for(const i of e.outputBatch.split("\n"))t.push(` ${i}`);t.push("")}if(!i){const i=e.errors??Rr;if(i.length>0){t.push("ERRORS");for(const e of i){const i=e.recovery?` — ${e.recovery}`:"";t.push(` ${e.code.padEnd(11)} ${e.when}${i}`)}}}for(;t.length>0&&""===t[t.length-1];)t.pop();return t.join("\n")}(n),r=e.command(t.verb).description(t.description);r.configureHelp({formatHelp:()=>o}),function(e,t,i){const n=t.verb;if(t.modelTopic){const i=t.modelTopic,o=e.command("model [service]").description("service ranking + decision logic; pass <service> for per-service profile");o.configureHelp({formatHelp:()=>Pr(n,i)}),o.action(e=>{console.log(Pr(n,i,e)),process.exit(0)})}if(t.preflightTopic){const i=t.preflightTopic,o=!!t.modelTopic,r=e.command("preflight").description("decisions you must make before the first call");r.configureHelp({formatHelp:()=>Lr(n,i,o)}),r.action(()=>{console.log(Lr(n,i,o)),process.exit(0)})}if(t.policyTopic){const i=t.policyTopic,n=e.command("policy").description("user-facing communication rules + payment-package gate");n.configureHelp({formatHelp:()=>zr(0,i)}),n.action(()=>{console.log(zr(0,i)),process.exit(0)})}if(t.compositionTopic){const i=t.compositionTopic,n=e.command("composition").description("how upstream / sibling skills consume this output");n.configureHelp({formatHelp:()=>Mr(0,i)}),n.action(()=>{console.log(Mr(0,i)),process.exit(0)})}if(t.asyncTopic){const i=t.asyncTopic,n=e.command("async").description("detach-by-default protocol + result shape");n.configureHelp({formatHelp:()=>Ur(0,i)}),n.action(()=>{console.log(Ur(0,i)),process.exit(0)})}if(t.publishTopic){const i=t.publishTopic,n=e.command("publish").description("handing the result off to publish_content");n.configureHelp({formatHelp:()=>Fr(0,i)}),n.action(()=>{console.log(Fr(0,i)),process.exit(0)})}if(!!(t.modelTopic||t.preflightTopic||t.policyTopic||t.compositionTopic||t.asyncTopic||t.publishTopic)){if(t.examples.length>0||t.notExamples&&t.notExamples.length>0){const t=e.command("examples").description("copy-paste-ready calls per scenario");t.configureHelp({formatHelp:()=>Dr(0,i)}),t.action(()=>{console.log(Dr(0,i)),process.exit(0)})}const n=e.command("errors").description("failure codes + recovery breadcrumbs");n.configureHelp({formatHelp:()=>Hr(0,i)}),n.action(()=>{console.log(Hr(0,i)),process.exit(0)})}}(r,t,n);const a=function(e){const t=[e.name()];let i=e.parent;for(;i&&i.parent;)t.unshift(i.name()),i=i.parent;return t.join(" ")}(r);for(const e of i)Ls(r,e);if(t.extraFlags)for(const e of t.extraFlags)void 0!==e.default?r.option(e.spec,e.description,e.default):r.option(e.spec,e.description);t.supportsBatch&&(r.option("--jobs <inline-json>","BATCH MODE (recommended): JSON array of {job_key, ...same fields as scalars above} as an inline string; lets pi-extension preflight charge the full batch cost"),r.option("--jobs-file <path|->","BATCH MODE (legacy): JSON array via file path; `-` reads stdin. Prefer --jobs because the LLM-side billing extension cannot count jobs from a file path and must fall back to per-job best-effort charging.")),r.option("--print-schema","emit JSON schema for this verb's single + batch shape and exit"),r.option("--echo-parsed","echo canonicalised input on stderr (debug)"),r.option("--dry-run","validate, quote, and render approval preview without submitting vendor work or requiring user approval"),r.option("--quote","emit the credit quote for this command and exit without submitting vendor work"),r.action(async e=>{const n=e;n.printSchema&&function(e,t,i){const n={};for(const e of t)e.required&&(n[e.flag]=Ms(e));const o=e.extraFlags?.map(e=>({flag:e.spec.split(/\s+/)[0],type:"string",required:!1,...e.enum?{enum:e.enum}:{},...void 0!==e.default?{default:e.default}:{}}))??[],r={ok:!0,verb:i,single:{scalars:[...t.map(e=>({flag:`--${e.flag}`,type:e.kind,required:e.required,...e.enum?{enum:e.enum}:{},...void 0!==e.minimum?{minimum:e.minimum}:{},...void 0!==e.maximum?{maximum:e.maximum}:{},...void 0!==e.default?{default:e.default}:{},...e.internal?{internal:!0,note:"stripped before submit"}:{}})),...o],example:n},batch:e.supportsBatch?{shape:"array<object>",item_required:["job_key",...t.filter(e=>e.required).map(e=>e.jsonName)],example:[{job_key:"job_0",...Us(t)}]}:null};process.stdout.write(`${JSON.stringify(r,null,2)}\n`),process.exit(0)}(t,i,a),!0===n.dryRun&&!0===n.quote&&ys("E_SCHEMA","--dry-run and --quote are mutually exclusive","use --dry-run for agent-facing validation/preview, or --quote for runtime approval pricing.",{verb:a});const o="string"==typeof n.jobs&&""!==n.jobs,r="string"==typeof n.jobsFile&&""!==n.jobsFile,s=o||r,l=function(e,t){for(const i of e){const e=t[zs(i.flag)];if(void 0!==e&&("boolean"!=typeof e||!1!==e))return!0}return!1}(i,n);o&&r&&ys("E_SCHEMA","--jobs and --jobs-file are mutually exclusive","pick one batch input mode; --jobs is preferred so the billing extension can preflight charge the full batch cost.",{verb:a}),s&&l&&ys("E_SCHEMA","batch flag is mutually exclusive with the per-job scalar flags",`pick one mode: pass a job array via --jobs '<inline-json>' (or --jobs-file=path) OR pass scalar flags directly. Run \`dl ${a} --print-schema\` to see both shapes.`,{verb:a});try{s?await async function(e,t,i,n){const o="string"==typeof i.jobs&&""!==i.jobs,r=o?"--jobs":"--jobs-file",{data:a}=o?us(String(i.jobs),"--jobs"):await ds(String(i.jobsFile),"--jobs-file");if(!o){const e=String(i.jobsFile),t="-"===e?"<path/to/jobs.json>":e;process.stderr.write(`[dl] DEPRECATED: --jobs-file=${e} prevents the billing extension from sizing the batch, so insufficient-credit requests can only be reconciled after vendor submit (partial free work possible). Switch to --jobs '<inline-json>'.\n[dl] Migration: dl ${n} --jobs "$(cat ${t})"\n[dl] See: dl ${n} -h (BATCH MODE section).\n`)}0===a.length&&ys("E_SCHEMA",`${r} must be a non-empty JSON array`,`run \`dl ${n} --print-schema\` for the batch shape`,{verb:n,flag:r});const s=[],l=[];for(let i=0;i<a.length;i++){try{a[i]=Ts(a[i]),e.transformParams&&(a[i]=e.transformParams(a[i],{mode:"batch"}))}catch(e){if(e instanceof wa){s.push({code:"custom",path:[i],message:e.message});continue}throw e}if(e.strictBatchParams){const e=Ds(a[i],t);if(e.length>0){s.push({code:"unrecognized_keys",keys:e,path:[i],message:`Unrecognized key${1===e.length?"":"s"}: ${e.join(", ")}`});continue}}const n=e.schema.safeParse(a[i]);if(n.success){const t=a[i],o="string"==typeof t.job_key?t.job_key:`job_${i}`;if(e.preflight)try{e.preflight(n.data)}catch(e){if(!(e instanceof wa))throw e;s.push({code:"custom",path:[i],message:e.message});continue}l.push({jobKey:o,params:n.data})}else for(const e of n.error.issues)s.push({...e,path:[i,...e.path]})}if(s.length>0){const e=As(s,{verb:n,flags:t,mode:"batch",jobs:a,input:a}),i=e[0];ys("E_SCHEMA",i.message,i.hint,{verb:i.verb,instance_path:i.instance_path,expected:i.expected,got:i.got,...void 0!==i.job_index?{job_index:i.job_index}:{},...i.job_key?{job_key:i.job_key}:{},...e.length>1?{details:e.slice(1)}:{}})}const c=e.resolveActionName?e.resolveActionName(i):e.actionName,d=l.map((i,o)=>{try{const r=Fs(e,i.params,{fullVerb:n,flags:t,mode:"batch",input:i.params,command:n,action:c,jobIndex:o,jobKey:i.jobKey}),a=e.approvalPreview?.(i.params,{mode:"batch",verb:n,action:c});return{...i,billing:r,...a?{approvalPreview:a}:{}}}catch(e){throw e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_index:o,job_key:i.jobKey}),e}});_s({command:n,mode:"batch",jobs:a}),!0===i.quote&&function(e,t,i){const n=i.map((t,i)=>(t.billing||Bs(e),{index:i,jobKey:t.jobKey,...t.billing})),o=Hs(e,i);gs({ok:!0,mode:"batch",source:"dl",action:t,totalCredits:n.reduce((e,t)=>e+t.credits,0),items:n,...o?{approvalPreview:o}:{}})}(n,c,d),!0===i.dryRun&&function(e,t){const i=t.map((e,t)=>({index:t,jobKey:e.jobKey,params:e.params,...e.billing?{billing:e.billing}:{}})),n=Hs("dry-run",t);gs({ok:!0,mode:"batch",source:"dl",dryRun:!0,action:e,totalCredits:t.reduce((e,t)=>e+(t.billing?.credits??0),0),jobs:i,...n?{approvalPreview:n}:{}})}(c,d.map(e=>({jobKey:e.jobKey,params:e.params,billing:e.billing,...e.approvalPreview?{approvalPreview:e.approvalPreview}:{}})));const u=await Promise.all(d.map(async(e,t)=>{const i=e.params,n=k(),o=e.billing;try{const r=await Za(c,i,n,{billing:o,billingTrace:{mode:"batch",batchIndex:t,jobKey:e.jobKey}});ws({action:c,job_ref:n,mode:"batch",job_key:e.jobKey,index:t});const{job_ref:a,...s}=r;return Ka(c)?{job_key:e.jobKey,index:t,job_ref:n,...o?{billing:o}:{},...s}:{job_key:e.jobKey,index:t,job_ref:n,status:"pending",...o?{billing:o}:{},...s}}catch(i){if(i instanceof wa)return{job_key:e.jobKey,index:t,job_ref:n,status:"failed",code:i.code,error:i.message,message:i.message,...i.hint?{hint:i.hint}:{},...i.extra??{}};const o=i instanceof Error?i.message:String(i);return{job_key:e.jobKey,index:t,job_ref:n,status:"failed",error:o}}})),p=u.some(e=>"failed"===e.status),m={ok:!p,action:c,results:u};u.some(e=>"E_INSUFFICIENT_CREDITS"===e.code)&&ys("E_INSUFFICIENT_CREDITS","one or more batch jobs failed because credits are insufficient","Top up credits and retry; jobs with status=failed were not submitted to upstream vendors.",m),p&&vs("one or more batch jobs failed","inspect .results[].status",m),gs(m)}(t,i,n,a):await async function(e,t,i,n){let o=function(e,t){const i={};for(const n of e){const e=t[Qa(n.flag)];void 0!==e&&(i[n.jsonName]=ss(n,e))}return i}(t,i);try{o=Ts(o),e.transformParams&&(o=e.transformParams(o,{opts:i,mode:"single"}))}catch(e){throw e instanceof wa&&bs(e),e}const r=e.schema.safeParse(o);if(!r.success){const e=As(r.error,{verb:n,flags:t,mode:"single",input:o}),i=e[0];ys("E_SCHEMA",i.message,i.hint,{verb:i.verb,instance_path:i.instance_path,expected:i.expected,got:i.got,...i.flag?{flag:i.flag}:{},...e.length>1?{details:e.slice(1)}:{}})}if(e.preflight)try{e.preflight(r.data)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:n,mode:"single",params:r.data});const a=k(),s=e.resolveActionName?e.resolveActionName(i):e.actionName,l=Fs(e,r.data,{fullVerb:n,flags:t,mode:"single",input:r.data,command:n,action:s});if(!0===i.quote){const t=e.approvalPreview?.(r.data,{opts:i,mode:"single",verb:n,action:s});!function(e,t,i,n){i||Bs(e),gs({ok:!0,mode:"single",source:"dl",action:t,totalCredits:i.credits,items:[i],...n?{approvalPreview:n}:{}})}(n,s,l,t)}if(!0===i.dryRun){const t=e.approvalPreview?.(r.data,{opts:i,mode:"single",verb:n,action:s});!function(e,t,i,n){gs({ok:!0,mode:"single",source:"dl",dryRun:!0,action:e,params:t,...i?{billing:i}:{},...n?{approvalPreview:n}:{}})}(s,r.data,l,t)}try{const t=r.data,n=await Za(s,t,a,{billing:l,billingTrace:{mode:"single"}}),o=e.transformResult?e.transformResult(n,{params:r.data,opts:i,mode:"single"}):n;ws({action:s,job_ref:a,mode:"single"}),Ka(s)&&gs({ok:!0,...o,...l?{billing:l}:{}}),gs({ok:!0,status:"pending",...o,...l?{billing:l}:{}})}catch(t){t instanceof Ba&&ys("E_SCHEMA",t.message,`run \`dl ${n} --print-schema\` for required fields`,{verb:n,details:t.errors}),t instanceof wa&&ys(t.code,t.message,t.hint,{...t.extra??{},job_ref:a,action:e.actionName}),vs(t instanceof Error?t.message:String(t),void 0,{job_ref:a,action:e.actionName})}}(t,i,n,a)}catch(e){throw e instanceof wa&&bs(e),e}})}function Ls(e,t){const i=`--${t.flag}`,n=function(e){const t=[];return t.push(e.required?"REQUIRED":"optional"),e.enum&&t.push(`one of: ${e.enum.join(", ")}`),void 0===e.minimum&&void 0===e.maximum||t.push([void 0!==e.minimum?`>= ${e.minimum}`:void 0,void 0!==e.maximum?`<= ${e.maximum}`:void 0].filter(Boolean).join(", ")),e.description&&t.push(e.description),t.join(" — ")}(t);switch(t.kind){case"boolean":return void e.option(i,n);case"array":return void e.option(`${i} <${t.itemKind??"value"}>`,`${n}; repeatable`,(e,t=[])=>[...t,e]);case"integer":case"number":return void e.option(`${i} <n>`,n,e=>Number(e));default:e.option(`${i} <value>`,n)}}function zs(e){return e.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function Ms(e){if(e.enum&&e.enum.length>0)return e.enum[0];switch(e.kind){case"boolean":return!1;case"integer":case"number":return 0;case"array":return[];default:return"<value>"}}function Us(e){const t={};for(const i of e)i.required&&(t[i.jsonName]=Ms(i));return t}function Fs(e,t,i){if(!e.billing)return null;const n=e.billing.select(t),o=e.billing.schema.safeParse(n);if(!o.success){const e=As(o.error,{verb:i.fullVerb,flags:i.flags,mode:i.mode,input:i.input}),t=e[0];ys("E_SCHEMA",`billing schema validation failed: ${t.message}`,t.hint,{verb:t.verb,instance_path:t.instance_path,expected:t.expected,got:t.got,...t.flag?{flag:t.flag}:{},...void 0!==i.jobIndex?{job_index:i.jobIndex}:{},...i.jobKey?{job_key:i.jobKey}:{},...e.length>1?{details:e.slice(1)}:{}})}return e.billing.quote(o.data,{command:i.command,action:i.action})}function Ds(e,t){if("object"!=typeof e||null===e||Array.isArray(e))return[];const i=new Set(["job_key",...t.map(e=>e.jsonName)]);return Object.keys(e).filter(e=>!i.has(e))}function Hs(e,t){const i=t.filter(e=>e.approvalPreview);if(0!==i.length)return{kind:"batch",title:`${e} batch`,summary:`${t.length} jobs`,sections:i.flatMap((e,t)=>{const i=e.approvalPreview;if(!i)return[];const n=e.jobKey||`job_${t}`;return i.sections.map(e=>{const t="title"in e&&e.title?`[${n}] ${e.title}`:`[${n}]`;return{...e,title:t}})})}}function Bs(e){ys("E_SCHEMA",`dl ${e} --quote is only supported for billable actions`,"remove --quote or use a billable command that defines pricing",{verb:e})}const Vs="for media (video/image/audio) use the upload_file tool and store the returned URL inside a JSON artifact; if this really is text, pass --content-type application/json or text/plain";function Js(e,t){const i=e.resolve?.(t)??e,n={};for(const e of i.scalars)e.required&&(n[e.name]=Gs(e));const o={};for(const e of i.files)o[e.name]=JSON.parse(Ks(e));process.stdout.write(`${JSON.stringify({ok:!0,command:i.command,summary:i.summary,scalars:i.scalars,files:i.files,example:{scalars:n,files:o}},null,2)}\n`),process.exit(0)}function Ks(e){if("text"===e.kind)return JSON.stringify(e.example);try{return JSON.parse(e.example),e.example}catch{return"array"===e.kind?"[]":"{}"}}function Gs(e){if(e.enum&&e.enum.length>0)return e.enum[0];switch(e.type){case"boolean":return!1;case"integer":case"number":return 0;default:return"<value>"}}const Ys=/^https?:\/\//i,Ws=/https?:\/\/[^\s"'<>]+/gi;function Zs(e,t="$"){const i=[];return Xs(e,t,i),i}function Xs(e,t,i){if(null!=e)if("string"!=typeof e){if(Array.isArray(e))for(let n=0;n<e.length;n++)Xs(e[n],`${t}[${n}]`,i);else if("object"==typeof e)for(const[n,o]of Object.entries(e))Xs(o,`${t}.${n}`,i)}else Ys.test(e)&&i.push({path:t,url:e})}function Qs(e){let t=e;for(;t.length>0;){const e=t[t.length-1];if(!e)break;if(".,;:!?".includes(e))t=t.slice(0,-1);else if(")"===e&&el(t,"(")<el(t,")"))t=t.slice(0,-1);else if("]"===e&&el(t,"[")<el(t,"]"))t=t.slice(0,-1);else{if(!("}"===e&&el(t,"{")<el(t,"}")))break;t=t.slice(0,-1)}}return t}function el(e,t){let i=0;for(const n of e)n===t&&i++;return i}async function tl(e,t,i,n,o){const r=n+1;let a;for(let n=1;n<=r;n++)try{const s=await t(e,{method:"HEAD",signal:AbortSignal.timeout(i)});if(s.status>=200&&s.status<400)return{status:s.status};if(s.status>=400&&s.status<500)return{status:s.status};if(a=`http ${s.status}`,n<r){await il(o);continue}return{status:s.status,reason:a}}catch(e){if(a=e instanceof Error?e.message:String(e),n<r){await il(o);continue}return{status:0,reason:a}}return{status:0,reason:a}}function il(e){return new Promise(t=>setTimeout(t,e))}async function nl(e,t){try{return await Da("artifact",e,t,{timeoutMs:3e4,retries:0})}catch(e){if(e instanceof Jr&&vs(e.message,e.hint),e instanceof Sa){const t=function(e){if(e)try{const t=JSON.parse(e);if(t&&!1===t.ok&&"string"==typeof t.error)return t}catch{}}(e.bodyText);if(t)return t}throw e}}function ol(e){if(e.ok)return e;"E_SCHEMA"===e.code&&ys("E_SCHEMA",e.error,e.hint,void 0!==e.details?{details:e.details}:void 0),vs(e.error,e.hint,void 0!==e.details?{details:e.details}:void 0)}function rl(e){const{ok:t,...i}=e;return i}function al(e,t,i){const n={};for(const i of t)i in e&&(n[i]=e[i]);return i&&"content"in e&&(n.content=e.content),n}async function sl(e,t){if(t||0===e.length)return;const i=await async function(e,t={}){const i=t.concurrency??20,n=t.timeoutMs??3e3,o=t.retries??1,r=t.retryDelayMs??500,a=t.fetchImpl??globalThis.fetch,s=new Map;for(const{url:t,path:i}of e){const e=s.get(t);e?e.push(i):s.set(t,[i])}const l=Array.from(s.keys()),c=new Map;let d=0;const u=Math.min(i,l.length);await Promise.all(Array.from({length:u},()=>(async()=>{for(;;){const e=d++;if(e>=l.length)return;const t=l[e];c.set(t,await tl(t,a,n,o,r))}})()));const p=[];for(const e of l){const{status:t,reason:i}=c.get(e)??{status:0};if(!(t>=200&&t<400))for(const n of s.get(e)??[])p.push({path:n,url:e,status:t,...i?{reason:i}:{}})}return p}(e);0!==i.length&&ys("E_URL_UNREACHABLE",function(e){if(0===e.length)return"";const t=e[0],i=1===e.length?"URL is":"URLs are",n=e.length>1?` (${e.length-1} more in details.failures)`:"";return`${e.length} ${i} unreachable${n}: path=${t.path} status=${t.status} url=${t.url}`}(i),"One or more artifact URLs are not reachable by HEAD. Fix each URL at details.failures[].path and retry. Use --skip-url-check only for offline fixtures or intentional non-public URLs.",{failures:i,count:i.length})}function ll(e,t){let i;d(e)||ys("E_SCHEMA",`--contract must be an absolute path, got ${e}`,"skill resource references resolve to absolute paths at tool-call time; pass that absolute path here.",{flag:"--contract",given:e});try{i=JSON.parse(r(e,"utf8"))}catch(t){ys("E_FILE_PARSE",`failed to read --contract ${e}: ${t instanceof Error?t.message:String(t)}`,void 0,{flag:"--contract",given:e})}const n=(i.slots??{})[t],o={},a=c(u(e),".."),s=new Set;n?.schema_ref&&s.add(n.schema_ref);for(const e of s){const t=d(e)?e:c(a,e);try{o[e]=JSON.parse(r(t,"utf8"))}catch(i){ys("E_FILE_PARSE",`failed to read schema_ref ${e} (resolved ${t}): ${i instanceof Error?i.message:String(i)}`,void 0,{schema_ref:e})}}return{contract:i,schemas:o}}function cl(e){return`${JSON.stringify(e)}\n`}async function dl(e,t){const i=ya(t);if(i.sandbox)return{exitCode:0,stdout:cl({ok:!0,logged_in:!0,mode:"sandbox",sandbox_flavors:i.flavors,hint:"already authenticated with sandbox-injected credentials; `login` is a no-op here. byoa login is only for running dl/ilands on your own machine."})};const n=function(e){const t={},i=new Set,n=new Set(["--client-id","--issuer","--gateway","--timeout-seconds"]),o=new Set(["--no-browser"]);for(let r=0;r<e.length;r++){const a=e[r];if(void 0===a)break;const s=a.indexOf("="),l=s>=0?a.slice(0,s):a;if(o.has(l)){if(s>=0)return{error:`${l} does not take a value`};i.add(l);continue}if(!n.has(l))return{error:`unknown flag: ${l}`};const c=s>=0?a.slice(s+1):e[++r];if(void 0===c)return{error:`${l} requires a value`};t[l]=c}return{values:t,booleans:i}}(e);if("error"in n)return{exitCode:2,stderr:cl({ok:!1,code:"E_UNKNOWN_OPTION",message:n.error})};const o=n.values["--client-id"]?.trim()||(t.ILANDS_OAUTH_CLIENT_ID??"").trim()||"fIQZIN6q7FhwiF4z",r=n.values["--issuer"]?.trim()||(t.ILANDS_OAUTH_ISSUER??"").trim()||"https://clerk.ilands.ai",a=n.values["--gateway"]?.trim()||(t.ILANDS_GATEWAY_URL??"").trim()||void 0,s=Number(n.values["--timeout-seconds"]??""),l=n.booleans.has("--no-browser");try{const e=await async function(e){const{verifier:t,challenge:i}=function(){const e=Gr(_(48));return{verifier:e,challenge:Gr(w("sha256").update(e).digest())}}(),n=Gr(_(16)),o=e.timeoutMs??18e4,{server:r,redirectUri:a,result:s}=await function(e,t){return new Promise((i,n)=>{let o=null,r=null;const a=new Promise((e,t)=>{o=e,r=t}),s=x((t,i)=>{const n=new URL(t.url??"/","http://127.0.0.1");if("/callback"!==n.pathname)return void i.writeHead(404).end("not found");const a=n.searchParams.get("error"),s=n.searchParams.get("code"),l=n.searchParams.get("state"),c=(e,t)=>{i.writeHead(e,{"content-type":"text/html; charset=utf-8"}).end(t)};return a?(c(200,"<h3>Login failed — you can close this window.</h3>"),void r?.(new Kr(`authorization was denied: ${a}`))):s&&l===e?(c(200,"<h3>✅ Logged in to ilands — you can close this window.</h3>"),void o?.({code:s})):(c(400,"<h3>Invalid callback — you can close this window.</h3>"),void r?.(new Kr("callback missing code or state mismatch")))});setTimeout(()=>{r?.(new Kr(`login timed out after ${Math.round(t/1e3)}s`))},t).unref(),s.on("error",n),s.listen(0,"127.0.0.1",()=>{const e=s.address();i({server:s,redirectUri:`http://127.0.0.1:${e.port}/callback`,result:a})})})}(n,o);try{const o=function(e){const t=new URLSearchParams({response_type:"code",client_id:e.clientId,redirect_uri:e.redirectUri,scope:"profile email offline_access",state:e.state,code_challenge:e.challenge,code_challenge_method:"S256"});return`${Yr(e.issuer)}/oauth/authorize?${t.toString()}`}({issuer:e.issuer,clientId:e.clientId,redirectUri:a,challenge:i,state:n});e.onAuthorizeUrl?await e.onAuthorizeUrl(o):function(e){try{const[t,i]="darwin"===process.platform?["open",[e]]:"win32"===process.platform?["cmd",["/c","start","",e]]:["xdg-open",[e]];return g(t,i,{stdio:"ignore",detached:!0}).unref(),!0}catch{return!1}}(o)||process.stderr.write(`open this URL in your browser to continue:\n${o}\n`);const{code:r}=await s,l=await async function(e){return Wr(`${Yr(e.issuer)}/oauth/token`,{grant_type:"authorization_code",code:e.code,redirect_uri:e.redirectUri,client_id:e.clientId,code_verifier:e.verifier},e.fetchImpl??fetch)}({issuer:e.issuer,clientId:e.clientId,code:r,redirectUri:a,verifier:t,fetchImpl:e.fetchImpl}),c=await async function(e){const t=e.fetchImpl??fetch,i=await t(`${Yr(e.issuer)}/oauth/userinfo`,{headers:{Authorization:`Bearer ${e.accessToken}`}});if(!i.ok)throw new Kr(`userinfo endpoint returned ${i.status}`);const n=await i.json(),o="string"==typeof n.user_id&&n.user_id||"string"==typeof n.sub&&n.sub||"";if(!o)throw new Kr("userinfo response has no user id (sub/user_id)");const r="string"==typeof n.name&&n.name.trim()||[n.given_name,n.family_name].filter(e=>"string"==typeof e&&!!e.trim()).join(" ")||void 0,a="string"==typeof n.email&&n.email.trim()?n.email:void 0;return{id:o,...r?{name:r}:{},...a?{email:a}:{}}}({issuer:e.issuer,accessToken:l.access_token,fetchImpl:e.fetchImpl});return{version:1,issuer:Yr(e.issuer),client_id:e.clientId,access_token:l.access_token,...l.refresh_token?{refresh_token:l.refresh_token}:{},expires_at:Math.floor(Date.now()/1e3)+(l.expires_in??3600),user:c,...e.gatewayUrl?{gateway_url:Yr(e.gatewayUrl)}:{}}}finally{r.close()}}({issuer:r,clientId:o,...a?{gatewayUrl:a}:{},...Number.isFinite(s)&&s>0?{timeoutMs:1e3*s}:{},...l?{onAuthorizeUrl:e=>{process.stderr.write(`open this URL in your browser to continue:\n${e}\n`)}}:{}}),i=ua(e,t);return{exitCode:0,stdout:cl({ok:!0,logged_in:!0,user:e.user,issuer:e.issuer,gateway_url:e.gateway_url??pa,access_token_expires_at:e.expires_at,credential_store:i,hint:"both `ilands` and `dl` now use this login (shared credential store)."})}}catch(e){const t=e instanceof Error?e.message:String(e),i=e instanceof Error&&"hint"in e?e.hint:void 0;return{exitCode:1,stderr:cl({ok:!1,code:"E_BACKEND",message:`login failed: ${t}`,...i?{hint:i}:{}})}}}function ul(e){e.stdout&&process.stdout.write(e.stdout),e.stderr&&process.stderr.write(e.stderr),process.exit(e.exitCode)}const pl=wo({});function ml(e,t){return{source:"dl",event:"shot_detect",credits:50,command:t.command,action:t.action??"detect_shots",details:{rule:"detect-shots.fixed"}}}const hl=wo({});function fl(e,t){return{source:"dl",event:"download_media",credits:5,command:t.command,action:t.action??"download_media",details:{rule:"download-media.fixed"}}}wo({mode:Oo(["text","markdown","raw"])});const gl=Ho.pick({service:!0}),vl={"banana-pro":150,"banana-2":100,seedream:50,"seedream-5-lte":50,"gpt-image-2":75};function yl(e,t){const i=e.service||"seedream";return{source:"dl",event:"image_generate",credits:vl[i],command:t.command,action:t.action??"generate_image",details:{service:e.service,billable_service:i,rule:"generate-image.service.fixed"}}}const bl=Yo.pick({service:!0}),_l={"suno-v5":100,"suno-v5_5":100,minimax:200};function wl(e,t){return{source:"dl",event:"music_generate",credits:_l[e.service],command:t.command,action:t.action??"generate_music",details:{service:e.service,billable_service:e.service,rule:"generate-music.service.fixed"}}}const kl=Zo.pick({text:!0,service:!0});function xl(e,t){const i=e.text.length>0?e.text.length:100;return{source:"dl",event:"tts_generate",credits:Math.max(1,Math.ceil(i/40)),command:t.command,action:t.action??"generate_tts",details:{service:e.service,text_length:e.text.length,billable_characters:i,chars_per_credit:40,rule:"generate-tts.text-length"}}}const Sl="dlim2v",El=Jo.pick({service:!0,duration:!0,resolution:!0}),Ol={"seedance-2-0":{"480p":70,"720p":150,"1080p":360,"4k":720},"seedance-2-0-fast":{"480p":55,"720p":120,"1080p":null,"4k":null},"seedance-2-0-mini":{"480p":35,"720p":75,"1080p":null,"4k":null},"kling-o3-ref2v":{"480p":50,"720p":120,"1080p":300},"kling-o3-pro-ref2v":{"480p":65,"720p":130,"1080p":240},"kling-o3-v2v":{"480p":50,"720p":100,"1080p":300},"kling-o3-pro-v2v":{"480p":65,"720p":130,"1080p":240},"seedance-1-5":{"720p":60,"1080p":120},dli2v3:{_default:30,"720p":30,"1080p":60},dlai2v_pro:{"720p":70,"1080p":200},dlai2v_pro_multiframe:{"720p":70,"1080p":200},"kling3.0":{"720p":100,"1080p":200},dlai2v:{_default:50},dlim2v:{_default:50},"happyhorse-1-0-i2v":{_default:150},"happyhorse-1-0-r2v":{_default:150},"happyhorse-1-0-video-edit":{_default:150},"gemini-omni-video":{"480p":null,"720p":50,"1080p":150,"4k":300},"grok-imagine-1.5":{"480p":50,"720p":80},"longcat-avatar-1-5":{_default:100}};function Tl(e,t){const{billableService:i,pricedResolution:n,rate:o}=function(e,t){const i=Ol[e]??Ol[Sl],n=Ol[e]?e:Sl,o=function(e){const t=e?.trim().toLowerCase();return"480p"===t||"720p"===t||"1080p"===t||"4k"===t?t:null}(t);if(o){const e=i?.[o];if(void 0!==e)return{billableService:n,pricedResolution:o,rate:Al(e,n,o)}}return void 0!==i?._default?{billableService:n,pricedResolution:"_default",rate:Al(i._default,n,"_default")}:void 0!==i?.["720p"]?{billableService:n,pricedResolution:"720p",rate:Al(i["720p"],n,"720p")}:{billableService:Sl,pricedResolution:"_default",rate:50}}(e.service,e.resolution),r=function(e,t){if("number"!=typeof t||!Number.isFinite(t)||t<=0)return 8;if("seedance-2-0-mini"===e&&(t<5||t>12))throw new wa("E_SCHEMA","--duration must be between 5 and 12 for seedance-2-0-mini","Seedance 2.0 Mini supports 5-12s for text-to-video. Pick an integer duration in that range, then trim the final segment after generation if needed.",{service:e,flag:"--duration"});return t}(e.service,e.duration);return{source:"dl",event:"video_generate",credits:Math.ceil(o*r),command:t.command,action:t.action??"generate_video",details:{service:e.service,billable_service:i,resolution:e.resolution,priced_resolution:n,duration_seconds:e.duration,billable_duration_seconds:r,rate_credits_per_second:o,rule:"generate-video.service-resolution.duration"}}}function Al(e,t,i){if(null!==e)return e;throw new wa("E_SCHEMA",`generate-video pricing is not defined for service '${t}' at '${i}'`,"Pick a priced service/resolution from docs/billing/billing-pricing.md before submitting the job.",{service:t,resolution:i,pricing_status:"unpriced"})}const $l=wo({mode:Oo(["forward","reverse"])});function Nl(e,t){return{source:"dl",event:"geocode",credits:5,command:t.command,action:t.action??"geocode",details:{rule:"geocode.fixed",mode:e.mode}}}wo({});const jl=Ko.pick({service:!0,duration:!0,resolution:!0}),Cl={dlai2v_pro:{"720p":70,"1080p":200},dlai2v_pro_multiframe:{"720p":70,"1080p":200},dlai2v:{_default:null},"longcat-avatar":{_default:100}};function Il(e,t){const{pricedResolution:i,rate:n}=function(e,t){const i=Cl[e],n=function(e){const t=e?.trim().toLowerCase();return"480p"===t||"720p"===t||"1080p"===t?t:null}(t);if(n){const t=i?.[n];if(void 0!==t)return{pricedResolution:n,rate:Rl(t,e,n)}}return void 0!==i?._default?{pricedResolution:"_default",rate:Rl(i._default,e,"_default")}:void 0!==i?.["720p"]?{pricedResolution:"720p",rate:Rl(i["720p"],e,"720p")}:{pricedResolution:"_default",rate:190}}(e.service,e.resolution),o=function(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?e:8}(e.duration);return{source:"dl",event:"lipsync_generate",credits:Math.ceil(n*o),command:t.command,action:t.action??"lipsync",details:{service:e.service,resolution:e.resolution,priced_resolution:i,duration_seconds:e.duration,billable_duration_seconds:o,rate_credits_per_second:n,rule:"lipsync.service-resolution.duration"}}}function Rl(e,t,i){if(null!==e)return e;throw new wa("E_SCHEMA",`lipsync pricing is not defined for service '${t}' at '${i}'`,"Pick a priced service/resolution from docs/billing/billing-pricing.md before submitting the job.",{service:t,resolution:i,pricing_status:"unpriced"})}const ql=wo({service:Oo(["dreamactor","kling3.0-motion"]),tier:Oo(["pro","std"]).optional(),duration:co().int().min(1).optional()});function Pl(e,t){const{pricedTier:i,rate:n}=(r=e.service,a=e.tier,"dreamactor"===r?{pricedTier:"_default",rate:60}:"kling3.0-motion"===r?"std"===a?{pricedTier:"std",rate:100}:{pricedTier:"pro",rate:200}:{pricedTier:"_default",rate:100}),o=function(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?e:10}(e.duration);var r,a;return{source:"dl",event:"motion_control_generate",credits:Math.ceil(n*o),command:t.command,action:t.action??"motion_control",details:{service:e.service,tier:e.tier,priced_tier:i,duration_seconds:e.duration,billable_duration_seconds:o,rate_credits_per_second:n,rule:"motion-control.service-tier.duration"}}}const Ll=wo({});function zl(e,t){return{source:"dl",event:"places",credits:20,command:t.command,action:t.action??"place_photo",details:{rule:"places.fixed",subcommand:"photo"}}}const Ml=wo({});function Ul(e,t){return{source:"dl",event:"places",credits:20,command:t.command,action:t.action??"places_search",details:{rule:"places.fixed",subcommand:"search"}}}wo({});const Fl=wo({});function Dl(e,t){return{source:"dl",event:"render_caption",credits:50,command:t.command,action:t.action??"render_caption",details:{rule:"render-caption.fixed"}}}wo({provider:Oo(["baidu","baidu-image","serper","tavily","brave"])});const Hl=wo({});function Bl(e,t){return{source:"dl",event:"static_map",credits:5,command:t.command,action:t.action??"static_map",details:{rule:"static-map.fixed"}}}wo({provider:Fn().min(1),native_id:Fn().min(1)}),wo({type:Oo(["image","video"]),mode:Oo(["fallback","fanout"]),limit:co().int().min(1).max(30),providers:bo(Fn().min(1)).min(1)});const Vl=wo({});function Jl(e,t){return{source:"dl",event:"streetview",credits:10,command:t.command,action:t.action??"streetview_image",details:{rule:"streetview.fixed",subcommand:"image"}}}const Kl=wo({});function Gl(e,t){return{source:"dl",event:"streetview",credits:10,command:t.command,action:t.action??"streetview_metadata",details:{rule:"streetview.fixed",subcommand:"metadata"}}}const Yl=wo({});function Wl(e,t){return{source:"dl",event:"audio_transcribe",credits:50,command:t.command,action:t.action??"transcribe",details:{rule:"transcribe.fixed"}}}const Zl=["text","markdown","raw"];function Xl(e){const t=Number(e);if(!Number.isFinite(t)||!Number.isInteger(t)||t<7e3||t>12e4)throw new Error(`--timeout-ms must be an integer between 7000 and 120000, got ${e}`);return t}function Ql(e,t){const i=e[t];return"string"==typeof i&&""!==i.trim()?i.trim():void 0}const ec="按特征选路由: ffprobe / -c copy / 简单 trim 用本地 ffmpeg; -c:v 重编码 / filter_complex / 输入 >2min 走 dl ffmpeg; >5min 编码加 --async 走 callback。";function tc(e){return e?`${e}; ${ec}`:ec}const ic=["img_url","image","image_urls"];function nc(e){return Array.isArray(e)?e.length>0:"string"==typeof e?e.trim().length>0:null!=e}function oc(e){const t=ic.filter(t=>nc(e[t]));if(t.length>0)throw new wa("E_SCHEMA","`generate-image-prompt` does not accept reference image fields.","Use `dl generate-image-ref` when a source/reference image is required.",{fields:t});return e}function rc(e){if(!function(e){return ic.some(t=>nc(e[t]))}(e))throw new wa("E_SCHEMA","`generate-image-ref` requires at least one reference image.","Pass `--img-url` or `--image-urls`; use `dl generate-image-prompt` for prompt-only generation.",{required_one_of:ic})}function ac(e){return"string"==typeof e&&e.trim().length>0?[e]:Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.trim().length>0):[]}function sc(e,t,i){const n="ref"===i;Ps(e,{verb:t,actionName:"generate_image",schema:n?Vo:Bo,billing:{schema:gl,select:e=>({service:e.service}),quote:yl},preflight:n?rc:void 0,transformParams:n?void 0:oc,approvalPreview:e=>function(e,t){const i=(n=[...ac(t.img_url),...ac(t.image),...ac(t.image_urls)],[...new Set(n)]);var n;const o=[];"string"==typeof t.service&&o.push({label:"Service",value:t.service}),"string"==typeof t.aspect_ratio&&o.push({label:"Aspect ratio",value:t.aspect_ratio});const r="string"==typeof t.image_size?t.image_size:t.size;return"string"==typeof r&&o.push({label:"Image size",value:r}),{kind:"generate_image",title:"ref"===e?"Image generation with references":"Image generation",sections:[{type:"text",title:"Prompt",value:"string"==typeof t.prompt?t.prompt:"",display:"prewrap"},...i.length>0?[{type:"media",title:"Reference images",items:i.map((e,t)=>({kind:"image",url:e,label:`Reference ${t+1}`}))}]:[],...o.length>0?[{type:"kv",title:"Details",items:o}]:[]]}}(i,e),strictBatchParams:!0,supportsBatch:!0,description:n?"Generate or edit a still image from required source/reference image URL(s).":"Generate a still image from a text prompt only; reference image inputs are rejected.",notes:n?["`--img-url` (repeatable) is the canonical i2i input; `--image-urls` is its array-form alias.","`--image` is a legacy alias for `--img-url` — prefer `--img-url` in new calls."]:["This command is prompt-only and does not expose reference image flags.","If the task says use/keep/match a photo, same person, likeness, outfit, style image, or source image, use `dl generate-image-ref` instead."],whenToUse:n?["You need to edit an existing image (i2i)","You need a character reference sheet, likeness, outfit transfer, style/scene composition, or any output grounded in uploaded/source images","Multi-reference composition — pass `--img-url` repeatedly or use `--image-urls`"]:["You need a still image from text only","No user/source/reference image is part of the generation contract","Multi-aspect-ratio fan-out for prompt-only jobs"],whenNotToUse:n?["You need a prompt-only image with no source/reference images — use `dl generate-image-prompt`","You need a video — use `dl generate-video`","You need style-reference search before generating — use `dl knowledge search --domain=visual_style` first"]:["The user said use this picture/photo/image, make it look like me, keep the same person, match this outfit, or preserve identity/likeness — use `dl generate-image-ref`","You need a video — use `dl generate-video`","You need style-reference search before generating — use `dl knowledge search --domain=visual_style` first"],examples:[{caption:"single, banana-2 (newest in banana family, faster + better)",command:'dl generate-image-prompt \\\n --service=banana-2 \\\n --prompt="a corgi astronaut floating above earth, cinematic light" \\\n --aspect-ratio=16:9 \\\n --image-size=2K'},{caption:"i2i with multiple reference images",command:'dl generate-image-ref \\\n --service=gpt-image-2 \\\n --prompt="merge: subject from img1 in the setting of img2" \\\n --img-url="https://1.png" \\\n --img-url="https://2.png"'},{caption:"batch via stdin",command:'cat <<EOF | dl generate-image-prompt --jobs-file=-\n[\n {"job_key":"keyframe_01","service":"banana-2","prompt":"opening shot, dawn","aspect_ratio":"16:9"},\n {"job_key":"keyframe_02","service":"banana-2","prompt":"crescendo, fireworks","aspect_ratio":"16:9"}\n]\nEOF'}],notExamples:[{command:'dl generate-image-prompt --params=\'{"service":"banana-pro"}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"url":"https://storage.../image.png","width":1920,"height":1080}}',outputBatch:'{"ok":true,"action":"generate_image","results":[\n {"job_key":"keyframe_01","job_ref":"<uuid>","status":"pending"},\n ...\n]} // batch is non-blocking; each completed job is pushed back to the session via [async-callback]',modelTopic:{rankingSummary:["Overall quality ranking (strongest to weakest): gpt-image-2 > banana-2 > banana-pro > seedream-5-lte / seedream.",'Higher rank does NOT mean "better in every scenario" — it means "stronger on the combined axes of','photorealism + text rendering + instruction following + multi-image composition". For specific scenarios pick by the SERVICES table + DECISION LOGIC below.',"Service-name ↔ model-name mapping: banana-pro = nano-banana-pro (Imagen3 series, older / cheaper / slower), banana-2 = nano-banana-2 (Imagen4 4K, newest generation — materially faster AND higher quality than banana-pro; default first choice within the banana family)."],services:[{service:"gpt-image-2",label:"OpenAI GPT-Image-2",tier:"🥇 #1 Overall strongest",bestFor:"Overall strongest. The only reliable choice for precise text rendering, the only instruction-driven editor, and the only multi-image compositor (up to 16 reference images). Expensive and slow — use only when these exclusive capabilities are needed",quality:"Very High",speed:"10s-2min",cost:"high",description:["OpenAI GPT-Image-2 is exposed through the api-layer. Overall quality is strongest + 3 exclusive capabilities (","text rendering / instruction edit / multi-image composition, up to 16 refs).","The api-layer auto-routes to the backend that precisely honors the passed field: passing","`aspect_ratio` routes to a backend that natively honors `aspect_ratio`; passing a `size` pixel string","(`1024*1536`) triggers a backend that precisely honors `size`. Callers do not pick the vendor manually."],promptTips:['To render text you must use quotes: `the word "HELLO" in chrome letters` — this is one of the few models that can render text reliably','For edits, use the "keep X, change Y" framing rather than just describing the target','For multi-image composition, number them in prose: "the subject in image 1", "the background in image 2"',"Prefer full natural-language descriptions, not keyword soup","When using a `search-visual-style` hit as style ref: take the `prompt_gpt` field (gpt-image-2 specific variant), not `prompt` — `prompt` is for other services (banana / seedream etc.)."],constraints:["Expensive + slow (10s-2min); only use when you need the 3 exclusive capabilities","At most 16 reference images (via --image-urls)"],flagSubset:["service","prompt","img-url","image-urls","aspect-ratio","size","nsfw-checker"],examples:[{caption:"text-in-image",command:`dl ${t} --service=gpt-image-2 \\\n --prompt='A minimalist poster: the bold word "KAIROS" centered, off-white paper background, subtle grain, Helvetica Bold'`},{caption:"multi-image edit",command:'dl generate-image-ref --service=gpt-image-2 \\\n --prompt="Place the product from image 1 onto the desk in image 2, match the lighting of image 2" \\\n --image-urls=https://.../product.jpg \\\n --image-urls=https://.../scene.jpg'}]},{service:"banana-2",label:"Imagen4 4K (nano-banana-2) — newest, faster + stronger than banana-pro",tier:"🥈 #2",bestFor:"Overall quality runner-up to gpt-image-2 AND faster + higher quality than banana-pro. Imagen4 4K (nano-banana-2), the newest generation in the banana family. Default first choice within the banana family unless explicit cost-saving",quality:"Very High",speed:"10-60s (materially faster than banana-pro)",cost:"high",description:["Google Imagen4 4K family (nano-banana-2). The newest banana generation: BOTH faster AND clearly stronger overall","quality than banana-pro (Imagen3). Cost is higher than banana-pro but typically worth it given the speed + quality","win. Use this as the default within the banana family; drop to banana-pro only when cost-saving is explicit."],flagSubset:["service","prompt","aspect-ratio","image-size","img-url"],examples:[{caption:"single, banana-2 (newest, faster + better)",command:`dl ${t} --service=banana-2 \\\n --prompt="cinematic photo: a mountaineer at dawn on a glacier, ultra-detailed" \\\n --aspect-ratio=3:4 \\\n --image-size=2K`}]},{service:"banana-pro",label:"Imagen3 2K (nano-banana-pro) — older, cheaper, slower",tier:"🥉 #3",bestFor:"Imagen3 family (nano-banana-pro), up to 2K. One generation OLDER than banana-2: cheaper but slower and lower quality. Drop to this tier only when cost-saving is explicit",quality:"High",speed:"30s-3min (slower than banana-2)",cost:"low",description:["Google Imagen3 family (nano-banana-pro). The cheap-and-slow version of banana-2 — one generation older,","both slower and one quality tier below. Pick it only when cost-saving is explicit; banana-2 is the default","banana choice otherwise."],flagSubset:["service","prompt","aspect-ratio","image-size","img-url"],examples:[{caption:"single, banana-pro (cost-saving fallback)",command:`dl ${t} --service=banana-pro \\\n --prompt="a corgi astronaut floating above earth, cinematic light" \\\n --aspect-ratio=16:9 \\\n --image-size=2K`}]},{service:"seedream-5-lte",label:"ByteDance Seedream 5.0",tier:"4",bestFor:"Below the 3 overall tiers above. ByteDance Seedream 5.0, fast (10-30s), usable for general scenarios but overall not as strong as the banana family",quality:"Very High",speed:"10-30s",cost:"low",description:["ByteDance Seedream 5.0. Fast and cheap, overall below the banana family but renders in 10-30s."],flagSubset:["service","prompt","model","size","image"],examples:[{caption:"single, seedream-5-lte",command:`dl ${t} --service=seedream-5-lte \\\n --prompt="风格化插画:一只穿越赛博朋克城市的猫" \\\n --size=1:1`}]},{service:"seedream",label:"Seedream 4.5",tier:"5",bestFor:"Weakest overall tier. Seedream 4.5 — historically strong on Asian aesthetic / Asian-face portraits / marketing imagery, but overall quality is below the four above",quality:"High",speed:"10-30s",cost:"low",description:["ByteDance Seedream 4.5. Historically strong on Asian aesthetic / Asian-face portraits / Chinese marketing imagery;","overall quality is below the top 4 tiers but performs more reliably in these specialized scenarios."],flagSubset:["service","prompt","model","size","image"],examples:[{caption:"single, seedream",command:`dl ${t} --service=seedream \\\n --prompt="温暖光感的亚洲女性肖像,中景,白底" \\\n --model=seedream-4-5-251128 \\\n --size=3:4`}]}],decisionLogic:[{when:"No special user requirements / default case",pick:"gpt-image-2 (overall strongest, first choice)"},{when:"gpt-image-2 is too expensive / too slow and you don't need its exclusive capabilities",pick:"banana-2 (overall runner-up, Imagen4 4K / nano-banana-2, newest banana generation)"},{when:"Must render text — logo / tagline / UI text",pick:"gpt-image-2 (exclusively reliable)"},{when:'Must do instruction-driven edits ("keep the person, swap background to...")',pick:"gpt-image-2 (exclusive)"},{when:"Must do multi-image composition (place an object from image A into the scene of image B)",pick:"gpt-image-2 (exclusive, 16 refs)"},{when:"Explicit 4K / high-resolution / strong photorealism need, and no need for gpt-image-2 exclusives",pick:"banana-2"},{when:"Explicit cost-saving / general scenario can accept one generation lower",pick:"banana-pro (cheap version, Imagen3 2K / nano-banana-pro)"},{when:"Specialized Asian-face portraits / Chinese marketing imagery",pick:"seedream (historical strength)"},{when:"Need a fast preview (10-30s)",pick:"seedream-5-lte or seedream"}]},preflightTopic:{intro:`Before the first \`dl ${t}\` call, the following four decisions must be explicit (for the per-service flag shape see \`dl ${t} model <service>\` — positional; \`model -h <service>\` short-circuits to the overview):`,decisions:[{name:"Service / model family",description:`Which service to use. Decide per the SERVICES table + DECISION LOGIC in \`dl ${t} model -h\` (overview), or \`dl ${t} model <service>\` (per-service profile).`},{name:"Aspect ratio / size dimension",description:`Ratio / pixel string / resolution tier use different fields across services (the FLAG SUBSET in \`dl ${t} model <service>\`\nexposes them explicitly); you only need to decide the target ratio + target resolution tier, leave the field mapping to --help.`},{name:"Reference-input plan",description:"Whether reference images are needed, which URLs go in, and whether you need multi-reference / instruction-driven\nedit / multi-image composition (only the latter two are reliable on gpt-image-2)."},{name:"Generation count / budget sensitivity",description:"Single image or batch, batch cap, and whether the user asked for a lower-cost service."}],notes:["If cost-sensitive or unsure about service choice, read `pricing-and-policies-dramaland-faq/SKILL.md` for a planning estimate before locking the package parameters","Do not submit until all four decisions are explicit — switching service later requires confirming the changed generation parameters"]},policyTopic:{intro:"Two classes of hard rules: external communication must not leak internal details (rule 1 below); generation parameters must be explicit before submit (rule 2 below).",rules:[{title:"1. ⚠ User-Facing Communication Rule — do not leak internal details",body:["Never surface internal infrastructure details to the end user:"," - any vendor / backend internal name"," - any USD / RMB price figure"," - any internal model code name (e.g. `nano-banana-pro`, `seedream-4-5-251128`)"," - any internal trace identifier: job_id / task_id / request_id /"," prompt_id / raw_task_id / or any other UUID / hex-form ID string"," (these are for debug, appear in the raw JSON returned by dl CLI; do not repeat them to the user)","","Applies to: generation-parameter ask cards / chat narration / progress messages / any user-visible string.","","When confirming generation parameters with the user, summarize **only**:"," - the service name (e.g. banana-pro, banana-2, gpt-image-2, seedream)"," - the user-meaningful constraint the user actually asked for"," (aspect ratio, count, edit vs. new, etc.)",' - the action ("Generate", "Edit")',"","✅ Good:",' - "确认生成一张 9:16 比例的图片(GPT-Image-2)?"',' - "Confirm: generate 1 image at 9:16 with gpt-image-2?"',"","❌ Bad (leaks internal info):",' - "将使用 GPT-Image-2 + Wavespeed 供应商,预计约 $0.10/张,确认开始生成吗?"',' - "Will route via internal_vendor_name (~$0.10), confirm?"',"","Do not put credit amounts, balances, spend, refunds, or billing approval into ask cards.","The app shows the exact credit cost and asks for confirmation immediately before the actual","generation starts. The pricing skill is only for budget planning estimates."]},{title:"2. Production Package Rule — do not call before parameters are explicit",body:["This verb's service / model family, aspect ratio / size, generation count (including","batch range), and reference image plan are all components of the generation package.",`Do not call \`dl ${t}\` before those parameters are explicit.`,"","Within the same parameter package you can batch-generate — do not block per-image.","Only re-ask when the package changes (switching service, changing size / ratio, increasing count,","fallback, regeneration, or replacing key inputs). Ask about the changed creative / technical","choice only, not credit consumption."]}]},compositionTopic:{intro:"This atomic skill only produces URLs; artifact / canvas registration and other downstream responsibilities are not this verb's job.",integrations:[{skill:"music-video reference-pack workflow",rule:["Keep every returned candidate URL in the upstream","`reference_list.ref_img_urls` array and choose `selected_url`","explicitly instead of discarding alternates."]},{skill:"full-song MV segment production",rule:["Image generation may also be used for segment-specific lip-sync","keyframe stills. Those stills should combine the segment's selected","character, location, and prop references into a front-facing","performance image that can drive lip-sync.","","Preserve the returned URLs in the downstream segment metadata or","generation notes so the lip-sync input can be audited. When a","composition workflow requires these stills, generate them before","the lip-sync call; do not let the raw character reference sheet","become the final lip-sync input."]},{skill:"right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs `dl artifact write` or `patch-json pi_media_log` on your behalf —","that is the composition layer's job. The upstream workflow (visual-production / music-video","composition) is responsible for placing the returned URL into its own artifact slot","(`reference_list.ref_img_urls` / `storyboard.references` etc.)."]}]},asyncTopic:{intro:[`\`dl ${t}\` by default returns { job_ref, status: "pending" } and exits immediately — do not poll.`,"Results are injected into the current session as `[async-callback] job=<ref>` text; during that window you can make","other tool calls, or simply end the turn and let the session sit idle until the callback arrives.","",'Only run `dl poll` separately when "the next step strictly requires the result"; the dl subcommand itself no longer supports',"`--wait` blocking."],resultShape:['{ "url": "https://storage.googleapis.com/.../image.png" }'],notes:["The URL field is the atomic skill's sole product handed up to the upper layer","The upstream workflow is responsible for placing this URL into its own artifact slot; the atomic skill no longer registers canvas on your behalf","⚠ This URL already lives on our GCS — feed it directly to downstream tools / artifacts; do NOT pass to upload_file (would re-host an identical blob under a different URL)."]},publishTopic:{intro:["After producing your image URL(s), call `publish_content` with","`presentation_family='text_image'` and the explicit media fields.",'See "Publishing Your Work / text_image" in your creation playbook for',"the full field mapping template."],fields:[{name:"presentation_family",value:"'text_image'"},{name:"media_urls.images[]",value:"<returned image URLs (preserve all candidates)>"},{name:"thumbnail_url",value:"media_urls.images[0]"},{name:"delivery_format",value:"'image'"},{name:"experience_format",value:"'passive_media'"}]}})}const lc=["minimax","elevenlabs","elevenlabs-dialogue","voxcpm"],cc={minimax:"generate_tts",elevenlabs:"generate_tts_elevenlabs","elevenlabs-dialogue":"generate_tts_dialogue",voxcpm:"generate_tts"};function dc(e){return"string"==typeof e&&e.trim().length>0?[e]:Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.trim().length>0):[]}function uc(e){return[...new Set(e)]}function pc(e){return"string"==typeof e&&e.trim().length>0?e:void 0}function mc(e,t,i,n){("string"==typeof i&&i.trim().length>0||"number"==typeof i&&Number.isFinite(i)||"boolean"==typeof i&&(i||n?.includeFalse))&&e.push({label:t,value:i})}function hc(e,t){return t.length>0?{type:"media",title:e,items:[...t]}:void 0}function fc(e,t){return t.length>0?{type:"kv",title:e,items:[...t]}:void 0}function gc(e,t){const i=pc(t);return i?{type:"text",title:e,value:i,display:"prewrap"}:void 0}function vc(e,t,i){return t.map((t,n)=>({kind:e,url:t,label:`${i} ${n+1}`}))}function yc(e){return Array.isArray(e)?e.flatMap((e,t)=>{const i=_c(e);if(!i)return[];const n=pc(i.image_url);if(!n)return[];const o=bc(i.frame_position)??bc(i.frame_ratio);return[{kind:"image",url:n,label:o?`Keyframe ${t+1} (${o})`:`Keyframe ${t+1}`}]}):[]}function bc(e){return"string"==typeof e&&e.trim().length>0?e:"number"==typeof e&&Number.isFinite(e)?String(e):void 0}function _c(e){if("string"==typeof e)try{return _c(JSON.parse(e))}catch{return}if("object"==typeof e&&null!==e&&!Array.isArray(e))return e}const wc="--refs-from";function kc(e){return null==e?[]:Array.isArray(e)?e.filter(e=>"string"==typeof e):"string"==typeof e?[e]:[]}function xc(e){const t=new Set,i=[];for(const n of e)t.has(n)||(t.add(n),i.push(n));return i}function Sc(e){return"seedance-2-0"===e||"seedance-2-0-fast"===e||"seedance-2-0-mini"===e}function Ec(e,t){vs(`dl ${e} is not implemented on pi yet`,t)}const Oc=["sfx","stinger","bgm","amb","audio_any","visual_style","voice","writing_plot","writing_character","writing_payoff","writing_conflict","writing_hook","writing_any","meme"],Tc=["elevenlabs","minimax"],Ac=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function $c(){const e=JSON.stringify({event:"hint",code:"ASYNC_DETACH",message:"dl poll is single-shot — never call it in a bash loop. Bash has a ~5min hard cap and the sandbox is reclaimed on inactivity, so wait loops die as 'sandbox not running' or 'terminated' before the callback arrives. End your turn; the callback re-spawns a fresh sandbox with [async-callback] when ready."});process.stderr.write(`${e}\n`)}const Nc=65536,jc="DL_BEGIN",Cc="DL_END";const Ic=["baidu","baidu-image","serper","tavily","brave"],Rc=new Set(["pd","pw","pm","py"]),qc=["web","image","video"],Pc=4194304;function Lc(e,t){return Math.min(t??10,{web:50,image:30,video:10}[e])}async function zc(e){const t=e.extra?.image;if(void 0!==t){if("string"!=typeof t||""===t.trim())throw new wa("E_SCHEMA","--params-file image must be a non-empty base64 string",void 0,{flag:"--params-file",expected:"object with image:string"});return t}if(!e.imageFile)throw new wa("E_SCHEMA","--image-file is required for provider=baidu-image",'pass a jpg/png file path, or pass {"image":"<base64>"} through --params-file',{flag:"--image-file",provider:"baidu-image"});const i=c(e.imageFile);let n;try{n=await O(i)}catch(t){const n=t instanceof Error?t.message:String(t);throw new wa("E_FILE_MISSING",`--image-file: cannot read file at ${i} (${n})`,"make sure the path exists in the sandbox",{flag:"--image-file",given:e.imageFile,resolved:i,cwd:process.cwd()})}if(0===n.byteLength)throw new wa("E_SCHEMA",`--image-file (${i}): expected non-empty jpg/png image`,void 0,{flag:"--image-file",resolved:i});if(n.byteLength>Pc)throw new wa("E_SCHEMA",`--image-file (${i}): image must be <= 4MB before base64 encoding`,void 0,{flag:"--image-file",resolved:i,max_bytes:Pc,bytes:n.byteLength});return n.toString("base64")}async function Mc(e,t,i){if("baidu"===e)return async function(e,t){const i=t.resourceType??"web",n={messages:[{role:"user",content:e}],search_source:"baidu_search_v2",resource_type_filter:[{type:i,top_k:Lc(i,t.k)}]};if(t.freshness){const e={pw:"week",pm:"month",py:"year"}[t.freshness];if(!e)throw new Error("--freshness=pd is not supported by baidu; use pw|pm|py or provider=brave");n.search_recency_filter=e}return t.extra&&Object.assign(n,t.extra),((await Da("search/baidu","v2/ai_search/web_search",n,{timeoutMs:2e4,retries:1,...t.billing?{billing:{jobRef:t.billing.jobRef,quote:t.billing.quote}}:{}})).references??[]).slice(0,t.k??10).map(e=>{const t=e.image?.width??e.video?.width,i=e.image?.height??e.video?.height;return{title:e.title??e.web_anchor??"",url:e.url??e.video?.url??e.image?.url??"",snippet:e.snippet??e.content??"",...e.date?{publishedAt:e.date}:{},...e.website?{source:e.website}:{},...e.type?{type:e.type}:{},...e.image?.url?{imageUrl:e.image.url}:{},...e.video?.url?{videoUrl:e.video.url}:{},...e.video?.hover_pic?{thumbnailUrl:e.video.hover_pic}:{},...void 0!==t?{width:t}:{},...void 0!==i?{height:i}:{},...void 0!==e.video?.duration?{duration:e.video.duration}:{},...void 0!==e.video?.size?{size:e.video.size}:{}}})}(t,i);if("baidu-image"===e)return async function(e){const t={image:await zc(e),count:Math.min(e.k??10,50)};if(e.extra)for(const[i,n]of Object.entries(e.extra))"image"!==i&&(t[i]=n);const i=await Da("search/baidu-image","v2/tools/image_similar_info",t,{timeoutMs:2e4,retries:1,...e.billing?{billing:{jobRef:e.billing.jobRef,quote:e.billing.quote}}:{}}),n=i.result?.res_data?.result_page;return(i.result?.res_data?.res_items??[]).slice(0,e.k??10).map(e=>({title:e.title??"",url:e.fromurl??e.detail_page??e.objurl??"",snippet:e.site_name??"",..."string"==typeof e.update_time||"number"==typeof e.update_time?{publishedAt:String(e.update_time)}:{},...e.site_name?{source:e.site_name}:{},...e.objurl?{imageUrl:e.objurl}:{},...e.result_page??n?{resultPage:e.result_page??n}:{},..."number"==typeof e.sim_level?{similarityLevel:e.sim_level}:{},...e.item_cate?{category:e.item_cate}:{},...void 0!==e.width?{width:e.width}:{},...void 0!==e.height?{height:e.height}:{}}))}(i);if("serper"===e)return async function(e,t){const i={q:e,num:t.k??10};if(t.country&&(i.gl=t.country),t.freshness){const e={pd:"qdr:d",pw:"qdr:w",pm:"qdr:m",py:"qdr:y"};i.tbs=e[t.freshness]??i.tbs}return t.extra&&Object.assign(i,t.extra),((await Da("search/serper","search",i,{timeoutMs:2e4,retries:1,...t.billing?{billing:{jobRef:t.billing.jobRef,quote:t.billing.quote}}:{}})).organic??[]).slice(0,t.k??10).map(e=>({title:e.title??"",url:e.link??"",snippet:e.snippet??"",...e.date?{publishedAt:e.date}:{},...e.source?{source:e.source}:{}}))}(t,i);if("tavily"===e)return async function(e,t){const i={query:e,max_results:t.k??10,search_depth:"basic"};if(t.freshness){const e={pd:"day",pw:"week",pm:"month",py:"year"};i.time_range=e[t.freshness]??i.time_range}return t.extra&&Object.assign(i,t.extra),((await Da("search/tavily","search",i,{timeoutMs:2e4,retries:1,...t.billing?{billing:{jobRef:t.billing.jobRef,quote:t.billing.quote}}:{}})).results??[]).slice(0,t.k??10).map(e=>({title:e.title??"",url:e.url??"",snippet:e.content??"",...e.published_date?{publishedAt:e.published_date}:{}}))}(t,i);if("brave"===e)return async function(e,t){const i={q:e,count:String(t.k??10)};if(t.country&&(i.country=t.country),t.freshness&&(i.freshness=t.freshness),t.extra)for(const[e,n]of Object.entries(t.extra))"string"!=typeof n&&"number"!=typeof n&&"boolean"!=typeof n||(i[e]=String(n));const n=await Ha("search/brave","res/v1/web/search",i,{timeoutMs:2e4,retries:1,headers:{Accept:"application/json"},...t.billing?{billing:{jobRef:t.billing.jobRef,quote:t.billing.quote}}:{}});return(n.web?.results??[]).slice(0,t.k??10).map(e=>({title:e.title??"",url:e.url??"",snippet:e.description??"",...e.age?{publishedAt:e.age}:{}}))}(t,i);throw new Error(`unsupported provider: ${e}`)}const Uc="40bcd04",Fc="@pawlogic/dl",Dc="/home/user/.local";async function Hc(e){const t=(process.env.CALLBACK_SERVER_URL??"").trim().replace(/\/+$/,""),i=(process.env.DL_PROXY_TOKEN??"").trim();if(!t||!i)return;const n="latest"===e.distTag||"staging"===e.distTag?e.distTag:"unknown",o=e=>{const t=(process.env[e]??"").trim();return t&&/^[A-Za-z0-9_-]+$/.test(t)?t:null},r=o("PI_PROJECT_ID"),a=o("PI_MODE"),s=o("PI_USER_TIER"),l=o("PI_USER_ID"),c=o("PI_PROMPT_ID"),d=o("PI_TOOL_CALL_ID"),u=(process.env.HOSTNAME??S.hostname()??"").trim(),p=u&&/^[A-Za-z0-9_-]+$/.test(u)?u:null,m=new AbortController,h=setTimeout(()=>m.abort(),2e3);try{await fetch(`${t}/sandbox-rpc/dl/selfupdate-event`,{method:"POST",signal:m.signal,headers:{"content-type":"application/json",authorization:`Bearer ${i}`},body:JSON.stringify({trigger:e.trigger,dist_tag:n,outcome:e.outcome,duration_ms:e.durationMs,installed_version:e.installedVersion,build_short_sha:e.buildShortSha,project_id:r,mode:a,user_tier:s,user_id:l,prompt_id:c,tool_call_id:d,sandbox_id:p})})}catch{}finally{clearTimeout(h)}}async function Bc(){const e=(process.env.CALLBACK_SERVER_URL??"").trim().replace(/\/+$/,"");if(!e)return null;const t=await async function(e){const t=new AbortController,i=setTimeout(()=>t.abort(),5e3);try{const i=await fetch(e,{signal:t.signal});return i.ok?(await i.text()).trim():null}catch{return null}finally{clearTimeout(i)}}(`${e}/health`);if(!t)return null;try{const e=JSON.parse(t),i=e.build_short_sha?.trim();return i&&/^[a-f0-9]{7}$/i.test(i)?i.slice(0,7):null}catch{return null}}function Vc(){for(const e of[`${Dc}/lib/node_modules/${Fc}/package.json`,`${Dc}/lib/node_modules/${Fc.replace("@pawlogic/","")}/package.json`])try{if(!o(e))continue;const t=JSON.parse(r(e,"utf8"));if("string"==typeof t.version&&t.version.trim())return t.version}catch{}try{const e=u(m(import.meta.url));for(const t of["../package.json","../../package.json","../../../package.json"]){const i=c(e,t);if(!o(i))continue;const n=JSON.parse(r(i,"utf8"));if(n.name===Fc&&"string"==typeof n.version)return n.version}}catch{}return null}async function Jc(){const e=(process.env.DL_NPM_DIST_TAG??"").trim()||null;return{dl_build_short_sha:Uc,dl_build_full_sha:"40bcd045ce6af4bb65013c42f2f0e7c70d0ec544",npm_dist_tag:e,npm_installed_version:Vc(),callback_server_url:(process.env.CALLBACK_SERVER_URL??"").trim()||null,callback_build_short_sha:await Bc(),updated:!1,skipped_reason:null}}function Kc(e,t){const i=t.replace(/^\/+/,"");var n;n={use_tool:"read",skill:e,relative_path:i,hint:`Call the \`read\` tool with path \`dirname(<location of skill "${e}" in <available_skills>>) + "/${i}"\`.`},process.stdout.write(`${JSON.stringify({ok:!0,...n})}\n`),process.exit(0)}const Gc="/workspace/.stock-media",Yc=209715200,Wc=/^([a-z0-9_-]+):([a-zA-Z0-9_.-]+)$/,Zc=new Map([["image/jpeg","jpg"],["image/jpg","jpg"],["image/png","png"],["image/webp","webp"],["image/gif","gif"],["image/avif","avif"],["video/mp4","mp4"],["video/quicktime","mov"],["video/webm","webm"],["video/x-matroska","mkv"]]);class Xc extends Error{hint;constructor(e,t){super(e),this.hint=t,this.name="StockDownloadError"}}function Qc(e,t){const i=e&&e.length>0?e:t;return d(i)||vs(`--to must be an absolute path; got "${i}"`,"use an absolute /workspace/... path"),i.startsWith("/workspace/")||"/workspace"===i||vs(`--to must be under /workspace/; got "${i}"`,"stock-media downloads only target sandbox /workspace."),i}const ed={name:"openverse",supports:{image:!0,video:!1},async search(e){if("image"!==e.type)return[];const t={q:e.query,page_size:String(e.perProviderLimit)};"landscape"===e.orientation?t.aspect_ratio="wide":"portrait"===e.orientation?t.aspect_ratio="tall":"square"===e.orientation&&(t.aspect_ratio="square"),void 0!==e.minWidth&&(t.size="large");let i=((await Ha("stock-media/openverse","v1/images",t)).results??[]).map(e=>{const t=function(e,t,i){const n=e.toUpperCase(),o=t??"4.0";return{license:"CC0"===n?"CC0 1.0 (Public Domain)":`CC ${n} ${o}`,license_url:i??("CC0"===n?"https://creativecommons.org/publicdomain/zero/1.0/":`https://creativecommons.org/licenses/${e.toLowerCase()}/${o}/`),attribution_required:"CC0"!==n}}(e.license,e.license_version,e.license_url),i=e.creator??"Unknown";return{asset_id:`openverse:${e.id}`,provider:"openverse",type:"image",preview_url:e.thumbnail,download_url:e.url,dimensions:{width:e.width,height:e.height},duration:null,tags:(e.tags??[]).map(e=>e.name).filter(Boolean),author:i,author_url:e.creator_url??"",license:t.license,license_url:t.license_url,attribution_required:t.attribution_required,attribution_text:(n={title:e.title,creator:e.creator,license:t.license},`${n.title?`"${n.title}"`:"Image"}${n.creator?` by ${n.creator}`:""} (${n.license}) via Openverse`),source_url:e.foreign_landing_url??e.url};var n});return void 0!==e.minWidth&&(i=i.filter(t=>t.dimensions.width>=e.minWidth)),i}},td="Pexels License",id="https://www.pexels.com/license/";function nd(e,t){const i=e.filter(e=>"video/mp4"===e.file_type),n=i.length>0?i:e,o=t?n.filter(e=>e.width>=t):n;return(o.length>0?o:n).slice().sort((e,t)=>t.width-e.width)[0]??null}const od="Pixabay Content License",rd="https://pixabay.com/service/license-summary/";function ad(e){return e.split(",").map(e=>e.trim()).filter(e=>e.length>0)}function sd(e,t){const i=[e.large,e.medium,e.small,e.tiny].filter(e=>!!e&&!!e.url);if(0===i.length)return null;const n=t?i.filter(e=>e.width>=t):i;return(n.length>0?n:i).slice().sort((e,t)=>t.width-e.width)[0]??null}const ld={pexels:{name:"pexels",supports:{image:!0,video:!0},async search(e){const t={query:e.query,per_page:String(e.perProviderLimit)};if(e.orientation&&(t.orientation=e.orientation),"image"===e.type){let i=((await Ha("stock-media/pexels","v1/search",t)).photos??[]).map(e=>{const t=e.alt?e.alt.split(/[,\s]+/).filter(e=>e.length>1):[];return{asset_id:`pexels:${e.id}`,provider:"pexels",type:"image",preview_url:e.src.medium??e.src.small??e.src.tiny??e.src.original,download_url:e.src.original,dimensions:{width:e.width,height:e.height},duration:null,tags:t,author:e.photographer,author_url:e.photographer_url,license:td,license_url:id,attribution_required:!1,attribution_text:`Photo by ${e.photographer} on Pexels`,source_url:e.url}});return e.minWidth&&(i=i.filter(t=>t.dimensions.width>=e.minWidth)),i}let i=function(e,t){const i=e.videos??[],n=[];for(const e of i){const i=nd(e.video_files,t);i&&n.push({asset_id:`pexels:${e.id}`,provider:"pexels",type:"video",preview_url:e.image,download_url:i.link,dimensions:{width:i.width,height:i.height},duration:e.duration,tags:e.tags??[],author:e.user.name,author_url:e.user.url,license:td,license_url:id,attribution_required:!1,attribution_text:`Video by ${e.user.name} on Pexels`,source_url:e.url})}return n}(await Ha("stock-media/pexels","videos/search",t),e.minWidth);return void 0!==e.durationMin&&(i=i.filter(t=>(t.duration??0)>=e.durationMin)),void 0!==e.durationMax&&(i=i.filter(t=>(t.duration??0)<=e.durationMax)),i}},pixabay:{name:"pixabay",supports:{image:!0,video:!0},async search(e){const t={q:e.query,per_page:String(e.perProviderLimit)};if("landscape"===e.orientation?t.orientation="horizontal":"portrait"===e.orientation&&(t.orientation="vertical"),"image"===e.type)return t.image_type="photo",void 0!==e.minWidth&&(t.min_width=String(e.minWidth)),((await Ha("stock-media/pixabay","api",t)).hits??[]).map(e=>({asset_id:`pixabay:${e.id}`,provider:"pixabay",type:"image",preview_url:e.webformatURL??e.previewURL,download_url:e.largeImageURL??e.webformatURL,dimensions:{width:e.imageWidth,height:e.imageHeight},duration:null,tags:ad(e.tags),author:e.user,author_url:`https://pixabay.com/users/${encodeURIComponent(e.user)}/`,license:od,license_url:rd,attribution_required:!1,attribution_text:`Image by ${e.user} on Pixabay`,source_url:e.pageURL}));let i=function(e,t){const i=e.hits??[],n=[];for(const e of i){const i=sd(e.videos,t);i&&n.push({asset_id:`pixabay:${e.id}`,provider:"pixabay",type:"video",preview_url:e.picture_id?`https://i.vimeocdn.com/video/${e.picture_id}_640x360.jpg`:e.userImageURL,download_url:i.url,dimensions:{width:i.width,height:i.height},duration:e.duration,tags:ad(e.tags),author:e.user,author_url:`https://pixabay.com/users/${encodeURIComponent(e.user)}/`,license:od,license_url:rd,attribution_required:!1,attribution_text:`Video by ${e.user} on Pixabay`,source_url:e.pageURL})}return n}(await Ha("stock-media/pixabay","api/videos",t),e.minWidth);return void 0!==e.durationMin&&(i=i.filter(t=>(t.duration??0)>=e.durationMin)),void 0!==e.durationMax&&(i=i.filter(t=>(t.duration??0)<=e.durationMax)),i}},openverse:ed},cd=["pexels","pixabay","openverse"],dd=new Set(["landscape","portrait","square"]),ud=new Set(["image","video"]),pd=["fallback","fanout"];function md(e,t,i){const n=Number(e);return(!Number.isFinite(n)||!Number.isInteger(n)||n<1||n>i)&&vs(`${t} must be a positive integer ≤ ${i}; got ${e}`),n}function hd(e,t){const i=Number(e);return(!Number.isFinite(i)||i<0)&&vs(`${t} must be a non-negative number; got ${e}`),i}function fd(e,t){return t instanceof Sa?{provider:e,status:t.status,reason:`${t.status}: ${t.message}`}:t instanceof Jr?{provider:e,reason:`proxy-client: ${t.message}${t.hint?` (${t.hint})`:""}`}:t instanceof Error?{provider:e,reason:t.message}:{provider:e,reason:String(t)}}function gd(e,t){const i=[],n=new Set,o=e.map(()=>0);let r=e.filter(e=>e.length>0).length;for(;i.length<t&&r>0;){r=0;for(let a=0;a<e.length;a++){const s=e[a];if(o[a]<s.length){const e=s[o[a]];if(o[a]+=1,!n.has(e.asset_id)&&(n.add(e.asset_id),i.push(e),i.length>=t))break;o[a]<s.length&&(r+=1)}}}return i}const vd=(e,t)=>ld[e].search(t);async function yd(e){try{await Ua({jobRef:e.jobRef,quote:e.quote,reason:e.reason,chargeId:e.receipt.charge_id})}catch(t){process.stderr.write(`${JSON.stringify({level:"warn",event:"dl_billing_refund_failed",job_ref:e.jobRef,reason:e.reason,error:t instanceof Error?t.message:String(t)})}\n`)}}function bd(e,t){const i={};for(const t of["job_ref","task_id","data"])void 0!==e[t]&&(i[t]=e[t]);return void 0!==e.error&&null!==e.error&&(i.error=e.error),i}const _d=new oe;_d.name("dl").description(["DramaLand CLI","","Generation:"," lipsync transcribe generate-image-prompt generate-image-ref generate-video generate-music generate-sound generate-lyrics"," generate-tts analyze-beats render-caption motion-control detect-shots download-media","","Geo:"," geocode streetview <command> places <command> static-map","","Pipelines:"," ffmpeg remotion poll search stock <command> fetch","","Local:"," self-update script <command> skill <command>","","Resources:"," artifact <command> asset <command> knowledge <command>","","Batch: pass --jobs '<inline-json>' per verb (recommended; --jobs-file is legacy).","Run `dl <command> --help` for the full per-command shape.","","Output: JSON on stdout when ok, JSON {ok:false,code,error,hint?} on stderr on failure.","Codes: E_FILE_MISSING / E_FILE_PARSE / E_SCHEMA / E_UNKNOWN_OPTION (exit 2)"," E_INSUFFICIENT_CREDITS / E_BACKEND (exit 1)"].join("\n")).version(function(){try{const e=u(m(import.meta.url));for(const t of["./package.json","../package.json","../../package.json"])try{const i=JSON.parse(r(c(e,t),"utf8"));if("string"==typeof i.version&&i.version.trim())return`${i.version} (build ${Uc})`}catch{}}catch{}return`unknown (build ${Uc})`}()),function(e){e.command("login").description("Log in with your ilands account for local (non-sandbox) use — opens the browser (Clerk OAuth). No-op inside the hosted sandbox (credentials are already injected). Shared with the `ilands` bin.").option("--client-id <id>","OAuth client id (default: ILANDS_OAUTH_CLIENT_ID)").option("--issuer <url>","OAuth issuer (default: https://clerk.ilands.ai)").option("--gateway <url>","BYOA gateway base URL (stored with the login)").option("--timeout-seconds <n>","how long to wait for the browser callback (default 180)").option("--no-browser","print the authorize URL instead of opening a browser").action(async e=>{const t=[];e.clientId&&t.push(`--client-id=${e.clientId}`),e.issuer&&t.push(`--issuer=${e.issuer}`),e.gateway&&t.push(`--gateway=${e.gateway}`),e.timeoutSeconds&&t.push(`--timeout-seconds=${e.timeoutSeconds}`),!1===e.browser&&t.push("--no-browser"),ul(await dl(t,process.env))}),e.command("logout").description("Clear the stored local ilands login (both `dl` and `ilands`). No-op inside the hosted sandbox.").action(async()=>{ul(await async function(e,t){if(ya(t).sandbox)return{exitCode:0,stdout:cl({ok:!0,logged_out:!1,mode:"sandbox",hint:"running with sandbox-injected credentials; there is no byoa login to clear here."})};const i=null!==ca(t);return function(e=process.env){"darwin"===process.platform&&aa(),"linux"===process.platform&&ta("secret-tool")&&la(),function(e){try{a(ea(e),{force:!0})}catch{}}(e)}(t),{exitCode:0,stdout:cl({ok:!0,logged_in:!1,cleared:i})}}(0,process.env))}),e.command("whoami").description("Show the current credential mode (sandbox / byoa login / none).").action(async()=>{ul(await async function(e,t){const i=ya(t);if(i.sandbox)return{exitCode:0,stdout:cl({ok:!0,mode:"sandbox",sandbox_flavors:i.flavors,hint:"running with sandbox-injected credentials; byoa login is not used here."})};const n=ca(t);if(!n)return{exitCode:1,stderr:cl({ok:!1,logged_in:!1,message:"not logged in",hint:"run `ilands login` (or `dl login`)"})};const o=Math.floor(Date.now()/1e3);return{exitCode:0,stdout:cl({ok:!0,mode:"byoa",logged_in:!0,user:n.user,issuer:n.issuer,gateway_url:va(n,t),access_token_expires_at:n.expires_at,access_token_expired:n.expires_at<=o,has_refresh_token:!!n.refresh_token})}}(0,process.env))})}(_d),function(e){e.command("self-update").description("Reinstall @pawlogic/dl from npmjs.com. Shows dl build SHA vs live callback-server build SHA.").addHelpText("after",["","Sandbox 内部 dl 由 npm install -g --prefix=/home/user/.local @pawlogic/dl@<tag> 装出。","沙箱 wrapper `/usr/local/bin/dl` 每次调用前跑 dl-npm-update.sh(TTL 300s)。本命令绕开 TTL。","","DL_NPM_DIST_TAG env 由 template bake 时按 alias 注入:"," prod (pi-sandbox-dl) → latest"," staging (pi-sandbox-dl-staging) → staging"," PR preview (pi-sandbox-dl-pr-N) → 空 → 本命令 no-op,沙箱 dl 锁版","","CALLBACK_SERVER_URL 用于通过 GET /health 对账 dl ↔ callback-server 是否同 SHA。","","Flags:"," --check 不装,只打印当前状态 JSON"," --force 绕过 TTL 强制重装(默认行为也是绕过)"].join("\n")).option("--check","只打状态 JSON,不联 registry").option("--force","绕过 300s TTL 缓存(CLI 默认就绕)").action(async e=>{const t=e.check?await Jc():await async function(e={}){const t=await Jc(),i=e.force?"cli_force":"cli";if(!t.npm_dist_tag)return t.skipped_reason="DL_NPM_DIST_TAG unset (PR preview / local — no npm self-update)",await Hc({trigger:i,distTag:t.npm_dist_tag,outcome:"no_tag",durationMs:null,installedVersion:t.npm_installed_version,buildShortSha:"unknown"!==t.dl_build_short_sha?t.dl_build_short_sha:null}),t;const n=Date.now();let o="ok";try{const e=y("npm",["install","-g",`--prefix=${Dc}`,"--silent","--no-audit","--no-fund","--no-update-notifier","--force",`${Fc}@${t.npm_dist_tag}`],{env:{...process.env,HOME:"/home/user"},stdio:"pipe",timeout:3e4});if(0!==e.status)return t.skipped_reason=`npm install exit=${e.status??"signal"}: ${(e.stderr??Buffer.from("")).toString("utf8").slice(0,200)}`,o="SIGTERM"===e.signal?"timeout":"npm_fail",await Hc({trigger:i,distTag:t.npm_dist_tag,outcome:o,durationMs:Date.now()-n,installedVersion:t.npm_installed_version,buildShortSha:"unknown"!==t.dl_build_short_sha?t.dl_build_short_sha:null}),t}catch(e){return t.skipped_reason=`npm install threw: ${String(e).slice(0,200)}`,await Hc({trigger:i,distTag:t.npm_dist_tag,outcome:"npm_fail",durationMs:Date.now()-n,installedVersion:t.npm_installed_version,buildShortSha:"unknown"!==t.dl_build_short_sha?t.dl_build_short_sha:null}),t}try{v("sh",["-c","printf '%s' \"$(date +%s)\" > /tmp/dl-npm-checkedat"],{stdio:"ignore"})}catch{}try{v("ln",["-sf","/usr/local/bin/dl",`${Dc}/bin/dl`],{stdio:"ignore"})}catch{}return t.npm_installed_version=Vc(),t.updated=!0,t.skipped_reason=null,await Hc({trigger:i,distTag:t.npm_dist_tag,outcome:o,durationMs:Date.now()-n,installedVersion:t.npm_installed_version,buildShortSha:"unknown"!==t.dl_build_short_sha?t.dl_build_short_sha:null}),t}({force:e.force}),i="unknown"!==t.dl_build_short_sha&&null!==t.callback_build_short_sha&&t.dl_build_short_sha===t.callback_build_short_sha;gs({ok:!0,...t,build_short_sha_aligned_with_callback:i,hint:i?null:"dl build SHA 跟 live callback-server 的 build SHA 对不齐 —— 可能需要 staging-deploy(staging) 或 prod-deploy(latest) 把 dl 推到同一个 commit"})})}(_d),function(e){e.command("script").description("Local python3 sandbox — ulimit CPU seconds / 64 KiB output.").command("exec").description(["Run a python3 transform. --inputs-file keys are injected as top-level variables;","assign to `result` to return a value.",""," --script-file=<path|-> python source; `-` reads stdin (preferred for one-off scripts)."," --inputs-file=<path|-> JSON object whose keys become globals; `-` reads stdin.","","Example (script via stdin, inputs from disk):"," cat <<'PY' | dl script exec --script-file=- --inputs-file=/workspace/inputs.json --timeout=5"," result = sum(items)"," PY"].join("\n")).option("--script <text>",'RECOMMENDED: python source inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --script "$(cat script.py)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --script-file.').option("--script-file <path|->",'LEGACY: python source via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --script "$(cat file)". Use --script-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--inputs <inline-json>",'RECOMMENDED: JSON object whose keys become globals, inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --inputs "$(cat inputs.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --inputs-file.').option("--inputs-file <path|->",'LEGACY: JSON object whose keys become globals, via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --inputs "$(cat file)". Use --inputs-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--timeout <s>","CPU seconds (1–5, default 5)",e=>Number(e)).option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").action(async e=>{e.printSchema&&Js({command:"dl script exec",summary:"Run a python3 transform in the local sandbox; assign `result` to return a value.",scalars:[{name:"timeout",type:"integer",required:!1,description:"CPU seconds (1–5, default 5)"},{name:"script",type:"string",required:!1,description:"RECOMMENDED inline python source (required: pass this or --script-file)"},{name:"inputs",type:"string",required:!1,description:"RECOMMENDED inline JSON object whose keys become globals (sibling of --inputs-file)"}],files:[{name:"script-file",required:!1,kind:"text",description:"LEGACY: python source via file/stdin (prefer --script inline)",example:"result = sum(items)\n"},{name:"inputs-file",required:!1,kind:"object",description:"LEGACY: JSON object of globals via file/stdin (prefer --inputs inline)",example:'{"items":[1,2,3]}'}]});let t,i,n="",o={};e.script||e.scriptFile||ys("E_SCHEMA","--script is required (pass the python source inline, or use --script-file for the legacy file/stdin path)","run `dl script exec --print-schema` to see the expected shape",{flag:"--script"});try{const r=await hs(e.script?String(e.script):void 0,e.scriptFile?String(e.scriptFile):void 0,{inline:"--script",file:"--script-file"});r&&(n=r.raw,t=r.label);const a=await ms(e.inputs?String(e.inputs):void 0,e.inputsFile?String(e.inputsFile):void 0,{inline:"--inputs",file:"--inputs-file"});a&&(o=a.data,i=a.source.label)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:"script exec",script_source:t??null,inputs:o,inputs_source:i??null});const r=void 0!==e.timeout?Number(e.timeout):void 0,a=await async function(e,t={},i={}){const n=Date.now(),o=Math.max(1,Math.min(i.timeoutSeconds??5,5)),r=1e3*(o+1),a=`ulimit -t ${o} 2>/dev/null; ulimit -v 65536 2>/dev/null; exec python3 -I -c "$PY_SCRIPT"`,s={PY_SCRIPT:["import json as __dl_json","import sys as __dl_sys","__dl_inputs_raw = __dl_sys.stdin.read()","__dl_inputs = __dl_json.loads(__dl_inputs_raw) if __dl_inputs_raw else {}","for __dl_k, __dl_v in __dl_inputs.items():"," globals()[__dl_k] = __dl_v","__dl_input_keys = set(__dl_inputs.keys())","# --- user script ---",e,"# --- end user script ---","__dl_result = globals().get('result')","__dl_outputs = {}","for __dl_k, __dl_v in list(globals().items()):"," if __dl_k.startswith('_') or __dl_k == 'result':"," continue"," if __dl_k in __dl_input_keys:"," continue"," if __dl_k in ('json','sys') or callable(__dl_v) or isinstance(__dl_v, type):"," continue"," try:"," __dl_json.dumps(__dl_v, default=str)"," except Exception:"," continue"," __dl_outputs[__dl_k] = __dl_v",`__dl_sys.stdout.write(${JSON.stringify(jc)} + __dl_json.dumps({'result': __dl_result, 'output_variables': __dl_outputs}, default=str) + ${JSON.stringify(Cc)} + '\\n')`].join("\n"),LANG:"C.UTF-8",PATH:process.env.PATH??"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},l=g("/bin/sh",["-c",a],{env:s,stdio:["pipe","pipe","pipe"]});let c="",d="",u=0,p=0;l.stdout.on("data",e=>{if(u>=Nc)return;const t=Nc-u,i=e.length>t?e.subarray(0,t):e;c+=i.toString("utf8"),u+=i.length}),l.stderr.on("data",e=>{if(p>=Nc)return;const t=Nc-p,i=e.length>t?e.subarray(0,t):e;d+=i.toString("utf8"),p+=i.length}),l.stdin.write(JSON.stringify(t)),l.stdin.end();let m=!1;const h=setTimeout(()=>{m=!0,l.kill("SIGKILL")},r+6e3-6e3+6e3),f=await new Promise(e=>{l.on("close",(t,i)=>e({code:t??-1,signal:i}))});clearTimeout(h);const v=Date.now()-n,y=Buffer.byteLength(e,"utf8"),b=m||"SIGKILL"===f.signal||"SIGXCPU"===f.signal||137===f.code||152===f.code;let _,w={},k=c;const x=c.lastIndexOf(jc),S=c.lastIndexOf(Cc);if(-1!==x&&-1!==S&&S>x){const e=c.slice(x+10,S);try{const t=JSON.parse(e);_=t.result,w=t.output_variables??{},k=c.slice(0,x)}catch{}}return b?{success:!1,result:null,output_variables:{},error:`script timed out (CPU limit ${o}s)`,stdout:k,stderr:d,duration_ms:v,script_size_bytes:y,timed_out:!0,exit_code:f.code}:0!==f.code?{success:!1,result:null,output_variables:{},error:d.trim().slice(-500)||`script exited with code ${f.code}`,stdout:k,stderr:d,duration_ms:v,script_size_bytes:y,timed_out:!1,exit_code:f.code}:{success:!0,result:_,output_variables:w,error:null,stdout:k,stderr:d,duration_ms:v,script_size_bytes:y,timed_out:!1,exit_code:f.code}}(n,o,{timeoutSeconds:r});a.success||vs(a.error??`script exited with code ${a.exit_code}`,void 0,{stdout:a.stdout,stderr:a.stderr,exit_code:a.exit_code,duration_ms:a.duration_ms,script_size_bytes:a.script_size_bytes,timed_out:a.timed_out}),gs({ok:!0,success:!0,result:a.result,output_variables:a.output_variables,error:null,duration_ms:a.duration_ms,script_size_bytes:a.script_size_bytes,stdout:a.stdout,stderr:a.stderr})})}(_d),function(e){const t=e.command("skill").description("Return a pointer the model hands to the built-in `read` tool; no file I/O happens here.");t.command("read").description("Return a `read`-tool pointer for this skill's `SKILL.md`.").requiredOption("--name <name>","skill name (matches `<name>` in `<available_skills>`)").action(e=>{Kc(String(e.name),"SKILL.md")}),t.command("resource").description("Return a `read`-tool pointer for a file inside a skill's directory.").option("--skill <name>","skill name (matches `<name>` in `<available_skills>`)").option("--name <name>","legacy alias of --skill (kept for back-compat with older skill md)").requiredOption("--path <path>","path inside the skill's directory, relative to the skill root").action(e=>{const t=String(e.skill??e.name??"");t||vs("either --skill or --name is required","e.g. dl skill resource --skill=video-breakdown --path=resources/analysis_system_prompt.txt"),Kc(t,String(e.path))});for(const e of["activate","compile","draft-create","draft-update","fork","publish","search","validate"])t.command(e,{hidden:!0}).description("skill authoring command — NOT implemented on Pi").allowUnknownOption(!0).action(()=>Ec(`skill ${e}`,"skill authoring commands (activate/compile/draft-*/fork/publish/search/validate) are iLands-runtime-only. On Pi, read a skill file with the built-in `read` tool using `dirname(<location>) + <relative-path>`."))._hidden=!0}(_d),function(e){const t=e.command("artifact").description("Versioned slot store for skill artifacts (drafts, validation, canonical promotion).").addHelpText("after",["","Storage layout per project:"," slots/<slot> + versions/<n> — drafts, latest version pointer."," canonical/<slot> — promoted, immutable."," receipts/<autoId> — finalize / promote event stream.","","Status: draft → verified (finalize) → stale (upstream changed)"," any → invalidated (terminal)."].join("\n"));t.command("list").description("List every slot header in the current session.").option("--quiet","emit only {ok,count,slots:[{slot,status,currentVersion}]}").action(async e=>{try{const t=(ol(await nl("list",{})).slots??[]).map(t=>({slot:t.slotName,status:t.status,currentVersion:t.currentVersion,contentType:t.contentType,...e.quiet?{}:{updatedAt:t.updatedAt},...e.quiet?{}:t.inputFence?{inputFence:t.inputFence}:{}}));gs({ok:!0,count:t.length,slots:t})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("read").description("Read a slot version (default: current).").requiredOption("--slot <name>").option("--version <n>","version number (default: header.currentVersion)",e=>parseInt(e,10)).option("--quiet","omit metadata, return content only").action(async e=>{try{const t=ol(await nl("read",{slot:String(e.slot),...void 0!==e.version?{version:e.version}:{}})),i=t.header,n=t.version;n||vs(`slot has no version content: ${e.slot}`),e.quiet&&gs({ok:!0,content:n.content}),gs({ok:!0,slot:i?.slotName,version:n.version,content:n.content,contentType:n.contentType,changeType:n.changeType,contentHash:n.contentHash,status:n.status,createdAt:n.createdAt,currentVersion:i?.currentVersion,headerStatus:i?.status,...n.changeSummary?{changeSummary:n.changeSummary}:{},...n.inputFence?{inputFence:n.inputFence}:{}})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("write").description("Write a new version of a slot. Resets status to draft.").addHelpText("after",["","`--contract` is OPTIONAL. Without it, write is best-effort: JSON parse +","state-machine checks only. With it, the slot's `schema_ref` is run through","ajv in RELAXED mode (every `additionalProperties: false` in the schema is","flipped to `true` before compile, so extra domain fields are accepted","while `required` / `type` / `enum` / `minLength` still apply). Pass","`--strict-schema` to use the contract schema exactly as written.","Content-type mismatches with the contract downgrade to warnings.","","Example (stdin):"," cat <<EOF | dl artifact write --slot=music_candidate --content-type=application/json --content-file=-",' {"service":"banana-pro","prompt":"a cat in a hat"}'," EOF"].join("\n")).option("--slot <name>").option("--content <text>",'RECOMMENDED: content body inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --content "$(cat body.json)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --content-file.').option("--content-file <path|->",'LEGACY: content body as raw text (JSON for application/json) via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --content "$(cat file)". Use --content-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--contract <path>","absolute path to artifact_contract.json (optional)").option("--strict-schema","validate against the contract schema as-written (default: relaxed — `additionalProperties: false` is flipped to `true`)").option("--content-type <ct>","MIME type","application/json").option("--change-summary <text>","human-readable summary of the write").option("--dry-run","validate but do not persist").option("--include-content","include the full written content in the response (default: omitted)").option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").option("--skip-url-check","skip URL reachability preflight for JSON content").action(async e=>{e.printSchema&&Js({command:"dl artifact write",summary:"Write a new version of a slot.",scalars:[{name:"slot",type:"string",required:!0,description:"slot name"},{name:"content-type",type:"string",required:!1,description:"MIME (default application/json)"},{name:"contract",type:"string",required:!1,description:"absolute path to artifact_contract.json (optional)"},{name:"strict-schema",type:"boolean",required:!1,description:"validate against contract schema as-written (default: relaxed)"},{name:"change-summary",type:"string",required:!1,description:""},{name:"dry-run",type:"boolean",required:!1,description:""},{name:"include-content",type:"boolean",required:!1,description:"include full written content in response (default: omitted)"},{name:"skip-url-check",type:"boolean",required:!1,description:"skip URL reachability preflight for JSON content"},{name:"content",type:"string",required:!1,description:"RECOMMENDED inline raw-text content body (required: pass this or --content-file)"}],files:[{name:"content-file",required:!1,kind:"text",description:"LEGACY: content body via file/stdin (prefer --content inline)",example:'{"service":"banana-pro","prompt":"a cat"}'}]}),e.slot||ys("E_SCHEMA","--slot is required","run `dl artifact write --print-schema` for the expected shape",{flag:"--slot"}),e.content||e.contentFile||ys("E_SCHEMA","--content is required (pass the content inline, or use --content-file for the legacy file/stdin path)","run `dl artifact write --print-schema` to see the expected shape",{flag:"--content"});{const i=function(e){const t=e.split(";")[0]?.trim().toLowerCase()??"";return!(!t||"application/json"!==t&&!t.startsWith("text/")&&!t.endsWith("+json")&&!t.endsWith("+xml")&&"application/xml"!==t&&"application/yaml"!==t&&"application/x-yaml"!==t)}(t=String(e.contentType))?null:{message:`artifact content-type "${t}" is not text/JSON — artifact slots store text only`,hint:Vs,extra:{contentType:t}};i&&ys("E_SCHEMA",i.message,i.hint,i.extra)}var t;let i,n="";try{const t=await hs(e.content?String(e.content):void 0,e.contentFile?String(e.contentFile):void 0,{inline:"--content",file:"--content-file"});t&&(n=t.raw,i=t.label)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:"artifact write",slot:String(e.slot),content_source:i??null,content_bytes:Buffer.byteLength(n,"utf8")});{const e=function(e){return function(e){return/[\u0000\uFFFD]/.test(e)}(e)?{message:"artifact content contains binary bytes (NUL or U+FFFD replacement chars) — looks like a binary file read as text",hint:Vs,extra:{reason:"binary-content"}}:null}(n);e&&ys("E_SCHEMA",e.message,e.hint,e.extra)}if(!e.skipUrlCheck&&String(e.contentType).includes("json")){let e;try{e=JSON.parse(n)}catch{e=void 0}void 0!==e&&await sl(Zs(e),!1)}const o=e.contract?ll(String(e.contract),String(e.slot)):void 0;try{gs({ok:!0,...al(rl(ol(await nl("write",{slot:String(e.slot),content:n,contentType:String(e.contentType),...o?{contract:o.contract,schemas:o.schemas}:{},...e.strictSchema?{strictSchema:!0}:{},...e.changeSummary?{changeSummary:String(e.changeSummary)}:{},...e.dryRun?{dryRun:!0}:{}}))),["slotName","version","status","contentHash","warnings"],!!e.includeContent)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("patch").description("Text patch: unique find+replace. Writes a new version (changeType=patch).").requiredOption("--slot <name>").requiredOption("--from <string>","exact substring to replace (must match exactly once)").requiredOption("--to <string>","replacement string").option("--change-summary <text>").option("--dry-run","report what would change, do not persist").option("--include-content","include full patched content in response (default: omitted)").option("--skip-url-check","skip URL reachability preflight for --to text").action(async e=>{await sl(function(e){const t=new Set,i=[];for(const n of e.matchAll(Ws)){const e=Qs(n[0]);e&&!t.has(e)&&(t.add(e),i.push({path:"$.to",url:e}))}return i}(String(e.to)),!!e.skipUrlCheck);try{gs({ok:!0,...al(rl(ol(await nl("patch",{slot:String(e.slot),from:String(e.from),to:String(e.to),...e.changeSummary?{changeSummary:String(e.changeSummary)}:{},...e.dryRun?{dryRun:!0}:{}}))),["slotName","version","status","contentHash"],!!e.includeContent)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("patch-json").description("Atomic JSONPath-lite patch on a slot's JSON content (set/merge/append/delete).").addHelpText("after",["","`--operations-file` is a JSON array of `{path, op, value?}` entries."," path — JSONPath-lite: dot/bracket access only (`a.b.c[2]`); no filters / wildcards"," op — one of: set | merge | append | delete"," value — required for set/merge/append; omitted for delete","","Example (stdin):"," cat <<EOF | dl artifact patch-json --slot=storyboard --operations-file=-",' [{"path":"segments[0].text","op":"set","value":"hi"}]'," EOF"].join("\n")).option("--slot <name>").option("--operations <inline-json>",'RECOMMENDED: JSON array of {path,op,value?} inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --operations "$(cat ops.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --operations-file.').option("--operations-file <path|->",'LEGACY: JSON array of {path,op,value?} via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --operations "$(cat file)". Use --operations-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--change-summary <text>").option("--dry-run","report op count, do not persist").option("--include-content","include full patched content in response (default: omitted)").option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").option("--skip-url-check","skip URL reachability preflight for operations[].value").action(async e=>{e.printSchema&&Js({command:"dl artifact patch-json",summary:"Atomic JSONPath-lite patch on a slot's JSON content.",scalars:[{name:"slot",type:"string",required:!0,description:"slot name"},{name:"change-summary",type:"string",required:!1,description:""},{name:"dry-run",type:"boolean",required:!1,description:""},{name:"include-content",type:"boolean",required:!1,description:"include full patched content in response (default: omitted)"},{name:"skip-url-check",type:"boolean",required:!1,description:"skip URL reachability preflight for operations[].value"},{name:"operations",type:"string",required:!1,description:"RECOMMENDED inline JSON array of {path,op,value?} (required: pass this or --operations-file)"}],files:[{name:"operations-file",required:!1,kind:"array",description:"LEGACY: array of {path,op,value?} via file/stdin (prefer --operations inline)",example:'[{"path":"segments[0].text","op":"set","value":"hi"}]'}]}),e.slot||ys("E_SCHEMA","--slot is required","run `dl artifact patch-json --print-schema` for the expected shape",{flag:"--slot"}),e.operations||e.operationsFile||ys("E_SCHEMA","--operations is required (pass the JSON array inline, or use --operations-file for the legacy file/stdin path)","run `dl artifact patch-json --print-schema` to see the expected shape",{flag:"--operations"});let t,i=[];try{const n=await async function(e,t,i){const n="string"==typeof e&&""!==e,o="string"==typeof t&&""!==t;return n&&o&&ps(i),n?us(e,i.inline):o?ds(t,i.file):void 0}(e.operations?String(e.operations):void 0,e.operationsFile?String(e.operationsFile):void 0,{inline:"--operations",file:"--operations-file"});n&&(i=n.data,t=n.source.label)}catch(e){throw e instanceof wa&&bs(e),e}if(0===i.length&&ys("E_SCHEMA","--operations must be a non-empty JSON array",void 0,{flag:"--operations"}),_s({command:"artifact patch-json",slot:String(e.slot),operations:i,operations_source:t??null}),!e.skipUrlCheck){const e=[];for(let t=0;t<i.length;t++){const n=i[t].value;if(void 0!==n)for(const i of Zs(n,`$.operations[${t}].value`))e.push(i)}await sl(e,!1)}try{gs({ok:!0,...al(rl(ol(await nl("patch-json",{slot:String(e.slot),operations:i,...e.changeSummary?{changeSummary:String(e.changeSummary)}:{},...e.dryRun?{dryRun:!0}:{}}))),["slotName","version","status","contentHash"],!!e.includeContent)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("diff").description("Line-level diff between two versions of a slot (default: current vs. current-1).").requiredOption("--slot <name>").option("--from <n>","older version",e=>parseInt(e,10)).option("--to <n>","newer version (default: current)",e=>parseInt(e,10)).option("--quiet","just return patch string").action(async e=>{try{const t=ol(await nl("read",{slot:String(e.slot)})).header;t||vs(`slot not found: ${e.slot}`);const i=Number(t?.currentVersion??1),n=e.to??i,o=e.from??Math.max(1,n-1);o===n&&gs({ok:!0,slot:e.slot,from:o,to:n,unchanged:!0,diff:""});const[r,a]=await Promise.all([nl("read",{slot:String(e.slot),version:o}),nl("read",{slot:String(e.slot),version:n})]),s=ol(r),l=ol(a),c=function(e,t){const i=e.split("\n"),n=t.split("\n"),o=i.length,r=n.length,a=Array.from({length:o+1},()=>new Array(r+1).fill(0));for(let e=0;e<o;e++)for(let t=0;t<r;t++)a[e+1][t+1]=i[e]===n[t]?a[e][t]+1:Math.max(a[e+1][t],a[e][t+1]);const s=[];let l=o,c=r;for(;l>0&&c>0;)i[l-1]===n[c-1]?(s.push({type:"ctx",line:i[l-1]}),l--,c--):a[l][c-1]>=a[l-1][c]?(s.push({type:"add",line:n[c-1]}),c--):(s.push({type:"del",line:i[l-1]}),l--);for(;l>0;)s.push({type:"del",line:i[l-1]}),l--;for(;c>0;)s.push({type:"add",line:n[c-1]}),c--;return s.reverse()}(String(s.version?.content??""),String(l.version?.content??"")),d=function(e){return e.map(e=>"add"===e.type?`+${e.line}`:"del"===e.type?`-${e.line}`:` ${e.line}`).join("\n")}(c);e.quiet&&gs({ok:!0,diff:d}),gs({ok:!0,slot:e.slot,from:o,to:n,added:c.filter(e=>"add"===e.type).length,deleted:c.filter(e=>"del"===e.type).length,diff:d})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("validate").description("Run contract validation without changing state. Returns issues + warnings + staleness.").addHelpText("after",["","`--contract` is OPTIONAL. Without it, only state-machine + emptiness +","staleness checks run. With it, schema is validated in RELAXED mode unless","`--strict-schema` is passed (see `dl artifact write --help`)."].join("\n")).requiredOption("--slot <name>").option("--contract <path>","absolute path to artifact_contract.json (optional)").option("--strict-schema","validate against the contract schema as-written (default: relaxed)").option("--quiet").action(async e=>{try{const t=e.contract?ll(String(e.contract),String(e.slot)):void 0,i=ol(await nl("validate",{slot:String(e.slot),...t?{contract:t.contract,schemas:t.schemas}:{},...e.strictSchema?{strictSchema:!0}:{}}));e.quiet&&gs({ok:!0,verified:i.verified,isStale:i.isStale,issueCount:Array.isArray(i.issues)?i.issues.length:0}),gs({ok:!0,...rl(i)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("fork").description("Copy the latest version of --source into --target as a new draft (changeType=fork).").requiredOption("--source <name>").requiredOption("--target <name>").option("--dry-run").option("--include-content","include full forked content in response (default: omitted)").action(async e=>{try{gs({ok:!0,...al(rl(ol(await nl("fork",{source:String(e.source),target:String(e.target),...e.dryRun?{dryRun:!0}:{}}))),["slotName","version","changeType"],!!e.includeContent)})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("finalize").description("Verify slot against its contract. mode=verify_and_promote also flips draft→verified, writes canonical, emits receipt.").addHelpText("after",["","`--contract` is OPTIONAL. Without it, only state-machine + emptiness +","staleness checks run; the slot still flips to `verified` (or promotes","in `verify_and_promote` mode). With it, schema validates in RELAXED mode","unless `--strict-schema` is passed (see `dl artifact write --help`)."].join("\n")).requiredOption("--slot <name>").option("--contract <path>","absolute path to artifact_contract.json (optional)").option("--strict-schema","validate against the contract schema as-written (default: relaxed)").option("--mode <mode>","verify | verify_and_promote","verify").option("--dry-run","never promote, even if mode=verify_and_promote").option("--include-content","include full finalized content in response (default: omitted)").action(async e=>{["verify","verify_and_promote"].includes(String(e.mode))||vs(`unsupported mode: ${e.mode}`,'use "verify" or "verify_and_promote".');try{const t=e.contract?ll(String(e.contract),String(e.slot)):void 0,i=e.dryRun?"verify":String(e.mode);gs({ok:!0,...al(rl(ol(await nl("finalize",{slot:String(e.slot),mode:i,...t?{contract:t.contract,schemas:t.schemas}:{},...e.strictSchema?{strictSchema:!0}:{}}))),["slotName","version","verified","promoted","status","canonicalId"],!!e.includeContent),...e.dryRun?{dryRun:!0}:{}})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("select").description("NOT implemented — use `artifact finalize --mode=verify_and_promote` to lock a canonical version.").requiredOption("--slot <name>").option("--quiet").action(()=>{vs("dl artifact select is not implemented on pi","pi does not model active variants; use `artifact finalize --mode=verify_and_promote` to lock a canonical version instead.")})._hidden=!0,t.command("canonical").description("Read the canonical (promoted) snapshot of a slot, if any.").requiredOption("--slot <name>").option("--quiet").action(async e=>{try{const t=ol(await nl("canonical",{slot:String(e.slot)})).canonical??null;t||vs(`no canonical promotion for slot: ${e.slot}`),e.quiet&&gs({ok:!0,content:t.content,contentHash:t.contentHash}),gs({ok:!0,...t})}catch(e){vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){const t=e.command("asset").description("Register / fetch media assets (groups + assets) for downstream generate-* verbs.");t.command("register").description("Create an asset group and register one Image / Video / Audio asset under it; the server assigns the real group_id.").requiredOption("--group-id <name>","human-readable group NAME (despite the flag's spelling — server assigns the real id)").requiredOption("--name <name>").requiredOption("--url <url>").requiredOption("--asset-type <type>","one of: Image / Video / Audio (iLands capitalization)").option("--project-name <name>","default project","default").addHelpText("after",'\n\nSeedance asset usage:\n - Video assets are supported by dl asset register. Use --asset-type=Video for .mp4 / video URLs.\n - For Seedance 2.0 generate-video, a registered video asset must be passed by asset id:\n --ark-asset-ids=<asset_id> and reference it in the prompt as @assetN.\n - Do not also pass the same registered video URL via --ref-video-url; that raw URL flag is for unregistered video references.\n\nExamples:\n dl asset register --group-id=healthfood-girl --name=tiktok-healthfood-ref \\\n --url="https://example.com/ref.mp4" --asset-type=Video\n\n dl generate-video --service=seedance-2-0 \\\n --prompt="follow @asset1 as the reference video rhythm, no BGM" \\\n --duration=6 --aspect-ratio=9:16 --resolution=720p \\\n --ark-asset-ids=asset_xxx').action(async e=>{try{const t=await async function(e){return Da("media/register-asset","api/asset/create-group",{name:e.name,project_name:e.project_name??"default",...e.description?{description:e.description}:{}},{timeoutMs:3e4,retries:1})}({name:String(e.groupId),project_name:String(e.projectName??"default")}),i=t.group_id??t.data?.Result?.Id??"";i||vs("create-group returned no group_id",void 0,{response:t});const n=await async function(e){return Da("media/register-asset","api/asset/create",e,{timeoutMs:3e4,retries:1})}({group_id:i,name:String(e.name),url:String(e.url),asset_type:String(e.assetType)});gs({ok:!0,group:{group_id:i,name:e.groupId},asset:n})}catch(e){vs(e instanceof Error?e.message:String(e))}}),t.command("get").description("Fetch a single asset by id.").requiredOption("--id <id>").action(async e=>{try{gs({ok:!0,asset:await async function(e){return Da("media/get-asset","api/asset/get",{id:e},{timeoutMs:3e4,retries:1})}(String(e.id))})}catch(e){vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){const t=e.command("knowledge").description("Knowledge-base search across domain libraries (sfx, bgm, visual_style, voice, writing, meme).");t.command("search").description("Search a knowledge domain; returns `data` plus domain metadata and CDN URLs.").addHelpText("after",["","Domains: sfx, stinger, bgm, amb, audio_any, visual_style, voice,"," writing_plot/character/payoff/conflict/hook/any, meme.","","`--provider` (voice-only): filter to a specific TTS provider —"," `elevenlabs` (high-quality English, audio tags) or `minimax` (CN+EN).",' Equivalent to adding `{"vendor":"<v>"}` to --filters-file but'," surfaces in --help / --print-schema for easier agent discovery.","","Example (stdin):",' cat <<EOF | dl knowledge search --domain=voice --query="deep narrator" --filters-file=-',' {"language":"EN","gender":"Male"}'," EOF","","Example (provider filter):",' dl knowledge search --domain=voice --provider=elevenlabs --query="warm narrator"'].join("\n")).requiredOption("--domain <name>",`one of: ${Oc.join(", ")}`).requiredOption("--query <q>").option("--kind <tag>","domain-specific shape filter (e.g. meme: ready|template)").option("--provider <name>",`(voice domain only) filter to a TTS provider: ${Tc.join(" | ")}`).option("--k <n>","max hits (default 10)",e=>{const t=Number(e);if(!Number.isFinite(t)||!Number.isInteger(t)||t<1||t>100)throw new Error(`--k invalid: ${e}`);return t}).option("--filters <inline-json>",'RECOMMENDED: domain-specific filters inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --filters "$(cat filters.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --filters-file.').option("--filters-file <path|->",'LEGACY: domain-specific filters JSON object via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --filters "$(cat file)". Use --filters-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--print-schema","print scalar+file schema and exit").action(async e=>{e.printSchema&&Js({command:"dl knowledge search",summary:"Knowledge-base search for domain-specific asset libraries.",scalars:[{name:"domain",type:"string",required:!0,description:"asset library domain",enum:Oc},{name:"query",type:"string",required:!0,description:"search query"},{name:"kind",type:"string",required:!1,description:"domain-specific shape filter (e.g. meme: ready|template)"},{name:"provider",type:"string",required:!1,description:"voice-domain only: filter by TTS provider (elevenlabs | minimax)",enum:Tc},{name:"k",type:"integer",required:!1,description:"max hits (default 10, max 100)"},{name:"filters",type:"string",required:!1,description:"RECOMMENDED inline JSON object of domain-specific filters (sibling of --filters-file)"}],files:[{name:"filters-file",required:!1,kind:"object",description:"LEGACY: domain-specific filters (prefer --filters inline)",example:'{"language":"EN","gender":"Female","vendor":"elevenlabs"}'}]});const t=String(e.domain);Oc.includes(t)||vs(`--domain must be one of ${Oc.join(", ")}; got ${t}`);const i=String(e.query),n=Math.min(e.k??10,20),o=e.kind?String(e.kind):void 0,r=e.provider?String(e.provider):void 0;r&&(Tc.includes(r)||vs(`--provider must be one of ${Tc.join(", ")}; got ${r}`),"voice"!==t&&vs(`--provider is only valid with --domain=voice; got --domain=${t}`,"drop --provider, or switch --domain=voice if you meant to search voices."));let a={};try{const t=await ms(e.filters?String(e.filters):void 0,e.filtersFile?String(e.filtersFile):void 0,{inline:"--filters",file:"--filters-file"});t&&(a=t.data)}catch(e){throw e instanceof wa&&bs(e),e}if("voice"===t&&"provider"in a){const{provider:e,...t}=a;a={...t,..."vendor"in t?{}:{vendor:e}}}const s={...a,...o?{kind:o}:{},...r?{vendor:r}:{}},l={domain:t,query:i,limit:n};Object.keys(s).length>0&&(l.filters=s);try{const e=await Da("knowledge","api/v1/knowledge/search",l,{timeoutMs:3e4,retries:1}),o=Array.isArray(e.data)?e.data:[],r=e.meta&&"object"==typeof e.meta?e.meta:{domain:t,query:i,limit:n,count:o.length};gs({ok:!0,domain:t,query:i,...e,data:o,meta:r,hits:o})}catch(e){if(e instanceof Jr&&vs(e.message,e.hint),e instanceof Sa){const t=function(e){let t;try{t=JSON.parse(e)}catch{return}if(!t||"object"!=typeof t)return;const i=t.error;if(!i||"object"!=typeof i)return;const n=i.message;return"string"==typeof n&&n.length>0?n:void 0}(e.bodyText),i=e.status>=400&&e.status<500;vs(`knowledge search failed (http ${e.status})${t?`: ${t}`:""}`,i?"fix request filters; run `dl knowledge search --print-schema` for the expected shape":"check backend reachability",{status:e.status,body:e.bodyText.slice(0,500)})}vs(e instanceof Error?e.message:String(e))}});for(const e of["agent-profile","context-find","context-write","materials","platform","trending","web","web-read"])t.command(e).description("iLands-runtime-only knowledge verb — NOT implemented on pi").allowUnknownOption(!0).action(()=>Ec(`knowledge ${e}`,"iLands-runtime-only knowledge verb — on Pi, use `dl search` / `dl web-fetch` / `dl artifact write` as appropriate."))._hidden=!0}(_d),function(e){Ps(e,{verb:"lipsync",actionName:"lipsync",schema:Ko,billing:{schema:jl,select:e=>({service:e.service,duration:e.duration,resolution:e.resolution}),quote:Il},approvalPreview:e=>function(e){const t=[...vc("image","string"==typeof e.image_url?[e.image_url]:[],"Face image"),...yc(e.keyframes)],i=vc("audio","string"==typeof e.audio_url?[e.audio_url]:[],"Driving audio"),n=[];return mc(n,"Service",e.service),mc(n,"Resolution",e.resolution),mc(n,"Quality",e.quality_preset),"number"==typeof e.width&&"number"==typeof e.height&&n.push({label:"Dimensions",value:`${e.width}x${e.height}`}),mc(n,"Seed",e.seed),mc(n,"Billing duration",e.duration),{kind:"lipsync",title:"Lip-sync video",summary:"string"==typeof e.service?e.service:void 0,sections:[gc("Prompt",e.prompt),hc("Face / keyframes",t),hc("Driving audio",i),fc("Details",n)].filter(e=>void 0!==e)}}(e),supportsBatch:!0,description:"Generate a talking-head video where a character's lips sync to a driving audio track. Submits one job (or N via --jobs-file) and returns {job_ref, status:'pending'}; the rendered video URL arrives via [async-callback].",notes:["Preferred default service: `dlai2v_pro` (LTX 2 Pro / LTX 2.3 multi-frame).","Use `dlai2v` (LTX 2 baseline) when you need explicit --width / --height / --seed / --quality-preset control.","`--audio-url` determines lipsync duration. Do not pass --duration to control output length; if present, duration is billing-only and vendor does not read it.","","LTX 2 family (`dlai2v_pro` / `dlai2v`) prompt template — every prompt must contain all three:",' 1. Subject is speaking/singing (e.g. "the character speaks naturally with perfect lip synchronization")'," 2. Character action description (head nods, hands, shoulders, breathing, gaze, …)",' 3. Camera movement description (e.g. "Dolly in", "slow push in", "static medium close-up")',"Reference template:",' --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods'," and tilts, hands resting gently or making small conversational gestures, relaxed",' shoulders, natural breathing motion, high quality, natural lighting, Dolly in"',"","## Multi-keyframe mode (--keyframes, dlai2v / dlai2v_pro / dlai2v_pro_multiframe only)","--image-url and --keyframes are mutually exclusive. --image-url = single reference image","(api-layer auto-wraps it into keyframes[0]). --keyframes = 1-5 explicit keyframe images","for richer camera movement — the model interpolates animation between keyframes + audio-driven lip sync.","",'Each --keyframes value is a JSON object: {"image_url":"...","frame_position":"first|middle|last"}'," - frame_position controls where in the timeline the keyframe anchors"," - All keyframe images must be the same character and same aspect ratio"," - Typical MV workflow: generate a 2×2 grid image (same character, 4 poses) via dl generate-image-ref when source/reference images exist, otherwise dl generate-image-prompt,"," ffmpeg crop into 4 panels, pass as 4 keyframes → rich camera movement + pose transitions","","Constraints: --keyframes only works with dlai2v / dlai2v_pro / dlai2v_pro_multiframe","(preflight rejects other services); 1-5 keyframes for dlai2v / dlai2v_pro,","2-4 keyframes for dlai2v_pro_multiframe; do NOT pass both --image-url and --keyframes.","","## dlai2v_pro_multiframe (LTX 2.3 真·多帧变体)","真正的多帧关键帧引导视频生成(不是单帧 wrap)。必须用 --keyframes (2-4 帧);","每帧支持 {image_url (必填), frame_ratio? (0.0-1.0 时间位置), weight? (0.0-1.0 强度, 默认 0.4)}。","frame_ratio 不传则按数量等分: 2帧=[0,1] / 3帧=[0,0.5,1] / 4帧=[0,0.33,0.67,1]。","api-layer 按 keyframes 数量自动 router 到 mutiframe_{2f,3f,4f} workflow。","--aspect-ratio 支持 16:9/9:16/1:1;resolution 强制 720p (不可改);","不支持显式 --width / --height / --resolution。"],whenToUse:["You have a face image + audio and want a video of the face speaking","Multi-segment lipsync (split the song / dialogue into beats and fan out via --jobs-file)"],whenNotToUse:["You only need text → speech (no face) — use `dl generate-tts`","You need a music track — use `dl generate-music`","You need a talking head from scratch with no audio: not supported on Pi"],examples:[{caption:"single, the common case — dlai2v_pro with the LTX-family prompt template",command:'dl lipsync \\\n --service=dlai2v_pro \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods and tilts, hands resting gently or making small conversational gestures, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"'},{caption:"single, dlai2v (LTX 2 baseline) when you need width/height/seed control",command:'dl lipsync \\\n --service=dlai2v \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="the singer performs the chorus line with perfect lip synchronization, subtle head nods, hands lightly gripping the mic, relaxed shoulders, natural breathing between phrases, high quality, natural lighting, slow dolly in" \\\n --quality-preset=high \\\n --width=1280 \\\n --height=736'},{caption:"multi-keyframe (4 poses from a 2×2 grid crop) — richer camera movement",command:'dl lipsync \\\n --service=dlai2v_pro \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf_top_left.png","frame_position":"first"}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf_top_right.png","frame_position":"middle"}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf_bottom_left.png","frame_position":"middle"}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf_bottom_right.png","frame_position":"last"}\' \\\n --audio-url="https://cdn.example.com/segment.mp3" \\\n --prompt="A person sings expressively with perfect lip synchronization, dynamic head movement, confident posture shifts, high quality, natural lighting, slow dolly in"'},{caption:"batch via stdin (parallel fan-out)",command:'cat <<EOF | dl lipsync --jobs-file=-\n[\n {"job_key":"seg_001","service":"dlai2v_pro","image_url":"https://1.png","audio_url":"https://1.mp3","prompt":"A person speaks naturally with perfect lip synchronization, subtle head nods and tilts, hands resting gently, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"},\n {"job_key":"seg_002","service":"dlai2v","image_url":"https://2.png","audio_url":"https://2.mp3","prompt":"A person sings clearly with perfect lip synchronization, subtle head nods, relaxed shoulders, natural breathing motion, high quality, natural lighting, static medium close-up"}\n]\nEOF'},{caption:"batch with multi-keyframe job",command:'cat <<EOF | dl lipsync --jobs-file=-\n[\n {"job_key":"seg_001","service":"dlai2v_pro","image_url":"https://face.png","audio_url":"https://1.mp3","prompt":"A person speaks naturally with perfect lip synchronization, subtle head nods, hands resting gently, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"},\n {"job_key":"seg_002","service":"dlai2v_pro","keyframes":[{"image_url":"https://kf1.png","frame_position":"first"},{"image_url":"https://kf2.png","frame_position":"middle"},{"image_url":"https://kf3.png","frame_position":"last"}],"audio_url":"https://2.mp3","prompt":"A person sings expressively with perfect lip synchronization, dynamic head movement, confident posture, high quality, natural lighting, slow push in"}\n]\nEOF'}],notExamples:[{command:'dl lipsync --params=\'{"service":"dlai2v","image_url":"...","audio_url":"..."}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"},{command:"dl lipsync --image-url=... --audio-url=... --jobs-file=batch.json",whyItFails:"scalar flags + --jobs-file are mutually exclusive; raises E_SCHEMA"},{command:"dl lipsync --service=dlai2v_pro --image-url=... --keyframes='...' --audio-url=...",whyItFails:"--image-url and --keyframes are mutually exclusive; preflight rejects. Use one or the other."}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"url":"https://storage.../video.mp4","duration_ms":3200}}',outputBatch:'{"ok":true,"action":"lipsync","results":[\n {"job_key":"seg_001","job_ref":"<uuid>","status":"pending"},\n ...\n]} // batch is non-blocking; each completed job is pushed back to the session via [async-callback]',preflight:e=>{const t=String(e.service??""),i="string"==typeof e.image_url&&""!==e.image_url,n=Array.isArray(e.keyframes)&&e.keyframes.length>0;if(!i&&!n)throw new wa("E_SCHEMA","either --image-url or --keyframes is required","provide a face image via --image-url, or multiple keyframes via --keyframes",{verb:"lipsync",service:t});if(i&&n)throw new wa("E_SCHEMA","--image-url and --keyframes are mutually exclusive","use --image-url for single-image lipsync, or --keyframes for multi-keyframe lipsync (1-5 frames); do not pass both",{verb:"lipsync",service:t});if(n&&"dlai2v"!==t&&"dlai2v_pro"!==t&&"dlai2v_pro_multiframe"!==t)throw new wa("E_SCHEMA",`--keyframes is only supported for dlai2v / dlai2v_pro / dlai2v_pro_multiframe, not ${t}`,"use --image-url instead, or switch --service to dlai2v / dlai2v_pro / dlai2v_pro_multiframe for multi-keyframe lipsync",{flag:"--keyframes",verb:"lipsync",service:t});if("dlai2v_pro_multiframe"===t){if(!n)throw new wa("E_SCHEMA","dlai2v_pro_multiframe requires --keyframes (2-4 frames); --image-url alone is not supported","pass 2-4 --keyframes flags; if you only have 1 image, use --service=dlai2v_pro instead",{verb:"lipsync",service:t});const i=e.keyframes.length;if(i<2||i>4)throw new wa("E_SCHEMA",`dlai2v_pro_multiframe requires 2-4 keyframes, got ${i}`,"adjust to 2/3/4 keyframes; api-layer routes to mutiframe_{2f,3f,4f} workflow by count",{flag:"--keyframes",verb:"lipsync",service:t})}if(n&&e.keyframes.length>5)throw new wa("E_SCHEMA",`--keyframes accepts 1-5 frames, got ${e.keyframes.length}`,"reduce to at most 5 keyframe images",{flag:"--keyframes",verb:"lipsync",service:t})},modelTopic:{rankingSummary:["Overall ranking (strongest → weakest) + recommended default:"," 🥇 dlai2v_pro LTX 2 Pro / LTX 2.3 multi-frame — **preferred default for new lipsync work**"," 🥈 dlai2v LTX 2 baseline — when you need explicit width/height/seed/quality-preset control"," 🥉 longcat-avatar Longer audio + simple setup, weaker resolution control"],services:[{service:"dlai2v_pro",label:"LTX 2 Pro (LTX 2.3 multi-frame)",tier:"🥇 Preferred default",bestFor:"Default choice for new lipsync work. LTX-2's successor multi-frame workflow; scene-style prompt (subject + action + camera) + face still + audio",quality:"Very High",speed:"2-5min",cost:"mid",description:["LTX 2 Pro, routes to the LTX-2.3 multi-frame workflow.","","Two input modes:"," Mode 1 (single image): --image-url — api-layer auto-wraps into keyframes[0]."," Mode 2 (multi-keyframe): --keyframes (1-5 frames) — explicit keyframe images for richer"," camera movement. Model interpolates between keyframes + audio-driven lip sync.",' Each keyframe: {"image_url":"...","frame_position":"first|middle|last"}'," Typical workflow: generate 2×2 grid (same character, 4 poses), ffmpeg crop → 4 keyframes.","","--image-url and --keyframes are mutually exclusive."],promptTips:["⚠ LTX family prompt template — all three segments required:"," 1. Subject is speaking/singing (explicitly say the character is *speaking* or *singing* with perfect lip sync)"," 2. Character action (head nods/tilts / gaze / hands / shoulders / breathing)"," 3. Camera movement (Dolly in / slow push in / static medium close-up; static must also be stated explicitly)","Append a quality / lighting tail: 'high quality, natural lighting'","","Reference template:",' "A person speaks naturally with perfect lip synchronization, subtle'," head nods and tilts, hands resting gently or making small conversational"," gestures, relaxed shoulders, natural breathing motion, high quality,",' natural lighting, Dolly in"'],flagSubset:["service","image-url","audio-url","prompt","keyframes"],constraints:["⚠ dlai2v_pro accepts a **strict subset** of flags — do NOT copy a dlai2v example and just swap the service name"," Invalid: --quality-preset / --width / --height / --resolution / --seed"," Invalid: --ark-asset-ids / --reference-subject-type (not part of the lipsync surface)"," Invalid: --duration (audio_url determines the output duration)"," Passing them is silently ignored (the multi-frame workflow uses fixed output dimensions)","--keyframes: 1-5 frames, mutually exclusive with --image-url","audio_url ≤ 100MB & ≤ 20s","audio formats: mp3 / wav / ogg / flac / m4a / aac / webm"],examples:[{caption:"single, dlai2v_pro default (LTX 2 Pro)",command:'dl lipsync --service=dlai2v_pro \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods and tilts, hands resting gently or making small conversational gestures, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"'}]},{service:"dlai2v",label:"LTX 2 baseline (Multimodal)",tier:"🥈 When you need width/height/seed control",bestFor:"You need explicit --width / --height / --seed / --quality-preset control (dlai2v_pro's fixed-dimension multi-frame does not expose these)",quality:"Very High",speed:"2-5min",cost:"mid",description:["LTX 2 baseline. Prompt template is the same as dlai2v_pro (subject speaking + character action + camera move).","Also supports --keyframes (1-5 frames) for multi-keyframe mode, same as dlai2v_pro."],promptTips:["Same three-segment template as dlai2v_pro","--quality-preset='ultra' gives the best lip sync but is slower"],flagSubset:["service","image-url","audio-url","prompt","quality-preset","width","height","seed","keyframes"],constraints:["audio ≤ 19s & ≤ 50MB","--keyframes: 1-5 frames, mutually exclusive with --image-url","Do NOT pass --duration to control output length; audio_url determines the lipsync length"],examples:[{caption:"dlai2v with explicit width/height/seed",command:'dl lipsync --service=dlai2v \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods, hands resting gently, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in" \\\n --quality-preset=high --width=1280 --height=736 --seed=42'}]},{service:"longcat-avatar",label:"LongCat Avatar",tier:"Long audio + simple",bestFor:"Longer audio + simple parameter setup",quality:"High",speed:"1-3min",cost:"low",description:["LongCat Avatar. Handles longer audio with relatively simple parameters, but resolution control is weaker."],promptTips:["Relatively permissive — 'a person speaking' will run; the LTX-family three-segment template still produces better results"],flagSubset:["service","image-url","audio-url","prompt","resolution","seed"],constraints:["Few resolution options (mainly 480p); no fine-grained width/height control","Do NOT pass --duration; audio_url determines output length"],examples:[{caption:"longcat-avatar simple setup",command:'dl lipsync --service=longcat-avatar \\\n --image-url=https://... --audio-url=https://... \\\n --prompt="a person speaking" --resolution=480p --seed=42'}]}],decisionLogic:[{when:"Default / unsure / new lipsync work",pick:"dlai2v_pro (LTX 2 Pro, preferred default)"},{when:"Need explicit --width / --height / --seed / --quality-preset control",pick:"dlai2v (LTX 2 baseline)"},{when:"Longer audio + simple parameters (< control needs)",pick:"longcat-avatar"}]},preflightTopic:{intro:"Confirm these 5 items before the first dl lipsync call (MV segment workflow adds a 6th):",decisions:[{name:"Service / model",description:"Pick a supported lipsync service (dlai2v_pro default / dlai2v / dlai2v_pro_multiframe / longcat-avatar).\nDetermines prompt template shape + flag subset + audio duration cap."},{name:"Driving duration",description:"Whether audio length is within the selected service cap (dlai2v_pro ≤ 20s / dlai2v ≤ 19s; check the selected service profile for other caps).\n`--audio-url` determines the request duration; do not use --duration to control output length.\nIf the intended final segment is shorter than 3s, trim the driving audio upstream or trim padded output afterward;\nlonger than the service cap MUST be split upstream. **Driving audio is canonical** — do NOT crop / pad /\nstretch / integer-round it to match vendor duration. If the vendor outputs padded video, trim back\nto exact storyboard / audio duration."},{name:"Resolution package",description:"480p / 720p / explicit width-height (depends on service). dlai2v_pro does NOT accept resolution / width / height (fixed dim);\ndlai2v accepts width / height / quality-preset."},{name:"Face / reference plan",description:"Decide the face image source: real-looking human portrait / generated performance still / registered asset bundle.\n**MV segment workflow**: for the LTX family, do NOT use a raw character reference sheet directly;\nuse dl generate-image-ref to produce a segment-specific performance still first when source/reference images exist —\nfront-facing / mouth clearly visible / matching the segment's scene / lighting / wardrobe / props."}],notes:["Cost-sensitive / service / resolution unclear → read pricing-and-policies-dramaland-faq/SKILL.md first","Batch lipsync goes through --jobs-file; do not block per segment. Do NOT flatten nested jobs[].params"]},policyTopic:{intro:"Six categories of hard rules: User-facing isolation / Package gate / LTX prompt template / URL hygiene / MV duration & still / Fallback ladder.",rules:[{title:"1. User-Facing Communication — never leak internal details",body:["Vendor / pricing / internal model code (LTX-2.3 multi-frame workflow / Seedance 2.0 Pro) /","trace id must NOT surface to the user. User-facing summary only mentions: service alias","(LTX / Seedance / LongCat) + character / duration + action (lip-sync / lip-sync video)."]},{title:"2. Production Package Gate — never call before authorization",body:["service / model / driving duration / resolution / width-height / job count (including batch","segment range) / face / reference plan / audio source plan are all components of the paid","package authorization. Do not call before the package is authorized; once authorized, batch","within the package. Only re-ask on package overflow (service switch / duration change /","resolution change / quantity increment / swap of a key input / fallback / paid regeneration)."]},{title:"3. LTX-family Prompt Template Discipline (dlai2v_pro / dlai2v)",body:["LTX 2 family prompt MUST contain all three segments:"," (1) Subject speaking/singing (explicitly say the character is *speaking* or *singing* with perfect lip sync)"," (2) Character action (head nods / tilts / gaze / hands / shoulders / breathing)"," (3) Camera movement (Dolly in / slow push in / static medium close-up; static must be stated explicitly)","","Append a quality / lighting tail: 'high quality, natural lighting'.","","❌ Bad — 'a person speaking' (too vague; the model improvises)","✅ Good — see the reference template in the dlai2v_pro service profile"]},{title:"4. URL Hygiene — public HTTPS / never fabricate storage URLs",body:["All media URLs (image_url / audio_url) MUST be real publicly reachable HTTPS URLs. Legitimate sources:"," - dl generate-image-prompt / dl generate-image-ref / generate-tts / generate-music submit results (GCS storage URLs)"," - URLs uploaded by the user or provided in the conversation"," - URLs returned by platform queries like dl content list","","NEVER fabricate storage URLs / guess domains / invent paths. Need a face image → run dl generate-image-ref first when source/reference images exist, otherwise dl generate-image-prompt;","need audio → run dl generate-tts or generate-music first."]},{title:"5. MV Segment Duration & Keyframe Boundary",body:["**Driving audio is canonical**: do NOT crop / pad / stretch / integer-round audio to match","vendor duration, and do NOT pass --duration. If the vendor outputs padded video, ffmpeg trim back to the exact","storyboard / audio duration.","","Intended final segment shorter than 3s → request at least the vendor minimum, then trim back;","longer than 15-20s → MUST split upstream — do not feed it all at once.","","LTX family MUST NOT use a raw character design / reference sheet directly as image_url.","Use dl generate-image-ref to produce a segment-specific performance still when source/reference images exist — front-facing /","mouth clearly visible / matching the segment's scene / lighting / wardrobe / props."]},{title:"6. Fallback Ladder",body:["When this verb produces jitter / mouth drift / gaze drift / character drift / moderation block, in order:","","1. Retry once (transient network / quota jitter usually clears)","2. Swap within supported LTX-family modes: dlai2v_pro ↔ dlai2v, or switch between single image and keyframes","3. Re-pick the face still: performance still not sharp enough / not front-facing enough →"," regenerate a segment-specific still via image-generation","4. Edit the prompt: LTX-family three segments incomplete → fill in","5. Split segments: audio too long / model's segment handling capped → split upstream"]}]},compositionTopic:{intro:"This atomic skill only produces a lipsync video URL; artifact / canvas / publish_content downstream responsibilities are not in this verb's scope.",integrations:[{skill:"generate-tts / generate-music (audio source)",rule:["audio_url sources: dl generate-tts (dialogue / narration) or dl generate-music (song / vocal track).","Confirm ownership before feeding raw user-uploaded audio; never fabricate a GCS URL.","Do not use duration to control output length; audio_url determines the requested length."]},{skill:"generate-image-ref (face / performance still source)",rule:["image_url source: dl generate-image-ref producing a segment-specific performance still when source/reference images exist.","MV segment workflow: do NOT use a raw character design directly as the lipsync image_url;","generate a segment-specific still first (front-facing / mouth clearly visible / matching scene)."]},{skill:"Right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs dl artifact write / patch-json on pi_media_log on its caller's behalf — that is the composition layer's job."]},{skill:"publish_content (final delivery)",rule:["Hand the lipsync output video URL to publish_content with presentation_family='video'","(see the publish subtopic for details)."]}]},asyncTopic:{intro:["dl lipsync returns { job_ref, status: 'pending' } and exits immediately by default — do NOT poll.","The result is injected into the session as [async-callback] job=<ref> text; typical wait is 1-5 minutes.","If the next step must have the result (e.g. immediately feeding ffmpeg) → query separately with","dl poll --job-ref=<ref>; dl subcommands themselves no longer support --wait blocking (removed in #294)."],resultShape:['{ "url": "https://storage.googleapis.com/.../video.mp4", "original_url": "...", "vendor": "..." }',"vendor / original_url / other internal metadata fields MUST NOT be exposed to the user"],notes:["⚠ Do NOT write a bash poll loop (while sleep + dl poll) — forbidden by the agent runtime async rules (#389)","Batch lipsync goes through --jobs-file; each job's completion is pushed back independently via [async-callback]","⚠ The returned URL already lives on our GCS — feed it directly to downstream tools / artifacts; do NOT pass to upload_file."]},publishTopic:{intro:["After producing the lipsync video URL, call publish_content with presentation_family='video' +","explicit media fields. See 'Publishing Your Work / video' in the creation playbook for the full field map."],fields:[{name:"presentation_family",value:"'video'"},{name:"media_urls.video",value:"<lipsync output URL>"},{name:"delivery_format",value:"'video'"}]}})}(_d),function(e){Ps(e,{verb:"transcribe",actionName:"transcribe",schema:Xo,billing:{schema:Yl,select:()=>({}),quote:Wl},supportsBatch:!1,description:"Asynchronously transcribe audio to SRT subtitles. Returns {status:'pending', job_ref} immediately; the SRT lands via [async-callback] in a later turn.",notes:["Async by default — submit returns `{status:'pending', job_ref, data:{task_id}}`; do NOT wrap in `nohup ... &` / bash poll loop. End the turn and wait for `[async-callback] job=<ref>` to land.","`--language` accepts `auto` (detect) or any ISO-639-1 code (`en`, `zh`, `ja`, `es`, `fr`, …).","`--transcript-text` skips ASR recognition and aligns the provided text to the audio to produce SRT/timestamps.","`--word-timestamps` controls whether the callback payload includes full `text`/`segments`/`words` in addition to `srt_url`/`srt_content`.","`--model-size` is intentionally not supported; ASR uses the server-side Qwen3 + stable-ts pipeline."],whenToUse:["You have an audio URL and need SRT subtitles (single language or auto-detect)","Music-video phase 01 / shot-by-shot caption work that needs subtitle timing"],whenNotToUse:["You need beat / tempo analysis (use `dl analyze-beats` instead)","You need to download a remote video before transcribing — `dl transcribe` only accepts a public URL"],examples:[{caption:"auto-detect language, return SRT only when callback lands",command:'dl transcribe --audio-url="https://cdn.example.com/voice.mp3" --language=auto'},{caption:"request word timestamps in callback payload",command:'dl transcribe \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --language=en \\\n --word-timestamps'},{caption:"align an existing transcript without ASR recognition",command:'dl transcribe \\\n --audio-url="https://cdn.example.com/song.mp3" \\\n --transcript-text="Known lyric line. Next lyric line." \\\n --language=auto'}],notExamples:[{command:'nohup dl transcribe --audio-url="https://cdn.example.com/voice.mp3" --language=zh > /tmp/asr.json &',whyItFails:"transcribe is async — submit returns immediately and the result arrives as [async-callback] in a later turn. Backgrounding orphans the child when the sandbox is reclaimed and there is no job_ref to poll."},{command:'dl transcribe --audio-url="https://cdn.example.com/voice.mp3" --model-size=large-v3',whyItFails:"`--model-size` is no longer a valid CLI flag; model selection is server-side"},{command:'dl transcribe --params=\'{"audio_url":"...","language":"auto"}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"},{command:"dl transcribe --audio-url=face.mp3",whyItFails:"audio_url must be a fully-qualified public URL; raises E_BACKEND"}],outputSingle:'{"ok":true,"status":"pending","job_ref":"<uuid>","data":{"task_id":"ag:asr:qwen3-asr:<id>","status":"pending"}}',transformResult:bd,preflightTopic:{intro:"Confirm these 4 items before the first dl transcribe call:",decisions:[{name:"Audio URL is publicly reachable",description:"audio_url must be a publicly accessible URL (or platform-internal storage URL).\nFor private buckets (GCS / S3) sign the URL first. Local file paths / data: URIs are rejected."},{name:"Language hint",description:"--language=auto (default) works for most content; explicitly write the\nISO-639-1 code (en / zh / ja / es / fr) when the language is known — improves\nASR accuracy and speed."},{name:"Callback payload mode (pick one)",description:'Default callback payload: srt_content + srt_url only (token-thrifty, fits direct caption rendering).\n--word-timestamps: callback also includes text + segments + words (word-level timing,\n for MV beat alignment / lip-sync / by-word fine cut).\n--transcript-text="...": skips ASR recognition; ASR vendor only time-aligns the given text\n to the audio (use for user-supplied lyrics / pre-edited transcripts / alignment-after-other-ASR).'},{name:"Tuning (optional)",description:"--vad-filter: enables stable-ts VAD for cleaner segment splitting.\n--denoise-audio: ASR defaults to true (Demucs denoising / vocal separation); make explicit if you want.\n--max-segment-duration=5: readable upper bound per caption line in seconds; 5 is usually enough."}],notes:["Async by default — submit returns `{status:'pending', job_ref, data:{task_id}}` immediately; end the turn and wait for `[async-callback] job=<ref>`. See `dl transcribe async -h`.","Do NOT pass --model-size — it's not a valid CLI flag (server-side picks the pipeline)","Server-side budget is ~590s per identification (cold-start GPU + long denoised audio can hit this); pre-split very long audio if a single segment risks this limit"]},policyTopic:{intro:"Four hard rules: User-facing isolation / Package gate / Default callback trim / Server-side model selection.",rules:[{title:"1. User-Facing Communication — never leak internal details",body:["Vendor / internal pipeline (Qwen3-ASR / stable-ts / DTW) / trace id must NOT","surface to the end user. User-facing summary only mentions: action (transcribe /","caption / time-align) + language + duration."]},{title:"2. Production Package Gate — never call before authorization",body:["Audio source / target language / word-level need / downstream usage (caption render","vs beat sync vs alignment of known text) are all components of the paid production","package authorization. Do not call before the package is authorized; once authorized,","batch within the package by parallel `dl transcribe` calls (no `--jobs-file`; api-layer","already fan-outs jobs server-side). Only re-ask on package overflow (language switch /","adding word-level / adding text alignment / fallback / paid regeneration).","","Cost reference: 50 platform tokens / transcription, ~590s server-side ASR budget per identification."]},{title:"3. Default Callback Trim — word-timestamps controls the callback payload, not the CLI response",body:["The CLI `dl transcribe` response is always the submit acknowledgement:","`{ok:true, status:'pending', job_ref, data:{task_id}}`. The SRT lives in the","`[async-callback]` payload that lands in a later turn.","","By default the callback payload's `result` carries srt_content + srt_url only.","The text / segments / words fields are **intentionally dropped** from the callback","payload to save tokens. Only pass --word-timestamps when the caller explicitly","needs word-level timing (MV beat sync / lip-sync alignment / by-word fine cut).","Phase 01 storyboards typically need default SRT only; downstream caption renderers","(create-subtitles) also consume srt_content / srt_url directly."]},{title:"4. Server-side Model Selection — --model-size is NOT exposed",body:["The ASR pipeline is server-selected (Qwen3-ASR for text + stable-ts for","timestamps + DTW fallback for alignment). There is no --model-size CLI flag.","Passing it raises E_UNKNOWN_OPTION."]}]},compositionTopic:{intro:"transcribe is an atomic skill — it only produces SRT + optional word-level timing. Downstream caption rendering / beat cutting / alignment publishing are NOT this verb's responsibility.",integrations:[{skill:"create-subtitles (caption rendering)",rule:["The create-subtitles SOP consumes transcribe's callback `result.srt_url` / `srt_content`,","then runs dl render-caption / ffmpeg to burn subtitles. transcribe only","emits the SRT — styling / fonts / burn-in are not its job."]},{skill:"lipsync / hyperframes-cli (lip alignment / beat-driven animation)",rule:["Beat-driven animation / lip alignment workflow: transcribe --word-timestamps →","feed callback `result.words[]` to hyperframes-cli for beat anchoring, or feed","`result.segments[]` to dl lipsync as a prompt condition. These workflows explicitly","need word-level timing, so set --word-timestamps; default trimming drops these","fields from the callback payload."]},{skill:"publish_content (delivering the SRT file to the user)",rule:["If the final deliverable is a .srt file (no further downstream rendering),","go through publish_content's subtitle / transcript slot; see the publish-related","skill for details."]},{skill:"create-complex-music-video-from-music (audio_analysis artifact slot)",rule:["Persist post-fallback transcript to the `audio_analysis` slot via read-modify-write:","`dl artifact read` → set `transcription.text` / `srt_content` / `language` / `segments[]`","(preserve existing `beats` / `track`) → `dl artifact write --contract='<ARTIFACT_CONTRACT_PATH>'`.","Two separate Bash calls. Full procedure: skills/audio-transcription/SKILL.md."]}]},asyncTopic:{intro:["dl transcribe is async via the api-layer task queue (#395). Submit returns","`{ok:true, status:'pending', job_ref, data:{task_id}}` immediately and exits — **do NOT poll**.","The transcription result arrives later as `[async-callback] job=<ref>` user message that","re-enters the session in a new turn.","","End the turn after submit. Do NOT wrap the call in `nohup ... &`, do NOT poll in a","`sleep`/`for`/`while` loop, and do NOT call `dl poll` proactively — see customPrompt §9","for the async detach rules that govern all submit-style verbs."],resultShape:['// Callback payload\'s "result" object (default — srt only)','{ "success": true, "language": "en", "duration": 12.408,',' "srt_content": "1\\n00:00:00,000 --\x3e 00:00:02,500\\nFirst segment of speech.\\n",',' "srt_url": "https://storage.googleapis.com/dramaland-public/asr/srt/<date>/<hash>.srt",',' "alignment_method_used": "stable-ts", "alignment_quality": "high" }','// alignment_quality ∈ "high" | "medium" | "low" or absent — only "high" trustworthy (see Quality fallback note).',"",'// With --word-timestamps, the callback "result" also includes:','{ "text": "...", "segments": [{"id":0,"start":0.0,"end":2.5,"text":"..."}],',' "words": [{"word":"First","start":0.0,"end":0.4,"probability":0.98}] }'],notes:["⚠ Do NOT write a bash poll loop (while sleep + dl poll) — agent runtime async rules forbid it (#389)","Lost-callback escape hatch: if significantly more than the expected window (~5-60s short / longer for cold-start GPU / multi-minute audio) passes without `[async-callback]` landing, you may do exactly ONE single-shot `dl poll --job-ref=<ref>` — never in a loop. See customPrompt §9.","Batch fan-out: api-layer queues each transcribe submit independently — for multiple audios call `dl transcribe` in parallel; do NOT use `--jobs-file` (supportsBatch is false on this verb).","Quality fallback: when `result.alignment_quality` is `low` / `medium` / missing, word-level timing is unreliable. Call the built-in `understand_media` tool on the same audio to recover a clean transcript, then resubmit `dl transcribe --audio-url=<same> --transcript-text=<clean> --word-timestamps=true` to time-align via DTW. The second callback supersedes the first — do not mix segments across the two. Full procedure: skills/audio-transcription/SKILL.md → 'Low alignment_quality → understand_media fallback'."]},publishTopic:{intro:["transcribe atomic does NOT call publish_content directly. Its outputs","srt_content / srt_url usually feed downstream caption renderers","(create-subtitles / hyperframes-cli).","If the final deliverable is the SRT itself, map publish_content fields as:"],fields:[{name:"presentation_family",value:"'document' or 'caption-bundle' (per publish_content schema)"},{name:"media_urls.subtitle",value:"<srt_url>"},{name:"delivery_format",value:"'srt'"}]}})}(_d),function(e){sc(e,"generate-image-prompt","prompt"),sc(e,"generate-image-ref","ref"),function(e){e.command("generate-image",{hidden:!1}).allowUnknownOption(!0).allowExcessArguments(!0).description("Deprecated ambiguous image generation command. Use generate-image-prompt or generate-image-ref.").action(()=>{ys("E_DEPRECATED","`dl generate-image` is ambiguous and has been retired.","Use `dl generate-image-prompt` for prompt-only generation, or `dl generate-image-ref` when any source/reference image is required.",{replacements:["generate-image-prompt","generate-image-ref"]})})}(e)}(_d),function(e){Ps(e,{verb:"generate-video",actionName:"generate_video",schema:Jo,supportsBatch:!0,billing:{schema:El,select:e=>({service:e.service,duration:e.duration,resolution:e.resolution}),quote:Tl},approvalPreview:e=>function(e){const t=[...vc("image",dc(e.image_url),"Image input"),...vc("image",dc(e.image_urls),"Reference image"),...vc("image",dc(e.urls),"Reference URL"),...vc("image",dc(e.last_frame_url),"Last frame"),...vc("image",dc(e.end_image_url),"End frame"),...yc(e.keyframes),...(i=e.elements,Array.isArray(i)?i.flatMap((e,t)=>{const i=_c(e);if(!i)return[];const n=t+1,o=uc([...dc(i.url),...dc(i.image_url),...dc(i.frontal_image_url)]),r=dc(i.reference_image_urls);return[...o.map((e,t)=>({kind:"image",url:e,label:1===o.length?`Element ${n}`:`Element ${n}.${t+1}`})),...r.map((e,t)=>({kind:"image",url:e,label:`Element ${n} ref ${t+1}`}))]}):[])];var i;const n=[...vc("video",dc(e.video_url),"Source video"),...vc("video",dc(e.ref_video_url),"Reference video"),...vc("video",dc(e.video_urls),"Reference video")],o=[...vc("audio",dc(e.reference_audio_url),"Reference audio"),...vc("audio",dc(e.audio_url),"Driving audio")],r=uc(dc(e.ark_asset_ids)).map((e,t)=>({label:`Asset ${t+1}`,value:e})),a=[];mc(a,"Service",e.service),mc(a,"Duration",e.duration),mc(a,"Aspect ratio",e.aspect_ratio),mc(a,"Resolution",e.resolution),mc(a,"Mode",e.mode),mc(a,"Quality",e.quality_preset),mc(a,"Seed",e.seed),"number"==typeof e.width&&"number"==typeof e.height&&a.push({label:"Dimensions",value:`${e.width}x${e.height}`}),mc(a,"Generate audio",e.generate_audio),mc(a,"Sound",e.sound),mc(a,"Draft",e.draft),mc(a,"Camera fixed",e.camera_fixed),mc(a,"Audio setting",e.audio_setting),mc(a,"Reference subject",e._reference_subject_type),mc(a,"CFG scale",e.cfg_scale);const s=[pc(e.service),"number"==typeof e.duration?`${e.duration}s`:void 0].filter(e=>!!e).join(" · ");return{kind:"generate_video",title:"Video generation",...s?{summary:s}:{},sections:[gc("Prompt",e.prompt),gc("Negative prompt",e.negative_prompt),hc("Image / keyframe references",t),hc("Video references",n),hc("Audio references",o),fc("Asset references",r),fc("Details",a)].filter(e=>void 0!==e)}}(e),strictBatchParams:!0,description:"Generate a short video clip from a text prompt (optionally seeded with reference images / audio).",notes:["Prompt placeholders are 1-indexed and get substituted at submit time:"," @imageN → image_urls[N-1] @audioN → reference_audio_url"," @videoN → ref_video_url @assetN → ark_asset_ids[N-1]"," @assetN can point at a registered Image / Video / Audio asset; Seedance routes by asset type.","","--prompt supports loading from a JSON file:"," --prompt=@file:/abs/path.json#/json/pointer"," When prefixed with @file:, extract a string per RFC 6901 JSON Pointer as the prompt.","","--refs-from bulk-binds reference assets from a JSON file such as a storyboard:"," --refs-from=@file:/abs/storyboard.json#/segments/0/references"," The pointer must point at a [{element_id, url}, ...] array; element_id routes by prefix:"," image* → image_urls, asset* → ark_asset_ids,"," audio* → reference_audio_url, video* → ref_video_url."," If a video has already been registered as an asset, route it as asset* / @assetN, not video* / @videoN.","If Seedance audio output is moderation-blocked, retry with prompt text like 'no BGM' / 'no background music'; do not pass --generate-audio.","Seedance 2.0 分辨率:Pro(seedance-2-0)支持小写 480p / 720p / 1080p / 4k;Fast / Mini 仅支持 480p / 720p。"," 4K 成片必须使用 --service=seedance-2-0 --resolution=4k,价格为 720 credits/s。","","FEEDBACK-BASED GUARDRAILS — avoid the common expensive failures:"," 1. Short continuous video → prefer one Seedance clip; do NOT split only because the prompt has multiple visual beats."," 2. Identity-critical work (real face / selfie / actor / artist / fixed character) → choose a reference-consistent model first; weak reference-following models can produce random people."," 3. Real-looking human / known-IP with Seedance 2.0 → register assets first, then reference @assetN; do not rely on raw media URLs."," 4. Before submitting a segment, check whether a successful or pending job already exists; never resubmit unless the user explicitly asks for regeneration."," 5. Multi-segment / long-form workflows (N>=4 segments or >30s total) → run a sample wave first: 1-3 representative segments, show playable URLs, get explicit user OK before full batch."," 6. For multi-segment lip-sync workflows, use dl lipsync for the sample wave and prove one representative clip before committing a large batch."," 7. Fallback is allowed, but non-Seedance models need role-locked frames/keyframes first; do not pass --ark-asset-ids or @assetN to Veo/Grok/Kling.","","⚠ SEEDANCE 2.0 ASSET RULES (seedance-2-0 / seedance-2-0-fast / seedance-2-0-mini) — read before composing the call:"," 1. Real-person / known-IP media input MUST go through `dl asset register` first;"," passing a raw real-person media URL via --image-url / --image-urls / --ref-video-url is blocked by upstream policy."," 2. Once an image / video / audio is registered as an asset, reference it ONLY via --ark-asset-ids + @assetN"," in the prompt. Do NOT also pass that same media through --image-url / --image-urls / --ref-video-url —"," the two channels are mutually exclusive for the same media; double-passing wastes a ref"," slot and produces unpredictable routing on the vendor side."," 3. Set --reference-subject-type=real_person on real-person asset calls."," 4. Registered Video assets are supported; pass them as --ark-asset-ids + @assetN, not --ref-video-url + @videoN."," 5. --image-urls / --ref-video-url are reserved for non-registered scene / prop / video refs that are NOT real people."," 6. ARK r2v counts all reference_video inputs together and requires total reference-video duration <=15.2s."," Multiple video refs are allowed only when they are distinct and the combined duration is within the limit;"," never pass the same video twice as both --ark-asset-ids/@assetN and --ref-video-url/@videoN."," Full constraint list: `dl generate-video model seedance-2-0` (or `model seedance-2-0-fast` / `model seedance-2-0-mini`)."],whenToUse:["You need a short clip (2–10s) from a prompt","You need image-to-video (i2v) using the @imageN placeholders","Multi-segment storyboards with discrete scenes: split intentionally and fan out via --jobs-file"],whenNotToUse:["You need lip-sync — use `dl lipsync`","You need motion transfer between two videos — use `dl motion-control`","You need still images — use `dl generate-image-prompt` for prompt-only images or `dl generate-image-ref` when source/reference images are required"],examples:[{caption:"single, seedance-2-0",command:'dl generate-video \\\n --service=seedance-2-0 \\\n --prompt="a corgi astronaut floating, slow zoom in" \\\n --duration=5 \\\n --resolution=720p'},{caption:"i2v with reference frame",command:'dl generate-video \\\n --service=dli2v3 \\\n --prompt="@image1 starts moving forward into the snow" \\\n --image-urls="https://1.png" \\\n --duration=4'},{caption:"prompt + references from storyboard JSON",command:'dl generate-video \\\n --service=seedance-2-0 \\\n --prompt="@file:/abs/storyboard.json#/segments/0/detail/prompt" \\\n --refs-from="@file:/abs/storyboard.json#/segments/0/references" \\\n --duration=10 --resolution=720p'}],notExamples:[{command:'dl generate-video --params=\'{"service":"seedance-2-0","prompt":"..."}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"url":"https://storage.../video.mp4","duration_ms":5000}}',outputBatch:'{"ok":true,"action":"generate_video","results":[\n {"job_key":"scene_01","job_ref":"<uuid>","status":"pending"},\n ...\n]} // batch is non-blocking; each completed job is pushed back to the session via [async-callback]',extraFlags:[{spec:"--refs-from <ref>",description:"Bulk-bind reference assets: @file:PATH#POINTER, pointer must point at a [{element_id, url}, ...] array"}],transformParams:(e,t)=>{let i=e;if(Ss(i.prompt)){const e=Es(i.prompt,{flag:"--prompt",requireString:!0});i={...i,prompt:e}}if("single"===t.mode){const e=t.opts?.refsFrom;"string"==typeof e&&""!==e&&(i=function(e,t){const i={...e};if(t.image_urls.length>0){const e=kc(i.image_urls);i.image_urls=xc([...t.image_urls,...e])}if(t.ark_asset_ids.length>0){const e=kc(i.ark_asset_ids);i.ark_asset_ids=xc([...t.ark_asset_ids,...e])}return t.reference_audio_url&&void 0===i.reference_audio_url&&(i.reference_audio_url=t.reference_audio_url),t.ref_video_url&&void 0===i.ref_video_url&&(i.ref_video_url=t.ref_video_url),i}(i,function(e){if(!Ss(e))throw new wa("E_SCHEMA",`${wc} 仅支持 @file:PATH#POINTER 语法,收到:${e}`,"示例:--refs-from=@file:/abs/storyboard.json#/segments/0/references",{flag:wc});const t=Es(e,{flag:wc});if(!Array.isArray(t))throw new wa("E_SCHEMA",`${wc} JSON Pointer 命中的不是数组(实际类型:${typeof t})`,"references 应该是 [{element_id, url}, ...] 形式",{flag:wc});return function(e){const t={image_urls:[],ark_asset_ids:[]},i=[],n=[],o=[],r=[];if(e.forEach((e,t)=>{if(!e||"object"!=typeof e)throw new wa("E_SCHEMA",`${wc} references[${t}] 不是对象(实际:${null===e?"null":typeof e})`,void 0,{flag:wc});const a=e,s=a.element_id,l=a.url;if("string"!=typeof s||""===s)throw new wa("E_SCHEMA",`${wc} references[${t}].element_id 缺失或不是非空字符串`,void 0,{flag:wc});if("string"!=typeof l||""===l)throw new wa("E_SCHEMA",`${wc} references[${t}].url 缺失或不是非空字符串(element_id=${s})`,void 0,{flag:wc});const c=/^([a-z]+)(\d*)$/i.exec(s);if(!c)throw new wa("E_SCHEMA",`${wc} references[${t}].element_id 不符合 <prefix><N?> 规范:${s}`,"形如 image1 / asset2 / audio1 / video1",{flag:wc});const d=c[1].toLowerCase(),u=c[2],p=""===u?0:Number(u);switch(d){case"image":o.push({n:p,id:s,url:l});break;case"asset":r.push({n:p,id:s,url:l});break;case"audio":i.push({id:s,url:l});break;case"video":n.push({id:s,url:l});break;default:throw new wa("E_SCHEMA",`${wc} 未知的 element_id 前缀:${s}`,"支持:image / asset / audio / video(后缀数字可选,作为排序)",{flag:wc})}}),i.length>1)throw new wa("E_SCHEMA",`${wc} 最多只能有一个 audio* 引用(实际 ${i.length}:${i.map(e=>e.id).join(", ")})`,void 0,{flag:wc});if(n.length>1)throw new wa("E_SCHEMA",`${wc} 最多只能有一个 video* 引用(实际 ${n.length}:${n.map(e=>e.id).join(", ")})`,void 0,{flag:wc});return o.sort((e,t)=>e.n-t.n),r.sort((e,t)=>e.n-t.n),t.image_urls=o.map(e=>e.url),t.ark_asset_ids=r.map(e=>e.url),i[0]&&(t.reference_audio_url=i[0].url),n[0]&&(t.ref_video_url=n[0].url),t}(t)}(e)))}return i},preflight:e=>{const t=String(e.service??"");if(function(e,t){if(!Sc(t))return;if("seedance-2-0-mini"===t&&"number"==typeof e.duration&&(e.duration<5||e.duration>12))throw new wa("E_SCHEMA","--duration must be between 5 and 12 for seedance-2-0-mini","Seedance 2.0 Mini supports 5-12s for text-to-video. Pick an integer duration in that range, then trim the final segment after generation if needed.",{verb:"generate-video",service:t,flag:"--duration"});if("string"!=typeof e.resolution)return;const i="seedance-2-0"===t?["480p","720p","1080p","4k"]:["480p","720p"];if(!i.includes(e.resolution)){const e=i.join(", ");throw new wa("E_SCHEMA",`--resolution must be one of ${e} for ${t}`,"seedance-2-0"===t?"Seedance 2.0 Pro 支持 480p、720p、1080p 和 4k;请使用小写 4k。":"Seedance 2.0 Fast / Mini 仅支持 480p 和 720p;1080p 与 4k 会被拒绝且不计价。",{verb:"generate-video",service:t,flag:"--resolution"})}}(e,t),function(e,t){if(Sc(t))return;const i=Array.isArray(e.ark_asset_ids)&&e.ark_asset_ids.length>0,n="string"==typeof e.prompt?e.prompt:"",o=/@asset\d+\b/.test(n);if(i||o)throw new wa("E_SCHEMA",`Seedance asset references require --service=seedance-2-0, --service=seedance-2-0-fast, or --service=seedance-2-0-mini, not ${t}`,"Fallback is allowed, but rebuild the segment for the target model first: generate role-locked frame/keyframe images from the character reference, then pass those frames through --image-url / --image-urls / --keyframes as supported by that model. Do not pass --ark-asset-ids or @assetN to non-Seedance services.",{verb:"generate-video",service:t,expected:"seedance-2-0|seedance-2-0-fast|seedance-2-0-mini",flag:i?"--ark-asset-ids":"--prompt"})}(e,t),function(e,t){if("grok-imagine-1.5"!==t)return;const i="string"==typeof e.image_url&&""!==e.image_url.trim(),n=Array.isArray(e.image_urls)?e.image_urls.filter(e=>"string"==typeof e):[];if(!i)throw new wa("E_SCHEMA","--image-url is required for grok-imagine-1.5","Grok Imagine 1.5 is exposed through api-layer as a single-reference image-to-video service. Pass exactly one reference via --image-url.",{verb:"generate-video",service:t,flag:"--image-url"});if(n.length>0)throw new wa("E_SCHEMA","--image-urls is not supported for grok-imagine-1.5","Use --image-url for the single reference image. Do not pass multi-reference images to Grok Imagine 1.5.",{verb:"generate-video",service:t,flag:"--image-urls"});if("number"==typeof e.duration&&(e.duration<1||e.duration>15))throw new wa("E_SCHEMA","--duration must be between 1 and 15 for grok-imagine-1.5","Pick an integer duration from 1 to 15 seconds.",{verb:"generate-video",service:t,flag:"--duration"});if("string"==typeof e.resolution&&"480p"!==e.resolution&&"720p"!==e.resolution)throw new wa("E_SCHEMA","--resolution must be 480p or 720p for grok-imagine-1.5","Use --resolution=480p or --resolution=720p. Other tiers are not supported by the api-layer Grok 1.5 provider.",{verb:"generate-video",service:t,flag:"--resolution"});if("string"==typeof e.aspect_ratio&&!["auto","1:1","16:9","9:16","4:3","3:4","3:2","2:3"].includes(e.aspect_ratio))throw new wa("E_SCHEMA","--aspect-ratio is not supported for grok-imagine-1.5","Use one of: auto, 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3.",{verb:"generate-video",service:t,flag:"--aspect-ratio"})}(e,t),"dlai2v_pro"!==t&&"dlai2v_pro_multiframe"!==t)return;const i="string"==typeof e.image_url&&""!==e.image_url,n=Array.isArray(e.keyframes)&&e.keyframes.length>0;if("string"!=typeof e.audio_url||""===e.audio_url)throw new wa("E_SCHEMA",`--audio-url is required for ${t} (the LTX 2.3 workflow derives video length from the driving audio)`,"pass --audio-url=<driving audio>; output length follows the audio. Do NOT use --duration to control length (billing-only here)",{verb:"generate-video",service:t});if(!i&&!n)throw new wa("E_SCHEMA",`either --image-url or --keyframes is required for ${t}`,"provide a face/scene still via --image-url, or multiple keyframes via --keyframes",{verb:"generate-video",service:t});if(i&&n)throw new wa("E_SCHEMA","--image-url and --keyframes are mutually exclusive","use --image-url for a single still (api-layer wraps it into keyframes[0]), or --keyframes for explicit multi-frame guidance; not both",{verb:"generate-video",service:t});if("dlai2v_pro_multiframe"===t){if(!n)throw new wa("E_SCHEMA","dlai2v_pro_multiframe requires --keyframes (2-4 frames); --image-url alone is not supported","pass 2-4 --keyframes flags; if you only have 1 image, use --service=dlai2v_pro instead",{verb:"generate-video",service:t});const i=e.keyframes.length;if(i<2||i>4)throw new wa("E_SCHEMA",`dlai2v_pro_multiframe requires 2-4 keyframes, got ${i}`,"adjust to 2/3/4 keyframes; api-layer routes to mutiframe_{2f,3f,4f} workflow by count",{flag:"--keyframes",verb:"generate-video",service:t})}else if(n&&e.keyframes.length>5)throw new wa("E_SCHEMA",`--keyframes accepts 1-5 frames for dlai2v_pro, got ${e.keyframes.length}`,"reduce to at most 5 keyframe images, or switch to --service=dlai2v_pro_multiframe (2-4 frames)",{flag:"--keyframes",verb:"generate-video",service:t})},modelTopic:{rankingSummary:["Overall quality tiers (strongest to weakest):"," 🥇 Top tier: seedance-2-0 family (Pro + Fast + Mini)"," 🥈 Runner-up tier: happyhorse-1-0-* family (r2v / i2v / video-edit)"," 🥈 Unique-capability tier: kling-o3-pro-v2v / kling-o3-v2v (video-to-video editing — Kling-side alternative to happyhorse-1-0-video-edit)"," 🥉 Third tier: rest of kling-o3-* family (ref2v Pro / std) + kling3.0"," Below that: dli2v3 / dlim2v / seedance-1-5","","This ranking is overall quality (character consistency / camera stability / physical plausibility / duration cap);","it does NOT mean you should always pick the top tier — special scenarios (video edit / Chinese prompt /","multi-ref) have exclusive capabilities per family.","","Note: seedance-2-0-fast and seedance-2-0-mini are cheaper variants of the same generation/family with the same","field shape (auto-keyframe / multi-ref / audio coupling / video ref continuation). Fast remains the quality/cost","baseline; Mini is the lowest-cost Seedance 2.0 option for draft / preview and budget-sensitive MV segments.","","Separate category — audio-driven talking / singing video (lip-synced, output length = driving audio, --audio-url REQUIRED):"," dlai2v_pro (single still or 1-5 keyframes) / dlai2v_pro_multiframe (2-4 keyframes, richer movement)"," — same LTX-2.3 engine as the matching `dl lipsync` services; use whichever verb your pipeline composes through."," longcat-avatar-1-5 (self-hosted; very stable lip-sync but slow ~8-10min)."," These are NOT ranked against the t2v/i2v tiers above — they solve a different problem."],services:[{service:"seedance-2-0",label:"Seedance 2.0 Pro",tier:"🥇 Top tier (Pro)",bestFor:"Overall strongest quality. Character consistency + auto-keyframe + video ref / continuation + audio-coupled generation — the fullest feature set. Expensive and requires asset register (for real-looking human / IP scenarios you must first call dl asset register)",quality:"Very High",speed:"2-5min",cost:"high",description:["ByteDance Seedance 2.0 Pro. Currently strongest overall quality, fullest capability set:"," - auto-keyframe (auto-generates multiple keyframes)"," - multi-reference images (image_urls)"," - video ref / continuation (raw video via ref_video_url, registered video via ark_asset_ids + @assetN)"," - audio coupling (reference_audio_url + @audio1)"," - duration <=15s or -1 for auto"," - resolution 480p / 720p / 1080p / 4k(4k 仅 Pro;720 credits/s)"],promptTips:["Placeholders are 1-indexed: @imageN → image_urls[N-1] / @audioN → reference_audio_url / @videoN → ref_video_url / @assetN → ark_asset_ids[N-1]","Registered Image / Video / Audio assets all use @assetN; do not switch a registered video asset back to @videoN","For audio + image lip-sync scenarios use dl lipsync — do not force-fit them into generate-video","reference_audio_url must be ≤15s and cannot be the only reference on its own (must be paired with image_urls or ref_video_url)"],constraints:["Real-looking human / known-IP inputs must be passed through dl asset register first; after registration pass that source ref via --ark-asset-ids + @assetN only, never again via --image-urls + @imageN or --ref-video-url + @videoN","Registered Video assets are valid Seedance refs; pass the asset id through --ark-asset-ids and mention @assetN in the prompt","r2v reference-video limit: ARK requires the total duration of all reference_video inputs to be <=15.2s. Multiple video refs are allowed only when they are distinct and their combined duration stays within the limit; never pass the same video twice as both registered Video asset and raw --ref-video-url.","If generated/output audio triggers moderation, retry with prompt text such as 'no BGM' / 'no background music'; do not pass --generate-audio","Field-name trap: use ref_video_url (not video_url) / reference_audio_url (not audio_url) — get it wrong and the vendor silently drops the ref","duration 4-15s or -1 (auto); the Pi CLI currently requires integer — use ceil(intended) then ffmpeg trim","Read skills/video-generation/docs/seedance_reference_assets.md (real-looking human scenarios)"],flagSubset:["service","prompt","duration","aspect-ratio","resolution","image-urls","reference-audio-url","ref-video-url","ark-asset-ids","generate-audio","reference-subject-type"],examples:[{caption:"single, seedance-2-0 with @audio1 + image ref",command:'dl generate-video --service=seedance-2-0 \\\n --prompt="the character speaks @audio1 with clear articulation, @image1 sets the scene" \\\n --duration=8 --aspect-ratio=16:9 --resolution=720p \\\n --image-urls=https://.../keyframe.jpg \\\n --reference-audio-url=https://.../speech.mp3'},{caption:"real-looking human with asset register",command:'# Register asset first\ndl asset register --group-id=actor-jane --name=jane-headshot \\\n --url=https://.../actor.jpg --asset-type=Image\n# Then generate (use the real asset_id from the previous step\'s response)\ndl generate-video --service=seedance-2-0 \\\n --prompt="@asset1 walks through a cyberpunk street, no BGM" \\\n --duration=6 --resolution=720p \\\n --ark-asset-ids=asset_xxx \\\n --reference-subject-type=real_person'},{caption:"registered reference video asset",command:'# Register video asset first\ndl asset register --group-id=healthfood-girl --name=tiktok-healthfood-ref \\\n --url=https://.../reference.mp4 --asset-type=Video\n# Then generate (use the real asset_id from the previous step\'s response)\ndl generate-video --service=seedance-2-0 \\\n --prompt="follow @asset1 for camera structure and action rhythm, no BGM" \\\n --duration=6 --aspect-ratio=9:16 --resolution=720p \\\n --ark-asset-ids=asset_xxx'}]},{service:"seedance-2-0-fast",label:"Seedance 2.0 Fast",tier:"🥇 Top tier (Fast variant)",bestFor:"Same family and capabilities as Pro (auto-keyframe / multi-ref / audio coupling / video ref), just slightly lower quality than Pro, faster, and cheaper. Prefer this when Pro is too expensive or you only need a preview — do not drop to a lower-tier model instead",quality:"Very High",speed:"1-3min",cost:"mid",description:["The Fast variant of seedance-2-0. Same family and capability set, slightly lower quality / faster / cheaper.","For default scenarios with no special requirements → pick this; do not default to Pro and do not default to a lower-tier."],constraints:["Constraints are identical to seedance-2-0: real-looking human / IP and registered video refs must go through asset register and then asset-only for that source ref (do not also pass its URL in image_urls or ref_video_url); ARK r2v reference_video total duration <=15.2s; distinct multi-video refs are allowed, but do not pass the same video twice through asset + raw URL; ref_video_url / reference_audio_url field-name trap; duration 4-15s integer; audio moderation fallback is prompt text 'no BGM', not --generate-audio","分辨率仅支持 480p / 720p;不支持 1080p / 4k"],flagSubset:["service","prompt","duration","aspect-ratio","resolution","image-urls","reference-audio-url","ref-video-url","ark-asset-ids","generate-audio"],examples:[{caption:"single, seedance-2-0-fast (default first choice)",command:'dl generate-video --service=seedance-2-0-fast \\\n --prompt="a corgi astronaut floating, slow zoom in" \\\n --duration=5 --resolution=720p'}]},{service:"seedance-2-0-mini",label:"Seedance 2.0 Mini",tier:"🥇 Top tier family (Mini / lowest-cost Seedance 2.0)",bestFor:"Lowest-cost Seedance 2.0 family option. Use it as the default low-cost preview / MV non-lipsync workhorse when budget matters more than Pro/Fast quality. Prefer Fast or Pro for hero shots, identity-critical close-ups, or final high-quality passes.",quality:"High",speed:"1-3min",cost:"low",description:["Dreamina Seedance 2.0 Mini via BytePlus ARK. Same command shape as seedance-2-0 / fast.","Model: dreamina-seedance-2-0-mini-260615. Supports 480p / 720p, 5-12s text-to-video, 24fps, and one concurrent upstream task.","Credits: 35 credits/s at 480p, 75 credits/s at 720p. 1080p / 4k 均不支持且不计价。"],constraints:["Reference rules are identical to seedance-2-0: real-looking human / IP and registered video refs must go through asset register and then asset-only for that source ref; do not also pass its URL in image_urls or ref_video_url","r2v reference-video limit: ARK requires total reference_video duration <=15.2s. Distinct multi-video refs are allowed, but do not pass the same video twice through asset + raw URL.","Resolution 仅支持 480p / 720p;1080p / 4k 会被拒绝且不计价","Duration 5-12s for text-to-video; use integer duration and trim after generation if the final segment is shorter","Field-name trap: use ref_video_url (not video_url) / reference_audio_url (not audio_url)"],flagSubset:["service","prompt","duration","aspect-ratio","resolution","image-urls","reference-audio-url","ref-video-url","ark-asset-ids","generate-audio"],examples:[{caption:"single, seedance-2-0-mini low-cost preview",command:'dl generate-video --service=seedance-2-0-mini \\\n --prompt="a cinematic handheld shot of a quiet neon alley, no BGM" \\\n --duration=5 --resolution=720p --aspect-ratio=16:9'}]},{service:"happyhorse-1-0-r2v",label:"HappyHorse 1.0 R2V (Alibaba)",tier:"🥈 Runner-up tier",bestFor:"Overall runner-up to seedance. Made by Alibaba, strong on Chinese prompts. 1-9 ref multi-subject composition",quality:"High",speed:"2-5min",cost:"mid",description:["Alibaba HappyHorse 1.0 reference-to-video (multi-ref composition).","Markedly better on Chinese prompts than other families; 1-9 reference images for multi-subject composition."],constraints:["image_urls 1-9 images is REQUIRED; prompt is also REQUIRED","aspect_ratio only 16:9 / 9:16 / 3:4 / 4:3 / 1:1 (no adaptive / 21:9)","resolution uses uppercase: 720P / 1080P (lowercase 720p is rejected — the opposite of other families!)","duration integer 3-15s"],flagSubset:["service","prompt","image-urls","duration","aspect-ratio","resolution","seed"],examples:[{caption:"multi-character composition",command:'dl generate-video --service=happyhorse-1-0-r2v \\\n --prompt="两个人在花园相遇,午后柔光" \\\n --image-urls=https://1.png --image-urls=https://2.png \\\n --duration=5 --resolution=1080P --aspect-ratio=16:9'}]},{service:"happyhorse-1-0-i2v",label:"HappyHorse 1.0 I2V",tier:"🥈 Runner-up tier",bestFor:"HappyHorse family — use this for the single-first-frame i2v scenario",quality:"High",speed:"2-5min",cost:"mid",description:["HappyHorse 1.0 single-first-frame image-to-video. Same family but only accepts a single image_url (not image_urls)."],constraints:["image_url (singular) is REQUIRED","resolution uppercase: 720P / 1080P (default 1080P)","duration 3-15s integer (default 5)"],flagSubset:["service","prompt","image-url","duration","resolution","seed"],examples:[{caption:"single first-frame i2v",command:'dl generate-video --service=happyhorse-1-0-i2v \\\n --prompt="角色缓慢转身,镜头微微推近" \\\n --image-url=https://.../first-frame.jpg \\\n --duration=5 --resolution=1080P'}]},{service:"happyhorse-1-0-video-edit",label:"HappyHorse 1.0 Video Edit",tier:"🥈 Exclusive capability",bestFor:"HappyHorse family video-to-video edit. The only true video editor in the whole table (change style / change scene while preserving composition)",quality:"High",speed:"3-5min",cost:"mid",description:["HappyHorse video-to-video edit. **The only entry in the generate-video table** that supports true","video editing: input a video + 0-5 refs + prompt, output a new video with changed style / scene but preserved","composition."],constraints:["video_url (singular) is REQUIRED — this is the source video; the field name differs from seedance's ref_video_url and **cannot be interchanged**","image_urls 0-5 optional (repeatable flag)","audio_setting: auto (default, HappyHorse decides) or origin (preserves source audio) — does not accept a generate_audio bool","Output duration = input video duration, do not pass --duration","resolution uppercase: 720P / 1080P"],flagSubset:["service","prompt","video-url","image-urls","resolution","audio-setting","seed"],examples:[{caption:"video edit — change scene to dusk",command:'dl generate-video --service=happyhorse-1-0-video-edit \\\n --prompt="keep original composition, change scene to dusk city skyline" \\\n --video-url=https://.../source.mp4 \\\n --image-urls=https://.../style-ref.png \\\n --resolution=1080P --audio-setting=auto'}]},{service:"kling-o3-pro-ref2v",label:"Kling O3 Pro Ref2V",tier:"🥉 Third tier",bestFor:"Kuaishou Kling O3 high-spec. multi-reference + character elements + first/end frame. Overall behind happyhorse",quality:"High",speed:"3-5min",cost:"mid",description:["Kling O3 ref-to-video Pro. Supports first frame + end frame + multi-reference","+ structured JSON via --elements to control character / scene elements. Overall quality slightly","below happyhorse, but first/end frame control is the advantage."],constraints:["image_url is the first frame, optional (without it, text-to-video only)","end_image_url is the last frame","elements is structured JSON: {frontal_image_url, reference_image_urls[]}"],flagSubset:["service","prompt","image-url","end-image-url","image-urls","elements","duration","aspect-ratio"],examples:[{caption:"first + end frame control",command:'dl generate-video --service=kling-o3-pro-ref2v \\\n --prompt="smooth transition from morning to noon" \\\n --image-url=https://.../start.png \\\n --end-image-url=https://.../end.png \\\n --duration=5 --aspect-ratio=16:9'}]},{service:"kling-o3-ref2v",label:"Kling O3 Ref2V",tier:"🥉 Third tier",bestFor:"Kling O3 standard. Same as Pro but slightly lower quality / cheaper",quality:"High",speed:"2-5min",cost:"low",description:["Kling O3 standard. Same params as Pro, slightly lower quality and cheaper. Backup when Pro is too expensive."],constraints:["Parameters are the same as kling-o3-pro-ref2v"],flagSubset:["service","prompt","image-url","end-image-url","image-urls","elements","duration","aspect-ratio"]},{service:"kling-o3-pro-v2v",label:"Kling O3 Pro V2V (video-edit)",tier:"🥈 Unique capability",bestFor:"Kling O3 Pro **video editing**: input video + prompt to change the frame contents; optional image_urls / elements as auxiliary refs. Pro quality. Use as the Kling-side alternative to happyhorse-1-0-video-edit or as fallback when seedance-2-0 video ref / continuation is unavailable.",quality:"Very High",speed:"3-5min",cost:"mid-high",description:["Kling O3 Pro **V2V (video-to-video) editing**. Input an existing video, write a prompt","describing how to change the frame contents (re-style / change scene / preserve composition),","and the model edits the input video accordingly. Auxiliary references via image_urls (≤4)","or structured elements JSON. Output duration / aspect_ratio **match the input video** —","you must NOT pass --duration / --aspect-ratio.","","Business positioning: Kling-side alternative to `happyhorse-1-0-video-edit` (Alibaba","ecosystem). Also a video-edit fallback when seedance-2-0 video-ref continuation is","unavailable."],promptTips:["Prompt describes the **edit operation** (e.g., 'change style to anime', 'replace background with night city', 'preserve composition, change wardrobe to formal suit')","image_urls (≤4) act as style / element auxiliary refs, not first-frame anchors","elements is structured JSON for fine-grained element control (see --print-schema)"],flagSubset:["service","prompt","video-url","image-urls","elements","negative-prompt","cfg-scale"],constraints:["video_url REQUIRED","Output duration / aspect_ratio = input video's (do NOT pass --duration / --aspect-ratio — raises E_SCHEMA or is silently overridden)","image_urls ≤ 4 auxiliary refs (optional)","Same param contract as kling-o3-v2v; Pro is higher quality / slower / more expensive"],examples:[{caption:"v2v Pro — change scene to anime",command:'dl generate-video --service=kling-o3-pro-v2v \\\n --prompt="re-style the video into anime; preserve composition and motion" \\\n --video-url=https://.../source.mp4 \\\n --image-urls=https://.../style-ref.png \\\n --negative-prompt="blurry, low contrast" --cfg-scale=7'}]},{service:"kling-o3-v2v",label:"Kling O3 Std V2V (video-edit)",tier:"🥈 Unique capability",bestFor:"Kling O3 standard **video editing**. Same param contract as Pro v2v but slightly lower quality / cheaper / faster. The cheap alternative to happyhorse-1-0-video-edit / Pro v2v.",quality:"High",speed:"2-5min",cost:"mid",description:["Kling O3 standard V2V (video-edit). Same input contract as kling-o3-pro-v2v","(video_url + prompt + optional image_urls / elements / negative_prompt / cfg_scale).","Slightly lower quality, faster, cheaper. Use as the cheap variant of Pro v2v, or","the Kling-side cheap alternative to happyhorse-1-0-video-edit."],promptTips:["Same as kling-o3-pro-v2v: prompt describes the edit operation, not a new scene from scratch"],flagSubset:["service","prompt","video-url","image-urls","elements","negative-prompt","cfg-scale"],constraints:["Same as kling-o3-pro-v2v (video_url required, output duration / aspect_ratio match input, image_urls ≤ 4)"]},{service:"kling3.0",label:"Kling 3.0",tier:"🥉 Third tier",bestFor:"Kling legacy version, i2v + audio support",quality:"High",speed:"1-3min",cost:"low",description:["Kling 3.0 (legacy). Usable for simple i2v + audio scenarios; overall behind kling-o3-*."],constraints:["image_url REQUIRED (image-to-video only)","sound / cfg-scale / negative-prompt optional"],flagSubset:["service","prompt","image-url","duration","aspect-ratio","sound","negative-prompt","cfg-scale"],examples:[{caption:"Kling 3.0 i2v with sound",command:'dl generate-video --service=kling3.0 \\\n --prompt="character speaks calmly" \\\n --image-url=https://.../portrait.jpg \\\n --duration=10 --aspect-ratio=16:9 --sound'}]},{service:"dli2v3",label:"Veo 3.1 Fast",tier:"Below that",bestFor:"Google Veo 3.1 Fast variant, text/image-to-video. Overall behind all of the above",quality:"Mid",speed:"1-3min",cost:"low",description:["Google Veo 3.1 Fast. 1-3 reference images, overall quality is middling."],constraints:["image_url 1-3, optional; last_frame_url optional; duration auto"],flagSubset:["service","prompt","image-url","last-frame-url","aspect-ratio"],examples:[{caption:"Veo 3.1 with first frame",command:'dl generate-video --service=dli2v3 \\\n --prompt="@image1 starts moving forward into the snow" \\\n --image-urls=https://1.png --duration=4'}]},{service:"dlim2v",label:"Grok Imagine",tier:"Below that",bestFor:"xAI Grok. Creative / stylized / fun mode is the strong suit, overall quality is middling",quality:"Mid",speed:"1-3min",cost:"low",description:["xAI Grok Imagine. Creative / fun stylized is the signature; overall quality is middling."],constraints:["duration 6s or 10s","mode=normal (default)"],flagSubset:["service","prompt","image-url","duration","aspect-ratio","mode"]},{service:"seedance-1-5",label:"Seedance 1.5 Pro",tier:"Below that",bestFor:"seedance legacy (1.5, NOT the 2.0 family); only suited to draft previews (first+last frame control)",quality:"Mid",speed:"1-3min",cost:"low",description:["seedance 1.5 Pro (legacy family — not the same generation as 2.0). first frame + last frame control,","only suited to draft previews; quality is clearly below the 2.0 family."],constraints:["duration 4-12s","first/last frame URL optional; generate-audio optional"],flagSubset:["service","prompt","image-url","last-frame-url","duration","aspect-ratio","resolution","generate-audio","seed"]},{service:"grok-imagine-1.5",label:"Grok Imagine 1.5 (xAI)",tier:"Single-reference i2v",bestFor:"xAI Grok Imagine 1.5 image-to-video from a SINGLE reference image. Fast, creative / stylized motion. Keep the prompt about action / camera / mood — do NOT over-describe makeup or fine facial detail (over-specifying makeup degrades the result).",quality:"Mid-High",speed:"1-3min",cost:"low",description:["xAI Grok Imagine 1.5 (preview). Single-reference image-to-video — one reference image drives the clip."," - takes exactly ONE reference image (image_url); it is NOT a multi-ref model"," - duration 1-15s, resolution 480p / 720p"," - strong at creative / stylized motion"],promptTips:["Single reference image only — pass it via --image-url","Keep the prompt focused on motion / camera / mood; do NOT over-describe makeup or fine facial detail — over-specifying makeup makes results worse"],constraints:["image_url REQUIRED (image-to-video, single reference)","duration 1-15s; resolution 480p / 720p","aspect_ratio: auto / 1:1 / 16:9 / 9:16 / 4:3 / 3:4 / 3:2 / 2:3"],flagSubset:["service","prompt","image-url","duration","aspect-ratio","resolution"],examples:[{caption:"single-ref i2v",command:'dl generate-video --service=grok-imagine-1.5 \\\n --prompt="she turns toward the camera and smiles, soft cinematic light" \\\n --image-url=https://.../portrait.jpg \\\n --duration=6 --resolution=720p'}]},{service:"gemini-omni-video",label:"Gemini Omni Video (Google)",tier:"Exclusive capability (video editing)",bestFor:"Google Gemini Omni any-to-any video. Its standout strength is VIDEO EDITING — feed a source video + prompt and it re-works the clip impressively. Also does text-to-video and image-to-video (up to 7 reference images).",quality:"High",speed:"2-5min",cost:"mid",description:["Google Gemini Omni any-to-any multimodal video generation."," - **video editing is the killer feature**: pass a source video (--video-url) + prompt to re-edit it"," - also text-to-video and image-to-video (image_urls up to 7)"," - duration 4 / 6 / 8 / 10s; resolution 720p / 1080p / 4k; aspect 16:9 / 9:16"],promptTips:["For video editing pass the source clip via --video-url and describe the edit in the prompt","--video-start / --video-ends (seconds) optionally select a SUB-SEGMENT to edit (e.g. only 2–7s of a clip). Omit them to edit from the start; the provider caps the edited segment at 10s, so for sources longer than 10s pass an explicit ≤10s window","image_urls (≤7) act as reference subjects for generation"],constraints:["prompt REQUIRED","duration one of 4 / 6 / 8 / 10 (default 8); IGNORED when --video-url is provided — the edit follows the source segment","resolution 720p / 1080p / 4k (default 720p); aspect_ratio 16:9 / 9:16","image_urls ≤ 7 (optional); --video-url is the source for video editing (optional)","--video-start / --video-ends (seconds): OPTIONAL source segment; ends>start, (ends-start) ≤ 10s; omit → from 0 up to 10s (api-layer default, no probing needed)","editing real / recognizable people (incl. realistic digital-human avatars) may be rejected by the provider's prominent-people safety filter — not a flag issue; use a non-Google v2v service (kling-o3-v2v / happyhorse-1-0-video-edit) for those"],flagSubset:["service","prompt","duration","aspect-ratio","resolution","image-urls","video-url","video-start","video-ends","seed"],examples:[{caption:"video editing — re-work a whole source clip (add --video-start/--video-ends only to edit a sub-segment)",command:'dl generate-video --service=gemini-omni-video \\\n --prompt="restyle this clip into a rainy neon cyberpunk night, keep the subject\'s motion" \\\n --video-url=https://.../source.mp4 \\\n --resolution=720p'},{caption:"text-to-video",command:'dl generate-video --service=gemini-omni-video \\\n --prompt="a paper boat sailing down a sunlit street gutter, cinematic" \\\n --duration=8 --aspect-ratio=16:9 --resolution=720p'}]},{service:"longcat-avatar-1-5",label:"LongCat 1.5 (self-hosted)",tier:"Exclusive capability (audio-driven talking-head)",bestFor:"Audio-driven talking-head: one face image + one driving audio → a lip-synced video. Lip-sync is very stable — that is the reason to pick it; the trade-off is speed (noticeably slow, ~8-10min). Self-hosted on our own RunPod.",quality:"High (lip-sync stability)",speed:"8-10min (slow)",cost:"mid",description:["Self-hosted LongCat 1.5 audio-driven talking-head (distinct from the WaveSpeed longcat-avatar in `dl lipsync`).","Feeds a single face image + a driving audio and renders a lip-synced talking-head video."," - lip-sync is very stable — the strongest reason to pick it"," - output length follows the driving audio (do not pass --duration)"," - width / height default 1280x720 (pass both together to override)"," - noticeably slow (~8-10min); use it when lip-sync fidelity matters more than turnaround"],promptTips:["image_url is the face; audio_url is the driving speech — both REQUIRED","prompt is optional and only lightly steers the scene; the mouth is driven by the audio, not the prompt"],constraints:["image_url (face) REQUIRED","audio_url (driving audio, ≤20s) REQUIRED","output length = audio length; do NOT pass --duration","width / height optional but must be passed as a pair (default 1280x720)"],flagSubset:["service","prompt","image-url","audio-url","width","height"],examples:[{caption:"talking-head from face + audio",command:"dl generate-video --service=longcat-avatar-1-5 \\\n --image-url=https://.../face.jpg \\\n --audio-url=https://.../speech.mp3"}]},{service:"dlai2v_pro",label:"LTX 2 Pro (LTX 2.3 audio-driven)",tier:"Exclusive capability (audio-driven talking / singing video)",bestFor:"Audio-driven talking / singing video: one face/scene still (or 1-5 keyframes) + a driving audio → a lip-synced clip whose length follows the audio. Same engine as `dl lipsync --service=dlai2v_pro`; reach for it here when your pipeline composes through generate-video rather than the lipsync verb.",quality:"Very High",speed:"2-5min",cost:"mid",description:["LTX 2 Pro (routes to the LTX-2.3 audio workflow). **Audio-driven** — the ComfyUI","workflow derives video length from the driving audio, so --audio-url is REQUIRED.","","Two visual-input modes (mutually exclusive):"," Mode 1 (single still): --image-url — api-layer auto-wraps it into keyframes[0]."," Mode 2 (multi-keyframe): --keyframes (1-5 frames) for richer camera movement;",' each keyframe is {"image_url":"...","frame_position":"first|middle|last"}.',"","Output length = audio length; do NOT pass --duration to control length (--duration is","billing-only here, the vendor ignores it)."],promptTips:["⚠ LTX-family prompt template — all three segments required:"," 1. Subject is speaking/singing (explicitly say the character speaks/sings with perfect lip sync)"," 2. Character action (head nods/tilts / gaze / hands / shoulders / breathing)"," 3. Camera movement (Dolly in / slow push in / static medium close-up — state static explicitly)","Append a quality / lighting tail: 'high quality, natural lighting'"],flagSubset:["service","prompt","image-url","audio-url","keyframes","duration"],constraints:["--audio-url REQUIRED (drives output length); audio ≤ 20s & ≤ 100MB; mp3 / wav / ogg / flac / m4a / aac / webm","--image-url and --keyframes are mutually exclusive; --keyframes 1-5 frames","Do NOT pass --duration to control length (billing-only); width / height / resolution are fixed by the workflow","For the same single image + audio lip-sync need you can equally use `dl lipsync --service=dlai2v_pro` — identical engine"],examples:[{caption:"single still + driving audio (talking-head)",command:'dl generate-video --service=dlai2v_pro \\\n --image-url="https://cdn.example.com/face.png" \\\n --audio-url="https://cdn.example.com/voice.mp3" \\\n --prompt="A person speaks naturally with perfect lip synchronization, subtle head nods and tilts, hands resting gently or making small conversational gestures, relaxed shoulders, natural breathing motion, high quality, natural lighting, Dolly in"'}]},{service:"dlai2v_pro_multiframe",label:"LTX 2 Pro Multi-frame (LTX 2.3 真·多帧)",tier:"Exclusive capability (keyframe-guided audio-driven video)",bestFor:"True multi-keyframe (2-4) guided, audio-driven video: the model interpolates animation across the keyframes while lip-syncing to the driving audio — richer camera / pose movement than single-still dlai2v_pro. Same engine as `dl lipsync --service=dlai2v_pro_multiframe`.",quality:"Very High",speed:"2-5min",cost:"mid",description:["LTX 2.3 真·多帧变体(真正的多帧关键帧引导,不是单帧 wrap)。**Audio-driven** — audio","时长决定视频帧数,所以 --audio-url 必填;api-layer 按 keyframes 数量自动 router 到","mutiframe_{2f,3f,4f} workflow。","",'每帧 keyframe:{"image_url"(必填),"frame_ratio"?(0.0-1.0 时间位置),"weight"?(0.0-1.0 强度,默认 0.4)}。',"frame_ratio 不传则按帧数等分:2帧=[0,1] / 3帧=[0,0.5,1] / 4帧=[0,0.33,0.67,1]。","所有 keyframe 必须同一角色、同一画幅。"],promptTips:["Same LTX-family three-segment template as dlai2v_pro (subject speaking/singing + character action + camera move)"],flagSubset:["service","prompt","keyframes","audio-url","aspect-ratio","duration"],constraints:["--keyframes REQUIRED, 2-4 frames (api-layer routes to mutiframe_{2f,3f,4f} by count); --image-url alone not supported — use dlai2v_pro for a single still","--audio-url REQUIRED (drives output length / frame count)","--aspect-ratio 支持 16:9 / 9:16 / 1:1;resolution 强制 720p(不可改);不支持 --width / --height / --resolution","Do NOT pass --duration to control length (billing-only)"],examples:[{caption:"3 keyframes + driving audio",command:'dl generate-video --service=dlai2v_pro_multiframe \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf1.png","frame_ratio":0}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf2.png","frame_ratio":0.5}\' \\\n --keyframes=\'{"image_url":"https://cdn.example.com/kf3.png","frame_ratio":1}\' \\\n --audio-url="https://cdn.example.com/segment.mp3" \\\n --aspect-ratio=9:16 \\\n --prompt="A person sings expressively with perfect lip synchronization, dynamic head movement, confident posture shifts, high quality, natural lighting, slow push in"'}]}],decisionLogic:[{when:"Default / no special requirement",pick:"seedance-2-0-mini for low-cost drafts / MV non-lipsync batches; seedance-2-0-fast when quality matters more"},{when:"Cost-sensitive but still wants Seedance 2.0 reference consistency",pick:"seedance-2-0-mini (lowest-cost Seedance 2.0 family option; 480p/720p only, 5-12s)"},{when:"Want the highest overall quality + need character consistency / video ref / audio coupling",pick:"seedance-2-0 (top-tier Pro, expensive)"},{when:"Real-looking human / known-IP actor",pick:"seedance-2-0 / seedance-2-0-fast / seedance-2-0-mini, **must first run dl asset register**"},{when:"Already registered a Seedance reference video asset",pick:"seedance-2-0 / seedance-2-0-fast / seedance-2-0-mini with --ark-asset-ids + @assetN, not --ref-video-url + @videoN"},{when:"Video editing (change style / change scene while preserving composition)",pick:"happyhorse-1-0-video-edit (Alibaba-side, Chinese-prompt-friendly) OR kling-o3-pro-v2v / kling-o3-v2v (Kling-side; also serves as fallback when happyhorse / seedance-2-0 video-ref is unavailable)"},{when:"Chinese prompt / Alibaba preference / 1-9 multi-subject refs",pick:"happyhorse-1-0-r2v or happyhorse-1-0-i2v"},{when:"multi-reference + character elements + first/end frame control",pick:"kling-o3-pro-ref2v (quality-priority) or kling-o3-ref2v (cheap)"},{when:"Quick draft preview",pick:"seedance-2-0-mini (cheapest Seedance 2.0) or seedance-2-0-fast (higher quality)"},{when:"Creative / fun stylized",pick:"dlim2v (Grok specialty)"},{when:"Single-reference creative i2v (one image → stylized motion)",pick:"grok-imagine-1.5 (xAI; single ref image, keep prompt off makeup / facial detail)"},{when:"Edit / re-work an existing video clip (any-to-any)",pick:"gemini-omni-video (Google; standout at re-editing a source video) — also see happyhorse-1-0-video-edit / kling-o3-pro-v2v"},{when:"Audio-driven talking-head / stable lip-sync",pick:"longcat-avatar-1-5 (self-hosted; very stable lip-sync, slow ~8-10min). For other lip-sync routes see dl lipsync"},{when:"Audio-driven talking / singing video from a single still (lip-synced, output = audio length)",pick:"dlai2v_pro (LTX 2 Pro, audio-driven; --image-url + --audio-url). Same engine as dl lipsync --service=dlai2v_pro"},{when:"Audio-driven video with 2-4 keyframe guidance (richer camera / pose movement, lip-synced)",pick:"dlai2v_pro_multiframe (LTX 2.3 multi-frame; 2-4 --keyframes + --audio-url). Same engine as dl lipsync --service=dlai2v_pro_multiframe"}]},preflightTopic:{intro:"Before the first dl generate-video call, these five decisions must be explicit (for the per-service flag shape see `dl generate-video model <service>` — positional; `model -h <service>` short-circuits to the overview):",decisions:[{name:"Service / model",description:"Which service to use. Decide per the SERVICES table + DECISION LOGIC in `dl generate-video model -h` (overview), or `dl generate-video model <service>` (per-service profile)."},{name:"Duration plan",description:"Provider's valid duration range + the trim-back plan if the final segment is shorter than the provider min.\nseedance-2-0 / fast currently require integer duration (4-15s); seedance-2-0-mini requires 5-12s — use ceil(intended) then ffmpeg trim;\nhappyhorse video-edit's duration auto-follows the source video — do not pass it."},{name:"Aspect ratio",description:"Target frame ratio. The allowed enum varies per service:\n seedance-2-0 supports adaptive / 16:9 / 4:3 / 1:1 / 3:4 / 9:16 / 21:9;\n happyhorse-r2v does not accept adaptive / 21:9, only 16:9 / 9:16 / 3:4 / 4:3 / 1:1."},{name:"Resolution package",description:"Resolution tier. Field-casing trap per service:\n seedance-2-0 Pro 使用小写 480p / 720p / 1080p / 4k;Fast / Mini 仅支持小写 480p / 720p;\n happyhorse-* uses **uppercase** 720P / 1080P (lowercase is rejected — opposite of seedance)."},{name:"Reference-input plan",description:"Which image / audio / video / asset will enter this call.\nReal-looking human / IP → Seedance 2.0 family must first go through dl asset register, then submit that source ref asset-only; do not also submit its URL.\nIf a video has already been registered as an asset, submit its asset id via --ark-asset-ids and use @assetN; do not submit the same URL via --ref-video-url.\nFor Seedance r2v, ARK counts all reference_video inputs together and requires total duration <=15.2s; multiple video refs are allowed only when they are distinct and fit the combined-duration limit."}],notes:["Seedance 2.0 family mandatory preflight: using a real-looking human but skipping asset register, or submitting the same source ref both as ark_asset_ids and raw image/video URL fields, causes upstream policy block or unpredictable result","Seedance r2v reference-video limit: ARK requires all reference_video inputs together to be <=15.2s; distinct multi-video refs are allowed, but do not pass the same video twice through registered asset + raw URL.","If Seedance generated/output audio is moderation-blocked, retry with prompt text 'no BGM' / 'no background music'; do not pass --generate-audio","If cost-sensitive or unsure about service choice, read pricing-and-policies-dramaland-faq/SKILL.md before locking the package"]},policyTopic:{intro:"Three classes of hard rules: external communication must not leak internal details; paid package must be authorized before submit; URLs must be real and accessible.",rules:[{title:"1. User-Facing Communication Rule — do not leak internal details",body:["Never surface vendor / backend internal name / USD/RMB price /","internal model code (seedance-2-0 vendor routing etc.) / trace identifier","(job_id / task_id / request_id / other UUIDs) to the end user.","","User-facing summary should mention **only**:"," - service name (seedance-2-0 / happyhorse-1-0-r2v / kling3.0 etc.)",' - user-meaningful constraint (duration, aspect, "edit" vs "generate" etc.)'," - action (generate / edit video)"]},{title:"2. Production Package Gate — do not call before paid authorization",body:["service / model, duration plan, aspect ratio, resolution, generation count (including batch","segment range), and image / audio / video / asset reference plan are all components of the system",'prompt-level "paid media production package authorization". Do not submit before authorization.',"","Within the same authorized package you can batch-generate — do not block per segment.","Only re-ask on package overflow (switching service / changing duration / changing resolution /","adding count / fallback / paid regeneration)."]},{title:"3. URL Hygiene — do not fabricate storage URLs",body:["All reference URLs (image / audio / video) must be real accessible HTTPS. Legal sources:"," - dl generate-image-prompt / dl generate-image-ref / dl generate-music / other submit results (GCS URLs)"," - URLs uploaded by the user or provided by the conversation context"," - URLs returned by dl content list or other platform queries","","NEVER fabricate or guess storage URLs. If a reference image is missing, generate it via dl","generate-image-prompt or generate-image-ref first; if audio is missing, generate it — do not invent domains / paths.","","Seedance 2.0 registered refs are stricter: after dl asset register, pass only","--ark-asset-ids + @assetN for that media; do not also submit its raw image/video URL.","For Seedance r2v, ARK requires total reference_video duration <=15.2s across all video refs.","Distinct multi-video refs are allowed; do not duplicate the same source through asset + raw URL.","If output audio is moderation-blocked, retry with prompt text 'no BGM' / 'no background music';","do not pass --generate-audio."]}]},compositionTopic:{intro:"This atomic skill only produces a video URL; artifact / canvas registration and other downstream responsibilities are not this verb's job.",integrations:[{skill:"full-song MV / multi-segment video workflow",rule:["Distinguish the storyboard's intended final segment duration from the provider request","duration. If the final segment is shorter than the provider min, request the provider min, then ffmpeg","trim back to the original intended length. Do not round up to a whole number / do not audio-retime to match provider duration.","","If the provider requires integer duration (seedance-2-0 currently does), use ceil(intended);","do not floor / do not nearest-integer round.","","If the segment already has resolved reference assets (reference_list) → pass those real","URLs / registered asset ids directly; do not rely on prompt text alone.","For Seedance real-looking human media, pass the registered asset id only and omit the same raw URL.","For Seedance video references, use registered asset ids for registered videos and raw URLs for unregistered videos; do not send the same source through both channels."]},{skill:"ffmpeg (probe / trim / concat / crop)",rule:["This verb only handles vendor generation, no ffmpeg work. For trim / concat / probe →","load the ffmpeg skill and use dl ffmpeg; do not install system ffmpeg in the sandbox."]},{skill:"right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs dl artifact write / patch-json pi_media_log on your behalf —","that is the composition layer's job. The upstream workflow (visual-production / music-video","composition) is responsible for placing the returned URL into its own artifact slot."]}]},asyncTopic:{intro:["dl generate-video by default returns { job_ref, status: 'pending' } and exits immediately — do not poll.","Results are injected into the current session as [async-callback] job=<ref> text; typical duration 1-5 minutes.","","Only run dl poll separately when 'the next step strictly requires the result' (e.g. immediately feeding ffmpeg)."],resultShape:['{ "url": "https://storage.googleapis.com/.../video.mp4",',' "original_url": "...",',' "vendor": "..." }'],notes:["The URL field is the atomic skill's sole product handed up to the upper layer","The vendor field is debug-only; per the user-facing communication policy, do not leak it to the user","⚠ This URL already lives on our GCS — feed it directly to downstream tools / artifacts; do NOT pass to upload_file (would re-host an identical blob under a different URL)."]},publishTopic:{intro:["After producing your video URL, call publish_content with","presentation_family='video' and the explicit media fields. See","'Publishing Your Work / video' in your creation playbook for the full","field mapping template."],fields:[{name:"presentation_family",value:"'video'"},{name:"media_urls.video",value:"<returned video URL>"},{name:"frameRatio",value:"<from your aspect_ratio decision>"},{name:"thumbnail_url",value:"<optional poster frame>"},{name:"duration_seconds",value:"<intended final, after ffmpeg trim>"},{name:"delivery_format",value:"'video'"},{name:"experience_format",value:"'passive_media'"}]}})}(_d),function(e){Ps(e,{verb:"generate-music",actionName:"generate_music",schema:Yo,billing:{schema:bl,select:e=>({service:e.service}),quote:wl},supportsBatch:!0,description:"Generate music from a required prompt; prompt is music direction unless --custom makes it lyrics.",notes:["Services: suno-v5, suno-v5_5, minimax.","`--prompt` is always required; there is no title/tags-only mode.","`--custom` changes prompt semantics: with --custom it is lyrics; otherwise it is music direction and Suno may write lyrics.","`--instrumental` requests no vocals; still pass --prompt as music direction and usually omit --custom.","`--vocal-gender` is capitalized: `Male` / `Female` (not lowercase) — backend is case-sensitive.","Need lyrics for `--custom` and the user did not provide any? Run `dl generate-lyrics --prompt=<brief>` first (returns 2-3 candidates with [Verse]/[Chorus] markers); only hand-write lyrics yourself when that command fails."],whenToUse:["You need a generated music track from a required music brief or explicit lyrics","You're producing a music-video reference track and want to fan out style variants via --jobs-file"],whenNotToUse:["You need spoken text — use `dl generate-tts`","You need beat positions of an existing audio file — use `dl analyze-beats`"],examples:[{caption:"suno-v5_5, model-written lyrics",command:'dl generate-music \\\n --service=suno-v5_5 \\\n --prompt="bright synth-pop anthem with retro arcade textures, energetic chorus, glossy modern mix" \\\n --title="Neon High Score" \\\n --tags="synth-pop, retro arcade, energetic, glossy chorus" \\\n --vocal-gender=Female'},{caption:"instrumental only",command:'dl generate-music \\\n --service=suno-v5_5 \\\n --prompt="wordless cinematic piano and warm string pads, slow emotional build, 72 BPM, clean mix" \\\n --title="After the Rain" \\\n --tags="instrumental, cinematic piano, warm strings, reflective, 72 BPM" \\\n --negative-tags="vocals, singing, lyrics, spoken word" \\\n --instrumental'},{caption:"custom lyrics",command:'dl generate-music \\\n --service=suno-v5_5 \\\n --prompt="[Verse] Neon streets are waking [Chorus] We rise above the static" \\\n --title="Above the Static" \\\n --tags="electropop, female vocal, uplifting chorus" \\\n --custom \\\n --vocal-gender=Female'}],notExamples:[{command:'dl generate-music --service=suno-v5_5 --title="After the Rain" --tags="instrumental, cinematic" --instrumental',whyItFails:"--prompt is required even for instrumental tracks; derive a brief from the title/tags instead"},{command:'dl generate-music --params=\'{"service":"suno-v5","prompt":"..."}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"url":"https://storage.../audio.mp3","duration_ms":120000}}',modelTopic:{rankingSummary:["Ranked by overall quality (head-to-head on the same song; earlier = stronger):"," 🥇 suno-v5_5 (2 tracks) — current strongest Suno; vocals / arrangement / mix all beat v5 and minimax;"," long structure (verse / chorus / bridge) is stable. **Default / preferred for final delivery.**"," 🥈 suno-v5 (2 tracks) — previous-generation Suno; clearly lower quality than v5_5, but still **significantly stronger than minimax**."," Fall back to it only when v5_5 is unavailable or when you want dual-service comparison candidates."," 🥉 minimax (1 track) — single-track fast generation; quality below both Suno tiers (more mechanical vocals),"," fastest single-track speed, lowest cost. **Only suitable as a stopgap BGM / placeholder / quick demo**; not recommended for final delivery."],services:[{service:"suno-v5_5",label:"Suno V5.5",tier:"🥇 Default / Strongest",bestFor:"Default / unsure / final delivery. Vocals, arrangement, and mix are all strongest; long structure is stable",quality:"Very High",speed:"1-3min",cost:"mid-high",description:["Suno V5.5, Pi's current strongest music service. Each generation returns **2 candidate tracks**","(MUST normalize them into music_candidate.content[] preserving all of them; finalize only after user pick)."],promptTips:["prompt semantics shift with --custom / --instrumental:"," No-vocal BGM: --instrumental + prompt = music direction (style / mood / arrangement /"," BPM / structure / use case); do NOT write lyrics; usually omit --custom"," Suno writes its own lyrics: omit --custom + omit --instrumental + prompt = music direction"," Custom lyrics: --custom + prompt = actual lyrics; STRONGLY recommended to use [Verse] /"," [Chorus] / [Bridge] / [Outro] structure markers","","title / tags are auxiliary controls only — they CANNOT replace prompt (prompt is always required).","For pure music, add --negative-tags='vocals, singing, lyrics, spoken word' to reinforce no-vocal."],flagSubset:["service","prompt","title","tags","negative-tags","custom","instrumental","vocal-gender"],constraints:["⚠ Always returns 2 tracks; evaluate and recommend the best, but MUST NOT use a track as the downstream music_url without user pick","--vocal-gender is case-sensitive: `Male` / `Female` (not lowercase)","No native duration parameter — express target duration via prompt + tags"],examples:[{caption:"suno-v5_5, Suno-written lyrics (default case)",command:'dl generate-music --service=suno-v5_5 \\\n --prompt="bright synth-pop anthem with retro arcade textures, energetic chorus, glossy modern mix" \\\n --title="Neon High Score" \\\n --tags="synth-pop, retro arcade, energetic, glossy chorus" \\\n --vocal-gender=Female'},{caption:"suno-v5_5, custom lyrics",command:'dl generate-music --service=suno-v5_5 \\\n --prompt="[Verse] Neon streets are waking [Chorus] We rise above the static" \\\n --title="Above the Static" \\\n --tags="electropop, female vocal, uplifting chorus" \\\n --custom --vocal-gender=Female'},{caption:"suno-v5_5, instrumental / no-vocal BGM",command:'dl generate-music --service=suno-v5_5 \\\n --prompt="wordless cinematic piano and warm string pads, slow emotional build, 72 BPM, clean mix for a reflective closing scene" \\\n --title="After the Rain" \\\n --tags="instrumental, cinematic piano, warm strings, reflective, 72 BPM" \\\n --negative-tags="vocals, singing, lyrics, spoken word" --instrumental'}]},{service:"suno-v5",label:"Suno V5",tier:"🥈 Runner-up",bestFor:"v5_5 unavailable, or you want v5_5 + v5 dual-service comparison candidates",quality:"High",speed:"1-3min",cost:"mid",description:["Suno V5, previous generation. Vocal nuance / harmonic layering / style fidelity are all clearly","below v5_5, but still **significantly stronger than minimax**. Also returns 2 tracks. Parameters /","semantics are identical to v5_5 — only the service name differs."],promptTips:["Same as suno-v5_5; the custom / instrumental triangle contract is identical"],flagSubset:["service","prompt","title","tags","negative-tags","custom","instrumental","vocal-gender"],constraints:["Same as suno-v5_5 (2 tracks / user pick required / vocal-gender casing)"]},{service:"minimax",label:"MiniMax Music",tier:"🥉 Stopgap placeholder",bestFor:"ONLY stopgap BGM / placeholder music / quick demo, or when the user explicitly asks for fast/cheap",quality:"Mid",speed:"30-90s",cost:"low",description:["MiniMax single-track fast generation. Quality is below both Suno tiers (more mechanical vocals,","weaker style control, flatter structure). Single track → single candidate (one entry in content[];","the selected fields can be set directly on the first write).","**Not recommended for final delivery.**"],promptTips:["Same custom / instrumental semantics as the Suno family"],flagSubset:["service","prompt","title","tags","negative-tags","custom","instrumental","vocal-gender"],constraints:["⚠ Single-track return — no head-to-head comparison candidate","minimax title is forwarded into params; the api-layer may echo it in the result (not guaranteed to reach the upstream API)"]}],decisionLogic:[{when:"Default / unsure / final delivery",pick:"suno-v5_5 (strongest quality)"},{when:"v5_5 having issues / want dual-service comparison candidates",pick:"add suno-v5 (do NOT fall straight to minimax)"},{when:"ONLY stopgap BGM / placeholder / quick demo, or user explicitly asks fast/cheap",pick:"minimax"},{when:"Need lyrics but user did not provide any",pick:"Call `dl generate-lyrics --prompt=<brief>` first (returns 2-3 candidates), pick one, then Any Suno service + custom: true. Fall back to agent-written lyrics or `custom: false` only when generate-lyrics is unavailable"},{when:"Let Suno write its own lyrics (no separate lyrics call)",pick:"Any Suno service + custom: false"},{when:"User has already provided complete lyrics",pick:"Any Suno service + custom: true + [Verse]/[Chorus] markers"},{when:"No-vocal BGM (no lyrics)",pick:"Any service + --instrumental + prompt = music direction"}]},preflightTopic:{intro:"Explicitly prepare the generation brief before the first dl generate-music call — if ANY of the 7 items below is undecided, do not start the call:",decisions:[{name:"Generation mode",description:"Net-new generation vs remix / continuation. **The current CLI only exposes net-new.**\nIf the request is remix / continuation and the runtime exposes no true remix controls, STOP and\nsurface the capability mismatch directly — do not disguise it as a normal generate call."},{name:"Instrumental vs vocal",description:"Decide whether to pass --instrumental. The prompt-writing rule follows from this choice."},{name:"Custom mode (decide explicitly, do not rely on default)",description:"--custom determines prompt semantics:\n --custom=true → prompt is the **actual lyrics**; use [Verse] / [Chorus] / [Bridge] structure markers\n --custom=false → prompt is **music direction**; Suno may write its own lyrics (unless --instrumental)\nDo not rely on defaults — make the decision explicit."},{name:"Lyrics strategy",description:'For a vocal track: are lyrics provided by the user / generated via `dl generate-lyrics` / written by the agent / left to Suno via non-custom mode?\n**Preferred order when the user did not hand over lyrics:**\n 1. Try `dl generate-lyrics --prompt="<short brief, ≤200 chars>"` first — returns 2-3 KIE-Suno lyric candidates with [Verse]/[Chorus] markers; pick one and feed it as `dl generate-music --custom --prompt=<lyrics>`.\n 2. If `dl generate-lyrics` returns E_BACKEND / sensitive-word block / timeout, fall back to writing lyrics yourself with explicit [Verse]/[Chorus]/[Bridge] structure markers.\n 3. Only let Suno auto-write lyrics (omit --custom) when neither route is available or the brief is too vague to land lyrics.\nA pure instrumental track MUST NOT include lyric text in the prompt and SHOULD NOT call generate-lyrics.'},{name:"Target duration",description:"Target seconds or duration band. The current generate_music CLI has NO native duration parameter,\nso this intent must be expressed via prompt / title / tags and reflected in the subsequent evaluation."},{name:"Style package",description:"title / tags / negative-tags / era / genre / energy / tempo feel / instrumentation /\nvocal-gender (when relevant) — all need to be decided before calling the service."},{name:"Service choice (decide only after the brief is fully clear)",description:"Choose service from the brief: default suno-v5_5 / add suno-v5 for dual candidates / minimax only for stopgap.\nCost-sensitive or unclear choice → read pricing-and-policies-dramaland-faq/SKILL.md first, then lock."}],notes:["Cost-sensitive / unclear service → read pricing-and-policies-dramaland-faq/SKILL.md first","Batch generation goes through --jobs-file (JSON array); do not block per item; escape multi-line lyrics with \\n inside JSON strings"]},policyTopic:{intro:"Five categories of hard rules: User-facing isolation / Package gate / **Prompt-Custom-Instrumental triangle contract** / **Artifact-Finalize Gate** / Fallback ladder.",rules:[{title:"1. User-Facing Communication — never leak internal details",body:["Vendor / pricing / internal model code (Suno V5.5 / Suno V5 / MiniMax) / trace id must NOT","surface to the user. User-facing summary only mentions: service alias (Suno / MiniMax) +","action (generate music / score / candidate songs) + candidate count."]},{title:"2. Production Package Gate — never call before authorization",body:["service / generation count / candidate count / instrumental / vocal / custom mode / lyrics","strategy / target duration / style package / source / brief plan are all components of the paid","package authorization. Do not call before authorization; once authorized, batch and normalize","candidates within the package — do not block per candidate. Only re-ask on package overflow","(service swap / candidate-count change / duration change / lyrics-strategy change / fallback /","paid regeneration)."]},{title:"3. Prompt / Custom / Instrumental Triangle Contract (#391)",body:["`prompt` is ALWAYS required; there is no 'title + tags only' generation mode.","","| Goal | Flags | prompt meaning |","|-----|-----|-------------|","| No-vocal BGM | --instrumental, usually OMIT --custom | **Music direction**: style / mood / arrangement / tempo / structure / scene. Do NOT write lyrics |","| Suno writes lyrics | OMIT --custom, OMIT --instrumental | **Music direction**; Suno V5.5 / V5 writes its own lyrics based on the brief |","| Custom lyrics | Pass --custom | **Actual lyrics**; recommended to use [Verse] / [Chorus] / [Bridge] / [Outro] structure markers |","","For pure music, add --negative-tags='vocals, singing, lyrics, spoken word' to reinforce the no-vocal constraint.","title and tags are auxiliary controls only — they CANNOT replace prompt.","If the user only provided title / tags, synthesize a short prompt from them first — do not omit prompt.","For multi-line lyrics, prefer --jobs-file and escape with \\n inside JSON strings; do not use literal heredoc newlines.","Need lyrics but the user did not provide any? Call `dl generate-lyrics --prompt=<short brief>` first (KIE Suno, returns 2-3 candidates with [Verse]/[Chorus] markers) and feed the chosen text into --custom. Only hand-write lyrics yourself when generate-lyrics fails."]},{title:"4. Artifact-Finalize Gate (music_candidate slot)",body:["Results from this verb MUST land in the music_candidate slot (new artifact protocol — pure","domain `data`, no UI fields). Landing flow:",""," 1. Read schemas/artifact_contract.json (in this skill's directory); record ARTIFACT_CONTRACT_PATH"," 2. Read schemas/music_candidate.schema.json + templates/music_candidate.minimum.json"," 3. Normalize the provider response into data.candidates[] — preserve ALL tracks;"," normalize tags 'pop, electronic' into the array ['pop', 'electronic']; each candidate"," includes a lyrics field (#306)"," 4. Single-track (minimax) → one entry; data.selected_candidate_index = 0 and"," data.selected_audio_url copied from candidates[0].audio_url on the first write"," 5. Multi-track (suno-v5 / suno-v5_5) → multiple entries in data.candidates[]; selected_* = null;"," MUST wait for user pick (media_choice ask rendered from candidates[]) before patch-json"," selected_candidate_index + selected_audio_url, then re-finalize","","⚠ Any artifact call failure → the slot does not exist; do NOT pretend it succeeded / do NOT keep using a temp file.","⚠ ARTIFACT-FINALIZE GATE requires user consent before finalize; do NOT finalize a multi-track candidate before pick."," selected_audio_url is only usable as the downstream music_url when the slot is verified + non-null."]},{title:"5. Fallback Ladder",body:["When this verb produces issues (insufficient quality / wrong style / moderation block / service unavailable), in order:","","1. Retry once (transient network / quota jitter usually clears)","2. Edit prompt: strengthen style brief; add negative-tags; fill missing [Verse]/[Chorus] structure markers","3. Swap service: v5_5 → add v5 head-to-head (do NOT fall straight to minimax)","4. Adjust mode switches: vocal-gender / instrumental / custom","5. Only fall back to minimax when the user explicitly asks for 'fast/cheap' or confirms it is a stopgap placeholder"]}]},compositionTopic:{intro:"This atomic skill mandatorily lands results in the music_candidate artifact slot; downstream (lipsync / analyze-beats / publish_content) consumes selected_audio_url (only after user pick + finalize).",integrations:[{skill:"dl artifact (music_candidate slot)",rule:["MANDATORY: after generation, normalize results into the music_candidate slot (Artifact protocol 0509)."," - Multi-track providers (suno-v5 / suno-v5_5) → preserve all candidates in content[];"," selected_* = null; wait for user pick before patch-json + re-finalize"," - Single-track provider (minimax) → wrapper selected_* can be set on the first write","See schemas/music_candidate.schema.json and the schemas/ + templates/ in this skill's directory."]},{skill:"dl lipsync (audio source for lipsync)",rule:["selected_audio_url can be used as lipsync --audio-url.","⚠ Only usable when the slot is verified + selected_audio_url is non-null; otherwise treat as not generated."]},{skill:"dl analyze-beats (beat / sync points)",rule:["MV beat sync: selected_audio_url → dl analyze-beats to extract beats + segmentation."]},{skill:"publish_content (final delivery)",rule:["publish_content presentation_family='text' + media_urls.audio=<url> +","delivery_format='audio' (the runtime does NOT auto-infer audio from presentation_family,","media_urls.audio MUST be written explicitly)."]}]},asyncTopic:{intro:["dl generate-music returns { job_ref, status: 'pending' } and exits immediately by default — do NOT poll.","The result is injected into the session as [async-callback] job=<ref> text; typical wait is 1-3 minutes (minimax 30-90s).","If the next step must have the result (immediately normalize into the artifact or feed lipsync) →","query separately with dl poll --job-ref=<ref>; dl subcommands themselves no longer support --wait blocking (#294)."],resultShape:["// suno-v5 / suno-v5_5 (2 tracks)",'{ "musics": [',' { "id": "<uuid>", "audio_url": "https://storage.../track1.mp3",',' "title": "...", "tags": "...", "prompt": "..." },',' { "id": "<uuid>", "audio_url": "https://storage.../track2.mp3", ... }'," ] }","// minimax (1 track)",'{ "audio_url": "https://storage.../track.mp3", "title": "...", ... }',"vendor / internal metadata fields MUST NOT be exposed to the user"],notes:["⚠ Do NOT write a bash poll loop (while sleep + dl poll) — forbidden by the agent runtime async rules (#389)","Batch goes through --jobs-file; each job's completion is pushed back independently via [async-callback]"]},publishTopic:{intro:["After producing audio_url, publish_content goes through the 'text' presentation_family (audio is not a standalone family).","The runtime does NOT auto-infer audio from presentation_family; media_urls.audio MUST be written explicitly."],fields:[{name:"presentation_family",value:"'text'"},{name:"media_urls.audio",value:"<selected_audio_url> (only available after user pick + slot verified)"},{name:"delivery_format",value:"'audio'"}]}})}(_d),function(e){Ps(e,{verb:"generate-sound",actionName:"generate_sound",schema:Wo,supportsBatch:!0,description:"Generate a short sound effect (SFX / Foley / ambient / short loop) from a text description. ElevenLabs Sound Effects v2, duration 0.5–30s.",notes:["Only service is `elevenlabs-sound` (single provider for now).","`--duration-seconds` hard cap is 30s (ElevenLabs v2 limit). Omit to let the model pick a duration.","`--loop` produces a seamlessly looping clip — only valid on v2 (the default model).","`--prompt-influence` controls how strictly the model follows the text (0–1, default 0.3 server-side).","For a full song with vocals or longer than 30s, use `dl generate-music` instead."],whenToUse:["You need a short cinematic SFX / Foley / ambient bed / UI sound / short loop","You want a looping background texture for a video or scene transition","Batch dispatch a set of SFX cues via --jobs-file (each job 0.5–30s)"],whenNotToUse:["You need a full music track with melody / vocals / structure — use `dl generate-music`","You need spoken text — use `dl generate-tts`","You need an audio file longer than 30 seconds — current SFX model caps at 30s"],examples:[{caption:"rain ambience, 10s",command:'dl generate-sound \\\n --service=elevenlabs-sound \\\n --text="steady rain on a tin roof, distant low thunder, no music" \\\n --duration-seconds=10'},{caption:"UI confirmation chime, seamless loop",command:'dl generate-sound \\\n --service=elevenlabs-sound \\\n --text="soft synthetic confirmation chime, two short notes, clean digital" \\\n --duration-seconds=2 \\\n --loop \\\n --prompt-influence=0.6'},{caption:"short emotional music bed (probe SFX model for short-music territory)",command:'dl generate-sound \\\n --service=elevenlabs-sound \\\n --text="dreamy romantic piano with soft strings, warm and intimate, slow tempo" \\\n --duration-seconds=15'}],notExamples:[{command:'dl generate-sound --service=elevenlabs-sound --text="..." --duration-seconds=60',whyItFails:"duration_seconds is capped at 30 by the ElevenLabs SFX v2 model; the schema rejects values > 30"},{command:'dl generate-sound --service=elevenlabs-sound --text="full pop song with vocals and chorus"',whyItFails:"This verb is short-SFX only; for vocal songs / longer compositions use `dl generate-music`"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed",\n "data":{"audio_url":"https://storage.../sound.mp3","duration_ms":10031,"format":"mp3","sample_rate":44100}}'})}(_d),function(e){e.command("generate-lyrics").description("Generate Suno-style song lyrics from a short brief (<=200 chars). Returns 2-3 candidates synchronously; pick one and feed to `dl generate-music --custom`.").addHelpText("after",["","WHEN TO USE"," - You're about to call `dl generate-music --custom` and need lyrics with [Verse]/[Chorus] markers."," - You want 2-3 lyric variants to choose from before committing to a music generation.","","WHEN NOT TO USE"," - The song is instrumental — skip lyrics entirely, pass `--instrumental` to generate-music."," - You already have lyrics from the user — pass them directly to `dl generate-music --custom --prompt=...`.","","PRESENT TO USER (after candidates return)"," The user must be able to READ the full lyrics before choosing — never offer titles alone."," Build ONE select-v1 ask: one option per candidate, where"," - label = the candidate title"," - description = a one-line hook/preview (e.g. the first lyric line)"," - detail = the candidate's FULL `text`, with [Verse]/[Chorus] line breaks kept"," The card renders detail collapsed with an expand toggle, so the user reads the full"," lyrics inline and picks in the same card. Add a text option like 「都不满意,重新写」."," No separate 'here are the lyrics' message is needed — detail carries the full text."," Example option:",' {"id":"coney","label":"Coney Island Kiss","description":"有 Rap 段 · 纽约场景感强","detail":"[Verse]\\n...\\n[Chorus]\\n..."}',"","FALLBACK"," - If this command fails (E_BACKEND / E_SENSITIVE / E_TIMEOUT), hand-write lyrics yourself with [Verse]/[Chorus] structure and continue to generate-music.","","OUTPUT",' {"ok":true,"data":{"task_id":"...","lyrics":[{"title":"...","text":"[Verse]...","status":"complete"}, ...]}}',"","Example:",' dl generate-lyrics --prompt="bittersweet synth-pop about leaving a small town at sunrise"'].join("\n")).requiredOption("--prompt <text>","REQUIRED — short brief describing the song (<=200 chars)").action(async e=>{const t=String(e.prompt??"").trim();t||vs("--prompt is required and must be non-empty"),t.length>200&&vs("--prompt must be <=200 characters (KIE limit)",`current length: ${t.length}`);try{const e=await Da("media/submit","api/forward/lyrics",{prompt:t},{timeoutMs:14e4,retries:0});e.success&&e.data?.lyrics||vs(e.error||"lyrics generation returned no candidates"),gs({ok:!0,data:e.data})}catch(e){e instanceof Jr&&vs(e.message,e.hint),vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){Ps(e,{verb:"analyze-beats",actionName:"analyze_beats",schema:tr,supportsBatch:!1,description:"Analyse beat structure of an audio file. Synchronous — returns the beat list directly.",notes:["`--beat-method` is one of: `madmom_rnn` (default), `librosa`. Override only when you have a specific reason."],whenToUse:["Music-video planning: you need beat positions to anchor segment boundaries","Tempo / downbeat estimation before scheduling cuts"],whenNotToUse:["You need a transcript — use `dl transcribe`","You need to generate music — use `dl generate-music`"],examples:[{caption:"default beat method",command:'dl analyze-beats --audio-url="https://cdn.example.com/song.mp3"'},{caption:"explicit librosa (faster but different output)",command:'dl analyze-beats \\\n --audio-url="https://cdn.example.com/song.mp3" \\\n --beat-method=librosa'}],notExamples:[{command:'dl analyze-beats --params=\'{"audio_url":"..."}\'',whyItFails:"inline JSON via --params is removed; raises E_UNKNOWN_OPTION"}],outputSingle:'{"ok":true,"success":true,"beats":[{"position":1,"time":0.45,"strength":0.9}, ...]}'})}(_d),function(e){Ps(e,{verb:"render-caption",actionName:"render_caption",schema:er,billing:{schema:Fl,select:()=>({}),quote:Dl},supportsBatch:!1,description:"Burn SRT captions into a video. Synchronous — returns the captioned video URL directly.",notes:["`--caption` is a JSON object. Supported fields include fill_color, border_color, font_id, font_weight, shadow, position, position_value, font_size, and font_size_px.","`font_size_px` takes precedence over the `font_size` preset."],whenToUse:["You already have a video URL and SRT content and need a burned-caption video","The create-subtitles skill has generated SRT and the user requested embedded subtitles"],whenNotToUse:["You need ASR first — use `dl transcribe` or the create-subtitles skill","You only need an external SRT file — do not render captions"],examples:[{caption:"burn default-style captions",command:'dl render-caption \\\n --video-url="https://cdn.example.com/video.mp4" \\\n --srt-content="1\\n00:00:00,000 --\x3e 00:00:02,500\\nHello\\n" \\\n --caption=\'{"fill_color":"#FFFFFF","border_color":"#000000","font_id":"noto_sans","font_weight":"bold","position":"bottom","position_value":0.1,"font_size_px":36}\''}],notExamples:[{command:'dl render-caption --params=\'{"video_url":"..."}\'',whyItFails:"inline JSON via --params is removed; pass scalar flags directly"}],outputSingle:'{"ok":true,"success":true,"video_url":"https://.../captioned.mp4"}'})}(_d),function(e){Ps(e,{verb:"motion-control",actionName:"motion_control",schema:Go,billing:{schema:ql,select:e=>({service:e.service,tier:e.tier,duration:e.duration}),quote:Pl},supportsBatch:!0,description:"Transfer motion / pose from a source video onto one or more target characters (services: dreamactor, kling3.0-motion). dreamactor supports multi-person via --image-urls; kling3.0-motion is single-person only.",notes:["Provide exactly one of --image-url / --image-urls / --image-base64; supplying more than one (or none) raises E_SCHEMA.","`--image-urls` 是多人入口,**仅 dreamactor 支持**——传 N 个 URL,driving video 里就要有匹配的 N 个角色;kling3.0-motion 传 --image-urls 会被 vendor 拒绝。","`--duration=<seconds>` 是**计费专用**字段(整数,driving video 的秒数),vendor 不读。不传时计费按 10s 兜底,可能少扣 —— 请用 dl ffmpeg / 上传 metadata 拿到真实长度后传过来。"],whenToUse:["You have a reference performance video and a target character image","You need multi-character motion transfer (dreamactor + --image-urls)"],whenNotToUse:["You want a clip generated from scratch — use `dl generate-video`","You need lip-sync (not body motion) — use `dl lipsync`"],examples:[{caption:"single, dreamactor (--duration 整 driving video 秒数,计费用)",command:"dl motion-control --service=dreamactor --video-url=https://v.mp4 --image-url=https://char.png --duration=12"},{caption:"multi-person, dreamactor (N image_urls ↔ N 角色 in driving video)",command:"dl motion-control --service=dreamactor \\\n --video-url=https://.../two-people-dancing.mp4 \\\n --image-urls=https://.../alice.png \\\n --image-urls=https://.../bob.png \\\n --duration=12"}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed","data":{"url":"https://...mp4"}}',modelTopic:{rankingSummary:["2 services: dreamactor (fast + simple) / kling3.0-motion (quality + orientation control)."],services:[{service:"dreamactor",label:"DreamActor M2.0 (BytePlus)",tier:"Fast + simple",bestFor:"Single- or multi-character pose / motion transfer from video to image(s)",quality:"High",speed:"1-3min",cost:"low",description:["BytePlus DreamActor M2.0. General motion transfer, fast and with simple parameters.","Supports multi-person: pass N reference images via --image-urls and the driving video should contain N matching characters."],constraints:["GCS URL → api-layer rewrites to CDN URL automatically (BytePlus cannot reach GCS directly)","Recommend cut_first_second=true to drop the first-second transition artifact","Multi-person via --image-urls: 数组里每个 URL 对应 driving video 里一个角色,数量需匹配"],flagSubset:["service","video-url","image-url","image-urls","image-base64","cut-first-second"],examples:[{caption:"single, dreamactor",command:"dl motion-control --service=dreamactor \\\n --video-url=https://.../driving.mp4 \\\n --image-url=https://.../character.png \\\n --cut-first-second"},{caption:"multi-person, dreamactor (image_urls 数组)",command:"dl motion-control --service=dreamactor \\\n --video-url=https://.../two-people-dancing.mp4 \\\n --image-urls=https://.../alice.png \\\n --image-urls=https://.../bob.png \\\n --cut-first-second"}]},{service:"kling3.0-motion",label:"Kling 3.0 Motion",tier:"High quality + control",bestFor:"High-quality motion transfer + orientation control + quality tier + negative prompt",quality:"Very High",speed:"2-5min",cost:"mid",description:["Kling 3.0 Motion. Higher quality, supports:"," - character_orientation control (image / video)"," - tier (std / pro quality)"," - negative_prompt / prompt guidance"],constraints:["character_orientation='image' → character orientation follows the image; 'video' → follows the driving video","tier='pro' is higher quality than 'std' but slower"],flagSubset:["service","video-url","image-url","image-base64","character-orientation","tier","prompt","negative-prompt","sound"],examples:[{caption:"kling3.0-motion high quality + orientation",command:"dl motion-control --service=kling3.0-motion \\\n --video-url=https://.../driving.mp4 \\\n --image-url=https://.../character.png \\\n --character-orientation=image --tier=pro"}]}],decisionLogic:[{when:"Simple motion transfer, fast",pick:"dreamactor"},{when:"Need character orientation control / quality tier / negative prompt",pick:"kling3.0-motion"}]},preflightTopic:{intro:"Confirm these 3 items before the first dl motion-control call:",decisions:[{name:"Service",description:"dreamactor (fast and simple) or kling3.0-motion (high quality + control)."},{name:"Driving video + target character image(s)",description:"Driving video source + character image source.\nvideo_url is always required. Image source: exactly one of --image-url (single, both services) / --image-urls (multi-person, dreamactor only) / --image-base64 (single, both services). Missing all three or supplying more than one raises E_SCHEMA."},{name:"kling3.0-motion-specific",description:"If choosing kling3.0-motion, decide up front: character_orientation (image / video) +\ntier (std / pro) + whether to include prompt / negative_prompt / sound."}]},policyTopic:{rules:[{title:"1. User-Facing Communication",body:["Do not leak vendor / price / internal model code. Only mention service name + action (motion transfer)."]},{title:"2. Production Package Gate",body:["service / tier / task count / source video plan / target image plan /","character_orientation / sound / prompt are all components of the paid-package authorization.","Do not call before authorization; only re-ask on package overflow (switching service / tier / adding count /","replacing key inputs / fallback / paid regeneration)."]}]},compositionTopic:{intro:"This atomic skill only produces a motion-controlled video URL; artifact / canvas registration and other downstream responsibilities are not this verb's job.",integrations:[{skill:"right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs dl artifact write / patch-json pi_media_log on your behalf — that is the composition layer's job."]}]},asyncTopic:{intro:["dl motion-control by default returns { job_ref, status: 'pending' } and exits immediately — do not poll.","Results are injected into the session as [async-callback] job=<ref> text; typical duration 1-5 minutes."],resultShape:['{ "url": "https://storage.googleapis.com/.../video.mp4", ... }'],notes:["The URL field is the atomic skill's sole product","vendor / internal metadata fields must not be leaked to the user"]},publishTopic:{intro:["After producing motion-controlled video URL, call publish_content with","presentation_family='video' + media fields."],fields:[{name:"presentation_family",value:"'video'"},{name:"media_urls.video",value:"<motion control output URL>"},{name:"delivery_format",value:"'video'"}]}})}(_d),function(e){Ps(e,{verb:"generate-tts",actionName:"generate_tts",schema:Zo,billing:{schema:kl,select:e=>({service:e.service,text:e.text}),quote:xl},supportsBatch:!0,description:"Generate speech audio from text. `--provider` picks the backend (minimax / elevenlabs / elevenlabs-dialogue / voxcpm).",whenToUse:["You need synthetic speech from text","Multi-line / multi-voice via --jobs-file","As the first step of a talking-head pipeline; pipe the resulting `audio_url` into `dl lipsync`","You need to create a voice sample from an authorized reference audio clip — use `--provider=voxcpm` with `--audio-url=<reference>`","You need a custom voice from a free-form voice description — use `--provider=voxcpm` without `--audio-url` and put the description in `--control`"],whenNotToUse:["You need a music track (vocals or instrumental) — use `dl generate-music`","You only need the lip-sync stage and already have the audio — use `dl lipsync` directly"],notes:["Per-provider routing is via `--provider` (extraFlag). The `--service` enum (minimax-tts / voxcpm) is selected to match the provider.","For minimax / elevenlabs / elevenlabs-dialogue, look up the voice id with `dl knowledge search --domain=voice --query=…`.","`--provider=voxcpm` does NOT use voice_id. Pass `--audio-url` (reference audio) to clone; omit it to synthesize from `--control` (voice description). See `dl generate-tts model voxcpm` for the full call shape."],examples:[{caption:"single, minimax (default)",command:'dl generate-tts --service=minimax-tts --text="Hello, world." --emotion=calm'},{caption:"elevenlabs single voice",command:'dl generate-tts --provider=elevenlabs --service=minimax-tts \\\n --voice-id=<elevenlabs_voice_id> --text="Hello, world." --speed=1'},{caption:"elevenlabs multi-voice dialogue",command:'dl generate-tts --provider=elevenlabs-dialogue --service=minimax-tts \\\n --text="Speaker turns…" --speed=1'},{caption:"voxcpm clone — clone a real person's voice from reference audio",command:'dl generate-tts --provider=voxcpm --service=voxcpm \\\n --audio-url=https://.../reference.m4a \\\n --text="要朗读的台词" --control="calm warm"'},{caption:"voxcpm prompt — synthesize from voice description (no reference audio)",command:'dl generate-tts --provider=voxcpm --service=voxcpm \\\n --text="要朗读的台词" --control="warm calm female narrator"'}],outputSingle:'{"ok":true,"job_ref":"<uuid>","status":"completed","data":{"url":"https://...mp3"}}',extraFlags:[{spec:"--provider <name>",description:"backend route",default:"minimax",enum:lc}],resolveActionName:e=>{const t=String(e.provider??"minimax"),i=cc[t];if(!i)throw new Error(`unknown --provider: ${t}; expected one of ${lc.join(", ")}`);return i},modelTopic:{rankingSummary:["⚠ provider is selected via the `--provider` extraFlag. `--service` mirrors the chosen","provider (minimax-tts for the three platform providers; voxcpm for self-hosted voxcpm).","The four providers route to different backend actions / wire shapes:"," --provider=minimax → MiniMax TTS (default, multilingual + explicit pause control)"," --provider=elevenlabs → ElevenLabs single voice"," --provider=elevenlabs-dialogue → ElevenLabs multi-voice dialogue"," --provider=voxcpm → VoxCPM2 self-hosted (audio-reference voice cloning or description-based custom voice)"],services:[{service:"minimax",label:"MiniMax TTS",tier:"🥇 Default",bestFor:"Multilingual (Chinese / English / Japanese / etc.), explicit pause control, emotion control",quality:"High",speed:"30-60s",cost:"low",description:["MiniMax TTS, Pi's default provider.","Multilingual + emotion control via --emotion + <#X#> pause + language boost.","The voice library is searchable via dl knowledge search --domain=voice","(101 profiles: 40 Chinese + 61 English)."],promptTips:["Use native MiniMax markers only for deliberate pauses: <#X#> pause (X seconds, decimal); punctuation — long dashes / ... ellipsis are processed as natural short pauses","Keep --text to spoken words, punctuation, and pause markers; do not add inline emotion tags","Do not apply other TTS vendors' bracketed tags — MiniMax does not recognize them and reads them as literal characters","For code-mixed text, you must add --language-boost"],constraints:["voice_id must be found via dl knowledge search --domain=voice — do not rely on memory or fabricate","text length cap / model list / speed / vol / pitch / sample_rate / bitrate valid ranges all per --help"],flagSubset:["provider","service","text","voice-id","model","speed","vol","pitch","emotion","language-boost","format","sample-rate","bitrate"],examples:[{caption:"single, minimax default",command:'dl generate-tts --provider=minimax --service=minimax-tts \\\n --text="今天<#0.5#>真是个好天气,你看天上多蓝。" \\\n --voice-id=<voice_id> --emotion=calm --language-boost=auto'}]},{service:"elevenlabs",label:"ElevenLabs single voice",tier:"High-quality English / multilingual",bestFor:"ElevenLabs single voice. Higher quality, rich English / multilingual detail",quality:"Very High",speed:"30-60s",cost:"mid",description:["ElevenLabs single voice. Higher quality — suits scenarios that need the ElevenLabs distinctive voice library or","mixed Chinese-English / long-form narration.","","⚠ voice_id must be an ElevenLabs one, not MiniMax — use","dl knowledge search --domain=voice --query='<desc>' with filters to","pick a voice sourced from elevenlabs."],constraints:["voice_id must come from ElevenLabs — cannot use a MiniMax voice_id","--provider=elevenlabs (not --service)"],flagSubset:["provider","service","text","voice-id","model","speed"],examples:[{caption:"elevenlabs single voice",command:'dl generate-tts --provider=elevenlabs --service=minimax-tts \\\n --voice-id=<elevenlabs_voice_id> --text="Hello, world." --speed=1'}]},{service:"elevenlabs-dialogue",label:"ElevenLabs multi-voice dialogue",tier:"Multi-character dialogue",bestFor:"Multi-character dialogue synthesis (dialogue / interview / multi speaker turns)",quality:"Very High",speed:"1-2min",cost:"high",description:["ElevenLabs multi-voice dialogue. One call synthesizes dialogue across multiple speakers.","Usage differs from single voice — write text in multi-turn form and the vendor routes the voices itself."],constraints:["text must follow the vendor-expected multi-speaker format; run --print-schema for the exact schema"],flagSubset:["provider","service","text","speed"],examples:[{caption:"elevenlabs dialogue",command:'dl generate-tts --provider=elevenlabs-dialogue --service=minimax-tts \\\n --text="Speaker A: Hello.\\nSpeaker B: Hi there!" --speed=1'}]},{service:"voxcpm",label:"VoxCPM2 (self-hosted custom voice sample / authorized reference cloning)",tier:"Custom voice sample generator + authorized reference cloner",bestFor:"Create a custom voice sample from a free-form text description when no reference audio exists, or clone an authorized reference voice from one clean audio clip. Use this when MiniMax / ElevenLabs voice libraries don't cover the target voice and no reusable platform voice_id should be created.",quality:"Very High (clone fidelity scales with reference audio quality)",speed:"10-30s inference + 0-150s RunPod cold start",cost:"low (self-hosted, only pays RunPod GPU seconds)",description:["VoxCPM2 deployed on RunPod serverless (dramaland-ai-small). Use it for voice samples","that are represented by the returned audio URL plus prompt/reference metadata, not by","a reusable provider voice_id.","","Two internal modes, automatically chosen by api-layer from the `--audio-url` field:"," - voiceclone (audio_url present) → authorized reference audio + text → clone the audio's voice"," - voiceprompt (audio_url absent) → voice description + text → synthesize from description","","There is NO voice_id concept in voxcpm — voice identity is either the reference audio or","the textual description in --control."],promptTips:["`--audio-url` must be an authorized clean 3-30s clip of the target voice; clearer reference → better clone fidelity","`--control` semantics flip by mode:"," - clone mode (with --audio-url): emotion / style controls, e.g. `calm`, `excited`, `whisper`"," - prompt mode (without --audio-url): voice description, e.g. `warm calm female narrator`"," English short phrases work best either way","voxcpm reads text literally — MiniMax pause markers like <#X#> are NOT recognized; use punctuation for pauses instead"],constraints:["text length cap 4096 characters","reference audio max 50MB; content-type must be audio/* (video / image refused)","clone mode requires `--audio-url`; if you don't have a reference clip, omit `--audio-url` (auto-falls to prompt mode)","do NOT pass --voice-id / --emotion / --language-boost / etc. — those are minimax-specific and ignored here","cold start can add up to ~150s on first call; the api-layer's async submit/poll handles this transparently — don't add your own retries"],flagSubset:["provider","service","text","audio-url","control"],examples:[{caption:"voxcpm clone — clone the voice in a reference audio",command:'dl generate-tts --provider=voxcpm --service=voxcpm \\\n --audio-url=https://.../target-voice.m4a \\\n --text="要朗读的台词" --control="calm"'},{caption:"voxcpm prompt — no reference audio, synthesize from voice description",command:'dl generate-tts --provider=voxcpm --service=voxcpm \\\n --text="要朗读的台词" --control="warm calm female narrator"'}]}],decisionLogic:[{when:"Default / Chinese / pause markers + request-level emotion",pick:"--provider=minimax (default)"},{when:"Need the ElevenLabs voice library / higher English quality",pick:"--provider=elevenlabs"},{when:"Multi-speaker dialogue synthesis",pick:"--provider=elevenlabs-dialogue"},{when:"Need a VoxCPM voice sample from an authorized reference audio, with no reusable provider voice_id",pick:"--provider=voxcpm with --audio-url=<reference>"},{when:"Need a custom voice from a free-form text description, when no reference audio is available",pick:"--provider=voxcpm with --control='<voice description>' (no --audio-url)"}]},preflightTopic:{intro:"Confirm these 4 items before the first dl generate-tts call:",decisions:[{name:"Provider",description:"Which provider to use (minimax / elevenlabs / elevenlabs-dialogue / voxcpm). Decides the voice-identity mechanism + marker syntax + which flags are read.\n - minimax / elevenlabs / elevenlabs-dialogue → platform voice library (voice_id required)\n - voxcpm → no voice_id; supply --audio-url (clone) or --control (voice description)"},{name:"Voice identity",description:"For minimax / elevenlabs / elevenlabs-dialogue: search a voice_id via `dl knowledge search --domain=voice`\n(query is natural-language; filter fields / valid enums per `dl knowledge search --help`).\nFor voxcpm: either an `--audio-url` reference clip (clone) OR a textual `--control` voice description (prompt). voxcpm ignores voice_id."},{name:"Text preparation",description:"Prepare text per the chosen provider's marker syntax.\n - MiniMax: <#X#> pauses + standard punctuation for short pauses; set tone with --emotion instead of inline tags\n - voxcpm: plain text, no markers — punctuation only (markers are read literally)\n - elevenlabs / elevenlabs-dialogue: per ElevenLabs marker conventions (see model -h)"},{name:"Audio format",description:"format / sample_rate / bitrate — defaults are usually enough. Adjust only if downstream has special requirements (lipsync / concat). voxcpm's output format follows its handler default (mp3 / flac) and ignores these flags."}],notes:["If cost-sensitive → read pricing-and-policies-dramaland-faq/SKILL.md first","For batch generation use --jobs-file, do not block per item"]},policyTopic:{intro:"Five classes of hard rules: User-facing non-leak / Package gate / **Marker syntax discipline** / **TTS pronounceability discipline** / Failure fallback ladder.",rules:[{title:"1. User-Facing Communication — do not leak internal details",body:["vendor / price / internal model code / trace id must not be surfaced to the user.","User-facing summary only mentions: provider name (MiniMax / ElevenLabs) + character /","language + action (generate TTS / TTS dialogue)."]},{title:"2. Production Package Gate — do not call before paid authorization",body:["provider / model / voice_id / generation count / text segment range / text length / target","duration / audio format parameters / downstream usage are all components of the paid package authorization. Do not call before authorization;","within the same package you can batch; only re-ask on package overflow (switching model / voice / adding count /","changing format / fallback / paid regeneration)."]},{title:"3. MiniMax Marker syntax discipline (provider=minimax only)",body:["MiniMax marker syntax **must use native forms** — do not apply other TTS vendors' bracketed","tags (MiniMax does not recognize them and reads them as literal characters, producing noise).","Keep script text to spoken words, punctuation, and explicit pause markers; do not add inline emotion tags.","","### Pauses"," - <#X#>, X is seconds as a decimal (<#0.3#> / <#0.8#> / <#1.5#>)"," - Punctuation substitutes: long dashes (—) / ... ellipsis are processed naturally as short pauses","","### Emotion"," - Do not put inline emotion tags in --text"," - Per-request: attach --emotion=... (valid enum per --help)","","### Language hint"," - For code-mixed text, you must add --language-boost (valid values per --help)"]},{title:"4. TTS pronounceability discipline — hard constraint on the script side",body:["When writing the script, spell out complex numbers / currency / abbreviations / units / dates / ratios — **do not bet","on TTS getting them right on its own**. Simple integers (5 / 27 / 120) / bare 4-digit years (2024) / whole percentages","(50%) are usually OK; otherwise spell them out:",""," $1.4M → one point four million dollars"," 42.7% → forty-two point seven percent"," Q3 2024 → third quarter of twenty twenty-four"," 3:1 → three to one"," 42°F → forty-two degrees Fahrenheit"," ROI → R O I (spaces force letter-by-letter) or return on investment"," Chinese percent → 百分之四十二点七"," Chinese currency magnitude → 一点四亿美元 or 14 亿美元","","Mispronunciation can only be fixed by editing the caption — you cannot re-pronounce the audio — so **handle it at script time**."]},{title:"5. voxcpm input discipline (provider=voxcpm only)",body:["voxcpm reads text **literally**. Markers from other TTS vendors (MiniMax `<#X#>`, ElevenLabs","`[break]`, inline emotion tags) are NOT recognized and will be pronounced as","literal characters. Use plain text + punctuation for pauses.","","### Voice identity"," - Clone mode (with --audio-url): voice timbre comes from the reference audio; --control controls emotion / style (`calm` / `excited`)"," - Prompt mode (without --audio-url): voice timbre comes from the --control description (`warm calm female narrator`); English short phrases work best","","### Flags voxcpm ignores"," --voice-id / --emotion / --language-boost / --model / --sample-rate / --bitrate / --pitch / --vol"," (those are minimax-specific; voxcpm silently drops them)"]},{title:"6. Failure fallback ladder",body:["When this verb produces jitter / silence / clipping / content-moderation blocks, in order:","","1. Retry once (transient network / quota wobbles usually pass; voxcpm cold start can add ~150s)","2. Switch model / tune knobs: step within the model list listed by --help (high-quality vs fast)"," or tune speed / emotion / language_boost (minimax only)","3. Re-pick voice identity:"," - minimax / elevenlabs: pick another voice_id via dl knowledge search --domain=voice"," - voxcpm clone: try a cleaner / longer / different reference --audio-url"," - voxcpm prompt: refine --control description","4. Switch provider — esp. when MiniMax / ElevenLabs voice library cannot match the target voice:"," fall back to --provider=voxcpm with an authorized reference audio.","5. Fall back to script changes: too long / too dense markers / too many hard-to-pronounce expressions → shorten + dilute"," markers + convert un-spelled-out complex numbers / abbreviations into pronounceable form (see rule 4)"]}]},compositionTopic:{intro:"This atomic skill only produces an audio URL; artifact / canvas registration and other downstream responsibilities are not this verb's job.",integrations:[{skill:"Voice ID search (dl knowledge search --domain=voice) — minimax / elevenlabs only",rule:["MiniMax voice library has 101 profiles (40 CN + 61 EN). Search:"," dl knowledge search --domain=voice --query='<natural-language description>' \\",' --filters-file=- <<<\'{"language":"CN","gender":"Female"}\'',"","For specific filter fields / valid enums see dl knowledge search --help.","","For the ElevenLabs voice library, filter via --filters-file with 'provider': 'elevenlabs'.","","voxcpm does NOT use this knowledge base — its voice identity is either the reference","--audio-url (clone) or the --control description (prompt). Skip voice search entirely","when --provider=voxcpm."]},{skill:"downstream lipsync / video composition",rule:["The generated audio_url can be fed directly into:"," - dl lipsync --audio-url=... (seedance 2.0 ≤ 15s / dlai2v ≤ 19s, see lipsync model -h)"," - dl generate-video --reference-audio-url=... (seedance 2.0 same 15s cap)","","Target duration must be aligned with the downstream audio duration cap during the generate-tts stage."]},{skill:"right-side canvas (pi_media_log)",rule:["The atomic skill no longer performs dl artifact write / patch-json pi_media_log on your behalf —","that is the composition layer's job."]}]},asyncTopic:{intro:["dl generate-tts by default returns { job_ref, status: 'pending' } and exits immediately — do not poll.","Results are injected into the session as [async-callback] job=<ref> text; typical duration 30s-2min.","","Only run dl poll separately when the next step strictly requires the result (immediately feeding lipsync / ffmpeg concat)."],resultShape:['{ "audio_url": "https://storage.googleapis.com/.../speech.mp3",',' "duration_ms": 3200,',' "format": "mp3",',' "usage_characters": 42 }'],notes:["audio_url is the atomic skill's sole product and can serve directly as a downstream reference_audio_url","vendor-internal metadata fields must not be leaked to the user"]},publishTopic:{intro:["After producing TTS audio URL, call publish_content with presentation_family='text',","media_urls.audio=<url>, delivery_format='audio'. The playbook 'Publishing Your Work /","text' template is the closest match; pass media_urls.audio explicitly (the runtime will not infer audio from","presentation_family)."],fields:[{name:"presentation_family",value:"'text'"},{name:"media_urls.audio",value:"<TTS audio URL>"},{name:"delivery_format",value:"'audio'"}]}})}(_d),function(e){Ps(e,{verb:"detect-shots",actionName:"detect_shots",schema:ir,billing:{schema:pl,select:()=>({}),quote:ml},supportsBatch:!1,description:"Detect shot boundaries via TransNetV2. Synchronous — returns the shot list directly.",whenToUse:["You need shot-level segmentation of a video for breakdown / analysis"],whenNotToUse:["You need a transcript of the video's audio — use `dl transcribe`","You need beat / tempo of the audio track — use `dl analyze-beats`"],examples:[{caption:"default threshold",command:"dl detect-shots --video-url=https://example.com/clip.mp4 --output-format=full"}],outputSingle:'{"ok":true,"success":true,"shots":[{"index":0,"start_time":0,"end_time":7.97,...}, ...]}'})}(_d),function(e){Ps(e,{verb:"download-media",actionName:"download_media",schema:nr,billing:{schema:hl,select:()=>({}),quote:fl},supportsBatch:!1,description:"Download social-media media (TikTok / Instagram / Twitter / Bilibili / …) and re-host on CDN.",notes:["Sources supported: TikTok, Instagram, Twitter/X, Bilibili, and most cobalt-supported sites.","YouTube is currently NOT supported. Limits: ≤500MB per asset, 30 requests/minute."],whenToUse:["You have a social-media URL and need a persistent CDN copy for downstream tools"],whenNotToUse:["The URL is a YouTube link — not supported; surface the limitation to the user instead","You only need to fetch+extract HTML/text — use `dl fetch`"],examples:[{caption:"auto format",command:"dl download-media --url=https://www.tiktok.com/@user/video/123 --format=auto"}],outputSingle:'{"ok":true,"success":true,"data":{"url":"https://storage.../media.mp4"}}',preflightTopic:{intro:"Confirm these 2 items before the first dl download-media call:",decisions:[{name:"Source platform",description:"Supported: TikTok / Instagram / Twitter / Bilibili / Reddit / Vimeo /\nSoundCloud / Twitch / Pinterest / Dailymotion / Loom / Rutube / Streamable.\n**YouTube is NOT supported** (anti-bot block) — if the user gives a YouTube link,\nsurface the limitation; do not retry blindly."},{name:"Format / quality",description:"--format=auto (default) / video / audio / image.\n--video-quality: default is usually enough; on large files + file_too_large error → lower\nquality and retry."}],notes:["≤500MB per file","30 req/min/instance (rate limit)","Synchronous call, no dl poll"]},policyTopic:{rules:[{title:"1. Error handling loop (full error-code table)",body:["When error_code is returned, handle per the table:",""," rate_limited → wait the hinted seconds and retry"," cobalt_unavailable → ~30s retry"," download_timeout → ~30s retry"," gcs_upload_failed → ~30s retry"," content_not_found → unrecoverable, tell the user the source is unreachable"," content_requires_auth → same as above (common for YouTube)"," content_geo_restricted → same as above"," content_age_restricted → same as above"," file_too_large → lower video_quality or --format=audio and retry"," local_processing_required → same as above"," platform_unsupported → unrecoverable, platform not supported"," internal_error / service_misconfigured → escalate (do not retry)"]},{title:"2. Warning handling",body:["warning_code: gcs_fallback → R2 upload failed, the URL is a temporary direct link that may expire."," If you need a persistent URL, re-run.","","warning_code: picker_first_only → the source has multiple items (e.g. Instagram carousel),"," only the first was taken. For others, the source URL must explicitly point to the specific item."]},{title:"3. YouTube hard-unsupported",body:["YouTube links are currently blocked by anti-bot and return content_requires_auth.","Do not retry blindly — tell the user that YouTube is not supported."]}]},compositionTopic:{intro:"The download result is a persistent CDN URL on our R2 — feed it directly into downstream verbs / artifacts. Do NOT pass to upload_file (it is already hosted by us).",integrations:[{skill:"downstream verbs using the downloaded URL",rule:["output_url is public + permanent and can be passed directly to:"," - dl generate-video --image-urls=... / --ref-video-url=..."," - dl lipsync --image-url=... / --audio-url=..."," - dl render-caption / dl ffmpeg, etc.","","If you hit warning_code: gcs_fallback, re-run first to get a stable URL before feeding downstream;","do not risk expiration."]}]},asyncTopic:{intro:["⚠ dl download-media is **synchronous** (supportsBatch=false). The response includes output_url","+ filename + content_type + file_size_bytes + source_platform and other fields.","Typical duration 5-15s (short clips) / up to 120s (large files)."],resultShape:['{ "ok": true, "success": true,',' "data": { "output_url": "https://public.ilands.ai/.../media.mp4",',' "filename": "...",',' "content_type": "video/mp4",',' "file_size_bytes": 12345678,',' "source_platform": "tiktok" } }']}})}(_d),function(e){Ps(e,{verb:"geocode",actionName:"geocode",schema:ar,billing:{schema:$l,select:e=>({mode:"string"==typeof e.address&&e.address.trim()?"forward":"reverse"}),quote:Nl},supportsBatch:!1,description:"Forward (address → coords) or reverse (coords → address) geocoding.",notes:["Pass exactly one of: `--address` (forward) OR `--latitude`+`--longitude` (reverse).","Provider auto-routes by region (Google globally, AMap inside China, Panoramax in France)."],whenToUse:["You need to look up coordinates for a place name, or a place name for coordinates"],whenNotToUse:["You need a list of POIs near a point — use `dl places search`"],examples:[{caption:"forward",command:'dl geocode --address="Tokyo Tower, Tokyo"'},{caption:"reverse",command:"dl geocode --latitude=35.6586 --longitude=139.7454"}],outputSingle:'{"ok":true,"success":true,"data":{...}}'})}(_d),function(e){const t=e.command("streetview").description("Street-level imagery and coverage info (Google / AMap / Panoramax).");Ps(t,{verb:"metadata",actionName:"streetview_metadata",schema:rr,billing:{schema:Kl,select:()=>({}),quote:Gl},supportsBatch:!1,description:"Check street-view coverage at coordinates. Low-cost — call before `dl streetview image`.",whenToUse:["You're about to fetch a streetview image but want to confirm coverage exists first"],examples:[{caption:"coverage probe",command:"dl streetview metadata --latitude=35.6586 --longitude=139.7454"}]}),Ps(t,{verb:"image",actionName:"streetview_image",schema:or,billing:{schema:Vl,select:()=>({}),quote:Jl},supportsBatch:!1,description:"Street-level image at coordinates; auto-routes provider (Google / AMap / Panoramax).",whenToUse:["You need a ground-level photo at known coordinates"],examples:[{caption:"with view direction",command:"dl streetview image --latitude=35.6586 --longitude=139.7454 --heading=90 --pitch=0 --fov=90"}]})}(_d),function(e){const t=e.command("places").description("Search places / POIs near coordinates and fetch their photos.");Ps(t,{verb:"search",actionName:"places_search",schema:sr,billing:{schema:Ml,select:()=>({}),quote:Ul},supportsBatch:!1,description:"Search places / POIs near coordinates by keyword.",whenToUse:["You need a list of places matching a keyword near a known location"],examples:[{caption:"ramen near Tokyo Tower",command:"dl places search --query=ramen --latitude=35.6586 --longitude=139.7454 --radius=500"}]}),Ps(t,{verb:"photo",actionName:"place_photo",schema:lr,billing:{schema:Ll,select:()=>({}),quote:zl},supportsBatch:!1,description:"Fetch a photo by photo_reference (returned from `dl places search`).",whenToUse:["You have a photo_reference token from places search and want to materialise the image"],examples:[{caption:"default size",command:"dl places photo --photo-reference=<token> --max-width=1600"}]})}(_d),function(e){Ps(e,{verb:"static-map",actionName:"static_map",schema:cr,billing:{schema:Hl,select:()=>({}),quote:Bl},supportsBatch:!1,description:"Bird's-eye view map image at coordinates with optional markers.",notes:["`--size` is `WIDTHxHEIGHT` in pixels (e.g. `600x400`); both must be positive integers."],whenToUse:["You need a static map tile centred on coordinates for embedding / reference"],whenNotToUse:["You need a street-level photo, not a top-down map — use `dl streetview image`","You need to search for POIs at the location — use `dl places search`"],examples:[{caption:"default",command:"dl static-map --latitude=35.6586 --longitude=139.7454 --zoom=15 --size=600x400"}],outputSingle:'{"ok":true,"success":true,"data":{"url":"https://storage.../map.png"}}'})}(_d),function(e){e.command("ffmpeg").description("Run raw ffmpeg / ffprobe in the remote ffmpeg sandbox. Synchronous by default (returns URL or probe JSON). Pass --async for long encodes — returns { status: 'pending', job_ref } and resumes via [async-callback].").addHelpText("after",["","Routing guidance:"," ffprobe / -c copy / 简单 trim 用本地 ffmpeg (秒级)。"," -c:v 重编码 / filter_complex / 输入 >2min 走 dl ffmpeg (同步, 默认)。"," >5min 编码 / MV 长任务 加 --async 走 callback (远程 sandbox 上限 1800s)。","","Sync mode (default):"," Polls until done or --timeout-ms expires. Default budget 10min;"," wrap with bash { timeout: N } to extend past the 5min sandbox cap.","","Async mode (--async):"," Returns { status: 'pending', job_ref } immediately. End the turn —"," result arrives as [async-callback] job=<ref> in a later turn."," Do NOT poll, do NOT re-submit, do NOT sleep/while wait.","","Example (sync, 默认):"," cat <<EOF | dl ffmpeg --command-file=- --input=src=https://…"," ffprobe -v quiet -print_format json -show_format -show_streams /input/src"," EOF","","Example (async, 长编码):"," cat <<EOF | dl ffmpeg --async --command-file=- --input=src=https://…"," ffmpeg -i /input/src -c:v libx264 -preset medium -crf 23 /output/out.mp4"," EOF"," # 命令立刻返回 pending; end turn 等 [async-callback]。"].join("\n")).option("--command <text>",'RECOMMENDED: ffmpeg/ffprobe command line inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --command "$(cat cmd.txt)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --command-file.').option("--command-file <path|->",'LEGACY: ffmpeg/ffprobe command line as raw text via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --command "$(cat file)". Use --command-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--input <name=url>","name=url for /input/{name}; pass multiple --input flags",(e,t={})=>{const i=e.indexOf("=");if(i<=0)throw new ie(`--input expects name=url, got ${e}`);return t[e.slice(0,i)]=e.slice(i+1),t},{}).option("--output-kind <tag>","classification tag echoed back in the response").option("--timeout <s>","sandbox-side timeout seconds (capped at 1800)",e=>Number(e)).option("--agent-id <n>","",e=>Number(e)).option("--async","async callback mode: return { status: 'pending', job_ref } immediately, resume via [async-callback]. Default is sync polling.").option("--timeout-ms <n>","[sync only] client polling budget (default 600000 = 10min)",e=>Number(e)).option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").action(async e=>{e.printSchema&&Js({command:"dl ffmpeg",summary:"Run raw ffmpeg / ffprobe in the remote sandbox. Synchronous by default (returns URL or probe JSON). Pass --async for long encodes — returns { status: 'pending', job_ref } and resumes via [async-callback].",scalars:[{name:"input",type:"string",required:!1,description:"name=url; repeatable; mounted as /input/<name>"},{name:"output-kind",type:"string",required:!1,description:"tag echoed back in response"},{name:"timeout",type:"integer",required:!1,description:"sandbox timeout seconds (capped at 1800)"},{name:"agent-id",type:"integer",required:!1,description:""},{name:"async",type:"boolean",required:!1,description:"async callback mode (default is sync polling)"},{name:"timeout-ms",type:"integer",required:!1,description:"[sync only] client polling budget (default 600000)"},{name:"command",type:"string",required:!1,description:"RECOMMENDED inline ffmpeg/ffprobe command line (required: pass this or --command-file)"}],files:[{name:"command-file",required:!1,kind:"text",description:"LEGACY: ffmpeg/ffprobe command line via file/stdin (prefer --command inline)",example:'ffmpeg -i /input/a -i /input/b -filter_complex "[0:v][1:v]overlay" /output/out.mp4'}]});let t,i="";try{const n=await hs(e.command?String(e.command):void 0,e.commandFile?String(e.commandFile):void 0,{inline:"--command",file:"--command-file"});n&&(i=n.raw.trim(),t=n.label)}catch(e){throw e instanceof wa&&bs(e),e}i||ys("E_SCHEMA","--command is required (pass the ffmpeg command inline, or use --command-file for the legacy file/stdin path)",tc("run `dl ffmpeg --print-schema` to see the expected shape"),{flag:"--command"});const n=e.input&&Object.keys(e.input).length>0?e.input:void 0,o=!0===e.async;_s({command:"ffmpeg",ffmpeg_command:i,inputs:n??null,source:t??null,mode:o?"async":"sync"});const r=k();try{let t;if(o&&(t=function(e){const t=(process.env.CALLBACK_SERVER_URL??"").replace(/\/+$/,"");if(!t)throw new Jr("CALLBACK_SERVER_URL not set — async ffmpeg submit needs it for the vendor callback target","hono-pi-e2b injects this on every commands.run; drop --async to use the default polling path, or set it manually in LOCAL_SANDBOX dev");const i=(process.env.PI_PROJECT_ID??"").trim();if(!i)throw new Jr("PI_PROJECT_ID not set — required for callback URL routing under callback-resume v2","hono-pi-e2b injects PI_PROJECT_ID on every commands.run; drop --async to use the default polling path, or set it manually in LOCAL_SANDBOX dev");return`${t}/callback/${encodeURIComponent(i)}/${e}`}(r)),await Da("ffmpeg-sandbox","cli",{job_id:r,command:i,...n?{inputs:n}:{},...void 0!==e.timeout?{timeout:Number(e.timeout)}:{},...void 0!==e.agentId?{agent_id:Number(e.agentId)}:{},...e.outputKind?{output_kind:String(e.outputKind)}:{},...t?{callback_url:t}:{}}),o)return ws({action:"ffmpeg",job_ref:r,mode:"single"}),void gs({ok:!0,status:"pending",job_ref:r,output_kind:e.outputKind??null});const a=await async function(e,t){const i=Date.now();for(;Date.now()-i<t;){const t=await Ha("ffmpeg-sandbox",`jobs/${e}`,{},{timeoutMs:3e4,retries:0});if("completed"===t.status)return t.data??t;if("failed"===t.status)throw new Error(`ffmpeg-sandbox: ${t.error??"failed"}`);await new Promise(e=>setTimeout(e,2e3))}throw new Error(`ffmpeg-sandbox: timeout after ${t}ms`)}(r,e.timeoutMs??6e5);gs({ok:!0,output_kind:e.outputKind??null,data:a})}catch(e){e instanceof Jr&&vs(e.message,tc(e.hint)),vs(e instanceof Error?e.message:String(e),ec)}})}(_d),function(e){e.command("remotion").description("Render a Remotion composition.").addHelpText("after",["","`--source-file` is the LOCAL path to a Component.tsx file readable at","runtime — dl reads it, ships the source through the gateway, and the","renderer compiles it server-side. No upload step required.","","Example (stdin for inputProps):"," cat <<EOF | dl remotion --source-file=/workspace/remotion/title_card.tsx \\"," --duration-in-frames=120 --fps=30 --width=1080 --height=1920 \\"," --input-props-file=-",' {"title":"Hello"}'," EOF"].join("\n")).option("--source <text>",'RECOMMENDED: Component.tsx source inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --source "$(cat title_card.tsx)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --source-file.').option("--source-file <path>",'LEGACY: local path to a Component.tsx file (read at submit time, shipped server-side). File content is invisible to the billing extension + dl adapter, so prefer --source "$(cat file)". Use --source-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--duration-in-frames <n>","",e=>Number(e)).option("--fps <n>","",e=>Number(e)).option("--width <n>","",e=>Number(e)).option("--height <n>","",e=>Number(e)).option("--composition-id <id>").option("--input-props <inline-json>",'RECOMMENDED: JSON inputProps inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --input-props "$(cat props.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --input-props-file.').option("--input-props-file <path|->",'LEGACY: JSON inputProps via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --input-props "$(cat file)". Use --input-props-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--agent-id <n>","",e=>Number(e)).option("--timeout-ms <n>","client polling budget (default 900000 = 15min)",e=>Number(e)).option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{let t,i,n,o;if(e.printSchema&&Js({command:"dl remotion",summary:"Render a Remotion composition.",scalars:[{name:"source",type:"string",required:!1,description:"RECOMMENDED inline Component.tsx source (required: pass this or --source-file)"},{name:"source-file",type:"string",required:!1,description:"LEGACY: absolute path to a Component.tsx (prefer --source inline)"},{name:"duration-in-frames",type:"integer",required:!0,description:""},{name:"fps",type:"integer",required:!1,description:""},{name:"width",type:"integer",required:!1,description:""},{name:"height",type:"integer",required:!1,description:""},{name:"composition-id",type:"string",required:!1,description:""},{name:"agent-id",type:"integer",required:!1,description:""},{name:"timeout-ms",type:"integer",required:!1,description:""},{name:"input-props",type:"string",required:!1,description:"RECOMMENDED inline JSON inputProps (sibling of --input-props-file)"}],files:[{name:"input-props-file",required:!1,kind:"object",description:"LEGACY: JSON inputProps via file/stdin (prefer --input-props inline)",example:'{"title":"Hello"}'}]}),e.source||e.sourceFile||ys("E_SCHEMA","--source is required (pass the Component.tsx inline, or use --source-file for the legacy file path)","pi skills should pass the component inline via --source, or an absolute path via --source-file",{flag:"--source"}),e.source&&e.sourceFile&&ys("E_SCHEMA","--source and --source-file are mutually exclusive","prefer --source (inline); file content is invisible to the billing extension / dl adapter",{inline_flag:"--source",file_flag:"--source-file"}),void 0===e.durationInFrames&&ys("E_SCHEMA","--duration-in-frames is required",void 0,{flag:"--duration-in-frames"}),e.source)t=String(e.source),i="inline";else{try{t=await O(String(e.sourceFile),"utf8")}catch(t){const i=t instanceof Error?t.message:String(t);ys("E_FILE_MISSING",`--source-file: cannot read ${e.sourceFile} (${i})`,"make sure the path exists in the sandbox",{flag:"--source-file",given:String(e.sourceFile)})}i=String(e.sourceFile)}t||ys("E_SCHEMA",e.source?"--source is empty":"--source-file is empty","pi skills should resolve the component via --source (inline) or an absolute --source-file path.",{flag:e.source?"--source":"--source-file"});try{const t=await ms(e.inputProps?String(e.inputProps):void 0,e.inputPropsFile?String(e.inputPropsFile):void 0,{inline:"--input-props",file:"--input-props-file"});t&&(n=t.data,o=t.source.label)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:"remotion",source_file:i,input_props:n??null,input_props_source:o??null});const r=k(),a={source:"dl",event:"remotion_render",credits:20,command:(s={command:"remotion",action:"remotion_render"}).command,action:s.action??"remotion_render",details:{rule:"remotion.fixed"}};var s;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"remotion_render",totalCredits:a.credits,items:[a]});const l={source_code:t,duration_in_frames:Number(e.durationInFrames),...e.compositionId?{composition_id:String(e.compositionId)}:{},...void 0!==e.fps?{fps:Number(e.fps)}:{},...void 0!==e.width?{width:Number(e.width)}:{},...void 0!==e.height?{height:Number(e.height)}:{},...n?{input_props:n}:{}};let c=!1;try{await Da("remotion","renders",{job_id:r,params:l,agent_id:e.agentId??0},{billing:{jobRef:r,quote:a}}),c=!0;const t=await async function(e,t){const i=Date.now();for(;Date.now()-i<t;){const t=await Ha("remotion",`renders/${e}`,{},{timeoutMs:3e4,retries:0});if("completed"===t.status)return t.data??t;if("failed"===t.status)throw new Error(`remotion: ${t.error??"failed"}`);await new Promise(e=>setTimeout(e,2e3))}throw new Error(`remotion: timeout after ${t}ms`)}(r,e.timeoutMs??9e5);gs({ok:!0,job_ref:r,data:t,billing:a})}catch(e){c&&await async function(e){try{await Ua({jobRef:e.jobRef,quote:e.quote,reason:e.reason})}catch(t){process.stderr.write(`${JSON.stringify({level:"warn",event:"dl_billing_refund_failed",job_ref:e.jobRef,reason:e.reason,error:t instanceof Error?t.message:String(t)})}\n`)}}({jobRef:r,quote:a,reason:"remotion_render_failed"}),e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:r}),e instanceof Jr&&vs(e.message,e.hint,{job_ref:r}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:r})}})}(_d),function(e){e.command("hyperframes").description("Render a HyperFrames HTML composition to MP4 (remote fallback path).").addHelpText("after",["","`--source-file` is the LOCAL path to a `.html` composition file —","dl reads it, ships the source through the gateway, and the renderer","runs hyperframes CLI server-side. No upload step required.","","Prefer local `npx hyperframes render` for short renders; use `dl","hyperframes` when sandbox CPU/memory limits are hit or the job is","large enough to want the GCS-uploaded output URL directly.","","Example (stdin for inputProps):"," cat <<EOF | dl hyperframes --source-file=/workspace/hf/title-card.html \\"," --duration-in-frames=120 --fps=30 --width=1080 --height=1920 \\"," --input-props-file=-",' {"title":"Hello"}'," EOF"].join("\n")).option("--source <text>",'RECOMMENDED: HTML composition source inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --source "$(cat title-card.html)" — keeps multi-line content out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --source-file.').option("--source-file <path>",'LEGACY: local path to an HTML composition file (read at submit time, shipped server-side). File content is invisible to the billing extension + dl adapter, so prefer --source "$(cat file)". Use --source-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--duration-in-frames <n>","",e=>Number(e)).option("--fps <n>","",e=>Number(e)).option("--width <n>","",e=>Number(e)).option("--height <n>","",e=>Number(e)).option("--composition-id <id>").option("--input-props <inline-json>",'RECOMMENDED: JSON inputProps inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --input-props "$(cat props.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --input-props-file.').option("--input-props-file <path|->",'LEGACY: JSON inputProps via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --input-props "$(cat file)". Use --input-props-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--agent-id <n>","",e=>Number(e)).option("--timeout-ms <n>","client polling budget (default 900000 = 15min)",e=>Number(e)).option("--print-schema","print scalar+file schema and exit").option("--echo-parsed","echo canonical parsed input on stderr").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{let t,i,n,o;if(e.printSchema&&Js({command:"dl hyperframes",summary:"Render a HyperFrames HTML composition to MP4 (remote fallback path).",scalars:[{name:"source",type:"string",required:!1,description:"RECOMMENDED inline HTML composition source (required: pass this or --source-file)"},{name:"source-file",type:"string",required:!1,description:"LEGACY: absolute path to a .html composition (prefer --source inline)"},{name:"duration-in-frames",type:"integer",required:!0,description:""},{name:"fps",type:"integer",required:!1,description:""},{name:"width",type:"integer",required:!1,description:""},{name:"height",type:"integer",required:!1,description:""},{name:"composition-id",type:"string",required:!1,description:""},{name:"agent-id",type:"integer",required:!1,description:""},{name:"timeout-ms",type:"integer",required:!1,description:""},{name:"input-props",type:"string",required:!1,description:"RECOMMENDED inline JSON inputProps (sibling of --input-props-file)"}],files:[{name:"input-props-file",required:!1,kind:"object",description:"LEGACY: JSON inputProps via file/stdin (prefer --input-props inline)",example:'{"title":"Hello"}'}]}),e.source||e.sourceFile||ys("E_SCHEMA","--source is required (pass the HTML composition inline, or use --source-file for the legacy file path)","pi skills should pass the composition inline via --source, or an absolute path via --source-file",{flag:"--source"}),e.source&&e.sourceFile&&ys("E_SCHEMA","--source and --source-file are mutually exclusive","prefer --source (inline); file content is invisible to the billing extension / dl adapter",{inline_flag:"--source",file_flag:"--source-file"}),void 0===e.durationInFrames&&ys("E_SCHEMA","--duration-in-frames is required",void 0,{flag:"--duration-in-frames"}),e.source)t=String(e.source),i="inline";else{try{t=await O(String(e.sourceFile),"utf8")}catch(t){const i=t instanceof Error?t.message:String(t);ys("E_FILE_MISSING",`--source-file: cannot read ${e.sourceFile} (${i})`,"make sure the path exists in the sandbox",{flag:"--source-file",given:String(e.sourceFile)})}i=String(e.sourceFile)}t||ys("E_SCHEMA",e.source?"--source is empty":"--source-file is empty","pi skills should resolve the composition via --source (inline) or an absolute --source-file path.",{flag:e.source?"--source":"--source-file"});try{const t=await ms(e.inputProps?String(e.inputProps):void 0,e.inputPropsFile?String(e.inputPropsFile):void 0,{inline:"--input-props",file:"--input-props-file"});t&&(n=t.data,o=t.source.label)}catch(e){throw e instanceof wa&&bs(e),e}_s({command:"hyperframes",source_file:i,input_props:n??null,input_props_source:o??null});const r=k(),a={source:"dl",event:"hyperframes_render",credits:50,command:(s={command:"hyperframes",action:"hyperframes_render"}).command,action:s.action??"hyperframes_render",details:{rule:"hyperframes.fixed"}};var s;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"hyperframes_render",totalCredits:a.credits,items:[a]});const l={source_code:t,duration_in_frames:Number(e.durationInFrames),...e.compositionId?{composition_id:String(e.compositionId)}:{},...void 0!==e.fps?{fps:Number(e.fps)}:{},...void 0!==e.width?{width:Number(e.width)}:{},...void 0!==e.height?{height:Number(e.height)}:{},...n?{input_props:n}:{}};let c=!1;try{await Da("hyperframes","renders",{job_id:r,params:l,agent_id:e.agentId??0},{billing:{jobRef:r,quote:a}}),c=!0;const t=await async function(e,t){const i=Date.now();for(;Date.now()-i<t;){const t=await Ha("hyperframes",`renders/${e}`,{},{timeoutMs:3e4,retries:0});if("completed"===t.status)return t.data??t;if("failed"===t.status)throw new Error(`hyperframes: ${t.error??"failed"}`);await new Promise(e=>setTimeout(e,2e3))}throw new Error(`hyperframes: timeout after ${t}ms`)}(r,e.timeoutMs??9e5);gs({ok:!0,job_ref:r,data:t,billing:a})}catch(e){c&&await async function(e){try{await Ua({jobRef:e.jobRef,quote:e.quote,reason:e.reason})}catch(t){process.stderr.write(`${JSON.stringify({level:"warn",event:"dl_billing_refund_failed",job_ref:e.jobRef,reason:e.reason,error:t instanceof Error?t.message:String(t)})}\n`)}}({jobRef:r,quote:a,reason:"hyperframes_render_failed"}),e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:r}),e instanceof Jr&&vs(e.message,e.hint,{job_ref:r}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:r})}})}(_d),function(e){e.command("poll").description("Single one-shot status check for an async job by job_ref. Does NOT loop — call at most once; end your turn and let [async-callback] resume you when the job lands.").addHelpText("after",["","Output (success):",' {"ok":true,"job_ref":"<uuid>","status":"completed"|"failed"|"pending","data":{...}}',"","`status=pending` means the job exists but hasn't terminated yet. 404 from","the backend also maps to `pending` (job_ref not yet registered).","","DO NOT call this inside `sleep` / `for` / `while` loops to wait for a job to","finish. Bash commands have a ~5-minute cap, the sandbox is reclaimed on","inactivity, and the proxy token TTL tracks the command budget — any wait","loop will be killed before the callback fires. End the turn instead; the","vendor result arrives as a `[async-callback] job=<ref>` user message in a","later turn, re-spawning a fresh sandbox."].join("\n")).requiredOption("--job-ref <ref>","the job_ref returned by a previous async submit (e.g. dl generate-music)").action(async e=>{try{const t=String(e.jobRef).trim();Ac.test(t)||ys("E_SCHEMA","--job-ref must be the full UUID returned by the submit command","Do not use short prefixes like 2988ed2c; callback-server stores async job docs by the full job_ref.",{job_ref:t});const i=(process.env.CALLBACK_SERVER_URL??"").replace(/\/+$/,"")||ha(process.env),n=await fetch(`${i}/result/${encodeURIComponent(t)}`,{method:"GET",signal:AbortSignal.timeout(15e3)});n.ok||(404===n.status&&($c(),gs({ok:!0,job_ref:t,status:"pending"})),vs(`poll http ${n.status}`));const o=await n.json();"pending"===o.status&&$c(),gs({ok:!0,job_ref:t,...o})}catch(e){vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){e.command("search").description("External web search via Baidu / Serper / Tavily / Brave, plus Baidu similar-image search.").addHelpText("after",["","`--provider` is required; pick the adapter to use (no auto-fanout).","For Baidu image/video discovery, use `--provider=baidu --resource-type=image|video`.","For Baidu similar-image search, use `--provider=baidu-image --image-file=<jpg|png>`.","For URL fetch (not a query), use `dl fetch` instead.","","Example (stdin):",' cat <<EOF | dl search --query="cats" --provider=tavily --params-file=-',' {"safe":"strict"}'," EOF"].join("\n")).option("--query <q>","search query string").requiredOption("--provider <name>","search adapter: baidu|baidu-image|serper|tavily|brave").option("--k <n>","max hits (default 10, max 100)",e=>function(e,t,i=100){const n=Number(e);if(!Number.isFinite(n)||!Number.isInteger(n)||n<1||n>i)throw new Error(`${t} must be a positive integer ≤ ${i}, got ${e}`);return n}(e,"--k")).option("--resource-type <type>","baidu only: web|image|video (default web)").option("--image-file <path>","jpg/png file for provider=baidu-image").option("--country <cc>","ISO country hint (serper/brave only)").option("--freshness <win>","freshness window: pd (day) | pw (week) | pm (month) | py (year)").option("--params <inline-json>",'RECOMMENDED: adapter-specific extras inline so the billing extension + dl adapter can read it from argv. Write it to a file and pass --params "$(cat extras.json)" — keeps complex JSON out of shell quoting. Over ~100KB (argv single-arg cap ~128KB) fall back to --params-file.').option("--params-file <path|->",'LEGACY: adapter-specific extras JSON object via file path; `-` reads stdin. File/stdin content is invisible to the billing extension + dl adapter, so prefer --params "$(cat file)". Use --params-file only when the payload is too large for argv (single-arg cap ~128KB).').option("--print-schema","print scalar+file schema and exit").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{e.printSchema&&Js({command:"dl search",summary:"External web search via Baidu / Serper / Tavily / Brave, plus Baidu similar-image search.",scalars:[{name:"query",type:"string",required:!1,description:"search query (required except provider=baidu-image)"},{name:"provider",type:"string",required:!0,description:"baidu|baidu-image|serper|tavily|brave",enum:Ic},{name:"k",type:"integer",required:!1,description:"max hits (default 10, max 100)"},{name:"resource-type",type:"string",required:!1,description:"baidu only: web|image|video (default web)",enum:qc},{name:"image-file",type:"string",required:!1,description:"jpg/png path for provider=baidu-image"},{name:"country",type:"string",required:!1,description:"ISO country hint (serper/brave)"},{name:"freshness",type:"string",required:!1,description:"pd|pw|pm|py",enum:["pd","pw","pm","py"]},{name:"params",type:"string",required:!1,description:"RECOMMENDED inline JSON object of adapter-specific extras (sibling of --params-file)"}],files:[{name:"params-file",required:!1,kind:"object",description:"LEGACY: adapter-specific extras (prefer --params inline)",example:'{"safe":"strict"}'}]});const t=String(e.provider??"");let i;if(Ic.includes(t)||vs(`--provider must be one of ${Ic.join(", ")}; got ${t}`,"only baidu/baidu-image/serper/tavily/brave are wired; auto-fanout is not supported."),"baidu-image"===t||e.query||ys("E_SCHEMA","--query is required","pass --query for text search providers",{flag:"--query"}),e.resourceType){const t=String(e.resourceType);n=t,qc.includes(n)||ys("E_SCHEMA",`--resource-type must be web|image|video; got ${t}`,void 0,{flag:"--resource-type"}),i=t}var n;let o;i&&"baidu"!==t&&ys("E_SCHEMA","--resource-type is only supported with --provider=baidu",void 0,{flag:"--resource-type",provider:t}),e.freshness&&!Rc.has(String(e.freshness))&&vs(`--freshness must be pd|pw|pm|py; got ${e.freshness}`);try{const t=await ms(e.params?String(e.params):void 0,e.paramsFile?String(e.paramsFile):void 0,{inline:"--params",file:"--params-file"});t&&(o=t.data)}catch(e){throw e instanceof wa&&bs(e),e}const r=k(),a={source:"dl",event:"search",credits:10,command:(s={command:"search",action:"search"}).command,action:s.action??"search",details:{rule:"search.fixed",provider:{provider:t}.provider}};var s;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"search",totalCredits:a.credits,items:[a]});try{gs({ok:!0,job_ref:r,provider:t,hits:await Mc(t,e.query?String(e.query):"",{k:e.k,...i?{resourceType:i}:{},...e.imageFile?{imageFile:String(e.imageFile)}:{},...e.country?{country:String(e.country)}:{},...e.freshness?{freshness:e.freshness}:{},...o?{extra:o}:{},billing:{jobRef:r,quote:a}}),billing:a})}catch(e){e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:r}),e instanceof Jr&&vs(e.message,e.hint),vs(e instanceof Error?e.message:String(e))}})}(_d),function(e){const t=e.command("stock").description("Search and download public stock media (Pexels / Pixabay / Openverse) for b-roll.");t.command("search").description("Sequential-fallback search across providers (Pexels → Pixabay → Openverse). Use --mode=fanout for parallel.").addHelpText("after",["","Modes:"," fallback (default) - calls Pexels -> Pixabay -> Openverse in order and stops once limit results are collected."," If one provider returns too few results, it falls through to the next; lowest API budget."," fanout - calls all enabled providers concurrently and merges for provider diversity."," Costs about 3x API budget; use only when cross-vendor diversity is required (rare queries).","","Provider selection:"," --providers defaults to all supports-current-type providers in default order."," Openverse is image-only; for --type=video it is auto-skipped."," Custom order: --providers=pixabay,pexels lets agent reorder fallback.","","Output: JSON { ok, job_ref, query, type, mode, results[], providers_queried, providers_failed[], billing }."," Fallback mode: providers_queried may be shorter than enabled when later providers are not needed."," Each result carries asset_id, download_url and full license metadata —"," pass them to `dl stock download` for the fetch.","","Examples:",' dl stock search --query="sunset beach" --type=image --limit=10',' dl stock search --query="city traffic" --type=video --duration-min=5 --duration-max=15',' dl stock search --query="rare landscape" --type=image --mode=fanout # needs diversity',' dl stock search --query="..." --providers=pixabay,pexels # custom order'].join("\n")).requiredOption("--query <q>","natural-language search query").requiredOption("--type <t>","image | video").option("--orientation <o>","landscape | portrait | square").option("--min-width <n>","minimum dimensions.width in px (filter post-normalize)",e=>md(e,"--min-width",1e5)).option("--duration-min <s>","minimum video duration in seconds (video only)",e=>hd(e,"--duration-min")).option("--duration-max <s>","maximum video duration in seconds (video only)",e=>hd(e,"--duration-max")).option("--limit <n>","max results to return (1..30, default 10)",e=>md(e,"--limit",30),10).option("--providers <list>",`csv of providers in custom order; default order: ${cd.join(", ")}`).option("--mode <m>",`search strategy: ${pd.join(" | ")} (default fallback saves API budget; use fanout only when diversity is required)`,"fallback").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{const t=String(e.type);ud.has(t)||vs(`--type must be image|video; got ${e.type}`),e.orientation&&!dd.has(String(e.orientation))&&vs(`--orientation must be landscape|portrait|square; got ${e.orientation}`);const i=String(e.mode);pd.includes(i)||vs(`--mode must be one of ${pd.join(", ")}; got ${e.mode}`);const n=e.limit??10,o=function(e,t){const i=e?e.split(",").map(e=>e.trim()).filter(Boolean):[...cd],n=[];for(const e of i){const i=ld[e];i||vs(`unknown stock provider: ${e}`,`supported providers: ${cd.join(", ")}`),("image"===t&&i.supports.image||"video"===t&&i.supports.video)&&n.push(e)}return 0===n.length&&vs(`no providers support type=${t}`,"try --providers=pexels,pixabay"),n}(e.providers?String(e.providers):void 0,t),r="fanout"===i?Math.max(1,Math.ceil(1.5*n/o.length)):n,a={query:String(e.query),type:t,orientation:e.orientation?String(e.orientation):void 0,minWidth:e.minWidth,durationMin:e.durationMin,durationMax:e.durationMax,perProviderLimit:r},s=k(),l={source:"dl",event:"stock_search",credits:5,command:(d={command:"stock search",action:"stock_search"}).command,action:d.action??"stock_search",details:{rule:"stock-search.fixed",type:(c={type:t,mode:i,limit:n,providers:o}).type,mode:c.mode,limit:c.limit,providers:c.providers}};var c,d;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"stock_search",totalCredits:l.credits,items:[l]});let u=null;try{u=await Ma({jobRef:s,quote:l});const{results:r,queried:c,failed:d}="fanout"===i?await async function(e,t,i,n=vd){const o=await Promise.allSettled(e.map(e=>n(e,t))),r=[],a=[];for(let t=0;t<e.length;t++){const i=o[t];"fulfilled"===i.status?r.push(i.value):(r.push([]),a.push(fd(e[t],i.reason)))}return{results:gd(r,i),queried:[...e],failed:a}}(o,a,n):await async function(e,t,i,n=vd){const o=[],r=new Set,a=[],s=[];for(const l of e){a.push(l);try{const e=await n(l,t);for(const t of e)if(!r.has(t.asset_id)&&(r.add(t.asset_id),o.push(t),o.length>=i))break}catch(e){s.push(fd(l,e))}if(o.length>=i)break}return{results:o.slice(0,i),queried:a,failed:s}}(o,a,n);0===r.length&&d.length>0&&d.length===c.length&&(await yd({jobRef:s,quote:l,receipt:u,reason:"stock_search_failed"}),vs(`all stock-media providers failed for "${e.query}"`,"check API keys / quota; see providers_failed for per-provider reason.",{job_ref:s,mode:i,providers_queried:c,providers_failed:d})),gs({ok:!0,job_ref:s,query:a.query,type:t,mode:i,results:r,providers_queried:c,providers_failed:d,billing:l})}catch(e){u&&await yd({jobRef:s,quote:l,receipt:u,reason:"stock_search_failed"}),e instanceof Jr&&vs(e.message,e.hint,{job_ref:s}),e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:s}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:s})}}),function(e){e.command("download").description("Fetch a stock-media asset (CDN URL from search result) into /workspace and echo full metadata.").addHelpText("after",["","Flow: callback-server handles billing-only charge/refund; dl directly fetches the public CDN URL."," The --metadata-json from your search result is passed through verbatim,"," so agents have everything to write credits / track usage later.","","Example:"," RESULT=$(dl stock search --query=cats --type=image --limit=1 | jq '.results[0]')"," dl stock download \\",' --asset-id="$(jq -r .asset_id <<<"$RESULT")" \\',' --url="$(jq -r .download_url <<<\\"$RESULT\\")" \\',' --metadata-json="$RESULT"'].join("\n")).requiredOption("--asset-id <id>","<provider>:<native_id> from a search result").requiredOption("--url <url>","direct CDN URL from search result's download_url").option("--to <path>",`absolute path under /workspace (default: ${Gc}/<provider>-<id>.<ext>)`).option("--metadata-json <json>","JSON-encoded metadata object from search result; echoed back in output for downstream credit-tracking").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{const{provider:t,nativeId:i}=function(e){const t=Wc.exec(e);return t||vs(`invalid --asset-id "${e}"`,"expected `<provider>:<native_id>`, e.g. pexels:12345 (from search results)."),{provider:t[1],nativeId:t[2]}}(String(e.assetId)),n=String(e.url);try{const e=new URL(n);"https:"!==e.protocol&&"http:"!==e.protocol&&vs(`--url must be http(s); got protocol ${e.protocol}`)}catch(e){throw"TypeError"===e.name&&vs(`--url is not a valid URL: ${n}`),e}const o=function(e){if(!e)return null;try{const t=JSON.parse(e);return("object"!=typeof t||null===t||Array.isArray(t))&&vs("--metadata-json must be a JSON object; got "+("object"==typeof t?"array/null":typeof t)),t}catch(e){vs(`--metadata-json failed to parse: ${e.message}`)}}(e.metadataJson),r=e.to?Qc(String(e.to),String(e.to)):void 0,a=k(),s={source:"dl",event:"stock_download",credits:5,command:(c={command:"stock download",action:"stock_download"}).command,action:c.action??"stock_download",details:{rule:"stock-download.fixed",provider:(l={provider:t,native_id:i}).provider,native_id:l.native_id}};var l,c;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"stock_download",totalCredits:s.credits,items:[s]});let d=null;try{d=await Ma({jobRef:a,quote:s});const{buf:e,contentType:l}=await async function(e){const t=new AbortController,i=setTimeout(()=>t.abort(),6e4);try{const i=await fetch(e,{signal:t.signal});if(!i.ok)throw new Xc(`download failed: HTTP ${i.status} from ${e}`);const n=i.headers.get("content-length");if(n&&Number(n)>Yc)throw new Xc(`download too large: ${n} bytes exceeds 209715200 cap`,"this looks like an unusually large asset; double-check the URL.");const o=await i.arrayBuffer();if(o.byteLength>Yc)throw new Xc(`download too large: ${o.byteLength} bytes exceeds 209715200 cap`,"this looks like an unusually large asset; double-check the URL.");return{buf:Buffer.from(o),contentType:i.headers.get("content-type")}}catch(t){if(t instanceof Xc)throw t;if("AbortError"===t.name)throw new Xc("download timed out after 60000ms",`url: ${e}`);throw new Xc(`download fetch error: ${t.message}`,`url: ${e}`)}finally{clearTimeout(i)}}(n),c=function(e,t){if(t){const e=t.split(";")[0]?.trim().toLowerCase();if(e&&Zc.has(e))return Zc.get(e)}try{const t=new URL(e),i=p(t.pathname).replace(/^\./,"").toLowerCase();if(i&&/^[a-z0-9]{2,5}$/.test(i))return i}catch{}return"bin"}(n,l),m=r??Qc(void 0,`${Gc}/${t}-${i}.${c}`);await T(u(m),{recursive:!0}),await A(m,e),gs({ok:!0,job_ref:a,asset_id:`${t}:${i}`,local_path:m,size_bytes:e.length,mime_type:l?.split(";")[0]?.trim()??null,metadata:o,billing:s})}catch(e){d&&await async function(e){try{await Ua({jobRef:e.jobRef,quote:e.quote,reason:e.reason,chargeId:e.receipt.charge_id})}catch(t){process.stderr.write(`${JSON.stringify({level:"warn",event:"dl_billing_refund_failed",job_ref:e.jobRef,reason:e.reason,error:t instanceof Error?t.message:String(t)})}\n`)}}({jobRef:a,quote:s,receipt:d,reason:"stock_download_failed"}),e instanceof Xc&&vs(e.message,e.hint,{job_ref:a}),e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:a}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:a})}})}(t)}(_d),function(e){e.command("fetch").description("Fetch a URL and emit extracted text / markdown / raw body (--mode). Non-2xx → error.").addHelpText("after",["","For a search query (not a URL), use `dl search`.","For social-media downloads (TikTok / IG / etc.), use `dl download-media`.","","Example:"," dl fetch --url=https://example.com --mode=markdown --max-bytes=1000000"].join("\n")).requiredOption("--url <url>").option("--mode <mode>","text|markdown|raw","text").option("--max-bytes <n>","max bytes to read (default 2000000, max 50000000)",e=>function(e,t,i){const n=Number(e);if(!Number.isFinite(n)||!Number.isInteger(n)||n<1||n>i)throw new Error(`--max-bytes must be a positive integer ≤ ${i}, got ${e}`);return n}(e,0,5e7)).option("--timeout-ms <n>","end-to-end timeout in ms (default 30000, min 7000, max 120000)",Xl).option("--user-agent <ua>","override UA header").option("--quote","emit the credit quote for this command and exit without submitting vendor work").action(async e=>{const t=String(e.mode??"text");var i;i=t,Zl.includes(i)||vs(`--mode must be text|markdown|raw, got ${t}`);const n=k(),o=e.timeoutMs??3e4,r={source:"dl",event:"fetch",credits:5,command:(a={command:"fetch",action:"fetch"}).command,action:a.action??"fetch",details:{rule:"fetch.fixed",mode:{mode:t}.mode}};var a;!0===e.quote&&gs({ok:!0,mode:"single",source:"dl",action:"fetch",totalCredits:r.credits,items:[r]});try{gs({ok:!0,job_ref:n,...await Da("web-fetch","",{url:String(e.url),mode:t,max_bytes:e.maxBytes??2e6,timeout_ms:o,...e.userAgent?{user_agent:String(e.userAgent)}:{}},{timeoutMs:o,retries:0,billing:{jobRef:n,quote:r}}),billing:r})}catch(e){if(e instanceof wa&&ys(e.code,e.message,e.hint,{...e.extra??{},job_ref:n}),e instanceof Sa){const t=function(e){const t=function(e){let t;try{t=JSON.parse(e)}catch{return null}if("object"!=typeof(i=t)||null===i||Array.isArray(i))return null;var i;const n=Ql(t,"error")??Ql(t,"message");return n?{message:n,errorCode:Ql(t,"error_code"),provider:Ql(t,"provider"),..."boolean"==typeof t.retryable?{retryable:t.retryable}:{}}:null}(e.bodyText),i=t?.errorCode,n="FIRECRAWL_RATE_LIMITED"===i?"Firecrawl 正在限流,请按 Retry-After 稍后重试。":"FIRECRAWL_QUOTA_EXHAUSTED"===i?"Firecrawl Cloud quota 已耗尽,请补充 quota 后重试。":!0===t?.retryable?"这是可重试的上游失败,请稍后重试。":void 0;return{message:t?.message??`fetch gateway returned HTTP ${e.status}`,...n?{hint:n}:{},extra:{http_status:e.status,...i?{error_code:i}:{},...t?.provider?{provider:t.provider}:{},...void 0!==t?.retryable?{retryable:t.retryable}:{}}}}(e);ys("E_BACKEND",t.message,t.hint,{...t.extra,job_ref:n})}e instanceof Jr&&vs(e.message,e.hint,{job_ref:n}),vs(e instanceof Error?e.message:String(e),void 0,{job_ref:n})}})}(_d),_d.configureHelp({subcommandTerm(e){const t=e.name(),i=e.commands.length>0,n=(e.registeredArguments??[]).length>0;return i?`${t} <command>`:n?`${t} ${e.usage()}`:`${t} [options]`}}),function(e){const t=e=>{e.exitOverride(),e.configureOutput({writeErr:()=>{},outputError:()=>{}}),e.commands.forEach(t)};t(e);const i=e.parseAsync.bind(e);e.parseAsync=async n=>{t(e);try{return await i(n)}catch(t){!function(e,t){const i=t,n=i?.code??"",o=i?.message??String(t??"");if("commander.unknownOption"===n){const t=function(e){const t=/unknown option ['`"]?([-a-zA-Z0-9_]+)['`"]?/.exec(e);return t?.[1]}(o)??"",i=function(e){const t=new Set,i=e=>{for(const i of e.options)i.long&&t.add(i.long),i.short&&t.add(i.short);for(const t of e.commands)i(t)};return i(e),[...t]}(e),n=t?xa(t,i):void 0,r=n&&n!==t?n:void 0;ys("E_UNKNOWN_OPTION",r?`unknown option \`${t}\` (did you mean \`${r}\`?)`:`unknown option \`${t||"<unknown>"}\``,"run the command with --help for the full flag list",{flag:t,...r?{suggestion:r}:{}})}"commander.unknownCommand"===n&&ys("E_UNKNOWN_OPTION",`unknown command: ${o}`,"run --help for the list of subcommands",{commander_code:n}),"commander.help"!==n&&"commander.helpDisplayed"!==n&&"commander.version"!==n||process.exit(0),"commander.missingMandatoryOptionValue"!==n&&"commander.missingArgument"!==n||ys("E_SCHEMA",o,"see --help; required scalar / argument is missing",{commander_code:n}),"commander.invalidOptionArgumentValue"!==n&&"commander.invalidArgument"!==n||ys("E_SCHEMA",o,"see --help for accepted values",{commander_code:n}),process.stderr.write(`${JSON.stringify({ok:!1,code:"E_BACKEND",error:o})}\n`),process.exit("number"==typeof i?.exitCode?i.exitCode:1)}(e,t)}}}(_d),_d.parseAsync(process.argv).catch(e=>{e instanceof wa&&(process.stderr.write(`${JSON.stringify({ok:!1,code:e.code,error:e.message,message:e.message,...e.hint?{hint:e.hint}:{},...e.extra??{}})}\n`),process.exit(_a(e.code)));const t=e instanceof Error?e.message:String(e),i=e instanceof Error&&"hint"in e&&"string"==typeof e.hint?e.hint:void 0;process.stderr.write(`${JSON.stringify({ok:!1,code:"E_BACKEND",error:t,...i?{hint:i}:{}})}\n`),process.exit(1)});
|