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

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.
@@ -0,0 +1 @@
1
+ import{a as r}from"./chunk-EI7MMDWY.js";import{spawnManagedProcess as a}from"aitable-workflow-core";function d(n){let o=i(n);try{let e=a({...o,stdio:"ignore",detached:!0});e.child.once("error",()=>t(n)),e.unref()}catch{t(n)}}r(d,"openExternalUrl");function i(n,o=process.platform){return o==="darwin"?{command:"open",args:[n]}:o==="win32"?{command:"rundll32.exe",args:["url.dll,FileProtocolHandler",n]}:{command:"xdg-open",args:[n]}}r(i,"openInvocation");function t(n){console.log(`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${n}`)}r(t,"printFallback");export{d as a};
@@ -0,0 +1 @@
1
+ import{a as i}from"./chunk-EI7MMDWY.js";import{readFile as a,writeFile as c,mkdir as l,rm as u}from"fs/promises";import o from"path";import m from"os";import{assertPortableId as p}from"aitable-workflow-core";var f=o.join(m.homedir(),".aitable-workflow","daemons");function s(r){return o.join(f,p(r,{label:"agentId"}))}i(s,"daemonDir");function n(r){return o.join(s(r),"daemon.pid")}i(n,"pidFilePath");function d(r){try{return process.kill(r,0),!0}catch{return!1}}i(d,"isProcessAlive");async function w(r){try{let e=await a(n(r),"utf8"),t=parseInt(e.trim(),10);return Number.isFinite(t)&&t>0?t:null}catch{return null}}i(w,"readPidFile");async function h(r){let e=s(r);await l(e,{recursive:!0});let t=await w(r);if(t!==null&&d(t))throw new Error(`Agent "${r}" \u5DF2\u5728\u8FD0\u884C (PID: ${t})\u3002\u5148\u6267\u884C \`aitable-workflow stop --agent ${r}\` \u518D\u542F\u52A8\u3002`);await c(n(r),String(process.pid),"utf8")}i(h,"writePidFile");async function F(r){try{await u(n(r),{force:!0})}catch{}}i(F,"removePidFile");export{f as a,s as b,n as c,d,w as e,h as f,F as g};
package/dist/cli.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{b as U,d as x,e as z,f as le,g as j}from"./chunk-U773UWB7.js";import{a as c}from"./chunk-EI7MMDWY.js";import{config as xe}from"dotenv";import{Command as G}from"commander";import{createApp as vt,loadSettings as K,loadWorkflowTemplate as Ce,logger as g,activateGlobalDwsOnPath as bt,createExecShellToolkit as St,ensureTsxRegistered as Et,runInit as It,runDesignCommand as $t,runCheck as Ie,runSetupCommand as Tt,runKbCompileCommand as xt,runKbUpdateCommand as Ct,runKbStatusCommand as _t,runKbIngestCommand as Lt,runSync as Dt,checkWorkflowRecipes as Pt,listCodingAgents as Ot,Tracer as Mt,saveCredential as Ut,listCredentials as ae,setActiveAgent as jt,getActiveCredential as A,readCredentials as Nt,findConflictingCredential as Ft,maskSecret as H,runMigrate as Bt,checkMigrateHint as _e}from"aitable-workflow-core";import{startServer as Wt,resolveServeConfig as Vt}from"aitable-workflow-server";import I from"os";import R from"path";import{mkdir as Ge,readFile as Ke}from"fs/promises";import{mkdirSync as He}from"fs";import{execSync as qe}from"child_process";import{logger as p,detectInstalledAgents as Je,runCodingAgent as ze,DwsClient as Xe,getActiveCredential as Qe}from"aitable-workflow-core";import X from"ws";import{logger as b,RELAY_REJECTED_CODE as Oe,isRelayMessage as Me}from"aitable-workflow-core";var S="relay:conn",ge=1e3,Ue=3e4,je=Number(process.env.AITABLE_RELAY_SERVER_STALE_MS??9e4),N=class{static{c(this,"RelayConnection")}ws=null;delay=ge;timer=null;watchdog=null;should=!0;permanentlyRejected=!1;accepted=!1;lastServerFrameAt=0;serverUrl;key;token;onMessage;onOpen;onAccepted;onPermanentReject;mkWs;staleMs;constructor(e){this.serverUrl=e.serverUrl,this.key=e.key??"",this.token=e.token??"",this.onMessage=e.onMessage,this.onOpen=e.onOpen,this.onAccepted=e.onAccepted,this.onPermanentReject=e.onPermanentReject,this.mkWs=e.mkWs??(n=>new X(n)),this.staleMs=e.staleMs??je}connect(){this.permanentlyRejected||(this.should=!0,this.doConnect())}send(e){this.ws&&this.ws.readyState===X.OPEN&&this.ws.send(JSON.stringify(e))}close(){this.should=!1,this.timer&&(clearTimeout(this.timer),this.timer=null),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.ws?.close()}isPermanentlyRejected(){return this.permanentlyRejected}currentSocket(){return this.ws}buildUrl(){let e=this.serverUrl.replace(/\/+$/,"").replace(/^http/,"ws"),n=this.token?`token=${encodeURIComponent(this.token)}`:`key=${encodeURIComponent(this.key)}`;return`${e}/api/relay/connect?${n}`}doConnect(){if(!this.should||this.permanentlyRejected)return;let e=this.buildUrl();b.info(S,"connecting",{serverUrl:this.serverUrl}),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.accepted=!1,this.lastServerFrameAt=0;let n=this.mkWs(e);this.ws=n,n.on("open",()=>{b.info(S,"connected"),this.onOpen?.(n)}),n.on("message",o=>{this.accepted||(this.accepted=!0,this.delay=ge,this.onAccepted?.(n)),this.lastServerFrameAt=Date.now(),this.armWatchdog();let r;try{r=JSON.parse(typeof o=="string"?o:String(o))}catch{return}Me(r)&&(r.type==="ping"&&this.send({type:"pong"}),this.onMessage(r))}),n.on("close",(o,r)=>{this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null);let i=r==null?"":String(r);if(o===Oe){this.permanentlyRejected=!0,this.should=!1,b.error(S,"server permanently rejected this machine: its connection key is unknown or was removed; re-issue the relay connect command and restart with the new key",{code:o,reason:i}),this.onPermanentReject?.({code:o,reason:i});return}b.warn(S,"disconnected",{code:o}),this.scheduleReconnect()}),n.on("error",o=>{b.error(S,"ws error",{detail:o instanceof Error?o.message:String(o)})})}armWatchdog(){this.watchdog&&clearTimeout(this.watchdog),this.watchdog=setTimeout(()=>{if(!(!this.accepted||!this.lastServerFrameAt||this.ws?.readyState!==X.OPEN)){b.warn(S,"server heartbeat stale; closing socket to reconnect",{staleMs:Date.now()-this.lastServerFrameAt});try{this.ws.close()}catch{}}},this.staleMs+1),this.watchdog.unref?.()}scheduleReconnect(){!this.should||this.permanentlyRejected||this.timer||(b.info(S,"reconnecting",{ms:this.delay}),this.timer=setTimeout(()=>{this.timer=null,this.doConnect()},this.delay),this.timer.unref?.(),this.delay=Math.min(this.delay*2,Ue))}};import{createHash as Ne}from"crypto";import{readdir as Fe,readFile as Be,stat as We}from"fs/promises";import de from"path";import{isAllowedArtifactPath as Ve,normalizeArtifactRelPath as Ye}from"aitable-workflow-core";var me={async upload(t,e,n){let o=await fetch(t,{method:"PUT",body:e,headers:{...n}});if(!o.ok)throw new Error(`artifact PUT failed: ${o.status} ${o.statusText}`)}};async function fe(t){let e=[];return await pe(t,t,e),e.sort((n,o)=>n.relPath.localeCompare(o.relPath))}c(fe,"scanArtifacts");async function pe(t,e,n){let o;try{o=await Fe(e,{withFileTypes:!0})}catch{return}for(let r of o){if(r.name==="node_modules"||r.name.startsWith("."))continue;let i=de.join(e,r.name);if(r.isDirectory())await pe(t,i,n);else if(r.isFile()){let s=de.relative(t,i).replace(/\\/g,"/");if(!Ve(s))continue;let a=await We(i),l=await Be(i),m=Ne("sha256").update(l).digest("hex");n.push({relPath:Ye(s),absPath:i,size:a.size,sha256:m})}}}c(pe,"walk");var u="relay:daemon",ue=["aitable"],Ze="dws";function et(t,e=ue){if(!Array.isArray(t)||t.length===0)return{ok:!1,reason:"dws args must be a non-empty array"};for(let o of t){if(typeof o!="string")return{ok:!1,reason:"dws args must all be strings"};if(o.length===0)return{ok:!1,reason:"dws args must not contain empty tokens"};if(/[\u0000-\u001f]/.test(o))return{ok:!1,reason:"dws args must not contain control characters"}}let n=t[0];return n.startsWith("-")?{ok:!1,reason:"first dws arg must be a subcommand, not a flag"}:e.length>0&&!e.includes(n)?{ok:!1,reason:`dws command "${n}" is not allowed`}:{ok:!0}}c(et,"validateDwsArgs");function tt(t){try{return qe(`${t} --version`,{encoding:"utf8",timeout:5e3,stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}c(tt,"detectDwsAvailable");var Q=class{static{c(this,"RelayDaemon")}config;allowedDwsCommands;conn;runAgent;createDwsClient;detectAgents;detectDws;hostname;osString;onPermanentReject;artifactUploader;grantTimeoutMs;pendingGrants=new Map;maxTasks;inflight=0;taskQueue=[];machineId;constructor(e,n={}){this.config={...e,dwsBin:e.dwsBin??Ze},this.machineId=e.machineId,this.allowedDwsCommands=e.allowedDwsCommands??ue,this.runAgent=n.runAgent??ze,this.createDwsClient=n.createDwsClient??((r,i)=>new Xe({bin:r,timeoutMs:i})),this.detectAgents=n.detectAgents??(()=>Je()),this.detectDws=n.detectDws??(r=>tt(r)),this.hostname=n.hostname??(()=>I.hostname()),this.osString=n.osString??(()=>`${I.platform()} ${I.arch()}`),this.onPermanentReject=n.onPermanentReject,this.artifactUploader=n.artifactUploader??me,this.grantTimeoutMs=n.grantTimeoutMs??3e4,this.maxTasks=Math.max(1,Math.floor(e.maxTasks??1));let o=n.createConnection??(r=>new N(r));this.conn=o({serverUrl:this.config.serverUrl,key:this.config.key,token:this.config.token,onMessage:c(r=>this.handleMessage(r),"onMessage"),onOpen:c(()=>this.handleOpen(),"onOpen"),onPermanentReject:c(r=>this.handlePermanentReject(r),"onPermanentReject")})}start(){p.info(u,"starting",{serverUrl:this.config.serverUrl,workspaceRoot:this.config.workspaceRoot}),this.config.name||p.warn(u,"\u672A\u6307\u5B9A --name\uFF0C\u5C06\u4F7F\u7528\u4E3B\u673A\u540D\u4F5C\u4E3A\u673A\u5668\u6CE8\u518C\u540D\uFF1B\u591A\u673A\u573A\u666F\u4E0B hostname \u82E5\u91CD\u590D\u4F1A\u5BFC\u81F4\u8FDE\u63A5\u4E92\u76F8\u9876\u66FF\uFF0C\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A --name",{hostname:this.hostname()}),this.conn.connect()}stop(){p.info(u,"stopping"),this.conn.close()}buildReady(){let n={type:"ready",runtimes:Array.from(new Set(this.detectAgents().map(o=>o.type))),hasDws:this.detectDws(this.config.dwsBin),hostname:this.hostname(),os:this.osString()};return this.machineId&&(n.machineId=this.machineId),this.config.name&&(n.name=this.config.name),this.config.displayName&&(n.displayName=this.config.displayName),this.config.description&&(n.description=this.config.description),this.maxTasks>1&&(n.maxTasks=this.maxTasks),n}handleOpen(){let e=this.buildReady();p.info(u,"connected; sending ready",{runtimes:e.runtimes,hasDws:e.hasDws}),this.conn.send(e)}handlePermanentReject(e){p.error(u,"permanently rejected by gateway",{...e}),this.onPermanentReject?.(e)}handleMessage(e){switch(e.type){case"run:agent":this.enqueueTask(()=>this.handleRunAgent(e));break;case"run:dws":this.enqueueTask(()=>this.handleRunDws(e));break;case"upload:grant":this.resolveGrant(e);break;case"ready:ack":e.machineId&&(this.machineId=e.machineId,p.info(u,"machine id assigned",{machineId:e.machineId}));break;default:break}}enqueueTask(e){let n=c(()=>{this.inflight+=1,e().finally(()=>{this.inflight-=1;let o=this.taskQueue.shift();o&&o()})},"exec");this.inflight<this.maxTasks?n():this.taskQueue.push(n)}async handleRunAgent(e){let{requestId:n}=e;p.info(u,"run:agent received",{requestId:n,projectId:e.projectId,agent:e.agent});try{let o=this.resolveWorkDir(e.projectId,e.workDir);await Ge(o,{recursive:!0});let r=this.rewritePromptWorkDir(e.prompt,e.workDir,o),i={agent:e.agent,workDir:o,onEvent:c(l=>this.conn.send({type:"event",requestId:n,event:l}),"onEvent")};e.sessionId&&(i.sessionId=e.sessionId),e.permissionMode&&(i.adapterOptions={permissionMode:e.permissionMode}),this.config.agentTimeoutMs!=null&&(i.timeoutMs=this.config.agentTimeoutMs);let s=await this.runAgent(r,i),a;try{a=await this.collectAndUploadArtifacts(n,e.projectId,o)}catch(l){let m=l instanceof Error?l.message:String(l);p.error(u,"artifact upload failed",{requestId:n,error:m}),this.conn.send({type:"error",requestId:n,code:"artifact_upload_failed",message:m});return}this.conn.send({type:"result",requestId:n,ok:!0,response:s.response,sessionId:s.sessionId,...a?{artifacts:a}:{}}),p.info(u,"run:agent done",{requestId:n,sessionId:s.sessionId,artifacts:a?a.files.length:0})}catch(o){let r=o instanceof Error?o.message:String(o);p.error(u,"run:agent failed",{requestId:n,error:r}),this.conn.send({type:"error",requestId:n,code:"agent_failed",message:r})}}async collectAndUploadArtifacts(e,n,o){let r=await fe(o);if(r.length===0)return;this.conn.send({type:"upload:request",requestId:e,projectId:n,files:r.map(a=>({path:a.relPath,size:a.size,sha256:a.sha256}))});let i=await this.awaitGrant(e);if(!i)throw new Error("upload:grant \u7B49\u5F85\u8D85\u65F6");if(i.grants.length===0){p.warn(u,"upload:grant \u65E0\u6388\u6743\u9879\uFF08gateway \u672A\u914D\u7F6E store \u6216\u5168\u88AB\u62D2\uFF09",{requestId:e,rejected:(i.rejected??[]).length});return}let s=[];for(let a of i.grants){let l=r.find(h=>h.relPath===a.path);if(!l)continue;let m=await Ke(l.absPath);await this.artifactUploader.upload(a.url,m,a.headers),s.push({path:a.path,key:a.key,sha256:l.sha256,size:l.size})}return{store:"oss",files:s}}awaitGrant(e){return new Promise(n=>{let o=setTimeout(()=>{this.pendingGrants.delete(e),n(void 0)},this.grantTimeoutMs);o.unref?.(),this.pendingGrants.set(e,r=>{clearTimeout(o),n(r)})})}resolveGrant(e){let n=this.pendingGrants.get(e.requestId);n&&(this.pendingGrants.delete(e.requestId),n(e))}async handleRunDws(e){let{requestId:n}=e,o=et(e.args,this.allowedDwsCommands);if(!o.ok){p.warn(u,"run:dws rejected",{requestId:n,reason:o.reason}),this.conn.send({type:"error",requestId:n,code:"dws_rejected",message:o.reason});return}p.info(u,"run:dws received",{requestId:n,command:e.args[0]});try{let i=await this.createDwsClient(this.config.dwsBin,e.timeoutMs).runJson(e.args,e.timeoutMs!=null?{timeoutMs:e.timeoutMs}:void 0);this.conn.send({type:"result",requestId:n,ok:!0,response:JSON.stringify(i)}),p.info(u,"run:dws done",{requestId:n})}catch(r){let i=r instanceof Error?r.message:String(r);p.error(u,"run:dws failed",{requestId:n,error:i}),this.conn.send({type:"error",requestId:n,code:"dws_failed",message:i})}}resolveWorkDir(e,n){if(n&&n.trim()!=="")if(R.isAbsolute(n))p.warn(u,"\u5FFD\u7565\u670D\u52A1\u7AEF\u4E0B\u53D1\u7684\u7EDD\u5BF9\u8DEF\u5F84 workDir\uFF0C\u56DE\u9000\u5230 workspaceRoot/projectId",{workDir:n,projectId:e});else return R.resolve(this.config.workspaceRoot,n);return R.join(this.config.workspaceRoot,e)}rewritePromptWorkDir(e,n,o){let r=n?.trim();return!r||!R.isAbsolute(r)||r===o?e:e.split(r).join(o)}};function Z(t,e){let n,o=t?.trim();if(o)n=R.isAbsolute(o)?R.resolve(o):R.resolve(I.homedir(),o);else{let r=e?.trim()?e.trim():"default";n=R.join(I.homedir(),".aitable-workflow","workspaces",r)}return He(n,{recursive:!0}),n}c(Z,"resolveWorkspaceRoot");function nt(t,e=process.env){let n=t.serverUrl??e.AITABLE_RELAY_SERVER_URL,o=t.key??e.AITABLE_RELAY_BOOTSTRAP_KEY,r=t.token??e.AITABLE_RELAY_TOKEN,i=t.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT,s=t.machineId??e.AITABLE_RELAY_MACHINE_ID,a=t.name??e.AITABLE_RELAY_NAME,l=t.desc??e.AITABLE_RELAY_DESC,m=t.maxTasks??e.AITABLE_RELAY_MAX_TASKS,h=[];if(n||h.push("--server-url (\u6216 AITABLE_RELAY_SERVER_URL)"),!o&&!r&&h.push("--key/--token (\u6216 AITABLE_RELAY_BOOTSTRAP_KEY/AITABLE_RELAY_TOKEN)"),h.length>0)throw new Error(`relay \u7F3A\u5C11\u5FC5\u8981\u53C2\u6570: ${h.join(", ")}
3
- \u{1F4A1} \u63D0\u793A: \u4F7F\u7528 \`aitable-workflow connect\` \u6CE8\u518C\u540E\u53EF\u7701\u7565\u8FD9\u4E9B\u53C2\u6570`);let w=a??I.hostname()??"default",f={serverUrl:n,workspaceRoot:Z(i,w)};if(r?f.token=r:o&&(f.key=o),s&&(f.machineId=s),a&&(f.name=a,f.displayName=a),l&&(f.description=l),m!=null&&m!==""){let T=Math.floor(Number(m));Number.isFinite(T)&&T>=1&&(f.maxTasks=T)}return f}c(nt,"resolveRelayCliConfig");async function C(t,e=process.env){let n=null;try{n=await Qe()}catch{n=null}let o={serverUrl:t.serverUrl??e.AITABLE_RELAY_SERVER_URL??n?.serverUrl,key:t.key??e.AITABLE_RELAY_BOOTSTRAP_KEY??n?.key,token:t.token??e.AITABLE_RELAY_TOKEN??n?.token,name:t.name??e.AITABLE_RELAY_NAME??n?.name,desc:t.desc??e.AITABLE_RELAY_DESC,workspaceRoot:t.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT??n?.workspaceRoot,machineId:t.machineId??e.AITABLE_RELAY_MACHINE_ID??n?.machineId,maxTasks:t.maxTasks??e.AITABLE_RELAY_MAX_TASKS};return nt(o,e)}c(C,"resolveDaemonConfig");async function ee(t){let e=await C(t),n=new Q(e,{onPermanentReject:c(()=>{process.exit(1)},"onPermanentReject")}),o=c(()=>{n.stop(),process.exit(0)},"shutdown");return process.on("SIGINT",o),process.on("SIGTERM",o),n.start(),n}c(ee,"runRelayDaemon");import{spawn as rt}from"child_process";import{existsSync as st}from"fs";import L from"path";import{fileURLToPath as it}from"url";import{appendFileSync as Sn,statSync as En,renameSync as In,mkdirSync as $n,existsSync as Tn}from"fs";import ot from"path";var _n=10*1024*1024;function _(t){return ot.join(U(t),"daemon.log")}c(_,"logFilePath");var F=L.dirname(it(import.meta.url));function at(){let t=[L.resolve(F,"..","..","bin","aitable-workflow.mjs"),L.resolve(F,"..","bin","aitable-workflow.mjs"),L.resolve(F,"..","..","dist","cli.js"),L.resolve(F,"cli.js")];return t.find(e=>st(e))??t[0]}c(at,"resolveDaemonEntry");var ct=at();async function B(t){await le(t.agentId);let e=["relay"];t.serverUrl&&e.push("--server-url",t.serverUrl),t.token&&e.push("--token",t.token),t.key&&e.push("--key",t.key),t.name&&e.push("--name",t.name),t.workspaceRoot&&e.push("--workspace-root",t.workspaceRoot),t.machineId&&e.push("--machine-id",t.machineId),t.maxTasks&&e.push("--max-tasks",String(t.maxTasks));let n=await import("fs").then(s=>{let a=_(t.agentId);return s.openSync(a,"a")}),o=rt(process.execPath,[ct,...e],{detached:!0,stdio:["ignore",n,n],env:{...process.env}});try{let{closeSync:s}=await import("fs");s(n)}catch{}o.unref();let{writeFile:r}=await import("fs/promises"),{pidFilePath:i}=await import("./pid-file-HPTFI54H.js");return o.pid&&await r(i(t.agentId),String(o.pid),"utf8"),{pid:o.pid??0}}c(B,"startDaemon");async function W(t,e=5e3){let n=await z(t);if(n===null||!x(n))return await j(t),!1;try{process.kill(n,"SIGTERM")}catch{return await j(t),!1}let o=Date.now()+e;for(;Date.now()<o&&x(n);)await new Promise(r=>setTimeout(r,200));if(x(n))try{process.kill(n,"SIGKILL")}catch{}return await j(t),!0}c(W,"stopDaemon");async function V(t){let e=await z(t),n=e!==null&&x(e),o=null;if(n&&e!==null)try{let{readFile:r}=await import("fs/promises"),i=await r(`/proc/${e}/stat`,"utf8"),s=parseInt(i.split(" ")[21]??"0",10),a=await r("/proc/uptime","utf8"),h=parseFloat(a.split(" ")[0]??"0")-s/100;o=Math.round(h*1e3)}catch{}return{agentId:t,running:n,pid:n?e:null,uptimeMs:o,logFile:_(t)}}c(V,"getDaemonStatus");import{readFile as lt,writeFile as Yn,mkdir as Gn}from"fs/promises";import gt from"path";var he={connectionState:"disconnected",lastHeartbeatAt:null,machineId:null,serverUrl:"",runningTasks:0,queuedTasks:0,lastDisconnectReason:null,updatedAt:new Date().toISOString()};function dt(t){return gt.join(U(t),"state.json")}c(dt,"stateFilePath");async function te(t){try{let e=await lt(dt(t),"utf8");return{...he,...JSON.parse(e)}}catch{return{...he}}}c(te,"readState");import{execSync as D}from"child_process";import{writeFile as mt,rm as ft,mkdir as pt,access as ut}from"fs/promises";import v from"path";import we from"os";import{readCredentials as ht}from"aitable-workflow-core";var wt="com.alibaba.aitable-workflow.daemon",ne="\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\uFF1Anpm i -g @ali/aitable-workflow";function P(t){return`${wt}.${t}`}c(P,"plistLabel");function oe(t){return v.join(we.homedir(),"Library","LaunchAgents",`${P(t)}.plist`)}c(oe,"plistPath");function E(){return process.platform==="darwin"}c(E,"isMacOS");function ye(){try{return D("which aitable-workflow",{encoding:"utf8"}).trim()||null}catch{return null}}c(ye,"resolveGlobalCliEntry");function ke(t){if(!t||!t.trim())throw new Error(`\u672A\u627E\u5230\u5168\u5C40\u5B89\u88C5\u7684 aitable-workflow CLI \u5165\u53E3\uFF0C\u65E0\u6CD5\u914D\u7F6E\u5F00\u673A\u81EA\u542F\u3002
4
- \u{1F4A1} ${ne}`);if(t.includes("/_npx/")||t.includes(`${v.sep}_npx${v.sep}`))throw new Error(`\u68C0\u6D4B\u5230 CLI \u5165\u53E3\u4F4D\u4E8E npx \u4E34\u65F6\u7F13\u5B58\uFF0C\u5F00\u673A\u81EA\u542F\u4F1A\u5931\u6548\uFF1A${t}
5
- \u{1F4A1} ${ne}`);if(!v.isAbsolute(t))throw new Error(`CLI \u5165\u53E3\u4E0D\u662F\u7A33\u5B9A\u7684\u5168\u5C40\u7EDD\u5BF9\u8DEF\u5F84\uFF1A${t}
6
- \u{1F4A1} ${ne}`)}c(ke,"assertStableCliEntry");async function yt(t){let e={};e.AITABLE_RELAY_NAME=t;let n;try{let o=await ht();n=o.agents.find(r=>r.name===t)??o.agents.find(r=>r.name===o.activeAgent)??void 0}catch{n=void 0}return n&&(n.serverUrl&&(e.AITABLE_RELAY_SERVER_URL=n.serverUrl),n.token&&(e.AITABLE_RELAY_TOKEN=n.token),n.workspaceRoot&&(e.AITABLE_RELAY_WORKSPACE_ROOT=n.workspaceRoot)),e}c(yt,"buildRelayEnv");function kt(t,e){let n=P(t),o=e?.cliEntry??ye();ke(o);let r=["relay"];e?.maxTasks&&r.push("--max-tasks",String(e.maxTasks));let i=v.join(we.homedir(),".aitable-workflow","daemons",t),s=v.join(i,"launchd.log"),a=v.join(i,"launchd.err.log"),l=[o,...r].map(w=>` <string>${$(w)}</string>`).join(`
2
+ import{b as U,d as x,e as z,f as le,g as j}from"./chunk-W3EUICMH.js";import{a as ge}from"./chunk-IG7PZYXN.js";import{a as c}from"./chunk-EI7MMDWY.js";import{config as Le}from"dotenv";import{Command as G}from"commander";import{createApp as It,loadSettings as K,loadWorkflowTemplate as De,logger as g,activateGlobalDwsOnPath as $t,createExecShellToolkit as Tt,ensureTsxRegistered as xt,runInit as Ct,runDesignCommand as _t,runCheck as xe,runSetupCommand as Lt,runKbCompileCommand as Dt,runKbUpdateCommand as Pt,runKbStatusCommand as Ot,runKbIngestCommand as Mt,runSync as Ut,checkWorkflowRecipes as jt,listCodingAgents as Nt,Tracer as Ft,saveCredential as Bt,listCredentials as ae,setActiveAgent as Wt,getActiveCredential as A,readCredentials as Vt,findConflictingCredential as Yt,maskSecret as H,runMigrate as Gt,checkMigrateHint as Pe}from"aitable-workflow-core";import{startServer as Kt,resolveServeConfig as Ht}from"aitable-workflow-server";import I from"os";import E from"path";import{mkdir as qe,readFile as Je}from"fs/promises";import{mkdirSync as ze}from"fs";import{logger as p,detectInstalledAgents as Xe,runCodingAgent as Qe,DwsClient as Ze,getActiveCredential as et,assertPortableId as we,resolveInsideRoot as he,probeCommand as tt}from"aitable-workflow-core";import X from"ws";import{logger as v,RELAY_REJECTED_CODE as je,isRelayMessage as Ne}from"aitable-workflow-core";var b="relay:conn",de=1e3,Fe=3e4,Be=Number(process.env.AITABLE_RELAY_SERVER_STALE_MS??9e4),N=class{static{c(this,"RelayConnection")}ws=null;delay=de;timer=null;watchdog=null;should=!0;permanentlyRejected=!1;accepted=!1;lastServerFrameAt=0;serverUrl;key;token;onMessage;onOpen;onAccepted;onPermanentReject;mkWs;staleMs;constructor(e){this.serverUrl=e.serverUrl,this.key=e.key??"",this.token=e.token??"",this.onMessage=e.onMessage,this.onOpen=e.onOpen,this.onAccepted=e.onAccepted,this.onPermanentReject=e.onPermanentReject,this.mkWs=e.mkWs??(n=>new X(n)),this.staleMs=e.staleMs??Be}connect(){this.permanentlyRejected||(this.should=!0,this.doConnect())}send(e){this.ws&&this.ws.readyState===X.OPEN&&this.ws.send(JSON.stringify(e))}close(){this.should=!1,this.timer&&(clearTimeout(this.timer),this.timer=null),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.ws?.close()}isPermanentlyRejected(){return this.permanentlyRejected}currentSocket(){return this.ws}buildUrl(){let e=this.serverUrl.replace(/\/+$/,"").replace(/^http/,"ws"),n=this.token?`token=${encodeURIComponent(this.token)}`:`key=${encodeURIComponent(this.key)}`;return`${e}/api/relay/connect?${n}`}doConnect(){if(!this.should||this.permanentlyRejected)return;let e=this.buildUrl();v.info(b,"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",()=>{v.info(b,"connected"),this.onOpen?.(n)}),n.on("message",o=>{this.accepted||(this.accepted=!0,this.delay=de,this.onAccepted?.(n)),this.lastServerFrameAt=Date.now(),this.armWatchdog();let r;try{r=JSON.parse(typeof o=="string"?o:String(o))}catch{return}Ne(r)&&(r.type==="ping"&&this.send({type:"pong"}),this.onMessage(r))}),n.on("close",(o,r)=>{this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null);let i=r==null?"":String(r);if(o===je){this.permanentlyRejected=!0,this.should=!1,v.error(b,"server permanently rejected this machine: its connection key is unknown or was removed; re-issue the relay connect command and restart with the new key",{code:o,reason:i}),this.onPermanentReject?.({code:o,reason:i});return}v.warn(b,"disconnected",{code:o}),this.scheduleReconnect()}),n.on("error",o=>{v.error(b,"ws error",{detail:o instanceof Error?o.message:String(o)})})}armWatchdog(){this.watchdog&&clearTimeout(this.watchdog),this.watchdog=setTimeout(()=>{if(!(!this.accepted||!this.lastServerFrameAt||this.ws?.readyState!==X.OPEN)){v.warn(b,"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||(v.info(b,"reconnecting",{ms:this.delay}),this.timer=setTimeout(()=>{this.timer=null,this.doConnect()},this.delay),this.timer.unref?.(),this.delay=Math.min(this.delay*2,Fe))}};import{createHash as We}from"crypto";import{readdir as Ve,readFile as Ye,stat as Ge}from"fs/promises";import me from"path";import{isAllowedArtifactPath as Ke,normalizeArtifactRelPath as He}from"aitable-workflow-core";var fe={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 pe(t){let e=[];return await ue(t,t,e),e.sort((n,o)=>n.relPath.localeCompare(o.relPath))}c(pe,"scanArtifacts");async function ue(t,e,n){let o;try{o=await Ve(e,{withFileTypes:!0})}catch{return}for(let r of o){if(r.name==="node_modules"||r.name.startsWith("."))continue;let i=me.join(e,r.name);if(r.isDirectory())await ue(t,i,n);else if(r.isFile()){let s=me.relative(t,i).replace(/\\/g,"/");if(!Ke(s))continue;let a=await Ge(i),l=await Ye(i),m=We("sha256").update(l).digest("hex");n.push({relPath:He(s),absPath:i,size:a.size,sha256:m})}}}c(ue,"walk");var u="relay:daemon",ye=["aitable"],nt="dws";function ot(t,e=ye){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(ot,"validateDwsArgs");function rt(t){return tt(t,["--version"],{timeoutMs:5e3}).ok}c(rt,"detectDwsAvailable");var Q=class{static{c(this,"RelayDaemon")}config;allowedDwsCommands;conn;runAgent;createDwsClient;detectAgents;detectDws;hostname;osString;onPermanentReject;artifactUploader;grantTimeoutMs;pendingGrants=new Map;maxTasks;inflight=0;taskQueue=[];machineId;constructor(e,n={}){this.config={...e,dwsBin:e.dwsBin??nt},this.machineId=e.machineId,this.allowedDwsCommands=e.allowedDwsCommands??ye,this.runAgent=n.runAgent??Qe,this.createDwsClient=n.createDwsClient??((r,i)=>new Ze({bin:r,timeoutMs:i})),this.detectAgents=n.detectAgents??(()=>Xe()),this.detectDws=n.detectDws??(r=>rt(r)),this.hostname=n.hostname??(()=>I.hostname()),this.osString=n.osString??(()=>`${I.platform()} ${I.arch()}`),this.onPermanentReject=n.onPermanentReject,this.artifactUploader=n.artifactUploader??fe,this.grantTimeoutMs=n.grantTimeoutMs??3e4,this.maxTasks=Math.max(1,Math.floor(e.maxTasks??1));let o=n.createConnection??(r=>new N(r));this.conn=o({serverUrl:this.config.serverUrl,key:this.config.key,token:this.config.token,onMessage:c(r=>this.handleMessage(r),"onMessage"),onOpen:c(()=>this.handleOpen(),"onOpen"),onPermanentReject:c(r=>this.handlePermanentReject(r),"onPermanentReject")})}start(){p.info(u,"starting",{serverUrl:this.config.serverUrl,workspaceRoot:this.config.workspaceRoot}),this.config.name||p.warn(u,"\u672A\u6307\u5B9A --name\uFF0C\u5C06\u4F7F\u7528\u4E3B\u673A\u540D\u4F5C\u4E3A\u673A\u5668\u6CE8\u518C\u540D\uFF1B\u591A\u673A\u573A\u666F\u4E0B hostname \u82E5\u91CD\u590D\u4F1A\u5BFC\u81F4\u8FDE\u63A5\u4E92\u76F8\u9876\u66FF\uFF0C\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A --name",{hostname:this.hostname()}),this.conn.connect()}stop(){p.info(u,"stopping"),this.conn.close()}buildReady(){let n={type:"ready",runtimes:Array.from(new Set(this.detectAgents().map(o=>o.type))),hasDws:this.detectDws(this.config.dwsBin),hostname:this.hostname(),os:this.osString()};return this.machineId&&(n.machineId=this.machineId),this.config.name&&(n.name=this.config.name),this.config.displayName&&(n.displayName=this.config.displayName),this.config.description&&(n.description=this.config.description),this.maxTasks>1&&(n.maxTasks=this.maxTasks),n}handleOpen(){let e=this.buildReady();p.info(u,"connected; sending ready",{runtimes:e.runtimes,hasDws:e.hasDws}),this.conn.send(e)}handlePermanentReject(e){p.error(u,"permanently rejected by gateway",{...e}),this.onPermanentReject?.(e)}handleMessage(e){switch(e.type){case"run:agent":this.enqueueTask(()=>this.handleRunAgent(e));break;case"run:dws":this.enqueueTask(()=>this.handleRunDws(e));break;case"upload:grant":this.resolveGrant(e);break;case"ready:ack":e.machineId&&(this.machineId=e.machineId,p.info(u,"machine id assigned",{machineId:e.machineId}));break;default:break}}enqueueTask(e){let n=c(()=>{this.inflight+=1,e().finally(()=>{this.inflight-=1;let o=this.taskQueue.shift();o&&o()})},"exec");this.inflight<this.maxTasks?n():this.taskQueue.push(n)}async handleRunAgent(e){let{requestId:n}=e;p.info(u,"run:agent received",{requestId:n,projectId:e.projectId,agent:e.agent});try{let o=this.resolveWorkDir(e.projectId,e.workDir);await qe(o,{recursive:!0});let r=this.rewritePromptWorkDir(e.prompt,e.workDir,o),i={agent:e.agent,workDir:o,onEvent:c(l=>this.conn.send({type:"event",requestId:n,event:l}),"onEvent")};e.sessionId&&(i.sessionId=e.sessionId),e.permissionMode&&(i.adapterOptions={permissionMode:e.permissionMode}),this.config.agentTimeoutMs!=null&&(i.timeoutMs=this.config.agentTimeoutMs);let s=await this.runAgent(r,i),a;try{a=await this.collectAndUploadArtifacts(n,e.projectId,o)}catch(l){let m=l instanceof Error?l.message:String(l);p.error(u,"artifact upload failed",{requestId:n,error:m}),this.conn.send({type:"error",requestId:n,code:"artifact_upload_failed",message:m});return}this.conn.send({type:"result",requestId:n,ok:!0,response:s.response,sessionId:s.sessionId,...a?{artifacts:a}:{}}),p.info(u,"run:agent done",{requestId:n,sessionId:s.sessionId,artifacts:a?a.files.length:0})}catch(o){let r=o instanceof Error?o.message:String(o);p.error(u,"run:agent failed",{requestId:n,error:r}),this.conn.send({type:"error",requestId:n,code:"agent_failed",message:r})}}async collectAndUploadArtifacts(e,n,o){let r=await pe(o);if(r.length===0)return;this.conn.send({type:"upload:request",requestId:e,projectId:n,files:r.map(a=>({path:a.relPath,size:a.size,sha256:a.sha256}))});let i=await this.awaitGrant(e);if(!i)throw new Error("upload:grant \u7B49\u5F85\u8D85\u65F6");if(i.grants.length===0){p.warn(u,"upload:grant \u65E0\u6388\u6743\u9879\uFF08gateway \u672A\u914D\u7F6E store \u6216\u5168\u88AB\u62D2\uFF09",{requestId:e,rejected:(i.rejected??[]).length});return}let s=[];for(let a of i.grants){let l=r.find(h=>h.relPath===a.path);if(!l)continue;let m=await Je(l.absPath);await this.artifactUploader.upload(a.url,m,a.headers),s.push({path:a.path,key:a.key,sha256:l.sha256,size:l.size})}return{store:"oss",files:s}}awaitGrant(e){return new Promise(n=>{let o=setTimeout(()=>{this.pendingGrants.delete(e),n(void 0)},this.grantTimeoutMs);o.unref?.(),this.pendingGrants.set(e,r=>{clearTimeout(o),n(r)})})}resolveGrant(e){let n=this.pendingGrants.get(e.requestId);n&&(this.pendingGrants.delete(e.requestId),n(e))}async handleRunDws(e){let{requestId:n}=e,o=ot(e.args,this.allowedDwsCommands);if(!o.ok){p.warn(u,"run:dws rejected",{requestId:n,reason:o.reason}),this.conn.send({type:"error",requestId:n,code:"dws_rejected",message:o.reason});return}p.info(u,"run:dws received",{requestId:n,command:e.args[0]});try{let i=await this.createDwsClient(this.config.dwsBin,e.timeoutMs).runJson(e.args,e.timeoutMs!=null?{timeoutMs:e.timeoutMs}:void 0);this.conn.send({type:"result",requestId:n,ok:!0,response:JSON.stringify(i)}),p.info(u,"run:dws done",{requestId:n})}catch(r){let i=r instanceof Error?r.message:String(r);p.error(u,"run:dws failed",{requestId:n,error:i}),this.conn.send({type:"error",requestId:n,code:"dws_failed",message:i})}}resolveWorkDir(e,n){if(n&&n.trim()!=="")if(E.isAbsolute(n))p.warn(u,"\u5FFD\u7565\u670D\u52A1\u7AEF\u4E0B\u53D1\u7684\u7EDD\u5BF9\u8DEF\u5F84 workDir\uFF0C\u56DE\u9000\u5230 workspaceRoot/projectId",{workDir:n,projectId:e});else return he(this.config.workspaceRoot,n,{allowRoot:!1});return he(this.config.workspaceRoot,we(e,{label:"projectId"}),{allowRoot:!1})}rewritePromptWorkDir(e,n,o){let r=n?.trim();return!r||!E.isAbsolute(r)||r===o?e:e.split(r).join(o)}};function Z(t,e){let n,o=t?.trim();if(o)n=E.isAbsolute(o)?E.resolve(o):E.resolve(I.homedir(),o);else{let r=e?.trim()?e.trim():"default";n=E.join(I.homedir(),".aitable-workflow","workspaces",we(r,{label:"agentId"}))}return ze(n,{recursive:!0}),n}c(Z,"resolveWorkspaceRoot");function st(t,e=process.env){let n=t.serverUrl??e.AITABLE_RELAY_SERVER_URL,o=t.key??e.AITABLE_RELAY_BOOTSTRAP_KEY,r=t.token??e.AITABLE_RELAY_TOKEN,i=t.workspaceRoot??e.AITABLE_RELAY_WORKSPACE_ROOT,s=t.machineId??e.AITABLE_RELAY_MACHINE_ID,a=t.name??e.AITABLE_RELAY_NAME,l=t.desc??e.AITABLE_RELAY_DESC,m=t.maxTasks??e.AITABLE_RELAY_MAX_TASKS,h=[];if(n||h.push("--server-url (\u6216 AITABLE_RELAY_SERVER_URL)"),!o&&!r&&h.push("--key/--token (\u6216 AITABLE_RELAY_BOOTSTRAP_KEY/AITABLE_RELAY_TOKEN)"),h.length>0)throw new Error(`relay \u7F3A\u5C11\u5FC5\u8981\u53C2\u6570: ${h.join(", ")}
3
+ \u{1F4A1} \u63D0\u793A: \u4F7F\u7528 \`aitable-workflow connect\` \u6CE8\u518C\u540E\u53EF\u7701\u7565\u8FD9\u4E9B\u53C2\u6570`);let w=a??I.hostname()??"default",f={serverUrl:n,workspaceRoot:Z(i,w)};if(r?f.token=r:o&&(f.key=o),s&&(f.machineId=s),a&&(f.name=a,f.displayName=a),l&&(f.description=l),m!=null&&m!==""){let T=Math.floor(Number(m));Number.isFinite(T)&&T>=1&&(f.maxTasks=T)}return f}c(st,"resolveRelayCliConfig");async function C(t,e=process.env){let n=null;try{n=await et()}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 st(o,e)}c(C,"resolveDaemonConfig");async function ee(t){let e=await C(t),n=new Q(e,{onPermanentReject:c(()=>{process.exit(1)},"onPermanentReject")}),o=c(()=>{n.stop(),process.exit(0)},"shutdown");return process.on("SIGINT",o),process.on("SIGTERM",o),n.start(),n}c(ee,"runRelayDaemon");import{spawn as at}from"child_process";import{existsSync as ct}from"fs";import L from"path";import{fileURLToPath as lt}from"url";import{appendFileSync as En,statSync as In,renameSync as $n,mkdirSync as Tn,existsSync as xn}from"fs";import it from"path";var Ln=10*1024*1024;function _(t){return it.join(U(t),"daemon.log")}c(_,"logFilePath");var F=L.dirname(lt(import.meta.url));function gt(){let t=[L.resolve(F,"..","..","bin","aitable-workflow.mjs"),L.resolve(F,"..","bin","aitable-workflow.mjs"),L.resolve(F,"..","..","dist","cli.js"),L.resolve(F,"cli.js")];return t.find(e=>ct(e))??t[0]}c(gt,"resolveDaemonEntry");var dt=gt();async function B(t){await le(t.agentId);let e=["relay"];t.serverUrl&&e.push("--server-url",t.serverUrl),t.token&&e.push("--token",t.token),t.key&&e.push("--key",t.key),t.name&&e.push("--name",t.name),t.workspaceRoot&&e.push("--workspace-root",t.workspaceRoot),t.machineId&&e.push("--machine-id",t.machineId),t.maxTasks&&e.push("--max-tasks",String(t.maxTasks));let n=await import("fs").then(s=>{let a=_(t.agentId);return s.openSync(a,"a")}),o=at(process.execPath,[dt,...e],{detached:!0,stdio:["ignore",n,n],env:{...process.env}});try{let{closeSync:s}=await import("fs");s(n)}catch{}o.unref();let{writeFile:r}=await import("fs/promises"),{pidFilePath:i}=await import("./pid-file-3JTHFPFF.js");return o.pid&&await r(i(t.agentId),String(o.pid),"utf8"),{pid:o.pid??0}}c(B,"startDaemon");async function W(t,e=5e3){let n=await z(t);if(n===null||!x(n))return await j(t),!1;try{process.kill(n,"SIGTERM")}catch{return await j(t),!1}let o=Date.now()+e;for(;Date.now()<o&&x(n);)await new Promise(r=>setTimeout(r,200));if(x(n))try{process.kill(n,"SIGKILL")}catch{}return await j(t),!0}c(W,"stopDaemon");async function V(t){let e=await z(t),n=e!==null&&x(e),o=null;if(n&&e!==null)try{let{readFile:r}=await import("fs/promises"),i=await r(`/proc/${e}/stat`,"utf8"),s=parseInt(i.split(" ")[21]??"0",10),a=await r("/proc/uptime","utf8"),h=parseFloat(a.split(" ")[0]??"0")-s/100;o=Math.round(h*1e3)}catch{}return{agentId:t,running:n,pid:n?e:null,uptimeMs:o,logFile:_(t)}}c(V,"getDaemonStatus");import{readFile as mt,writeFile as Gn,mkdir as Kn}from"fs/promises";import ft from"path";var ke={connectionState:"disconnected",lastHeartbeatAt:null,machineId:null,serverUrl:"",runningTasks:0,queuedTasks:0,lastDisconnectReason:null,updatedAt:new Date().toISOString()};function pt(t){return ft.join(U(t),"state.json")}c(pt,"stateFilePath");async function te(t){try{let e=await mt(pt(t),"utf8");return{...ke,...JSON.parse(e)}}catch{return{...ke}}}c(te,"readState");import{execSync as D}from"child_process";import{writeFile as ut,rm as ht,mkdir as wt,access as yt}from"fs/promises";import R from"path";import Ae from"os";import{assertPortableId as kt,readCredentials as At}from"aitable-workflow-core";var Rt="com.alibaba.aitable-workflow.daemon",ne="\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\uFF1Anpm i -g @ali/aitable-workflow";function P(t){return`${Rt}.${kt(t,{label:"agentId"})}`}c(P,"plistLabel");function oe(t){return R.join(Ae.homedir(),"Library","LaunchAgents",`${P(t)}.plist`)}c(oe,"plistPath");function S(){return process.platform==="darwin"}c(S,"isMacOS");function Re(){try{return D("which aitable-workflow",{encoding:"utf8"}).trim()||null}catch{return null}}c(Re,"resolveGlobalCliEntry");function ve(t){if(!t||!t.trim())throw new Error(`\u672A\u627E\u5230\u5168\u5C40\u5B89\u88C5\u7684 aitable-workflow CLI \u5165\u53E3\uFF0C\u65E0\u6CD5\u914D\u7F6E\u5F00\u673A\u81EA\u542F\u3002
4
+ \u{1F4A1} ${ne}`);if(t.includes("/_npx/")||t.includes(`${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} ${ne}`);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} ${ne}`)}c(ve,"assertStableCliEntry");async function vt(t){let e={};e.AITABLE_RELAY_NAME=t;let n;try{let o=await At();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(vt,"buildRelayEnv");function bt(t,e){let n=P(t),o=e?.cliEntry??Re();ve(o);let r=["relay"];e?.maxTasks&&r.push("--max-tasks",String(e.maxTasks));let i=R.join(Ae.homedir(),".aitable-workflow","daemons",t),s=R.join(i,"launchd.log"),a=R.join(i,"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,f])=>` <key>${$(w)}</key>
8
8
  <string>${$(f)}</string>`).join(`
9
9
  `);return`<?xml version="1.0" encoding="UTF-8"?>
@@ -30,41 +30,41 @@ ${h}
30
30
  <string>${$(a)}</string>
31
31
  </dict>
32
32
  </plist>
33
- `}c(kt,"generatePlist");function $(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}c($,"escapeXml");function Y(){let t=process.getuid?.();if(t===void 0)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237 UID\uFF08\u4EC5\u652F\u6301 macOS/Linux\uFF09");return t}c(Y,"getUid");async function Ae(t,e){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let n=ye();ke(n);let o=await yt(t),r=oe(t),i=P(t);try{D(`launchctl bootout gui/${Y()}/${i} 2>/dev/null`,{encoding:"utf8"})}catch{}await pt(v.dirname(r),{recursive:!0});let s=kt(t,{maxTasks:e?.maxTasks,relayEnv:o,cliEntry:n});await mt(r,s,"utf8"),D(`launchctl bootstrap gui/${Y()} ${r}`,{encoding:"utf8"})}c(Ae,"enableAutostart");async function Re(t){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=oe(t);try{D(`launchctl bootout gui/${Y()}/${e} 2>/dev/null`,{encoding:"utf8"})}catch{}await ft(n,{force:!0})}c(Re,"disableAutostart");async function re(t){if(!E())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=oe(t),o=!1;try{await ut(n),o=!0}catch{o=!1}let r=!1,i=!1,s=null;try{let a=D(`launchctl print gui/${Y()}/${e} 2>/dev/null`,{encoding:"utf8"});r=!0;let l=a.match(/pid\s*=\s*(\d+)/);l&&(s=parseInt(l[1],10),i=!0)}catch{r=!1}return{installed:o,loaded:r,running:i,pid:s}}c(re,"getAutostartStatus");import{createRequire as At}from"module";var ve="aitable-workflow-",Rt=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function be(){try{return At(import.meta.url)("../package.json")}catch{return{}}}c(be,"loadCliPackageManifest");function se(t){return t.version??"0.0.0"}c(se,"resolveCliVersion");function Se(t){let e=se(t),n={};t.name?.startsWith(ve)&&(n[t.name]=e);for(let[o,r]of Object.entries(t.dependencies??{}))o.startsWith(ve)&&(n[o]=Rt.test(r)?r:e);return n}c(Se,"resolveMonorepoPackageVersions");function ie(t){return t.skipConfig||t.skipConfigIfValid&&t.configValid===!0}c(ie,"canSkipSetupConfig");function Ee(t){return ie(t)?"setup":t.uiEnabled&&t.webAvailable?"web":"cli"}c(Ee,"resolveSetupConfigRoute");import y from"path";import{fileURLToPath as Yt}from"url";import{watchFile as Gt,statSync as Kt,openSync as Ht,readSync as qt,closeSync as Jt,existsSync as $e}from"fs";import{readFile as Te}from"fs/promises";import{spawn as zt}from"child_process";var O=y.dirname(Yt(import.meta.url));xe({override:!1,quiet:!0});xe({path:y.resolve(O,"..",".env"),override:!1,quiet:!0});var Le=be(),M=se(Le),De=Se(Le),k="./aitable-workflow.config.yml";function Xt(){let n=[],o=c(()=>{let r=Date.now();for(n.push(r);n.length>0&&r-n[0]>6e4;)n.shift();n.length>=10&&(g.error("cli",`60000ms \u5185\u53D1\u751F ${n.length} \u6B21\u672A\u6355\u83B7\u5F02\u5E38\uFF0C\u7591\u4F3C\u975E\u5076\u53D1\u9519\u8BEF\uFF0C\u4E3B\u52A8\u9000\u51FA`),process.exit(1))},"recordCrashAndMaybeExit");process.on("uncaughtException",r=>{g.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406\u5F02\u5E38\uFF08\u5DF2\u5B58\u6D3B\uFF0C\u4EA4\u7531\u91CD\u8FDE/\u91CD\u8BD5\u903B\u8F91\u81EA\u6108\uFF09",{error:r instanceof Error?r.message:String(r),stack:r instanceof Error?r.stack:void 0}),o()}),process.on("unhandledRejection",r=>{g.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406 Promise \u62D2\u7EDD\uFF08\u5DF2\u5B58\u6D3B\uFF09",{error:r instanceof Error?r.message:String(r),stack:r instanceof Error?r.stack:void 0}),o()})}c(Xt,"installLongRunningCrashGuards");function Qt(t){let e=process.platform,n=e==="darwin"?"open":e==="win32"?"cmd":"xdg-open",o=e==="win32"?["/c","start","",t]:[t];try{let r=zt(n,o,{stdio:"ignore",detached:!0});r.on("error",()=>{console.log(`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t}`)}),r.unref()}catch{console.log(`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t}`)}}c(Qt,"openBrowser");var d=new G().name("aitable-workflow").description("\u901A\u7528\u4E1A\u52A1\u6D41\u7A0B\u5F15\u64CE \u2014 \u914D\u7F6E\u9A71\u52A8\u7684 AI \u8868\u683C\u5DE5\u4F5C\u6D41\u81EA\u52A8\u5316").version(M).option("-d, --debug","\u8F93\u51FA debug \u7EA7\u522B\u65E5\u5FD7\uFF08\u542B recipe \u5185\u90E8 log\uFF09").hook("preAction",async(t,e)=>{e.name()!=="init"&&await bt()}).hook("preAction",(t,e)=>{t.opts().debug?g.setLevel("debug"):e.name()==="config"&&g.setLevel("warn")});d.command("init").description("\u4EA4\u4E92\u5F0F\u521D\u59CB\u5316 \u2014 \u9009\u62E9 Coding Agent\u3001\u914D\u7F6E\u5DE5\u4F5C\u76EE\u5F55\u3001\u63CF\u8FF0\u4E1A\u52A1\u573A\u666F\uFF1B\u6216\u7528 --template \u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6").option("-c, --config <path>","\u76EE\u6807\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").option("-f, --force","\u8986\u76D6\u5DF2\u6709\u914D\u7F6E\u6587\u4EF6").option("-y, --yes","\u4F7F\u7528\u9ED8\u8BA4\u503C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u5411\u5BFC").option("-t, --template <name>","\u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6(\u5F53\u524D\u63A8\u8350 support-qa),\u62F7\u8D1D\u5B8C\u6574\u53EF\u8FD0\u884C\u9879\u76EE\u5230\u76EE\u6807\u76EE\u5F55").option("--profile <name>","\u9009\u5B9A\u6A21\u677F\u4E0B\u7684 profile \u4E1A\u52A1\u5305(\u5982 support-qa \u7684 aitable),\u8986\u76D6\u5F0F\u53E0\u52A0\u5230\u5B9E\u4F8B").action(async t=>{try{await It({config:t.config,force:!!t.force,yes:!!t.yes,template:t.template,profile:t.profile,templatesDir:y.resolve(O,"..","templates"),templatePackageVersions:De,cliVersion:M})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","\u521D\u59CB\u5316\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("migrate").description("\u5347\u7EA7\u9879\u76EE\u76EE\u5F55\u5230\u6700\u65B0\u6A21\u677F\u7248\u672C\uFF0C\u81EA\u52A8\u4FDD\u7559\u7528\u6237\u914D\u7F6E").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u8DEF\u5F84",k).option("--dry-run","\u4EC5\u9884\u89C8\u53D8\u66F4\uFF0C\u4E0D\u5B9E\u9645\u5199\u5165").option("--no-backup","\u8DF3\u8FC7\u81EA\u52A8\u5907\u4EFD").option("--force","\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A").option("--template <name>","\u6307\u5B9A\u76EE\u6807\u6A21\u677F").option("--profile <name>","\u6307\u5B9A\u76EE\u6807 profile").option("--rollback","\u56DE\u6EDA\u5230\u4E0A\u4E00\u6B21\u8FC1\u79FB\u524D\u7684\u72B6\u6001").option("--list","\u5217\u51FA\u6240\u6709\u5907\u4EFD").action(async t=>{try{await Bt({config:t.config,dryRun:t.dryRun,noBackup:t.backup===!1,force:t.force,template:t.template,profile:t.profile,rollback:t.rollback,list:t.list,templatesDir:y.resolve(O,"..","templates"),templatePackageVersions:De,cliVersion:M})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","migrate \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("design").description("\u8BA9 Coding Agent \u6839\u636E\u573A\u666F\u63CF\u8FF0\u751F\u6210\u5B8C\u6574\u7684 workflow \u548C recipes").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-y, --yes","\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u8865\u5145\uFF0C\u76F4\u63A5\u4F7F\u7528 config \u4E2D\u7684 scene").option("--skip-questions","\u8DF3\u8FC7\u6F84\u6E05\u95EE\u5377\uFF08\u4ECD\u4F1A\u4EA4\u4E92\u8865\u5145\u9700\u6C42\uFF09").action(async t=>{try{await $t(t)}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","design \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("setup").description("\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E\uFF0C\u518D\u521D\u59CB\u5316 AI \u8868\u683C\u7ED3\u6784 + \u7F16\u8BD1\u77E5\u8BC6\u5E93 \u2014 \u4E00\u6B21\u5B8C\u6210 config + \u5EFA\u8868").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--no-clean","\u4E0D\u6E05\u7406\u7A7A\u767D\u884C").option("--no-kb","\u8DF3\u8FC7\u77E5\u8BC6\u5E93\u7F16\u8BD1").option("--kb-full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1\u77E5\u8BC6\u5E93").option("--skip-config","\u8DF3\u8FC7\u524D\u7F6E\u7684\u4EA4\u4E92\u5F0F\u914D\u7F6E\u6821\u9A8C\uFF08CI/\u5DF2\u786E\u8BA4\u914D\u7F6E\u65F6\u4F7F\u7528\uFF09").option("--skip-config-if-valid","\u5148\u6821\u9A8C\u914D\u7F6E\uFF1B\u65E0\u963B\u65AD\u9879\u65F6\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u76F4\u63A5\u5F00\u59CB\u642D\u5EFA").option("--no-ui","\u5F3A\u5236\u4F7F\u7528\u547D\u4EE4\u884C\u4EA4\u4E92\uFF08\u8DF3\u8FC7\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762\uFF09").action(async t=>{try{if(await _e(y.dirname(y.resolve(t.config)),M),!t.skipConfig){let e=t.ui!==!1,n=!1;if(t.skipConfigIfValid){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u9879\u76EE\u914D\u7F6E");let o=await Ie({configPath:t.config});if(n=ie({skipConfig:!1,skipConfigIfValid:!0,configValid:o.ok}),n){let r=[];o.summary.warnings>0&&r.push(`${o.summary.warnings} \u9879\u8B66\u544A`),o.summary.suggestions>0&&r.push(`${o.summary.suggestions} \u9879\u5EFA\u8BAE`);let i=r.length>0?`\uFF08${r.join("\uFF0C")}\uFF0C\u5747\u4E0D\u963B\u65AD\uFF09`:"";console.log(`\u2713 \u914D\u7F6E\u65E0\u963B\u65AD\u9879${i}\uFF0C\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u7EE7\u7EED\u642D\u5EFA\u3002`)}else console.log(`\u2139 \u68C0\u6D4B\u5230 ${o.summary.errors} \u9879\u963B\u65AD\uFF0C\u8FDB\u5165\u914D\u7F6E\u73AF\u8282\u3002`)}if(!n&&e){let{hasWebRoot:o,runConfigUI:r}=await import("./config-ui-server-7H5HRTRE.js");if(Ee({skipConfig:!1,skipConfigIfValid:t.skipConfigIfValid===!0,uiEnabled:e,webAvailable:o(),configValid:n})==="web"){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");try{await r({configPath:t.config}),n=(await Ie({configPath:t.config})).ok}catch(s){console.warn(`
33
+ `}c(bt,"generatePlist");function $(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}c($,"escapeXml");function Y(){let t=process.getuid?.();if(t===void 0)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237 UID\uFF08\u4EC5\u652F\u6301 macOS/Linux\uFF09");return t}c(Y,"getUid");async function be(t,e){if(!S())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let n=Re();ve(n);let o=await vt(t),r=oe(t),i=P(t);try{D(`launchctl bootout gui/${Y()}/${i} 2>/dev/null`,{encoding:"utf8"})}catch{}await wt(R.dirname(r),{recursive:!0});let s=bt(t,{maxTasks:e?.maxTasks,relayEnv:o,cliEntry:n});await ut(r,s,"utf8"),D(`launchctl bootstrap gui/${Y()} ${r}`,{encoding:"utf8"})}c(be,"enableAutostart");async function Se(t){if(!S())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=oe(t);try{D(`launchctl bootout gui/${Y()}/${e} 2>/dev/null`,{encoding:"utf8"})}catch{}await ht(n,{force:!0})}c(Se,"disableAutostart");async function re(t){if(!S())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=P(t),n=oe(t),o=!1;try{await yt(n),o=!0}catch{o=!1}let r=!1,i=!1,s=null;try{let a=D(`launchctl print gui/${Y()}/${e} 2>/dev/null`,{encoding:"utf8"});r=!0;let l=a.match(/pid\s*=\s*(\d+)/);l&&(s=parseInt(l[1],10),i=!0)}catch{r=!1}return{installed:o,loaded:r,running:i,pid:s}}c(re,"getAutostartStatus");import{createRequire as St}from"module";var Ee="aitable-workflow-",Et=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function Ie(){try{return St(import.meta.url)("../package.json")}catch{return{}}}c(Ie,"loadCliPackageManifest");function se(t){return t.version??"0.0.0"}c(se,"resolveCliVersion");function $e(t){let e=se(t),n={};t.name?.startsWith(Ee)&&(n[t.name]=e);for(let[o,r]of Object.entries(t.dependencies??{}))o.startsWith(Ee)&&(n[o]=Et.test(r)?r:e);return n}c($e,"resolveMonorepoPackageVersions");function ie(t){return t.skipConfig||t.skipConfigIfValid&&t.configValid===!0}c(ie,"canSkipSetupConfig");function Te(t){return ie(t)?"setup":t.uiEnabled&&t.webAvailable?"web":"cli"}c(Te,"resolveSetupConfigRoute");import y from"path";import{fileURLToPath as qt}from"url";import{watchFile as Jt,statSync as zt,openSync as Xt,readSync as Qt,closeSync as Zt,existsSync as Ce}from"fs";import{readFile as _e}from"fs/promises";var O=y.dirname(qt(import.meta.url));Le({override:!1,quiet:!0});Le({path:y.resolve(O,"..",".env"),override:!1,quiet:!0});var Oe=Ie(),M=se(Oe),Me=$e(Oe),k="./aitable-workflow.config.yml";function en(){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(en,"installLongRunningCrashGuards");var d=new G().name("aitable-workflow").description("\u901A\u7528\u4E1A\u52A1\u6D41\u7A0B\u5F15\u64CE \u2014 \u914D\u7F6E\u9A71\u52A8\u7684 AI \u8868\u683C\u5DE5\u4F5C\u6D41\u81EA\u52A8\u5316").version(M).option("-d, --debug","\u8F93\u51FA debug \u7EA7\u522B\u65E5\u5FD7\uFF08\u542B recipe \u5185\u90E8 log\uFF09").hook("preAction",async(t,e)=>{e.name()!=="init"&&await $t()}).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 Ct({config:t.config,force:!!t.force,yes:!!t.yes,template:t.template,profile:t.profile,templatesDir:y.resolve(O,"..","templates"),templatePackageVersions:Me,cliVersion:M})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","\u521D\u59CB\u5316\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("migrate").description("\u5347\u7EA7\u9879\u76EE\u76EE\u5F55\u5230\u6700\u65B0\u6A21\u677F\u7248\u672C\uFF0C\u81EA\u52A8\u4FDD\u7559\u7528\u6237\u914D\u7F6E").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u8DEF\u5F84",k).option("--dry-run","\u4EC5\u9884\u89C8\u53D8\u66F4\uFF0C\u4E0D\u5B9E\u9645\u5199\u5165").option("--no-backup","\u8DF3\u8FC7\u81EA\u52A8\u5907\u4EFD").option("--force","\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A").option("--template <name>","\u6307\u5B9A\u76EE\u6807\u6A21\u677F").option("--profile <name>","\u6307\u5B9A\u76EE\u6807 profile").option("--rollback","\u56DE\u6EDA\u5230\u4E0A\u4E00\u6B21\u8FC1\u79FB\u524D\u7684\u72B6\u6001").option("--list","\u5217\u51FA\u6240\u6709\u5907\u4EFD").action(async t=>{try{await Gt({config:t.config,dryRun:t.dryRun,noBackup:t.backup===!1,force:t.force,template:t.template,profile:t.profile,rollback:t.rollback,list:t.list,templatesDir:y.resolve(O,"..","templates"),templatePackageVersions:Me,cliVersion:M})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","migrate \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("design").description("\u8BA9 Coding Agent \u6839\u636E\u573A\u666F\u63CF\u8FF0\u751F\u6210\u5B8C\u6574\u7684 workflow \u548C recipes").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-y, --yes","\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u8865\u5145\uFF0C\u76F4\u63A5\u4F7F\u7528 config \u4E2D\u7684 scene").option("--skip-questions","\u8DF3\u8FC7\u6F84\u6E05\u95EE\u5377\uFF08\u4ECD\u4F1A\u4EA4\u4E92\u8865\u5145\u9700\u6C42\uFF09").action(async t=>{try{await _t(t)}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","design \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("setup").description("\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E\uFF0C\u518D\u521D\u59CB\u5316 AI \u8868\u683C\u7ED3\u6784 + \u7F16\u8BD1\u77E5\u8BC6\u5E93 \u2014 \u4E00\u6B21\u5B8C\u6210 config + \u5EFA\u8868").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--no-clean","\u4E0D\u6E05\u7406\u7A7A\u767D\u884C").option("--no-kb","\u8DF3\u8FC7\u77E5\u8BC6\u5E93\u7F16\u8BD1").option("--kb-full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1\u77E5\u8BC6\u5E93").option("--skip-config","\u8DF3\u8FC7\u524D\u7F6E\u7684\u4EA4\u4E92\u5F0F\u914D\u7F6E\u6821\u9A8C\uFF08CI/\u5DF2\u786E\u8BA4\u914D\u7F6E\u65F6\u4F7F\u7528\uFF09").option("--skip-config-if-valid","\u5148\u6821\u9A8C\u914D\u7F6E\uFF1B\u65E0\u963B\u65AD\u9879\u65F6\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u76F4\u63A5\u5F00\u59CB\u642D\u5EFA").option("--no-ui","\u5F3A\u5236\u4F7F\u7528\u547D\u4EE4\u884C\u4EA4\u4E92\uFF08\u8DF3\u8FC7\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762\uFF09").action(async t=>{try{if(await Pe(y.dirname(y.resolve(t.config)),M),!t.skipConfig){let e=t.ui!==!1,n=!1;if(t.skipConfigIfValid){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u9879\u76EE\u914D\u7F6E");let o=await xe({configPath:t.config});if(n=ie({skipConfig:!1,skipConfigIfValid:!0,configValid:o.ok}),n){let r=[];o.summary.warnings>0&&r.push(`${o.summary.warnings} \u9879\u8B66\u544A`),o.summary.suggestions>0&&r.push(`${o.summary.suggestions} \u9879\u5EFA\u8BAE`);let i=r.length>0?`\uFF08${r.join("\uFF0C")}\uFF0C\u5747\u4E0D\u963B\u65AD\uFF09`:"";console.log(`\u2713 \u914D\u7F6E\u65E0\u963B\u65AD\u9879${i}\uFF0C\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u7EE7\u7EED\u642D\u5EFA\u3002`)}else console.log(`\u2139 \u68C0\u6D4B\u5230 ${o.summary.errors} \u9879\u963B\u65AD\uFF0C\u8FDB\u5165\u914D\u7F6E\u73AF\u8282\u3002`)}if(!n&&e){let{hasWebRoot:o,runConfigUI:r}=await import("./config-ui-server-4BCW6GOE.js");if(Te({skipConfig:!1,skipConfigIfValid:t.skipConfigIfValid===!0,uiEnabled:e,webAvailable:o(),configValid:n})==="web"){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");try{await r({configPath:t.config}),n=(await xe({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-O7YLFPAN.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 Tt(t)}catch(e){g.error("cli","setup \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("run").description("\u542F\u52A8\u7F16\u6392\u5F15\u64CE\uFF0C\u5F00\u59CB\u8F6E\u8BE2\u5904\u7406\u5DE5\u5355").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async t=>{try{await _e(y.dirname(y.resolve(t.config)),M),Xt(),await Et();let e=await vt(t.config),n=!1,o=c(async()=>{n&&(g.warn("cli","\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),n=!0,g.info("cli","\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u7B49\u5F85\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u5B8C\u6210...");try{await e.stop()}finally{process.exit(0)}},"shutdown");process.on("SIGINT",o),process.on("SIGTERM",o),await e.start()}catch(e){g.error("cli","\u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("validate").description("\u9A8C\u8BC1\u914D\u7F6E\u6587\u4EF6\u548C\u5DE5\u4F5C\u6D41\u6A21\u677F").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async t=>{try{let e=await K(t.config);console.log("\u2713 \u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u901A\u8FC7");let n=await Ce(e.workflowTemplatePath,{envSource:e.envSource});console.log(`\u2713 \u5DE5\u4F5C\u6D41\u6A21\u677F\u9A8C\u8BC1\u901A\u8FC7: ${n.meta.name} (${n.orderedStepIds.length} \u6B65)`),console.log(`
38
+ `)}await Lt(t)}catch(e){g.error("cli","setup \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("run").description("\u542F\u52A8\u7F16\u6392\u5F15\u64CE\uFF0C\u5F00\u59CB\u8F6E\u8BE2\u5904\u7406\u5DE5\u5355").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async t=>{try{await Pe(y.dirname(y.resolve(t.config)),M),en(),await xt();let e=await It(t.config),n=!1,o=c(async()=>{n&&(g.warn("cli","\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),n=!0,g.info("cli","\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u7B49\u5F85\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u5B8C\u6210...");try{await e.stop()}finally{process.exit(0)}},"shutdown");process.on("SIGINT",o),process.on("SIGTERM",o),await e.start()}catch(e){g.error("cli","\u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("validate").description("\u9A8C\u8BC1\u914D\u7F6E\u6587\u4EF6\u548C\u5DE5\u4F5C\u6D41\u6A21\u677F").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async t=>{try{let e=await K(t.config);console.log("\u2713 \u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u901A\u8FC7");let n=await De(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 i=n.steps.find(a=>a.id===r),s=o<n.orderedStepIds.length-1?" \u2192":" \u2713";console.log(` ${o+1}. [${r}] ${i?.name??"?"}${s}`)}console.log(`
40
- \u914D\u7F6E\u6458\u8981:`),console.log(` AI \u8868\u683C: base=${e.tracker.base_id} table=${e.tracker.table_id}`),console.log(` \u5F15\u64CE: ${e.agent.engine}`),console.log(` \u8F6E\u8BE2\u95F4\u9694: ${e.polling.interval_ms}ms`)}catch(e){console.error(`\u2717 \u9A8C\u8BC1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});d.command("exec").description("\u9003\u751F\u8231\uFF1A\u5728\u5B9E\u4F8B\u4E0A\u4E0B\u6587\u4E0B\u8BD5\u8DD1\u4E00\u6761\u547D\u4EE4\uFF08\u590D\u7528 shell toolkit \u7684 bins \u89E3\u6790/\u8D85\u65F6/\u8131\u654F\uFF09\uFF0C\u7528\u4E8E dws/git \u547D\u4EE4\u9762 smoke\u3002\u7528\u6CD5\uFF1Aaitable-agent exec [-c <path>] [--json] -- <bin> <args...>").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--timeout <ms>","\u5355\u6B21\u6267\u884C\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").option("--json","\u4EE5 runJson \u65B9\u5F0F\u6267\u884C\uFF1A\u8981\u6C42 exit=0 \u4E14 stdout \u4E3A\u5408\u6CD5 JSON\uFF0C\u6253\u5370\u89E3\u6790\u540E\u7684\u5BF9\u8C61").allowUnknownOption().argument("<command...>","\u8981\u6267\u884C\u7684\u547D\u4EE4\u53CA\u53C2\u6570\uFF08\u5EFA\u8BAE\u7528 -- \u5206\u9694\uFF09\uFF0C\u5982\uFF1Adws chat group create --name x --format json").action(async(t,e)=>{try{let[n,...o]=t;n||(console.error("\u2717 \u672A\u63D0\u4F9B\u8981\u6267\u884C\u7684\u547D\u4EE4\uFF1B\u7528\u6CD5\uFF1Aaitable-agent exec [-c <path>] -- <bin> <args...>"),process.exit(1));let r=await K(e.config),i=St(r,n),s=e.timeout?Number.parseInt(e.timeout,10):void 0;if(s!==void 0&&(Number.isNaN(s)||s<=0)&&(console.error("\u2717 --timeout \u5FC5\u987B\u662F\u6B63\u6574\u6570\uFF08\u6BEB\u79D2\uFF09"),process.exit(1)),e.json){let l=await i.runJson(n,o,{timeoutMs:s});console.log(JSON.stringify(l??{},null,2));return}let a=await i.run(n,o,{timeoutMs:s});a.stdout&&process.stdout.write(a.stdout),a.stderr&&process.stderr.write(a.stderr),a.truncated&&console.error(`
41
- \u26A0\uFE0F \u8F93\u51FA\u56E0\u8D85\u8FC7\u4E0A\u9650\u88AB\u622A\u65AD`),process.exit(a.exitCode??0)}catch(n){console.error(`\u2717 exec \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});d.command("config").description("\u6821\u9A8C\u9879\u76EE\u914D\u7F6E\u5B8C\u6574\u6027\uFF0C\u5E76\u53EF\u4EA4\u4E92\u5F0F\u4FEE\u6539\u53C2\u6570").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u6821\u9A8C\u7684\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u6821\u9A8C\u5168\u90E8\uFF09").option("--json","JSON \u683C\u5F0F\u8F93\u51FA\u6821\u9A8C\u7ED3\u679C").option("--no-interactive","\u4EC5\u6821\u9A8C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u4FEE\u6539").action(async t=>{try{let{runConfigCommand:e}=await import("./config-command-O7YLFPAN.js");await e({configPath:t.config,workflowId:t.workflow,json:t.json,interactive:t.interactive})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","config \u547D\u4EE4\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("sync").description("\u68C0\u6D4B\u914D\u7F6E\u4E0E\u8868\u7684\u504F\u5DEE\uFF08\u5B57\u6BB5\u7C7B\u578B/\u9009\u9879 drift\uFF09\uFF0C\u8F93\u51FA\u8BCA\u65AD\u62A5\u544A\u548C\u4FEE\u590D\u5EFA\u8BAE").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-y, --yes","\u975E\u4EA4\u4E92\u6A21\u5F0F").action(async t=>{try{await Dt({configPath:t.config,yes:t.yes})}catch(e){g.error("cli","sync \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("agents").description("\u5217\u51FA\u5168\u90E8\u652F\u6301\u7684 Coding Agent \u9002\u914D\u5668\uFF0C\u5E76\u6807\u6CE8\u672C\u673A\u5DF2\u63A2\u6D4B\u5230\u5B89\u88C5\u7684").option("--json","\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action(t=>{try{let e=Ot();if(t.json){process.stdout.write(JSON.stringify(e,null,2)+`
40
+ \u914D\u7F6E\u6458\u8981:`),console.log(` AI \u8868\u683C: base=${e.tracker.base_id} table=${e.tracker.table_id}`),console.log(` \u5F15\u64CE: ${e.agent.engine}`),console.log(` \u8F6E\u8BE2\u95F4\u9694: ${e.polling.interval_ms}ms`)}catch(e){console.error(`\u2717 \u9A8C\u8BC1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});d.command("exec").description("\u9003\u751F\u8231\uFF1A\u5728\u5B9E\u4F8B\u4E0A\u4E0B\u6587\u4E0B\u8BD5\u8DD1\u4E00\u6761\u547D\u4EE4\uFF08\u590D\u7528 shell toolkit \u7684 bins \u89E3\u6790/\u8D85\u65F6/\u8131\u654F\uFF09\uFF0C\u7528\u4E8E dws/git \u547D\u4EE4\u9762 smoke\u3002\u7528\u6CD5\uFF1Aaitable-agent exec [-c <path>] [--json] -- <bin> <args...>").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--timeout <ms>","\u5355\u6B21\u6267\u884C\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").option("--json","\u4EE5 runJson \u65B9\u5F0F\u6267\u884C\uFF1A\u8981\u6C42 exit=0 \u4E14 stdout \u4E3A\u5408\u6CD5 JSON\uFF0C\u6253\u5370\u89E3\u6790\u540E\u7684\u5BF9\u8C61").allowUnknownOption().argument("<command...>","\u8981\u6267\u884C\u7684\u547D\u4EE4\u53CA\u53C2\u6570\uFF08\u5EFA\u8BAE\u7528 -- \u5206\u9694\uFF09\uFF0C\u5982\uFF1Adws chat group create --name x --format json").action(async(t,e)=>{try{let[n,...o]=t;n||(console.error("\u2717 \u672A\u63D0\u4F9B\u8981\u6267\u884C\u7684\u547D\u4EE4\uFF1B\u7528\u6CD5\uFF1Aaitable-agent exec [-c <path>] -- <bin> <args...>"),process.exit(1));let r=await K(e.config),i=Tt(r,n),s=e.timeout?Number.parseInt(e.timeout,10):void 0;if(s!==void 0&&(Number.isNaN(s)||s<=0)&&(console.error("\u2717 --timeout \u5FC5\u987B\u662F\u6B63\u6574\u6570\uFF08\u6BEB\u79D2\uFF09"),process.exit(1)),e.json){let l=await i.runJson(n,o,{timeoutMs:s});console.log(JSON.stringify(l??{},null,2));return}let a=await i.run(n,o,{timeoutMs:s});a.stdout&&process.stdout.write(a.stdout),a.stderr&&process.stderr.write(a.stderr),a.truncated&&console.error(`
41
+ \u26A0\uFE0F \u8F93\u51FA\u56E0\u8D85\u8FC7\u4E0A\u9650\u88AB\u622A\u65AD`),process.exit(a.exitCode??0)}catch(n){console.error(`\u2717 exec \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});d.command("config").description("\u6821\u9A8C\u9879\u76EE\u914D\u7F6E\u5B8C\u6574\u6027\uFF0C\u5E76\u53EF\u4EA4\u4E92\u5F0F\u4FEE\u6539\u53C2\u6570").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u6821\u9A8C\u7684\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u6821\u9A8C\u5168\u90E8\uFF09").option("--json","JSON \u683C\u5F0F\u8F93\u51FA\u6821\u9A8C\u7ED3\u679C").option("--no-interactive","\u4EC5\u6821\u9A8C\uFF0C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u4FEE\u6539").action(async t=>{try{let{runConfigCommand:e}=await import("./config-command-O7YLFPAN.js");await e({configPath:t.config,workflowId:t.workflow,json:t.json,interactive:t.interactive})}catch(e){e instanceof Error&&e.message.includes("cancelled")&&process.exit(0),g.error("cli","config \u547D\u4EE4\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("sync").description("\u68C0\u6D4B\u914D\u7F6E\u4E0E\u8868\u7684\u504F\u5DEE\uFF08\u5B57\u6BB5\u7C7B\u578B/\u9009\u9879 drift\uFF09\uFF0C\u8F93\u51FA\u8BCA\u65AD\u62A5\u544A\u548C\u4FEE\u590D\u5EFA\u8BAE").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-y, --yes","\u975E\u4EA4\u4E92\u6A21\u5F0F").action(async t=>{try{await Ut({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=Nt();if(t.json){process.stdout.write(JSON.stringify(e,null,2)+`
42
42
  `);return}let n=e.filter(o=>o.installed).length;console.log(`
43
43
  \u652F\u6301 ${e.length} \u4E2A Coding Agent\uFF0C\u672C\u673A\u5DF2\u63A2\u6D4B\u5230 ${n} \u4E2A\uFF1A
44
- `);for(let o of e){let r=o.installed?"\u2713":"\u2717",i=[o.bin,...o.fallbackBins].join(" / "),s=o.installed?`\u5DF2\u5B89\u88C5 (${o.detectedCmd}${o.detectedVersion?` ${o.detectedVersion}`:""})`:"\u672A\u63A2\u6D4B\u5230";console.log(` ${r} ${o.name.padEnd(16)} [${o.id}] bin: ${i.padEnd(24)} ${s}`)}console.log("")}catch(e){g.error("cli","\u5217\u51FA agents \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("serve").description("\u542F\u52A8\u672C\u5730 HTTP API \u670D\u52A1\u5E76\u6258\u7BA1 Web \u524D\u7AEF\u9875\u9762\uFF08local \u6A21\u5F0F\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF09").option("-p, --port <number>","\u76D1\u542C\u7AEF\u53E3\uFF08\u9ED8\u8BA4 8787\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_PORT \u8986\u76D6\uFF09").option("--host <host>","\u76D1\u542C\u5730\u5740\uFF08\u9ED8\u8BA4 127.0.0.1\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_HOST \u8986\u76D6\uFF09").option("--data-root <path>","\u9879\u76EE\u5DE5\u4F5C\u533A\u6570\u636E\u76EE\u5F55\uFF08\u9ED8\u8BA4 .sandbox/aitable-workflow-server\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_DATA_DIR \u8986\u76D6\uFF09").option("--web-root <path>","Web \u524D\u7AEF\u9759\u6001\u8D44\u6E90\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u968F CLI \u6253\u5305\u7684 dist/web\uFF09").option("--no-open","\u542F\u52A8\u540E\u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF08\u9ED8\u8BA4\u81EA\u52A8\u6253\u5F00\uFF09").action(async t=>{try{let e={};if(t.port!==void 0){let o=Number.parseInt(t.port,10);Number.isFinite(o)&&o>0&&(e.port=o)}if(t.host!==void 0&&(e.host=t.host),t.dataRoot!==void 0&&(e.dataRoot=t.dataRoot),t.webRoot!==void 0)e.webRoot=t.webRoot;else{let o=y.join(O,"web");if($e(y.join(o,"index.html")))e.webRoot=o;else{let r=y.resolve(O,"..","..","web","dist");$e(y.join(r,"index.html"))&&(e.webRoot=r)}}let n=Vt(e);if(await Wt(n),n.webRoot&&t.open!==!1){let o=n.host==="0.0.0.0"?"127.0.0.1":n.host;Qt(`http://${o}:${n.port}`)}}catch(e){g.error("cli","HTTP \u670D\u52A1\u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("start").description("\u4EE5\u540E\u53F0\u8FDB\u7A0B\u542F\u52A8 relay daemon").option("--agent <name>","Agent \u540D\u79F0\uFF08\u9ED8\u8BA4\u4F7F\u7528 activeAgent\uFF09").option("--server-url <url>","Gateway \u5730\u5740").option("--token <ownerToken>","owner-token").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `--agent <name>` \u6307\u5B9A\u3002");e=r.name}let n=await C({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:e,maxTasks:t.maxTasks}),o=await B({agentId:e,serverUrl:n.serverUrl,token:n.token,key:n.key,name:n.name??e,workspaceRoot:n.workspaceRoot,machineId:n.machineId,maxTasks:n.maxTasks});console.log("\u2705 Daemon \u5DF2\u542F\u52A8"),console.log(` Agent: ${e}`),console.log(` PID: ${o.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${e}/daemon.log`)}catch(e){g.error("cli","start \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("stop").description("\u505C\u6B62\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--all","\u505C\u6B62\u6240\u6709 daemon").action(async t=>{try{if(t.all){let e=await ae(),n=0;for(let o of e)await W(o.name)&&n++;console.log(`\u2705 \u5DF2\u505C\u6B62 ${n} \u4E2A daemon`)}else{let e=t.agent;if(!e){let o=await A();if(!o)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=o.name}let n=await W(e);console.log(n?`\u2705 Daemon "${e}" \u5DF2\u505C\u6B62`:`\u26A0\uFE0F Daemon "${e}" \u672A\u5728\u8FD0\u884C`)}}catch(e){g.error("cli","stop \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("restart").description("\u91CD\u542F\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=r.name}console.log(`\u{1F504} \u6B63\u5728\u91CD\u542F "${e}"...`),await W(e);let n=await C({name:e,maxTasks:t.maxTasks}),o=await B({agentId:e,serverUrl:n.serverUrl,token:n.token,key:n.key,name:n.name??e,workspaceRoot:n.workspaceRoot,machineId:n.machineId,maxTasks:n.maxTasks});console.log(`\u2705 Daemon \u5DF2\u91CD\u542F (PID: ${o.pid})`)}catch(e){g.error("cli","restart \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("status").description("\u67E5\u770B daemon \u72B6\u6001").option("--agent <name>","Agent \u540D\u79F0").option("-v, --verbose","\u5C55\u793A\u5B8C\u6574\u914D\u7F6E").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r){console.log("\u65E0\u6D3B\u8DC3 Agent");return}e=r.name}let n=await V(e),o=await A();if(console.log(`
44
+ `);for(let o of e){let r=o.installed?"\u2713":"\u2717",i=[o.bin,...o.fallbackBins].join(" / "),s=o.installed?`\u5DF2\u5B89\u88C5 (${o.detectedCmd}${o.detectedVersion?` ${o.detectedVersion}`:""})`:"\u672A\u63A2\u6D4B\u5230";console.log(` ${r} ${o.name.padEnd(16)} [${o.id}] bin: ${i.padEnd(24)} ${s}`)}console.log("")}catch(e){g.error("cli","\u5217\u51FA agents \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("serve").description("\u542F\u52A8\u672C\u5730 HTTP API \u670D\u52A1\u5E76\u6258\u7BA1 Web \u524D\u7AEF\u9875\u9762\uFF08local \u6A21\u5F0F\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF09").option("-p, --port <number>","\u76D1\u542C\u7AEF\u53E3\uFF08\u9ED8\u8BA4 8787\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_PORT \u8986\u76D6\uFF09").option("--host <host>","\u76D1\u542C\u5730\u5740\uFF08\u9ED8\u8BA4 127.0.0.1\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_HOST \u8986\u76D6\uFF09").option("--data-root <path>","\u9879\u76EE\u5DE5\u4F5C\u533A\u6570\u636E\u76EE\u5F55\uFF08\u9ED8\u8BA4 .sandbox/aitable-workflow-server\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_DATA_DIR \u8986\u76D6\uFF09").option("--web-root <path>","Web \u524D\u7AEF\u9759\u6001\u8D44\u6E90\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u968F CLI \u6253\u5305\u7684 dist/web\uFF09").option("--no-open","\u542F\u52A8\u540E\u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF08\u9ED8\u8BA4\u81EA\u52A8\u6253\u5F00\uFF09").action(async t=>{try{let e={};if(t.port!==void 0){let o=Number.parseInt(t.port,10);Number.isFinite(o)&&o>0&&(e.port=o)}if(t.host!==void 0&&(e.host=t.host),t.dataRoot!==void 0&&(e.dataRoot=t.dataRoot),t.webRoot!==void 0)e.webRoot=t.webRoot;else{let o=y.join(O,"web");if(Ce(y.join(o,"index.html")))e.webRoot=o;else{let r=y.resolve(O,"..","..","web","dist");Ce(y.join(r,"index.html"))&&(e.webRoot=r)}}let n=Ht(e);if(await Kt(n),n.webRoot&&t.open!==!1){let o=n.host==="0.0.0.0"?"127.0.0.1":n.host;ge(`http://${o}:${n.port}`)}}catch(e){g.error("cli","HTTP \u670D\u52A1\u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("start").description("\u4EE5\u540E\u53F0\u8FDB\u7A0B\u542F\u52A8 relay daemon").option("--agent <name>","Agent \u540D\u79F0\uFF08\u9ED8\u8BA4\u4F7F\u7528 activeAgent\uFF09").option("--server-url <url>","Gateway \u5730\u5740").option("--token <ownerToken>","owner-token").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `--agent <name>` \u6307\u5B9A\u3002");e=r.name}let n=await C({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:e,maxTasks:t.maxTasks}),o=await B({agentId:e,serverUrl:n.serverUrl,token:n.token,key:n.key,name:n.name??e,workspaceRoot:n.workspaceRoot,machineId:n.machineId,maxTasks:n.maxTasks});console.log("\u2705 Daemon \u5DF2\u542F\u52A8"),console.log(` Agent: ${e}`),console.log(` PID: ${o.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${e}/daemon.log`)}catch(e){g.error("cli","start \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("stop").description("\u505C\u6B62\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--all","\u505C\u6B62\u6240\u6709 daemon").action(async t=>{try{if(t.all){let e=await ae(),n=0;for(let o of e)await W(o.name)&&n++;console.log(`\u2705 \u5DF2\u505C\u6B62 ${n} \u4E2A daemon`)}else{let e=t.agent;if(!e){let o=await A();if(!o)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=o.name}let n=await W(e);console.log(n?`\u2705 Daemon "${e}" \u5DF2\u505C\u6B62`:`\u26A0\uFE0F Daemon "${e}" \u672A\u5728\u8FD0\u884C`)}}catch(e){g.error("cli","stop \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("restart").description("\u91CD\u542F\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=r.name}console.log(`\u{1F504} \u6B63\u5728\u91CD\u542F "${e}"...`),await W(e);let n=await C({name:e,maxTasks:t.maxTasks}),o=await B({agentId:e,serverUrl:n.serverUrl,token:n.token,key:n.key,name:n.name??e,workspaceRoot:n.workspaceRoot,machineId:n.machineId,maxTasks:n.maxTasks});console.log(`\u2705 Daemon \u5DF2\u91CD\u542F (PID: ${o.pid})`)}catch(e){g.error("cli","restart \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("status").description("\u67E5\u770B daemon \u72B6\u6001").option("--agent <name>","Agent \u540D\u79F0").option("-v, --verbose","\u5C55\u793A\u5B8C\u6574\u914D\u7F6E").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r){console.log("\u65E0\u6D3B\u8DC3 Agent");return}e=r.name}let n=await V(e),o=await A();if(console.log(`
45
45
  Agent: ${n.agentId}`),console.log(`Running: ${n.running?"\u2705 yes":"\u274C no"}`),n.pid&&console.log(`PID: ${n.pid}`),n.uptimeMs!==null){let r=Math.floor(n.uptimeMs/1e3),i=Math.floor(r/60),s=Math.floor(i/60);console.log(`Uptime: ${s}h ${i%60}m ${r%60}s`)}console.log(`Log file: ${n.logFile}`),t.verbose&&o&&(console.log(`
46
- --- Configuration ---`),console.log(`Server: ${o.serverUrl}`),console.log(`Token: ${H(o.token)}`),o.machineId&&console.log(`MachineID: ${o.machineId}`),o.workspaceRoot&&console.log(`Workspace: ${o.workspaceRoot}`)),console.log("")}catch(e){g.error("cli","status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("logs").description("\u67E5\u770B daemon \u65E5\u5FD7").option("--agent <name>","Agent \u540D\u79F0").option("-f, --follow","\u6301\u7EED\u8DDF\u8E2A\u65E5\u5FD7\u8F93\u51FA").option("-n <lines>","\u663E\u793A\u6700\u8FD1 N \u884C","50").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=r.name}let n=_(e),o=parseInt(t.n,10)||50;if(t.follow){let r=await Te(n,"utf8").catch(()=>"");if(r){let s=r.trimEnd().split(`
46
+ --- Configuration ---`),console.log(`Server: ${o.serverUrl}`),console.log(`Token: ${H(o.token)}`),o.machineId&&console.log(`MachineID: ${o.machineId}`),o.workspaceRoot&&console.log(`Workspace: ${o.workspaceRoot}`)),console.log("")}catch(e){g.error("cli","status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("logs").description("\u67E5\u770B daemon \u65E5\u5FD7").option("--agent <name>","Agent \u540D\u79F0").option("-f, --follow","\u6301\u7EED\u8DDF\u8E2A\u65E5\u5FD7\u8F93\u51FA").option("-n <lines>","\u663E\u793A\u6700\u8FD1 N \u884C","50").action(async t=>{try{let e=t.agent;if(!e){let r=await A();if(!r)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");e=r.name}let n=_(e),o=parseInt(t.n,10)||50;if(t.follow){let r=await _e(n,"utf8").catch(()=>"");if(r){let s=r.trimEnd().split(`
47
47
  `);console.log(s.slice(-o).join(`
48
- `))}let i=r.length;Gt(n,{interval:500},()=>{try{let s=Kt(n);if(s.size>i){let a=Ht(n,"r"),l=Buffer.alloc(s.size-i);qt(a,l,0,l.length,i),Jt(a),process.stdout.write(l.toString("utf8")),i=s.size}}catch{}})}else{let r=await Te(n,"utf8").catch(()=>"");if(!r){console.log(`\u6682\u65E0\u65E5\u5FD7 (${n})`);return}let i=r.trimEnd().split(`
48
+ `))}let i=r.length;Jt(n,{interval:500},()=>{try{let s=zt(n);if(s.size>i){let a=Xt(n,"r"),l=Buffer.alloc(s.size-i);Qt(a,l,0,l.length,i),Zt(a),process.stdout.write(l.toString("utf8")),i=s.size}}catch{}})}else{let r=await _e(n,"utf8").catch(()=>"");if(!r){console.log(`\u6682\u65E0\u65E5\u5FD7 (${n})`);return}let i=r.trimEnd().split(`
49
49
  `);console.log(i.slice(-o).join(`
50
- `))}}catch(e){g.error("cli","logs \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});var Zt=d.command("daemon").description("Daemon \u540E\u53F0\u5B88\u62A4\u7BA1\u7406");Zt.command("autostart").description("macOS \u5F00\u673A\u81EA\u542F\u7BA1\u7406").addCommand(new G("enable").description("\u542F\u7528 macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650").action(async t=>{try{E()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await Ae(t.agentId,{maxTasks:t.maxTasks?parseInt(t.maxTasks,10):void 0}),console.log("\u2705 \u81EA\u542F\u52A8\u5DF2\u542F\u7528"),console.log(` Agent: ${t.agentId}`),console.log(` Plist: ~/Library/LaunchAgents/com.alibaba.aitable-workflow.daemon.${t.agentId}.plist`)}catch(e){g.error("cli","autostart enable \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}})).addCommand(new G("disable").description("\u5173\u95ED macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").action(async t=>{try{E()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await Re(t.agentId),console.log(`\u2705 \u81EA\u542F\u52A8\u5DF2\u5173\u95ED (${t.agentId})`)}catch(e){g.error("cli","autostart disable \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}})).addCommand(new G("status").description("\u67E5\u770B macOS \u81EA\u542F\u52A8\u72B6\u6001").option("--agent-id <id>","Agent ID / \u540D\u79F0\uFF08\u4E0D\u6307\u5B9A\u5219\u5217\u51FA\u6240\u6709\uFF09").action(async t=>{try{if(E()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),t.agentId){let e=await re(t.agentId);console.log(`
51
- Agent: ${t.agentId}`),console.log(`Installed: ${e.installed?"yes":"no"}`),console.log(`Loaded: ${e.loaded?"yes":"no"}`),console.log(`Running: ${e.running?`yes (PID: ${e.pid})`:"no"}`),console.log("")}else{let e=await ae();if(e.length===0){console.log("\u65E0\u5DF2\u6CE8\u518C\u7684 Agent");return}for(let n of e){let o=await re(n.name),r=o.running?`running (PID: ${o.pid})`:o.loaded?"loaded":o.installed?"installed":"not installed";console.log(` ${n.name}: ${r}`)}}}catch(e){g.error("cli","autostart status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}}));d.command("connect").description("\u4E00\u952E\u6CE8\u518C + \u4FDD\u5B58\u51ED\u8BC1 + \u540E\u53F0\u542F\u52A8 daemon\uFF08\u5BF9\u6807 Harness connect\uFF09").requiredOption("--server-url <url>","Gateway / \u5E73\u53F0\u5730\u5740").option("--token <ownerToken>","owner-token\uFF08\u81EA\u6CE8\u518C\uFF0C\u4E0E --key \u4E8C\u9009\u4E00\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF0C\u4E0E --token \u4E8C\u9009\u4E00\uFF09").requiredOption("--name <name>","Agent \u540D\u79F0").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u53EF\u9009\uFF09").option("--no-start","\u53EA\u6CE8\u518C\u4E0D\u542F\u52A8 daemon").option("--foreground","\u6CE8\u518C\u540E\u5728\u524D\u53F0\u8FD0\u884C relay\uFF08\u963B\u585E\u7EC8\u7AEF\uFF0C\u4FBF\u4E8E\u8C03\u8BD5\uFF09").option("--force","\u8986\u76D6\u540C\u540D\u4F46\u7F51\u5173\u4E0D\u540C\u7684\u5DF2\u6709\u51ED\u8BC1").action(async t=>{try{if(!t.token&&!t.key)throw new Error("\u5FC5\u987B\u63D0\u4F9B --token\uFF08owner-token\uFF09\u6216 --key\uFF08per-machine key\uFF0Csk_machine_*\uFF09\u5176\u4E2D\u4E4B\u4E00\u3002");if(!t.force){let s=await Ft(t.name,t.serverUrl);s&&(console.error(`\u26A0\uFE0F \u62D2\u7EDD\u8986\u76D6\uFF1AAgent \u540D\u79F0 "${t.name}" \u5DF2\u7ED1\u5B9A\u5230\u53E6\u4E00\u4E2A\u7F51\u5173\u3002`),console.error(` \u65E7\u7F51\u5173: ${s.serverUrl}`),console.error(` \u65B0\u7F51\u5173: ${t.serverUrl}`),console.error(" \u7EE7\u7EED\u5C06\u8986\u76D6\u672C\u673A\u8BE5\u51ED\u8BC1\uFF0C\u4E14\u65E7\u7F51\u5173\u7684 daemon \u65E0\u6CD5\u4E0E\u65B0\u7684\u5171\u5B58\uFF08PID \u4E92\u65A5\uFF09\u3002"),console.error(" \u8BF7\u9009\u62E9\u5176\u4E00\uFF1A"),console.error(" 1) \u6362\u4E00\u4E2A --name\uFF08\u591A\u7F51\u5173\u5EFA\u8BAE\u6BCF\u4E2A\u7F51\u5173\u7528\u4E0D\u540C\u540D\u79F0\uFF09"),console.error(" 2) \u786E\u5B9E\u8981\u6539\u7ED1\uFF0C\u52A0 --force \u5F3A\u5236\u8986\u76D6"),process.exit(1))}let e=t.workspaceRoot?Z(t.workspaceRoot,t.name):void 0,n={name:t.name,serverUrl:t.serverUrl,token:t.token??"",key:t.key,workspaceRoot:e,createdAt:new Date().toISOString()};if(await Ut(n),console.log(`\u2705 Agent "${t.name}" \u5DF2\u6CE8\u518C\u5E76\u4FDD\u5B58\u51ED\u8BC1`),console.log(` Server: ${t.serverUrl}`),console.log(` ${t.token?"Token":"Key"}: ${H(t.token??t.key??"")}`),e&&console.log(` Workspace: ${e}`),console.log(" \u51ED\u8BC1\u6587\u4EF6: ~/.aitable-workflow/credentials.json"),!t.start){t.foreground&&console.log(`
50
+ `))}}catch(e){g.error("cli","logs \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});var tn=d.command("daemon").description("Daemon \u540E\u53F0\u5B88\u62A4\u7BA1\u7406");tn.command("autostart").description("macOS \u5F00\u673A\u81EA\u542F\u7BA1\u7406").addCommand(new G("enable").description("\u542F\u7528 macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650").action(async t=>{try{S()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await be(t.agentId,{maxTasks:t.maxTasks?parseInt(t.maxTasks,10):void 0}),console.log("\u2705 \u81EA\u542F\u52A8\u5DF2\u542F\u7528"),console.log(` Agent: ${t.agentId}`),console.log(` Plist: ~/Library/LaunchAgents/com.alibaba.aitable-workflow.daemon.${t.agentId}.plist`)}catch(e){g.error("cli","autostart enable \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}})).addCommand(new G("disable").description("\u5173\u95ED macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").action(async t=>{try{S()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await Se(t.agentId),console.log(`\u2705 \u81EA\u542F\u52A8\u5DF2\u5173\u95ED (${t.agentId})`)}catch(e){g.error("cli","autostart disable \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}})).addCommand(new G("status").description("\u67E5\u770B macOS \u81EA\u542F\u52A8\u72B6\u6001").option("--agent-id <id>","Agent ID / \u540D\u79F0\uFF08\u4E0D\u6307\u5B9A\u5219\u5217\u51FA\u6240\u6709\uFF09").action(async t=>{try{if(S()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),t.agentId){let e=await re(t.agentId);console.log(`
51
+ Agent: ${t.agentId}`),console.log(`Installed: ${e.installed?"yes":"no"}`),console.log(`Loaded: ${e.loaded?"yes":"no"}`),console.log(`Running: ${e.running?`yes (PID: ${e.pid})`:"no"}`),console.log("")}else{let e=await ae();if(e.length===0){console.log("\u65E0\u5DF2\u6CE8\u518C\u7684 Agent");return}for(let n of e){let o=await re(n.name),r=o.running?`running (PID: ${o.pid})`:o.loaded?"loaded":o.installed?"installed":"not installed";console.log(` ${n.name}: ${r}`)}}}catch(e){g.error("cli","autostart status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}}));d.command("connect").description("\u4E00\u952E\u6CE8\u518C + \u4FDD\u5B58\u51ED\u8BC1 + \u540E\u53F0\u542F\u52A8 daemon\uFF08\u5BF9\u6807 Harness connect\uFF09").requiredOption("--server-url <url>","Gateway / \u5E73\u53F0\u5730\u5740").option("--token <ownerToken>","owner-token\uFF08\u81EA\u6CE8\u518C\uFF0C\u4E0E --key \u4E8C\u9009\u4E00\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF0C\u4E0E --token \u4E8C\u9009\u4E00\uFF09").requiredOption("--name <name>","Agent \u540D\u79F0").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u53EF\u9009\uFF09").option("--no-start","\u53EA\u6CE8\u518C\u4E0D\u542F\u52A8 daemon").option("--foreground","\u6CE8\u518C\u540E\u5728\u524D\u53F0\u8FD0\u884C relay\uFF08\u963B\u585E\u7EC8\u7AEF\uFF0C\u4FBF\u4E8E\u8C03\u8BD5\uFF09").option("--force","\u8986\u76D6\u540C\u540D\u4F46\u7F51\u5173\u4E0D\u540C\u7684\u5DF2\u6709\u51ED\u8BC1").action(async t=>{try{if(!t.token&&!t.key)throw new Error("\u5FC5\u987B\u63D0\u4F9B --token\uFF08owner-token\uFF09\u6216 --key\uFF08per-machine key\uFF0Csk_machine_*\uFF09\u5176\u4E2D\u4E4B\u4E00\u3002");if(!t.force){let s=await Yt(t.name,t.serverUrl);s&&(console.error(`\u26A0\uFE0F \u62D2\u7EDD\u8986\u76D6\uFF1AAgent \u540D\u79F0 "${t.name}" \u5DF2\u7ED1\u5B9A\u5230\u53E6\u4E00\u4E2A\u7F51\u5173\u3002`),console.error(` \u65E7\u7F51\u5173: ${s.serverUrl}`),console.error(` \u65B0\u7F51\u5173: ${t.serverUrl}`),console.error(" \u7EE7\u7EED\u5C06\u8986\u76D6\u672C\u673A\u8BE5\u51ED\u8BC1\uFF0C\u4E14\u65E7\u7F51\u5173\u7684 daemon \u65E0\u6CD5\u4E0E\u65B0\u7684\u5171\u5B58\uFF08PID \u4E92\u65A5\uFF09\u3002"),console.error(" \u8BF7\u9009\u62E9\u5176\u4E00\uFF1A"),console.error(" 1) \u6362\u4E00\u4E2A --name\uFF08\u591A\u7F51\u5173\u5EFA\u8BAE\u6BCF\u4E2A\u7F51\u5173\u7528\u4E0D\u540C\u540D\u79F0\uFF09"),console.error(" 2) \u786E\u5B9E\u8981\u6539\u7ED1\uFF0C\u52A0 --force \u5F3A\u5236\u8986\u76D6"),process.exit(1))}let e=t.workspaceRoot?Z(t.workspaceRoot,t.name):void 0,n={name:t.name,serverUrl:t.serverUrl,token:t.token??"",key:t.key,workspaceRoot:e,createdAt:new Date().toISOString()};if(await Bt(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(`
52
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(`
53
53
  \u{1F4A1} \u542F\u52A8 daemon: aitable-workflow start \u6216 aitable-workflow relay`);return}if(t.foreground){console.log(`
54
54
  \u{1F680} \u524D\u53F0\u542F\u52A8 relay\uFF08Ctrl-C \u9000\u51FA\uFF09...`),await ee({serverUrl:t.serverUrl,token:t.token,key:t.key,name:t.name,workspaceRoot:e});return}let o=t.name,r=await C({serverUrl:t.serverUrl,token:t.token,key:t.key,workspaceRoot:t.workspaceRoot,name:o}),i=await B({agentId:o,serverUrl:r.serverUrl,token:r.token,key:r.key,name:r.name??o,workspaceRoot:r.workspaceRoot,machineId:r.machineId,maxTasks:r.maxTasks});console.log(`
55
55
  \u{1F680} Daemon \u5DF2\u540E\u53F0\u542F\u52A8`),console.log(` Agent: ${o}`),console.log(` PID: ${i.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${o}/daemon.log`),console.log(`
56
- \u{1F4CB} \u5E38\u7528\u547D\u4EE4\uFF1A`),console.log(` \u67E5\u770B\u72B6\u6001: aitable-workflow status --agent ${o}`),console.log(` \u8DDF\u8E2A\u65E5\u5FD7: aitable-workflow logs -f --agent ${o}`),console.log(` \u505C\u6B62: aitable-workflow stop --agent ${o}`),console.log(` \u91CD\u542F: aitable-workflow restart --agent ${o}`),console.log(" \u5217\u51FA Agent: aitable-workflow agent list"),console.log(" \u5207\u6362 Agent: aitable-workflow agent use <name>"),console.log(` \u5F00\u673A\u81EA\u542F: aitable-workflow daemon autostart enable --agent-id ${o}`)}catch(e){g.error("cli","connect \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});var q=d.command("agent").description("Agent \u51ED\u8BC1\u7BA1\u7406");q.command("list").description("\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684 Agent \u51ED\u8BC1").action(async()=>{try{let t=await ae();if(t.length===0){console.log("\u6682\u65E0\u5DF2\u4FDD\u5B58\u7684 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let e=await Nt();console.log(`
56
+ \u{1F4CB} \u5E38\u7528\u547D\u4EE4\uFF1A`),console.log(` \u67E5\u770B\u72B6\u6001: aitable-workflow status --agent ${o}`),console.log(` \u8DDF\u8E2A\u65E5\u5FD7: aitable-workflow logs -f --agent ${o}`),console.log(` \u505C\u6B62: aitable-workflow stop --agent ${o}`),console.log(` \u91CD\u542F: aitable-workflow restart --agent ${o}`),console.log(" \u5217\u51FA Agent: aitable-workflow agent list"),console.log(" \u5207\u6362 Agent: aitable-workflow agent use <name>"),console.log(` \u5F00\u673A\u81EA\u542F: aitable-workflow daemon autostart enable --agent-id ${o}`)}catch(e){g.error("cli","connect \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});var q=d.command("agent").description("Agent \u51ED\u8BC1\u7BA1\u7406");q.command("list").description("\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684 Agent \u51ED\u8BC1").action(async()=>{try{let t=await ae();if(t.length===0){console.log("\u6682\u65E0\u5DF2\u4FDD\u5B58\u7684 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let e=await Vt();console.log(`
57
57
  \u5DF2\u4FDD\u5B58 ${t.length} \u4E2A Agent\uFF08\u6D3B\u8DC3: ${e.activeAgent??"\u65E0"}\uFF09:
58
- `);for(let n of t){let o=n.name===e.activeAgent?" \u2190 active":"";console.log(` \u2022 ${n.name}${o}`),console.log(` Server: ${n.serverUrl}`),console.log(` Token: ${H(n.token)}`),n.machineId&&console.log(` MachineID: ${n.machineId}`),n.workspaceRoot&&console.log(` Workspace: ${n.workspaceRoot}`),console.log(` Created: ${n.createdAt}`)}console.log("")}catch(t){g.error("cli","agent list \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}});q.command("use <name>").description("\u5207\u6362\u6D3B\u8DC3 Agent").action(async t=>{try{let e=await jt(t);console.log(`\u2705 \u5DF2\u5207\u6362\u5230 Agent "${e.activeAgent}"`)}catch(e){g.error("cli","agent use \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});q.command("whoami").description("\u663E\u793A\u5F53\u524D\u6D3B\u8DC3 Agent").action(async()=>{try{let t=await A();if(!t){console.log("\u5F53\u524D\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `aitable-workflow agent use <name>` \u5207\u6362\u3002");return}console.log(`Agent: ${t.name}`),console.log(`Server: ${t.serverUrl}`),console.log(`Token: ${H(t.token)}`),t.machineId&&console.log(`MachineID: ${t.machineId}`),t.workspaceRoot&&console.log(`Workspace: ${t.workspaceRoot}`)}catch(t){g.error("cli","agent whoami \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}});q.command("status").description("\u67E5\u770B Agent \u8FDE\u63A5\u72B6\u6001\u4E0E\u8FD0\u884C\u65F6\u4FE1\u606F").option("--json","JSON \u683C\u5F0F\u8F93\u51FA").action(async t=>{try{let e=await A();if(!e){console.log("\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let n=await V(e.name),o=await te(e.name),r={agent:e.name,serverUrl:e.serverUrl,connectionState:n.running?o.connectionState:"stopped",machineId:o.machineId??e.machineId??null,lastHeartbeatAt:o.lastHeartbeatAt,runningTasks:o.runningTasks,queuedTasks:o.queuedTasks,lastDisconnectReason:o.lastDisconnectReason,pid:n.pid};if(t.json){process.stdout.write(JSON.stringify(r,null,2)+`
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 Wt(t);console.log(`\u2705 \u5DF2\u5207\u6362\u5230 Agent "${e.activeAgent}"`)}catch(e){g.error("cli","agent use \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});q.command("whoami").description("\u663E\u793A\u5F53\u524D\u6D3B\u8DC3 Agent").action(async()=>{try{let t=await A();if(!t){console.log("\u5F53\u524D\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `aitable-workflow agent use <name>` \u5207\u6362\u3002");return}console.log(`Agent: ${t.name}`),console.log(`Server: ${t.serverUrl}`),console.log(`Token: ${H(t.token)}`),t.machineId&&console.log(`MachineID: ${t.machineId}`),t.workspaceRoot&&console.log(`Workspace: ${t.workspaceRoot}`)}catch(t){g.error("cli","agent whoami \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}});q.command("status").description("\u67E5\u770B Agent \u8FDE\u63A5\u72B6\u6001\u4E0E\u8FD0\u884C\u65F6\u4FE1\u606F").option("--json","JSON \u683C\u5F0F\u8F93\u51FA").action(async t=>{try{let e=await A();if(!e){console.log("\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let n=await V(e.name),o=await te(e.name),r={agent:e.name,serverUrl:e.serverUrl,connectionState:n.running?o.connectionState:"stopped",machineId:o.machineId??e.machineId??null,lastHeartbeatAt:o.lastHeartbeatAt,runningTasks:o.runningTasks,queuedTasks:o.queuedTasks,lastDisconnectReason:o.lastDisconnectReason,pid:n.pid};if(t.json){process.stdout.write(JSON.stringify(r,null,2)+`
59
59
  `);return}let i=r.connectionState==="connected"?"\u{1F7E2}":r.connectionState==="reconnecting"?"\u{1F7E1}":"\u{1F534}";console.log(`
60
- ${i} Agent: ${r.agent}`),console.log(` Server: ${r.serverUrl}`),console.log(` Connection: ${r.connectionState}`),r.machineId&&console.log(` MachineID: ${r.machineId}`),r.lastHeartbeatAt&&console.log(` Last HB: ${r.lastHeartbeatAt}`),n.running&&(console.log(` PID: ${r.pid}`),console.log(` Tasks: ${r.runningTasks} running, ${r.queuedTasks} queued`)),r.lastDisconnectReason&&console.log(` Last Error: ${r.lastDisconnectReason}`),console.log("")}catch(e){g.error("cli","agent status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("heartbeat").description("\u5411\u670D\u52A1\u7AEF\u53D1\u9001\u5FC3\u8DF3\u5E76\u8FD4\u56DE\u4EFB\u52A1\u5206\u914D\u60C5\u51B5").action(async()=>{try{let t=await A();if(!t)throw new Error("\u65E0\u6D3B\u8DC3 Agent");if(!(await V(t.name)).running){console.log("\u26A0\uFE0F Daemon \u672A\u5728\u8FD0\u884C\u3002\u4F7F\u7528 `aitable-workflow start` \u542F\u52A8\u3002");return}let n=await te(t.name);console.log("\u2705 Heartbeat OK"),console.log(` Agent: ${t.name}`),console.log(` Connection: ${n.connectionState}`),console.log(` Running: ${n.runningTasks} tasks`),console.log(` Queued: ${n.queuedTasks} tasks`),n.lastHeartbeatAt&&console.log(` Last HB: ${n.lastHeartbeatAt}`)}catch(t){g.error("cli","heartbeat \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}});d.command("relay").description("\u4EE5\u672C\u673A relay \u5B88\u62A4\u8EAB\u4EFD\u53CD\u8FDE RelayGateway\uFF0C\u6309\u9700\u5728\u672C\u673A\u6267\u884C Agent/dws \u4EFB\u52A1").option("--server-url <url>","Gateway \u5730\u5740\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_SERVER_URL\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--token <ownerToken>","owner-token \u81EA\u6CE8\u518C\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_TOKEN\uFF1B\u4F18\u5148\u4E8E --key\uFF09").option("--name <name>","\u81EA\u6CE8\u518C\u673A\u5668\u540D\uFF08\u53EF\u9009\uFF0C\u7F3A\u7701\u81EA\u52A8\u4F7F\u7528\u4E3B\u673A\u540D\uFF1Bowner+name \u5E42\u7B49\u952E\uFF0C\u591A\u673A\u573A\u666F\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A\u4EE5\u907F\u514D hostname \u51B2\u7A81\u4E92\u76F8\u9876\u8FDE\u63A5\uFF1B\u4E5F\u53EF\u7528 AITABLE_RELAY_NAME\uFF09").option("--desc <description>","\u81EA\u6CE8\u518C\u673A\u5668\u63CF\u8FF0\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_DESC\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_WORKSPACE_ROOT\uFF09").option("--machine-id <id>","\u7A33\u5B9A\u673A\u5668\u8EAB\u4EFD\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MACHINE_ID\uFF09").option("--max-tasks <n>","\u672C\u673A\u5E76\u53D1\u6267\u884C\u4E0A\u9650\uFF0C\u9ED8\u8BA4 1\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_TASKS\uFF09").action(t=>{try{ee(t)}catch(e){g.error("cli","relay \u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("inspect [recordId]").description("\u67E5\u770B\u5DE5\u5355\u6267\u884C trace\uFF1B\u6216\u7528 --recipes / --validate \u67E5\u770B\u6821\u9A8C recipe schema \u4E0E workflow \u5BF9\u9F50").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-s, --step <stepId>","\u67E5\u770B\u7279\u5B9A\u6B65\u9AA4").option("-l, --latest","\u67E5\u770B\u6700\u8FD1\u6267\u884C").option("-n, --limit <number>","\u6700\u591A\u663E\u793A\u6761\u6570","10").option("--recipes","\u5217\u51FA\u5404\u6B65\u9AA4 recipe \u7684 input / output / config schema\u4E0E step \u914D\u7F6E").option("--validate","\u6821\u9A8C step.config / input_mapping / output_mapping \u662F\u5426\u7B26\u5408 recipe schema").option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u53D6\u7B2C\u4E00\u4E2A\uFF09").action(async(t,e)=>{try{if(e.recipes||e.validate){await en(e);return}let n=await K(e.config),o=y.resolve(n.configDir,n.agent.trace_dir),r=new Mt(o),i=parseInt(e.limit,10)||10,s;if(e.latest||!t){if(s=await r.getLatestTraces(i),s.length===0){console.log("\u26A0\uFE0F \u6682\u65E0 trace \u8BB0\u5F55\u3002\u8FD0\u884C `run` \u547D\u4EE4\u540E\u518D\u67E5\u770B\u3002");return}console.log(`
60
+ ${i} Agent: ${r.agent}`),console.log(` Server: ${r.serverUrl}`),console.log(` Connection: ${r.connectionState}`),r.machineId&&console.log(` MachineID: ${r.machineId}`),r.lastHeartbeatAt&&console.log(` Last HB: ${r.lastHeartbeatAt}`),n.running&&(console.log(` PID: ${r.pid}`),console.log(` Tasks: ${r.runningTasks} running, ${r.queuedTasks} queued`)),r.lastDisconnectReason&&console.log(` Last Error: ${r.lastDisconnectReason}`),console.log("")}catch(e){g.error("cli","agent status \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("heartbeat").description("\u5411\u670D\u52A1\u7AEF\u53D1\u9001\u5FC3\u8DF3\u5E76\u8FD4\u56DE\u4EFB\u52A1\u5206\u914D\u60C5\u51B5").action(async()=>{try{let t=await A();if(!t)throw new Error("\u65E0\u6D3B\u8DC3 Agent");if(!(await V(t.name)).running){console.log("\u26A0\uFE0F Daemon \u672A\u5728\u8FD0\u884C\u3002\u4F7F\u7528 `aitable-workflow start` \u542F\u52A8\u3002");return}let n=await te(t.name);console.log("\u2705 Heartbeat OK"),console.log(` Agent: ${t.name}`),console.log(` Connection: ${n.connectionState}`),console.log(` Running: ${n.runningTasks} tasks`),console.log(` Queued: ${n.queuedTasks} tasks`),n.lastHeartbeatAt&&console.log(` Last HB: ${n.lastHeartbeatAt}`)}catch(t){g.error("cli","heartbeat \u5931\u8D25",{error:t instanceof Error?t.message:String(t)}),process.exit(1)}});d.command("relay").description("\u4EE5\u672C\u673A relay \u5B88\u62A4\u8EAB\u4EFD\u53CD\u8FDE RelayGateway\uFF0C\u6309\u9700\u5728\u672C\u673A\u6267\u884C Agent/dws \u4EFB\u52A1").option("--server-url <url>","Gateway \u5730\u5740\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_SERVER_URL\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--token <ownerToken>","owner-token \u81EA\u6CE8\u518C\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_TOKEN\uFF1B\u4F18\u5148\u4E8E --key\uFF09").option("--name <name>","\u81EA\u6CE8\u518C\u673A\u5668\u540D\uFF08\u53EF\u9009\uFF0C\u7F3A\u7701\u81EA\u52A8\u4F7F\u7528\u4E3B\u673A\u540D\uFF1Bowner+name \u5E42\u7B49\u952E\uFF0C\u591A\u673A\u573A\u666F\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A\u4EE5\u907F\u514D hostname \u51B2\u7A81\u4E92\u76F8\u9876\u8FDE\u63A5\uFF1B\u4E5F\u53EF\u7528 AITABLE_RELAY_NAME\uFF09").option("--desc <description>","\u81EA\u6CE8\u518C\u673A\u5668\u63CF\u8FF0\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_DESC\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_WORKSPACE_ROOT\uFF09").option("--machine-id <id>","\u7A33\u5B9A\u673A\u5668\u8EAB\u4EFD\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MACHINE_ID\uFF09").option("--max-tasks <n>","\u672C\u673A\u5E76\u53D1\u6267\u884C\u4E0A\u9650\uFF0C\u9ED8\u8BA4 1\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_TASKS\uFF09").action(t=>{try{ee(t)}catch(e){g.error("cli","relay \u542F\u52A8\u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}});d.command("inspect [recordId]").description("\u67E5\u770B\u5DE5\u5355\u6267\u884C trace\uFF1B\u6216\u7528 --recipes / --validate \u67E5\u770B\u6821\u9A8C recipe schema \u4E0E workflow \u5BF9\u9F50").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("-s, --step <stepId>","\u67E5\u770B\u7279\u5B9A\u6B65\u9AA4").option("-l, --latest","\u67E5\u770B\u6700\u8FD1\u6267\u884C").option("-n, --limit <number>","\u6700\u591A\u663E\u793A\u6761\u6570","10").option("--recipes","\u5217\u51FA\u5404\u6B65\u9AA4 recipe \u7684 input / output / config schema\u4E0E step \u914D\u7F6E").option("--validate","\u6821\u9A8C step.config / input_mapping / output_mapping \u662F\u5426\u7B26\u5408 recipe schema").option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u53D6\u7B2C\u4E00\u4E2A\uFF09").action(async(t,e)=>{try{if(e.recipes||e.validate){await nn(e);return}let n=await K(e.config),o=y.resolve(n.configDir,n.agent.trace_dir),r=new Ft(o),i=parseInt(e.limit,10)||10,s;if(e.latest||!t){if(s=await r.getLatestTraces(i),s.length===0){console.log("\u26A0\uFE0F \u6682\u65E0 trace \u8BB0\u5F55\u3002\u8FD0\u884C `run` \u547D\u4EE4\u540E\u518D\u67E5\u770B\u3002");return}console.log(`
61
61
  \u{1F4C4} \u6700\u8FD1 ${s.length} \u6761\u6267\u884C\u8BB0\u5F55:
62
62
  `)}else{if(s=await r.getTraces(t),s.length===0){console.log(`\u26A0\uFE0F \u672A\u627E\u5230\u5DE5\u5355 ${t} \u7684 trace \u8BB0\u5F55\u3002`);return}e.step&&(s=s.filter(a=>a.step_id===e.step)),console.log(`
63
63
  \u{1F4C4} \u5DE5\u5355 ${t} \u7684\u6267\u884C\u5386\u53F2 (${s.length} \u6B65):
64
- `)}for(let a of s){let l=a.status==="success"?"\u2705":a.status==="failed"?"\u274C":"\u23F8\uFE0F",m=(a.duration_ms/1e3).toFixed(1);console.log(`${l} [${a.step_id}] ${a.step_name} \u2014 ${m}s \u2014 ${a.status.toUpperCase()}`);for(let[h,w]of a.llm_calls.entries()){let f=h===a.llm_calls.length-1,T=f?" \u2514\u2500":" \u251C\u2500",ce=f?" ":" \u2502 ",Pe=(w.duration_ms/1e3).toFixed(1);console.log(`${T} LLM: ${w.model} (${Pe}s)`),console.log(`${ce}Input: ${w.prompt_summary.slice(0,80)}${w.prompt_summary.length>80?"...":""}`),console.log(`${ce}Output: ${w.response_summary.slice(0,100)}${w.response_summary.length>100?"...":""}`)}if(Object.keys(a.outputs).length>0){let h=Object.entries(a.outputs).map(([w,f])=>`${w}=${typeof f=="string"?f.slice(0,50):JSON.stringify(f)}`).join(", ");console.log(` \u2514\u2500 Outputs: ${h}`)}a.error&&console.log(` \u2514\u2500 Error: ${a.error}`),console.log()}}catch(n){console.error(`\u2717 inspect \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});var J=d.command("kb").description("\u77E5\u8BC6\u5E93(LLM-Wiki)\u7F16\u8BD1\u4E0E\u72B6\u6001\u7BA1\u7406");J.command("compile [collections...]").description("\u7F16\u8BD1\u77E5\u8BC6\u5E93\u4E3A wiki\uFF08\u4E0D\u6307\u5B9A collection \u65F6\u7F16\u8BD1\u89D2\u8272\u58F0\u660E\u7684\u5168\u90E8\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1").action(async(t,e)=>{try{await xt(t,e)}catch(n){console.error(`\u2717 kb compile \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("update [collections...]").description("\u6E90\u6587\u6863\u53D8\u66F4\u540E\u89E6\u53D1\u589E\u91CF\u7F16\u8BD1\uFF08\u672A\u53D8\u66F4\u5219\u8DF3\u8FC7\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async(t,e)=>{try{await Ct(t,e)}catch(n){console.error(`\u2717 kb update \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("status [collections...]").description("\u67E5\u770B\u77E5\u8BC6\u5E93\u7F16\u8BD1\u72B6\u6001\uFF08\u7F16\u8BD1\u4E2D/\u5B8C\u6210/\u5931\u8D25 + \u6E90\u662F\u5426\u5DF2\u53D8\u66F4\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async(t,e)=>{try{await _t(t,e)}catch(n){console.error(`\u2717 kb status \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("ingest <url-or-path>").description("\u5BFC\u5165\u6587\u6863\u5230 wiki \u76EE\u5F55\uFF08\u652F\u6301\u9489\u9489 URL \u6216\u672C\u5730\u8DEF\u5F84\uFF0Cdocx/pdf \u81EA\u52A8\u8F6C md\uFF09").option("-o, --output <dir>","\u8F93\u51FA\u76EE\u5F55\uFF08\u9ED8\u8BA4 ./wiki\uFF09").option("-t, --type <type>","\u6E90\u7C7B\u578B: dingtalk-doc\uFF08\u4E0D\u4F20\u5219\u81EA\u52A8\u8BC6\u522B\uFF09").option("--flat","\u4E0D\u4FDD\u7559\u8FDC\u7AEF\u76EE\u5F55\u7ED3\u6784\uFF08\u6240\u6709\u6587\u6863\u5E73\u94FA\u5230\u8F93\u51FA\u76EE\u5F55\uFF09").option("--force","\u5F3A\u5236\u91CD\u65B0\u62C9\u53D6\u6240\u6709\u6587\u6863\uFF08\u5FFD\u7565\u589E\u91CF\u5224\u65AD\uFF09").option("--compile","\u5BFC\u5165\u540E\u81EA\u52A8\u89E6\u53D1 kb compile").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--timeout <ms>","\u5355\u6587\u6863\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").action(async(t,e)=>{try{await Lt(t,e)}catch(n){console.error(`\u2717 kb ingest \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});async function en(t){let e=await K(t.config),n=t.workflow?e.workflowEntries.find(s=>s.id===t.workflow):e.workflowEntries[0];n||(console.error(`\u2717 \u672A\u627E\u5230\u5DE5\u4F5C\u6D41\u300C${t.workflow}\u300D\u3002\u53EF\u7528\uFF1A${e.workflowEntries.map(s=>s.id).join(", ")}`),process.exit(1));let o=await Ce(n.templatePath,{envSource:e.envSource}),{issues:r,rows:i}=await Pt(n.recipeDir,o);if(t.recipes){console.log(`
64
+ `)}for(let a of s){let l=a.status==="success"?"\u2705":a.status==="failed"?"\u274C":"\u23F8\uFE0F",m=(a.duration_ms/1e3).toFixed(1);console.log(`${l} [${a.step_id}] ${a.step_name} \u2014 ${m}s \u2014 ${a.status.toUpperCase()}`);for(let[h,w]of a.llm_calls.entries()){let f=h===a.llm_calls.length-1,T=f?" \u2514\u2500":" \u251C\u2500",ce=f?" ":" \u2502 ",Ue=(w.duration_ms/1e3).toFixed(1);console.log(`${T} LLM: ${w.model} (${Ue}s)`),console.log(`${ce}Input: ${w.prompt_summary.slice(0,80)}${w.prompt_summary.length>80?"...":""}`),console.log(`${ce}Output: ${w.response_summary.slice(0,100)}${w.response_summary.length>100?"...":""}`)}if(Object.keys(a.outputs).length>0){let h=Object.entries(a.outputs).map(([w,f])=>`${w}=${typeof f=="string"?f.slice(0,50):JSON.stringify(f)}`).join(", ");console.log(` \u2514\u2500 Outputs: ${h}`)}a.error&&console.log(` \u2514\u2500 Error: ${a.error}`),console.log()}}catch(n){console.error(`\u2717 inspect \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});var J=d.command("kb").description("\u77E5\u8BC6\u5E93(LLM-Wiki)\u7F16\u8BD1\u4E0E\u72B6\u6001\u7BA1\u7406");J.command("compile [collections...]").description("\u7F16\u8BD1\u77E5\u8BC6\u5E93\u4E3A wiki\uFF08\u4E0D\u6307\u5B9A collection \u65F6\u7F16\u8BD1\u89D2\u8272\u58F0\u660E\u7684\u5168\u90E8\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1").action(async(t,e)=>{try{await Dt(t,e)}catch(n){console.error(`\u2717 kb compile \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("update [collections...]").description("\u6E90\u6587\u6863\u53D8\u66F4\u540E\u89E6\u53D1\u589E\u91CF\u7F16\u8BD1\uFF08\u672A\u53D8\u66F4\u5219\u8DF3\u8FC7\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async(t,e)=>{try{await Pt(t,e)}catch(n){console.error(`\u2717 kb update \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("status [collections...]").description("\u67E5\u770B\u77E5\u8BC6\u5E93\u7F16\u8BD1\u72B6\u6001\uFF08\u7F16\u8BD1\u4E2D/\u5B8C\u6210/\u5931\u8D25 + \u6E90\u662F\u5426\u5DF2\u53D8\u66F4\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).action(async(t,e)=>{try{await Ot(t,e)}catch(n){console.error(`\u2717 kb status \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});J.command("ingest <url-or-path>").description("\u5BFC\u5165\u6587\u6863\u5230 wiki \u76EE\u5F55\uFF08\u652F\u6301\u9489\u9489 URL \u6216\u672C\u5730\u8DEF\u5F84\uFF0Cdocx/pdf \u81EA\u52A8\u8F6C md\uFF09").option("-o, --output <dir>","\u8F93\u51FA\u76EE\u5F55\uFF08\u9ED8\u8BA4 ./wiki\uFF09").option("-t, --type <type>","\u6E90\u7C7B\u578B: dingtalk-doc\uFF08\u4E0D\u4F20\u5219\u81EA\u52A8\u8BC6\u522B\uFF09").option("--flat","\u4E0D\u4FDD\u7559\u8FDC\u7AEF\u76EE\u5F55\u7ED3\u6784\uFF08\u6240\u6709\u6587\u6863\u5E73\u94FA\u5230\u8F93\u51FA\u76EE\u5F55\uFF09").option("--force","\u5F3A\u5236\u91CD\u65B0\u62C9\u53D6\u6240\u6709\u6587\u6863\uFF08\u5FFD\u7565\u589E\u91CF\u5224\u65AD\uFF09").option("--compile","\u5BFC\u5165\u540E\u81EA\u52A8\u89E6\u53D1 kb compile").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",k).option("--timeout <ms>","\u5355\u6587\u6863\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").action(async(t,e)=>{try{await Mt(t,e)}catch(n){console.error(`\u2717 kb ingest \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}});async function nn(t){let e=await K(t.config),n=t.workflow?e.workflowEntries.find(s=>s.id===t.workflow):e.workflowEntries[0];n||(console.error(`\u2717 \u672A\u627E\u5230\u5DE5\u4F5C\u6D41\u300C${t.workflow}\u300D\u3002\u53EF\u7528\uFF1A${e.workflowEntries.map(s=>s.id).join(", ")}`),process.exit(1));let o=await De(n.templatePath,{envSource:e.envSource}),{issues:r,rows:i}=await jt(n.recipeDir,o);if(t.recipes){console.log(`
65
65
  \u{1F4CB} \u5DE5\u4F5C\u6D41\u300C${o.meta.name}\u300D(${n.id}) \u7684 recipe schema:
66
66
  `);for(let s of i){let a=s.configSummary.length>0?s.configSummary.join(", "):"(none)",l=s.loaded?"":" \u26A0 \u52A0\u8F7D\u5931\u8D25";console.log(` [${s.stepId} \u2192 ${s.recipeId}]${l}`),console.log(` config: ${a}`),console.log()}}if(t.validate)if(r.length===0)console.log(`
67
67
  \u2705 \u5DE5\u4F5C\u6D41\u300C${o.meta.name}\u300D(${n.id}) \u5168\u90E8\u6B65\u9AA4\u6821\u9A8C\u901A\u8FC7
68
68
  `);else{let s=r.filter(l=>l.level==="error"),a=r.filter(l=>l.level==="warn");console.log(`
69
69
  \u6821\u9A8C\u7ED3\u679C\uFF1A${s.length} \u4E2A\u9519\u8BEF\uFF0C${a.length} \u4E2A\u8B66\u544A
70
- `);for(let l of r){let m=l.level==="error"?"\u274C":"\u26A0\uFE0F ";console.log(` ${m} [${l.stepId} \u2192 ${l.recipeId}] ${l.message}`)}console.log(),s.length>0&&process.exit(1)}}c(en,"runRecipeInspect");await d.parseAsync();
70
+ `);for(let l of r){let m=l.level==="error"?"\u274C":"\u26A0\uFE0F ";console.log(` ${m} [${l.stepId} \u2192 ${l.recipeId}] ${l.message}`)}console.log(),s.length>0&&process.exit(1)}}c(nn,"runRecipeInspect");await d.parseAsync();
@@ -0,0 +1,8 @@
1
+ import{a as H}from"./chunk-IG7PZYXN.js";import{l as U,n as L,p as F,q as M}from"./chunk-FW6MXYUM.js";import{a as g}from"./chunk-EI7MMDWY.js";import{createServer as rt}from"http";import{stat as Y,readFile as E,mkdir as W,writeFile as z,rm as st}from"fs/promises";import{createReadStream as it,existsSync as D}from"fs";import w from"path";import{fileURLToPath as at}from"url";import ct from"crypto";import lt from"os";import B from"yaml";import{runCheck as C,writeBack as G,resolveConfigPath as V,loadSettings as ft,detectCodingEngines as ut,loadWorkflowTemplate as dt,collectEnvRefs as mt,resolveInsideRoot as x,assertPortableId as K}from"aitable-workflow-core";var X=w.dirname(at(import.meta.url)),pt={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".ico":"image/x-icon"},gt=1800*1e3;function ht(){return process.platform==="darwin"||process.platform==="win32"||process.env.DISPLAY||process.env.WAYLAND_DISPLAY?"local-gui":"remote"}g(ht,"detectEnvironment");function Q(){let n=w.join(X,"web");if(D(w.join(n,"index.html")))return n;let e=w.resolve(X,"..","..","..","web","dist");return D(w.join(e,"index.html"))?e:null}g(Q,"resolveWebRoot");function Nt(){return Q()!==null}g(Nt,"hasWebRoot");async function q(n){let{createServer:e}=await import("net");return new Promise((t,r)=>{let i=e();i.listen(n,()=>{let m=i.address(),o=typeof m=="object"&&m?m.port:n;i.close(()=>t(o))}),i.on("error",()=>{n<8800?q(n+1).then(t,r):r(new Error("\u65E0\u6CD5\u627E\u5230\u53EF\u7528\u7AEF\u53E3 (8788-8800)"))})})}g(q,"getAvailablePort");var wt=1024*1024,vt=50*1024*1024;async function $(n,e=wt){return new Promise((t,r)=>{let i=[],m=0;n.on("data",o=>{if(m+=o.length,m>e){n.destroy(),r(new Error("Request body too large"));return}i.push(o)}),n.on("end",()=>{try{t(JSON.parse(Buffer.concat(i).toString("utf8")))}catch{r(new Error("Invalid JSON body"))}}),n.on("error",r)})}g($,"readJson");function R(n,e,t=200){let r=JSON.stringify(e);n.writeHead(t,{"Content-Type":"application/json; charset=utf-8","Content-Length":Buffer.byteLength(r)}),n.end(r)}g(R,"sendJson");function y(n,e,t){R(n,{ok:!1,error:t},e)}g(y,"sendError");function P(n){let e=JSON.parse(JSON.stringify(n));for(let t of e.modules){let r=t.workflows?t.workflows.flatMap(i=>i.items):t.items;for(let i of r)i.sensitive&&i.value!==void 0&&(i.value="***")}return e}g(P,"maskSensitive");function tt(n){let e=[];for(let t of n.modules)if(t.workflows)for(let r of t.workflows)e.push(...r.items);else e.push(...t.items);return e}g(tt,"collectAllItems");function yt(n,e){for(let t of n){let r=tt(e).find(i=>{if(!i.writeTarget)return!1;let m=i.writeTarget,o=t.writeTarget;return m.type!==o.type?!1:m.type==="yaml"&&o.type==="yaml"?m.file===o.file&&JSON.stringify(m.yamlPath)===JSON.stringify(o.yamlPath):!1});if(r&&M(r)&&t.value.trim().length>0)return t.value.trim()}return null}g(yt,"findSavedBaseId");async function jt(n){let e=await q(8788),t=ht(),r=ct.randomUUID(),i=t==="remote"?"0.0.0.0":"127.0.0.1",m=Q();if(!m)throw new Error("Web \u8D44\u6E90\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u542F\u52A8\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");let o=await V(n.configPath),u=w.dirname(o),l=null,f=new Promise(v=>l=v),a=null,c=g(()=>{a&&clearTimeout(a),a=setTimeout(()=>{console.log(`
2
+ \u2139 \u914D\u7F6E\u754C\u9762\u8D85\u8FC7 30 \u5206\u949F\u65E0\u6D3B\u52A8\uFF0C\u5DF2\u81EA\u52A8\u5173\u95ED\u3002`),l?.()},gt)},"resetTimeout"),d=rt(async(v,s)=>{let p=new URL(v.url??"/",`http://${v.headers.host??"localhost"}`),k=v.headers.origin;if(k){let _=`http://127.0.0.1:${e}`;(k===_||t==="remote")&&s.setHeader("Access-Control-Allow-Origin",k)}if(s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),v.method==="OPTIONS"){s.writeHead(204),s.end();return}if(p.pathname.startsWith("/dev/")){if((p.searchParams.get("token")??v.headers.authorization?.replace("Bearer ",""))!==r){y(s,401,"Unauthorized");return}c();try{await kt(p,v,s,n.configPath,u,l)}catch(I){let b=I instanceof Error?I.message:String(I);y(s,500,b)}return}Rt(p,s,m)});await new Promise(v=>d.listen(e,i,v)),c();let T=t==="local-gui"?`http://127.0.0.1:${e}/setup?token=${r}`:`http://${lt.hostname()}:${e}/setup?token=${r}`;t==="local-gui"?(H(T),console.log(`\u2139 \u6D4F\u89C8\u5668\u5DF2\u6253\u5F00: ${T}`)):(console.log("\u2139 \u914D\u7F6E\u754C\u9762\u5DF2\u542F\u52A8\uFF0C\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00:"),console.log(` ${T}`),console.log(`
3
+ \u5982\u679C\u65E0\u6CD5\u76F4\u63A5\u8BBF\u95EE\uFF0C\u53EF\u901A\u8FC7 SSH \u7AEF\u53E3\u8F6C\u53D1:
4
+ ssh -L ${e}:127.0.0.1:${e} <your-host>`),console.log(` \u7136\u540E\u6253\u5F00: http://127.0.0.1:${e}/setup?token=${r}`)),console.log(`
5
+ \uFF08\u7B49\u5F85\u914D\u7F6E\u5B8C\u6210\u540E\u81EA\u52A8\u7EE7\u7EED setup \u6D41\u7A0B\uFF09`),console.log(` \uFF08\u6309 Ctrl+C \u9000\u51FA | --no-ui \u56DE\u9000\u547D\u4EE4\u884C\u4EA4\u4E92\uFF09
6
+ `),await f,a&&clearTimeout(a),d.close()}g(jt,"runConfigUI");async function kt(n,e,t,r,i,m){if(e.method==="GET"&&n.pathname==="/dev/config/check"){let o=await C({configPath:r});R(t,P(o));return}if(e.method==="GET"&&n.pathname==="/dev/config/enriched"){let o=await C({configPath:r}),u=ut(),l=await ft(r),f={},a={},c=new Set,d=/\$\{env\.([A-Za-z_][A-Za-z0-9_]*)(\?)?\}/g;try{let s=await V(r),p=await E(s,"utf8");for(let k of mt([p]))c.add(k)}catch{}try{let s=await E(w.join(i,"profile","profile.yml"),"utf8"),p=B.parse(s),k=p?.workflows;if(k&&typeof k=="object"&&(a=k),p&&typeof p=="object"){let{workflows:_,...I}=p;for(let b of JSON.stringify(I).matchAll(d))c.add(b[1])}}catch{}for(let s of l.workflowEntries)try{let p=await dt(s.templatePath),k=p.steps.map(h=>({id:h.id,name:h.name,recipe:h.recipe,engine:h.engine,auto:h.auto})),_=p.edges.filter(h=>h.from!=="__start__"&&h.to!=="__end__").map(h=>({from:h.from,to:h.to,condition:h.condition})),I={},b=new Set,A;try{A=B.parse(await E(s.templatePath,"utf8"))}catch{}if(A){for(let S of JSON.stringify(A).matchAll(d))b.add(S[1]);let h=a[s.id];if(h&&typeof h=="object")for(let S of JSON.stringify(h).matchAll(d))b.add(S[1]);let et=Array.isArray(A.steps)?A.steps:[];for(let S=0;S<p.steps.length;S++){let N=p.steps[S],O=et[S];if(O){let j=JSON.stringify(O),J=new Set;for(let nt of j.matchAll(d))J.add(nt[1]);J.size>0&&(I[N.id]=[...J])}}let ot=Array.isArray(A.event_sources)?A.event_sources:[];for(let S of ot)if(S){let N=JSON.stringify(S),O=new Set;for(let j of N.matchAll(d))O.add(j[1]);O.size>0&&(I.__event_sources__=[...I.__event_sources__??[],...O])}}f[s.id]={steps:k,edges:_,stepEnvRefs:I,envRefs:[...b].sort()}}catch{f[s.id]={steps:[],edges:[],stepEnvRefs:{},envRefs:[]}}let T=new Set;for(let s of Object.values(f))for(let p of s.envRefs??[])T.add(p);let v=o.modules.find(s=>s.id==="env");for(let s of v?.items??[])s.writeTarget?.type==="env"&&!T.has(s.key)&&c.add(s.key);R(t,{config:P(o),engines:{available:u.available.map(s=>({engine:s.engine,cmd:s.cmd,version:s.version})),recommended:u.recommendedEngine},workflowTopology:f,projectEnvRefs:[...c].sort()});return}if(e.method==="POST"&&n.pathname==="/dev/config/save"){let o=await $(e);if(!Array.isArray(o.updates)){y(t,400,"updates must be an array");return}for(let a of o.updates){let c=[];if(a.writeTarget.type==="yamlAll")for(let d of a.writeTarget.targets)c.push(d.file);else c.push(a.writeTarget.file);for(let d of c)try{x(i,d,{allowRoot:!1})}catch{y(t,403,`\u8DEF\u5F84\u8D8A\u754C: ${d}`);return}}let u=0;for(let a of o.updates)await G(a.writeTarget,a.value,i),u++;let l=await C({configPath:r}),f=yt(o.updates,l);if(f){let a=0;for(let c of tt(l))c.writeTarget&&(c.status==="error"||c.status==="warn")&&M(c)&&F(c)==="baseId"&&(!c.value||typeof c.value=="string"&&!c.value.trim())&&(await G(c.writeTarget,f,i),a++);a>0&&(l=await C({configPath:r}),u+=a)}R(t,{ok:!0,written:u,recheck:P(l)});return}if(e.method==="POST"&&n.pathname==="/dev/kb/ingest"){let o=await $(e);if(!o.roleId||!o.source){y(t,400,"roleId and source are required");return}try{K(o.roleId,{label:"roleId"})}catch(c){y(t,400,c instanceof Error?c.message:"roleId \u4E0D\u5408\u6CD5");return}let u=w.resolve(i,"roles",`${o.roleId}.role.yml`),l=await L(u,o.roleId),f=await U({source:o.source,collectionName:l,configDir:i}),a=await C({configPath:r});R(t,{ok:f.success,message:f.message,recheck:P(a)});return}if(e.method==="POST"&&n.pathname==="/dev/kb/upload"){let o=await $(e,vt);if(!o.roleId||!Array.isArray(o.files)||o.files.length===0){y(t,400,"roleId and files are required");return}try{K(o.roleId,{label:"roleId"})}catch(a){y(t,400,a instanceof Error?a.message:"roleId \u4E0D\u5408\u6CD5");return}let u=w.resolve(i,"roles",`${o.roleId}.role.yml`),l=await L(u,o.roleId),f=w.resolve(i,".kb-upload-tmp",`upload-${Date.now()}`);try{await W(f,{recursive:!0});for(let d of o.files){let T;try{T=x(f,d.relativePath,{allowRoot:!1})}catch{y(t,400,`\u4E0A\u4F20\u6587\u4EF6\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${d.relativePath}`);return}let v=w.dirname(T);await W(v,{recursive:!0});let s=d.encoding==="base64"?Buffer.from(d.content,"base64"):Buffer.from(d.content,"utf8");await z(T,s)}let a=await U({source:f,collectionName:l,configDir:i}),c=await C({configPath:r});R(t,{ok:a.success,message:a.message,recheck:P(c)})}finally{await st(f,{recursive:!0,force:!0}).catch(()=>{})}return}if(e.method==="GET"&&n.pathname==="/dev/file/read"){let o=n.searchParams.get("path")??"",u=Z(o,i);if(!u){y(t,403,`\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${o}`);return}try{let l=await E(u,"utf8");R(t,{ok:!0,path:o,content:l,exists:!0})}catch{R(t,{ok:!0,path:o,content:"",exists:!1})}return}if(e.method==="POST"&&n.pathname==="/dev/file/write"){let o=await $(e),u=typeof o.path=="string"?o.path:"",l=Z(u,i);if(!l||typeof o.content!="string"){y(t,403,`\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${u}`);return}let f=St(u,o.content);if(f){R(t,{ok:!1,error:f},400);return}await W(w.dirname(l),{recursive:!0}),await z(l,o.content.endsWith(`
7
+ `)?o.content:o.content+`
8
+ `,"utf8");let a=await C({configPath:r});R(t,{ok:!0,recheck:P(a)});return}if(e.method==="POST"&&n.pathname==="/dev/setup/complete"){R(t,{ok:!0}),m?.();return}y(t,404,"Unknown endpoint")}g(kt,"handleDevApi");function Z(n,e){let t=n.trim();if(!t||!/\.(ya?ml|json)$/i.test(t))return null;try{return x(e,t,{allowRoot:!1})}catch{return null}}g(Z,"resolveInsideConfigDir");function St(n,e){try{return/\.json$/i.test(n)?JSON.parse(e):B.parse(e),null}catch(t){return`${/\.json$/i.test(n)?"JSON":"YAML"} \u8BED\u6CD5\u9519\u8BEF\uFF0C\u672A\u4FDD\u5B58: ${t instanceof Error?t.message:String(t)}`}}g(St,"validateStructuredText");async function Rt(n,e,t){let r;try{let o=decodeURIComponent(n.pathname).replace(/^\/+/,"")||"index.html";r=x(t,o,{allowRoot:!1})}catch{e.writeHead(403),e.end("Forbidden");return}try{(await Y(r)).isDirectory()&&(r=w.join(r,"index.html"))}catch{r=w.join(t,"index.html")}try{await Y(r)}catch{e.writeHead(404),e.end("Not Found");return}let i=w.extname(r),m=pt[i]??"application/octet-stream";e.writeHead(200,{"Content-Type":m}),it(r).pipe(e)}g(Rt,"serveStatic");export{ht as detectEnvironment,Nt as hasWebRoot,Q as resolveWebRoot,jt as runConfigUI};
@@ -1 +1 @@
1
- import{a,b,c,d,e,f,g}from"./chunk-U773UWB7.js";import"./chunk-EI7MMDWY.js";export{a as DAEMON_DATA_DIR,b as daemonDir,d as isProcessAlive,c as pidFilePath,e as readPidFile,g as removePidFile,f as writePidFile};
1
+ import{a,b,c,d,e,f,g}from"./chunk-W3EUICMH.js";import"./chunk-EI7MMDWY.js";export{a as DAEMON_DATA_DIR,b as daemonDir,d as isProcessAlive,c as pidFilePath,e as readPidFile,g as removePidFile,f as writePidFile};