aitable-workflow-cli 0.1.28 → 0.1.29-beta.1790736949347
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/assistant/assets/index-BA6il19d.css +1 -0
- package/dist/assistant/assets/{index-B3LvYfRW.js → index-BMzAOp70.js} +31 -31
- package/dist/assistant/index.html +2 -2
- package/dist/chunk-BBP5RVFU.js +15 -0
- package/dist/cli.js +180 -73
- package/dist/{config-ui-server-4SVD42Z3.js → config-ui-server-UWELHUH4.js} +1 -1
- package/dist/web/assets/index-Bnmnydwk.css +1 -0
- package/dist/web/assets/index-Dbs1xWB9.js +331 -0
- package/dist/web/index.html +2 -2
- package/dist/web/install.ps1 +173 -0
- package/dist/web/install.sh +188 -0
- package/package.json +3 -3
- package/templates/ai-native-sdlc/.env.example +11 -0
- package/templates/ai-native-sdlc/aitable-workflow.config.yml +47 -0
- package/templates/ai-native-sdlc/coding-agents.config.json +17 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-15-ai-native-sdlc-dual-staff-implementation-plan.md +150 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-15-ai-native-sdlc-dual-staff.md +213 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-16-domain-role-notification-routing.md +36 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-16-execution-resume-and-cr-loop.md +29 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-16-project-handoff.md +148 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-17-prd-code-context-and-readable-prompts.md +37 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-21-plan-merge-sync-and-agent-source.md +19 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-21-sdlc-base-ref-and-review-notification.md +18 -0
- package/templates/ai-native-sdlc/docs/plans/2026-09-29-borrow-from-joe-design.md +943 -0
- package/templates/ai-native-sdlc/lib/artifacts.ts +126 -0
- package/templates/ai-native-sdlc/lib/recipe-config.ts +34 -0
- package/templates/ai-native-sdlc/lib/recipe-helpers.ts +595 -0
- package/templates/ai-native-sdlc/npmrc +1 -0
- package/templates/ai-native-sdlc/package.json +19 -0
- package/templates/ai-native-sdlc/profile/profile.yml +115 -0
- package/templates/ai-native-sdlc/setup/module-config.seed.json +37 -0
- package/templates/ai-native-sdlc/test/artifacts.test.ts +72 -0
- package/templates/ai-native-sdlc/test/recipe-helpers.test.ts +931 -0
- package/templates/ai-native-sdlc/tsconfig.json +17 -0
- package/templates/ai-native-sdlc/workflows/.gitkeep +3 -0
- package/templates/ai-native-sdlc/workflows/execution/automations/blocked-questions-dev.json +91 -0
- package/templates/ai-native-sdlc/workflows/execution/automations/blocked-questions.json +91 -0
- package/templates/ai-native-sdlc/workflows/execution/automations/cr-review-dev.json +80 -0
- package/templates/ai-native-sdlc/workflows/execution/automations/cr-review.json +81 -0
- package/templates/ai-native-sdlc/workflows/execution/automations/resume-answers.json +42 -0
- package/templates/ai-native-sdlc/workflows/execution/automations/spec-review-dev.json +138 -0
- package/templates/ai-native-sdlc/workflows/execution/recipes/coding.recipe.ts +161 -0
- package/templates/ai-native-sdlc/workflows/execution/recipes/prd-review.recipe.ts +200 -0
- package/templates/ai-native-sdlc/workflows/execution/recipes/prd.recipe.ts +163 -0
- package/templates/ai-native-sdlc/workflows/execution/recipes/review.recipe.ts +257 -0
- package/templates/ai-native-sdlc/workflows/execution/recipes/spec-review.recipe.ts +242 -0
- package/templates/ai-native-sdlc/workflows/execution/recipes/spec.recipe.ts +173 -0
- package/templates/ai-native-sdlc/workflows/execution/workflow.yml +79 -0
- package/templates/ai-native-sdlc/workflows/intake/automations/accept-intake.json +101 -0
- package/templates/ai-native-sdlc/workflows/intake/recipes/classify-module.recipe.ts +133 -0
- package/templates/ai-native-sdlc/workflows/intake/recipes/create-change.recipe.ts +94 -0
- package/templates/ai-native-sdlc/workflows/intake/recipes/mechanical-deduplicate.recipe.ts +33 -0
- package/templates/ai-native-sdlc/workflows/intake/workflow.yml +62 -0
- package/templates/ai-native-sdlc/workspaces/dev/AGENTS.md +69 -0
- package/templates/ai-native-sdlc/workspaces/pm/AGENTS.md +48 -0
- package/templates/ai-native-sdlc/workspaces/reviewer/AGENTS.md +79 -0
- package/dist/assistant/assets/index-CCEHOkkJ.css +0 -1
- package/dist/chunk-YDJTCQW4.js +0 -15
- package/dist/web/assets/index-DPc2WOdp.css +0 -1
- package/dist/web/assets/index-HTw8K38o.js +0 -332
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Workbench · 对话 UI</title>
|
|
7
|
-
<script type="module" crossorigin src="/assistant/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assistant/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assistant/assets/index-BMzAOp70.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assistant/assets/index-BA6il19d.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import{o as fe,q as me}from"./chunk-4B6V7VHM.js";import{a}from"./chunk-EI7MMDWY.js";import{createServer as no}from"http";import{stat as et,readFile as ae,mkdir as ce,writeFile as Re,rm as so}from"fs/promises";import{createReadStream as io,existsSync as tt,unlinkSync as ao}from"fs";import I from"path";import{fileURLToPath as co}from"url";import lt from"crypto";import lo from"os";import Te from"yaml";import{runCheck as Z,resolveConfigPath as ut,loadSettings as uo,detectCodingEngines as po,loadWorkflowTemplate as go,collectEnvRefs as fo,applyConfigSave as mo,ConfigSaveError as wo,runSetupCommand as ho,resolveInsideRoot as Ce,assertPortableId as ot}from"aitable-workflow-core";import{mkdir as xt,readFile as V,writeFile as Ot}from"fs/promises";import $ from"path";import J from"yaml";import{BotProvisioner as At,BotProvisionError as Ae,DwsClient as Se,DwsDevRunner as _e,fetchFields as ve,loadSettings as Ne,loadWorkflowTemplate as _t,listDwsConversations as Nt,readState as Gt,resetProfileCache as Ge,runDwsCommand as Bt,runCommand as Ut,setupKnowledgeBases as $t,writeBack as be,assertPortableId as jt}from"aitable-workflow-core";import ne from"path";import{closeSync as ht,existsSync as Pe,openSync as yt,readFileSync as bt}from"fs";import{createExecShellToolkit as kt,createStandaloneExecShellToolkit as St,loadSettings as vt,logger as It,resolveConfigPath as Rt,spawnManagedProcess as Tt}from"aitable-workflow-core";function Ct(e){let r=bt(ne.resolve(e),"utf8").replace(/^\uFEFF/,""),t;try{t=JSON.parse(r)}catch(o){throw new Error(`--argv-file \u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${e}\uFF08${o instanceof Error?o.message:String(o)}\uFF09`)}if(!Array.isArray(t)||t.length===0||t.some(o=>typeof o!="string"||o.length===0))throw new Error(`--argv-file \u5FC5\u987B\u662F\u975E\u7A7A JSON \u5B57\u7B26\u4E32\u6570\u7EC4\uFF1A${e}`);return t}a(Ct,"readExecArgvFile");function Et(e){if(!e||typeof e!="object")return;let r=e;if(r.success!==!0){if(r.success===!1)return String(r.errorMsg??r.error??r.message??r.errorCode??"\u4E0B\u6E38\u547D\u4EE4\u62A5\u544A\u5931\u8D25");for(let t of["error","errorMsg"]){let o=r[t];if(typeof o=="string"&&o.trim())return o.trim();if(o&&typeof o=="object")return JSON.stringify(o)}if(r.errorCode!==void 0&&r.success!==!0)return String(r.errorCode)}}a(Et,"jsonPayloadError");async function Pt(e,r,t={}){let o=await Rt(e);if(t.standalone||!Pe(o))return{shell:St(r,{configDir:ne.dirname(o)}),mode:"standalone",bins:{},configPath:o};let n=await vt(e),s=n.raw?.toolkit_config?.shell??{};return{shell:kt(n,r),mode:"project",bins:s.bins??{},configPath:o}}a(Pt,"createToolkitForExec");async function we(e,r,t){let o=ne.resolve(t.logFile),n=ne.dirname(o);if(!Pe(n))throw new Error(`\u65E5\u5FD7\u6587\u4EF6\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${n}`);let s=t.bins?.[e]??e,i=yt(o,"w"),c;try{return c=Tt({command:s,args:r,stdio:["ignore",i,i]}),await new Promise((p,g)=>{let d=c.child,h=a(k=>g(k),"onError");d.once("error",h),d.once("spawn",()=>{d.removeListener("error",h),p()})}),c.unref(),{pid:c.child.pid,logFile:o}}finally{ht(i)}}a(we,"runDetached");function $o(e,r){e.command("exec").description("\u9003\u751F\u8231\uFF1A\u8BD5\u8DD1\u4E00\u6761\u547D\u4EE4\uFF08\u590D\u7528 shell toolkit \u7684 bins \u89E3\u6790/\u8D85\u65F6/\u8131\u654F\uFF09\uFF0C\u7528\u4E8E dws/git \u547D\u4EE4\u9762 smoke\u3002\u590D\u6742\u53C2\u6570\u53EF\u653E\u5165 UTF-8 JSON \u5B57\u7B26\u4E32\u6570\u7EC4\u6587\u4EF6\u3002\u7528\u6CD5\uFF1Aaitable-workflow exec [-c <path>] [--standalone] [--json | --detach <file>] [--argv-file <file>] -- <bin> <args...>").option("-c, --config <path>","\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84",r.defaultConfig).option("--standalone","\u663E\u5F0F\u65E0\u9879\u76EE\u6A21\u5F0F\uFF1A\u4E0D\u8BFB\u53D6\u9879\u76EE\u914D\u7F6E\uFF0C\u9002\u5408 bootstrap / design \u4EA7\u7269\u751F\u6210\u524D\u63A2\u6D4B dws").option("--timeout <ms>","\u5355\u6B21\u6267\u884C\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09").option("--json","\u4EE5 run \u65B9\u5F0F\u6267\u884C\u5E76\u89E3\u6790 stdout JSON\uFF1A\u4E0D\u56E0\u975E\u96F6\u9000\u51FA\u91CD\u8BD5\uFF0Cpayload \u7EA7\u9519\u8BEF\uFF08success/errorMsg\uFF09\u5355\u72EC\u68C0\u6D4B").option("--argv-file <file>","\u4ECE UTF-8 JSON \u5B57\u7B26\u4E32\u6570\u7EC4\u8BFB\u53D6\u5B8C\u6574\u547D\u4EE4\uFF08\u7B2C\u4E00\u9879 bin\uFF0C\u5176\u4F59\u4E3A\u53C2\u6570\uFF1B\u652F\u6301 BOM\uFF09").option("--detach <file>","\u540E\u53F0\u5206\u79BB\u8FD0\u884C\uFF1A\u547D\u4EE4\u8F93\u51FA\u5B9E\u65F6\u5199\u5165\u8BE5\u6587\u4EF6\u5E76\u7ACB\u5373\u8FD4\u56DE\uFF08\u65E0\u8D85\u65F6/\u91CD\u8BD5\uFF09\u3002\u9002\u5408 dws auth login --device \u7B49\u9700\u5728\u8FD0\u884C\u4E2D\u8BFB\u53D6\u8F93\u51FA\u7684\u6D41\u7A0B").allowUnknownOption().argument("[command...]","\u8981\u6267\u884C\u7684\u547D\u4EE4\u53CA\u53C2\u6570\uFF08\u5EFA\u8BAE\u7528 -- \u5206\u9694\uFF09\uFF0C\u5982\uFF1Adws chat group create --name x --format json").action(async(t,o)=>{try{let n=o.argvFile?Ct(o.argvFile):t;if(o.argvFile&&t.length>0)throw new Error("--argv-file \u4E0D\u80FD\u4E0E\u547D\u4EE4\u884C\u547D\u4EE4\u540C\u65F6\u4F7F\u7528");let[s,...i]=n;s||(console.error("\u2717 \u672A\u63D0\u4F9B\u8981\u6267\u884C\u7684\u547D\u4EE4\uFF1B\u7528\u6CD5\uFF1Aaitable-workflow exec [-c <path>] -- <bin> <args...>"),process.exit(1));let c=o.timeout?Number.parseInt(o.timeout,10):void 0;c!==void 0&&(Number.isNaN(c)||c<=0)&&(console.error("\u2717 --timeout \u5FC5\u987B\u662F\u6B63\u6574\u6570\uFF08\u6BEB\u79D2\uFF09"),process.exit(1)),o.detach&&(o.json||c!==void 0)&&(console.error("\u2717 --detach \u4E0E --json / --timeout \u4E92\u65A5\uFF08\u5206\u79BB\u8FD0\u884C\u65E0\u8D85\u65F6\u4E0E JSON \u8BED\u4E49\uFF09"),process.exit(1)),o.json&&It.setLevel("warn");let p=await Pt(o.config,s,{standalone:o.standalone===!0});if(o.detach){let{pid:d,logFile:h}=await we(s,i,{bins:p.bins,logFile:o.detach});console.log(`\u2713 \u5DF2\u540E\u53F0\u542F\u52A8\uFF08pid ${d}\uFF09\uFF0C\u8F93\u51FA\u5B9E\u65F6\u5199\u5165\uFF1A${h}`),console.error("\u63D0\u793A\uFF1A\u5206\u79BB\u8FD0\u884C\u65E0\u8D85\u65F6\u4E0E\u91CD\u8BD5\u63A7\u5236\uFF0C\u7ED3\u679C\u4EE5\u65E5\u5FD7\u6587\u4EF6\u5185\u5BB9\u4E0E\u5B9E\u9645\u6548\u679C\u4E3A\u51C6\u3002");return}if(o.json){let d=await p.shell.run(s,i,{timeoutMs:c}),h=d.stdout.trim(),k={};if(h!=="")try{k=JSON.parse(h)}catch{console.error("\u2717 exec --json \u5931\u8D25: \u547D\u4EE4\u672A\u8FD4\u56DE\u5408\u6CD5 JSON"),d.stderr&&process.stderr.write(d.stderr),process.exit(1)}let P=Et(k);if(d.exitCode!==0||P){d.stderr&&process.stderr.write(d.stderr);let G=P?`\uFF1A${P}`:`\uFF08\u9000\u51FA\u7801 ${d.exitCode}\uFF09`;console.error(`\u2717 exec --json \u5931\u8D25${G}`),process.exit(1)}console.log(JSON.stringify(k,null,2));return}let g=await p.shell.run(s,i,{timeoutMs:c});g.stdout&&process.stdout.write(g.stdout),g.stderr&&process.stderr.write(g.stderr),g.truncated&&console.error(`
|
|
2
|
+
\u26A0\uFE0F \u8F93\u51FA\u56E0\u8D85\u8FC7\u4E0A\u9650\u88AB\u622A\u65AD`),process.exit(g.exitCode??0)}catch(n){console.error(`\u2717 exec \u5931\u8D25: ${n instanceof Error?n.message:String(n)}`),process.exit(1)}})}a($o,"registerExecCommand");async function Be(e={}){let r=e.list??Nt;try{let{conversations:t}=await r({role:"admin"});return{ok:!0,groups:t}}catch(t){return{ok:!1,message:t instanceof Error?t.message:String(t)}}}a(Be,"listAdminGroups");async function Q(e,r){let t={};try{let c=await Ne(e,{lenientEnv:!0});for(let p of c.workflowEntries)try{let d=(await _t(p.templatePath,{envSource:c.envSource})).tracker;if(!d)continue;t[p.id]={baseId:String(d.base_id??"").trim(),tableId:String(d.table_id??"").trim(),...d.label?{label:String(d.label)}:{}}}catch{}}catch{}let o=await Ue(r),n=Object.values(t),s=Object.values(o);return{ok:!0,ready:n.length>0?n.every(c=>c.baseId&&c.tableId)&&s.every(c=>c.baseId&&c.tableId):n.some(c=>c.baseId&&c.tableId),trackers:t,configTables:o}}a(Q,"readSetupArtifacts");async function Ue(e){let r={},t=$.resolve(e,"profile","profile.yml"),o;try{o=J.parse(await V(t,"utf8"))}catch{return r}let n=R(o)?o.workflows:void 0;if(!R(n))return r;for(let s of Object.values(n)){let i=R(s)?s.steps:void 0;if(R(i)){for(let c of Object.values(i))if(R(c))for(let[p,g]of Object.entries(c)){if(!R(g))continue;let d="baseId"in g||"base_id"in g,h="tableId"in g||"table_id"in g;!d||!h||(r[p]={baseId:String(g.baseId??g.base_id??"").trim(),tableId:String(g.tableId??g.table_id??"").trim()})}}}return r}a(Ue,"readProfileConfigTables");var L="wiki/official-aitable-faq";async function Dt(e,r){let t=$.resolve(e,"profile","profile.yml"),o;try{o=J.parse(await V(t,"utf8"))}catch{return[]}let n=R(o)?o.roles:void 0,s=R(n)?n[r]:void 0,i=R(s)?s.knowledge_scope:void 0,c=R(i)?i.kb_collections:void 0;return Array.isArray(c)?c.map(p=>typeof p=="string"?p:R(p)&&typeof p.collection=="string"?p.collection:null).filter(p=>p!==null):[]}a(Dt,"readRoleCollections");function xe(e){if(J.isScalar(e))return typeof e.value=="string"?e.value:null;if(J.isMap(e)){let r=e.get("collection",!0);return J.isScalar(r)&&typeof r.value=="string"?r.value:null}return null}a(xe,"kbEntryValue");async function Ft(e,r,t){let o=$.resolve(e,"profile","profile.yml"),n;try{n=await V(o,"utf8")}catch{return{ok:!1,code:"KB_PROFILE_MISSING",message:"profile.yml \u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u5207\u6362\u5B98\u65B9\u77E5\u8BC6\u5E93",collections:[],changed:!1}}let s=J.parseDocument(n),i=s.getIn(["roles",r,"knowledge_scope","kb_collections"],!0);if(!J.isSeq(i))return{ok:!1,code:"KB_ROLE_NOT_FOUND",message:`profile.yml \u4E2D\u672A\u627E\u5230 roles.${r}.knowledge_scope.kb_collections\uFF0C\u65E0\u6CD5\u5207\u6362`,collections:[],changed:!1};let c=i.items.map(xe).filter(d=>d!==null),p=c.includes(L),g=c.find(d=>d!==L)??null;if(t===p)return{ok:!0,message:t?"\u5B98\u65B9\u77E5\u8BC6\u5E93\u5DF2\u5904\u4E8E\u542F\u7528\u72B6\u6001":"\u5B98\u65B9\u77E5\u8BC6\u5E93\u5DF2\u5904\u4E8E\u5173\u95ED\u72B6\u6001",collections:c,changed:!1};if(!t&&!g)return{ok:!1,code:"KB_LAST_SOURCE",message:"\u5F53\u524D profile \u672A\u58F0\u660E\u7528\u6237\u5E93\uFF0C\u5173\u95ED\u5B98\u65B9\u5E93\u5C06\u5BFC\u81F4\u52A9\u624B\u65E0\u4EFB\u4F55\u77E5\u8BC6\u6765\u6E90",collections:c,changed:!1};if(t)i.add(L);else{let d=i.items.findIndex(h=>xe(h)===L);d>=0&&i.delete(d)}return await Ot(o,s.toString(),"utf8"),{ok:!0,message:t?"\u5DF2\u542F\u7528\u5B98\u65B9\u77E5\u8BC6\u5E93":"\u5DF2\u5173\u95ED\u5B98\u65B9\u77E5\u8BC6\u5E93",changed:!0,collections:t?[...c,L]:c.filter(d=>d!==L)}}a(Ft,"writeOfficialToggle");async function $e(e,r,t,o){jt(t,{label:"roleId"});let n=await Ft(r,t,o);if(!n.ok)return{...n,compile:void 0};Ge();let s=o&&n.changed?De(e):void 0;return{...n,compile:s}}a($e,"setOfficialKbEnabled");function je(e){return{ok:!0,...De(e)}}a(je,"recompileKnowledgeBases");var he=null;function De(e){return he?{started:!1}:(he=Lt(e).finally(()=>{he=null}),{started:!0})}a(De,"triggerCompile");async function Mt(e,r){let t={};for(let o of r){let n=await Gt(e,o);t[o]=n?{status:n.status,...typeof n.fileCount=="number"?{sourceCount:n.fileCount}:{},...typeof n.compiledCount=="number"?{articleCount:n.compiledCount}:{},...typeof n.finishedAt=="string"?{finishedAt:n.finishedAt}:{}}:{status:"unknown"}}return t}a(Mt,"readKbStats");async function Lt(e){try{let r=await Ne(e,{lenientEnv:!0}),t=await $t({settings:r});return{ok:!t.results.some(n=>n.action==="failed"),collections:t.collections,...t.skippedReason?{skippedReason:t.skippedReason}:{}}}catch(r){return{ok:!1,collections:[],skippedReason:r instanceof Error?r.message:String(r)}}}a(Lt,"recompileKb");async function oe(e){let r=await eo(e),t={ok:!0,scenario:null,workflowId:null,eventSourceName:null,kbRoleId:null,kb:{userCollection:null,officialOn:!1,stats:{}},groups:[],groupBotsStaging:[],groupTableRef:null};if(!r)return t;let o=Jt(r),n=Kt(r),s=o&&n?"group-qa":null,i=n?await Dt(e,n):[],c=o?U(U(r.workflows)?.[o.workflowId]):void 0,p=o?U(U(c?.event_sources)?.[o.eventSourceName]):void 0,d=(await Ue(e)).group_table??null;return{ok:!0,scenario:s,workflowId:o?.workflowId??null,eventSourceName:o?.eventSourceName??null,kbRoleId:n,kb:{userCollection:i.find(h=>h!==L)??null,officialOn:i.includes(L),stats:await Mt(e,i)},groups:to(p?.conversation_ids),groupBotsStaging:await Ht(e,o?.workflowId??"group-qa"),groupTableRef:d}}a(oe,"readConsoleState");function Jt(e){let r=U(e.workflows);if(!r)return null;for(let[t,o]of Object.entries(r)){let n=U(U(o)?.event_sources);if(n){for(let[s,i]of Object.entries(n))if(U(i)&&"conversation_ids"in i)return{workflowId:t,eventSourceName:s}}}return null}a(Jt,"locateGroupQa");function Kt(e){let r=U(e.roles);if(!r)return null;for(let[t,o]of Object.entries(r)){let n=U(U(o)?.knowledge_scope);if(Array.isArray(n?.kb_collections)&&n.kb_collections.length>0)return t}return null}a(Kt,"locateKbRole");async function Fe(e,r,t,o){let n=[...new Set(o.map(p=>p.trim()).filter(Boolean))],s=n.join(`
|
|
3
|
+
`),i=["workflows",r,"event_sources",t],c=$.join("profile","profile.yml");return await be({type:"yaml",file:c,yamlPath:[...i,"conversation_ids"],valueType:"string[]"},s,e),await be({type:"yaml",file:c,yamlPath:[...i,"handler_config","conversation_ids"],valueType:"string[]"},s,e),Ge(),{ok:!0,message:n.length>0?`\u5DF2\u4FDD\u5B58 ${n.length} \u4E2A\u7FA4`:"\u5DF2\u6E05\u7A7A\u7FA4\u5217\u8868"}}a(Fe,"writeGroupList");var Me="GROUP_BOTS_STAGING";async function se(e){let r=await Xt(e,Me);if(!r)return[];try{let t=JSON.parse(r);return Array.isArray(t)?t:[]}catch{return[]}}a(se,"readGroupBotStagingRaw");async function Le(e,r){await be({type:"env",file:".env",envKey:Me},JSON.stringify(r),e)}a(Le,"writeGroupBotStagingRaw");function Wt(e){return e?e.type==="enterprise"?{type:"enterprise",appKey:e.appKey,...e.name?{name:e.name}:{}}:{type:"custom",name:e.name,webhookUrl:e.webhookUrl}:null}a(Wt,"maskBot");async function Ie(e,r,t){let o=t.conversationId.trim();if(!o)return{ok:!1,message:"conversationId \u5FC5\u586B"};let n=await se(e),s=n.findIndex(p=>p.conversationId===o),i=n[s]??{conversationId:o,title:"",enabled:!0,bot:null},c={conversationId:o,title:t.title!==void 0?t.title:i.title,...t.groupType??i.groupType?{groupType:t.groupType??i.groupType}:{},...t.corpId??i.corpId?{corpId:t.corpId??i.corpId}:{},enabled:t.enabled!==void 0?t.enabled:i.enabled,bot:t.bot!==void 0?t.bot:i.bot};return s>=0?n[s]=c:n.push(c),await Le(e,n),{ok:!0,message:"\u5DF2\u4FDD\u5B58"}}a(Ie,"saveGroupBotStaging");async function Ht(e,r){return(await se(e)).map(o=>({...o,bot:Wt(o.bot)}))}a(Ht,"readGroupBotStaging");var ye="ai\u8868\u683C\u7FA4\u7B54\u7591\u52A9\u624B";function Oe(e){return e instanceof Ae?`${e.guidance}
|
|
4
|
+
\uFF08\u539F\u59CB\u9519\u8BEF\uFF1A${e.message}\uFF09`:e instanceof Error?e.message:String(e)}a(Oe,"provisionErrorMessage");async function Je(){try{return await new _e().getCurrentCorpId()}catch{return}}a(Je,"resolveCurrentCorpId");async function Ke(e,r,t,o={}){let n=o.provision??new At({runner:new _e}),s=$.join(e,".env"),i;try{i=await n.resolveEnterpriseRobot({name:ye,desc:`${ye} - aitable-workflow`,envFile:s})}catch(p){return{ok:!1,message:Oe(p)}}let c=!1;try{await n.addBotToGroup(i.appKey,t.conversationId)}catch(p){if(p instanceof Ae&&p.kind==="bot_already_installed")c=!0;else return{ok:!1,message:Oe(p)}}return await Ie(e,r,{conversationId:t.conversationId,title:t.title,...t.groupType?{groupType:t.groupType}:{},corpId:i.corpId,enabled:!0,bot:{type:"enterprise",appKey:i.appKey,appSecret:i.appSecret,name:ye}}),{ok:!0,message:c?"\u8BE5\u7FA4\u5DF2\u5B89\u88C5\u8FC7\u6B64\u673A\u5668\u4EBA\uFF0C\u5DF2\u76F4\u63A5\u8BB0\u5F55\u914D\u7F6E":"\u673A\u5668\u4EBA\u5DF2\u52A0\u5165\u7FA4\u804A"}}a(Ke,"addEnterpriseBotToGroup");function Yt(e){let r=[];for(let t of e){if(!t.enabled||!t.bot)continue;let o={\u7FA4ID:t.conversationId,\u7FA4\u540D\u79F0:t.title,...t.groupType?{\u7FA4\u7C7B\u578B:t.groupType==="internal"?"\u5185\u90E8\u7FA4":"\u5916\u90E8\u7FA4"}:{},...t.corpId?{\u7FA4\u5F52\u5C5E\u4F01\u4E1AcorpId:t.corpId}:{},...t.bot.name?{\u673A\u5668\u4EBA\u6635\u79F0:t.bot.name}:{}};t.bot.type==="enterprise"?r.push({...o,\u5165\u7AD9\u65B9\u5F0F:"stream",\u51FA\u7AD9\u65B9\u5F0F:"session",appKey:t.bot.appKey,...t.bot.appSecret?{appSecret:t.bot.appSecret}:{}}):r.push({...o,\u5165\u7AD9\u65B9\u5F0F:"dws",\u51FA\u7AD9\u65B9\u5F0F:"webhook",webhookUrl:t.bot.webhookUrl,...t.bot.webhookSecret?{webhookSecret:t.bot.webhookSecret}:{}})}return r}a(Yt,"stagingToGroupTableRecords");async function ie(e,r,t={}){let o=t.artifacts??await Q(e,r),n=o.configTables.group_table,s=n?.baseId?.trim()??"",i=n?.tableId?.trim()??"";if(!s||!i)return{ok:!1,created:0,message:"\u7FA4\u914D\u7F6E\u8868\u5C1A\u672A\u5C31\u7EEA\uFF08\u7F3A baseId/tableId\uFF09\uFF0C\u6682\u5B58\u4FDD\u7559"};let c=a(async()=>{o.ready&&await Le(r,[])},"clearStaging"),p=await se(r),g=Yt(p);if(g.length===0)return await c(),{ok:!0,created:0,message:"\u65E0\u53EF\u5199\u5165\u7684\u7FA4\u673A\u5668\u4EBA\u914D\u7F6E"};let d=t.dws??new Se({bin:"dws",timeoutMs:9e4}),h=t.existingGroupIds??(await ke(s,i,{dws:d,fields:t.fields})).groups.map(x=>x.groupId),k=g.filter(x=>!h.includes(x.\u7FA4ID??""));if(k.length===0)return await c(),{ok:!0,created:0,message:"\u6682\u5B58\u5DF2\u5168\u90E8\u5728\u7FA4\u914D\u7F6E\u8868\u4E2D"};let P=t.fields??await ve(d,s,i),G=new Map(P.map(x=>[x.fieldName,x.fieldId])),K=k.map(x=>{let F={};for(let[u,l]of Object.entries(x)){let f=G.get(u);f&&(F[f]=l)}return{cells:F}});return await d.runJson(["aitable","record","create","--base-id",s,"--table-id",i,"--records",JSON.stringify(K),"--yes"]),await c(),{ok:!0,created:k.length,message:`\u5DF2\u5199\u5165 ${k.length} \u6761\u7FA4\u914D\u7F6E`}}a(ie,"writeStagingToGroupTable");var A={groupId:"\u7FA4ID",groupName:"\u7FA4\u540D\u79F0",groupType:"\u7FA4\u7C7B\u578B",corpId:"\u7FA4\u5F52\u5C5E\u4F01\u4E1AcorpId",inbound:"\u5165\u7AD9\u65B9\u5F0F",outbound:"\u51FA\u7AD9\u65B9\u5F0F",webhookUrl:"webhookUrl",webhookSecret:"webhookSecret",appKey:"appKey",appSecret:"appSecret",botNick:"\u673A\u5668\u4EBA\u6635\u79F0",enabled:"\u662F\u5426\u542F\u7528"};function _(e){if(e==null)return"";if(typeof e=="string")return e.trim();if(typeof e=="number")return String(e);if(typeof e=="boolean")return e?"true":"";if(Array.isArray(e))return e.map(_).filter(Boolean).join(",");if(R(e)){if(typeof e.name=="string")return e.name.trim();if(typeof e.value=="string")return e.value.trim();if(typeof e.text=="string")return e.text.trim()}return""}a(_,"cellToText");function qt(e){if(e==null||e==="")return!0;let r=_(e).toLowerCase();return["true","1","yes","on","\u662F","\u5F00\u542F","\u542F\u7528","\u5DF2\u52FE\u9009"].includes(r)||(typeof e=="boolean"?e:!1)}a(qt,"cellToEnabled");function zt(e){let r=_(e);if(r.includes("\u5185\u90E8"))return"internal";if(r.includes("\u5916\u90E8"))return"external"}a(zt,"cellToGroupType");function Vt(e){if(!R(e))return[];let t=(R(e.data)?e.data:e).records;return Array.isArray(t)?t:[]}a(Vt,"extractConsoleRecords");async function ke(e,r,t={}){if(!e||!r)return{ok:!1,baseId:e,tableId:r,groups:[]};let o=t.dws??new Se({bin:"dws",timeoutMs:9e4}),[n,s]=await Promise.all([t.fields?Promise.resolve(t.fields):ve(o,e,r),o.runJson(["aitable","record","query","--base-id",e,"--table-id",r,"--all","--format","json"])]),i=new Map(n.map(g=>[g.fieldName,g.fieldId])),c=a((g,d)=>{if(d in g)return g[d];let h=i.get(d);return h?g[h]:void 0},"readCol"),p=[];for(let g of Vt(s)){let d=R(g.cells)?g.cells:{},h=_(c(d,A.groupId));if(!h)continue;let k=_(c(d,A.appSecret)),P=_(c(d,A.webhookSecret)),G=zt(c(d,A.groupType));p.push({recordId:String(g.recordId??g.id??""),groupId:h,groupName:_(c(d,A.groupName)),...G?{groupType:G}:{},corpId:_(c(d,A.corpId)),inbound:_(c(d,A.inbound)),outbound:_(c(d,A.outbound)),webhookUrl:_(c(d,A.webhookUrl)),webhookSecret:P?"***":"",appKey:_(c(d,A.appKey)),appSecret:k?"***":"",botNick:_(c(d,A.botNick)),enabled:qt(c(d,A.enabled))})}return{ok:!0,baseId:e,tableId:r,groups:p}}a(ke,"readGroupConfigTable");async function We(e,r,t={}){let o=t.artifacts??await Q(e,r),n=o.configTables.group_table,s=n?.baseId?.trim()??"",i=n?.tableId?.trim()??"";if(!s||!i)return{ok:!1,baseId:s,tableId:i,groups:[]};let c=await ke(s,i,t);if(c.ok&&c.groups.length===0&&(await se(r)).length>0){let g=await ie(e,r,{...t,artifacts:o,existingGroupIds:[]});g.ok&&g.created>0&&(c=await ke(s,i,t))}return c}a(We,"readGroupConfigTableForConsole");async function He(e,r,t,o,n={}){if(!e||!r||!t)return{ok:!1,message:"baseId / tableId / recordId \u5FC5\u586B"};let s=n.dws??new Se({bin:"dws",timeoutMs:9e4}),i=n.fields??await ve(s,e,r),c=new Map(i.map(g=>[g.fieldName,g.fieldId])),p={};for(let[g,d]of Object.entries(o)){if(d===void 0)continue;let h=A[g];if(!h)continue;let k=c.get(h)??h;p[k]=d}return Object.keys(p).length===0?{ok:!1,message:"\u65E0\u53EF\u66F4\u65B0\u5B57\u6BB5"}:(await s.runJson(["aitable","record","update","--base-id",e,"--table-id",r,"--records",JSON.stringify([{recordId:t,cells:p}]),"--yes"]),{ok:!0,message:"\u8BB0\u5F55\u5DF2\u66F4\u65B0"})}a(He,"updateGroupConfigRecord");var Qt=["loggedIn","isLoggedIn","isLogin","authenticated","tokenValid","isValid"];function Ye(e){if(!e||typeof e!="object")return null;let r=e;for(let t of Qt)if(typeof r[t]=="boolean")return r[t];for(let t of Object.values(r)){let o=Ye(t);if(o!==null)return o}return null}a(Ye,"findAuthBoolean");async function qe(e={}){let r=e.bin??"dws",t=e.runner??((o,n)=>Ut(o,n,{timeoutMs:15e3}));try{let o=await Bt(r,["auth","status","--format","json"],{runner:t}),n=`${o.stdout}
|
|
5
|
+
${o.stderr}`.trim();for(let s of[n,...n.split(/\r?\n/).reverse()])try{let i=Ye(JSON.parse(s));if(i!==null)return{loggedIn:i}}catch{}return/(未登录|登录失效|token\s*(?:is\s*)?(?:invalid|expired)|not\s+(?:logged|authenticated)|unauthenticated)/i.test(n)?{loggedIn:!1,message:n.split(/\r?\n/)[0]?.slice(0,200)}:o.exitCode===0?{loggedIn:!0}:{loggedIn:!1,message:n.split(/\r?\n/)[0]?.slice(0,200)||"dws auth status \u5931\u8D25"}}catch(o){return{loggedIn:!1,message:o instanceof Error?o.message:String(o)}}}a(qe,"checkDwsAuthStatus");var ze=$.join(".aitable-workflow","dws-login.log"),Zt=/https:\/\/login\.dingtalk\.com\/oauth2\/device\/verify\.htm\?user_code=[A-Za-z0-9-]+/;async function Ve(e,r={}){let t=$.resolve(e,ze);await xt($.dirname(t),{recursive:!0});try{return await we(r.bin??"dws",["auth","login","--device","--yes","--no-browser"],{logFile:t}),{ok:!0,logFile:t}}catch(o){return{ok:!1,message:o instanceof Error?o.message:String(o)}}}a(Ve,"startDwsDeviceLogin");async function Qe(e){try{return{verifyUrl:(await V($.resolve(e,ze),"utf8")).match(Zt)?.[0]??null}}catch{return{verifyUrl:null}}}a(Qe,"readDwsLoginProgress");async function Xt(e,r){let t;try{t=await V($.resolve(e,".env"),"utf8")}catch{return null}let o=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=t.match(new RegExp(`^${o}=(.*)$`,"m"));if(!n)return null;let s=n[1].trim();return s.startsWith("'")&&s.endsWith("'")&&s.length>=2?s=s.slice(1,-1):s.startsWith('"')&&s.endsWith('"')&&s.length>=2&&(s=s.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\")),s||null}a(Xt,"readEnvKey");async function eo(e){try{let r=J.parse(await V($.resolve(e,"profile","profile.yml"),"utf8"));return R(r)?r:null}catch{return null}}a(eo,"readProfileDoc");function U(e){return R(e)?e:void 0}a(U,"asRecord");function to(e){return Array.isArray(e)?e.filter(r=>typeof r=="string"):[]}a(to,"toStringArray");function R(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}a(R,"isRecord");import{spawnManagedProcess as oo}from"aitable-workflow-core";function Xe(e){let r=ro(e);try{let t=oo({...r,stdio:"ignore",detached:!0});t.child.once("error",()=>Ze(e)),t.unref()}catch{Ze(e)}}a(Xe,"openExternalUrl");function ro(e,r=process.platform){return r==="darwin"?{command:"open",args:[e]}:r==="win32"?{command:"rundll32.exe",args:["url.dll,FileProtocolHandler",e]}:{command:"xdg-open",args:[e]}}a(ro,"openInvocation");function Ze(e){console.log(`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${e}`)}a(Ze,"printFallback");function rt(e){return e?`workbench/${e}`:"setup"}a(rt,"consoleStartPath");var nt=I.dirname(co(import.meta.url)),yo={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".ico":"image/x-icon"},bo=1800*1e3;function ko(e){let r=null,t=a(()=>{r&&clearTimeout(r),r=null},"clear");return{clear:t,armed:a(()=>r!==null,"armed"),reset:a(()=>{t(),e.isEnabled()&&(r=setTimeout(e.onTimeout,e.timeoutMs))},"reset")}}a(ko,"createIdleTimer");var E={phase:"idle"},v={status:"idle"},X=Promise.resolve(),So=12e4,re=new Set,D=class extends Error{constructor(t,o){super(o);this.status=t;this.name="TriggerOnceHttpError"}status;static{a(this,"TriggerOnceHttpError")}},ee=class extends Error{constructor(t,o){super(o);this.status=t;this.name="PromotionHttpError"}status;static{a(this,"PromotionHttpError")}},vo=6e4,le=!1;function Io(){return process.platform==="darwin"||process.platform==="win32"||process.env.DISPLAY||process.env.WAYLAND_DISPLAY?"local-gui":"remote"}a(Io,"detectEnvironment");function dt(){let e=I.join(nt,"web");if(tt(I.join(e,"index.html")))return e;let r=I.resolve(nt,"..","..","..","web","dist");return tt(I.join(r,"index.html"))?r:null}a(dt,"resolveWebRoot");function lr(){return dt()!==null}a(lr,"hasWebRoot");async function Ro(e){let t=e+13-1,{createServer:o}=await import("net"),n=a(s=>new Promise((i,c)=>{let p=o();p.listen(s,()=>{let g=p.address(),d=typeof g=="object"&&g?g.port:s;p.close(()=>i(d))}),p.on("error",()=>{s<t?n(s+1).then(i,c):c(new Error(`\u65E0\u6CD5\u627E\u5230\u53EF\u7528\u7AEF\u53E3 (${e}-${t})`))})}),"tryListen");return n(e)}a(Ro,"getAvailablePort");var To=1024*1024,Co=50*1024*1024,pt=I.join(".aitable-workflow","console-access.json");async function gt(e,r){let t=I.join(e,pt);return await ce(I.dirname(t),{recursive:!0}),await Re(t,`${JSON.stringify(r,null,2)}
|
|
6
|
+
`,"utf8"),t}a(gt,"writeConsoleAccessFile");function Eo(e){try{ao(I.join(e,pt))}catch{}}a(Eo,"clearConsoleAccessFile");async function j(e,r=To){return new Promise((t,o)=>{let n=[],s=0;e.on("data",i=>{if(s+=i.length,s>r){e.destroy(),o(new Error("Request body too large"));return}n.push(i)}),e.on("end",()=>{try{t(JSON.parse(Buffer.concat(n).toString("utf8")))}catch{o(new Error("Invalid JSON body"))}}),e.on("error",o)})}a(j,"readJson");function m(e,r,t=200){let o=JSON.stringify(r);e.writeHead(t,{"Content-Type":"application/json; charset=utf-8","Content-Length":Buffer.byteLength(o)}),e.end(o)}a(m,"sendJson");function b(e,r,t){m(e,{ok:!1,error:t},r)}a(b,"sendError");function Y(e){let r=JSON.parse(JSON.stringify(e));for(let t of r.modules){let o=t.workflows?t.workflows.flatMap(n=>n.items):t.items;for(let n of o)n.sensitive&&n.value!==void 0&&(n.value="***")}return r}a(Y,"maskSensitive");async function ur(e){let r=e.port??8788,t=await Ro(r),o=Io(),n=lt.randomUUID(),s=o==="remote"?"0.0.0.0":"127.0.0.1",i=dt(),c=e.mode??"setup",p=e.app;if(c==="runtime"&&!p)throw new Error("runtime \u6A21\u5F0F\u5FC5\u987B\u4F20\u5165 App \u5B9E\u4F8B");if(!i)throw new Error("Web \u8D44\u6E90\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u542F\u52A8\u53EF\u89C6\u5316\u914D\u7F6E\u754C\u9762");let g=await ut(e.configPath),d=I.dirname(g);E={phase:"idle"},v={status:"idle"},X=Promise.resolve(),re.clear();let h=e.assembleApp?{assembleApp:e.assembleApp,commit:a(l=>{p=l,c="runtime",x(),e.onAppAssembled?.(l)},"commit")}:void 0,k="";e.initialRunStatus&&(v=e.initialRunStatus);let P=null,G=new Promise(l=>P=l),K=ko({timeoutMs:bo,isEnabled:a(()=>c==="setup","isEnabled"),onTimeout:a(()=>{console.log(`
|
|
7
|
+
\u2139 \u914D\u7F6E\u754C\u9762\u8D85\u8FC7 30 \u5206\u949F\u65E0\u6D3B\u52A8\uFF0C\u5DF2\u81EA\u52A8\u5173\u95ED\u3002`),P?.()},"onTimeout")}),x=a(()=>K.reset(),"resetTimeout"),F=no(async(l,f)=>{let w=new URL(l.url??"/",`http://${l.headers.host??"localhost"}`),y=l.headers.origin;if(y){let N=`http://127.0.0.1:${t}`;(y===N||o==="remote")&&f.setHeader("Access-Control-Allow-Origin",y)}if(f.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),f.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),l.method==="OPTIONS"){f.writeHead(204),f.end();return}if(w.pathname.startsWith("/dev/")){if((w.searchParams.get("token")??l.headers.authorization?.replace("Bearer ",""))!==n){b(f,401,"Unauthorized");return}x();try{await Po({url:w,req:l,res:f,configPath:e.configPath,configDir:d,completionResolve:P,setupOptions:e.setupOptions,mode:c,app:p,promotion:h?{...h,access:{configDir:d,url:k,port:t}}:void 0,exitOnSetupError:e.exitOnSetupError!==!1,traceUrl:e.traceUrl})}catch(C){let M=C instanceof Error?C.message:String(C);b(f,500,M)}return}if(w.pathname.startsWith("/api/")){m(f,{error:{message:"\u914D\u7F6E\u754C\u9762\u4E0D\u63D0\u4F9B /api \u63A5\u53E3"}},404);return}No(w,f,i)});await new Promise(l=>F.listen(t,s,l)),x();let u=(await oe(d).catch(()=>null))?.scenario??null;k=o==="local-gui"?`http://127.0.0.1:${t}/${rt(u)}?token=${n}`:`http://${lo.hostname()}:${t}/${rt(u)}?token=${n}`,await gt(d,{url:k,port:t,mode:c,pid:process.pid,since:new Date().toISOString()}),process.on("exit",()=>Eo(d)),o==="local-gui"?e.open!==!1?(Xe(k),console.log(`\u2139 \u6D4F\u89C8\u5668\u5DF2\u6253\u5F00: ${k}`)):console.log(`\u2139 \u8BF7\u624B\u52A8\u6253\u5F00\u6D4F\u89C8\u5668: ${k}`):(console.log("\u2139 \u914D\u7F6E\u754C\u9762\u5DF2\u542F\u52A8\uFF0C\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00:"),console.log(` ${k}`),console.log(`
|
|
8
|
+
\u5982\u679C\u65E0\u6CD5\u76F4\u63A5\u8BBF\u95EE\uFF0C\u53EF\u901A\u8FC7 SSH \u7AEF\u53E3\u8F6C\u53D1:
|
|
9
|
+
ssh -L ${t}:127.0.0.1:${t} <your-host>`),console.log(` \u7136\u540E\u6253\u5F00: http://127.0.0.1:${t}/setup?token=${n}`)),c==="runtime"?(console.log(`
|
|
10
|
+
\uFF08\u63A7\u5236\u53F0\u968F start \u8FDB\u7A0B\u4FDD\u6301\u8FD0\u884C\uFF0C\u5173\u95ED\u6D4F\u89C8\u5668\u4E0D\u4F1A\u505C\u6B62\u5DE5\u4F5C\u6D41\uFF09`),console.log(` \uFF08\u6309 Ctrl+C \u505C\u6B62 start \u8FDB\u7A0B | \u63A7\u5236\u53F0\u53EF\u505C\u6B62/\u91CD\u542F\u8FD0\u884C\uFF09
|
|
11
|
+
`)):(console.log(`
|
|
12
|
+
\uFF08\u914D\u7F6E\u53F0\u4F1A\u4FDD\u6301\u8FD0\u884C\uFF0Csetup \u5B8C\u6210\u540E\u53EF\u7EE7\u7EED\u67E5\u770B\u7B54\u7591\u8BB0\u5F55/\u4E13\u5BB6\u914D\u7F6E/\u77E5\u8BC6\u5E93\uFF09`),console.log(` \uFF08\u6309 Ctrl+C \u9000\u51FA | --no-ui \u56DE\u9000\u547D\u4EE4\u884C\u4EA4\u4E92\uFF09
|
|
13
|
+
`)),await G,K.clear(),F.close()}a(ur,"runConfigUI");async function Po(e){let{url:r,req:t,res:o,configPath:n,configDir:s,completionResolve:i,setupOptions:c,mode:p,app:g,promotion:d,exitOnSetupError:h,traceUrl:k}=e;if(t.method==="GET"&&r.pathname==="/dev/config/check"){let u=await Z({configPath:n});m(o,Y(u));return}if(t.method==="GET"&&r.pathname==="/dev/config/enriched"){let u=await Z({configPath:n}),l=po(),f=await uo(n),w={},y={},N=new Set,C=/\$\{env\.([A-Za-z_][A-Za-z0-9_]*)(\?)?\}/g;try{let S=await ut(n),O=await ae(S,"utf8");for(let W of fo([O]))N.add(W)}catch{}try{let S=await ae(I.join(s,"profile","profile.yml"),"utf8"),O=Te.parse(S),W=O?.workflows;if(W&&typeof W=="object"&&(y=W),O&&typeof O=="object"){let{workflows:Ee,...q}=O;for(let te of JSON.stringify(q).matchAll(C))N.add(te[1])}}catch{}for(let S of f.workflowEntries)try{let O=await go(S.templatePath),W=O.steps.map(T=>({id:T.id,name:T.name,recipe:T.recipe,engine:T.engine,auto:T.auto})),Ee=O.edges.filter(T=>T.from!=="__start__"&&T.to!=="__end__").map(T=>({from:T.from,to:T.to,condition:T.condition})),q={},te=new Set,H;try{H=Te.parse(await ae(S.templatePath,"utf8"))}catch{}if(H){for(let B of JSON.stringify(H).matchAll(C))te.add(B[1]);let T=y[S.id];if(T&&typeof T=="object")for(let B of JSON.stringify(T).matchAll(C))te.add(B[1]);let ft=Array.isArray(H.steps)?H.steps:[];for(let B=0;B<O.steps.length;B++){let de=O.steps[B],z=ft[B];if(z){let pe=JSON.stringify(z),ge=new Set;for(let wt of pe.matchAll(C))ge.add(wt[1]);ge.size>0&&(q[de.id]=[...ge])}}let mt=Array.isArray(H.event_sources)?H.event_sources:[];for(let B of mt)if(B){let de=JSON.stringify(B),z=new Set;for(let pe of de.matchAll(C))z.add(pe[1]);z.size>0&&(q.__event_sources__=[...q.__event_sources__??[],...z])}}w[S.id]={steps:W,edges:Ee,stepEnvRefs:q,envRefs:[...te].sort()}}catch{w[S.id]={steps:[],edges:[],stepEnvRefs:{},envRefs:[]}}let M=new Set;for(let S of Object.values(w))for(let O of S.envRefs??[])M.add(O);let ue=u.modules.find(S=>S.id==="env");for(let S of ue?.items??[])S.writeTarget?.type==="env"&&!M.has(S.key)&&N.add(S.key);m(o,{config:Y(u),engines:{available:l.available.map(S=>({engine:S.engine,cmd:S.cmd,version:S.version})),recommended:l.recommendedEngine},workflowTopology:w,projectEnvRefs:[...N].sort()});return}if(t.method==="POST"&&r.pathname==="/dev/config/save"){let u=await j(t);try{let l=await mo(u,s,n);m(o,{ok:!0,written:l.written,recheck:Y(l.recheck)})}catch(l){if(l instanceof wo){b(o,l.status,l.message);return}throw l}return}if(t.method==="POST"&&r.pathname==="/dev/kb/ingest"){let u=await j(t);if(!u.roleId||!u.source){b(o,400,"roleId and source are required");return}try{ot(u.roleId,{label:"roleId"})}catch(N){b(o,400,N instanceof Error?N.message:"roleId \u4E0D\u5408\u6CD5");return}let l=I.resolve(s,"roles",`${u.roleId}.role.yml`),f=await me(l,u.roleId),w=await fe({source:u.source,collectionName:f,configDir:s}),y=await Z({configPath:n});m(o,{ok:w.success,message:w.message,recheck:Y(y)});return}if(t.method==="POST"&&r.pathname==="/dev/kb/upload"){let u=await j(t,Co);if(!u.roleId||!Array.isArray(u.files)||u.files.length===0){b(o,400,"roleId and files are required");return}try{ot(u.roleId,{label:"roleId"})}catch(y){b(o,400,y instanceof Error?y.message:"roleId \u4E0D\u5408\u6CD5");return}let l=I.resolve(s,"roles",`${u.roleId}.role.yml`),f=await me(l,u.roleId),w=I.resolve(s,".kb-upload-tmp",`upload-${Date.now()}`);try{await ce(w,{recursive:!0});for(let C of u.files){let M;try{M=Ce(w,C.relativePath,{allowRoot:!1})}catch{b(o,400,`\u4E0A\u4F20\u6587\u4EF6\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${C.relativePath}`);return}let ue=I.dirname(M);await ce(ue,{recursive:!0});let S=C.encoding==="base64"?Buffer.from(C.content,"base64"):Buffer.from(C.content,"utf8");await Re(M,S)}let y=await fe({source:w,collectionName:f,configDir:s}),N=await Z({configPath:n});m(o,{ok:y.success,message:y.message,recheck:Y(N)})}finally{await so(w,{recursive:!0,force:!0}).catch(()=>{})}return}if(t.method==="GET"&&r.pathname==="/dev/file/read"){let u=r.searchParams.get("path")??"",l=ct(u,s);if(!l){b(o,403,`\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${u}`);return}try{let f=await ae(l,"utf8");m(o,{ok:!0,path:u,content:f,exists:!0})}catch{m(o,{ok:!0,path:u,content:"",exists:!1})}return}if(t.method==="POST"&&r.pathname==="/dev/file/write"){let u=await j(t),l=typeof u.path=="string"?u.path:"",f=ct(l,s);if(!f||typeof u.content!="string"){b(o,403,`\u8DEF\u5F84\u8D8A\u754C\u6216\u4E0D\u5408\u6CD5: ${l}`);return}let w=Ao(l,u.content);if(w){m(o,{ok:!1,error:w},400);return}await ce(I.dirname(f),{recursive:!0}),await Re(f,u.content.endsWith(`
|
|
14
|
+
`)?u.content:u.content+`
|
|
15
|
+
`,"utf8");let y=await Z({configPath:n});m(o,{ok:!0,recheck:Y(y)});return}if(t.method==="POST"&&r.pathname==="/dev/setup/complete"){if(E.phase==="running"){b(o,409,"setup \u5DF2\u5728\u8FD0\u884C\u4E2D");return}E={phase:"running",logs:[]},m(o,{ok:!0});let u=a(async()=>{try{let l=await ie(n,s);l.ok||console.error(`[group-qa] \u7FA4\u914D\u7F6E\u5199\u5165\u672A\u5B8C\u6210: ${l.message}`)}catch(l){console.error(`[group-qa] \u7FA4\u914D\u7F6E\u5199\u5165\u5F02\u5E38: ${l instanceof Error?l.message:String(l)}`)}},"flushStaging");(async()=>{try{await u(),await ho({config:n,...c??{}}),await u();let l=await Q(n,s),f=_o(l),w={mode:p};if(p==="setup"&&d){let y=await it({configPath:n,...d});w=y.ok?{mode:"runtime"}:{mode:"setup",promotionError:y.error}}E={phase:"done",artifacts:l,baseUrl:f,...w}}catch(l){E={phase:"error",message:l instanceof Error?l.message:String(l)},h&&i?.()}})();return}if(t.method==="GET"&&r.pathname==="/dev/setup/progress"){m(o,E);return}if(t.method==="GET"&&r.pathname==="/dev/setup/artifacts"){m(o,await Q(n,s));return}if(t.method==="GET"&&r.pathname==="/dev/console/state"){m(o,await oe(s));return}if(t.method==="POST"&&r.pathname==="/dev/console/groups"){let u=await j(t);if(!u.workflowId||!u.eventSourceName||!Array.isArray(u.conversationIds)){b(o,400,"workflowId / eventSourceName / conversationIds \u5FC5\u586B");return}let l=await Fe(s,u.workflowId,u.eventSourceName,u.conversationIds),f=await Z({configPath:n});m(o,{...l,recheck:Y(f)});return}if(t.method==="GET"&&r.pathname==="/dev/console/admin-groups"){m(o,await Be());return}if(t.method==="GET"&&r.pathname==="/dev/console/dws-auth"){m(o,await qe());return}if(t.method==="POST"&&r.pathname==="/dev/console/dws-auth/login"){let u=await Ve(s);m(o,u,u.ok?200:400);return}if(t.method==="GET"&&r.pathname==="/dev/console/dws-auth/login"){m(o,await Qe(s));return}let P=r.pathname.match(/^\/dev\/console\/groups\/([^/]+)\/add-enterprise-bot$/);if(t.method==="POST"&&P){let u=decodeURIComponent(P[1]),l=await j(t),f=await oe(s),w=await Ke(s,f.workflowId??"group-qa",{conversationId:u,title:l.title??"",...l.groupType?{groupType:l.groupType}:{}});m(o,w,w.ok?200:400);return}let G=r.pathname.match(/^\/dev\/console\/groups\/([^/]+)\/custom-bot$/);if(t.method==="POST"&&G){let u=decodeURIComponent(G[1]),l=await j(t);if(!l.name||!l.webhook||!l.secret){b(o,400,"name / webhook / secret \u5FC5\u586B");return}if(!/^https?:\/\//.test(l.webhook)){b(o,400,"webhook \u5FC5\u987B\u4EE5 http(s):// \u5F00\u5934");return}let f=await oe(s),w=await Je(),y=await Ie(s,f.workflowId??"group-qa",{conversationId:u,...l.title!==void 0?{title:l.title}:{},...l.groupType?{groupType:l.groupType}:{},...w?{corpId:w}:{},enabled:!0,bot:{type:"custom",name:l.name,webhookUrl:l.webhook,...l.secret?{webhookSecret:l.secret}:{}}});m(o,y,y.ok?200:400);return}if(t.method==="GET"&&r.pathname==="/dev/console/group-config-table"){try{m(o,await We(n,s))}catch(u){b(o,502,u instanceof Error?u.message:"\u7FA4\u914D\u7F6E\u8868\u8BFB\u53D6\u5931\u8D25")}return}if(t.method==="POST"&&r.pathname==="/dev/console/group-config-table/flush-staging"){let u=await ie(n,s);m(o,u,u.ok?200:400);return}let K=r.pathname.match(/^\/dev\/console\/group-config-table\/([^/]+)$/);if(t.method==="POST"&&K){let u=decodeURIComponent(K[1]),l=await j(t),w=(await Q(n,s)).configTables.group_table;if(!w?.baseId||!w.tableId){b(o,400,"\u7FA4\u914D\u7F6E\u8868\u5C1A\u672A\u5C31\u7EEA");return}try{let y=await He(w.baseId,w.tableId,u,l);m(o,y,y.ok?200:400)}catch(y){b(o,502,y instanceof Error?y.message:"\u7FA4\u914D\u7F6E\u8868\u5199\u5165\u5931\u8D25")}return}if(t.method==="POST"&&r.pathname==="/dev/kb/official"){let u=await j(t);if(!u.roleId||typeof u.enabled!="boolean"){m(o,{ok:!1,code:"KB_BAD_REQUEST",message:"roleId \u4E0E enabled(boolean) \u5FC5\u586B"},400);return}let l;try{l=await $e(n,s,u.roleId,u.enabled)}catch(f){m(o,{ok:!1,code:"KB_TOGGLE_FAILED",message:f instanceof Error?f.message:"\u5B98\u65B9\u77E5\u8BC6\u5E93\u5F00\u5173\u5931\u8D25",collections:[]},400);return}m(o,l,l.ok?200:400);return}if(t.method==="POST"&&r.pathname==="/dev/kb/recompile"){let u=await je(n);m(o,u);return}if(t.method==="GET"&&r.pathname==="/dev/console/mode"){m(o,{ok:!0,mode:p,promotable:p==="setup"&&!!d,traceUrl:k??null});return}if(t.method==="POST"&&r.pathname==="/dev/console/promote"){if(p==="runtime"){m(o,{ok:!0,mode:"runtime"});return}if(!d){b(o,409,"\u5F53\u524D\u63A7\u5236\u53F0\u4E0D\u652F\u6301\u5C31\u5730\u664B\u5347\uFF08setup \u547D\u4EE4\u8BF7\u4F7F\u7528 aitable-workflow start\uFF09");return}if(E.phase!=="done"){b(o,409,"\u642D\u5EFA\u5C1A\u672A\u5B8C\u6210\uFF0C\u65E0\u6CD5\u8FDB\u5165\u8FD0\u884C\u6A21\u5F0F");return}try{let u=await it({configPath:n,...d});u.ok?m(o,{ok:!0,mode:"runtime"}):m(o,{ok:!1,mode:"setup",error:u.error},u.status)}catch(u){let l=u instanceof ee?u.status:500;b(o,l,u instanceof Error?u.message:String(u))}return}if(t.method==="GET"&&r.pathname==="/dev/run/status"){if(p==="setup"){m(o,{ok:!0,status:"unknown"});return}m(o,{ok:!0,...st()});return}let F={"/dev/run/start":"start","/dev/run/stop":"stop"}[r.pathname];if(t.method==="POST"&&F){if(p==="setup"){b(o,409,"setup \u6A21\u5F0F\u4E0D\u652F\u6301\u8FD0\u884C\u63A7\u5236\uFF0C\u8BF7\u4F7F\u7528 aitable-workflow start \u547D\u4EE4");return}let u=await xo(F,g);m(o,{...u,status:st()});return}if(t.method==="POST"&&r.pathname==="/dev/workflow/trigger-once"){if(p==="setup"){b(o,409,"setup \u6A21\u5F0F\u6CA1\u6709\u8FD0\u884C\u4E2D\u7684\u5F15\u64CE\uFF0C\u65E0\u6CD5\u89E6\u53D1\u5DE5\u4F5C\u6D41");return}let u;try{u=await j(t)}catch(l){b(o,400,l instanceof Error?l.message:String(l));return}try{let l=await Oo(String(u.workflowId??""),g);m(o,{ok:!0,...l})}catch(l){let f=l instanceof D?l.status:500;b(o,f,l instanceof Error?l.message:String(l))}return}b(o,404,"Unknown endpoint")}a(Po,"handleDevApi");function st(){return v}a(st,"getRuntimeRunStatus");async function xo(e,r){let t=lt.randomUUID();return e==="start"?v.status==="running"||v.status==="starting"?{ok:!0,action:e,requestId:t}:(v={status:"starting",since:new Date().toISOString(),lastError:null},X=X.then(()=>{let o=r.start();v.status==="starting"&&(v={status:"running",since:new Date().toISOString(),lastError:null}),o.catch(n=>{v={status:"error",lastError:n instanceof Error?n.message:String(n)}})}).catch(o=>{v={status:"error",lastError:o instanceof Error?o.message:String(o)}}),{ok:!0,action:e,requestId:t}):e==="stop"?v.status==="stopping"?{ok:!0,action:e,requestId:t}:v.status!=="running"&&v.status!=="starting"?(v={status:"stopped",lastError:null},{ok:!0,action:e,requestId:t}):(v={status:"stopping",lastError:null},X=X.then(async()=>{await r.stop(),v={status:"stopped",lastError:null}}).catch(o=>{v={status:"error",lastError:o instanceof Error?o.message:String(o)}}),{ok:!0,action:e,requestId:t}):{ok:!1,action:e,requestId:t}}a(xo,"handleRuntimeRunControl");async function Oo(e,r,t={}){if(typeof e!="string"||e.length===0)throw new D(400,"\u7F3A\u5C11 workflowId");if(!r.instances.some(i=>i.id===e)){let i=r.instances.map(c=>c.id).join("\u3001")||"\uFF08\u65E0\uFF09";throw new D(400,`\u672A\u77E5\u5DE5\u4F5C\u6D41 "${e}"\u3002\u5F53\u524D\u53EF\u89E6\u53D1\uFF1A${i}`)}if(re.has(e))throw new D(409,`\u5DE5\u4F5C\u6D41 "${e}" \u6B63\u5728\u89E6\u53D1\u4E2D\uFF0C\u8BF7\u7B49\u672C\u6B21\u5B8C\u6210`);re.add(e);let o=new AbortController,n=null,s=t.timeoutMs??So;try{let i=new Promise((p,g)=>{n=setTimeout(()=>{o.abort(),g(new D(504,`\u89E6\u53D1\u8D85\u65F6\uFF08${s}ms\uFF09\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u6267\u884C`))},s)}),c=await Promise.race([r.triggerWorkflowOnce(e,{signal:o.signal}),i]);return{workflowId:e,...c}}catch(i){throw i instanceof D?i:new D(500,i instanceof Error?i.message:String(i))}finally{n&&clearTimeout(n),re.delete(e)}}a(Oo,"handleTriggerWorkflowOnce");function dr(){re.clear()}a(dr,"resetTriggerOnceForTest");async function it(e,r={}){if(le)throw new ee(409,"\u664B\u5347\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u672C\u6B21\u5B8C\u6210");le=!0;let t=r.timeoutMs??vo,o=null;try{let n=new Promise((i,c)=>{o=setTimeout(()=>c(new ee(504,`\u88C5\u914D\u8D85\u65F6\uFF08${t}ms\uFF09\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u664B\u5347`)),t)}),s=await Promise.race([e.assembleApp(e.configPath),n]);if(e.commit(s),v={status:"idle"},e.access)try{await gt(e.access.configDir,{url:e.access.url,port:e.access.port,mode:"runtime",pid:process.pid,since:new Date().toISOString()})}catch(i){console.error(`[console] console-access.json \u91CD\u5199\u5931\u8D25: ${i instanceof Error?i.message:String(i)}`)}return at({ok:!0,mode:"runtime"}),{ok:!0,mode:"runtime"}}catch(n){let s=n instanceof ee?n.status:500,i=n instanceof Error?n.message:String(n);console.error(`[console] setup\u2192runtime \u664B\u5347\u5931\u8D25: ${i}`);let c={ok:!1,mode:"setup",status:s,error:i};return at(c),c}finally{o&&clearTimeout(o),le=!1}}a(it,"handleConsolePromotion");function at(e){if(E.phase==="done")if(e.ok){let{promotionError:r,...t}=E;E={...t,mode:"runtime"}}else E={...E,mode:"setup",promotionError:e.error}}a(at,"applyPromotionToDoneProgress");function pr(){v={status:"idle"},X=Promise.resolve()}a(pr,"resetRuntimeRunStatusForTest");function gr(){le=!1,E={phase:"idle"},v={status:"idle"}}a(gr,"resetPromotionForTest");function fr(e){E=e}a(fr,"setSetupProgressForTest");function mr(){return E}a(mr,"getSetupProgressForTest");function ct(e,r){let t=e.trim();if(!t||!/\.(ya?ml|json)$/i.test(t))return null;try{return Ce(r,t,{allowRoot:!1})}catch{return null}}a(ct,"resolveInsideConfigDir");function Ao(e,r){try{return/\.json$/i.test(e)?JSON.parse(r):Te.parse(r),null}catch(t){return`${/\.json$/i.test(e)?"JSON":"YAML"} \u8BED\u6CD5\u9519\u8BEF\uFF0C\u672A\u4FDD\u5B58: ${t instanceof Error?t.message:String(t)}`}}a(Ao,"validateStructuredText");function _o(e){let r=Object.values(e.trackers).find(t=>t.baseId&&t.tableId);return r?.baseId?`https://alidocs.dingtalk.com/i/nodes/${encodeURIComponent(r.baseId)}`:null}a(_o,"deriveBaseUrl");async function No(e,r,t){let o;try{let i=decodeURIComponent(e.pathname).replace(/^\/+/,"")||"index.html";o=Ce(t,i,{allowRoot:!1})}catch{r.writeHead(403),r.end("Forbidden");return}try{(await et(o)).isDirectory()&&(o=I.join(o,"index.html"))}catch{o=I.join(t,"index.html")}try{await et(o)}catch{r.writeHead(404),r.end("Not Found");return}let n=I.extname(o),s=yo[n]??"application/octet-stream";r.writeHead(200,{"Content-Type":s}),io(o).pipe(r)}a(No,"serveStatic");export{$o as a,Xe as b,rt as c,ko as d,D as e,ee as f,Io as g,dt as h,lr as i,pt as j,gt as k,Eo as l,ur as m,st as n,xo as o,Oo as p,dr as q,it as r,pr as s,gr as t,fr as u,mr as v,No as w};
|