aitable-workflow-cli 0.1.16 → 0.1.17-beta.1786415522134

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/cli.js CHANGED
@@ -1,70 +1,77 @@
1
1
  #!/usr/bin/env node
2
- import{b as U,d as x,e as z,f as le,g as j}from"./chunk-U773UWB7.js";import{a as c}from"./chunk-EI7MMDWY.js";import{config as xe}from"dotenv";import{Command as G}from"commander";import{createApp as vt,loadSettings as K,loadWorkflowTemplate as Ce,logger as g,activateGlobalDwsOnPath as bt,createExecShellToolkit as St,ensureTsxRegistered as Et,runInit as It,runDesignCommand as $t,runCheck as Ie,runSetupCommand as Tt,runKbCompileCommand as xt,runKbUpdateCommand as Ct,runKbStatusCommand as _t,runKbIngestCommand as Lt,runSync as Dt,checkWorkflowRecipes as Pt,listCodingAgents as Ot,Tracer as Mt,saveCredential as Ut,listCredentials as ae,setActiveAgent as jt,getActiveCredential as A,readCredentials as Nt,findConflictingCredential as Ft,maskSecret as H,runMigrate as Bt,checkMigrateHint as _e}from"aitable-workflow-core";import{startServer as Wt,resolveServeConfig as Vt}from"aitable-workflow-server";import I from"os";import R from"path";import{mkdir as Ge,readFile as Ke}from"fs/promises";import{mkdirSync as He}from"fs";import{execSync as qe}from"child_process";import{logger as p,detectInstalledAgents as Je,runCodingAgent as ze,DwsClient as Xe,getActiveCredential as Qe}from"aitable-workflow-core";import X from"ws";import{logger as b,RELAY_REJECTED_CODE as Oe,isRelayMessage as Me}from"aitable-workflow-core";var S="relay:conn",ge=1e3,Ue=3e4,je=Number(process.env.AITABLE_RELAY_SERVER_STALE_MS??9e4),N=class{static{c(this,"RelayConnection")}ws=null;delay=ge;timer=null;watchdog=null;should=!0;permanentlyRejected=!1;accepted=!1;lastServerFrameAt=0;serverUrl;key;token;onMessage;onOpen;onAccepted;onPermanentReject;mkWs;staleMs;constructor(e){this.serverUrl=e.serverUrl,this.key=e.key??"",this.token=e.token??"",this.onMessage=e.onMessage,this.onOpen=e.onOpen,this.onAccepted=e.onAccepted,this.onPermanentReject=e.onPermanentReject,this.mkWs=e.mkWs??(n=>new X(n)),this.staleMs=e.staleMs??je}connect(){this.permanentlyRejected||(this.should=!0,this.doConnect())}send(e){this.ws&&this.ws.readyState===X.OPEN&&this.ws.send(JSON.stringify(e))}close(){this.should=!1,this.timer&&(clearTimeout(this.timer),this.timer=null),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.ws?.close()}isPermanentlyRejected(){return this.permanentlyRejected}currentSocket(){return this.ws}buildUrl(){let e=this.serverUrl.replace(/\/+$/,"").replace(/^http/,"ws"),n=this.token?`token=${encodeURIComponent(this.token)}`:`key=${encodeURIComponent(this.key)}`;return`${e}/api/relay/connect?${n}`}doConnect(){if(!this.should||this.permanentlyRejected)return;let e=this.buildUrl();b.info(S,"connecting",{serverUrl:this.serverUrl}),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.accepted=!1,this.lastServerFrameAt=0;let n=this.mkWs(e);this.ws=n,n.on("open",()=>{b.info(S,"connected"),this.onOpen?.(n)}),n.on("message",o=>{this.accepted||(this.accepted=!0,this.delay=ge,this.onAccepted?.(n)),this.lastServerFrameAt=Date.now(),this.armWatchdog();let r;try{r=JSON.parse(typeof o=="string"?o:String(o))}catch{return}Me(r)&&(r.type==="ping"&&this.send({type:"pong"}),this.onMessage(r))}),n.on("close",(o,r)=>{this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null);let i=r==null?"":String(r);if(o===Oe){this.permanentlyRejected=!0,this.should=!1,b.error(S,"server permanently rejected this machine: its connection key is unknown or was removed; re-issue the relay connect command and restart with the new key",{code:o,reason:i}),this.onPermanentReject?.({code:o,reason:i});return}b.warn(S,"disconnected",{code:o}),this.scheduleReconnect()}),n.on("error",o=>{b.error(S,"ws error",{detail:o instanceof Error?o.message:String(o)})})}armWatchdog(){this.watchdog&&clearTimeout(this.watchdog),this.watchdog=setTimeout(()=>{if(!(!this.accepted||!this.lastServerFrameAt||this.ws?.readyState!==X.OPEN)){b.warn(S,"server heartbeat stale; closing socket to reconnect",{staleMs:Date.now()-this.lastServerFrameAt});try{this.ws.close()}catch{}}},this.staleMs+1),this.watchdog.unref?.()}scheduleReconnect(){!this.should||this.permanentlyRejected||this.timer||(b.info(S,"reconnecting",{ms:this.delay}),this.timer=setTimeout(()=>{this.timer=null,this.doConnect()},this.delay),this.timer.unref?.(),this.delay=Math.min(this.delay*2,Ue))}};import{createHash as Ne}from"crypto";import{readdir as Fe,readFile as Be,stat as We}from"fs/promises";import de from"path";import{isAllowedArtifactPath as Ve,normalizeArtifactRelPath as Ye}from"aitable-workflow-core";var me={async upload(t,e,n){let o=await fetch(t,{method:"PUT",body:e,headers:{...n}});if(!o.ok)throw new Error(`artifact PUT failed: ${o.status} ${o.statusText}`)}};async function fe(t){let e=[];return await pe(t,t,e),e.sort((n,o)=>n.relPath.localeCompare(o.relPath))}c(fe,"scanArtifacts");async function pe(t,e,n){let o;try{o=await Fe(e,{withFileTypes:!0})}catch{return}for(let r of o){if(r.name==="node_modules"||r.name.startsWith("."))continue;let i=de.join(e,r.name);if(r.isDirectory())await pe(t,i,n);else if(r.isFile()){let s=de.relative(t,i).replace(/\\/g,"/");if(!Ve(s))continue;let a=await We(i),l=await Be(i),m=Ne("sha256").update(l).digest("hex");n.push({relPath:Ye(s),absPath:i,size:a.size,sha256:m})}}}c(pe,"walk");var u="relay:daemon",ue=["aitable"],Ze="dws";function et(t,e=ue){if(!Array.isArray(t)||t.length===0)return{ok:!1,reason:"dws args must be a non-empty array"};for(let o of t){if(typeof o!="string")return{ok:!1,reason:"dws args must all be strings"};if(o.length===0)return{ok:!1,reason:"dws args must not contain empty tokens"};if(/[\u0000-\u001f]/.test(o))return{ok:!1,reason:"dws args must not contain control characters"}}let n=t[0];return n.startsWith("-")?{ok:!1,reason:"first dws arg must be a subcommand, not a flag"}:e.length>0&&!e.includes(n)?{ok:!1,reason:`dws command "${n}" is not allowed`}:{ok:!0}}c(et,"validateDwsArgs");function tt(t){try{return qe(`${t} --version`,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}c(tt,"detectDwsAvailable");var Q=class{static{c(this,"RelayDaemon")}config;allowedDwsCommands;conn;runAgent;createDwsClient;detectAgents;detectDws;hostname;osString;onPermanentReject;artifactUploader;grantTimeoutMs;pendingGrants=new Map;maxTasks;inflight=0;taskQueue=[];machineId;constructor(e,n={}){this.config={...e,dwsBin:e.dwsBin??Ze},this.machineId=e.machineId,this.allowedDwsCommands=e.allowedDwsCommands??ue,this.runAgent=n.runAgent??ze,this.createDwsClient=n.createDwsClient??((r,i)=>new Xe({bin:r,timeoutMs:i})),this.detectAgents=n.detectAgents??(()=>Je()),this.detectDws=n.detectDws??(r=>tt(r)),this.hostname=n.hostname??(()=>I.hostname()),this.osString=n.osString??(()=>`${I.platform()} ${I.arch()}`),this.onPermanentReject=n.onPermanentReject,this.artifactUploader=n.artifactUploader??me,this.grantTimeoutMs=n.grantTimeoutMs??3e4,this.maxTasks=Math.max(1,Math.floor(e.maxTasks??1));let o=n.createConnection??(r=>new N(r));this.conn=o({serverUrl:this.config.serverUrl,key:this.config.key,token:this.config.token,onMessage:c(r=>this.handleMessage(r),"onMessage"),onOpen:c(()=>this.handleOpen(),"onOpen"),onPermanentReject:c(r=>this.handlePermanentReject(r),"onPermanentReject")})}start(){p.info(u,"starting",{serverUrl:this.config.serverUrl,workspaceRoot:this.config.workspaceRoot}),this.config.name||p.warn(u,"\u672A\u6307\u5B9A --name\uFF0C\u5C06\u4F7F\u7528\u4E3B\u673A\u540D\u4F5C\u4E3A\u673A\u5668\u6CE8\u518C\u540D\uFF1B\u591A\u673A\u573A\u666F\u4E0B hostname \u82E5\u91CD\u590D\u4F1A\u5BFC\u81F4\u8FDE\u63A5\u4E92\u76F8\u9876\u66FF\uFF0C\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A --name",{hostname:this.hostname()}),this.conn.connect()}stop(){p.info(u,"stopping"),this.conn.close()}buildReady(){let n={type:"ready",runtimes:Array.from(new Set(this.detectAgents().map(o=>o.type))),hasDws:this.detectDws(this.config.dwsBin),hostname:this.hostname(),os:this.osString()};return this.machineId&&(n.machineId=this.machineId),this.config.name&&(n.name=this.config.name),this.config.displayName&&(n.displayName=this.config.displayName),this.config.description&&(n.description=this.config.description),this.maxTasks>1&&(n.maxTasks=this.maxTasks),n}handleOpen(){let e=this.buildReady();p.info(u,"connected; sending ready",{runtimes:e.runtimes,hasDws:e.hasDws}),this.conn.send(e)}handlePermanentReject(e){p.error(u,"permanently rejected by gateway",{...e}),this.onPermanentReject?.(e)}handleMessage(e){switch(e.type){case"run:agent":this.enqueueTask(()=>this.handleRunAgent(e));break;case"run:dws":this.enqueueTask(()=>this.handleRunDws(e));break;case"upload:grant":this.resolveGrant(e);break;case"ready:ack":e.machineId&&(this.machineId=e.machineId,p.info(u,"machine id assigned",{machineId:e.machineId}));break;default:break}}enqueueTask(e){let n=c(()=>{this.inflight+=1,e().finally(()=>{this.inflight-=1;let o=this.taskQueue.shift();o&&o()})},"exec");this.inflight<this.maxTasks?n():this.taskQueue.push(n)}async handleRunAgent(e){let{requestId:n}=e;p.info(u,"run:agent received",{requestId:n,projectId:e.projectId,agent:e.agent});try{let o=this.resolveWorkDir(e.projectId,e.workDir);await Ge(o,{recursive:!0});let r=this.rewritePromptWorkDir(e.prompt,e.workDir,o),i={agent:e.agent,workDir:o,onEvent:c(l=>this.conn.send({type:"event",requestId:n,event:l}),"onEvent")};e.sessionId&&(i.sessionId=e.sessionId),e.permissionMode&&(i.adapterOptions={permissionMode:e.permissionMode}),this.config.agentTimeoutMs!=null&&(i.timeoutMs=this.config.agentTimeoutMs);let s=await this.runAgent(r,i),a;try{a=await this.collectAndUploadArtifacts(n,e.projectId,o)}catch(l){let m=l instanceof Error?l.message:String(l);p.error(u,"artifact upload failed",{requestId:n,error:m}),this.conn.send({type:"error",requestId:n,code:"artifact_upload_failed",message:m});return}this.conn.send({type:"result",requestId:n,ok:!0,response:s.response,sessionId:s.sessionId,...a?{artifacts:a}:{}}),p.info(u,"run:agent done",{requestId:n,sessionId:s.sessionId,artifacts:a?a.files.length:0})}catch(o){let r=o instanceof Error?o.message:String(o);p.error(u,"run:agent failed",{requestId:n,error:r}),this.conn.send({type:"error",requestId:n,code:"agent_failed",message:r})}}async collectAndUploadArtifacts(e,n,o){let r=await fe(o);if(r.length===0)return;this.conn.send({type:"upload:request",requestId:e,projectId:n,files:r.map(a=>({path:a.relPath,size:a.size,sha256:a.sha256}))});let i=await this.awaitGrant(e);if(!i)throw new Error("upload:grant \u7B49\u5F85\u8D85\u65F6");if(i.grants.length===0){p.warn(u,"upload:grant \u65E0\u6388\u6743\u9879\uFF08gateway \u672A\u914D\u7F6E store \u6216\u5168\u88AB\u62D2\uFF09",{requestId:e,rejected:(i.rejected??[]).length});return}let s=[];for(let a of i.grants){let l=r.find(h=>h.relPath===a.path);if(!l)continue;let m=await Ke(l.absPath);await this.artifactUploader.upload(a.url,m,a.headers),s.push({path:a.path,key:a.key,sha256:l.sha256,size:l.size})}return{store:"oss",files:s}}awaitGrant(e){return new Promise(n=>{let o=setTimeout(()=>{this.pendingGrants.delete(e),n(void 0)},this.grantTimeoutMs);o.unref?.(),this.pendingGrants.set(e,r=>{clearTimeout(o),n(r)})})}resolveGrant(e){let n=this.pendingGrants.get(e.requestId);n&&(this.pendingGrants.delete(e.requestId),n(e))}async handleRunDws(e){let{requestId:n}=e,o=et(e.args,this.allowedDwsCommands);if(!o.ok){p.warn(u,"run:dws rejected",{requestId:n,reason:o.reason}),this.conn.send({type:"error",requestId:n,code:"dws_rejected",message:o.reason});return}p.info(u,"run:dws received",{requestId:n,command:e.args[0]});try{let i=await this.createDwsClient(this.config.dwsBin,e.timeoutMs).runJson(e.args,e.timeoutMs!=null?{timeoutMs:e.timeoutMs}:void 0);this.conn.send({type:"result",requestId:n,ok:!0,response:JSON.stringify(i)}),p.info(u,"run:dws done",{requestId:n})}catch(r){let i=r instanceof Error?r.message:String(r);p.error(u,"run:dws failed",{requestId:n,error:i}),this.conn.send({type:"error",requestId:n,code:"dws_failed",message:i})}}resolveWorkDir(e,n){if(n&&n.trim()!=="")if(R.isAbsolute(n))p.warn(u,"\u5FFD\u7565\u670D\u52A1\u7AEF\u4E0B\u53D1\u7684\u7EDD\u5BF9\u8DEF\u5F84 workDir\uFF0C\u56DE\u9000\u5230 workspaceRoot/projectId",{workDir:n,projectId:e});else return R.resolve(this.config.workspaceRoot,n);return R.join(this.config.workspaceRoot,e)}rewritePromptWorkDir(e,n,o){let r=n?.trim();return!r||!R.isAbsolute(r)||r===o?e:e.split(r).join(o)}};function Z(t,e){let n,o=t?.trim();if(o)n=R.isAbsolute(o)?R.resolve(o):R.resolve(I.homedir(),o);else{let r=e?.trim()?e.trim():"default";n=R.join(I.homedir(),".aitable-workflow","workspaces",r)}return He(n,{recursive:!0}),n}c(Z,"resolveWorkspaceRoot");function nt(t,e=process.env){let n=t.serverUrl??e.AITABLE_RELAY_SERVER_URL,o=t.key??e.AITABLE_RELAY_BOOTSTRAP_KEY,r=t.token??e.AITABLE_RELAY_TOKEN,i=t.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT,s=t.machineId??e.AITABLE_RELAY_MACHINE_ID,a=t.name??e.AITABLE_RELAY_NAME,l=t.desc??e.AITABLE_RELAY_DESC,m=t.maxTasks??e.AITABLE_RELAY_MAX_TASKS,h=[];if(n||h.push("--server-url (\u6216 AITABLE_RELAY_SERVER_URL)"),!o&&!r&&h.push("--key/--token (\u6216 AITABLE_RELAY_BOOTSTRAP_KEY/AITABLE_RELAY_TOKEN)"),h.length>0)throw new Error(`relay \u7F3A\u5C11\u5FC5\u8981\u53C2\u6570: ${h.join(", ")}
3
- \u{1F4A1} \u63D0\u793A: \u4F7F\u7528 \`aitable-workflow connect\` \u6CE8\u518C\u540E\u53EF\u7701\u7565\u8FD9\u4E9B\u53C2\u6570`);let w=a??I.hostname()??"default",f={serverUrl:n,workspaceRoot:Z(i,w)};if(r?f.token=r:o&&(f.key=o),s&&(f.machineId=s),a&&(f.name=a,f.displayName=a),l&&(f.description=l),m!=null&&m!==""){let T=Math.floor(Number(m));Number.isFinite(T)&&T>=1&&(f.maxTasks=T)}return f}c(nt,"resolveRelayCliConfig");async function C(t,e=process.env){let n=null;try{n=await Qe()}catch{n=null}let o={serverUrl:t.serverUrl??e.AITABLE_RELAY_SERVER_URL??n?.serverUrl,key:t.key??e.AITABLE_RELAY_BOOTSTRAP_KEY??n?.key,token:t.token??e.AITABLE_RELAY_TOKEN??n?.token,name:t.name??e.AITABLE_RELAY_NAME??n?.name,desc:t.desc??e.AITABLE_RELAY_DESC,workspaceRoot:t.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT??n?.workspaceRoot,machineId:t.machineId??e.AITABLE_RELAY_MACHINE_ID??n?.machineId,maxTasks:t.maxTasks??e.AITABLE_RELAY_MAX_TASKS};return nt(o,e)}c(C,"resolveDaemonConfig");async function ee(t){let e=await C(t),n=new Q(e,{onPermanentReject:c(()=>{process.exit(1)},"onPermanentReject")}),o=c(()=>{n.stop(),process.exit(0)},"shutdown");return process.on("SIGINT",o),process.on("SIGTERM",o),n.start(),n}c(ee,"runRelayDaemon");import{spawn as rt}from"child_process";import{existsSync as st}from"fs";import L from"path";import{fileURLToPath as it}from"url";import{appendFileSync as Sn,statSync as En,renameSync as In,mkdirSync as $n,existsSync as Tn}from"fs";import ot from"path";var _n=10*1024*1024;function _(t){return ot.join(U(t),"daemon.log")}c(_,"logFilePath");var F=L.dirname(it(import.meta.url));function at(){let t=[L.resolve(F,"..","..","bin","aitable-workflow.mjs"),L.resolve(F,"..","bin","aitable-workflow.mjs"),L.resolve(F,"..","..","dist","cli.js"),L.resolve(F,"cli.js")];return t.find(e=>st(e))??t[0]}c(at,"resolveDaemonEntry");var ct=at();async function B(t){await le(t.agentId);let e=["relay"];t.serverUrl&&e.push("--server-url",t.serverUrl),t.token&&e.push("--token",t.token),t.key&&e.push("--key",t.key),t.name&&e.push("--name",t.name),t.workspaceRoot&&e.push("--workspace-root",t.workspaceRoot),t.machineId&&e.push("--machine-id",t.machineId),t.maxTasks&&e.push("--max-tasks",String(t.maxTasks));let n=await import("fs").then(s=>{let a=_(t.agentId);return s.openSync(a,"a")}),o=rt(process.execPath,[ct,...e],{detached:!0,stdio:["ignore",n,n],env:{...process.env}});try{let{closeSync:s}=await import("fs");s(n)}catch{}o.unref();let{writeFile:r}=await import("fs/promises"),{pidFilePath:i}=await import("./pid-file-HPTFI54H.js");return o.pid&&await r(i(t.agentId),String(o.pid),"utf8"),{pid:o.pid??0}}c(B,"startDaemon");async function W(t,e=5e3){let n=await z(t);if(n===null||!x(n))return await j(t),!1;try{process.kill(n,"SIGTERM")}catch{return await j(t),!1}let o=Date.now()+e;for(;Date.now()<o&&x(n);)await new Promise(r=>setTimeout(r,200));if(x(n))try{process.kill(n,"SIGKILL")}catch{}return await j(t),!0}c(W,"stopDaemon");async function V(t){let e=await z(t),n=e!==null&&x(e),o=null;if(n&&e!==null)try{let{readFile:r}=await import("fs/promises"),i=await r(`/proc/${e}/stat`,"utf8"),s=parseInt(i.split(" ")[21]??"0",10),a=await r("/proc/uptime","utf8"),h=parseFloat(a.split(" ")[0]??"0")-s/100;o=Math.round(h*1e3)}catch{}return{agentId:t,running:n,pid:n?e:null,uptimeMs:o,logFile:_(t)}}c(V,"getDaemonStatus");import{readFile as lt,writeFile as Yn,mkdir as Gn}from"fs/promises";import gt from"path";var he={connectionState:"disconnected",lastHeartbeatAt:null,machineId:null,serverUrl:"",runningTasks:0,queuedTasks:0,lastDisconnectReason:null,updatedAt:new Date().toISOString()};function dt(t){return gt.join(U(t),"state.json")}c(dt,"stateFilePath");async function te(t){try{let e=await lt(dt(t),"utf8");return{...he,...JSON.parse(e)}}catch{return{...he}}}c(te,"readState");import{execSync as D}from"child_process";import{writeFile as mt,rm as ft,mkdir as pt,access as ut}from"fs/promises";import v from"path";import we from"os";import{readCredentials as ht}from"aitable-workflow-core";var wt="com.alibaba.aitable-workflow.daemon",ne="\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\uFF1Anpm i -g @ali/aitable-workflow";function P(t){return`${wt}.${t}`}c(P,"plistLabel");function oe(t){return v.join(we.homedir(),"Library","LaunchAgents",`${P(t)}.plist`)}c(oe,"plistPath");function E(){return process.platform==="darwin"}c(E,"isMacOS");function ye(){try{return D("which aitable-workflow",{encoding:"utf8"}).trim()||null}catch{return null}}c(ye,"resolveGlobalCliEntry");function ke(t){if(!t||!t.trim())throw new Error(`\u672A\u627E\u5230\u5168\u5C40\u5B89\u88C5\u7684 aitable-workflow CLI \u5165\u53E3\uFF0C\u65E0\u6CD5\u914D\u7F6E\u5F00\u673A\u81EA\u542F\u3002
4
- \u{1F4A1} ${ne}`);if(t.includes("/_npx/")||t.includes(`${v.sep}_npx${v.sep}`))throw new Error(`\u68C0\u6D4B\u5230 CLI \u5165\u53E3\u4F4D\u4E8E npx \u4E34\u65F6\u7F13\u5B58\uFF0C\u5F00\u673A\u81EA\u542F\u4F1A\u5931\u6548\uFF1A${t}
5
- \u{1F4A1} ${ne}`);if(!v.isAbsolute(t))throw new Error(`CLI \u5165\u53E3\u4E0D\u662F\u7A33\u5B9A\u7684\u5168\u5C40\u7EDD\u5BF9\u8DEF\u5F84\uFF1A${t}
6
- \u{1F4A1} ${ne}`)}c(ke,"assertStableCliEntry");async function yt(t){let e={};e.AITABLE_RELAY_NAME=t;let n;try{let o=await ht();n=o.agents.find(r=>r.name===t)??o.agents.find(r=>r.name===o.activeAgent)??void 0}catch{n=void 0}return n&&(n.serverUrl&&(e.AITABLE_RELAY_SERVER_URL=n.serverUrl),n.token&&(e.AITABLE_RELAY_TOKEN=n.token),n.workspaceRoot&&(e.AITABLE_RELAY_WORKSPACE_ROOT=n.workspaceRoot)),e}c(yt,"buildRelayEnv");function kt(t,e){let n=P(t),o=e?.cliEntry??ye();ke(o);let r=["relay"];e?.maxTasks&&r.push("--max-tasks",String(e.maxTasks));let i=v.join(we.homedir(),".aitable-workflow","daemons",t),s=v.join(i,"launchd.log"),a=v.join(i,"launchd.err.log"),l=[o,...r].map(w=>` <string>${$(w)}</string>`).join(`
7
- `),m={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",...e?.relayEnv??{}},h=Object.entries(m).map(([w,f])=>` <key>${$(w)}</key>
8
- <string>${$(f)}</string>`).join(`
2
+ import{a as Pe}from"./chunk-IG7PZYXN.js";import{b as z,d as B,e as fe,f as Le,g as X}from"./chunk-W3EUICMH.js";import{a as c}from"./chunk-EI7MMDWY.js";import{config as Dt}from"dotenv";import{Command as Zo}from"commander";import{logger as Mt,activateGlobalDwsOnPath as er}from"aitable-workflow-core";import{createRequire as Wt}from"module";var _e="aitable-workflow-",Nt=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function Me(){try{return Wt(import.meta.url)("../package.json")}catch{return{}}}c(Me,"loadCliPackageManifest");function he(r){return r.version??"0.0.0"}c(he,"resolveCliVersion");function De(r){let e=he(r),t={};r.name?.startsWith(_e)&&(t[r.name]=e);for(let[n,o]of Object.entries(r.dependencies??{}))n.startsWith(_e)&&(t[n]=Nt.test(o)?o:e);return t}c(De,"resolveMonorepoPackageVersions");import Ot from"path";import{fileURLToPath as tr}from"url";var Oe="./aitable-workflow.config.yml";import{runInit as Gt,logger as Ht}from"aitable-workflow-core";import Kt from"path";function Ue(r,e){r.command("init").description("\u4EA4\u4E92\u5F0F\u521D\u59CB\u5316 \u2014 \u9009\u62E9 Coding Agent\u3001\u914D\u7F6E\u5DE5\u4F5C\u76EE\u5F55\u3001\u63CF\u8FF0\u4E1A\u52A1\u573A\u666F\uFF1B\u6216\u7528 --template \u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6").option("-c, --config <path>","\u76EE\u6807\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").option("-f, --force","\u8986\u76D6\u5DF2\u6709\u914D\u7F6E\u6587\u4EF6").option("-y, --yes","\u4F7F\u7528\u9ED8\u8BA4\u503C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u5411\u5BFC").option("-t, --template <name>","\u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6(\u5F53\u524D\u63A8\u8350 support-qa),\u62F7\u8D1D\u5B8C\u6574\u53EF\u8FD0\u884C\u9879\u76EE\u5230\u76EE\u6807\u76EE\u5F55").option("--profile <name>","\u9009\u5B9A\u6A21\u677F\u4E0B\u7684 profile \u4E1A\u52A1\u5305(\u5982 support-qa \u7684 aitable),\u8986\u76D6\u5F0F\u53E0\u52A0\u5230\u5B9E\u4F8B").action(async t=>{try{await Gt({config:t.config,force:!!t.force,yes:!!t.yes,template:t.template,profile:t.profile,templatesDir:Kt.resolve(e.cliDir,"..","templates"),templatePackageVersions:e.packageVersions,cliVersion:e.version})}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),Ht.error("cli","\u521D\u59CB\u5316\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Ue,"registerInitCommand");import{runMigrate as qt,logger as Yt}from"aitable-workflow-core";import Vt from"path";function Fe(r,e){r.command("migrate").description("\u5347\u7EA7\u9879\u76EE\u76EE\u5F55\u5230\u6700\u65B0\u6A21\u677F\u7248\u672C\uFF0C\u81EA\u52A8\u4FDD\u7559\u7528\u6237\u914D\u7F6E\uFF1B\u6216\u7528 --from/--to \u5728\u4E24\u4E2A\u76EE\u5F55\u95F4\u505A\u5408\u5E76\u8FC1\u79FB").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u8DEF\u5F84",e.defaultConfig).option("--from <dir>","\u6E90\u76EE\u5F55\uFF1A\u4EE5\u8BE5\u76EE\u5F55\u4E3A\u8FC1\u79FB\u57FA\u51C6\uFF08\u4E0D\u6309\u540D scaffold \u6A21\u677F\uFF09\uFF0C\u4E0E --template/--profile \u4E92\u65A5").option("--to <dir>","\u76EE\u6807\u9879\u76EE\u76EE\u5F55\uFF08--config \u7684\u540C\u4E49\u53C2\u6570\uFF0C\u4F18\u5148\u751F\u6548\uFF09").option("--dry-run","\u4EC5\u9884\u89C8\u53D8\u66F4\uFF0C\u4E0D\u5B9E\u9645\u5199\u5165").option("--no-backup","\u8DF3\u8FC7\u81EA\u52A8\u5907\u4EFD").option("--force","\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A").option("--template <name>","\u6307\u5B9A\u76EE\u6807\u6A21\u677F").option("--profile <name>","\u6307\u5B9A\u76EE\u6807 profile").option("--rollback","\u56DE\u6EDA\u5230\u4E0A\u4E00\u6B21\u8FC1\u79FB\u524D\u7684\u72B6\u6001").option("--list","\u5217\u51FA\u6240\u6709\u5907\u4EFD").action(async t=>{try{await qt({config:t.config,from:t.from,to:t.to,dryRun:t.dryRun,noBackup:t.backup===!1,force:t.force,template:t.template,profile:t.profile,rollback:t.rollback,list:t.list,templatesDir:Vt.resolve(e.cliDir,"..","templates"),templatePackageVersions:e.packageVersions,cliVersion:e.version})}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),Yt.error("cli","migrate \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Fe,"registerMigrateCommand");import{runDesignCommand as Jt,logger as zt}from"aitable-workflow-core";function Be(r,e){r.command("design").description("\u8BA9 Coding Agent \u6839\u636E\u573A\u666F\u63CF\u8FF0\u751F\u6210\u5B8C\u6574\u7684 workflow \u548C recipes").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("-y, --yes","\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u8865\u5145\uFF0C\u76F4\u63A5\u4F7F\u7528 config \u4E2D\u7684 scene").option("--skip-questions","\u4E0D\u56DE\u7B54 Agent \u7684\u6F84\u6E05\u63D0\u95EE\uFF08Agent \u6309\u5047\u8BBE\u751F\u6210\u5E76\u5217\u51FA\u5F85\u786E\u8BA4\u9879\uFF09").action(async t=>{try{await Jt(t)}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),zt.error("cli","design \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Be,"registerDesignCommand");import{runCheck as Ne,runSetupCommand as Xt,checkMigrateHint as Qt,logger as Zt}from"aitable-workflow-core";import Ge from"path";function we(r){return r.skipConfig||r.skipConfigIfValid&&r.configValid===!0}c(we,"canSkipSetupConfig");function We(r){return we(r)?"setup":r.uiEnabled&&r.webAvailable?"web":"cli"}c(We,"resolveSetupConfigRoute");function He(r,e){r.command("setup").description("\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E\uFF0C\u518D\u521D\u59CB\u5316 AI \u8868\u683C\u7ED3\u6784 + \u7F16\u8BD1\u77E5\u8BC6\u5E93 \u2014 \u4E00\u6B21\u5B8C\u6210 config + \u5EFA\u8868").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("--no-clean","\u4E0D\u6E05\u7406\u7A7A\u767D\u884C").option("--no-kb","\u8DF3\u8FC7\u77E5\u8BC6\u5E93\u7F16\u8BD1").option("--kb-full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1\u77E5\u8BC6\u5E93").option("--skip-config","\u8DF3\u8FC7\u524D\u7F6E\u7684\u4EA4\u4E92\u5F0F\u914D\u7F6E\u6821\u9A8C\uFF08CI/\u5DF2\u786E\u8BA4\u914D\u7F6E\u65F6\u4F7F\u7528\uFF09").option("--skip-config-if-valid","\u5148\u6821\u9A8C\u914D\u7F6E\uFF1B\u65E0\u963B\u65AD\u9879\u65F6\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u76F4\u63A5\u5F00\u59CB\u642D\u5EFA").option("--no-ui","\u5F3A\u5236\u4F7F\u7528\u547D\u4EE4\u884C\u4EA4\u4E92\uFF08\u8DF3\u8FC7\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762\uFF09").action(async t=>{try{if(await Qt(Ge.dirname(Ge.resolve(t.config)),e.version),!t.skipConfig){let n=t.ui!==!1,o=!1;if(t.skipConfigIfValid){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u9879\u76EE\u914D\u7F6E");let i=await Ne({configPath:t.config});if(o=we({skipConfig:!1,skipConfigIfValid:!0,configValid:i.ok}),o){let s=[];i.summary.warnings>0&&s.push(`${i.summary.warnings} \u9879\u8B66\u544A`),i.summary.suggestions>0&&s.push(`${i.summary.suggestions} \u9879\u5EFA\u8BAE`);let a=s.length>0?`\uFF08${s.join("\uFF0C")}\uFF0C\u5747\u4E0D\u963B\u65AD\uFF09`:"";console.log(`\u2713 \u914D\u7F6E\u65E0\u963B\u65AD\u9879${a}\uFF0C\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u7EE7\u7EED\u642D\u5EFA\u3002`)}else console.log(`\u2139 \u68C0\u6D4B\u5230 ${i.summary.errors} \u9879\u963B\u65AD\uFF0C\u8FDB\u5165\u914D\u7F6E\u73AF\u8282\u3002`)}if(!o&&n){let{hasWebRoot:i,runConfigUI:s}=await import("./config-ui-server-BEAEXJ5Z.js");if(We({skipConfig:!1,skipConfigIfValid:t.skipConfigIfValid===!0,uiEnabled:n,webAvailable:i(),configValid:o})==="web"){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");try{await s({configPath:t.config}),o=(await Ne({configPath:t.config})).ok}catch(l){console.warn(`
3
+ \u26A0 \u53EF\u89C6\u5316\u754C\u9762\u5F02\u5E38\uFF0C\u56DE\u9000\u5230\u547D\u4EE4\u884C\u4EA4\u4E92: ${l instanceof Error?l.message:String(l)}
4
+ `)}}}if(!o){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E");let{runConfigCommand:i}=await import("./config-command-JNDJNEFV.js");(await i({configPath:t.config,interactive:!0,offerSkipToBuild:!0})).ok||(console.error(`
5
+ \u2717 \u9879\u76EE\u914D\u7F6E\u4ECD\u4E0D\u5B8C\u6574\uFF0C\u5DF2\u4E2D\u6B62 setup\u3002\u8BF7\u8865\u9F50\u5FC5\u586B\u9879\u540E\u91CD\u8BD5\uFF08\u6216\u7528 --skip-config \u8DF3\u8FC7\uFF09\u3002`),process.exit(1))}console.log(`
6
+ \u{1F527} \u6B65\u9AA4 2/2\uFF1A\u521D\u59CB\u5316\u8868\u7ED3\u6784 + \u7F16\u8BD1\u77E5\u8BC6\u5E93
7
+ `)}await Xt(t)}catch(n){Zt.error("cli","setup \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(He,"registerSetupCommand");import{createApp as en,ensureTsxRegistered as tn,checkMigrateHint as nn,logger as P}from"aitable-workflow-core";import Ke from"path";function on(){let t=[],n=c(()=>{let o=Date.now();for(t.push(o);t.length>0&&o-t[0]>6e4;)t.shift();t.length>=10&&(P.error("cli",`60000ms \u5185\u53D1\u751F ${t.length} \u6B21\u672A\u6355\u83B7\u5F02\u5E38\uFF0C\u7591\u4F3C\u975E\u5076\u53D1\u9519\u8BEF\uFF0C\u4E3B\u52A8\u9000\u51FA`),process.exit(1))},"recordCrashAndMaybeExit");process.on("uncaughtException",o=>{P.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406\u5F02\u5E38\uFF08\u5DF2\u5B58\u6D3B\uFF0C\u4EA4\u7531\u91CD\u8FDE/\u91CD\u8BD5\u903B\u8F91\u81EA\u6108\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()}),process.on("unhandledRejection",o=>{P.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406 Promise \u62D2\u7EDD\uFF08\u5DF2\u5B58\u6D3B\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()})}c(on,"installLongRunningCrashGuards");function qe(r,e){r.command("run").description("\u542F\u52A8\u7F16\u6392\u5F15\u64CE\uFF0C\u5F00\u59CB\u8F6E\u8BE2\u5904\u7406\u5DE5\u5355").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("--emit-events <channel>","\u8FD0\u884C\u4E8B\u4EF6\u4E0A\u629B\u901A\u9053\uFF1Aipc = \u7ECF process.send \u53D1\u7ED9\u7236\u8FDB\u7A0B\uFF08daemon runner \u7528\uFF09\uFF0C\u7F3A\u7701\u4E0D\u4E0A\u629B").action(async t=>{try{await nn(Ke.dirname(Ke.resolve(t.config)),e.version),on(),await tn();let n=t.emitEvents==="ipc"&&typeof process.send=="function",o=await en(t.config,n?{onRunEvent:c(a=>{process.send?.({type:"run-event",event:a})},"onRunEvent")}:{}),i=!1,s=c(async()=>{i&&(P.warn("cli","\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),i=!0,P.info("cli","\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u7B49\u5F85\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u5B8C\u6210...");try{await o.stop()}finally{process.exit(0)}},"shutdown");process.on("SIGINT",s),process.on("SIGTERM",s),await o.start()}catch(n){P.error("cli","\u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(qe,"registerRunCommand");import{loadSettings as rn,loadWorkflowTemplate as sn}from"aitable-workflow-core";function Ye(r,e){r.command("validate").description("\u9A8C\u8BC1\u914D\u7F6E\u6587\u4EF6\u548C\u5DE5\u4F5C\u6D41\u6A21\u677F").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).action(async t=>{try{let n=await rn(t.config);console.log("\u2713 \u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u901A\u8FC7");let o=await sn(n.workflowTemplatePath,{envSource:n.envSource});console.log(`\u2713 \u5DE5\u4F5C\u6D41\u6A21\u677F\u9A8C\u8BC1\u901A\u8FC7: ${o.meta.name} (${o.orderedStepIds.length} \u6B65)`),console.log(`
8
+ \u6B65\u9AA4\u94FE:`);for(let[i,s]of o.orderedStepIds.entries()){let a=o.steps.find(m=>m.id===s),l=i<o.orderedStepIds.length-1?" \u2192":" \u2713";console.log(` ${i+1}. [${s}] ${a?.name??"?"}${l}`)}console.log(`
9
+ \u914D\u7F6E\u6458\u8981:`),console.log(` AI \u8868\u683C: base=${n.tracker.base_id} table=${n.tracker.table_id}`),console.log(` \u5F15\u64CE: ${n.agent.engine}`),console.log(` \u8F6E\u8BE2\u95F4\u9694: ${n.polling.interval_ms}ms`)}catch(n){console.error(`\u2717 \u9A8C\u8BC1\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}})}c(Ye,"registerValidateCommand");import{createExecShellToolkit as an,loadSettings as cn}from"aitable-workflow-core";function Ve(r,e){r.command("exec").description("\u9003\u751F\u8231\uFF1A\u5728\u5B9E\u4F8B\u4E0A\u4E0B\u6587\u4E0B\u8BD5\u8DD1\u4E00\u6761\u547D\u4EE4\uFF08\u590D\u7528 shell toolkit \u7684 bins \u89E3\u6790/\u8D85\u65F6/\u8131\u654F\uFF09\uFF0C\u7528\u4E8E dws/git \u547D\u4EE4\u9762 smoke\u3002\u7528\u6CD5\uFF1Aaitable-workflow exec [-c <path>] [--json] -- <bin> <args...>").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("--timeout <ms>","\u5355\u6B21\u6267\u884C\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").option("--json","\u4EE5 runJson \u65B9\u5F0F\u6267\u884C\uFF1A\u8981\u6C42 exit=0 \u4E14 stdout \u4E3A\u5408\u6CD5 JSON\uFF0C\u6253\u5370\u89E3\u6790\u540E\u7684\u5BF9\u8C61").allowUnknownOption().argument("<command...>","\u8981\u6267\u884C\u7684\u547D\u4EE4\u53CA\u53C2\u6570\uFF08\u5EFA\u8BAE\u7528 -- \u5206\u9694\uFF09\uFF0C\u5982\uFF1Adws chat group create --name x --format json").action(async(t,n)=>{try{let[o,...i]=t;o||(console.error("\u2717 \u672A\u63D0\u4F9B\u8981\u6267\u884C\u7684\u547D\u4EE4\uFF1B\u7528\u6CD5\uFF1Aaitable-workflow exec [-c <path>] -- <bin> <args...>"),process.exit(1));let s=await cn(n.config),a=an(s,o),l=n.timeout?Number.parseInt(n.timeout,10):void 0;if(l!==void 0&&(Number.isNaN(l)||l<=0)&&(console.error("\u2717 --timeout \u5FC5\u987B\u662F\u6B63\u6574\u6570\uFF08\u6BEB\u79D2\uFF09"),process.exit(1)),n.json){let p=await a.runJson(o,i,{timeoutMs:l});console.log(JSON.stringify(p??{},null,2));return}let m=await a.run(o,i,{timeoutMs:l});m.stdout&&process.stdout.write(m.stdout),m.stderr&&process.stderr.write(m.stderr),m.truncated&&console.error(`
10
+ \u26A0\uFE0F \u8F93\u51FA\u56E0\u8D85\u8FC7\u4E0A\u9650\u88AB\u622A\u65AD`),process.exit(m.exitCode??0)}catch(o){console.error(`\u2717 exec \u5931\u8D25: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}})}c(Ve,"registerExecCommand");import{logger as ln}from"aitable-workflow-core";function Je(r,e){r.command("config").description("\u6821\u9A8C\u9879\u76EE\u914D\u7F6E\u5B8C\u6574\u6027\uFF0C\u5E76\u53EF\u4EA4\u4E92\u5F0F\u4FEE\u6539\u53C2\u6570").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u6821\u9A8C\u7684\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u6821\u9A8C\u5168\u90E8\uFF09").option("--json","JSON \u683C\u5F0F\u8F93\u51FA\u6821\u9A8C\u7ED3\u679C").option("--no-interactive","\u4EC5\u6821\u9A8C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u4FEE\u6539").action(async t=>{try{let{runConfigCommand:n}=await import("./config-command-JNDJNEFV.js");await n({configPath:t.config,workflowId:t.workflow,json:t.json,interactive:t.interactive})}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),ln.error("cli","config \u547D\u4EE4\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Je,"registerConfigCommand");import{runSync as mn,logger as dn}from"aitable-workflow-core";function ze(r,e){r.command("sync").description("\u68C0\u6D4B\u914D\u7F6E\u4E0E\u8868\u7684\u504F\u5DEE\uFF08\u5B57\u6BB5\u7C7B\u578B/\u9009\u9879 drift\uFF09\uFF0C\u8F93\u51FA\u8BCA\u65AD\u62A5\u544A\u548C\u4FEE\u590D\u5EFA\u8BAE").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("-y, --yes","\u975E\u4EA4\u4E92\u6A21\u5F0F").action(async t=>{try{await mn({configPath:t.config,yes:t.yes})}catch(n){dn.error("cli","sync \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(ze,"registerSyncCommand");import{listCodingAgents as pn,logger as gn}from"aitable-workflow-core";function Xe(r,e){r.command("agents").description("\u5217\u51FA\u5168\u90E8\u652F\u6301\u7684 Coding Agent \u9002\u914D\u5668\uFF0C\u5E76\u6807\u6CE8\u672C\u673A\u5DF2\u63A2\u6D4B\u5230\u5B89\u88C5\u7684").option("--json","\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action(t=>{try{let n=pn();if(t.json){process.stdout.write(JSON.stringify(n,null,2)+`
11
+ `);return}let o=n.filter(i=>i.installed).length;console.log(`
12
+ \u652F\u6301 ${n.length} \u4E2A Coding Agent\uFF0C\u672C\u673A\u5DF2\u63A2\u6D4B\u5230 ${o} \u4E2A\uFF1A
13
+ `);for(let i of n){let s=i.installed?"\u2713":"\u2717",a=[i.bin,...i.fallbackBins].join(" / "),l=i.installed?`\u5DF2\u5B89\u88C5 (${i.detectedCmd}${i.detectedVersion?` ${i.detectedVersion}`:""})`:"\u672A\u63A2\u6D4B\u5230";console.log(` ${s} ${i.name.padEnd(16)} [${i.id}] bin: ${a.padEnd(24)} ${l}`)}console.log("")}catch(n){gn.error("cli","\u5217\u51FA agents \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Xe,"registerAgentsCommand");import{logger as un}from"aitable-workflow-core";import{startServer as fn,resolveServeConfig as hn}from"aitable-workflow-server";import Q from"path";import{existsSync as Qe}from"fs";function Ze(r,e){r.command("serve").description("\u542F\u52A8\u672C\u5730 HTTP API \u670D\u52A1\u5E76\u6258\u7BA1 Web \u524D\u7AEF\u9875\u9762\uFF08local \u6A21\u5F0F\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF09").option("-p, --port <number>","\u76D1\u542C\u7AEF\u53E3\uFF08\u9ED8\u8BA4 8787\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_PORT \u8986\u76D6\uFF09").option("--host <host>","\u76D1\u542C\u5730\u5740\uFF08\u9ED8\u8BA4 127.0.0.1\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_HOST \u8986\u76D6\uFF09").option("--data-root <path>","\u9879\u76EE\u5DE5\u4F5C\u533A\u6570\u636E\u76EE\u5F55\uFF08\u9ED8\u8BA4 .sandbox/aitable-workflow-server\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_DATA_DIR \u8986\u76D6\uFF09").option("--web-root <path>","Web \u524D\u7AEF\u9759\u6001\u8D44\u6E90\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u968F CLI \u6253\u5305\u7684 dist/web\uFF09").option("--no-open","\u542F\u52A8\u540E\u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF08\u9ED8\u8BA4\u81EA\u52A8\u6253\u5F00\uFF09").action(async t=>{try{let n={};if(t.port!==void 0){let i=Number.parseInt(t.port,10);Number.isFinite(i)&&i>0&&(n.port=i)}if(t.host!==void 0&&(n.host=t.host),t.dataRoot!==void 0&&(n.dataRoot=t.dataRoot),t.webRoot!==void 0)n.webRoot=t.webRoot;else{let i=Q.join(e.cliDir,"web");if(Qe(Q.join(i,"index.html")))n.webRoot=i;else{let s=Q.resolve(e.cliDir,"..","..","web","dist");Qe(Q.join(s,"index.html"))&&(n.webRoot=s)}}let o=hn(n);if(await fn(o),o.webRoot&&t.open!==!1){let i=o.host==="0.0.0.0"?"127.0.0.1":o.host;Pe(`http://${i}:${o.port}`)}}catch(n){un.error("cli","HTTP \u670D\u52A1\u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Ze,"registerServeCommand");import{Command as $e}from"commander";import{logger as I,listCredentials as Ct,getActiveCredential as j,maskSecret as $o}from"aitable-workflow-core";import O from"os";import D from"path";import{mkdir as ro,readFile as io}from"fs/promises";import{mkdirSync as so}from"fs";import{logger as f,detectInstalledAgents as ao,runCodingAgent as co,DwsClient as lo,getActiveCredential as mo,assertPortableId as ft,resolveInsideRoot as ut,probeCommand as po}from"aitable-workflow-core";import ye from"ws";import{logger as S,RELAY_REJECTED_CODE as wn,isRelayMessage as yn}from"aitable-workflow-core";var E="relay:conn",et=1e3,kn=3e4,vn=Number(process.env.AITABLE_RELAY_SERVER_STALE_MS??9e4),Z=class{static{c(this,"RelayConnection")}ws=null;delay=et;timer=null;watchdog=null;should=!0;permanentlyRejected=!1;accepted=!1;lastServerFrameAt=0;serverUrl;key;token;onMessage;onOpen;onAccepted;onPermanentReject;mkWs;staleMs;constructor(e){this.serverUrl=e.serverUrl,this.key=e.key??"",this.token=e.token??"",this.onMessage=e.onMessage,this.onOpen=e.onOpen,this.onAccepted=e.onAccepted,this.onPermanentReject=e.onPermanentReject,this.mkWs=e.mkWs??(t=>new ye(t)),this.staleMs=e.staleMs??vn}connect(){this.permanentlyRejected||(this.should=!0,this.doConnect())}send(e){this.ws&&this.ws.readyState===ye.OPEN&&this.ws.send(JSON.stringify(e))}close(){this.should=!1,this.timer&&(clearTimeout(this.timer),this.timer=null),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.ws?.close()}isPermanentlyRejected(){return this.permanentlyRejected}currentSocket(){return this.ws}buildUrl(){let e=this.serverUrl.replace(/\/+$/,"").replace(/^http/,"ws"),t=this.token?`token=${encodeURIComponent(this.token)}`:`key=${encodeURIComponent(this.key)}`;return`${e}/api/relay/connect?${t}`}doConnect(){if(!this.should||this.permanentlyRejected)return;let e=this.buildUrl();S.info(E,"connecting",{serverUrl:this.serverUrl}),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.accepted=!1,this.lastServerFrameAt=0;let t=this.mkWs(e);this.ws=t,t.on("open",()=>{S.info(E,"connected"),this.onOpen?.(t)}),t.on("message",n=>{this.accepted||(this.accepted=!0,this.delay=et,this.onAccepted?.(t)),this.lastServerFrameAt=Date.now(),this.armWatchdog();let o;try{o=JSON.parse(typeof n=="string"?n:String(n))}catch{return}yn(o)&&(o.type==="ping"&&this.send({type:"pong"}),this.onMessage(o))}),t.on("close",(n,o)=>{this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null);let i=o==null?"":String(o);if(n===wn){this.permanentlyRejected=!0,this.should=!1,S.error(E,"server permanently rejected this machine: its connection key is unknown or was removed; re-issue the relay connect command and restart with the new key",{code:n,reason:i}),this.onPermanentReject?.({code:n,reason:i});return}S.warn(E,"disconnected",{code:n}),this.scheduleReconnect()}),t.on("error",n=>{S.error(E,"ws error",{detail:n instanceof Error?n.message:String(n)})})}armWatchdog(){this.watchdog&&clearTimeout(this.watchdog),this.watchdog=setTimeout(()=>{if(!(!this.accepted||!this.lastServerFrameAt||this.ws?.readyState!==ye.OPEN)){S.warn(E,"server heartbeat stale; closing socket to reconnect",{staleMs:Date.now()-this.lastServerFrameAt});try{this.ws.close()}catch{}}},this.staleMs+1),this.watchdog.unref?.()}scheduleReconnect(){!this.should||this.permanentlyRejected||this.timer||(S.info(E,"reconnecting",{ms:this.delay}),this.timer=setTimeout(()=>{this.timer=null,this.doConnect()},this.delay),this.timer.unref?.(),this.delay=Math.min(this.delay*2,kn))}};import{createHash as Rn}from"crypto";import{readdir as bn,readFile as Cn,stat as In}from"fs/promises";import tt from"path";import{isAllowedArtifactPath as An,normalizeArtifactRelPath as xn}from"aitable-workflow-core";var nt={async upload(r,e,t){let n=await fetch(r,{method:"PUT",body:e,headers:{...t}});if(!n.ok)throw new Error(`artifact PUT failed: ${n.status} ${n.statusText}`)}};async function ot(r){let e=[];return await rt(r,r,e),e.sort((t,n)=>t.relPath.localeCompare(n.relPath))}c(ot,"scanArtifacts");async function rt(r,e,t){let n;try{n=await bn(e,{withFileTypes:!0})}catch{return}for(let o of n){if(o.name==="node_modules"||o.name.startsWith("."))continue;let i=tt.join(e,o.name);if(o.isDirectory())await rt(r,i,t);else if(o.isFile()){let s=tt.relative(r,i).replace(/\\/g,"/");if(!An(s))continue;let a=await In(i),l=await Cn(i),m=Rn("sha256").update(l).digest("hex");t.push({relPath:xn(s),absPath:i,size:a.size,sha256:m})}}}c(rt,"walk");import gt from"path";import{logger as v}from"aitable-workflow-core";import{logger as L,spawnManagedProcess as Sn}from"aitable-workflow-core";var _="engine-supervisor",ee=class{static{c(this,"EngineSupervisor")}options;doSpawn;setTimer;clearTimer;child=null;childGen=0;consecutiveFailures=0;lastExitCode=null;lastError=null;restartTimer=null;stopped=!0;constructor(e){this.options=e,this.doSpawn=e.spawnImpl??Sn,this.setTimer=e.setTimeoutImpl??((t,n)=>setTimeout(t,n)),this.clearTimer=e.clearTimeoutImpl??(t=>clearTimeout(t))}get status(){return{running:this.child!=null,pid:this.child?.managed.child.pid??null,generation:this.childGen,startedAt:this.child?new Date(this.child.startedAt).toISOString():null,consecutiveFailures:this.consecutiveFailures,lastExitCode:this.lastExitCode,lastError:this.lastError}}start(){this.stopped=!1,!this.child&&this.spawnChild()}async stop(){this.stopped=!0,this.restartTimer&&(this.clearTimer(this.restartTimer),this.restartTimer=null);let e=this.child;if(!e)return;e.stopping=!0;let t=e.managed.child.pid;if(t==null){this.child=null;return}let n=e.gen;await e.managed.terminateTree({gracePeriodMs:this.options.drainTimeoutMs??2e4}),e.managed.child.exitCode==null&&e.managed.child.signalCode==null&&(L.error(_,"\u5F15\u64CE\u8FDB\u7A0B\u672A\u54CD\u5E94\u5F3A\u5236\u7EC8\u6B62\uFF0C\u653E\u5F03\u7B49\u5F85\uFF08\u53EF\u80FD\u6B8B\u7559\u5B64\u513F\u8FDB\u7A0B\uFF09",{projectId:this.options.projectId,pid:t,generation:n}),this.child?.gen===n&&(this.child=null))}spawnChild(){this.childGen+=1;let e=this.childGen,t=["run","--config",this.options.workspaceDir,"--emit-events","ipc"],n=this.doSpawn({command:process.execPath,args:[this.options.cliPath,...t],cwd:this.options.workspaceDir,stdio:["ignore","pipe","pipe","ipc"],...this.options.env?{env:this.options.env}:{}}),o=n.child,i={managed:n,gen:e,startedAt:Date.now(),stopping:!1};this.child=i,L.info(_,"engine started",{projectId:this.options.projectId,pid:o.pid,generation:e}),o.on("message",s=>{En(s)&&this.options.onRunEvent?.(s.event)}),o.on("error",s=>{this.lastError=s.message,L.error(_,"engine spawn error",{projectId:this.options.projectId,error:s.message})}),o.on("exit",(s,a)=>this.handleExit(i,s,a))}handleExit(e,t,n){if(this.child?.gen===e.gen&&(this.child=null),this.lastExitCode=t,L.info(_,"engine exited",{projectId:this.options.projectId,generation:e.gen,code:t,signal:n}),e.stopping||this.stopped)return;this.consecutiveFailures+=1;let o=this.options.maxConsecutiveFailures??5;if(this.consecutiveFailures>=o){L.error(_,"engine crash loop\uFF0C\u505C\u6B62\u91CD\u542F\u5E76\u4E0A\u62A5",{projectId:this.options.projectId,failures:this.consecutiveFailures}),this.stopped=!0,this.options.onCrashLoop?.({projectId:this.options.projectId,failures:this.consecutiveFailures,lastExitCode:t});return}let i=this.options.restartBackoffMs??1e3,s=this.options.restartBackoffMaxMs??6e4,a=Math.min(s,i*2**(this.consecutiveFailures-1));L.warn(_,"engine \u5F02\u5E38\u9000\u51FA\uFF0C\u9000\u907F\u91CD\u542F",{projectId:this.options.projectId,failures:this.consecutiveFailures,delayMs:a}),this.restartTimer=this.setTimer(()=>{this.restartTimer=null,!this.stopped&&!this.child&&this.spawnChild()},a)}markHealthy(){this.consecutiveFailures=0}};function En(r){return typeof r=="object"&&r!==null&&r.type==="run-event"&&"event"in r}c(En,"isRunEventMessage");import{appendFile as Tn,mkdir as $n,rename as jn,stat as Pn}from"fs/promises";import Ln from"path";import{logger as te}from"aitable-workflow-core";var ne="event-spool",oe=class{static{c(this,"EventSpool")}options;setInterval;clearInterval;now;buffer=[];pending=[];seq=0;timer=null;flushing=!1;constructor(e){this.options=e,this.setInterval=e.setIntervalImpl??((t,n)=>setInterval(t,n)),this.clearInterval=e.clearIntervalImpl??(t=>clearInterval(t)),this.now=e.now??Date.now}get lastSeq(){return this.seq}get pendingCount(){return this.pending.length}start(){this.timer||(this.timer=this.setInterval(()=>{this.flush()},this.options.flushIntervalMs??500))}async stop(){this.timer&&(this.clearInterval(this.timer),this.timer=null),await this.flush()}append(e){this.seq+=1;let t={seq:this.seq,ts:new Date(this.now()).toISOString(),event:e};this.pending.push(t),this.buffer.push(t);let n=this.options.maxPending??5e3;if(this.pending.length>n){let i=this.pending.splice(0,this.pending.length-n);te.warn(ne,"\u5F85\u53D1\u4E8B\u4EF6\u8D85\u4E0A\u9650\uFF0C\u4E22\u5F03\u6700\u65E7\u7684\u6279\u6B21",{projectId:this.options.projectId,dropped:i.length,untilSeq:i[i.length-1]?.seq})}let o=this.options.retain??2e3;this.buffer.length>o&&this.buffer.splice(0,this.buffer.length-o),this.options.persist!==!1&&this.persist(t)}async flush(){if(this.flushing||this.pending.length===0)return;this.flushing=!0;let e=this.pending.slice(0,this.options.maxBatch??200);try{await this.options.send(e);let t=new Set(e.map(n=>n.seq));this.pending=this.pending.filter(n=>!t.has(n.seq))}catch(t){te.warn(ne,"\u4E8B\u4EF6\u6279\u4E0A\u884C\u5931\u8D25\uFF08\u4FDD\u7559\u5F85\u4E0B\u8F6E\u91CD\u8BD5\uFF09",{projectId:this.options.projectId,count:e.length,error:t instanceof Error?t.message:String(t)})}finally{this.flushing=!1}}replayFrom(e){let t=new Set(this.pending.map(o=>o.seq)),n=this.buffer.filter(o=>o.seq>e&&!t.has(o.seq));return n.length===0?0:(this.pending=[...this.pending,...n].sort((o,i)=>o.seq-i.seq),te.info(ne,"\u8865\u4F20\u7F3A\u53E3\u4E8B\u4EF6",{projectId:this.options.projectId,serverLastSeq:e,replay:n.length}),n.length)}async persist(e){let t=Ln.join(this.options.spoolDir,"run-events.jsonl");try{await $n(this.options.spoolDir,{recursive:!0}),await Pn(t).then(o=>o.size).catch(()=>0)>(this.options.rotateBytes??10*1024*1024)&&await jn(t,`${t}.1`).catch(()=>{}),await Tn(t,`${JSON.stringify(e)}
14
+ `,"utf8")}catch(n){te.warn(ne,"spool \u843D\u76D8\u5931\u8D25",{projectId:this.options.projectId,error:n instanceof Error?n.message:String(n)})}}};import{readdir as Ce,rm as be,stat as se}from"fs/promises";import M from"path";import{logger as W}from"aitable-workflow-core";import{createHash as Bn}from"crypto";import{mkdir as ve,readFile as Wn,rename as Nn,rm as Gn,writeFile as ct}from"fs/promises";import re from"path";import{decodeWorkspaceBundle as Hn,logger as Kn,resolveInsideRoot as qn}from"aitable-workflow-core";import{chmod as _n,readFile as Mn,rename as Dn,writeFile as On}from"fs/promises";var it="# \u2500\u2500\u2500 aitable-workflow managed credentials (auto-generated, do not edit) \u2500\u2500\u2500",st="# \u2500\u2500\u2500 end managed credentials \u2500\u2500\u2500";function Un(r,e){let t=r.split(`
15
+ `),n=t.indexOf(it),o=t.indexOf(st),i;n!==-1&&o!==-1&&o>n?i=[...t.slice(0,n),...t.slice(o+1)].join(`
16
+ `):i=r,i=i.replace(/^\n+/,"");let s=Object.entries(e).sort(([l],[m])=>l.localeCompare(m));return s.length===0?i:`${[it,...s.map(([l,m])=>`${l}=${Fn(m)}`),st].join(`
17
+ `)}
18
+ ${i?`
19
+ ${i}`:""}`}c(Un,"mergeEnvContent");function Fn(r){return r===""||/[\s#'"`\\]/.test(r)?`"${r.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`:r}c(Fn,"quoteEnvValue");async function at(r,e){let t=await Mn(r,"utf8").catch(()=>""),n=Un(t,e);if(n===t||n===""&&t==="")return!1;let o=`${r}.aitable-sync-tmp`;return await On(o,n,{encoding:"utf8",mode:384}),await _n(o,384).catch(()=>{}),await Dn(o,r),!0}c(at,"mergeEnvFile");var Yn="workspace-sync",ie=".workspace-meta.json";function Vn(r){return Bn("sha256").update(r).digest("hex")}c(Vn,"sha256Hex");async function ke(r,e){let n=await(r.fetchImpl??fetch)(`${r.gatewayUrl.replace(/\/+$/,"")}${e}`,{headers:{authorization:`Bearer ${r.machineKey}`}});if(!n.ok){let o=await n.text().catch(()=>"");throw new Error(`runner API ${e} \u5931\u8D25: HTTP ${n.status} ${o.slice(0,200)}`)}return n}c(ke,"apiGet");async function Jn(r){try{let e=await Wn(re.join(r,ie),"utf8"),t=JSON.parse(e);return t&&typeof t.projectId=="string"?t:null}catch{return null}}c(Jn,"readWorkspaceMeta");function Re(r,e){return qn(r,e,{allowRoot:!1})}c(Re,"resolveTracked");async function zn(r,e){let t=Re(r,e.path);await ve(re.dirname(t),{recursive:!0});let n=`${t}.aitable-sync-tmp`;await ct(n,e.content,"utf8"),await Nn(n,t)}c(zn,"writeTracked");async function lt(r,e,t){let n=await Jn(t);if(n&&n.projectId!==e)throw new Error(`\u5DE5\u4F5C\u533A\u76EE\u5F55\u5F52\u5C5E\u4E0D\u7B26: \u76EE\u5F55\u8BB0\u5F55 projectId=${n.projectId}\uFF0C\u8BF7\u6C42\u540C\u6B65 ${e}\uFF08${t}\uFF09`);let i=await(await ke(r,`/api/runner/workspace/${e}`)).json(),s=0,a=0,l="up-to-date",m=n?.trackedManifest??{};if(!n||n.revision!==i.revision){l="synced";let y=await ke(r,`/api/runner/workspace/${e}/bundle`),C=Hn(Buffer.from(await y.arrayBuffer()));if(C.projectId!==e)throw new Error(`\u5FEB\u7167\u5305\u5F52\u5C5E\u4E0D\u7B26: \u5305\u5185 projectId=${C.projectId}\uFF0C\u671F\u671B ${e}`);C.revision!==i.revision&&(i.revision=C.revision),await ve(t,{recursive:!0});let x={};for(let b of C.files)x[b.path]=Vn(b.content);for(let b of C.files)Re(t,b.path);let J=n?.trackedManifest??{};for(let b of C.files)J[b.path]!==x[b.path]&&(await zn(t,b),s+=1);for(let b of Object.keys(J))if(x[b]===void 0){let je;try{je=Re(t,b)}catch(ue){Kn.warn(Yn,"\u8DF3\u8FC7\u8D8A\u754C\u7684\u65E7 manifest \u6761\u76EE",{projectId:e,path:b,error:ue instanceof Error?ue.message:String(ue)});continue}await Gn(je,{force:!0}).catch(()=>{}),a+=1}m=x}let u=await(await ke(r,`/api/runner/workspace/${e}/credentials`)).json();await ve(t,{recursive:!0});let g=await at(re.join(t,".env"),u.credentials??{}),d={projectId:e,revision:i.revision,syncedAt:new Date().toISOString(),trackedManifest:m};return await ct(re.join(t,ie),`${JSON.stringify(d,null,2)}
20
+ `,"utf8"),{projectId:e,revision:i.revision,action:l,written:s,deleted:a,envUpdated:g}}c(lt,"syncWorkspace");var N="runner-gc";async function dt(r){let e=0,t;try{t=await Ce(r,{withFileTypes:!0})}catch{return 0}for(let n of t){let o=M.join(r,n.name);if(!n.isSymbolicLink()){if(n.isDirectory()){e+=await dt(o);continue}e+=await se(o).then(i=>i.size).catch(()=>0)}}return e}c(dt,"dirSize");async function Xn(r){let e=M.join(r,"projects"),t;try{t=await Ce(e,{withFileTypes:!0})}catch{return[]}let n=[];for(let o of t){if(!o.isDirectory())continue;let i=M.join(e,o.name),s=await se(M.join(i,ie)).then(l=>l.mtimeMs).catch(()=>null),a=await se(i).then(l=>l.mtimeMs).catch(()=>0);n.push({projectId:o.name,dir:i,lastTouchedMs:s??a,sizeBytes:await dt(i)})}return n}c(Xn,"scanProjects");async function mt(r,e){let t=M.join(r,"traces"),n;try{n=await Ce(t,{withFileTypes:!0})}catch{return 0}let o=[];for(let a of n){if(!a.isFile())continue;let l=M.join(t,a.name),m=await se(l).catch(()=>null);m&&o.push({full:l,size:m.size,mtimeMs:m.mtimeMs})}let i=o.reduce((a,l)=>a+l.size,0);if(i<=e)return 0;o.sort((a,l)=>a.mtimeMs-l.mtimeMs);let s=0;for(let a of o){if(i<=e)break;await be(a.full,{force:!0}).catch(()=>{}),i-=a.size,s+=a.size}return s}c(mt,"pruneTraces");async function pt(r){let e=(r.now??Date.now)(),t=(r.ttlDays??14)*24*60*60*1e3,n=r.tracesMaxBytes??500*1024*1024,o=r.maxDiskBytes??20*1024*1024*1024,i=new Set(r.activeProjectIds),s=await Xn(r.workspaceRoot),a=[],l=0;for(let g of s){if(i.has(g.projectId)){l+=await mt(g.dir,n);continue}if(e-g.lastTouchedMs>=t){await be(g.dir,{recursive:!0,force:!0}).catch(d=>{W.warn(N,"\u9879\u76EE\u76EE\u5F55\u56DE\u6536\u5931\u8D25",{projectId:g.projectId,error:d instanceof Error?d.message:String(d)})}),a.push(g.projectId),W.info(N,"\u56DE\u6536\u8FC7\u671F\u9879\u76EE\u76EE\u5F55",{projectId:g.projectId,idleDays:Math.floor((e-g.lastTouchedMs)/864e5)});continue}l+=await mt(g.dir,n)}let m=s.filter(g=>!a.includes(g.projectId)),p=m.reduce((g,d)=>g+d.sizeBytes,0)-l,u=!1;if(p>o){u=!0,W.warn(N,"\u5DE5\u4F5C\u533A\u8D85\u78C1\u76D8\u6C34\u4F4D\uFF0C\u5F00\u59CB\u56DE\u6536\u6700\u4E45\u672A\u8BA4\u9886\u9879\u76EE",{totalBytes:p,maxDiskBytes:o});let g=m.filter(d=>!i.has(d.projectId)).sort((d,y)=>d.lastTouchedMs-y.lastTouchedMs);for(let d of g){if(p<=o)break;await be(d.dir,{recursive:!0,force:!0}).catch(()=>{}),a.push(d.projectId),p-=d.sizeBytes,W.warn(N,"\u6C34\u4F4D\u56DE\u6536\u9879\u76EE\u76EE\u5F55",{projectId:d.projectId,freedBytes:d.sizeBytes})}p>o&&W.error(N,"\u56DE\u6536\u540E\u4ECD\u8D85\u78C1\u76D8\u6C34\u4F4D\uFF08\u6D3B\u8DC3\u9879\u76EE\u5360\u7528\uFF09\uFF0C\u9700\u4EBA\u5DE5\u4ECB\u5165",{totalBytes:p,maxDiskBytes:o})}return{removedProjects:a,tracesFreedBytes:l,diskPressure:u,totalBytes:Math.max(0,p)}}c(pt,"runGc");var R="runner-loop",ae=class{static{c(this,"RunnerLoop")}options;maxWorkflows;setTimer;clearTimer;doSync;holdings=new Map;pollTimer=null;gcTimer=null;running=!1;claiming=!1;constructor(e){this.options=e,this.maxWorkflows=Math.max(1,Math.floor(e.maxWorkflows??3)),this.setTimer=e.setTimeoutImpl??((t,n)=>setTimeout(t,n)),this.clearTimer=e.clearTimeoutImpl??(t=>clearTimeout(t)),this.doSync=e.syncImpl??lt}get held(){return[...this.holdings.values()].map(e=>({projectId:e.projectId,generation:e.generation,revision:e.revision,engine:e.engine.status}))}get freeSlots(){return Math.max(0,this.maxWorkflows-this.holdings.size)}start(){this.running||(this.running=!0,v.info(R,"runner loop \u542F\u52A8",{maxWorkflows:this.maxWorkflows,workspaceRoot:this.options.workspaceRoot}),this.claimOnce(),this.scheduleGc(0))}async stop(){this.running=!1,this.pollTimer&&(this.clearTimer(this.pollTimer),this.pollTimer=null),this.gcTimer&&(this.clearTimer(this.gcTimer),this.gcTimer=null),await Promise.all([...this.holdings.keys()].map(e=>this.releaseHolding(e,"daemon_shutdown")))}scheduleGc(e){let t=this.options.gcIntervalMs??864e5;!this.running||t<=0||(this.gcTimer&&this.clearTimer(this.gcTimer),this.gcTimer=this.setTimer(()=>{this.gcTimer=null,this.gcOnce().finally(()=>this.scheduleGc(t))},e))}async gcOnce(){try{let e=await(this.options.gcImpl??pt)({workspaceRoot:this.options.workspaceRoot,activeProjectIds:[...this.holdings.keys()],...this.options.gcOptions??{}});(e.removedProjects.length>0||e.tracesFreedBytes>0)&&v.info(R,"\u672C\u673A\u56DE\u6536\u5B8C\u6210",{removed:e.removedProjects.length,tracesFreedBytes:e.tracesFreedBytes,totalBytes:e.totalBytes})}catch(e){v.warn(R,"\u672C\u673A\u56DE\u6536\u5931\u8D25",{error:T(e)})}}onWakeup(){this.running&&this.claimOnce()}async claimOnce(){if(!this.running||this.claiming)return;this.claiming=!0;let e=this.options.defaultPollMs??1e4;try{let t=this.freeSlots;if(t>0){let n=await this.post("/api/runner/workflows/claim",{capacity:t});typeof n.nextPollAfterMs=="number"&&n.nextPollAfterMs>0&&(e=n.nextPollAfterMs);for(let o of n.grants??[])await this.acceptGrant(o,n.heartbeatIntervalSeconds)}}catch(t){v.warn(R,"claim \u5931\u8D25\uFF08\u9000\u907F\u540E\u91CD\u8BD5\uFF09",{error:T(t)}),e=Math.max(e,5e3)}finally{this.claiming=!1,this.scheduleNextPoll(e)}}scheduleNextPoll(e){this.running&&(this.pollTimer&&this.clearTimer(this.pollTimer),this.pollTimer=this.setTimer(()=>{this.pollTimer=null,this.claimOnce()},e))}async acceptGrant(e,t){if(this.holdings.has(e.projectId))return;let n=gt.join(this.options.workspaceRoot,"projects",e.projectId);v.info(R,"\u8BA4\u9886\u9879\u76EE",{projectId:e.projectId,generation:e.generation,workspaceDir:n});let o;try{o=await this.doSync(this.clientConfig(),e.projectId,n)}catch(l){v.error(R,"\u5DE5\u4F5C\u533A\u540C\u6B65\u5931\u8D25\uFF0C\u4EA4\u8FD8\u79DF\u7EA6",{projectId:e.projectId,error:T(l)}),await this.postSafe(`/api/runner/workflows/${e.projectId}/release`,{generation:e.generation,reason:"workspace_sync_failed"});return}let i=(this.options.createSupervisor??Qn)({projectId:e.projectId,workspaceDir:n,cliPath:this.options.cliPath,onRunEvent:c(l=>this.handleRunEvent(e.projectId,l),"onRunEvent"),onCrashLoop:c(()=>{this.releaseHolding(e.projectId,"engine_crash_loop")},"onCrashLoop")}),s=this.options.sendRunEvents?new oe({projectId:e.projectId,spoolDir:n,send:c(l=>this.options.sendRunEvents(e.projectId,l),"send")}):null;s?.start();let a={projectId:e.projectId,generation:e.generation,revision:o.revision,engine:i,spool:s,heartbeatTimer:null,busy:!1};this.holdings.set(e.projectId,a),i.start(),this.scheduleHeartbeat(a,(t??15)*1e3)}handleRunEvent(e,t){this.holdings.get(e)?.spool?.append(t),this.options.onRunEvent?.(e,t)}scheduleHeartbeat(e,t){this.running&&(e.heartbeatTimer&&this.clearTimer(e.heartbeatTimer),e.heartbeatTimer=this.setTimer(()=>{e.heartbeatTimer=null,this.heartbeatOnce(e)},t))}async heartbeatOnce(e){if(!this.running||e.busy||!this.holdings.has(e.projectId))return;let t=this.options.defaultHeartbeatMs??15e3;try{let n=await this.post(`/api/runner/workflows/${e.projectId}/heartbeat`,{generation:e.generation,workspaceRevision:e.revision,engineStatus:e.engine.status,...e.spool?{lastEventSeq:e.spool.lastSeq}:{}}),o=typeof n.nextIntervalSeconds=="number"&&n.nextIntervalSeconds>0?n.nextIntervalSeconds*1e3:t;if(e.spool&&typeof n.lastEventSeq=="number"&&e.spool.replayFrom(n.lastEventSeq),n.action==="stop"){v.info(R,"\u5FC3\u8DF3\u4E0B\u53D1 stop\uFF0C\u505C\u6B62\u5F15\u64CE",{projectId:e.projectId}),await this.releaseHolding(e.projectId,"heartbeat_stop");return}if(n.action==="resync"){await this.resyncHolding(e)&&this.scheduleHeartbeat(e,o);return}e.engine.markHealthy(),this.scheduleHeartbeat(e,o)}catch(n){v.warn(R,"\u5FC3\u8DF3\u5931\u8D25\uFF08\u4FDD\u6301\u5F15\u64CE\u8FD0\u884C\uFF0C\u7B49\u5F85\u6062\u590D\u6216\u79DF\u7EA6\u8FC7\u671F\uFF09",{projectId:e.projectId,error:T(n)}),this.scheduleHeartbeat(e,Math.min(t,5e3))}}async resyncHolding(e){if(e.busy)return!0;e.busy=!0;let t=gt.join(this.options.workspaceRoot,"projects",e.projectId);try{v.info(R,"\u5DE5\u4F5C\u533A\u9700\u91CD\u540C\u6B65\uFF0C\u91CD\u542F\u5F15\u64CE",{projectId:e.projectId}),await e.engine.stop();let n=await this.doSync(this.clientConfig(),e.projectId,t);e.revision=n.revision,e.engine.start()}catch(n){return v.error(R,"\u91CD\u540C\u6B65\u5931\u8D25\uFF0C\u4EA4\u8FD8\u79DF\u7EA6",{projectId:e.projectId,error:T(n)}),e.busy=!1,await this.releaseHolding(e.projectId,"resync_failed"),!1}return e.busy=!1,!0}async releaseHolding(e,t){let n=this.holdings.get(e);n&&(this.holdings.delete(e),n.heartbeatTimer&&(this.clearTimer(n.heartbeatTimer),n.heartbeatTimer=null),await n.engine.stop().catch(o=>{v.warn(R,"\u505C\u6B62\u5F15\u64CE\u5F02\u5E38",{projectId:e,error:T(o)})}),await n.spool?.stop().catch(()=>{}),await this.postSafe(`/api/runner/workflows/${e}/release`,{generation:n.generation,reason:t}),v.info(R,"\u5DF2\u8BA9\u51FA\u79DF\u7EA6",{projectId:e,reason:t}),this.running&&this.scheduleNextPoll(this.options.defaultPollMs??1e4))}clientConfig(){return{gatewayUrl:this.options.gatewayUrl,machineKey:this.options.machineKey,...this.options.fetchImpl?{fetchImpl:this.options.fetchImpl}:{}}}async post(e,t){let o=await(this.options.fetchImpl??fetch)(`${this.options.gatewayUrl.replace(/\/+$/,"")}${e}`,{method:"POST",headers:{authorization:`Bearer ${this.options.machineKey}`,"content-type":"application/json"},body:JSON.stringify(t??{})});if(!o.ok){let i=await o.text().catch(()=>"");throw new Error(`runner API ${e} \u5931\u8D25: HTTP ${o.status} ${i.slice(0,200)}`)}return await o.json()}async postSafe(e,t){try{await this.post(e,t)}catch(n){v.warn(R,"\u6536\u5C3E\u8BF7\u6C42\u5931\u8D25\uFF08\u79DF\u7EA6\u5C06\u7531\u670D\u52A1\u7AEF\u8FC7\u671F\u56DE\u6536\uFF09",{pathname:e,error:T(n)})}}};function Qn(r){return new ee({projectId:r.projectId,workspaceDir:r.workspaceDir,cliPath:r.cliPath,...r.onRunEvent?{onRunEvent:r.onRunEvent}:{},...r.onCrashLoop?{onCrashLoop:c(()=>r.onCrashLoop(),"onCrashLoop")}:{}})}c(Qn,"defaultSupervisorFactory");function T(r){return r instanceof Error?r.message:String(r)}c(T,"describeError");import{spawn as eo}from"child_process";import{existsSync as to}from"fs";import H from"path";import{fileURLToPath as no}from"url";import{appendFileSync as Wi,statSync as Ni,renameSync as Gi,mkdirSync as Hi,existsSync as Ki}from"fs";import Zn from"path";var Vi=10*1024*1024;function G(r){return Zn.join(z(r),"daemon.log")}c(G,"logFilePath");var ce=H.dirname(no(import.meta.url));function Ie(){let r=[H.resolve(ce,"..","..","bin","aitable-workflow.mjs"),H.resolve(ce,"..","bin","aitable-workflow.mjs"),H.resolve(ce,"..","..","dist","cli.js"),H.resolve(ce,"cli.js")];return r.find(e=>to(e))??r[0]}c(Ie,"resolveDaemonEntry");var oo=Ie();async function K(r){await Le(r.agentId);let e=["relay"];r.serverUrl&&e.push("--server-url",r.serverUrl),r.token&&e.push("--token",r.token),r.key&&e.push("--key",r.key),r.name&&e.push("--name",r.name),r.workspaceRoot&&e.push("--workspace-root",r.workspaceRoot),r.machineId&&e.push("--machine-id",r.machineId),r.maxTasks&&e.push("--max-tasks",String(r.maxTasks));let t=await import("fs").then(s=>{let a=G(r.agentId);return s.openSync(a,"a")}),n=eo(process.execPath,[oo,...e],{detached:!0,stdio:["ignore",t,t],env:{...process.env}});try{let{closeSync:s}=await import("fs");s(t)}catch{}n.unref();let{writeFile:o}=await import("fs/promises"),{pidFilePath:i}=await import("./pid-file-3JTHFPFF.js");return n.pid&&await o(i(r.agentId),String(n.pid),"utf8"),{pid:n.pid??0}}c(K,"startDaemon");async function le(r,e=5e3){let t=await fe(r);if(t===null||!B(t))return await X(r),!1;try{process.kill(t,"SIGTERM")}catch{return await X(r),!1}let n=Date.now()+e;for(;Date.now()<n&&B(t);)await new Promise(o=>setTimeout(o,200));if(B(t))try{process.kill(t,"SIGKILL")}catch{}return await X(r),!0}c(le,"stopDaemon");async function q(r){let e=await fe(r),t=e!==null&&B(e),n=null;if(t&&e!==null)try{let{readFile:o}=await import("fs/promises"),i=await o(`/proc/${e}/stat`,"utf8"),s=parseInt(i.split(" ")[21]??"0",10),a=await o("/proc/uptime","utf8"),p=parseFloat(a.split(" ")[0]??"0")-s/100;n=Math.round(p*1e3)}catch{}return{agentId:r,running:t,pid:t?e:null,uptimeMs:n,logFile:G(r)}}c(q,"getDaemonStatus");function go(r){return r.replace(/\/+$/,"").replace(/^ws/,"http")}c(go,"toHttpBase");var h="relay:daemon",ht=["aitable"],uo="dws";function fo(r,e=ht){if(!Array.isArray(r)||r.length===0)return{ok:!1,reason:"dws args must be a non-empty array"};for(let n of r){if(typeof n!="string")return{ok:!1,reason:"dws args must all be strings"};if(n.length===0)return{ok:!1,reason:"dws args must not contain empty tokens"};if(/[\u0000-\u001f]/.test(n))return{ok:!1,reason:"dws args must not contain control characters"}}let t=r[0];return t.startsWith("-")?{ok:!1,reason:"first dws arg must be a subcommand, not a flag"}:e.length>0&&!e.includes(t)?{ok:!1,reason:`dws command "${t}" is not allowed`}:{ok:!0}}c(fo,"validateDwsArgs");function ho(r){return po(r,["--version"],{timeoutMs:5e3}).ok}c(ho,"detectDwsAvailable");var Ae=class{static{c(this,"RelayDaemon")}config;allowedDwsCommands;conn;runAgent;createDwsClient;detectAgents;detectDws;hostname;osString;onPermanentReject;artifactUploader;grantTimeoutMs;pendingGrants=new Map;maxTasks;inflight=0;taskQueue=[];runnerLoop;machineId;constructor(e,t={}){this.config={...e,dwsBin:e.dwsBin??uo},this.machineId=e.machineId,this.allowedDwsCommands=e.allowedDwsCommands??ht,this.runAgent=t.runAgent??co,this.createDwsClient=t.createDwsClient??((o,i)=>new lo({bin:o,timeoutMs:i})),this.detectAgents=t.detectAgents??(()=>ao()),this.detectDws=t.detectDws??(o=>ho(o)),this.hostname=t.hostname??(()=>O.hostname()),this.osString=t.osString??(()=>`${O.platform()} ${O.arch()}`),this.onPermanentReject=t.onPermanentReject,this.artifactUploader=t.artifactUploader??nt,this.grantTimeoutMs=t.grantTimeoutMs??3e4,this.maxTasks=Math.max(1,Math.floor(e.maxTasks??1));let n=t.createConnection??(o=>new Z(o));this.conn=n({serverUrl:this.config.serverUrl,key:this.config.key,token:this.config.token,onMessage:c(o=>this.handleMessage(o),"onMessage"),onOpen:c(()=>this.handleOpen(),"onOpen"),onPermanentReject:c(o=>this.handlePermanentReject(o),"onPermanentReject")}),this.runnerLoop=this.buildRunnerLoop(t)}buildRunnerLoop(e){let t=Math.max(0,Math.floor(this.config.maxWorkflows??3));if(t===0)return null;let n=this.config.key??this.config.token;if(!n)return f.warn(h,"\u65E0 machine key/owner-token\uFF0C\u8DF3\u8FC7 RunnerLoop\uFF08run \u9636\u6BB5\u4E0D\u8BA4\u9886\u9879\u76EE\uFF09"),null;let o={gatewayUrl:go(this.config.serverUrl),machineKey:n,workspaceRoot:this.config.workspaceRoot,cliPath:Ie(),maxWorkflows:t,sendRunEvents:c((i,s)=>this.sendRunEvents(i,s),"sendRunEvents")};return(e.createRunnerLoop??(i=>new ae(i)))(o)}sendRunEvents(e,t){t.length!==0&&this.conn.send({type:"run:events",projectId:e,entries:t})}start(){f.info(h,"starting",{serverUrl:this.config.serverUrl,workspaceRoot:this.config.workspaceRoot}),this.config.name||f.warn(h,"\u672A\u6307\u5B9A --name\uFF0C\u5C06\u4F7F\u7528\u4E3B\u673A\u540D\u4F5C\u4E3A\u673A\u5668\u6CE8\u518C\u540D\uFF1B\u591A\u673A\u573A\u666F\u4E0B hostname \u82E5\u91CD\u590D\u4F1A\u5BFC\u81F4\u8FDE\u63A5\u4E92\u76F8\u9876\u66FF\uFF0C\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A --name",{hostname:this.hostname()}),this.conn.connect(),this.runnerLoop?.start()}stop(){return f.info(h,"stopping"),this.conn.close(),this.runnerLoop?this.runnerLoop.stop().catch(e=>{f.warn(h,"runner loop \u505C\u6B62\u5F02\u5E38",{error:e instanceof Error?e.message:String(e)})}):Promise.resolve()}buildReady(){let t={type:"ready",runtimes:Array.from(new Set(this.detectAgents().map(n=>n.type))),hasDws:this.detectDws(this.config.dwsBin),hostname:this.hostname(),os:this.osString()};return this.machineId&&(t.machineId=this.machineId),this.config.name&&(t.name=this.config.name),this.config.displayName&&(t.displayName=this.config.displayName),this.config.description&&(t.description=this.config.description),this.maxTasks>1&&(t.maxTasks=this.maxTasks),t}handleOpen(){let e=this.buildReady();f.info(h,"connected; sending ready",{runtimes:e.runtimes,hasDws:e.hasDws}),this.conn.send(e)}handlePermanentReject(e){f.error(h,"permanently rejected by gateway",{...e}),this.onPermanentReject?.(e)}handleMessage(e){switch(e.type){case"run:agent":this.enqueueTask(()=>this.handleRunAgent(e));break;case"run:dws":this.enqueueTask(()=>this.handleRunDws(e));break;case"upload:grant":this.resolveGrant(e);break;case"wf:available":this.runnerLoop?.onWakeup();break;case"ready:ack":e.machineId&&(this.machineId=e.machineId,f.info(h,"machine id assigned",{machineId:e.machineId}));break;default:break}}enqueueTask(e){let t=c(()=>{this.inflight+=1,e().finally(()=>{this.inflight-=1;let n=this.taskQueue.shift();n&&n()})},"exec");this.inflight<this.maxTasks?t():this.taskQueue.push(t)}async handleRunAgent(e){let{requestId:t}=e;f.info(h,"run:agent received",{requestId:t,projectId:e.projectId,agent:e.agent});try{let n=this.resolveWorkDir(e.projectId,e.workDir);await ro(n,{recursive:!0});let o=this.rewritePromptWorkDir(e.prompt,e.workDir,n),i={agent:e.agent,workDir:n,onEvent:c(l=>this.conn.send({type:"event",requestId:t,event:l}),"onEvent")};e.sessionId&&(i.sessionId=e.sessionId),e.permissionMode&&(i.adapterOptions={permissionMode:e.permissionMode}),e.timeoutMs!==void 0?i.timeoutMs=e.timeoutMs:this.config.agentTimeoutMs!=null&&(i.timeoutMs=this.config.agentTimeoutMs);let s=await this.runAgent(o,i),a;try{a=await this.collectAndUploadArtifacts(t,e.projectId,n)}catch(l){let m=l instanceof Error?l.message:String(l);f.error(h,"artifact upload failed",{requestId:t,error:m}),this.conn.send({type:"error",requestId:t,code:"artifact_upload_failed",message:m});return}this.conn.send({type:"result",requestId:t,ok:!0,response:s.response,sessionId:s.sessionId,...a?{artifacts:a}:{}}),f.info(h,"run:agent done",{requestId:t,sessionId:s.sessionId,artifacts:a?a.files.length:0})}catch(n){let o=n instanceof Error?n.message:String(n);f.error(h,"run:agent failed",{requestId:t,error:o}),this.conn.send({type:"error",requestId:t,code:"agent_failed",message:o})}}async collectAndUploadArtifacts(e,t,n){let o=await ot(n);if(o.length===0)return;this.conn.send({type:"upload:request",requestId:e,projectId:t,files:o.map(a=>({path:a.relPath,size:a.size,sha256:a.sha256}))});let i=await this.awaitGrant(e);if(!i)throw new Error("upload:grant \u7B49\u5F85\u8D85\u65F6");if(i.grants.length===0){f.warn(h,"upload:grant \u65E0\u6388\u6743\u9879\uFF08gateway \u672A\u914D\u7F6E store \u6216\u5168\u88AB\u62D2\uFF09",{requestId:e,rejected:(i.rejected??[]).length});return}let s=[];for(let a of i.grants){let l=o.find(p=>p.relPath===a.path);if(!l)continue;let m=await io(l.absPath);await this.artifactUploader.upload(a.url,m,a.headers),s.push({path:a.path,key:a.key,sha256:l.sha256,size:l.size})}return{store:"oss",files:s}}awaitGrant(e){return new Promise(t=>{let n=setTimeout(()=>{this.pendingGrants.delete(e),t(void 0)},this.grantTimeoutMs);n.unref?.(),this.pendingGrants.set(e,o=>{clearTimeout(n),t(o)})})}resolveGrant(e){let t=this.pendingGrants.get(e.requestId);t&&(this.pendingGrants.delete(e.requestId),t(e))}async handleRunDws(e){let{requestId:t}=e,n=fo(e.args,this.allowedDwsCommands);if(!n.ok){f.warn(h,"run:dws rejected",{requestId:t,reason:n.reason}),this.conn.send({type:"error",requestId:t,code:"dws_rejected",message:n.reason});return}f.info(h,"run:dws received",{requestId:t,command:e.args[0]});try{let i=await this.createDwsClient(this.config.dwsBin,e.timeoutMs).runJson(e.args,e.timeoutMs!=null?{timeoutMs:e.timeoutMs}:void 0);this.conn.send({type:"result",requestId:t,ok:!0,response:JSON.stringify(i)}),f.info(h,"run:dws done",{requestId:t})}catch(o){let i=o instanceof Error?o.message:String(o);f.error(h,"run:dws failed",{requestId:t,error:i}),this.conn.send({type:"error",requestId:t,code:"dws_failed",message:i})}}resolveWorkDir(e,t){if(t&&t.trim()!=="")if(D.isAbsolute(t))f.warn(h,"\u5FFD\u7565\u670D\u52A1\u7AEF\u4E0B\u53D1\u7684\u7EDD\u5BF9\u8DEF\u5F84 workDir\uFF0C\u56DE\u9000\u5230 workspaceRoot/projectId",{workDir:t,projectId:e});else return ut(this.config.workspaceRoot,t,{allowRoot:!1});return ut(this.config.workspaceRoot,ft(e,{label:"projectId"}),{allowRoot:!1})}rewritePromptWorkDir(e,t,n){let o=t?.trim();return!o||!D.isAbsolute(o)||o===n?e:e.split(o).join(n)}};function xe(r,e){let t,n=r?.trim();if(n)t=D.isAbsolute(n)?D.resolve(n):D.resolve(O.homedir(),n);else{let o=e?.trim()?e.trim():"default";t=D.join(O.homedir(),".aitable-workflow","workspaces",ft(o,{label:"agentId"}))}return so(t,{recursive:!0}),t}c(xe,"resolveWorkspaceRoot");function wo(r,e=process.env){let t=r.serverUrl??e.AITABLE_RELAY_SERVER_URL,n=r.key??e.AITABLE_RELAY_BOOTSTRAP_KEY,o=r.token??e.AITABLE_RELAY_TOKEN,i=r.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT,s=r.machineId??e.AITABLE_RELAY_MACHINE_ID,a=r.name??e.AITABLE_RELAY_NAME,l=r.desc??e.AITABLE_RELAY_DESC,m=r.maxTasks??e.AITABLE_RELAY_MAX_TASKS,p=r.maxWorkflows??e.AITABLE_RELAY_MAX_WORKFLOWS,u=[];if(t||u.push("--server-url (\u6216 AITABLE_RELAY_SERVER_URL)"),!n&&!o&&u.push("--key/--token (\u6216 AITABLE_RELAY_BOOTSTRAP_KEY/AITABLE_RELAY_TOKEN)"),u.length>0)throw new Error(`relay \u7F3A\u5C11\u5FC5\u8981\u53C2\u6570: ${u.join(", ")}
21
+ \u{1F4A1} \u63D0\u793A: \u4F7F\u7528 \`aitable-workflow connect\` \u6CE8\u518C\u540E\u53EF\u7701\u7565\u8FD9\u4E9B\u53C2\u6570`);let g=a??O.hostname()??"default",d={serverUrl:t,workspaceRoot:xe(i,g)};if(o?d.token=o:n&&(d.key=n),s&&(d.machineId=s),a&&(d.name=a,d.displayName=a),l&&(d.description=l),m!=null&&m!==""){let y=Math.floor(Number(m));Number.isFinite(y)&&y>=1&&(d.maxTasks=y)}if(p!=null&&p!==""){let y=Math.floor(Number(p));Number.isFinite(y)&&y>=0&&(d.maxWorkflows=y)}return d}c(wo,"resolveRelayCliConfig");async function U(r,e=process.env){let t=null;try{t=await mo()}catch{t=null}let n={serverUrl:r.serverUrl??e.AITABLE_RELAY_SERVER_URL??t?.serverUrl,key:r.key??e.AITABLE_RELAY_BOOTSTRAP_KEY??t?.key,token:r.token??e.AITABLE_RELAY_TOKEN??t?.token,name:r.name??e.AITABLE_RELAY_NAME??t?.name,desc:r.desc??e.AITABLE_RELAY_DESC,workspaceRoot:r.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT??t?.workspaceRoot,machineId:r.machineId??e.AITABLE_RELAY_MACHINE_ID??t?.machineId,maxTasks:r.maxTasks??e.AITABLE_RELAY_MAX_TASKS,maxWorkflows:r.maxWorkflows??e.AITABLE_RELAY_MAX_WORKFLOWS};return wo(n,e)}c(U,"resolveDaemonConfig");async function me(r){let e=await U(r),t=new Ae(e,{onPermanentReject:c(()=>{process.exit(1)},"onPermanentReject")}),n=!1,o=c(()=>{n&&(f.warn(h,"\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),n=!0,t.stop().catch(()=>{}).finally(()=>process.exit(0))},"shutdown");return process.on("SIGINT",o),process.on("SIGTERM",o),t.start(),t}c(me,"runRelayDaemon");import{readFile as yo,writeFile as ys,mkdir as ks}from"fs/promises";import ko from"path";var wt={connectionState:"disconnected",lastHeartbeatAt:null,machineId:null,serverUrl:"",runningTasks:0,queuedTasks:0,lastDisconnectReason:null,updatedAt:new Date().toISOString()};function vo(r){return ko.join(z(r),"state.json")}c(vo,"stateFilePath");async function de(r){try{let e=await yo(vo(r),"utf8");return{...wt,...JSON.parse(e)}}catch{return{...wt}}}c(de,"readState");import{execSync as Y}from"child_process";import{writeFile as Ro,rm as bo,mkdir as Co,access as Io}from"fs/promises";import A from"path";import yt from"os";import{assertPortableId as Ao,readCredentials as xo}from"aitable-workflow-core";var So="com.alibaba.aitable-workflow.daemon",Se="\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\uFF1Anpm i -g @ali/aitable-workflow";function V(r){return`${So}.${Ao(r,{label:"agentId"})}`}c(V,"plistLabel");function Ee(r){return A.join(yt.homedir(),"Library","LaunchAgents",`${V(r)}.plist`)}c(Ee,"plistPath");function $(){return process.platform==="darwin"}c($,"isMacOS");function kt(){try{return Y("which aitable-workflow",{encoding:"utf8"}).trim()||null}catch{return null}}c(kt,"resolveGlobalCliEntry");function vt(r){if(!r||!r.trim())throw new Error(`\u672A\u627E\u5230\u5168\u5C40\u5B89\u88C5\u7684 aitable-workflow CLI \u5165\u53E3\uFF0C\u65E0\u6CD5\u914D\u7F6E\u5F00\u673A\u81EA\u542F\u3002
22
+ \u{1F4A1} ${Se}`);if(r.includes("/_npx/")||r.includes(`${A.sep}_npx${A.sep}`))throw new Error(`\u68C0\u6D4B\u5230 CLI \u5165\u53E3\u4F4D\u4E8E npx \u4E34\u65F6\u7F13\u5B58\uFF0C\u5F00\u673A\u81EA\u542F\u4F1A\u5931\u6548\uFF1A${r}
23
+ \u{1F4A1} ${Se}`);if(!A.isAbsolute(r))throw new Error(`CLI \u5165\u53E3\u4E0D\u662F\u7A33\u5B9A\u7684\u5168\u5C40\u7EDD\u5BF9\u8DEF\u5F84\uFF1A${r}
24
+ \u{1F4A1} ${Se}`)}c(vt,"assertStableCliEntry");async function Eo(r){let e={};e.AITABLE_RELAY_NAME=r;let t;try{let n=await xo();t=n.agents.find(o=>o.name===r)??n.agents.find(o=>o.name===n.activeAgent)??void 0}catch{t=void 0}return t&&(t.serverUrl&&(e.AITABLE_RELAY_SERVER_URL=t.serverUrl),t.token&&(e.AITABLE_RELAY_TOKEN=t.token),t.workspaceRoot&&(e.AITABLE_RELAY_WORKSPACE_ROOT=t.workspaceRoot)),e}c(Eo,"buildRelayEnv");function To(r,e){let t=V(r),n=e?.cliEntry??kt();vt(n);let o=["relay"];e?.maxTasks&&o.push("--max-tasks",String(e.maxTasks));let i=A.join(yt.homedir(),".aitable-workflow","daemons",r),s=A.join(i,"launchd.log"),a=A.join(i,"launchd.err.log"),l=[n,...o].map(u=>` <string>${F(u)}</string>`).join(`
25
+ `),m={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",...e?.relayEnv??{}},p=Object.entries(m).map(([u,g])=>` <key>${F(u)}</key>
26
+ <string>${F(g)}</string>`).join(`
9
27
  `);return`<?xml version="1.0" encoding="UTF-8"?>
10
28
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
11
29
  <plist version="1.0">
12
30
  <dict>
13
31
  <key>Label</key>
14
- <string>${$(n)}</string>
32
+ <string>${F(t)}</string>
15
33
  <key>ProgramArguments</key>
16
34
  <array>
17
35
  ${l}
18
36
  </array>
19
37
  <key>EnvironmentVariables</key>
20
38
  <dict>
21
- ${h}
39
+ ${p}
22
40
  </dict>
23
41
  <key>KeepAlive</key>
24
42
  <true/>
25
43
  <key>RunAtLoad</key>
26
44
  <true/>
27
45
  <key>StandardOutPath</key>
28
- <string>${$(s)}</string>
46
+ <string>${F(s)}</string>
29
47
  <key>StandardErrorPath</key>
30
- <string>${$(a)}</string>
48
+ <string>${F(a)}</string>
31
49
  </dict>
32
50
  </plist>
33
- `}c(kt,"generatePlist");function $(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}c($,"escapeXml");function Y(){let t=process.getuid?.();if(t===void 0)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237 UID\uFF08\u4EC5\u652F\u6301 macOS/Linux\uFF09");return t}c(Y,"getUid");async function Ae(t,e){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let n=ye();ke(n);let o=await yt(t),r=oe(t),i=P(t);try{D(`launchctl bootout gui/${Y()}/${i} 2>/dev/null`,{encoding:"utf8"})}catch{}await pt(v.dirname(r),{recursive:!0});let s=kt(t,{maxTasks:e?.maxTasks,relayEnv:o,cliEntry:n});await mt(r,s,"utf8"),D(`launchctl bootstrap gui/${Y()} ${r}`,{encoding:"utf8"})}c(Ae,"enableAutostart");async function Re(t){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=oe(t);try{D(`launchctl bootout gui/${Y()}/${e} 2>/dev/null`,{encoding:"utf8"})}catch{}await ft(n,{force:!0})}c(Re,"disableAutostart");async function re(t){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=oe(t),o=!1;try{await ut(n),o=!0}catch{o=!1}let r=!1,i=!1,s=null;try{let a=D(`launchctl print gui/${Y()}/${e} 2>/dev/null`,{encoding:"utf8"});r=!0;let l=a.match(/pid\s*=\s*(\d+)/);l&&(s=parseInt(l[1],10),i=!0)}catch{r=!1}return{installed:o,loaded:r,running:i,pid:s}}c(re,"getAutostartStatus");import{createRequire as At}from"module";var ve="aitable-workflow-",Rt=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function be(){try{return At(import.meta.url)("../package.json")}catch{return{}}}c(be,"loadCliPackageManifest");function se(t){return t.version??"0.0.0"}c(se,"resolveCliVersion");function Se(t){let e=se(t),n={};t.name?.startsWith(ve)&&(n[t.name]=e);for(let[o,r]of Object.entries(t.dependencies??{}))o.startsWith(ve)&&(n[o]=Rt.test(r)?r:e);return n}c(Se,"resolveMonorepoPackageVersions");function ie(t){return t.skipConfig||t.skipConfigIfValid&&t.configValid===!0}c(ie,"canSkipSetupConfig");function Ee(t){return ie(t)?"setup":t.uiEnabled&&t.webAvailable?"web":"cli"}c(Ee,"resolveSetupConfigRoute");import y from"path";import{fileURLToPath as Yt}from"url";import{watchFile as Gt,statSync as Kt,openSync as Ht,readSync as qt,closeSync as Jt,existsSync as $e}from"fs";import{readFile as Te}from"fs/promises";import{spawn as zt}from"child_process";var O=y.dirname(Yt(import.meta.url));xe({override:!1,quiet:!0});xe({path:y.resolve(O,"..",".env"),override:!1,quiet:!0});var Le=be(),M=se(Le),De=Se(Le),k="./aitable-workflow.config.yml";function Xt(){let n=[],o=c(()=>{let r=Date.now();for(n.push(r);n.length>0&&r-n[0]>6e4;)n.shift();n.length>=10&&(g.error("cli",`60000ms \u5185\u53D1\u751F ${n.length} \u6B21\u672A\u6355\u83B7\u5F02\u5E38\uFF0C\u7591\u4F3C\u975E\u5076\u53D1\u9519\u8BEF\uFF0C\u4E3B\u52A8\u9000\u51FA`),process.exit(1))},"recordCrashAndMaybeExit");process.on("uncaughtException",r=>{g.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406\u5F02\u5E38\uFF08\u5DF2\u5B58\u6D3B\uFF0C\u4EA4\u7531\u91CD\u8FDE/\u91CD\u8BD5\u903B\u8F91\u81EA\u6108\uFF09",{error:r instanceof Error?r.message:String(r),stack:r instanceof Error?r.stack:void 0}),o()}),process.on("unhandledRejection",r=>{g.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406 Promise \u62D2\u7EDD\uFF08\u5DF2\u5B58\u6D3B\uFF09",{error:r instanceof Error?r.message:String(r),stack:r instanceof Error?r.stack:void 0}),o()})}c(Xt,"installLongRunningCrashGuards");function Qt(t){let e=process.platform,n=e==="darwin"?"open":e==="win32"?"cmd":"xdg-open",o=e==="win32"?["/c","start","",t]:[t];try{let r=zt(n,o,{stdio:"ignore",detached:!0});r.on("error",()=>{console.log(`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t}`)}),r.unref()}catch{console.log(`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t}`)}}c(Qt,"openBrowser");var d=new G().name("aitable-workflow").description("\u901A\u7528\u4E1A\u52A1\u6D41\u7A0B\u5F15\u64CE \u2014 \u914D\u7F6E\u9A71\u52A8\u7684 AI \u8868\u683C\u5DE5\u4F5C\u6D41\u81EA\u52A8\u5316").version(M).option("-d, --debug","\u8F93\u51FA debug \u7EA7\u522B\u65E5\u5FD7\uFF08\u542B recipe \u5185\u90E8 log\uFF09").hook("preAction",async(t,e)=>{e.name()!=="init"&&await bt()}).hook("preAction",(t,e)=>{t.opts().debug?g.setLevel("debug"):e.name()==="config"&&g.setLevel("warn")});d.command("init").description("\u4EA4\u4E92\u5F0F\u521D\u59CB\u5316 \u2014 \u9009\u62E9 Coding Agent\u3001\u914D\u7F6E\u5DE5\u4F5C\u76EE\u5F55\u3001\u63CF\u8FF0\u4E1A\u52A1\u573A\u666F\uFF1B\u6216\u7528 --template \u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6").option("-c, --config <path>","\u76EE\u6807\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").option("-f, --force","\u8986\u76D6\u5DF2\u6709\u914D\u7F6E\u6587\u4EF6").option("-y, --yes","\u4F7F\u7528\u9ED8\u8BA4\u503C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u5411\u5BFC").option("-t, --template <name>","\u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6(\u5F53\u524D\u63A8\u8350 support-qa),\u62F7\u8D1D\u5B8C\u6574\u53EF\u8FD0\u884C\u9879\u76EE\u5230\u76EE\u6807\u76EE\u5F55").option("--profile <name>","\u9009\u5B9A\u6A21\u677F\u4E0B\u7684 profile \u4E1A\u52A1\u5305(\u5982 support-qa \u7684 aitable),\u8986\u76D6\u5F0F\u53E0\u52A0\u5230\u5B9E\u4F8B").action(async t=>{try{await It({config:t.config,force:!!t.force,yes:!!t.yes,template:t.template,profile:t.profile,templatesDir:y.resolve(O,"..","templates"),templatePackageVersions:De,cliVersion:M})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","\u521D\u59CB\u5316\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("migrate").description("\u5347\u7EA7\u9879\u76EE\u76EE\u5F55\u5230\u6700\u65B0\u6A21\u677F\u7248\u672C\uFF0C\u81EA\u52A8\u4FDD\u7559\u7528\u6237\u914D\u7F6E").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u8DEF\u5F84",k).option("--dry-run","\u4EC5\u9884\u89C8\u53D8\u66F4\uFF0C\u4E0D\u5B9E\u9645\u5199\u5165").option("--no-backup","\u8DF3\u8FC7\u81EA\u52A8\u5907\u4EFD").option("--force","\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A").option("--template <name>","\u6307\u5B9A\u76EE\u6807\u6A21\u677F").option("--profile <name>","\u6307\u5B9A\u76EE\u6807 profile").option("--rollback","\u56DE\u6EDA\u5230\u4E0A\u4E00\u6B21\u8FC1\u79FB\u524D\u7684\u72B6\u6001").option("--list","\u5217\u51FA\u6240\u6709\u5907\u4EFD").action(async t=>{try{await Bt({config:t.config,dryRun:t.dryRun,noBackup:t.backup===!1,force:t.force,template:t.template,profile:t.profile,rollback:t.rollback,list:t.list,templatesDir:y.resolve(O,"..","templates"),templatePackageVersions:De,cliVersion:M})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","migrate \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("design").description("\u8BA9 Coding Agent \u6839\u636E\u573A\u666F\u63CF\u8FF0\u751F\u6210\u5B8C\u6574\u7684 workflow \u548C recipes").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-y, --yes","\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u8865\u5145\uFF0C\u76F4\u63A5\u4F7F\u7528 config \u4E2D\u7684 scene").option("--skip-questions","\u8DF3\u8FC7\u6F84\u6E05\u95EE\u5377\uFF08\u4ECD\u4F1A\u4EA4\u4E92\u8865\u5145\u9700\u6C42\uFF09").action(async t=>{try{await $t(t)}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","design \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("setup").description("\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E\uFF0C\u518D\u521D\u59CB\u5316 AI \u8868\u683C\u7ED3\u6784 + \u7F16\u8BD1\u77E5\u8BC6\u5E93 \u2014 \u4E00\u6B21\u5B8C\u6210 config + \u5EFA\u8868").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--no-clean","\u4E0D\u6E05\u7406\u7A7A\u767D\u884C").option("--no-kb","\u8DF3\u8FC7\u77E5\u8BC6\u5E93\u7F16\u8BD1").option("--kb-full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1\u77E5\u8BC6\u5E93").option("--skip-config","\u8DF3\u8FC7\u524D\u7F6E\u7684\u4EA4\u4E92\u5F0F\u914D\u7F6E\u6821\u9A8C\uFF08CI/\u5DF2\u786E\u8BA4\u914D\u7F6E\u65F6\u4F7F\u7528\uFF09").option("--skip-config-if-valid","\u5148\u6821\u9A8C\u914D\u7F6E\uFF1B\u65E0\u963B\u65AD\u9879\u65F6\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u76F4\u63A5\u5F00\u59CB\u642D\u5EFA").option("--no-ui","\u5F3A\u5236\u4F7F\u7528\u547D\u4EE4\u884C\u4EA4\u4E92\uFF08\u8DF3\u8FC7\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762\uFF09").action(async t=>{try{if(await _e(y.dirname(y.resolve(t.config)),M),!t.skipConfig){let e=t.ui!==!1,n=!1;if(t.skipConfigIfValid){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u9879\u76EE\u914D\u7F6E");let o=await Ie({configPath:t.config});if(n=ie({skipConfig:!1,skipConfigIfValid:!0,configValid:o.ok}),n){let r=[];o.summary.warnings>0&&r.push(`${o.summary.warnings} \u9879\u8B66\u544A`),o.summary.suggestions>0&&r.push(`${o.summary.suggestions} \u9879\u5EFA\u8BAE`);let i=r.length>0?`\uFF08${r.join("\uFF0C")}\uFF0C\u5747\u4E0D\u963B\u65AD\uFF09`:"";console.log(`\u2713 \u914D\u7F6E\u65E0\u963B\u65AD\u9879${i}\uFF0C\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u7EE7\u7EED\u642D\u5EFA\u3002`)}else console.log(`\u2139 \u68C0\u6D4B\u5230 ${o.summary.errors} \u9879\u963B\u65AD\uFF0C\u8FDB\u5165\u914D\u7F6E\u73AF\u8282\u3002`)}if(!n&&e){let{hasWebRoot:o,runConfigUI:r}=await import("./config-ui-server-7H5HRTRE.js");if(Ee({skipConfig:!1,skipConfigIfValid:t.skipConfigIfValid===!0,uiEnabled:e,webAvailable:o(),configValid:n})==="web"){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");try{await r({configPath:t.config}),n=(await Ie({configPath:t.config})).ok}catch(s){console.warn(`
34
- \u26A0 \u53EF\u89C6\u5316\u754C\u9762\u5F02\u5E38\uFF0C\u56DE\u9000\u5230\u547D\u4EE4\u884C\u4EA4\u4E92: ${s instanceof Error?s.message:String(s)}
35
- `)}}}if(!n){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E");let{runConfigCommand:o}=await import("./config-command-O7YLFPAN.js");(await o({configPath:t.config,interactive:!0,offerSkipToBuild:!0})).ok||(console.error(`
36
- \u2717 \u9879\u76EE\u914D\u7F6E\u4ECD\u4E0D\u5B8C\u6574\uFF0C\u5DF2\u4E2D\u6B62 setup\u3002\u8BF7\u8865\u9F50\u5FC5\u586B\u9879\u540E\u91CD\u8BD5\uFF08\u6216\u7528 --skip-config \u8DF3\u8FC7\uFF09\u3002`),process.exit(1))}console.log(`
37
- \u{1F527} \u6B65\u9AA4 2/2\uFF1A\u521D\u59CB\u5316\u8868\u7ED3\u6784 + \u7F16\u8BD1\u77E5\u8BC6\u5E93
38
- `)}await Tt(t)}catch(e){g.error("cli","setup \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("run").description("\u542F\u52A8\u7F16\u6392\u5F15\u64CE\uFF0C\u5F00\u59CB\u8F6E\u8BE2\u5904\u7406\u5DE5\u5355").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async t=>{try{await _e(y.dirname(y.resolve(t.config)),M),Xt(),await Et();let e=await vt(t.config),n=!1,o=c(async()=>{n&&(g.warn("cli","\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),n=!0,g.info("cli","\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u7B49\u5F85\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u5B8C\u6210...");try{await e.stop()}finally{process.exit(0)}},"shutdown");process.on("SIGINT",o),process.on("SIGTERM",o),await e.start()}catch(e){g.error("cli","\u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("validate").description("\u9A8C\u8BC1\u914D\u7F6E\u6587\u4EF6\u548C\u5DE5\u4F5C\u6D41\u6A21\u677F").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async t=>{try{let e=await K(t.config);console.log("\u2713 \u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u901A\u8FC7");let n=await Ce(e.workflowTemplatePath,{envSource:e.envSource});console.log(`\u2713 \u5DE5\u4F5C\u6D41\u6A21\u677F\u9A8C\u8BC1\u901A\u8FC7: ${n.meta.name} (${n.orderedStepIds.length} \u6B65)`),console.log(`
39
- \u6B65\u9AA4\u94FE:`);for(let[o,r]of n.orderedStepIds.entries()){let i=n.steps.find(a=>a.id===r),s=o<n.orderedStepIds.length-1?" \u2192":" \u2713";console.log(` ${o+1}. [${r}] ${i?.name??"?"}${s}`)}console.log(`
40
- \u914D\u7F6E\u6458\u8981:`),console.log(` AI \u8868\u683C: base=${e.tracker.base_id} table=${e.tracker.table_id}`),console.log(` \u5F15\u64CE: ${e.agent.engine}`),console.log(` \u8F6E\u8BE2\u95F4\u9694: ${e.polling.interval_ms}ms`)}catch(e){console.error(`\u2717 \u9A8C\u8BC1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});d.command("exec").description("\u9003\u751F\u8231\uFF1A\u5728\u5B9E\u4F8B\u4E0A\u4E0B\u6587\u4E0B\u8BD5\u8DD1\u4E00\u6761\u547D\u4EE4\uFF08\u590D\u7528 shell toolkit \u7684 bins \u89E3\u6790/\u8D85\u65F6/\u8131\u654F\uFF09\uFF0C\u7528\u4E8E dws/git \u547D\u4EE4\u9762 smoke\u3002\u7528\u6CD5\uFF1Aaitable-agent exec [-c <path>] [--json] -- <bin> <args...>").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--timeout <ms>","\u5355\u6B21\u6267\u884C\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").option("--json","\u4EE5 runJson \u65B9\u5F0F\u6267\u884C\uFF1A\u8981\u6C42 exit=0 \u4E14 stdout \u4E3A\u5408\u6CD5 JSON\uFF0C\u6253\u5370\u89E3\u6790\u540E\u7684\u5BF9\u8C61").allowUnknownOption().argument("<command...>","\u8981\u6267\u884C\u7684\u547D\u4EE4\u53CA\u53C2\u6570\uFF08\u5EFA\u8BAE\u7528 -- \u5206\u9694\uFF09\uFF0C\u5982\uFF1Adws chat group create --name x --format json").action(async(t,e)=>{try{let[n,...o]=t;n||(console.error("\u2717 \u672A\u63D0\u4F9B\u8981\u6267\u884C\u7684\u547D\u4EE4\uFF1B\u7528\u6CD5\uFF1Aaitable-agent exec [-c <path>] -- <bin> <args...>"),process.exit(1));let r=await K(e.config),i=St(r,n),s=e.timeout?Number.parseInt(e.timeout,10):void 0;if(s!==void 0&&(Number.isNaN(s)||s<=0)&&(console.error("\u2717 --timeout \u5FC5\u987B\u662F\u6B63\u6574\u6570\uFF08\u6BEB\u79D2\uFF09"),process.exit(1)),e.json){let l=await i.runJson(n,o,{timeoutMs:s});console.log(JSON.stringify(l??{},null,2));return}let a=await i.run(n,o,{timeoutMs:s});a.stdout&&process.stdout.write(a.stdout),a.stderr&&process.stderr.write(a.stderr),a.truncated&&console.error(`
41
- \u26A0\uFE0F \u8F93\u51FA\u56E0\u8D85\u8FC7\u4E0A\u9650\u88AB\u622A\u65AD`),process.exit(a.exitCode??0)}catch(n){console.error(`\u2717 exec \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});d.command("config").description("\u6821\u9A8C\u9879\u76EE\u914D\u7F6E\u5B8C\u6574\u6027\uFF0C\u5E76\u53EF\u4EA4\u4E92\u5F0F\u4FEE\u6539\u53C2\u6570").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u6821\u9A8C\u7684\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u6821\u9A8C\u5168\u90E8\uFF09").option("--json","JSON \u683C\u5F0F\u8F93\u51FA\u6821\u9A8C\u7ED3\u679C").option("--no-interactive","\u4EC5\u6821\u9A8C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u4FEE\u6539").action(async t=>{try{let{runConfigCommand:e}=await import("./config-command-O7YLFPAN.js");await e({configPath:t.config,workflowId:t.workflow,json:t.json,interactive:t.interactive})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","config \u547D\u4EE4\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("sync").description("\u68C0\u6D4B\u914D\u7F6E\u4E0E\u8868\u7684\u504F\u5DEE\uFF08\u5B57\u6BB5\u7C7B\u578B/\u9009\u9879 drift\uFF09\uFF0C\u8F93\u51FA\u8BCA\u65AD\u62A5\u544A\u548C\u4FEE\u590D\u5EFA\u8BAE").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-y, --yes","\u975E\u4EA4\u4E92\u6A21\u5F0F").action(async t=>{try{await Dt({configPath:t.config,yes:t.yes})}catch(e){g.error("cli","sync \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("agents").description("\u5217\u51FA\u5168\u90E8\u652F\u6301\u7684 Coding Agent \u9002\u914D\u5668\uFF0C\u5E76\u6807\u6CE8\u672C\u673A\u5DF2\u63A2\u6D4B\u5230\u5B89\u88C5\u7684").option("--json","\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action(t=>{try{let e=Ot();if(t.json){process.stdout.write(JSON.stringify(e,null,2)+`
42
- `);return}let n=e.filter(o=>o.installed).length;console.log(`
43
- \u652F\u6301 ${e.length} \u4E2A Coding Agent\uFF0C\u672C\u673A\u5DF2\u63A2\u6D4B\u5230 ${n} \u4E2A\uFF1A
44
- `);for(let o of e){let r=o.installed?"\u2713":"\u2717",i=[o.bin,...o.fallbackBins].join(" / "),s=o.installed?`\u5DF2\u5B89\u88C5 (${o.detectedCmd}${o.detectedVersion?` ${o.detectedVersion}`:""})`:"\u672A\u63A2\u6D4B\u5230";console.log(` ${r} ${o.name.padEnd(16)} [${o.id}] bin: ${i.padEnd(24)} ${s}`)}console.log("")}catch(e){g.error("cli","\u5217\u51FA agents \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("serve").description("\u542F\u52A8\u672C\u5730 HTTP API \u670D\u52A1\u5E76\u6258\u7BA1 Web \u524D\u7AEF\u9875\u9762\uFF08local \u6A21\u5F0F\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF09").option("-p, --port <number>","\u76D1\u542C\u7AEF\u53E3\uFF08\u9ED8\u8BA4 8787\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_PORT \u8986\u76D6\uFF09").option("--host <host>","\u76D1\u542C\u5730\u5740\uFF08\u9ED8\u8BA4 127.0.0.1\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_HOST \u8986\u76D6\uFF09").option("--data-root <path>","\u9879\u76EE\u5DE5\u4F5C\u533A\u6570\u636E\u76EE\u5F55\uFF08\u9ED8\u8BA4 .sandbox/aitable-workflow-server\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_DATA_DIR \u8986\u76D6\uFF09").option("--web-root <path>","Web \u524D\u7AEF\u9759\u6001\u8D44\u6E90\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u968F CLI \u6253\u5305\u7684 dist/web\uFF09").option("--no-open","\u542F\u52A8\u540E\u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF08\u9ED8\u8BA4\u81EA\u52A8\u6253\u5F00\uFF09").action(async t=>{try{let e={};if(t.port!==void 0){let o=Number.parseInt(t.port,10);Number.isFinite(o)&&o>0&&(e.port=o)}if(t.host!==void 0&&(e.host=t.host),t.dataRoot!==void 0&&(e.dataRoot=t.dataRoot),t.webRoot!==void 0)e.webRoot=t.webRoot;else{let o=y.join(O,"web");if($e(y.join(o,"index.html")))e.webRoot=o;else{let r=y.resolve(O,"..","..","web","dist");$e(y.join(r,"index.html"))&&(e.webRoot=r)}}let n=Vt(e);if(await Wt(n),n.webRoot&&t.open!==!1){let o=n.host==="0.0.0.0"?"127.0.0.1":n.host;Qt(`http://${o}:${n.port}`)}}catch(e){g.error("cli","HTTP \u670D\u52A1\u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("start").description("\u4EE5\u540E\u53F0\u8FDB\u7A0B\u542F\u52A8 relay daemon").option("--agent <name>","Agent \u540D\u79F0\uFF08\u9ED8\u8BA4\u4F7F\u7528 activeAgent\uFF09").option("--server-url <url>","Gateway \u5730\u5740").option("--token <ownerToken>","owner-token").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `--agent <name>` \u6307\u5B9A\u3002");e=r.name}let n=await C({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:e,maxTasks:t.maxTasks}),o=await B({agentId:e,serverUrl:n.serverUrl,token:n.token,key:n.key,name:n.name??e,workspaceRoot:n.workspaceRoot,machineId:n.machineId,maxTasks:n.maxTasks});console.log("\u2705 Daemon \u5DF2\u542F\u52A8"),console.log(` Agent: ${e}`),console.log(` PID: ${o.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${e}/daemon.log`)}catch(e){g.error("cli","start \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("stop").description("\u505C\u6B62\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--all","\u505C\u6B62\u6240\u6709 daemon").action(async t=>{try{if(t.all){let e=await ae(),n=0;for(let o of e)await W(o.name)&&n++;console.log(`\u2705 \u5DF2\u505C\u6B62 ${n} \u4E2A daemon`)}else{let e=t.agent;if(!e){let o=await A();if(!o)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=o.name}let n=await W(e);console.log(n?`\u2705 Daemon "${e}" \u5DF2\u505C\u6B62`:`\u26A0\uFE0F Daemon "${e}" \u672A\u5728\u8FD0\u884C`)}}catch(e){g.error("cli","stop \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("restart").description("\u91CD\u542F\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=r.name}console.log(`\u{1F504} \u6B63\u5728\u91CD\u542F "${e}"...`),await W(e);let n=await C({name:e,maxTasks:t.maxTasks}),o=await B({agentId:e,serverUrl:n.serverUrl,token:n.token,key:n.key,name:n.name??e,workspaceRoot:n.workspaceRoot,machineId:n.machineId,maxTasks:n.maxTasks});console.log(`\u2705 Daemon \u5DF2\u91CD\u542F (PID: ${o.pid})`)}catch(e){g.error("cli","restart \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("status").description("\u67E5\u770B daemon \u72B6\u6001").option("--agent <name>","Agent \u540D\u79F0").option("-v, --verbose","\u5C55\u793A\u5B8C\u6574\u914D\u7F6E").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r){console.log("\u65E0\u6D3B\u8DC3 Agent");return}e=r.name}let n=await V(e),o=await A();if(console.log(`
45
- Agent: ${n.agentId}`),console.log(`Running: ${n.running?"\u2705 yes":"\u274C no"}`),n.pid&&console.log(`PID: ${n.pid}`),n.uptimeMs!==null){let r=Math.floor(n.uptimeMs/1e3),i=Math.floor(r/60),s=Math.floor(i/60);console.log(`Uptime: ${s}h ${i%60}m ${r%60}s`)}console.log(`Log file: ${n.logFile}`),t.verbose&&o&&(console.log(`
46
- --- Configuration ---`),console.log(`Server: ${o.serverUrl}`),console.log(`Token: ${H(o.token)}`),o.machineId&&console.log(`MachineID: ${o.machineId}`),o.workspaceRoot&&console.log(`Workspace: ${o.workspaceRoot}`)),console.log("")}catch(e){g.error("cli","status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("logs").description("\u67E5\u770B daemon \u65E5\u5FD7").option("--agent <name>","Agent \u540D\u79F0").option("-f, --follow","\u6301\u7EED\u8DDF\u8E2A\u65E5\u5FD7\u8F93\u51FA").option("-n <lines>","\u663E\u793A\u6700\u8FD1 N \u884C","50").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=r.name}let n=_(e),o=parseInt(t.n,10)||50;if(t.follow){let r=await Te(n,"utf8").catch(()=>"");if(r){let s=r.trimEnd().split(`
47
- `);console.log(s.slice(-o).join(`
48
- `))}let i=r.length;Gt(n,{interval:500},()=>{try{let s=Kt(n);if(s.size>i){let a=Ht(n,"r"),l=Buffer.alloc(s.size-i);qt(a,l,0,l.length,i),Jt(a),process.stdout.write(l.toString("utf8")),i=s.size}}catch{}})}else{let r=await Te(n,"utf8").catch(()=>"");if(!r){console.log(`\u6682\u65E0\u65E5\u5FD7 (${n})`);return}let i=r.trimEnd().split(`
49
- `);console.log(i.slice(-o).join(`
50
- `))}}catch(e){g.error("cli","logs \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});var Zt=d.command("daemon").description("Daemon \u540E\u53F0\u5B88\u62A4\u7BA1\u7406");Zt.command("autostart").description("macOS \u5F00\u673A\u81EA\u542F\u7BA1\u7406").addCommand(new G("enable").description("\u542F\u7528 macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650").action(async t=>{try{E()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await Ae(t.agentId,{maxTasks:t.maxTasks?parseInt(t.maxTasks,10):void 0}),console.log("\u2705 \u81EA\u542F\u52A8\u5DF2\u542F\u7528"),console.log(` Agent: ${t.agentId}`),console.log(` Plist: ~/Library/LaunchAgents/com.alibaba.aitable-workflow.daemon.${t.agentId}.plist`)}catch(e){g.error("cli","autostart enable \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}})).addCommand(new G("disable").description("\u5173\u95ED macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").action(async t=>{try{E()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await Re(t.agentId),console.log(`\u2705 \u81EA\u542F\u52A8\u5DF2\u5173\u95ED (${t.agentId})`)}catch(e){g.error("cli","autostart disable \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}})).addCommand(new G("status").description("\u67E5\u770B macOS \u81EA\u542F\u52A8\u72B6\u6001").option("--agent-id <id>","Agent ID / \u540D\u79F0\uFF08\u4E0D\u6307\u5B9A\u5219\u5217\u51FA\u6240\u6709\uFF09").action(async t=>{try{if(E()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),t.agentId){let e=await re(t.agentId);console.log(`
51
- Agent: ${t.agentId}`),console.log(`Installed: ${e.installed?"yes":"no"}`),console.log(`Loaded: ${e.loaded?"yes":"no"}`),console.log(`Running: ${e.running?`yes (PID: ${e.pid})`:"no"}`),console.log("")}else{let e=await ae();if(e.length===0){console.log("\u65E0\u5DF2\u6CE8\u518C\u7684 Agent");return}for(let n of e){let o=await re(n.name),r=o.running?`running (PID: ${o.pid})`:o.loaded?"loaded":o.installed?"installed":"not installed";console.log(` ${n.name}: ${r}`)}}}catch(e){g.error("cli","autostart status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}}));d.command("connect").description("\u4E00\u952E\u6CE8\u518C + \u4FDD\u5B58\u51ED\u8BC1 + \u540E\u53F0\u542F\u52A8 daemon\uFF08\u5BF9\u6807 Harness connect\uFF09").requiredOption("--server-url <url>","Gateway / \u5E73\u53F0\u5730\u5740").option("--token <ownerToken>","owner-token\uFF08\u81EA\u6CE8\u518C\uFF0C\u4E0E --key \u4E8C\u9009\u4E00\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF0C\u4E0E --token \u4E8C\u9009\u4E00\uFF09").requiredOption("--name <name>","Agent \u540D\u79F0").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u53EF\u9009\uFF09").option("--no-start","\u53EA\u6CE8\u518C\u4E0D\u542F\u52A8 daemon").option("--foreground","\u6CE8\u518C\u540E\u5728\u524D\u53F0\u8FD0\u884C relay\uFF08\u963B\u585E\u7EC8\u7AEF\uFF0C\u4FBF\u4E8E\u8C03\u8BD5\uFF09").option("--force","\u8986\u76D6\u540C\u540D\u4F46\u7F51\u5173\u4E0D\u540C\u7684\u5DF2\u6709\u51ED\u8BC1").action(async t=>{try{if(!t.token&&!t.key)throw new Error("\u5FC5\u987B\u63D0\u4F9B --token\uFF08owner-token\uFF09\u6216 --key\uFF08per-machine key\uFF0Csk_machine_*\uFF09\u5176\u4E2D\u4E4B\u4E00\u3002");if(!t.force){let s=await Ft(t.name,t.serverUrl);s&&(console.error(`\u26A0\uFE0F \u62D2\u7EDD\u8986\u76D6\uFF1AAgent \u540D\u79F0 "${t.name}" \u5DF2\u7ED1\u5B9A\u5230\u53E6\u4E00\u4E2A\u7F51\u5173\u3002`),console.error(` \u65E7\u7F51\u5173: ${s.serverUrl}`),console.error(` \u65B0\u7F51\u5173: ${t.serverUrl}`),console.error(" \u7EE7\u7EED\u5C06\u8986\u76D6\u672C\u673A\u8BE5\u51ED\u8BC1\uFF0C\u4E14\u65E7\u7F51\u5173\u7684 daemon \u65E0\u6CD5\u4E0E\u65B0\u7684\u5171\u5B58\uFF08PID \u4E92\u65A5\uFF09\u3002"),console.error(" \u8BF7\u9009\u62E9\u5176\u4E00\uFF1A"),console.error(" 1) \u6362\u4E00\u4E2A --name\uFF08\u591A\u7F51\u5173\u5EFA\u8BAE\u6BCF\u4E2A\u7F51\u5173\u7528\u4E0D\u540C\u540D\u79F0\uFF09"),console.error(" 2) \u786E\u5B9E\u8981\u6539\u7ED1\uFF0C\u52A0 --force \u5F3A\u5236\u8986\u76D6"),process.exit(1))}let e=t.workspaceRoot?Z(t.workspaceRoot,t.name):void 0,n={name:t.name,serverUrl:t.serverUrl,token:t.token??"",key:t.key,workspaceRoot:e,createdAt:new Date().toISOString()};if(await Ut(n),console.log(`\u2705 Agent "${t.name}" \u5DF2\u6CE8\u518C\u5E76\u4FDD\u5B58\u51ED\u8BC1`),console.log(` Server: ${t.serverUrl}`),console.log(` ${t.token?"Token":"Key"}: ${H(t.token??t.key??"")}`),e&&console.log(` Workspace: ${e}`),console.log(" \u51ED\u8BC1\u6587\u4EF6: ~/.aitable-workflow/credentials.json"),!t.start){t.foreground&&console.log(`
51
+ `}c(To,"generatePlist");function F(r){return r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}c(F,"escapeXml");function pe(){let r=process.getuid?.();if(r===void 0)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237 UID\uFF08\u4EC5\u652F\u6301 macOS/Linux\uFF09");return r}c(pe,"getUid");async function Rt(r,e){if(!$())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let t=kt();vt(t);let n=await Eo(r),o=Ee(r),i=V(r);try{Y(`launchctl bootout gui/${pe()}/${i} 2>/dev/null`,{encoding:"utf8"})}catch{}await Co(A.dirname(o),{recursive:!0});let s=To(r,{maxTasks:e?.maxTasks,relayEnv:n,cliEntry:t});await Ro(o,s,"utf8"),Y(`launchctl bootstrap gui/${pe()} ${o}`,{encoding:"utf8"})}c(Rt,"enableAutostart");async function bt(r){if(!$())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=V(r),t=Ee(r);try{Y(`launchctl bootout gui/${pe()}/${e} 2>/dev/null`,{encoding:"utf8"})}catch{}await bo(t,{force:!0})}c(bt,"disableAutostart");async function Te(r){if(!$())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=V(r),t=Ee(r),n=!1;try{await Io(t),n=!0}catch{n=!1}let o=!1,i=!1,s=null;try{let a=Y(`launchctl print gui/${pe()}/${e} 2>/dev/null`,{encoding:"utf8"});o=!0;let l=a.match(/pid\s*=\s*(\d+)/);l&&(s=parseInt(l[1],10),i=!0)}catch{o=!1}return{installed:n,loaded:o,running:i,pid:s}}c(Te,"getAutostartStatus");import{watchFile as jo,statSync as Po,openSync as Lo,readSync as _o,closeSync as Mo}from"fs";import{readFile as It}from"fs/promises";function At(r,e){r.command("start").description("\u4EE5\u540E\u53F0\u8FDB\u7A0B\u542F\u52A8 relay daemon").option("--agent <name>","Agent \u540D\u79F0\uFF08\u9ED8\u8BA4\u4F7F\u7528 activeAgent\uFF09").option("--server-url <url>","Gateway \u5730\u5740").option("--token <ownerToken>","owner-token").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `--agent <name>` \u6307\u5B9A\u3002");o=a.name}let i=await U({serverUrl:n.serverUrl,token:n.token,key:n.key,workspaceRoot:n.workspaceRoot,name:o,maxTasks:n.maxTasks}),s=await K({agentId:o,serverUrl:i.serverUrl,token:i.token,key:i.key,name:i.name??o,workspaceRoot:i.workspaceRoot,machineId:i.machineId,maxTasks:i.maxTasks});console.log("\u2705 Daemon \u5DF2\u542F\u52A8"),console.log(` Agent: ${o}`),console.log(` PID: ${s.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${o}/daemon.log`)}catch(o){I.error("cli","start \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),r.command("stop").description("\u505C\u6B62\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--all","\u505C\u6B62\u6240\u6709 daemon").action(async n=>{try{if(n.all){let o=await Ct(),i=0;for(let s of o)await le(s.name)&&i++;console.log(`\u2705 \u5DF2\u505C\u6B62 ${i} \u4E2A daemon`)}else{let o=n.agent;if(!o){let s=await j();if(!s)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=s.name}let i=await le(o);console.log(i?`\u2705 Daemon "${o}" \u5DF2\u505C\u6B62`:`\u26A0\uFE0F Daemon "${o}" \u672A\u5728\u8FD0\u884C`)}}catch(o){I.error("cli","stop \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),r.command("restart").description("\u91CD\u542F\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=a.name}console.log(`\u{1F504} \u6B63\u5728\u91CD\u542F "${o}"...`),await le(o);let i=await U({name:o,maxTasks:n.maxTasks}),s=await K({agentId:o,serverUrl:i.serverUrl,token:i.token,key:i.key,name:i.name??o,workspaceRoot:i.workspaceRoot,machineId:i.machineId,maxTasks:i.maxTasks});console.log(`\u2705 Daemon \u5DF2\u91CD\u542F (PID: ${s.pid})`)}catch(o){I.error("cli","restart \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),r.command("status").description("\u67E5\u770B daemon \u72B6\u6001").option("--agent <name>","Agent \u540D\u79F0").option("-v, --verbose","\u5C55\u793A\u5B8C\u6574\u914D\u7F6E").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a){console.log("\u65E0\u6D3B\u8DC3 Agent");return}o=a.name}let i=await q(o),s=await j();if(console.log(`
52
+ Agent: ${i.agentId}`),console.log(`Running: ${i.running?"\u2705 yes":"\u274C no"}`),i.pid&&console.log(`PID: ${i.pid}`),i.uptimeMs!==null){let a=Math.floor(i.uptimeMs/1e3),l=Math.floor(a/60),m=Math.floor(l/60);console.log(`Uptime: ${m}h ${l%60}m ${a%60}s`)}console.log(`Log file: ${i.logFile}`),n.verbose&&s&&(console.log(`
53
+ --- Configuration ---`),console.log(`Server: ${s.serverUrl}`),console.log(`Token: ${$o(s.token)}`),s.machineId&&console.log(`MachineID: ${s.machineId}`),s.workspaceRoot&&console.log(`Workspace: ${s.workspaceRoot}`)),console.log("")}catch(o){I.error("cli","status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),r.command("logs").description("\u67E5\u770B daemon \u65E5\u5FD7").option("--agent <name>","Agent \u540D\u79F0").option("-f, --follow","\u6301\u7EED\u8DDF\u8E2A\u65E5\u5FD7\u8F93\u51FA").option("-n <lines>","\u663E\u793A\u6700\u8FD1 N \u884C","50").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=a.name}let i=G(o),s=parseInt(n.n,10)||50;if(n.follow){let a=await It(i,"utf8").catch(()=>"");if(a){let m=a.trimEnd().split(`
54
+ `);console.log(m.slice(-s).join(`
55
+ `))}let l=a.length;jo(i,{interval:500},()=>{try{let m=Po(i);if(m.size>l){let p=Lo(i,"r"),u=Buffer.alloc(m.size-l);_o(p,u,0,u.length,l),Mo(p),process.stdout.write(u.toString("utf8")),l=m.size}}catch{}})}else{let a=await It(i,"utf8").catch(()=>"");if(!a){console.log(`\u6682\u65E0\u65E5\u5FD7 (${i})`);return}let l=a.trimEnd().split(`
56
+ `);console.log(l.slice(-s).join(`
57
+ `))}}catch(o){I.error("cli","logs \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),r.command("daemon").description("Daemon \u540E\u53F0\u5B88\u62A4\u7BA1\u7406").command("autostart").description("macOS \u5F00\u673A\u81EA\u542F\u7BA1\u7406").addCommand(new $e("enable").description("\u542F\u7528 macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650").action(async n=>{try{$()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await Rt(n.agentId,{maxTasks:n.maxTasks?parseInt(n.maxTasks,10):void 0}),console.log("\u2705 \u81EA\u542F\u52A8\u5DF2\u542F\u7528"),console.log(` Agent: ${n.agentId}`),console.log(` Plist: ~/Library/LaunchAgents/com.alibaba.aitable-workflow.daemon.${n.agentId}.plist`)}catch(o){I.error("cli","autostart enable \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})).addCommand(new $e("disable").description("\u5173\u95ED macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").action(async n=>{try{$()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await bt(n.agentId),console.log(`\u2705 \u81EA\u542F\u52A8\u5DF2\u5173\u95ED (${n.agentId})`)}catch(o){I.error("cli","autostart disable \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})).addCommand(new $e("status").description("\u67E5\u770B macOS \u81EA\u542F\u52A8\u72B6\u6001").option("--agent-id <id>","Agent ID / \u540D\u79F0\uFF08\u4E0D\u6307\u5B9A\u5219\u5217\u51FA\u6240\u6709\uFF09").action(async n=>{try{if($()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),n.agentId){let o=await Te(n.agentId);console.log(`
58
+ Agent: ${n.agentId}`),console.log(`Installed: ${o.installed?"yes":"no"}`),console.log(`Loaded: ${o.loaded?"yes":"no"}`),console.log(`Running: ${o.running?`yes (PID: ${o.pid})`:"no"}`),console.log("")}else{let o=await Ct();if(o.length===0){console.log("\u65E0\u5DF2\u6CE8\u518C\u7684 Agent");return}for(let i of o){let s=await Te(i.name),a=s.running?`running (PID: ${s.pid})`:s.loaded?"loaded":s.installed?"installed":"not installed";console.log(` ${i.name}: ${a}`)}}}catch(o){I.error("cli","autostart status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}))}c(At,"registerDaemonCommands");function xt(r,e){r.command("heartbeat").description("\u5411\u670D\u52A1\u7AEF\u53D1\u9001\u5FC3\u8DF3\u5E76\u8FD4\u56DE\u4EFB\u52A1\u5206\u914D\u60C5\u51B5").action(async()=>{try{let t=await j();if(!t)throw new Error("\u65E0\u6D3B\u8DC3 Agent");if(!(await q(t.name)).running){console.log("\u26A0\uFE0F Daemon \u672A\u5728\u8FD0\u884C\u3002\u4F7F\u7528 `aitable-workflow start` \u542F\u52A8\u3002");return}let o=await de(t.name);console.log("\u2705 Heartbeat OK"),console.log(` Agent: ${t.name}`),console.log(` Connection: ${o.connectionState}`),console.log(` Running: ${o.runningTasks} tasks`),console.log(` Queued: ${o.queuedTasks} tasks`),o.lastHeartbeatAt&&console.log(` Last HB: ${o.lastHeartbeatAt}`)}catch(t){I.error("cli","heartbeat \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}})}c(xt,"registerHeartbeatCommand");import{logger as Do,saveCredential as Oo,findConflictingCredential as Uo,maskSecret as Fo}from"aitable-workflow-core";function St(r,e){r.command("connect").description("\u4E00\u952E\u6CE8\u518C + \u4FDD\u5B58\u51ED\u8BC1 + \u540E\u53F0\u542F\u52A8 daemon\uFF08\u5BF9\u6807 Harness connect\uFF09").requiredOption("--server-url <url>","Gateway / \u5E73\u53F0\u5730\u5740").option("--token <ownerToken>","owner-token\uFF08\u81EA\u6CE8\u518C\uFF0C\u4E0E --key \u4E8C\u9009\u4E00\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF0C\u4E0E --token \u4E8C\u9009\u4E00\uFF09").requiredOption("--name <name>","Agent \u540D\u79F0").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u53EF\u9009\uFF09").option("--no-start","\u53EA\u6CE8\u518C\u4E0D\u542F\u52A8 daemon").option("--foreground","\u6CE8\u518C\u540E\u5728\u524D\u53F0\u8FD0\u884C relay\uFF08\u963B\u585E\u7EC8\u7AEF\uFF0C\u4FBF\u4E8E\u8C03\u8BD5\uFF09").option("--force","\u8986\u76D6\u540C\u540D\u4F46\u7F51\u5173\u4E0D\u540C\u7684\u5DF2\u6709\u51ED\u8BC1").action(async t=>{try{if(!t.token&&!t.key)throw new Error("\u5FC5\u987B\u63D0\u4F9B --token\uFF08owner-token\uFF09\u6216 --key\uFF08per-machine key\uFF0Csk_machine_*\uFF09\u5176\u4E2D\u4E4B\u4E00\u3002");if(!t.force){let l=await Uo(t.name,t.serverUrl);l&&(console.error(`\u26A0\uFE0F \u62D2\u7EDD\u8986\u76D6\uFF1AAgent \u540D\u79F0 "${t.name}" \u5DF2\u7ED1\u5B9A\u5230\u53E6\u4E00\u4E2A\u7F51\u5173\u3002`),console.error(` \u65E7\u7F51\u5173: ${l.serverUrl}`),console.error(` \u65B0\u7F51\u5173: ${t.serverUrl}`),console.error(" \u7EE7\u7EED\u5C06\u8986\u76D6\u672C\u673A\u8BE5\u51ED\u8BC1\uFF0C\u4E14\u65E7\u7F51\u5173\u7684 daemon \u65E0\u6CD5\u4E0E\u65B0\u7684\u5171\u5B58\uFF08PID \u4E92\u65A5\uFF09\u3002"),console.error(" \u8BF7\u9009\u62E9\u5176\u4E00\uFF1A"),console.error(" 1) \u6362\u4E00\u4E2A --name\uFF08\u591A\u7F51\u5173\u5EFA\u8BAE\u6BCF\u4E2A\u7F51\u5173\u7528\u4E0D\u540C\u540D\u79F0\uFF09"),console.error(" 2) \u786E\u5B9E\u8981\u6539\u7ED1\uFF0C\u52A0 --force \u5F3A\u5236\u8986\u76D6"),process.exit(1))}let n=t.workspaceRoot?xe(t.workspaceRoot,t.name):void 0,o={name:t.name,serverUrl:t.serverUrl,token:t.token??"",key:t.key,workspaceRoot:n,createdAt:new Date().toISOString()};if(await Oo(o),console.log(`\u2705 Agent "${t.name}" \u5DF2\u6CE8\u518C\u5E76\u4FDD\u5B58\u51ED\u8BC1`),console.log(` Server: ${t.serverUrl}`),console.log(` ${t.token?"Token":"Key"}: ${Fo(t.token??t.key??"")}`),n&&console.log(` Workspace: ${n}`),console.log(" \u51ED\u8BC1\u6587\u4EF6: ~/.aitable-workflow/credentials.json"),!t.start){t.foreground&&console.log(`
52
59
  \u{1F4A1} --no-start \u4E0E --foreground \u540C\u65F6\u6307\u5B9A\uFF0C\u6309 --no-start \u4F18\u5148\uFF1A\u4EC5\u6CE8\u518C\u4E0D\u542F\u52A8\u3002`),console.log(`
53
60
  \u{1F4A1} \u542F\u52A8 daemon: aitable-workflow start \u6216 aitable-workflow relay`);return}if(t.foreground){console.log(`
54
- \u{1F680} \u524D\u53F0\u542F\u52A8 relay\uFF08Ctrl-C \u9000\u51FA\uFF09...`),await ee({serverUrl:t.serverUrl,token:t.token,key:t.key,name:t.name,workspaceRoot:e});return}let o=t.name,r=await C({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:o}),i=await B({agentId:o,serverUrl:r.serverUrl,token:r.token,key:r.key,name:r.name??o,workspaceRoot:r.workspaceRoot,machineId:r.machineId,maxTasks:r.maxTasks});console.log(`
55
- \u{1F680} Daemon \u5DF2\u540E\u53F0\u542F\u52A8`),console.log(` Agent: ${o}`),console.log(` PID: ${i.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${o}/daemon.log`),console.log(`
56
- \u{1F4CB} \u5E38\u7528\u547D\u4EE4\uFF1A`),console.log(` \u67E5\u770B\u72B6\u6001: aitable-workflow status --agent ${o}`),console.log(` \u8DDF\u8E2A\u65E5\u5FD7: aitable-workflow logs -f --agent ${o}`),console.log(` \u505C\u6B62: aitable-workflow stop --agent ${o}`),console.log(` \u91CD\u542F: aitable-workflow restart --agent ${o}`),console.log(" \u5217\u51FA Agent: aitable-workflow agent list"),console.log(" \u5207\u6362 Agent: aitable-workflow agent use <name>"),console.log(` \u5F00\u673A\u81EA\u542F: aitable-workflow daemon autostart enable --agent-id ${o}`)}catch(e){g.error("cli","connect \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});var q=d.command("agent").description("Agent \u51ED\u8BC1\u7BA1\u7406");q.command("list").description("\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684 Agent \u51ED\u8BC1").action(async()=>{try{let t=await ae();if(t.length===0){console.log("\u6682\u65E0\u5DF2\u4FDD\u5B58\u7684 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let e=await Nt();console.log(`
57
- \u5DF2\u4FDD\u5B58 ${t.length} \u4E2A Agent\uFF08\u6D3B\u8DC3: ${e.activeAgent??"\u65E0"}\uFF09:
58
- `);for(let n of t){let o=n.name===e.activeAgent?" \u2190 active":"";console.log(` \u2022 ${n.name}${o}`),console.log(` Server: ${n.serverUrl}`),console.log(` Token: ${H(n.token)}`),n.machineId&&console.log(` MachineID: ${n.machineId}`),n.workspaceRoot&&console.log(` Workspace: ${n.workspaceRoot}`),console.log(` Created: ${n.createdAt}`)}console.log("")}catch(t){g.error("cli","agent list \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}});q.command("use <name>").description("\u5207\u6362\u6D3B\u8DC3 Agent").action(async t=>{try{let e=await jt(t);console.log(`\u2705 \u5DF2\u5207\u6362\u5230 Agent "${e.activeAgent}"`)}catch(e){g.error("cli","agent use \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});q.command("whoami").description("\u663E\u793A\u5F53\u524D\u6D3B\u8DC3 Agent").action(async()=>{try{let t=await A();if(!t){console.log("\u5F53\u524D\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `aitable-workflow agent use <name>` \u5207\u6362\u3002");return}console.log(`Agent: ${t.name}`),console.log(`Server: ${t.serverUrl}`),console.log(`Token: ${H(t.token)}`),t.machineId&&console.log(`MachineID: ${t.machineId}`),t.workspaceRoot&&console.log(`Workspace: ${t.workspaceRoot}`)}catch(t){g.error("cli","agent whoami \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}});q.command("status").description("\u67E5\u770B Agent \u8FDE\u63A5\u72B6\u6001\u4E0E\u8FD0\u884C\u65F6\u4FE1\u606F").option("--json","JSON \u683C\u5F0F\u8F93\u51FA").action(async t=>{try{let e=await A();if(!e){console.log("\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let n=await V(e.name),o=await te(e.name),r={agent:e.name,serverUrl:e.serverUrl,connectionState:n.running?o.connectionState:"stopped",machineId:o.machineId??e.machineId??null,lastHeartbeatAt:o.lastHeartbeatAt,runningTasks:o.runningTasks,queuedTasks:o.queuedTasks,lastDisconnectReason:o.lastDisconnectReason,pid:n.pid};if(t.json){process.stdout.write(JSON.stringify(r,null,2)+`
59
- `);return}let i=r.connectionState==="connected"?"\u{1F7E2}":r.connectionState==="reconnecting"?"\u{1F7E1}":"\u{1F534}";console.log(`
60
- ${i} Agent: ${r.agent}`),console.log(` Server: ${r.serverUrl}`),console.log(` Connection: ${r.connectionState}`),r.machineId&&console.log(` MachineID: ${r.machineId}`),r.lastHeartbeatAt&&console.log(` Last HB: ${r.lastHeartbeatAt}`),n.running&&(console.log(` PID: ${r.pid}`),console.log(` Tasks: ${r.runningTasks} running, ${r.queuedTasks} queued`)),r.lastDisconnectReason&&console.log(` Last Error: ${r.lastDisconnectReason}`),console.log("")}catch(e){g.error("cli","agent status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("heartbeat").description("\u5411\u670D\u52A1\u7AEF\u53D1\u9001\u5FC3\u8DF3\u5E76\u8FD4\u56DE\u4EFB\u52A1\u5206\u914D\u60C5\u51B5").action(async()=>{try{let t=await A();if(!t)throw new Error("\u65E0\u6D3B\u8DC3 Agent");if(!(await V(t.name)).running){console.log("\u26A0\uFE0F Daemon \u672A\u5728\u8FD0\u884C\u3002\u4F7F\u7528 `aitable-workflow start` \u542F\u52A8\u3002");return}let n=await te(t.name);console.log("\u2705 Heartbeat OK"),console.log(` Agent: ${t.name}`),console.log(` Connection: ${n.connectionState}`),console.log(` Running: ${n.runningTasks} tasks`),console.log(` Queued: ${n.queuedTasks} tasks`),n.lastHeartbeatAt&&console.log(` Last HB: ${n.lastHeartbeatAt}`)}catch(t){g.error("cli","heartbeat \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}});d.command("relay").description("\u4EE5\u672C\u673A relay \u5B88\u62A4\u8EAB\u4EFD\u53CD\u8FDE RelayGateway\uFF0C\u6309\u9700\u5728\u672C\u673A\u6267\u884C Agent/dws \u4EFB\u52A1").option("--server-url <url>","Gateway \u5730\u5740\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_SERVER_URL\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--token <ownerToken>","owner-token \u81EA\u6CE8\u518C\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_TOKEN\uFF1B\u4F18\u5148\u4E8E --key\uFF09").option("--name <name>","\u81EA\u6CE8\u518C\u673A\u5668\u540D\uFF08\u53EF\u9009\uFF0C\u7F3A\u7701\u81EA\u52A8\u4F7F\u7528\u4E3B\u673A\u540D\uFF1Bowner+name \u5E42\u7B49\u952E\uFF0C\u591A\u673A\u573A\u666F\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A\u4EE5\u907F\u514D hostname \u51B2\u7A81\u4E92\u76F8\u9876\u8FDE\u63A5\uFF1B\u4E5F\u53EF\u7528 AITABLE_RELAY_NAME\uFF09").option("--desc <description>","\u81EA\u6CE8\u518C\u673A\u5668\u63CF\u8FF0\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_DESC\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_WORKSPACE_ROOT\uFF09").option("--machine-id <id>","\u7A33\u5B9A\u673A\u5668\u8EAB\u4EFD\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MACHINE_ID\uFF09").option("--max-tasks <n>","\u672C\u673A\u5E76\u53D1\u6267\u884C\u4E0A\u9650\uFF0C\u9ED8\u8BA4 1\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_TASKS\uFF09").action(t=>{try{ee(t)}catch(e){g.error("cli","relay \u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("inspect [recordId]").description("\u67E5\u770B\u5DE5\u5355\u6267\u884C trace\uFF1B\u6216\u7528 --recipes / --validate \u67E5\u770B\u6821\u9A8C recipe schema \u4E0E workflow \u5BF9\u9F50").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-s, --step <stepId>","\u67E5\u770B\u7279\u5B9A\u6B65\u9AA4").option("-l, --latest","\u67E5\u770B\u6700\u8FD1\u6267\u884C").option("-n, --limit <number>","\u6700\u591A\u663E\u793A\u6761\u6570","10").option("--recipes","\u5217\u51FA\u5404\u6B65\u9AA4 recipe \u7684 input / output / config schema\u4E0E step \u914D\u7F6E").option("--validate","\u6821\u9A8C step.config / input_mapping / output_mapping \u662F\u5426\u7B26\u5408 recipe schema").option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u53D6\u7B2C\u4E00\u4E2A\uFF09").action(async(t,e)=>{try{if(e.recipes||e.validate){await en(e);return}let n=await K(e.config),o=y.resolve(n.configDir,n.agent.trace_dir),r=new Mt(o),i=parseInt(e.limit,10)||10,s;if(e.latest||!t){if(s=await r.getLatestTraces(i),s.length===0){console.log("\u26A0\uFE0F \u6682\u65E0 trace \u8BB0\u5F55\u3002\u8FD0\u884C `run` \u547D\u4EE4\u540E\u518D\u67E5\u770B\u3002");return}console.log(`
61
- \u{1F4C4} \u6700\u8FD1 ${s.length} \u6761\u6267\u884C\u8BB0\u5F55:
62
- `)}else{if(s=await r.getTraces(t),s.length===0){console.log(`\u26A0\uFE0F \u672A\u627E\u5230\u5DE5\u5355 ${t} \u7684 trace \u8BB0\u5F55\u3002`);return}e.step&&(s=s.filter(a=>a.step_id===e.step)),console.log(`
63
- \u{1F4C4} \u5DE5\u5355 ${t} \u7684\u6267\u884C\u5386\u53F2 (${s.length} \u6B65):
64
- `)}for(let a of s){let l=a.status==="success"?"\u2705":a.status==="failed"?"\u274C":"\u23F8\uFE0F",m=(a.duration_ms/1e3).toFixed(1);console.log(`${l} [${a.step_id}] ${a.step_name} \u2014 ${m}s \u2014 ${a.status.toUpperCase()}`);for(let[h,w]of a.llm_calls.entries()){let f=h===a.llm_calls.length-1,T=f?" \u2514\u2500":" \u251C\u2500",ce=f?" ":" \u2502 ",Pe=(w.duration_ms/1e3).toFixed(1);console.log(`${T} LLM: ${w.model} (${Pe}s)`),console.log(`${ce}Input: ${w.prompt_summary.slice(0,80)}${w.prompt_summary.length>80?"...":""}`),console.log(`${ce}Output: ${w.response_summary.slice(0,100)}${w.response_summary.length>100?"...":""}`)}if(Object.keys(a.outputs).length>0){let h=Object.entries(a.outputs).map(([w,f])=>`${w}=${typeof f=="string"?f.slice(0,50):JSON.stringify(f)}`).join(", ");console.log(` \u2514\u2500 Outputs: ${h}`)}a.error&&console.log(` \u2514\u2500 Error: ${a.error}`),console.log()}}catch(n){console.error(`\u2717 inspect \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});var J=d.command("kb").description("\u77E5\u8BC6\u5E93(LLM-Wiki)\u7F16\u8BD1\u4E0E\u72B6\u6001\u7BA1\u7406");J.command("compile [collections...]").description("\u7F16\u8BD1\u77E5\u8BC6\u5E93\u4E3A wiki\uFF08\u4E0D\u6307\u5B9A collection \u65F6\u7F16\u8BD1\u89D2\u8272\u58F0\u660E\u7684\u5168\u90E8\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1").action(async(t,e)=>{try{await xt(t,e)}catch(n){console.error(`\u2717 kb compile \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("update [collections...]").description("\u6E90\u6587\u6863\u53D8\u66F4\u540E\u89E6\u53D1\u589E\u91CF\u7F16\u8BD1\uFF08\u672A\u53D8\u66F4\u5219\u8DF3\u8FC7\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async(t,e)=>{try{await Ct(t,e)}catch(n){console.error(`\u2717 kb update \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("status [collections...]").description("\u67E5\u770B\u77E5\u8BC6\u5E93\u7F16\u8BD1\u72B6\u6001\uFF08\u7F16\u8BD1\u4E2D/\u5B8C\u6210/\u5931\u8D25 + \u6E90\u662F\u5426\u5DF2\u53D8\u66F4\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async(t,e)=>{try{await _t(t,e)}catch(n){console.error(`\u2717 kb status \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("ingest <url-or-path>").description("\u5BFC\u5165\u6587\u6863\u5230 wiki \u76EE\u5F55\uFF08\u652F\u6301\u9489\u9489 URL \u6216\u672C\u5730\u8DEF\u5F84\uFF0Cdocx/pdf \u81EA\u52A8\u8F6C md\uFF09").option("-o, --output <dir>","\u8F93\u51FA\u76EE\u5F55\uFF08\u9ED8\u8BA4 ./wiki\uFF09").option("-t, --type <type>","\u6E90\u7C7B\u578B: dingtalk-doc\uFF08\u4E0D\u4F20\u5219\u81EA\u52A8\u8BC6\u522B\uFF09").option("--flat","\u4E0D\u4FDD\u7559\u8FDC\u7AEF\u76EE\u5F55\u7ED3\u6784\uFF08\u6240\u6709\u6587\u6863\u5E73\u94FA\u5230\u8F93\u51FA\u76EE\u5F55\uFF09").option("--force","\u5F3A\u5236\u91CD\u65B0\u62C9\u53D6\u6240\u6709\u6587\u6863\uFF08\u5FFD\u7565\u589E\u91CF\u5224\u65AD\uFF09").option("--compile","\u5BFC\u5165\u540E\u81EA\u52A8\u89E6\u53D1 kb compile").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--timeout <ms>","\u5355\u6587\u6863\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").action(async(t,e)=>{try{await Lt(t,e)}catch(n){console.error(`\u2717 kb ingest \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});async function en(t){let e=await K(t.config),n=t.workflow?e.workflowEntries.find(s=>s.id===t.workflow):e.workflowEntries[0];n||(console.error(`\u2717 \u672A\u627E\u5230\u5DE5\u4F5C\u6D41\u300C${t.workflow}\u300D\u3002\u53EF\u7528\uFF1A${e.workflowEntries.map(s=>s.id).join(", ")}`),process.exit(1));let o=await Ce(n.templatePath,{envSource:e.envSource}),{issues:r,rows:i}=await Pt(n.recipeDir,o);if(t.recipes){console.log(`
65
- \u{1F4CB} \u5DE5\u4F5C\u6D41\u300C${o.meta.name}\u300D(${n.id}) \u7684 recipe schema:
66
- `);for(let s of i){let a=s.configSummary.length>0?s.configSummary.join(", "):"(none)",l=s.loaded?"":" \u26A0 \u52A0\u8F7D\u5931\u8D25";console.log(` [${s.stepId} \u2192 ${s.recipeId}]${l}`),console.log(` config: ${a}`),console.log()}}if(t.validate)if(r.length===0)console.log(`
67
- \u2705 \u5DE5\u4F5C\u6D41\u300C${o.meta.name}\u300D(${n.id}) \u5168\u90E8\u6B65\u9AA4\u6821\u9A8C\u901A\u8FC7
68
- `);else{let s=r.filter(l=>l.level==="error"),a=r.filter(l=>l.level==="warn");console.log(`
61
+ \u{1F680} \u524D\u53F0\u542F\u52A8 relay\uFF08Ctrl-C \u9000\u51FA\uFF09...`),await me({serverUrl:t.serverUrl,token:t.token,key:t.key,name:t.name,workspaceRoot:n});return}let i=t.name,s=await U({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:i}),a=await K({agentId:i,serverUrl:s.serverUrl,token:s.token,key:s.key,name:s.name??i,workspaceRoot:s.workspaceRoot,machineId:s.machineId,maxTasks:s.maxTasks});console.log(`
62
+ \u{1F680} Daemon \u5DF2\u540E\u53F0\u542F\u52A8`),console.log(` Agent: ${i}`),console.log(` PID: ${a.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${i}/daemon.log`),console.log(`
63
+ \u{1F4CB} \u5E38\u7528\u547D\u4EE4\uFF1A`),console.log(` \u67E5\u770B\u72B6\u6001: aitable-workflow status --agent ${i}`),console.log(` \u8DDF\u8E2A\u65E5\u5FD7: aitable-workflow logs -f --agent ${i}`),console.log(` \u505C\u6B62: aitable-workflow stop --agent ${i}`),console.log(` \u91CD\u542F: aitable-workflow restart --agent ${i}`),console.log(" \u5217\u51FA Agent: aitable-workflow agent list"),console.log(" \u5207\u6362 Agent: aitable-workflow agent use <name>"),console.log(` \u5F00\u673A\u81EA\u542F: aitable-workflow daemon autostart enable --agent-id ${i}`)}catch(n){Do.error("cli","connect \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(St,"registerConnectCommand");import{logger as ge,listCredentials as Bo,setActiveAgent as Wo,getActiveCredential as Et,readCredentials as No,maskSecret as Tt}from"aitable-workflow-core";function $t(r,e){let t=r.command("agent").description("Agent \u51ED\u8BC1\u7BA1\u7406");t.command("list").description("\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684 Agent \u51ED\u8BC1").action(async()=>{try{let n=await Bo();if(n.length===0){console.log("\u6682\u65E0\u5DF2\u4FDD\u5B58\u7684 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let o=await No();console.log(`
64
+ \u5DF2\u4FDD\u5B58 ${n.length} \u4E2A Agent\uFF08\u6D3B\u8DC3: ${o.activeAgent??"\u65E0"}\uFF09:
65
+ `);for(let i of n){let s=i.name===o.activeAgent?" \u2190 active":"";console.log(` \u2022 ${i.name}${s}`),console.log(` Server: ${i.serverUrl}`),console.log(` Token: ${Tt(i.token)}`),i.machineId&&console.log(` MachineID: ${i.machineId}`),i.workspaceRoot&&console.log(` Workspace: ${i.workspaceRoot}`),console.log(` Created: ${i.createdAt}`)}console.log("")}catch(n){ge.error("cli","agent list \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}}),t.command("use <name>").description("\u5207\u6362\u6D3B\u8DC3 Agent").action(async n=>{try{let o=await Wo(n);console.log(`\u2705 \u5DF2\u5207\u6362\u5230 Agent "${o.activeAgent}"`)}catch(o){ge.error("cli","agent use \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),t.command("whoami").description("\u663E\u793A\u5F53\u524D\u6D3B\u8DC3 Agent").action(async()=>{try{let n=await Et();if(!n){console.log("\u5F53\u524D\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `aitable-workflow agent use <name>` \u5207\u6362\u3002");return}console.log(`Agent: ${n.name}`),console.log(`Server: ${n.serverUrl}`),console.log(`Token: ${Tt(n.token)}`),n.machineId&&console.log(`MachineID: ${n.machineId}`),n.workspaceRoot&&console.log(`Workspace: ${n.workspaceRoot}`)}catch(n){ge.error("cli","agent whoami \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}}),t.command("status").description("\u67E5\u770B Agent \u8FDE\u63A5\u72B6\u6001\u4E0E\u8FD0\u884C\u65F6\u4FE1\u606F").option("--json","JSON \u683C\u5F0F\u8F93\u51FA").action(async n=>{try{let o=await Et();if(!o){console.log("\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let i=await q(o.name),s=await de(o.name),a={agent:o.name,serverUrl:o.serverUrl,connectionState:i.running?s.connectionState:"stopped",machineId:s.machineId??o.machineId??null,lastHeartbeatAt:s.lastHeartbeatAt,runningTasks:s.runningTasks,queuedTasks:s.queuedTasks,lastDisconnectReason:s.lastDisconnectReason,pid:i.pid};if(n.json){process.stdout.write(JSON.stringify(a,null,2)+`
66
+ `);return}let l=a.connectionState==="connected"?"\u{1F7E2}":a.connectionState==="reconnecting"?"\u{1F7E1}":"\u{1F534}";console.log(`
67
+ ${l} Agent: ${a.agent}`),console.log(` Server: ${a.serverUrl}`),console.log(` Connection: ${a.connectionState}`),a.machineId&&console.log(` MachineID: ${a.machineId}`),a.lastHeartbeatAt&&console.log(` Last HB: ${a.lastHeartbeatAt}`),i.running&&(console.log(` PID: ${a.pid}`),console.log(` Tasks: ${a.runningTasks} running, ${a.queuedTasks} queued`)),a.lastDisconnectReason&&console.log(` Last Error: ${a.lastDisconnectReason}`),console.log("")}catch(o){ge.error("cli","agent status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})}c($t,"registerAgentCommands");import{logger as Go}from"aitable-workflow-core";function jt(r,e){r.command("relay").description("\u4EE5\u672C\u673A relay \u5B88\u62A4\u8EAB\u4EFD\u53CD\u8FDE RelayGateway\uFF0C\u6309\u9700\u5728\u672C\u673A\u6267\u884C Agent/dws \u4EFB\u52A1").option("--server-url <url>","Gateway \u5730\u5740\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_SERVER_URL\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--token <ownerToken>","owner-token \u81EA\u6CE8\u518C\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_TOKEN\uFF1B\u4F18\u5148\u4E8E --key\uFF09").option("--name <name>","\u81EA\u6CE8\u518C\u673A\u5668\u540D\uFF08\u53EF\u9009\uFF0C\u7F3A\u7701\u81EA\u52A8\u4F7F\u7528\u4E3B\u673A\u540D\uFF1Bowner+name \u5E42\u7B49\u952E\uFF0C\u591A\u673A\u573A\u666F\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A\u4EE5\u907F\u514D hostname \u51B2\u7A81\u4E92\u76F8\u9876\u8FDE\u63A5\uFF1B\u4E5F\u53EF\u7528 AITABLE_RELAY_NAME\uFF09").option("--desc <description>","\u81EA\u6CE8\u518C\u673A\u5668\u63CF\u8FF0\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_DESC\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_WORKSPACE_ROOT\uFF09").option("--machine-id <id>","\u7A33\u5B9A\u673A\u5668\u8EAB\u4EFD\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MACHINE_ID\uFF09").option("--max-tasks <n>","\u672C\u673A\u5E76\u53D1\u6267\u884C\u4E0A\u9650\uFF0C\u9ED8\u8BA4 1\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_TASKS\uFF09").option("--max-workflows <n>","\u672C\u673A\u53EF\u540C\u65F6\u8FD0\u884C\u7684\u5DE5\u4F5C\u6D41\u5F15\u64CE\u6570\uFF0C\u9ED8\u8BA4 3\uFF1B0 = \u4E0D\u8BA4\u9886\u5DE5\u4F5C\u6D41\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_WORKFLOWS\uFF09").action(t=>{try{me(t)}catch(n){Go.error("cli","relay \u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(jt,"registerRelayCommand");import{loadSettings as Pt,loadWorkflowTemplate as Ho,checkWorkflowRecipes as Ko,Tracer as qo}from"aitable-workflow-core";import Yo from"path";function Lt(r,e){r.command("inspect [recordId]").description("\u67E5\u770B\u5DE5\u5355\u6267\u884C trace\uFF1B\u6216\u7528 --recipes / --validate \u67E5\u770B\u6821\u9A8C recipe schema \u4E0E workflow \u5BF9\u9F50").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("-s, --step <stepId>","\u67E5\u770B\u7279\u5B9A\u6B65\u9AA4").option("-l, --latest","\u67E5\u770B\u6700\u8FD1\u6267\u884C").option("-n, --limit <number>","\u6700\u591A\u663E\u793A\u6761\u6570","10").option("--recipes","\u5217\u51FA\u5404\u6B65\u9AA4 recipe \u7684 input / output / config schema\u4E0E step \u914D\u7F6E").option("--validate","\u6821\u9A8C step.config / input_mapping / output_mapping \u662F\u5426\u7B26\u5408 recipe schema").option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u53D6\u7B2C\u4E00\u4E2A\uFF09").action(async(t,n)=>{try{if(n.recipes||n.validate){await Vo(n);return}let o=await Pt(n.config),i=Yo.resolve(o.configDir,o.agent.trace_dir),s=new qo(i),a=parseInt(n.limit,10)||10,l;if(n.latest||!t){if(l=await s.getLatestTraces(a),l.length===0){console.log("\u26A0\uFE0F \u6682\u65E0 trace \u8BB0\u5F55\u3002\u8FD0\u884C `run` \u547D\u4EE4\u540E\u518D\u67E5\u770B\u3002");return}console.log(`
68
+ \u{1F4C4} \u6700\u8FD1 ${l.length} \u6761\u6267\u884C\u8BB0\u5F55:
69
+ `)}else{if(l=await s.getTraces(t),l.length===0){console.log(`\u26A0\uFE0F \u672A\u627E\u5230\u5DE5\u5355 ${t} \u7684 trace \u8BB0\u5F55\u3002`);return}n.step&&(l=l.filter(m=>m.step_id===n.step)),console.log(`
70
+ \u{1F4C4} \u5DE5\u5355 ${t} \u7684\u6267\u884C\u5386\u53F2 (${l.length} \u6B65):
71
+ `)}for(let m of l){let p=m.status==="success"?"\u2705":m.status==="failed"?"\u274C":"\u23F8\uFE0F",u=(m.duration_ms/1e3).toFixed(1);console.log(`${p} [${m.step_id}] ${m.step_name} \u2014 ${u}s \u2014 ${m.status.toUpperCase()}`);for(let[g,d]of m.llm_calls.entries()){let y=g===m.llm_calls.length-1,C=y?" \u2514\u2500":" \u251C\u2500",x=y?" ":" \u2502 ",J=(d.duration_ms/1e3).toFixed(1);console.log(`${C} LLM: ${d.model} (${J}s)`),console.log(`${x}Input: ${d.prompt_summary.slice(0,80)}${d.prompt_summary.length>80?"...":""}`),console.log(`${x}Output: ${d.response_summary.slice(0,100)}${d.response_summary.length>100?"...":""}`)}if(Object.keys(m.outputs).length>0){let g=Object.entries(m.outputs).map(([d,y])=>`${d}=${typeof y=="string"?y.slice(0,50):JSON.stringify(y)}`).join(", ");console.log(` \u2514\u2500 Outputs: ${g}`)}m.error&&console.log(` \u2514\u2500 Error: ${m.error}`),console.log()}}catch(o){console.error(`\u2717 inspect \u5931\u8D25: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}})}c(Lt,"registerInspectCommand");async function Vo(r){let e=await Pt(r.config),t=r.workflow?e.workflowEntries.find(s=>s.id===r.workflow):e.workflowEntries[0];t||(console.error(`\u2717 \u672A\u627E\u5230\u5DE5\u4F5C\u6D41\u300C${r.workflow}\u300D\u3002\u53EF\u7528\uFF1A${e.workflowEntries.map(s=>s.id).join(", ")}`),process.exit(1));let n=await Ho(t.templatePath,{envSource:e.envSource}),{issues:o,rows:i}=await Ko(t.recipeDir,n);if(r.recipes){console.log(`
72
+ \u{1F4CB} \u5DE5\u4F5C\u6D41\u300C${n.meta.name}\u300D(${t.id}) \u7684 recipe schema:
73
+ `);for(let s of i){let a=s.configSummary.length>0?s.configSummary.join(", "):"(none)",l=s.loaded?"":" \u26A0 \u52A0\u8F7D\u5931\u8D25";console.log(` [${s.stepId} \u2192 ${s.recipeId}]${l}`),console.log(` config: ${a}`),console.log()}}if(r.validate)if(o.length===0)console.log(`
74
+ \u2705 \u5DE5\u4F5C\u6D41\u300C${n.meta.name}\u300D(${t.id}) \u5168\u90E8\u6B65\u9AA4\u6821\u9A8C\u901A\u8FC7
75
+ `);else{let s=o.filter(l=>l.level==="error"),a=o.filter(l=>l.level==="warn");console.log(`
69
76
  \u6821\u9A8C\u7ED3\u679C\uFF1A${s.length} \u4E2A\u9519\u8BEF\uFF0C${a.length} \u4E2A\u8B66\u544A
70
- `);for(let l of r){let m=l.level==="error"?"\u274C":"\u26A0\uFE0F ";console.log(` ${m} [${l.stepId} \u2192 ${l.recipeId}] ${l.message}`)}console.log(),s.length>0&&process.exit(1)}}c(en,"runRecipeInspect");await d.parseAsync();
77
+ `);for(let l of o){let m=l.level==="error"?"\u274C":"\u26A0\uFE0F ";console.log(` ${m} [${l.stepId} \u2192 ${l.recipeId}] ${l.message}`)}console.log(),s.length>0&&process.exit(1)}}c(Vo,"runRecipeInspect");import{runKbCompileCommand as Jo,runKbUpdateCommand as zo,runKbStatusCommand as Xo,runKbIngestCommand as Qo}from"aitable-workflow-core";function _t(r,e){let t=r.command("kb").description("\u77E5\u8BC6\u5E93(LLM-Wiki)\u7F16\u8BD1\u4E0E\u72B6\u6001\u7BA1\u7406");t.command("compile [collections...]").description("\u7F16\u8BD1\u77E5\u8BC6\u5E93\u4E3A wiki\uFF08\u4E0D\u6307\u5B9A collection \u65F6\u7F16\u8BD1\u89D2\u8272\u58F0\u660E\u7684\u5168\u90E8\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("--full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1").action(async(n,o)=>{try{await Jo(n,o)}catch(i){console.error(`\u2717 kb compile \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),t.command("update [collections...]").description("\u6E90\u6587\u6863\u53D8\u66F4\u540E\u89E6\u53D1\u589E\u91CF\u7F16\u8BD1\uFF08\u672A\u53D8\u66F4\u5219\u8DF3\u8FC7\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).action(async(n,o)=>{try{await zo(n,o)}catch(i){console.error(`\u2717 kb update \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),t.command("status [collections...]").description("\u67E5\u770B\u77E5\u8BC6\u5E93\u7F16\u8BD1\u72B6\u6001\uFF08\u7F16\u8BD1\u4E2D/\u5B8C\u6210/\u5931\u8D25 + \u6E90\u662F\u5426\u5DF2\u53D8\u66F4\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).action(async(n,o)=>{try{await Xo(n,o)}catch(i){console.error(`\u2717 kb status \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),t.command("ingest <url-or-path>").description("\u5BFC\u5165\u6587\u6863\u5230 wiki \u76EE\u5F55\uFF08\u652F\u6301\u9489\u9489 URL \u6216\u672C\u5730\u8DEF\u5F84\uFF0Cdocx/pdf \u81EA\u52A8\u8F6C md\uFF09").option("-o, --output <dir>","\u8F93\u51FA\u76EE\u5F55\uFF08\u9ED8\u8BA4 ./wiki\uFF09").option("-t, --type <type>","\u6E90\u7C7B\u578B: dingtalk-doc\uFF08\u4E0D\u4F20\u5219\u81EA\u52A8\u8BC6\u522B\uFF09").option("--flat","\u4E0D\u4FDD\u7559\u8FDC\u7AEF\u76EE\u5F55\u7ED3\u6784\uFF08\u6240\u6709\u6587\u6863\u5E73\u94FA\u5230\u8F93\u51FA\u76EE\u5F55\uFF09").option("--force","\u5F3A\u5236\u91CD\u65B0\u62C9\u53D6\u6240\u6709\u6587\u6863\uFF08\u5FFD\u7565\u589E\u91CF\u5224\u65AD\uFF09").option("--compile","\u5BFC\u5165\u540E\u81EA\u52A8\u89E6\u53D1 kb compile").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",e.defaultConfig).option("--timeout <ms>","\u5355\u6587\u6863\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").action(async(n,o)=>{try{await Qo(n,o)}catch(i){console.error(`\u2717 kb ingest \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}})}c(_t,"registerKbCommands");var Ut=Ot.dirname(tr(import.meta.url));Dt({override:!1,quiet:!0});Dt({path:Ot.resolve(Ut,"..",".env"),override:!1,quiet:!0});var Ft=Me(),Bt=he(Ft),nr=De(Ft),w=new Zo().name("aitable-workflow").description("\u901A\u7528\u4E1A\u52A1\u6D41\u7A0B\u5F15\u64CE \u2014 \u914D\u7F6E\u9A71\u52A8\u7684 AI \u8868\u683C\u5DE5\u4F5C\u6D41\u81EA\u52A8\u5316").version(Bt).option("-d, --debug","\u8F93\u51FA debug \u7EA7\u522B\u65E5\u5FD7\uFF08\u542B recipe \u5185\u90E8 log\uFF09").hook("preAction",async(r,e)=>{e.name()!=="init"&&await er()}).hook("preAction",(r,e)=>{r.opts().debug?Mt.setLevel("debug"):e.name()==="config"&&Mt.setLevel("warn")}),k={cliDir:Ut,version:Bt,packageVersions:nr,defaultConfig:Oe};Ue(w,k);Fe(w,k);Be(w,k);He(w,k);qe(w,k);Ye(w,k);Ve(w,k);Je(w,k);ze(w,k);Xe(w,k);Ze(w,k);At(w,k);St(w,k);$t(w,k);xt(w,k);jt(w,k);Lt(w,k);_t(w,k);await w.parseAsync();
@@ -1 +1 @@
1
- import{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q}from"./chunk-FW6MXYUM.js";import"./chunk-EI7MMDWY.js";export{q as canOfferDefaultFor,j as collectEditableChoices,i as collectEditableItems,b as collectErrorItems,f as collectPromptDefaults,d as collectPromptItems,c as collectSuggestionItems,p as getSemanticKey,l as ingestToCollection,e as isOptionalPromptItem,k as isUrl,g as promptDefaultForItem,o as redactConfigResultForJson,h as rememberPromptValue,n as resolveRoleKbCollection,m as roleCollectionName,a as runConfigCommand};
1
+ import{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q}from"./chunk-KGQEW2IX.js";import"./chunk-EI7MMDWY.js";export{q as canOfferDefaultFor,j as collectEditableChoices,i as collectEditableItems,b as collectErrorItems,f as collectPromptDefaults,d as collectPromptItems,c as collectSuggestionItems,p as getSemanticKey,l as ingestToCollection,e as isOptionalPromptItem,k as isUrl,g as promptDefaultForItem,o as redactConfigResultForJson,h as rememberPromptValue,n as resolveRoleKbCollection,m as roleCollectionName,a as runConfigCommand};
@@ -0,0 +1,8 @@
1
+ import{a as Y}from"./chunk-IG7PZYXN.js";import{l as U,n as L,p as F,q as M}from"./chunk-KGQEW2IX.js";import{a as h}from"./chunk-EI7MMDWY.js";import{createServer as rt}from"http";import{stat as z,readFile as E,mkdir as W,writeFile as D,rm as st}from"fs/promises";import{createReadStream as it,existsSync as G}from"fs";import v from"path";import{fileURLToPath as at}from"url";import ct from"crypto";import lt from"os";import B from"yaml";import{runCheck as I,writeBack as K,writeJsonFile as ft,resolveConfigPath as Q,loadSettings as ut,detectCodingEngines as dt,loadWorkflowTemplate as mt,collectEnvRefs as pt,getDefaultAgentEntry as gt,resolveInsideRoot as x,assertPortableId as X}from"aitable-workflow-core";var Z=v.dirname(at(import.meta.url)),ht={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".ico":"image/x-icon"},wt=1800*1e3;function yt(){return process.platform==="darwin"||process.platform==="win32"||process.env.DISPLAY||process.env.WAYLAND_DISPLAY?"local-gui":"remote"}h(yt,"detectEnvironment");function q(){let n=v.join(Z,"web");if(G(v.join(n,"index.html")))return n;let e=v.resolve(Z,"..","..","..","web","dist");return G(v.join(e,"index.html"))?e:null}h(q,"resolveWebRoot");function Jt(){return q()!==null}h(Jt,"hasWebRoot");async function tt(n){let{createServer:e}=await import("net");return new Promise((t,r)=>{let i=e();i.listen(n,()=>{let p=i.address(),o=typeof p=="object"&&p?p.port:n;i.close(()=>t(o))}),i.on("error",()=>{n<8800?tt(n+1).then(t,r):r(new Error("\u65E0\u6CD5\u627E\u5230\u53EF\u7528\u7AEF\u53E3 (8788-8800)"))})})}h(tt,"getAvailablePort");var vt=1024*1024,kt=50*1024*1024;async function $(n,e=vt){return new Promise((t,r)=>{let i=[],p=0;n.on("data",o=>{if(p+=o.length,p>e){n.destroy(),r(new Error("Request body too large"));return}i.push(o)}),n.on("end",()=>{try{t(JSON.parse(Buffer.concat(i).toString("utf8")))}catch{r(new Error("Invalid JSON body"))}}),n.on("error",r)})}h($,"readJson");function R(n,e,t=200){let r=JSON.stringify(e);n.writeHead(t,{"Content-Type":"application/json; charset=utf-8","Content-Length":Buffer.byteLength(r)}),n.end(r)}h(R,"sendJson");function k(n,e,t){R(n,{ok:!1,error:t},e)}h(k,"sendError");function P(n){let e=JSON.parse(JSON.stringify(n));for(let t of e.modules){let r=t.workflows?t.workflows.flatMap(i=>i.items):t.items;for(let i of r)i.sensitive&&i.value!==void 0&&(i.value="***")}return e}h(P,"maskSensitive");function H(n){let e=[];for(let t of n.modules)if(t.workflows)for(let r of t.workflows)e.push(...r.items);else e.push(...t.items);return e}h(H,"collectAllItems");function Tt(n,e){for(let t of n){let r=H(e).find(i=>{if(!i.writeTarget)return!1;let p=i.writeTarget,o=t.writeTarget;return p.type!==o.type?!1:p.type==="yaml"&&o.type==="yaml"?p.file===o.file&&JSON.stringify(p.yamlPath)===JSON.stringify(o.yamlPath):!1});if(r&&M(r)&&t.value.trim().length>0)return t.value.trim()}return null}h(Tt,"findSavedBaseId");async function Ut(n){let e=await tt(8788),t=yt(),r=ct.randomUUID(),i=t==="remote"?"0.0.0.0":"127.0.0.1",p=q();if(!p)throw new Error("Web \u8D44\u6E90\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u542F\u52A8\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");let o=await Q(n.configPath),d=v.dirname(o),l=null,m=new Promise(w=>l=w),f=null,c=h(()=>{f&&clearTimeout(f),f=setTimeout(()=>{console.log(`
2
+ \u2139 \u914D\u7F6E\u754C\u9762\u8D85\u8FC7 30 \u5206\u949F\u65E0\u6D3B\u52A8\uFF0C\u5DF2\u81EA\u52A8\u5173\u95ED\u3002`),l?.()},wt)},"resetTimeout"),a=rt(async(w,s)=>{let u=new URL(w.url??"/",`http://${w.headers.host??"localhost"}`),T=w.headers.origin;if(T){let _=`http://127.0.0.1:${e}`;(T===_||t==="remote")&&s.setHeader("Access-Control-Allow-Origin",T)}if(s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),w.method==="OPTIONS"){s.writeHead(204),s.end();return}if(u.pathname.startsWith("/dev/")){if((u.searchParams.get("token")??w.headers.authorization?.replace("Bearer ",""))!==r){k(s,401,"Unauthorized");return}c();try{await St(u,w,s,n.configPath,d,l)}catch(b){let A=b instanceof Error?b.message:String(b);k(s,500,A)}return}bt(u,s,p)});await new Promise(w=>a.listen(e,i,w)),c();let g=t==="local-gui"?`http://127.0.0.1:${e}/setup?token=${r}`:`http://${lt.hostname()}:${e}/setup?token=${r}`;t==="local-gui"?(Y(g),console.log(`\u2139 \u6D4F\u89C8\u5668\u5DF2\u6253\u5F00: ${g}`)):(console.log("\u2139 \u914D\u7F6E\u754C\u9762\u5DF2\u542F\u52A8\uFF0C\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00:"),console.log(` ${g}`),console.log(`
3
+ \u5982\u679C\u65E0\u6CD5\u76F4\u63A5\u8BBF\u95EE\uFF0C\u53EF\u901A\u8FC7 SSH \u7AEF\u53E3\u8F6C\u53D1:
4
+ ssh -L ${e}:127.0.0.1:${e} <your-host>`),console.log(` \u7136\u540E\u6253\u5F00: http://127.0.0.1:${e}/setup?token=${r}`)),console.log(`
5
+ \uFF08\u7B49\u5F85\u914D\u7F6E\u5B8C\u6210\u540E\u81EA\u52A8\u7EE7\u7EED setup \u6D41\u7A0B\uFF09`),console.log(` \uFF08\u6309 Ctrl+C \u9000\u51FA | --no-ui \u56DE\u9000\u547D\u4EE4\u884C\u4EA4\u4E92\uFF09
6
+ `),await m,f&&clearTimeout(f),a.close()}h(Ut,"runConfigUI");async function St(n,e,t,r,i,p){if(e.method==="GET"&&n.pathname==="/dev/config/check"){let o=await I({configPath:r});R(t,P(o));return}if(e.method==="GET"&&n.pathname==="/dev/config/enriched"){let o=await I({configPath:r}),d=dt(),l=await ut(r),m={},f={},c=new Set,a=/\$\{env\.([A-Za-z_][A-Za-z0-9_]*)(\?)?\}/g;try{let s=await Q(r),u=await E(s,"utf8");for(let T of pt([u]))c.add(T)}catch{}try{let s=await E(v.join(i,"profile","profile.yml"),"utf8"),u=B.parse(s),T=u?.workflows;if(T&&typeof T=="object"&&(f=T),u&&typeof u=="object"){let{workflows:_,...b}=u;for(let A of JSON.stringify(b).matchAll(a))c.add(A[1])}}catch{}for(let s of l.workflowEntries)try{let u=await mt(s.templatePath),T=u.steps.map(y=>({id:y.id,name:y.name,recipe:y.recipe,engine:y.engine,auto:y.auto})),_=u.edges.filter(y=>y.from!=="__start__"&&y.to!=="__end__").map(y=>({from:y.from,to:y.to,condition:y.condition})),b={},A=new Set,C;try{C=B.parse(await E(s.templatePath,"utf8"))}catch{}if(C){for(let S of JSON.stringify(C).matchAll(a))A.add(S[1]);let y=f[s.id];if(y&&typeof y=="object")for(let S of JSON.stringify(y).matchAll(a))A.add(S[1]);let et=Array.isArray(C.steps)?C.steps:[];for(let S=0;S<u.steps.length;S++){let j=u.steps[S],O=et[S];if(O){let N=JSON.stringify(O),J=new Set;for(let nt of N.matchAll(a))J.add(nt[1]);J.size>0&&(b[j.id]=[...J])}}let ot=Array.isArray(C.event_sources)?C.event_sources:[];for(let S of ot)if(S){let j=JSON.stringify(S),O=new Set;for(let N of j.matchAll(a))O.add(N[1]);O.size>0&&(b.__event_sources__=[...b.__event_sources__??[],...O])}}m[s.id]={steps:T,edges:_,stepEnvRefs:b,envRefs:[...A].sort()}}catch{m[s.id]={steps:[],edges:[],stepEnvRefs:{},envRefs:[]}}let g=new Set;for(let s of Object.values(m))for(let u of s.envRefs??[])g.add(u);let w=o.modules.find(s=>s.id==="env");for(let s of w?.items??[])s.writeTarget?.type==="env"&&!g.has(s.key)&&c.add(s.key);R(t,{config:P(o),engines:{available:d.available.map(s=>({engine:s.engine,cmd:s.cmd,version:s.version})),recommended:d.recommendedEngine},workflowTopology:m,projectEnvRefs:[...c].sort()});return}if(e.method==="POST"&&n.pathname==="/dev/config/save"){let o=await $(e);if(!Array.isArray(o.updates)){k(t,400,"updates must be an array");return}for(let c of o.updates){let a=[];if(c.writeTarget.type==="yamlAll")for(let g of c.writeTarget.targets)a.push(g.file);else a.push(c.writeTarget.file);for(let g of a)try{x(i,g,{allowRoot:!1})}catch{k(t,403,`\u8DEF\u5F84\u8D8A\u754C: ${g}`);return}}let d=0;for(let c of o.updates)await K(c.writeTarget,c.value,i),d++;let l=await I({configPath:r}),m=Tt(o.updates,l);if(m){let c=0;for(let a of H(l))a.writeTarget&&(a.status==="error"||a.status==="warn")&&M(a)&&F(a)==="baseId"&&(!a.value||typeof a.value=="string"&&!a.value.trim())&&(await K(a.writeTarget,m,i),c++);c>0&&(l=await I({configPath:r}),d+=c)}let f=0;for(let c of H(l))if(c.key==="coding_agent.config.enabled"&&c.status==="error"&&c.writeTarget?.type==="json"){let a=c.writeTarget.jsonPath[1];if(!a)continue;let g=gt(a),w=v.resolve(i,"coding-agents.config.json");for(let[s,u]of Object.entries(g))(typeof u=="string"||typeof u=="boolean")&&await ft(w,["agents",a,s],u);f++}f>0&&(l=await I({configPath:r}),d+=f),R(t,{ok:!0,written:d,recheck:P(l)});return}if(e.method==="POST"&&n.pathname==="/dev/kb/ingest"){let o=await $(e);if(!o.roleId||!o.source){k(t,400,"roleId and source are required");return}try{X(o.roleId,{label:"roleId"})}catch(c){k(t,400,c instanceof Error?c.message:"roleId \u4E0D\u5408\u6CD5");return}let d=v.resolve(i,"roles",`${o.roleId}.role.yml`),l=await L(d,o.roleId),m=await U({source:o.source,collectionName:l,configDir:i}),f=await I({configPath:r});R(t,{ok:m.success,message:m.message,recheck:P(f)});return}if(e.method==="POST"&&n.pathname==="/dev/kb/upload"){let o=await $(e,kt);if(!o.roleId||!Array.isArray(o.files)||o.files.length===0){k(t,400,"roleId and files are required");return}try{X(o.roleId,{label:"roleId"})}catch(f){k(t,400,f instanceof Error?f.message:"roleId \u4E0D\u5408\u6CD5");return}let d=v.resolve(i,"roles",`${o.roleId}.role.yml`),l=await L(d,o.roleId),m=v.resolve(i,".kb-upload-tmp",`upload-${Date.now()}`);try{await W(m,{recursive:!0});for(let a of o.files){let g;try{g=x(m,a.relativePath,{allowRoot:!1})}catch{k(t,400,`\u4E0A\u4F20\u6587\u4EF6\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${a.relativePath}`);return}let w=v.dirname(g);await W(w,{recursive:!0});let s=a.encoding==="base64"?Buffer.from(a.content,"base64"):Buffer.from(a.content,"utf8");await D(g,s)}let f=await U({source:m,collectionName:l,configDir:i}),c=await I({configPath:r});R(t,{ok:f.success,message:f.message,recheck:P(c)})}finally{await st(m,{recursive:!0,force:!0}).catch(()=>{})}return}if(e.method==="GET"&&n.pathname==="/dev/file/read"){let o=n.searchParams.get("path")??"",d=V(o,i);if(!d){k(t,403,`\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${o}`);return}try{let l=await E(d,"utf8");R(t,{ok:!0,path:o,content:l,exists:!0})}catch{R(t,{ok:!0,path:o,content:"",exists:!1})}return}if(e.method==="POST"&&n.pathname==="/dev/file/write"){let o=await $(e),d=typeof o.path=="string"?o.path:"",l=V(d,i);if(!l||typeof o.content!="string"){k(t,403,`\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${d}`);return}let m=Rt(d,o.content);if(m){R(t,{ok:!1,error:m},400);return}await W(v.dirname(l),{recursive:!0}),await D(l,o.content.endsWith(`
7
+ `)?o.content:o.content+`
8
+ `,"utf8");let f=await I({configPath:r});R(t,{ok:!0,recheck:P(f)});return}if(e.method==="POST"&&n.pathname==="/dev/setup/complete"){R(t,{ok:!0}),p?.();return}k(t,404,"Unknown endpoint")}h(St,"handleDevApi");function V(n,e){let t=n.trim();if(!t||!/\.(ya?ml|json)$/i.test(t))return null;try{return x(e,t,{allowRoot:!1})}catch{return null}}h(V,"resolveInsideConfigDir");function Rt(n,e){try{return/\.json$/i.test(n)?JSON.parse(e):B.parse(e),null}catch(t){return`${/\.json$/i.test(n)?"JSON":"YAML"} \u8BED\u6CD5\u9519\u8BEF\uFF0C\u672A\u4FDD\u5B58: ${t instanceof Error?t.message:String(t)}`}}h(Rt,"validateStructuredText");async function bt(n,e,t){let r;try{let o=decodeURIComponent(n.pathname).replace(/^\/+/,"")||"index.html";r=x(t,o,{allowRoot:!1})}catch{e.writeHead(403),e.end("Forbidden");return}try{(await z(r)).isDirectory()&&(r=v.join(r,"index.html"))}catch{r=v.join(t,"index.html")}try{await z(r)}catch{e.writeHead(404),e.end("Not Found");return}let i=v.extname(r),p=ht[i]??"application/octet-stream";e.writeHead(200,{"Content-Type":p}),it(r).pipe(e)}h(bt,"serveStatic");export{yt as detectEnvironment,Jt as hasWebRoot,q as resolveWebRoot,Ut as runConfigUI};
@@ -1 +1 @@
1
- import{a,b,c,d,e,f,g}from"./chunk-U773UWB7.js";import"./chunk-EI7MMDWY.js";export{a as DAEMON_DATA_DIR,b as daemonDir,d as isProcessAlive,c as pidFilePath,e as readPidFile,g as removePidFile,f as writePidFile};
1
+ import{a,b,c,d,e,f,g}from"./chunk-W3EUICMH.js";import"./chunk-EI7MMDWY.js";export{a as DAEMON_DATA_DIR,b as daemonDir,d as isProcessAlive,c as pidFilePath,e as readPidFile,g as removePidFile,f as writePidFile};