aitable-workflow-cli 0.1.13-beta.1 → 0.1.14-beta.1785831237955

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.
Files changed (2) hide show
  1. package/dist/cli.js +20 -19
  2. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{b as O,d as x,e as V,f as ie,g as M}from"./chunk-U773UWB7.js";import{a as c}from"./chunk-EI7MMDWY.js";import{config as Ee}from"dotenv";import{Command as Y}from"commander";import{createApp as ht,loadSettings as re,loadWorkflowTemplate as Ie,logger as g,activateGlobalDwsOnPath as wt,ensureTsxRegistered as yt,runInit as kt,runDesignCommand as At,runSetupCommand as Rt,runKbCompileCommand as vt,runKbUpdateCommand as bt,runKbStatusCommand as St,runKbIngestCommand as Et,runSync as It,checkWorkflowRecipes as $t,listCodingAgents as Tt,Tracer as xt,saveCredential as _t,listCredentials as se,setActiveAgent as Lt,getActiveCredential as k,readCredentials as Ct,findConflictingCredential as Dt,maskSecret as K}from"aitable-workflow-core";import{startServer as Pt,resolveServeConfig as Ot}from"aitable-workflow-server";import I from"os";import A from"path";import{mkdir as Fe,readFile as Be}from"fs/promises";import{mkdirSync as We}from"fs";import{execSync as Ne}from"child_process";import{logger as f,detectInstalledAgents as Ye,runCodingAgent as Ge,DwsClient as Ke,getActiveCredential as He}from"aitable-workflow-core";import J from"ws";import{logger as b,RELAY_REJECTED_CODE as xe,isRelayMessage as _e}from"aitable-workflow-core";var S="relay:conn",ce=1e3,Le=3e4,Ce=Number(process.env.AITABLE_RELAY_SERVER_STALE_MS??9e4),U=class{static{c(this,"RelayConnection")}ws=null;delay=ce;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 J(n)),this.staleMs=e.staleMs??Ce}connect(){this.permanentlyRejected||(this.should=!0,this.doConnect())}send(e){this.ws&&this.ws.readyState===J.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=ce,this.onAccepted?.(n)),this.lastServerFrameAt=Date.now(),this.armWatchdog();let r;try{r=JSON.parse(typeof o=="string"?o:String(o))}catch{return}_e(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 s=r==null?"":String(r);if(o===xe){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:s}),this.onPermanentReject?.({code:o,reason:s});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!==J.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,Le))}};import{createHash as De}from"crypto";import{readdir as Pe,readFile as Oe,stat as Me}from"fs/promises";import le from"path";import{isAllowedArtifactPath as Ue,normalizeArtifactRelPath as je}from"aitable-workflow-core";var ge={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 de(t){let e=[];return await me(t,t,e),e.sort((n,o)=>n.relPath.localeCompare(o.relPath))}c(de,"scanArtifacts");async function me(t,e,n){let o;try{o=await Pe(e,{withFileTypes:!0})}catch{return}for(let r of o){if(r.name==="node_modules"||r.name.startsWith("."))continue;let s=le.join(e,r.name);if(r.isDirectory())await me(t,s,n);else if(r.isFile()){let a=le.relative(t,s).replace(/\\/g,"/");if(!Ue(a))continue;let i=await Me(s),l=await Oe(s),m=De("sha256").update(l).digest("hex");n.push({relPath:je(a),absPath:s,size:i.size,sha256:m})}}}c(me,"walk");var u="relay:daemon",pe=["aitable"],qe="dws";function Ve(t,e=pe){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(Ve,"validateDwsArgs");function Je(t){try{return Ne(`${t} --version`,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}c(Je,"detectDwsAvailable");var z=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??qe},this.machineId=e.machineId,this.allowedDwsCommands=e.allowedDwsCommands??pe,this.runAgent=n.runAgent??Ge,this.createDwsClient=n.createDwsClient??((r,s)=>new Ke({bin:r,timeoutMs:s})),this.detectAgents=n.detectAgents??(()=>Ye()),this.detectDws=n.detectDws??(r=>Je(r)),this.hostname=n.hostname??(()=>I.hostname()),this.osString=n.osString??(()=>`${I.platform()} ${I.arch()}`),this.onPermanentReject=n.onPermanentReject,this.artifactUploader=n.artifactUploader??ge,this.grantTimeoutMs=n.grantTimeoutMs??3e4,this.maxTasks=Math.max(1,Math.floor(e.maxTasks??1));let o=n.createConnection??(r=>new U(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(){f.info(u,"starting",{serverUrl:this.config.serverUrl,workspaceRoot:this.config.workspaceRoot}),this.config.name||f.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(){f.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();f.info(u,"connected; sending ready",{runtimes:e.runtimes,hasDws:e.hasDws}),this.conn.send(e)}handlePermanentReject(e){f.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,f.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;f.info(u,"run:agent received",{requestId:n,projectId:e.projectId,agent:e.agent});try{let o=this.resolveWorkDir(e.projectId,e.workDir);await Fe(o,{recursive:!0});let r=this.rewritePromptWorkDir(e.prompt,e.workDir,o),s={agent:e.agent,workDir:o,onEvent:c(l=>this.conn.send({type:"event",requestId:n,event:l}),"onEvent")};e.sessionId&&(s.sessionId=e.sessionId),e.permissionMode&&(s.adapterOptions={permissionMode:e.permissionMode}),this.config.agentTimeoutMs!=null&&(s.timeoutMs=this.config.agentTimeoutMs);let a=await this.runAgent(r,s),i;try{i=await this.collectAndUploadArtifacts(n,e.projectId,o)}catch(l){let m=l instanceof Error?l.message:String(l);f.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:a.response,sessionId:a.sessionId,...i?{artifacts:i}:{}}),f.info(u,"run:agent done",{requestId:n,sessionId:a.sessionId,artifacts:i?i.files.length:0})}catch(o){let r=o instanceof Error?o.message:String(o);f.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 de(o);if(r.length===0)return;this.conn.send({type:"upload:request",requestId:e,projectId:n,files:r.map(i=>({path:i.relPath,size:i.size,sha256:i.sha256}))});let s=await this.awaitGrant(e);if(!s)throw new Error("upload:grant \u7B49\u5F85\u8D85\u65F6");if(s.grants.length===0){f.warn(u,"upload:grant \u65E0\u6388\u6743\u9879\uFF08gateway \u672A\u914D\u7F6E store \u6216\u5168\u88AB\u62D2\uFF09",{requestId:e,rejected:(s.rejected??[]).length});return}let a=[];for(let i of s.grants){let l=r.find(h=>h.relPath===i.path);if(!l)continue;let m=await Be(l.absPath);await this.artifactUploader.upload(i.url,m,i.headers),a.push({path:i.path,key:i.key,sha256:l.sha256,size:l.size})}return{store:"oss",files:a}}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=Ve(e.args,this.allowedDwsCommands);if(!o.ok){f.warn(u,"run:dws rejected",{requestId:n,reason:o.reason}),this.conn.send({type:"error",requestId:n,code:"dws_rejected",message:o.reason});return}f.info(u,"run:dws received",{requestId:n,command:e.args[0]});try{let s=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(s)}),f.info(u,"run:dws done",{requestId:n})}catch(r){let s=r instanceof Error?r.message:String(r);f.error(u,"run:dws failed",{requestId:n,error:s}),this.conn.send({type:"error",requestId:n,code:"dws_failed",message:s})}}resolveWorkDir(e,n){if(n&&n.trim()!=="")if(A.isAbsolute(n))f.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 A.resolve(this.config.workspaceRoot,n);return A.join(this.config.workspaceRoot,e)}rewritePromptWorkDir(e,n,o){let r=n?.trim();return!r||!A.isAbsolute(r)||r===o?e:e.split(r).join(o)}};function X(t,e){let n,o=t?.trim();if(o)n=A.isAbsolute(o)?A.resolve(o):A.resolve(I.homedir(),o);else{let r=e?.trim()?e.trim():"default";n=A.join(I.homedir(),".aitable-workflow","workspaces",r)}return We(n,{recursive:!0}),n}c(X,"resolveWorkspaceRoot");function ze(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,s=t.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT,a=t.machineId??e.AITABLE_RELAY_MACHINE_ID,i=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=i??I.hostname()??"default",p={serverUrl:n,workspaceRoot:X(s,w)};if(r?p.token=r:o&&(p.key=o),a&&(p.machineId=a),i&&(p.name=i,p.displayName=i),l&&(p.description=l),m!=null&&m!==""){let T=Math.floor(Number(m));Number.isFinite(T)&&T>=1&&(p.maxTasks=T)}return p}c(ze,"resolveRelayCliConfig");async function _(t,e=process.env){let n=null;try{n=await He()}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 ze(o,e)}c(_,"resolveDaemonConfig");async function Q(t){let e=await _(t),n=new z(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(Q,"runRelayDaemon");import{spawn as Qe}from"child_process";import{existsSync as Ze}from"fs";import C from"path";import{fileURLToPath as et}from"url";import{appendFileSync as yn,statSync as kn,renameSync as An,mkdirSync as Rn,existsSync as vn}from"fs";import Xe from"path";var En=10*1024*1024;function L(t){return Xe.join(O(t),"daemon.log")}c(L,"logFilePath");var j=C.dirname(et(import.meta.url));function tt(){let t=[C.resolve(j,"..","..","bin","aitable-workflow.mjs"),C.resolve(j,"..","bin","aitable-workflow.mjs"),C.resolve(j,"..","..","dist","cli.js"),C.resolve(j,"cli.js")];return t.find(e=>Ze(e))??t[0]}c(tt,"resolveDaemonEntry");var nt=tt();async function F(t){await ie(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(a=>{let i=L(t.agentId);return a.openSync(i,"a")}),o=Qe(process.execPath,[nt,...e],{detached:!0,stdio:["ignore",n,n],env:{...process.env}});try{let{closeSync:a}=await import("fs");a(n)}catch{}o.unref();let{writeFile:r}=await import("fs/promises"),{pidFilePath:s}=await import("./pid-file-HPTFI54H.js");return o.pid&&await r(s(t.agentId),String(o.pid),"utf8"),{pid:o.pid??0}}c(F,"startDaemon");async function B(t,e=5e3){let n=await V(t);if(n===null||!x(n))return await M(t),!1;try{process.kill(n,"SIGTERM")}catch{return await M(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 M(t),!0}c(B,"stopDaemon");async function W(t){let e=await V(t),n=e!==null&&x(e),o=null;if(n&&e!==null)try{let{readFile:r}=await import("fs/promises"),s=await r(`/proc/${e}/stat`,"utf8"),a=parseInt(s.split(" ")[21]??"0",10),i=await r("/proc/uptime","utf8"),h=parseFloat(i.split(" ")[0]??"0")-a/100;o=Math.round(h*1e3)}catch{}return{agentId:t,running:n,pid:n?e:null,uptimeMs:o,logFile:L(t)}}c(W,"getDaemonStatus");import{readFile as ot,writeFile as jn,mkdir as Fn}from"fs/promises";import rt from"path";var fe={connectionState:"disconnected",lastHeartbeatAt:null,machineId:null,serverUrl:"",runningTasks:0,queuedTasks:0,lastDisconnectReason:null,updatedAt:new Date().toISOString()};function st(t){return rt.join(O(t),"state.json")}c(st,"stateFilePath");async function Z(t){try{let e=await ot(st(t),"utf8");return{...fe,...JSON.parse(e)}}catch{return{...fe}}}c(Z,"readState");import{execSync as D}from"child_process";import{writeFile as at,rm as it,mkdir as ct,access as lt}from"fs/promises";import R from"path";import ue from"os";import{readCredentials as gt}from"aitable-workflow-core";var dt="com.alibaba.aitable-workflow.daemon",ee="\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\uFF1Anpm i -g @ali/aitable-workflow";function P(t){return`${dt}.${t}`}c(P,"plistLabel");function te(t){return R.join(ue.homedir(),"Library","LaunchAgents",`${P(t)}.plist`)}c(te,"plistPath");function E(){return process.platform==="darwin"}c(E,"isMacOS");function he(){try{return D("which aitable-workflow",{encoding:"utf8"}).trim()||null}catch{return null}}c(he,"resolveGlobalCliEntry");function we(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} ${ee}`);if(t.includes("/_npx/")||t.includes(`${R.sep}_npx${R.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} ${ee}`);if(!R.isAbsolute(t))throw new Error(`CLI \u5165\u53E3\u4E0D\u662F\u7A33\u5B9A\u7684\u5168\u5C40\u7EDD\u5BF9\u8DEF\u5F84\uFF1A${t}
6
- \u{1F4A1} ${ee}`)}c(we,"assertStableCliEntry");async function mt(t){let e={};e.AITABLE_RELAY_NAME=t;let n;try{let o=await gt();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(mt,"buildRelayEnv");function pt(t,e){let n=P(t),o=e?.cliEntry??he();we(o);let r=["relay"];e?.maxTasks&&r.push("--max-tasks",String(e.maxTasks));let s=R.join(ue.homedir(),".aitable-workflow","daemons",t),a=R.join(s,"launchd.log"),i=R.join(s,"launchd.err.log"),l=[o,...r].map(w=>` <string>${$(w)}</string>`).join(`
2
+ import{b as O,d as x,e as J,f as ie,g as M}from"./chunk-U773UWB7.js";import{a as c}from"./chunk-EI7MMDWY.js";import{config as Ee}from"dotenv";import{Command as Y}from"commander";import{createApp as ht,loadSettings as K,loadWorkflowTemplate as Ie,logger as g,activateGlobalDwsOnPath as wt,createExecShellToolkit as yt,ensureTsxRegistered as kt,runInit as At,runDesignCommand as Rt,runSetupCommand as vt,runKbCompileCommand as bt,runKbUpdateCommand as St,runKbStatusCommand as Et,runKbIngestCommand as It,runSync as $t,checkWorkflowRecipes as Tt,listCodingAgents as xt,Tracer as _t,saveCredential as Lt,listCredentials as se,setActiveAgent as Ct,getActiveCredential as k,readCredentials as Dt,findConflictingCredential as Pt,maskSecret as H}from"aitable-workflow-core";import{startServer as Ot,resolveServeConfig as Mt}from"aitable-workflow-server";import I from"os";import A from"path";import{mkdir as Fe,readFile as Ne}from"fs/promises";import{mkdirSync as Be}from"fs";import{execSync as We}from"child_process";import{logger as f,detectInstalledAgents as Ye,runCodingAgent as Ge,DwsClient as Ke,getActiveCredential as He}from"aitable-workflow-core";import z from"ws";import{logger as b,RELAY_REJECTED_CODE as xe,isRelayMessage as _e}from"aitable-workflow-core";var S="relay:conn",ce=1e3,Le=3e4,Ce=Number(process.env.AITABLE_RELAY_SERVER_STALE_MS??9e4),U=class{static{c(this,"RelayConnection")}ws=null;delay=ce;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 z(n)),this.staleMs=e.staleMs??Ce}connect(){this.permanentlyRejected||(this.should=!0,this.doConnect())}send(e){this.ws&&this.ws.readyState===z.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=ce,this.onAccepted?.(n)),this.lastServerFrameAt=Date.now(),this.armWatchdog();let r;try{r=JSON.parse(typeof o=="string"?o:String(o))}catch{return}_e(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 s=r==null?"":String(r);if(o===xe){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:s}),this.onPermanentReject?.({code:o,reason:s});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!==z.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,Le))}};import{createHash as De}from"crypto";import{readdir as Pe,readFile as Oe,stat as Me}from"fs/promises";import le from"path";import{isAllowedArtifactPath as Ue,normalizeArtifactRelPath as je}from"aitable-workflow-core";var ge={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 de(t){let e=[];return await me(t,t,e),e.sort((n,o)=>n.relPath.localeCompare(o.relPath))}c(de,"scanArtifacts");async function me(t,e,n){let o;try{o=await Pe(e,{withFileTypes:!0})}catch{return}for(let r of o){if(r.name==="node_modules"||r.name.startsWith("."))continue;let s=le.join(e,r.name);if(r.isDirectory())await me(t,s,n);else if(r.isFile()){let a=le.relative(t,s).replace(/\\/g,"/");if(!Ue(a))continue;let i=await Me(s),l=await Oe(s),m=De("sha256").update(l).digest("hex");n.push({relPath:je(a),absPath:s,size:i.size,sha256:m})}}}c(me,"walk");var u="relay:daemon",pe=["aitable"],qe="dws";function Ve(t,e=pe){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(Ve,"validateDwsArgs");function Je(t){try{return We(`${t} --version`,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}c(Je,"detectDwsAvailable");var X=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??qe},this.machineId=e.machineId,this.allowedDwsCommands=e.allowedDwsCommands??pe,this.runAgent=n.runAgent??Ge,this.createDwsClient=n.createDwsClient??((r,s)=>new Ke({bin:r,timeoutMs:s})),this.detectAgents=n.detectAgents??(()=>Ye()),this.detectDws=n.detectDws??(r=>Je(r)),this.hostname=n.hostname??(()=>I.hostname()),this.osString=n.osString??(()=>`${I.platform()} ${I.arch()}`),this.onPermanentReject=n.onPermanentReject,this.artifactUploader=n.artifactUploader??ge,this.grantTimeoutMs=n.grantTimeoutMs??3e4,this.maxTasks=Math.max(1,Math.floor(e.maxTasks??1));let o=n.createConnection??(r=>new U(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(){f.info(u,"starting",{serverUrl:this.config.serverUrl,workspaceRoot:this.config.workspaceRoot}),this.config.name||f.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(){f.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();f.info(u,"connected; sending ready",{runtimes:e.runtimes,hasDws:e.hasDws}),this.conn.send(e)}handlePermanentReject(e){f.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,f.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;f.info(u,"run:agent received",{requestId:n,projectId:e.projectId,agent:e.agent});try{let o=this.resolveWorkDir(e.projectId,e.workDir);await Fe(o,{recursive:!0});let r=this.rewritePromptWorkDir(e.prompt,e.workDir,o),s={agent:e.agent,workDir:o,onEvent:c(l=>this.conn.send({type:"event",requestId:n,event:l}),"onEvent")};e.sessionId&&(s.sessionId=e.sessionId),e.permissionMode&&(s.adapterOptions={permissionMode:e.permissionMode}),this.config.agentTimeoutMs!=null&&(s.timeoutMs=this.config.agentTimeoutMs);let a=await this.runAgent(r,s),i;try{i=await this.collectAndUploadArtifacts(n,e.projectId,o)}catch(l){let m=l instanceof Error?l.message:String(l);f.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:a.response,sessionId:a.sessionId,...i?{artifacts:i}:{}}),f.info(u,"run:agent done",{requestId:n,sessionId:a.sessionId,artifacts:i?i.files.length:0})}catch(o){let r=o instanceof Error?o.message:String(o);f.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 de(o);if(r.length===0)return;this.conn.send({type:"upload:request",requestId:e,projectId:n,files:r.map(i=>({path:i.relPath,size:i.size,sha256:i.sha256}))});let s=await this.awaitGrant(e);if(!s)throw new Error("upload:grant \u7B49\u5F85\u8D85\u65F6");if(s.grants.length===0){f.warn(u,"upload:grant \u65E0\u6388\u6743\u9879\uFF08gateway \u672A\u914D\u7F6E store \u6216\u5168\u88AB\u62D2\uFF09",{requestId:e,rejected:(s.rejected??[]).length});return}let a=[];for(let i of s.grants){let l=r.find(h=>h.relPath===i.path);if(!l)continue;let m=await Ne(l.absPath);await this.artifactUploader.upload(i.url,m,i.headers),a.push({path:i.path,key:i.key,sha256:l.sha256,size:l.size})}return{store:"oss",files:a}}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=Ve(e.args,this.allowedDwsCommands);if(!o.ok){f.warn(u,"run:dws rejected",{requestId:n,reason:o.reason}),this.conn.send({type:"error",requestId:n,code:"dws_rejected",message:o.reason});return}f.info(u,"run:dws received",{requestId:n,command:e.args[0]});try{let s=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(s)}),f.info(u,"run:dws done",{requestId:n})}catch(r){let s=r instanceof Error?r.message:String(r);f.error(u,"run:dws failed",{requestId:n,error:s}),this.conn.send({type:"error",requestId:n,code:"dws_failed",message:s})}}resolveWorkDir(e,n){if(n&&n.trim()!=="")if(A.isAbsolute(n))f.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 A.resolve(this.config.workspaceRoot,n);return A.join(this.config.workspaceRoot,e)}rewritePromptWorkDir(e,n,o){let r=n?.trim();return!r||!A.isAbsolute(r)||r===o?e:e.split(r).join(o)}};function Q(t,e){let n,o=t?.trim();if(o)n=A.isAbsolute(o)?A.resolve(o):A.resolve(I.homedir(),o);else{let r=e?.trim()?e.trim():"default";n=A.join(I.homedir(),".aitable-workflow","workspaces",r)}return Be(n,{recursive:!0}),n}c(Q,"resolveWorkspaceRoot");function ze(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,s=t.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT,a=t.machineId??e.AITABLE_RELAY_MACHINE_ID,i=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=i??I.hostname()??"default",p={serverUrl:n,workspaceRoot:Q(s,w)};if(r?p.token=r:o&&(p.key=o),a&&(p.machineId=a),i&&(p.name=i,p.displayName=i),l&&(p.description=l),m!=null&&m!==""){let T=Math.floor(Number(m));Number.isFinite(T)&&T>=1&&(p.maxTasks=T)}return p}c(ze,"resolveRelayCliConfig");async function _(t,e=process.env){let n=null;try{n=await He()}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 ze(o,e)}c(_,"resolveDaemonConfig");async function Z(t){let e=await _(t),n=new X(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(Z,"runRelayDaemon");import{spawn as Qe}from"child_process";import{existsSync as Ze}from"fs";import C from"path";import{fileURLToPath as et}from"url";import{appendFileSync as kn,statSync as An,renameSync as Rn,mkdirSync as vn,existsSync as bn}from"fs";import Xe from"path";var In=10*1024*1024;function L(t){return Xe.join(O(t),"daemon.log")}c(L,"logFilePath");var j=C.dirname(et(import.meta.url));function tt(){let t=[C.resolve(j,"..","..","bin","aitable-workflow.mjs"),C.resolve(j,"..","bin","aitable-workflow.mjs"),C.resolve(j,"..","..","dist","cli.js"),C.resolve(j,"cli.js")];return t.find(e=>Ze(e))??t[0]}c(tt,"resolveDaemonEntry");var nt=tt();async function F(t){await ie(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(a=>{let i=L(t.agentId);return a.openSync(i,"a")}),o=Qe(process.execPath,[nt,...e],{detached:!0,stdio:["ignore",n,n],env:{...process.env}});try{let{closeSync:a}=await import("fs");a(n)}catch{}o.unref();let{writeFile:r}=await import("fs/promises"),{pidFilePath:s}=await import("./pid-file-HPTFI54H.js");return o.pid&&await r(s(t.agentId),String(o.pid),"utf8"),{pid:o.pid??0}}c(F,"startDaemon");async function N(t,e=5e3){let n=await J(t);if(n===null||!x(n))return await M(t),!1;try{process.kill(n,"SIGTERM")}catch{return await M(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 M(t),!0}c(N,"stopDaemon");async function B(t){let e=await J(t),n=e!==null&&x(e),o=null;if(n&&e!==null)try{let{readFile:r}=await import("fs/promises"),s=await r(`/proc/${e}/stat`,"utf8"),a=parseInt(s.split(" ")[21]??"0",10),i=await r("/proc/uptime","utf8"),h=parseFloat(i.split(" ")[0]??"0")-a/100;o=Math.round(h*1e3)}catch{}return{agentId:t,running:n,pid:n?e:null,uptimeMs:o,logFile:L(t)}}c(B,"getDaemonStatus");import{readFile as ot,writeFile as Fn,mkdir as Nn}from"fs/promises";import rt from"path";var fe={connectionState:"disconnected",lastHeartbeatAt:null,machineId:null,serverUrl:"",runningTasks:0,queuedTasks:0,lastDisconnectReason:null,updatedAt:new Date().toISOString()};function st(t){return rt.join(O(t),"state.json")}c(st,"stateFilePath");async function ee(t){try{let e=await ot(st(t),"utf8");return{...fe,...JSON.parse(e)}}catch{return{...fe}}}c(ee,"readState");import{execSync as D}from"child_process";import{writeFile as at,rm as it,mkdir as ct,access as lt}from"fs/promises";import R from"path";import ue from"os";import{readCredentials as gt}from"aitable-workflow-core";var dt="com.alibaba.aitable-workflow.daemon",te="\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\uFF1Anpm i -g @ali/aitable-workflow";function P(t){return`${dt}.${t}`}c(P,"plistLabel");function ne(t){return R.join(ue.homedir(),"Library","LaunchAgents",`${P(t)}.plist`)}c(ne,"plistPath");function E(){return process.platform==="darwin"}c(E,"isMacOS");function he(){try{return D("which aitable-workflow",{encoding:"utf8"}).trim()||null}catch{return null}}c(he,"resolveGlobalCliEntry");function we(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} ${te}`);if(t.includes("/_npx/")||t.includes(`${R.sep}_npx${R.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} ${te}`);if(!R.isAbsolute(t))throw new Error(`CLI \u5165\u53E3\u4E0D\u662F\u7A33\u5B9A\u7684\u5168\u5C40\u7EDD\u5BF9\u8DEF\u5F84\uFF1A${t}
6
+ \u{1F4A1} ${te}`)}c(we,"assertStableCliEntry");async function mt(t){let e={};e.AITABLE_RELAY_NAME=t;let n;try{let o=await gt();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(mt,"buildRelayEnv");function pt(t,e){let n=P(t),o=e?.cliEntry??he();we(o);let r=["relay"];e?.maxTasks&&r.push("--max-tasks",String(e.maxTasks));let s=R.join(ue.homedir(),".aitable-workflow","daemons",t),a=R.join(s,"launchd.log"),i=R.join(s,"launchd.err.log"),l=[o,...r].map(w=>` <string>${$(w)}</string>`).join(`
7
7
  `),m={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",...e?.relayEnv??{}},h=Object.entries(m).map(([w,p])=>` <key>${$(w)}</key>
8
8
  <string>${$(p)}</string>`).join(`
9
9
  `);return`<?xml version="1.0" encoding="UTF-8"?>
@@ -30,40 +30,41 @@ ${h}
30
30
  <string>${$(i)}</string>
31
31
  </dict>
32
32
  </plist>
33
- `}c(pt,"generatePlist");function $(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}c($,"escapeXml");function N(){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(N,"getUid");async function ye(t,e){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let n=he();we(n);let o=await mt(t),r=te(t),s=P(t);try{D(`launchctl bootout gui/${N()}/${s} 2>/dev/null`,{encoding:"utf8"})}catch{}await ct(R.dirname(r),{recursive:!0});let a=pt(t,{maxTasks:e?.maxTasks,relayEnv:o,cliEntry:n});await at(r,a,"utf8"),D(`launchctl bootstrap gui/${N()} ${r}`,{encoding:"utf8"})}c(ye,"enableAutostart");async function ke(t){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=te(t);try{D(`launchctl bootout gui/${N()}/${e} 2>/dev/null`,{encoding:"utf8"})}catch{}await it(n,{force:!0})}c(ke,"disableAutostart");async function ne(t){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=te(t),o=!1;try{await lt(n),o=!0}catch{o=!1}let r=!1,s=!1,a=null;try{let i=D(`launchctl print gui/${N()}/${e} 2>/dev/null`,{encoding:"utf8"});r=!0;let l=i.match(/pid\s*=\s*(\d+)/);l&&(a=parseInt(l[1],10),s=!0)}catch{r=!1}return{installed:o,loaded:r,running:s,pid:a}}c(ne,"getAutostartStatus");import{createRequire as ft}from"module";var Ae="aitable-workflow-",ut=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function Re(){try{return ft(import.meta.url)("../package.json")}catch{return{}}}c(Re,"loadCliPackageManifest");function oe(t){return t.version??"0.0.0"}c(oe,"resolveCliVersion");function ve(t){let e=oe(t),n={};t.name?.startsWith(Ae)&&(n[t.name]=e);for(let[o,r]of Object.entries(t.dependencies??{}))o.startsWith(Ae)&&(n[o]=ut.test(r)?r:e);return n}c(ve,"resolveMonorepoPackageVersions");import v from"path";import{fileURLToPath as Mt}from"url";import{watchFile as Ut,statSync as jt,openSync as Ft,readSync as Bt,closeSync as Wt,existsSync as be}from"fs";import{readFile as Se}from"fs/promises";import{spawn as Nt}from"child_process";var G=v.dirname(Mt(import.meta.url));Ee({override:!1,quiet:!0});Ee({path:v.resolve(G,"..",".env"),override:!1,quiet:!0});var $e=Re(),Yt=oe($e),Gt=ve($e),y="./aitable-workflow.config.yml";function Kt(){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(Kt,"installLongRunningCrashGuards");function Ht(t){let e=process.platform,n=e==="darwin"?"open":e==="win32"?"cmd":"xdg-open",o=e==="win32"?["/c","start","",t]:[t];try{let r=Nt(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(Ht,"openBrowser");var d=new Y().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(Yt).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 wt()}).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 kt({config:t.config,force:!!t.force,yes:!!t.yes,template:t.template,profile:t.profile,templatesDir:v.resolve(G,"..","templates"),templatePackageVersions:Gt})}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("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",y).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 At(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",y).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("--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(!t.skipConfig){let e=t.ui!==!1,n=!1;if(e){let{hasWebRoot:o,runConfigUI:r}=await import("./config-ui-server-JQMJSJHD.js");if(o()){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");try{await r({configPath:t.config});let{runCheck:s}=await import("aitable-workflow-core");n=(await s({configPath:t.config})).ok}catch(s){console.warn(`
33
+ `}c(pt,"generatePlist");function $(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}c($,"escapeXml");function W(){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(W,"getUid");async function ye(t,e){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let n=he();we(n);let o=await mt(t),r=ne(t),s=P(t);try{D(`launchctl bootout gui/${W()}/${s} 2>/dev/null`,{encoding:"utf8"})}catch{}await ct(R.dirname(r),{recursive:!0});let a=pt(t,{maxTasks:e?.maxTasks,relayEnv:o,cliEntry:n});await at(r,a,"utf8"),D(`launchctl bootstrap gui/${W()} ${r}`,{encoding:"utf8"})}c(ye,"enableAutostart");async function ke(t){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=ne(t);try{D(`launchctl bootout gui/${W()}/${e} 2>/dev/null`,{encoding:"utf8"})}catch{}await it(n,{force:!0})}c(ke,"disableAutostart");async function oe(t){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=ne(t),o=!1;try{await lt(n),o=!0}catch{o=!1}let r=!1,s=!1,a=null;try{let i=D(`launchctl print gui/${W()}/${e} 2>/dev/null`,{encoding:"utf8"});r=!0;let l=i.match(/pid\s*=\s*(\d+)/);l&&(a=parseInt(l[1],10),s=!0)}catch{r=!1}return{installed:o,loaded:r,running:s,pid:a}}c(oe,"getAutostartStatus");import{createRequire as ft}from"module";var Ae="aitable-workflow-",ut=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function Re(){try{return ft(import.meta.url)("../package.json")}catch{return{}}}c(Re,"loadCliPackageManifest");function re(t){return t.version??"0.0.0"}c(re,"resolveCliVersion");function ve(t){let e=re(t),n={};t.name?.startsWith(Ae)&&(n[t.name]=e);for(let[o,r]of Object.entries(t.dependencies??{}))o.startsWith(Ae)&&(n[o]=ut.test(r)?r:e);return n}c(ve,"resolveMonorepoPackageVersions");import v from"path";import{fileURLToPath as Ut}from"url";import{watchFile as jt,statSync as Ft,openSync as Nt,readSync as Bt,closeSync as Wt,existsSync as be}from"fs";import{readFile as Se}from"fs/promises";import{spawn as Yt}from"child_process";var G=v.dirname(Ut(import.meta.url));Ee({override:!1,quiet:!0});Ee({path:v.resolve(G,"..",".env"),override:!1,quiet:!0});var $e=Re(),Gt=re($e),Kt=ve($e),y="./aitable-workflow.config.yml";function Ht(){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(Ht,"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=Yt(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 Y().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(Gt).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 wt()}).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 At({config:t.config,force:!!t.force,yes:!!t.yes,template:t.template,profile:t.profile,templatesDir:v.resolve(G,"..","templates"),templatePackageVersions:Kt})}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("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",y).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 Rt(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",y).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("--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(!t.skipConfig){let e=t.ui!==!1,n=!1;if(e){let{hasWebRoot:o,runConfigUI:r}=await import("./config-ui-server-JQMJSJHD.js");if(o()){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");try{await r({configPath:t.config});let{runCheck:s}=await import("aitable-workflow-core");n=(await s({configPath:t.config})).ok}catch(s){console.warn(`
34
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
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-EPY7IOF2.js");(await o({configPath:t.config,interactive:!0,offerSkipToBuild:!0})).ok||(console.error(`
36
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
37
  \u{1F527} \u6B65\u9AA4 2/2\uFF1A\u521D\u59CB\u5316\u8868\u7ED3\u6784 + \u7F16\u8BD1\u77E5\u8BC6\u5E93
38
- `)}await Rt(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",y).action(async t=>{try{Kt(),await yt();let e=await ht(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",y).action(async t=>{try{let e=await re(t.config);console.log("\u2713 \u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u901A\u8FC7");let n=await Ie(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(`
38
+ `)}await vt(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",y).action(async t=>{try{Ht(),await kt();let e=await ht(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",y).action(async t=>{try{let e=await K(t.config);console.log("\u2713 \u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u901A\u8FC7");let n=await Ie(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
39
  \u6B65\u9AA4\u94FE:`);for(let[o,r]of n.orderedStepIds.entries()){let s=n.steps.find(i=>i.id===r),a=o<n.orderedStepIds.length-1?" \u2192":" \u2713";console.log(` ${o+1}. [${r}] ${s?.name??"?"}${a}`)}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("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",y).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-EPY7IOF2.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",y).option("-y, --yes","\u975E\u4EA4\u4E92\u6A21\u5F0F").action(async t=>{try{await It({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=Tt();if(t.json){process.stdout.write(JSON.stringify(e,null,2)+`
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",y).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),s=yt(r,n),a=e.timeout?Number.parseInt(e.timeout,10):void 0;if(e.json){let l=await s.runJson(n,o,{timeoutMs:a});console.log(JSON.stringify(l,null,2));return}let i=await s.run(n,o,{timeoutMs:a});i.stdout&&process.stdout.write(i.stdout),i.stderr&&process.stderr.write(i.stderr),i.truncated&&console.error(`
41
+ \u26A0\uFE0F \u8F93\u51FA\u56E0\u8D85\u8FC7\u4E0A\u9650\u88AB\u622A\u65AD`),process.exit(i.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",y).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-EPY7IOF2.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",y).option("-y, --yes","\u975E\u4EA4\u4E92\u6A21\u5F0F").action(async t=>{try{await $t({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=xt();if(t.json){process.stdout.write(JSON.stringify(e,null,2)+`
41
42
  `);return}let n=e.filter(o=>o.installed).length;console.log(`
42
43
  \u652F\u6301 ${e.length} \u4E2A Coding Agent\uFF0C\u672C\u673A\u5DF2\u63A2\u6D4B\u5230 ${n} \u4E2A\uFF1A
43
- `);for(let o of e){let r=o.installed?"\u2713":"\u2717",s=[o.bin,...o.fallbackBins].join(" / "),a=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: ${s.padEnd(24)} ${a}`)}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=v.join(G,"web");if(be(v.join(o,"index.html")))e.webRoot=o;else{let r=v.resolve(G,"..","..","web","dist");be(v.join(r,"index.html"))&&(e.webRoot=r)}}let n=Ot(e);if(await Pt(n),n.webRoot&&t.open!==!1){let o=n.host==="0.0.0.0"?"127.0.0.1":n.host;Ht(`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 k();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 _({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:e,maxTasks:t.maxTasks}),o=await F({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 se(),n=0;for(let o of e)await B(o.name)&&n++;console.log(`\u2705 \u5DF2\u505C\u6B62 ${n} \u4E2A daemon`)}else{let e=t.agent;if(!e){let o=await k();if(!o)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=o.name}let n=await B(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 k();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 B(e);let n=await _({name:e,maxTasks:t.maxTasks}),o=await F({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 k();if(!r){console.log("\u65E0\u6D3B\u8DC3 Agent");return}e=r.name}let n=await W(e),o=await k();if(console.log(`
44
+ `);for(let o of e){let r=o.installed?"\u2713":"\u2717",s=[o.bin,...o.fallbackBins].join(" / "),a=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: ${s.padEnd(24)} ${a}`)}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=v.join(G,"web");if(be(v.join(o,"index.html")))e.webRoot=o;else{let r=v.resolve(G,"..","..","web","dist");be(v.join(r,"index.html"))&&(e.webRoot=r)}}let n=Mt(e);if(await Ot(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 k();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 _({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:e,maxTasks:t.maxTasks}),o=await F({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 se(),n=0;for(let o of e)await N(o.name)&&n++;console.log(`\u2705 \u5DF2\u505C\u6B62 ${n} \u4E2A daemon`)}else{let e=t.agent;if(!e){let o=await k();if(!o)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=o.name}let n=await N(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 k();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 N(e);let n=await _({name:e,maxTasks:t.maxTasks}),o=await F({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 k();if(!r){console.log("\u65E0\u6D3B\u8DC3 Agent");return}e=r.name}let n=await B(e),o=await k();if(console.log(`
44
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),s=Math.floor(r/60),a=Math.floor(s/60);console.log(`Uptime: ${a}h ${s%60}m ${r%60}s`)}console.log(`Log file: ${n.logFile}`),t.verbose&&o&&(console.log(`
45
- --- Configuration ---`),console.log(`Server: ${o.serverUrl}`),console.log(`Token: ${K(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 k();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=r.name}let n=L(e),o=parseInt(t.n,10)||50;if(t.follow){let r=await Se(n,"utf8").catch(()=>"");if(r){let a=r.trimEnd().split(`
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 k();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=r.name}let n=L(e),o=parseInt(t.n,10)||50;if(t.follow){let r=await Se(n,"utf8").catch(()=>"");if(r){let a=r.trimEnd().split(`
46
47
  `);console.log(a.slice(-o).join(`
47
- `))}let s=r.length;Ut(n,{interval:500},()=>{try{let a=jt(n);if(a.size>s){let i=Ft(n,"r"),l=Buffer.alloc(a.size-s);Bt(i,l,0,l.length,s),Wt(i),process.stdout.write(l.toString("utf8")),s=a.size}}catch{}})}else{let r=await Se(n,"utf8").catch(()=>"");if(!r){console.log(`\u6682\u65E0\u65E5\u5FD7 (${n})`);return}let s=r.trimEnd().split(`
48
+ `))}let s=r.length;jt(n,{interval:500},()=>{try{let a=Ft(n);if(a.size>s){let i=Nt(n,"r"),l=Buffer.alloc(a.size-s);Bt(i,l,0,l.length,s),Wt(i),process.stdout.write(l.toString("utf8")),s=a.size}}catch{}})}else{let r=await Se(n,"utf8").catch(()=>"");if(!r){console.log(`\u6682\u65E0\u65E5\u5FD7 (${n})`);return}let s=r.trimEnd().split(`
48
49
  `);console.log(s.slice(-o).join(`
49
- `))}}catch(e){g.error("cli","logs \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});var qt=d.command("daemon").description("Daemon \u540E\u53F0\u5B88\u62A4\u7BA1\u7406");qt.command("autostart").description("macOS \u5F00\u673A\u81EA\u542F\u7BA1\u7406").addCommand(new Y("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 ye(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 Y("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 ke(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 Y("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 ne(t.agentId);console.log(`
50
- 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 se();if(e.length===0){console.log("\u65E0\u5DF2\u6CE8\u518C\u7684 Agent");return}for(let n of e){let o=await ne(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 a=await Dt(t.name,t.serverUrl);a&&(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: ${a.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?X(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 _t(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"}: ${K(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(`
50
+ `))}}catch(e){g.error("cli","logs \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});var Vt=d.command("daemon").description("Daemon \u540E\u53F0\u5B88\u62A4\u7BA1\u7406");Vt.command("autostart").description("macOS \u5F00\u673A\u81EA\u542F\u7BA1\u7406").addCommand(new Y("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 ye(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 Y("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 ke(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 Y("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 oe(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 se();if(e.length===0){console.log("\u65E0\u5DF2\u6CE8\u518C\u7684 Agent");return}for(let n of e){let o=await oe(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 a=await Pt(t.name,t.serverUrl);a&&(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: ${a.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?Q(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 Lt(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
52
  \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(`
52
53
  \u{1F4A1} \u542F\u52A8 daemon: aitable-workflow start \u6216 aitable-workflow relay`);return}if(t.foreground){console.log(`
53
- \u{1F680} \u524D\u53F0\u542F\u52A8 relay\uFF08Ctrl-C \u9000\u51FA\uFF09...`),await Q({serverUrl:t.serverUrl,token:t.token,key:t.key,name:t.name,workspaceRoot:e});return}let o=t.name,r=await _({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:o}),s=await F({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(`
54
+ \u{1F680} \u524D\u53F0\u542F\u52A8 relay\uFF08Ctrl-C \u9000\u51FA\uFF09...`),await Z({serverUrl:t.serverUrl,token:t.token,key:t.key,name:t.name,workspaceRoot:e});return}let o=t.name,r=await _({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:o}),s=await F({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(`
54
55
  \u{1F680} Daemon \u5DF2\u540E\u53F0\u542F\u52A8`),console.log(` Agent: ${o}`),console.log(` PID: ${s.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${o}/daemon.log`),console.log(`
55
- \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 H=d.command("agent").description("Agent \u51ED\u8BC1\u7BA1\u7406");H.command("list").description("\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684 Agent \u51ED\u8BC1").action(async()=>{try{let t=await se();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 Ct();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 se();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 Dt();console.log(`
56
57
  \u5DF2\u4FDD\u5B58 ${t.length} \u4E2A Agent\uFF08\u6D3B\u8DC3: ${e.activeAgent??"\u65E0"}\uFF09:
57
- `);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: ${K(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)}});H.command("use <name>").description("\u5207\u6362\u6D3B\u8DC3 Agent").action(async t=>{try{let e=await Lt(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)}});H.command("whoami").description("\u663E\u793A\u5F53\u524D\u6D3B\u8DC3 Agent").action(async()=>{try{let t=await k();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: ${K(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)}});H.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 k();if(!e){console.log("\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let n=await W(e.name),o=await Z(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)+`
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 Ct(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 k();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 k();if(!e){console.log("\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let n=await B(e.name),o=await ee(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)+`
58
59
  `);return}let s=r.connectionState==="connected"?"\u{1F7E2}":r.connectionState==="reconnecting"?"\u{1F7E1}":"\u{1F534}";console.log(`
59
- ${s} 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 k();if(!t)throw new Error("\u65E0\u6D3B\u8DC3 Agent");if(!(await W(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 Z(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{Q(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",y).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 Vt(e);return}let n=await re(e.config),o=v.resolve(n.configDir,n.agent.trace_dir),r=new xt(o),s=parseInt(e.limit,10)||10,a;if(e.latest||!t){if(a=await r.getLatestTraces(s),a.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(`
60
+ ${s} 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 k();if(!t)throw new Error("\u65E0\u6D3B\u8DC3 Agent");if(!(await B(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 ee(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{Z(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",y).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 Jt(e);return}let n=await K(e.config),o=v.resolve(n.configDir,n.agent.trace_dir),r=new _t(o),s=parseInt(e.limit,10)||10,a;if(e.latest||!t){if(a=await r.getLatestTraces(s),a.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(`
60
61
  \u{1F4C4} \u6700\u8FD1 ${a.length} \u6761\u6267\u884C\u8BB0\u5F55:
61
62
  `)}else{if(a=await r.getTraces(t),a.length===0){console.log(`\u26A0\uFE0F \u672A\u627E\u5230\u5DE5\u5355 ${t} \u7684 trace \u8BB0\u5F55\u3002`);return}e.step&&(a=a.filter(i=>i.step_id===e.step)),console.log(`
62
63
  \u{1F4C4} \u5DE5\u5355 ${t} \u7684\u6267\u884C\u5386\u53F2 (${a.length} \u6B65):
63
- `)}for(let i of a){let l=i.status==="success"?"\u2705":i.status==="failed"?"\u274C":"\u23F8\uFE0F",m=(i.duration_ms/1e3).toFixed(1);console.log(`${l} [${i.step_id}] ${i.step_name} \u2014 ${m}s \u2014 ${i.status.toUpperCase()}`);for(let[h,w]of i.llm_calls.entries()){let p=h===i.llm_calls.length-1,T=p?" \u2514\u2500":" \u251C\u2500",ae=p?" ":" \u2502 ",Te=(w.duration_ms/1e3).toFixed(1);console.log(`${T} LLM: ${w.model} (${Te}s)`),console.log(`${ae}Input: ${w.prompt_summary.slice(0,80)}${w.prompt_summary.length>80?"...":""}`),console.log(`${ae}Output: ${w.response_summary.slice(0,100)}${w.response_summary.length>100?"...":""}`)}if(Object.keys(i.outputs).length>0){let h=Object.entries(i.outputs).map(([w,p])=>`${w}=${typeof p=="string"?p.slice(0,50):JSON.stringify(p)}`).join(", ");console.log(` \u2514\u2500 Outputs: ${h}`)}i.error&&console.log(` \u2514\u2500 Error: ${i.error}`),console.log()}}catch(n){console.error(`\u2717 inspect \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});var q=d.command("kb").description("\u77E5\u8BC6\u5E93(LLM-Wiki)\u7F16\u8BD1\u4E0E\u72B6\u6001\u7BA1\u7406");q.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",y).option("--full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1").action(async(t,e)=>{try{await vt(t,e)}catch(n){console.error(`\u2717 kb compile \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});q.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",y).action(async(t,e)=>{try{await bt(t,e)}catch(n){console.error(`\u2717 kb update \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});q.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",y).action(async(t,e)=>{try{await St(t,e)}catch(n){console.error(`\u2717 kb status \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});q.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",y).option("--timeout <ms>","\u5355\u6587\u6863\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").action(async(t,e)=>{try{await Et(t,e)}catch(n){console.error(`\u2717 kb ingest \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});async function Vt(t){let e=await re(t.config),n=t.workflow?e.workflowEntries.find(a=>a.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(a=>a.id).join(", ")}`),process.exit(1));let o=await Ie(n.templatePath,{envSource:e.envSource}),{issues:r,rows:s}=await $t(n.recipeDir,o);if(t.recipes){console.log(`
64
+ `)}for(let i of a){let l=i.status==="success"?"\u2705":i.status==="failed"?"\u274C":"\u23F8\uFE0F",m=(i.duration_ms/1e3).toFixed(1);console.log(`${l} [${i.step_id}] ${i.step_name} \u2014 ${m}s \u2014 ${i.status.toUpperCase()}`);for(let[h,w]of i.llm_calls.entries()){let p=h===i.llm_calls.length-1,T=p?" \u2514\u2500":" \u251C\u2500",ae=p?" ":" \u2502 ",Te=(w.duration_ms/1e3).toFixed(1);console.log(`${T} LLM: ${w.model} (${Te}s)`),console.log(`${ae}Input: ${w.prompt_summary.slice(0,80)}${w.prompt_summary.length>80?"...":""}`),console.log(`${ae}Output: ${w.response_summary.slice(0,100)}${w.response_summary.length>100?"...":""}`)}if(Object.keys(i.outputs).length>0){let h=Object.entries(i.outputs).map(([w,p])=>`${w}=${typeof p=="string"?p.slice(0,50):JSON.stringify(p)}`).join(", ");console.log(` \u2514\u2500 Outputs: ${h}`)}i.error&&console.log(` \u2514\u2500 Error: ${i.error}`),console.log()}}catch(n){console.error(`\u2717 inspect \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});var V=d.command("kb").description("\u77E5\u8BC6\u5E93(LLM-Wiki)\u7F16\u8BD1\u4E0E\u72B6\u6001\u7BA1\u7406");V.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",y).option("--full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1").action(async(t,e)=>{try{await bt(t,e)}catch(n){console.error(`\u2717 kb compile \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});V.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",y).action(async(t,e)=>{try{await St(t,e)}catch(n){console.error(`\u2717 kb update \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});V.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",y).action(async(t,e)=>{try{await Et(t,e)}catch(n){console.error(`\u2717 kb status \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});V.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",y).option("--timeout <ms>","\u5355\u6587\u6863\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").action(async(t,e)=>{try{await It(t,e)}catch(n){console.error(`\u2717 kb ingest \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});async function Jt(t){let e=await K(t.config),n=t.workflow?e.workflowEntries.find(a=>a.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(a=>a.id).join(", ")}`),process.exit(1));let o=await Ie(n.templatePath,{envSource:e.envSource}),{issues:r,rows:s}=await Tt(n.recipeDir,o);if(t.recipes){console.log(`
64
65
  \u{1F4CB} \u5DE5\u4F5C\u6D41\u300C${o.meta.name}\u300D(${n.id}) \u7684 recipe schema:
65
66
  `);for(let a of s){let i=a.configSummary.length>0?a.configSummary.join(", "):"(none)",l=a.loaded?"":" \u26A0 \u52A0\u8F7D\u5931\u8D25";console.log(` [${a.stepId} \u2192 ${a.recipeId}]${l}`),console.log(` config: ${i}`),console.log()}}if(t.validate)if(r.length===0)console.log(`
66
67
  \u2705 \u5DE5\u4F5C\u6D41\u300C${o.meta.name}\u300D(${n.id}) \u5168\u90E8\u6B65\u9AA4\u6821\u9A8C\u901A\u8FC7
67
68
  `);else{let a=r.filter(l=>l.level==="error"),i=r.filter(l=>l.level==="warn");console.log(`
68
69
  \u6821\u9A8C\u7ED3\u679C\uFF1A${a.length} \u4E2A\u9519\u8BEF\uFF0C${i.length} \u4E2A\u8B66\u544A
69
- `);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(),a.length>0&&process.exit(1)}}c(Vt,"runRecipeInspect");await d.parseAsync();
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(),a.length>0&&process.exit(1)}}c(Jt,"runRecipeInspect");await d.parseAsync();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aitable-workflow-cli",
3
- "version": "0.1.13-beta.1",
3
+ "version": "0.1.14-beta.1785831237955",
4
4
  "description": "aitable-workflow 命令行工具(cli):init/design/setup/run/serve 等命令;含 relay 本地反连客户端与 daemon 进程管理。bin: aitable-workflow。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,8 +19,8 @@
19
19
  "access": "public"
20
20
  },
21
21
  "dependencies": {
22
- "aitable-workflow-core": "0.1.13-beta.1",
23
- "aitable-workflow-server": "0.1.13-beta.1",
22
+ "aitable-workflow-core": "0.1.14-beta.1785831237955",
23
+ "aitable-workflow-server": "0.1.14-beta.1785831237955",
24
24
  "@inquirer/prompts": "^8.5.2",
25
25
  "commander": "^14.0.2",
26
26
  "dotenv": "^17.4.2",