@tikagent/video-editor-cli 1.5.0-preview.4 → 1.5.0-preview.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- "use strict";const e=require("fs"),r=require("os"),o=require("path"),t=require("http"),n=require("https"),{spawn:s,spawnSync:i}=require("./processes"),{Transform:a}=require("stream"),{pipeline:c}=require("stream/promises"),{extractZip:u}=require("./browser-zip"),l="153.0.8010.52",w=["S-1-15-3-1024-3424233489-972189580-2057154623-747635277-1604371224-316187997-3786583170-1043257646","S-1-15-3-1024-2302894289-466761758-1166120688-1039016420-2430351297-4240214049-4028510897-3317428798"];function m(){return o.join(process.env.SystemRoot||"C:\\Windows","System32","icacls.exe")}function d(r){try{if(!e.statSync(r).isFile())return!1}catch{return!1}const o=i(m(),[r],{encoding:"utf8",timeout:3e4});if(o.error||0!==o.status)return!1;const t=`${o.stdout||""}${o.stderr||""}`.replace(/\s+/g,"");return w.every(e=>t.includes(e))}function p(e){for(const r of w){const o=i(m(),[e,"/grant",`*${r}:(OI)(CI)(RX)`,"/C","/Q"],{encoding:"utf8",timeout:12e4});if(o.error||0!==o.status){const e=`${o.stdout||""}${o.stderr||""}`.trim()||o.error?.message||"icacls failed";throw new Error("Could not grant Chrome sandbox access: "+e)}}}async function h(r,o,t,n){if(!await n(o)&&(await t(r),e.existsSync(o)&&!await n(o)))throw new Error("Chrome sandbox access was not applied to the browser executable")}function f(e=process.platform,r=process.arch){return{"darwin-arm64":"mac-arm64","darwin-x64":"mac-x64","linux-x64":"linux64","linux-arm64":"linux-arm64","win32-x64":"win64","win32-ia32":"win32"}[`${e}-${r}`]}function y(e){return o.join("chrome-"+e,e.startsWith("mac-")?"Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing":e.startsWith("win")?"chrome.exe":"chrome")}function g(r){try{return!!e.statSync(r).isFile()&&(e.accessSync(r,"win32"===process.platform?e.constants.F_OK:e.constants.X_OK),!0)}catch{return!1}}function b(e){if(o.isAbsolute(e)||/[/\\]/.test(e))return g(o.resolve(e))?o.resolve(e):null;for(const r of(process.env.PATH||"").split(o.delimiter).filter(Boolean))for(const t of"win32"===process.platform?["",".exe"]:[""]){const n=o.resolve(r,e+t);if(g(n))return n}return null}function x(){return["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Chromium.app/Contents/MacOS/Chromium",...[process.env.PROGRAMFILES,process.env["PROGRAMFILES(X86)"],process.env.LOCALAPPDATA].filter(Boolean).map(e=>o.join(e,"Google/Chrome/Application/chrome.exe")),"google-chrome","google-chrome-stable","chromium","chromium-browser","chrome"]}async function C(r,o,t){const s=new AbortController,i=setTimeout(()=>s.abort(),9e5);try{const i=await async function e(r,o=0){const t=new URL(r);if("https:"!==t.protocol||t.username||t.password)throw new Error("Browser downloads require an HTTPS URL without credentials");return new Promise((r,i)=>{const a=n.get(t,{signal:s.signal,timeout:3e4},n=>{if(n.on("error",i),[301,302,303,307,308].includes(n.statusCode)){if(n.resume(),!n.headers.location||o>=5)return i(new Error("Too many browser download redirects"));try{r(e(new URL(n.headers.location,t),o+1))}catch(e){i(e)}}else 200!==n.statusCode?(n.resume(),i(new Error(`Browser download returned HTTP ${n.statusCode}`))):r(n)});a.on("timeout",()=>a.destroy(new Error("Browser download timed out"))),a.on("error",i)})}(r),u=Number(i.headers["content-length"]||0);let l=0,w=Date.now();const m=new a({transform(e,r,o){if(l+=e.length,l>536870912)return o(new Error("Browser download exceeds 512 MiB"));Date.now()-w>2e3&&(t(`Downloading browser: ${Math.round(l/1048576)}${u?"/"+Math.round(u/1048576):""} MiB`),w=Date.now()),o(null,e)}});if(await c(i,m,e.createWriteStream(o,{flags:"wx"}),{signal:s.signal}),!l||u&&l!==u)throw new Error("Incomplete browser download")}finally{clearTimeout(i),s.abort()}}async function S(n){const i=e.mkdtempSync(o.join(r.tmpdir(),"tik-browser-check-")),a=require("crypto").randomBytes(16).toString("hex");let c,u,l,w,m="";const d=new Promise(e=>{w=e}),p=t.createServer((e,r)=>{e.url==="/"+a?(r.writeHead(200,{"Content-Type":"text/html"}),r.end(`<script>fetch("/${a}/ready")<\/script>`)):e.url===`/${a}/ready`?(r.end("ok"),w()):(r.writeHead(404),r.end())});try{await new Promise((e,r)=>{p.once("error",r),p.listen(0,"127.0.0.1",e)}),c=s(n,["--headless=new","--no-first-run","--no-default-browser-check",..."darwin"===process.platform?["--use-mock-keychain"]:[],"--user-data-dir="+i,`http://127.0.0.1:${p.address().port}/${a}`],{stdio:["ignore","ignore","pipe"],windowsHide:!0}),u=new Promise(e=>c.once("close",e)),c.stderr.on("data",e=>{m=(m+e).slice(-600)}),await Promise.race([d,new Promise((e,r)=>{c.once("error",r),c.once("close",e=>r(new Error(`Chrome exited (${e})`))),l=setTimeout(()=>r(new Error("Chrome startup timed out")),3e4)})])}catch(e){throw new Error(`Downloaded Chrome could not run: ${e.message}. Check OS compatibility and, on Linux, required system libraries. ${m}`)}finally{if(clearTimeout(l),c&&null===c.exitCode&&null===c.signalCode){c.kill();const e=setTimeout(()=>c.kill("SIGKILL"),3e3);await u,clearTimeout(e)}p.closeAllConnections?.(),await new Promise(e=>p.close(e)),e.rmSync(i,{recursive:!0,force:!0})}}function E(e,r){try{require("./telemetry").reportError("BrowserSetupFailed",e,r)}catch{}}module.exports={ensureBrowser:async function(t,{cacheRoot:n=o.join(r.homedir(),".tik-video-editor-cli","browsers"),env:s=process.env,platform:i=process.platform,arch:a=process.arch,candidates:c=x(),download:w=C,verify:m=S,grantSandboxAccess:A=p,sandboxGranted:$=d,log:T=e=>process.stderr.write(e+"\n")}={}){const R=t||s.CHROME_PATH;if(R){const e=b(R);if(!e){const e=new Error("Browser is not executable: "+R+"; fix --browser / CHROME_PATH or unset it for automatic setup");throw E(e,{source:"explicit"}),e}return e}const B=f(i,a),O=B&&o.join(n,l,B),v=B&&o.join(O,y(B)),P=()=>{try{return g(v)&&e.readFileSync(o.join(O,".complete"),"utf8")===l}catch{return!1}};if(B&&P()){if("win32"===i)try{await h(O,v,A,$)}catch(e){throw E(e,{source:"sandbox-access",platform:B}),new Error(`Automatic browser setup failed: ${e.message}. Retry export, set FABLECUT_BROWSER_DOWNLOAD_BASE_URL to a trusted HTTPS mirror, or use --browser <path>.`)}return v}for(const e of c){const r=b(e);if(r)return r}if(!B)throw new Error(`Automatic browser setup is unavailable on ${i}/${a}; pass --browser <path> or set CHROME_PATH`);const L=`${(s.FABLECUT_BROWSER_DOWNLOAD_BASE_URL||"https://cdn.npmmirror.com/binaries/chrome-for-testing").replace(/\/+$/,"")}/${l}/${B}/chrome-${B}.zip`,_=o.dirname(O);await e.promises.mkdir(_,{recursive:!0});const k=await e.promises.mkdtemp(o.join(_,".install-"));try{T(`Preparing Chrome for Testing ${l} (${B}); this download is cached for future exports.`);const r=o.join(k,"browser.zip"),t=o.join(k,"unpacked");await w(L,r,T),await e.promises.mkdir(t),"win32"===i&&await h(t,o.join(t,y(B)),A,$),T("Extracting browser…"),await u(r,t);const n=o.join(t,y(B));if(!g(n))throw new Error("Browser archive is missing its executable");if("win32"===i&&await h(t,n,A,$),await m(n),await e.promises.writeFile(o.join(t,".complete"),l),!P())try{await e.promises.rename(t,O)}catch(e){if(!P())throw new Error(`${e.message}; remove the incomplete cache at ${O} and retry`)}return T("Browser ready."),v}catch(e){throw E(e,{source:"download",platform:B}),new Error(`Automatic browser setup failed: ${e.message}. Retry export, set FABLECUT_BROWSER_DOWNLOAD_BASE_URL to a trusted HTTPS mirror, or use --browser <path>.`)}finally{await e.promises.rm(k,{recursive:!0,force:!0})}},downloadArchive:C,verifyBrowser:S,platformKey:f,executable:y,VERSION:l,chromeSandboxSids:w};
1
+ "use strict";const e=require("fs"),r=require("os"),t=require("path"),n=require("http"),o=require("https"),{spawn:i,spawnSync:s}=require("./processes"),{Transform:a}=require("stream"),{pipeline:c}=require("stream/promises"),{extractZip:l}=require("./browser-zip"),u="153.0.8010.52",d=["S-1-15-3-1024-3424233489-972189580-2057154623-747635277-1604371224-316187997-3786583170-1043257646","S-1-15-3-1024-2302894289-466761758-1166120688-1039016420-2430351297-4240214049-4028510897-3317428798"];function m(){return t.join(process.env.SystemRoot||"C:\\Windows","System32","icacls.exe")}function f(r){try{if(!e.statSync(r).isFile())return!1}catch{return!1}const t=s(m(),[r],{encoding:"utf8",timeout:3e4});if(t.error||0!==t.status)return!1;const n=`${t.stdout||""}${t.stderr||""}`.replace(/\s+/g,"");return d.every(e=>n.includes(e))}function p(e){for(const r of d){const t=s(m(),[e,"/grant",`*${r}:(OI)(CI)(RX)`,"/C","/Q"],{encoding:"utf8",timeout:12e4});if(t.error||0!==t.status){const e=`${t.stdout||""}${t.stderr||""}`.trim()||t.error?.message||"icacls failed";throw new Error("Could not grant Chrome sandbox access: "+e)}}}async function w(r,t,n,o){if(!await o(t)&&(await n(r),e.existsSync(t)&&!await o(t)))throw new Error("Chrome sandbox access was not applied to the browser executable")}function h(e=process.platform,r=process.arch){return{"darwin-arm64":"mac-arm64","darwin-x64":"mac-x64","linux-x64":"linux64","linux-arm64":"linux-arm64","win32-x64":"win64","win32-ia32":"win32"}[`${e}-${r}`]}function g(e){return t.join("chrome-"+e,e.startsWith("mac-")?"Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing":e.startsWith("win")?"chrome.exe":"chrome")}function y(r){try{return!!e.statSync(r).isFile()&&(e.accessSync(r,"win32"===process.platform?e.constants.F_OK:e.constants.X_OK),!0)}catch{return!1}}function E(e){if(t.isAbsolute(e)||/[/\\]/.test(e))return y(t.resolve(e))?t.resolve(e):null;for(const r of(process.env.PATH||"").split(t.delimiter).filter(Boolean))for(const n of"win32"===process.platform?["",".exe"]:[""]){const o=t.resolve(r,e+n);if(y(o))return o}return null}function S(e){return[process.env.PROGRAMFILES,process.env["PROGRAMFILES(X86)"],process.env.LOCALAPPDATA].filter(Boolean).flatMap(r=>e.map(e=>t.join(r,e)))}function A(){return[["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge","/Applications/Chromium.app/Contents/MacOS/Chromium",...S(["Google/Chrome/Application/chrome.exe","Microsoft/Edge/Application/msedge.exe","Chromium/Application/chrome.exe"]),"google-chrome","google-chrome-stable","microsoft-edge","microsoft-edge-stable","msedge","chromium","chromium-browser","chrome"],["/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta","/Applications/Microsoft Edge Beta.app/Contents/MacOS/Microsoft Edge Beta",...S(["Google/Chrome Beta/Application/chrome.exe","Microsoft/Edge Beta/Application/msedge.exe"]),"google-chrome-beta","microsoft-edge-beta"],["/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev","/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev",...S(["Google/Chrome Dev/Application/chrome.exe","Microsoft/Edge Dev/Application/msedge.exe"]),"google-chrome-unstable","microsoft-edge-dev"]]}function C(e){const r=String(e??"").match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);return r?[r[1],r[2],r[3],r[4]].map(Number):null}function x(e){const r=String(e??"").match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);return r?[r[1],r[2],r[3],r[4]].map(Number):null}function b(e,r){if(!e&&!r)return 0;if(!e)return-1;if(!r)return 1;for(let t=0;t<4;t++){const n=(e[t]||0)-(r[t]||0);if(n)return n}return 0}function L(r,t,n,o){if(t<0||n<=0||t>o||t+n>o)return null;const i=Buffer.alloc(n);return e.readSync(r,i,0,n,t)!==n?null:i}function v(e,r){for(const t of r){const r=Math.max(t.virtualSize,t.rawSize);if(t.rawPointer>0&&r>0&&e>=t.virtualAddress&&e<t.virtualAddress+r)return t.rawPointer+(e-t.virtualAddress)}return null}function B(e,r,t,n,o){if(o<0||o+16>t)return null;const i=L(e,r+o,16,n);if(!i)return null;const s=i.readUInt16LE(12),a=i.readUInt16LE(14),c=s+a;if(c<1||c>512||o+16+8*c>t)return null;const l=L(e,r+o+16,8*c,n);return l?{named:s,ids:a,entries:l}:null}function $(e,r){return e.entries.readUInt32LE(8*r+4)}function I(e){return s(e,["--version"],{encoding:"utf8",timeout:2e3,windowsHide:!0})}function U(e,r){if(!r&&"win32"===process.platform)return null;try{const t=(r||I)(e);return!t||t.error?null:C(`${t.stdout||""}\n${t.stderr||""}`)}catch{return null}}function M(r){try{return function(r){const n=t.join(t.dirname(r),t.basename(r,t.extname(r))+".VisualElementsManifest.xml");try{return C(e.readFileSync(n,"utf8"))}catch{return null}}(r)||function(r){let n;try{n=e.readdirSync(t.dirname(r),{withFileTypes:!0})}catch{return null}let o=null;for(const e of n){if(!e.isDirectory())continue;const r=x(e.name);b(r,o)>0&&(o=r)}return o}(r)||function(r){try{const n=e.readFileSync(t.join(t.dirname(r),"..","Info.plist"),"utf8").match(/<key>\s*CFBundleShortVersionString\s*<\/key>\s*<string>\s*([^<]+?)\s*<\/string>/);return n?C(n[1]):null}catch{return null}}(r)||function(r){let t;try{const n=e.statSync(r);if(!n.isFile()||n.size<128||n.size>536870912)return null;t=e.openSync(r,"r");const o=L(t,0,64,n.size);if(!o||23117!==o.readUInt16LE(0))return null;const i=o.readUInt32LE(60),s=L(t,i,24,n.size);if(!s||17744!==s.readUInt32LE(0))return null;const a=s.readUInt16LE(6),c=s.readUInt16LE(20);if(a<1||a>96||c<96||c>1024)return null;const l=L(t,i+24,c,n.size);if(!l)return null;const u=l.readUInt16LE(0),d=267===u?96:523===u?112:-1;if(d<0||l.length<d+24||l.readUInt32LE(d-4)<3)return null;const m=l.readUInt32LE(d+16),f=l.readUInt32LE(d+20);if(!m||!f||f>n.size)return null;const p=L(t,i+24+c,40*a,n.size);if(!p)return null;const w=[];for(let e=0;e<a;e++){const r=40*e;w.push({virtualSize:p.readUInt32LE(r+8),virtualAddress:p.readUInt32LE(r+12),rawSize:p.readUInt32LE(r+16),rawPointer:p.readUInt32LE(r+20)})}const h=v(m,w);if(null===h)return null;const g=B(t,h,f,n.size,0),y=g&&function(e){for(let r=0;r<e.ids;r++){const t=8*(e.named+r);if(16===e.entries.readUInt32LE(t))return e.entries.readUInt32LE(t+4)}return null}(g);if(null===y||!(2147483648&y))return null;const E=B(t,h,f,n.size,2147483647&y),S=E&&$(E,0);if(null===S||!(2147483648&S))return null;const A=B(t,h,f,n.size,2147483647&S),C=A&&$(A,0);if(null===C||2147483648&C||C+8>f)return null;const x=L(t,h+C,8,n.size);if(!x)return null;const b=x.readUInt32LE(4),I=v(x.readUInt32LE(0),w);return b&&null!==I?function(e){if(!e)return null;for(let r=0;r+16<=e.length;r+=4){if(4277077181!==e.readUInt32LE(r))continue;const t=e.readUInt32LE(r+8),n=e.readUInt32LE(r+12),o=[t>>>16,65535&t,n>>>16,65535&n];if(o.some(e=>e>0))return o}return null}(L(t,I,Math.min(b,4096),n.size)):null}catch{return null}finally{if(void 0!==t)try{e.closeSync(t)}catch{}}}(r)||U(r)}catch{return null}}function T(e){const r=t.resolve(e);return"win32"===process.platform?r.toLowerCase():r}function O(e,r){try{const t=e(r);return Array.isArray(t)&&t.length>=4?t.slice(0,4).map(Number):null}catch{return null}}function R(e,r){let t=e[0],n=O(r,t);for(let o=1;o<e.length;o++){const i=O(r,e[o]);b(i,n)>0&&(t=e[o],n=i)}return t}async function P(r,t,n){const i=new AbortController,s=setTimeout(()=>i.abort(),9e5);try{const s=await async function e(r,t=0){const n=new URL(r);if("https:"!==n.protocol||n.username||n.password)throw new Error("Browser downloads require an HTTPS URL without credentials");return new Promise((r,s)=>{const a=o.get(n,{signal:i.signal,timeout:3e4},o=>{if(o.on("error",s),[301,302,303,307,308].includes(o.statusCode)){if(o.resume(),!o.headers.location||t>=5)return s(new Error("Too many browser download redirects"));try{r(e(new URL(o.headers.location,n),t+1))}catch(e){s(e)}}else 200!==o.statusCode?(o.resume(),s(new Error(`Browser download returned HTTP ${o.statusCode}`))):r(o)});a.on("timeout",()=>a.destroy(new Error("Browser download timed out"))),a.on("error",s)})}(r),l=Number(s.headers["content-length"]||0);let u=0,d=Date.now();const m=new a({transform(e,r,t){if(u+=e.length,u>536870912)return t(new Error("Browser download exceeds 512 MiB"));Date.now()-d>2e3&&(n(`Downloading browser: ${Math.round(u/1048576)}${l?"/"+Math.round(l/1048576):""} MiB`),d=Date.now()),t(null,e)}});if(await c(s,m,e.createWriteStream(t,{flags:"wx"}),{signal:i.signal}),!u||l&&u!==l)throw new Error("Incomplete browser download")}finally{clearTimeout(s),i.abort()}}async function z(o){const s=e.mkdtempSync(t.join(r.tmpdir(),"tik-browser-check-")),a=require("crypto").randomBytes(16).toString("hex");let c,l,u,d,m="";const f=new Promise(e=>{d=e}),p=n.createServer((e,r)=>{e.url==="/"+a?(r.writeHead(200,{"Content-Type":"text/html"}),r.end(`<script>fetch("/${a}/ready")<\/script>`)):e.url===`/${a}/ready`?(r.end("ok"),d()):(r.writeHead(404),r.end())});try{await new Promise((e,r)=>{p.once("error",r),p.listen(0,"127.0.0.1",e)}),c=i(o,["--headless=new","--no-first-run","--no-default-browser-check",..."darwin"===process.platform?["--use-mock-keychain"]:[],"--user-data-dir="+s,`http://127.0.0.1:${p.address().port}/${a}`],{stdio:["ignore","ignore","pipe"],windowsHide:!0}),l=new Promise(e=>c.once("close",e)),c.stderr.on("data",e=>{m=(m+e).slice(-600)}),await Promise.race([f,new Promise((e,r)=>{c.once("error",r),c.once("close",e=>r(new Error(`Chrome exited (${e})`))),u=setTimeout(()=>r(new Error("Chrome startup timed out")),3e4)})])}catch(e){throw new Error(`Downloaded Chrome could not run: ${e.message}. Check OS compatibility and, on Linux, required system libraries. ${m}`)}finally{if(clearTimeout(u),c&&null===c.exitCode&&null===c.signalCode){c.kill();const e=setTimeout(()=>c.kill("SIGKILL"),3e3);await l,clearTimeout(e)}p.closeAllConnections?.(),await new Promise(e=>p.close(e)),e.rmSync(s,{recursive:!0,force:!0})}}function D(e,r){try{require("./telemetry").reportError("BrowserSetupFailed",e,r)}catch{}}module.exports={ensureBrowser:async function(n,{cacheRoot:o=t.join(r.homedir(),".tik-video-editor-cli","browsers"),env:i=process.env,platform:s=process.platform,arch:a=process.arch,candidates:c=A(),download:d=P,verify:m=z,grantSandboxAccess:S=p,sandboxGranted:C=f,versionOf:x=M,log:b=e=>process.stderr.write(e+"\n")}={}){const L=n||i.CHROME_PATH;if(L){const e=E(L);if(!e){const e=new Error("Browser is not executable: "+L+"; fix --browser / CHROME_PATH or unset it for automatic setup");throw D(e,{source:"explicit"}),e}return e}const v=function(e,r){for(const t of e){if(!Array.isArray(t))continue;const e=new Set,n=[];for(const r of t){if("string"!=typeof r||!r)continue;const t=E(r);if(!t)continue;const o=T(t);e.has(o)||(e.add(o),n.push(t))}if(1===n.length)return n[0];if(n.length>1)return R(n,r)}return null}(function(e){return Array.isArray(e)?e.length&&Array.isArray(e[0])?e:e.length?[e]:[]:A()}(c),x);if(v)return v;const B=h(s,a),$=B&&t.join(o,u,B),I=B&&t.join($,g(B)),U=()=>{try{return y(I)&&e.readFileSync(t.join($,".complete"),"utf8")===u}catch{return!1}};if(B&&U()){if("win32"===s)try{await w($,I,S,C)}catch(e){throw D(e,{source:"sandbox-access",platform:B}),new Error(`Automatic browser setup failed: ${e.message}. Retry export, set FABLECUT_BROWSER_DOWNLOAD_BASE_URL to a trusted HTTPS mirror, or use --browser <path>.`)}return I}if(!B)throw new Error(`Automatic browser setup is unavailable on ${s}/${a}; pass --browser <path> or set CHROME_PATH`);const O=`${(i.FABLECUT_BROWSER_DOWNLOAD_BASE_URL||"https://cdn.npmmirror.com/binaries/chrome-for-testing").replace(/\/+$/,"")}/${u}/${B}/chrome-${B}.zip`,k=t.dirname($);await e.promises.mkdir(k,{recursive:!0});const F=await e.promises.mkdtemp(t.join(k,".install-"));try{b(`Preparing Chrome for Testing ${u} (${B}); this download is cached for future exports.`);const r=t.join(F,"browser.zip"),n=t.join(F,"unpacked");await d(O,r,b),await e.promises.mkdir(n),"win32"===s&&await w(n,t.join(n,g(B)),S,C),b("Extracting browser…"),await l(r,n);const o=t.join(n,g(B));if(!y(o))throw new Error("Browser archive is missing its executable");if("win32"===s&&await w(n,o,S,C),await m(o),await e.promises.writeFile(t.join(n,".complete"),u),!U())try{await e.promises.rename(n,$)}catch(e){if(!U())throw new Error(`${e.message}; remove the incomplete cache at ${$} and retry`)}return b("Browser ready."),I}catch(e){throw D(e,{source:"download",platform:B}),new Error(`Automatic browser setup failed: ${e.message}. Retry export, set FABLECUT_BROWSER_DOWNLOAD_BASE_URL to a trusted HTTPS mirror, or use --browser <path>.`)}finally{await e.promises.rm(F,{recursive:!0,force:!0})}},downloadArchive:P,verifyBrowser:z,platformKey:h,executable:g,VERSION:u,chromeSandboxSids:d,systemCandidateTiers:A,detectBrowserVersion:M,compareVersions:b,versionFromCommand:U};
@@ -2153,13 +2153,12 @@ body.file-drag::after {
2153
2153
  .cover-source .btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
2154
2154
  .cover-pencil { margin-bottom: 12px; }
2155
2155
 
2156
- /* 时间轴禁止滚动,轨道在区域中整体居中。 */
2157
- .timeline-scroll { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: clip; scrollbar-width: none; }
2156
+ /* 时间轴支持手动横向滚动,轨道在可用高度中整体居中。 */
2157
+ .timeline-scroll { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow-x: auto; overflow-y: hidden; }
2158
2158
  .timeline-scroll .ruler { flex: none; }
2159
2159
  .timeline-scroll .tracks-content { flex: 1; min-height: 0; padding-bottom: 0; display: flow-root; }
2160
2160
  .track-head { justify-content: center; }
2161
2161
  .timeline-sidebar:has(.cover-control[data-ui-visible]) { width: 152px; }
2162
- .timeline-scroll::-webkit-scrollbar { display: none; width: 0; height: 0; }
2163
2162
  .cover-delete { position: absolute; top: -6px; right: -6px; width: 18px; height: 18px; padding: 0; display: flex; align-items: center; justify-content: center; border: 1px solid var(--panel); border-radius: 50%; background: #e1e1e6; color: #29292e; font-size: 15px; line-height: 1; cursor: pointer; opacity: 0; pointer-events: none; }
2164
2163
  .cover-delete[hidden] { display: none; }
2165
2164
  .cover-control:hover .cover-delete, .cover-control:focus-within .cover-delete { opacity: 1; pointer-events: auto; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tikagent/video-editor-cli",
3
- "version": "1.5.0-preview.4",
3
+ "version": "1.5.0-preview.6",
4
4
  "description": "Local video editing, on-demand preview, and headless",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "commonjs",