@helixlife-ai/xiantao 0.1.28 → 0.1.30
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/README.md +2 -2
- package/dist/base-command.js +1 -1
- package/dist/commands/auth/login.js +2 -2
- package/dist/commands/auth/logout.js +1 -1
- package/dist/commands/auth/status.js +2 -2
- package/dist/commands/config/get.js +1 -1
- package/dist/commands/config/set.js +2 -2
- package/dist/commands/history/delete.js +1 -1
- package/dist/commands/history/download.js +5 -5
- package/dist/commands/history/list.js +3 -3
- package/dist/commands/history/rename.js +1 -1
- package/dist/commands/history/save.js +1 -1
- package/dist/commands/history/view.js +3 -3
- package/dist/commands/login.js +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/plot/download.js +1 -1
- package/dist/commands/plot/fetch-all.js +1 -1
- package/dist/commands/plot/login.js +2 -2
- package/dist/commands/plot/menu.js +1 -1
- package/dist/commands/plot/menus-raw.js +1 -1
- package/dist/commands/plot/menus.js +2 -2
- package/dist/commands/plot/resolve.js +1 -1
- package/dist/commands/plot/run.js +9 -9
- package/dist/commands/status.js +1 -1
- package/dist/commands/tool/cloud.js +1 -1
- package/dist/commands/tool/download.js +1 -1
- package/dist/commands/tool/exec.js +1 -1
- package/dist/commands/tool/fetch-all.js +1 -1
- package/dist/commands/tool/inspect.js +3 -3
- package/dist/commands/tool/login.js +1 -1
- package/dist/commands/tool/prepare.js +1 -1
- package/dist/commands/tool/run.js +1 -1
- package/dist/commands/tool/search.js +2 -2
- package/dist/hooks/init/update.js +1 -1
- package/dist/lib/auth.js +1 -1
- package/dist/lib/config.js +2 -2
- package/dist/lib/constants.js +1 -1
- package/dist/lib/debug.js +2 -2
- package/dist/lib/download.js +1 -1
- package/dist/lib/encrypt.js +1 -0
- package/dist/lib/envelope.js +1 -1
- package/dist/lib/errors.js +1 -1
- package/dist/lib/flags.js +1 -1
- package/dist/lib/history.js +1 -1
- package/dist/lib/http.js +1 -1
- package/dist/lib/json.js +1 -1
- package/dist/lib/login-flow.js +1 -1
- package/dist/lib/open-url.js +1 -1
- package/dist/lib/plot-interactive.js +33 -33
- package/dist/lib/plot-options.js +1 -1
- package/dist/lib/plot-schema.js +1 -1
- package/dist/lib/plot.js +1 -1
- package/dist/lib/storage.js +2 -2
- package/dist/lib/tool-inputs.js +1 -1
- package/dist/lib/update.js +5 -5
- package/dist/lib/xiantao-cloud.js +1 -1
- package/dist/lib/xiantao-plot.js +1 -1
- package/dist/lib/xiantao.js +1 -1
- package/dist/xtz-help.js +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -141,9 +141,9 @@ For agent workflows, do not use `xt tool run`. Treat `xt tool run` as the human-
|
|
|
141
141
|
|
|
142
142
|
## Notes
|
|
143
143
|
|
|
144
|
-
For Xiantao tool commands that accept `--toolProductUuid`, the default
|
|
144
|
+
For Xiantao tool commands that accept `--toolProductUuid`, the CLI resolves the default from `GET /api/v1/xiantaozi/user_tool_products` and uses the first normal user product UUID. You can override it with `--toolProductUuid`, `XIANTAO_TOOL_PRODUCT_UUID`, or `~/.config/xtz/config.json` under `xiantao.toolProductUuid`. If the user product list is empty, pass an explicit tool product UUID.
|
|
145
145
|
|
|
146
|
-
The CLI also loads a project-root `.env` file on startup. You can set `XIANTAO_BASE_URL=https://agent.helixlife.cn` there to switch the API base URL without prefixing each command manually, and `XIANTAO_LOGIN_URL=https://www.helixlife.net/` to override the login page. The same values can be stored with `xt config set base-url ...` and `xt config set login-url ...`.
|
|
146
|
+
The CLI also loads a project-root `.env` file on startup. You can set `XIANTAO_BASE_URL=https://agent.helixlife.cn/api/v1` there to switch the API base URL without prefixing each command manually, and `XIANTAO_LOGIN_URL=https://www.helixlife.net/` to override the login page. The same values can be stored with `xt config set base-url ...` and `xt config set login-url ...`.
|
|
147
147
|
|
|
148
148
|
`xt tool search <keyword>` searches remote tool menus by tool id, title, path, and route. `xt tool inspect <tool_id>` prints resolved metadata together with the dynamic `args_main` schema, the full `args_data` payload in JSON mode, and the detected input source summary, including `XTCloud`, per-field `XTUpload`, and `XTRecord` defaults. `xt tool run <tool_id>` runs a Xiantao bioinformatics tool in the human-first path. `xt tool exec <tool_id>` is the agent-safe submit command and also supports `--download <path>` when a local artifact is needed. `xt tool resolve <tool_id>` remains available as the low-level UUID and route lookup. `xt tool menus` returns a concise catalog with each tool title, `module_id`, `path`, and `route`, which is useful when `tool search` finds nothing helpful or when you want to shortlist tools for recommendation.
|
|
149
149
|
|
package/dist/base-command.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Command as
|
|
1
|
+
import{Command as s}from"@oclif/core";import{createErrorEnvelope as n,createSuccessEnvelope as a}from"./lib/envelope.js";import{XtzError as o}from"./lib/errors.js";import{resolveAgent as u}from"./lib/storage.js";class l extends s{async getProfile(t){return u(t)}async getAgent(t){return this.getProfile(t)}print(t,e,i,r){if(t.json){if(r){this.log(JSON.stringify(a(r.profile,r.command??this.getCommandName(),e),null,2));return}this.log(JSON.stringify(e,null,2));return}this.log(i)}async catch(t){if(this.isJsonOutputRequested()){const e=await this.getProfile(this.readProfileFlagFromArgv());this.log(JSON.stringify(n(e,this.getCommandName(),t),null,2)),this.exit(1)}throw t instanceof o&&this.error(t.message,{exit:1}),t}warnIfLegacyPlotCommand(){if(!this.id?.startsWith("plot:")||this.argv.includes("--json"))return;const t=this.id.replaceAll(":"," "),e=t.replace(/^plot\b/,"tool");this.warn(`\`xt ${t}\` \u5DF2\u517C\u5BB9\u4FDD\u7559\uFF0C\u5EFA\u8BAE\u6539\u7528 \`xt ${e}\``)}warnIfLegacyAuthCommand(){if(!this.id?.startsWith("auth:")||this.argv.includes("--json"))return;const t=this.id.replaceAll(":"," "),e=t.replace(/^auth /,"");this.warn(`\`xt ${t}\` \u5DF2\u517C\u5BB9\u4FDD\u7559\uFF0C\u5EFA\u8BAE\u6539\u7528 \`xt ${e}\``)}getCommandName(){return this.id?.replaceAll(":"," ")??"unknown"}isJsonOutputRequested(){return this.argv.includes("--json")}readProfileFlagFromArgv(){for(let t=0;t<this.argv.length;t+=1){const e=this.argv[t];if((e==="--profile"||e==="--agent")&&this.argv[t+1])return this.argv[t+1];if(e.startsWith("--profile="))return e.slice(10);if(e.startsWith("--agent="))return e.slice(8)}}}export{l as XtzCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Flags as
|
|
1
|
+
import{Flags as h}from"@oclif/core";import{XtzCommand as d}from"../../base-command.js";import{globalFlags as F}from"../../lib/flags.js";import{formatTokenPreview as p,startLoginAuth as g}from"../../lib/auth.js";import{loginAll as w}from"../../lib/login-flow.js";import{getTokenPath as k}from"../../lib/storage.js";class i extends d{static description="Authorize and store the current profile token";static flags={...F,open:h.boolean({allowNo:!0,default:!0,description:"Open the login page in a Playwright browser"}),wait:h.boolean({allowNo:!0,default:!0,description:"Wait until the browser login token is captured before exiting"})};async run(){this.warnIfLegacyAuthCommand();const{flags:t}=await this.parse(i),e=await this.getProfile(t.profile),r=t.open&&this.shouldWait(t),u=r?await w(e,t.open,({auth:a,phase:s})=>{if(!t.json){if(s==="auth_started"){this.log(a.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u767B\u5F55\u9875\u9762\uFF0C\u7B49\u5F85\u767B\u5F55\u5B8C\u6210...":`\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u767B\u5F55\u9875\u9762: ${a.linkUrl}`);return}if(s==="token_saved"){const l=p(a.token);this.log(`\u5DF2\u8BB0\u5F55 token: ${a.tokenPath}${l?` (${l})`:""}`);return}this.log("\u767B\u5F55\u5DF2\u786E\u8BA4\u3002")}}):{auth:await g(e)},o=!!u.auth.token,n=p(u.auth.token);this.print(t,{agent:e,authorization_pending:!o,authorized:o,browser_opened:u.auth.browserOpened,link_url:u.auth.linkUrl,token_preview:n,token_path:u.auth.tokenPath,token_saved:o,wait:r},this.formatLoginText({agent:e,authorized:o,browserOpened:u.auth.browserOpened,linkUrl:u.auth.linkUrl,tokenPreview:n}),{profile:e})}shouldWait(t){return this.hasExplicitWaitFlag()?t.wait:!t.json}hasExplicitWaitFlag(){return this.argv.includes("--wait")||this.argv.includes("--no-wait")}formatLoginText(t){const e=[`profile: ${t.agent}`,`token: ${k(t.agent)}`,`authorized: ${t.authorized}`,`token_saved: ${t.authorized}`];return t.authorized?(t.tokenPreview&&e.push(`token_preview: ${t.tokenPreview}`),e.join(`
|
|
2
2
|
`)):(e.push(t.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u767B\u5F55\u9875\u9762\uFF0C\u8BF7\u5B8C\u6210\u767B\u5F55\u540E\u8FD0\u884C `xt status`\u3002":`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t.linkUrl}`),e.join(`
|
|
3
|
-
`))}}export{
|
|
3
|
+
`))}}export{i as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{XtzCommand as
|
|
1
|
+
import{XtzCommand as r}from"../../base-command.js";import{globalFlags as i}from"../../lib/flags.js";import{deleteToken as n,getTokenPath as e}from"../../lib/storage.js";class a extends r{static description="Delete the stored token for the current profile";static flags={...i};async run(){this.warnIfLegacyAuthCommand();const{flags:o}=await this.parse(a),t=await this.getProfile(o.profile),s=await n(t);this.print(o,{agent:t,removed:s,token_path:e(t)},s?`\u5DF2\u5220\u9664 token: ${e(t)}`:`\u672A\u627E\u5230 token: ${e(t)}`,{profile:t})}}export{a as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{XtzCommand as
|
|
2
|
-
`)}}export{i as default};
|
|
1
|
+
import{XtzCommand as n}from"../../base-command.js";import{XtzError as l}from"../../lib/errors.js";import{checkToken as d,formatTokenPreview as c}from"../../lib/auth.js";import{globalFlags as h}from"../../lib/flags.js";import{getTokenPath as p,loadToken as f}from"../../lib/storage.js";class i extends n{static description="Show token auth status for the current profile";static flags={...h};async run(){this.warnIfLegacyAuthCommand();const{flags:e}=await this.parse(i),o=await this.getProfile(e.profile),s=p(o),a=await f(o),r=c(a),t=a?await this.resolveAuthorization(o,a):{authorized:!1,reason:"missing_token",toolProducts:[]},u=this.resolveDefaultToolProduct(t.toolProducts);this.print(e,{agent:o,authorized:t.authorized,reason:t.reason,tool_product:u??null,tool_product_title:u?.title??null,tool_product_uuid:u?.uuid??null,tool_products:t.toolProducts,token_preview:r,token_path:s,token_saved:!!a},this.formatStatusText(o,s,!!a,r,t),{profile:o})}async resolveAuthorization(e,o){try{return{authorized:!0,reason:null,toolProducts:await d(e,o)}}catch(s){if(!(s instanceof l)||!s.message.includes("\u6388\u6743\u5DF2\u8FC7\u671F"))throw s;return{authorized:!1,reason:"expired_token",toolProducts:[]}}}formatStatusText(e,o,s,a,r){const t=[`profile: ${e}`,`authorized: ${r.authorized}`,`token: ${o}`,`token_saved: ${s}`];a&&t.push(`token_preview: ${a}`);const u=this.resolveDefaultToolProduct(r.toolProducts);return u&&t.push(`tool_product: ${u.title||"-"} (${u.uuid})`),r.toolProducts.length>1&&t.push(`tool_products: ${r.toolProducts.length}`),!r.authorized&&r.reason&&(t.push(`reason: ${r.reason}`),t.push(`run: xt login --profile ${e}`)),t.join(`
|
|
2
|
+
`)}resolveDefaultToolProduct(e){return e.find(o=>o.status==="normal")??e[0]}}export{i as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as i,Flags as
|
|
1
|
+
import{Args as i,Flags as r}from"@oclif/core";import{XtzCommand as o}from"../../base-command.js";import{resolveXiantaoConfigValue as n}from"../../lib/config.js";class s extends o{static description="Get a resolved config value";static args={key:i.string({description:"Config key, such as base-url or login-url",required:!0})};static flags={json:r.boolean({default:!1,description:"Output JSON"})};async run(){const{args:t,flags:e}=await this.parse(s),a=await n(t.key);this.print(e,a,a.value)}}export{s as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Args as
|
|
2
|
-
`)}}export{
|
|
1
|
+
import{Args as o,Flags as u}from"@oclif/core";import{XtzCommand as n}from"../../base-command.js";import{resolveXiantaoConfigValue as l,setXiantaoConfigValue as c}from"../../lib/config.js";class i extends n{static description="Set a config value";static args={key:o.string({description:"Config key, such as base-url or login-url",required:!0}),value:o.string({description:"Config value",required:!0})};static flags={json:u.boolean({default:!1,description:"Output JSON"})};async run(){const{args:a,flags:t}=await this.parse(i),e=await c(a.key,a.value),s=await l(e.key),r={...e,active_source:s.source,active_value:s.value};this.print(t,r,this.formatSetText(e,s))}formatSetText(a,t){const e=[`${a.key}: ${a.value}`,`path: ${a.path}`];return(t.source!=="config"||t.value!==a.value)&&e.push(`active: ${t.value} (${t.source})`),e.join(`
|
|
2
|
+
`)}}export{i as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as
|
|
1
|
+
import{Args as d,Flags as n}from"@oclif/core";import{XtzCommand as m}from"../../base-command.js";import{getAuthContext as f}from"../../lib/auth.js";import{deleteXiantaoHistoryRecord as l,findXiantaoHistoryRecordByFuid as c}from"../../lib/history.js";import{globalFlags as u}from"../../lib/flags.js";class o extends m{static description="Delete a Xiantao history record";static args={fuid:d.string({description:"History record fuid",required:!0})};static flags={...u,token:n.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"})};async run(){const{args:t,flags:i}=await this.parse(o),a=await this.getProfile(i.profile),r=await f(a,i.token),e=await c(r,t.fuid);await l(r,{fuid:t.fuid});const s={agent:a,fuid:t.fuid,module_id:e?.module_id?.trim()??"",module_name:e?.module_name?.trim()??"",name:e?.name?.trim()??""};this.print(i,s,t.fuid,{command:"history delete",profile:a})}}export{o as default};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{Args as
|
|
2
|
-
${this.buildMultipleDownloadsMessage(t)}`)}if(t.length===1)return t[0]}pickDownloadItemByIndex(t,e){if(!Number.isInteger(e)||e<1||e>t.length)throw new
|
|
3
|
-
${this.buildMultipleDownloadsMessage(t)}`);return t[e-1]}pickDownloadItemByLabel(t,e){const i=e.trim().toLowerCase();if(!i)return;const
|
|
4
|
-
${this.buildMultipleDownloadsMessage(t)}`)}inferDeviceFromOutputPath(t){const e=t?.trim().split(".").pop()?.toLowerCase();return e?this.normalizeDevice(e):void 0}normalizeDevice(t){const e=t?.trim().toLowerCase();if(e)return e==="tif"?"tiff":e==="jpg"?"jpeg":e}buildMultipleDownloadsMessage(t){const e=["\u5F53\u524D\u5386\u53F2\u8BB0\u5F55\u5305\u542B\u591A\u4E2A\u53EF\u4E0B\u8F7D\u6587\u4EF6\uFF0C\u8BF7\u4F7F\u7528 `--item`\u3001`--label` \u6216 `--device` \u660E\u786E\u9009\u62E9\u3002","\u53EF\u9009\u4E0B\u8F7D\u9879\uFF1A"];return t.forEach((i,
|
|
5
|
-
`)}}export{
|
|
1
|
+
import{Args as c,Flags as l}from"@oclif/core";import{XtzCommand as p}from"../../base-command.js";import{getAuthContext as w}from"../../lib/auth.js";import{XIANTAO_HISTORY_UUID as F}from"../../lib/constants.js";import{downloadToPath as h}from"../../lib/download.js";import{XtzError as a}from"../../lib/errors.js";import{fetchXiantaoHistoryDownloadButtons as D,findXiantaoHistoryRecordByFuid as g}from"../../lib/history.js";import{globalFlags as E}from"../../lib/flags.js";import{resolveXiantaoDownload as b}from"../../lib/xiantao-plot.js";class s extends p{static description="Download a file from a Xiantao history record";static args={fuid:c.string({description:"History record fuid",required:!0})};static flags={...E,device:l.string({description:"Preferred device/format, e.g. pdf, xlsx, zip"}),item:l.integer({description:"Select a download item by its 1-based index from the listed results"}),label:l.string({description:"Select a download item by its label"}),output:l.string({char:"o",description:"Destination path; defaults to ~/Downloads/<file name>"}),token:l.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"})};async run(){const{args:t,flags:e}=await this.parse(s),i=await this.getProfile(e.profile),u=await w(i,e.token),o=await g(u,t.fuid);if(e.item!==void 0&&e.label)throw new a("`--item` \u4E0E `--label` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");if(!o?.module_id?.trim())throw new a(`\u672A\u627E\u5230 fuid \u4E3A ${t.fuid} \u7684\u5386\u53F2\u8BB0\u5F55\u3002`);const d=await D(u,{fuid:t.fuid}),r=this.pickDownloadItem(d.downloads,{device:e.device,item:e.item,label:e.label,outputPath:e.output});if(!r)throw new a(this.buildMultipleDownloadsMessage(d.downloads));const n=await b(u,{item:r,moduleId:o.module_id.trim(),uuid:F}),m=await h(n.url,e.output),f={agent:i,device:r.device,endpoint:r.endpoint,file_name:n.fileName??r.label,fuid:t.fuid,module_id:o.module_id.trim(),output:m,url:n.url};this.print(e,f,m,{command:"history download",profile:i})}pickDownloadItem(t,e){if(e.item!==void 0)return this.pickDownloadItemByIndex(t,e.item);if(e.label)return this.pickDownloadItemByLabel(t,e.label);const i=this.normalizeDevice(e.device??this.inferDeviceFromOutputPath(e.outputPath));if(i){const u=t.filter(o=>this.normalizeDevice(o.device)===i);if(u.length===1)return u[0];if(u.length>1)throw new a(`\u4E0B\u8F7D\u683C\u5F0F ${i} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--item\` \u6216 \`--label\` \u7CBE\u786E\u9009\u62E9\u3002
|
|
2
|
+
${this.buildMultipleDownloadsMessage(t)}`)}if(t.length===1)return t[0]}pickDownloadItemByIndex(t,e){if(!Number.isInteger(e)||e<1||e>t.length)throw new a(`\u4E0B\u8F7D\u9879\u5E8F\u53F7 ${e} \u65E0\u6548\uFF0C\u53EF\u9009\u8303\u56F4\u4E3A 1-${t.length}\u3002
|
|
3
|
+
${this.buildMultipleDownloadsMessage(t)}`);return t[e-1]}pickDownloadItemByLabel(t,e){const i=e.trim().toLowerCase();if(!i)return;const u=t.filter(o=>o.label.trim().toLowerCase()===i);if(u.length===1)return u[0];if(u.length>1)throw new a(`\u4E0B\u8F7D\u9879\u540D\u79F0 ${e} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--item\` \u7CBE\u786E\u9009\u62E9\u3002
|
|
4
|
+
${this.buildMultipleDownloadsMessage(t)}`)}inferDeviceFromOutputPath(t){const e=t?.trim().split(".").pop()?.toLowerCase();return e?this.normalizeDevice(e):void 0}normalizeDevice(t){const e=t?.trim().toLowerCase();if(e)return e==="tif"?"tiff":e==="jpg"?"jpeg":e}buildMultipleDownloadsMessage(t){const e=["\u5F53\u524D\u5386\u53F2\u8BB0\u5F55\u5305\u542B\u591A\u4E2A\u53EF\u4E0B\u8F7D\u6587\u4EF6\uFF0C\u8BF7\u4F7F\u7528 `--item`\u3001`--label` \u6216 `--device` \u660E\u786E\u9009\u62E9\u3002","\u53EF\u9009\u4E0B\u8F7D\u9879\uFF1A"];return t.forEach((i,u)=>{e.push(`${u+1}. ${i.label} (device=${i.device}, endpoint=${i.endpoint})`)}),e.join(`
|
|
5
|
+
`)}}export{s as default};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Flags as
|
|
2
|
-
`);for(const t of a)e.push(""),e.push(`${t.module_id||"-"} ${t.module_name||"-"}`),e.push(` status: ${t.status}`),e.push(` time: ${t.time||"-"}`),e.push(` type: ${t.type||"-"}`),e.push(` fuid: ${t.fuid||"-"}`),t.name&&e.push(` name: ${t.name}`);return
|
|
3
|
-
`)}}export{
|
|
1
|
+
import{Flags as u}from"@oclif/core";import{XtzCommand as m}from"../../base-command.js";import{getAuthContext as p}from"../../lib/auth.js";import{fetchXiantaoHistoryRecords as l,getXiantaoHistoryRecordStatus as d}from"../../lib/history.js";import{globalFlags as f}from"../../lib/flags.js";class n extends m{static description="List Xiantao history records";static flags={...f,page:u.integer({default:1,description:"History page number",min:1}),token:u.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"})};async run(){const{flags:i}=await this.parse(n),r=await this.getProfile(i.profile),o=await p(r,i.token),a=await l(o,{currentPage:i.page}),s=a.records.map(t=>({fuid:t.fuid?.trim()??"",id:typeof t.id=="number"?t.id:null,module_id:t.module_id?.trim()??"",module_name:t.module_name?.trim()??"",name:t.name?.trim()??"",status:d(t),time:t.time?.trim()??"",type:t.type?.trim()??""})),e={agent:r,current_page:a.currentPage,info:a.info,last_page:a.lastPage,per_page:a.perPage,records:s,total:a.total};this.print(i,e,this.formatHistoryText(a.currentPage,a.lastPage,a.total,s,a.info),{command:"history list",profile:r})}formatHistoryText(i,r,o,a,s){const e=[`\u5386\u53F2\u8BB0\u5F55 ${o} \u6761\uFF0C\u7B2C ${i}/${r} \u9875`];if(a.length===0)return e.push(""),e.push("\u6682\u65E0\u5386\u53F2\u8BB0\u5F55"),e.join(`
|
|
2
|
+
`);for(const t of a)e.push(""),e.push(`${t.module_id||"-"} ${t.module_name||"-"}`),e.push(` status: ${t.status}`),e.push(` time: ${t.time||"-"}`),e.push(` type: ${t.type||"-"}`),e.push(` fuid: ${t.fuid||"-"}`),t.name&&e.push(` name: ${t.name}`);return s&&(e.push(""),e.push(s)),e.join(`
|
|
3
|
+
`)}}export{n as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as
|
|
1
|
+
import{Args as s,Flags as d}from"@oclif/core";import{XtzCommand as m}from"../../base-command.js";import{getAuthContext as f}from"../../lib/auth.js";import{findXiantaoHistoryRecordByFuid as c,renameXiantaoHistoryRecord as l}from"../../lib/history.js";import{globalFlags as u}from"../../lib/flags.js";class e extends m{static description="Rename a Xiantao history record";static args={fuid:s.string({description:"History record fuid",required:!0}),name:s.string({description:"New history record name",required:!0})};static flags={...u,token:d.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"})};async run(){const{args:a,flags:t}=await this.parse(e),i=await this.getProfile(t.profile),r=await f(i,t.token),o=await c(r,a.fuid);await l(r,{fuid:a.fuid,newName:a.name});const n={agent:i,fuid:a.fuid,module_id:o?.module_id?.trim()??"",module_name:o?.module_name?.trim()??"",name:a.name};this.print(t,n,`${a.fuid} -> ${a.name}`,{command:"history rename",profile:i})}}export{e as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as
|
|
1
|
+
import{Args as t,Flags as d}from"@oclif/core";import{XtzCommand as n}from"../../base-command.js";import{getAuthContext as u}from"../../lib/auth.js";import{globalFlags as l}from"../../lib/flags.js";import{saveXiantaoOutput as m}from"../../lib/xiantao-plot.js";class s extends n{static description="Save a direct analysis result to history";static args={fuid:t.string({description:"Result fuid returned by tool exec",required:!0}),uuid:t.string({description:"Tool UUID used in the analysis",required:!0}),moduleId:t.string({description:"Module id, e.g. gokegg_analysis",required:!0}),name:t.string({description:"Name to save the record as",required:!0})};static flags={...l,token:d.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"})};async run(){const{args:e,flags:i}=await this.parse(s),a=await this.getProfile(i.profile),o=await u(a,i.token);await m(o,{fuid:e.fuid,moduleId:e.moduleId,name:e.name,uuid:e.uuid});const r={agent:a,fuid:e.fuid,module_id:e.moduleId,name:e.name,uuid:e.uuid};this.print(i,r,`\u5DF2\u4FDD\u5B58: ${e.name}`,{command:"history save",profile:a})}}export{s as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Args as
|
|
1
|
+
import{Args as u,Flags as d}from"@oclif/core";import{XtzCommand as f}from"../../base-command.js";import{getAuthContext as l}from"../../lib/auth.js";import{fetchXiantaoHistoryDownloadButtons as c}from"../../lib/history.js";import{globalFlags as g}from"../../lib/flags.js";class e extends f{static description="View downloadable files for a Xiantao history record";static args={fuid:u.string({description:"History record fuid",required:!0})};static flags={...g,token:d.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"})};async run(){const{args:o,flags:t}=await this.parse(e),a=await this.getProfile(t.profile),i=await l(a,t.token),r=await c(i,{fuid:o.fuid}),s={agent:a,downloads:r.downloads,fuid:o.fuid},n=this.formatText(o.fuid,r.downloads);this.print(t,s,n,{command:"history view",profile:a})}formatText(o,t){if(t.length===0)return`fuid: ${o}
|
|
2
2
|
|
|
3
|
-
\u6682\u65E0\u53EF\u4E0B\u8F7D\u6587\u4EF6`;const
|
|
4
|
-
`)}}export{
|
|
3
|
+
\u6682\u65E0\u53EF\u4E0B\u8F7D\u6587\u4EF6`;const a=[`fuid: ${o}`,"",`\u53EF\u4E0B\u8F7D\u6587\u4EF6\uFF08\u5171 ${t.length} \u9879\uFF09\uFF1A`];return t.forEach((i,r)=>{a.push(` ${r+1}. ${i.label} (device=${i.device})`)}),a.join(`
|
|
4
|
+
`)}}export{e as default};
|
package/dist/commands/login.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"./auth/login.js";class t extends e{}export{t as default};
|
package/dist/commands/logout.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"./auth/logout.js";class t extends e{}export{t as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as
|
|
1
|
+
import{Args as i,Flags as r}from"@oclif/core";import{XtzCommand as e}from"../../base-command.js";import{downloadToPath as l}from"../../lib/download.js";class t extends e{static description="Download a generated tool result URL to a local file";static args={url:i.string({description:"Direct file URL returned by a tool command",required:!0})};static flags={json:r.boolean({default:!1,description:"Output JSON"}),output:r.string({char:"o",description:"Destination path; defaults to ~/Downloads/<file name>"})};async run(){this.warnIfLegacyPlotCommand();const{args:a,flags:o}=await this.parse(t),s=await l(a.url,o.output);this.print(o,{path:s,url:a.url},s)}}export{t as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as
|
|
1
|
+
import{Args as g,Flags as l}from"@oclif/core";import{XtzCommand as c}from"../../base-command.js";import{getAuthContext as m}from"../../lib/auth.js";import{globalFlags as u}from"../../lib/flags.js";import{buildArgsMainFromSchema as f,buildArgsSpecificFromSchema as p}from"../../lib/plot-schema.js";import{fetchAllPlotArgs as h}from"../../lib/xiantao.js";class s extends c{static description="Fetch raw dynamic args for a Xiantao tool via public.args.fetch-all";static args={moduleId:g.string({description:"Tool id, e.g. violin_flat",required:!0})};static flags={...u,token:l.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),uuid:l.string({description:"Tool UUID used in the public.args.fetch-all payload",required:!0})};async run(){this.warnIfLegacyPlotCommand();const{args:r,flags:i}=await this.parse(s),t=await this.getProfile(i.profile),d=await m(t,i.token),a=await h(d,{moduleId:r.moduleId,uuid:i.uuid}),n=f(a.args_main),e=a.args_specific??[],o={agent:t,args_data:a.args_data??[],args_main:a.args_main??[],args_main_defaults:n,args_specific:e,args_specific_defaults:p(e),duid:a.id?.duid??"",module_id:r.moduleId,notice:a.notice??"",uuid:i.uuid};this.print(i,o,JSON.stringify(o,null,2),{profile:t})}}export{s as default};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Flags as
|
|
1
|
+
import{Flags as h}from"@oclif/core";import{XtzCommand as d}from"../../base-command.js";import{formatTokenPreview as p,startLoginAuth as F}from"../../lib/auth.js";import{globalFlags as g}from"../../lib/flags.js";import{loginAll as w}from"../../lib/login-flow.js";import{getTokenPath as k}from"../../lib/storage.js";class i extends d{static description="Authorize and store the current profile token";static flags={...g,open:h.boolean({allowNo:!0,default:!0,description:"Open the login page in a Playwright browser"}),wait:h.boolean({allowNo:!0,default:!0,description:"Wait until the browser login token is captured before exiting"})};async run(){this.warnIfLegacyPlotCommand();const{flags:t}=await this.parse(i),e=await this.getProfile(t.profile),r=t.open&&this.shouldWait(t),u=r?await w(e,t.open,({auth:a,phase:s})=>{if(!t.json){if(s==="auth_started"){this.log(a.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u767B\u5F55\u9875\u9762\uFF0C\u7B49\u5F85\u767B\u5F55\u5B8C\u6210...":`\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u767B\u5F55\u9875\u9762: ${a.linkUrl}`);return}if(s==="token_saved"){const l=p(a.token);this.log(`\u5DF2\u8BB0\u5F55 token: ${a.tokenPath}${l?` (${l})`:""}`);return}this.log("\u767B\u5F55\u5DF2\u786E\u8BA4\u3002")}}):{auth:await F(e)},o=!!u.auth.token,n=p(u.auth.token);this.print(t,{agent:e,authorization_pending:!o,authorized:o,browser_opened:u.auth.browserOpened,link_url:u.auth.linkUrl,token_preview:n,token_path:u.auth.tokenPath,token_saved:o,wait:r},this.formatLoginText({agent:e,authorized:o,browserOpened:u.auth.browserOpened,linkUrl:u.auth.linkUrl,tokenPreview:n}),{profile:e})}shouldWait(t){return this.hasExplicitWaitFlag()?t.wait:!t.json}hasExplicitWaitFlag(){return this.argv.includes("--wait")||this.argv.includes("--no-wait")}formatLoginText(t){const e=[`profile: ${t.agent}`,`token: ${k(t.agent)}`,`authorized: ${t.authorized}`,`token_saved: ${t.authorized}`];return t.authorized?(t.tokenPreview&&e.push(`token_preview: ${t.tokenPreview}`),e.join(`
|
|
2
2
|
`)):(e.push(t.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u767B\u5F55\u9875\u9762\uFF0C\u8BF7\u5B8C\u6210\u767B\u5F55\u540E\u8FD0\u884C `xt status`\u3002":`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t.linkUrl}`),e.join(`
|
|
3
|
-
`))}}export{
|
|
3
|
+
`))}}export{i as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as u,Flags as
|
|
1
|
+
import{Args as u,Flags as s}from"@oclif/core";import{XtzCommand as l}from"../../base-command.js";import{getAuthContext as d}from"../../lib/auth.js";import{globalFlags as m}from"../../lib/flags.js";import{resolveXiantaoToolProductUuid as c}from"../../lib/storage.js";import{fetchToolMenu as f}from"../../lib/xiantao.js";class a extends l{static description="Fetch Xiantao menu metadata for a tool menu UUID";static args={menuUuid:u.string({description:"Tool menu UUID from /tool/menus/:uuid",required:!0})};static flags={...m,token:s.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:s.string({description:"tool_product_uuid used in the menu filter payload; defaults to the current user product UUID"})};async run(){this.warnIfLegacyPlotCommand();const{args:n,flags:t}=await this.parse(a),o=await this.getProfile(t.profile),e=await d(o,t.token),i=await c(t.toolProductUuid,e),r=await f(e,n.menuUuid,i);this.print(t,{agent:o,menu:r,tool_product_uuid:i},JSON.stringify(r,null,2),{profile:o})}}export{a as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Flags as
|
|
1
|
+
import{Flags as s}from"@oclif/core";import{XtzCommand as n}from"../../base-command.js";import{getAuthContext as l}from"../../lib/auth.js";import{globalFlags as u}from"../../lib/flags.js";import{resolveXiantaoToolProductUuid as d}from"../../lib/storage.js";import{fetchToolMenus as c}from"../../lib/xiantao.js";class a extends n{static description="Fetch all raw Xiantao menu metadata for a tool product";static flags={...u,token:s.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:s.string({description:"tool_product_uuid used in the menu filter payload; defaults to the current user product UUID"})};async run(){this.warnIfLegacyPlotCommand();const{flags:t}=await this.parse(a),o=await this.getProfile(t.profile),e=await l(o,t.token),r=await d(t.toolProductUuid,e),i=await c(e,r);this.print(t,{agent:o,menus:i,tool_product_uuid:r},JSON.stringify(i,null,2),{profile:o})}}export{a as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Flags as
|
|
2
|
-
`)}}export{
|
|
1
|
+
import{Flags as s}from"@oclif/core";import{XtzCommand as u}from"../../base-command.js";import{getAuthContext as n}from"../../lib/auth.js";import{globalFlags as l}from"../../lib/flags.js";import{resolveXiantaoToolProductUuid as d}from"../../lib/storage.js";import{fetchToolMenus as p,listToolMenuSummaries as f}from"../../lib/xiantao.js";class a extends u{static description="List Xiantao tools with title, tool id, path, and route for a product";static flags={...l,token:s.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:s.string({description:"tool_product_uuid used in the menu filter payload; defaults to the current user product UUID"})};async run(){this.warnIfLegacyPlotCommand();const{flags:o}=await this.parse(a),t=await this.getProfile(o.profile),e=await n(t,o.token),i=await d(o.toolProductUuid,e),r=f(await p(e,i));this.print(o,{agent:t,menus:r,tool_product_uuid:i},this.formatMenusText(r),{profile:t})}formatMenusText(o){if(o.length===0)return"\u672A\u627E\u5230\u53EF\u7528\u5DE5\u5177";const t=[`\u5171 ${o.length} \u4E2A\u5DE5\u5177`];for(const e of o)t.push(""),t.push(`${e.title}`),t.push(` ${e.module_id}`),e.path&&t.push(` ${e.path}`),t.push(` ${e.route}`);return t.join(`
|
|
2
|
+
`)}}export{a as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as
|
|
1
|
+
import{Args as s,Flags as d}from"@oclif/core";import{XtzCommand as l}from"../../base-command.js";import{getAuthContext as n}from"../../lib/auth.js";import{globalFlags as p}from"../../lib/flags.js";import{resolveXiantaoToolProductUuid as m}from"../../lib/storage.js";import{resolveToolMenuByCode as c}from"../../lib/xiantao.js";class r extends l{static description="Resolve a Xiantao tool id to its UUID and route";static args={moduleId:s.string({description:"Tool id, e.g. violin_flat",required:!0})};static flags={...p,token:d.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:d.string({description:"tool_product_uuid from the /products/apply/:uuid URL; defaults to the current user product UUID"})};async run(){this.warnIfLegacyPlotCommand();const{args:i,flags:o}=await this.parse(r),e=await this.getProfile(o.profile),u=await n(e,o.token),a=await m(o.toolProductUuid,u),t=await c(u,a,i.moduleId);this.print(o,{agent:e,module_id:i.moduleId,path:t.path,route:t.route,title:t.title,tool_product_uuid:a,uuid:t.uuid},JSON.stringify({module_id:i.moduleId,path:t.path,route:t.route,title:t.title,tool_product_uuid:a,uuid:t.uuid},null,2),{profile:e})}}export{r as default};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{readFile as L}from"node:fs/promises";import{Args as
|
|
2
|
-
`)}formatAsyncHistoryText(
|
|
3
|
-
`)}formatAsyncHistoryDownloadText(
|
|
4
|
-
`)}async downloadResult(
|
|
5
|
-
${this.buildMultipleDownloadsMessage(
|
|
6
|
-
${this.buildMultipleDownloadsMessage(
|
|
7
|
-
${this.buildMultipleDownloadsMessage(
|
|
8
|
-
`)}validateDownloadFlags(
|
|
9
|
-
`)}buildCloudSelectionData(
|
|
1
|
+
import{readFile as L}from"node:fs/promises";import{Args as v,Flags as p}from"@oclif/core";import{XtzCommand as z}from"../../base-command.js";import{getAuthContext as k}from"../../lib/auth.js";import{XIANTAO_HISTORY_UUID as N}from"../../lib/constants.js";import{downloadToPath as g}from"../../lib/download.js";import{XtzChoiceRequiredError as X,XtzError as a}from"../../lib/errors.js";import{globalFlags as O,toolCloudFlags as j}from"../../lib/flags.js";import{fetchXiantaoHistoryDownloadButtons as J,getXiantaoHistoryRecordStatus as K,waitForLatestXiantaoHistoryRecord as q,waitForXiantaoHistoryRecordCompletion as V}from"../../lib/history.js";import{deepMerge as D,isJsonObject as P}from"../../lib/json.js";import{confirmPlotArgsMain as G,promptPlotArgsMain as Q,promptPlotCloudRecordSelection as Y,promptPlotFilePath as $,promptPlotInputSource as W,promptPlotMenuSelection as Z,promptPlotResultSelection as uu}from"../../lib/plot-interactive.js";import{uploadFile as ou}from"../../lib/plot.js";import{applySpecificOverrides as M,parseSetOverrides as eu,plotOverrideFlags as tu}from"../../lib/plot-options.js";import{buildArgsMainFromSchema as C,buildArgsSpecificFromSchema as x}from"../../lib/plot-schema.js";import{loadPlotArgsMainConfig as du,resolveXiantaoToolProductUuid as iu}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as b,findDefaultXiantaoRecord as S,listXiantaoUploadFields as B}from"../../lib/tool-inputs.js";import{fetchXiantaoCloudData as U}from"../../lib/xiantao-cloud.js";import{buildSubmitArgsData as lu,resolveXiantaoDownload as T,submitXiantaoPlot as ru,verifyXiantaoPlotUpload as au}from"../../lib/xiantao-plot.js";import{fetchAllPlotArgs as nu,fetchToolMenu as su,fetchToolMenus as cu,resolveToolMenuByCode as mu,updatePlotArgs as pu}from"../../lib/xiantao.js";class H extends z{resolveToolFileInputs(u,o){if(u&&o&&o.length>0)throw new a("FILE \u4E0E `--file` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");return u?[u]:o??[]}async prepareToolRun(u,o,e){this.validateInputSourceFlags(o,e);const t=await this.getProfile(e.profile),d=await k(t,e.token),i=await this.resolveModule(u,e,d),{moduleId:r,route:l,toolProductUuid:n,uuid:s}=i,c=await nu(d,{moduleId:r,uuid:s}),F=await this.resolveInputMode(c,{cloudRequested:!!(e.cloudDataId?.trim()||e.cloudFilter?.trim()||typeof e.cloudIndex=="number"||e.cloudKey?.trim()||e.cloudRecordFile||e.cloudRecordJson),demo:e.demo,fileInputs:o,interactive:e.interactive}),h=await du(r,e.config),I=D(h,eu(e.set));let f=c.args_main??[],w=c.args_specific??[],E=D(C(f),I),A=M(x(w),e.specific),m=F.mode==="cloud"?await this.resolveCloudInput(c,e,r,d,s):F.mode==="demo"?this.resolveDemoInput(c,r):F.mode==="record"?this.resolveRecordInput(c,r):await this.uploadAndVerify(t,F.fileInputs??[],{argsMain:E,argsData:c.args_data??[],moduleId:r,uuid:s},d);if(m.schema.length&&(f=m.schema,E=D(C(f),I)),m.input.kind==="cloud"){const _=await pu(d,{argsData:lu(m.duid,m.input),argsKey:m.input.cloud.key,argsMain:E,argsSpecific:A,moduleId:r,uuid:s}),y=b(_.args_data??[]);y&&(m={...m,input:{kind:"cloud",cloud:{key:y.key,label:y.label,record:this.normalizeCloudRecord(y.record)}}}),f=_.args_main??f,w=_.args_specific??w,E=D(C(f),I),A=M(x(w),e.specific)}return{agent:t,argsMain:E,argsSpecific:A,argsSpecificSchema:w,auth:d,duid:m.duid,input:m.input,inputMode:F.mode,inputSummary:this.summarizePreparedInput(m.input),moduleId:r,notice:c.notice??"",route:l,schema:f,toolProductUuid:n,uuid:s}}async executeToolRun(u,o,e){this.validateDownloadFlags(e);const t=await this.prepareToolRun(u,o,e);let d=t.argsMain;const i=t.argsSpecific;e.interactive&&(d=await Q(t.schema??[],d),await G(d));const r=Date.now(),l=await ru(t.auth,{argsMain:d,argsSpecific:i,duid:t.duid,input:t.input,moduleId:t.moduleId,route:t.route,uuid:t.uuid});if(l.asyncSubmission)return this.resolveAsyncToolRun(t,d,i,e,r,l.message);const n=e.download?await this.downloadResult(t.auth,{downloadPath:e.download,downloadItem:e.downloadItem,downloadLabel:e.downloadLabel,downloads:l.downloads,file:l.file,moduleId:t.moduleId,uuid:t.uuid}):await this.downloadInteractiveResults(t.auth,{choice:e.interactive?await uu({downloads:l.downloads,hasFile:!!l.file}):{downloadFile:!1,downloads:[]},file:l.file,moduleId:t.moduleId,uuid:t.uuid}),s=n[0];return{data:{agent:t.agent,args_main:d,args_specific:i,body:l.body,download_path:s,download_paths:n,downloads:l.downloads,duid:t.duid,file:l.file??null,history:null,history_hint:null,...t.inputSummary,mode:t.inputMode,module_id:t.moduleId,notice:t.notice,result_source:"direct",route:t.route,submission_message:l.message,tool_product_uuid:t.toolProductUuid,uuid:t.uuid},text:this.formatResultText(l,n,e.interactive&&!e.download)}}async resolveAsyncToolRun(u,o,e,t,d,i){const r=await q(u.auth,{intervalMs:3e3,moduleId:u.moduleId,submittedAtMs:d,timeoutMs:t.download?6e4:12e3}),l=r?this.toHistorySummary(r,u.moduleId):null;if(!t.download)return{data:{agent:u.agent,args_main:o,args_specific:e,body:"",download_path:void 0,download_paths:[],downloads:[],duid:u.duid,file:null,history:l,history_hint:this.buildHistoryHint(l),...u.inputSummary,mode:u.inputMode,module_id:u.moduleId,notice:u.notice,result_source:"history",route:u.route,submission_message:i,tool_product_uuid:u.toolProductUuid,uuid:u.uuid},text:this.formatAsyncHistoryText(l,i)};if(!r?.fuid?.trim())return{data:{agent:u.agent,args_main:o,args_specific:e,body:"",download_path:void 0,download_paths:[],downloads:[],duid:u.duid,file:null,history:l,history_hint:this.buildHistoryHint(l),...u.inputSummary,mode:u.inputMode,module_id:u.moduleId,notice:u.notice,result_source:"history",route:u.route,submission_message:i,tool_product_uuid:u.toolProductUuid,uuid:u.uuid},text:this.formatAsyncHistoryText(l,`${i}\uFF0C\u4F46\u6682\u672A\u5B9A\u4F4D\u5230\u5386\u53F2\u8BB0\u5F55\u3002`)};const n=await V(u.auth,{fuid:r.fuid.trim(),intervalMs:3e3,timeoutMs:6e4}),s=n?this.toHistorySummary(n,u.moduleId):l;if(!n?.fuid?.trim())return{data:{agent:u.agent,args_main:o,args_specific:e,body:"",download_path:void 0,download_paths:[],downloads:[],duid:u.duid,file:null,history:s,history_hint:this.buildHistoryHint(s),...u.inputSummary,mode:u.inputMode,module_id:u.moduleId,notice:u.notice,result_source:"history",route:u.route,submission_message:`${i}\uFF0C\u4F46\u7B49\u5F85\u5386\u53F2\u8BB0\u5F55\u5B8C\u6210\u8D85\u65F6\u3002`,tool_product_uuid:u.toolProductUuid,uuid:u.uuid},text:this.formatAsyncHistoryText(s,`${i}\uFF0C\u4F46\u7B49\u5F85\u5386\u53F2\u8BB0\u5F55\u5B8C\u6210\u8D85\u65F6\u3002`)};const{body:c,downloads:F,paths:h}=await this.downloadAsyncHistoryResult(u.auth,{downloadPath:t.download,downloadItem:t.downloadItem,downloadLabel:t.downloadLabel,fuid:n.fuid.trim(),moduleId:u.moduleId});return{data:{agent:u.agent,args_main:o,args_specific:e,body:c,download_path:h[0],download_paths:h,downloads:F,duid:u.duid,file:null,history:s,history_hint:this.buildHistoryHint(s),...u.inputSummary,mode:u.inputMode,module_id:u.moduleId,notice:u.notice,result_source:"history",route:u.route,submission_message:i,tool_product_uuid:u.toolProductUuid,uuid:u.uuid},text:this.formatAsyncHistoryDownloadText(s,h)}}async downloadAsyncHistoryResult(u,o){let e;for(let t=0;t<4;t+=1){const d=await J(u,{fuid:o.fuid});try{const i=await this.downloadResult(u,{downloadPath:o.downloadPath,downloadItem:o.downloadItem,downloadLabel:o.downloadLabel,downloads:d.downloads,moduleId:o.moduleId,uuid:N});return{body:d.body,downloads:d.downloads,paths:i}}catch(i){if(!(i instanceof a)||!this.isRetryableAsyncDownloadError(i)||t===3)throw i;e=i,await this.sleep(3e3)}}throw e??new a("\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5")}formatResultText(u,o,e){const t=[];if(u.file&&t.push(u.file),!u.file&&(u.downloads.length>0||u.body)&&t.push("\u5206\u6790\u5B8C\u6210"),!u.file&&!u.body&&u.downloads.length===0)return"\u63D0\u4EA4\u5B8C\u6210";if(u.downloads.length>0&&!e)for(const d of u.downloads)t.push(`${d.label} (${d.device})`);for(const d of o)t.push(d);return t.join(`
|
|
2
|
+
`)}formatAsyncHistoryText(u,o){const e=[o];return u&&e.push(`\u5386\u53F2\u8BB0\u5F55: ${u.fuid} (${u.status})`),e.push(this.buildHistoryHint(u)),e.join(`
|
|
3
|
+
`)}formatAsyncHistoryDownloadText(u,o){const e=[];u&&e.push(`\u5386\u53F2\u8BB0\u5F55: ${u.fuid} (${u.status})`);for(const t of o)e.push(t);return e.join(`
|
|
4
|
+
`)}async downloadResult(u,o){if(o.downloads.length>0){const e=this.pickDownloadItem(o.downloads,{item:o.downloadItem,label:o.downloadLabel,outputPath:o.downloadPath});if(!e)throw new a(this.buildMultipleDownloadsMessage(o.downloads));const t=await T(u,{item:e,moduleId:o.moduleId,uuid:o.uuid});return[await g(t.url,o.downloadPath)]}if(o.file)return[await g(o.file,o.downloadPath)];throw new a("\u5F53\u524D\u6A21\u5757\u672A\u8FD4\u56DE\u53EF\u4E0B\u8F7D\u6587\u4EF6\u3002")}pickDownloadItem(u,o){if(o.item!==void 0)return this.pickDownloadItemByIndex(u,o.item);if(o.label)return this.pickDownloadItemByLabel(u,o.label);const e=this.inferDownloadDevice(o.outputPath);if(e){const d=u.filter(i=>this.normalizeDevice(i.device)===e);if(d.length===1)return d[0];if(d.length>1)throw new a(`\u4E0B\u8F7D\u683C\u5F0F ${e} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--downloadItem\` \u6216 \`--downloadLabel\` \u7CBE\u786E\u9009\u62E9\u3002
|
|
5
|
+
${this.buildMultipleDownloadsMessage(u)}`)}const t=u.filter(d=>d.endpoint==="public.output.download-result");if(t.length===1)return t[0];if(u.length===1)return u[0]}pickDownloadItemByIndex(u,o){if(!Number.isInteger(o)||o<1||o>u.length)throw new a(`\u4E0B\u8F7D\u9879\u5E8F\u53F7 ${o} \u65E0\u6548\uFF0C\u53EF\u9009\u8303\u56F4\u4E3A 1-${u.length}\u3002
|
|
6
|
+
${this.buildMultipleDownloadsMessage(u)}`);return u[o-1]}pickDownloadItemByLabel(u,o){const e=o.trim().toLowerCase();if(!e)return;const t=u.filter(d=>d.label.trim().toLowerCase()===e);if(t.length===1)return t[0];if(t.length>1)throw new a(`\u4E0B\u8F7D\u9879\u540D\u79F0 ${o} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--downloadItem\` \u7CBE\u786E\u9009\u62E9\u3002
|
|
7
|
+
${this.buildMultipleDownloadsMessage(u)}`)}inferDownloadDevice(u){if(!u)return;const o=u.trim().split(".").pop()?.toLowerCase();if(o)return this.normalizeDevice(o)}normalizeDevice(u){const o=u.trim().toLowerCase();return o==="tif"?"tiff":o==="jpg"?"jpeg":o}buildMultipleDownloadsMessage(u){const o=["\u5F53\u524D\u6A21\u5757\u8FD4\u56DE\u591A\u4E2A\u53EF\u4E0B\u8F7D\u6587\u4EF6\uFF0C\u8BF7\u4F7F\u7528 `--downloadItem`\u3001`--downloadLabel` \u6216\u5E26\u76EE\u6807\u6269\u5C55\u540D\u7684 `--download` \u8DEF\u5F84\u660E\u786E\u9009\u62E9\u3002","\u53EF\u9009\u4E0B\u8F7D\u9879\uFF1A"];return u.forEach((e,t)=>{o.push(`${t+1}. ${e.label} (device=${e.device}, endpoint=${e.endpoint})`)}),o.join(`
|
|
8
|
+
`)}validateDownloadFlags(u){if(u.downloadItem!==void 0&&u.downloadLabel)throw new a("`--downloadItem` \u4E0E `--downloadLabel` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");if((u.downloadItem!==void 0||u.downloadLabel)&&!u.download)throw new a("`--downloadItem` \u548C `--downloadLabel` \u4EC5\u53EF\u4E0E `--download` \u4E00\u8D77\u4F7F\u7528\u3002")}toHistorySummary(u,o){const e=u.fuid?.trim();return e?{fuid:e,id:typeof u.id=="number"?u.id:null,module_id:u.module_id?.trim()||o,module_name:u.module_name?.trim()||"",name:u.name?.trim()||"",status:K(u),time:u.time?.trim()||"",type:u.type?.trim()||""}:null}buildHistoryHint(u){return u?`\u53EF\u4F7F\u7528 \`xt history download ${u.fuid} --device pdf\` \u6216 \`xt history list\` \u67E5\u770B\u7ED3\u679C`:"\u53EF\u4F7F\u7528 `xt history list` \u67E5\u770B\u4EFB\u52A1\u8FDB\u5EA6"}async downloadSelectedResults(u,o){const e=[];for(const t of o.downloads){const d=await T(u,{item:t,moduleId:o.moduleId,uuid:o.uuid});e.push(await g(d.url,d.fileName))}return e}async downloadInteractiveResults(u,o){const e=[];return o.choice.downloadFile&&o.file&&e.push(await g(o.file)),o.choice.downloads.length>0&&e.push(...await this.downloadSelectedResults(u,{downloads:o.choice.downloads,moduleId:o.moduleId,uuid:o.uuid})),e}isRetryableAsyncDownloadError(u){return u.message.includes("\u4E0B\u8F7D\u5931\u8D25")||u.message.includes("\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5")}async sleep(u){await new Promise(o=>setTimeout(o,u))}async resolveInputMode(u,o){if(o.demo)return this.hasDemoInput(u)?{mode:"demo"}:this.hasRecordInput(u)?{mode:"record"}:this.hasCloudInput(u)?{mode:"cloud"}:{mode:"demo"};if(o.fileInputs.length>0)return{fileInputs:o.fileInputs,mode:"upload"};if(o.cloudRequested)return{mode:"cloud"};if(this.hasRecordInput(u))return{mode:"record"};if(this.hasCloudInput(u))return{mode:"cloud"};if(!o.interactive)return{mode:"upload"};if(!this.hasDemoInput(u))return{fileInputs:[await $()],mode:"upload"};const e=await W();return e==="demo"?{mode:e}:{fileInputs:[await $()],mode:e}}resolveDemoInput(u,o){const e=u.id?.duid?.trim();if(!e)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE demo duid\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);const t=B(u.args_data??[]);if(!t.length||t.some(d=>!d.defaultUpload))throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE\u53EF\u7528\u7684 demo \u6587\u4EF6\u4FE1\u606F\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);return{duid:e,input:{kind:"upload",uploads:t.map(d=>({key:d.key,label:d.label,upload:{fileName:d.defaultUpload.fileName,fileOss:d.defaultUpload.fileOss,fileSize:d.defaultUpload.fileSize}}))},schema:[]}}hasDemoInput(u){if(!u.id?.duid?.trim())return!1;const o=B(u.args_data??[]);return o.length>0&&o.every(e=>!!e.defaultUpload)}async resolveCloudInput(u,o,e,t,d){const i=b(u.args_data??[]),r=o.cloudKey?.trim()||i?.key||"";if(!r)throw new a(`\u6A21\u5757 ${e} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u4E91\u7AEF\u6570\u636E\u53C2\u6570\uFF0C\u8BF7\u663E\u5F0F\u4F20\u5165 \`--cloudKey\`.`);const l=await this.resolveCloudRecord(t,o,{argsKey:r,defaultRecord:i?.record,moduleId:e,uuid:d});if(!l)throw new a(`\u6A21\u5757 ${e} \u672A\u8FD4\u56DE\u9ED8\u8BA4\u4E91\u7AEF\u6570\u636E\uFF0C\u8BF7\u4F20\u5165 \`--cloudRecordJson\` \u6216 \`--cloudRecordFile\`.`);return{duid:u.id?.duid?.trim()||"cloud",input:{kind:"cloud",cloud:{key:r,label:i?.label??"",record:this.normalizeCloudRecord(l)}},schema:[]}}resolveRecordInput(u,o){const e=u.id?.duid?.trim();if(!e)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE record duid\uFF0C\u65E0\u6CD5\u4F7F\u7528\u5386\u53F2\u8BB0\u5F55\u8F93\u5165\u3002`);const t=S(u.args_data??[]);if(!t)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u6570\u636E\u8BB0\u5F55\uFF0C\u65E0\u6CD5\u76F4\u63A5\u8FD0\u884C\u3002`);return{duid:e,input:{kind:"record",record:{key:t.key,label:t.label,moduleId:t.moduleId,moduleName:t.moduleName,recordId:t.recordId,recordName:t.recordName,time:t.time}},schema:[]}}hasRecordInput(u){return!!(u.id?.duid?.trim()&&S(u.args_data??[]))}hasCloudInput(u){return!!b(u.args_data??[])}async uploadAndVerify(u,o,e,t){const d=await this.uploadFiles(u,o,e.argsData??[],e.moduleId),i=await au(t,{argsMain:e.argsMain,moduleId:e.moduleId,uploads:d,uuid:e.uuid});return{duid:i.duid,input:{kind:"upload",uploads:d},schema:i.schema}}summarizePreparedInput(u){if(u.kind==="cloud")return{file_name:null,file_oss:null,file_size:null,input_cloud:this.summarizeCloudInput(u.cloud),input_record:null,input_uploads:null};if(u.kind==="record")return{file_name:null,file_oss:null,file_size:null,input_cloud:null,input_record:{label:u.record.label,module_id:u.record.moduleId,module_name:u.record.moduleName,record_id:u.record.recordId,record_name:u.record.recordName,time:u.record.time},input_uploads:null};const o=u.uploads.map(t=>({file_name:t.upload.fileName,file_oss:t.upload.fileOss,file_size:t.upload.fileSize,key:t.key,label:t.label})),e=o.length===1?o[0]:null;return{file_name:e?.file_name??null,file_oss:e?.file_oss??null,file_size:e?.file_size??null,input_cloud:null,input_record:null,input_uploads:o}}summarizeCloudInput(u){return{data_filter:this.readCloudOptionValue(u.record.data_filter),data_id:typeof u.record.data_id=="string"?u.record.data_id.trim():"",data_process:this.readCloudOptionValue(u.record.data_process),key:u.key,label:u.label,record:structuredClone(u.record),record_label:typeof u.record.label=="string"?u.record.label.trim():""}}readCloudOptionValue(u){return P(u)&&(typeof u.value=="string"?u.value.trim():"")||null}async resolveCloudRecord(u,o,e){return o.cloudRecordJson?this.parseCloudRecord(o.cloudRecordJson,"--cloudRecordJson"):o.cloudRecordFile?this.parseCloudRecord(await L(o.cloudRecordFile,"utf8"),"--cloudRecordFile"):o.cloudFilter?.trim()||o.cloudDataId?.trim()||typeof o.cloudIndex=="number"?this.resolveCloudRecordByQuery(u,o,e):e.defaultRecord}parseCloudRecord(u,o){let e;try{e=JSON.parse(u)}catch{throw new a(`${o} \u4E0D\u662F\u5408\u6CD5 JSON\u3002`)}if(!P(e))throw new a(`${o} \u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002`);return e}normalizeCloudRecord(u){const o={};for(const[e,t]of Object.entries(u))t!==void 0&&(o[e]=structuredClone(t));return(typeof o.type!="string"||!o.type.trim())&&(o.type="cloud"),o}validateInputSourceFlags(u,o){const e=!!(o.cloudRecordJson||o.cloudRecordFile),t=!!(o.cloudDataId?.trim()||o.cloudFilter?.trim()||typeof o.cloudIndex=="number"),d=e||t;if(o.cloudRecordJson&&o.cloudRecordFile)throw new a("`--cloudRecordJson` \u4E0E `--cloudRecordFile` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");if(e&&t)throw new a("\u663E\u5F0F\u4E91\u7AEF\u8BB0\u5F55\u53C2\u6570\u4E0D\u80FD\u4E0E `--cloudFilter` / `--cloudDataId` / `--cloudIndex` \u540C\u65F6\u4F7F\u7528\u3002");if(o.demo&&d)throw new a("`--demo` \u4E0D\u80FD\u4E0E\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u53C2\u6570\u540C\u65F6\u4F7F\u7528\u3002");if(u.length>0&&d)throw new a("`--file` \u4E0D\u80FD\u4E0E\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u53C2\u6570\u540C\u65F6\u4F7F\u7528\u3002")}async resolveCloudRecordByQuery(u,o,e){const t=await this.fetchCloudRecords(u,{argsKey:e.argsKey,filter:o.cloudFilter?.trim(),moduleId:e.moduleId,selectedRecord:e.defaultRecord,uuid:e.uuid});if(t.length===0){const i=o.cloudFilter?.trim();throw i?new a(`\u672A\u627E\u5230\u5339\u914D\u4E91\u7AEF\u6570\u636E: ${i}`):new a("\u5F53\u524D\u6A21\u5757\u6CA1\u6709\u53EF\u9009\u7684\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u3002")}const d=o.cloudDataId?.trim();if(d){const i=t.find(r=>(typeof r.data_id=="string"?r.data_id.trim():"")===d);if(!i)throw new a(`\u672A\u627E\u5230 data_id=${d} \u5BF9\u5E94\u7684\u4E91\u7AEF\u6570\u636E\u3002`);return i}if(typeof o.cloudIndex=="number"){const i=t[o.cloudIndex];if(!i)throw new a(`\u4E91\u7AEF\u6570\u636E\u7D22\u5F15\u8D85\u51FA\u8303\u56F4: ${o.cloudIndex}\uFF0C\u5F53\u524D\u5171\u6709 ${t.length} \u6761\u3002`);return i}if(t.length===1)return t[0];if(o.interactive)return this.normalizeCloudRecord(await Y(t));throw new X(this.buildCloudSelectionHint(t,o.cloudFilter?.trim()),this.buildCloudSelectionData(t,o.cloudFilter?.trim()))}async fetchCloudRecords(u,o){const e=await U(u,{argsKey:o.argsKey,currentPage:1,filter:o.filter,moduleId:o.moduleId,selectedRecord:o.selectedRecord,uuid:o.uuid}),t=e.records.map(d=>this.normalizeCloudRecord(d));for(let d=e.currentPage+1;d<=e.lastPage;d+=1){const i=await U(u,{argsKey:o.argsKey,currentPage:d,filter:o.filter,moduleId:o.moduleId,selectedRecord:o.selectedRecord,uuid:o.uuid});t.push(...i.records.map(r=>this.normalizeCloudRecord(r)))}return t}buildCloudSelectionHint(u,o){const e=[o?`\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E: ${o}`:"\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E","\u8BF7\u4F7F\u7528 `--cloudIndex` \u6216 `--cloudDataId` \u6307\u5B9A\u5176\u4E2D\u4E00\u6761\uFF1A"];return u.forEach((t,d)=>{const i=typeof t.data_id=="string"?t.data_id.trim():"",r=typeof t.label=="string"?t.label.trim():"";e.push(` [${d}] ${r||i}`)}),e.join(`
|
|
9
|
+
`)}buildCloudSelectionData(u,o){return{choices:u.map((e,t)=>{const d=typeof e.data_id=="string"?e.data_id.trim():"",i=typeof e.label=="string"?e.label.trim():"";return{data_id:d,index:t,label:i||d}}),filter:o??"",selection_type:"cloud_record"}}async uploadFiles(u,o,e,t){const d=B(e??[]),i=this.resolveUploadInputs(o,d,t),r=await k(u),l=[];for(const n of i){const s=await ou(r,n.filePath);l.push({key:n.key,label:n.label,upload:s})}return l}resolveUploadInputs(u,o,e){if(!o.length)throw new a(`\u6A21\u5757 ${e} \u672A\u68C0\u6D4B\u5230\u53EF\u4E0A\u4F20\u8F93\u5165\uFF0C\u4E0D\u80FD\u4F7F\u7528 \`--file\`\u3002`);if(!u.length)throw o.length===1?new a("\u901A\u7528\u6A21\u5F0F\u8BF7\u4F20\u5165 FILE / `--file <xlsx>`\uFF0C\u6216\u6539\u7528 `--demo`\u3002"):new a(`\u6A21\u5757 ${e} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(l=>l.key).join(", ")}`);const[t]=o;if(o.length===1&&u.length===1){const l=this.parseUploadFileInput(u[0]);if(l.key&&l.key!==t.key)throw new a(`\u6A21\u5757 ${e} \u4EC5\u652F\u6301\u4E0A\u4F20\u5B57\u6BB5 ${t.key}\uFF0C\u6536\u5230 ${l.key}\u3002`);return[{filePath:l.path,key:t.key,label:t.label}]}const d=new Map(o.map(l=>[l.key,l])),i=new Map;for(const l of u){const n=this.parseUploadFileInput(l);if(!n.key){if(o.length===1){if(i.has(t.key))throw new a(`\u6A21\u5757 ${e} \u4EC5\u9700\u8981 1 \u4E2A\u4E0A\u4F20\u6587\u4EF6\uFF0C\u6536\u5230\u91CD\u590D\u8F93\u5165\u3002`);i.set(t.key,n.path);continue}throw new a(`\u6A21\u5757 ${e} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(c=>c.key).join(", ")}`)}const s=d.get(n.key);if(!s)throw new a(`\u6A21\u5757 ${e} \u4E0D\u5B58\u5728\u4E0A\u4F20\u5B57\u6BB5 ${n.key}\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(c=>c.key).join(", ")}`);if(i.has(s.key))throw new a(`\u4E0A\u4F20\u5B57\u6BB5 ${s.key} \u91CD\u590D\u4F20\u5165\u3002`);i.set(s.key,n.path)}const r=o.filter(l=>l.required&&!i.has(l.key));if(r.length>0)throw new a(`\u6A21\u5757 ${e} \u7F3A\u5C11\u5FC5\u586B\u4E0A\u4F20\u5B57\u6BB5: ${r.map(l=>l.key).join(", ")}`);return o.flatMap(l=>{const n=i.get(l.key);return n?[{filePath:n,key:l.key,label:l.label}]:[]})}parseUploadFileInput(u){const o=u.trim();if(!o)throw new a("`--file` \u4E0D\u80FD\u4E3A\u7A7A\u3002");const e=o.indexOf("=");if(e<=0)return{path:o};const t=o.slice(0,e).trim(),d=o.slice(e+1).trim();if(!t||!d)throw new a("\u591A\u4E0A\u4F20\u6A21\u5757\u8BF7\u4F7F\u7528 `--file key=path`\u3002");return{key:t,path:d}}async resolveModule(u,o,e){const t=u?.trim(),d=o.route?.trim(),i=o.uuid?.trim(),r=await iu(o.toolProductUuid,e);if(!t){if(!o.interactive)throw new a("\u8BF7\u4F20\u5165 `module_id`\uFF0C\u6216\u4F7F\u7528 `--interactive --file <xlsx>` \u5148\u4ECE\u83DC\u5355\u9009\u62E9\u5DE5\u5177\u3002");const n=await Z(this.sortTopLevelMenus(await cu(e,r)));return{moduleId:n.code,route:d??n.route,toolProductUuid:r,uuid:i??n.uuid}}if(d&&i)return{moduleId:t,route:d,toolProductUuid:r,uuid:i};const l=o.menuUuid?.trim();if(l&&r){const n=await su(e,l,r),s=d??this.requireMenuRoute(n),c=n.code?.trim();if(c&&c!==t)throw new a(`\u83DC\u5355\u6A21\u5757 code \u4E3A ${c}\uFF0C\u4E0E\u4F20\u5165\u7684 module_id ${t} \u4E0D\u4E00\u81F4\u3002`);return{moduleId:t,route:s,toolProductUuid:r,uuid:i??l}}if(r){const n=await mu(e,r,t);return{moduleId:t,route:d??n.route,toolProductUuid:r,uuid:i??n.uuid}}if(!i)throw new a("\u901A\u7528\u6A21\u5F0F\u9700\u8981\u4F20\u5165 `--uuid`\uFF0C\u6216\u4F7F\u7528\u9ED8\u8BA4/\u663E\u5F0F `toolProductUuid` \u81EA\u52A8\u89E3\u6790\u3002");if(!d)throw new a("\u901A\u7528\u6A21\u5F0F\u9700\u8981\u4F20\u5165 `--route`\uFF0C\u6216\u4F7F\u7528\u9ED8\u8BA4/\u663E\u5F0F `toolProductUuid` \u81EA\u52A8\u89E3\u6790\u3002");return{moduleId:t,route:d,toolProductUuid:r,uuid:i}}sortTopLevelMenus(u){const o=["\u57FA\u7840\u7ED8\u56FE","\u8868\u8FBE\u5DEE\u5F02","\u529F\u80FD\u805A\u7C7B","\u4EA4\u4E92\u7F51\u7EDC","\u4E34\u5E8A\u610F\u4E49","\u5176\u4ED6"],e=new Map(o.map((t,d)=>[t,d]));return[...u].sort((t,d)=>{const i=e.get(t.title?.trim()??"")??Number.MAX_SAFE_INTEGER,r=e.get(d.title?.trim()??"")??Number.MAX_SAFE_INTEGER;return i-r})}requireMenuRoute(u){const o=u.route;if(typeof o!="string"||!o.trim())throw new a("\u83DC\u5355\u672A\u8FD4\u56DE\u53EF\u7528 route\uFF0C\u8BF7\u6539\u7528 `--route` \u663E\u5F0F\u6307\u5B9A\u3002");return o.trim()}}class R extends H{static description="Run a Xiantao bioinformatics tool";static args={tool:v.string({description:"Tool id; optional with --interactive to choose from menus"}),file:v.string({description:"Path to the local xlsx file; optional with --demo or --interactive"})};static flags={...O,...j,...tu,demo:p.boolean({default:!1,description:"Prefer the module default remote input returned by fetch-all instead of uploading a local file"}),file:p.string({description:"Path to the local xlsx file; repeat or use KEY=PATH for named upload fields",multiple:!0}),download:p.string({description:"Download the generated file or preferred analysis result to this local path after submission"}),downloadItem:p.integer({description:"Select a download item by its 1-based index when --download matches multiple results"}),downloadLabel:p.string({description:"Select a download item by its label when --download matches multiple results"}),interactive:p.boolean({default:!1,description:"Prompt for dynamic args before submitting the module"}),menuUuid:p.string({description:"Tool menu UUID from /products/apply/:toolProductUuid/analyse/:uuid"}),route:p.string({description:"Tool route like app1.violin_flat in generic mode"}),token:p.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:p.string({description:"tool_product_uuid used to auto-resolve module UUID and route in generic mode; defaults to the current user product UUID"}),uuid:p.string({description:"Tool UUID used in generic mode for fetch-all and verify-upload; optional when --toolProductUuid is provided"})};async run(){this.warnIfLegacyPlotCommand();const{args:u,flags:o}=await this.parse(R);if(o.interactive&&o.json)throw new a("`--interactive` \u4E0D\u80FD\u4E0E `--json` \u540C\u65F6\u4F7F\u7528\u3002");const e=this.resolveToolFileInputs(u.file,o.file),t=await this.executeToolRun(u.tool,e,o);this.print(o,t.data,t.text,{profile:t.data.agent})}}export{H as ToolRunCommandBase,R as default};
|
package/dist/commands/status.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import s from"./auth/status.js";class t extends s{}export{t as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile as y}from"node:fs/promises";import{Args as
|
|
1
|
+
import{readFile as y}from"node:fs/promises";import{Args as v,Flags as u}from"@oclif/core";import{XtzCommand as E}from"../../base-command.js";import{getAuthContext as _}from"../../lib/auth.js";import{createErrorEnvelope as P,createSuccessEnvelope as S}from"../../lib/envelope.js";import{XtzError as d}from"../../lib/errors.js";import{globalFlags as C}from"../../lib/flags.js";import{isJsonObject as J}from"../../lib/json.js";import{resolveXiantaoToolProductUuid as b}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as k}from"../../lib/tool-inputs.js";import{fetchXiantaoCloudData as w}from"../../lib/xiantao-cloud.js";import{fetchAllPlotArgs as A,fetchToolMenu as O,resolveToolMenuByCode as x}from"../../lib/xiantao.js";class m extends E{static description="Fetch paginated cloud data options for a Xiantao tool in agent mode";static usage="tool cloud <tool> --json [--filter <value>] [--page <value> | --all]";static args={tool:v.string({description:"Tool id, e.g. km_plot_gene",required:!0})};static flags={...C,all:u.boolean({default:!1,description:"Fetch from the current page through the last page and merge all records"}),argsKey:u.string({description:"Cloud data key such as surv; defaults to the detected cloud input key"}),filter:u.string({description:"Cloud data filter value, such as a disease name"}),page:u.integer({default:1,description:"1-based cloud data page number",min:1}),recordFile:u.string({description:"Path to a JSON file containing the current cloud record seed"}),recordJson:u.string({description:"JSON string for the current cloud record seed"}),token:u.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:u.string({description:"tool_product_uuid used to auto-resolve the tool UUID; defaults to the current user product UUID"}),uuid:u.string({description:"Tool UUID for the public.clouds.fetch-data payload; optional when the module can be auto-resolved"})};async catch(t){const e=await this.getProfile(this.readProfileFlag());this.log(JSON.stringify(P(e,"tool cloud",this.normalizeError(t)),null,2)),this.exit(1)}async run(){const{args:t,flags:e}=await this.parse(m);if(!e.json)throw new d("`xt tool cloud` \u4EC5\u652F\u6301 `--json` \u8F93\u51FA\u3002");if(e.recordJson&&e.recordFile)throw new d("`--recordJson` \u4E0E `--recordFile` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");const r=await this.getProfile(e.profile),s=await _(r,e.token),c=await b(e.toolProductUuid,s),o=await this.resolveToolMeta(s,c,t.tool,e.uuid),n=await A(s,{moduleId:t.tool,uuid:o.uuid}),a=k(n.args_data??[]),f=e.argsKey?.trim()||a?.key||"";if(!f)throw new d(`\u6A21\u5757 ${t.tool} \u672A\u81EA\u52A8\u8BC6\u522B\u4E91\u6570\u636E\u53C2\u6570\uFF0C\u8BF7\u663E\u5F0F\u4F20\u5165 \`--argsKey\`.`);const p=await this.resolveSelectedRecord(e.recordJson,e.recordFile,a?.record),i=await w(s,{argsKey:f,currentPage:e.page,filter:e.filter,moduleId:t.tool,selectedRecord:p,uuid:o.uuid}),F=[i.currentPage],h=[...i.records];if(e.all)for(let l=i.currentPage+1;l<=i.lastPage;l+=1){const g=await w(s,{argsKey:f,currentPage:l,filter:e.filter,moduleId:t.tool,selectedRecord:p,uuid:o.uuid});F.push(g.currentPage),h.push(...g.records)}this.log(JSON.stringify(S(r,"tool cloud",{agent:r,args_key:f,choices:h.map((l,g)=>({data_id:typeof l.data_id=="string"?l.data_id.trim():"",index:g,label:typeof l.label=="string"?l.label.trim():""})),columns:i.columnAttrs,default_cloud:a?{key:a.key,label:a.label,record:a.record}:null,filter:{options:i.filter.options,value:i.filter.value},filter_keyword:e.filter?.trim()??"",info:i.info,module_id:t.tool,page:i.currentPage,pages_fetched:F,path:o.path,records:h,route:o.route,selected_record:p??null,selected_record_source:this.inferSelectedRecordSource(e.recordJson,e.recordFile,a?.record),title:o.title,tool_product_uuid:c,total:i.total,total_pages:i.lastPage,uuid:o.uuid}),null,2))}async resolveToolMeta(t,e,r,s){const c=s?.trim();if(!c){const a=await x(t,e,r);return{path:a.path,route:a.route,title:a.title,uuid:a.uuid}}const o=await O(t,c,e),n=o.code?.trim();if(n&&n!==r)throw new d(`\`--uuid\` \u5BF9\u5E94\u7684\u6A21\u5757\u662F ${n}\uFF0C\u4E0E ${r} \u4E0D\u4E00\u81F4\u3002`);return{path:o.path?.trim()??"",route:o.route?.trim()??"",title:o.title?.trim()??"",uuid:c}}async resolveSelectedRecord(t,e,r){return t?this.parseSelectedRecord(t,"--recordJson"):e?this.parseSelectedRecord(await y(e,"utf8"),"--recordFile"):r}parseSelectedRecord(t,e){let r;try{r=JSON.parse(t)}catch{throw new d(`${e} \u4E0D\u662F\u5408\u6CD5 JSON\u3002`)}if(!J(r))throw new d(`${e} \u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002`);return r}inferSelectedRecordSource(t,e,r){return t?"record_json":e?"record_file":r?"default":"none"}readProfileFlag(){for(let t=0;t<this.argv.length;t+=1){const e=this.argv[t];if((e==="--profile"||e==="--agent")&&this.argv[t+1])return this.argv[t+1];if(e.startsWith("--profile="))return e.slice(10);if(e.startsWith("--agent="))return e.slice(8)}}normalizeError(t){return t.message.replace(/\u001B\[[0-?]*[ -/]*[@-~]/g,"").includes("required arg")?new d("`xt tool cloud` \u9700\u8981\u4F20\u5165 TOOL\u3002"):t}}export{m as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"../plot/download.js";class o extends e{}export{o as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as a,Flags as o}from"@oclif/core";import{createErrorEnvelope as d,createSuccessEnvelope as u}from"../../lib/envelope.js";import{XtzError as i}from"../../lib/errors.js";import{globalFlags as c,toolCloudFlags as f}from"../../lib/flags.js";import{plotOverrideFlags as g}from"../../lib/plot-options.js";import{ToolRunCommandBase as p}from"../plot/run.js";class
|
|
1
|
+
import{Args as a,Flags as o}from"@oclif/core";import{createErrorEnvelope as d,createSuccessEnvelope as u}from"../../lib/envelope.js";import{XtzError as i}from"../../lib/errors.js";import{globalFlags as c,toolCloudFlags as f}from"../../lib/flags.js";import{plotOverrideFlags as g}from"../../lib/plot-options.js";import{ToolRunCommandBase as p}from"../plot/run.js";class r extends p{static description="Execute a Xiantao bioinformatics tool in agent mode";static usage="tool exec <tool> [--file <value> ... | --demo] --json [--download <path> [--downloadItem <n> | --downloadLabel <value>]]";static args={tool:a.string({description:"Tool id, e.g. violin_flat",required:!0}),file:a.string({hidden:!0})};static flags={...c,...f,...g,demo:o.boolean({default:!1,description:"Prefer the module default remote input returned by fetch-all instead of uploading a local file"}),download:o.string({description:"Download the generated file or preferred analysis result to this local path after submission"}),downloadItem:o.integer({description:"Select a download item by its 1-based index when --download matches multiple results"}),downloadLabel:o.string({description:"Select a download item by its label when --download matches multiple results"}),file:o.string({description:"Path to the local xlsx file; repeat or use KEY=PATH for named upload fields",multiple:!0}),interactive:o.boolean({default:!1,hidden:!0}),menuUuid:o.string({description:"Tool menu UUID from /products/apply/:toolProductUuid/analyse/:uuid"}),route:o.string({description:"Tool route like app1.violin_flat in generic mode"}),token:o.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:o.string({description:"tool_product_uuid used to auto-resolve module UUID and route in generic mode; defaults to the current user product UUID"}),uuid:o.string({description:"Tool UUID used in generic mode for fetch-all and verify-upload; optional when --toolProductUuid is provided"})};async catch(t){const e=await this.getProfile(this.readProfileFlag());this.log(JSON.stringify(d(e,"tool exec",this.normalizeError(t)),null,2)),this.exit(1)}async run(){const{args:t,flags:e}=await this.parse(r);if(!e.json)throw new i("`xt tool exec` \u4EC5\u652F\u6301 `--json` \u8F93\u51FA\u3002");const l=this.resolveToolFileInputs(t.file,e.file);if(e.demo&&l.length>0)throw new i("`--demo` \u4E0E `--file` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");const s=await this.executeToolRun(t.tool,l,{...e,interactive:!1}),n=await this.getProfile(e.profile);this.log(JSON.stringify(u(n,"tool exec",s.data),null,2))}readProfileFlag(){for(let t=0;t<this.argv.length;t+=1){const e=this.argv[t];if((e==="--profile"||e==="--agent")&&this.argv[t+1])return this.argv[t+1];if(e.startsWith("--profile="))return e.slice(10);if(e.startsWith("--agent="))return e.slice(8)}}normalizeError(t){return t.message.replace(/\u001B\[[0-?]*[ -/]*[@-~]/g,"").includes("required arg")?new i("`xt tool exec` \u9700\u8981\u4F20\u5165 TOOL\u3002"):t}}export{r as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"../plot/fetch-all.js";class t extends e{}export{t as default};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Args as $,Flags as h}from"@oclif/core";import{XtzCommand as b}from"../../base-command.js";import{getAuthContext as y}from"../../lib/auth.js";import{globalFlags as
|
|
2
|
-
`);r.push(`args_main: ${
|
|
3
|
-
`)}summarizeInputs(e,
|
|
1
|
+
import{Args as $,Flags as h}from"@oclif/core";import{XtzCommand as b}from"../../base-command.js";import{getAuthContext as y}from"../../lib/auth.js";import{globalFlags as v}from"../../lib/flags.js";import{isJsonObject as k}from"../../lib/json.js";import{buildArgsMainFromSchema as S,buildArgsSpecificFromSchema as q}from"../../lib/plot-schema.js";import{resolveXiantaoToolProductUuid as F}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as C,findDefaultXiantaoRecord as I,listXiantaoUploadFields as U}from"../../lib/tool-inputs.js";import{fetchAllPlotArgs as z,resolveToolMenuByCode as x}from"../../lib/xiantao.js";class p extends b{static description="Inspect a Xiantao tool and its dynamic inputs";static args={tool:$.string({description:"Tool id, e.g. violin_flat",required:!0})};static flags={...v,token:h.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:h.string({description:"tool_product_uuid used in the menu filter payload; defaults to the current user product UUID"})};async run(){const{args:e,flags:a}=await this.parse(p),o=await this.getProfile(a.profile),d=await y(o,a.token),u=await F(a.toolProductUuid,d),s=await x(d,u,e.tool),i=await z(d,{moduleId:e.tool,uuid:s.uuid}),n=i.args_main??[],l=i.args_specific??[],c=this.summarizeInputs(i.args_data??[],i.id?.duid??""),r=this.summarizeSchema(n),t={agent:o,args_data:i.args_data??[],args_main:n,args_main_defaults:S(n),args_specific:l,args_specific_defaults:q(l),duid:i.id?.duid??"",inputs:c,module_id:e.tool,notice:i.notice??"",path:s.path,route:s.route,summary:r,title:s.title,tool_product_uuid:u,uuid:s.uuid};this.print(a,t,this.formatInspectText(t.module_id,t.title,t.path,t.route,t.uuid,t.notice,c,r,l,n),{profile:o})}formatInspectText(e,a,o,d,u,s,i,n,l,c){const r=[`${e} ${a}`,`path: ${o||"-"}`,`route: ${d}`,`uuid: ${u}`];s&&r.push(`notice: ${s}`),r.push("input:"),r.push(` cloud: ${i.cloud_available?this.formatCloudSummary(i.cloud_default):"unavailable"}`),r.push(` upload: ${i.upload_available?`${i.upload_fields.length} fields`:"not detected"}`);for(const t of i.upload_fields){const m=[t.label&&t.label!==t.key?t.label:void 0,t.required?"required":void 0,t.demo_upload?this.formatDemoSummary(t.demo_upload):"no demo default"].filter(Boolean);r.push(` - ${t.key}${m.length>0?` - ${m.join(", ")}`:""}`)}if(r.push(` demo: ${i.demo_available?"available":"unavailable"}`),r.push(` record: ${i.record_available?this.formatRecordSummary(i.record_default):"unavailable"}`),l.length>0){r.push(`args_specific: ${l.length} fields`);for(const t of l){const m=[this.formatFieldLabel(t),t.type?.trim(),t.required?"required":void 0,t.multiple?"multiple":void 0,this.formatDefaultValue(t.default_value)].filter(Boolean);r.push(` ${t.key}${m.length>0?` - ${m.join(", ")}`:""}`)}}else r.push("args_specific: none");if(c.length===0)return r.push("args_main: none"),r.join(`
|
|
2
|
+
`);r.push(`args_main: ${n.section_count} sections, ${n.field_count} fields, ${n.required_field_count} required`);for(const t of c){const m=t.form??[],g=m.filter(f=>f.required).length;r.push(`- ${t.label?.trim()||t.key} (${t.key}) - ${m.length} fields, ${g} required`);for(const f of t.form??[]){const _=[this.formatFieldLabel(f),f.type?.trim(),f.required?"required":void 0,f.multiple?"multiple":void 0,f.options?.length?`options:${f.options.length}`:void 0,this.formatDefaultValue(f.default_value)].filter(Boolean);r.push(` ${f.key}${_.length>0?` - ${_.join(", ")}`:""}`)}}return r.join(`
|
|
3
|
+
`)}summarizeInputs(e,a){const o=U(e),d=I(e),u=C(e),s=!!(a.trim()&&o.length>0&&o.every(l=>!!l.defaultUpload)),i=!!(a.trim()&&d),n=i&&d?{key:d.key,label:d.label,module_id:d.moduleId,module_name:d.moduleName,record_id:d.recordId,record_name:d.recordName,time:d.time}:null;return{cloud_available:!!u,cloud_default:u?this.toCloudSummary(u.key,u.label,u.record):null,demo_available:s,record_available:i,record_default:n,upload_available:o.length>0,upload_fields:o.map(l=>({demo_upload:l.defaultUpload?{file_name:l.defaultUpload.fileName,file_oss:l.defaultUpload.fileOss,file_size:l.defaultUpload.fileSize,key:l.key,label:l.label}:null,key:l.key,label:l.label,required:l.required}))}}summarizeSchema(e){const a=e.flatMap(o=>o.form??[]);return{field_count:a.length,required_field_count:a.filter(o=>o.required).length,section_count:e.length}}formatDemoSummary(e){return`${e.file_name} (${this.formatFileSize(e.file_size)})`}formatRecordSummary(e){return e?`${e.module_id||"-"} ${e.record_id}${e.time?` (${e.time})`:""}`:"available"}formatCloudSummary(e){if(!e)return"available";const a=[e.record_label||e.data_id,e.data_filter?`filter:${e.data_filter}`:void 0,e.data_process?`process:${e.data_process}`:void 0].filter(Boolean);return`${e.key}${a.length>0?` (${a.join(", ")})`:""}`}toCloudSummary(e,a,o){const d=this.readCloudOptionValue(o.data_filter),u=this.readCloudOptionValue(o.data_process);return{data_filter:d,data_id:typeof o.data_id=="string"?o.data_id.trim():"",data_process:u,key:e,label:a,record_label:typeof o.label=="string"?o.label.trim():""}}readCloudOptionValue(e){return k(e)&&(typeof e.value=="string"?e.value.trim():"")||null}formatFileSize(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}formatFieldLabel(e){if(typeof e.label!="string")return;const a=e.label.trim();return a&&a!==e.key?a:void 0}formatDefaultValue(e){if(!(e==null||e===""))return typeof e=="string"?`default:${e}`:typeof e=="number"||typeof e=="boolean"?`default:${String(e)}`:Array.isArray(e)?e.length>0?`default:${e.length} items`:void 0:"default:object"}}export{p as default};
|