@lingjingai/scriptctl 0.65.3 → 0.65.4
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/changes/0.65.4.md +13 -0
- package/dist/bin.js +1 -1
- package/dist/{chunk-TPKRTUVV.js → chunk-LT747D45.js} +1 -1
- package/dist/cli.js +1 -1
- package/package.json +1 -1
- package/skills/scriptctl/SKILL.md +1 -1
package/dist/bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{b as s}from"./chunk-
|
|
2
|
+
import{b as s}from"./chunk-LT747D45.js";import{Console as r}from"node:console";var o=new r({stdout:process.stderr,stderr:process.stderr});console.debug=o.debug.bind(o);console.info=o.info.bind(o);console.log=o.log.bind(o);s(process.argv.slice(2)).then(e=>{process.exitCode=e}).catch(e=>{console.error(e),process.exitCode=70});
|
|
@@ -141,7 +141,7 @@ Rules:
|
|
|
141
141
|
`)}
|
|
142
142
|
`)}return e.exitCode}var _d=new WeakMap;function ME(e){return e.replace(/([A-Z])/g,"_$1").toLowerCase()}function NE(e){return Object.fromEntries(Object.entries(e).map(([t,n])=>[ME(t),n]))}function LE(e){let t=[],n=e;for(;n;)t.unshift(n),n=n.parent;return Object.assign({},...t.map(o=>o.opts()))}function H(e,t){return async(...n)=>{let o=n[n.length-1],i=n.slice(0,-2).filter(d=>d!==void 0),r=NE(LE(o));i.length>0&&(r._args=i),t.jsonMode=!!r.json,t.format=typeof r.format=="string"?r.format:void 0;let s=async()=>e(r),[c,a]=_d.get(o)==="write"?await Ts(ge(r),s):await s();gf(c,a,t.jsonMode,t.format),t.exitCode=a}}function Me(e,t){return e.registeredArguments.forEach((n,o)=>{n.description=t[o]??""}),e}function te(e,t="write"){return _d.set(e,t),e.option("-p, --script-path <path>","Script JSON file (default: ./workspace/script.json)")}function Ed(e){return _d.set(e,"write"),e.option("-p, --script-path <path>","Local script JSON file (default: ./workspace/script.json)").option("--project-group-no <no>","Remote project group number")}function hf(e,t){let n=e.command("authoring").description("Structured screenplay compilation and atomic application transactions"),o=te(n.command("write <file>")).description("Plan or apply a complete structured authoring document").option("--create","Create the selected target").option("--replace","Replace the selected target").option("--apply","Apply the exact plan").option("--plan <digest>","Exact plan digest to apply").action(H(uf,t));Me(o,["Structured .scriptctl file"]);let i=te(n.command("compose <file>")).description("Compile a readable scene JSON draft with generated identities and timing").option("--apply","Apply the exact plan").option("--plan <digest>","Exact plan digest to apply").action(H(Iu,t));Me(i,["Readable scene JSON file"]);let r=n.command("export").description("Export complete structured content, including identities and extensions"),s=["script","episodes","episode-spans","scenes","scene-spans","action-spans"];for(let c of s){let a=te(r.command(c),"read").description(`Export structured ${c}`).requiredOption("-o, --output <file>","Destination .scriptctl file");c!=="script"&&a.requiredOption("-i, --in <selector>","Formal ID or @ep:N selector / inclusive range"),a.action(H(d=>Tu(c,d),t))}}import*as qs from"node:fs";import*as Od from"node:path";import*as Id from"node:fs";import*as Ji from"node:path";import{fileURLToPath as UE}from"node:url";var Sd="@lingjingai/scriptctl",xd="";function Ad(){if(xd)return xd;let e=Ji.dirname(UE(import.meta.url));for(;;){try{let n=Id.readFileSync(Ji.join(e,"package.json"),"utf-8");if(JSON.parse(n).name===Sd)return xd=e,e}catch{}let t=Ji.dirname(e);if(t===e)throw new Error(`${Sd} package root not found`);e=t}}function ji(){let e=Id.readFileSync(Ji.join(Ad(),"package.json"),"utf-8"),t=JSON.parse(e).version;if(typeof t!="string")throw new Error(`${Sd} package.json has no string version`);return t}var yf=/^\d+\.\d+\.\d+$/,PE="unreleased";function wf(){return Od.join(Ad(),"changes")}function CE(){return ji()}function Dr(e){if(!yf.test(e))throw new S("Version must use x.y.z.",{exitCode:J,errorCode:"CHANGELOG_VERSION_INVALID",hint:"Pass a released version such as `scriptctl changelog 0.25.10`.",data:{expected:["x.y.z"],actual:[e||"<empty>"]}});let[t,n,o]=e.split(".").map(i=>Number(i));return[t,n,o]}function bd(e,t){let n=Dr(e),o=Dr(t);for(let i=0;i<3;i++)if(n[i]!==o[i])return n[i]-o[i];return 0}function TE(){let e=wf();return qs.readdirSync(e).filter(t=>t.endsWith(".md")).map(t=>t.slice(0,-3)).filter(t=>yf.test(t)).sort(bd)}function Ys(e){return qs.readFileSync(Od.join(wf(),`${e}.md`),"utf-8").trimEnd()}function kd(e,t){return new S(`No changelog entry exists for ${e}.`,{exitCode:k,errorCode:"CHANGELOG_VERSION_NOT_FOUND",hint:t.length>0?`Available versions: ${t.join(", ")}`:"Add changes/<version>.md first.",data:{expected:["existing changelog version"],actual:[e]}})}function VE(e,t){return new S(`No released changelog entries found after ${e} through ${t}.`,{exitCode:k,errorCode:"CHANGELOG_RANGE_EMPTY",hint:"Choose a wider range or run `scriptctl changelog <version>` for a known release.",data:{expected:["a version range containing released changelog entries"],actual:[`--from ${e}`,`--to ${t}`]}})}function $E(e){return e.map(Ys).join(`
|
|
143
143
|
|
|
144
|
-
`)}function _f(e){let t=e._args??[],n=t[0]?.trim()??"",o=String(e.from??"").trim(),i=String(e.to??"").trim(),r=!!e.unreleased;if(t.length>1)throw new S("changelog accepts at most one version argument.",{exitCode:J,errorCode:"CHANGELOG_TOO_MANY_ARGS",hint:"Pass a single version, or use --from/--to for a range.",data:{expected:["scriptctl changelog [version] [--from X] [--to Y] [--unreleased]"],actual:[t.join(" ")]}});if(r&&(n||o||i))throw new S("--unreleased cannot combine with version, --from, or --to.",{exitCode:J,errorCode:"CHANGELOG_SELECTOR_CONFLICT",hint:"Run `scriptctl changelog --unreleased` by itself.",data:{expected:["either --unreleased, a version, or a --from/--to range"],actual:["--unreleased with another selector"]}});if(n&&(o||i))throw new S("A version argument cannot combine with --from or --to.",{exitCode:J,errorCode:"CHANGELOG_SELECTOR_CONFLICT",hint:"Run `scriptctl changelog 0.25.10` or `scriptctl changelog --from 0.25.8 --to 0.25.10`.",data:{expected:["either a version argument, or --from/--to"],actual:[n,o?`--from ${o}`:"",i?`--to ${i}`:""].filter(Boolean)}});if(r){let d=Ys(PE);return[{text:d,data:{content:d,versions:[],unreleased:!0}},B]}let s=TE(),c=CE();if(n){if(Dr(n),!s.includes(n))throw kd(n,s);let d=Ys(n);return[{text:d,data:{content:d,versions:[n],unreleased:!1}},B]}if(o||i){if(!o)throw new S("--from is required for range queries.",{exitCode:J,errorCode:"CHANGELOG_FROM_MISSING",hint:"Run `scriptctl changelog --from 0.25.8 --to 0.25.10`.",data:{expected:["--from <x.y.z>"],actual:[i?`--to ${i}`:"<missing>"]}});Dr(o);let d=i||c;if(Dr(d),!s.includes(d))throw kd(d,s);let p=s.filter(f=>bd(f,o)>0&&bd(f,d)<=0);if(p.length===0)throw VE(o,d);let l=$E(p);return[{text:l,data:{content:l,versions:p,from:o,to:d,unreleased:!1}},B]}if(!s.includes(c))throw kd(c,s);let a=Ys(c);return[{text:a,data:{content:a,versions:[c],unreleased:!1}},B]}import*as Bt from"node:fs";import*as ii from"node:path";import{createRequire as Bx}from"node:module";import*as Hn from"node:fs";import*as Eo from"node:path";import*as xf from"node:os";import{fileURLToPath as DE}from"node:url";function Ef(e){return e.startsWith("~")?Eo.join(xf.homedir(),e.slice(1)):e}function GE(e){let t=Hn.readFileSync(e,"utf-8");for(let n of t.split(/\r?\n/)){let o=n.trim();if(!o||o.startsWith("#"))continue;o.startsWith("export ")&&(o=o.slice(7).trim());let i=o.indexOf("=");if(i<0)continue;let r=o.slice(0,i).trim(),s=o.slice(i+1).trim();s.length>=2&&s[0]===s[s.length-1]&&(s[0]==="'"||s[0]==='"')&&(s=s.slice(1,-1)),r&&s&&!process.env[r]&&(process.env[r]=s)}}function vd(){let e=[],t=(process.env.SCRIPTCTL_ENV_FILE??"").trim();t&&e.push(Ef(t));let n=(process.env.SCRIPTCTL_SKILL_DIR??"").trim();n&&e.push(Eo.join(Ef(n),".env"));let o;try{o=DE(import.meta.url)}catch{o=process.cwd()}let i=Eo.resolve(o),r=new Set;for(;;){let s=Eo.dirname(i);if(s===i||r.has(s))break;r.add(s),e.push(Eo.join(s,".env")),i=s}return e}function Sf(){let e=process.env.SCRIPTCTL_NO_DOTENV;if(e==="1"||e==="true"||e==="True")return;let t=new Set;for(let n of vd()){let o;try{o=Hn.existsSync(n)?Hn.realpathSync(n):n}catch{o=n}t.has(o)||!Hn.existsSync(n)||!Hn.statSync(n).isFile()||(t.add(o),GE(n))}}var me=class extends Error{status;code;payload;configMissing;constructor(t,n={}){super(t),this.name="ScriptOutputApiError",this.status=n.status??null,this.code=n.code??null,this.payload=n.payload,this.configMissing=n.configMissing??null}};async function Rd(e,t){if(e.updateEpisodeCount)try{await e.updateEpisodeCount(t)}catch{}}function If(e){let t=!!e?.remote,n=!!e?.local;if(t&&n)return{mode:null,conflict:!0};if(t)return{mode:"remote",conflict:!1};if(n)return{mode:"local",conflict:!1};let o=(process.env.SCRIPTCTL_OUTPUT_MODE??"").trim().toLowerCase();if(o==="local"||o==="remote")return{mode:o,conflict:!1};if(o!=="")return{mode:null,conflict:!1};let i=typeof e?.projectGroupNo=="string"?e.projectGroupNo.trim():"",r=(process.env.SANDBOX_PROJECT_GROUP_NO??"").trim();return i!==""||r!==""?{mode:"remote",conflict:!1}:{mode:null,conflict:!1}}import*as Jr from"node:fs";import*as kf from"node:os";import*as Gr from"node:path";import{parseDocument as BE}from"yaml";function ae(e,t,n){return{id:e,mode:t,version:"1",maxOutputTokens:n,defaultProfile:"default"}}var An={"direct.episode-titles":ae("direct.episode-titles","tool",4096),"direct.batch-extract":ae("direct.batch-extract","text",16e3),"direct.episode-synopsis":ae("direct.episode-synopsis","tool",2048),"direct.synopsis-reduction":ae("direct.synopsis-reduction","tool",4096),"direct.script-synopsis":ae("direct.script-synopsis","tool",2048),"direct.asset-grouping":ae("direct.asset-grouping","text",8e3),"direct.asset-curation":ae("direct.asset-curation","text",2e4),"direct.asset-curation-audit":ae("direct.asset-curation-audit","text",2e4),"direct.location-canonicalization":ae("direct.location-canonicalization","text",2e4),"direct.state-curation":ae("direct.state-curation","text",2e4),"direct.state-binding":ae("direct.state-binding","tool",16e3),"metadata.global":ae("metadata.global","text",16e3),"metadata.descriptions":ae("metadata.descriptions","text",16e3),"synopsis.chunk":ae("synopsis.chunk","text",4096),"synopsis.episode":ae("synopsis.episode","text",4096),"synopsis.arc":ae("synopsis.arc","text",16e3),"synopsis.script-overview":ae("synopsis.script-overview","text",16e3),"ingest.body-start":ae("ingest.body-start","text",16e3),"ingest.arc-summary":ae("ingest.arc-summary","text",4096),"ingest.text-normalize":ae("ingest.text-normalize","text",32e3),"ingest.episode-assets":ae("ingest.episode-assets","tool",32e3),"ingest.name-fix":ae("ingest.name-fix","tool",16e3),"ingest.mention-resolve":ae("ingest.mention-resolve","text",8e3),"ingest.asset-extract":ae("ingest.asset-extract","text",8e3),"ingest.asset-curate":ae("ingest.asset-curate","text",32e3),"ingest.asset-recall":ae("ingest.asset-recall","text",65536),"ingest.asset-refine":ae("ingest.asset-refine","text",32e3),"ingest.state-reconcile":ae("ingest.state-reconcile","text",32e3),"ingest.asset-audit":ae("ingest.asset-audit","tool",32e3),"ingest.speaker-audit":ae("ingest.speaker-audit","tool",16e3),"ingest.comic-serial":{id:"ingest.comic-serial",mode:"document",version:"1",defaultProfile:"default"},"ingest.video-serial":ae("ingest.video-serial","video",65536)},Af=Object.keys(An).filter(Md);function Md(e){return Object.hasOwn(An,e)}var JE=new Set(["protocol","baseUrl","apiKey","timeoutMs","maxAttempts","videoResponseSchemaField","videoUploadMode","documentResponseSchemaField","documentUploadMode"]),jE=new Set(["provider","model","thinking","reasoning","temperature","fallbacks"]),KE=new Set(["env"]),zE=new Set(["budgetTokens"]);function Oe(e,t=[]){return new S(e,{exitCode:k,errorCode:"LLM_CONFIG_INVALID",hint:"Fix the selected LLM configuration or environment and rerun `scriptctl doctor`.",data:{expected:["valid scriptctl LLM YAML configuration"],actual:t}})}function Ud(e,t){let n;try{n=new URL(e)}catch{throw Oe(`${t} must be an absolute URL.`)}if(n.protocol!=="http:"&&n.protocol!=="https:")throw Oe(`${t} must use http or https.`);return n.toString().replace(/\/$/,"")}function Pd(e,t="provider base URL"){return Ud(e,t)}function HE(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function xo(e,t){if(!HE(e))throw Oe(`${t} must be a mapping.`,[`${t}: ${typeof e}`]);return e}function So(e,t){if(typeof e!="string"||!e.trim())throw Oe(`${t} must be a non-empty string.`);return e.trim()}function Ld(e,t,n,o){if(!Number.isInteger(e)||typeof e!="number"||e<n||o!==void 0&&e>o)throw Oe(`${t} must be an integer in ${o===void 0?`[${n}, +\u221E)`:`[${n}, ${o}]`}.`);return e}function Br(e,t,n){let o=Object.keys(e).filter(i=>!t.has(i));if(o.length>0)throw Oe(`${n} contains unknown fields.`,o)}function FE(e,t){let n=xo(t,`providers.${e}`);Br(n,JE,`providers.${e}`);let o=So(n.protocol,`providers.${e}.protocol`);if(o!=="anthropic"&&o!=="openai-compatible"&&o!=="google-gemini"&&o!=="google-vertex")throw Oe(`providers.${e}.protocol is unsupported.`,[o]);let i=n.baseUrl===void 0&&o!=="openai-compatible"?null:Ud(So(n.baseUrl,`providers.${e}.baseUrl`),`providers.${e}.baseUrl`),r="";if(o!=="google-vertex"){let c=xo(n.apiKey,`providers.${e}.apiKey`);if(Br(c,KE,`providers.${e}.apiKey`),r=So(c.env,`providers.${e}.apiKey.env`),!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r))throw Oe(`providers.${e}.apiKey.env must be an environment variable name.`)}let s={protocol:o,baseUrl:i,apiKeyEnv:r,timeoutMs:Ld(n.timeoutMs,`providers.${e}.timeoutMs`,1),maxAttempts:Ld(n.maxAttempts,`providers.${e}.maxAttempts`,1,6)};for(let c of["videoResponseSchemaField","documentResponseSchemaField"]){let a=n[c];if(a!==void 0){if(o!=="google-gemini"&&o!=="google-vertex")throw Oe(`providers.${e}.${c} requires a Gemini ${c.startsWith("video")?"video":"document"} provider.`);if(a!=="responseJsonSchema"&&a!=="responseSchema")throw Oe(`providers.${e}.${c} must be responseJsonSchema or responseSchema.`);s[c]=a}}for(let c of["videoUploadMode","documentUploadMode"]){let a=n[c];if(a!==void 0){if(o!=="google-gemini"&&o!=="google-vertex")throw Oe(`providers.${e}.${c} requires a Gemini ${c.startsWith("video")?"video":"document"} provider.`);if(a!=="file-api"&&a!=="base64")throw Oe(`providers.${e}.${c} must be file-api or base64.`);s[c]=a}}return s}function QE(e,t,n){let o=xo(t,`models.${e}`);Br(o,jE,`models.${e}`);let i=So(o.provider,`models.${e}.provider`),r=n[i];if(!r)throw Oe(`models.${e} references an unknown provider.`,[i]);let s={provider:i,model:So(o.model,`models.${e}.model`)};if(o.reasoning!==void 0&&(s.reasoning=So(o.reasoning,`models.${e}.reasoning`)),o.fallbacks!==void 0){let c=o.fallbacks;if(!Array.isArray(c))throw Oe(`models.${e}.fallbacks must be a list of model profiles.`);s.fallbacks=c.map((a,d)=>So(a,`models.${e}.fallbacks[${d}]`))}if(o.temperature!==void 0){let c=o.temperature;if(typeof c!="number"||!Number.isFinite(c)||c<0)throw Oe(`models.${e}.temperature must be a number \u2265 0.`);s.temperature=c}if(o.thinking!==void 0){if(r.protocol!=="anthropic")throw Oe(`models.${e}.thinking is only valid for anthropic providers.`);let c=xo(o.thinking,`models.${e}.thinking`);Br(c,zE,`models.${e}.thinking`),s.thinkingBudgetTokens=Ld(c.budgetTokens,`models.${e}.thinking.budgetTokens`,1024)}return s}function YE(e,t){let n=xo(e,"config");if(Br(n,new Set(["version","providers","models","tasks"]),"config"),n.version!==1)throw Oe("config.version must be 1.");let o=xo(n.providers,"providers"),i={};for(let[a,d]of Object.entries(o))i[a]=FE(a,d);let r=xo(n.models,"models"),s={};for(let[a,d]of Object.entries(r))s[a]=QE(a,d,i);if(!s.default)throw Oe("models.default is required.");for(let[a,d]of Object.entries(s))for(let p of d.fallbacks??[])if(!s[p]||p===a)throw Oe(`models.${a}.fallbacks references an unknown or the same profile.`,[p]);let c={};if(n.tasks!==void 0){let a=xo(n.tasks,"tasks");for(let[d,p]of Object.entries(a)){if(!Md(d))throw Oe("tasks contains an unknown task id.",[d]);let l=So(p,`tasks.${d}`);if(!s[l])throw Oe(`tasks.${d} references an unknown model profile.`,[l]);c[d]=l}}return{version:1,providers:i,models:s,tasks:c,source:"file",sourcePath:t}}var ei={version:1,providers:{gw:{protocol:"openai-compatible",baseUrl:null,apiKeyEnv:"PROJECT_LITELLM_GATEWAY_API_KEY",timeoutMs:3e5,maxAttempts:3},"gw-anthropic":{protocol:"anthropic",baseUrl:null,apiKeyEnv:"PROJECT_LITELLM_GATEWAY_API_KEY",timeoutMs:3e5,maxAttempts:3},"google-gemini":{protocol:"google-vertex",baseUrl:null,apiKeyEnv:"",timeoutMs:6e5,maxAttempts:3},nnyyai:{protocol:"google-gemini",baseUrl:"https://api.nnyyai.com",apiKeyEnv:"NNYYAI_API_KEY",timeoutMs:6e5,maxAttempts:3,videoResponseSchemaField:"responseSchema",videoUploadMode:"base64",documentResponseSchemaField:"responseSchema",documentUploadMode:"base64"}},models:{default:{provider:"gw",model:"deepseek-v4-flash-packy",temperature:0},"ingest-low":{provider:"gw",model:"deepseek-v4-flash-packy",temperature:0},"ingest-normalize":{provider:"gw",model:"claude-sonnet-4-6-aihubmix",temperature:0},"ingest-video":{provider:"nnyyai",model:"gemini-3.8-flash"},"ingest-comic":{provider:"nnyyai",model:"gemini-3.8-flash"},"review-text":{provider:"google-gemini",model:"gemini-3.8-flash",temperature:0},"review-comic":{provider:"nnyyai",model:"gemini-3.8-flash",temperature:0},"review-agent":{provider:"google-gemini",model:"gemini-3.8-flash",temperature:0},reskin:{provider:"google-gemini",model:"gemini-3.8-flash"},"reskin-claude":{provider:"gw-anthropic",model:"claude-opus-5-5-nnyy-offical"}},tasks:{"ingest.body-start":"ingest-low","ingest.arc-summary":"ingest-low","ingest.text-normalize":"ingest-low","ingest.mention-resolve":"ingest-low","ingest.asset-recall":"ingest-low","ingest.asset-audit":"ingest-normalize","ingest.episode-assets":"ingest-normalize","ingest.name-fix":"ingest-normalize","ingest.video-serial":"ingest-video","ingest.comic-serial":"ingest-comic"},source:"builtin",sourcePath:null};function qE(){let e=(process.env.PROJECT_LITELLM_GATEWAY_BASE_URL??"").trim(),t=e?Ud(e,"PROJECT_LITELLM_GATEWAY_BASE_URL"):null;return{...ei,providers:{gw:{...ei.providers.gw,baseUrl:t},"gw-anthropic":{...ei.providers["gw-anthropic"],baseUrl:t?t.replace(/\/v1\/?$/,""):null},"google-gemini":{...ei.providers["google-gemini"]},nnyyai:{...ei.providers.nnyyai}},models:{...ei.models},tasks:{...ei.tasks}}}function ZE(){let e=(process.env.XDG_CONFIG_HOME??"").trim();return e?Gr.join(e,"scriptctl","llm.yaml"):Gr.join(kf.homedir(),".config","scriptctl","llm.yaml")}function Nd(e){if(!Jr.existsSync(e))throw Oe("LLM configuration file does not exist.",[e]);let t=BE(Jr.readFileSync(e,"utf-8"),{uniqueKeys:!0});if(t.errors.length>0)throw Oe("LLM configuration YAML is invalid.",t.errors.map(o=>o.message));let n=t.toJS();return YE(n,Gr.resolve(e))}function Io(e){let t=(e??"").trim();if(t)return Nd(t);let n=(process.env.SCRIPTCTL_LLM_CONFIG??"").trim();if(n)return Nd(n);let o=ZE();return Jr.existsSync(o)?Nd(o):qE()}import*as Df from"node:crypto";import*as Gf from"node:fs";import ex,{APIConnectionError as tx,APIConnectionTimeoutError as nx,APIError as ox,APIUserAbortError as ix}from"@anthropic-ai/sdk";var Cd=1e8;function WE(e){switch(e){case"auth":return{failure_type:"authentication",failure_code:"authentication_failed"};case"permission_denied":return{failure_type:"authorization",failure_code:"permission_denied"};case"endpoint":return{failure_type:"provider",failure_code:"resource_not_found"};case"network":return{failure_type:"network",failure_code:"network_failed"};case"timeout":return{failure_type:"timeout",failure_code:"request_timeout"};case"rate_limited":return{failure_type:"rate_limit",failure_code:"rate_limited"};case"request_failed":return{failure_type:"provider",failure_code:"request_rejected"};case"truncated":return{failure_type:"response",failure_code:"output_truncated"};case"content_filtered":return{failure_type:"policy",failure_code:"content_blocked"};case"empty_response":return{failure_type:"response",failure_code:"empty_response"};case"invalid_response":return{failure_type:"response",failure_code:"malformed_response"};case"cancelled":return{failure_type:"cancelled",failure_code:"cancelled"}}}var T=class extends Error{code;retryable;details;failure;modelFailures;attempts;usage;constructor(t,n,o={}){super(n),this.name="LlmTransportError",this.code=t,this.retryable=o.retryable??!1,this.details=o.details??[],this.attempts=o.attempts??1,this.usage=o.usage??{},this.failure=Ut(o.classification??WE(t),{retryable:this.retryable,message:n,...o.context,...this.details.length>0?{details:this.details}:{}}),this.modelFailures=o.modelFailures??[]}};function XE(e){return new Promise(t=>setTimeout(t,e))}function Xt(e={},t={}){let n=c=>e[c]===void 0&&t[c]===void 0?void 0:(e[c]??0)+(t[c]??0),o=n("inputTokens"),i=n("outputTokens"),r=n("cachedInputTokens"),s=n("cacheCreationTokens");return{...o!==void 0?{inputTokens:o}:{},...i!==void 0?{outputTokens:i}:{},...r!==void 0?{cachedInputTokens:r}:{},...s!==void 0?{cacheCreationTokens:s}:{}}}async function en(e,t){let n={};for(let o=1;o<=e;o+=1)try{return{value:await t(),attempts:o,failedUsage:n}}catch(i){if(i instanceof T&&(n=Xt(n,i.usage),i.attempts=o,i.usage=n),!(i instanceof T)||!i.retryable||o===e)throw i;await XE(Math.min(3e4,1e3*2**(o-1)))}throw new Error("unreachable retry state")}function bf(e){let t=e.usage;if(!t)return{};let n=t.cache_read_input_tokens??0,o=t.cache_creation_input_tokens??0;return{inputTokens:(t.input_tokens??0)+n+o,outputTokens:t.output_tokens??0,cachedInputTokens:n,cacheCreationTokens:o}}function Of(e){if(e instanceof T)return e;if(e instanceof ix)return new T("request_failed","Anthropic request was aborted.");if(e instanceof nx)return new T("timeout","Anthropic request timed out.",{retryable:!0});if(e instanceof tx)return new T("request_failed","Anthropic connection failed.",{retryable:!0,details:[e.message.slice(0,500)]});if(e instanceof ox){let n=e.status??0,o=n===408||n===429||n>=500,i=n===401||n===403?"auth":n===429?"rate_limited":"request_failed";return new T(i,"Anthropic request failed.",{retryable:o,details:[`status: ${n}`,e.message.slice(0,500)]})}let t=e instanceof Error?e.message:String(e);return new T("request_failed","Anthropic request failed.",{details:[t.slice(0,500)]})}var Zs=class{constructor(t,n,o){this.provider=t;this.model=n;let i={apiKey:o};t.baseUrl&&(i.baseURL=t.baseUrl),this.client=new ex({...i,maxRetries:0})}provider;model;client;params(t){let n={model:this.model.model,max_tokens:t.maxOutputTokens,stream:!1,messages:[{role:"user",content:t.user}]};return t.system.trim()&&(n.system=t.system),this.model.thinkingBudgetTokens!==void 0&&(n.thinking={type:"enabled",budget_tokens:this.model.thinkingBudgetTokens}),n}async generateText(t){let n=await en(this.provider.maxAttempts,async()=>{try{let o=await this.client.messages.create(this.params(t),{timeout:this.provider.timeoutMs,signal:t.signal}),i=bf(o);if(o.stop_reason==="max_tokens")throw new T("truncated","Provider output was truncated.",{usage:i});if(o.stop_reason==="refusal")throw new T("content_filtered","Provider filtered the response.",{usage:i});let r=o.content.filter(s=>s.type==="text").map(s=>s.text).join(`
|
|
144
|
+
`)}function _f(e){let t=e._args??[],n=t[0]?.trim()??"",o=String(e.from??"").trim(),i=String(e.to??"").trim(),r=!!e.unreleased;if(t.length>1)throw new S("changelog accepts at most one version argument.",{exitCode:J,errorCode:"CHANGELOG_TOO_MANY_ARGS",hint:"Pass a single version, or use --from/--to for a range.",data:{expected:["scriptctl changelog [version] [--from X] [--to Y] [--unreleased]"],actual:[t.join(" ")]}});if(r&&(n||o||i))throw new S("--unreleased cannot combine with version, --from, or --to.",{exitCode:J,errorCode:"CHANGELOG_SELECTOR_CONFLICT",hint:"Run `scriptctl changelog --unreleased` by itself.",data:{expected:["either --unreleased, a version, or a --from/--to range"],actual:["--unreleased with another selector"]}});if(n&&(o||i))throw new S("A version argument cannot combine with --from or --to.",{exitCode:J,errorCode:"CHANGELOG_SELECTOR_CONFLICT",hint:"Run `scriptctl changelog 0.25.10` or `scriptctl changelog --from 0.25.8 --to 0.25.10`.",data:{expected:["either a version argument, or --from/--to"],actual:[n,o?`--from ${o}`:"",i?`--to ${i}`:""].filter(Boolean)}});if(r){let d=Ys(PE);return[{text:d,data:{content:d,versions:[],unreleased:!0}},B]}let s=TE(),c=CE();if(n){if(Dr(n),!s.includes(n))throw kd(n,s);let d=Ys(n);return[{text:d,data:{content:d,versions:[n],unreleased:!1}},B]}if(o||i){if(!o)throw new S("--from is required for range queries.",{exitCode:J,errorCode:"CHANGELOG_FROM_MISSING",hint:"Run `scriptctl changelog --from 0.25.8 --to 0.25.10`.",data:{expected:["--from <x.y.z>"],actual:[i?`--to ${i}`:"<missing>"]}});Dr(o);let d=i||c;if(Dr(d),!s.includes(d))throw kd(d,s);let p=s.filter(f=>bd(f,o)>0&&bd(f,d)<=0);if(p.length===0)throw VE(o,d);let l=$E(p);return[{text:l,data:{content:l,versions:p,from:o,to:d,unreleased:!1}},B]}if(!s.includes(c))throw kd(c,s);let a=Ys(c);return[{text:a,data:{content:a,versions:[c],unreleased:!1}},B]}import*as Bt from"node:fs";import*as ii from"node:path";import{createRequire as Bx}from"node:module";import*as Hn from"node:fs";import*as Eo from"node:path";import*as xf from"node:os";import{fileURLToPath as DE}from"node:url";function Ef(e){return e.startsWith("~")?Eo.join(xf.homedir(),e.slice(1)):e}function GE(e){let t=Hn.readFileSync(e,"utf-8");for(let n of t.split(/\r?\n/)){let o=n.trim();if(!o||o.startsWith("#"))continue;o.startsWith("export ")&&(o=o.slice(7).trim());let i=o.indexOf("=");if(i<0)continue;let r=o.slice(0,i).trim(),s=o.slice(i+1).trim();s.length>=2&&s[0]===s[s.length-1]&&(s[0]==="'"||s[0]==='"')&&(s=s.slice(1,-1)),r&&s&&!process.env[r]&&(process.env[r]=s)}}function vd(){let e=[],t=(process.env.SCRIPTCTL_ENV_FILE??"").trim();t&&e.push(Ef(t));let n=(process.env.SCRIPTCTL_SKILL_DIR??"").trim();n&&e.push(Eo.join(Ef(n),".env"));let o;try{o=DE(import.meta.url)}catch{o=process.cwd()}let i=Eo.resolve(o),r=new Set;for(;;){let s=Eo.dirname(i);if(s===i||r.has(s))break;r.add(s),e.push(Eo.join(s,".env")),i=s}return e}function Sf(){let e=process.env.SCRIPTCTL_NO_DOTENV;if(e==="1"||e==="true"||e==="True")return;let t=new Set;for(let n of vd()){let o;try{o=Hn.existsSync(n)?Hn.realpathSync(n):n}catch{o=n}t.has(o)||!Hn.existsSync(n)||!Hn.statSync(n).isFile()||(t.add(o),GE(n))}}var me=class extends Error{status;code;payload;configMissing;constructor(t,n={}){super(t),this.name="ScriptOutputApiError",this.status=n.status??null,this.code=n.code??null,this.payload=n.payload,this.configMissing=n.configMissing??null}};async function Rd(e,t){if(e.updateEpisodeCount)try{await e.updateEpisodeCount(t)}catch{}}function If(e){let t=!!e?.remote,n=!!e?.local;if(t&&n)return{mode:null,conflict:!0};if(t)return{mode:"remote",conflict:!1};if(n)return{mode:"local",conflict:!1};let o=(process.env.SCRIPTCTL_OUTPUT_MODE??"").trim().toLowerCase();if(o==="local"||o==="remote")return{mode:o,conflict:!1};if(o!=="")return{mode:null,conflict:!1};let i=typeof e?.projectGroupNo=="string"?e.projectGroupNo.trim():"",r=(process.env.SANDBOX_PROJECT_GROUP_NO??"").trim();return i!==""||r!==""?{mode:"remote",conflict:!1}:{mode:null,conflict:!1}}import*as Jr from"node:fs";import*as kf from"node:os";import*as Gr from"node:path";import{parseDocument as BE}from"yaml";function ae(e,t,n){return{id:e,mode:t,version:"1",maxOutputTokens:n,defaultProfile:"default"}}var An={"direct.episode-titles":ae("direct.episode-titles","tool",4096),"direct.batch-extract":ae("direct.batch-extract","text",16e3),"direct.episode-synopsis":ae("direct.episode-synopsis","tool",2048),"direct.synopsis-reduction":ae("direct.synopsis-reduction","tool",4096),"direct.script-synopsis":ae("direct.script-synopsis","tool",2048),"direct.asset-grouping":ae("direct.asset-grouping","text",8e3),"direct.asset-curation":ae("direct.asset-curation","text",2e4),"direct.asset-curation-audit":ae("direct.asset-curation-audit","text",2e4),"direct.location-canonicalization":ae("direct.location-canonicalization","text",2e4),"direct.state-curation":ae("direct.state-curation","text",2e4),"direct.state-binding":ae("direct.state-binding","tool",16e3),"metadata.global":ae("metadata.global","text",16e3),"metadata.descriptions":ae("metadata.descriptions","text",16e3),"synopsis.chunk":ae("synopsis.chunk","text",4096),"synopsis.episode":ae("synopsis.episode","text",4096),"synopsis.arc":ae("synopsis.arc","text",16e3),"synopsis.script-overview":ae("synopsis.script-overview","text",16e3),"ingest.body-start":ae("ingest.body-start","text",16e3),"ingest.arc-summary":ae("ingest.arc-summary","text",4096),"ingest.text-normalize":ae("ingest.text-normalize","text",32e3),"ingest.episode-assets":ae("ingest.episode-assets","tool",32e3),"ingest.name-fix":ae("ingest.name-fix","tool",16e3),"ingest.mention-resolve":ae("ingest.mention-resolve","text",8e3),"ingest.asset-extract":ae("ingest.asset-extract","text",8e3),"ingest.asset-curate":ae("ingest.asset-curate","text",32e3),"ingest.asset-recall":ae("ingest.asset-recall","text",65536),"ingest.asset-refine":ae("ingest.asset-refine","text",32e3),"ingest.state-reconcile":ae("ingest.state-reconcile","text",32e3),"ingest.asset-audit":ae("ingest.asset-audit","tool",32e3),"ingest.speaker-audit":ae("ingest.speaker-audit","tool",16e3),"ingest.comic-serial":{id:"ingest.comic-serial",mode:"document",version:"1",defaultProfile:"default"},"ingest.video-serial":ae("ingest.video-serial","video",65536)},Af=Object.keys(An).filter(Md);function Md(e){return Object.hasOwn(An,e)}var JE=new Set(["protocol","baseUrl","apiKey","timeoutMs","maxAttempts","videoResponseSchemaField","videoUploadMode","documentResponseSchemaField","documentUploadMode"]),jE=new Set(["provider","model","thinking","reasoning","temperature","fallbacks"]),KE=new Set(["env"]),zE=new Set(["budgetTokens"]);function Oe(e,t=[]){return new S(e,{exitCode:k,errorCode:"LLM_CONFIG_INVALID",hint:"Fix the selected LLM configuration or environment and rerun `scriptctl doctor`.",data:{expected:["valid scriptctl LLM YAML configuration"],actual:t}})}function Ud(e,t){let n;try{n=new URL(e)}catch{throw Oe(`${t} must be an absolute URL.`)}if(n.protocol!=="http:"&&n.protocol!=="https:")throw Oe(`${t} must use http or https.`);return n.toString().replace(/\/$/,"")}function Pd(e,t="provider base URL"){return Ud(e,t)}function HE(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function xo(e,t){if(!HE(e))throw Oe(`${t} must be a mapping.`,[`${t}: ${typeof e}`]);return e}function So(e,t){if(typeof e!="string"||!e.trim())throw Oe(`${t} must be a non-empty string.`);return e.trim()}function Ld(e,t,n,o){if(!Number.isInteger(e)||typeof e!="number"||e<n||o!==void 0&&e>o)throw Oe(`${t} must be an integer in ${o===void 0?`[${n}, +\u221E)`:`[${n}, ${o}]`}.`);return e}function Br(e,t,n){let o=Object.keys(e).filter(i=>!t.has(i));if(o.length>0)throw Oe(`${n} contains unknown fields.`,o)}function FE(e,t){let n=xo(t,`providers.${e}`);Br(n,JE,`providers.${e}`);let o=So(n.protocol,`providers.${e}.protocol`);if(o!=="anthropic"&&o!=="openai-compatible"&&o!=="google-gemini"&&o!=="google-vertex")throw Oe(`providers.${e}.protocol is unsupported.`,[o]);let i=n.baseUrl===void 0&&o!=="openai-compatible"?null:Ud(So(n.baseUrl,`providers.${e}.baseUrl`),`providers.${e}.baseUrl`),r="";if(o!=="google-vertex"){let c=xo(n.apiKey,`providers.${e}.apiKey`);if(Br(c,KE,`providers.${e}.apiKey`),r=So(c.env,`providers.${e}.apiKey.env`),!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r))throw Oe(`providers.${e}.apiKey.env must be an environment variable name.`)}let s={protocol:o,baseUrl:i,apiKeyEnv:r,timeoutMs:Ld(n.timeoutMs,`providers.${e}.timeoutMs`,1),maxAttempts:Ld(n.maxAttempts,`providers.${e}.maxAttempts`,1,6)};for(let c of["videoResponseSchemaField","documentResponseSchemaField"]){let a=n[c];if(a!==void 0){if(o!=="google-gemini"&&o!=="google-vertex")throw Oe(`providers.${e}.${c} requires a Gemini ${c.startsWith("video")?"video":"document"} provider.`);if(a!=="responseJsonSchema"&&a!=="responseSchema")throw Oe(`providers.${e}.${c} must be responseJsonSchema or responseSchema.`);s[c]=a}}for(let c of["videoUploadMode","documentUploadMode"]){let a=n[c];if(a!==void 0){if(o!=="google-gemini"&&o!=="google-vertex")throw Oe(`providers.${e}.${c} requires a Gemini ${c.startsWith("video")?"video":"document"} provider.`);if(a!=="file-api"&&a!=="base64")throw Oe(`providers.${e}.${c} must be file-api or base64.`);s[c]=a}}return s}function QE(e,t,n){let o=xo(t,`models.${e}`);Br(o,jE,`models.${e}`);let i=So(o.provider,`models.${e}.provider`),r=n[i];if(!r)throw Oe(`models.${e} references an unknown provider.`,[i]);let s={provider:i,model:So(o.model,`models.${e}.model`)};if(o.reasoning!==void 0&&(s.reasoning=So(o.reasoning,`models.${e}.reasoning`)),o.fallbacks!==void 0){let c=o.fallbacks;if(!Array.isArray(c))throw Oe(`models.${e}.fallbacks must be a list of model profiles.`);s.fallbacks=c.map((a,d)=>So(a,`models.${e}.fallbacks[${d}]`))}if(o.temperature!==void 0){let c=o.temperature;if(typeof c!="number"||!Number.isFinite(c)||c<0)throw Oe(`models.${e}.temperature must be a number \u2265 0.`);s.temperature=c}if(o.thinking!==void 0){if(r.protocol!=="anthropic")throw Oe(`models.${e}.thinking is only valid for anthropic providers.`);let c=xo(o.thinking,`models.${e}.thinking`);Br(c,zE,`models.${e}.thinking`),s.thinkingBudgetTokens=Ld(c.budgetTokens,`models.${e}.thinking.budgetTokens`,1024)}return s}function YE(e,t){let n=xo(e,"config");if(Br(n,new Set(["version","providers","models","tasks"]),"config"),n.version!==1)throw Oe("config.version must be 1.");let o=xo(n.providers,"providers"),i={};for(let[a,d]of Object.entries(o))i[a]=FE(a,d);let r=xo(n.models,"models"),s={};for(let[a,d]of Object.entries(r))s[a]=QE(a,d,i);if(!s.default)throw Oe("models.default is required.");for(let[a,d]of Object.entries(s))for(let p of d.fallbacks??[])if(!s[p]||p===a)throw Oe(`models.${a}.fallbacks references an unknown or the same profile.`,[p]);let c={};if(n.tasks!==void 0){let a=xo(n.tasks,"tasks");for(let[d,p]of Object.entries(a)){if(!Md(d))throw Oe("tasks contains an unknown task id.",[d]);let l=So(p,`tasks.${d}`);if(!s[l])throw Oe(`tasks.${d} references an unknown model profile.`,[l]);c[d]=l}}return{version:1,providers:i,models:s,tasks:c,source:"file",sourcePath:t}}var ei={version:1,providers:{gw:{protocol:"openai-compatible",baseUrl:null,apiKeyEnv:"PROJECT_LITELLM_GATEWAY_API_KEY",timeoutMs:3e5,maxAttempts:3},"gw-anthropic":{protocol:"anthropic",baseUrl:null,apiKeyEnv:"PROJECT_LITELLM_GATEWAY_API_KEY",timeoutMs:3e5,maxAttempts:3},"google-gemini":{protocol:"google-vertex",baseUrl:null,apiKeyEnv:"",timeoutMs:6e5,maxAttempts:3},nnyyai:{protocol:"google-gemini",baseUrl:"https://api.nnyyai.com",apiKeyEnv:"NNYYAI_API_KEY",timeoutMs:6e5,maxAttempts:3,videoResponseSchemaField:"responseSchema",videoUploadMode:"base64",documentResponseSchemaField:"responseSchema",documentUploadMode:"base64"}},models:{default:{provider:"gw",model:"deepseek-v4-flash-packy",temperature:0},synopsis:{provider:"gw",model:"deepseek-v4.1-flash-huoshan",temperature:0},"ingest-low":{provider:"gw",model:"deepseek-v4-flash-packy",temperature:0},"ingest-normalize":{provider:"gw",model:"claude-sonnet-4-6-aihubmix",temperature:0},"ingest-video":{provider:"nnyyai",model:"gemini-3.8-flash"},"ingest-comic":{provider:"nnyyai",model:"gemini-3.8-flash"},"review-text":{provider:"google-gemini",model:"gemini-3.8-flash",temperature:0},"review-comic":{provider:"nnyyai",model:"gemini-3.8-flash",temperature:0},"review-agent":{provider:"google-gemini",model:"gemini-3.8-flash",temperature:0},reskin:{provider:"google-gemini",model:"gemini-3.8-flash"},"reskin-claude":{provider:"gw-anthropic",model:"claude-opus-5-5-nnyy-offical"}},tasks:{"synopsis.chunk":"synopsis","synopsis.episode":"synopsis","synopsis.arc":"synopsis","synopsis.script-overview":"synopsis","ingest.body-start":"ingest-low","ingest.arc-summary":"ingest-low","ingest.text-normalize":"ingest-low","ingest.mention-resolve":"ingest-low","ingest.asset-recall":"ingest-low","ingest.asset-audit":"ingest-normalize","ingest.episode-assets":"ingest-normalize","ingest.name-fix":"ingest-normalize","ingest.video-serial":"ingest-video","ingest.comic-serial":"ingest-comic"},source:"builtin",sourcePath:null};function qE(){let e=(process.env.PROJECT_LITELLM_GATEWAY_BASE_URL??"").trim(),t=e?Ud(e,"PROJECT_LITELLM_GATEWAY_BASE_URL"):null;return{...ei,providers:{gw:{...ei.providers.gw,baseUrl:t},"gw-anthropic":{...ei.providers["gw-anthropic"],baseUrl:t?t.replace(/\/v1\/?$/,""):null},"google-gemini":{...ei.providers["google-gemini"]},nnyyai:{...ei.providers.nnyyai}},models:{...ei.models},tasks:{...ei.tasks}}}function ZE(){let e=(process.env.XDG_CONFIG_HOME??"").trim();return e?Gr.join(e,"scriptctl","llm.yaml"):Gr.join(kf.homedir(),".config","scriptctl","llm.yaml")}function Nd(e){if(!Jr.existsSync(e))throw Oe("LLM configuration file does not exist.",[e]);let t=BE(Jr.readFileSync(e,"utf-8"),{uniqueKeys:!0});if(t.errors.length>0)throw Oe("LLM configuration YAML is invalid.",t.errors.map(o=>o.message));let n=t.toJS();return YE(n,Gr.resolve(e))}function Io(e){let t=(e??"").trim();if(t)return Nd(t);let n=(process.env.SCRIPTCTL_LLM_CONFIG??"").trim();if(n)return Nd(n);let o=ZE();return Jr.existsSync(o)?Nd(o):qE()}import*as Df from"node:crypto";import*as Gf from"node:fs";import ex,{APIConnectionError as tx,APIConnectionTimeoutError as nx,APIError as ox,APIUserAbortError as ix}from"@anthropic-ai/sdk";var Cd=1e8;function WE(e){switch(e){case"auth":return{failure_type:"authentication",failure_code:"authentication_failed"};case"permission_denied":return{failure_type:"authorization",failure_code:"permission_denied"};case"endpoint":return{failure_type:"provider",failure_code:"resource_not_found"};case"network":return{failure_type:"network",failure_code:"network_failed"};case"timeout":return{failure_type:"timeout",failure_code:"request_timeout"};case"rate_limited":return{failure_type:"rate_limit",failure_code:"rate_limited"};case"request_failed":return{failure_type:"provider",failure_code:"request_rejected"};case"truncated":return{failure_type:"response",failure_code:"output_truncated"};case"content_filtered":return{failure_type:"policy",failure_code:"content_blocked"};case"empty_response":return{failure_type:"response",failure_code:"empty_response"};case"invalid_response":return{failure_type:"response",failure_code:"malformed_response"};case"cancelled":return{failure_type:"cancelled",failure_code:"cancelled"}}}var T=class extends Error{code;retryable;details;failure;modelFailures;attempts;usage;constructor(t,n,o={}){super(n),this.name="LlmTransportError",this.code=t,this.retryable=o.retryable??!1,this.details=o.details??[],this.attempts=o.attempts??1,this.usage=o.usage??{},this.failure=Ut(o.classification??WE(t),{retryable:this.retryable,message:n,...o.context,...this.details.length>0?{details:this.details}:{}}),this.modelFailures=o.modelFailures??[]}};function XE(e){return new Promise(t=>setTimeout(t,e))}function Xt(e={},t={}){let n=c=>e[c]===void 0&&t[c]===void 0?void 0:(e[c]??0)+(t[c]??0),o=n("inputTokens"),i=n("outputTokens"),r=n("cachedInputTokens"),s=n("cacheCreationTokens");return{...o!==void 0?{inputTokens:o}:{},...i!==void 0?{outputTokens:i}:{},...r!==void 0?{cachedInputTokens:r}:{},...s!==void 0?{cacheCreationTokens:s}:{}}}async function en(e,t){let n={};for(let o=1;o<=e;o+=1)try{return{value:await t(),attempts:o,failedUsage:n}}catch(i){if(i instanceof T&&(n=Xt(n,i.usage),i.attempts=o,i.usage=n),!(i instanceof T)||!i.retryable||o===e)throw i;await XE(Math.min(3e4,1e3*2**(o-1)))}throw new Error("unreachable retry state")}function bf(e){let t=e.usage;if(!t)return{};let n=t.cache_read_input_tokens??0,o=t.cache_creation_input_tokens??0;return{inputTokens:(t.input_tokens??0)+n+o,outputTokens:t.output_tokens??0,cachedInputTokens:n,cacheCreationTokens:o}}function Of(e){if(e instanceof T)return e;if(e instanceof ix)return new T("request_failed","Anthropic request was aborted.");if(e instanceof nx)return new T("timeout","Anthropic request timed out.",{retryable:!0});if(e instanceof tx)return new T("request_failed","Anthropic connection failed.",{retryable:!0,details:[e.message.slice(0,500)]});if(e instanceof ox){let n=e.status??0,o=n===408||n===429||n>=500,i=n===401||n===403?"auth":n===429?"rate_limited":"request_failed";return new T(i,"Anthropic request failed.",{retryable:o,details:[`status: ${n}`,e.message.slice(0,500)]})}let t=e instanceof Error?e.message:String(e);return new T("request_failed","Anthropic request failed.",{details:[t.slice(0,500)]})}var Zs=class{constructor(t,n,o){this.provider=t;this.model=n;let i={apiKey:o};t.baseUrl&&(i.baseURL=t.baseUrl),this.client=new ex({...i,maxRetries:0})}provider;model;client;params(t){let n={model:this.model.model,max_tokens:t.maxOutputTokens,stream:!1,messages:[{role:"user",content:t.user}]};return t.system.trim()&&(n.system=t.system),this.model.thinkingBudgetTokens!==void 0&&(n.thinking={type:"enabled",budget_tokens:this.model.thinkingBudgetTokens}),n}async generateText(t){let n=await en(this.provider.maxAttempts,async()=>{try{let o=await this.client.messages.create(this.params(t),{timeout:this.provider.timeoutMs,signal:t.signal}),i=bf(o);if(o.stop_reason==="max_tokens")throw new T("truncated","Provider output was truncated.",{usage:i});if(o.stop_reason==="refusal")throw new T("content_filtered","Provider filtered the response.",{usage:i});let r=o.content.filter(s=>s.type==="text").map(s=>s.text).join(`
|
|
145
145
|
`).trim();if(!r)throw new T("empty_response","Provider returned an empty text response.",{usage:i});return{text:r,finishReason:o.stop_reason??"",usage:i,raw:o}}catch(o){throw Of(o)}});return{...n.value,attempts:n.attempts,usage:Xt(n.failedUsage,n.value.usage)}}async generateTool(t){let n=await en(this.provider.maxAttempts,async()=>{try{let o={name:t.tool.name,description:t.tool.description,input_schema:{type:"object",...t.tool.inputSchema}},i=await this.client.messages.create({...this.params(t),tools:[o],tool_choice:{type:"tool",name:t.tool.name,disable_parallel_tool_use:!0}},{timeout:this.provider.timeoutMs,signal:t.signal}),r=bf(i);if(i.stop_reason==="max_tokens")throw new T("truncated","Provider tool output was truncated.",{usage:r});if(i.stop_reason==="refusal")throw new T("content_filtered","Provider filtered the response.",{usage:r});let s=i.content.find(c=>c.type==="tool_use"&&c.name===t.tool.name);if(!s||s.type!=="tool_use")throw new T("invalid_response","Provider did not return the required tool call.",{usage:r});return{input:s.input,finishReason:i.stop_reason??"",usage:r,raw:i}}catch(o){throw Of(o)}});return{...n.value,attempts:n.attempts,usage:Xt(n.failedUsage,n.value.usage)}}};import*as Dd from"node:fs";import*as Gd from"node:path";import{File as px}from"node:buffer";import{Agent as lx,fetch as Xs,FormData as ux}from"undici";function rx(e){return typeof e=="object"&&e!==null}function Td(e){let t=[],n=new Set,o=e;for(;rx(o)&&!n.has(o);)n.add(o),t.push(o),o=o.cause;return t}function Ws(e){for(let t of Td(e)){if(typeof t.status=="number")return t.status;if(typeof t.statusCode=="number")return t.statusCode}return null}function sx(e){for(let t of Td(e))if(typeof t.code=="string")return t.code}function ax(e){for(let t of Td(e))if(typeof t.name=="string")return t.name}function cx(e){let t=ax(e);return t==="AbortError"||t==="TimeoutError"||t==="RequestTimeoutError"||t==="APIConnectionTimeoutError"}function dx(e){return e?["ENOTFOUND","EAI_AGAIN"].includes(e)?{failure_type:"network",failure_code:"dns_failed"}:e==="ECONNREFUSED"?{failure_type:"network",failure_code:"connection_refused"}:["ECONNRESET","EPIPE","UND_ERR_SOCKET"].includes(e)?{failure_type:"network",failure_code:"connection_reset"}:["ENETUNREACH","EHOSTUNREACH"].includes(e)?{failure_type:"network",failure_code:"network_unreachable"}:e.startsWith("ERR_TLS_")||e.startsWith("ERR_SSL_")||e.startsWith("CERT_")||["DEPTH_ZERO_SELF_SIGNED_CERT","SELF_SIGNED_CERT_IN_CHAIN","UNABLE_TO_VERIFY_LEAF_SIGNATURE"].includes(e)?{failure_type:"network",failure_code:"tls_failed"}:["ETIMEDOUT","UND_ERR_CONNECT_TIMEOUT"].includes(e)?{failure_type:"timeout",failure_code:"connect_timeout"}:{failure_type:"network",failure_code:"network_failed"}:{failure_type:"network",failure_code:"network_failed"}}function ti(e,t,n,o,i={}){if(t?.aborted)return new T("cancelled",n,{details:[o],classification:{failure_type:"cancelled",failure_code:"cancelled"},context:i});let r=sx(e),s=cx(e)?{failure_type:"timeout",failure_code:"request_timeout"}:dx(r),c=s.failure_type==="timeout"?"timeout":"network";return new T(c,n,{retryable:!0,details:[o],classification:s,context:{...i,...r?{system_code:r}:{}}})}function ni(e,t,n,o={}){let i,r,s=!1;return e===401?(i="auth",r={failure_type:"authentication",failure_code:"authentication_failed"}):e===403?(i="permission_denied",r={failure_type:"authorization",failure_code:"permission_denied"}):e===404?(i="endpoint",r={failure_type:"provider",failure_code:"resource_not_found"}):e===408?(i="timeout",r={failure_type:"timeout",failure_code:"request_timeout"},s=!0):e===413&&o.operation==="upload"?(i="request_failed",r={failure_type:"media",failure_code:"media_too_large"}):e===415&&o.operation==="upload"?(i="request_failed",r={failure_type:"media",failure_code:"unsupported_media"}):e===429?(i="rate_limited",r={failure_type:"rate_limit",failure_code:"rate_limited"},s=!0):e>=500?(i="request_failed",r={failure_type:"provider",failure_code:"provider_unavailable"},s=!0):o.operation==="upload"?(i="request_failed",r={failure_type:"media",failure_code:"media_upload_failed"}):(i="request_failed",r={failure_type:"provider",failure_code:"request_rejected"}),new T(i,t,{retryable:s,details:[`status: ${e}`,n],classification:r,context:{...o,http_status:e}})}var fx=2e3;function mx(e){return new Promise(t=>setTimeout(t,e))}function Vd(e,t,n,o){if(e instanceof T)return e;let i=e instanceof Error?e.message:String(e),r=Ws(e),s={provider:"doubao",model:o,operation:n};return r!==null?ni(r,`Doubao ${n} failed.`,i.slice(0,500),s):ti(e,t,`Doubao ${n} failed.`,i.slice(0,500),s)}function gx(e){if(!e)return{};let t=n=>typeof n=="number"?n:void 0;return{inputTokens:t(e.input_tokens),outputTokens:t(e.output_tokens)}}function hx(e){let t=[];for(let n of e.output??[])if(n.type==="message")for(let o of n.content??[])o.type==="output_text"&&typeof o.text=="string"&&t.push(o.text);return t.join("").trim()}var ea=class{constructor(t,n,o,i,r,s){this.model=t;this.timeoutMs=n;this.maxAttempts=o;this.client=s??yx(i,r,n)}model;timeoutMs;maxAttempts;client;async run(t){let{value:n}=await en(this.maxAttempts,async()=>{try{return await this.client.uploadFile({filePath:t.localPath,mimeType:t.localMime,fps:t.fps})}catch(i){throw Vd(i,t.signal,"upload",this.model)}});if(!n.id)throw new T("invalid_response","Doubao upload returned no file id.");let o=await this.pollActive(n.id,t.signal);try{return await this.generateOnce(o,t)}finally{await this.client.deleteFile({id:o}).catch(()=>{})}}async pollActive(t,n){let o=Date.now()+this.timeoutMs,i="processing";for(;i==="processing"||i==="";){if(n?.aborted)throw new T("cancelled","Doubao upload aborted.",{context:{provider:"doubao",model:this.model,operation:"file_poll"}});if(Date.now()>=o)throw new T("timeout","Doubao file processing timed out.",{retryable:!0,classification:{failure_type:"timeout",failure_code:"media_processing_timeout"},context:{provider:"doubao",model:this.model,operation:"file_poll"}});await mx(fx);let r;try{r=await this.client.getFile({id:t})}catch(s){throw Vd(s,n,"file_poll",this.model)}i=(r.status??"").toLowerCase()}if(i==="failed"||i==="error")throw new T("invalid_response","Doubao file processing failed.",{classification:{failure_type:"media",failure_code:"media_processing_failed"},context:{provider:"doubao",model:this.model,operation:"file_poll"}});return t}async generateOnce(t,n){let o={model:this.model,input:[{role:"user",content:[{type:"input_video",file_id:t},{type:"input_text",text:n.user}]}]};return n.system?.trim()&&(o.instructions=n.system),n.responseJsonSchema&&(o.text={format:{type:"json_schema",name:"video_serial",schema:n.responseJsonSchema}}),this.generateResponse(o,n.signal,!!n.responseJsonSchema,n.acceptsText)}async generateText(t){let n=this.textParams(t);return t.responseFormat&&(n.text={format:{type:t.responseFormat}}),this.generateResponse(n,t.signal,!!t.responseFormat)}async generateDocument(t,n){let o=t.media.kind==="base64"?t.media.data:n?Dd.readFileSync(n).toString("base64"):void 0;if(!o)throw new T("invalid_response","Doubao PDF recovery requires the original document bytes.");let i={model:this.model,input:[{role:"user",content:[{type:"input_file",filename:n?Gd.basename(n):"document.pdf",file_data:`data:application/pdf;base64,${o}`},{type:"input_text",text:t.user}]}]};return t.system?.trim()&&(i.instructions=t.system),t.responseJsonSchema&&(i.text={format:{type:"json_schema",name:"document",schema:t.responseJsonSchema}}),this.generateResponse(i,t.signal,!!t.responseJsonSchema)}async generateTool(t){let n=this.textParams(t);n.text={format:{type:"json_schema",name:t.tool.name,description:t.tool.description,schema:t.tool.inputSchema}};let o=await this.generateResponse(n,t.signal,!0);return{input:JSON.parse(o.text),finishReason:o.finishReason,attempts:o.attempts,usage:o.usage,raw:o.raw}}textParams(t){return{model:this.model,instructions:t.system,input:[{role:"user",content:[{type:"input_text",text:t.user}]}]}}async generateResponse(t,n,o,i){let{value:r,attempts:s,failedUsage:c}=await en(this.maxAttempts,async()=>{let a;try{a=await this.client.createResponse(t,n)}catch(f){throw Vd(f,n,"generate",this.model)}let d=(a.status??"").toLowerCase(),p=gx(a.usage);if(d==="incomplete"){let f=a.incomplete_details?.reason??"unknown";throw f==="max_output_tokens"||f==="length"?new T("truncated","Doubao output was truncated.",{usage:p}):new T("content_filtered",`Doubao response incomplete (reason=${f}).`,{usage:p})}let l=hx(a);if(!l)throw new T("empty_response","Doubao returned an empty response.",{retryable:!0,usage:p});if(i&&!i(l))throw new T("invalid_response","Doubao response does not match the requested output format.",{retryable:!0,usage:p,context:{provider:"doubao",model:this.model,operation:"generate"}});if(o)try{JSON.parse(l)}catch{throw new T("invalid_response","Doubao returned malformed JSON for a structured response.",{retryable:!0,usage:p,context:{provider:"doubao",model:this.model,operation:"generate"}})}return{text:l,usage:p,raw:a}});return{text:r.text,finishReason:"STOP",attempts:s,usage:Xt(c,r.usage),raw:r.raw}}},$d=class extends Error{constructor(n,o){super(o);this.status=n;this.name="HttpError"}status};function yx(e,t,n){let o=t.replace(/\/$/,""),i={Authorization:`Bearer ${e}`},r=new lx({headersTimeout:n,bodyTimeout:n});function s(a){let d=AbortSignal.timeout(n);return a?AbortSignal.any([a,d]):d}async function c(a){let d=await a.text().catch(()=>"");throw new $d(a.status,d.slice(0,500))}return{async uploadFile({filePath:a,mimeType:d,fps:p}){let l=new ux,f=Dd.readFileSync(a);l.append("file",new px([f],Gd.basename(a),{type:d})),l.append("purpose","user_data"),l.append("preprocess_configs[video][fps]",String(p));let u=await Xs(`${o}/files`,{method:"POST",headers:i,body:l,signal:s(),dispatcher:r});return u.ok||await c(u),await u.json()},async getFile({id:a}){let d=await Xs(`${o}/files/${a}`,{headers:i,signal:s(),dispatcher:r});return d.ok||await c(d),await d.json()},async createResponse(a,d){let p=await Xs(`${o}/responses`,{method:"POST",headers:{...i,"Content-Type":"application/json"},body:JSON.stringify(a),signal:s(d),dispatcher:r});return p.ok||await c(p),await p.json()},async deleteFile({id:a}){let d=await Xs(`${o}/files/${a}`,{method:"DELETE",headers:i,signal:s(),dispatcher:r});d.ok||await c(d)}}}import{GoogleAuth as wx}from"google-auth-library";function ta(){let e=process.env.GOOGLE_CLOUD_PROJECT?.trim();if(!e)throw new Error("GOOGLE_CLOUD_PROJECT is required for official Vertex AI");return e}var vf=new wx({scopes:["https://www.googleapis.com/auth/cloud-platform"]});import*as Uf from"node:fs";import{createRequire as bx}from"node:module";import*as na from"node:fs";import*as _x from"node:http";import*as Ex from"node:https";import{HttpsProxyAgent as xx}from"https-proxy-agent";var Mf="https://generativelanguage.googleapis.com";function Sx(e,t){let n=new URL(e??Mf);return n.pathname=`${n.pathname.replace(/\/+$/,"")}/upload/v1beta/files`,n.searchParams.set("key",t),n}function Ix(e,t){let n=new URL(t??Mf),o=new URL(e,n);if(!t)return o;o.protocol=n.protocol,o.host=n.host;let i=n.pathname.replace(/\/+$/,"");return i&&o.pathname!==i&&!o.pathname.startsWith(`${i}/`)&&(o.pathname=`${i}/${o.pathname.replace(/^\/+/,"")}`),o}function Ki(e,t){if(!t)return e;let n=e.split(t).join("[REDACTED]"),o=encodeURIComponent(t);return o!==t&&(n=n.split(o).join("[REDACTED]")),n}function Ax(e){return e?new xx(e):void 0}function Rf(e,t,n,o){return new Promise((i,r)=>{let c=(e.protocol==="http:"?_x:Ex).request({...t,agent:e.protocol==="https:"?t.agent:void 0,protocol:e.protocol,hostname:e.hostname,port:e.port||void 0,path:`${e.pathname}${e.search}`},a=>{let d="";a.on("data",p=>d+=p),a.on("end",()=>i({status:a.statusCode??0,headers:a.headers,body:d}))});if(c.on("error",r),o){if(o.aborted){c.destroy(new Error("aborted"));return}o.addEventListener("abort",()=>c.destroy(new Error("aborted")),{once:!0})}n&&typeof n.pipe=="function"?n.pipe(c):(n&&c.write(n),c.end())})}function kx(e,t){let n=e[t];return Array.isArray(n)?n[0]??"":n??""}async function Nf(e){let t=na.statSync(e.filePath).size,o={agent:Ax(e.proxyUrl??""),timeout:e.timeoutMs},i=Sx(e.baseUrl,e.apiKey),r=l=>Ki(l,e.apiKey),s;try{s=await Rf(i,{...o,method:"POST",headers:{"X-Goog-Upload-Protocol":"resumable","X-Goog-Upload-Command":"start","X-Goog-Upload-Header-Content-Length":String(t),"X-Goog-Upload-Header-Content-Type":e.mimeType,"Content-Type":"application/json"}},JSON.stringify({file:{}}),e.signal)}catch(l){let f=r(l instanceof Error?l.message:String(l));throw ti(l,e.signal,"Gemini upload start failed.",f,{operation:"upload"})}let c=kx(s.headers,"x-goog-upload-url");if(s.status<200||s.status>=300)throw ni(s.status,"Gemini upload start failed.",r(s.body).slice(0,300),{operation:"upload"});if(!c)throw new T("invalid_response","Gemini upload start returned no upload URL.",{details:[r(s.body).slice(0,300)],context:{operation:"upload",http_status:s.status}});let a=Ix(c,e.baseUrl),d;try{d=await Rf(a,{...o,method:"POST",headers:{"Content-Length":String(t),"X-Goog-Upload-Offset":"0","X-Goog-Upload-Command":"upload, finalize"}},na.createReadStream(e.filePath),e.signal)}catch(l){let f=r(l instanceof Error?l.message:String(l));throw ti(l,e.signal,"Gemini upload transfer failed.",f,{operation:"upload"})}if(d.status<200||d.status>=300)throw ni(d.status,"Gemini upload transfer failed.",r(d.body).slice(0,300),{operation:"upload"});let p;try{p=JSON.parse(d.body)}catch{throw new T("invalid_response","Gemini upload returned invalid JSON.",{details:[r(d.body).slice(0,300)]})}if(!p.file)throw new T("invalid_response","Gemini upload returned no file.",{details:[r(d.body).slice(0,300)]});return p.file}var Ox=new Set(["SAFETY","PROHIBITED_CONTENT","RECITATION","BLOCKLIST","SPII","IMAGE_SAFETY","IMAGE_PROHIBITED_CONTENT","IMAGE_RECITATION","ESCALATION"]),vx=new Set(["LANGUAGE","OTHER","MALFORMED_FUNCTION_CALL","IMAGE_OTHER","NO_IMAGE","UNEXPECTED_TOOL_CALL","TOO_MANY_TOOL_CALLS","MISSING_THOUGHT_SIGNATURE","MALFORMED_RESPONSE"]);function Bd(e){switch(e){case"SAFETY":case"PROHIBITED_CONTENT":case"BLOCKLIST":case"SPII":case"RECITATION":case"IMAGE_SAFETY":case"IMAGE_PROHIBITED_CONTENT":case"IMAGE_RECITATION":case"ESCALATION":case"OTHER":return e;case"":case"BLOCK_REASON_UNSPECIFIED":case"FINISH_REASON_UNSPECIFIED":return"UNSPECIFIED";default:return"UNKNOWN"}}function Lf(e){if(e?.length)return e.map(t=>({category:t.category??"UNSPECIFIED",probability:t.probability??"UNSPECIFIED",blocked:t.blocked??!1}))}function Rx(e){if(typeof e!="object"||e===null)return{};let t=e,n=o=>typeof o=="number"?o:void 0;return{inputTokens:n(t.promptTokenCount),outputTokens:n(t.candidatesTokenCount)}}function Mx(e){return/-c\d+$/.test(e)}function Nx(e){let t=e.indexOf("{"),n=e.lastIndexOf("}");if(t<0||n<t)throw new SyntaxError("JSON object not found");return e.slice(t,n+1)}var Lx=2e3;function Ux(e){return new Promise(t=>setTimeout(t,e))}function Jd(e,t,n,o,i,r){if(e instanceof T)return new T(e.code,Ki(e.message,o),{retryable:e.retryable,details:e.details.map(d=>Ki(d,o)),attempts:e.attempts,usage:e.usage,classification:Ni(e.failure),context:{...Sr(e.failure),provider:i,model:r,operation:n},modelFailures:e.modelFailures});let s=Ki(e instanceof Error?e.message:String(e),o),c=Ws(e),a={provider:i,model:r,operation:n};return c!==null?ni(c,`Gemini ${n} failed.`,s.slice(0,500),a):ti(e,t,`Gemini ${n} failed.`,s.slice(0,500),a)}var zi=class{constructor(t,n,o,i){this.provider=t;this.model=n;this.apiKey=o;this.client=i??Cx(o,t.timeoutMs,t.baseUrl,t.protocol==="google-vertex")}provider;model;apiKey;client;async prepare(t,n,o,i){return o==="base64"||this.provider.protocol==="google-vertex"?{kind:"base64",data:Uf.readFileSync(t,"base64"),mimeType:n}:{kind:"file-api",file:await this.uploadFile(t,n,i)}}async uploadFile(t,n,o){let{value:i}=await en(this.provider.maxAttempts,async()=>{try{return await this.client.files.upload({file:t,config:{mimeType:n}})}catch(s){throw Jd(s,o,"upload",this.apiKey,this.model.provider,this.model.model)}}),r=await this.pollActive(i,o);if(!r.name||!r.uri)throw new T("invalid_response","Gemini upload returned no file reference.",{context:{provider:this.model.provider,model:this.model.model,operation:"upload"}});return{name:r.name,uri:r.uri,mimeType:r.mimeType??n}}async pollActive(t,n){let o=t,i=Date.now()+this.provider.timeoutMs;for(;(o.state??"").toUpperCase()==="PROCESSING";){if(n?.aborted)throw new T("cancelled","Gemini upload aborted.",{context:{provider:this.model.provider,model:this.model.model,operation:"file_poll"}});if(Date.now()>=i)throw new T("timeout","Gemini file processing timed out.",{retryable:!0,classification:{failure_type:"timeout",failure_code:"media_processing_timeout"},context:{provider:this.model.provider,model:this.model.model,operation:"file_poll"}});if(await Ux(Lx),!o.name)throw new T("invalid_response","Gemini upload returned no file name to poll.",{context:{provider:this.model.provider,model:this.model.model,operation:"file_poll"}});try{o=await this.client.files.get({name:o.name})}catch(r){throw Jd(r,n,"file_poll",this.apiKey,this.model.provider,this.model.model)}}if((o.state??"").toUpperCase()==="FAILED")throw new T("invalid_response","Gemini file processing failed.",{details:[Ki(o.error?.message??"unknown media error",this.apiKey)],classification:{failure_type:"media",failure_code:"media_processing_failed"},context:{provider:this.model.provider,model:this.model.model,operation:"file_poll"}});return o}async generateMedia(t,n){let o=!!t.responseJsonSchema&&Mx(this.model.model),i={mediaResolution:"MEDIA_RESOLUTION_HIGH"},r=[t.system?.trim(),o?`\u8F93\u51FA\u5FC5\u987B\u662F\u4E00\u4E2A\u53EF\u89E3\u6790\u7684 JSON \u5BF9\u8C61\u3002\u53EA\u8FD4\u56DE JSON\uFF0C\u4E0D\u8981\u8F93\u51FA\u4EFB\u4F55\u989D\u5916\u6587\u5B57\u6216 Markdown \u4EE3\u7801\u5757\u3002
|
|
146
146
|
\u4EE5\u4E0B\u662F\u5B8C\u6574\u8F93\u51FA JSON Schema\u3002\u4E25\u683C\u9075\u5B88\u6240\u6709\u5C42\u7EA7\u7684\u5B57\u6BB5\u540D\u3001\u7C7B\u578B\u3001required\u3001\u679A\u4E3E\u3001\u683C\u5F0F\u7EA6\u675F\u548C description\uFF1B\u4E0D\u5F97\u81EA\u884C\u6539\u540D\u6216\u7701\u7565\u5FC5\u586B\u5B57\u6BB5\u3002\u8FD4\u56DE\u7B26\u5408\u8BE5\u5B9A\u4E49\u7684\u6570\u636E\u5BF9\u8C61\uFF0C\u4E0D\u8981\u8FD4\u56DE schema \u672C\u8EAB\u3002
|
|
147
147
|
<output_json_schema>
|
package/dist/cli.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a,b}from"./chunk-
|
|
1
|
+
import{a,b}from"./chunk-LT747D45.js";export{a as buildProgram,b as main};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ name: scriptctl
|
|
|
3
3
|
description: "剧本 script.json 的本地阅读、定位、原子修改、整场整集回写、素材 ingest 与 revision publish CLI。处理 Script v3/v4、剧本资产与 state、Action、场景引用或视频证据核对时使用。"
|
|
4
4
|
metadata:
|
|
5
5
|
version: "0.32.0"
|
|
6
|
-
scriptctl_version: "0.65.
|
|
6
|
+
scriptctl_version: "0.65.4"
|
|
7
7
|
author: "official"
|
|
8
8
|
---
|
|
9
9
|
|