@dlient-open/dev-tools 0.1.8 → 0.1.9

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/dist/worker.js CHANGED
@@ -5,7 +5,7 @@ const require = __dlientCreateRequire(import.meta.url);
5
5
  const __filename = __dlientFileURLToPath(import.meta.url);
6
6
  const __dirname = __dlientDirname(__filename);
7
7
 
8
- import{EventEmitter as rt}from"node:events";var ie="CMD_NPM";function it(e,t=!1){let n=Buffer.from(JSON.stringify(e),"utf-8");if(t)return Buffer.concat([n,Buffer.from(`
9
- `,"utf-8")]);let r=Buffer.alloc(4);return r.writeUInt32BE(n.length,0),Buffer.concat([r,n])}var ge=class{constructor(t,n){this.onMessage=n,this.buffer=Buffer.alloc(0),this.ndjson=t}push(t){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;if(this.buffer=this.buffer.length===0?n:Buffer.concat([this.buffer,n]),this.ndjson){let r;for(;(r=this.buffer.indexOf(10))>=0;){let i=this.buffer.subarray(0,r).toString("utf-8").trim();this.buffer=this.buffer.subarray(r+1),i&&this.tryParse(i)}return}for(;this.buffer.length>=4;){let r=this.buffer.readUInt32BE(0);if(this.buffer.length<4+r)break;let i=this.buffer.subarray(4,4+r).toString("utf-8");this.buffer=this.buffer.subarray(4+r),this.tryParse(i)}}tryParse(t){try{let n=JSON.parse(t);this.onMessage(n)}catch{}}};function st(e,t){return{write:n=>{e.stdin?.writable&&e.stdin.write(n)},end:()=>{try{e.stdin?.end()}catch{}},onStdout:n=>e.stdout?.on("data",r=>n(r.toString())),onExit:n=>e.on("exit",r=>n(r)),onError:n=>e.on("error",r=>n(r)),kill:()=>{if(t)try{t()}catch{}else try{e.kill()}catch{}}}}function ot(e){return{write:t=>{let n=typeof t=="string"?t:t.toString("utf8");e.write(n).catch(()=>{})},end:()=>{e.end().catch(()=>{})},onStdout:t=>e.onStdout(t),onExit:t=>e.onExit(n=>{t(n.code)}),onError:t=>e.onError(t),kill:()=>e.kill()}}function at(e){let{transport:t,proc:n,dispose:r,timeoutMs:i=3e4,heartbeatTimeoutMs:a=33e3,ndjson:o=!1}=e,c=(()=>{let D=t??(n?st(n,r):void 0);if(!D)throw new Error("createNativeHostClient: transport or proc required");return D})(),g=new rt,v=[],f=new Map,p=0,I=!1,y=new ge(o,D=>{_=Date.now();let C=D;if(C&&typeof C=="object"&&"ping"in C){R({pong:C.ping});return}if(C&&typeof C=="object"&&"event"in C){let P=C;g.emit(P.event,P.data);return}if(C&&typeof C=="object"&&"id"in C){let P=C,$=f.get(P.id);if(!$)return;if($.isStream){if(P.ok&&P.more){g.emit(`stream:${P.id}:data`,P.result);return}f.delete(P.id),$.timer&&clearTimeout($.timer),P.ok?$.resolve(P.result):$.reject(new Error(P.error??`native-host RPC failed: ${P.id}`));return}f.delete(P.id),$.timer&&clearTimeout($.timer),P.ok?$.resolve(P.result):$.reject(new Error(P.error??`native-host RPC failed: ${P.id}`))}});c.onStdout(D=>y.push(D));let R=D=>{I||c.write(it(D,o))},N=(D,C,P)=>{for(let[,$]of f)$.timer&&clearTimeout($.timer),$.reject(P);f.clear();for(let $ of v)try{$({code:C,reason:D})}catch{}};c.onExit(D=>{I||N("exit",D,new Error(`\u539F\u751F\u6A21\u5757\u8FDB\u7A0B\u5F02\u5E38\u9000\u51FA\uFF08code=${D??"unknown"}\uFF09\uFF0C\u8BF7\u91CD\u542F\u63D2\u4EF6`))}),c.onError(D=>{I||N("exit",null,new Error(`\u539F\u751F\u6A21\u5757\u8FDB\u7A0B\u542F\u52A8\u5931\u8D25: ${D.message}`))});let _=Date.now(),E=setInterval(()=>{I||Date.now()-_>a&&N("timeout",null,new Error("\u539F\u751F\u6A21\u5757\u8FDB\u7A0B\u5FC3\u8DF3\u8D85\u65F6\uFF08\u5931\u8054\uFF09\uFF0C\u8BF7\u91CD\u542F\u63D2\u4EF6"))},5e3);function G(D,C,P,$){return new Promise((K,O)=>{if(I)return O(new Error("native-host client disposed"));let z=`rpc-${++p}`,F={id:z,resolve:ne=>K(ne),reject:O,isStream:!1},X=$?.timeoutMs??i;X>0&&(F.timer=setTimeout(()=>{f.delete(z),O(new Error(`native-host RPC \u8D85\u65F6\uFF08${D}.${C} > ${X/1e3}s\uFF09`))},X)),f.set(z,F),R({id:z,service:D,method:C,params:P})})}function te(D,C,P){let $=`stream-${++p}`,K=[],O=[],z=[],F=`stream:${$}:data`,X={onData:j=>K.push(j),onDone:j=>O.push(j),onError:j=>z.push(j),abort:()=>{f.delete($),g.removeAllListeners(F)}},ne={id:$,resolve:j=>{for(let Y of O)try{Y(j)}catch{}g.removeAllListeners(F)},reject:j=>{for(let Y of z)try{Y(j)}catch{}g.removeAllListeners(F)},isStream:!0};return f.set($,ne),g.on(F,j=>{for(let Y of K)try{Y(j)}catch{}}),R({id:$,service:D,method:C,params:P}),X}function U(){if(I)return;I=!0,clearInterval(E),N("disposed",null,new Error("native-host client disposed"));try{c.end?.()}catch{}let D=c.kill();D&&typeof D.then=="function"&&D.catch(()=>{})}return{call:G,stream:te,onEvent:(D,C)=>g.on(D,C),onExit:D=>v.push(D),dispose:U}}function ct(e){let{backoffMs:t=300,maxBackoffMs:n=8e3,maxRestarts:r=10}=e,i=null,a,o=null,c=!1,g=!1,v=0,f=[],p=N=>new Promise(_=>setTimeout(_,N)),I=N=>{for(let _ of f)try{_(N)}catch{}};async function y(){if(c||g)return!1;try{let N=await e.spawn();return c||g?(N.dispose?.(),!1):(e.onRestarted&&await e.onRestarted(N.client),i=N.client,a=N.dispose,v=0,N.client.onExit(_=>{i=null,a=void 0,!c&&I({code:_.code,reason:_.reason==="disposed"?"disposed":_.reason==="timeout"?"timeout":"exit"})}),!0)}catch{if(v+=1,c||v>r)return g=!0,I({code:null,reason:"dead"}),!1;let _=Math.min(t*2**Math.min(v-1,8),n);return await p(_),y()}}let R=async()=>{if(i)return i;if(c)throw new Error("native-host \u5DF2\u505C\u6B62");if(g)throw new Error("native-host \u591A\u6B21\u542F\u52A8\u5931\u8D25\uFF0C\u8BF7\u91CD\u542F\u63D2\u4EF6");o||(o=y());let N=await o;if(o=null,!N||!i)throw new Error("native-host \u4E0D\u53EF\u7528");return i};return{call:async(N,_,E,G)=>(await R()).call(N,_,E,G),onExit:N=>f.push(N),stop:async()=>{c=!0;let N=a,_=i;i=null,a=void 0;try{_?.dispose()}catch{}if(N&&N!==_?.dispose)try{await N()}catch{}}}}var dt=["app.getVersion","app.getPath","app.isActive","app.isHidden","app.getName","app.getLocale","app.getLocaleCountryCode","app.getSystemLocale","app.getPreferredSystemLanguages","app.notify","app.setAutoLaunch","app.event","app.createNativeHost","app.createNativeClient","app.disposeNativeClient","app.window.close","app.window.focus","app.window.blur","app.window.show","app.window.hide","app.window.maximize","app.window.unmaximize","app.window.minimize","app.window.restore","app.window.isMaximized","app.window.setFullScreen","app.data.read","app.data.write","app.crypt.encrypt","app.crypt.decrypt","app.shortcut.register","app.shortcut.unregister","app.menu.popup",...["read","write","clear","has","availableFormats"].map(e=>`clipboard.${e}`),...["Text","HTML","RTF","Bookmark","FindText","Image","Buffer"].flatMap(e=>[`clipboard.read${e}`,`clipboard.write${e}`]),"dialog.showMessageBox","dialog.showOpenDialog","dialog.showSaveDialog","fs.read","fs.stat","fs.listDir","fs.watch","fs.unwatch","fs.mkdir","fs.write","fs.append","fs.delete","fs.copyDir","fs.lock","fs.unlock","fs.withLock","i18n.getLocale","net.isOnline","net.fetch","net.request","net.getFreePort","net.probePort","nodejs.checkLocal","nodejs.checkBundled","nodejs.resolveRuntime","nodejs.install","notification.isSupported","notification.send","notification.remove","notification.removeGroup","notification.subscribe","notification.unsubscribe","log.write","os.openExternal","os.showItemInFolder","permission.plugin.list","permission.revoke","permission.request","permission.list","plugin.invoke","plugin.requestGrant","plugin.capabilities","plugin.registry.report","plugin.start","plugin.stop","plugin.system","plugin.scanInstalled","plugin.runtimeList","plugin.installLocal","plugin.install","plugin.isRunning","plugin.cleanupUninstall","plugin.setActive","plugin.dev.selectDirectory","plugin.dev.getDirInfo","plugin.dev.sync","plugin.dev.startWatcher","plugin.dev.stopWatcher","plugin.dev.startDevWorker","plugin.dev.stopDevWorker","plugin.dev.isPortReady","plugin.dev.readLogs","plugin.dev.clearLogs","plugin.dev.list","plugin.dev.remove","plugin.logs.subscribe","plugin.logs.unsubscribe","powerSaveBlocker.start","powerSaveBlocker.stop","powerSaveBlocker.isStarted","screen.getCursorScreenPoint","screen.getPrimaryDisplay","screen.getAllDisplays","screen.getDisplayNearestPoint","screen.getDisplayMatching","screen.screenToDipPoint","screen.dipToScreenPoint","screen.screenToDipRect","screen.dipToScreenRect","system.getIdleState","system.listenNativeTheme","webview.create","webview.update","webview.destroy","webview.setVisible","webview.webContentsCall","webview.showWebviewByPlugin","webview.hideWebviewByPlugin"];function lt(e,t,n){let r=t.split("."),i=r.pop(),a=e;for(let o of r)(typeof a[o]!="object"||a[o]===null)&&(a[o]={}),a=a[o];a[i]=(...o)=>n(t,o)}function ut(e){let t={};for(let n of dt)lt(t,n,e);return t}var ft="__dlientPoolCtx",pt="__dlientRpcTable",J={OK:0,METHOD_NOT_REGISTERED:-2101,INTERNAL:-2200,THROW_ERROR:-2201};var m=class extends Error{constructor(t,n){super(typeof n=="string"?n:n?.zhCN??n?.enUS??`plugin error ${t}`),this.name="PluginError",this.code=t,this.msg=n}};function pe(e){if(e&&typeof e=="object"&&typeof e.code=="number")return e.code}function gt(e){if(e instanceof m&&e.msg!==void 0)return e.msg;if(e&&typeof e=="object"&&"msg"in e){let t=e.msg;if(typeof t=="string"||t&&typeof t=="object"&&typeof t.enUS=="string")return t}return e instanceof Error?e.message:String(e)}function wt(e){return!!e&&typeof e=="object"&&typeof e.code=="number"&&typeof e.from=="string"}function ht(e,t){let n=new Error(t);return n.code=e,n}function _e(e){let t=new Map,n=new Set,r=0,i=new Map,a=null,o=new Map,c,g,v=[],f=[],p=[],I=!1,y=()=>{if(!I){I=!0;for(let s of f)try{s()}catch(l){console.error(`[plugin:${E}] onReady failed:`,l)}}},R=globalThis[ft],N=process.parentPort,_=R?.controlPort??(typeof process<"u"?N:void 0),E=R?.pluginId??e,G=new Map,te=new Map,U=s=>{_?.postMessage(s)},D=s=>({code:J.OK,data:s,from:E}),C=(s,l)=>({code:s,msg:l,data:null,from:E}),P=s=>{a&&a.postMessage(s)},$=s=>{let l=s.data;switch(l.type){case"request":ne(l,!1);break;case"listen":ne(l,!0);break;case"cancel":o.get(l.request_id)?.abort(),o.delete(l.request_id);break}},K=new Set,O,z=s=>{let l=!K.has(s);O&&a&&a!==s&&(a.off?.("message",O),O=void 0),a=s,l&&(K.add(s),O=u=>{a===s&&$(u)},s.on("message",O),s.start?.()),U({type:"direct-port-ready",pluginId:E}),y()},F=R?.directPort;F&&z(F);let X=globalThis[pt]??={};X[E]={setDirectPort:z};function ne(s,l){let u=t.get(s.method);if(!u){let S=`Method "${s.method}" not found`;P({type:"error",request_id:s.request_id,error:S,error_code:J.METHOD_NOT_REGISTERED,result:C(J.METHOD_NOT_REGISTERED,S)});return}let w=new AbortController;o.set(s.request_id,w);let b=(S,x)=>{P({type:"stream",request_id:s.request_id,chunk:S,data:x?.data})},h={from_plugin_id:s.from_plugin_id,request_id:s.request_id,data:s.data,signal:w.signal,emit:l?b:void 0};Promise.resolve().then(()=>u(s.args,h)).then(S=>{if(w.signal.aborted)return;let x=S?.data,q=x instanceof ArrayBuffer?x:void 0,re=q!==void 0?S.result:S,T=wt(re)?re:D(re);P(l?{type:"stream-done",request_id:s.request_id,result:T}:{type:"response",request_id:s.request_id,result:T,data:q})}).catch(S=>{if(w.signal.aborted)return;let x=S instanceof Error?S.message:String(S),q=pe(S)??J.THROW_ERROR,re=C(q,gt(S));P(l?{type:"stream-error",request_id:s.request_id,error:x,error_code:q}:{type:"error",request_id:s.request_id,error:x,error_code:q,result:re})}).finally(()=>{o.delete(s.request_id)})}if(_){let s=Date.now();_.on("message",l=>{let u=l,w=u.data;switch(s=Date.now(),w.type){case"init":{w.pluginId&&(E=w.pluginId),U({type:"ready",pluginId:E,capabilities:Array.from(t.keys())}),y();break}case"port-setup":{let[b]=u.ports??[];b&&z(b);break}case"rpc-call":j(w);break;case"host-api-response":Y(w);break;case"child-control-response":et(w);break;case"child-event":{let h=w.child,S=h?.handleId;if(!S)break;let x=G.get(S);if(!x)break;h.event==="stdout"?x.onStdout?.(h.data??""):h.event==="stderr"?x.onStderr?.(h.data??""):h.event==="exit"?x.onExit?.({code:h.code??null,signal:h.signal??void 0,reason:"exited"}):h.event==="error"&&x.onError?.(new Error(h.data??"spawn error"));break}case"notification-event":{let b=w,h=te.get(b.id);if(!h)break;let S=h.events.get(b.event);if(!S)break;for(let x of Array.from(S))try{x(b.payload)}catch(q){console.error(`[plugin:${E}] notification "${b.event}" handler error:`,q)}break}case"snapshot-request":{let b=w;c&&Promise.resolve().then(()=>c()).then(h=>{let S={type:"snapshot-response",pluginId:E,request_id:b.request_id,snapshot:h};U(S)}).catch(h=>{let S={type:"snapshot-response",pluginId:E,request_id:b.request_id,error:h instanceof Error?h.message:String(h)};U(S)});break}case"snapshot-restore":{let b=w;g&&Promise.resolve().then(()=>g(b.snapshot)).catch(h=>console.error(`[plugin:${e}] snapshot restore failed:`,h));break}case"heartbeat":break;case"dispose":{(async()=>{for(let h=p.length-1;h>=0;h--)try{await p[h]()}catch(S){console.error(`[plugin:${E}] onDispose "${h}" failed:`,S)}p.length=0;for(let h=v.length-1;h>=0;h--)try{await v[h]()}catch(S){console.error(`[plugin:${E}] dispose "${h}" failed:`,S)}v.length=0,U({type:"dispose-done",pluginId:E})})();break}}}),_.start?.(),setInterval(()=>{U({type:"heartbeat",pluginId:E,ts:Date.now()})},1e4),setInterval(()=>{if(Date.now()-s>3e4){let l=new Error("Main process lost (no message for 30s)");for(let{reject:u}of i.values())u(l);i.clear()}},5e3)}let j=s=>{let l=t.get(s.method),u={type:"rpc-response",id:s.id,pluginId:E};if(!l)u.error=`Method "${s.method}" not found`,u.error_code=J.METHOD_NOT_REGISTERED;else{let w={from_plugin_id:s.from_plugin_id??"",request_id:s.id,signal:new AbortController().signal};try{let b=l(s.args,w);if(b instanceof Promise){b.then(h=>{u.result=h,U(u)},h=>{u.error=h.message,u.error_code=pe(h)??J.INTERNAL,U(u)});return}u.result=b}catch(b){u.error=b instanceof Error?b.message:String(b),u.error_code=pe(b)??J.INTERNAL}}U(u)},Y=s=>{let l=i.get(s.id);l&&(i.delete(s.id),s.error?l.reject(ht(s.error_code??J.INTERNAL,s.error)):l.resolve(s.result))},fe=new Map,Ze=0,et=s=>{let l=fe.get(s.id);l&&(fe.delete(s.id),s.ok?l.resolve():l.reject(new Error(s.reason??"child control failed")))},$e=s=>{U({type:"child-subscribe",pluginId:E,handleId:s})},ce=(s,l,u)=>{let w=`child-ctl-${E}-${++Ze}`,b={type:"child-control",id:w,pluginId:E,handleId:s,op:l,data:u};return new Promise((h,S)=>{fe.set(w,{resolve:h,reject:S}),U(b)})};return t.set("webview:create",([s])=>M("webview.create",[s])),t.set("webview:update",([s])=>M("webview.update",[s])),t.set("webview:destroy",([s])=>M("webview.destroy",[String(s??"")])),t.set("webview:setVisible",([s])=>M("webview.setVisible",[s])),t.set("webview:webContents:call",([s])=>M("webview.webContentsCall",[s])),t.set("onWebContentsEvent",([s])=>{let{viewId:l,name:u,args:w}=s??{};if(!l||!u)return;U({type:"push",pluginId:E,event:"webview:event",data:{viewId:l,name:u,args:w}})}),{...ut((s,l)=>M(s,l)),child:{spawn:async s=>{let l=await M("child.spawn",[{...s}]),u=String(l?.handleId??"");if(!u)throw new Error("child.spawn: handleId missing");return Ce(u,typeof l?.pid=="number"?l.pid:0)},execFile:s=>M("child.execFile",[{...s}])},notification:{isSupported:async()=>!!await M("notification.isSupported",[]),send:s=>tt(s),remove:async s=>{await M("notification.remove",[String(s)])},removeGroup:async()=>{await M("notification.removeGroup",[])},subscribe:async s=>{await M("notification.subscribe",[s])},unsubscribe:async s=>{await M("notification.unsubscribe",[s])}},getPluginId:()=>E,registerHandler:(s,l)=>{t.set(s,l),n.delete(s)},registerSnapshotHandler:s=>{c=s},registerRestoreHandler:s=>{g=s},effect:s=>{let l=!1,u;try{let w=s();w instanceof Promise?w.then(b=>{typeof b=="function"&&(u=b,v.push(u),l=!0)}).catch(b=>console.error(`[plugin:${E}] effect install failed:`,b)):typeof w=="function"&&(u=w,v.push(u),l=!0)}catch(w){console.error(`[plugin:${E}] effect install failed:`,w)}return l?u:void 0},onReady:s=>{if(f.push(s),I)try{s()}catch(l){console.error(`[plugin:${E}] onReady failed:`,l)}},onDispose:s=>{p.push(s)},registerStreamHandler:(s,l)=>{t.set(s,l),n.add(s)},push:(s,l)=>{U({type:"push",pluginId:E,event:s,data:l})},registerChildEvent:(s,l)=>{G.set(s,l)},unregisterChildEvent:s=>{G.delete(s)},childSubscribe:s=>$e(s),childControl:(s,l,u)=>ce(s,l,u),success:s=>D(s),error:(s,l)=>C(s,l),createNativeHost:async(s,l)=>{let u="";try{let T=await M("nodejs.resolveRuntime",[]);u=typeof T?.node=="string"?T.node:""}catch{}if(!u)return{host:null,client:null,error:"createNativeHost: nodejs runtime unavailable"};let w={};try{w=await M("app.createNativeHost",[{fileName:String(s),node:u}])}catch(T){return{host:null,client:null,error:T instanceof Error?T.message:String(T)}}let b=String(w?.handleId??"");if(!b)return{host:null,client:null,error:"createNativeHost: no handle"};let h=Ce(b,typeof w?.pid=="number"?w.pid:0),S;try{S=at({transport:ot(h)})}catch(T){return{host:null,client:null,error:T instanceof Error?T.message:String(T)}}let x=[],q=ct({spawn:async()=>({client:S,dispose:()=>void h.kill()}),onRestarted:async()=>{for(let T of x)try{T()}catch{}},maxRestarts:l?.maxRestarts,backoffMs:l?.backoffMs,maxBackoffMs:l?.maxBackoffMs});return{host:Object.assign(q,{onRestarted:T=>void x.push(T)}),client:S,error:void 0}}};function Ce(s,l){let u={};return G.set(s,u),$e(s),{handleId:s,pid:l,kill:()=>(G.delete(s),ce(s,"kill")),onStdout:w=>{u.onStdout=w},onStderr:w=>{u.onStderr=w},onExit:w=>{u.onExit=w},onError:w=>{u.onError=w},write:w=>ce(s,"write",w),end:()=>ce(s,"end")}}async function tt(s){let l=await M("notification.send",[s]),u=String(l?.id??"");if(!u)throw new Error("notification.send: id missing");return nt(u)}function nt(s){let l=new Map;te.set(s,{events:l});let u={id:s,on(w,b){let h=l.get(w)??[];return h.push(b),l.set(w,h),u},close:async()=>{te.delete(s),await M("notification.remove",[s])}};return M("notification.subscribe",[{id:s}]).catch(()=>{}),u}function M(s,l){let u=`host-api-${E}-${++r}`,w={type:"host-api-call",id:u,method:s,args:l,pluginId:E};return new Promise((b,h)=>{i.set(u,{resolve:b,reject:h}),U(w)})}}import{dirname as vt,join as L,normalize as Me}from"node:path";import{fileURLToPath as yt}from"node:url";var k={INVALID_ARG:-3001,PACKAGE_INVALID:-3002,BUILD_FAIL:-3003,NOT_FOUND:-3004,NODEJS_MISSING:-3010,DUPLICATE:-3011,PERMISSION_DENIED:-3012,CANCELED:-3013};import{basename as mt,join as Re}from"node:path";var we=10*60*1e3;function Ae(e){let{rpc:t}=e;async function n(o,c){let g=await e.readText(Re(o,"package.json"));if(g==null)throw new m(k.NOT_FOUND,{enUS:`Cannot read package.json in ${o}`,zhCN:`\u65E0\u6CD5\u8BFB\u53D6\u63D2\u4EF6\u76EE\u5F55\u4E0B\u7684 package.json\uFF1A${o}`});let v=JSON.parse(g),f=String(v?.dlient?.id??"");if(f!==c)throw new m(k.INVALID_ARG,{enUS:`Manifest id mismatch (expected "${c}", got "${f}")`,zhCN:`\u63D2\u4EF6 manifest \u7684 id \u4E0E\u8BF7\u6C42\u4E0D\u4E00\u81F4\uFF08\u671F\u671B\u300C${c}\u300D\uFF0C\u5B9E\u9645\u300C${f}\u300D\uFF09`});let p=String(v?.version??"").trim();if(!/^\d+\.\d+\.\d+([-+][0-9A-Za-z.-]+)?$/.test(p))throw new m(k.INVALID_ARG,{enUS:`Invalid or missing package.json version: "${p}"`,zhCN:`package.json \u7684 version \u7F3A\u5931\u6216\u4E0D\u5408\u6CD5\uFF1A\u300C${p}\u300D`});if(!v?.scripts?.pack)throw new m(k.BUILD_FAIL,{enUS:'This plugin has no "pack" script, cannot produce a .dlient package. Add e.g. "pack": "npm run build && node script/make-dlient.mjs"',zhCN:'\u8BE5\u63D2\u4EF6\u672A\u58F0\u660E pack \u811A\u672C\uFF0C\u65E0\u6CD5\u4EA7\u51FA .dlient \u5305\u3002\u8BF7\u53C2\u8003\u6A21\u677F\u52A0\u5165 "pack": "npm run build && node script/make-dlient.mjs"'});return{version:p}}async function r(o,c){await e.ensureNode();let g=await t.child.spawn({cmd:ie,args:["run","pack"],cwd:o}),v="";g.onStdout(p=>v+=p),g.onStderr(p=>v+=p);let f=await e.awaitChild(g,we);if(f.reason==="timeout")throw e.log("error","packDlient timeout",{pluginId:c}),new m(k.BUILD_FAIL,{enUS:`Packaging timed out after ${Math.round(we/6e4)} minutes${v.trim()?`: ${v.trim().slice(-300)}`:""}`,zhCN:`\u6253\u5305\u8D85\u65F6\uFF08${Math.round(we/6e4)} \u5206\u949F\uFF09${v.trim()?`\uFF1A${v.trim().slice(-300)}`:""}`});if(f.code!==0){let p=v.trim().slice(-500);throw e.log("error","packDlient failed",{pluginId:c,code:f.code}),new m(k.BUILD_FAIL,{enUS:`npm run pack failed (exit ${f.code??"unknown"})${p?`: ${p}`:""}`,zhCN:`npm run pack \u5931\u8D25\uFF08exit ${f.code??"unknown"}\uFF09${p?`\uFF1A${p}`:""}`})}}async function i(o,c){let f=(await t.fs.listDir(o).catch(()=>null)??[]).filter(p=>p.isFile!==!1&&/\.dlient$/i.test(String(p.name))&&Number(p.mtimeMs??0)>=c).sort((p,I)=>Number(I.mtimeMs??0)-Number(p.mtimeMs??0))[0];if(!f)throw new m(k.BUILD_FAIL,{enUS:`Packaging finished but no .dlient file was produced in ${o}`,zhCN:`\u6253\u5305\u5DF2\u7ED3\u675F\uFF0C\u4F46\u5728 ${o} \u672A\u627E\u5230\u65B0\u4EA7\u51FA\u7684 .dlient \u6587\u4EF6`});return Re(o,f.name)}return{async run(o,c){let g=String(c.pluginId??"");await n(o,g);let v=Date.now();e.log("info","packDlient start",{pluginId:g}),await r(o,g);let f=await i(o,v),p=mt(f);if(e.log("info","packDlient produced",{pluginId:g,name:p}),c.savePath)return await a(f,c.savePath),{ok:!0,name:p,savePath:c.savePath};let I=await t.dialog.showSaveDialog({defaultPath:f,filters:[{name:"dlient",extensions:["dlient"]}]}).catch(()=>null),y=String(I?.filePath??"");return y?(await a(f,y),{ok:!0,name:p,savePath:y}):{ok:!0,name:p,savePath:f}}};async function a(o,c){let g=String(await t.fs.read(o,{base64:!0}));await t.fs.write(c,{base64:g})}}var d=_e("dev-tools"),A={debug:(e,t)=>void d.log.write("debug",e,t),info:(e,t)=>void d.log.write("info",e,t),warn:(e,t)=>void d.log.write("warn",e,t),error:(e,t)=>void d.log.write("error",e,t)};async function ve(e){try{let t=await d.fs.stat(e);return{exists:!0,size:t?.size??0,mtimeMs:t?.mtimeMs??0}}catch{return null}}function ye(e){return ve(e).then(t=>t?.exists===!0)}async function Ue(e){try{return String(await d.fs.read(e))}catch{return null}}async function kt(e){try{return String(await d.fs.read(e,{base64:!0}))}catch{return null}}async function Le(e){await d.fs.mkdir(e)}async function je(e,t){await d.fs.write(e,t)}async function bt(e,t){await d.fs.write(e,{base64:t})}function St(e){return typeof e=="string"?e:void 0}var he=Promise.resolve();function W(){return d.app.data.read("plugins.json").then(e=>Array.isArray(e)?e:[])}function se(e){return he=he.then(()=>d.app.data.write("plugins.json",e)),he}var He=Promise.resolve();function It(e){He=e.then(()=>{},()=>{})}function Dt(){return He}async function be(e,t){try{let n=await d.permission.request([{type:"fs",path:e,mode:["read","write"]}],t);return!(n?.denied&&n.denied.length>0)}catch(n){return A.warn("ensureDirAccess failed",{dir:e,error:n instanceof Error?n.message:String(n)}),!1}}async function Nt(){let e=await W(),t=e.map(o=>o.path).filter(o=>!!o);if(t.length===0)return[];let n=await d.permission.request(t.map(o=>({type:"fs",path:o,mode:["read","write"]})),"dev \u63D2\u4EF6\u76EE\u5F55\u8BFB\u5199\uFF08\u540C\u610F\u540E\u7EB3\u5165 dev-tools \u7BA1\u7406\uFF1B\u62D2\u7EDD\u7684\u63D2\u4EF6\u5C06\u4ECE\u5217\u8868\u79FB\u9664\uFF09").catch(()=>null),r=new Set(n?.denied??[]);if(r.size===0)return[];let i=[],a=e.filter(o=>!o.path||!r.has(o.path)?!0:(i.push(o.id),!1));if(i.length>0){await se(a);for(let o of i)await Se(o);await ee(a),A.warn("dev dirs denied, removed from plugins.json",{removed:i})}return i}async function xe(e){try{let t=await W(),n=Me(e),r=t.find(a=>Me(String(a.path??""))===n);if(!r)return;let i=t.filter(a=>a!==r);if(i.length===t.length)return;await se(i),await Se(r.id),await ee(i),A.warn("dev entry removed (dir read failed)",{id:r.id,dir:e})}catch(t){A.error("dropEntryIfRegistered failed",{dir:e,error:t instanceof Error?t.message:String(t)})}}async function ee(e){await d.plugin.dev.sync(e).catch(()=>{})}async function Se(e){Oe(e),await Ee(e)}function Et(e){return JSON.stringify({permissions:e.permissions,dependencies:e.dependencies,fsDirs:e.fsDirs,spawnCmds:e.spawnCmds,expose:e.expose})}async function V(e){if(!await be(e,"dev \u63D2\u4EF6\u76EE\u5F55\u8BFB\u5199\uFF08\u540C\u610F\u540E\u7EB3\u5165 dev-tools \u7BA1\u7406\uFF09"))return A.warn("readManifest denied dir access",{dir:e}),xe(e),null;try{await Dt();let t=await d.fs.read(`${e}/package.json`),n=JSON.parse(String(t)),r=n.dlient??{};return{id:typeof r.id=="string"?r.id:void 0,name:typeof r.name=="string"?r.name:r.name?.default,dist:typeof r.dist=="string"?r.dist:void 0,version:typeof n.version=="string"?n.version:void 0,type:typeof r.type=="string"?r.type:void 0,system:r.system===!0,icon:St(r.icon),source:typeof r.source=="string"?r.source:void 0,nodeVersion:typeof r.nodeVersion=="string"?r.nodeVersion:void 0,authHash:Et(r),dependencies:Array.isArray(r.dependencies)?r.dependencies.map(i=>String(i)):r.dependencies&&typeof r.dependencies=="object"?Object.keys(r.dependencies):void 0}}catch(t){return A.warn("readManifest failed",{dir:e,error:t instanceof Error?t.message:String(t)}),xe(e),null}}function Ie(e){let t=e??"ui";return{hasUI:t!=="worker",needsWorker:t!=="ui"}}var le=new Map,ae=new Map,ke=new Map,Pt=1500;function Oe(e){let t=le.get(e);t&&(le.delete(e),d.fs.unwatch(t).catch(()=>{}));let n=ae.get(e);n&&(clearTimeout(n),ae.delete(e))}async function ze(e){if(Oe(e.id),!!await ye(L(e.path,"package.json")))try{let t=String(await d.fs.watch(e.path));le.set(e.id,t)}catch{}}d.registerHandler("dev-tools.fs-watch-event",([e,t])=>{if(String(t??"").replace(/\\/g,"/")!=="package.json")return;let n=Array.from(le.entries()).find(([,i])=>i===e)?.[0];if(!n)return;let r=ae.get(n);r&&clearTimeout(r),ae.set(n,setTimeout(async()=>{ae.delete(n);let i=ke.get(n);if(i&&Date.now()-i<Pt){ke.delete(n);return}try{let a=await W(),o=a.find(f=>f.id===n);if(!o)return;let c=await V(o.path);if(!c)return;let g={...o,name:c.name??o.name,version:c.version,type:c.type,dist:c.dist??o.dist,system:c.system===!0,icon:c.icon,authHash:c.authHash},v=a.map(f=>f.id===n?g:f);await se(v),await ee(v)}catch(a){A.error("sync package.json failed",{pluginId:n,error:a instanceof Error?a.message:String(a)})}},500))});d.registerHandler("dev-tools.list",async()=>(await W()).sort((t,n)=>t.addedAt-n.addedAt));async function Be(){return(await d.dialog.showOpenDialog(["fs.read","fs.write"],{properties:["openDirectory"]}).catch(()=>null))?.filePaths?.[0]??null}d.registerHandler("dev-tools.selectDirectory",()=>Be());d.registerHandler("dev-tools.checkImportable",async([e])=>{let t=String(e??"").trim();if(!t)return{ok:!1,error:{enUS:"Plugin directory cannot be empty",zhCN:"\u63D2\u4EF6\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A"}};if(!await be(t,"\u5BFC\u5165\u63D2\u4EF6\u76EE\u5F55"))return{ok:!1,error:{enUS:"Canceled: no access permission granted to this directory",zhCN:"\u5DF2\u53D6\u6D88\uFF1A\u672A\u6388\u4E88\u8BE5\u76EE\u5F55\u7684\u8BBF\u95EE\u6743\u9650"}};let n=await V(t);return n?.id?/^[a-z0-9-]+$/.test(n.id)?{ok:!0,needsDevChange:n.source!=="dev",id:n.id,name:n.name??n.id}:{ok:!1,error:{enUS:`Invalid plugin ID (only lowercase letters, digits and hyphens allowed, current: ${n.id})`,zhCN:`\u63D2\u4EF6 ID \u4E0D\u5408\u6CD5\uFF08\u4EC5\u5141\u8BB8\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\uFF0C\u5F53\u524D\uFF1A${n.id}\uFF09`}}:{ok:!1,error:{enUS:"No valid plugin manifest found in the directory (dlient.id in package.json)",zhCN:"\u76EE\u5F55\u4E2D\u672A\u627E\u5230\u6709\u6548\u7684\u63D2\u4EF6 manifest\uFF08package.json \u7684 dlient.id\uFF09"}}});d.registerHandler("dev-tools.changeToDev",async([e])=>{let t=String(e??"").trim();if(!t)throw new m(k.INVALID_ARG,{enUS:"Plugin directory cannot be empty",zhCN:"\u63D2\u4EF6\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A"});if(!await be(t,"\u5199\u56DE\u63D2\u4EF6 manifest\uFF08dlient.source=dev\uFF09"))throw new m(k.PERMISSION_DENIED,{enUS:"Canceled: no access permission granted to this directory",zhCN:"\u5DF2\u53D6\u6D88\uFF1A\u672A\u6388\u4E88\u8BE5\u76EE\u5F55\u7684\u8BBF\u95EE\u6743\u9650"});let n=String(await d.fs.read(`${t}/package.json`).catch(()=>""));if(!n)throw new m(k.PACKAGE_INVALID,{enUS:"No package.json found in the directory",zhCN:"\u76EE\u5F55\u4E2D\u672A\u627E\u5230 package.json"});let r=JSON.parse(n),i={...r.dlient??{}};return i.source==="dev"?{ok:!0,changed:!1}:(i.source="dev",await d.fs.write(`${t}/package.json`,`${JSON.stringify({...r,dlient:i},null,Ve(n))}
10
- `),{ok:!0,changed:!0})});async function We(e){let t=String(e??"").trim();if(!t)throw new m(k.INVALID_ARG,{enUS:"Plugin directory cannot be empty",zhCN:"\u63D2\u4EF6\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A"});let n=await V(t);if(!n?.id)throw new m(k.PACKAGE_INVALID,{enUS:"No valid plugin manifest found in the directory (dlient.id in package.json)",zhCN:"\u76EE\u5F55\u4E2D\u672A\u627E\u5230\u6709\u6548\u7684\u63D2\u4EF6 manifest\uFF08package.json \u7684 dlient.id\uFF09"});if(n.source!=="dev")throw new m(k.PACKAGE_INVALID,{enUS:`This plugin is not a dev plugin (dlient.source="${n.source??"unset"}"). Change dlient.source in package.json to "dev" and add it again.`,zhCN:`\u8BE5\u63D2\u4EF6\u4E0D\u662F dev \u63D2\u4EF6\uFF08dlient.source="${n.source??"\u672A\u58F0\u660E"}"\uFF09\u3002\u8BF7\u5C06 package.json \u7684 dlient.source \u6539\u4E3A "dev" \u540E\u91CD\u65B0\u6DFB\u52A0\u3002`});if(!/^[a-z0-9-]+$/.test(n.id))throw new m(k.INVALID_ARG,{enUS:`Invalid plugin ID (only lowercase letters, digits and hyphens allowed, current: ${n.id}). Edit dlient.id in package.json`,zhCN:`\u63D2\u4EF6 ID \u4E0D\u5408\u6CD5\uFF08\u4EC5\u5141\u8BB8\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\uFF0C\u5F53\u524D\uFF1A${n.id}\uFF09\uFF0C\u8BF7\u4FEE\u6539 package.json \u7684 dlient.id`});let r=await W(),i=r.find(c=>c.id===n.id),a={id:n.id,name:n.name??n.id,path:t,dist:n.dist??"dist",version:n.version,type:n.type,system:n.system===!0,icon:n.icon,authHash:n.authHash,addedAt:i?.addedAt??Date.now()},o=i?r.map(c=>c.id===a.id?a:c):[...r,a];return await se(o),await ze(a),await ee(o),a}d.registerHandler("dev-tools.register",([e])=>We(String(e)));d.registerHandler("dev-tools.remove",async([e])=>{let t=String(e),n=await W(),r=n.filter(i=>i.id!==t);return r.length===n.length?{ok:!1,error:{enUS:`Dev plugin not registered: ${t}`,zhCN:`dev \u63D2\u4EF6\u672A\u6CE8\u518C: ${t}`}}:(await se(r),await Se(t),await ee(r),{ok:!0})});async function H(e){let n=(await W()).find(r=>r.id===e);return n?{dir:n.path,dist:n.dist}:await d.plugin.dev.getDirInfo(e)}d.registerHandler("dev-tools.getDirInfo",([e])=>H(String(e)));var Fe=["name","description","type","platforms","icon","tags"];async function qe(e){let t=await H(e);if(!t)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${e}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${e}`});let n=String(await d.fs.read(`${t.dir}/package.json`));return{dir:t.dir,raw:n}}function Ve(e){let t=/\n([ \t]+)"/.exec(e);return t?t[1].includes(" ")?" ":t[1].length:2}d.registerHandler("dev-tools.readSettings",async([e])=>{let{dir:t,raw:n}=await qe(String(e)),r=JSON.parse(n),i=r.dlient??{},a={};for(let o of Fe)i[o]!==void 0&&(a[o]=i[o]);return{dir:t,version:typeof r.version=="string"?r.version:void 0,id:typeof i.id=="string"?i.id:void 0,dlient:a}});d.registerHandler("dev-tools.writeSettings",async([e,t])=>{let n=String(e),r=t??{},{dir:i,raw:a}=await qe(n),o=JSON.parse(a),c={...o.dlient??{}},g=!1;for(let p of Fe){if(!(p in r))continue;let I=r[p];if(I==null){p in c&&(delete c[p],g=!0);continue}JSON.stringify(c[p])!==JSON.stringify(I)&&(c[p]=I,g=!0)}if(!g)return{ok:!0,changed:!1};let v=JSON.stringify({...o,dlient:c},null,Ve(a));ke.set(n,Date.now()),await d.fs.write(`${i}/package.json`,`${v}
11
- `);let f=await V(i);if(f){let p=await W(),I=p.find(y=>y.id===n);if(I){let y={...I,name:f.name??I.name,version:f.version,type:f.type,dist:f.dist??I.dist,system:f.system===!0,icon:f.icon,authHash:f.authHash},R=p.map(N=>N.id===n?y:N);await se(R),await ee(R)}}return{ok:!0,changed:!0}});d.registerHandler("dev-tools.writeAsset",async([e,t,n])=>{let r=String(e),i=String(t??"");if(!/^icon[\w-]*\.(svg|png)$/.test(i))throw new m(k.INVALID_ARG,{enUS:`Invalid icon file name: ${i}`,zhCN:`\u975E\u6CD5\u7684\u56FE\u6807\u6587\u4EF6\u540D: ${i}`});let a=await H(r);if(!a)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${r}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${r}`});let o=Buffer.from(String(n??""),"base64");if(o.length===0||o.length>200*1024)throw new m(k.INVALID_ARG,{enUS:"Icon content is invalid or exceeds 200KB",zhCN:"\u56FE\u6807\u5185\u5BB9\u975E\u6CD5\u6216\u8D85\u8FC7 200KB"});let c=L(a.dir,"assets");return await Le(c),await bt(L(c,i),String(n??"")),A.info(`writeAsset ${r} ${i} ${o.length}B`),{ok:!0,path:`assets/${i}`}});d.registerHandler("dev-tools.readAsset",async([e,t])=>{let n=String(e),r=String(t??"");if(!/^icon[\w-]*\.(svg|png)$/.test(r))throw new m(k.INVALID_ARG,{enUS:`Invalid icon file name: ${r}`,zhCN:`\u975E\u6CD5\u7684\u56FE\u6807\u6587\u4EF6\u540D: ${r}`});let i=await H(n);if(!i)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${n}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${n}`});let a=L(i.dir,"assets",r),o=await kt(a);if(o==null||o.length===0)return{ok:!0,data:"",mime:"",exists:!1};let c=r.endsWith(".png")?"image/png":"image/svg+xml";return{ok:!0,data:o,mime:c,exists:!0}});var Ge=["index.md","index.zh-CN.md","index.en-US.md","SKILL.md"];d.registerHandler("dev-tools.readMarkdown",async([e,t])=>{let n=String(e),r=String(t??"");if(!Ge.includes(r))throw new m(k.INVALID_ARG,{enUS:`Invalid markdown file name: ${r}`,zhCN:`\u975E\u6CD5\u7684 markdown \u6587\u4EF6\u540D: ${r}`});let i=await H(n);if(!i)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${n}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${n}`});let a=L(i.dir,"assets",r);try{return{ok:!0,content:String(await d.fs.read(a)),exists:!0}}catch{return{ok:!0,content:"",exists:!1}}});d.registerHandler("dev-tools.writeMarkdown",async([e,t,n])=>{let r=String(e),i=String(t??"");if(!Ge.includes(i))throw new m(k.INVALID_ARG,{enUS:`Invalid markdown file name: ${i}`,zhCN:`\u975E\u6CD5\u7684 markdown \u6587\u4EF6\u540D: ${i}`});let a=await H(r);if(!a)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${r}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${r}`});let o=L(a.dir,"assets");return await Le(o),await je(L(o,i),String(n??"")),A.info(`writeMarkdown ${r} ${i} ${String(n??"").length}B`),{ok:!0}});async function De(e){let t=await d.nodejs.resolveRuntime(e?{version:e}:void 0).catch(()=>null);return!t||t.source==="none"||t.source===void 0?{ok:!1,reason:"runtime-missing"}:{ok:!0}}function $t(e){let t=/^v?(\d+)\.?(\d+)?\.?(\d+)?/.exec(e.trim().replace(/^>=?/,""));return t?[Number(t[1]),Number(t[2]??0),Number(t[3]??0)]:null}async function Ct(){try{let e=L(vt(yt(import.meta.url)),"..","package.json"),t=await d.fs.read(e),r=JSON.parse(String(t)).dlient??{};return{nodeVersion:typeof r.nodeVersion=="string"?r.nodeVersion:void 0}}catch{return null}}async function _t(){let t=[(await Ct())?.nodeVersion],n=await W();for(let a of n){let o=await V(a.path);o?.nodeVersion&&t.push(o.nodeVersion)}let r,i=null;for(let a of t){if(!a)continue;let o=$t(a);o&&(!i||o[0]>i[0]||o[0]===i[0]&&o[1]>i[1]||o[0]===i[0]&&o[1]===i[1]&&o[2]>i[2])&&(r=a,i=o)}return r}function Je(){return{enUS:"No usable Node.js runtime. Install system Node.js, or let the host download the built-in LTS runtime and retry.",zhCN:"\u672A\u68C0\u6D4B\u5230\u53EF\u7528\u7684 Node.js \u8FD0\u884C\u65F6\uFF1B\u8BF7\u5B89\u88C5\u7CFB\u7EDF Node.js\uFF0C\u6216\u7531\u5BBF\u4E3B\u4E0B\u8F7D\u5185\u7F6E LTS \u8FD0\u884C\u65F6\u540E\u91CD\u8BD5"}}d.registerHandler("dev-tools.checkNode",async()=>{await Nt();let e=await _t(),t=await De(e);if(!t.ok)return{ready:!1,reason:t.reason,requiredVersion:e};let n=await d.nodejs.resolveRuntime(e?{version:e}:void 0).catch(()=>null);return{ready:!0,version:n&&n.source!=="none"?n.version:void 0,requiredVersion:e}});d.registerHandler("dev-tools.installNode",async([e])=>{let t=typeof e=="string"&&e.trim()?e.trim():void 0,n=await d.nodejs.install(t).catch(r=>({ok:!1,error:r instanceof Error?r.message:String(r)}));if(n?.ok)return{ok:!0};throw new m(k.NODEJS_MISSING,{enUS:`Failed to install the built-in Node.js runtime: ${n?.error??"unknown error"}`,zhCN:`\u5B89\u88C5\u5185\u7F6E Node.js \u8FD0\u884C\u65F6\u5931\u8D25\uFF1A${n?.error??"\u672A\u77E5\u9519\u8BEF"}`})});async function Rt(e,t){let n=L(e,"package.json"),r=await Ue(n);if(r==null)return;let i=JSON.parse(r);i.dlient={...i.dlient??{},name:t},await je(n,JSON.stringify(i,null,2))}var At=18e4;async function Mt(e,t,n=At){let r;try{await ue();let c=await Ut();r=await d.child.spawn({cmd:ie,args:["exec","--yes",...c,...e],cwd:t})}catch(c){return{ok:!1,detail:String(c instanceof Error?c.message:c).slice(0,300)}}let i="";r.onStdout(c=>i+=c),r.onStderr(c=>i+=c);let a=await Ne(r,n);if(a.reason==="timeout")return{ok:!1,detail:`npm exec \u8D85\u65F6\uFF08${Math.round(n/1e3)}s\uFF09${i.trim()?`\uFF1A${i.trim().slice(0,300)}`:""}`};let o=i.trim();return a.code!==0?{ok:!1,detail:(o||`exit ${a.code}`).slice(0,500)}:{ok:!0}}d.registerHandler("dev-tools.devCreatePlugin",async([e,t])=>{let n=String(e??"").trim(),r=String(t??"").trim();if(!/^[a-z][a-z0-9-]*$/.test(n))throw new m(k.INVALID_ARG,{enUS:"Invalid plugin ID (must start with a lowercase letter; lowercase letters/digits/hyphens only)",zhCN:"\u63D2\u4EF6 ID \u4E0D\u5408\u6CD5\uFF08\u987B\u4EE5\u5C0F\u5199\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u542B\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u8FDE\u5B57\u7B26\uFF09"});if(!r)throw new m(k.INVALID_ARG,{enUS:"Plugin name cannot be empty",zhCN:"\u63D2\u4EF6\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"});let[i,a]=await Promise.all([W(),d.plugin.scanInstalled().catch(()=>[])]);if([...i,...a??[]].some(v=>v.id===n))throw new m(k.DUPLICATE,{enUS:`A plugin with the same ID "${n}" already exists locally and cannot be created`,zhCN:`\u672C\u5730\u5DF2\u5B58\u5728\u540C\u540D\u63D2\u4EF6\u300C${n}\u300D\uFF0C\u65E0\u6CD5\u521B\u5EFA`});let c=await Be();if(!c)return null;let g=await Mt(["@dlient-open/create-plugin","--",n,"--dir",c,"--skip-install","--no-git"],c);if(!g.ok)throw new m(k.BUILD_FAIL,{enUS:`npx @dlient-open/create-plugin failed: ${g.detail}`,zhCN:`npx @dlient-open/create-plugin \u521B\u5EFA\u5931\u8D25\uFF1A${g.detail}`});return await Rt(L(c,n),r),We(L(c,n))});d.registerHandler("dev-tools.runtimeStates",()=>d.plugin.runtimeList());d.registerHandler("dev-tools.previewInfo",async([e])=>{let t=String(e),n=await H(t),r=n?await V(n.dir):null,i=(r?.type??"ui")!=="worker";return{pluginId:`${t}@dev`,remoteEntryUrl:`dlientOpen://plugin/${t}@dev/dist/remoteEntry.js`,hasUI:i,manifest:r?.nodeVersion||r?.dependencies?.length?{nodeVersion:r.nodeVersion,dependencies:r.dependencies}:void 0}});var Q=new Map,B=new Map,Z=new Map,oe=new Map,Te=5e3;function me(e,t,n){if(!n)return;let r=Z.get(e)??[];r.push({ts:Date.now(),stream:t,data:n}),r.length>Te&&r.splice(0,r.length-Te),Z.set(e,r)}var xt=["zh"],de;async function Ke(){if(de===void 0)try{de=String(await d.app.getLocale())}catch{de="en-US"}return xt.some(e=>de.startsWith(e))}async function Tt(e){let t=await Ke()?"https://registry.npmmirror.com":void 0;return!t||e.some(n=>n.startsWith("--registry"))?e:[...e,`--registry=${t}`]}async function Ut(){let e=await Ke()?"https://registry.npmmirror.com":void 0;return e?[`--registry=${e}`]:[]}async function ue(){if(!(await De()).ok)throw new m(k.NODEJS_MISSING,Je())}async function Ne(e,t){return new Promise(n=>{let r=!1,i=o=>{r||(r=!0,clearTimeout(a),n(o))};e.onExit(o=>i({code:o.code,reason:o.reason==="killed"?"killed":"exited"})),e.onError(o=>i({code:-1,reason:"error",message:o.message}));let a=setTimeout(()=>{e.kill().catch(()=>{}),i({code:null,reason:"timeout"})},t)})}async function Xe(e){let t=B.get(e);if(t&&t.status==="running")return{ok:!0,procId:t.procId,reused:!0};let n=await H(e);if(!n)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${e}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${e}`});try{await ue();let r=await d.child.spawn({cmd:ie,args:["run","dev"],cwd:n.dir});return Q.set(e,r),B.set(e,{procId:r.handleId,caller:"dev-tools",kind:"dev",pid:r.pid,status:"running",cwd:n.dir,startedAt:Date.now()}),Z.delete(e),oe.set(e,Date.now()),r.onStdout(i=>me(e,"stdout",i)),r.onStderr(i=>me(e,"stderr",i)),r.onExit(()=>{let i=B.get(e);i&&(i.status="exited")}),r.onError(i=>{let a=B.get(e);a&&(a.status="error"),me(e,"stderr",`spawn error: ${i.message}`)}),{ok:!0,procId:r.handleId}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}d.registerHandler("dev-tools.buildDev",([e])=>Xe(String(e)));d.registerHandler("dev-tools.stop",async([e])=>{let t=String(e),n=Array.from(B.entries()).find(([,r])=>r.procId===t)?.[0];if(n){let r=Q.get(n);r&&await r.kill().catch(()=>{}),Q.delete(n),B.delete(n),Z.delete(n),oe.delete(n)}return{ok:!0}});d.registerHandler("dev-tools.listBuilds",()=>Array.from(B.values()));d.registerHandler("dev-tools.log",([e,t])=>{let n=Array.from(B.entries()).find(([,i])=>i.procId===String(e))?.[0];if(!n)return[];let r=typeof t=="number"&&t>0?t:0;return(Z.get(n)??[]).filter(i=>i.ts>=r)});async function Ee(e){let t=Q.get(e);t&&(await t.kill().catch(()=>{}),Q.delete(e),B.delete(e),Z.delete(e),oe.delete(e))}async function Pe(e,t){try{await ue();let n=await Tt(t),r=await d.child.spawn({cmd:ie,args:n,cwd:e}),i="";r.onStderr(o=>i+=o);let a=await Ne(r,10*60*1e3);return a.reason==="timeout"?{ok:!1,detail:`npm ${t.join(" ")} \u8D85\u65F6\uFF0810min\uFF09`}:a.reason==="error"?{ok:!1,detail:`npm ${t.join(" ")} \u542F\u52A8\u5931\u8D25\uFF1A${a.message??""}`.slice(0,300)}:a.code!==0?{ok:!1,detail:(i.trim()||`npm ${t.join(" ")} \u8FD4\u56DE\u5931\u8D25`).slice(0,300)}:{ok:!0}}catch(n){return{ok:!1,detail:`\u6267\u884C npm \u5931\u8D25\uFF1A${n instanceof Error?n.message:String(n)}`.slice(0,300)}}}function Ye(e){return Pe(e,["install","--no-audit","--no-fund"])}d.registerHandler("dev-tools.ensureDeps",async([e])=>{let t=String(e),n=await H(t);if(!n)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${t}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${t}`});if(!(await De()).ok)throw new m(k.NODEJS_MISSING,Je());let{needsWorker:i}=Ie((await V(n.dir))?.type),a=!1;if(!await ye(L(n.dir,"node_modules"))){let o=await Ye(n.dir);if(!o.ok)throw new m(k.BUILD_FAIL,{enUS:`npm install failed: ${o.detail}`,zhCN:`npm install \u5931\u8D25\uFF1A${o.detail}`});a=!0}if(i&&!await ye(L(n.dir,n.dist,"worker.js"))){let o=await Pe(n.dir,["run","build:worker"]);if(!o.ok)throw new m(k.BUILD_FAIL,{enUS:`build:worker failed: ${o.detail}`,zhCN:`build:worker \u5931\u8D25\uFF1A${o.detail}`})}return{ok:!0,installed:a}});d.registerHandler("dev-tools.checkManifest",async([e])=>{let t=String(e??"").trim();if(!t)return{ok:!1,error:{enUS:"Plugin ID cannot be empty",zhCN:"\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"}};let n=await H(t);if(!n)return{ok:!1,error:{enUS:`Dev plugin does not exist: ${t}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${t}`}};let r=await V(n.dir);return r?.id?r.id!==t?{ok:!1,error:{enUS:`The dlient.id in the manifest (${r.id}) does not match the registered ID (${t})`,zhCN:`manifest \u7684 dlient.id\uFF08${r.id}\uFF09\u4E0E\u6CE8\u518C ID\uFF08${t}\uFF09\u4E0D\u4E00\u81F4`}}:/^[a-z0-9-]+$/.test(r.id)?r.source!=="dev"?{ok:!1,error:{enUS:`This plugin is not a dev plugin (dlient.source="${r.source??"unset"}"). Change dlient.source in package.json to "dev"`,zhCN:`\u8BE5\u63D2\u4EF6\u4E0D\u662F dev \u63D2\u4EF6\uFF08dlient.source="${r.source??"\u672A\u58F0\u660E"}"\uFF09\uFF0C\u8BF7\u5C06 package.json \u7684 dlient.source \u6539\u4E3A "dev"`}}:{ok:!0,id:r.id,name:r.name}:{ok:!1,error:{enUS:`Invalid plugin ID (only lowercase letters, digits and hyphens allowed, current: ${r.id})`,zhCN:`\u63D2\u4EF6 ID \u4E0D\u5408\u6CD5\uFF08\u4EC5\u5141\u8BB8\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\uFF0C\u5F53\u524D\uFF1A${r.id}\uFF09`}}:{ok:!1,error:{enUS:"No valid plugin manifest found in the directory (dlient.id in package.json)",zhCN:"\u76EE\u5F55\u4E2D\u672A\u627E\u5230\u6709\u6548\u7684\u63D2\u4EF6 manifest\uFF08package.json \u7684 dlient.id\uFF09"}}});d.registerHandler("dev-tools.ensureEnv",async([e])=>{let t=String(e??"").trim();if(!t)return{ok:!1,error:{enUS:"Plugin ID cannot be empty",zhCN:"\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"}};let n=await H(t);if(!n)return{ok:!1,error:{enUS:`Dev plugin does not exist: ${t}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${t}`}};let{hasUI:r,needsWorker:i}=Ie((await V(n.dir))?.type),a=oe.get(t)??0;return await Qe(n,r,i,a,3e4)?(await d.plugin.dev.startWatcher(t).catch(c=>A.error(`ensureEnv ${t} startWatcher`,{error:c instanceof Error?c.message:String(c)})),{ok:!0}):{ok:!1,error:{enUS:`${i?"worker.js":"remoteEntry.js"} initial build not complete (npm run dev did not produce new artifacts)`,zhCN:`${i?"worker.js":"remoteEntry.js"} \u521D\u59CB\u6784\u5EFA\u672A\u5B8C\u6210\uFF08npm run dev \u672A\u4EA7\u51FA\u65B0\u4EA7\u7269\uFF09`}}});d.registerHandler("dev-tools.closePlugin",async([e])=>{let t=String(e??"").trim();return t?(await d.plugin.dev.stopWatcher(t).catch(n=>A.error("closePlugin stopWatcher",{pluginId:t,error:n instanceof Error?n.message:String(n)})),await d.plugin.dev.stopDevWorker(t).catch(n=>A.error("closePlugin stopDevWorker",{pluginId:t,error:n instanceof Error?n.message:String(n)})),await Ee(t),{ok:!0}):{ok:!1,error:{enUS:"Plugin ID cannot be empty",zhCN:"\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"}}});function Lt(e){return new Promise(t=>setTimeout(t,e))}async function Qe(e,t,n,r,i,a){let o=[];t&&o.push(L(e.dir,e.dist,"remoteEntry.js")),n&&o.push(L(e.dir,e.dist,"worker.js"));let c=Date.now()+i;for(;Date.now()<c;){if((await Promise.all(o.map(p=>ve(p)))).every(p=>p?.exists===!0&&p.mtimeMs>=r))return!0;if(a){let p=Array.from(B.values()).find(I=>I.procId===a);if(p&&p.status!=="running")return!1}await Lt(500)}return(await Promise.all(o.map(v=>ve(v)))).every(v=>v?.exists===!0)}d.registerStreamHandler("dev-tools.refresh",async([e],t)=>{let n=String(e??"");if(!t?.emit)return{ok:!1,error:{enUS:"refresh requires a streaming call (api.listen)",zhCN:"refresh \u9700\u8981\u6D41\u5F0F\u8C03\u7528\uFF08api.listen\uFF09"}};let r=t.emit,i=(a,o,c)=>{let g={step:a,status:o};c?.detail!==void 0&&(g.detail=c.detail),c?.procId!==void 0&&(g.procId=c.procId),r(g)};try{let a=await H(n);if(!a)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${n}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${n}`});let{hasUI:o,needsWorker:c}=Ie((await V(a.dir))?.type);i(0,"running"),await d.plugin.dev.stopDevWorker(n).catch(y=>A.error("refresh stopDevWorker",{pluginId:n,error:y instanceof Error?y.message:String(y)})),i(0,"done"),await d.plugin.dev.stopWatcher(n).catch(y=>A.error("refresh stopWatcher",{pluginId:n,error:y instanceof Error?y.message:String(y)})),i(1,"running"),await Ee(n),i(1,"done"),i(2,"running");let g=await Ye(a.dir);if(!g.ok){let y={enUS:`npm install failed: ${g.detail}`,zhCN:`npm install \u5931\u8D25\uFF1A${g.detail}`};return i(2,"error",{detail:y}),i(5,"error",{detail:y}),{ok:!1,error:y}}i(2,"done"),i(3,"running");let v=Date.now();if(c){let y=await Pe(a.dir,["run","build:worker"]);if(!y.ok){let R={enUS:`build:worker failed: ${y.detail}`,zhCN:`build:worker \u5931\u8D25\uFF1A${y.detail}`};return i(3,"error",{detail:R}),i(5,"error",{detail:R}),{ok:!1,error:R}}}let f=await Xe(n);if(!f?.ok){let y=f?.error??"unknown",R={enUS:`Failed to start build: ${y}`,zhCN:`\u6784\u5EFA\u542F\u52A8\u5931\u8D25\uFF1A${y}`};return i(3,"error",{detail:R}),i(5,"error",{detail:R}),{ok:!1,error:R}}let p=oe.get(n)??v;if(!await Qe(a,o,c,p,12e4,f.procId)){let y={enUS:`${a.dist}/${c?"worker.js":"remoteEntry.js"} was not produced (build failed or timed out)`,zhCN:`${a.dist}/${c?"worker.js":"remoteEntry.js"} \u672A\u4EA7\u51FA\uFF08\u6784\u5EFA\u5931\u8D25\u6216\u8D85\u65F6\uFF09`};return i(3,"error",{detail:y}),i(5,"error",{detail:y}),{ok:!1,error:y}}return i(3,"done"),i(4,"running"),await d.plugin.dev.startWatcher(n).catch(y=>A.error("refresh startWatcher",{pluginId:n,error:y instanceof Error?y.message:String(y)})),i(4,"done"),i(5,"done",{procId:f.procId??null}),{ok:!0,procId:f.procId??null}}catch(a){let o=a instanceof m&&a.msg!==void 0?a.msg:a instanceof Error?a.message:String(a);return A.error("refresh failed",{pluginId:n,error:typeof o=="string"?o:o.zhCN}),i(5,"error",{detail:o}),{ok:!1,error:o}}});d.onReady(()=>{A.info("worker ready",{pid:process.pid}),It(W().then(async e=>{for(let t of e)await ze(t);await ee(e)}).catch(e=>A.error("initial sync failed",{error:e instanceof Error?e.message:String(e)})))});d.onDispose(async()=>{for(let e of Q.values())await e.kill().catch(()=>{});Q.clear(),B.clear(),Z.clear(),oe.clear()});var jt=Ae({rpc:d,ensureNode:ue,awaitChild:Ne,readText:Ue,log:(e,t,n)=>A[e](t,n)});d.registerHandler("dev-tools.packDlient",async([e])=>{let t=e??{},n=String(t.pluginId??"").trim();if(!n)throw new m(k.INVALID_ARG,{enUS:"pluginId required",zhCN:"\u7F3A\u5C11 pluginId \u53C2\u6570"});let r=await H(n);if(!r)throw new m(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${n}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${n}`});return jt.run(r.dir,{pluginId:n,savePath:t.savePath?String(t.savePath):void 0})});d.registerHandler("dev-tools.revealPath",async([e])=>{let t=String(e??"").trim();if(!t)throw new m(k.INVALID_ARG,{enUS:"path required",zhCN:"\u7F3A\u5C11 path \u53C2\u6570"});return await d.os.showItemInFolder(t),{ok:!0}});
8
+ import{EventEmitter as Ye}from"node:events";var oe="CMD_NPM";function Qe(e,t=!1){let n=Buffer.from(JSON.stringify(e),"utf-8");if(t)return Buffer.concat([n,Buffer.from(`
9
+ `,"utf-8")]);let r=Buffer.alloc(4);return r.writeUInt32BE(n.length,0),Buffer.concat([r,n])}var pe=class{constructor(t,n){this.onMessage=n,this.buffer=Buffer.alloc(0),this.ndjson=t}push(t){let n=typeof t=="string"?Buffer.from(t,"utf8"):t;if(this.buffer=this.buffer.length===0?n:Buffer.concat([this.buffer,n]),this.ndjson){let r;for(;(r=this.buffer.indexOf(10))>=0;){let i=this.buffer.subarray(0,r).toString("utf-8").trim();this.buffer=this.buffer.subarray(r+1),i&&this.tryParse(i)}return}for(;this.buffer.length>=4;){let r=this.buffer.readUInt32BE(0);if(this.buffer.length<4+r)break;let i=this.buffer.subarray(4,4+r).toString("utf-8");this.buffer=this.buffer.subarray(4+r),this.tryParse(i)}}tryParse(t){try{let n=JSON.parse(t);this.onMessage(n)}catch{}}};function Ze(e,t){return{write:n=>{e.stdin?.writable&&e.stdin.write(n)},end:()=>{try{e.stdin?.end()}catch{}},onStdout:n=>e.stdout?.on("data",r=>n(r.toString())),onExit:n=>e.on("exit",r=>n(r)),onError:n=>e.on("error",r=>n(r)),kill:()=>{if(t)try{t()}catch{}else try{e.kill()}catch{}}}}function et(e){return{write:t=>{let n=typeof t=="string"?t:t.toString("utf8");e.write(n).catch(()=>{})},end:()=>{e.end().catch(()=>{})},onStdout:t=>e.onStdout(t),onExit:t=>e.onExit(n=>{t(n.code)}),onError:t=>e.onError(t),kill:()=>e.kill()}}function tt(e){let{transport:t,proc:n,dispose:r,timeoutMs:i=3e4,heartbeatTimeoutMs:a=33e3,ndjson:o=!1}=e,c=(()=>{let D=t??(n?Ze(n,r):void 0);if(!D)throw new Error("createNativeHostClient: transport or proc required");return D})(),y=new Ye,g=[],w=new Map,I=0,S=!1,h=new pe(o,D=>{A=Date.now();let C=D;if(C&&typeof C=="object"&&"ping"in C){_({pong:C.ping});return}if(C&&typeof C=="object"&&"event"in C){let P=C;y.emit(P.event,P.data);return}if(C&&typeof C=="object"&&"id"in C){let P=C,$=w.get(P.id);if(!$)return;if($.isStream){if(P.ok&&P.more){y.emit(`stream:${P.id}:data`,P.result);return}w.delete(P.id),$.timer&&clearTimeout($.timer),P.ok?$.resolve(P.result):$.reject(new Error(P.error??`native-host RPC failed: ${P.id}`));return}w.delete(P.id),$.timer&&clearTimeout($.timer),P.ok?$.resolve(P.result):$.reject(new Error(P.error??`native-host RPC failed: ${P.id}`))}});c.onStdout(D=>h.push(D));let _=D=>{S||c.write(Qe(D,o))},E=(D,C,P)=>{for(let[,$]of w)$.timer&&clearTimeout($.timer),$.reject(P);w.clear();for(let $ of g)try{$({code:C,reason:D})}catch{}};c.onExit(D=>{S||E("exit",D,new Error(`\u539F\u751F\u6A21\u5757\u8FDB\u7A0B\u5F02\u5E38\u9000\u51FA\uFF08code=${D??"unknown"}\uFF09\uFF0C\u8BF7\u91CD\u542F\u63D2\u4EF6`))}),c.onError(D=>{S||E("exit",null,new Error(`\u539F\u751F\u6A21\u5757\u8FDB\u7A0B\u542F\u52A8\u5931\u8D25: ${D.message}`))});let A=Date.now(),N=setInterval(()=>{S||Date.now()-A>a&&E("timeout",null,new Error("\u539F\u751F\u6A21\u5757\u8FDB\u7A0B\u5FC3\u8DF3\u8D85\u65F6\uFF08\u5931\u8054\uFF09\uFF0C\u8BF7\u91CD\u542F\u63D2\u4EF6"))},5e3);function V(D,C,P,$){return new Promise((K,O)=>{if(S)return O(new Error("native-host client disposed"));let z=`rpc-${++I}`,W={id:z,resolve:ne=>K(ne),reject:O,isStream:!1},X=$?.timeoutMs??i;X>0&&(W.timer=setTimeout(()=>{w.delete(z),O(new Error(`native-host RPC \u8D85\u65F6\uFF08${D}.${C} > ${X/1e3}s\uFF09`))},X)),w.set(z,W),_({id:z,service:D,method:C,params:P})})}function te(D,C,P){let $=`stream-${++I}`,K=[],O=[],z=[],W=`stream:${$}:data`,X={onData:H=>K.push(H),onDone:H=>O.push(H),onError:H=>z.push(H),abort:()=>{w.delete($),y.removeAllListeners(W)}},ne={id:$,resolve:H=>{for(let Y of O)try{Y(H)}catch{}y.removeAllListeners(W)},reject:H=>{for(let Y of z)try{Y(H)}catch{}y.removeAllListeners(W)},isStream:!0};return w.set($,ne),y.on(W,H=>{for(let Y of K)try{Y(H)}catch{}}),_({id:$,service:D,method:C,params:P}),X}function U(){if(S)return;S=!0,clearInterval(N),E("disposed",null,new Error("native-host client disposed"));try{c.end?.()}catch{}let D=c.kill();D&&typeof D.then=="function"&&D.catch(()=>{})}return{call:V,stream:te,onEvent:(D,C)=>y.on(D,C),onExit:D=>g.push(D),dispose:U}}function nt(e){let{backoffMs:t=300,maxBackoffMs:n=8e3,maxRestarts:r=10}=e,i=null,a,o=null,c=!1,y=!1,g=0,w=[],I=E=>new Promise(A=>setTimeout(A,E)),S=E=>{for(let A of w)try{A(E)}catch{}};async function h(){if(c||y)return!1;try{let E=await e.spawn();return c||y?(E.dispose?.(),!1):(e.onRestarted&&await e.onRestarted(E.client),i=E.client,a=E.dispose,g=0,E.client.onExit(A=>{i=null,a=void 0,!c&&S({code:A.code,reason:A.reason==="disposed"?"disposed":A.reason==="timeout"?"timeout":"exit"})}),!0)}catch{if(g+=1,c||g>r)return y=!0,S({code:null,reason:"dead"}),!1;let A=Math.min(t*2**Math.min(g-1,8),n);return await I(A),h()}}let _=async()=>{if(i)return i;if(c)throw new Error("native-host \u5DF2\u505C\u6B62");if(y)throw new Error("native-host \u591A\u6B21\u542F\u52A8\u5931\u8D25\uFF0C\u8BF7\u91CD\u542F\u63D2\u4EF6");o||(o=h());let E=await o;if(o=null,!E||!i)throw new Error("native-host \u4E0D\u53EF\u7528");return i};return{call:async(E,A,N,V)=>(await _()).call(E,A,N,V),onExit:E=>w.push(E),stop:async()=>{c=!0;let E=a,A=i;i=null,a=void 0;try{A?.dispose()}catch{}if(E&&E!==A?.dispose)try{await E()}catch{}}}}var rt=["app.getVersion","app.getPath","app.isActive","app.isHidden","app.getName","app.getLocale","app.getLocaleCountryCode","app.getSystemLocale","app.getPreferredSystemLanguages","app.notify","app.setAutoLaunch","app.event","app.createNativeHost","app.createNativeClient","app.disposeNativeClient","app.window.close","app.window.focus","app.window.blur","app.window.show","app.window.hide","app.window.maximize","app.window.unmaximize","app.window.minimize","app.window.restore","app.window.isMaximized","app.window.setFullScreen","app.data.read","app.data.write","app.crypt.encrypt","app.crypt.decrypt","app.shortcut.register","app.shortcut.unregister","app.menu.popup",...["read","write","clear","has","availableFormats"].map(e=>`clipboard.${e}`),...["Text","HTML","RTF","Bookmark","FindText","Image","Buffer"].flatMap(e=>[`clipboard.read${e}`,`clipboard.write${e}`]),"dialog.showMessageBox","dialog.showOpenDialog","dialog.showSaveDialog","fs.read","fs.stat","fs.listDir","fs.watch","fs.unwatch","fs.mkdir","fs.write","fs.append","fs.delete","fs.copyDir","fs.lock","fs.unlock","fs.withLock","i18n.getLocale","net.isOnline","net.fetch","net.request","net.getFreePort","net.probePort","nodejs.checkLocal","nodejs.checkBundled","nodejs.resolveRuntime","nodejs.install","notification.isSupported","notification.send","notification.remove","notification.removeGroup","notification.subscribe","notification.unsubscribe","log.write","os.openExternal","os.showItemInFolder","permission.plugin.list","permission.revoke","permission.request","permission.list","plugin.invoke","plugin.requestGrant","plugin.capabilities","plugin.registry.report","plugin.start","plugin.stop","plugin.system","plugin.scanInstalled","plugin.runtimeList","plugin.installLocal","plugin.install","plugin.isRunning","plugin.cleanupUninstall","plugin.setActive","plugin.dev.selectDirectory","plugin.dev.getDirInfo","plugin.dev.sync","plugin.dev.startWatcher","plugin.dev.stopWatcher","plugin.dev.startDevWorker","plugin.dev.stopDevWorker","plugin.dev.isPortReady","plugin.dev.readLogs","plugin.dev.clearLogs","plugin.dev.list","plugin.dev.remove","plugin.logs.subscribe","plugin.logs.unsubscribe","powerSaveBlocker.start","powerSaveBlocker.stop","powerSaveBlocker.isStarted","screen.getCursorScreenPoint","screen.getPrimaryDisplay","screen.getAllDisplays","screen.getDisplayNearestPoint","screen.getDisplayMatching","screen.screenToDipPoint","screen.dipToScreenPoint","screen.screenToDipRect","screen.dipToScreenRect","system.getIdleState","system.listenNativeTheme","webview.create","webview.update","webview.destroy","webview.setVisible","webview.webContentsCall","webview.showWebviewByPlugin","webview.hideWebviewByPlugin"];function it(e,t,n){let r=t.split("."),i=r.pop(),a=e;for(let o of r)(typeof a[o]!="object"||a[o]===null)&&(a[o]={}),a=a[o];a[i]=(...o)=>n(t,o)}function st(e){let t={};for(let n of rt)it(t,n,e);return t}var ot="__dlientPoolCtx",at="__dlientRpcTable",J={OK:0,METHOD_NOT_REGISTERED:-2101,INTERNAL:-2200,THROW_ERROR:-2201};var v=class extends Error{constructor(t,n){super(typeof n=="string"?n:n?.zhCN??n?.enUS??`plugin error ${t}`),this.name="PluginError",this.code=t,this.msg=n}};function fe(e){if(e&&typeof e=="object"&&typeof e.code=="number")return e.code}function dt(e){if(e instanceof v&&e.msg!==void 0)return e.msg;if(e&&typeof e=="object"&&"msg"in e){let t=e.msg;if(typeof t=="string"||t&&typeof t=="object"&&typeof t.enUS=="string")return t}return e instanceof Error?e.message:String(e)}function ct(e){return!!e&&typeof e=="object"&&typeof e.code=="number"&&typeof e.from=="string"}function lt(e,t){let n=new Error(t);return n.code=e,n}function Pe(e){let t=new Map,n=new Set,r=0,i=new Map,a=null,o=new Map,c,y,g=[],w=[],I=[],S=!1,h=()=>{if(!S){S=!0;for(let s of w)try{s()}catch(l){console.error(`[plugin:${N}] onReady failed:`,l)}}},_=globalThis[ot],E=process.parentPort,A=_?.controlPort??(typeof process<"u"?E:void 0),N=_?.pluginId??e,V=new Map,te=new Map,U=s=>{A?.postMessage(s)},D=s=>({code:J.OK,data:s,from:N}),C=(s,l)=>({code:s,msg:l,data:null,from:N}),P=s=>{a&&a.postMessage(s)},$=s=>{let l=s.data;switch(l.type){case"request":ne(l,!1);break;case"listen":ne(l,!0);break;case"cancel":o.get(l.request_id)?.abort(),o.delete(l.request_id);break}},K=new Set,O,z=s=>{let l=!K.has(s);O&&a&&a!==s&&(a.off?.("message",O),O=void 0),a=s,l&&(K.add(s),O=u=>{a===s&&$(u)},s.on("message",O),s.start?.()),U({type:"direct-port-ready",pluginId:N}),h()},W=_?.directPort;W&&z(W);let X=globalThis[at]??={};X[N]={setDirectPort:z};function ne(s,l){let u=t.get(s.method);if(!u){let b=`Method "${s.method}" not found`;P({type:"error",request_id:s.request_id,error:b,error_code:J.METHOD_NOT_REGISTERED,result:C(J.METHOD_NOT_REGISTERED,b)});return}let f=new AbortController;o.set(s.request_id,f);let m=(b,M)=>{P({type:"stream",request_id:s.request_id,chunk:b,data:M?.data})},p={from_plugin_id:s.from_plugin_id,request_id:s.request_id,data:s.data,signal:f.signal,emit:l?m:void 0};Promise.resolve().then(()=>u(s.args,p)).then(b=>{if(f.signal.aborted)return;let M=b?.data,q=M instanceof ArrayBuffer?M:void 0,re=q!==void 0?b.result:b,x=ct(re)?re:D(re);P(l?{type:"stream-done",request_id:s.request_id,result:x}:{type:"response",request_id:s.request_id,result:x,data:q})}).catch(b=>{if(f.signal.aborted)return;let M=b instanceof Error?b.message:String(b),q=fe(b)??J.THROW_ERROR,re=C(q,dt(b));P(l?{type:"stream-error",request_id:s.request_id,error:M,error_code:q}:{type:"error",request_id:s.request_id,error:M,error_code:q,result:re})}).finally(()=>{o.delete(s.request_id)})}if(A){let s=Date.now();A.on("message",l=>{let u=l,f=u.data;switch(s=Date.now(),f.type){case"init":{f.pluginId&&(N=f.pluginId),U({type:"ready",pluginId:N,capabilities:Array.from(t.keys())}),h();break}case"port-setup":{let[m]=u.ports??[];m&&z(m);break}case"rpc-call":H(f);break;case"host-api-response":Y(f);break;case"child-control-response":Je(f);break;case"child-event":{let p=f.child,b=p?.handleId;if(!b)break;let M=V.get(b);if(!M)break;p.event==="stdout"?M.onStdout?.(p.data??""):p.event==="stderr"?M.onStderr?.(p.data??""):p.event==="exit"?M.onExit?.({code:p.code??null,signal:p.signal??void 0,reason:"exited"}):p.event==="error"&&M.onError?.(new Error(p.data??"spawn error"));break}case"notification-event":{let m=f,p=te.get(m.id);if(!p)break;let b=p.events.get(m.event);if(!b)break;for(let M of Array.from(b))try{M(m.payload)}catch(q){console.error(`[plugin:${N}] notification "${m.event}" handler error:`,q)}break}case"snapshot-request":{let m=f;c&&Promise.resolve().then(()=>c()).then(p=>{let b={type:"snapshot-response",pluginId:N,request_id:m.request_id,snapshot:p};U(b)}).catch(p=>{let b={type:"snapshot-response",pluginId:N,request_id:m.request_id,error:p instanceof Error?p.message:String(p)};U(b)});break}case"snapshot-restore":{let m=f;y&&Promise.resolve().then(()=>y(m.snapshot)).catch(p=>console.error(`[plugin:${e}] snapshot restore failed:`,p));break}case"heartbeat":break;case"dispose":{(async()=>{for(let p=I.length-1;p>=0;p--)try{await I[p]()}catch(b){console.error(`[plugin:${N}] onDispose "${p}" failed:`,b)}I.length=0;for(let p=g.length-1;p>=0;p--)try{await g[p]()}catch(b){console.error(`[plugin:${N}] dispose "${p}" failed:`,b)}g.length=0,U({type:"dispose-done",pluginId:N})})();break}}}),A.start?.(),setInterval(()=>{U({type:"heartbeat",pluginId:N,ts:Date.now()})},1e4),setInterval(()=>{if(Date.now()-s>3e4){let l=new Error("Main process lost (no message for 30s)");for(let{reject:u}of i.values())u(l);i.clear()}},5e3)}let H=s=>{let l=t.get(s.method),u={type:"rpc-response",id:s.id,pluginId:N};if(!l)u.error=`Method "${s.method}" not found`,u.error_code=J.METHOD_NOT_REGISTERED;else{let f={from_plugin_id:s.from_plugin_id??"",request_id:s.id,signal:new AbortController().signal};try{let m=l(s.args,f);if(m instanceof Promise){m.then(p=>{u.result=p,U(u)},p=>{u.error=p.message,u.error_code=fe(p)??J.INTERNAL,U(u)});return}u.result=m}catch(m){u.error=m instanceof Error?m.message:String(m),u.error_code=fe(m)??J.INTERNAL}}U(u)},Y=s=>{let l=i.get(s.id);l&&(i.delete(s.id),s.error?l.reject(lt(s.error_code??J.INTERNAL,s.error)):l.resolve(s.result))},ue=new Map,Ve=0,Je=s=>{let l=ue.get(s.id);l&&(ue.delete(s.id),s.ok?l.resolve():l.reject(new Error(s.reason??"child control failed")))},Ee=s=>{U({type:"child-subscribe",pluginId:N,handleId:s})},de=(s,l,u)=>{let f=`child-ctl-${N}-${++Ve}`,m={type:"child-control",id:f,pluginId:N,handleId:s,op:l,data:u};return new Promise((p,b)=>{ue.set(f,{resolve:p,reject:b}),U(m)})};return t.set("webview:create",([s])=>R("webview.create",[s])),t.set("webview:update",([s])=>R("webview.update",[s])),t.set("webview:destroy",([s])=>R("webview.destroy",[String(s??"")])),t.set("webview:setVisible",([s])=>R("webview.setVisible",[s])),t.set("webview:webContents:call",([s])=>R("webview.webContentsCall",[s])),t.set("onWebContentsEvent",([s])=>{let{viewId:l,name:u,args:f}=s??{};if(!l||!u)return;U({type:"push",pluginId:N,event:"webview:event",data:{viewId:l,name:u,args:f}})}),{...st((s,l)=>R(s,l)),child:{spawn:async s=>{let l=await R("child.spawn",[{...s}]),u=String(l?.handleId??"");if(!u)throw new Error("child.spawn: handleId missing");return Ne(u,typeof l?.pid=="number"?l.pid:0)},execFile:s=>R("child.execFile",[{...s}])},notification:{isSupported:async()=>!!await R("notification.isSupported",[]),send:s=>Ke(s),remove:async s=>{await R("notification.remove",[String(s)])},removeGroup:async()=>{await R("notification.removeGroup",[])},subscribe:async s=>{await R("notification.subscribe",[s])},unsubscribe:async s=>{await R("notification.unsubscribe",[s])}},getPluginId:()=>N,registerHandler:(s,l)=>{t.set(s,l),n.delete(s)},registerSnapshotHandler:s=>{c=s},registerRestoreHandler:s=>{y=s},effect:s=>{let l=!1,u;try{let f=s();f instanceof Promise?f.then(m=>{typeof m=="function"&&(u=m,g.push(u),l=!0)}).catch(m=>console.error(`[plugin:${N}] effect install failed:`,m)):typeof f=="function"&&(u=f,g.push(u),l=!0)}catch(f){console.error(`[plugin:${N}] effect install failed:`,f)}return l?u:void 0},onReady:s=>{if(w.push(s),S)try{s()}catch(l){console.error(`[plugin:${N}] onReady failed:`,l)}},onDispose:s=>{I.push(s)},registerStreamHandler:(s,l)=>{t.set(s,l),n.add(s)},push:(s,l)=>{U({type:"push",pluginId:N,event:s,data:l})},registerChildEvent:(s,l)=>{V.set(s,l)},unregisterChildEvent:s=>{V.delete(s)},childSubscribe:s=>Ee(s),childControl:(s,l,u)=>de(s,l,u),success:s=>D(s),error:(s,l)=>C(s,l),createNativeHost:async(s,l)=>{let u="";try{let x=await R("nodejs.resolveRuntime",[]);u=typeof x?.node=="string"?x.node:""}catch{}if(!u)return{host:null,client:null,error:"createNativeHost: nodejs runtime unavailable"};let f={};try{f=await R("app.createNativeHost",[{fileName:String(s),node:u}])}catch(x){return{host:null,client:null,error:x instanceof Error?x.message:String(x)}}let m=String(f?.handleId??"");if(!m)return{host:null,client:null,error:"createNativeHost: no handle"};let p=Ne(m,typeof f?.pid=="number"?f.pid:0),b;try{b=tt({transport:et(p)})}catch(x){return{host:null,client:null,error:x instanceof Error?x.message:String(x)}}let M=[],q=nt({spawn:async()=>({client:b,dispose:()=>void p.kill()}),onRestarted:async()=>{for(let x of M)try{x()}catch{}},maxRestarts:l?.maxRestarts,backoffMs:l?.backoffMs,maxBackoffMs:l?.maxBackoffMs});return{host:Object.assign(q,{onRestarted:x=>void M.push(x)}),client:b,error:void 0}}};function Ne(s,l){let u={};return V.set(s,u),Ee(s),{handleId:s,pid:l,kill:()=>(V.delete(s),de(s,"kill")),onStdout:f=>{u.onStdout=f},onStderr:f=>{u.onStderr=f},onExit:f=>{u.onExit=f},onError:f=>{u.onError=f},write:f=>de(s,"write",f),end:()=>de(s,"end")}}async function Ke(s){let l=await R("notification.send",[s]),u=String(l?.id??"");if(!u)throw new Error("notification.send: id missing");return Xe(u)}function Xe(s){let l=new Map;te.set(s,{events:l});let u={id:s,on(f,m){let p=l.get(f)??[];return p.push(m),l.set(f,p),u},close:async()=>{te.delete(s),await R("notification.remove",[s])}};return R("notification.subscribe",[{id:s}]).catch(()=>{}),u}function R(s,l){let u=`host-api-${N}-${++r}`,f={type:"host-api-call",id:u,method:s,args:l,pluginId:N};return new Promise((m,p)=>{i.set(u,{resolve:m,reject:p}),U(f)})}}import{dirname as ut,join as T,normalize as $e}from"node:path";import{fileURLToPath as ft}from"node:url";var k={INVALID_ARG:-3001,PACKAGE_INVALID:-3002,BUILD_FAIL:-3003,NOT_FOUND:-3004,AUTH_FAIL:-3005,NETWORK_FAIL:-3006,SIGNATURE_FAIL:-3007,UPLOAD_FAIL:-3008,INSTALL_LOCAL_FAIL:-3009,NODEJS_MISSING:-3010,DUPLICATE:-3011,PERMISSION_DENIED:-3012,CANCELED:-3013};var d=Pe("dev-tools"),L={debug:(e,t)=>void d.log.write("debug",e,t),info:(e,t)=>void d.log.write("info",e,t),warn:(e,t)=>void d.log.write("warn",e,t),error:(e,t)=>void d.log.write("error",e,t)};async function he(e){try{let t=await d.fs.stat(e);return{exists:!0,size:t?.size??0,mtimeMs:t?.mtimeMs??0}}catch{return null}}function me(e){return he(e).then(t=>t?.exists===!0)}async function Ae(e){try{return String(await d.fs.read(e))}catch{return null}}async function pt(e){try{return String(await d.fs.read(e,{base64:!0}))}catch{return null}}async function Re(e){await d.fs.mkdir(e)}async function Me(e,t){await d.fs.write(e,t)}async function gt(e,t){await d.fs.write(e,{base64:t})}function wt(e){return typeof e=="string"?e:void 0}var ge=Promise.resolve();function F(){return d.app.data.read("plugins.json").then(e=>Array.isArray(e)?e:[])}function ie(e){return ge=ge.then(()=>d.app.data.write("plugins.json",e)),ge}var Le=Promise.resolve();function ht(e){Le=e.then(()=>{},()=>{})}function mt(){return Le}async function ye(e,t){try{let n=await d.permission.request([{type:"fs",path:e,mode:["read","write"]}],t);return!(n?.denied&&n.denied.length>0)}catch(n){return L.warn("ensureDirAccess failed",{dir:e,error:n instanceof Error?n.message:String(n)}),!1}}async function vt(){let e=await F(),t=e.map(o=>o.path).filter(o=>!!o);if(t.length===0)return[];let n=await d.permission.request(t.map(o=>({type:"fs",path:o,mode:["read","write"]})),"dev \u63D2\u4EF6\u76EE\u5F55\u8BFB\u5199\uFF08\u540C\u610F\u540E\u7EB3\u5165 dev-tools \u7BA1\u7406\uFF1B\u62D2\u7EDD\u7684\u63D2\u4EF6\u5C06\u4ECE\u5217\u8868\u79FB\u9664\uFF09").catch(()=>null),r=new Set(n?.denied??[]);if(r.size===0)return[];let i=[],a=e.filter(o=>!o.path||!r.has(o.path)?!0:(i.push(o.id),!1));if(i.length>0){await ie(a);for(let o of i)await ke(o);await ee(a),L.warn("dev dirs denied, removed from plugins.json",{removed:i})}return i}async function Ce(e){try{let t=await F(),n=$e(e),r=t.find(a=>$e(String(a.path??""))===n);if(!r)return;let i=t.filter(a=>a!==r);if(i.length===t.length)return;await ie(i),await ke(r.id),await ee(i),L.warn("dev entry removed (dir read failed)",{id:r.id,dir:e})}catch(t){L.error("dropEntryIfRegistered failed",{dir:e,error:t instanceof Error?t.message:String(t)})}}async function ee(e){await d.plugin.dev.sync(e).catch(()=>{})}async function ke(e){xe(e),await Ie(e)}function yt(e){return JSON.stringify({permissions:e.permissions,dependencies:e.dependencies,fsDirs:e.fsDirs,spawnCmds:e.spawnCmds,expose:e.expose})}async function G(e){if(!await ye(e,"dev \u63D2\u4EF6\u76EE\u5F55\u8BFB\u5199\uFF08\u540C\u610F\u540E\u7EB3\u5165 dev-tools \u7BA1\u7406\uFF09"))return L.warn("readManifest denied dir access",{dir:e}),Ce(e),null;try{await mt();let t=await d.fs.read(`${e}/package.json`),n=JSON.parse(String(t)),r=n.dlient??{};return{id:typeof r.id=="string"?r.id:void 0,name:typeof r.name=="string"?r.name:r.name?.default,dist:typeof r.dist=="string"?r.dist:void 0,version:typeof n.version=="string"?n.version:void 0,type:typeof r.type=="string"?r.type:void 0,system:r.system===!0,icon:wt(r.icon),source:typeof r.source=="string"?r.source:void 0,nodeVersion:typeof r.nodeVersion=="string"?r.nodeVersion:void 0,authHash:yt(r),dependencies:Array.isArray(r.dependencies)?r.dependencies.map(i=>String(i)):r.dependencies&&typeof r.dependencies=="object"?Object.keys(r.dependencies):void 0}}catch(t){return L.warn("readManifest failed",{dir:e,error:t instanceof Error?t.message:String(t)}),Ce(e),null}}function Se(e){let t=e??"ui";return{hasUI:t!=="worker",needsWorker:t!=="ui"}}var le=new Map,ae=new Map,ve=new Map,kt=1500;function xe(e){let t=le.get(e);t&&(le.delete(e),d.fs.unwatch(t).catch(()=>{}));let n=ae.get(e);n&&(clearTimeout(n),ae.delete(e))}async function Ue(e){if(xe(e.id),!!await me(T(e.path,"package.json")))try{let t=String(await d.fs.watch(e.path));le.set(e.id,t)}catch{}}d.registerHandler("dev-tools.fs-watch-event",([e,t])=>{if(String(t??"").replace(/\\/g,"/")!=="package.json")return;let n=Array.from(le.entries()).find(([,i])=>i===e)?.[0];if(!n)return;let r=ae.get(n);r&&clearTimeout(r),ae.set(n,setTimeout(async()=>{ae.delete(n);let i=ve.get(n);if(i&&Date.now()-i<kt){ve.delete(n);return}try{let a=await F(),o=a.find(w=>w.id===n);if(!o)return;let c=await G(o.path);if(!c)return;let y={...o,name:c.name??o.name,version:c.version,type:c.type,dist:c.dist??o.dist,system:c.system===!0,icon:c.icon,authHash:c.authHash},g=a.map(w=>w.id===n?y:w);await ie(g),await ee(g)}catch(a){L.error("sync package.json failed",{pluginId:n,error:a instanceof Error?a.message:String(a)})}},500))});d.registerHandler("dev-tools.list",async()=>(await F()).sort((t,n)=>t.addedAt-n.addedAt));async function Te(){return(await d.dialog.showOpenDialog(["fs.read","fs.write"],{properties:["openDirectory"]}).catch(()=>null))?.filePaths?.[0]??null}d.registerHandler("dev-tools.selectDirectory",()=>Te());d.registerHandler("dev-tools.checkImportable",async([e])=>{let t=String(e??"").trim();if(!t)return{ok:!1,error:{enUS:"Plugin directory cannot be empty",zhCN:"\u63D2\u4EF6\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A"}};if(!await ye(t,"\u5BFC\u5165\u63D2\u4EF6\u76EE\u5F55"))return{ok:!1,error:{enUS:"Canceled: no access permission granted to this directory",zhCN:"\u5DF2\u53D6\u6D88\uFF1A\u672A\u6388\u4E88\u8BE5\u76EE\u5F55\u7684\u8BBF\u95EE\u6743\u9650"}};let n=await G(t);return n?.id?/^[a-z0-9-]+$/.test(n.id)?{ok:!0,needsDevChange:n.source!=="dev",id:n.id,name:n.name??n.id}:{ok:!1,error:{enUS:`Invalid plugin ID (only lowercase letters, digits and hyphens allowed, current: ${n.id})`,zhCN:`\u63D2\u4EF6 ID \u4E0D\u5408\u6CD5\uFF08\u4EC5\u5141\u8BB8\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\uFF0C\u5F53\u524D\uFF1A${n.id}\uFF09`}}:{ok:!1,error:{enUS:"No valid plugin manifest found in the directory (dlient.id in package.json)",zhCN:"\u76EE\u5F55\u4E2D\u672A\u627E\u5230\u6709\u6548\u7684\u63D2\u4EF6 manifest\uFF08package.json \u7684 dlient.id\uFF09"}}});d.registerHandler("dev-tools.changeToDev",async([e])=>{let t=String(e??"").trim();if(!t)throw new v(k.INVALID_ARG,{enUS:"Plugin directory cannot be empty",zhCN:"\u63D2\u4EF6\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A"});if(!await ye(t,"\u5199\u56DE\u63D2\u4EF6 manifest\uFF08dlient.source=dev\uFF09"))throw new v(k.PERMISSION_DENIED,{enUS:"Canceled: no access permission granted to this directory",zhCN:"\u5DF2\u53D6\u6D88\uFF1A\u672A\u6388\u4E88\u8BE5\u76EE\u5F55\u7684\u8BBF\u95EE\u6743\u9650"});let n=String(await d.fs.read(`${t}/package.json`).catch(()=>""));if(!n)throw new v(k.PACKAGE_INVALID,{enUS:"No package.json found in the directory",zhCN:"\u76EE\u5F55\u4E2D\u672A\u627E\u5230 package.json"});let r=JSON.parse(n),i={...r.dlient??{}};return i.source==="dev"?{ok:!0,changed:!1}:(i.source="dev",await d.fs.write(`${t}/package.json`,`${JSON.stringify({...r,dlient:i},null,ze(n))}
10
+ `),{ok:!0,changed:!0})});async function He(e){let t=String(e??"").trim();if(!t)throw new v(k.INVALID_ARG,{enUS:"Plugin directory cannot be empty",zhCN:"\u63D2\u4EF6\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A"});let n=await G(t);if(!n?.id)throw new v(k.PACKAGE_INVALID,{enUS:"No valid plugin manifest found in the directory (dlient.id in package.json)",zhCN:"\u76EE\u5F55\u4E2D\u672A\u627E\u5230\u6709\u6548\u7684\u63D2\u4EF6 manifest\uFF08package.json \u7684 dlient.id\uFF09"});if(n.source!=="dev")throw new v(k.PACKAGE_INVALID,{enUS:`This plugin is not a dev plugin (dlient.source="${n.source??"unset"}"). Change dlient.source in package.json to "dev" and add it again.`,zhCN:`\u8BE5\u63D2\u4EF6\u4E0D\u662F dev \u63D2\u4EF6\uFF08dlient.source="${n.source??"\u672A\u58F0\u660E"}"\uFF09\u3002\u8BF7\u5C06 package.json \u7684 dlient.source \u6539\u4E3A "dev" \u540E\u91CD\u65B0\u6DFB\u52A0\u3002`});if(!/^[a-z0-9-]+$/.test(n.id))throw new v(k.INVALID_ARG,{enUS:`Invalid plugin ID (only lowercase letters, digits and hyphens allowed, current: ${n.id}). Edit dlient.id in package.json`,zhCN:`\u63D2\u4EF6 ID \u4E0D\u5408\u6CD5\uFF08\u4EC5\u5141\u8BB8\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\uFF0C\u5F53\u524D\uFF1A${n.id}\uFF09\uFF0C\u8BF7\u4FEE\u6539 package.json \u7684 dlient.id`});let r=await F(),i=r.find(c=>c.id===n.id),a={id:n.id,name:n.name??n.id,path:t,dist:n.dist??"dist",version:n.version,type:n.type,system:n.system===!0,icon:n.icon,authHash:n.authHash,addedAt:i?.addedAt??Date.now()},o=i?r.map(c=>c.id===a.id?a:c):[...r,a];return await ie(o),await Ue(a),await ee(o),a}d.registerHandler("dev-tools.register",([e])=>He(String(e)));d.registerHandler("dev-tools.remove",async([e])=>{let t=String(e),n=await F(),r=n.filter(i=>i.id!==t);return r.length===n.length?{ok:!1,error:{enUS:`Dev plugin not registered: ${t}`,zhCN:`dev \u63D2\u4EF6\u672A\u6CE8\u518C: ${t}`}}:(await ie(r),await ke(t),await ee(r),{ok:!0})});async function j(e){let n=(await F()).find(r=>r.id===e);return n?{dir:n.path,dist:n.dist}:await d.plugin.dev.getDirInfo(e)}d.registerHandler("dev-tools.getDirInfo",([e])=>j(String(e)));var je=["name","description","type","platforms","icon","tags"];async function Oe(e){let t=await j(e);if(!t)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${e}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${e}`});let n=String(await d.fs.read(`${t.dir}/package.json`));return{dir:t.dir,raw:n}}function ze(e){let t=/\n([ \t]+)"/.exec(e);return t?t[1].includes(" ")?" ":t[1].length:2}d.registerHandler("dev-tools.readSettings",async([e])=>{let{dir:t,raw:n}=await Oe(String(e)),r=JSON.parse(n),i=r.dlient??{},a={};for(let o of je)i[o]!==void 0&&(a[o]=i[o]);return{dir:t,version:typeof r.version=="string"?r.version:void 0,id:typeof i.id=="string"?i.id:void 0,dlient:a}});d.registerHandler("dev-tools.writeSettings",async([e,t])=>{let n=String(e),r=t??{},{dir:i,raw:a}=await Oe(n),o=JSON.parse(a),c={...o.dlient??{}},y=!1;for(let I of je){if(!(I in r))continue;let S=r[I];if(S==null){I in c&&(delete c[I],y=!0);continue}JSON.stringify(c[I])!==JSON.stringify(S)&&(c[I]=S,y=!0)}if(!y)return{ok:!0,changed:!1};let g=JSON.stringify({...o,dlient:c},null,ze(a));ve.set(n,Date.now()),await d.fs.write(`${i}/package.json`,`${g}
11
+ `);let w=await G(i);if(w){let I=await F(),S=I.find(h=>h.id===n);if(S){let h={...S,name:w.name??S.name,version:w.version,type:w.type,dist:w.dist??S.dist,system:w.system===!0,icon:w.icon,authHash:w.authHash},_=I.map(E=>E.id===n?h:E);await ie(_),await ee(_)}}return{ok:!0,changed:!0}});d.registerHandler("dev-tools.writeAsset",async([e,t,n])=>{let r=String(e),i=String(t??"");if(!/^icon[\w-]*\.(svg|png)$/.test(i))throw new v(k.INVALID_ARG,{enUS:`Invalid icon file name: ${i}`,zhCN:`\u975E\u6CD5\u7684\u56FE\u6807\u6587\u4EF6\u540D: ${i}`});let a=await j(r);if(!a)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${r}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${r}`});let o=Buffer.from(String(n??""),"base64");if(o.length===0||o.length>200*1024)throw new v(k.INVALID_ARG,{enUS:"Icon content is invalid or exceeds 200KB",zhCN:"\u56FE\u6807\u5185\u5BB9\u975E\u6CD5\u6216\u8D85\u8FC7 200KB"});let c=T(a.dir,"assets");return await Re(c),await gt(T(c,i),String(n??"")),L.info(`writeAsset ${r} ${i} ${o.length}B`),{ok:!0,path:`assets/${i}`}});d.registerHandler("dev-tools.readAsset",async([e,t])=>{let n=String(e),r=String(t??"");if(!/^icon[\w-]*\.(svg|png)$/.test(r))throw new v(k.INVALID_ARG,{enUS:`Invalid icon file name: ${r}`,zhCN:`\u975E\u6CD5\u7684\u56FE\u6807\u6587\u4EF6\u540D: ${r}`});let i=await j(n);if(!i)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${n}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${n}`});let a=T(i.dir,"assets",r),o=await pt(a);if(o==null||o.length===0)return{ok:!0,data:"",mime:"",exists:!1};let c=r.endsWith(".png")?"image/png":"image/svg+xml";return{ok:!0,data:o,mime:c,exists:!0}});var Be=["index.md","index.zh-CN.md","index.en-US.md","SKILL.md"];d.registerHandler("dev-tools.readMarkdown",async([e,t])=>{let n=String(e),r=String(t??"");if(!Be.includes(r))throw new v(k.INVALID_ARG,{enUS:`Invalid markdown file name: ${r}`,zhCN:`\u975E\u6CD5\u7684 markdown \u6587\u4EF6\u540D: ${r}`});let i=await j(n);if(!i)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${n}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${n}`});let a=T(i.dir,"assets",r);try{return{ok:!0,content:String(await d.fs.read(a)),exists:!0}}catch{return{ok:!0,content:"",exists:!1}}});d.registerHandler("dev-tools.writeMarkdown",async([e,t,n])=>{let r=String(e),i=String(t??"");if(!Be.includes(i))throw new v(k.INVALID_ARG,{enUS:`Invalid markdown file name: ${i}`,zhCN:`\u975E\u6CD5\u7684 markdown \u6587\u4EF6\u540D: ${i}`});let a=await j(r);if(!a)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${r}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${r}`});let o=T(a.dir,"assets");return await Re(o),await Me(T(o,i),String(n??"")),L.info(`writeMarkdown ${r} ${i} ${String(n??"").length}B`),{ok:!0}});async function Fe(e){let t=await d.nodejs.resolveRuntime(e?{version:e}:void 0).catch(()=>null);return t==null||t.source==="none"?{ok:!1,reason:"runtime-missing"}:{ok:!0,version:t.version}}function St(e){let t=/^v?(\d+)\.?(\d+)?\.?(\d+)?/.exec(e.trim().replace(/^>=?/,""));return t?[Number(t[1]),Number(t[2]??0),Number(t[3]??0)]:null}async function bt(){try{let e=T(ut(ft(import.meta.url)),"..","package.json"),t=await d.fs.read(e),r=JSON.parse(String(t)).dlient??{};return{nodeVersion:typeof r.nodeVersion=="string"?r.nodeVersion:void 0}}catch{return null}}async function It(){let t=[(await bt())?.nodeVersion],n=await F();for(let a of n){let o=await G(a.path);o?.nodeVersion&&t.push(o.nodeVersion)}let r,i=null;for(let a of t){if(!a)continue;let o=St(a);o&&(!i||o[0]>i[0]||o[0]===i[0]&&o[1]>i[1]||o[0]===i[0]&&o[1]===i[1]&&o[2]>i[2])&&(r=a,i=o)}return r}function Dt(){return{enUS:"No Node.js runtime detected. Install system Node.js, or install the host-bundled runtime via nodejs.install, then retry.",zhCN:"\u672A\u68C0\u6D4B\u5230 Node.js \u8FD0\u884C\u73AF\u5883\uFF0C\u8BF7\u5B89\u88C5\u7CFB\u7EDF Node.js \u6216\u5B89\u88C5\u5BBF\u4E3B\u5185\u7F6E\u8FD0\u884C\u65F6\u540E\u91CD\u8BD5"}}d.registerHandler("dev-tools.checkNode",async()=>{await vt();let e=await It(),t=await Fe(e);return{ready:t.ok,reason:t.ok?void 0:t.reason,version:t.ok?t.version:void 0,requiredVersion:e}});d.registerHandler("dev-tools.installNode",async([e])=>{let t=typeof e=="string"&&e?e:void 0,n=await d.nodejs.install(t);if(!n?.ok)throw new v(k.NODEJS_MISSING,{enUS:`Failed to install the bundled Node.js runtime${n?.error?`: ${n.error}`:""}`,zhCN:`\u5B89\u88C5\u5BBF\u4E3B\u5185\u7F6E Node.js \u8FD0\u884C\u65F6\u5931\u8D25${n?.error?`\uFF1A${n.error}`:""}`});return{ok:!0,version:n.version}});async function Et(){return[]}function Nt(e,t){return typeof e=="string"?e===t:e&&typeof e=="object"?Object.values(e).some(n=>n===t):!1}async function Pt(e,t){let n=T(e,"package.json"),r=await Ae(n);if(r==null)return;let i=JSON.parse(r);i.dlient={...i.dlient??{},name:t},await Me(n,JSON.stringify(i,null,2))}var $t=18e4,Ct="@dlient-open/create-plugin";async function _t(e,t,n=$t){let r;try{r=await d.child.spawn({cmd:oe,args:["exec","--yes","--",Ct,e,"--dir",t,"--skip-install","--no-git"],cwd:t})}catch(c){return{ok:!1,detail:String(c instanceof Error?c.message:c).slice(0,300)}}let i="";r.onStdout(c=>i+=c),r.onStderr(c=>i+=c);let a=await be(r,n);if(a.reason==="timeout")return{ok:!1,detail:`\u521B\u5EFA\u63D2\u4EF6\u8D85\u65F6\uFF08${Math.round(n/1e3)}s\uFF09${i.trim()?`\uFF1A${i.trim().slice(0,300)}`:""}`};let o=i.trim();return a.code!==0?{ok:!1,detail:(o||`exit ${a.code}`).slice(0,500)}:{ok:!0}}d.registerHandler("dev-tools.devCreatePlugin",async([e,t])=>{let n=String(e??"").trim(),r=String(t??"").trim();if(!/^[a-z][a-z0-9-]*$/.test(n))throw new v(k.INVALID_ARG,{enUS:"Invalid plugin ID (must start with a lowercase letter; lowercase letters/digits/hyphens only)",zhCN:"\u63D2\u4EF6 ID \u4E0D\u5408\u6CD5\uFF08\u987B\u4EE5\u5C0F\u5199\u5B57\u6BCD\u5F00\u5934\uFF0C\u4EC5\u542B\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u8FDE\u5B57\u7B26\uFF09"});if(!r)throw new v(k.INVALID_ARG,{enUS:"Plugin name cannot be empty",zhCN:"\u63D2\u4EF6\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"});let i=await Et(),a=i.some(S=>String(S.id??"")===n),o=i.some(S=>Nt(S.name,r));if(a||o){let S=a&&o?"ID and name":a?"ID":"name",h=a&&o?"ID \u548C\u540D\u79F0":a?"ID":"\u540D\u79F0",_=a?n:r;throw new v(k.DUPLICATE,{enUS:`A plugin with this ${S} ("${_}") already exists in the plugin market and cannot be created`,zhCN:`\u63D2\u4EF6${h}\u300C${_}\u300D\u5DF2\u5B58\u5728\u4E8E\u63D2\u4EF6\u5E02\u573A\uFF0C\u65E0\u6CD5\u521B\u5EFA`})}let[c,y]=await Promise.all([F(),d.plugin.scanInstalled().catch(()=>[])]);if([...c,...y??[]].some(S=>S.id===n))throw new v(k.DUPLICATE,{enUS:`A plugin with the same ID "${n}" already exists locally and cannot be created`,zhCN:`\u672C\u5730\u5DF2\u5B58\u5728\u540C\u540D\u63D2\u4EF6\u300C${n}\u300D\uFF0C\u65E0\u6CD5\u521B\u5EFA`});let w=await Te();if(!w)return null;let I=await _t(n,w);if(!I.ok)throw new v(k.BUILD_FAIL,{enUS:`Failed to create plugin: ${I.detail}`,zhCN:`\u521B\u5EFA\u63D2\u4EF6\u5931\u8D25\uFF1A${I.detail}`});return await Pt(T(w,n),r),He(T(w,n))});d.registerHandler("dev-tools.runtimeStates",()=>d.plugin.runtimeList());d.registerHandler("dev-tools.previewInfo",async([e])=>{let t=String(e),n=await j(t),r=n?await G(n.dir):null,i=(r?.type??"ui")!=="worker",a=(r?.dependencies??[]).filter(c=>c!=="nodejs"),o=[];if(a.length>0){let c=await d.plugin.scanInstalled().catch(()=>[]),y=new Set((c??[]).map(g=>String(g?.id??"")));o=a.filter(g=>!y.has(g))}return{pluginId:`${t}@dev`,remoteEntryUrl:`dlientOpen://plugin/${t}@dev/dist/remoteEntry.js`,hasUI:i,missingDeps:o}});var Q=new Map,B=new Map,Z=new Map,se=new Map,_e=5e3;function we(e,t,n){if(!n)return;let r=Z.get(e)??[];r.push({ts:Date.now(),stream:t,data:n}),r.length>_e&&r.splice(0,r.length-_e),Z.set(e,r)}var At=["zh"],ce;async function Rt(){if(ce===void 0)try{ce=String(await d.app.getLocale())}catch{ce="en-US"}return At.some(e=>ce.startsWith(e))}async function Mt(e){let t=await Rt()?"https://registry.npmmirror.com":void 0;return!t||e.some(n=>n.startsWith("--registry"))?e:[...e,`--registry=${t}`]}async function be(e,t){return new Promise(n=>{let r=!1,i=o=>{r||(r=!0,clearTimeout(a),n(o))};e.onExit(o=>i({code:o.code,reason:o.reason==="killed"?"killed":"exited"})),e.onError(o=>i({code:-1,reason:"error",message:o.message}));let a=setTimeout(()=>{e.kill().catch(()=>{}),i({code:null,reason:"timeout"})},t)})}async function We(e){let t=B.get(e);if(t&&t.status==="running")return{ok:!0,procId:t.procId,reused:!0};let n=await j(e);if(!n)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${e}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${e}`});try{let r=await d.child.spawn({cmd:oe,args:["run","dev"],cwd:n.dir});return Q.set(e,r),B.set(e,{procId:r.handleId,caller:"dev-tools",kind:"dev",pid:r.pid,status:"running",cwd:n.dir,startedAt:Date.now()}),Z.delete(e),se.set(e,Date.now()),r.onStdout(i=>we(e,"stdout",i)),r.onStderr(i=>we(e,"stderr",i)),r.onExit(()=>{let i=B.get(e);i&&(i.status="exited")}),r.onError(i=>{let a=B.get(e);a&&(a.status="error"),we(e,"stderr",`spawn error: ${i.message}`)}),{ok:!0,procId:r.handleId}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}d.registerHandler("dev-tools.buildDev",([e])=>We(String(e)));d.registerHandler("dev-tools.stop",async([e])=>{let t=String(e),n=Array.from(B.entries()).find(([,r])=>r.procId===t)?.[0];if(n){let r=Q.get(n);r&&await r.kill().catch(()=>{}),Q.delete(n),B.delete(n),Z.delete(n),se.delete(n)}return{ok:!0}});d.registerHandler("dev-tools.listBuilds",()=>Array.from(B.values()));d.registerHandler("dev-tools.log",([e,t])=>{let n=Array.from(B.entries()).find(([,i])=>i.procId===String(e))?.[0];if(!n)return[];let r=typeof t=="number"&&t>0?t:0;return(Z.get(n)??[]).filter(i=>i.ts>=r)});async function Ie(e){let t=Q.get(e);t&&(await t.kill().catch(()=>{}),Q.delete(e),B.delete(e),Z.delete(e),se.delete(e))}async function De(e,t){try{let n=await Mt(t),r=await d.child.spawn({cmd:oe,args:n,cwd:e}),i="";r.onStderr(o=>i+=o);let a=await be(r,10*60*1e3);return a.reason==="timeout"?{ok:!1,detail:`npm ${t.join(" ")} \u8D85\u65F6\uFF0810min\uFF09`}:a.reason==="error"?{ok:!1,detail:`npm ${t.join(" ")} \u542F\u52A8\u5931\u8D25\uFF1A${a.message??""}`.slice(0,300)}:a.code!==0?{ok:!1,detail:(i.trim()||`npm ${t.join(" ")} \u8FD4\u56DE\u5931\u8D25`).slice(0,300)}:{ok:!0}}catch(n){return{ok:!1,detail:`\u6267\u884C npm \u5931\u8D25\uFF1A${n instanceof Error?n.message:String(n)}`.slice(0,300)}}}function qe(e){return De(e,["install","--no-audit","--no-fund"])}d.registerHandler("dev-tools.ensureDeps",async([e])=>{let t=String(e),n=await j(t);if(!n)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${t}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${t}`});if(!(await Fe()).ok)throw new v(k.NODEJS_MISSING,Dt());let{needsWorker:i}=Se((await G(n.dir))?.type),a=!1;if(!await me(T(n.dir,"node_modules"))){let o=await qe(n.dir);if(!o.ok)throw new v(k.BUILD_FAIL,{enUS:`npm install failed: ${o.detail}`,zhCN:`npm install \u5931\u8D25\uFF1A${o.detail}`});a=!0}if(i&&!await me(T(n.dir,n.dist,"worker.js"))){let o=await De(n.dir,["run","build:worker"]);if(!o.ok)throw new v(k.BUILD_FAIL,{enUS:`build:worker failed: ${o.detail}`,zhCN:`build:worker \u5931\u8D25\uFF1A${o.detail}`})}return{ok:!0,installed:a}});d.registerHandler("dev-tools.checkManifest",async([e])=>{let t=String(e??"").trim();if(!t)return{ok:!1,error:{enUS:"Plugin ID cannot be empty",zhCN:"\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"}};let n=await j(t);if(!n)return{ok:!1,error:{enUS:`Dev plugin does not exist: ${t}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${t}`}};let r=await G(n.dir);return r?.id?r.id!==t?{ok:!1,error:{enUS:`The dlient.id in the manifest (${r.id}) does not match the registered ID (${t})`,zhCN:`manifest \u7684 dlient.id\uFF08${r.id}\uFF09\u4E0E\u6CE8\u518C ID\uFF08${t}\uFF09\u4E0D\u4E00\u81F4`}}:/^[a-z0-9-]+$/.test(r.id)?r.source!=="dev"?{ok:!1,error:{enUS:`This plugin is not a dev plugin (dlient.source="${r.source??"unset"}"). Change dlient.source in package.json to "dev"`,zhCN:`\u8BE5\u63D2\u4EF6\u4E0D\u662F dev \u63D2\u4EF6\uFF08dlient.source="${r.source??"\u672A\u58F0\u660E"}"\uFF09\uFF0C\u8BF7\u5C06 package.json \u7684 dlient.source \u6539\u4E3A "dev"`}}:{ok:!0,id:r.id,name:r.name}:{ok:!1,error:{enUS:`Invalid plugin ID (only lowercase letters, digits and hyphens allowed, current: ${r.id})`,zhCN:`\u63D2\u4EF6 ID \u4E0D\u5408\u6CD5\uFF08\u4EC5\u5141\u8BB8\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\uFF0C\u5F53\u524D\uFF1A${r.id}\uFF09`}}:{ok:!1,error:{enUS:"No valid plugin manifest found in the directory (dlient.id in package.json)",zhCN:"\u76EE\u5F55\u4E2D\u672A\u627E\u5230\u6709\u6548\u7684\u63D2\u4EF6 manifest\uFF08package.json \u7684 dlient.id\uFF09"}}});d.registerHandler("dev-tools.ensureEnv",async([e])=>{let t=String(e??"").trim();if(!t)return{ok:!1,error:{enUS:"Plugin ID cannot be empty",zhCN:"\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"}};let n=await j(t);if(!n)return{ok:!1,error:{enUS:`Dev plugin does not exist: ${t}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${t}`}};let{hasUI:r,needsWorker:i}=Se((await G(n.dir))?.type),a=se.get(t)??0;return await Ge(n,r,i,a,3e4)?(await d.plugin.dev.startWatcher(t).catch(c=>L.error(`ensureEnv ${t} startWatcher`,{error:c instanceof Error?c.message:String(c)})),{ok:!0}):{ok:!1,error:{enUS:`${i?"worker.js":"remoteEntry.js"} initial build not complete (npm run dev did not produce new artifacts)`,zhCN:`${i?"worker.js":"remoteEntry.js"} \u521D\u59CB\u6784\u5EFA\u672A\u5B8C\u6210\uFF08npm run dev \u672A\u4EA7\u51FA\u65B0\u4EA7\u7269\uFF09`}}});d.registerHandler("dev-tools.closePlugin",async([e])=>{let t=String(e??"").trim();return t?(await d.plugin.dev.stopWatcher(t).catch(n=>L.error("closePlugin stopWatcher",{pluginId:t,error:n instanceof Error?n.message:String(n)})),await d.plugin.dev.stopDevWorker(t).catch(n=>L.error("closePlugin stopDevWorker",{pluginId:t,error:n instanceof Error?n.message:String(n)})),await Ie(t),{ok:!0}):{ok:!1,error:{enUS:"Plugin ID cannot be empty",zhCN:"\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"}}});function Lt(e){return new Promise(t=>setTimeout(t,e))}async function Ge(e,t,n,r,i,a){let o=[];t&&o.push(T(e.dir,e.dist,"remoteEntry.js")),n&&o.push(T(e.dir,e.dist,"worker.js"));let c=Date.now()+i;for(;Date.now()<c;){if((await Promise.all(o.map(I=>he(I)))).every(I=>I?.exists===!0&&I.mtimeMs>=r))return!0;if(a){let I=Array.from(B.values()).find(S=>S.procId===a);if(I&&I.status!=="running")return!1}await Lt(500)}return(await Promise.all(o.map(g=>he(g)))).every(g=>g?.exists===!0)}d.registerStreamHandler("dev-tools.refresh",async([e],t)=>{let n=String(e??"");if(!t?.emit)return{ok:!1,error:{enUS:"refresh requires a streaming call (api.listen)",zhCN:"refresh \u9700\u8981\u6D41\u5F0F\u8C03\u7528\uFF08api.listen\uFF09"}};let r=t.emit,i=(a,o,c)=>{let y={step:a,status:o};c?.detail!==void 0&&(y.detail=c.detail),c?.procId!==void 0&&(y.procId=c.procId),r(y)};try{let a=await j(n);if(!a)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${n}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${n}`});let{hasUI:o,needsWorker:c}=Se((await G(a.dir))?.type);i(0,"running"),await d.plugin.dev.stopDevWorker(n).catch(h=>L.error("refresh stopDevWorker",{pluginId:n,error:h instanceof Error?h.message:String(h)})),i(0,"done"),await d.plugin.dev.stopWatcher(n).catch(h=>L.error("refresh stopWatcher",{pluginId:n,error:h instanceof Error?h.message:String(h)})),i(1,"running"),await Ie(n),i(1,"done"),i(2,"running");let y=await qe(a.dir);if(!y.ok){let h={enUS:`npm install failed: ${y.detail}`,zhCN:`npm install \u5931\u8D25\uFF1A${y.detail}`};return i(2,"error",{detail:h}),i(5,"error",{detail:h}),{ok:!1,error:h}}i(2,"done"),i(3,"running");let g=Date.now();if(c){let h=await De(a.dir,["run","build:worker"]);if(!h.ok){let _={enUS:`build:worker failed: ${h.detail}`,zhCN:`build:worker \u5931\u8D25\uFF1A${h.detail}`};return i(3,"error",{detail:_}),i(5,"error",{detail:_}),{ok:!1,error:_}}}let w=await We(n);if(!w?.ok){let h=w?.error??"unknown",_={enUS:`Failed to start build: ${h}`,zhCN:`\u6784\u5EFA\u542F\u52A8\u5931\u8D25\uFF1A${h}`};return i(3,"error",{detail:_}),i(5,"error",{detail:_}),{ok:!1,error:_}}let I=se.get(n)??g;if(!await Ge(a,o,c,I,12e4,w.procId)){let h={enUS:`${a.dist}/${c?"worker.js":"remoteEntry.js"} was not produced (build failed or timed out)`,zhCN:`${a.dist}/${c?"worker.js":"remoteEntry.js"} \u672A\u4EA7\u51FA\uFF08\u6784\u5EFA\u5931\u8D25\u6216\u8D85\u65F6\uFF09`};return i(3,"error",{detail:h}),i(5,"error",{detail:h}),{ok:!1,error:h}}return i(3,"done"),i(4,"running"),await d.plugin.dev.startWatcher(n).catch(h=>L.error("refresh startWatcher",{pluginId:n,error:h instanceof Error?h.message:String(h)})),i(4,"done"),i(5,"done",{procId:w.procId??null}),{ok:!0,procId:w.procId??null}}catch(a){let o=a instanceof v&&a.msg!==void 0?a.msg:a instanceof Error?a.message:String(a);return L.error("refresh failed",{pluginId:n,error:typeof o=="string"?o:o.zhCN}),i(5,"error",{detail:o}),{ok:!1,error:o}}});d.onReady(()=>{L.info("worker ready",{pid:process.pid}),ht(F().then(async e=>{for(let t of e)await Ue(t);await ee(e)}).catch(e=>L.error("initial sync failed",{error:e instanceof Error?e.message:String(e)})))});d.onDispose(async()=>{for(let e of Q.values())await e.kill().catch(()=>{});Q.clear(),B.clear(),Z.clear(),se.clear()});d.registerHandler("dev-tools.packPlugin",async([e])=>{let t=String(e??"").trim();if(!t)throw new v(k.INVALID_ARG,{enUS:"pluginId required",zhCN:"\u7F3A\u5C11 pluginId \u53C2\u6570"});let n=await j(t);if(!n)throw new v(k.NOT_FOUND,{enUS:`Dev plugin does not exist: ${t}`,zhCN:`dev \u63D2\u4EF6\u4E0D\u5B58\u5728: ${t}`});let r;try{r=await d.child.spawn({cmd:oe,args:["run","pack"],cwd:n.dir})}catch(g){throw new v(k.BUILD_FAIL,{enUS:`Failed to start pack: ${g instanceof Error?g.message:String(g)}`,zhCN:`\u542F\u52A8\u6253\u5305\u5931\u8D25\uFF1A${g instanceof Error?g.message:String(g)}`})}let i="";r.onStdout(g=>i+=g),r.onStderr(g=>i+=g);let a=await be(r,10*60*1e3),o=i.trim().slice(-2e3);if(a.reason==="timeout")throw new v(k.BUILD_FAIL,{enUS:`Pack timed out (10min): ${o}`,zhCN:`\u6253\u5305\u8D85\u65F6\uFF0810 \u5206\u949F\uFF09\uFF1A${o}`});if(a.code!==0)throw new v(k.BUILD_FAIL,{enUS:`Pack failed (exit ${a.code}): ${o}`,zhCN:`\u6253\u5305\u5931\u8D25\uFF08exit ${a.code}\uFF09\uFF1A${o}`});let c="",y=await Ae(T(n.dir,"package.json"));if(y!=null)try{c=String(JSON.parse(y).version??"")}catch{}return d.success({ok:!0,dir:n.dir,file:`${t}-${c||"0.0.0"}.dlient`,output:o})});d.registerHandler("dev-tools.revealPath",async([e])=>{let t=String(e??"").trim();if(!t)throw new v(k.INVALID_ARG,{enUS:"path required",zhCN:"\u7F3A\u5C11 path \u53C2\u6570"});return await d.os.showItemInFolder(t),d.success({ok:!0})});
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@dlient-open/dev-tools",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "license": "MIT",
5
5
  "description": "dlient dev-plugin toolbox: create from template, auto-build, live preview, pack to .dlient, logs",
6
6
  "keywords": [
7
7
  "dlient-open-plugin",
8
8
  "dlient",
9
+ "app",
9
10
  "dev-tools",
10
11
  "plugin-development",
11
12
  "preview"
@@ -118,7 +119,6 @@
118
119
  "devDependencies": {
119
120
  "@atomic-editor/editor": "^0.6.2",
120
121
  "@dlient-open/api-bridge": "^0.1.0",
121
- "@dlient-open/create-plugin": "^0.1.7",
122
122
  "@dlient-open/i18n": "^0.1.0",
123
123
  "@dlient-open/plugin-sdk": "^0.1.4",
124
124
  "@dlient-open/ui": "^0.3.1",
@@ -103,7 +103,12 @@ try {
103
103
  })
104
104
  for (const sub of ['assets', 'skills']) {
105
105
  if (!existsSync(join(ROOT, sub))) continue
106
- cpSync(join(ROOT, sub), join(stage, sub), { recursive: true })
106
+ // dsh-chat-ui 资产已在构建期内联进 dist/worker.js(esbuild 虚拟模块 'dlient:chat-assets'),
107
+ // 包内不再重复打一份(仓库仍保留该目录作为构建源)
108
+ cpSync(join(ROOT, sub), join(stage, sub), {
109
+ recursive: true,
110
+ filter: (src) => !src.split(sep).includes('dsh-chat-ui'),
111
+ })
107
112
  }
108
113
 
109
114
  // ---- 递归收集 stage 文件 ----