aitable-workflow-cli 0.1.22 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import{a as He,b as qe,m as Ke}from"./chunk-VYYLEYUZ.js";import"./chunk-4B6V7VHM.js";import{b as X,d as W,e as ve,f as Ve,g as Q}from"./chunk-N2ATMPTO.js";import{a as c}from"./chunk-EI7MMDWY.js";import{config as mn}from"dotenv";import{Command as oi}from"commander";import{logger as pn,activateGlobalDwsOnPath as ri,initSlsReport as ii}from"aitable-workflow-core";import{createRequire as fn}from"module";var Ye="aitable-workflow-",hn=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function Je(){try{return fn(import.meta.url)("../package.json")}catch{return{}}}c(Je,"loadCliPackageManifest");function be(r){return r.version??"0.0.0"}c(be,"resolveCliVersion");function ze(r){let t=be(r),e={};r.name?.startsWith(Ye)&&(e[r.name]=t);for(let[n,o]of Object.entries(r.dependencies??{}))n.startsWith(Ye)&&(e[n]=hn.test(o)?o:t);return e}c(ze,"resolveMonorepoPackageVersions");import dn from"path";import{fileURLToPath as si}from"url";var Xe="./aitable-workflow.config.yml";import{runInit as wn,logger as yn}from"aitable-workflow-core";import kn from"path";function Qe(r,t){r.command("init").description("\u4EA4\u4E92\u5F0F\u521D\u59CB\u5316 \u2014 \u9009\u62E9 Coding Agent\u3001\u914D\u7F6E\u5DE5\u4F5C\u76EE\u5F55\u3001\u63CF\u8FF0\u4E1A\u52A1\u573A\u666F\uFF1B\u6216\u7528 --template \u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6").option("-c, --config <path>","\u76EE\u6807\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").option("-f, --force","\u8986\u76D6\u5DF2\u6709\u914D\u7F6E\u6587\u4EF6").option("-y, --yes","\u4F7F\u7528\u9ED8\u8BA4\u503C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u5411\u5BFC").option("-t, --template <name>","\u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6(\u5F53\u524D\u63A8\u8350 support-qa),\u62F7\u8D1D\u5B8C\u6574\u53EF\u8FD0\u884C\u9879\u76EE\u5230\u76EE\u6807\u76EE\u5F55").option("--profile <name>","\u9009\u5B9A\u6A21\u677F\u4E0B\u7684 profile \u4E1A\u52A1\u5305(\u5982 support-qa \u7684 aitable),\u8986\u76D6\u5F0F\u53E0\u52A0\u5230\u5B9E\u4F8B").action(async e=>{try{await wn({config:e.config,force:!!e.force,yes:!!e.yes,template:e.template,profile:e.profile,templatesDir:kn.resolve(t.cliDir,"..","templates"),templatePackageVersions:t.packageVersions,cliVersion:t.version})}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),yn.error("cli","\u521D\u59CB\u5316\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Qe,"registerInitCommand");import{runMigrate as vn,logger as bn}from"aitable-workflow-core";import Rn from"path";function Ze(r,t){r.command("migrate").description("\u5347\u7EA7\u9879\u76EE\u76EE\u5F55\u5230\u6700\u65B0\u6A21\u677F\u7248\u672C\uFF0C\u81EA\u52A8\u4FDD\u7559\u7528\u6237\u914D\u7F6E\uFF1B\u6216\u7528 --from/--to \u5728\u4E24\u4E2A\u76EE\u5F55\u95F4\u505A\u5408\u5E76\u8FC1\u79FB").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u8DEF\u5F84",t.defaultConfig).option("--from <dir>","\u6E90\u76EE\u5F55\uFF1A\u4EE5\u8BE5\u76EE\u5F55\u4E3A\u8FC1\u79FB\u57FA\u51C6\uFF08\u4E0D\u6309\u540D scaffold \u6A21\u677F\uFF09\uFF0C\u4E0E --template/--profile \u4E92\u65A5").option("--to <dir>","\u76EE\u6807\u9879\u76EE\u76EE\u5F55\uFF08--config \u7684\u540C\u4E49\u53C2\u6570\uFF0C\u4F18\u5148\u751F\u6548\uFF09").option("--dry-run","\u4EC5\u9884\u89C8\u53D8\u66F4\uFF0C\u4E0D\u5B9E\u9645\u5199\u5165").option("--no-backup","\u8DF3\u8FC7\u81EA\u52A8\u5907\u4EFD").option("--force","\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A").option("--template <name>","\u6307\u5B9A\u76EE\u6807\u6A21\u677F").option("--profile <name>","\u6307\u5B9A\u76EE\u6807 profile").option("--rollback","\u56DE\u6EDA\u5230\u4E0A\u4E00\u6B21\u8FC1\u79FB\u524D\u7684\u72B6\u6001").option("--list","\u5217\u51FA\u6240\u6709\u5907\u4EFD").action(async e=>{try{await vn({config:e.config,from:e.from,to:e.to,dryRun:e.dryRun,noBackup:e.backup===!1,force:e.force,template:e.template,profile:e.profile,rollback:e.rollback,list:e.list,templatesDir:Rn.resolve(t.cliDir,"..","templates"),templatePackageVersions:t.packageVersions,cliVersion:t.version})}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),bn.error("cli","migrate \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Ze,"registerMigrateCommand");import{runDesignCommand as Cn,logger as In}from"aitable-workflow-core";function et(r,t){r.command("design").description("\u8BA9 Coding Agent \u6839\u636E\u573A\u666F\u63CF\u8FF0\u751F\u6210\u5B8C\u6574\u7684 workflow \u548C recipes").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-y, --yes","\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u8865\u5145\uFF0C\u76F4\u63A5\u4F7F\u7528 config \u4E2D\u7684 scene").option("--skip-questions","\u4E0D\u56DE\u7B54 Agent \u7684\u6F84\u6E05\u63D0\u95EE\uFF08Agent \u6309\u5047\u8BBE\u751F\u6210\u5E76\u5217\u51FA\u5F85\u786E\u8BA4\u9879\uFF09").action(async e=>{try{await Cn(e)}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),In.error("cli","design \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(et,"registerDesignCommand");import{runCheck as An,runSetupCommand as Sn,checkMigrateHint as En,logger as xn,reportCliEvent as Z,setReportProject as Tn}from"aitable-workflow-core";import nt from"path";function Re(r){return r.skipConfig||r.skipConfigIfValid&&r.configValid===!0}c(Re,"canSkipSetupConfig");function tt(r){return Re(r)?"setup":r.uiEnabled&&r.webAvailable?"web":"cli"}c(tt,"resolveSetupConfigRoute");function ot(r,t){r.command("setup").description("\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E\uFF0C\u518D\u521D\u59CB\u5316 AI \u8868\u683C\u7ED3\u6784 + \u51C6\u5907\u77E5\u8BC6\u5E93 \u2014 \u4E00\u6B21\u5B8C\u6210 config + \u5EFA\u8868").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("--no-clean","\u4E0D\u6E05\u7406\u7A7A\u767D\u884C").option("--no-kb","\u8DF3\u8FC7\u77E5\u8BC6\u5E93\u51C6\u5907/\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").option("--only <round>","\u53EA\u6267\u884C\u6307\u5B9A\u73AF\u8282\uFF1B\u5F53\u524D\u4EC5\u652F\u6301 automations\uFF08\u6309 profile \u5F00\u5173\u5BF9\u9F50\u81EA\u52A8\u5316\uFF0C\u4E0D\u5EFA\u8868\u3001\u4E0D\u7F16\u77E5\u8BC6\u5E93\uFF09").action(async e=>{e.only!==void 0&&e.only!=="automations"&&(console.error(`\u2717 --only \u4E0D\u652F\u6301\u300C${e.only}\u300D\uFF0C\u5F53\u524D\u552F\u4E00\u5408\u6CD5\u503C\uFF1Aautomations`),process.exit(1));let n=e.only==="automations";Tn(e.config);let o=Date.now();Z("setup.start",{skipConfig:e.skipConfig===!0,clean:e.clean,kb:e.kb,kbFull:e.kbFull===!0,ui:e.ui!==!1,...n?{only:"automations"}:{}});try{if(await En(nt.dirname(nt.resolve(e.config)),t.version),!e.skipConfig&&!n){let i=e.ui!==!1,s=!1;if(e.skipConfigIfValid){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u9879\u76EE\u914D\u7F6E");let a=await An({configPath:e.config});if(s=Re({skipConfig:!1,skipConfigIfValid:!0,configValid:a.ok}),s){let l=[];a.summary.warnings>0&&l.push(`${a.summary.warnings} \u9879\u8B66\u544A`),a.summary.suggestions>0&&l.push(`${a.summary.suggestions} \u9879\u5EFA\u8BAE`);let p=l.length>0?`\uFF08${l.join("\uFF0C")}\uFF0C\u5747\u4E0D\u963B\u65AD\uFF09`:"";console.log(`\u2713 \u914D\u7F6E\u65E0\u963B\u65AD\u9879${p}\uFF0C\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u7EE7\u7EED\u642D\u5EFA\u3002`)}else console.log(`\u2139 \u68C0\u6D4B\u5230 ${a.summary.errors} \u9879\u963B\u65AD\uFF0C\u8FDB\u5165\u914D\u7F6E\u73AF\u8282\u3002`)}if(!s&&i){let{hasWebRoot:a,runConfigUI:l}=await import("./config-ui-server-GSFSGBRK.js");if(tt({skipConfig:!1,skipConfigIfValid:e.skipConfigIfValid===!0,uiEnabled:i,webAvailable:a(),configValid:s})==="web"){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");try{await l({configPath:e.config,setupOptions:{clean:e.clean,kb:e.kb,kbFull:e.kbFull}}),Z("setup.finish",{success:!0,route:"web",durationMs:Date.now()-o});return}catch(m){console.warn(`
2
+ import{a as He,b as qe,m as Ke}from"./chunk-IGB6WDLR.js";import"./chunk-4B6V7VHM.js";import{b as X,d as W,e as ve,f as Ve,g as Q}from"./chunk-N2ATMPTO.js";import{a as c}from"./chunk-EI7MMDWY.js";import{config as mn}from"dotenv";import{Command as ri}from"commander";import{logger as pn,activateGlobalDwsOnPath as ii,initSlsReport as si}from"aitable-workflow-core";import{createRequire as fn}from"module";var Ye="aitable-workflow-",hn=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function Je(){try{return fn(import.meta.url)("../package.json")}catch{return{}}}c(Je,"loadCliPackageManifest");function be(r){return r.version??"0.0.0"}c(be,"resolveCliVersion");function ze(r){let t=be(r),e={};r.name?.startsWith(Ye)&&(e[r.name]=t);for(let[n,o]of Object.entries(r.dependencies??{}))n.startsWith(Ye)&&(e[n]=hn.test(o)?o:t);return e}c(ze,"resolveMonorepoPackageVersions");import dn from"path";import{fileURLToPath as ai}from"url";var Xe="./aitable-workflow.config.yml";import{runInit as wn,logger as yn}from"aitable-workflow-core";import kn from"path";function Qe(r,t){r.command("init").description("\u4EA4\u4E92\u5F0F\u521D\u59CB\u5316 \u2014 \u9009\u62E9 Coding Agent\u3001\u914D\u7F6E\u5DE5\u4F5C\u76EE\u5F55\u3001\u63CF\u8FF0\u4E1A\u52A1\u573A\u666F\uFF1B\u6216\u7528 --template \u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6").option("-c, --config <path>","\u76EE\u6807\u76EE\u5F55\u6216\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09").option("-f, --force","\u8986\u76D6\u5DF2\u6709\u914D\u7F6E\u6587\u4EF6").option("-y, --yes","\u4F7F\u7528\u9ED8\u8BA4\u503C\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u5411\u5BFC").option("-t, --template <name>","\u4ECE\u5185\u7F6E\u6A21\u677F\u811A\u624B\u67B6(\u5F53\u524D\u63A8\u8350 support-qa),\u62F7\u8D1D\u5B8C\u6574\u53EF\u8FD0\u884C\u9879\u76EE\u5230\u76EE\u6807\u76EE\u5F55").option("--profile <name>","\u9009\u5B9A\u6A21\u677F\u4E0B\u7684 profile \u4E1A\u52A1\u5305(\u5982 support-qa \u7684 aitable),\u8986\u76D6\u5F0F\u53E0\u52A0\u5230\u5B9E\u4F8B").action(async e=>{try{await wn({config:e.config,force:!!e.force,yes:!!e.yes,template:e.template,profile:e.profile,templatesDir:kn.resolve(t.cliDir,"..","templates"),templatePackageVersions:t.packageVersions,cliVersion:t.version})}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),yn.error("cli","\u521D\u59CB\u5316\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Qe,"registerInitCommand");import{runMigrate as vn,logger as bn}from"aitable-workflow-core";import Cn from"path";function Ze(r,t){r.command("migrate").description("\u5347\u7EA7\u9879\u76EE\u76EE\u5F55\u5230\u6700\u65B0\u6A21\u677F\u7248\u672C\uFF0C\u81EA\u52A8\u4FDD\u7559\u7528\u6237\u914D\u7F6E\uFF1B\u6216\u7528 --from/--to \u5728\u4E24\u4E2A\u76EE\u5F55\u95F4\u505A\u5408\u5E76\u8FC1\u79FB").option("-c, --config <path>","\u9879\u76EE\u76EE\u5F55\u8DEF\u5F84",t.defaultConfig).option("--from <dir>","\u6E90\u76EE\u5F55\uFF1A\u4EE5\u8BE5\u76EE\u5F55\u4E3A\u8FC1\u79FB\u57FA\u51C6\uFF08\u4E0D\u6309\u540D scaffold \u6A21\u677F\uFF09\uFF0C\u4E0E --template/--profile \u4E92\u65A5").option("--to <dir>","\u76EE\u6807\u9879\u76EE\u76EE\u5F55\uFF08--config \u7684\u540C\u4E49\u53C2\u6570\uFF0C\u4F18\u5148\u751F\u6548\uFF09").option("--dry-run","\u4EC5\u9884\u89C8\u53D8\u66F4\uFF0C\u4E0D\u5B9E\u9645\u5199\u5165").option("--no-backup","\u8DF3\u8FC7\u81EA\u52A8\u5907\u4EFD").option("--force","\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A").option("--template <name>","\u6307\u5B9A\u76EE\u6807\u6A21\u677F").option("--profile <name>","\u6307\u5B9A\u76EE\u6807 profile").option("--rollback","\u56DE\u6EDA\u5230\u4E0A\u4E00\u6B21\u8FC1\u79FB\u524D\u7684\u72B6\u6001").option("--list","\u5217\u51FA\u6240\u6709\u5907\u4EFD").action(async e=>{try{await vn({config:e.config,from:e.from,to:e.to,dryRun:e.dryRun,noBackup:e.backup===!1,force:e.force,template:e.template,profile:e.profile,rollback:e.rollback,list:e.list,templatesDir:Cn.resolve(t.cliDir,"..","templates"),templatePackageVersions:t.packageVersions,cliVersion:t.version})}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),bn.error("cli","migrate \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Ze,"registerMigrateCommand");import{runDesignCommand as Rn,logger as In}from"aitable-workflow-core";function et(r,t){r.command("design").description("\u8BA9 Coding Agent \u6839\u636E\u573A\u666F\u63CF\u8FF0\u751F\u6210\u5B8C\u6574\u7684 workflow \u548C recipes").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-y, --yes","\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u8865\u5145\uFF0C\u76F4\u63A5\u4F7F\u7528 config \u4E2D\u7684 scene").option("--skip-questions","\u4E0D\u56DE\u7B54 Agent \u7684\u6F84\u6E05\u63D0\u95EE\uFF08Agent \u6309\u5047\u8BBE\u751F\u6210\u5E76\u5217\u51FA\u5F85\u786E\u8BA4\u9879\uFF09").action(async e=>{try{await Rn(e)}catch(n){n instanceof Error&&n.message.includes("cancelled")&&process.exit(0),In.error("cli","design \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(et,"registerDesignCommand");import{runCheck as An,runSetupCommand as Sn,checkMigrateHint as En,logger as xn,reportCliEvent as Z,setReportProject as Tn}from"aitable-workflow-core";import nt from"path";function Ce(r){return r.skipConfig||r.skipConfigIfValid&&r.configValid===!0}c(Ce,"canSkipSetupConfig");function tt(r){return Ce(r)?"setup":r.uiEnabled&&r.webAvailable?"web":"cli"}c(tt,"resolveSetupConfigRoute");function ot(r,t){r.command("setup").description("\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E\uFF0C\u518D\u521D\u59CB\u5316 AI \u8868\u683C\u7ED3\u6784 + \u51C6\u5907\u77E5\u8BC6\u5E93 \u2014 \u4E00\u6B21\u5B8C\u6210 config + \u5EFA\u8868").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("--no-clean","\u4E0D\u6E05\u7406\u7A7A\u767D\u884C").option("--no-kb","\u8DF3\u8FC7\u77E5\u8BC6\u5E93\u51C6\u5907/\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").option("--only <round>","\u53EA\u6267\u884C\u6307\u5B9A\u73AF\u8282\uFF1B\u5F53\u524D\u4EC5\u652F\u6301 automations\uFF08\u6309 profile \u5F00\u5173\u5BF9\u9F50\u81EA\u52A8\u5316\uFF0C\u4E0D\u5EFA\u8868\u3001\u4E0D\u7F16\u77E5\u8BC6\u5E93\uFF09").action(async e=>{e.only!==void 0&&e.only!=="automations"&&(console.error(`\u2717 --only \u4E0D\u652F\u6301\u300C${e.only}\u300D\uFF0C\u5F53\u524D\u552F\u4E00\u5408\u6CD5\u503C\uFF1Aautomations`),process.exit(1));let n=e.only==="automations";Tn(e.config);let o=Date.now();Z("setup.start",{skipConfig:e.skipConfig===!0,clean:e.clean,kb:e.kb,kbFull:e.kbFull===!0,ui:e.ui!==!1,...n?{only:"automations"}:{}});try{if(await En(nt.dirname(nt.resolve(e.config)),t.version),!e.skipConfig&&!n){let i=e.ui!==!1,s=!1;if(e.skipConfigIfValid){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u9879\u76EE\u914D\u7F6E");let a=await An({configPath:e.config});if(s=Ce({skipConfig:!1,skipConfigIfValid:!0,configValid:a.ok}),s){let l=[];a.summary.warnings>0&&l.push(`${a.summary.warnings} \u9879\u8B66\u544A`),a.summary.suggestions>0&&l.push(`${a.summary.suggestions} \u9879\u5EFA\u8BAE`);let p=l.length>0?`\uFF08${l.join("\uFF0C")}\uFF0C\u5747\u4E0D\u963B\u65AD\uFF09`:"";console.log(`\u2713 \u914D\u7F6E\u65E0\u963B\u65AD\u9879${p}\uFF0C\u8DF3\u8FC7\u914D\u7F6E\u754C\u9762\u5E76\u7EE7\u7EED\u642D\u5EFA\u3002`)}else console.log(`\u2139 \u68C0\u6D4B\u5230 ${a.summary.errors} \u9879\u963B\u65AD\uFF0C\u8FDB\u5165\u914D\u7F6E\u73AF\u8282\u3002`)}if(!s&&i){let{hasWebRoot:a,runConfigUI:l}=await import("./config-ui-server-CORDAOYI.js");if(tt({skipConfig:!1,skipConfigIfValid:e.skipConfigIfValid===!0,uiEnabled:i,webAvailable:a(),configValid:s})==="web"){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");try{await l({configPath:e.config,setupOptions:{clean:e.clean,kb:e.kb,kbFull:e.kbFull}}),Z("setup.finish",{success:!0,route:"web",durationMs:Date.now()-o});return}catch(m){console.warn(`
3
3
  \u26A0 \u53EF\u89C6\u5316\u754C\u9762\u5F02\u5E38\uFF0C\u56DE\u9000\u5230\u547D\u4EE4\u884C\u4EA4\u4E92: ${m instanceof Error?m.message:String(m)}
4
4
  `)}}}if(!s){console.log("\u{1F4CB} \u6B65\u9AA4 1/2\uFF1A\u6821\u9A8C\u5E76\u8865\u9F50\u9879\u76EE\u914D\u7F6E");let{runConfigCommand:a}=await import("./config-command-7ECUJOEU.js");(await a({configPath:e.config,interactive:!0,offerSkipToBuild:!0})).ok||(console.error(`
5
5
  \u2717 \u9879\u76EE\u914D\u7F6E\u4ECD\u4E0D\u5B8C\u6574\uFF0C\u5DF2\u4E2D\u6B62 setup\u3002\u8BF7\u8865\u9F50\u5FC5\u586B\u9879\u540E\u91CD\u8BD5\uFF08\u6216\u7528 --skip-config \u8DF3\u8FC7\uFF09\u3002`),process.exit(1))}console.log(`
6
6
  \u{1F527} \u6B65\u9AA4 2/2\uFF1A\u521D\u59CB\u5316\u8868\u7ED3\u6784 + \u51C6\u5907\u77E5\u8BC6\u5E93
7
- `)}await Sn({config:e.config,clean:e.clean,kb:e.kb,...e.kbFull?{kbFull:!0}:{},...n?{only:"automations"}:{}}),await Z("setup.finish",{success:!0,durationMs:Date.now()-o})}catch(i){xn.error("cli","setup \u5931\u8D25",{error:i instanceof Error?i.message:String(i)}),await Z("setup.finish",{success:!1,error:(i instanceof Error?i.message:String(i)).slice(0,500),durationMs:Date.now()-o}),process.exit(1)}})}c(ot,"registerSetupCommand");import rt from"path";import{createApp as it,ensureTsxRegistered as $n,checkMigrateHint as Pn,logger as v,runCheck as jn}from"aitable-workflow-core";function On(){let e=[],n=c(()=>{let o=Date.now();for(e.push(o);e.length>0&&o-e[0]>6e4;)e.shift();e.length>=10&&(v.error("cli",`60000ms \u5185\u53D1\u751F ${e.length} \u6B21\u672A\u6355\u83B7\u5F02\u5E38\uFF0C\u7591\u4F3C\u975E\u5076\u53D1\u9519\u8BEF\uFF0C\u4E3B\u52A8\u9000\u51FA`),process.exit(1))},"recordCrashAndMaybeExit");process.on("uncaughtException",o=>{v.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406\u5F02\u5E38\uFF08\u5DF2\u5B58\u6D3B\uFF0C\u4EA4\u7531\u91CD\u8FDE/\u91CD\u8BD5\u903B\u8F91\u81EA\u6108\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()}),process.on("unhandledRejection",o=>{v.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406 Promise \u62D2\u7EDD\uFF08\u5DF2\u5B58\u6D3B\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()})}c(On,"installLongRunningCrashGuards");function st(r,t){r.command("start").description("\u542F\u52A8\u7EDF\u4E00\u63A7\u5236\u53F0\uFF1A\u914D\u7F6E\u68C0\u6D4B + \u642D\u5EFA + \u8FD0\u884C\u4E00\u4F53\u5316").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-p, --port <number>","\u63A7\u5236\u53F0\u7AEF\u53E3\u9996\u9009\u503C\uFF08\u7F3A\u7701 8788\uFF0C\u4E0D\u53EF\u7528\u65F6\u5411\u4E0A\u907F\u8BA9 13 \u4E2A\u7AEF\u53E3\uFF1B\u591A\u9879\u76EE\u5E76\u884C\u65F6\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A\uFF09").option("--no-open","\u542F\u52A8\u540E\u4E0D\u8981\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668").option("--skip-config-if-valid","\u914D\u7F6E\u5DF2\u5B8C\u6574\u65F6\u76F4\u63A5\u542F\u52A8\u8FD0\u884C").action(async e=>{let n;if(e.port!==void 0){let o=Number.parseInt(e.port,10);(!Number.isFinite(o)||o<=0||o>65535)&&(v.error("cli",`--port \u53D6\u503C\u975E\u6CD5: "${e.port}"\uFF08\u9700\u4E3A 1-65535 \u6574\u6570\uFF09`),process.exit(1)),n=o}try{await Pn(rt.dirname(rt.resolve(e.config)),t.version),On(),await $n();let o=await jn({configPath:e.config}),i=!o.ok||o.summary.errors>0,s,a="setup";if(!i)try{a="runtime",s=await it(e.config,{})}catch(m){v.warn("cli","\u914D\u7F6E\u6821\u9A8C\u901A\u8FC7\u4F46\u88C5\u914D\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u642D\u5EFA\u6A21\u5F0F",{error:m instanceof Error?m.message:String(m)}),a="setup",s=void 0}a==="runtime"&&s?e.skipConfigIfValid?(v.info("cli","\u914D\u7F6E\u5DF2\u5B8C\u6574\uFF0C\u76F4\u63A5\u542F\u52A8\u8FD0\u884C"),s.start().catch(m=>{v.error("cli","\u8FD0\u884C\u542F\u52A8\u5931\u8D25\uFF0C\u53EF\u5728\u63A7\u5236\u53F0\u91CD\u8BD5\u542F\u52A8",{error:m instanceof Error?m.message:String(m)})})):v.info("cli","\u914D\u7F6E\u5DF2\u5B8C\u6574\uFF0C\u8BF7\u5728\u63A7\u5236\u53F0\u70B9\u51FB\u300C\u5F00\u59CB\u8FD0\u884C\u300D\u542F\u52A8\u670D\u52A1"):v.info("cli","\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF0C\u63A7\u5236\u53F0\u5C06\u5F15\u5BFC\u5B8C\u6210\u642D\u5EFA");let l=!1,p=c(async()=>{l&&(v.warn("cli","\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),l=!0,v.info("cli","\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u505C\u6B62\u8FD0\u884C...");try{await s?.stop()}finally{process.exit(0)}},"shutdown");process.on("SIGINT",p),process.on("SIGTERM",p),await Ke({configPath:e.config,mode:a,app:s,port:n,open:e.open,exitOnSetupError:!1,...a==="runtime"&&e.skipConfigIfValid?{initialRunStatus:{status:"running",since:new Date().toISOString(),lastError:null}}:{},...a==="setup"?{assembleApp:c(m=>it(m,{}),"assembleApp"),onAppAssembled:c(m=>{s=m,v.info("cli","\u63A7\u5236\u53F0\u5DF2\u5B8C\u6210 setup\u2192runtime \u664B\u5347\uFF0C\u53EF\u5728\u63A7\u5236\u53F0\u542F\u52A8\u8FD0\u884C")},"onAppAssembled")}:{}})}catch(o){v.error("cli","start \u547D\u4EE4\u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})}c(st,"registerStartCommand");import{createApp as _n,ensureTsxRegistered as Dn,checkMigrateHint as Ln,logger as O,reportCliEvent as ee,setReportProject as Mn}from"aitable-workflow-core";import at from"path";function Fn(){let e=[],n=c(async()=>{let o=Date.now();for(e.push(o);e.length>0&&o-e[0]>6e4;)e.shift();e.length>=10&&(O.error("cli",`60000ms \u5185\u53D1\u751F ${e.length} \u6B21\u672A\u6355\u83B7\u5F02\u5E38\uFF0C\u7591\u4F3C\u975E\u5076\u53D1\u9519\u8BEF\uFF0C\u4E3B\u52A8\u9000\u51FA`),await ee("run.exit",{reason:"crash-loop",crashes:e.length}),process.exit(1))},"recordCrashAndMaybeExit");process.on("uncaughtException",o=>{O.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406\u5F02\u5E38\uFF08\u5DF2\u5B58\u6D3B\uFF0C\u4EA4\u7531\u91CD\u8FDE/\u91CD\u8BD5\u903B\u8F91\u81EA\u6108\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()}),process.on("unhandledRejection",o=>{O.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406 Promise \u62D2\u7EDD\uFF08\u5DF2\u5B58\u6D3B\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()})}c(Fn,"installLongRunningCrashGuards");function ct(r,t){r.command("run").description("\u542F\u52A8\u7F16\u6392\u5F15\u64CE\uFF0C\u5F00\u59CB\u8F6E\u8BE2\u5904\u7406\u5DE5\u5355").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("--emit-events <channel>","\u8FD0\u884C\u4E8B\u4EF6\u4E0A\u629B\u901A\u9053\uFF1Aipc = \u7ECF process.send \u53D1\u7ED9\u7236\u8FDB\u7A0B\uFF08daemon runner \u7528\uFF09\uFF0C\u7F3A\u7701\u4E0D\u4E0A\u629B").option("-p, --port <number>","\uFF08\u4EC5\u517C\u5BB9 launcher \u900F\u4F20\uFF0Crun \u547D\u4EE4\u4E0D\u4F7F\u7528\u6B64\u53C2\u6570\uFF09").action(async e=>{Mn(e.config);try{await Ln(at.dirname(at.resolve(e.config)),t.version),Fn(),await Dn();let n=e.emitEvents==="ipc"&&typeof process.send=="function",o=await _n(e.config,n?{onRunEvent:c(a=>{process.send?.({type:"run-event",event:a})},"onRunEvent")}:{});ee("run.start",{emitEvents:e.emitEvents??null});let i=!1,s=c(async()=>{i&&(O.warn("cli","\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),i=!0,O.info("cli","\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u7B49\u5F85\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u5B8C\u6210...");try{await o.stop()}finally{await ee("run.exit",{reason:"signal"}),process.exit(0)}},"shutdown");process.on("SIGINT",s),process.on("SIGTERM",s),await o.start()}catch(n){O.error("cli","\u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),await ee("run.exit",{reason:"start-failure",error:(n instanceof Error?n.message:String(n)).slice(0,500)}),process.exit(1)}})}c(ct,"registerRunCommand");import{createApp as Bn,ensureTsxRegistered as Un,logger as Ce}from"aitable-workflow-core";function Wn(r,t){let e=`\u5DE5\u4F5C\u6D41 ${r} / \u4E8B\u4EF6\u6E90 ${t.sourceName}\uFF08handler: ${t.handlerRecipe}\uFF09`;return t.actions===0?`${e}\uFF1A\u5DF2\u89E6\u53D1\u4F46\u6CA1\u6709\u4EA7\u51FA\u52A8\u4F5C\uFF08\u8017\u65F6 ${t.durationMs}ms\uFF09\u3002\u8BF7\u68C0\u67E5\u6570\u636E\u6E90\u662F\u5426\u6709\u53EF\u7528\u884C\u3002`:`${e}\uFF1A\u4EA7\u51FA ${t.actions} \u4E2A\u52A8\u4F5C\uFF08\u843D\u5E93 ${t.applied}\uFF0C\u77AC\u6001 ${t.transient}\uFF09\uFF0C\u8017\u65F6 ${t.durationMs}ms\u3002`}c(Wn,"formatTriggerOnceResult");function lt(r){return new Promise(t=>{r.write("",()=>t())})}c(lt,"flushStream");function pt(){return Promise.all([lt(process.stdout),lt(process.stderr)])}c(pt,"flushOutputs");function mt(r,t){r.command("trigger-once").description("\u5355\u6B21\u89E6\u53D1\u67D0\u4E2A\u5DE5\u4F5C\u6D41\u7684\u4E8B\u4EF6\u6E90 handler \u8DD1\u4E00\u904D\uFF08\u53EA\u8DD1\u4E8B\u4EF6\u6E90 handler\uFF0C\u4E0D\u542F\u52A8\u5E38\u9A7B\u5F15\u64CE\uFF1B\u6B65\u9AA4\u94FE\u7531\u8FD0\u884C\u4E2D\u7684\u5F15\u64CE\u63A8\u8FDB\uFF09").requiredOption("-w, --workflow <id>","\u5DE5\u4F5C\u6D41 ID\uFF08\u591A\u5DE5\u4F5C\u6D41\u9879\u76EE\u91CC\u7684\u76EE\u5F55\u540D\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-s, --source <name>","\u53EA\u89E6\u53D1\u6307\u5B9A\u4E8B\u4EF6\u6E90\uFF1B\u7F3A\u7701\u7528\u8BE5\u5DE5\u4F5C\u6D41\u7684\u7B2C\u4E00\u4E2A\u4E8B\u4EF6\u6E90").option("--json","\u4EE5 JSON \u8F93\u51FA\u7ED3\u679C\uFF08\u4F9B\u811A\u672C\u6D88\u8D39\uFF09").action(async e=>{e.json&&Ce.setSink((n,o)=>process.stderr.write(`${o}
7
+ `)}await Sn({config:e.config,clean:e.clean,kb:e.kb,...e.kbFull?{kbFull:!0}:{},...n?{only:"automations"}:{}}),await Z("setup.finish",{success:!0,durationMs:Date.now()-o})}catch(i){xn.error("cli","setup \u5931\u8D25",{error:i instanceof Error?i.message:String(i)}),await Z("setup.finish",{success:!1,error:(i instanceof Error?i.message:String(i)).slice(0,500),durationMs:Date.now()-o}),process.exit(1)}})}c(ot,"registerSetupCommand");import rt from"path";import{createApp as it,ensureTsxRegistered as $n,checkMigrateHint as Pn,logger as v,runCheck as jn}from"aitable-workflow-core";function On(){let e=[],n=c(()=>{let o=Date.now();for(e.push(o);e.length>0&&o-e[0]>6e4;)e.shift();e.length>=10&&(v.error("cli",`60000ms \u5185\u53D1\u751F ${e.length} \u6B21\u672A\u6355\u83B7\u5F02\u5E38\uFF0C\u7591\u4F3C\u975E\u5076\u53D1\u9519\u8BEF\uFF0C\u4E3B\u52A8\u9000\u51FA`),process.exit(1))},"recordCrashAndMaybeExit");process.on("uncaughtException",o=>{v.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406\u5F02\u5E38\uFF08\u5DF2\u5B58\u6D3B\uFF0C\u4EA4\u7531\u91CD\u8FDE/\u91CD\u8BD5\u903B\u8F91\u81EA\u6108\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()}),process.on("unhandledRejection",o=>{v.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406 Promise \u62D2\u7EDD\uFF08\u5DF2\u5B58\u6D3B\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()})}c(On,"installLongRunningCrashGuards");function st(r,t){r.command("start").description("\u542F\u52A8\u7EDF\u4E00\u63A7\u5236\u53F0\uFF1A\u914D\u7F6E\u68C0\u6D4B + \u642D\u5EFA + \u8FD0\u884C\u4E00\u4F53\u5316").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-p, --port <number>","\u63A7\u5236\u53F0\u7AEF\u53E3\u9996\u9009\u503C\uFF08\u7F3A\u7701 8788\uFF0C\u4E0D\u53EF\u7528\u65F6\u5411\u4E0A\u907F\u8BA9 13 \u4E2A\u7AEF\u53E3\uFF1B\u591A\u9879\u76EE\u5E76\u884C\u65F6\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A\uFF09").option("--no-open","\u542F\u52A8\u540E\u4E0D\u8981\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668").option("--skip-config-if-valid","\u914D\u7F6E\u5DF2\u5B8C\u6574\u65F6\u76F4\u63A5\u542F\u52A8\u8FD0\u884C").action(async e=>{let n;if(e.port!==void 0){let o=Number.parseInt(e.port,10);(!Number.isFinite(o)||o<=0||o>65535)&&(v.error("cli",`--port \u53D6\u503C\u975E\u6CD5: "${e.port}"\uFF08\u9700\u4E3A 1-65535 \u6574\u6570\uFF09`),process.exit(1)),n=o}try{await Pn(rt.dirname(rt.resolve(e.config)),t.version),On(),await $n();let o=await jn({configPath:e.config}),i=!o.ok||o.summary.errors>0,s,a="setup";if(!i)try{a="runtime",s=await it(e.config,{})}catch(m){v.warn("cli","\u914D\u7F6E\u6821\u9A8C\u901A\u8FC7\u4F46\u88C5\u914D\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u642D\u5EFA\u6A21\u5F0F",{error:m instanceof Error?m.message:String(m)}),a="setup",s=void 0}a==="runtime"&&s?e.skipConfigIfValid?(v.info("cli","\u914D\u7F6E\u5DF2\u5B8C\u6574\uFF0C\u76F4\u63A5\u542F\u52A8\u8FD0\u884C"),s.start().catch(m=>{v.error("cli","\u8FD0\u884C\u542F\u52A8\u5931\u8D25\uFF0C\u53EF\u5728\u63A7\u5236\u53F0\u91CD\u8BD5\u542F\u52A8",{error:m instanceof Error?m.message:String(m)})})):v.info("cli","\u914D\u7F6E\u5DF2\u5B8C\u6574\uFF0C\u8BF7\u5728\u63A7\u5236\u53F0\u70B9\u51FB\u300C\u5F00\u59CB\u8FD0\u884C\u300D\u542F\u52A8\u670D\u52A1"):v.info("cli","\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF0C\u63A7\u5236\u53F0\u5C06\u5F15\u5BFC\u5B8C\u6210\u642D\u5EFA");let l=!1,p=c(async()=>{l&&(v.warn("cli","\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),l=!0,v.info("cli","\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u505C\u6B62\u8FD0\u884C...");try{await s?.stop()}finally{process.exit(0)}},"shutdown");process.on("SIGINT",p),process.on("SIGTERM",p),await Ke({configPath:e.config,mode:a,app:s,port:n,open:e.open,exitOnSetupError:!1,...a==="runtime"&&e.skipConfigIfValid?{initialRunStatus:{status:"running",since:new Date().toISOString(),lastError:null}}:{},...a==="setup"?{assembleApp:c(m=>it(m,{}),"assembleApp"),onAppAssembled:c(m=>{s=m,v.info("cli","\u63A7\u5236\u53F0\u5DF2\u5B8C\u6210 setup\u2192runtime \u664B\u5347\uFF0C\u53EF\u5728\u63A7\u5236\u53F0\u542F\u52A8\u8FD0\u884C")},"onAppAssembled")}:{}})}catch(o){v.error("cli","start \u547D\u4EE4\u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})}c(st,"registerStartCommand");import{createApp as _n,ensureTsxRegistered as Dn,checkMigrateHint as Ln,logger as O,reportCliEvent as ee,setReportProject as Mn}from"aitable-workflow-core";import at from"path";function Fn(){let e=[],n=c(async()=>{let o=Date.now();for(e.push(o);e.length>0&&o-e[0]>6e4;)e.shift();e.length>=10&&(O.error("cli",`60000ms \u5185\u53D1\u751F ${e.length} \u6B21\u672A\u6355\u83B7\u5F02\u5E38\uFF0C\u7591\u4F3C\u975E\u5076\u53D1\u9519\u8BEF\uFF0C\u4E3B\u52A8\u9000\u51FA`),await ee("run.exit",{reason:"crash-loop",crashes:e.length}),process.exit(1))},"recordCrashAndMaybeExit");process.on("uncaughtException",o=>{O.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406\u5F02\u5E38\uFF08\u5DF2\u5B58\u6D3B\uFF0C\u4EA4\u7531\u91CD\u8FDE/\u91CD\u8BD5\u903B\u8F91\u81EA\u6108\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()}),process.on("unhandledRejection",o=>{O.error("cli","\u6355\u83B7\u5230\u672A\u5904\u7406 Promise \u62D2\u7EDD\uFF08\u5DF2\u5B58\u6D3B\uFF09",{error:o instanceof Error?o.message:String(o),stack:o instanceof Error?o.stack:void 0}),n()})}c(Fn,"installLongRunningCrashGuards");function ct(r,t){r.command("run").description("\u542F\u52A8\u7F16\u6392\u5F15\u64CE\uFF0C\u5F00\u59CB\u8F6E\u8BE2\u5904\u7406\u5DE5\u5355").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("--emit-events <channel>","\u8FD0\u884C\u4E8B\u4EF6\u4E0A\u629B\u901A\u9053\uFF1Aipc = \u7ECF process.send \u53D1\u7ED9\u7236\u8FDB\u7A0B\uFF08daemon runner \u7528\uFF09\uFF0C\u7F3A\u7701\u4E0D\u4E0A\u629B").option("-p, --port <number>","\uFF08\u4EC5\u517C\u5BB9 launcher \u900F\u4F20\uFF0Crun \u547D\u4EE4\u4E0D\u4F7F\u7528\u6B64\u53C2\u6570\uFF09").action(async e=>{Mn(e.config);try{await Ln(at.dirname(at.resolve(e.config)),t.version),Fn(),await Dn();let n=e.emitEvents==="ipc"&&typeof process.send=="function",o=await _n(e.config,n?{onRunEvent:c(a=>{process.send?.({type:"run-event",event:a})},"onRunEvent")}:{});ee("run.start",{emitEvents:e.emitEvents??null});let i=!1,s=c(async()=>{i&&(O.warn("cli","\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),i=!0,O.info("cli","\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u7B49\u5F85\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u5B8C\u6210...");try{await o.stop()}finally{await ee("run.exit",{reason:"signal"}),process.exit(0)}},"shutdown");process.on("SIGINT",s),process.on("SIGTERM",s),await o.start()}catch(n){O.error("cli","\u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),await ee("run.exit",{reason:"start-failure",error:(n instanceof Error?n.message:String(n)).slice(0,500)}),process.exit(1)}})}c(ct,"registerRunCommand");import{createApp as Bn,ensureTsxRegistered as Un,logger as Re}from"aitable-workflow-core";function Wn(r,t){let e=`\u5DE5\u4F5C\u6D41 ${r} / \u4E8B\u4EF6\u6E90 ${t.sourceName}\uFF08handler: ${t.handlerRecipe}\uFF09`;return t.actions===0?`${e}\uFF1A\u5DF2\u89E6\u53D1\u4F46\u6CA1\u6709\u4EA7\u51FA\u52A8\u4F5C\uFF08\u8017\u65F6 ${t.durationMs}ms\uFF09\u3002\u8BF7\u68C0\u67E5\u6570\u636E\u6E90\u662F\u5426\u6709\u53EF\u7528\u884C\u3002`:`${e}\uFF1A\u4EA7\u51FA ${t.actions} \u4E2A\u52A8\u4F5C\uFF08\u843D\u5E93 ${t.applied}\uFF0C\u77AC\u6001 ${t.transient}\uFF09\uFF0C\u8017\u65F6 ${t.durationMs}ms\u3002`}c(Wn,"formatTriggerOnceResult");function lt(r){return new Promise(t=>{r.write("",()=>t())})}c(lt,"flushStream");function pt(){return Promise.all([lt(process.stdout),lt(process.stderr)])}c(pt,"flushOutputs");function mt(r,t){r.command("trigger-once").description("\u5355\u6B21\u89E6\u53D1\u67D0\u4E2A\u5DE5\u4F5C\u6D41\u7684\u4E8B\u4EF6\u6E90 handler \u8DD1\u4E00\u904D\uFF08\u53EA\u8DD1\u4E8B\u4EF6\u6E90 handler\uFF0C\u4E0D\u542F\u52A8\u5E38\u9A7B\u5F15\u64CE\uFF1B\u6B65\u9AA4\u94FE\u7531\u8FD0\u884C\u4E2D\u7684\u5F15\u64CE\u63A8\u8FDB\uFF09").requiredOption("-w, --workflow <id>","\u5DE5\u4F5C\u6D41 ID\uFF08\u591A\u5DE5\u4F5C\u6D41\u9879\u76EE\u91CC\u7684\u76EE\u5F55\u540D\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-s, --source <name>","\u53EA\u89E6\u53D1\u6307\u5B9A\u4E8B\u4EF6\u6E90\uFF1B\u7F3A\u7701\u7528\u8BE5\u5DE5\u4F5C\u6D41\u7684\u7B2C\u4E00\u4E2A\u4E8B\u4EF6\u6E90").option("--json","\u4EE5 JSON \u8F93\u51FA\u7ED3\u679C\uFF08\u4F9B\u811A\u672C\u6D88\u8D39\uFF09").action(async e=>{e.json&&Re.setSink((n,o)=>process.stderr.write(`${o}
8
8
  `));try{await Un();let o=await(await Bn(e.config)).triggerWorkflowOnce(e.workflow,{...e.source?{sourceName:e.source}:{}});e.json?process.stdout.write(`${JSON.stringify({ok:!0,workflowId:e.workflow,...o})}
9
- `):Ce.info("cli",Wn(e.workflow,o)),await pt(),process.exit(0)}catch(n){let o=n instanceof Error?n.message:String(n);e.json?process.stdout.write(`${JSON.stringify({ok:!1,error:o})}
10
- `):Ce.error("cli","\u89E6\u53D1\u5931\u8D25",{error:o}),await pt(),process.exit(1)}})}c(mt,"registerTriggerCommand");import{readFile as gt}from"fs/promises";import ne from"path";import ut from"yaml";import{logger as Nn,loadSettings as ft,loadWorkflowTemplate as Gn,resolveConfigPath as dt,scanWorkflowDirs as Hn,buildEnvSource as qn,loadProfileConfig as Kn,resetProfileCache as Vn,runWorkflowGates as Yn}from"aitable-workflow-core";function ht(r,t){let e=r.command("validate").description("\u9A8C\u8BC1\u914D\u7F6E\u6587\u4EF6\u548C\u5DE5\u4F5C\u6D41\u6A21\u677F").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).action(async n=>{try{let o=await dt(n.config),i=await ft(o);console.log("\u2713 \u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u901A\u8FC7");let s=await Gn(i.workflowTemplatePath,{envSource:i.envSource});console.log(`\u2713 \u5DE5\u4F5C\u6D41\u6A21\u677F\u9A8C\u8BC1\u901A\u8FC7: ${s.meta.name} (${s.orderedStepIds.length} \u6B65)`),console.log(`
9
+ `):Re.info("cli",Wn(e.workflow,o)),await pt(),process.exit(0)}catch(n){let o=n instanceof Error?n.message:String(n);e.json?process.stdout.write(`${JSON.stringify({ok:!1,error:o})}
10
+ `):Re.error("cli","\u89E6\u53D1\u5931\u8D25",{error:o}),await pt(),process.exit(1)}})}c(mt,"registerTriggerCommand");import{readFile as gt}from"fs/promises";import ne from"path";import ut from"yaml";import{logger as Nn,loadSettings as ft,loadWorkflowTemplate as Gn,resolveConfigPath as dt,scanWorkflowDirs as Hn,buildEnvSource as qn,loadProfileConfig as Kn,resetProfileCache as Vn,runWorkflowGates as Yn}from"aitable-workflow-core";function ht(r,t){let e=r.command("validate").description("\u9A8C\u8BC1\u914D\u7F6E\u6587\u4EF6\u548C\u5DE5\u4F5C\u6D41\u6A21\u677F").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).action(async n=>{try{let o=await dt(n.config),i=await ft(o);console.log("\u2713 \u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u901A\u8FC7");let s=await Gn(i.workflowTemplatePath,{envSource:i.envSource});console.log(`\u2713 \u5DE5\u4F5C\u6D41\u6A21\u677F\u9A8C\u8BC1\u901A\u8FC7: ${s.meta.name} (${s.orderedStepIds.length} \u6B65)`),console.log(`
11
11
  \u6B65\u9AA4\u94FE:`);for(let[u,d]of s.orderedStepIds.entries()){let w=s.steps.find(A=>A.id===d),I=u<s.orderedStepIds.length-1?" \u2192":" \u2713";console.log(` ${u+1}. [${d}] ${w?.name??"?"}${I}`)}let a=await gt(o,"utf8"),l=ut.parse(a),p=te(l.agent)?l.agent:{},g=typeof p.engine=="string"&&p.engine!==""?i.agent.engine:`\u672A\u914D\u7F6E\uFF08\u9ED8\u8BA4 ${i.agent.engine}\uFF09`;console.log(`
12
12
  \u914D\u7F6E\u6458\u8981:`),console.log(` AI \u8868\u683C: base=${i.tracker.base_id} table=${i.tracker.table_id}`),console.log(` \u5F15\u64CE: ${g}`),console.log(` \u8F6E\u8BE2\u95F4\u9694: ${i.polling.interval_ms}ms`),console.log("\n\u63D0\u793A: \u8FD0\u884C `validate workflow` \u6267\u884C\u5B8C\u6574\u5DE5\u4F5C\u6D41\u95E8\u7981\uFF08\u53C2\u6570\u6D41\u8F6C\u8FDE\u901A\u6027\u7B49\uFF09")}catch(o){console.error(`\u2717 \u9A8C\u8BC1\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}});e.command("workflow").description("\u5DE5\u4F5C\u6D41\u95E8\u7981\uFF1A\u68C0\u6D4B\u5DE5\u4F5C\u6D41\u6700\u57FA\u672C\u7684\u94FE\u8DEF\u662F\u5426\u80FD\u8DD1\u901A\uFF08\u7ED3\u6784/recipe \u7ED1\u5B9A/\u7C7B\u578B/\u914D\u7F6E\u5951\u7EA6/\u53C2\u6570\u6D41\u8F6C\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("--workflow <id>","\u53EA\u6821\u9A8C\u6307\u5B9A\u5DE5\u4F5C\u6D41\uFF08\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF09").option("--strict","warning \u7EA7\u95EE\u9898\u5347\u7EA7\u4E3A error").option("--no-typecheck","\u8DF3\u8FC7 recipe TS \u7C7B\u578B\u68C0\u67E5\uFF08\u6279\u91CF\u573A\u666F\u63D0\u901F\uFF09").option("--json","\u8F93\u51FA\u673A\u5668\u53EF\u8BFB GateReport JSON").action(async n=>{try{n.json&&Nn.setSink((g,u)=>process.stderr.write(`${u}
13
13
  `));let i=n.config&&n.config!==t.defaultConfig?n.config:e.opts().config??n.config,s=await dt(i),a=ne.dirname(s),l=await Jn(s,n.workflow);l.length===0&&(console.error("\u2717 \u672A\u627E\u5230\u4EFB\u4F55\u5DE5\u4F5C\u6D41"),process.exit(1));let p=await Xn(a),m=await Yn(l,{strict:n.strict===!0,includeTypecheck:n.typecheck!==!1,profile:p});m.configPath=s,n.json?console.log(JSON.stringify(m,null,2)):Zn(m),process.exit(m.ok?0:1)}catch(o){console.error(`\u2717 \u95E8\u7981\u6267\u884C\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}})}c(ht,"registerValidateCommand");async function Jn(r,t){let e=ne.dirname(r),n;try{n=(await ft(r,{lenientEnv:!0})).workflowEntries}catch{n=await zn(r,e)}if(t&&(n=n.filter(o=>o.id===t),n.length===0))throw new Error(`\u672A\u627E\u5230\u5DE5\u4F5C\u6D41\u300C${t}\u300D`);return n}c(Jn,"resolveWorkflowEntries");function te(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}c(te,"isRecord");async function zn(r,t){let e=await gt(r,"utf8"),n=ut.parse(e);if(!te(n))throw new Error("\u914D\u7F6E\u6587\u4EF6\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61");if(te(n.workflow)){let o=n.workflow.template,i=n.workflow.recipe_dir??"./recipes";if(typeof o=="string")return[{id:"default",templatePath:ne.resolve(t,o),recipeDir:ne.resolve(t,String(i))}]}if(te(n.workflows)&&typeof n.workflows.dir=="string")return await Hn(t,n.workflows.dir);throw new Error("\u914D\u7F6E\u4E2D\u672A\u627E\u5230 workflow / workflows \u6BB5")}c(zn,"inferEntriesFromRawYaml");async function Xn(r){try{Vn();let t=await qn(r);return Kn(r,t,{lenientEnv:!0})}catch{return null}}c(Xn,"tryLoadProfile");var Qn={structure:"\u7ED3\u6784\u5B8C\u6574\u6027",recipe_bind:"Recipe \u7ED1\u5B9A",recipe_typecheck:"\u7C7B\u578B\u68C0\u67E5",config_contract:"\u914D\u7F6E\u5951\u7EA6",dataflow:"\u53C2\u6570\u6D41\u8F6C"};function Zn(r){console.log(`\u5DE5\u4F5C\u6D41\u95E8\u7981\u6821\u9A8C${r.strict?"\uFF08--strict\uFF09":""}`),console.log("\u2550".repeat(56));for(let e of r.workflows){console.log(`
@@ -18,18 +18,18 @@ import{a as He,b as qe,m as Ke}from"./chunk-VYYLEYUZ.js";import"./chunk-4B6V7VHM
18
18
  `),process.exit(1)}})}c(wt,"registerConfigCommand");import{runSync as io,logger as so}from"aitable-workflow-core";function yt(r,t){r.command("sync").description("\u68C0\u6D4B\u914D\u7F6E\u4E0E\u8868\u7684\u504F\u5DEE\uFF08\u5B57\u6BB5\u7C7B\u578B/\u9009\u9879 drift\uFF09\uFF0C\u8F93\u51FA\u8BCA\u65AD\u62A5\u544A\u548C\u4FEE\u590D\u5EFA\u8BAE").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-y, --yes","\u975E\u4EA4\u4E92\u6A21\u5F0F").action(async e=>{try{await io({configPath:e.config,yes:e.yes})}catch(n){so.error("cli","sync \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(yt,"registerSyncCommand");import{listCodingAgents as ao,logger as co}from"aitable-workflow-core";function kt(r,t){r.command("agents").description("\u5217\u51FA\u5168\u90E8\u652F\u6301\u7684 Coding Agent \u9002\u914D\u5668\uFF0C\u5E76\u6807\u6CE8\u672C\u673A\u5DF2\u63A2\u6D4B\u5230\u5B89\u88C5\u7684").option("--json","\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action(e=>{try{let n=ao();if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
19
19
  `);return}let o=n.filter(i=>i.installed).length;console.log(`
20
20
  \u652F\u6301 ${n.length} \u4E2A Coding Agent\uFF0C\u672C\u673A\u5DF2\u63A2\u6D4B\u5230 ${o} \u4E2A\uFF1A
21
- `);for(let i of n){let s=i.installed?"\u2713":"\u2717",a=[i.bin,...i.fallbackBins].join(" / "),l=i.installed?`\u5DF2\u5B89\u88C5 (${i.detectedCmd}${i.detectedVersion?` ${i.detectedVersion}`:""})`:"\u672A\u63A2\u6D4B\u5230";console.log(` ${s} ${i.name.padEnd(16)} [${i.id}] bin: ${a.padEnd(24)} ${l}`)}console.log("")}catch(n){co.error("cli","\u5217\u51FA agents \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(kt,"registerAgentsCommand");import{logger as lo}from"aitable-workflow-core";import{startServer as po,resolveServeConfig as mo}from"aitable-workflow-server";import oe from"path";import{existsSync as vt}from"fs";function bt(r,t){r.command("serve").description("\u542F\u52A8\u672C\u5730 HTTP API \u670D\u52A1\u5E76\u6258\u7BA1 Web \u524D\u7AEF\u9875\u9762\uFF08local \u6A21\u5F0F\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF09").option("-p, --port <number>","\u76D1\u542C\u7AEF\u53E3\uFF08\u9ED8\u8BA4 8787\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_PORT \u8986\u76D6\uFF09").option("--host <host>","\u76D1\u542C\u5730\u5740\uFF08\u9ED8\u8BA4 127.0.0.1\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_HOST \u8986\u76D6\uFF09").option("--data-root <path>","\u9879\u76EE\u5DE5\u4F5C\u533A\u6570\u636E\u76EE\u5F55\uFF08\u9ED8\u8BA4 .sandbox/aitable-workflow-server\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_DATA_DIR \u8986\u76D6\uFF09").option("--web-root <path>","Web \u524D\u7AEF\u9759\u6001\u8D44\u6E90\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u968F CLI \u6253\u5305\u7684 dist/web\uFF09").option("--no-open","\u542F\u52A8\u540E\u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF08\u9ED8\u8BA4\u81EA\u52A8\u6253\u5F00\uFF09").action(async e=>{try{let n={};if(e.port!==void 0){let i=Number.parseInt(e.port,10);Number.isFinite(i)&&i>0&&(n.port=i)}if(e.host!==void 0&&(n.host=e.host),e.dataRoot!==void 0&&(n.dataRoot=e.dataRoot),e.webRoot!==void 0)n.webRoot=e.webRoot;else{let i=oe.join(t.cliDir,"web");if(vt(oe.join(i,"index.html")))n.webRoot=i;else{let s=oe.resolve(t.cliDir,"..","..","web","dist");vt(oe.join(s,"index.html"))&&(n.webRoot=s)}}let o=mo(n);if(await po(o),o.webRoot&&e.open!==!1){let i=o.host==="0.0.0.0"?"127.0.0.1":o.host;qe(`http://${i}:${o.port}`)}}catch(n){lo.error("cli","HTTP \u670D\u52A1\u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(bt,"registerServeCommand");import{Command as Le}from"commander";import{logger as S,listCredentials as qt,getActiveCredential as j,maskSecret as Ar}from"aitable-workflow-core";import F from"os";import M from"path";import{mkdir as er,readFile as tr}from"fs/promises";import{mkdirSync as nr}from"fs";import{logger as y,detectInstalledAgents as or,runCodingAgent as rr,DwsClient as ir,getActiveCredential as sr,assertPortableId as Mt,resolveInsideRoot as Lt,probeCommand as ar}from"aitable-workflow-core";import Ie from"ws";import{logger as x,RELAY_REJECTED_CODE as go,isRelayMessage as uo}from"aitable-workflow-core";var T="relay:conn",Rt=1e3,fo=3e4,ho=Number(process.env.AITABLE_RELAY_SERVER_STALE_MS??9e4),re=class{static{c(this,"RelayConnection")}ws=null;delay=Rt;timer=null;watchdog=null;should=!0;permanentlyRejected=!1;accepted=!1;lastServerFrameAt=0;serverUrl;key;token;onMessage;onOpen;onAccepted;onPermanentReject;mkWs;staleMs;constructor(t){this.serverUrl=t.serverUrl,this.key=t.key??"",this.token=t.token??"",this.onMessage=t.onMessage,this.onOpen=t.onOpen,this.onAccepted=t.onAccepted,this.onPermanentReject=t.onPermanentReject,this.mkWs=t.mkWs??(e=>new Ie(e)),this.staleMs=t.staleMs??ho}connect(){this.permanentlyRejected||(this.should=!0,this.doConnect())}send(t){this.ws&&this.ws.readyState===Ie.OPEN&&this.ws.send(JSON.stringify(t))}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 t=this.serverUrl.replace(/\/+$/,"").replace(/^http/,"ws"),e=this.token?`token=${encodeURIComponent(this.token)}`:`key=${encodeURIComponent(this.key)}`;return`${t}/api/relay/connect?${e}`}doConnect(){if(!this.should||this.permanentlyRejected)return;let t=this.buildUrl();x.info(T,"connecting",{serverUrl:this.serverUrl}),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.accepted=!1,this.lastServerFrameAt=0;let e=this.mkWs(t);this.ws=e,e.on("open",()=>{x.info(T,"connected"),this.onOpen?.(e)}),e.on("message",n=>{this.accepted||(this.accepted=!0,this.delay=Rt,this.onAccepted?.(e)),this.lastServerFrameAt=Date.now(),this.armWatchdog();let o;try{o=JSON.parse(typeof n=="string"?n:String(n))}catch{return}uo(o)&&(o.type==="ping"&&this.send({type:"pong"}),this.onMessage(o))}),e.on("close",(n,o)=>{this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null);let i=o==null?"":String(o);if(n===go){this.permanentlyRejected=!0,this.should=!1,x.error(T,"server permanently rejected this machine: its connection key is unknown or was removed; re-issue the relay connect command and restart with the new key",{code:n,reason:i}),this.onPermanentReject?.({code:n,reason:i});return}x.warn(T,"disconnected",{code:n}),this.scheduleReconnect()}),e.on("error",n=>{x.error(T,"ws error",{detail:n instanceof Error?n.message:String(n)})})}armWatchdog(){this.watchdog&&clearTimeout(this.watchdog),this.watchdog=setTimeout(()=>{if(!(!this.accepted||!this.lastServerFrameAt||this.ws?.readyState!==Ie.OPEN)){x.warn(T,"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||(x.info(T,"reconnecting",{ms:this.delay}),this.timer=setTimeout(()=>{this.timer=null,this.doConnect()},this.delay),this.timer.unref?.(),this.delay=Math.min(this.delay*2,fo))}};import{createHash as wo}from"crypto";import{readdir as yo,readFile as ko,stat as vo}from"fs/promises";import Ct from"path";import{isAllowedArtifactPath as bo,normalizeArtifactRelPath as Ro}from"aitable-workflow-core";var It={async upload(r,t,e){let n=await fetch(r,{method:"PUT",body:t,headers:{...e}});if(!n.ok)throw new Error(`artifact PUT failed: ${n.status} ${n.statusText}`)}};async function At(r){let t=[];return await St(r,r,t),t.sort((e,n)=>e.relPath.localeCompare(n.relPath))}c(At,"scanArtifacts");async function St(r,t,e){let n;try{n=await yo(t,{withFileTypes:!0})}catch{return}for(let o of n){if(o.name==="node_modules"||o.name.startsWith("."))continue;let i=Ct.join(t,o.name);if(o.isDirectory())await St(r,i,e);else if(o.isFile()){let s=Ct.relative(r,i).replace(/\\/g,"/");if(!bo(s))continue;let a=await vo(i),l=await ko(i),p=wo("sha256").update(l).digest("hex");e.push({relPath:Ro(s),absPath:i,size:a.size,sha256:p})}}}c(St,"walk");import Dt from"path";import{logger as b}from"aitable-workflow-core";import{logger as _,spawnManagedProcess as Co}from"aitable-workflow-core";var D="engine-supervisor",ie=class{static{c(this,"EngineSupervisor")}options;doSpawn;setTimer;clearTimer;child=null;childGen=0;consecutiveFailures=0;lastExitCode=null;lastError=null;restartTimer=null;stopped=!0;constructor(t){this.options=t,this.doSpawn=t.spawnImpl??Co,this.setTimer=t.setTimeoutImpl??((e,n)=>setTimeout(e,n)),this.clearTimer=t.clearTimeoutImpl??(e=>clearTimeout(e))}get status(){return{running:this.child!=null,pid:this.child?.managed.child.pid??null,generation:this.childGen,startedAt:this.child?new Date(this.child.startedAt).toISOString():null,consecutiveFailures:this.consecutiveFailures,lastExitCode:this.lastExitCode,lastError:this.lastError}}start(){this.stopped=!1,!this.child&&this.spawnChild()}async stop(){this.stopped=!0,this.restartTimer&&(this.clearTimer(this.restartTimer),this.restartTimer=null);let t=this.child;if(!t)return;t.stopping=!0;let e=t.managed.child.pid;if(e==null){this.child=null;return}let n=t.gen;await t.managed.terminateTree({gracePeriodMs:this.options.drainTimeoutMs??2e4}),t.managed.child.exitCode==null&&t.managed.child.signalCode==null&&(_.error(D,"\u5F15\u64CE\u8FDB\u7A0B\u672A\u54CD\u5E94\u5F3A\u5236\u7EC8\u6B62\uFF0C\u653E\u5F03\u7B49\u5F85\uFF08\u53EF\u80FD\u6B8B\u7559\u5B64\u513F\u8FDB\u7A0B\uFF09",{projectId:this.options.projectId,pid:e,generation:n}),this.child?.gen===n&&(this.child=null))}spawnChild(){this.childGen+=1;let t=this.childGen,e=["run","--config",this.options.workspaceDir,"--emit-events","ipc"],n=this.doSpawn({command:process.execPath,args:[this.options.cliPath,...e],cwd:this.options.workspaceDir,stdio:["ignore","pipe","pipe","ipc"],...this.options.env?{env:this.options.env}:{}}),o=n.child,i={managed:n,gen:t,startedAt:Date.now(),stopping:!1};this.child=i,_.info(D,"engine started",{projectId:this.options.projectId,pid:o.pid,generation:t}),o.on("message",s=>{Io(s)&&this.options.onRunEvent?.(s.event)}),o.on("error",s=>{this.lastError=s.message,_.error(D,"engine spawn error",{projectId:this.options.projectId,error:s.message})}),o.on("exit",(s,a)=>this.handleExit(i,s,a))}handleExit(t,e,n){if(this.child?.gen===t.gen&&(this.child=null),this.lastExitCode=e,_.info(D,"engine exited",{projectId:this.options.projectId,generation:t.gen,code:e,signal:n}),t.stopping||this.stopped)return;this.consecutiveFailures+=1;let o=this.options.maxConsecutiveFailures??5;if(this.consecutiveFailures>=o){_.error(D,"engine crash loop\uFF0C\u505C\u6B62\u91CD\u542F\u5E76\u4E0A\u62A5",{projectId:this.options.projectId,failures:this.consecutiveFailures}),this.stopped=!0,this.options.onCrashLoop?.({projectId:this.options.projectId,failures:this.consecutiveFailures,lastExitCode:e});return}let i=this.options.restartBackoffMs??1e3,s=this.options.restartBackoffMaxMs??6e4,a=Math.min(s,i*2**(this.consecutiveFailures-1));_.warn(D,"engine \u5F02\u5E38\u9000\u51FA\uFF0C\u9000\u907F\u91CD\u542F",{projectId:this.options.projectId,failures:this.consecutiveFailures,delayMs:a}),this.restartTimer=this.setTimer(()=>{this.restartTimer=null,!this.stopped&&!this.child&&this.spawnChild()},a)}markHealthy(){this.consecutiveFailures=0}};function Io(r){return typeof r=="object"&&r!==null&&r.type==="run-event"&&"event"in r}c(Io,"isRunEventMessage");import{appendFile as Ao,mkdir as So,rename as Eo,stat as xo}from"fs/promises";import To from"path";import{logger as se}from"aitable-workflow-core";var ae="event-spool",ce=class{static{c(this,"EventSpool")}options;setInterval;clearInterval;now;buffer=[];pending=[];seq=0;timer=null;flushing=!1;constructor(t){this.options=t,this.setInterval=t.setIntervalImpl??((e,n)=>setInterval(e,n)),this.clearInterval=t.clearIntervalImpl??(e=>clearInterval(e)),this.now=t.now??Date.now}get lastSeq(){return this.seq}get pendingCount(){return this.pending.length}start(){this.timer||(this.timer=this.setInterval(()=>{this.flush()},this.options.flushIntervalMs??500))}async stop(){this.timer&&(this.clearInterval(this.timer),this.timer=null),await this.flush()}append(t){this.seq+=1;let e={seq:this.seq,ts:new Date(this.now()).toISOString(),event:t};this.pending.push(e),this.buffer.push(e);let n=this.options.maxPending??5e3;if(this.pending.length>n){let i=this.pending.splice(0,this.pending.length-n);se.warn(ae,"\u5F85\u53D1\u4E8B\u4EF6\u8D85\u4E0A\u9650\uFF0C\u4E22\u5F03\u6700\u65E7\u7684\u6279\u6B21",{projectId:this.options.projectId,dropped:i.length,untilSeq:i[i.length-1]?.seq})}let o=this.options.retain??2e3;this.buffer.length>o&&this.buffer.splice(0,this.buffer.length-o),this.options.persist!==!1&&this.persist(e)}async flush(){if(this.flushing||this.pending.length===0)return;this.flushing=!0;let t=this.pending.slice(0,this.options.maxBatch??200);try{await this.options.send(t);let e=new Set(t.map(n=>n.seq));this.pending=this.pending.filter(n=>!e.has(n.seq))}catch(e){se.warn(ae,"\u4E8B\u4EF6\u6279\u4E0A\u884C\u5931\u8D25\uFF08\u4FDD\u7559\u5F85\u4E0B\u8F6E\u91CD\u8BD5\uFF09",{projectId:this.options.projectId,count:t.length,error:e instanceof Error?e.message:String(e)})}finally{this.flushing=!1}}replayFrom(t){let e=new Set(this.pending.map(o=>o.seq)),n=this.buffer.filter(o=>o.seq>t&&!e.has(o.seq));return n.length===0?0:(this.pending=[...this.pending,...n].sort((o,i)=>o.seq-i.seq),se.info(ae,"\u8865\u4F20\u7F3A\u53E3\u4E8B\u4EF6",{projectId:this.options.projectId,serverLastSeq:t,replay:n.length}),n.length)}async persist(t){let e=To.join(this.options.spoolDir,"run-events.jsonl");try{await So(this.options.spoolDir,{recursive:!0}),await xo(e).then(o=>o.size).catch(()=>0)>(this.options.rotateBytes??10*1024*1024)&&await Eo(e,`${e}.1`).catch(()=>{}),await Ao(e,`${JSON.stringify(t)}
21
+ `);for(let i of n){let s=i.installed?"\u2713":"\u2717",a=[i.bin,...i.fallbackBins].join(" / "),l=i.installed?`\u5DF2\u5B89\u88C5 (${i.detectedCmd}${i.detectedVersion?` ${i.detectedVersion}`:""})`:"\u672A\u63A2\u6D4B\u5230";console.log(` ${s} ${i.name.padEnd(16)} [${i.id}] bin: ${a.padEnd(24)} ${l}`)}console.log("")}catch(n){co.error("cli","\u5217\u51FA agents \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(kt,"registerAgentsCommand");import{logger as lo}from"aitable-workflow-core";import{startServer as po,resolveServeConfig as mo}from"aitable-workflow-server";import oe from"path";import{existsSync as vt}from"fs";function bt(r,t){r.command("serve").description("\u542F\u52A8\u672C\u5730 HTTP API \u670D\u52A1\u5E76\u6258\u7BA1 Web \u524D\u7AEF\u9875\u9762\uFF08local \u6A21\u5F0F\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF09").option("-p, --port <number>","\u76D1\u542C\u7AEF\u53E3\uFF08\u9ED8\u8BA4 8787\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_PORT \u8986\u76D6\uFF09").option("--host <host>","\u76D1\u542C\u5730\u5740\uFF08\u9ED8\u8BA4 127.0.0.1\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_HOST \u8986\u76D6\uFF09").option("--data-root <path>","\u9879\u76EE\u5DE5\u4F5C\u533A\u6570\u636E\u76EE\u5F55\uFF08\u9ED8\u8BA4 .sandbox/aitable-workflow-server\uFF0C\u53EF\u7528 AITABLE_WORKFLOW_DATA_DIR \u8986\u76D6\uFF09").option("--web-root <path>","Web \u524D\u7AEF\u9759\u6001\u8D44\u6E90\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u968F CLI \u6253\u5305\u7684 dist/web\uFF09").option("--no-open","\u542F\u52A8\u540E\u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF08\u9ED8\u8BA4\u81EA\u52A8\u6253\u5F00\uFF09").action(async e=>{try{let n={};if(e.port!==void 0){let i=Number.parseInt(e.port,10);Number.isFinite(i)&&i>0&&(n.port=i)}if(e.host!==void 0&&(n.host=e.host),e.dataRoot!==void 0&&(n.dataRoot=e.dataRoot),e.webRoot!==void 0)n.webRoot=e.webRoot;else{let i=oe.join(t.cliDir,"web");if(vt(oe.join(i,"index.html")))n.webRoot=i;else{let s=oe.resolve(t.cliDir,"..","..","web","dist");vt(oe.join(s,"index.html"))&&(n.webRoot=s)}}let o=mo(n);if(await po(o),o.webRoot&&e.open!==!1){let i=o.host==="0.0.0.0"?"127.0.0.1":o.host;qe(`http://${i}:${o.port}`)}}catch(n){lo.error("cli","HTTP \u670D\u52A1\u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(bt,"registerServeCommand");import{Command as Le}from"commander";import{logger as S,listCredentials as qt,getActiveCredential as j,maskSecret as Sr}from"aitable-workflow-core";import F from"os";import M from"path";import{mkdir as er,readFile as tr}from"fs/promises";import{mkdirSync as nr}from"fs";import{logger as y,detectInstalledAgents as or,runCodingAgent as rr,DwsClient as ir,getActiveCredential as sr,assertPortableId as Mt,resolveInsideRoot as Lt,probeCommand as ar,dwsCommandOptions as cr}from"aitable-workflow-core";import Ie from"ws";import{logger as x,RELAY_REJECTED_CODE as go,isRelayMessage as uo}from"aitable-workflow-core";var T="relay:conn",Ct=1e3,fo=3e4,ho=Number(process.env.AITABLE_RELAY_SERVER_STALE_MS??9e4),re=class{static{c(this,"RelayConnection")}ws=null;delay=Ct;timer=null;watchdog=null;should=!0;permanentlyRejected=!1;accepted=!1;lastServerFrameAt=0;serverUrl;key;token;onMessage;onOpen;onAccepted;onPermanentReject;mkWs;staleMs;constructor(t){this.serverUrl=t.serverUrl,this.key=t.key??"",this.token=t.token??"",this.onMessage=t.onMessage,this.onOpen=t.onOpen,this.onAccepted=t.onAccepted,this.onPermanentReject=t.onPermanentReject,this.mkWs=t.mkWs??(e=>new Ie(e)),this.staleMs=t.staleMs??ho}connect(){this.permanentlyRejected||(this.should=!0,this.doConnect())}send(t){this.ws&&this.ws.readyState===Ie.OPEN&&this.ws.send(JSON.stringify(t))}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 t=this.serverUrl.replace(/\/+$/,"").replace(/^http/,"ws"),e=this.token?`token=${encodeURIComponent(this.token)}`:`key=${encodeURIComponent(this.key)}`;return`${t}/api/relay/connect?${e}`}doConnect(){if(!this.should||this.permanentlyRejected)return;let t=this.buildUrl();x.info(T,"connecting",{serverUrl:this.serverUrl}),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.accepted=!1,this.lastServerFrameAt=0;let e=this.mkWs(t);this.ws=e,e.on("open",()=>{x.info(T,"connected"),this.onOpen?.(e)}),e.on("message",n=>{this.accepted||(this.accepted=!0,this.delay=Ct,this.onAccepted?.(e)),this.lastServerFrameAt=Date.now(),this.armWatchdog();let o;try{o=JSON.parse(typeof n=="string"?n:String(n))}catch{return}uo(o)&&(o.type==="ping"&&this.send({type:"pong"}),this.onMessage(o))}),e.on("close",(n,o)=>{this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null);let i=o==null?"":String(o);if(n===go){this.permanentlyRejected=!0,this.should=!1,x.error(T,"server permanently rejected this machine: its connection key is unknown or was removed; re-issue the relay connect command and restart with the new key",{code:n,reason:i}),this.onPermanentReject?.({code:n,reason:i});return}x.warn(T,"disconnected",{code:n}),this.scheduleReconnect()}),e.on("error",n=>{x.error(T,"ws error",{detail:n instanceof Error?n.message:String(n)})})}armWatchdog(){this.watchdog&&clearTimeout(this.watchdog),this.watchdog=setTimeout(()=>{if(!(!this.accepted||!this.lastServerFrameAt||this.ws?.readyState!==Ie.OPEN)){x.warn(T,"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||(x.info(T,"reconnecting",{ms:this.delay}),this.timer=setTimeout(()=>{this.timer=null,this.doConnect()},this.delay),this.timer.unref?.(),this.delay=Math.min(this.delay*2,fo))}};import{createHash as wo}from"crypto";import{readdir as yo,readFile as ko,stat as vo}from"fs/promises";import Rt from"path";import{isAllowedArtifactPath as bo,normalizeArtifactRelPath as Co}from"aitable-workflow-core";var It={async upload(r,t,e){let n=await fetch(r,{method:"PUT",body:t,headers:{...e}});if(!n.ok)throw new Error(`artifact PUT failed: ${n.status} ${n.statusText}`)}};async function At(r){let t=[];return await St(r,r,t),t.sort((e,n)=>e.relPath.localeCompare(n.relPath))}c(At,"scanArtifacts");async function St(r,t,e){let n;try{n=await yo(t,{withFileTypes:!0})}catch{return}for(let o of n){if(o.name==="node_modules"||o.name.startsWith("."))continue;let i=Rt.join(t,o.name);if(o.isDirectory())await St(r,i,e);else if(o.isFile()){let s=Rt.relative(r,i).replace(/\\/g,"/");if(!bo(s))continue;let a=await vo(i),l=await ko(i),p=wo("sha256").update(l).digest("hex");e.push({relPath:Co(s),absPath:i,size:a.size,sha256:p})}}}c(St,"walk");import Dt from"path";import{logger as b}from"aitable-workflow-core";import{logger as _,spawnManagedProcess as Ro}from"aitable-workflow-core";var D="engine-supervisor",ie=class{static{c(this,"EngineSupervisor")}options;doSpawn;setTimer;clearTimer;child=null;childGen=0;consecutiveFailures=0;lastExitCode=null;lastError=null;restartTimer=null;stopped=!0;constructor(t){this.options=t,this.doSpawn=t.spawnImpl??Ro,this.setTimer=t.setTimeoutImpl??((e,n)=>setTimeout(e,n)),this.clearTimer=t.clearTimeoutImpl??(e=>clearTimeout(e))}get status(){return{running:this.child!=null,pid:this.child?.managed.child.pid??null,generation:this.childGen,startedAt:this.child?new Date(this.child.startedAt).toISOString():null,consecutiveFailures:this.consecutiveFailures,lastExitCode:this.lastExitCode,lastError:this.lastError}}start(){this.stopped=!1,!this.child&&this.spawnChild()}async stop(){this.stopped=!0,this.restartTimer&&(this.clearTimer(this.restartTimer),this.restartTimer=null);let t=this.child;if(!t)return;t.stopping=!0;let e=t.managed.child.pid;if(e==null){this.child=null;return}let n=t.gen;await t.managed.terminateTree({gracePeriodMs:this.options.drainTimeoutMs??2e4}),t.managed.child.exitCode==null&&t.managed.child.signalCode==null&&(_.error(D,"\u5F15\u64CE\u8FDB\u7A0B\u672A\u54CD\u5E94\u5F3A\u5236\u7EC8\u6B62\uFF0C\u653E\u5F03\u7B49\u5F85\uFF08\u53EF\u80FD\u6B8B\u7559\u5B64\u513F\u8FDB\u7A0B\uFF09",{projectId:this.options.projectId,pid:e,generation:n}),this.child?.gen===n&&(this.child=null))}spawnChild(){this.childGen+=1;let t=this.childGen,e=["run","--config",this.options.workspaceDir,"--emit-events","ipc"],n=this.doSpawn({command:process.execPath,args:[this.options.cliPath,...e],cwd:this.options.workspaceDir,stdio:["ignore","pipe","pipe","ipc"],...this.options.env?{env:this.options.env}:{}}),o=n.child,i={managed:n,gen:t,startedAt:Date.now(),stopping:!1};this.child=i,_.info(D,"engine started",{projectId:this.options.projectId,pid:o.pid,generation:t}),o.on("message",s=>{Io(s)&&this.options.onRunEvent?.(s.event)}),o.on("error",s=>{this.lastError=s.message,_.error(D,"engine spawn error",{projectId:this.options.projectId,error:s.message})}),o.on("exit",(s,a)=>this.handleExit(i,s,a))}handleExit(t,e,n){if(this.child?.gen===t.gen&&(this.child=null),this.lastExitCode=e,_.info(D,"engine exited",{projectId:this.options.projectId,generation:t.gen,code:e,signal:n}),t.stopping||this.stopped)return;this.consecutiveFailures+=1;let o=this.options.maxConsecutiveFailures??5;if(this.consecutiveFailures>=o){_.error(D,"engine crash loop\uFF0C\u505C\u6B62\u91CD\u542F\u5E76\u4E0A\u62A5",{projectId:this.options.projectId,failures:this.consecutiveFailures}),this.stopped=!0,this.options.onCrashLoop?.({projectId:this.options.projectId,failures:this.consecutiveFailures,lastExitCode:e});return}let i=this.options.restartBackoffMs??1e3,s=this.options.restartBackoffMaxMs??6e4,a=Math.min(s,i*2**(this.consecutiveFailures-1));_.warn(D,"engine \u5F02\u5E38\u9000\u51FA\uFF0C\u9000\u907F\u91CD\u542F",{projectId:this.options.projectId,failures:this.consecutiveFailures,delayMs:a}),this.restartTimer=this.setTimer(()=>{this.restartTimer=null,!this.stopped&&!this.child&&this.spawnChild()},a)}markHealthy(){this.consecutiveFailures=0}};function Io(r){return typeof r=="object"&&r!==null&&r.type==="run-event"&&"event"in r}c(Io,"isRunEventMessage");import{appendFile as Ao,mkdir as So,rename as Eo,stat as xo}from"fs/promises";import To from"path";import{logger as se}from"aitable-workflow-core";var ae="event-spool",ce=class{static{c(this,"EventSpool")}options;setInterval;clearInterval;now;buffer=[];pending=[];seq=0;timer=null;flushing=!1;constructor(t){this.options=t,this.setInterval=t.setIntervalImpl??((e,n)=>setInterval(e,n)),this.clearInterval=t.clearIntervalImpl??(e=>clearInterval(e)),this.now=t.now??Date.now}get lastSeq(){return this.seq}get pendingCount(){return this.pending.length}start(){this.timer||(this.timer=this.setInterval(()=>{this.flush()},this.options.flushIntervalMs??500))}async stop(){this.timer&&(this.clearInterval(this.timer),this.timer=null),await this.flush()}append(t){this.seq+=1;let e={seq:this.seq,ts:new Date(this.now()).toISOString(),event:t};this.pending.push(e),this.buffer.push(e);let n=this.options.maxPending??5e3;if(this.pending.length>n){let i=this.pending.splice(0,this.pending.length-n);se.warn(ae,"\u5F85\u53D1\u4E8B\u4EF6\u8D85\u4E0A\u9650\uFF0C\u4E22\u5F03\u6700\u65E7\u7684\u6279\u6B21",{projectId:this.options.projectId,dropped:i.length,untilSeq:i[i.length-1]?.seq})}let o=this.options.retain??2e3;this.buffer.length>o&&this.buffer.splice(0,this.buffer.length-o),this.options.persist!==!1&&this.persist(e)}async flush(){if(this.flushing||this.pending.length===0)return;this.flushing=!0;let t=this.pending.slice(0,this.options.maxBatch??200);try{await this.options.send(t);let e=new Set(t.map(n=>n.seq));this.pending=this.pending.filter(n=>!e.has(n.seq))}catch(e){se.warn(ae,"\u4E8B\u4EF6\u6279\u4E0A\u884C\u5931\u8D25\uFF08\u4FDD\u7559\u5F85\u4E0B\u8F6E\u91CD\u8BD5\uFF09",{projectId:this.options.projectId,count:t.length,error:e instanceof Error?e.message:String(e)})}finally{this.flushing=!1}}replayFrom(t){let e=new Set(this.pending.map(o=>o.seq)),n=this.buffer.filter(o=>o.seq>t&&!e.has(o.seq));return n.length===0?0:(this.pending=[...this.pending,...n].sort((o,i)=>o.seq-i.seq),se.info(ae,"\u8865\u4F20\u7F3A\u53E3\u4E8B\u4EF6",{projectId:this.options.projectId,serverLastSeq:t,replay:n.length}),n.length)}async persist(t){let e=To.join(this.options.spoolDir,"run-events.jsonl");try{await So(this.options.spoolDir,{recursive:!0}),await xo(e).then(o=>o.size).catch(()=>0)>(this.options.rotateBytes??10*1024*1024)&&await Eo(e,`${e}.1`).catch(()=>{}),await Ao(e,`${JSON.stringify(t)}
22
22
  `,"utf8")}catch(n){se.warn(ae,"spool \u843D\u76D8\u5931\u8D25",{projectId:this.options.projectId,error:n instanceof Error?n.message:String(n)})}}};import{readdir as Te,rm as xe,stat as me}from"fs/promises";import L from"path";import{logger as N}from"aitable-workflow-core";import{createHash as Lo}from"crypto";import{mkdir as Se,readFile as Mo,rename as Fo,rm as Bo,writeFile as $t}from"fs/promises";import le from"path";import{decodeWorkspaceBundle as Uo,logger as Wo,resolveInsideRoot as No}from"aitable-workflow-core";import{chmod as $o,readFile as Po,rename as jo,writeFile as Oo}from"fs/promises";var Et="# \u2500\u2500\u2500 aitable-workflow managed credentials (auto-generated, do not edit) \u2500\u2500\u2500",xt="# \u2500\u2500\u2500 end managed credentials \u2500\u2500\u2500";function _o(r,t){let e=r.split(`
23
23
  `),n=e.indexOf(Et),o=e.indexOf(xt),i;n!==-1&&o!==-1&&o>n?i=[...e.slice(0,n),...e.slice(o+1)].join(`
24
24
  `):i=r,i=i.replace(/^\n+/,"");let s=Object.entries(t).sort(([l],[p])=>l.localeCompare(p));return s.length===0?i:`${[Et,...s.map(([l,p])=>`${l}=${Do(p)}`),xt].join(`
25
25
  `)}
26
26
  ${i?`
27
- ${i}`:""}`}c(_o,"mergeEnvContent");function Do(r){return r===""||/[\s#'"`\\]/.test(r)?`"${r.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`:r}c(Do,"quoteEnvValue");async function Tt(r,t){let e=await Po(r,"utf8").catch(()=>""),n=_o(e,t);if(n===e||n===""&&e==="")return!1;let o=`${r}.aitable-sync-tmp`;return await Oo(o,n,{encoding:"utf8",mode:384}),await $o(o,384).catch(()=>{}),await jo(o,r),!0}c(Tt,"mergeEnvFile");var Go="workspace-sync",pe=".workspace-meta.json";function Ho(r){return Lo("sha256").update(r).digest("hex")}c(Ho,"sha256Hex");async function Ae(r,t){let n=await(r.fetchImpl??fetch)(`${r.gatewayUrl.replace(/\/+$/,"")}${t}`,{headers:{authorization:`Bearer ${r.machineKey}`}});if(!n.ok){let o=await n.text().catch(()=>"");throw new Error(`runner API ${t} \u5931\u8D25: HTTP ${n.status} ${o.slice(0,200)}`)}return n}c(Ae,"apiGet");async function qo(r){try{let t=await Mo(le.join(r,pe),"utf8"),e=JSON.parse(t);return e&&typeof e.projectId=="string"?e:null}catch{return null}}c(qo,"readWorkspaceMeta");function Ee(r,t){return No(r,t,{allowRoot:!1})}c(Ee,"resolveTracked");async function Ko(r,t){let e=Ee(r,t.path);await Se(le.dirname(e),{recursive:!0});let n=`${e}.aitable-sync-tmp`;await $t(n,t.content,"utf8"),await Fo(n,e)}c(Ko,"writeTracked");async function Pt(r,t,e){let n=await qo(e);if(n&&n.projectId!==t)throw new Error(`\u5DE5\u4F5C\u533A\u76EE\u5F55\u5F52\u5C5E\u4E0D\u7B26: \u76EE\u5F55\u8BB0\u5F55 projectId=${n.projectId}\uFF0C\u8BF7\u6C42\u540C\u6B65 ${t}\uFF08${e}\uFF09`);let i=await(await Ae(r,`/api/runner/workspace/${t}`)).json(),s=0,a=0,l="up-to-date",p=n?.trackedManifest??{};if(!n||n.revision!==i.revision){l="synced";let w=await Ae(r,`/api/runner/workspace/${t}/bundle`),I=Uo(Buffer.from(await w.arrayBuffer()));if(I.projectId!==t)throw new Error(`\u5FEB\u7167\u5305\u5F52\u5C5E\u4E0D\u7B26: \u5305\u5185 projectId=${I.projectId}\uFF0C\u671F\u671B ${t}`);I.revision!==i.revision&&(i.revision=I.revision),await Se(e,{recursive:!0});let A={};for(let C of I.files)A[C.path]=Ho(C.content);for(let C of I.files)Ee(e,C.path);let z=n?.trackedManifest??{};for(let C of I.files)z[C.path]!==A[C.path]&&(await Ko(e,C),s+=1);for(let C of Object.keys(z))if(A[C]===void 0){let Ge;try{Ge=Ee(e,C)}catch(ke){Wo.warn(Go,"\u8DF3\u8FC7\u8D8A\u754C\u7684\u65E7 manifest \u6761\u76EE",{projectId:t,path:C,error:ke instanceof Error?ke.message:String(ke)});continue}await Bo(Ge,{force:!0}).catch(()=>{}),a+=1}p=A}let g=await(await Ae(r,`/api/runner/workspace/${t}/credentials`)).json();await Se(e,{recursive:!0});let u=await Tt(le.join(e,".env"),g.credentials??{}),d={projectId:t,revision:i.revision,syncedAt:new Date().toISOString(),trackedManifest:p};return await $t(le.join(e,pe),`${JSON.stringify(d,null,2)}
28
- `,"utf8"),{projectId:t,revision:i.revision,action:l,written:s,deleted:a,envUpdated:u}}c(Pt,"syncWorkspace");var G="runner-gc";async function Ot(r){let t=0,e;try{e=await Te(r,{withFileTypes:!0})}catch{return 0}for(let n of e){let o=L.join(r,n.name);if(!n.isSymbolicLink()){if(n.isDirectory()){t+=await Ot(o);continue}t+=await me(o).then(i=>i.size).catch(()=>0)}}return t}c(Ot,"dirSize");async function Vo(r){let t=L.join(r,"projects"),e;try{e=await Te(t,{withFileTypes:!0})}catch{return[]}let n=[];for(let o of e){if(!o.isDirectory())continue;let i=L.join(t,o.name),s=await me(L.join(i,pe)).then(l=>l.mtimeMs).catch(()=>null),a=await me(i).then(l=>l.mtimeMs).catch(()=>0);n.push({projectId:o.name,dir:i,lastTouchedMs:s??a,sizeBytes:await Ot(i)})}return n}c(Vo,"scanProjects");async function jt(r,t){let e=L.join(r,"traces"),n;try{n=await Te(e,{withFileTypes:!0})}catch{return 0}let o=[];for(let a of n){if(!a.isFile())continue;let l=L.join(e,a.name),p=await me(l).catch(()=>null);p&&o.push({full:l,size:p.size,mtimeMs:p.mtimeMs})}let i=o.reduce((a,l)=>a+l.size,0);if(i<=t)return 0;o.sort((a,l)=>a.mtimeMs-l.mtimeMs);let s=0;for(let a of o){if(i<=t)break;await xe(a.full,{force:!0}).catch(()=>{}),i-=a.size,s+=a.size}return s}c(jt,"pruneTraces");async function _t(r){let t=(r.now??Date.now)(),e=(r.ttlDays??14)*24*60*60*1e3,n=r.tracesMaxBytes??500*1024*1024,o=r.maxDiskBytes??20*1024*1024*1024,i=new Set(r.activeProjectIds),s=await Vo(r.workspaceRoot),a=[],l=0;for(let u of s){if(i.has(u.projectId)){l+=await jt(u.dir,n);continue}if(t-u.lastTouchedMs>=e){await xe(u.dir,{recursive:!0,force:!0}).catch(d=>{N.warn(G,"\u9879\u76EE\u76EE\u5F55\u56DE\u6536\u5931\u8D25",{projectId:u.projectId,error:d instanceof Error?d.message:String(d)})}),a.push(u.projectId),N.info(G,"\u56DE\u6536\u8FC7\u671F\u9879\u76EE\u76EE\u5F55",{projectId:u.projectId,idleDays:Math.floor((t-u.lastTouchedMs)/864e5)});continue}l+=await jt(u.dir,n)}let p=s.filter(u=>!a.includes(u.projectId)),m=p.reduce((u,d)=>u+d.sizeBytes,0)-l,g=!1;if(m>o){g=!0,N.warn(G,"\u5DE5\u4F5C\u533A\u8D85\u78C1\u76D8\u6C34\u4F4D\uFF0C\u5F00\u59CB\u56DE\u6536\u6700\u4E45\u672A\u8BA4\u9886\u9879\u76EE",{totalBytes:m,maxDiskBytes:o});let u=p.filter(d=>!i.has(d.projectId)).sort((d,w)=>d.lastTouchedMs-w.lastTouchedMs);for(let d of u){if(m<=o)break;await xe(d.dir,{recursive:!0,force:!0}).catch(()=>{}),a.push(d.projectId),m-=d.sizeBytes,N.warn(G,"\u6C34\u4F4D\u56DE\u6536\u9879\u76EE\u76EE\u5F55",{projectId:d.projectId,freedBytes:d.sizeBytes})}m>o&&N.error(G,"\u56DE\u6536\u540E\u4ECD\u8D85\u78C1\u76D8\u6C34\u4F4D\uFF08\u6D3B\u8DC3\u9879\u76EE\u5360\u7528\uFF09\uFF0C\u9700\u4EBA\u5DE5\u4ECB\u5165",{totalBytes:m,maxDiskBytes:o})}return{removedProjects:a,tracesFreedBytes:l,diskPressure:g,totalBytes:Math.max(0,m)}}c(_t,"runGc");var R="runner-loop",de=class{static{c(this,"RunnerLoop")}options;maxWorkflows;setTimer;clearTimer;doSync;holdings=new Map;pollTimer=null;gcTimer=null;running=!1;claiming=!1;constructor(t){this.options=t,this.maxWorkflows=Math.max(1,Math.floor(t.maxWorkflows??3)),this.setTimer=t.setTimeoutImpl??((e,n)=>setTimeout(e,n)),this.clearTimer=t.clearTimeoutImpl??(e=>clearTimeout(e)),this.doSync=t.syncImpl??Pt}get held(){return[...this.holdings.values()].map(t=>({projectId:t.projectId,generation:t.generation,revision:t.revision,engine:t.engine.status}))}get freeSlots(){return Math.max(0,this.maxWorkflows-this.holdings.size)}start(){this.running||(this.running=!0,b.info(R,"runner loop \u542F\u52A8",{maxWorkflows:this.maxWorkflows,workspaceRoot:this.options.workspaceRoot}),this.claimOnce(),this.scheduleGc(0))}async stop(){this.running=!1,this.pollTimer&&(this.clearTimer(this.pollTimer),this.pollTimer=null),this.gcTimer&&(this.clearTimer(this.gcTimer),this.gcTimer=null),await Promise.all([...this.holdings.keys()].map(t=>this.releaseHolding(t,"daemon_shutdown")))}scheduleGc(t){let e=this.options.gcIntervalMs??864e5;!this.running||e<=0||(this.gcTimer&&this.clearTimer(this.gcTimer),this.gcTimer=this.setTimer(()=>{this.gcTimer=null,this.gcOnce().finally(()=>this.scheduleGc(e))},t))}async gcOnce(){try{let t=await(this.options.gcImpl??_t)({workspaceRoot:this.options.workspaceRoot,activeProjectIds:[...this.holdings.keys()],...this.options.gcOptions??{}});(t.removedProjects.length>0||t.tracesFreedBytes>0)&&b.info(R,"\u672C\u673A\u56DE\u6536\u5B8C\u6210",{removed:t.removedProjects.length,tracesFreedBytes:t.tracesFreedBytes,totalBytes:t.totalBytes})}catch(t){b.warn(R,"\u672C\u673A\u56DE\u6536\u5931\u8D25",{error:$(t)})}}onWakeup(){this.running&&this.claimOnce()}async claimOnce(){if(!this.running||this.claiming)return;this.claiming=!0;let t=this.options.defaultPollMs??1e4;try{let e=this.freeSlots;if(e>0){let n=await this.post("/api/runner/workflows/claim",{capacity:e});typeof n.nextPollAfterMs=="number"&&n.nextPollAfterMs>0&&(t=n.nextPollAfterMs);for(let o of n.grants??[])await this.acceptGrant(o,n.heartbeatIntervalSeconds)}}catch(e){b.warn(R,"claim \u5931\u8D25\uFF08\u9000\u907F\u540E\u91CD\u8BD5\uFF09",{error:$(e)}),t=Math.max(t,5e3)}finally{this.claiming=!1,this.scheduleNextPoll(t)}}scheduleNextPoll(t){this.running&&(this.pollTimer&&this.clearTimer(this.pollTimer),this.pollTimer=this.setTimer(()=>{this.pollTimer=null,this.claimOnce()},t))}async acceptGrant(t,e){if(this.holdings.has(t.projectId))return;let n=Dt.join(this.options.workspaceRoot,"projects",t.projectId);b.info(R,"\u8BA4\u9886\u9879\u76EE",{projectId:t.projectId,generation:t.generation,workspaceDir:n});let o;try{o=await this.doSync(this.clientConfig(),t.projectId,n)}catch(l){b.error(R,"\u5DE5\u4F5C\u533A\u540C\u6B65\u5931\u8D25\uFF0C\u4EA4\u8FD8\u79DF\u7EA6",{projectId:t.projectId,error:$(l)}),await this.postSafe(`/api/runner/workflows/${t.projectId}/release`,{generation:t.generation,reason:"workspace_sync_failed"});return}let i=(this.options.createSupervisor??Yo)({projectId:t.projectId,workspaceDir:n,cliPath:this.options.cliPath,onRunEvent:c(l=>this.handleRunEvent(t.projectId,l),"onRunEvent"),onCrashLoop:c(()=>{this.releaseHolding(t.projectId,"engine_crash_loop")},"onCrashLoop")}),s=this.options.sendRunEvents?new ce({projectId:t.projectId,spoolDir:n,send:c(l=>this.options.sendRunEvents(t.projectId,l),"send")}):null;s?.start();let a={projectId:t.projectId,generation:t.generation,revision:o.revision,engine:i,spool:s,heartbeatTimer:null,busy:!1};this.holdings.set(t.projectId,a),i.start(),this.scheduleHeartbeat(a,(e??15)*1e3)}handleRunEvent(t,e){this.holdings.get(t)?.spool?.append(e),this.options.onRunEvent?.(t,e)}scheduleHeartbeat(t,e){this.running&&(t.heartbeatTimer&&this.clearTimer(t.heartbeatTimer),t.heartbeatTimer=this.setTimer(()=>{t.heartbeatTimer=null,this.heartbeatOnce(t)},e))}async heartbeatOnce(t){if(!this.running||t.busy||!this.holdings.has(t.projectId))return;let e=this.options.defaultHeartbeatMs??15e3;try{let n=await this.post(`/api/runner/workflows/${t.projectId}/heartbeat`,{generation:t.generation,workspaceRevision:t.revision,engineStatus:t.engine.status,...t.spool?{lastEventSeq:t.spool.lastSeq}:{}}),o=typeof n.nextIntervalSeconds=="number"&&n.nextIntervalSeconds>0?n.nextIntervalSeconds*1e3:e;if(t.spool&&typeof n.lastEventSeq=="number"&&t.spool.replayFrom(n.lastEventSeq),n.action==="stop"){b.info(R,"\u5FC3\u8DF3\u4E0B\u53D1 stop\uFF0C\u505C\u6B62\u5F15\u64CE",{projectId:t.projectId}),await this.releaseHolding(t.projectId,"heartbeat_stop");return}if(n.action==="resync"){await this.resyncHolding(t)&&this.scheduleHeartbeat(t,o);return}t.engine.markHealthy(),this.scheduleHeartbeat(t,o)}catch(n){b.warn(R,"\u5FC3\u8DF3\u5931\u8D25\uFF08\u4FDD\u6301\u5F15\u64CE\u8FD0\u884C\uFF0C\u7B49\u5F85\u6062\u590D\u6216\u79DF\u7EA6\u8FC7\u671F\uFF09",{projectId:t.projectId,error:$(n)}),this.scheduleHeartbeat(t,Math.min(e,5e3))}}async resyncHolding(t){if(t.busy)return!0;t.busy=!0;let e=Dt.join(this.options.workspaceRoot,"projects",t.projectId);try{b.info(R,"\u5DE5\u4F5C\u533A\u9700\u91CD\u540C\u6B65\uFF0C\u91CD\u542F\u5F15\u64CE",{projectId:t.projectId}),await t.engine.stop();let n=await this.doSync(this.clientConfig(),t.projectId,e);t.revision=n.revision,t.engine.start()}catch(n){return b.error(R,"\u91CD\u540C\u6B65\u5931\u8D25\uFF0C\u4EA4\u8FD8\u79DF\u7EA6",{projectId:t.projectId,error:$(n)}),t.busy=!1,await this.releaseHolding(t.projectId,"resync_failed"),!1}return t.busy=!1,!0}async releaseHolding(t,e){let n=this.holdings.get(t);n&&(this.holdings.delete(t),n.heartbeatTimer&&(this.clearTimer(n.heartbeatTimer),n.heartbeatTimer=null),await n.engine.stop().catch(o=>{b.warn(R,"\u505C\u6B62\u5F15\u64CE\u5F02\u5E38",{projectId:t,error:$(o)})}),await n.spool?.stop().catch(()=>{}),await this.postSafe(`/api/runner/workflows/${t}/release`,{generation:n.generation,reason:e}),b.info(R,"\u5DF2\u8BA9\u51FA\u79DF\u7EA6",{projectId:t,reason:e}),this.running&&this.scheduleNextPoll(this.options.defaultPollMs??1e4))}clientConfig(){return{gatewayUrl:this.options.gatewayUrl,machineKey:this.options.machineKey,...this.options.fetchImpl?{fetchImpl:this.options.fetchImpl}:{}}}async post(t,e){let o=await(this.options.fetchImpl??fetch)(`${this.options.gatewayUrl.replace(/\/+$/,"")}${t}`,{method:"POST",headers:{authorization:`Bearer ${this.options.machineKey}`,"content-type":"application/json"},body:JSON.stringify(e??{})});if(!o.ok){let i=await o.text().catch(()=>"");throw new Error(`runner API ${t} \u5931\u8D25: HTTP ${o.status} ${i.slice(0,200)}`)}return await o.json()}async postSafe(t,e){try{await this.post(t,e)}catch(n){b.warn(R,"\u6536\u5C3E\u8BF7\u6C42\u5931\u8D25\uFF08\u79DF\u7EA6\u5C06\u7531\u670D\u52A1\u7AEF\u8FC7\u671F\u56DE\u6536\uFF09",{pathname:t,error:$(n)})}}};function Yo(r){return new ie({projectId:r.projectId,workspaceDir:r.workspaceDir,cliPath:r.cliPath,...r.onRunEvent?{onRunEvent:r.onRunEvent}:{},...r.onCrashLoop?{onCrashLoop:c(()=>r.onCrashLoop(),"onCrashLoop")}:{}})}c(Yo,"defaultSupervisorFactory");function $(r){return r instanceof Error?r.message:String(r)}c($,"describeError");import{spawn as zo}from"child_process";import{existsSync as Xo}from"fs";import q from"path";import{fileURLToPath as Qo}from"url";import{appendFileSync as ea,statSync as ta,renameSync as na,mkdirSync as oa,existsSync as ra}from"fs";import Jo from"path";var aa=10*1024*1024;function H(r){return Jo.join(X(r),"daemon.log")}c(H,"logFilePath");var ge=q.dirname(Qo(import.meta.url));function $e(){let r=[q.resolve(ge,"..","..","bin","aitable-workflow.mjs"),q.resolve(ge,"..","bin","aitable-workflow.mjs"),q.resolve(ge,"..","..","dist","cli.js"),q.resolve(ge,"cli.js")];return r.find(t=>Xo(t))??r[0]}c($e,"resolveDaemonEntry");var Zo=$e();async function K(r){await Ve(r.agentId);let t=["relay"];r.serverUrl&&t.push("--server-url",r.serverUrl),r.token&&t.push("--token",r.token),r.key&&t.push("--key",r.key),r.name&&t.push("--name",r.name),r.workspaceRoot&&t.push("--workspace-root",r.workspaceRoot),r.machineId&&t.push("--machine-id",r.machineId),r.maxTasks&&t.push("--max-tasks",String(r.maxTasks));let e=await import("fs").then(s=>{let a=H(r.agentId);return s.openSync(a,"a")}),n=zo(process.execPath,[Zo,...t],{detached:!0,stdio:["ignore",e,e],env:{...process.env}});try{let{closeSync:s}=await import("fs");s(e)}catch{}n.unref();let{writeFile:o}=await import("fs/promises"),{pidFilePath:i}=await import("./pid-file-KT5KHCKU.js");return n.pid&&await o(i(r.agentId),String(n.pid),"utf8"),{pid:n.pid??0}}c(K,"startDaemon");async function ue(r,t=5e3){let e=await ve(r);if(e===null||!W(e))return await Q(r),!1;try{process.kill(e,"SIGTERM")}catch{return await Q(r),!1}let n=Date.now()+t;for(;Date.now()<n&&W(e);)await new Promise(o=>setTimeout(o,200));if(W(e))try{process.kill(e,"SIGKILL")}catch{}return await Q(r),!0}c(ue,"stopDaemon");async function V(r){let t=await ve(r),e=t!==null&&W(t),n=null;if(e&&t!==null)try{let{readFile:o}=await import("fs/promises"),i=await o(`/proc/${t}/stat`,"utf8"),s=parseInt(i.split(" ")[21]??"0",10),a=await o("/proc/uptime","utf8"),m=parseFloat(a.split(" ")[0]??"0")-s/100;n=Math.round(m*1e3)}catch{}return{agentId:r,running:e,pid:e?t:null,uptimeMs:n,logFile:H(r)}}c(V,"getDaemonStatus");function cr(r){return r.replace(/\/+$/,"").replace(/^ws/,"http")}c(cr,"toHttpBase");var k="relay:daemon",Ft=["aitable"],lr="dws";function pr(r,t=Ft){if(!Array.isArray(r)||r.length===0)return{ok:!1,reason:"dws args must be a non-empty array"};for(let n of r){if(typeof n!="string")return{ok:!1,reason:"dws args must all be strings"};if(n.length===0)return{ok:!1,reason:"dws args must not contain empty tokens"};if(/[\u0000-\u001f]/.test(n))return{ok:!1,reason:"dws args must not contain control characters"}}let e=r[0];return e.startsWith("-")?{ok:!1,reason:"first dws arg must be a subcommand, not a flag"}:t.length>0&&!t.includes(e)?{ok:!1,reason:`dws command "${e}" is not allowed`}:{ok:!0}}c(pr,"validateDwsArgs");function mr(r){return ar(r,["--version"],{timeoutMs:5e3}).ok}c(mr,"detectDwsAvailable");var Pe=class{static{c(this,"RelayDaemon")}config;allowedDwsCommands;conn;runAgent;createDwsClient;detectAgents;detectDws;hostname;osString;onPermanentReject;artifactUploader;grantTimeoutMs;pendingGrants=new Map;maxTasks;inflight=0;taskQueue=[];runnerLoop;machineId;constructor(t,e={}){this.config={...t,dwsBin:t.dwsBin??lr},this.machineId=t.machineId,this.allowedDwsCommands=t.allowedDwsCommands??Ft,this.runAgent=e.runAgent??rr,this.createDwsClient=e.createDwsClient??((o,i)=>new ir({bin:o,timeoutMs:i})),this.detectAgents=e.detectAgents??(()=>or()),this.detectDws=e.detectDws??(o=>mr(o)),this.hostname=e.hostname??(()=>F.hostname()),this.osString=e.osString??(()=>`${F.platform()} ${F.arch()}`),this.onPermanentReject=e.onPermanentReject,this.artifactUploader=e.artifactUploader??It,this.grantTimeoutMs=e.grantTimeoutMs??3e4,this.maxTasks=Math.max(1,Math.floor(t.maxTasks??1));let n=e.createConnection??(o=>new re(o));this.conn=n({serverUrl:this.config.serverUrl,key:this.config.key,token:this.config.token,onMessage:c(o=>this.handleMessage(o),"onMessage"),onOpen:c(()=>this.handleOpen(),"onOpen"),onPermanentReject:c(o=>this.handlePermanentReject(o),"onPermanentReject")}),this.runnerLoop=this.buildRunnerLoop(e)}buildRunnerLoop(t){let e=Math.max(0,Math.floor(this.config.maxWorkflows??3));if(e===0)return null;let n=this.config.key??this.config.token;if(!n)return y.warn(k,"\u65E0 machine key/owner-token\uFF0C\u8DF3\u8FC7 RunnerLoop\uFF08run \u9636\u6BB5\u4E0D\u8BA4\u9886\u9879\u76EE\uFF09"),null;let o={gatewayUrl:cr(this.config.serverUrl),machineKey:n,workspaceRoot:this.config.workspaceRoot,cliPath:$e(),maxWorkflows:e,sendRunEvents:c((i,s)=>this.sendRunEvents(i,s),"sendRunEvents")};return(t.createRunnerLoop??(i=>new de(i)))(o)}sendRunEvents(t,e){e.length!==0&&this.conn.send({type:"run:events",projectId:t,entries:e})}start(){y.info(k,"starting",{serverUrl:this.config.serverUrl,workspaceRoot:this.config.workspaceRoot}),this.config.name||y.warn(k,"\u672A\u6307\u5B9A --name\uFF0C\u5C06\u4F7F\u7528\u4E3B\u673A\u540D\u4F5C\u4E3A\u673A\u5668\u6CE8\u518C\u540D\uFF1B\u591A\u673A\u573A\u666F\u4E0B hostname \u82E5\u91CD\u590D\u4F1A\u5BFC\u81F4\u8FDE\u63A5\u4E92\u76F8\u9876\u66FF\uFF0C\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A --name",{hostname:this.hostname()}),this.conn.connect(),this.runnerLoop?.start()}stop(){return y.info(k,"stopping"),this.conn.close(),this.runnerLoop?this.runnerLoop.stop().catch(t=>{y.warn(k,"runner loop \u505C\u6B62\u5F02\u5E38",{error:t instanceof Error?t.message:String(t)})}):Promise.resolve()}buildReady(){let e={type:"ready",runtimes:Array.from(new Set(this.detectAgents().map(n=>n.type))),hasDws:this.detectDws(this.config.dwsBin),hostname:this.hostname(),os:this.osString()};return this.machineId&&(e.machineId=this.machineId),this.config.name&&(e.name=this.config.name),this.config.displayName&&(e.displayName=this.config.displayName),this.config.description&&(e.description=this.config.description),this.maxTasks>1&&(e.maxTasks=this.maxTasks),e}handleOpen(){let t=this.buildReady();y.info(k,"connected; sending ready",{runtimes:t.runtimes,hasDws:t.hasDws}),this.conn.send(t)}handlePermanentReject(t){y.error(k,"permanently rejected by gateway",{...t}),this.onPermanentReject?.(t)}handleMessage(t){switch(t.type){case"run:agent":this.enqueueTask(()=>this.handleRunAgent(t));break;case"run:dws":this.enqueueTask(()=>this.handleRunDws(t));break;case"upload:grant":this.resolveGrant(t);break;case"wf:available":this.runnerLoop?.onWakeup();break;case"ready:ack":t.machineId&&(this.machineId=t.machineId,y.info(k,"machine id assigned",{machineId:t.machineId}));break;default:break}}enqueueTask(t){let e=c(()=>{this.inflight+=1,t().finally(()=>{this.inflight-=1;let n=this.taskQueue.shift();n&&n()})},"exec");this.inflight<this.maxTasks?e():this.taskQueue.push(e)}async handleRunAgent(t){let{requestId:e}=t;y.info(k,"run:agent received",{requestId:e,projectId:t.projectId,agent:t.agent});try{let n=this.resolveWorkDir(t.projectId,t.workDir);await er(n,{recursive:!0});let o=this.rewritePromptWorkDir(t.prompt,t.workDir,n),i={agent:t.agent,workDir:n,onEvent:c(l=>this.conn.send({type:"event",requestId:e,event:l}),"onEvent")};t.sessionId&&(i.sessionId=t.sessionId),t.permissionMode&&(i.adapterOptions={permissionMode:t.permissionMode}),t.timeoutMs!==void 0?i.timeoutMs=t.timeoutMs:this.config.agentTimeoutMs!=null&&(i.timeoutMs=this.config.agentTimeoutMs);let s=await this.runAgent(o,i),a;try{a=await this.collectAndUploadArtifacts(e,t.projectId,n)}catch(l){let p=l instanceof Error?l.message:String(l);y.error(k,"artifact upload failed",{requestId:e,error:p}),this.conn.send({type:"error",requestId:e,code:"artifact_upload_failed",message:p});return}this.conn.send({type:"result",requestId:e,ok:!0,response:s.response,sessionId:s.sessionId,...a?{artifacts:a}:{}}),y.info(k,"run:agent done",{requestId:e,sessionId:s.sessionId,artifacts:a?a.files.length:0})}catch(n){let o=n instanceof Error?n.message:String(n);y.error(k,"run:agent failed",{requestId:e,error:o}),this.conn.send({type:"error",requestId:e,code:"agent_failed",message:o})}}async collectAndUploadArtifacts(t,e,n){let o=await At(n);if(o.length===0)return;this.conn.send({type:"upload:request",requestId:t,projectId:e,files:o.map(a=>({path:a.relPath,size:a.size,sha256:a.sha256}))});let i=await this.awaitGrant(t);if(!i)throw new Error("upload:grant \u7B49\u5F85\u8D85\u65F6");if(i.grants.length===0){y.warn(k,"upload:grant \u65E0\u6388\u6743\u9879\uFF08gateway \u672A\u914D\u7F6E store \u6216\u5168\u88AB\u62D2\uFF09",{requestId:t,rejected:(i.rejected??[]).length});return}let s=[];for(let a of i.grants){let l=o.find(m=>m.relPath===a.path);if(!l)continue;let p=await tr(l.absPath);await this.artifactUploader.upload(a.url,p,a.headers),s.push({path:a.path,key:a.key,sha256:l.sha256,size:l.size})}return{store:"oss",files:s}}awaitGrant(t){return new Promise(e=>{let n=setTimeout(()=>{this.pendingGrants.delete(t),e(void 0)},this.grantTimeoutMs);n.unref?.(),this.pendingGrants.set(t,o=>{clearTimeout(n),e(o)})})}resolveGrant(t){let e=this.pendingGrants.get(t.requestId);e&&(this.pendingGrants.delete(t.requestId),e(t))}async handleRunDws(t){let{requestId:e}=t,n=pr(t.args,this.allowedDwsCommands);if(!n.ok){y.warn(k,"run:dws rejected",{requestId:e,reason:n.reason}),this.conn.send({type:"error",requestId:e,code:"dws_rejected",message:n.reason});return}y.info(k,"run:dws received",{requestId:e,command:t.args[0]});try{let i=await this.createDwsClient(this.config.dwsBin,t.timeoutMs).runJson(t.args,t.timeoutMs!=null?{timeoutMs:t.timeoutMs}:void 0);this.conn.send({type:"result",requestId:e,ok:!0,response:JSON.stringify(i)}),y.info(k,"run:dws done",{requestId:e})}catch(o){let i=o instanceof Error?o.message:String(o);y.error(k,"run:dws failed",{requestId:e,error:i}),this.conn.send({type:"error",requestId:e,code:"dws_failed",message:i})}}resolveWorkDir(t,e){if(e&&e.trim()!=="")if(M.isAbsolute(e))y.warn(k,"\u5FFD\u7565\u670D\u52A1\u7AEF\u4E0B\u53D1\u7684\u7EDD\u5BF9\u8DEF\u5F84 workDir\uFF0C\u56DE\u9000\u5230 workspaceRoot/projectId",{workDir:e,projectId:t});else return Lt(this.config.workspaceRoot,e,{allowRoot:!1});return Lt(this.config.workspaceRoot,Mt(t,{label:"projectId"}),{allowRoot:!1})}rewritePromptWorkDir(t,e,n){let o=e?.trim();return!o||!M.isAbsolute(o)||o===n?t:t.split(o).join(n)}};function je(r,t){let e,n=r?.trim();if(n)e=M.isAbsolute(n)?M.resolve(n):M.resolve(F.homedir(),n);else{let o=t?.trim()?t.trim():"default";e=M.join(F.homedir(),".aitable-workflow","workspaces",Mt(o,{label:"agentId"}))}return nr(e,{recursive:!0}),e}c(je,"resolveWorkspaceRoot");function dr(r,t=process.env){let e=r.serverUrl??t.AITABLE_RELAY_SERVER_URL,n=r.key??t.AITABLE_RELAY_BOOTSTRAP_KEY,o=r.token??t.AITABLE_RELAY_TOKEN,i=r.workspaceRoot??t.AITABLE_RELAY_WORKSPACE_ROOT,s=r.machineId??t.AITABLE_RELAY_MACHINE_ID,a=r.name??t.AITABLE_RELAY_NAME,l=r.desc??t.AITABLE_RELAY_DESC,p=r.maxTasks??t.AITABLE_RELAY_MAX_TASKS,m=r.maxWorkflows??t.AITABLE_RELAY_MAX_WORKFLOWS,g=[];if(e||g.push("--server-url (\u6216 AITABLE_RELAY_SERVER_URL)"),!n&&!o&&g.push("--key/--token (\u6216 AITABLE_RELAY_BOOTSTRAP_KEY/AITABLE_RELAY_TOKEN)"),g.length>0)throw new Error(`relay \u7F3A\u5C11\u5FC5\u8981\u53C2\u6570: ${g.join(", ")}
29
- \u{1F4A1} \u63D0\u793A: \u4F7F\u7528 \`aitable-workflow connect\` \u6CE8\u518C\u540E\u53EF\u7701\u7565\u8FD9\u4E9B\u53C2\u6570`);let u=a??F.hostname()??"default",d={serverUrl:e,workspaceRoot:je(i,u)};if(o?d.token=o:n&&(d.key=n),s&&(d.machineId=s),a&&(d.name=a,d.displayName=a),l&&(d.description=l),p!=null&&p!==""){let w=Math.floor(Number(p));Number.isFinite(w)&&w>=1&&(d.maxTasks=w)}if(m!=null&&m!==""){let w=Math.floor(Number(m));Number.isFinite(w)&&w>=0&&(d.maxWorkflows=w)}return d}c(dr,"resolveRelayCliConfig");async function B(r,t=process.env){let e=null;try{e=await sr()}catch{e=null}let n={serverUrl:r.serverUrl??t.AITABLE_RELAY_SERVER_URL??e?.serverUrl,key:r.key??t.AITABLE_RELAY_BOOTSTRAP_KEY??e?.key,token:r.token??t.AITABLE_RELAY_TOKEN??e?.token,name:r.name??t.AITABLE_RELAY_NAME??e?.name,desc:r.desc??t.AITABLE_RELAY_DESC,workspaceRoot:r.workspaceRoot??t.AITABLE_RELAY_WORKSPACE_ROOT??e?.workspaceRoot,machineId:r.machineId??t.AITABLE_RELAY_MACHINE_ID??e?.machineId,maxTasks:r.maxTasks??t.AITABLE_RELAY_MAX_TASKS,maxWorkflows:r.maxWorkflows??t.AITABLE_RELAY_MAX_WORKFLOWS};return dr(n,t)}c(B,"resolveDaemonConfig");async function fe(r){let t=await B(r),e=new Pe(t,{onPermanentReject:c(()=>{process.exit(1)},"onPermanentReject")}),n=!1,o=c(()=>{n&&(y.warn(k,"\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),n=!0,e.stop().catch(()=>{}).finally(()=>process.exit(0))},"shutdown");return process.on("SIGINT",o),process.on("SIGTERM",o),e.start(),e}c(fe,"runRelayDaemon");import{readFile as gr,writeFile as Pa,mkdir as ja}from"fs/promises";import ur from"path";var Bt={connectionState:"disconnected",lastHeartbeatAt:null,machineId:null,serverUrl:"",runningTasks:0,queuedTasks:0,lastDisconnectReason:null,updatedAt:new Date().toISOString()};function fr(r){return ur.join(X(r),"state.json")}c(fr,"stateFilePath");async function he(r){try{let t=await gr(fr(r),"utf8");return{...Bt,...JSON.parse(t)}}catch{return{...Bt}}}c(he,"readState");import{execSync as Y}from"child_process";import{writeFile as hr,rm as wr,mkdir as yr,access as kr}from"fs/promises";import E from"path";import Ut from"os";import{assertPortableId as vr,readCredentials as br}from"aitable-workflow-core";var Rr="com.alibaba.aitable-workflow.daemon",Oe="\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\uFF1Anpm i -g @ali/aitable-workflow";function J(r){return`${Rr}.${vr(r,{label:"agentId"})}`}c(J,"plistLabel");function _e(r){return E.join(Ut.homedir(),"Library","LaunchAgents",`${J(r)}.plist`)}c(_e,"plistPath");function P(){return process.platform==="darwin"}c(P,"isMacOS");function Wt(){try{return Y("which aitable-workflow",{encoding:"utf8"}).trim()||null}catch{return null}}c(Wt,"resolveGlobalCliEntry");function Nt(r){if(!r||!r.trim())throw new Error(`\u672A\u627E\u5230\u5168\u5C40\u5B89\u88C5\u7684 aitable-workflow CLI \u5165\u53E3\uFF0C\u65E0\u6CD5\u914D\u7F6E\u5F00\u673A\u81EA\u542F\u3002
27
+ ${i}`:""}`}c(_o,"mergeEnvContent");function Do(r){return r===""||/[\s#'"`\\]/.test(r)?`"${r.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`:r}c(Do,"quoteEnvValue");async function Tt(r,t){let e=await Po(r,"utf8").catch(()=>""),n=_o(e,t);if(n===e||n===""&&e==="")return!1;let o=`${r}.aitable-sync-tmp`;return await Oo(o,n,{encoding:"utf8",mode:384}),await $o(o,384).catch(()=>{}),await jo(o,r),!0}c(Tt,"mergeEnvFile");var Go="workspace-sync",pe=".workspace-meta.json";function Ho(r){return Lo("sha256").update(r).digest("hex")}c(Ho,"sha256Hex");async function Ae(r,t){let n=await(r.fetchImpl??fetch)(`${r.gatewayUrl.replace(/\/+$/,"")}${t}`,{headers:{authorization:`Bearer ${r.machineKey}`}});if(!n.ok){let o=await n.text().catch(()=>"");throw new Error(`runner API ${t} \u5931\u8D25: HTTP ${n.status} ${o.slice(0,200)}`)}return n}c(Ae,"apiGet");async function qo(r){try{let t=await Mo(le.join(r,pe),"utf8"),e=JSON.parse(t);return e&&typeof e.projectId=="string"?e:null}catch{return null}}c(qo,"readWorkspaceMeta");function Ee(r,t){return No(r,t,{allowRoot:!1})}c(Ee,"resolveTracked");async function Ko(r,t){let e=Ee(r,t.path);await Se(le.dirname(e),{recursive:!0});let n=`${e}.aitable-sync-tmp`;await $t(n,t.content,"utf8"),await Fo(n,e)}c(Ko,"writeTracked");async function Pt(r,t,e){let n=await qo(e);if(n&&n.projectId!==t)throw new Error(`\u5DE5\u4F5C\u533A\u76EE\u5F55\u5F52\u5C5E\u4E0D\u7B26: \u76EE\u5F55\u8BB0\u5F55 projectId=${n.projectId}\uFF0C\u8BF7\u6C42\u540C\u6B65 ${t}\uFF08${e}\uFF09`);let i=await(await Ae(r,`/api/runner/workspace/${t}`)).json(),s=0,a=0,l="up-to-date",p=n?.trackedManifest??{};if(!n||n.revision!==i.revision){l="synced";let w=await Ae(r,`/api/runner/workspace/${t}/bundle`),I=Uo(Buffer.from(await w.arrayBuffer()));if(I.projectId!==t)throw new Error(`\u5FEB\u7167\u5305\u5F52\u5C5E\u4E0D\u7B26: \u5305\u5185 projectId=${I.projectId}\uFF0C\u671F\u671B ${t}`);I.revision!==i.revision&&(i.revision=I.revision),await Se(e,{recursive:!0});let A={};for(let R of I.files)A[R.path]=Ho(R.content);for(let R of I.files)Ee(e,R.path);let z=n?.trackedManifest??{};for(let R of I.files)z[R.path]!==A[R.path]&&(await Ko(e,R),s+=1);for(let R of Object.keys(z))if(A[R]===void 0){let Ge;try{Ge=Ee(e,R)}catch(ke){Wo.warn(Go,"\u8DF3\u8FC7\u8D8A\u754C\u7684\u65E7 manifest \u6761\u76EE",{projectId:t,path:R,error:ke instanceof Error?ke.message:String(ke)});continue}await Bo(Ge,{force:!0}).catch(()=>{}),a+=1}p=A}let g=await(await Ae(r,`/api/runner/workspace/${t}/credentials`)).json();await Se(e,{recursive:!0});let u=await Tt(le.join(e,".env"),g.credentials??{}),d={projectId:t,revision:i.revision,syncedAt:new Date().toISOString(),trackedManifest:p};return await $t(le.join(e,pe),`${JSON.stringify(d,null,2)}
28
+ `,"utf8"),{projectId:t,revision:i.revision,action:l,written:s,deleted:a,envUpdated:u}}c(Pt,"syncWorkspace");var G="runner-gc";async function Ot(r){let t=0,e;try{e=await Te(r,{withFileTypes:!0})}catch{return 0}for(let n of e){let o=L.join(r,n.name);if(!n.isSymbolicLink()){if(n.isDirectory()){t+=await Ot(o);continue}t+=await me(o).then(i=>i.size).catch(()=>0)}}return t}c(Ot,"dirSize");async function Vo(r){let t=L.join(r,"projects"),e;try{e=await Te(t,{withFileTypes:!0})}catch{return[]}let n=[];for(let o of e){if(!o.isDirectory())continue;let i=L.join(t,o.name),s=await me(L.join(i,pe)).then(l=>l.mtimeMs).catch(()=>null),a=await me(i).then(l=>l.mtimeMs).catch(()=>0);n.push({projectId:o.name,dir:i,lastTouchedMs:s??a,sizeBytes:await Ot(i)})}return n}c(Vo,"scanProjects");async function jt(r,t){let e=L.join(r,"traces"),n;try{n=await Te(e,{withFileTypes:!0})}catch{return 0}let o=[];for(let a of n){if(!a.isFile())continue;let l=L.join(e,a.name),p=await me(l).catch(()=>null);p&&o.push({full:l,size:p.size,mtimeMs:p.mtimeMs})}let i=o.reduce((a,l)=>a+l.size,0);if(i<=t)return 0;o.sort((a,l)=>a.mtimeMs-l.mtimeMs);let s=0;for(let a of o){if(i<=t)break;await xe(a.full,{force:!0}).catch(()=>{}),i-=a.size,s+=a.size}return s}c(jt,"pruneTraces");async function _t(r){let t=(r.now??Date.now)(),e=(r.ttlDays??14)*24*60*60*1e3,n=r.tracesMaxBytes??500*1024*1024,o=r.maxDiskBytes??20*1024*1024*1024,i=new Set(r.activeProjectIds),s=await Vo(r.workspaceRoot),a=[],l=0;for(let u of s){if(i.has(u.projectId)){l+=await jt(u.dir,n);continue}if(t-u.lastTouchedMs>=e){await xe(u.dir,{recursive:!0,force:!0}).catch(d=>{N.warn(G,"\u9879\u76EE\u76EE\u5F55\u56DE\u6536\u5931\u8D25",{projectId:u.projectId,error:d instanceof Error?d.message:String(d)})}),a.push(u.projectId),N.info(G,"\u56DE\u6536\u8FC7\u671F\u9879\u76EE\u76EE\u5F55",{projectId:u.projectId,idleDays:Math.floor((t-u.lastTouchedMs)/864e5)});continue}l+=await jt(u.dir,n)}let p=s.filter(u=>!a.includes(u.projectId)),m=p.reduce((u,d)=>u+d.sizeBytes,0)-l,g=!1;if(m>o){g=!0,N.warn(G,"\u5DE5\u4F5C\u533A\u8D85\u78C1\u76D8\u6C34\u4F4D\uFF0C\u5F00\u59CB\u56DE\u6536\u6700\u4E45\u672A\u8BA4\u9886\u9879\u76EE",{totalBytes:m,maxDiskBytes:o});let u=p.filter(d=>!i.has(d.projectId)).sort((d,w)=>d.lastTouchedMs-w.lastTouchedMs);for(let d of u){if(m<=o)break;await xe(d.dir,{recursive:!0,force:!0}).catch(()=>{}),a.push(d.projectId),m-=d.sizeBytes,N.warn(G,"\u6C34\u4F4D\u56DE\u6536\u9879\u76EE\u76EE\u5F55",{projectId:d.projectId,freedBytes:d.sizeBytes})}m>o&&N.error(G,"\u56DE\u6536\u540E\u4ECD\u8D85\u78C1\u76D8\u6C34\u4F4D\uFF08\u6D3B\u8DC3\u9879\u76EE\u5360\u7528\uFF09\uFF0C\u9700\u4EBA\u5DE5\u4ECB\u5165",{totalBytes:m,maxDiskBytes:o})}return{removedProjects:a,tracesFreedBytes:l,diskPressure:g,totalBytes:Math.max(0,m)}}c(_t,"runGc");var C="runner-loop",de=class{static{c(this,"RunnerLoop")}options;maxWorkflows;setTimer;clearTimer;doSync;holdings=new Map;pollTimer=null;gcTimer=null;running=!1;claiming=!1;constructor(t){this.options=t,this.maxWorkflows=Math.max(1,Math.floor(t.maxWorkflows??3)),this.setTimer=t.setTimeoutImpl??((e,n)=>setTimeout(e,n)),this.clearTimer=t.clearTimeoutImpl??(e=>clearTimeout(e)),this.doSync=t.syncImpl??Pt}get held(){return[...this.holdings.values()].map(t=>({projectId:t.projectId,generation:t.generation,revision:t.revision,engine:t.engine.status}))}get freeSlots(){return Math.max(0,this.maxWorkflows-this.holdings.size)}start(){this.running||(this.running=!0,b.info(C,"runner loop \u542F\u52A8",{maxWorkflows:this.maxWorkflows,workspaceRoot:this.options.workspaceRoot}),this.claimOnce(),this.scheduleGc(0))}async stop(){this.running=!1,this.pollTimer&&(this.clearTimer(this.pollTimer),this.pollTimer=null),this.gcTimer&&(this.clearTimer(this.gcTimer),this.gcTimer=null),await Promise.all([...this.holdings.keys()].map(t=>this.releaseHolding(t,"daemon_shutdown")))}scheduleGc(t){let e=this.options.gcIntervalMs??864e5;!this.running||e<=0||(this.gcTimer&&this.clearTimer(this.gcTimer),this.gcTimer=this.setTimer(()=>{this.gcTimer=null,this.gcOnce().finally(()=>this.scheduleGc(e))},t))}async gcOnce(){try{let t=await(this.options.gcImpl??_t)({workspaceRoot:this.options.workspaceRoot,activeProjectIds:[...this.holdings.keys()],...this.options.gcOptions??{}});(t.removedProjects.length>0||t.tracesFreedBytes>0)&&b.info(C,"\u672C\u673A\u56DE\u6536\u5B8C\u6210",{removed:t.removedProjects.length,tracesFreedBytes:t.tracesFreedBytes,totalBytes:t.totalBytes})}catch(t){b.warn(C,"\u672C\u673A\u56DE\u6536\u5931\u8D25",{error:$(t)})}}onWakeup(){this.running&&this.claimOnce()}async claimOnce(){if(!this.running||this.claiming)return;this.claiming=!0;let t=this.options.defaultPollMs??1e4;try{let e=this.freeSlots;if(e>0){let n=await this.post("/api/runner/workflows/claim",{capacity:e});typeof n.nextPollAfterMs=="number"&&n.nextPollAfterMs>0&&(t=n.nextPollAfterMs);for(let o of n.grants??[])await this.acceptGrant(o,n.heartbeatIntervalSeconds)}}catch(e){b.warn(C,"claim \u5931\u8D25\uFF08\u9000\u907F\u540E\u91CD\u8BD5\uFF09",{error:$(e)}),t=Math.max(t,5e3)}finally{this.claiming=!1,this.scheduleNextPoll(t)}}scheduleNextPoll(t){this.running&&(this.pollTimer&&this.clearTimer(this.pollTimer),this.pollTimer=this.setTimer(()=>{this.pollTimer=null,this.claimOnce()},t))}async acceptGrant(t,e){if(this.holdings.has(t.projectId))return;let n=Dt.join(this.options.workspaceRoot,"projects",t.projectId);b.info(C,"\u8BA4\u9886\u9879\u76EE",{projectId:t.projectId,generation:t.generation,workspaceDir:n});let o;try{o=await this.doSync(this.clientConfig(),t.projectId,n)}catch(l){b.error(C,"\u5DE5\u4F5C\u533A\u540C\u6B65\u5931\u8D25\uFF0C\u4EA4\u8FD8\u79DF\u7EA6",{projectId:t.projectId,error:$(l)}),await this.postSafe(`/api/runner/workflows/${t.projectId}/release`,{generation:t.generation,reason:"workspace_sync_failed"});return}let i=(this.options.createSupervisor??Yo)({projectId:t.projectId,workspaceDir:n,cliPath:this.options.cliPath,onRunEvent:c(l=>this.handleRunEvent(t.projectId,l),"onRunEvent"),onCrashLoop:c(()=>{this.releaseHolding(t.projectId,"engine_crash_loop")},"onCrashLoop")}),s=this.options.sendRunEvents?new ce({projectId:t.projectId,spoolDir:n,send:c(l=>this.options.sendRunEvents(t.projectId,l),"send")}):null;s?.start();let a={projectId:t.projectId,generation:t.generation,revision:o.revision,engine:i,spool:s,heartbeatTimer:null,busy:!1};this.holdings.set(t.projectId,a),i.start(),this.scheduleHeartbeat(a,(e??15)*1e3)}handleRunEvent(t,e){this.holdings.get(t)?.spool?.append(e),this.options.onRunEvent?.(t,e)}scheduleHeartbeat(t,e){this.running&&(t.heartbeatTimer&&this.clearTimer(t.heartbeatTimer),t.heartbeatTimer=this.setTimer(()=>{t.heartbeatTimer=null,this.heartbeatOnce(t)},e))}async heartbeatOnce(t){if(!this.running||t.busy||!this.holdings.has(t.projectId))return;let e=this.options.defaultHeartbeatMs??15e3;try{let n=await this.post(`/api/runner/workflows/${t.projectId}/heartbeat`,{generation:t.generation,workspaceRevision:t.revision,engineStatus:t.engine.status,...t.spool?{lastEventSeq:t.spool.lastSeq}:{}}),o=typeof n.nextIntervalSeconds=="number"&&n.nextIntervalSeconds>0?n.nextIntervalSeconds*1e3:e;if(t.spool&&typeof n.lastEventSeq=="number"&&t.spool.replayFrom(n.lastEventSeq),n.action==="stop"){b.info(C,"\u5FC3\u8DF3\u4E0B\u53D1 stop\uFF0C\u505C\u6B62\u5F15\u64CE",{projectId:t.projectId}),await this.releaseHolding(t.projectId,"heartbeat_stop");return}if(n.action==="resync"){await this.resyncHolding(t)&&this.scheduleHeartbeat(t,o);return}t.engine.markHealthy(),this.scheduleHeartbeat(t,o)}catch(n){b.warn(C,"\u5FC3\u8DF3\u5931\u8D25\uFF08\u4FDD\u6301\u5F15\u64CE\u8FD0\u884C\uFF0C\u7B49\u5F85\u6062\u590D\u6216\u79DF\u7EA6\u8FC7\u671F\uFF09",{projectId:t.projectId,error:$(n)}),this.scheduleHeartbeat(t,Math.min(e,5e3))}}async resyncHolding(t){if(t.busy)return!0;t.busy=!0;let e=Dt.join(this.options.workspaceRoot,"projects",t.projectId);try{b.info(C,"\u5DE5\u4F5C\u533A\u9700\u91CD\u540C\u6B65\uFF0C\u91CD\u542F\u5F15\u64CE",{projectId:t.projectId}),await t.engine.stop();let n=await this.doSync(this.clientConfig(),t.projectId,e);t.revision=n.revision,t.engine.start()}catch(n){return b.error(C,"\u91CD\u540C\u6B65\u5931\u8D25\uFF0C\u4EA4\u8FD8\u79DF\u7EA6",{projectId:t.projectId,error:$(n)}),t.busy=!1,await this.releaseHolding(t.projectId,"resync_failed"),!1}return t.busy=!1,!0}async releaseHolding(t,e){let n=this.holdings.get(t);n&&(this.holdings.delete(t),n.heartbeatTimer&&(this.clearTimer(n.heartbeatTimer),n.heartbeatTimer=null),await n.engine.stop().catch(o=>{b.warn(C,"\u505C\u6B62\u5F15\u64CE\u5F02\u5E38",{projectId:t,error:$(o)})}),await n.spool?.stop().catch(()=>{}),await this.postSafe(`/api/runner/workflows/${t}/release`,{generation:n.generation,reason:e}),b.info(C,"\u5DF2\u8BA9\u51FA\u79DF\u7EA6",{projectId:t,reason:e}),this.running&&this.scheduleNextPoll(this.options.defaultPollMs??1e4))}clientConfig(){return{gatewayUrl:this.options.gatewayUrl,machineKey:this.options.machineKey,...this.options.fetchImpl?{fetchImpl:this.options.fetchImpl}:{}}}async post(t,e){let o=await(this.options.fetchImpl??fetch)(`${this.options.gatewayUrl.replace(/\/+$/,"")}${t}`,{method:"POST",headers:{authorization:`Bearer ${this.options.machineKey}`,"content-type":"application/json"},body:JSON.stringify(e??{})});if(!o.ok){let i=await o.text().catch(()=>"");throw new Error(`runner API ${t} \u5931\u8D25: HTTP ${o.status} ${i.slice(0,200)}`)}return await o.json()}async postSafe(t,e){try{await this.post(t,e)}catch(n){b.warn(C,"\u6536\u5C3E\u8BF7\u6C42\u5931\u8D25\uFF08\u79DF\u7EA6\u5C06\u7531\u670D\u52A1\u7AEF\u8FC7\u671F\u56DE\u6536\uFF09",{pathname:t,error:$(n)})}}};function Yo(r){return new ie({projectId:r.projectId,workspaceDir:r.workspaceDir,cliPath:r.cliPath,...r.onRunEvent?{onRunEvent:r.onRunEvent}:{},...r.onCrashLoop?{onCrashLoop:c(()=>r.onCrashLoop(),"onCrashLoop")}:{}})}c(Yo,"defaultSupervisorFactory");function $(r){return r instanceof Error?r.message:String(r)}c($,"describeError");import{spawn as zo}from"child_process";import{existsSync as Xo}from"fs";import q from"path";import{fileURLToPath as Qo}from"url";import{appendFileSync as ta,statSync as na,renameSync as oa,mkdirSync as ra,existsSync as ia}from"fs";import Jo from"path";var ca=10*1024*1024;function H(r){return Jo.join(X(r),"daemon.log")}c(H,"logFilePath");var ge=q.dirname(Qo(import.meta.url));function $e(){let r=[q.resolve(ge,"..","..","bin","aitable-workflow.mjs"),q.resolve(ge,"..","bin","aitable-workflow.mjs"),q.resolve(ge,"..","..","dist","cli.js"),q.resolve(ge,"cli.js")];return r.find(t=>Xo(t))??r[0]}c($e,"resolveDaemonEntry");var Zo=$e();async function K(r){await Ve(r.agentId);let t=["relay"];r.serverUrl&&t.push("--server-url",r.serverUrl),r.token&&t.push("--token",r.token),r.key&&t.push("--key",r.key),r.name&&t.push("--name",r.name),r.workspaceRoot&&t.push("--workspace-root",r.workspaceRoot),r.machineId&&t.push("--machine-id",r.machineId),r.maxTasks&&t.push("--max-tasks",String(r.maxTasks));let e=await import("fs").then(s=>{let a=H(r.agentId);return s.openSync(a,"a")}),n=zo(process.execPath,[Zo,...t],{detached:!0,stdio:["ignore",e,e],env:{...process.env}});try{let{closeSync:s}=await import("fs");s(e)}catch{}n.unref();let{writeFile:o}=await import("fs/promises"),{pidFilePath:i}=await import("./pid-file-KT5KHCKU.js");return n.pid&&await o(i(r.agentId),String(n.pid),"utf8"),{pid:n.pid??0}}c(K,"startDaemon");async function ue(r,t=5e3){let e=await ve(r);if(e===null||!W(e))return await Q(r),!1;try{process.kill(e,"SIGTERM")}catch{return await Q(r),!1}let n=Date.now()+t;for(;Date.now()<n&&W(e);)await new Promise(o=>setTimeout(o,200));if(W(e))try{process.kill(e,"SIGKILL")}catch{}return await Q(r),!0}c(ue,"stopDaemon");async function V(r){let t=await ve(r),e=t!==null&&W(t),n=null;if(e&&t!==null)try{let{readFile:o}=await import("fs/promises"),i=await o(`/proc/${t}/stat`,"utf8"),s=parseInt(i.split(" ")[21]??"0",10),a=await o("/proc/uptime","utf8"),m=parseFloat(a.split(" ")[0]??"0")-s/100;n=Math.round(m*1e3)}catch{}return{agentId:r,running:e,pid:e?t:null,uptimeMs:n,logFile:H(r)}}c(V,"getDaemonStatus");function lr(r){return r.replace(/\/+$/,"").replace(/^ws/,"http")}c(lr,"toHttpBase");var k="relay:daemon",Ft=["aitable"],pr="dws";function mr(r,t=Ft){if(!Array.isArray(r)||r.length===0)return{ok:!1,reason:"dws args must be a non-empty array"};for(let n of r){if(typeof n!="string")return{ok:!1,reason:"dws args must all be strings"};if(n.length===0)return{ok:!1,reason:"dws args must not contain empty tokens"};if(/[\u0000-\u001f]/.test(n))return{ok:!1,reason:"dws args must not contain control characters"}}let e=r[0];return e.startsWith("-")?{ok:!1,reason:"first dws arg must be a subcommand, not a flag"}:t.length>0&&!t.includes(e)?{ok:!1,reason:`dws command "${e}" is not allowed`}:{ok:!0}}c(mr,"validateDwsArgs");function dr(r){return ar(r,["--version"],cr({timeoutMs:5e3})).ok}c(dr,"detectDwsAvailable");var Pe=class{static{c(this,"RelayDaemon")}config;allowedDwsCommands;conn;runAgent;createDwsClient;detectAgents;detectDws;hostname;osString;onPermanentReject;artifactUploader;grantTimeoutMs;pendingGrants=new Map;maxTasks;inflight=0;taskQueue=[];runnerLoop;machineId;constructor(t,e={}){this.config={...t,dwsBin:t.dwsBin??pr},this.machineId=t.machineId,this.allowedDwsCommands=t.allowedDwsCommands??Ft,this.runAgent=e.runAgent??rr,this.createDwsClient=e.createDwsClient??((o,i)=>new ir({bin:o,timeoutMs:i})),this.detectAgents=e.detectAgents??(()=>or()),this.detectDws=e.detectDws??(o=>dr(o)),this.hostname=e.hostname??(()=>F.hostname()),this.osString=e.osString??(()=>`${F.platform()} ${F.arch()}`),this.onPermanentReject=e.onPermanentReject,this.artifactUploader=e.artifactUploader??It,this.grantTimeoutMs=e.grantTimeoutMs??3e4,this.maxTasks=Math.max(1,Math.floor(t.maxTasks??1));let n=e.createConnection??(o=>new re(o));this.conn=n({serverUrl:this.config.serverUrl,key:this.config.key,token:this.config.token,onMessage:c(o=>this.handleMessage(o),"onMessage"),onOpen:c(()=>this.handleOpen(),"onOpen"),onPermanentReject:c(o=>this.handlePermanentReject(o),"onPermanentReject")}),this.runnerLoop=this.buildRunnerLoop(e)}buildRunnerLoop(t){let e=Math.max(0,Math.floor(this.config.maxWorkflows??3));if(e===0)return null;let n=this.config.key??this.config.token;if(!n)return y.warn(k,"\u65E0 machine key/owner-token\uFF0C\u8DF3\u8FC7 RunnerLoop\uFF08run \u9636\u6BB5\u4E0D\u8BA4\u9886\u9879\u76EE\uFF09"),null;let o={gatewayUrl:lr(this.config.serverUrl),machineKey:n,workspaceRoot:this.config.workspaceRoot,cliPath:$e(),maxWorkflows:e,sendRunEvents:c((i,s)=>this.sendRunEvents(i,s),"sendRunEvents")};return(t.createRunnerLoop??(i=>new de(i)))(o)}sendRunEvents(t,e){e.length!==0&&this.conn.send({type:"run:events",projectId:t,entries:e})}start(){y.info(k,"starting",{serverUrl:this.config.serverUrl,workspaceRoot:this.config.workspaceRoot}),this.config.name||y.warn(k,"\u672A\u6307\u5B9A --name\uFF0C\u5C06\u4F7F\u7528\u4E3B\u673A\u540D\u4F5C\u4E3A\u673A\u5668\u6CE8\u518C\u540D\uFF1B\u591A\u673A\u573A\u666F\u4E0B hostname \u82E5\u91CD\u590D\u4F1A\u5BFC\u81F4\u8FDE\u63A5\u4E92\u76F8\u9876\u66FF\uFF0C\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A --name",{hostname:this.hostname()}),this.conn.connect(),this.runnerLoop?.start()}stop(){return y.info(k,"stopping"),this.conn.close(),this.runnerLoop?this.runnerLoop.stop().catch(t=>{y.warn(k,"runner loop \u505C\u6B62\u5F02\u5E38",{error:t instanceof Error?t.message:String(t)})}):Promise.resolve()}buildReady(){let e={type:"ready",runtimes:Array.from(new Set(this.detectAgents().map(n=>n.type))),hasDws:this.detectDws(this.config.dwsBin),hostname:this.hostname(),os:this.osString()};return this.machineId&&(e.machineId=this.machineId),this.config.name&&(e.name=this.config.name),this.config.displayName&&(e.displayName=this.config.displayName),this.config.description&&(e.description=this.config.description),this.maxTasks>1&&(e.maxTasks=this.maxTasks),e}handleOpen(){let t=this.buildReady();y.info(k,"connected; sending ready",{runtimes:t.runtimes,hasDws:t.hasDws}),this.conn.send(t)}handlePermanentReject(t){y.error(k,"permanently rejected by gateway",{...t}),this.onPermanentReject?.(t)}handleMessage(t){switch(t.type){case"run:agent":this.enqueueTask(()=>this.handleRunAgent(t));break;case"run:dws":this.enqueueTask(()=>this.handleRunDws(t));break;case"upload:grant":this.resolveGrant(t);break;case"wf:available":this.runnerLoop?.onWakeup();break;case"ready:ack":t.machineId&&(this.machineId=t.machineId,y.info(k,"machine id assigned",{machineId:t.machineId}));break;default:break}}enqueueTask(t){let e=c(()=>{this.inflight+=1,t().finally(()=>{this.inflight-=1;let n=this.taskQueue.shift();n&&n()})},"exec");this.inflight<this.maxTasks?e():this.taskQueue.push(e)}async handleRunAgent(t){let{requestId:e}=t;y.info(k,"run:agent received",{requestId:e,projectId:t.projectId,agent:t.agent});try{let n=this.resolveWorkDir(t.projectId,t.workDir);await er(n,{recursive:!0});let o=this.rewritePromptWorkDir(t.prompt,t.workDir,n),i={agent:t.agent,workDir:n,onEvent:c(l=>this.conn.send({type:"event",requestId:e,event:l}),"onEvent")};t.sessionId&&(i.sessionId=t.sessionId),t.permissionMode&&(i.adapterOptions={permissionMode:t.permissionMode}),t.timeoutMs!==void 0?i.timeoutMs=t.timeoutMs:this.config.agentTimeoutMs!=null&&(i.timeoutMs=this.config.agentTimeoutMs);let s=await this.runAgent(o,i),a;try{a=await this.collectAndUploadArtifacts(e,t.projectId,n)}catch(l){let p=l instanceof Error?l.message:String(l);y.error(k,"artifact upload failed",{requestId:e,error:p}),this.conn.send({type:"error",requestId:e,code:"artifact_upload_failed",message:p});return}this.conn.send({type:"result",requestId:e,ok:!0,response:s.response,sessionId:s.sessionId,...a?{artifacts:a}:{}}),y.info(k,"run:agent done",{requestId:e,sessionId:s.sessionId,artifacts:a?a.files.length:0})}catch(n){let o=n instanceof Error?n.message:String(n);y.error(k,"run:agent failed",{requestId:e,error:o}),this.conn.send({type:"error",requestId:e,code:"agent_failed",message:o})}}async collectAndUploadArtifacts(t,e,n){let o=await At(n);if(o.length===0)return;this.conn.send({type:"upload:request",requestId:t,projectId:e,files:o.map(a=>({path:a.relPath,size:a.size,sha256:a.sha256}))});let i=await this.awaitGrant(t);if(!i)throw new Error("upload:grant \u7B49\u5F85\u8D85\u65F6");if(i.grants.length===0){y.warn(k,"upload:grant \u65E0\u6388\u6743\u9879\uFF08gateway \u672A\u914D\u7F6E store \u6216\u5168\u88AB\u62D2\uFF09",{requestId:t,rejected:(i.rejected??[]).length});return}let s=[];for(let a of i.grants){let l=o.find(m=>m.relPath===a.path);if(!l)continue;let p=await tr(l.absPath);await this.artifactUploader.upload(a.url,p,a.headers),s.push({path:a.path,key:a.key,sha256:l.sha256,size:l.size})}return{store:"oss",files:s}}awaitGrant(t){return new Promise(e=>{let n=setTimeout(()=>{this.pendingGrants.delete(t),e(void 0)},this.grantTimeoutMs);n.unref?.(),this.pendingGrants.set(t,o=>{clearTimeout(n),e(o)})})}resolveGrant(t){let e=this.pendingGrants.get(t.requestId);e&&(this.pendingGrants.delete(t.requestId),e(t))}async handleRunDws(t){let{requestId:e}=t,n=mr(t.args,this.allowedDwsCommands);if(!n.ok){y.warn(k,"run:dws rejected",{requestId:e,reason:n.reason}),this.conn.send({type:"error",requestId:e,code:"dws_rejected",message:n.reason});return}y.info(k,"run:dws received",{requestId:e,command:t.args[0]});try{let i=await this.createDwsClient(this.config.dwsBin,t.timeoutMs).runJson(t.args,t.timeoutMs!=null?{timeoutMs:t.timeoutMs}:void 0);this.conn.send({type:"result",requestId:e,ok:!0,response:JSON.stringify(i)}),y.info(k,"run:dws done",{requestId:e})}catch(o){let i=o instanceof Error?o.message:String(o);y.error(k,"run:dws failed",{requestId:e,error:i}),this.conn.send({type:"error",requestId:e,code:"dws_failed",message:i})}}resolveWorkDir(t,e){if(e&&e.trim()!=="")if(M.isAbsolute(e))y.warn(k,"\u5FFD\u7565\u670D\u52A1\u7AEF\u4E0B\u53D1\u7684\u7EDD\u5BF9\u8DEF\u5F84 workDir\uFF0C\u56DE\u9000\u5230 workspaceRoot/projectId",{workDir:e,projectId:t});else return Lt(this.config.workspaceRoot,e,{allowRoot:!1});return Lt(this.config.workspaceRoot,Mt(t,{label:"projectId"}),{allowRoot:!1})}rewritePromptWorkDir(t,e,n){let o=e?.trim();return!o||!M.isAbsolute(o)||o===n?t:t.split(o).join(n)}};function je(r,t){let e,n=r?.trim();if(n)e=M.isAbsolute(n)?M.resolve(n):M.resolve(F.homedir(),n);else{let o=t?.trim()?t.trim():"default";e=M.join(F.homedir(),".aitable-workflow","workspaces",Mt(o,{label:"agentId"}))}return nr(e,{recursive:!0}),e}c(je,"resolveWorkspaceRoot");function gr(r,t=process.env){let e=r.serverUrl??t.AITABLE_RELAY_SERVER_URL,n=r.key??t.AITABLE_RELAY_BOOTSTRAP_KEY,o=r.token??t.AITABLE_RELAY_TOKEN,i=r.workspaceRoot??t.AITABLE_RELAY_WORKSPACE_ROOT,s=r.machineId??t.AITABLE_RELAY_MACHINE_ID,a=r.name??t.AITABLE_RELAY_NAME,l=r.desc??t.AITABLE_RELAY_DESC,p=r.maxTasks??t.AITABLE_RELAY_MAX_TASKS,m=r.maxWorkflows??t.AITABLE_RELAY_MAX_WORKFLOWS,g=[];if(e||g.push("--server-url (\u6216 AITABLE_RELAY_SERVER_URL)"),!n&&!o&&g.push("--key/--token (\u6216 AITABLE_RELAY_BOOTSTRAP_KEY/AITABLE_RELAY_TOKEN)"),g.length>0)throw new Error(`relay \u7F3A\u5C11\u5FC5\u8981\u53C2\u6570: ${g.join(", ")}
29
+ \u{1F4A1} \u63D0\u793A: \u4F7F\u7528 \`aitable-workflow connect\` \u6CE8\u518C\u540E\u53EF\u7701\u7565\u8FD9\u4E9B\u53C2\u6570`);let u=a??F.hostname()??"default",d={serverUrl:e,workspaceRoot:je(i,u)};if(o?d.token=o:n&&(d.key=n),s&&(d.machineId=s),a&&(d.name=a,d.displayName=a),l&&(d.description=l),p!=null&&p!==""){let w=Math.floor(Number(p));Number.isFinite(w)&&w>=1&&(d.maxTasks=w)}if(m!=null&&m!==""){let w=Math.floor(Number(m));Number.isFinite(w)&&w>=0&&(d.maxWorkflows=w)}return d}c(gr,"resolveRelayCliConfig");async function B(r,t=process.env){let e=null;try{e=await sr()}catch{e=null}let n={serverUrl:r.serverUrl??t.AITABLE_RELAY_SERVER_URL??e?.serverUrl,key:r.key??t.AITABLE_RELAY_BOOTSTRAP_KEY??e?.key,token:r.token??t.AITABLE_RELAY_TOKEN??e?.token,name:r.name??t.AITABLE_RELAY_NAME??e?.name,desc:r.desc??t.AITABLE_RELAY_DESC,workspaceRoot:r.workspaceRoot??t.AITABLE_RELAY_WORKSPACE_ROOT??e?.workspaceRoot,machineId:r.machineId??t.AITABLE_RELAY_MACHINE_ID??e?.machineId,maxTasks:r.maxTasks??t.AITABLE_RELAY_MAX_TASKS,maxWorkflows:r.maxWorkflows??t.AITABLE_RELAY_MAX_WORKFLOWS};return gr(n,t)}c(B,"resolveDaemonConfig");async function fe(r){let t=await B(r),e=new Pe(t,{onPermanentReject:c(()=>{process.exit(1)},"onPermanentReject")}),n=!1,o=c(()=>{n&&(y.warn(k,"\u518D\u6B21\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)),n=!0,e.stop().catch(()=>{}).finally(()=>process.exit(0))},"shutdown");return process.on("SIGINT",o),process.on("SIGTERM",o),e.start(),e}c(fe,"runRelayDaemon");import{readFile as ur,writeFile as ja,mkdir as Oa}from"fs/promises";import fr from"path";var Bt={connectionState:"disconnected",lastHeartbeatAt:null,machineId:null,serverUrl:"",runningTasks:0,queuedTasks:0,lastDisconnectReason:null,updatedAt:new Date().toISOString()};function hr(r){return fr.join(X(r),"state.json")}c(hr,"stateFilePath");async function he(r){try{let t=await ur(hr(r),"utf8");return{...Bt,...JSON.parse(t)}}catch{return{...Bt}}}c(he,"readState");import{execSync as Y}from"child_process";import{writeFile as wr,rm as yr,mkdir as kr,access as vr}from"fs/promises";import E from"path";import Ut from"os";import{assertPortableId as br,readCredentials as Cr}from"aitable-workflow-core";var Rr="com.alibaba.aitable-workflow.daemon",Oe="\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\uFF1Anpm i -g @ali/aitable-workflow";function J(r){return`${Rr}.${br(r,{label:"agentId"})}`}c(J,"plistLabel");function _e(r){return E.join(Ut.homedir(),"Library","LaunchAgents",`${J(r)}.plist`)}c(_e,"plistPath");function P(){return process.platform==="darwin"}c(P,"isMacOS");function Wt(){try{return Y("which aitable-workflow",{encoding:"utf8"}).trim()||null}catch{return null}}c(Wt,"resolveGlobalCliEntry");function Nt(r){if(!r||!r.trim())throw new Error(`\u672A\u627E\u5230\u5168\u5C40\u5B89\u88C5\u7684 aitable-workflow CLI \u5165\u53E3\uFF0C\u65E0\u6CD5\u914D\u7F6E\u5F00\u673A\u81EA\u542F\u3002
30
30
  \u{1F4A1} ${Oe}`);if(r.includes("/_npx/")||r.includes(`${E.sep}_npx${E.sep}`))throw new Error(`\u68C0\u6D4B\u5230 CLI \u5165\u53E3\u4F4D\u4E8E npx \u4E34\u65F6\u7F13\u5B58\uFF0C\u5F00\u673A\u81EA\u542F\u4F1A\u5931\u6548\uFF1A${r}
31
31
  \u{1F4A1} ${Oe}`);if(!E.isAbsolute(r))throw new Error(`CLI \u5165\u53E3\u4E0D\u662F\u7A33\u5B9A\u7684\u5168\u5C40\u7EDD\u5BF9\u8DEF\u5F84\uFF1A${r}
32
- \u{1F4A1} ${Oe}`)}c(Nt,"assertStableCliEntry");async function Cr(r){let t={};t.AITABLE_RELAY_NAME=r;let e;try{let n=await br();e=n.agents.find(o=>o.name===r)??n.agents.find(o=>o.name===n.activeAgent)??void 0}catch{e=void 0}return e&&(e.serverUrl&&(t.AITABLE_RELAY_SERVER_URL=e.serverUrl),e.token&&(t.AITABLE_RELAY_TOKEN=e.token),e.workspaceRoot&&(t.AITABLE_RELAY_WORKSPACE_ROOT=e.workspaceRoot)),t}c(Cr,"buildRelayEnv");function Ir(r,t){let e=J(r),n=t?.cliEntry??Wt();Nt(n);let o=["relay"];t?.maxTasks&&o.push("--max-tasks",String(t.maxTasks));let i=E.join(Ut.homedir(),".aitable-workflow","daemons",r),s=E.join(i,"launchd.log"),a=E.join(i,"launchd.err.log"),l=[n,...o].map(g=>` <string>${U(g)}</string>`).join(`
32
+ \u{1F4A1} ${Oe}`)}c(Nt,"assertStableCliEntry");async function Ir(r){let t={};t.AITABLE_RELAY_NAME=r;let e;try{let n=await Cr();e=n.agents.find(o=>o.name===r)??n.agents.find(o=>o.name===n.activeAgent)??void 0}catch{e=void 0}return e&&(e.serverUrl&&(t.AITABLE_RELAY_SERVER_URL=e.serverUrl),e.token&&(t.AITABLE_RELAY_TOKEN=e.token),e.workspaceRoot&&(t.AITABLE_RELAY_WORKSPACE_ROOT=e.workspaceRoot)),t}c(Ir,"buildRelayEnv");function Ar(r,t){let e=J(r),n=t?.cliEntry??Wt();Nt(n);let o=["relay"];t?.maxTasks&&o.push("--max-tasks",String(t.maxTasks));let i=E.join(Ut.homedir(),".aitable-workflow","daemons",r),s=E.join(i,"launchd.log"),a=E.join(i,"launchd.err.log"),l=[n,...o].map(g=>` <string>${U(g)}</string>`).join(`
33
33
  `),p={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",...t?.relayEnv??{}},m=Object.entries(p).map(([g,u])=>` <key>${U(g)}</key>
34
34
  <string>${U(u)}</string>`).join(`
35
35
  `);return`<?xml version="1.0" encoding="UTF-8"?>
@@ -56,44 +56,44 @@ ${m}
56
56
  <string>${U(a)}</string>
57
57
  </dict>
58
58
  </plist>
59
- `}c(Ir,"generatePlist");function U(r){return r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}c(U,"escapeXml");function we(){let r=process.getuid?.();if(r===void 0)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237 UID\uFF08\u4EC5\u652F\u6301 macOS/Linux\uFF09");return r}c(we,"getUid");async function Gt(r,t){if(!P())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=Wt();Nt(e);let n=await Cr(r),o=_e(r),i=J(r);try{Y(`launchctl bootout gui/${we()}/${i} 2>/dev/null`,{encoding:"utf8"})}catch{}await yr(E.dirname(o),{recursive:!0});let s=Ir(r,{maxTasks:t?.maxTasks,relayEnv:n,cliEntry:e});await hr(o,s,"utf8"),Y(`launchctl bootstrap gui/${we()} ${o}`,{encoding:"utf8"})}c(Gt,"enableAutostart");async function Ht(r){if(!P())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let t=J(r),e=_e(r);try{Y(`launchctl bootout gui/${we()}/${t} 2>/dev/null`,{encoding:"utf8"})}catch{}await wr(e,{force:!0})}c(Ht,"disableAutostart");async function De(r){if(!P())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let t=J(r),e=_e(r),n=!1;try{await kr(e),n=!0}catch{n=!1}let o=!1,i=!1,s=null;try{let a=Y(`launchctl print gui/${we()}/${t} 2>/dev/null`,{encoding:"utf8"});o=!0;let l=a.match(/pid\s*=\s*(\d+)/);l&&(s=parseInt(l[1],10),i=!0)}catch{o=!1}return{installed:n,loaded:o,running:i,pid:s}}c(De,"getAutostartStatus");import{watchFile as Sr,statSync as Er,openSync as xr,readSync as Tr,closeSync as $r}from"fs";import{readFile as Kt}from"fs/promises";function Vt(r,t){let e=r.command("daemon").description("\u540E\u53F0 relay daemon \u751F\u547D\u5468\u671F\u7BA1\u7406");e.command("start").description("\u4EE5\u540E\u53F0\u8FDB\u7A0B\u542F\u52A8 relay daemon").option("--agent <name>","Agent \u540D\u79F0\uFF08\u9ED8\u8BA4\u4F7F\u7528 activeAgent\uFF09").option("--server-url <url>","Gateway \u5730\u5740").option("--token <ownerToken>","owner-token").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `--agent <name>` \u6307\u5B9A\u3002");o=a.name}let i=await B({serverUrl:n.serverUrl,token:n.token,key:n.key,workspaceRoot:n.workspaceRoot,name:o,maxTasks:n.maxTasks}),s=await K({agentId:o,serverUrl:i.serverUrl,token:i.token,key:i.key,name:i.name??o,workspaceRoot:i.workspaceRoot,machineId:i.machineId,maxTasks:i.maxTasks});console.log("\u2705 Daemon \u5DF2\u542F\u52A8"),console.log(` Agent: ${o}`),console.log(` PID: ${s.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${o}/daemon.log`)}catch(o){S.error("cli","start \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("stop").description("\u505C\u6B62\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--all","\u505C\u6B62\u6240\u6709 daemon").action(async n=>{try{if(n.all){let o=await qt(),i=0;for(let s of o)await ue(s.name)&&i++;console.log(`\u2705 \u5DF2\u505C\u6B62 ${i} \u4E2A daemon`)}else{let o=n.agent;if(!o){let s=await j();if(!s)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=s.name}let i=await ue(o);console.log(i?`\u2705 Daemon "${o}" \u5DF2\u505C\u6B62`:`\u26A0\uFE0F Daemon "${o}" \u672A\u5728\u8FD0\u884C`)}}catch(o){S.error("cli","stop \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("restart").description("\u91CD\u542F\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=a.name}console.log(`\u{1F504} \u6B63\u5728\u91CD\u542F "${o}"...`),await ue(o);let i=await B({name:o,maxTasks:n.maxTasks}),s=await K({agentId:o,serverUrl:i.serverUrl,token:i.token,key:i.key,name:i.name??o,workspaceRoot:i.workspaceRoot,machineId:i.machineId,maxTasks:i.maxTasks});console.log(`\u2705 Daemon \u5DF2\u91CD\u542F (PID: ${s.pid})`)}catch(o){S.error("cli","restart \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("status").description("\u67E5\u770B daemon \u72B6\u6001").option("--agent <name>","Agent \u540D\u79F0").option("-v, --verbose","\u5C55\u793A\u5B8C\u6574\u914D\u7F6E").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a){console.log("\u65E0\u6D3B\u8DC3 Agent");return}o=a.name}let i=await V(o),s=await j();if(console.log(`
59
+ `}c(Ar,"generatePlist");function U(r){return r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}c(U,"escapeXml");function we(){let r=process.getuid?.();if(r===void 0)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237 UID\uFF08\u4EC5\u652F\u6301 macOS/Linux\uFF09");return r}c(we,"getUid");async function Gt(r,t){if(!P())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let e=Wt();Nt(e);let n=await Ir(r),o=_e(r),i=J(r);try{Y(`launchctl bootout gui/${we()}/${i} 2>/dev/null`,{encoding:"utf8"})}catch{}await kr(E.dirname(o),{recursive:!0});let s=Ar(r,{maxTasks:t?.maxTasks,relayEnv:n,cliEntry:e});await wr(o,s,"utf8"),Y(`launchctl bootstrap gui/${we()} ${o}`,{encoding:"utf8"})}c(Gt,"enableAutostart");async function Ht(r){if(!P())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let t=J(r),e=_e(r);try{Y(`launchctl bootout gui/${we()}/${t} 2>/dev/null`,{encoding:"utf8"})}catch{}await yr(e,{force:!0})}c(Ht,"disableAutostart");async function De(r){if(!P())throw new Error("\u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS");let t=J(r),e=_e(r),n=!1;try{await vr(e),n=!0}catch{n=!1}let o=!1,i=!1,s=null;try{let a=Y(`launchctl print gui/${we()}/${t} 2>/dev/null`,{encoding:"utf8"});o=!0;let l=a.match(/pid\s*=\s*(\d+)/);l&&(s=parseInt(l[1],10),i=!0)}catch{o=!1}return{installed:n,loaded:o,running:i,pid:s}}c(De,"getAutostartStatus");import{watchFile as Er,statSync as xr,openSync as Tr,readSync as $r,closeSync as Pr}from"fs";import{readFile as Kt}from"fs/promises";function Vt(r,t){let e=r.command("daemon").description("\u540E\u53F0 relay daemon \u751F\u547D\u5468\u671F\u7BA1\u7406");e.command("start").description("\u4EE5\u540E\u53F0\u8FDB\u7A0B\u542F\u52A8 relay daemon").option("--agent <name>","Agent \u540D\u79F0\uFF08\u9ED8\u8BA4\u4F7F\u7528 activeAgent\uFF09").option("--server-url <url>","Gateway \u5730\u5740").option("--token <ownerToken>","owner-token").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `--agent <name>` \u6307\u5B9A\u3002");o=a.name}let i=await B({serverUrl:n.serverUrl,token:n.token,key:n.key,workspaceRoot:n.workspaceRoot,name:o,maxTasks:n.maxTasks}),s=await K({agentId:o,serverUrl:i.serverUrl,token:i.token,key:i.key,name:i.name??o,workspaceRoot:i.workspaceRoot,machineId:i.machineId,maxTasks:i.maxTasks});console.log("\u2705 Daemon \u5DF2\u542F\u52A8"),console.log(` Agent: ${o}`),console.log(` PID: ${s.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${o}/daemon.log`)}catch(o){S.error("cli","start \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("stop").description("\u505C\u6B62\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--all","\u505C\u6B62\u6240\u6709 daemon").action(async n=>{try{if(n.all){let o=await qt(),i=0;for(let s of o)await ue(s.name)&&i++;console.log(`\u2705 \u5DF2\u505C\u6B62 ${i} \u4E2A daemon`)}else{let o=n.agent;if(!o){let s=await j();if(!s)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=s.name}let i=await ue(o);console.log(i?`\u2705 Daemon "${o}" \u5DF2\u505C\u6B62`:`\u26A0\uFE0F Daemon "${o}" \u672A\u5728\u8FD0\u884C`)}}catch(o){S.error("cli","stop \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("restart").description("\u91CD\u542F\u540E\u53F0 daemon").option("--agent <name>","Agent \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650","1").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=a.name}console.log(`\u{1F504} \u6B63\u5728\u91CD\u542F "${o}"...`),await ue(o);let i=await B({name:o,maxTasks:n.maxTasks}),s=await K({agentId:o,serverUrl:i.serverUrl,token:i.token,key:i.key,name:i.name??o,workspaceRoot:i.workspaceRoot,machineId:i.machineId,maxTasks:i.maxTasks});console.log(`\u2705 Daemon \u5DF2\u91CD\u542F (PID: ${s.pid})`)}catch(o){S.error("cli","restart \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("status").description("\u67E5\u770B daemon \u72B6\u6001").option("--agent <name>","Agent \u540D\u79F0").option("-v, --verbose","\u5C55\u793A\u5B8C\u6574\u914D\u7F6E").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a){console.log("\u65E0\u6D3B\u8DC3 Agent");return}o=a.name}let i=await V(o),s=await j();if(console.log(`
60
60
  Agent: ${i.agentId}`),console.log(`Running: ${i.running?"\u2705 yes":"\u274C no"}`),i.pid&&console.log(`PID: ${i.pid}`),i.uptimeMs!==null){let a=Math.floor(i.uptimeMs/1e3),l=Math.floor(a/60),p=Math.floor(l/60);console.log(`Uptime: ${p}h ${l%60}m ${a%60}s`)}console.log(`Log file: ${i.logFile}`),n.verbose&&s&&(console.log(`
61
- --- Configuration ---`),console.log(`Server: ${s.serverUrl}`),console.log(`Token: ${Ar(s.token)}`),s.machineId&&console.log(`MachineID: ${s.machineId}`),s.workspaceRoot&&console.log(`Workspace: ${s.workspaceRoot}`)),console.log("")}catch(o){S.error("cli","status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("logs").description("\u67E5\u770B daemon \u65E5\u5FD7").option("--agent <name>","Agent \u540D\u79F0").option("-f, --follow","\u6301\u7EED\u8DDF\u8E2A\u65E5\u5FD7\u8F93\u51FA").option("-n <lines>","\u663E\u793A\u6700\u8FD1 N \u884C","50").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=a.name}let i=H(o),s=parseInt(n.n,10)||50;if(n.follow){let a=await Kt(i,"utf8").catch(()=>"");if(a){let p=a.trimEnd().split(`
61
+ --- Configuration ---`),console.log(`Server: ${s.serverUrl}`),console.log(`Token: ${Sr(s.token)}`),s.machineId&&console.log(`MachineID: ${s.machineId}`),s.workspaceRoot&&console.log(`Workspace: ${s.workspaceRoot}`)),console.log("")}catch(o){S.error("cli","status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("logs").description("\u67E5\u770B daemon \u65E5\u5FD7").option("--agent <name>","Agent \u540D\u79F0").option("-f, --follow","\u6301\u7EED\u8DDF\u8E2A\u65E5\u5FD7\u8F93\u51FA").option("-n <lines>","\u663E\u793A\u6700\u8FD1 N \u884C","50").action(async n=>{try{let o=n.agent;if(!o){let a=await j();if(!a)throw new Error("\u672A\u6307\u5B9A --agent \u4E14\u65E0\u6D3B\u8DC3 Agent");o=a.name}let i=H(o),s=parseInt(n.n,10)||50;if(n.follow){let a=await Kt(i,"utf8").catch(()=>"");if(a){let p=a.trimEnd().split(`
62
62
  `);console.log(p.slice(-s).join(`
63
- `))}let l=a.length;Sr(i,{interval:500},()=>{try{let p=Er(i);if(p.size>l){let m=xr(i,"r"),g=Buffer.alloc(p.size-l);Tr(m,g,0,g.length,l),$r(m),process.stdout.write(g.toString("utf8")),l=p.size}}catch{}})}else{let a=await Kt(i,"utf8").catch(()=>"");if(!a){console.log(`\u6682\u65E0\u65E5\u5FD7 (${i})`);return}let l=a.trimEnd().split(`
63
+ `))}let l=a.length;Er(i,{interval:500},()=>{try{let p=xr(i);if(p.size>l){let m=Tr(i,"r"),g=Buffer.alloc(p.size-l);$r(m,g,0,g.length,l),Pr(m),process.stdout.write(g.toString("utf8")),l=p.size}}catch{}})}else{let a=await Kt(i,"utf8").catch(()=>"");if(!a){console.log(`\u6682\u65E0\u65E5\u5FD7 (${i})`);return}let l=a.trimEnd().split(`
64
64
  `);console.log(l.slice(-s).join(`
65
65
  `))}}catch(o){S.error("cli","logs \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("autostart").description("macOS \u5F00\u673A\u81EA\u542F\u7BA1\u7406").addCommand(new Le("enable").description("\u542F\u7528 macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").option("--max-tasks <n>","\u5E76\u53D1\u4E0A\u9650").action(async n=>{try{P()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await Gt(n.agentId,{maxTasks:n.maxTasks?parseInt(n.maxTasks,10):void 0}),console.log("\u2705 \u81EA\u542F\u52A8\u5DF2\u542F\u7528"),console.log(` Agent: ${n.agentId}`),console.log(` Plist: ~/Library/LaunchAgents/com.alibaba.aitable-workflow.daemon.${n.agentId}.plist`)}catch(o){S.error("cli","autostart enable \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})).addCommand(new Le("disable").description("\u5173\u95ED macOS \u767B\u5F55\u81EA\u542F\u52A8").requiredOption("--agent-id <id>","Agent ID / \u540D\u79F0").action(async n=>{try{P()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),await Ht(n.agentId),console.log(`\u2705 \u81EA\u542F\u52A8\u5DF2\u5173\u95ED (${n.agentId})`)}catch(o){S.error("cli","autostart disable \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})).addCommand(new Le("status").description("\u67E5\u770B macOS \u81EA\u542F\u52A8\u72B6\u6001").option("--agent-id <id>","Agent ID / \u540D\u79F0\uFF08\u4E0D\u6307\u5B9A\u5219\u5217\u51FA\u6240\u6709\uFF09").action(async n=>{try{if(P()||(console.error("\u274C \u5F00\u673A\u81EA\u542F\u5F53\u524D\u4EC5\u652F\u6301 macOS"),process.exit(1)),n.agentId){let o=await De(n.agentId);console.log(`
66
- Agent: ${n.agentId}`),console.log(`Installed: ${o.installed?"yes":"no"}`),console.log(`Loaded: ${o.loaded?"yes":"no"}`),console.log(`Running: ${o.running?`yes (PID: ${o.pid})`:"no"}`),console.log("")}else{let o=await qt();if(o.length===0){console.log("\u65E0\u5DF2\u6CE8\u518C\u7684 Agent");return}for(let i of o){let s=await De(i.name),a=s.running?`running (PID: ${s.pid})`:s.loaded?"loaded":s.installed?"installed":"not installed";console.log(` ${i.name}: ${a}`)}}}catch(o){S.error("cli","autostart status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}))}c(Vt,"registerDaemonCommands");function Yt(r,t){r.command("heartbeat").description("\u5411\u670D\u52A1\u7AEF\u53D1\u9001\u5FC3\u8DF3\u5E76\u8FD4\u56DE\u4EFB\u52A1\u5206\u914D\u60C5\u51B5").action(async()=>{try{let e=await j();if(!e)throw new Error("\u65E0\u6D3B\u8DC3 Agent");if(!(await V(e.name)).running){console.log("\u26A0\uFE0F Daemon \u672A\u5728\u8FD0\u884C\u3002\u4F7F\u7528 `aitable-workflow daemon start` \u542F\u52A8\u3002");return}let o=await he(e.name);console.log("\u2705 Heartbeat OK"),console.log(` Agent: ${e.name}`),console.log(` Connection: ${o.connectionState}`),console.log(` Running: ${o.runningTasks} tasks`),console.log(` Queued: ${o.queuedTasks} tasks`),o.lastHeartbeatAt&&console.log(` Last HB: ${o.lastHeartbeatAt}`)}catch(e){S.error("cli","heartbeat \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}})}c(Yt,"registerHeartbeatCommand");import{logger as Pr,saveCredential as jr,findConflictingCredential as Or,maskSecret as _r}from"aitable-workflow-core";function Jt(r,t){r.command("connect").description("\u4E00\u952E\u6CE8\u518C + \u4FDD\u5B58\u51ED\u8BC1 + \u540E\u53F0\u542F\u52A8 daemon\uFF08\u5BF9\u6807 Harness connect\uFF09").requiredOption("--server-url <url>","Gateway / \u5E73\u53F0\u5730\u5740").option("--token <ownerToken>","owner-token\uFF08\u81EA\u6CE8\u518C\uFF0C\u4E0E --key \u4E8C\u9009\u4E00\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF0C\u4E0E --token \u4E8C\u9009\u4E00\uFF09").requiredOption("--name <name>","Agent \u540D\u79F0").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u53EF\u9009\uFF09").option("--no-start","\u53EA\u6CE8\u518C\u4E0D\u542F\u52A8 daemon").option("--foreground","\u6CE8\u518C\u540E\u5728\u524D\u53F0\u8FD0\u884C relay\uFF08\u963B\u585E\u7EC8\u7AEF\uFF0C\u4FBF\u4E8E\u8C03\u8BD5\uFF09").option("--force","\u8986\u76D6\u540C\u540D\u4F46\u7F51\u5173\u4E0D\u540C\u7684\u5DF2\u6709\u51ED\u8BC1").action(async e=>{try{if(!e.token&&!e.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(!e.force){let l=await Or(e.name,e.serverUrl);l&&(console.error(`\u26A0\uFE0F \u62D2\u7EDD\u8986\u76D6\uFF1AAgent \u540D\u79F0 "${e.name}" \u5DF2\u7ED1\u5B9A\u5230\u53E6\u4E00\u4E2A\u7F51\u5173\u3002`),console.error(` \u65E7\u7F51\u5173: ${l.serverUrl}`),console.error(` \u65B0\u7F51\u5173: ${e.serverUrl}`),console.error(" \u7EE7\u7EED\u5C06\u8986\u76D6\u672C\u673A\u8BE5\u51ED\u8BC1\uFF0C\u4E14\u65E7\u7F51\u5173\u7684 daemon \u65E0\u6CD5\u4E0E\u65B0\u7684\u5171\u5B58\uFF08PID \u4E92\u65A5\uFF09\u3002"),console.error(" \u8BF7\u9009\u62E9\u5176\u4E00\uFF1A"),console.error(" 1) \u6362\u4E00\u4E2A --name\uFF08\u591A\u7F51\u5173\u5EFA\u8BAE\u6BCF\u4E2A\u7F51\u5173\u7528\u4E0D\u540C\u540D\u79F0\uFF09"),console.error(" 2) \u786E\u5B9E\u8981\u6539\u7ED1\uFF0C\u52A0 --force \u5F3A\u5236\u8986\u76D6"),process.exit(1))}let n=e.workspaceRoot?je(e.workspaceRoot,e.name):void 0,o={name:e.name,serverUrl:e.serverUrl,token:e.token??"",key:e.key,workspaceRoot:n,createdAt:new Date().toISOString()};if(await jr(o),console.log(`\u2705 Agent "${e.name}" \u5DF2\u6CE8\u518C\u5E76\u4FDD\u5B58\u51ED\u8BC1`),console.log(` Server: ${e.serverUrl}`),console.log(` ${e.token?"Token":"Key"}: ${_r(e.token??e.key??"")}`),n&&console.log(` Workspace: ${n}`),console.log(" \u51ED\u8BC1\u6587\u4EF6: ~/.aitable-workflow/credentials.json"),!e.start){e.foreground&&console.log(`
66
+ Agent: ${n.agentId}`),console.log(`Installed: ${o.installed?"yes":"no"}`),console.log(`Loaded: ${o.loaded?"yes":"no"}`),console.log(`Running: ${o.running?`yes (PID: ${o.pid})`:"no"}`),console.log("")}else{let o=await qt();if(o.length===0){console.log("\u65E0\u5DF2\u6CE8\u518C\u7684 Agent");return}for(let i of o){let s=await De(i.name),a=s.running?`running (PID: ${s.pid})`:s.loaded?"loaded":s.installed?"installed":"not installed";console.log(` ${i.name}: ${a}`)}}}catch(o){S.error("cli","autostart status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}))}c(Vt,"registerDaemonCommands");function Yt(r,t){r.command("heartbeat").description("\u5411\u670D\u52A1\u7AEF\u53D1\u9001\u5FC3\u8DF3\u5E76\u8FD4\u56DE\u4EFB\u52A1\u5206\u914D\u60C5\u51B5").action(async()=>{try{let e=await j();if(!e)throw new Error("\u65E0\u6D3B\u8DC3 Agent");if(!(await V(e.name)).running){console.log("\u26A0\uFE0F Daemon \u672A\u5728\u8FD0\u884C\u3002\u4F7F\u7528 `aitable-workflow daemon start` \u542F\u52A8\u3002");return}let o=await he(e.name);console.log("\u2705 Heartbeat OK"),console.log(` Agent: ${e.name}`),console.log(` Connection: ${o.connectionState}`),console.log(` Running: ${o.runningTasks} tasks`),console.log(` Queued: ${o.queuedTasks} tasks`),o.lastHeartbeatAt&&console.log(` Last HB: ${o.lastHeartbeatAt}`)}catch(e){S.error("cli","heartbeat \u5931\u8D25",{error:e instanceof Error?e.message:String(e)}),process.exit(1)}})}c(Yt,"registerHeartbeatCommand");import{logger as jr,saveCredential as Or,findConflictingCredential as _r,maskSecret as Dr}from"aitable-workflow-core";function Jt(r,t){r.command("connect").description("\u4E00\u952E\u6CE8\u518C + \u4FDD\u5B58\u51ED\u8BC1 + \u540E\u53F0\u542F\u52A8 daemon\uFF08\u5BF9\u6807 Harness connect\uFF09").requiredOption("--server-url <url>","Gateway / \u5E73\u53F0\u5730\u5740").option("--token <ownerToken>","owner-token\uFF08\u81EA\u6CE8\u518C\uFF0C\u4E0E --key \u4E8C\u9009\u4E00\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF0C\u4E0E --token \u4E8C\u9009\u4E00\uFF09").requiredOption("--name <name>","Agent \u540D\u79F0").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u53EF\u9009\uFF09").option("--no-start","\u53EA\u6CE8\u518C\u4E0D\u542F\u52A8 daemon").option("--foreground","\u6CE8\u518C\u540E\u5728\u524D\u53F0\u8FD0\u884C relay\uFF08\u963B\u585E\u7EC8\u7AEF\uFF0C\u4FBF\u4E8E\u8C03\u8BD5\uFF09").option("--force","\u8986\u76D6\u540C\u540D\u4F46\u7F51\u5173\u4E0D\u540C\u7684\u5DF2\u6709\u51ED\u8BC1").action(async e=>{try{if(!e.token&&!e.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(!e.force){let l=await _r(e.name,e.serverUrl);l&&(console.error(`\u26A0\uFE0F \u62D2\u7EDD\u8986\u76D6\uFF1AAgent \u540D\u79F0 "${e.name}" \u5DF2\u7ED1\u5B9A\u5230\u53E6\u4E00\u4E2A\u7F51\u5173\u3002`),console.error(` \u65E7\u7F51\u5173: ${l.serverUrl}`),console.error(` \u65B0\u7F51\u5173: ${e.serverUrl}`),console.error(" \u7EE7\u7EED\u5C06\u8986\u76D6\u672C\u673A\u8BE5\u51ED\u8BC1\uFF0C\u4E14\u65E7\u7F51\u5173\u7684 daemon \u65E0\u6CD5\u4E0E\u65B0\u7684\u5171\u5B58\uFF08PID \u4E92\u65A5\uFF09\u3002"),console.error(" \u8BF7\u9009\u62E9\u5176\u4E00\uFF1A"),console.error(" 1) \u6362\u4E00\u4E2A --name\uFF08\u591A\u7F51\u5173\u5EFA\u8BAE\u6BCF\u4E2A\u7F51\u5173\u7528\u4E0D\u540C\u540D\u79F0\uFF09"),console.error(" 2) \u786E\u5B9E\u8981\u6539\u7ED1\uFF0C\u52A0 --force \u5F3A\u5236\u8986\u76D6"),process.exit(1))}let n=e.workspaceRoot?je(e.workspaceRoot,e.name):void 0,o={name:e.name,serverUrl:e.serverUrl,token:e.token??"",key:e.key,workspaceRoot:n,createdAt:new Date().toISOString()};if(await Or(o),console.log(`\u2705 Agent "${e.name}" \u5DF2\u6CE8\u518C\u5E76\u4FDD\u5B58\u51ED\u8BC1`),console.log(` Server: ${e.serverUrl}`),console.log(` ${e.token?"Token":"Key"}: ${Dr(e.token??e.key??"")}`),n&&console.log(` Workspace: ${n}`),console.log(" \u51ED\u8BC1\u6587\u4EF6: ~/.aitable-workflow/credentials.json"),!e.start){e.foreground&&console.log(`
67
67
  \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(`
68
68
  \u{1F4A1} \u542F\u52A8 daemon: aitable-workflow daemon start \u6216 aitable-workflow relay`);return}if(e.foreground){console.log(`
69
69
  \u{1F680} \u524D\u53F0\u542F\u52A8 relay\uFF08Ctrl-C \u9000\u51FA\uFF09...`),await fe({serverUrl:e.serverUrl,token:e.token,key:e.key,name:e.name,workspaceRoot:n});return}let i=e.name,s=await B({serverUrl:e.serverUrl,token:e.token,key:e.key,workspaceRoot:e.workspaceRoot,name:i}),a=await K({agentId:i,serverUrl:s.serverUrl,token:s.token,key:s.key,name:s.name??i,workspaceRoot:s.workspaceRoot,machineId:s.machineId,maxTasks:s.maxTasks});console.log(`
70
70
  \u{1F680} Daemon \u5DF2\u540E\u53F0\u542F\u52A8`),console.log(` Agent: ${i}`),console.log(` PID: ${a.pid}`),console.log(` Log: ~/.aitable-workflow/daemons/${i}/daemon.log`),console.log(`
71
- \u{1F4CB} \u5E38\u7528\u547D\u4EE4\uFF1A`),console.log(` \u67E5\u770B\u72B6\u6001: aitable-workflow daemon status --agent ${i}`),console.log(` \u8DDF\u8E2A\u65E5\u5FD7: aitable-workflow daemon logs -f --agent ${i}`),console.log(` \u505C\u6B62: aitable-workflow daemon stop --agent ${i}`),console.log(` \u91CD\u542F: aitable-workflow daemon restart --agent ${i}`),console.log(" \u5217\u51FA Agent: aitable-workflow agent list"),console.log(" \u5207\u6362 Agent: aitable-workflow agent use <name>"),console.log(` \u5F00\u673A\u81EA\u542F: aitable-workflow daemon autostart enable --agent-id ${i}`)}catch(n){Pr.error("cli","connect \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Jt,"registerConnectCommand");import{logger as ye,listCredentials as Dr,setActiveAgent as Lr,getActiveCredential as zt,readCredentials as Mr,maskSecret as Xt}from"aitable-workflow-core";function Qt(r,t){let e=r.command("agent").description("Agent \u51ED\u8BC1\u7BA1\u7406");e.command("list").description("\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684 Agent \u51ED\u8BC1").action(async()=>{try{let n=await Dr();if(n.length===0){console.log("\u6682\u65E0\u5DF2\u4FDD\u5B58\u7684 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let o=await Mr();console.log(`
71
+ \u{1F4CB} \u5E38\u7528\u547D\u4EE4\uFF1A`),console.log(` \u67E5\u770B\u72B6\u6001: aitable-workflow daemon status --agent ${i}`),console.log(` \u8DDF\u8E2A\u65E5\u5FD7: aitable-workflow daemon logs -f --agent ${i}`),console.log(` \u505C\u6B62: aitable-workflow daemon stop --agent ${i}`),console.log(` \u91CD\u542F: aitable-workflow daemon restart --agent ${i}`),console.log(" \u5217\u51FA Agent: aitable-workflow agent list"),console.log(" \u5207\u6362 Agent: aitable-workflow agent use <name>"),console.log(` \u5F00\u673A\u81EA\u542F: aitable-workflow daemon autostart enable --agent-id ${i}`)}catch(n){jr.error("cli","connect \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Jt,"registerConnectCommand");import{logger as ye,listCredentials as Lr,setActiveAgent as Mr,getActiveCredential as zt,readCredentials as Fr,maskSecret as Xt}from"aitable-workflow-core";function Qt(r,t){let e=r.command("agent").description("Agent \u51ED\u8BC1\u7BA1\u7406");e.command("list").description("\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684 Agent \u51ED\u8BC1").action(async()=>{try{let n=await Lr();if(n.length===0){console.log("\u6682\u65E0\u5DF2\u4FDD\u5B58\u7684 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let o=await Fr();console.log(`
72
72
  \u5DF2\u4FDD\u5B58 ${n.length} \u4E2A Agent\uFF08\u6D3B\u8DC3: ${o.activeAgent??"\u65E0"}\uFF09:
73
- `);for(let i of n){let s=i.name===o.activeAgent?" \u2190 active":"";console.log(` \u2022 ${i.name}${s}`),console.log(` Server: ${i.serverUrl}`),console.log(` Token: ${Xt(i.token)}`),i.machineId&&console.log(` MachineID: ${i.machineId}`),i.workspaceRoot&&console.log(` Workspace: ${i.workspaceRoot}`),console.log(` Created: ${i.createdAt}`)}console.log("")}catch(n){ye.error("cli","agent list \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}}),e.command("use <name>").description("\u5207\u6362\u6D3B\u8DC3 Agent").action(async n=>{try{let o=await Lr(n);console.log(`\u2705 \u5DF2\u5207\u6362\u5230 Agent "${o.activeAgent}"`)}catch(o){ye.error("cli","agent use \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("whoami").description("\u663E\u793A\u5F53\u524D\u6D3B\u8DC3 Agent").action(async()=>{try{let n=await zt();if(!n){console.log("\u5F53\u524D\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `aitable-workflow agent use <name>` \u5207\u6362\u3002");return}console.log(`Agent: ${n.name}`),console.log(`Server: ${n.serverUrl}`),console.log(`Token: ${Xt(n.token)}`),n.machineId&&console.log(`MachineID: ${n.machineId}`),n.workspaceRoot&&console.log(`Workspace: ${n.workspaceRoot}`)}catch(n){ye.error("cli","agent whoami \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}}),e.command("status").description("\u67E5\u770B Agent \u8FDE\u63A5\u72B6\u6001\u4E0E\u8FD0\u884C\u65F6\u4FE1\u606F").option("--json","JSON \u683C\u5F0F\u8F93\u51FA").action(async n=>{try{let o=await zt();if(!o){console.log("\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let i=await V(o.name),s=await he(o.name),a={agent:o.name,serverUrl:o.serverUrl,connectionState:i.running?s.connectionState:"stopped",machineId:s.machineId??o.machineId??null,lastHeartbeatAt:s.lastHeartbeatAt,runningTasks:s.runningTasks,queuedTasks:s.queuedTasks,lastDisconnectReason:s.lastDisconnectReason,pid:i.pid};if(n.json){process.stdout.write(JSON.stringify(a,null,2)+`
73
+ `);for(let i of n){let s=i.name===o.activeAgent?" \u2190 active":"";console.log(` \u2022 ${i.name}${s}`),console.log(` Server: ${i.serverUrl}`),console.log(` Token: ${Xt(i.token)}`),i.machineId&&console.log(` MachineID: ${i.machineId}`),i.workspaceRoot&&console.log(` Workspace: ${i.workspaceRoot}`),console.log(` Created: ${i.createdAt}`)}console.log("")}catch(n){ye.error("cli","agent list \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}}),e.command("use <name>").description("\u5207\u6362\u6D3B\u8DC3 Agent").action(async n=>{try{let o=await Mr(n);console.log(`\u2705 \u5DF2\u5207\u6362\u5230 Agent "${o.activeAgent}"`)}catch(o){ye.error("cli","agent use \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}}),e.command("whoami").description("\u663E\u793A\u5F53\u524D\u6D3B\u8DC3 Agent").action(async()=>{try{let n=await zt();if(!n){console.log("\u5F53\u524D\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u6216 `aitable-workflow agent use <name>` \u5207\u6362\u3002");return}console.log(`Agent: ${n.name}`),console.log(`Server: ${n.serverUrl}`),console.log(`Token: ${Xt(n.token)}`),n.machineId&&console.log(`MachineID: ${n.machineId}`),n.workspaceRoot&&console.log(`Workspace: ${n.workspaceRoot}`)}catch(n){ye.error("cli","agent whoami \u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}}),e.command("status").description("\u67E5\u770B Agent \u8FDE\u63A5\u72B6\u6001\u4E0E\u8FD0\u884C\u65F6\u4FE1\u606F").option("--json","JSON \u683C\u5F0F\u8F93\u51FA").action(async n=>{try{let o=await zt();if(!o){console.log("\u65E0\u6D3B\u8DC3 Agent\u3002\u4F7F\u7528 `aitable-workflow connect` \u6CE8\u518C\u3002");return}let i=await V(o.name),s=await he(o.name),a={agent:o.name,serverUrl:o.serverUrl,connectionState:i.running?s.connectionState:"stopped",machineId:s.machineId??o.machineId??null,lastHeartbeatAt:s.lastHeartbeatAt,runningTasks:s.runningTasks,queuedTasks:s.queuedTasks,lastDisconnectReason:s.lastDisconnectReason,pid:i.pid};if(n.json){process.stdout.write(JSON.stringify(a,null,2)+`
74
74
  `);return}let l=a.connectionState==="connected"?"\u{1F7E2}":a.connectionState==="reconnecting"?"\u{1F7E1}":"\u{1F534}";console.log(`
75
- ${l} Agent: ${a.agent}`),console.log(` Server: ${a.serverUrl}`),console.log(` Connection: ${a.connectionState}`),a.machineId&&console.log(` MachineID: ${a.machineId}`),a.lastHeartbeatAt&&console.log(` Last HB: ${a.lastHeartbeatAt}`),i.running&&(console.log(` PID: ${a.pid}`),console.log(` Tasks: ${a.runningTasks} running, ${a.queuedTasks} queued`)),a.lastDisconnectReason&&console.log(` Last Error: ${a.lastDisconnectReason}`),console.log("")}catch(o){ye.error("cli","agent status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})}c(Qt,"registerAgentCommands");import{logger as Fr}from"aitable-workflow-core";function Zt(r,t){r.command("relay").description("\u4EE5\u672C\u673A relay \u5B88\u62A4\u8EAB\u4EFD\u53CD\u8FDE RelayGateway\uFF0C\u6309\u9700\u5728\u672C\u673A\u6267\u884C Agent/dws \u4EFB\u52A1").option("--server-url <url>","Gateway \u5730\u5740\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_SERVER_URL\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--token <ownerToken>","owner-token \u81EA\u6CE8\u518C\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_TOKEN\uFF1B\u4F18\u5148\u4E8E --key\uFF09").option("--name <name>","\u81EA\u6CE8\u518C\u673A\u5668\u540D\uFF08\u53EF\u9009\uFF0C\u7F3A\u7701\u81EA\u52A8\u4F7F\u7528\u4E3B\u673A\u540D\uFF1Bowner+name \u5E42\u7B49\u952E\uFF0C\u591A\u673A\u573A\u666F\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A\u4EE5\u907F\u514D hostname \u51B2\u7A81\u4E92\u76F8\u9876\u8FDE\u63A5\uFF1B\u4E5F\u53EF\u7528 AITABLE_RELAY_NAME\uFF09").option("--desc <description>","\u81EA\u6CE8\u518C\u673A\u5668\u63CF\u8FF0\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_DESC\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_WORKSPACE_ROOT\uFF09").option("--machine-id <id>","\u7A33\u5B9A\u673A\u5668\u8EAB\u4EFD\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MACHINE_ID\uFF09").option("--max-tasks <n>","\u672C\u673A\u5E76\u53D1\u6267\u884C\u4E0A\u9650\uFF0C\u9ED8\u8BA4 1\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_TASKS\uFF09").option("--max-workflows <n>","\u672C\u673A\u53EF\u540C\u65F6\u8FD0\u884C\u7684\u5DE5\u4F5C\u6D41\u5F15\u64CE\u6570\uFF0C\u9ED8\u8BA4 3\uFF1B0 = \u4E0D\u8BA4\u9886\u5DE5\u4F5C\u6D41\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_WORKFLOWS\uFF09").action(e=>{try{fe(e)}catch(n){Fr.error("cli","relay \u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Zt,"registerRelayCommand");import{loadSettings as en,loadWorkflowTemplate as Br,checkWorkflowRecipes as Ur,Tracer as Wr}from"aitable-workflow-core";import Nr from"path";function tn(r,t){r.command("inspect [recordId]").description("\u67E5\u770B\u5DE5\u5355\u6267\u884C trace\uFF1B\u6216\u7528 --recipes / --validate \u67E5\u770B\u6821\u9A8C recipe schema \u4E0E workflow \u5BF9\u9F50").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-s, --step <stepId>","\u67E5\u770B\u7279\u5B9A\u6B65\u9AA4").option("-l, --latest","\u67E5\u770B\u6700\u8FD1\u6267\u884C").option("-n, --limit <number>","\u6700\u591A\u663E\u793A\u6761\u6570","10").option("--recipes","\u5217\u51FA\u5404\u6B65\u9AA4 recipe \u7684 input / output / config schema\u4E0E step \u914D\u7F6E").option("--validate","\u6821\u9A8C step.config / input_mapping / output_mapping \u662F\u5426\u7B26\u5408 recipe schema").option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u53D6\u7B2C\u4E00\u4E2A\uFF09").action(async(e,n)=>{try{if(n.recipes||n.validate){await Gr(n);return}let o=await en(n.config),i=Nr.resolve(o.configDir,o.agent.trace_dir),s=new Wr(i),a=parseInt(n.limit,10)||10,l;if(n.latest||!e){if(l=await s.getLatestTraces(a),l.length===0){console.log("\u26A0\uFE0F \u6682\u65E0 trace \u8BB0\u5F55\u3002\u8FD0\u884C `run` \u547D\u4EE4\u540E\u518D\u67E5\u770B\u3002");return}console.log(`
75
+ ${l} Agent: ${a.agent}`),console.log(` Server: ${a.serverUrl}`),console.log(` Connection: ${a.connectionState}`),a.machineId&&console.log(` MachineID: ${a.machineId}`),a.lastHeartbeatAt&&console.log(` Last HB: ${a.lastHeartbeatAt}`),i.running&&(console.log(` PID: ${a.pid}`),console.log(` Tasks: ${a.runningTasks} running, ${a.queuedTasks} queued`)),a.lastDisconnectReason&&console.log(` Last Error: ${a.lastDisconnectReason}`),console.log("")}catch(o){ye.error("cli","agent status \u5931\u8D25",{error:o instanceof Error?o.message:String(o)}),process.exit(1)}})}c(Qt,"registerAgentCommands");import{logger as Br}from"aitable-workflow-core";function Zt(r,t){r.command("relay").description("\u4EE5\u672C\u673A relay \u5B88\u62A4\u8EAB\u4EFD\u53CD\u8FDE RelayGateway\uFF0C\u6309\u9700\u5728\u672C\u673A\u6267\u884C Agent/dws \u4EFB\u52A1").option("--server-url <url>","Gateway \u5730\u5740\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_SERVER_URL\uFF09").option("--key <machineKey>","per-machine key\uFF08sk_machine_*\uFF09").option("--token <ownerToken>","owner-token \u81EA\u6CE8\u518C\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_TOKEN\uFF1B\u4F18\u5148\u4E8E --key\uFF09").option("--name <name>","\u81EA\u6CE8\u518C\u673A\u5668\u540D\uFF08\u53EF\u9009\uFF0C\u7F3A\u7701\u81EA\u52A8\u4F7F\u7528\u4E3B\u673A\u540D\uFF1Bowner+name \u5E42\u7B49\u952E\uFF0C\u591A\u673A\u573A\u666F\u5EFA\u8BAE\u663E\u5F0F\u6307\u5B9A\u4EE5\u907F\u514D hostname \u51B2\u7A81\u4E92\u76F8\u9876\u8FDE\u63A5\uFF1B\u4E5F\u53EF\u7528 AITABLE_RELAY_NAME\uFF09").option("--desc <description>","\u81EA\u6CE8\u518C\u673A\u5668\u63CF\u8FF0\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_DESC\uFF09").option("--workspace-root <dir>","\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_WORKSPACE_ROOT\uFF09").option("--machine-id <id>","\u7A33\u5B9A\u673A\u5668\u8EAB\u4EFD\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MACHINE_ID\uFF09").option("--max-tasks <n>","\u672C\u673A\u5E76\u53D1\u6267\u884C\u4E0A\u9650\uFF0C\u9ED8\u8BA4 1\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_TASKS\uFF09").option("--max-workflows <n>","\u672C\u673A\u53EF\u540C\u65F6\u8FD0\u884C\u7684\u5DE5\u4F5C\u6D41\u5F15\u64CE\u6570\uFF0C\u9ED8\u8BA4 3\uFF1B0 = \u4E0D\u8BA4\u9886\u5DE5\u4F5C\u6D41\uFF08\u4E5F\u53EF\u7528 AITABLE_RELAY_MAX_WORKFLOWS\uFF09").action(e=>{try{fe(e)}catch(n){Br.error("cli","relay \u542F\u52A8\u5931\u8D25",{error:n instanceof Error?n.message:String(n)}),process.exit(1)}})}c(Zt,"registerRelayCommand");import{loadSettings as en,loadWorkflowTemplate as Ur,checkWorkflowRecipes as Wr,Tracer as Nr}from"aitable-workflow-core";import Gr from"path";function tn(r,t){r.command("inspect [recordId]").description("\u67E5\u770B\u5DE5\u5355\u6267\u884C trace\uFF1B\u6216\u7528 --recipes / --validate \u67E5\u770B\u6821\u9A8C recipe schema \u4E0E workflow \u5BF9\u9F50").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).option("-s, --step <stepId>","\u67E5\u770B\u7279\u5B9A\u6B65\u9AA4").option("-l, --latest","\u67E5\u770B\u6700\u8FD1\u6267\u884C").option("-n, --limit <number>","\u6700\u591A\u663E\u793A\u6761\u6570","10").option("--recipes","\u5217\u51FA\u5404\u6B65\u9AA4 recipe \u7684 input / output / config schema\u4E0E step \u914D\u7F6E").option("--validate","\u6821\u9A8C step.config / input_mapping / output_mapping \u662F\u5426\u7B26\u5408 recipe schema").option("-w, --workflow <id>","\u591A\u5DE5\u4F5C\u6D41\u6A21\u5F0F\uFF1A\u6307\u5B9A\u5DE5\u4F5C\u6D41 ID\uFF08\u7F3A\u7701\u53D6\u7B2C\u4E00\u4E2A\uFF09").action(async(e,n)=>{try{if(n.recipes||n.validate){await Hr(n);return}let o=await en(n.config),i=Gr.resolve(o.configDir,o.agent.trace_dir),s=new Nr(i),a=parseInt(n.limit,10)||10,l;if(n.latest||!e){if(l=await s.getLatestTraces(a),l.length===0){console.log("\u26A0\uFE0F \u6682\u65E0 trace \u8BB0\u5F55\u3002\u8FD0\u884C `run` \u547D\u4EE4\u540E\u518D\u67E5\u770B\u3002");return}console.log(`
76
76
  \u{1F4C4} \u6700\u8FD1 ${l.length} \u6761\u6267\u884C\u8BB0\u5F55:
77
77
  `)}else{if(l=await s.getTraces(e),l.length===0){console.log(`\u26A0\uFE0F \u672A\u627E\u5230\u5DE5\u5355 ${e} \u7684 trace \u8BB0\u5F55\u3002`);return}n.step&&(l=l.filter(p=>p.step_id===n.step)),console.log(`
78
78
  \u{1F4C4} \u5DE5\u5355 ${e} \u7684\u6267\u884C\u5386\u53F2 (${l.length} \u6B65):
79
- `)}for(let p of l){let m=p.status==="success"?"\u2705":p.status==="failed"?"\u274C":"\u23F8\uFE0F",g=(p.duration_ms/1e3).toFixed(1);console.log(`${m} [${p.step_id}] ${p.step_name} \u2014 ${g}s \u2014 ${p.status.toUpperCase()}`);for(let[u,d]of p.llm_calls.entries()){let w=u===p.llm_calls.length-1,I=w?" \u2514\u2500":" \u251C\u2500",A=w?" ":" \u2502 ",z=(d.duration_ms/1e3).toFixed(1);console.log(`${I} LLM: ${d.model} (${z}s)`),console.log(`${A}Input: ${d.prompt_summary.slice(0,80)}${d.prompt_summary.length>80?"...":""}`),console.log(`${A}Output: ${d.response_summary.slice(0,100)}${d.response_summary.length>100?"...":""}`)}if(Object.keys(p.outputs).length>0){let u=Object.entries(p.outputs).map(([d,w])=>`${d}=${typeof w=="string"?w.slice(0,50):JSON.stringify(w)}`).join(", ");console.log(` \u2514\u2500 Outputs: ${u}`)}p.error&&console.log(` \u2514\u2500 Error: ${p.error}`),console.log()}}catch(o){console.error(`\u2717 inspect \u5931\u8D25: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}})}c(tn,"registerInspectCommand");async function Gr(r){let t=await en(r.config),e=r.workflow?t.workflowEntries.find(s=>s.id===r.workflow):t.workflowEntries[0];e||(console.error(`\u2717 \u672A\u627E\u5230\u5DE5\u4F5C\u6D41\u300C${r.workflow}\u300D\u3002\u53EF\u7528\uFF1A${t.workflowEntries.map(s=>s.id).join(", ")}`),process.exit(1));let n=await Br(e.templatePath,{envSource:t.envSource}),{issues:o,rows:i}=await Ur(e.recipeDir,n);if(r.recipes){console.log(`
79
+ `)}for(let p of l){let m=p.status==="success"?"\u2705":p.status==="failed"?"\u274C":"\u23F8\uFE0F",g=(p.duration_ms/1e3).toFixed(1);console.log(`${m} [${p.step_id}] ${p.step_name} \u2014 ${g}s \u2014 ${p.status.toUpperCase()}`);for(let[u,d]of p.llm_calls.entries()){let w=u===p.llm_calls.length-1,I=w?" \u2514\u2500":" \u251C\u2500",A=w?" ":" \u2502 ",z=(d.duration_ms/1e3).toFixed(1);console.log(`${I} LLM: ${d.model} (${z}s)`),console.log(`${A}Input: ${d.prompt_summary.slice(0,80)}${d.prompt_summary.length>80?"...":""}`),console.log(`${A}Output: ${d.response_summary.slice(0,100)}${d.response_summary.length>100?"...":""}`)}if(Object.keys(p.outputs).length>0){let u=Object.entries(p.outputs).map(([d,w])=>`${d}=${typeof w=="string"?w.slice(0,50):JSON.stringify(w)}`).join(", ");console.log(` \u2514\u2500 Outputs: ${u}`)}p.error&&console.log(` \u2514\u2500 Error: ${p.error}`),console.log()}}catch(o){console.error(`\u2717 inspect \u5931\u8D25: ${o instanceof Error?o.message:String(o)}`),process.exit(1)}})}c(tn,"registerInspectCommand");async function Hr(r){let t=await en(r.config),e=r.workflow?t.workflowEntries.find(s=>s.id===r.workflow):t.workflowEntries[0];e||(console.error(`\u2717 \u672A\u627E\u5230\u5DE5\u4F5C\u6D41\u300C${r.workflow}\u300D\u3002\u53EF\u7528\uFF1A${t.workflowEntries.map(s=>s.id).join(", ")}`),process.exit(1));let n=await Ur(e.templatePath,{envSource:t.envSource}),{issues:o,rows:i}=await Wr(e.recipeDir,n);if(r.recipes){console.log(`
80
80
  \u{1F4CB} \u5DE5\u4F5C\u6D41\u300C${n.meta.name}\u300D(${e.id}) \u7684 recipe schema:
81
81
  `);for(let s of i){let a=s.configSummary.length>0?s.configSummary.join(", "):"(none)",l=s.loaded?"":" \u26A0 \u52A0\u8F7D\u5931\u8D25";console.log(` [${s.stepId} \u2192 ${s.recipeId}]${l}`),console.log(` config: ${a}`),console.log()}}if(r.validate)if(o.length===0)console.log(`
82
82
  \u2705 \u5DE5\u4F5C\u6D41\u300C${n.meta.name}\u300D(${e.id}) \u5168\u90E8\u6B65\u9AA4\u6821\u9A8C\u901A\u8FC7
83
83
  `);else{let s=o.filter(l=>l.level==="error"),a=o.filter(l=>l.level==="warn");console.log(`
84
84
  \u6821\u9A8C\u7ED3\u679C\uFF1A${s.length} \u4E2A\u9519\u8BEF\uFF0C${a.length} \u4E2A\u8B66\u544A
85
- `);for(let l of o){let p=l.level==="error"?"\u274C":"\u26A0\uFE0F ";console.log(` ${p} [${l.stepId} \u2192 ${l.recipeId}] ${l.message}`)}console.log(),s.length>0&&process.exit(1)}}c(Gr,"runRecipeInspect");import{runKbCompileCommand as Hr,runKbUpdateCommand as qr,runKbStatusCommand as Kr,runKbIngestCommand as Vr,runKbCleanupCommand as Yr}from"aitable-workflow-core";function nn(r,t){let e=r.command("kb").description("\u77E5\u8BC6\u5E93(LLM-Wiki)\u7F16\u8BD1\u4E0E\u72B6\u6001\u7BA1\u7406");e.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",t.defaultConfig).option("--full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1").action(async(n,o)=>{try{await Hr(n,o)}catch(i){console.error(`\u2717 kb compile \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),e.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",t.defaultConfig).action(async(n,o)=>{try{await qr(n,o)}catch(i){console.error(`\u2717 kb update \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),e.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",t.defaultConfig).action(async(n,o)=>{try{await Kr(n,o)}catch(i){console.error(`\u2717 kb status \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),e.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",t.defaultConfig).option("--timeout <ms>","\u5355\u6587\u6863\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").action(async(n,o)=>{try{await Vr(n,o)}catch(i){console.error(`\u2717 kb ingest \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),e.command("cleanup <collection>").description("\u6E05\u7406\u77E5\u8BC6\u5E93\u4E2D\u7684\u5B64\u513F\u6587\u7AE0\uFF08\u6E90\u884C\u5DF2\u5220\u4F46 articles/ \u8FD8\u5728\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).action(async(n,o)=>{try{await Yr(n,o)}catch(i){console.error(`\u2717 kb cleanup \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}})}c(nn,"registerKbCommands");import Fe from"path";import{BotProvisioner as Jr,BotProvisionError as an,DwsDevRunner as Be,buildBotApprovalReportLines as zr,defaultProvisionStatePath as Ue,groupEntriesOf as Xr,loadProvisionState as cn,resolveConfigPath as We,validateProvisionName as Qr}from"aitable-workflow-core";import{logger as on}from"aitable-workflow-core";function rn(r){for(let t of r){let e=t.title?`\u300C${t.title}\u300D${t.openConversationId}`:t.openConversationId;t.outcome==="added"?console.log(`
85
+ `);for(let l of o){let p=l.level==="error"?"\u274C":"\u26A0\uFE0F ";console.log(` ${p} [${l.stepId} \u2192 ${l.recipeId}] ${l.message}`)}console.log(),s.length>0&&process.exit(1)}}c(Hr,"runRecipeInspect");import{runKbCompileCommand as qr,runKbUpdateCommand as Kr,runKbStatusCommand as Vr,runKbIngestCommand as Yr,runKbCleanupCommand as Jr}from"aitable-workflow-core";function nn(r,t){let e=r.command("kb").description("\u77E5\u8BC6\u5E93(LLM-Wiki)\u7F16\u8BD1\u4E0E\u72B6\u6001\u7BA1\u7406");e.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",t.defaultConfig).option("--full","\u5F3A\u5236\u5168\u91CF\u91CD\u7F16\u8BD1").action(async(n,o)=>{try{await qr(n,o)}catch(i){console.error(`\u2717 kb compile \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),e.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",t.defaultConfig).action(async(n,o)=>{try{await Kr(n,o)}catch(i){console.error(`\u2717 kb update \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),e.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",t.defaultConfig).action(async(n,o)=>{try{await Vr(n,o)}catch(i){console.error(`\u2717 kb status \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),e.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",t.defaultConfig).option("--timeout <ms>","\u5355\u6587\u6863\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").action(async(n,o)=>{try{await Yr(n,o)}catch(i){console.error(`\u2717 kb ingest \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}}),e.command("cleanup <collection>").description("\u6E05\u7406\u77E5\u8BC6\u5E93\u4E2D\u7684\u5B64\u513F\u6587\u7AE0\uFF08\u6E90\u884C\u5DF2\u5220\u4F46 articles/ \u8FD8\u5728\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",t.defaultConfig).action(async(n,o)=>{try{await Jr(n,o)}catch(i){console.error(`\u2717 kb cleanup \u5931\u8D25: ${i instanceof Error?i.message:String(i)}`),process.exit(1)}})}c(nn,"registerKbCommands");import Fe from"path";import{BotProvisioner as zr,BotProvisionError as an,DwsDevRunner as Be,buildBotApprovalReportLines as Xr,defaultProvisionStatePath as Ue,groupEntriesOf as Qr,loadProvisionState as cn,resolveConfigPath as We,validateProvisionName as Zr}from"aitable-workflow-core";import{logger as on}from"aitable-workflow-core";function rn(r){for(let t of r){let e=t.title?`\u300C${t.title}\u300D${t.openConversationId}`:t.openConversationId;t.outcome==="added"?console.log(`
86
86
  \u2705 \u7FA4 ${e}\uFF1A\u672C\u6B21\u5DF2\u771F\u5B9E\u8C03\u7528 add-bot \u5165\u7FA4${t.robotName?`\uFF08\u673A\u5668\u4EBA\u663E\u793A\u540D=${t.robotName}\uFF09`:""}\u3002`):t.source==="server"?console.log(`
87
87
  \u2139\uFE0F \u7FA4 ${e}\uFF1A\u670D\u52A1\u7AEF\u786E\u8BA4\u8BE5\u7FA4\u5DF2\u5B89\u88C5\u6B64\u673A\u5668\u4EBA\uFF08500043\uFF09\uFF0C\u89C6\u540C\u5165\u7FA4\u6210\u529F\u3002`):(console.log(`
88
- \u2139\uFE0F \u7FA4 ${e}\uFF1A\u5DF2\u5728\u7FA4\u53F0\u8D26\uFF08addedAt=${t.addedAt??"?"}\uFF09\uFF0C\u672C\u6B21\u672A\u53D1\u8D77\u4EFB\u4F55 API \u8C03\u7528\u3002`),console.log(" \u6CE8\u610F\uFF1A\u82E5\u673A\u5668\u4EBA\u66FE\u88AB\u624B\u52A8\u79FB\u51FA\u7FA4\uFF0C\u91CD\u8DD1\u672C\u547D\u4EE4\u4E0D\u4F1A\u91CD\u65B0\u6DFB\u52A0\uFF1B\u4EE5\u7FA4\u8BBE\u7F6E\u9875\u6216\u7FA4\u91CC @ \u5B9E\u6D4B\u4E3A\u51C6\u3002"))}}c(rn,"printGroupOutcomes");function ln(r,t,e={}){let n=e.exit??(i=>process.exit(i)),o=r.command("bot").description("\u9489\u9489\u673A\u5668\u4EBA provisioning\uFF08\u5EFA\u53F7 / \u51ED\u636E\u7ED1\u5B9A / \u53D1\u5E03\u5BA1\u6279 / \u62C9\u7FA4\uFF09");o.command("provision").description("\u786E\u5B9A\u6027\u5EFA\u53F7\u5E76\u7ED1\u5B9A\u51ED\u636E\uFF08\u5E42\u7B49\u3001\u53EF\u65AD\u70B9\u7EED\u8DD1\uFF1B--publish/--group \u8D70\u4EBA\u5BA1\u4E0E\u62C9\u7FA4\u76F8\uFF09").requiredOption("--name <name>","\u5E94\u7528\u540D\uFF08\u4F01\u4E1A\u5185\u552F\u4E00\uFF0C2-20 \u5B57\uFF09").option("--robot-name <robotName>","\u673A\u5668\u4EBA\u663E\u793A\u540D\uFF08\u7F3A\u7701\u540C --name\uFF09").option("--desc <desc>","\u5E94\u7528\u63CF\u8FF0\uFF08\u2264200 \u5B57\uFF09").option("--group <group>","\u62C9\u7FA4\u76EE\u6807\uFF1AopenConversationId \u6216\u7FA4\u540D\uFF0C\u9017\u53F7\u5206\u9694\u591A\u7FA4\uFF08\u9700\u5DF2\u5B8C\u6210 publish \u76F8\uFF1B\u5DF2\u5728\u7FA4\u53F0\u8D26\u7684\u7FA4\u96F6\u8C03\u7528\u8DF3\u8FC7\uFF09").option("--publish","\u8FDB\u5165\u53D1\u5E03\u76F8\uFF08\u771F\u5B9E\u6253\u6270\u7BA1\u7406\u5458\u5BA1\u6279\uFF0C\u9700\u914D\u5408 --approver-user-id \u786E\u8BA4\uFF09").option("--approver-user-id <userId>","\u5BA1\u6279\u4EBA userId\uFF08\u5019\u9009\u7531 check-approval \u5217\u51FA\uFF1B\u4EBA\u5BA1\u95E8\u4E0D\u5F97\u9759\u9ED8\u4EE3\u9009\uFF09").option("--state-file <path>","\u72B6\u6001\u6587\u4EF6\u8DEF\u5F84\uFF08\u7F3A\u7701 <configDir>/.aitable/provision-state.json\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u7528\u4E8E\u5B9A\u4F4D configDir\uFF09",t.defaultConfig).option("--yes","\u4E0E dws \u8BED\u4E49\u5BF9\u9F50\uFF1A\u8DF3\u8FC7\u786E\u8BA4\uFF08provision \u5168\u7A0B\u975E\u4EA4\u4E92\uFF0C\u5199\u64CD\u4F5C\u5DF2\u5E26 --yes\uFF09").action(async i=>{try{let s=await Zr(i,t,e);s!==0&&n(s)}catch(s){Me(s),n(1)}}),o.command("status").description("\u67E5\u770B provision \u76F8\u4F4D / \u53D1\u5E03\u5BA1\u6279\u72B6\u6001 / \u5BA1\u6279\u4EBA\u5019\u9009\u4E0E\u50AC\u529E\u547D\u4EE4\u6A21\u677F").option("--state-file <path>","\u72B6\u6001\u6587\u4EF6\u8DEF\u5F84\uFF08\u7F3A\u7701 <configDir>/.aitable/provision-state.json\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u7528\u4E8E\u5B9A\u4F4D configDir\uFF09",t.defaultConfig).option("--refresh","\u5B9E\u65F6\u67E5\u8BE2 dws\uFF08version status + check-approval\uFF09\uFF0C\u800C\u975E\u53EA\u8BFB\u72B6\u6001\u6587\u4EF6").action(async i=>{try{let s=await ti(i,t,e);s!==0&&n(s)}catch(s){Me(s),n(1)}});for(let[i,s]of[["disable","\u505C\u7528"],["enable","\u542F\u7528"]])o.command(i).description(`${s}\u673A\u5668\u4EBA\u80FD\u529B\u6216\u6574\u4E2A\u5E94\u7528\uFF08\u53EF\u9006\uFF1B--scope app \u4F5C\u7528\u4E8E\u6574\u4E2A\u5E94\u7528\uFF09`).option("--scope <scope>","\u4F5C\u7528\u8303\u56F4\uFF1Arobot\uFF08\u9ED8\u8BA4\uFF0C\u4EC5\u673A\u5668\u4EBA\u80FD\u529B\uFF09| app\uFF08\u6574\u4E2A\u5E94\u7528\uFF09","robot").option("--unified-app-id <id>","\u76EE\u6807\u5E94\u7528 unifiedAppId\uFF08\u7F3A\u7701\u4ECE\u72B6\u6001\u6587\u4EF6\u8BFB\uFF09").option("--state-file <path>","\u72B6\u6001\u6587\u4EF6\u8DEF\u5F84\uFF08\u7F3A\u7701 <configDir>/.aitable/provision-state.json\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u7528\u4E8E\u5B9A\u4F4D configDir\uFF09",t.defaultConfig).action(async a=>{try{let l=await ni(i,a,t,e);l!==0&&n(l)}catch(l){Me(l),n(1)}})}c(ln,"registerBotCommands");async function Zr(r,t,e){let n=Qr(r.name);if(n)return console.error(`\u274C ${n}`),1;let o=Fe.dirname(await We(r.config??t.defaultConfig)),i=r.stateFile??Ue(o);r.publish&&!r.approverUserId&&console.log("\u2139 --publish \u672A\u6307\u5B9A --approver-user-id\uFF1A\u82E5\u7EC4\u7EC7\u5BA1\u6279\u7B56\u7565\u9700\u9009\u4EBA\uFF0C\u5C06\u5217\u51FA\u5019\u9009\u540E\u505C\u4E0B\uFF0C\u7531\u4F60\u663E\u5F0F\u786E\u8BA4\u3002");let s=e.createProvisioner?.()??new Jr({runner:new Be}),a={name:r.name,robotName:r.robotName,desc:r.desc,stateFile:i,publish:r.publish,approverUserId:r.approverUserId,group:r.group};console.log(`\u{1F916} \u5F00\u59CB provision\u300C${r.name}\u300D\uFF08\u72B6\u6001\u6587\u4EF6: ${i}\uFF09`);let l=await s.provision(a);return ei(l,{stateFile:i})}c(Zr,"runProvision");function ei(r,t){switch(r.status){case"bound":{console.log(`
88
+ \u2139\uFE0F \u7FA4 ${e}\uFF1A\u5DF2\u5728\u7FA4\u53F0\u8D26\uFF08addedAt=${t.addedAt??"?"}\uFF09\uFF0C\u672C\u6B21\u672A\u53D1\u8D77\u4EFB\u4F55 API \u8C03\u7528\u3002`),console.log(" \u6CE8\u610F\uFF1A\u82E5\u673A\u5668\u4EBA\u66FE\u88AB\u624B\u52A8\u79FB\u51FA\u7FA4\uFF0C\u91CD\u8DD1\u672C\u547D\u4EE4\u4E0D\u4F1A\u91CD\u65B0\u6DFB\u52A0\uFF1B\u4EE5\u7FA4\u8BBE\u7F6E\u9875\u6216\u7FA4\u91CC @ \u5B9E\u6D4B\u4E3A\u51C6\u3002"))}}c(rn,"printGroupOutcomes");function ln(r,t,e={}){let n=e.exit??(i=>process.exit(i)),o=r.command("bot").description("\u9489\u9489\u673A\u5668\u4EBA provisioning\uFF08\u5EFA\u53F7 / \u51ED\u636E\u7ED1\u5B9A / \u53D1\u5E03\u5BA1\u6279 / \u62C9\u7FA4\uFF09");o.command("provision").description("\u786E\u5B9A\u6027\u5EFA\u53F7\u5E76\u7ED1\u5B9A\u51ED\u636E\uFF08\u5E42\u7B49\u3001\u53EF\u65AD\u70B9\u7EED\u8DD1\uFF1B--publish/--group \u8D70\u4EBA\u5BA1\u4E0E\u62C9\u7FA4\u76F8\uFF09").requiredOption("--name <name>","\u5E94\u7528\u540D\uFF08\u4F01\u4E1A\u5185\u552F\u4E00\uFF0C2-20 \u5B57\uFF09").option("--robot-name <robotName>","\u673A\u5668\u4EBA\u663E\u793A\u540D\uFF08\u7F3A\u7701\u540C --name\uFF09").option("--desc <desc>","\u5E94\u7528\u63CF\u8FF0\uFF08\u2264200 \u5B57\uFF09").option("--group <group>","\u62C9\u7FA4\u76EE\u6807\uFF1AopenConversationId \u6216\u7FA4\u540D\uFF0C\u9017\u53F7\u5206\u9694\u591A\u7FA4\uFF08\u9700\u5DF2\u5B8C\u6210 publish \u76F8\uFF1B\u5DF2\u5728\u7FA4\u53F0\u8D26\u7684\u7FA4\u96F6\u8C03\u7528\u8DF3\u8FC7\uFF09").option("--publish","\u8FDB\u5165\u53D1\u5E03\u76F8\uFF08\u771F\u5B9E\u6253\u6270\u7BA1\u7406\u5458\u5BA1\u6279\uFF0C\u9700\u914D\u5408 --approver-user-id \u786E\u8BA4\uFF09").option("--approver-user-id <userId>","\u5BA1\u6279\u4EBA userId\uFF08\u5019\u9009\u7531 check-approval \u5217\u51FA\uFF1B\u4EBA\u5BA1\u95E8\u4E0D\u5F97\u9759\u9ED8\u4EE3\u9009\uFF09").option("--state-file <path>","\u72B6\u6001\u6587\u4EF6\u8DEF\u5F84\uFF08\u7F3A\u7701 <configDir>/.aitable/provision-state.json\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u7528\u4E8E\u5B9A\u4F4D configDir\uFF09",t.defaultConfig).option("--yes","\u4E0E dws \u8BED\u4E49\u5BF9\u9F50\uFF1A\u8DF3\u8FC7\u786E\u8BA4\uFF08provision \u5168\u7A0B\u975E\u4EA4\u4E92\uFF0C\u5199\u64CD\u4F5C\u5DF2\u5E26 --yes\uFF09").action(async i=>{try{let s=await ei(i,t,e);s!==0&&n(s)}catch(s){Me(s),n(1)}}),o.command("status").description("\u67E5\u770B provision \u76F8\u4F4D / \u53D1\u5E03\u5BA1\u6279\u72B6\u6001 / \u5BA1\u6279\u4EBA\u5019\u9009\u4E0E\u50AC\u529E\u547D\u4EE4\u6A21\u677F").option("--state-file <path>","\u72B6\u6001\u6587\u4EF6\u8DEF\u5F84\uFF08\u7F3A\u7701 <configDir>/.aitable/provision-state.json\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u7528\u4E8E\u5B9A\u4F4D configDir\uFF09",t.defaultConfig).option("--refresh","\u5B9E\u65F6\u67E5\u8BE2 dws\uFF08version status + check-approval\uFF09\uFF0C\u800C\u975E\u53EA\u8BFB\u72B6\u6001\u6587\u4EF6").action(async i=>{try{let s=await ni(i,t,e);s!==0&&n(s)}catch(s){Me(s),n(1)}});for(let[i,s]of[["disable","\u505C\u7528"],["enable","\u542F\u7528"]])o.command(i).description(`${s}\u673A\u5668\u4EBA\u80FD\u529B\u6216\u6574\u4E2A\u5E94\u7528\uFF08\u53EF\u9006\uFF1B--scope app \u4F5C\u7528\u4E8E\u6574\u4E2A\u5E94\u7528\uFF09`).option("--scope <scope>","\u4F5C\u7528\u8303\u56F4\uFF1Arobot\uFF08\u9ED8\u8BA4\uFF0C\u4EC5\u673A\u5668\u4EBA\u80FD\u529B\uFF09| app\uFF08\u6574\u4E2A\u5E94\u7528\uFF09","robot").option("--unified-app-id <id>","\u76EE\u6807\u5E94\u7528 unifiedAppId\uFF08\u7F3A\u7701\u4ECE\u72B6\u6001\u6587\u4EF6\u8BFB\uFF09").option("--state-file <path>","\u72B6\u6001\u6587\u4EF6\u8DEF\u5F84\uFF08\u7F3A\u7701 <configDir>/.aitable/provision-state.json\uFF09").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08\u7528\u4E8E\u5B9A\u4F4D configDir\uFF09",t.defaultConfig).action(async a=>{try{let l=await oi(i,a,t,e);l!==0&&n(l)}catch(l){Me(l),n(1)}})}c(ln,"registerBotCommands");async function ei(r,t,e){let n=Zr(r.name);if(n)return console.error(`\u274C ${n}`),1;let o=Fe.dirname(await We(r.config??t.defaultConfig)),i=r.stateFile??Ue(o);r.publish&&!r.approverUserId&&console.log("\u2139 --publish \u672A\u6307\u5B9A --approver-user-id\uFF1A\u82E5\u7EC4\u7EC7\u5BA1\u6279\u7B56\u7565\u9700\u9009\u4EBA\uFF0C\u5C06\u5217\u51FA\u5019\u9009\u540E\u505C\u4E0B\uFF0C\u7531\u4F60\u663E\u5F0F\u786E\u8BA4\u3002");let s=e.createProvisioner?.()??new zr({runner:new Be}),a={name:r.name,robotName:r.robotName,desc:r.desc,stateFile:i,publish:r.publish,approverUserId:r.approverUserId,group:r.group};console.log(`\u{1F916} \u5F00\u59CB provision\u300C${r.name}\u300D\uFF08\u72B6\u6001\u6587\u4EF6: ${i}\uFF09`);let l=await s.provision(a);return ti(l,{stateFile:i})}c(ei,"runProvision");function ti(r,t){switch(r.status){case"bound":{console.log(`
89
89
  \u2705 \u51ED\u636E\u5DF2\u7ED1\u5B9A\uFF08bound \u76F8\uFF09\u3002`),console.log(` appKey=${r.state.clientId??"?"}`),console.log(` AppSecret \u4E0D\u56DE\u663E\uFF0C\u590D\u53D6: dws dev app credentials get --unified-app-id ${r.state.unifiedAppId??"<unifiedAppId>"}`),console.log(" \u51ED\u636E\u843D\u70B9\u662F AI \u8868\u683C\u7FA4\u914D\u7F6E\u8868\u7684 appKey / appSecret \u5217\uFF0C\u7531 config-sync \u53D1\u5E03\u7ED9\u5F15\u64CE\u3002"),console.log(" \u72B6\u6001\u6587\u4EF6:",t.stateFile),console.log("\n\u26A0\uFE0F Stream \u5355\u6D3E\u53D1\u4E92\u65A5\uFF1A\u52FF\u5BF9\u540C\u4E00\u673A\u5668\u4EBA\u540C\u65F6\u8FD0\u884C `dws dev connect`\uFF0C\u5426\u5219\u6D88\u606F\u53EA\u6D3E\u53D1\u5176\u4E00\u3002"),console.log("\u{1F4A1} \u771F\u5B9E\u7528\u6237\u6D41\u91CF\uFF08\u7FA4\u91CC @bot / \u5355\u804A\u53D1\u73B0\uFF09\u9700\u516C\u5F00\u53D1\u5E03\uFF1A`aitable-workflow bot provision --name <\u540C\u540D> --publish`");break}case"publish_pending":{console.log(`
90
90
  \u23F3 \u53D1\u5E03\u5DF2\u63D0\u4EA4\uFF0C\u7B49\u5F85\u7BA1\u7406\u5458\u5BA1\u6279\uFF08publish_pending \u76F8\uFF09\u3002`),console.log(" \u67E5\u770B\u8FDB\u5EA6\u4E0E\u50AC\u529E: aitable-workflow bot status --refresh");break}case"published":{console.log(`
91
- \u2705 \u5DF2\u53D1\u5E03\uFF08published \u76F8\uFF09\u2014\u2014\u771F\u5B9E\u7528\u6237\u6D41\u91CF\u53EF\u7528\u3002`),console.log("\u{1F4A1} \u62C9\u7FA4: `aitable-workflow bot provision --name <\u540C\u540D> --group <openConversationId|\u7FA4\u540D>`\uFF08\u591A\u7FA4\u9017\u53F7\u5206\u9694\uFF09");break}case"grouped":{if(r.groups.length===0){let e=Object.keys(Xr(r.state)).length;console.log(`
91
+ \u2705 \u5DF2\u53D1\u5E03\uFF08published \u76F8\uFF09\u2014\u2014\u771F\u5B9E\u7528\u6237\u6D41\u91CF\u53EF\u7528\u3002`),console.log("\u{1F4A1} \u62C9\u7FA4: `aitable-workflow bot provision --name <\u540C\u540D> --group <openConversationId|\u7FA4\u540D>`\uFF08\u591A\u7FA4\u9017\u53F7\u5206\u9694\uFF09");break}case"grouped":{if(r.groups.length===0){let e=Object.keys(Qr(r.state)).length;console.log(`
92
92
  \u2705 grouped \u76F8\uFF1A\u7FA4\u53F0\u8D26\u5DF2\u6709 ${e} \u4E2A\u7FA4\u3002\u672C\u6B21\u672A\u4F20 --group\uFF0C\u672A\u53D1\u8D77\u4EFB\u4F55\u62C9\u7FA4\u8C03\u7528\u3002`);break}rn(r.groups),console.log("\u{1F4A1} add-bot \u7684 success \u53EA\u662F\u53D7\u7406\u4FE1\u53F7\uFF08dws \u65E0\u5728\u7FA4\u5217\u8868\u67E5\u8BE2\u63A5\u53E3\uFF09\uFF1A\u8BF7\u5230\u7FA4\u8BBE\u7F6E\u6838\u5BF9\u673A\u5668\u4EBA\u5728\u7FA4\u3002");break}case"approver_required":{console.error(`
93
93
  \u26D4 \u516C\u5F00\u53D1\u5E03\u9700\u771F\u4EBA\u5BA1\u6279\uFF0C\u4E14\u672C\u7EC4\u7EC7\u7B56\u7565\u8981\u6C42\u663E\u5F0F\u9009\u5BA1\u6279\u4EBA\uFF08\u4EBA\u5BA1\u95E8\u4E0D\u5F97\u9759\u9ED8\u4EE3\u9009\uFF09\u3002`),console.error(" \u5BA1\u6279\u4EBA\u5019\u9009\uFF08\u6765\u81EA check-approval\uFF09:");for(let e of r.candidates)console.error(` - ${e.name??"(\u672A\u77E5)"} userId=${e.userId}${e.mainAdmin?"\uFF08\u4E3B\u7BA1\u7406\u5458\uFF09":""}`);return console.error(" \u786E\u8BA4\u540E\u91CD\u8DD1: aitable-workflow bot provision --name <\u540C\u540D> --publish --approver-user-id <userId>"),2}case"failed":return r.groups&&r.groups.length>0&&rn(r.groups),console.error(`
94
- \u274C provision \u5931\u8D25: ${r.message}`),console.error(" \uFF08\u72B6\u6001\u6587\u4EF6\u5DF2\u4FDD\u7559\u8FDB\u5EA6\uFF0C\u4FEE\u590D\u540E\u53EF\u65AD\u70B9\u7EED\u8DD1: \u91CD\u8DD1\u540C\u4E00\u547D\u4EE4\uFF09"),1}return 0}c(ei,"printProvisionResult");async function ti(r,t,e){let n=Fe.dirname(await We(r.config??t.defaultConfig)),o=r.stateFile??Ue(n),i=await cn(o),s,a=null,l=null;if(r.refresh&&i?.unifiedAppId&&i.versionId){let m=e.createRunner?.()??new Be;try{s=(await m.versionStatus(i.unifiedAppId,i.versionId)).versionStatus}catch(g){l=sn(g)}if(!l)try{a=await m.checkApproval(i.unifiedAppId,i.versionId)}catch(g){l=sn(g)}}let p=zr({state:i,versionStatus:s,approval:a,error:l});return console.log(p.map(m=>` ${m}`).join(`
94
+ \u274C provision \u5931\u8D25: ${r.message}`),console.error(" \uFF08\u72B6\u6001\u6587\u4EF6\u5DF2\u4FDD\u7559\u8FDB\u5EA6\uFF0C\u4FEE\u590D\u540E\u53EF\u65AD\u70B9\u7EED\u8DD1: \u91CD\u8DD1\u540C\u4E00\u547D\u4EE4\uFF09"),1}return 0}c(ti,"printProvisionResult");async function ni(r,t,e){let n=Fe.dirname(await We(r.config??t.defaultConfig)),o=r.stateFile??Ue(n),i=await cn(o),s,a=null,l=null;if(r.refresh&&i?.unifiedAppId&&i.versionId){let m=e.createRunner?.()??new Be;try{s=(await m.versionStatus(i.unifiedAppId,i.versionId)).versionStatus}catch(g){l=sn(g)}if(!l)try{a=await m.checkApproval(i.unifiedAppId,i.versionId)}catch(g){l=sn(g)}}let p=Xr({state:i,versionStatus:s,approval:a,error:l});return console.log(p.map(m=>` ${m}`).join(`
95
95
  `)),console.log(`
96
- \u72B6\u6001\u6587\u4EF6: ${o}`),i&&!r.refresh&&(i.phase==="publish_pending"||i.phase==="version_created")&&console.log(" \u63D0\u793A: \u52A0 --refresh \u5B9E\u65F6\u67E5\u8BE2\u5BA1\u6279\u72B6\u6001\u4E0E\u5019\u9009\u3002"),i?0:1}c(ti,"runStatus");function sn(r){return r instanceof an?`${r.message}\uFF08${r.guidance}\uFF09`:r instanceof Error?r.message:String(r)}c(sn,"describeError");async function ni(r,t,e,n){let o=t.scope??"robot";if(o!=="robot"&&o!=="app")return console.error(`\u274C --scope \u53EA\u652F\u6301 robot | app\uFF0C\u6536\u5230: ${o}`),1;let i=t.unifiedAppId?.trim();if(!i){let m=Fe.dirname(await We(t.config??e.defaultConfig)),g=t.stateFile??Ue(m);if(i=(await cn(g))?.unifiedAppId??void 0,!i)return console.error(`\u274C \u65E0\u6CD5\u786E\u5B9A\u76EE\u6807\u5E94\u7528\uFF1A\u72B6\u6001\u6587\u4EF6\u65E0 unifiedAppId\uFF08${g}\uFF09\uFF0C\u8BF7\u7528 --unified-app-id \u663E\u5F0F\u6307\u5B9A\u3002`),1}let s=r==="disable"?"\u505C\u7528":"\u542F\u7528",a=n.createRunner?.()??new Be,l=o==="app"?"\u6574\u4E2A\u5E94\u7528":"\u673A\u5668\u4EBA\u80FD\u529B";return console.log(`\u{1F916} ${s}${l}\uFF08unifiedAppId=${i}\uFF09`),o==="app"&&r==="disable"&&console.log("\u2139 --scope app \u4F1A\u505C\u7528\u6574\u4E2A\u5E94\u7528\uFF08\u673A\u5668\u4EBA/\u7F51\u9875\u5E94\u7528\u7B49\u5168\u90E8\u4E0D\u53EF\u7528\uFF09\uFF1B\u53EA\u60F3\u505C\u673A\u5668\u4EBA\u7528\u9ED8\u8BA4 --scope robot\u3002"),await{disable:{robot:a.disableRobot.bind(a),app:a.disableApp.bind(a)},enable:{robot:a.enableRobot.bind(a),app:a.enableApp.bind(a)}}[r][o](i),console.log(`
97
- \u2705 \u5DF2${s}${l}\u3002`),r==="disable"&&(console.log(` \u6062\u590D: ${o==="app"?"aitable-workflow bot enable --scope app":"aitable-workflow bot enable"}\uFF08\u542F\u505C\u53EF\u9006\uFF1B.env \u51ED\u636E\u4E0E\u72B6\u6001\u6587\u4EF6\u4E0D\u53D7\u5F71\u54CD\uFF09`),console.log(" \u26A0\uFE0F \u505C\u7528\u540E Stream \u5EFA\u8054/\u6D88\u606F\u6536\u53D1\u4F1A\u5931\u8D25\uFF1B\u8FD0\u884C\u4E2D\u7684\u5F15\u64CE\u4F1A\u6301\u7EED\u62A5\u9519\u76F4\u5230\u6062\u590D\u3002")),0}c(ni,"runToggle");function Me(r){if(r instanceof an)on.error("cli","bot \u547D\u4EE4\u5931\u8D25",{kind:r.kind}),console.error(`
96
+ \u72B6\u6001\u6587\u4EF6: ${o}`),i&&!r.refresh&&(i.phase==="publish_pending"||i.phase==="version_created")&&console.log(" \u63D0\u793A: \u52A0 --refresh \u5B9E\u65F6\u67E5\u8BE2\u5BA1\u6279\u72B6\u6001\u4E0E\u5019\u9009\u3002"),i?0:1}c(ni,"runStatus");function sn(r){return r instanceof an?`${r.message}\uFF08${r.guidance}\uFF09`:r instanceof Error?r.message:String(r)}c(sn,"describeError");async function oi(r,t,e,n){let o=t.scope??"robot";if(o!=="robot"&&o!=="app")return console.error(`\u274C --scope \u53EA\u652F\u6301 robot | app\uFF0C\u6536\u5230: ${o}`),1;let i=t.unifiedAppId?.trim();if(!i){let m=Fe.dirname(await We(t.config??e.defaultConfig)),g=t.stateFile??Ue(m);if(i=(await cn(g))?.unifiedAppId??void 0,!i)return console.error(`\u274C \u65E0\u6CD5\u786E\u5B9A\u76EE\u6807\u5E94\u7528\uFF1A\u72B6\u6001\u6587\u4EF6\u65E0 unifiedAppId\uFF08${g}\uFF09\uFF0C\u8BF7\u7528 --unified-app-id \u663E\u5F0F\u6307\u5B9A\u3002`),1}let s=r==="disable"?"\u505C\u7528":"\u542F\u7528",a=n.createRunner?.()??new Be,l=o==="app"?"\u6574\u4E2A\u5E94\u7528":"\u673A\u5668\u4EBA\u80FD\u529B";return console.log(`\u{1F916} ${s}${l}\uFF08unifiedAppId=${i}\uFF09`),o==="app"&&r==="disable"&&console.log("\u2139 --scope app \u4F1A\u505C\u7528\u6574\u4E2A\u5E94\u7528\uFF08\u673A\u5668\u4EBA/\u7F51\u9875\u5E94\u7528\u7B49\u5168\u90E8\u4E0D\u53EF\u7528\uFF09\uFF1B\u53EA\u60F3\u505C\u673A\u5668\u4EBA\u7528\u9ED8\u8BA4 --scope robot\u3002"),await{disable:{robot:a.disableRobot.bind(a),app:a.disableApp.bind(a)},enable:{robot:a.enableRobot.bind(a),app:a.enableApp.bind(a)}}[r][o](i),console.log(`
97
+ \u2705 \u5DF2${s}${l}\u3002`),r==="disable"&&(console.log(` \u6062\u590D: ${o==="app"?"aitable-workflow bot enable --scope app":"aitable-workflow bot enable"}\uFF08\u542F\u505C\u53EF\u9006\uFF1B.env \u51ED\u636E\u4E0E\u72B6\u6001\u6587\u4EF6\u4E0D\u53D7\u5F71\u54CD\uFF09`),console.log(" \u26A0\uFE0F \u505C\u7528\u540E Stream \u5EFA\u8054/\u6D88\u606F\u6536\u53D1\u4F1A\u5931\u8D25\uFF1B\u8FD0\u884C\u4E2D\u7684\u5F15\u64CE\u4F1A\u6301\u7EED\u62A5\u9519\u76F4\u5230\u6062\u590D\u3002")),0}c(oi,"runToggle");function Me(r){if(r instanceof an)on.error("cli","bot \u547D\u4EE4\u5931\u8D25",{kind:r.kind}),console.error(`
98
98
  \u274C ${r.message}`),console.error(` \u21B3 ${r.guidance}`);else{let t=r instanceof Error?r.message:String(r);on.error("cli","bot \u547D\u4EE4\u5931\u8D25",{error:t}),console.error(`
99
- \u274C ${t}`)}}c(Me,"failWithDiagnostics");var gn=dn.dirname(si(import.meta.url));mn({override:!1,quiet:!0});mn({path:dn.resolve(gn,"..",".env"),override:!1,quiet:!0});var un=Je(),Ne=be(un),ai=ze(un);ii({version:Ne});var f=new oi().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(Ne).enablePositionalOptions().option("-d, --debug","\u8F93\u51FA debug \u7EA7\u522B\u65E5\u5FD7\uFF08\u542B recipe \u5185\u90E8 log\uFF09\uFF1B\u9700\u5199\u5728\u547D\u4EE4\u540D\u4E4B\u524D").hook("preAction",(r,t)=>{r.opts().debug?pn.setLevel("debug"):(t.name()==="config"||t.parent?.name()==="config")&&pn.setLevel("warn")}).hook("preAction",async(r,t)=>{t.name()!=="init"&&await ri()}),h={cliDir:gn,version:Ne,packageVersions:ai,defaultConfig:Xe};Qe(f,h);Ze(f,h);et(f,h);ot(f,h);st(f,h);ct(f,h);mt(f,h);ht(f,h);He(f,h);wt(f,h);yt(f,h);kt(f,h);bt(f,h);Vt(f,h);Jt(f,h);Qt(f,h);Yt(f,h);Zt(f,h);tn(f,h);nn(f,h);ln(f,h);await f.parseAsync();
99
+ \u274C ${t}`)}}c(Me,"failWithDiagnostics");var gn=dn.dirname(ai(import.meta.url));mn({override:!1,quiet:!0});mn({path:dn.resolve(gn,"..",".env"),override:!1,quiet:!0});var un=Je(),Ne=be(un),ci=ze(un);si({version:Ne});var f=new ri().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(Ne).enablePositionalOptions().option("-d, --debug","\u8F93\u51FA debug \u7EA7\u522B\u65E5\u5FD7\uFF08\u542B recipe \u5185\u90E8 log\uFF09\uFF1B\u9700\u5199\u5728\u547D\u4EE4\u540D\u4E4B\u524D").hook("preAction",(r,t)=>{r.opts().debug?pn.setLevel("debug"):(t.name()==="config"||t.parent?.name()==="config")&&pn.setLevel("warn")}).hook("preAction",async(r,t)=>{t.name()!=="init"&&await ii()}),h={cliDir:gn,version:Ne,packageVersions:ci,defaultConfig:Xe};Qe(f,h);Ze(f,h);et(f,h);ot(f,h);st(f,h);ct(f,h);mt(f,h);ht(f,h);He(f,h);wt(f,h);yt(f,h);kt(f,h);bt(f,h);Vt(f,h);Jt(f,h);Qt(f,h);Yt(f,h);Zt(f,h);tn(f,h);nn(f,h);ln(f,h);await f.parseAsync();