@helixlife-ai/xiantao 0.1.20 → 0.1.21
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 +11 -1
- package/dist/commands/plot/fetch-all.js +1 -1
- package/dist/commands/plot/run.js +5 -4
- package/dist/commands/tool/cloud.js +1 -0
- package/dist/commands/tool/exec.js +1 -1
- package/dist/commands/tool/inspect.js +3 -3
- package/dist/commands/tool/prepare.js +1 -1
- package/dist/lib/envelope.js +1 -1
- package/dist/lib/errors.js +1 -1
- package/dist/lib/flags.js +1 -1
- package/dist/lib/plot-interactive.js +20 -16
- package/dist/lib/plot-options.js +1 -1
- package/dist/lib/plot-schema.js +1 -1
- package/dist/lib/tool-inputs.js +1 -1
- package/dist/lib/xiantao-auth.js +1 -1
- package/dist/lib/xiantao-cloud.js +1 -0
- package/dist/lib/xiantao-plot.js +1 -1
- package/dist/lib/xiantao.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,6 +42,11 @@ xt tool exec gsea_analysis --demo --profile opencode --json
|
|
|
42
42
|
xt tool prepare gsea_plot --profile opencode --json
|
|
43
43
|
xt tool exec gsea_plot --profile opencode --json --download ./gsea_plot.pdf
|
|
44
44
|
xt tool exec gsea_customize --file gene_set=./gene_set.gmt --file data=./rank.xlsx --profile opencode --json
|
|
45
|
+
|
|
46
|
+
xt tool cloud km_plot_gene --profile opencode --json --filter '胆管癌'
|
|
47
|
+
xt tool exec km_plot_gene --profile opencode --json --cloudFilter '胆管癌'
|
|
48
|
+
xt tool exec km_plot_gene --profile opencode --json --cloudFilter '胆管癌' --cloudIndex 1
|
|
49
|
+
xt tool exec km_plot_gene --profile opencode --json --cloudDataId tcga-chol-2
|
|
45
50
|
```
|
|
46
51
|
|
|
47
52
|
For machine callers, use `xt tool prepare` to fetch the final schema, then `xt tool exec` to submit. Keep `--json`, pass an explicit profile with `--profile`, and avoid interactive-only flows.
|
|
@@ -52,11 +57,15 @@ The examples below illustrate command shapes, not a fixed allowlist of tools. Ap
|
|
|
52
57
|
- multi-upload modules: repeat `--file key=path`, for example `--file gene_set=./gene_set.gmt --file data=./rank.xlsx`
|
|
53
58
|
- demo-capable upload modules: pass `--demo`
|
|
54
59
|
- history-record modules such as `gsea_plot`: pass neither `--file` nor `--demo`; the CLI reuses the default `XTRecord` returned by `tool inspect` / `tool prepare`
|
|
60
|
+
- cloud-capable modules: use `--cloudFilter <keyword>` to narrow cloud records, then retry with `--cloudIndex <n>` or `--cloudDataId <id>` when multiple matches exist
|
|
55
61
|
|
|
56
62
|
Current operational notes for agent-style callers:
|
|
57
63
|
- serialize `xt tool exec` submits per profile; Xiantao may reject overlapping or too-frequent submits with `NETWORK_ERROR`
|
|
58
64
|
- `tool inspect` now includes the full `args_data` payload in JSON output and summarizes every detected `XTUpload` field
|
|
65
|
+
- `tool inspect` also reports `inputs.cloud_available` and `inputs.cloud_default` for `XTCloud` modules
|
|
59
66
|
- for multi-upload modules, pass keyed uploads in the same field names returned by `tool inspect`
|
|
67
|
+
- `tool cloud --json --filter <keyword>` returns structured cloud candidates via `data.choices`
|
|
68
|
+
- if `tool prepare` or `tool exec` returns `code=TOOL_AMBIGUOUS` with `data.selection_type=cloud_record`, do not auto-pick; ask the user which item to use, then retry with `--cloudIndex` or `--cloudDataId`
|
|
60
69
|
- `gsea_customize` has been validated through `tool prepare` and `tool exec` with repeated `--file gene_set=... --file data=...`
|
|
61
70
|
|
|
62
71
|
For agent workflows, do not use `xt tool run`. Treat `xt tool run` as the human-first path and `xt tool exec` as the machine path.
|
|
@@ -83,6 +92,7 @@ For agent workflows, do not use `xt tool run`. Treat `xt tool run` as the human-
|
|
|
83
92
|
|
|
84
93
|
- `xt tool search`
|
|
85
94
|
- `xt tool inspect`
|
|
95
|
+
- `xt tool cloud`
|
|
86
96
|
- `xt tool prepare`
|
|
87
97
|
- `xt tool run`
|
|
88
98
|
- `xt tool exec`
|
|
@@ -102,7 +112,7 @@ For the common Xiantao tool product, `tool search`, `tool inspect`, `tool run`,
|
|
|
102
112
|
|
|
103
113
|
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.
|
|
104
114
|
|
|
105
|
-
`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 per-field `XTUpload` defaults and `
|
|
115
|
+
`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 cloud <tool_id>` fetches paginated cloud candidates and returns a machine-friendly `data.choices` list when `--json` is used. `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. `--demo` reuses the demo file metadata returned by `tool fetch-all`; `--file` uploads a local file first; multi-upload modules accept repeated `--file key=path`; for `XTRecord` modules the CLI can submit directly from the default history record returned by `fetch-all`; for `XTCloud` modules use `--cloudFilter`, then `--cloudIndex` or `--cloudDataId` to pin one cloud record before submit. Run `xt login` first to authorize the stored token. When cloud filtering matches multiple records, `tool prepare` and `tool exec` return `code=TOOL_AMBIGUOUS` plus `data.selection_type=cloud_record` and `data.choices`; callers should ask the user which record to use before retrying. When a tool exposes multiple downloadable results, `--download <path>` uses the output file extension to select the matching artifact.
|
|
106
116
|
|
|
107
117
|
For the current GSEA tool family, `gsea_plot`, `gsea_plot2`, `gsea_bar`, `gsea_point`, `gsea_ridge`, `gsea_emapplot`, `gsea_tree`, and `gsea_path_cluster` are record-backed visual modules that reuse the default `gsea_analysis` history record. `gsea_analysis` itself is an upload/demo analysis module. `gsea_customize` is a custom gene-set upload module whose frontend expects two uploads, `gene_set` and `data`; submit it with `--file gene_set=... --file data=...`. A real CLI submit path has been verified with the sample files in [`docs/GSEA-基因集.csv`](/Users/chenyunjie/Desktop/xtz-cli/xiantao/docs/GSEA-基因集.csv) and [`docs/GSEA-分子.xlsx`](/Users/chenyunjie/Desktop/xtz-cli/xiantao/docs/GSEA-分子.xlsx).
|
|
108
118
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as d,Flags as
|
|
1
|
+
import{Args as d,Flags as o}from"@oclif/core";import{XtzCommand as c}from"../../base-command.js";import{getAuthContext as u}from"../../lib/auth.js";import{globalFlags as g}from"../../lib/flags.js";import{buildArgsMainFromSchema as f,buildArgsSpecificFromSchema as m}from"../../lib/plot-schema.js";import{fetchAllPlotArgs as p}from"../../lib/xiantao.js";class r extends c{static description="Fetch raw dynamic args for a Xiantao tool via public.args.fetch-all";static args={moduleId:d.string({description:"Tool id, e.g. violin_flat",required:!0})};static flags={...g,token:o.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),uuid:o.string({description:"Tool UUID used in the public.args.fetch-all payload",required:!0})};async run(){this.warnIfLegacyPlotCommand();const{args:s,flags:i}=await this.parse(r),a=await this.getProfile(i.profile),l=await u(a,i.token),t=await p(l,{moduleId:s.moduleId,uuid:i.uuid}),n=f(t.args_main),e={agent:a,args_data:t.args_data??[],args_main:t.args_main??[],args_main_defaults:n,args_specific:t.args_specific??[],args_specific_defaults:m(t.args_specific),duid:t.id?.duid??"",module_id:s.moduleId,notice:t.notice??"",uuid:i.uuid};this.print(i,e,JSON.stringify(e,null,2),{profile:a})}}export{r as default};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import{Args as
|
|
2
|
-
`)}formatAsyncHistoryText(o,
|
|
3
|
-
`)}formatAsyncHistoryDownloadText(o,
|
|
4
|
-
`)}async downloadResult(o,t){if(t.downloads.length>0){const i=this.pickDownloadItem(t.downloads,t.downloadPath);if(!i)throw new l("\u5F53\u524D\u6A21\u5757\u8FD4\u56DE\u591A\u4E2A\u53EF\u4E0B\u8F7D\u7ED3\u679C\uFF0C\u8BF7\u5C06 `--download` \u8DEF\u5F84\u6539\u4E3A\u5E26\u76EE\u6807\u6269\u5C55\u540D\u7684\u6587\u4EF6\u540D\uFF0C\u6216\u4F7F\u7528 `--interactive` \u9009\u62E9\u3002");const e=await R(o,{item:i,moduleId:t.moduleId,uuid:t.uuid});return[await y(e.url,t.downloadPath)]}if(t.file)return[await y(t.file,t.downloadPath)];throw new l("\u5F53\u524D\u6A21\u5757\u672A\u8FD4\u56DE\u53EF\u4E0B\u8F7D\u6587\u4EF6\u3002")}pickDownloadItem(o,t){const i=this.inferDownloadDevice(t);if(i){const n=o.filter(r=>this.normalizeDevice(r.device)===i);if(n.length===1)return n[0]}const e=o.filter(n=>n.endpoint==="public.output.download-result");if(e.length===1)return e[0];if(o.length===1)return o[0]}inferDownloadDevice(o){if(!o)return;const t=o.trim().split(".").pop()?.toLowerCase();if(t)return this.normalizeDevice(t)}normalizeDevice(o){const t=o.trim().toLowerCase();return t==="tif"?"tiff":t==="jpg"?"jpeg":t}toHistorySummary(o,t){const i=o.fuid?.trim();return i?{fuid:i,id:typeof o.id=="number"?o.id:null,module_id:o.module_id?.trim()||t,module_name:o.module_name?.trim()||"",name:o.name?.trim()||"",status:A(o),time:o.time?.trim()||"",type:o.type?.trim()||""}:null}buildHistoryHint(o){return o?`\u53EF\u4F7F\u7528 \`xt history download ${o.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(o,t){const i=[];for(const e of t.downloads){const n=await R(o,{item:e,moduleId:t.moduleId,uuid:t.uuid});i.push(await y(n.url,n.fileName))}return i}async downloadInteractiveResults(o,t){const i=[];return t.choice.downloadFile&&t.file&&i.push(await y(t.file)),t.choice.downloads.length>0&&i.push(...await this.downloadSelectedResults(o,{downloads:t.choice.downloads,moduleId:t.moduleId,uuid:t.uuid})),i}isRetryableAsyncDownloadError(o){return o.message.includes("\u4E0B\u8F7D\u5931\u8D25")||o.message.includes("\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5")}async sleep(o){await new Promise(t=>setTimeout(t,o))}async resolveInputMode(o,t){if(t.demo)return{mode:"demo"};if(t.fileInputs.length>0)return{fileInputs:t.fileInputs,mode:"upload"};if(this.hasRecordInput(o))return{mode:"record"};if(!t.interactive)return{mode:"upload"};if(!this.hasDemoInput(o))return{fileInputs:[await P()],mode:"upload"};const i=await F();return i==="demo"?{mode:i}:{fileInputs:[await P()],mode:i}}resolveDemoInput(o,t){const i=o.id?.duid?.trim();if(!i)throw new l(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE demo duid\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);const e=g(o.args_data??[]);if(!e.length||e.some(n=>!n.defaultUpload))throw new l(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE\u53EF\u7528\u7684 demo \u6587\u4EF6\u4FE1\u606F\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);return{duid:i,input:{kind:"upload",uploads:e.map(n=>({key:n.key,label:n.label,upload:{fileName:n.defaultUpload.fileName,fileOss:n.defaultUpload.fileOss,fileSize:n.defaultUpload.fileSize}}))},schema:[]}}hasDemoInput(o){if(!o.id?.duid?.trim())return!1;const i=g(o.args_data??[]);return i.length>0&&i.every(e=>!!e.defaultUpload)}resolveRecordInput(o,t){const i=o.id?.duid?.trim();if(!i)throw new l(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE record duid\uFF0C\u65E0\u6CD5\u4F7F\u7528\u5386\u53F2\u8BB0\u5F55\u8F93\u5165\u3002`);const e=x(o.args_data??[]);if(!e)throw new l(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u6570\u636E\u8BB0\u5F55\uFF0C\u65E0\u6CD5\u76F4\u63A5\u8FD0\u884C\u3002`);return{duid:i,input:{kind:"record",record:{key:e.key,label:e.label,moduleId:e.moduleId,moduleName:e.moduleName,recordId:e.recordId,recordName:e.recordName,time:e.time}},schema:[]}}hasRecordInput(o){return!!(o.id?.duid?.trim()&&x(o.args_data??[]))}async uploadAndVerify(o,t,i,e){const n=await this.uploadFiles(o,t,i.argsData??[],i.moduleId),r=await G(e,{argsMain:i.argsMain,moduleId:i.moduleId,uploads:n,uuid:i.uuid});return{duid:r.duid,input:{kind:"upload",uploads:n},schema:r.schema}}summarizePreparedInput(o){if(o.kind==="record")return{file_name:null,file_oss:null,file_size:null,input_record:{label:o.record.label,module_id:o.record.moduleId,module_name:o.record.moduleName,record_id:o.record.recordId,record_name:o.record.recordName,time:o.record.time},input_uploads:null};const t=o.uploads.map(e=>({file_name:e.upload.fileName,file_oss:e.upload.fileOss,file_size:e.upload.fileSize,key:e.key,label:e.label})),i=t.length===1?t[0]:null;return{file_name:i?.file_name??null,file_oss:i?.file_oss??null,file_size:i?.file_size??null,input_record:null,input_uploads:t}}async uploadFiles(o,t,i,e){const n=g(i??[]),r=this.resolveUploadInputs(t,n,e),d=await b(o),a=[];for(const u of r){const c=await C(d,u.filePath);a.push({key:u.key,label:u.label,upload:c})}return a}resolveUploadInputs(o,t,i){if(!t.length)throw new l(`\u6A21\u5757 ${i} \u672A\u68C0\u6D4B\u5230\u53EF\u4E0A\u4F20\u8F93\u5165\uFF0C\u4E0D\u80FD\u4F7F\u7528 \`--file\`\u3002`);if(!o.length)throw t.length===1?new l("\u901A\u7528\u6A21\u5F0F\u8BF7\u4F20\u5165 FILE / `--file <xlsx>`\uFF0C\u6216\u6539\u7528 `--demo`\u3002"):new l(`\u6A21\u5757 ${i} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${t.map(a=>a.key).join(", ")}`);const[e]=t;if(t.length===1&&o.length===1){const a=this.parseUploadFileInput(o[0]);if(a.key&&a.key!==e.key)throw new l(`\u6A21\u5757 ${i} \u4EC5\u652F\u6301\u4E0A\u4F20\u5B57\u6BB5 ${e.key}\uFF0C\u6536\u5230 ${a.key}\u3002`);return[{filePath:a.path,key:e.key,label:e.label}]}const n=new Map(t.map(a=>[a.key,a])),r=new Map;for(const a of o){const u=this.parseUploadFileInput(a);if(!u.key){if(t.length===1){if(r.has(e.key))throw new l(`\u6A21\u5757 ${i} \u4EC5\u9700\u8981 1 \u4E2A\u4E0A\u4F20\u6587\u4EF6\uFF0C\u6536\u5230\u91CD\u590D\u8F93\u5165\u3002`);r.set(e.key,u.path);continue}throw new l(`\u6A21\u5757 ${i} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${t.map(s=>s.key).join(", ")}`)}const c=n.get(u.key);if(!c)throw new l(`\u6A21\u5757 ${i} \u4E0D\u5B58\u5728\u4E0A\u4F20\u5B57\u6BB5 ${u.key}\u3002\u53EF\u7528\u5B57\u6BB5: ${t.map(s=>s.key).join(", ")}`);if(r.has(c.key))throw new l(`\u4E0A\u4F20\u5B57\u6BB5 ${c.key} \u91CD\u590D\u4F20\u5165\u3002`);r.set(c.key,u.path)}const d=t.filter(a=>a.required&&!r.has(a.key));if(d.length>0)throw new l(`\u6A21\u5757 ${i} \u7F3A\u5C11\u5FC5\u586B\u4E0A\u4F20\u5B57\u6BB5: ${d.map(a=>a.key).join(", ")}`);return t.flatMap(a=>{const u=r.get(a.key);return u?[{filePath:u,key:a.key,label:a.label}]:[]})}parseUploadFileInput(o){const t=o.trim();if(!t)throw new l("`--file` \u4E0D\u80FD\u4E3A\u7A7A\u3002");const i=t.indexOf("=");if(i<=0)return{path:t};const e=t.slice(0,i).trim(),n=t.slice(i+1).trim();if(!e||!n)throw new l("\u591A\u4E0A\u4F20\u6A21\u5757\u8BF7\u4F7F\u7528 `--file key=path`\u3002");return{key:e,path:n}}async resolveModule(o,t,i){const e=o?.trim(),n=t.route?.trim(),r=t.uuid?.trim(),d=await q(t.toolProductUuid);if(!e){if(!t.interactive)throw new l("\u8BF7\u4F20\u5165 `module_id`\uFF0C\u6216\u4F7F\u7528 `--interactive --file <xlsx>` \u5148\u4ECE\u83DC\u5355\u9009\u62E9\u5DE5\u5177\u3002");const u=await E(this.sortTopLevelMenus(await J(i,d)));return{moduleId:u.code,route:n??u.route,toolProductUuid:d,uuid:r??u.uuid}}if(n&&r)return{moduleId:e,route:n,toolProductUuid:d,uuid:r};const a=t.menuUuid?.trim();if(a&&d){const u=await Y(i,a,d),c=n??this.requireMenuRoute(u),s=u.code?.trim();if(s&&s!==e)throw new l(`\u83DC\u5355\u6A21\u5757 code \u4E3A ${s}\uFF0C\u4E0E\u4F20\u5165\u7684 module_id ${e} \u4E0D\u4E00\u81F4\u3002`);return{moduleId:e,route:c,toolProductUuid:d,uuid:r??a}}if(d){const u=await Q(i,d,e);return{moduleId:e,route:n??u.route,toolProductUuid:d,uuid:r??u.uuid}}if(!r)throw new l("\u901A\u7528\u6A21\u5F0F\u9700\u8981\u4F20\u5165 `--uuid`\uFF0C\u6216\u4F7F\u7528\u9ED8\u8BA4/\u663E\u5F0F `toolProductUuid` \u81EA\u52A8\u89E3\u6790\u3002");if(!n)throw new l("\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:e,route:n,toolProductUuid:d,uuid:r}}sortTopLevelMenus(o){const t=["\u57FA\u7840\u7ED8\u56FE","\u8868\u8FBE\u5DEE\u5F02","\u529F\u80FD\u805A\u7C7B","\u4EA4\u4E92\u7F51\u7EDC","\u4E34\u5E8A\u610F\u4E49","\u5176\u4ED6"],i=new Map(t.map((e,n)=>[e,n]));return[...o].sort((e,n)=>{const r=i.get(e.title?.trim()??"")??Number.MAX_SAFE_INTEGER,d=i.get(n.title?.trim()??"")??Number.MAX_SAFE_INTEGER;return r-d})}requireMenuRoute(o){const t=o.route;if(typeof t!="string"||!t.trim())throw new l("\u83DC\u5355\u672A\u8FD4\u56DE\u53EF\u7528 route\uFF0C\u8BF7\u6539\u7528 `--route` \u663E\u5F0F\u6307\u5B9A\u3002");return t.trim()}}class I extends W{static description="Run a Xiantao bioinformatics tool";static args={tool:k.string({description:"Tool id; optional with --interactive to choose from menus"}),file:k.string({description:"Path to the local xlsx file; optional with --demo or --interactive"})};static flags={...$,...L,demo:m.boolean({default:!1,description:"Use the module demo data returned by fetch-all instead of uploading a local file"}),file:m.string({description:"Path to the local xlsx file; repeat or use KEY=PATH for named upload fields",multiple:!0}),download:m.string({description:"Download the generated file or preferred analysis result to this local path after submission"}),interactive:m.boolean({default:!1,description:"Prompt for dynamic args before submitting the module"}),menuUuid:m.string({description:"Tool menu UUID from /products/apply/:toolProductUuid/analyse/:uuid"}),route:m.string({description:"Tool route like app1.violin_flat in generic mode"}),token:m.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:m.string({description:"tool_product_uuid used to auto-resolve module UUID and route in generic mode; defaults to the main Xiantao product UUID"}),uuid:m.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:o,flags:t}=await this.parse(I);if(t.interactive&&t.json)throw new l("`--interactive` \u4E0D\u80FD\u4E0E `--json` \u540C\u65F6\u4F7F\u7528\u3002");const i=this.resolveToolFileInputs(o.file,t.file),e=await this.executeToolRun(o.tool,i,t);this.print(t,e.data,e.text,{profile:e.data.agent})}}export{W as ToolRunCommandBase,I as default};
|
|
1
|
+
import{readFile as X}from"node:fs/promises";import{Args as D,Flags as f}from"@oclif/core";import{XtzCommand as O}from"../../base-command.js";import{getAuthContext as $}from"../../lib/auth.js";import{XIANTAO_HISTORY_UUID as N}from"../../lib/constants.js";import{downloadToPath as R}from"../../lib/download.js";import{XtzChoiceRequiredError as E,XtzError as u}from"../../lib/errors.js";import{globalFlags as j,toolCloudFlags as B}from"../../lib/flags.js";import{fetchXiantaoHistoryDownloadButtons as K,getXiantaoHistoryRecordStatus as J,waitForLatestXiantaoHistoryRecord as L,waitForXiantaoHistoryRecordCompletion as V}from"../../lib/history.js";import{deepMerge as y,isJsonObject as F}from"../../lib/json.js";import{confirmPlotArgsMain as q,promptPlotArgsMain as Q,promptPlotCloudRecordSelection as G,promptPlotFilePath as T,promptPlotInputSource as Y,promptPlotMenuSelection as W,promptPlotResultSelection as Z}from"../../lib/plot-interactive.js";import{uploadFile as oo}from"../../lib/plot.js";import{parseSetOverrides as eo,parseSpecificOverrides as to,plotOverrideFlags as io}from"../../lib/plot-options.js";import{buildArgsMainFromSchema as P,buildArgsSpecificFromSchema as H}from"../../lib/plot-schema.js";import{loadPlotArgsMainConfig as ro,resolveXiantaoToolProductUuid as no}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as x,findDefaultXiantaoRecord as M,listXiantaoUploadFields as C}from"../../lib/tool-inputs.js";import{fetchXiantaoCloudData as A}from"../../lib/xiantao-cloud.js";import{buildSubmitArgsData as lo,resolveXiantaoDownload as z,submitXiantaoPlot as uo,verifyXiantaoPlotUpload as ao}from"../../lib/xiantao-plot.js";import{fetchAllPlotArgs as so,fetchToolMenu as co,fetchToolMenus as mo,resolveToolMenuByCode as fo,updatePlotArgs as ho}from"../../lib/xiantao.js";class wo extends O{resolveToolFileInputs(o,e){if(o&&e&&e.length>0)throw new u("FILE \u4E0E `--file` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");return o?[o]:e??[]}async prepareToolRun(o,e,t){this.validateInputSourceFlags(e,t);const i=await this.getProfile(t.profile),d=await $(i,t.token),r=await this.resolveModule(o,t,d),{moduleId:l,route:n,toolProductUuid:a,uuid:s}=r,c=await so(d,{moduleId:l,uuid:s}),h=await this.resolveInputMode(c,{cloudRequested:!!(t.cloudDataId?.trim()||t.cloudFilter?.trim()||typeof t.cloudIndex=="number"||t.cloudKey?.trim()||t.cloudRecordFile||t.cloudRecordJson),demo:t.demo,fileInputs:e,interactive:t.interactive}),p=await ro(l,t.config),b=y(p,eo(t.set)),S=to(t.specific);let w=c.args_main??[],_=c.args_specific??[],g=y(P(w),b),v=y(H(_),S),m=h.mode==="cloud"?await this.resolveCloudInput(c,t,l,d,s):h.mode==="demo"?this.resolveDemoInput(c,l):h.mode==="record"?this.resolveRecordInput(c,l):await this.uploadAndVerify(i,h.fileInputs??[],{argsMain:g,argsData:c.args_data??[],moduleId:l,uuid:s},d);if(m.schema.length&&(w=m.schema,g=y(P(w),b)),m.input.kind==="cloud"){const k=await ho(d,{argsData:lo(m.duid,m.input),argsKey:m.input.cloud.key,argsMain:g,argsSpecific:v,moduleId:l,uuid:s}),I=x(k.args_data??[]);I&&(m={...m,input:{kind:"cloud",cloud:{key:I.key,label:I.label,record:this.normalizeCloudRecord(I.record)}}}),w=k.args_main??w,_=k.args_specific??_,g=y(P(w),b),v=y(H(_),S)}return{agent:i,argsMain:g,argsSpecific:v,argsSpecificSchema:_,auth:d,duid:m.duid,input:m.input,inputMode:h.mode,inputSummary:this.summarizePreparedInput(m.input),moduleId:l,notice:c.notice??"",route:n,schema:w,toolProductUuid:a,uuid:s}}async executeToolRun(o,e,t){const i=await this.prepareToolRun(o,e,t);let d=i.argsMain;const r=i.argsSpecific;t.interactive&&(d=await Q(i.schema??[],d),await q(d));const l=Date.now(),n=await uo(i.auth,{argsMain:d,argsSpecific:r,duid:i.duid,input:i.input,moduleId:i.moduleId,route:i.route,uuid:i.uuid});if(n.asyncSubmission)return this.resolveAsyncToolRun(i,d,r,t,l,n.message);const a=t.download?await this.downloadResult(i.auth,{downloadPath:t.download,downloads:n.downloads,file:n.file,moduleId:i.moduleId,uuid:i.uuid}):await this.downloadInteractiveResults(i.auth,{choice:t.interactive?await Z({downloads:n.downloads,hasFile:!!n.file}):{downloadFile:!1,downloads:[]},file:n.file,moduleId:i.moduleId,uuid:i.uuid}),s=a[0];return{data:{agent:i.agent,args_main:d,args_specific:r,body:n.body,download_path:s,download_paths:a,downloads:n.downloads,duid:i.duid,file:n.file??null,history:null,history_hint:null,...i.inputSummary,mode:i.inputMode,module_id:i.moduleId,notice:i.notice,result_source:"direct",route:i.route,submission_message:n.message,tool_product_uuid:i.toolProductUuid,uuid:i.uuid},text:this.formatResultText(n,a,t.interactive&&!t.download)}}async resolveAsyncToolRun(o,e,t,i,d,r){const l=await L(o.auth,{intervalMs:3e3,moduleId:o.moduleId,submittedAtMs:d,timeoutMs:i.download?6e4:12e3}),n=l?this.toHistorySummary(l,o.moduleId):null;if(!i.download)return{data:{agent:o.agent,args_main:e,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:o.duid,file:null,history:n,history_hint:this.buildHistoryHint(n),...o.inputSummary,mode:o.inputMode,module_id:o.moduleId,notice:o.notice,result_source:"history",route:o.route,submission_message:r,tool_product_uuid:o.toolProductUuid,uuid:o.uuid},text:this.formatAsyncHistoryText(n,r)};if(!l?.fuid?.trim())return{data:{agent:o.agent,args_main:e,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:o.duid,file:null,history:n,history_hint:this.buildHistoryHint(n),...o.inputSummary,mode:o.inputMode,module_id:o.moduleId,notice:o.notice,result_source:"history",route:o.route,submission_message:r,tool_product_uuid:o.toolProductUuid,uuid:o.uuid},text:this.formatAsyncHistoryText(n,`${r}\uFF0C\u4F46\u6682\u672A\u5B9A\u4F4D\u5230\u5386\u53F2\u8BB0\u5F55\u3002`)};const a=await V(o.auth,{fuid:l.fuid.trim(),intervalMs:3e3,timeoutMs:6e4}),s=a?this.toHistorySummary(a,o.moduleId):n;if(!a?.fuid?.trim())return{data:{agent:o.agent,args_main:e,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:o.duid,file:null,history:s,history_hint:this.buildHistoryHint(s),...o.inputSummary,mode:o.inputMode,module_id:o.moduleId,notice:o.notice,result_source:"history",route:o.route,submission_message:`${r}\uFF0C\u4F46\u7B49\u5F85\u5386\u53F2\u8BB0\u5F55\u5B8C\u6210\u8D85\u65F6\u3002`,tool_product_uuid:o.toolProductUuid,uuid:o.uuid},text:this.formatAsyncHistoryText(s,`${r}\uFF0C\u4F46\u7B49\u5F85\u5386\u53F2\u8BB0\u5F55\u5B8C\u6210\u8D85\u65F6\u3002`)};const{body:c,downloads:h,paths:p}=await this.downloadAsyncHistoryResult(o.auth,{downloadPath:i.download,fuid:a.fuid.trim(),moduleId:o.moduleId});return{data:{agent:o.agent,args_main:e,args_specific:t,body:c,download_path:p[0],download_paths:p,downloads:h,duid:o.duid,file:null,history:s,history_hint:this.buildHistoryHint(s),...o.inputSummary,mode:o.inputMode,module_id:o.moduleId,notice:o.notice,result_source:"history",route:o.route,submission_message:r,tool_product_uuid:o.toolProductUuid,uuid:o.uuid},text:this.formatAsyncHistoryDownloadText(s,p)}}async downloadAsyncHistoryResult(o,e){let t;for(let i=0;i<4;i+=1){const d=await K(o,{fuid:e.fuid});try{const r=await this.downloadResult(o,{downloadPath:e.downloadPath,downloads:d.downloads,moduleId:e.moduleId,uuid:N});return{body:d.body,downloads:d.downloads,paths:r}}catch(r){if(!(r instanceof u)||!this.isRetryableAsyncDownloadError(r)||i===3)throw r;t=r,await this.sleep(3e3)}}throw t??new u("\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5")}formatResultText(o,e,t){const i=[];if(o.file&&i.push(o.file),!o.file&&(o.downloads.length>0||o.body)&&i.push("\u5206\u6790\u5B8C\u6210"),!o.file&&!o.body&&o.downloads.length===0)return"\u63D0\u4EA4\u5B8C\u6210";if(o.downloads.length>0&&!t)for(const d of o.downloads)i.push(`${d.label} (${d.device})`);for(const d of e)i.push(d);return i.join(`
|
|
2
|
+
`)}formatAsyncHistoryText(o,e){const t=[e];return o&&t.push(`\u5386\u53F2\u8BB0\u5F55: ${o.fuid} (${o.status})`),t.push(this.buildHistoryHint(o)),t.join(`
|
|
3
|
+
`)}formatAsyncHistoryDownloadText(o,e){const t=[];o&&t.push(`\u5386\u53F2\u8BB0\u5F55: ${o.fuid} (${o.status})`);for(const i of e)t.push(i);return t.join(`
|
|
4
|
+
`)}async downloadResult(o,e){if(e.downloads.length>0){const t=this.pickDownloadItem(e.downloads,e.downloadPath);if(!t)throw new u("\u5F53\u524D\u6A21\u5757\u8FD4\u56DE\u591A\u4E2A\u53EF\u4E0B\u8F7D\u7ED3\u679C\uFF0C\u8BF7\u5C06 `--download` \u8DEF\u5F84\u6539\u4E3A\u5E26\u76EE\u6807\u6269\u5C55\u540D\u7684\u6587\u4EF6\u540D\uFF0C\u6216\u4F7F\u7528 `--interactive` \u9009\u62E9\u3002");const i=await z(o,{item:t,moduleId:e.moduleId,uuid:e.uuid});return[await R(i.url,e.downloadPath)]}if(e.file)return[await R(e.file,e.downloadPath)];throw new u("\u5F53\u524D\u6A21\u5757\u672A\u8FD4\u56DE\u53EF\u4E0B\u8F7D\u6587\u4EF6\u3002")}pickDownloadItem(o,e){const t=this.inferDownloadDevice(e);if(t){const d=o.filter(r=>this.normalizeDevice(r.device)===t);if(d.length===1)return d[0]}const i=o.filter(d=>d.endpoint==="public.output.download-result");if(i.length===1)return i[0];if(o.length===1)return o[0]}inferDownloadDevice(o){if(!o)return;const e=o.trim().split(".").pop()?.toLowerCase();if(e)return this.normalizeDevice(e)}normalizeDevice(o){const e=o.trim().toLowerCase();return e==="tif"?"tiff":e==="jpg"?"jpeg":e}toHistorySummary(o,e){const t=o.fuid?.trim();return t?{fuid:t,id:typeof o.id=="number"?o.id:null,module_id:o.module_id?.trim()||e,module_name:o.module_name?.trim()||"",name:o.name?.trim()||"",status:J(o),time:o.time?.trim()||"",type:o.type?.trim()||""}:null}buildHistoryHint(o){return o?`\u53EF\u4F7F\u7528 \`xt history download ${o.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(o,e){const t=[];for(const i of e.downloads){const d=await z(o,{item:i,moduleId:e.moduleId,uuid:e.uuid});t.push(await R(d.url,d.fileName))}return t}async downloadInteractiveResults(o,e){const t=[];return e.choice.downloadFile&&e.file&&t.push(await R(e.file)),e.choice.downloads.length>0&&t.push(...await this.downloadSelectedResults(o,{downloads:e.choice.downloads,moduleId:e.moduleId,uuid:e.uuid})),t}isRetryableAsyncDownloadError(o){return o.message.includes("\u4E0B\u8F7D\u5931\u8D25")||o.message.includes("\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5")}async sleep(o){await new Promise(e=>setTimeout(e,o))}async resolveInputMode(o,e){if(e.demo)return{mode:"demo"};if(e.fileInputs.length>0)return{fileInputs:e.fileInputs,mode:"upload"};if(e.cloudRequested)return{mode:"cloud"};if(this.hasRecordInput(o))return{mode:"record"};if(this.hasCloudInput(o))return{mode:"cloud"};if(!e.interactive)return{mode:"upload"};if(!this.hasDemoInput(o))return{fileInputs:[await T()],mode:"upload"};const t=await Y();return t==="demo"?{mode:t}:{fileInputs:[await T()],mode:t}}resolveDemoInput(o,e){const t=o.id?.duid?.trim();if(!t)throw new u(`\u6A21\u5757 ${e} \u672A\u8FD4\u56DE demo duid\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);const i=C(o.args_data??[]);if(!i.length||i.some(d=>!d.defaultUpload))throw new u(`\u6A21\u5757 ${e} \u672A\u8FD4\u56DE\u53EF\u7528\u7684 demo \u6587\u4EF6\u4FE1\u606F\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);return{duid:t,input:{kind:"upload",uploads:i.map(d=>({key:d.key,label:d.label,upload:{fileName:d.defaultUpload.fileName,fileOss:d.defaultUpload.fileOss,fileSize:d.defaultUpload.fileSize}}))},schema:[]}}hasDemoInput(o){if(!o.id?.duid?.trim())return!1;const t=C(o.args_data??[]);return t.length>0&&t.every(i=>!!i.defaultUpload)}async resolveCloudInput(o,e,t,i,d){const r=x(o.args_data??[]),l=e.cloudKey?.trim()||r?.key||"";if(!l)throw new u(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u4E91\u7AEF\u6570\u636E\u53C2\u6570\uFF0C\u8BF7\u663E\u5F0F\u4F20\u5165 \`--cloudKey\`.`);const n=await this.resolveCloudRecord(i,e,{argsKey:l,defaultRecord:r?.record,moduleId:t,uuid:d});if(!n)throw new u(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE\u9ED8\u8BA4\u4E91\u7AEF\u6570\u636E\uFF0C\u8BF7\u4F20\u5165 \`--cloudRecordJson\` \u6216 \`--cloudRecordFile\`.`);return{duid:o.id?.duid?.trim()||"cloud",input:{kind:"cloud",cloud:{key:l,label:r?.label??"",record:this.normalizeCloudRecord(n)}},schema:[]}}resolveRecordInput(o,e){const t=o.id?.duid?.trim();if(!t)throw new u(`\u6A21\u5757 ${e} \u672A\u8FD4\u56DE record duid\uFF0C\u65E0\u6CD5\u4F7F\u7528\u5386\u53F2\u8BB0\u5F55\u8F93\u5165\u3002`);const i=M(o.args_data??[]);if(!i)throw new u(`\u6A21\u5757 ${e} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u6570\u636E\u8BB0\u5F55\uFF0C\u65E0\u6CD5\u76F4\u63A5\u8FD0\u884C\u3002`);return{duid:t,input:{kind:"record",record:{key:i.key,label:i.label,moduleId:i.moduleId,moduleName:i.moduleName,recordId:i.recordId,recordName:i.recordName,time:i.time}},schema:[]}}hasRecordInput(o){return!!(o.id?.duid?.trim()&&M(o.args_data??[]))}hasCloudInput(o){return!!x(o.args_data??[])}async uploadAndVerify(o,e,t,i){const d=await this.uploadFiles(o,e,t.argsData??[],t.moduleId),r=await ao(i,{argsMain:t.argsMain,moduleId:t.moduleId,uploads:d,uuid:t.uuid});return{duid:r.duid,input:{kind:"upload",uploads:d},schema:r.schema}}summarizePreparedInput(o){if(o.kind==="cloud")return{file_name:null,file_oss:null,file_size:null,input_cloud:this.summarizeCloudInput(o.cloud),input_record:null,input_uploads:null};if(o.kind==="record")return{file_name:null,file_oss:null,file_size:null,input_cloud:null,input_record:{label:o.record.label,module_id:o.record.moduleId,module_name:o.record.moduleName,record_id:o.record.recordId,record_name:o.record.recordName,time:o.record.time},input_uploads:null};const e=o.uploads.map(i=>({file_name:i.upload.fileName,file_oss:i.upload.fileOss,file_size:i.upload.fileSize,key:i.key,label:i.label})),t=e.length===1?e[0]:null;return{file_name:t?.file_name??null,file_oss:t?.file_oss??null,file_size:t?.file_size??null,input_cloud:null,input_record:null,input_uploads:e}}summarizeCloudInput(o){return{data_filter:this.readCloudOptionValue(o.record.data_filter),data_id:typeof o.record.data_id=="string"?o.record.data_id.trim():"",data_process:this.readCloudOptionValue(o.record.data_process),key:o.key,label:o.label,record:structuredClone(o.record),record_label:typeof o.record.label=="string"?o.record.label.trim():""}}readCloudOptionValue(o){return F(o)&&(typeof o.value=="string"?o.value.trim():"")||null}async resolveCloudRecord(o,e,t){return e.cloudRecordJson?this.parseCloudRecord(e.cloudRecordJson,"--cloudRecordJson"):e.cloudRecordFile?this.parseCloudRecord(await X(e.cloudRecordFile,"utf8"),"--cloudRecordFile"):e.cloudFilter?.trim()||e.cloudDataId?.trim()||typeof e.cloudIndex=="number"?this.resolveCloudRecordByQuery(o,e,t):t.defaultRecord}parseCloudRecord(o,e){let t;try{t=JSON.parse(o)}catch{throw new u(`${e} \u4E0D\u662F\u5408\u6CD5 JSON\u3002`)}if(!F(t))throw new u(`${e} \u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002`);return t}normalizeCloudRecord(o){const e={};for(const[t,i]of Object.entries(o))i!==void 0&&(e[t]=structuredClone(i));return(typeof e.type!="string"||!e.type.trim())&&(e.type="cloud"),e}validateInputSourceFlags(o,e){const t=!!(e.cloudRecordJson||e.cloudRecordFile),i=!!(e.cloudDataId?.trim()||e.cloudFilter?.trim()||typeof e.cloudIndex=="number"),d=t||i;if(e.cloudRecordJson&&e.cloudRecordFile)throw new u("`--cloudRecordJson` \u4E0E `--cloudRecordFile` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");if(t&&i)throw new u("\u663E\u5F0F\u4E91\u7AEF\u8BB0\u5F55\u53C2\u6570\u4E0D\u80FD\u4E0E `--cloudFilter` / `--cloudDataId` / `--cloudIndex` \u540C\u65F6\u4F7F\u7528\u3002");if(e.demo&&d)throw new u("`--demo` \u4E0D\u80FD\u4E0E\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u53C2\u6570\u540C\u65F6\u4F7F\u7528\u3002");if(o.length>0&&d)throw new u("`--file` \u4E0D\u80FD\u4E0E\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u53C2\u6570\u540C\u65F6\u4F7F\u7528\u3002")}async resolveCloudRecordByQuery(o,e,t){const i=await this.fetchCloudRecords(o,{argsKey:t.argsKey,filter:e.cloudFilter?.trim(),moduleId:t.moduleId,selectedRecord:t.defaultRecord,uuid:t.uuid});if(i.length===0){const r=e.cloudFilter?.trim();throw r?new u(`\u672A\u627E\u5230\u5339\u914D\u4E91\u7AEF\u6570\u636E: ${r}`):new u("\u5F53\u524D\u6A21\u5757\u6CA1\u6709\u53EF\u9009\u7684\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u3002")}const d=e.cloudDataId?.trim();if(d){const r=i.find(l=>(typeof l.data_id=="string"?l.data_id.trim():"")===d);if(!r)throw new u(`\u672A\u627E\u5230 data_id=${d} \u5BF9\u5E94\u7684\u4E91\u7AEF\u6570\u636E\u3002`);return r}if(typeof e.cloudIndex=="number"){const r=i[e.cloudIndex];if(!r)throw new u(`\u4E91\u7AEF\u6570\u636E\u7D22\u5F15\u8D85\u51FA\u8303\u56F4: ${e.cloudIndex}\uFF0C\u5F53\u524D\u5171\u6709 ${i.length} \u6761\u3002`);return r}if(i.length===1)return i[0];if(e.interactive)return this.normalizeCloudRecord(await G(i));throw new E(this.buildCloudSelectionHint(i,e.cloudFilter?.trim()),this.buildCloudSelectionData(i,e.cloudFilter?.trim()))}async fetchCloudRecords(o,e){const t=await A(o,{argsKey:e.argsKey,currentPage:1,filter:e.filter,moduleId:e.moduleId,selectedRecord:e.selectedRecord,uuid:e.uuid}),i=t.records.map(d=>this.normalizeCloudRecord(d));for(let d=t.currentPage+1;d<=t.lastPage;d+=1){const r=await A(o,{argsKey:e.argsKey,currentPage:d,filter:e.filter,moduleId:e.moduleId,selectedRecord:e.selectedRecord,uuid:e.uuid});i.push(...r.records.map(l=>this.normalizeCloudRecord(l)))}return i}buildCloudSelectionHint(o,e){const t=[e?`\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E: ${e}`:"\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E","\u8BF7\u4F7F\u7528 `--cloudIndex` \u6216 `--cloudDataId` \u6307\u5B9A\u5176\u4E2D\u4E00\u6761\uFF1A"];return o.forEach((i,d)=>{const r=typeof i.data_id=="string"?i.data_id.trim():"",l=typeof i.label=="string"?i.label.trim():"";t.push(` [${d}] ${l||r}`)}),t.join(`
|
|
5
|
+
`)}buildCloudSelectionData(o,e){return{choices:o.map((t,i)=>{const d=typeof t.data_id=="string"?t.data_id.trim():"",r=typeof t.label=="string"?t.label.trim():"";return{data_id:d,index:i,label:r||d}}),filter:e??"",selection_type:"cloud_record"}}async uploadFiles(o,e,t,i){const d=C(t??[]),r=this.resolveUploadInputs(e,d,i),l=await $(o),n=[];for(const a of r){const s=await oo(l,a.filePath);n.push({key:a.key,label:a.label,upload:s})}return n}resolveUploadInputs(o,e,t){if(!e.length)throw new u(`\u6A21\u5757 ${t} \u672A\u68C0\u6D4B\u5230\u53EF\u4E0A\u4F20\u8F93\u5165\uFF0C\u4E0D\u80FD\u4F7F\u7528 \`--file\`\u3002`);if(!o.length)throw e.length===1?new u("\u901A\u7528\u6A21\u5F0F\u8BF7\u4F20\u5165 FILE / `--file <xlsx>`\uFF0C\u6216\u6539\u7528 `--demo`\u3002"):new u(`\u6A21\u5757 ${t} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${e.map(n=>n.key).join(", ")}`);const[i]=e;if(e.length===1&&o.length===1){const n=this.parseUploadFileInput(o[0]);if(n.key&&n.key!==i.key)throw new u(`\u6A21\u5757 ${t} \u4EC5\u652F\u6301\u4E0A\u4F20\u5B57\u6BB5 ${i.key}\uFF0C\u6536\u5230 ${n.key}\u3002`);return[{filePath:n.path,key:i.key,label:i.label}]}const d=new Map(e.map(n=>[n.key,n])),r=new Map;for(const n of o){const a=this.parseUploadFileInput(n);if(!a.key){if(e.length===1){if(r.has(i.key))throw new u(`\u6A21\u5757 ${t} \u4EC5\u9700\u8981 1 \u4E2A\u4E0A\u4F20\u6587\u4EF6\uFF0C\u6536\u5230\u91CD\u590D\u8F93\u5165\u3002`);r.set(i.key,a.path);continue}throw new u(`\u6A21\u5757 ${t} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${e.map(c=>c.key).join(", ")}`)}const s=d.get(a.key);if(!s)throw new u(`\u6A21\u5757 ${t} \u4E0D\u5B58\u5728\u4E0A\u4F20\u5B57\u6BB5 ${a.key}\u3002\u53EF\u7528\u5B57\u6BB5: ${e.map(c=>c.key).join(", ")}`);if(r.has(s.key))throw new u(`\u4E0A\u4F20\u5B57\u6BB5 ${s.key} \u91CD\u590D\u4F20\u5165\u3002`);r.set(s.key,a.path)}const l=e.filter(n=>n.required&&!r.has(n.key));if(l.length>0)throw new u(`\u6A21\u5757 ${t} \u7F3A\u5C11\u5FC5\u586B\u4E0A\u4F20\u5B57\u6BB5: ${l.map(n=>n.key).join(", ")}`);return e.flatMap(n=>{const a=r.get(n.key);return a?[{filePath:a,key:n.key,label:n.label}]:[]})}parseUploadFileInput(o){const e=o.trim();if(!e)throw new u("`--file` \u4E0D\u80FD\u4E3A\u7A7A\u3002");const t=e.indexOf("=");if(t<=0)return{path:e};const i=e.slice(0,t).trim(),d=e.slice(t+1).trim();if(!i||!d)throw new u("\u591A\u4E0A\u4F20\u6A21\u5757\u8BF7\u4F7F\u7528 `--file key=path`\u3002");return{key:i,path:d}}async resolveModule(o,e,t){const i=o?.trim(),d=e.route?.trim(),r=e.uuid?.trim(),l=await no(e.toolProductUuid);if(!i){if(!e.interactive)throw new u("\u8BF7\u4F20\u5165 `module_id`\uFF0C\u6216\u4F7F\u7528 `--interactive --file <xlsx>` \u5148\u4ECE\u83DC\u5355\u9009\u62E9\u5DE5\u5177\u3002");const a=await W(this.sortTopLevelMenus(await mo(t,l)));return{moduleId:a.code,route:d??a.route,toolProductUuid:l,uuid:r??a.uuid}}if(d&&r)return{moduleId:i,route:d,toolProductUuid:l,uuid:r};const n=e.menuUuid?.trim();if(n&&l){const a=await co(t,n,l),s=d??this.requireMenuRoute(a),c=a.code?.trim();if(c&&c!==i)throw new u(`\u83DC\u5355\u6A21\u5757 code \u4E3A ${c}\uFF0C\u4E0E\u4F20\u5165\u7684 module_id ${i} \u4E0D\u4E00\u81F4\u3002`);return{moduleId:i,route:s,toolProductUuid:l,uuid:r??n}}if(l){const a=await fo(t,l,i);return{moduleId:i,route:d??a.route,toolProductUuid:l,uuid:r??a.uuid}}if(!r)throw new u("\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 u("\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:i,route:d,toolProductUuid:l,uuid:r}}sortTopLevelMenus(o){const e=["\u57FA\u7840\u7ED8\u56FE","\u8868\u8FBE\u5DEE\u5F02","\u529F\u80FD\u805A\u7C7B","\u4EA4\u4E92\u7F51\u7EDC","\u4E34\u5E8A\u610F\u4E49","\u5176\u4ED6"],t=new Map(e.map((i,d)=>[i,d]));return[...o].sort((i,d)=>{const r=t.get(i.title?.trim()??"")??Number.MAX_SAFE_INTEGER,l=t.get(d.title?.trim()??"")??Number.MAX_SAFE_INTEGER;return r-l})}requireMenuRoute(o){const e=o.route;if(typeof e!="string"||!e.trim())throw new u("\u83DC\u5355\u672A\u8FD4\u56DE\u53EF\u7528 route\uFF0C\u8BF7\u6539\u7528 `--route` \u663E\u5F0F\u6307\u5B9A\u3002");return e.trim()}}class U extends wo{static description="Run a Xiantao bioinformatics tool";static args={tool:D.string({description:"Tool id; optional with --interactive to choose from menus"}),file:D.string({description:"Path to the local xlsx file; optional with --demo or --interactive"})};static flags={...j,...B,...io,demo:f.boolean({default:!1,description:"Use the module demo data returned by fetch-all instead of uploading a local file"}),file:f.string({description:"Path to the local xlsx file; repeat or use KEY=PATH for named upload fields",multiple:!0}),download:f.string({description:"Download the generated file or preferred analysis result to this local path after submission"}),interactive:f.boolean({default:!1,description:"Prompt for dynamic args before submitting the module"}),menuUuid:f.string({description:"Tool menu UUID from /products/apply/:toolProductUuid/analyse/:uuid"}),route:f.string({description:"Tool route like app1.violin_flat in generic mode"}),token:f.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:f.string({description:"tool_product_uuid used to auto-resolve module UUID and route in generic mode; defaults to the main Xiantao product UUID"}),uuid:f.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:o,flags:e}=await this.parse(U);if(e.interactive&&e.json)throw new u("`--interactive` \u4E0D\u80FD\u4E0E `--json` \u540C\u65F6\u4F7F\u7528\u3002");const t=this.resolveToolFileInputs(o.file,e.file),i=await this.executeToolRun(o.tool,t,e);this.print(e,i.data,i.text,{profile:i.data.agent})}}export{wo as ToolRunCommandBase,U as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readFile as y}from"node:fs/promises";import{Args as P,Flags as l}from"@oclif/core";import{XtzCommand as _}from"../../base-command.js";import{getAuthContext as S}from"../../lib/auth.js";import{createErrorEnvelope as k,createSuccessEnvelope as b}from"../../lib/envelope.js";import{XtzError as n}from"../../lib/errors.js";import{globalFlags as F}from"../../lib/flags.js";import{isJsonObject as J}from"../../lib/json.js";import{resolveXiantaoToolProductUuid as x}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as O}from"../../lib/tool-inputs.js";import{fetchXiantaoCloudData as v}from"../../lib/xiantao-cloud.js";import{fetchAllPlotArgs as U,fetchToolMenu as R,resolveToolMenuByCode as C}from"../../lib/xiantao.js";class m extends _{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:P.string({description:"Tool id, e.g. km_plot_gene",required:!0})};static flags={...F,all:l.boolean({default:!1,description:"Fetch from the current page through the last page and merge all records"}),argsKey:l.string({description:"Cloud data key such as surv; defaults to the detected cloud input key"}),filter:l.string({description:"Cloud data filter value, such as a disease name"}),page:l.integer({default:1,description:"1-based cloud data page number",min:1}),recordFile:l.string({description:"Path to a JSON file containing the current cloud record seed"}),recordJson:l.string({description:"JSON string for the current cloud record seed"}),token:l.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),toolProductUuid:l.string({description:"tool_product_uuid used to auto-resolve the tool UUID; defaults to the main Xiantao product UUID"}),uuid:l.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(k(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 n("`xt tool cloud` \u4EC5\u652F\u6301 `--json` \u8F93\u51FA\u3002");if(e.recordJson&&e.recordFile)throw new n("`--recordJson` \u4E0E `--recordFile` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");const r=await this.getProfile(e.profile),d=await S(r,e.token),c=await x(e.toolProductUuid),o=await this.resolveToolMeta(d,c,t.tool,e.uuid),u=await U(d,{moduleId:t.tool,uuid:o.uuid}),i=O(u.args_data??[]),f=e.argsKey?.trim()||i?.key||"";if(!f)throw new n(`\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,i?.record),a=await v(d,{argsKey:f,currentPage:e.page,filter:e.filter,moduleId:t.tool,selectedRecord:p,uuid:o.uuid}),w=[a.currentPage],h=[...a.records];if(e.all)for(let s=a.currentPage+1;s<=a.lastPage;s+=1){const g=await v(d,{argsKey:f,currentPage:s,filter:e.filter,moduleId:t.tool,selectedRecord:p,uuid:o.uuid});w.push(g.currentPage),h.push(...g.records)}this.log(JSON.stringify(b(r,"tool cloud",{agent:r,args_key:f,choices:h.map((s,g)=>({data_id:typeof s.data_id=="string"?s.data_id.trim():"",index:g,label:typeof s.label=="string"?s.label.trim():""})),columns:a.columnAttrs,default_cloud:i?{key:i.key,label:i.label,record:i.record}:null,filter:{options:a.filter.options,value:a.filter.value},filter_keyword:e.filter?.trim()??"",info:a.info,module_id:t.tool,page:a.currentPage,pages_fetched:w,path:o.path,records:h,route:o.route,selected_record:p??null,selected_record_source:this.inferSelectedRecordSource(e.recordJson,e.recordFile,i?.record),title:o.title,tool_product_uuid:c,total:a.total,total_pages:a.lastPage,uuid:o.uuid}),null,2))}async resolveToolMeta(t,e,r,d){const c=d?.trim();if(!c){const i=await C(t,e,r);return{path:i.path,route:i.route,title:i.title,uuid:i.uuid}}const o=await R(t,c,e),u=o.code?.trim();if(u&&u!==r)throw new n(`\`--uuid\` \u5BF9\u5E94\u7684\u6A21\u5757\u662F ${u}\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 n(`${e} \u4E0D\u662F\u5408\u6CD5 JSON\u3002`)}if(!J(r))throw new n(`${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 n("`xt tool cloud` \u9700\u8981\u4F20\u5165 TOOL\u3002"):t}}export{m 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 f}from"../../lib/flags.js";import{plotOverrideFlags as
|
|
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 f,toolCloudFlags as c}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>]";static args={tool:a.string({description:"Tool id, e.g. violin_flat",required:!0}),file:a.string({hidden:!0})};static flags={...f,...c,...g,demo:o.boolean({default:!1,description:"Use the module demo data 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"}),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 main Xiantao 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 n=await this.executeToolRun(t.tool,l,{...e,interactive:!1}),s=await this.getProfile(e.profile);this.log(JSON.stringify(u(s,"tool exec",n.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,3 +1,3 @@
|
|
|
1
|
-
import{Args as
|
|
2
|
-
`);
|
|
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 k}from"../../lib/flags.js";import{isJsonObject as q}from"../../lib/json.js";import{buildArgsMainFromSchema as v,buildArgsSpecificFromSchema as x}from"../../lib/plot-schema.js";import{resolveXiantaoToolProductUuid as B}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as A,findDefaultXiantaoRecord as C,listXiantaoUploadFields as F}from"../../lib/tool-inputs.js";import{fetchAllPlotArgs as I,resolveToolMenuByCode as S}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={...k,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 main Xiantao product UUID"})};async run(){const{args:e,flags:l}=await this.parse(p),a=await this.getProfile(l.profile),n=await y(a,l.token),u=await B(l.toolProductUuid),s=await S(n,u,e.tool),i=await I(n,{moduleId:e.tool,uuid:s.uuid}),f=i.args_main??[],r=this.summarizeInputs(i.args_data??[],i.id?.duid??""),c=this.summarizeSchema(f),t={agent:a,args_data:i.args_data??[],args_main:f,args_main_defaults:v(f),args_specific:i.args_specific??[],args_specific_defaults:x(i.args_specific),duid:i.id?.duid??"",inputs:r,module_id:e.tool,notice:i.notice??"",path:s.path,route:s.route,summary:c,title:s.title,tool_product_uuid:u,uuid:s.uuid};this.print(l,t,this.formatInspectText(t.module_id,t.title,t.path,t.route,t.uuid,t.notice,r,c,i.args_specific??[],f),{profile:a})}formatInspectText(e,l,a,n,u,s,i,f,r,c){const t=[`${e} ${l}`,`path: ${a||"-"}`,`route: ${n}`,`uuid: ${u}`];s&&t.push(`notice: ${s}`),t.push("input:"),t.push(` cloud: ${i.cloud_available?this.formatCloudSummary(i.cloud_default):"unavailable"}`),t.push(` upload: ${i.upload_available?`${i.upload_fields.length} fields`:"not detected"}`);for(const o of i.upload_fields){const m=[o.label&&o.label!==o.key?o.label:void 0,o.required?"required":void 0,o.demo_upload?this.formatDemoSummary(o.demo_upload):"no demo default"].filter(Boolean);t.push(` - ${o.key}${m.length>0?` - ${m.join(", ")}`:""}`)}if(t.push(` demo: ${i.demo_available?"available":"unavailable"}`),t.push(` record: ${i.record_available?this.formatRecordSummary(i.record_default):"unavailable"}`),r.length>0){t.push(`args_specific: ${r.length} fields`);for(const o of r){const m=[o.label?.trim()&&o.label.trim()!==o.key?o.label.trim():void 0,o.type?.trim(),o.required?"required":void 0,o.multiple?"multiple":void 0,this.formatDefaultValue(o.default_value)].filter(Boolean);t.push(` ${o.key}${m.length>0?` - ${m.join(", ")}`:""}`)}}else t.push("args_specific: none");if(c.length===0)return t.push("args_main: none"),t.join(`
|
|
2
|
+
`);t.push(`args_main: ${f.section_count} sections, ${f.field_count} fields, ${f.required_field_count} required`);for(const o of c){const m=o.form??[],g=m.filter(d=>d.required).length;t.push(`- ${o.label?.trim()||o.key} (${o.key}) - ${m.length} fields, ${g} required`);for(const d of o.form??[]){const _=[d.label?.trim()&&d.label.trim()!==d.key?d.label.trim():void 0,d.type?.trim(),d.required?"required":void 0,d.multiple?"multiple":void 0,d.options?.length?`options:${d.options.length}`:void 0,this.formatDefaultValue(d.default_value)].filter(Boolean);t.push(` ${d.key}${_.length>0?` - ${_.join(", ")}`:""}`)}}return t.join(`
|
|
3
|
+
`)}summarizeInputs(e,l){const a=F(e),n=C(e),u=A(e),s=!!(l.trim()&&a.length>0&&a.every(r=>!!r.defaultUpload)),i=!!(l.trim()&&n),f=i&&n?{key:n.key,label:n.label,module_id:n.moduleId,module_name:n.moduleName,record_id:n.recordId,record_name:n.recordName,time:n.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:f,upload_available:a.length>0,upload_fields:a.map(r=>({demo_upload:r.defaultUpload?{file_name:r.defaultUpload.fileName,file_oss:r.defaultUpload.fileOss,file_size:r.defaultUpload.fileSize,key:r.key,label:r.label}:null,key:r.key,label:r.label,required:r.required}))}}summarizeSchema(e){const l=e.flatMap(a=>a.form??[]);return{field_count:l.length,required_field_count:l.filter(a=>a.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 l=[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}${l.length>0?` (${l.join(", ")})`:""}`}toCloudSummary(e,l,a){const n=this.readCloudOptionValue(a.data_filter),u=this.readCloudOptionValue(a.data_process);return{data_filter:n,data_id:typeof a.data_id=="string"?a.data_id.trim():"",data_process:u,key:e,label:l,record_label:typeof a.label=="string"?a.label.trim():""}}readCloudOptionValue(e){return q(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`}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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as n,Flags as
|
|
1
|
+
import{Args as n,Flags as o}from"@oclif/core";import{createErrorEnvelope as u,createSuccessEnvelope as d}from"../../lib/envelope.js";import{XtzError as r}from"../../lib/errors.js";import{globalFlags as p,toolCloudFlags as c}from"../../lib/flags.js";import{plotOverrideFlags as f}from"../../lib/plot-options.js";import{buildArgsMainFromSchema as m,buildArgsSpecificFromSchema as g}from"../../lib/plot-schema.js";import{ToolRunCommandBase as h}from"../plot/run.js";class a extends h{static description="Prepare a Xiantao bioinformatics tool in agent mode and return the final dynamic schema";static usage="tool prepare <tool> [--file <value> ... | --demo] --json";static args={tool:n.string({description:"Tool id, e.g. violin_flat",required:!0}),file:n.string({hidden:!0})};static flags={...p,...c,...f,demo:o.boolean({default:!1,description:"Use the module demo data returned by fetch-all instead of uploading a local file"}),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 main Xiantao 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 i=await this.getProfile(this.readProfileFlag());this.log(JSON.stringify(u(i,"tool prepare",this.normalizeError(t)),null,2)),this.exit(1)}async run(){const{args:t,flags:i}=await this.parse(a);if(!i.json)throw new r("`xt tool prepare` \u4EC5\u652F\u6301 `--json` \u8F93\u51FA\u3002");const l=this.resolveToolFileInputs(t.file,i.file);if(i.demo&&l.length>0)throw new r("`--demo` \u4E0E `--file` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");const e=await this.prepareToolRun(t.tool,l,{...i,interactive:!1}),s=await this.getProfile(i.profile);this.log(JSON.stringify(d(s,"tool prepare",{agent:e.agent,args_main:e.schema??[],args_main_defaults:m(e.schema),args_main_prepared:e.argsMain,args_specific:e.argsSpecificSchema,args_specific_defaults:g(e.argsSpecificSchema),args_specific_prepared:e.argsSpecific,duid:e.duid,file_name:e.inputSummary.file_name,file_oss:e.inputSummary.file_oss,file_size:e.inputSummary.file_size,input_cloud:e.inputSummary.input_cloud,input_record:e.inputSummary.input_record,input_uploads:e.inputSummary.input_uploads,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,route:e.route,tool_product_uuid:e.toolProductUuid,uuid:e.uuid}),null,2))}readProfileFlag(){for(let t=0;t<this.argv.length;t+=1){const i=this.argv[t];if((i==="--profile"||i==="--agent")&&this.argv[t+1])return this.argv[t+1];if(i.startsWith("--profile="))return i.slice(10);if(i.startsWith("--agent="))return i.slice(8)}}normalizeError(t){return t.message.replace(/\u001B\[[0-?]*[ -/]*[@-~]/g,"").includes("required arg")?new r("`xt tool prepare` \u9700\u8981\u4F20\u5165 TOOL\u3002"):t}}export{a as default};
|
package/dist/lib/envelope.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
import{XtzChoiceRequiredError as d}from"./errors.js";function e(n,u,i){return{code:"OK",data:i,message:"",meta:{command:u,profile:n,version:"1"},ok:!0}}function o(n,u,i){const r=i instanceof Error?i.message:String(i),c=i instanceof d?i.data:null;return{code:l(r),data:c,message:r,meta:{command:u,profile:n,version:"1"},ok:!1}}function l(n){return n.includes("\u6388\u6743\u5DF2\u8FC7\u671F")||n.includes("\u6388\u6743\u5DF2\u8FC7\u671F\u6216\u65E0\u6548")?"AUTH_EXPIRED":n.includes("\u672A\u627E\u5230")&&n.includes("token")?"AUTH_REQUIRED":n.includes("\u672A\u627E\u5230\u6A21\u5757")?"TOOL_NOT_FOUND":n.includes("\u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C")||n.includes("\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E")?"TOOL_AMBIGUOUS":n.includes("Missing 1 required arg")||n.includes("Missing 2 required args")||n.includes("Missing required arg")||n.includes("\u9700\u8981\u4F20\u5165 TOOL")||n.includes("\u8BF7\u4F20\u5165 `module_id`")||n.includes("\u8BF7\u4F20\u5165 FILE")||n.includes("\u9700\u8981 `--uuid`")||n.includes("\u9700\u8981 `--route`")||n.includes("\u9700\u8981 `--file`")?"INPUT_REQUIRED":n.includes("\u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E")||n.includes("\u4E0D\u662F\u5408\u6CD5 JSON")||n.includes("Unexpected argument:")||n.includes("\u4E0D\u80FD\u540C\u65F6\u4F7F\u7528")||n.includes("\u4E0D\u80FD\u4E0E")||n.includes("\u65E0\u6548")||n.includes("\u4E0D\u4E00\u81F4")?"INPUT_INVALID":n.includes("\u672A\u8FD4\u56DE\u53EF\u4E0B\u8F7D\u6587\u4EF6")||n.includes("\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5")?"DOWNLOAD_NOT_AVAILABLE":n.includes("\u7F51\u7EDC")||n.includes("\u4E0B\u8F7D\u5931\u8D25")||n.includes("\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94")?"NETWORK_ERROR":"INTERNAL_ERROR"}export{o as createErrorEnvelope,e as createSuccessEnvelope};
|
package/dist/lib/errors.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{deleteToken as
|
|
1
|
+
import{deleteToken as o}from"./storage.js";class t extends Error{constructor(n){super(n),this.name="XtzError"}}class c extends t{data;constructor(n,r){super(n),this.data=r,this.name="XtzChoiceRequiredError"}}function w(e){return e.includes("\u672A\u6388\u6743")||e.includes("\u8BF7\u767B\u5F55")||e.includes("\u91CD\u65B0\u767B\u5F55")||e.includes("\u8EAB\u4EFD\u9A8C\u8BC1\u5DF2\u8FC7\u671F")}async function h(e,n={}){const r=e.message??"\u8BF7\u6C42\u5931\u8D25",i=String(e.code??"");throw w(r)?(n.agent&&await o(n.agent),new t("\u60A8\u7684\u6388\u6743\u5DF2\u8FC7\u671F\u6216\u65E0\u6548\uFF0C\u8BF7\u91CD\u65B0\u5B8C\u6210\u6388\u6743\u3002")):r.includes("\u65E0\u6743\u9650")||r.includes("\u6743\u9650")?new t("\u9700\u8D2D\u4E70\u4ED9\u6843\u9AD8\u7EA7\u7248 https://www.xiantaozi.com/"):i==="5000000101"?new t("\u5F53\u524D\u7F51\u7EDC\u72B6\u6001\u5F02\u5E38\uFF0C\u8BF7\u524D\u5F80 https://www.helixlife.cn \u8054\u7CFB\u5BA2\u670D"):i==="4000020101"||i==="400008"?new t("\u60A8\u7684\u8D26\u53F7\u72B6\u6001\u5F02\u5E38\uFF0C\u8BF7\u8054\u7CFB https://www.helixlife.cn"):i==="400004"?new t("\u8BE5\u83DC\u5355\u6216\u5546\u54C1\u5DF2\u4E0B\u67B6\uFF0C\u8BF7\u66F4\u6362 tool_product_uuid \u6216 menu uuid\u3002"):i==="50000"||i==="40000"||i==="40004"?new t("\u8BF7\u524D\u5F80 https://www.helixlife.cn \u8054\u7CFB\u5BA2\u670D"):r.includes("\u901F\u7387\u9650\u5236")?new t("\u5EFA\u8BAE\u6B21\u65E5\u518D\u8BD5"):new t(r||"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u5BA2\u670D https://www.helixlife.cn")}export{c as XtzChoiceRequiredError,t as XtzError,h as raiseApiError};
|
package/dist/lib/flags.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Flags as
|
|
1
|
+
import{Flags as e}from"@oclif/core";const t={profile:e.string({aliases:["agent"],description:"Profile name used for token lookup"}),json:e.boolean({default:!1,description:"Output JSON"})},d={cloudDataId:e.string({description:"Select a cloud record by data_id, such as tcga-brca-2"}),cloudKey:e.string({description:"Cloud data key such as surv; defaults to the detected cloud input key"}),cloudFilter:e.string({description:"Filter cloud records by disease or keyword, such as \u4E73\u817A\u6D78\u6DA6\u764C"}),cloudIndex:e.integer({description:"0-based index into the matched cloud records",min:0}),cloudRecordFile:e.string({description:"Path to a JSON file containing the selected cloud record"}),cloudRecordJson:e.string({description:"JSON string containing the selected cloud record"})};export{t as globalFlags,d as toolCloudFlags};
|
|
@@ -1,35 +1,39 @@
|
|
|
1
|
-
import m from"node:readline/promises";import{stdin as d,stdout as s}from"node:process";import{XtzError as a}from"./errors.js";import{isJsonObject as y}from"./json.js";import{formatSetOverrides as x}from"./plot-options.js";import{getBrowsableToolMenuChildren as S,isRunnableToolMenu as
|
|
1
|
+
import m from"node:readline/promises";import{stdin as d,stdout as s}from"node:process";import{XtzError as a}from"./errors.js";import{isJsonObject as y}from"./json.js";import{formatSetOverrides as x}from"./plot-options.js";import{getBrowsableToolMenuChildren as S,isRunnableToolMenu as C}from"./xiantao.js";async function V(t,e){h();const n=m.createInterface({input:d,output:s}),r=structuredClone(e);try{let i=0,o=0;for(;i<t.length;){const u=t[i],l=u.form??[];if(l.length===0){i+=1,o=0;continue}for(s.write(`
|
|
2
2
|
[${u.label?.trim()||u.key}]
|
|
3
3
|
`),s.write(`\u56DE\u8F66\u4FDD\u7559\u9ED8\u8BA4\u503C\uFF0C\u8F93\u5165 < \u8FD4\u56DE\u4E0A\u4E00\u9879\uFF0C\u8F93\u5165 /skip \u8DF3\u8FC7\u672C\u7EC4\u3002
|
|
4
|
-
`);o<
|
|
5
|
-
`);continue}i=
|
|
4
|
+
`);o<l.length;){const w=l[o],c=r[u.key];if(!y(c)){o+=1;continue}const f=c[w.key];if(!y(f)){o+=1;continue}const p=await k(n,w,f.value);if(p.type==="back"){const N=R(t,i,o);if(!N){s.write(`\u5DF2\u7ECF\u662F\u7B2C\u4E00\u9879\u3002
|
|
5
|
+
`);continue}i=N.sectionIndex,o=N.fieldIndex;break}if(p.type==="skip"){i+=1,o=0;break}f.value=p.value,o+=1}o>=l.length&&(i+=1,o=0)}}finally{n.close()}return r}async function tt(t){h(),s.write(`
|
|
6
6
|
\u6700\u7EC8\u53C2\u6570:
|
|
7
7
|
`),s.write(`${JSON.stringify(t,null,2)}
|
|
8
8
|
`),s.write(`
|
|
9
9
|
\u53EF\u590D\u7528 --set:
|
|
10
10
|
`);for(const n of x(t))s.write(`${n}
|
|
11
|
-
`);const e=m.createInterface({input:d,output:s});try{const n=(await e.question("\u786E\u8BA4\u63D0\u4EA4? [y/N] ")).trim().toLowerCase();if(n!=="y"&&n!=="yes")throw new a("\u5DF2\u53D6\u6D88\u63D0\u4EA4\u3002")}finally{e.close()}}async function
|
|
11
|
+
`);const e=m.createInterface({input:d,output:s});try{const n=(await e.question("\u786E\u8BA4\u63D0\u4EA4? [y/N] ")).trim().toLowerCase();if(n!=="y"&&n!=="yes")throw new a("\u5DF2\u53D6\u6D88\u63D0\u4EA4\u3002")}finally{e.close()}}async function et(t){if(h(),t.length===0)return[];const e=m.createInterface({input:d,output:s});try{return await v(e,t)}finally{e.close()}}async function nt(t){h();const e=t.filter(u=>_(u));if(e.length===0)throw new a("\u5F53\u524D\u4EA7\u54C1\u672A\u8FD4\u56DE\u53EF\u9009\u5DE5\u5177\u76EE\u5F55\u3002");const n=m.createInterface({input:d,output:s}),r=[];let i=e,o="\u9009\u62E9\u5927\u7C7B";try{for(;;){s.write(`
|
|
12
12
|
[${o}]
|
|
13
|
-
`),i.forEach((
|
|
14
|
-
`)});const u=r.length>0?"\u8F93\u5165\u7F16\u53F7\uFF0C< \u8FD4\u56DE\u4E0A\u4E00\u7EA7\uFF0C\u56DE\u8F66\u53D6\u6D88: ":"\u8F93\u5165\u7F16\u53F7\uFF0C\u56DE\u8F66\u53D6\u6D88: ";try{const
|
|
15
|
-
`);continue}i=p.menus,o=p.title;continue}const w=Number(
|
|
16
|
-
`)}}}finally{n.close()}}async function
|
|
17
|
-
\u8F93\u5165\u5F85\u4E0A\u4F20\u7684 xlsx \u6587\u4EF6\u8DEF\u5F84\uFF0C\u56DE\u8F66\u53D6\u6D88: `)).trim();if(!e)throw new a("\u5DF2\u53D6\u6D88\u6587\u4EF6\u9009\u62E9\u3002");return e}}finally{t.close()}}async function
|
|
13
|
+
`),i.forEach((l,w)=>{const c=A(l),f=S(l).length>0?" >":` (${l.code?.trim()??"-"})`;s.write(` ${w+1}. ${c}${f}
|
|
14
|
+
`)});const u=r.length>0?"\u8F93\u5165\u7F16\u53F7\uFF0C< \u8FD4\u56DE\u4E0A\u4E00\u7EA7\uFF0C\u56DE\u8F66\u53D6\u6D88: ":"\u8F93\u5165\u7F16\u53F7\uFF0C\u56DE\u8F66\u53D6\u6D88: ";try{const l=(await n.question(u)).trim();if(!l)throw new a("\u5DF2\u53D6\u6D88\u5DE5\u5177\u9009\u62E9\u3002");if(l==="<"){const p=r.pop();if(!p){s.write(`\u5DF2\u7ECF\u662F\u9876\u5C42\u76EE\u5F55\u3002
|
|
15
|
+
`);continue}i=p.menus,o=p.title;continue}const w=Number(l);if(!Number.isInteger(w)||w<1||w>i.length)throw new a(`\u65E0\u6548\u9009\u9879: ${l}`);const c=i[w-1],f=S(c);if(f.length>0){r.push({menus:i,title:o}),i=f,o=A(c);continue}if(!C(c))throw new a(`${A(c)} \u7F3A\u5C11\u53EF\u6267\u884C\u4FE1\u606F\uFF0C\u8BF7\u6539\u7528\u663E\u5F0F module_id/uuid\u3002`);return D(c)}catch(l){if(!(l instanceof a))throw l;s.write(`${l.message}
|
|
16
|
+
`)}}}finally{n.close()}}async function rt(){h();const t=m.createInterface({input:d,output:s});try{for(;;){const e=(await t.question(`
|
|
17
|
+
\u8F93\u5165\u5F85\u4E0A\u4F20\u7684 xlsx \u6587\u4EF6\u8DEF\u5F84\uFF0C\u56DE\u8F66\u53D6\u6D88: `)).trim();if(!e)throw new a("\u5DF2\u53D6\u6D88\u6587\u4EF6\u9009\u62E9\u3002");return e}}finally{t.close()}}async function it(){h();const t=m.createInterface({input:d,output:s});try{for(;;)try{s.write(`
|
|
18
18
|
[\u6570\u636E\u6765\u6E90]
|
|
19
19
|
`),s.write(` 1. \u4E0A\u4F20\u672C\u5730\u6587\u4EF6
|
|
20
20
|
`),s.write(` 2. \u4F7F\u7528 demo \u6570\u636E
|
|
21
21
|
`);const e=(await t.question("\u8F93\u5165\u7F16\u53F7\uFF0C\u56DE\u8F66\u53D6\u6D88: ")).trim();if(!e)throw new a("\u5DF2\u53D6\u6D88\u6570\u636E\u6765\u6E90\u9009\u62E9\u3002");if(e==="1")return"upload";if(e==="2")return"demo";throw new a(`\u65E0\u6548\u9009\u9879: ${e}`)}catch(e){if(!(e instanceof a))throw e;s.write(`${e.message}
|
|
22
|
-
`)}}finally{t.close()}}async function
|
|
22
|
+
`)}}finally{t.close()}}async function ot(t){if(h(),t.length===0)throw new a("\u5F53\u524D\u6CA1\u6709\u53EF\u9009\u7684\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u3002");const e=m.createInterface({input:d,output:s});try{for(;;)try{s.write(`
|
|
23
|
+
[\u4E91\u7AEF\u6570\u636E]
|
|
24
|
+
`),t.forEach((i,o)=>{s.write(` ${o+1}. ${P(i)}
|
|
25
|
+
`)});const n=(await e.question("\u8F93\u5165\u7F16\u53F7\uFF0C\u56DE\u8F66\u53D6\u6D88: ")).trim();if(!n)throw new a("\u5DF2\u53D6\u6D88\u4E91\u7AEF\u6570\u636E\u9009\u62E9\u3002");const r=Number(n);if(!Number.isInteger(r)||r<1||r>t.length)throw new a(`\u65E0\u6548\u9009\u9879: ${n}`);return structuredClone(t[r-1])}catch(n){if(!(n instanceof a))throw n;s.write(`${n.message}
|
|
26
|
+
`)}}finally{e.close()}}async function st(t){if(h(),!t.hasFile&&t.downloads.length===0)return{downloadFile:!1,downloads:[]};const e=H(t),n=m.createInterface({input:d,output:s});try{for(;;)try{s.write(`
|
|
23
27
|
[\u7ED3\u679C\u5904\u7406]
|
|
24
|
-
`),e.forEach((u,
|
|
28
|
+
`),e.forEach((u,l)=>{s.write(` ${l+1}. ${u.label}
|
|
25
29
|
`)});const r=(await n.question("\u8F93\u5165\u7F16\u53F7\uFF0C\u56DE\u8F66\u8DF3\u8FC7: ")).trim();if(!r)return{downloadFile:!1,downloads:[]};const i=Number(r);if(!Number.isInteger(i)||i<1||i>e.length)throw new a(`\u65E0\u6548\u9009\u9879: ${r}`);const o=e[i-1];return o.type==="skip"?{downloadFile:!1,downloads:[]}:o.type==="file"?{downloadFile:!0,downloads:[]}:o.type==="all"?{downloadFile:!0,downloads:t.downloads}:{downloadFile:!1,downloads:t.downloads.length<=1?t.downloads:await v(n,t.downloads)}}catch(r){if(!(r instanceof a))throw r;s.write(`${r.message}
|
|
26
30
|
`)}}finally{n.close()}}function h(){if(!d.isTTY||!s.isTTY)throw new a("`--interactive` \u4EC5\u652F\u6301\u5728\u7EC8\u7AEF\u4E2D\u4F7F\u7528\u3002")}async function v(t,e){for(s.write(`
|
|
27
31
|
[\u4E0B\u8F7D\u7ED3\u679C]
|
|
28
32
|
`),e.forEach((n,r)=>{s.write(` ${r+1}. ${n.label} (${n.device})
|
|
29
33
|
`)});;)try{const n=(await t.question("\u8F93\u5165\u7F16\u53F7\u4E0B\u8F7D\uFF0C\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF0C\u56DE\u8F66\u8DF3\u8FC7: ")).trim();return n?J(n,e.length).map(i=>e[i]):[]}catch(n){if(!(n instanceof a))throw n;s.write(`${n.message}
|
|
30
|
-
`)}}async function
|
|
31
|
-
`),
|
|
32
|
-
`)}}function F(t,e){const n=t.trim(),r=Number(n);if(Number.isInteger(r)&&r>=1&&r<=e.length)return structuredClone(e[r-1]);const i=e.find(o=>String(o)===n);if(i===void 0)throw new a(`\u65E0\u6548\u9009\u9879: ${t}`);return structuredClone(i)}function O(t,e){const n=t.split(/[,,]/).map(r=>r.trim()).filter(Boolean);if(n.length===0)throw new a("\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u9009\u9879\u3002");return n.map(r=>{const i=Number(r);if(Number.isInteger(i)&&i>=1&&i<=e.length)return structuredClone(e[i-1]);const o=e.find(u=>String(u)===r);if(o===void 0)throw new a(`\u65E0\u6548\u9009\u9879: ${r}`);return structuredClone(o)})}function J(t,e){const n=t.split(/[,,]/).map(i=>i.trim()).filter(Boolean);if(n.length===0)throw new a("\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u9009\u9879\u3002");const r=n.map(i=>{const o=Number(i);if(!Number.isInteger(o)||o<1||o>e)throw new a(`\u65E0\u6548\u9009\u9879: ${i}`);return o-1});return[...new Set(r)]}function q(t,e){if(typeof e=="boolean")return I(t);if(typeof e=="number"){const n=Number(t);if(Number.isNaN(n))throw new a(`\u65E0\u6548\u6570\u5B57: ${t}`);return n}if(Array.isArray(e))return M(t);if(y(e))try{const n=JSON.parse(t);if(!y(n))throw new a(`\u8BF7\u8F93\u5165 JSON \u5BF9\u8C61: ${t}`);return n}catch{throw new a(`\u8BF7\u8F93\u5165\u5408\u6CD5 JSON \u5BF9\u8C61: ${t}`)}return t}function M(t){if(t.startsWith("["))try{const e=JSON.parse(t);if(!Array.isArray(e))throw new a(`\u8BF7\u8F93\u5165 JSON \u6570\u7EC4: ${t}`);return e}catch{throw new a(`\u8BF7\u8F93\u5165\u5408\u6CD5 JSON \u6570\u7EC4: ${t}`)}return t.split(",").map(e=>e.trim()).filter(Boolean)}function I(t){const e=t.trim().toLowerCase();if(["y","yes","true","1","on","\u5F00"].includes(e))return!0;if(["n","no","false","0","off","\u5173"].includes(e))return!1;throw new a(`\u65E0\u6548\u5F00\u5173\u503C: ${t}`)}function
|
|
33
|
-
`)})}function b(t){if(t==="<")return{type:"back"};if(t==="/skip")return{type:"skip"}}function
|
|
34
|
+
`)}}async function k(t,e,n){for(;;)try{const r=e.label?.trim()||e.key,i="\u8F93\u5165 < \u8FD4\u56DE\u4E0A\u4E00\u9879\uFF0C/skip \u8DF3\u8FC7\u672C\u7EC4";if(e.options?.length){s.write(`${r}
|
|
35
|
+
`),L(e.options,n);const c=e.multiple?`\u8F93\u5165\u7F16\u53F7\u6216\u9009\u9879\u503C\uFF0C\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF0C${i}`:`\u8F93\u5165\u7F16\u53F7\u6216\u9009\u9879\u503C\uFF0C${i}`,f=(await t.question(`${c} [${g(n)}]: `)).trim();if(!f)return{type:"value",value:n};const p=b(f);return p||{type:"value",value:e.multiple?O(f,e.options):F(f,e.options)}}if(e.type==="XTSwitch"){const c=(await t.question(`${r} (\u5F00/\u5173\uFF0C${i}) [${E(n)}]: `)).trim();if(!c)return{type:"value",value:n};const f=b(c);return f||{type:"value",value:I(c)}}if(e.type==="XTColor"){X(n);const c=(await t.question(`${r} (\u989C\u8272\u7528\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF0C${i}) [${B(n)}]: `)).trim();if(!c)return{type:"value",value:n};const f=b(c);return f||{type:"value",value:T(c,n)}}const o=e.placeholder?.trim()||e.tips?.trim()||z(n),u=o?`${r} (${o}\uFF0C${i}) [${g(n)}]: `:`${r} (${i}) [${g(n)}]: `,l=(await t.question(u)).trim();if(!l)return{type:"value",value:n};const w=b(l);return w||{type:"value",value:q(l,n)}}catch(r){if(!(r instanceof a))throw r;s.write(`${r.message}
|
|
36
|
+
`)}}function F(t,e){const n=t.trim(),r=Number(n);if(Number.isInteger(r)&&r>=1&&r<=e.length)return structuredClone(e[r-1]);const i=e.find(o=>String(o)===n);if(i===void 0)throw new a(`\u65E0\u6548\u9009\u9879: ${t}`);return structuredClone(i)}function O(t,e){const n=t.split(/[,,]/).map(r=>r.trim()).filter(Boolean);if(n.length===0)throw new a("\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u9009\u9879\u3002");return n.map(r=>{const i=Number(r);if(Number.isInteger(i)&&i>=1&&i<=e.length)return structuredClone(e[i-1]);const o=e.find(u=>String(u)===r);if(o===void 0)throw new a(`\u65E0\u6548\u9009\u9879: ${r}`);return structuredClone(o)})}function J(t,e){const n=t.split(/[,,]/).map(i=>i.trim()).filter(Boolean);if(n.length===0)throw new a("\u81F3\u5C11\u9009\u62E9\u4E00\u4E2A\u9009\u9879\u3002");const r=n.map(i=>{const o=Number(i);if(!Number.isInteger(o)||o<1||o>e)throw new a(`\u65E0\u6548\u9009\u9879: ${i}`);return o-1});return[...new Set(r)]}function q(t,e){if(typeof e=="boolean")return I(t);if(typeof e=="number"){const n=Number(t);if(Number.isNaN(n))throw new a(`\u65E0\u6548\u6570\u5B57: ${t}`);return n}if(Array.isArray(e))return M(t);if(y(e))try{const n=JSON.parse(t);if(!y(n))throw new a(`\u8BF7\u8F93\u5165 JSON \u5BF9\u8C61: ${t}`);return n}catch{throw new a(`\u8BF7\u8F93\u5165\u5408\u6CD5 JSON \u5BF9\u8C61: ${t}`)}return t}function P(t){const e=typeof t.data_id=="string"?t.data_id.trim():"",n=typeof t.label=="string"?t.label.trim():"";return n&&e?`${n} (${e})`:n||e||"\u672A\u547D\u540D\u8BB0\u5F55"}function M(t){if(t.startsWith("["))try{const e=JSON.parse(t);if(!Array.isArray(e))throw new a(`\u8BF7\u8F93\u5165 JSON \u6570\u7EC4: ${t}`);return e}catch{throw new a(`\u8BF7\u8F93\u5165\u5408\u6CD5 JSON \u6570\u7EC4: ${t}`)}return t.split(",").map(e=>e.trim()).filter(Boolean)}function I(t){const e=t.trim().toLowerCase();if(["y","yes","true","1","on","\u5F00"].includes(e))return!0;if(["n","no","false","0","off","\u5173"].includes(e))return!1;throw new a(`\u65E0\u6548\u5F00\u5173\u503C: ${t}`)}function T(t,e){if(t.startsWith("["))try{const r=JSON.parse(t);if(!Array.isArray(r)||!r.every(i=>typeof i=="string"))throw new a(`\u8BF7\u8F93\u5165\u5B57\u7B26\u4E32\u6570\u7EC4: ${t}`);return Array.isArray(e)?r.map($):$(r[0]??"")}catch{throw new a(`\u8BF7\u8F93\u5165\u5408\u6CD5\u989C\u8272\u6570\u7EC4: ${t}`)}const n=t.split(/[\s,,]+/).map(r=>r.trim()).filter(Boolean);if(n.length===0)throw new a("\u8BF7\u81F3\u5C11\u8F93\u5165\u4E00\u4E2A\u989C\u8272\u503C\u3002");return Array.isArray(e)?n.map($):$(n[0])}function z(t){return typeof t=="boolean"?"\u5F00/\u5173":Array.isArray(t)?"\u8F93\u5165 JSON \u6570\u7EC4\u6216\u9017\u53F7\u5206\u9694\u503C":y(t)?"\u8F93\u5165 JSON \u5BF9\u8C61":""}function g(t){return typeof t=="string"?t:JSON.stringify(t)}function E(t){return t===!0?"\u5F00":"\u5173"}function B(t){return Array.isArray(t)?t.join(", "):g(t)}function L(t,e){const n=Array.isArray(e)?e.map(String):[String(e)];t.forEach((r,i)=>{const o=String(r),u=n.includes(o)?"*":" ";s.write(` ${u} ${i+1}. ${o}
|
|
37
|
+
`)})}function b(t){if(t==="<")return{type:"back"};if(t==="/skip")return{type:"skip"}}function R(t,e,n){if(n>0)return{fieldIndex:n-1,sectionIndex:e};for(let r=e-1;r>=0;r-=1){const i=t[r].form??[];if(i.length>0)return{fieldIndex:i.length-1,sectionIndex:r}}}function $(t){const e=t.trim();return/^[0-9a-fA-F]{3}$/.test(e)||/^[0-9a-fA-F]{6}$/.test(e)?`#${e}`:e}function _(t){return!!(t.title?.trim()||t.code?.trim())}function A(t){return t.title?.trim()||t.code?.trim()||"\u672A\u547D\u540D"}function D(t){const e=t.code?.trim(),n=t.route?.trim(),r=t.title?.trim(),i=t.uuid?.trim();if(!e||!n||!r||!i)throw new a("\u9009\u4E2D\u7684\u5DE5\u5177\u7F3A\u5C11\u5FC5\u8981\u4FE1\u606F\uFF0C\u8BF7\u6539\u7528\u663E\u5F0F module_id/uuid\u3002");return{code:e,path:t.path?.trim()??"",route:n,title:r,uuid:i}}function H(t){const e=[];return t.hasFile&&e.push({label:"\u4E0B\u8F7D\u751F\u56FE",type:"file"}),t.downloads.length>0&&e.push({label:t.downloads.length===1?"\u4E0B\u8F7D\u5206\u6790\u7ED3\u679C":"\u9009\u62E9\u5206\u6790\u7ED3\u679C\u4E0B\u8F7D",type:"analysis"}),t.hasFile&&t.downloads.length>0&&e.push({label:"\u4E0B\u8F7D\u751F\u56FE\u548C\u5168\u90E8\u5206\u6790\u7ED3\u679C",type:"all"}),e.push({label:"\u8DF3\u8FC7",type:"skip"}),e}function X(t){const n=(Array.isArray(t)?t:[t]).filter(r=>typeof r=="string");n.length!==0&&(s.write(`\u5F53\u524D\u989C\u8272:
|
|
34
38
|
`),n.forEach(r=>{const i=$(r);s.write(` ${j(i)} ${i}
|
|
35
|
-
`)}))}function j(t){const e=W(t);return e?`\x1B[48;2;${e.r};${e.g};${e.b}m \x1B[0m`:"[?]"}function W(t){const e=t.trim(),n=e.match(/^#([0-9a-fA-F]{3})$/);if(n){const[i,o,u]=n[1].split("").map(
|
|
39
|
+
`)}))}function j(t){const e=W(t);return e?`\x1B[48;2;${e.r};${e.g};${e.b}m \x1B[0m`:"[?]"}function W(t){const e=t.trim(),n=e.match(/^#([0-9a-fA-F]{3})$/);if(n){const[i,o,u]=n[1].split("").map(l=>Number.parseInt(l+l,16));return{r:i,g:o,b:u}}const r=e.match(/^#([0-9a-fA-F]{6})$/);if(r)return{r:Number.parseInt(r[1].slice(0,2),16),g:Number.parseInt(r[1].slice(2,4),16),b:Number.parseInt(r[1].slice(4,6),16)}}export{tt as confirmPlotArgsMain,V as promptPlotArgsMain,ot as promptPlotCloudRecordSelection,et as promptPlotDownloads,rt as promptPlotFilePath,it as promptPlotInputSource,nt as promptPlotMenuSelection,st as promptPlotResultSelection};
|
package/dist/lib/plot-options.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Flags as
|
|
1
|
+
import{Flags as a}from"@oclif/core";import{XtzError as c}from"./errors.js";import{isJsonObject as f}from"./json.js";const O={config:a.string({description:"Path to a JSON file with raw argsMain overrides"}),specific:a.string({description:"Override argsSpecific value by key, e.g. --specific genes=TP53",multiple:!0}),set:a.string({description:"Override argsMain value by dotted path, e.g. --set title.title=My Title",multiple:!0})};function m(e){const i={};for(const r of e??[]){const t=r.indexOf("=");if(t<=0||t===r.length-1)throw new c(`--set \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${r}`);const s=r.slice(0,t).trim(),o=r.slice(t+1).trim(),n=s.split(".").filter(Boolean);if(n.length===0)throw new c(`--set \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${r}`);const l=n.at(-1)==="value"?n:[...n,"value"];d(i,l,u(o,"--set"))}return i}function w(e){const i={};for(const r of e??[]){const t=r.indexOf("=");if(t<=0||t===r.length-1)throw new c(`--specific \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${r}`);const s=r.slice(0,t).trim(),o=r.slice(t+1).trim();if(!s)throw new c(`--specific \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${r}`);i[s]=u(o,"--specific")}return i}function y(e){const i=[];for(const[r,t]of Object.entries(e))if(f(t))for(const[s,o]of Object.entries(t)){if(!f(o)||!("value"in o))continue;const n=o.value,l=`${r}.${s}=${JSON.stringify(n)}`;i.push(`--set ${p(l)}`)}return i}function d(e,i,r){let t=e;for(const s of i.slice(0,-1)){const o=t[s];f(o)||(t[s]={}),t=t[s]}t[i.at(-1)]=r}function u(e,i){if(e==="true")return!0;if(e==="false")return!1;if(e==="null")return null;if(/^-?\d+(\.\d+)?$/.test(e))return Number(e);if(e.startsWith("{")||e.startsWith("[")||e.startsWith('"'))try{return JSON.parse(e)}catch{throw new c(`${i} \u53C2\u6570\u503C\u4E0D\u662F\u5408\u6CD5 JSON: ${e}`)}return e}function p(e){return`'${e.replaceAll("'","'\\''")}'`}export{y as formatSetOverrides,m as parseSetOverrides,w as parseSpecificOverrides,O as plotOverrideFlags};
|
package/dist/lib/plot-schema.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function r(n){const o={};for(const e of n??[]){const i={};for(const t of e.form??[]){const c={value:t.default_value??""};t.options&&(c.options=t.options),i[t.key]=c}o[e.key]=i}return o}function f(n){const o={};for(const e of n??[])o[e.key]=structuredClone(e.default_value??"");return o}export{r as buildArgsMainFromSchema,f as buildArgsSpecificFromSchema};
|
package/dist/lib/tool-inputs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isJsonObject as
|
|
1
|
+
import{isJsonObject as i}from"./json.js";function a(n){return n.flatMap(e=>{if(!i(e)||e.type!=="XTUpload")return[];const r=typeof e.key=="string"?e.key.trim():"";if(!r)return[];const t=i(e.default_value)?e.default_value:void 0,o=typeof t?.file_name=="string"?t.file_name.trim():"",l=typeof t?.file_oss=="string"?t.file_oss.trim():"",f=typeof t?.file_size=="number"?t.file_size:void 0;return[{defaultUpload:o&&l&&typeof f=="number"?{fileName:o,fileOss:l,fileSize:f}:null,key:r,label:typeof e.label=="string"?e.label.trim():"",required:e.required===!0}]})}function s(n){for(const e of n){if(!i(e)||e.type!=="XTRecord")continue;const r=typeof e.key=="string"?e.key.trim():"",t=i(e.default_value)?e.default_value:void 0,o=typeof t?.record_id=="string"?t.record_id.trim():"";if(!(!r||!o))return{key:r,label:typeof e.label=="string"?e.label.trim():"",moduleId:typeof t?.module_id=="string"?t.module_id.trim():"",moduleName:typeof t?.module_name=="string"?t.module_name.trim():"",recordId:o,recordName:typeof t?.record_name=="string"?t.record_name.trim():"",time:typeof t?.time=="string"?t.time.trim():""}}return null}function c(n){for(const e of n){if(!i(e))continue;const r=typeof e.key=="string"?e.key.trim():"";if(!r)continue;const t=d(e);if(t)return{key:r,label:typeof e.label=="string"?e.label.trim():"",record:t}}return null}function d(n,e=0){if(!i(n)||e>3)return null;if(typeof n.data_id=="string"?n.data_id.trim():"")return structuredClone(n);for(const t of Object.values(n)){if(!i(t))continue;const o=d(t,e+1);if(o)return o}return null}export{c as findDefaultXiantaoCloudInput,s as findDefaultXiantaoRecord,a as listXiantaoUploadFields};
|
package/dist/lib/xiantao-auth.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import m from"node:http";import{AUTH_BIND_ENDPOINT as p,PASSPORT_JUMP_ENDPOINT as w}from"./constants.js";import{openUrl as d}from"./open-url.js";import{XtzError as c}from"./errors.js";import{requestJson as E}from"./http.js";import{getXiantaoTokenPath as F,loadXiantaoToken as f,requireXiantaoToken as D,saveXiantaoToken as k}from"./storage.js";async function y(t,e){const a=e?.trim()||process.env.XIANTAO_TOKEN?.trim()||await D(t);return{agent:t,token:a}}async function h(t){const e=await f(t);return e?{agent:t,token:e}:void 0}async function C(t){const e=await g(),a=e.callbackUrl.toString(),u=new URL(w);u.searchParams.set("cb_url",a);const
|
|
1
|
+
import m from"node:http";import{AUTH_BIND_ENDPOINT as p,PASSPORT_JUMP_ENDPOINT as w}from"./constants.js";import{openUrl as d}from"./open-url.js";import{XtzError as c}from"./errors.js";import{requestJson as E}from"./http.js";import{getXiantaoTokenPath as F,loadXiantaoToken as f,requireXiantaoToken as D,saveXiantaoToken as k}from"./storage.js";async function y(t,e){const a=e?.trim()||process.env.XIANTAO_TOKEN?.trim()||await D(t);return{agent:t,token:a}}async function h(t){const e=await f(t);return e?{agent:t,token:e}:void 0}async function C(t){const e=await g(),a=e.callbackUrl.toString(),u=new URL(w);u.searchParams.set("cb_url",a);const o=await d(u.toString()),i=await e.waitForToken(),l=await k(t,i);return{browserOpened:o,callbackUrl:a,jumpUrl:u.toString(),reused:!1,token:i,tokenPath:l}}async function T(t,e){const a=await h(t);if(a){try{await E(p,{body:JSON.stringify({auth_key:e}),headers:{Authorization:`Bearer ${a.token}`,"Content-Type":"application/json",origin:"https://www.helixlife.net",platform:"pc",referer:"https://www.helixlife.net/",source:"PC"},method:"POST"},{agent:t,tokenKind:"xiantao"})}catch(u){if(u instanceof c&&u.message.includes("\u4ED9\u6843\u7F51\u9875\u6388\u6743\u5DF2\u8FC7\u671F\u6216\u65E0\u6548"))return;throw u}return{browserOpened:!1,reused:!0,token:a.token,tokenPath:F(t)}}}async function g(){let t,e;const a=new Promise((r,n)=>{t=r,e=n}),u=m.createServer((r,n)=>{const s=new URL(r.url??"/","http://127.0.0.1").searchParams.get("t")?.trim();if(n.statusCode=s?200:400,n.setHeader("Content-Type","text/html; charset=utf-8"),n.end(s?B:P),u.close(),s){t(s);return}e(new c("\u672A\u4ECE\u6D4F\u89C8\u5668\u56DE\u8C03\u4E2D\u83B7\u53D6\u5230\u4ED9\u6843\u7F51\u9875 token"))});await new Promise((r,n)=>{u.listen(0,"127.0.0.1",()=>r()),u.once("error",n)});const o=u.address();if(!o||typeof o=="string")throw u.close(),new c("\u65E0\u6CD5\u542F\u52A8\u672C\u5730\u767B\u5F55\u56DE\u8C03\u670D\u52A1");const i=new URL(`http://127.0.0.1:${o.port}/callback`),l=setTimeout(()=>{u.close(),e(new c("\u7B49\u5F85\u4ED9\u6843\u7F51\u9875\u767B\u5F55\u56DE\u8C03\u8D85\u65F6"))},300*1e3);return{callbackUrl:i,waitForToken:async()=>{try{return await a}finally{clearTimeout(l)}}}}const B=`<!doctype html>
|
|
2
2
|
<html lang="zh-CN">
|
|
3
3
|
<head><meta charset="utf-8"><title>\u767B\u5F55\u6210\u529F</title></head>
|
|
4
4
|
<body><p>\u4ED9\u6843\u7F51\u9875\u767B\u5F55\u6210\u529F\uFF0C\u73B0\u5728\u53EF\u4EE5\u5173\u95ED\u6B64\u9875\u9762\u5E76\u56DE\u5230\u7EC8\u7AEF\u3002</p></body>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{XIANTAO_BIO_API_ENDPOINT as e}from"./constants.js";import{requestJson as o}from"./http.js";import{buildXiantaoHeaders as d}from"./xiantao.js";async function u(r,t){const a=await o(e,{body:JSON.stringify({version:"v3",name:"public.clouds.fetch-data",args:{id:{module_id:t.moduleId,uuid:t.uuid},current_page:t.currentPage,filter:t.filter??"",args_key:t.argsKey,args_data:s(t.argsKey,t.selectedRecord)}}),headers:d(r,!0),method:"POST"},{agent:r.agent});return{columnAttrs:a.data.column_attrs??[],currentPage:a.data.current_page??t.currentPage,filter:{options:a.data.filter?.options??[],value:a.data.filter?.value??[]},from:a.data.from??0,info:a.data.info?.trim()??"",lastPage:a.data.last_page??a.data.current_page??t.currentPage,perPage:a.data.per_page??0,records:a.data.data_records??[],to:a.data.to??0,total:a.data.total??0}}function s(r,t){const a={};return t&&(a[r]=t),{duid:"cloud",info:a}}export{u as fetchXiantaoCloudData};
|
package/dist/lib/xiantao-plot.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{XIANTAO_BIO_API_ENDPOINT as s}from"./constants.js";import{XtzError as t}from"./errors.js";import{requestJson as l}from"./http.js";import{buildXiantaoHeaders as m}from"./xiantao.js";async function I(
|
|
1
|
+
import{XIANTAO_BIO_API_ENDPOINT as s}from"./constants.js";import{XtzError as t}from"./errors.js";import{requestJson as l}from"./http.js";import{buildXiantaoHeaders as m}from"./xiantao.js";async function I(r,e){const o=await l(s,{body:JSON.stringify({version:"v3",name:"public.verify.upload",args:{id:{module_id:e.moduleId,uuid:e.uuid},args_data:{duid:"",info:c(e.uploads)},args_main:e.argsMain}}),headers:m(r,!0),method:"POST"},{agent:r.agent}),i=o.data.id?.duid;if(!i)throw new t(o.message??"\u672A\u83B7\u53D6\u5230 duid");return{duid:i,schema:o.data.args_main??[]}}async function h(r,e){const o=await l(s,{body:JSON.stringify({version:"v3",name:"common.module",extra_args:{name:e.route},args:{action:"submit",id:{module_id:e.moduleId,uuid:e.uuid},args_data:w(e.duid,e.input),args_main:e.argsMain,args_specific:e.argsSpecific}}),headers:m(r,!0),method:"POST"},{agent:r.agent,allowErrorPayload:u=>f(u.message)}),i=g(o.data.data),d=typeof o.data.file=="string"&&o.data.file.trim()?o.data.file.trim():void 0,n=o.data.body??"",a=o.message??"";if(!d&&!n&&i.length===0){if(f(a))return{asyncSubmission:!0,body:n,downloads:i,file:d,message:a};throw new t(a||"\u672A\u83B7\u53D6\u5230\u53EF\u7528\u7ED3\u679C")}return{asyncSubmission:!1,body:n,downloads:i,file:d,message:a}}async function N(r,e){const o=await l(s,{body:JSON.stringify({version:"v3",name:e.item.endpoint,args:{tag:"download",name:e.item.endpoint,fuid:e.item.fuid,sign:e.item.sign,device:e.item.device,index:e.item.index,info:e.item.info,pos:e.item.pos,id:{uuid:e.uuid,module_id:e.moduleId}}}),headers:m(r,!0),method:"POST"},{agent:r.agent}),i=o.data.url?.trim();if(!i)throw new t(o.message??"\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5");return{fileName:o.data.file_name?.trim()||void 0,url:i}}function g(r){const e=[...r?.buttons??[]];for(const o of r?.tabs??[])for(const i of o.sections??[])e.push(...i.button??[]);return e.flatMap(o=>o.tag!=="download"||!o.device||!o.endpoint||!o.fuid||!o.label?[]:[{device:o.device,endpoint:o.endpoint,fuid:o.fuid,index:o.index,info:o.info,label:o.label,pos:o.pos,sign:o.sign}])}function y(r){return r.fileOssPath??r.fileOss}function _(r){return r.fileSizeForXiantao??r.fileSize}function w(r,e){return e.kind==="cloud"?{duid:r,info:{[e.cloud.key]:b(e.cloud.record)}}:e.kind==="record"?{duid:r,info:{[e.record.key]:{label:e.record.label,module_id:e.record.moduleId,module_name:e.record.moduleName,record_id:e.record.recordId,record_name:e.record.recordName,time:e.record.time,type:"record"}}}:{duid:r,info:c(e.uploads)}}function b(r){const e=structuredClone(r);return(typeof e.type!="string"||!e.type.trim())&&(e.type="cloud"),e}function c(r){return Object.fromEntries(r.map(e=>[e.key,{file_oss:y(e.upload),file_name:e.upload.fileName,file_size:_(e.upload),type:"upload"}]))}function f(r){return!!r?.includes("\u4EFB\u52A1\u63D0\u4EA4\u6210\u529F")}export{w as buildSubmitArgsData,N as resolveXiantaoDownload,h as submitXiantaoPlot,I as verifyXiantaoPlotUpload};
|
package/dist/lib/xiantao.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{XIANTAO_BASE_URL as h,XIANTAO_BIO_API_ENDPOINT as
|
|
1
|
+
import{XIANTAO_BASE_URL as h,XIANTAO_BIO_API_ENDPOINT as p,XIANTAO_TOOL_MENUS_ENDPOINT as m}from"./constants.js";import{XtzError as u}from"./errors.js";import{requestJson as a}from"./http.js";async function y(e,t,o){const r=new URL(`${m}/${t}`);r.searchParams.set("f",C({tool_product_uuid:o}));try{return(await a(r.toString(),{headers:c(e),method:"GET"},{agent:e.agent})).data}catch(n){if(!(n instanceof u)||!n.message.includes("\u5DF2\u4E0B\u67B6"))throw n;const s=M(await g(e,o),t);if(s)return s;throw n}}async function g(e,t){const o=new URL(m);return o.searchParams.set("f",C({is_all:1,tool_product_uuid:t})),(await a(o.toString(),{headers:c(e),method:"GET"},{agent:e.agent})).data}async function N(e,t,o){const r=o.trim(),n=l(await g(e,t),r);if(n.length===0)throw new u(`\u672A\u627E\u5230\u6A21\u5757 ${r}\uFF0C\u8BF7\u786E\u8BA4 module_id \u6216 tool_product_uuid \u662F\u5426\u6B63\u786E\u3002`);if(n.length>1)throw new u(`\u6A21\u5757 ${r} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--uuid\` \u663E\u5F0F\u6307\u5B9A\u3002`);return n[0]}function T(e){return l(e)}function I(e){return T(e).map(t=>({module_id:t.code,path:t.path,route:t.route,title:t.title}))}function L(e,t){const o=t.trim().toLowerCase();return T(e).filter(r=>[r.code,r.title,r.path,r.route].some(s=>s.toLowerCase().includes(o))).sort((r,n)=>w(n,o)-w(r,o))}async function P(e,t){return(await a(p,{body:JSON.stringify({args:{id:{module_id:t.moduleId,uuid:t.uuid}},name:"public.args.fetch-all",version:"v3"}),headers:c(e,!0),method:"POST"},{agent:e.agent})).data}async function b(e,t){return(await a(p,{body:JSON.stringify({args:{args_data:t.argsData,args_key:t.argsKey,args_main:t.argsMain,args_specific:t.argsSpecific,id:{module_id:t.moduleId,uuid:t.uuid}},name:"public.args.update-args",version:"v3"}),headers:c(e,!0),method:"POST"},{agent:e.agent})).data}function _(e){return(e.children??[]).filter(t=>!!(t.title?.trim()||t.code?.trim()))}function O(e){return!!(e.code?.trim()&&e.route?.trim()&&e.title?.trim()&&e.uuid?.trim())}function l(e,t){const o=[];for(const r of e){const n=r.code?.trim();if((!t||n===t)&&O(r)){const i=r.route?.trim(),d=r.title?.trim(),f=r.uuid?.trim();n&&i&&d&&f&&o.push({code:n,path:r.path?.trim()??"",route:i,title:d,uuid:f})}const s=_(r);s.length>0&&o.push(...l(s,t))}return o}function M(e,t){const o=t.trim();for(const r of e){if(r.uuid?.trim()===o||String(r.id??"").trim()===o)return r;const n=_(r);if(n.length>0){const s=M(n,o);if(s)return s}}}function w(e,t){let o=0;const r=e.code.toLowerCase(),n=e.title.toLowerCase(),s=e.path.toLowerCase(),i=e.route.toLowerCase();return r===t?o+=500:r.startsWith(t)?o+=300:r.includes(t)&&(o+=150),n===t?o+=400:n.startsWith(t)?o+=250:n.includes(t)&&(o+=120),s.includes(t)&&(o+=80),i.includes(t)&&(o+=40),o}function C(e){return encodeURIComponent(JSON.stringify(e))}function c(e,t=!1){const o={Authorization:`Bearer ${e.token}`,origin:h,platform:"pc",referer:h,source:"PC"};return t&&(o["Content-Type"]="application/json"),o}export{c as buildXiantaoHeaders,P as fetchAllPlotArgs,y as fetchToolMenu,g as fetchToolMenus,_ as getBrowsableToolMenuChildren,O as isRunnableToolMenu,T as listResolvedToolMenus,I as listToolMenuSummaries,N as resolveToolMenuByCode,L as searchResolvedToolMenus,b as updatePlotArgs};
|