@helixlife-ai/xiantao 0.1.24 → 0.1.26

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 CHANGED
@@ -45,32 +45,63 @@ xt tool exec gsea_customize --file gene_set=./gene_set.gmt --file data=./rank.xl
45
45
 
46
46
  xt tool cloud km_plot_gene --profile opencode --json --filter '胆管癌'
47
47
  xt tool exec km_plot_gene --profile opencode --json --cloudFilter '胆管癌'
48
- xt tool exec km_plot_gene --profile opencode --json --cloudFilter '胆管癌' --cloudIndex 1
48
+ xt tool prepare km_plot_gene --profile opencode --json --cloudDataId tcga-chol-2
49
+ xt tool exec km_plot_gene --profile opencode --json --cloudFilter '胆管癌' --cloudIndex 0
49
50
  xt tool exec km_plot_gene --profile opencode --json --cloudDataId tcga-chol-2
50
51
  ```
51
52
 
52
53
  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.
53
54
  The examples below illustrate command shapes, not a fixed allowlist of tools. Apply the same patterns to any tool with the same input mode.
54
55
 
55
- `xt tool prepare` and `xt tool exec` support three input patterns:
56
+ `xt tool prepare` and `xt tool exec` support the following input patterns:
56
57
  - upload modules: pass `--file <xlsx>`
57
58
  - multi-upload modules: repeat `--file key=path`, for example `--file gene_set=./gene_set.gmt --file data=./rank.xlsx`
58
59
  - demo-capable upload modules: pass `--demo`
59
60
  - 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
61
+ - cloud-capable modules: use `xt tool cloud` to inspect candidates, then pass `--cloudFilter <keyword>`, `--cloudIndex <n>`, or `--cloudDataId <id>` to `tool prepare` / `tool exec`
62
+
63
+ `args_specific` defaults come from the dynamic schema returned by Xiantao. Use repeated `--specific` flags to override a whole key or a nested dotted path; array paths use numeric indexes.
64
+
65
+ ```bash
66
+ xt tool prepare km_plot_gene --profile opencode --json --cloudDataId tcga-brca-2 --specific 'genes=TP53[ENSG00000141510.17]'
67
+ xt tool prepare group_plot_clin --profile opencode --json --cloudDataId tcga-brca-2 --specific 'genes=["TP53[ENSG00000141510.17]"]' --specific 'clin_list_1n.0.variable=(临床)Age'
68
+ xt tool prepare cox_analysis_cloud --profile opencode --json --cloudDataId tcga-brca-2 --specific 'surv_list_nn.0.variable=(临床)Gender' --specific 'surv_list_nn.0.attrs_list.0.attrs=["Female [50]","Male [49]"]'
69
+ ```
70
+
71
+ ### Cloud Data Flow
72
+
73
+ `xt tool cloud` is the read-only helper for `XTCloud` modules. It lists candidate cloud records and only supports `--json`. Actual preparation and submission still happen through `xt tool prepare` and `xt tool exec`.
74
+
75
+ ```bash
76
+ xt tool inspect km_plot_gene --profile opencode --json
77
+ xt tool cloud km_plot_gene --profile opencode --json --filter '胆管癌'
78
+ xt tool prepare km_plot_gene --profile opencode --json --cloudDataId tcga-chol-2
79
+ xt tool exec km_plot_gene --profile opencode --json --cloudDataId tcga-chol-2
80
+ ```
81
+
82
+ Typical cloud flow:
83
+ - run `xt tool inspect <tool_id> --json` first and confirm `inputs.cloud_available=true`
84
+ - run `xt tool cloud <tool_id> --json [--filter <keyword>]` to list candidates; use `data.choices[*].index` or `data_id` from the JSON output
85
+ - if the filter matches one record, `tool prepare` / `tool exec` can use `--cloudFilter <keyword>` directly
86
+ - if multiple records match, retry with `--cloudIndex <n>` or `--cloudDataId <id>`; `--cloudIndex` is 0-based
87
+ - if you already have the full record payload, pass `--cloudRecordJson` or `--cloudRecordFile` to `tool prepare` / `tool exec`
88
+
89
+ Useful cloud flags:
90
+ - `xt tool cloud`: `--filter`, `--page`, `--all`, `--argsKey`, `--recordJson`, `--recordFile`
91
+ - `xt tool prepare` / `xt tool exec`: `--cloudFilter`, `--cloudIndex`, `--cloudDataId`, `--cloudKey`, `--cloudRecordJson`, `--cloudRecordFile`
61
92
 
62
93
  Current operational notes for agent-style callers:
63
94
  - serialize `xt tool exec` submits per profile; Xiantao may reject overlapping or too-frequent submits with `NETWORK_ERROR`
64
95
  - `tool inspect` now includes the full `args_data` payload in JSON output and summarizes every detected `XTUpload` field
65
96
  - `tool inspect` also reports `inputs.cloud_available` and `inputs.cloud_default` for `XTCloud` modules
66
97
  - 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`
98
+ - `tool cloud` only supports `--json` and returns structured cloud candidates via `data.choices`
68
99
  - 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`
69
100
  - `gsea_customize` has been validated through `tool prepare` and `tool exec` with repeated `--file gene_set=... --file data=...`
70
101
 
71
102
  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.
72
103
 
73
- `xt login --json` now returns the authorization link immediately and defaults to `authorized: false` until the browser step completes. Use `xt login --json --wait` when you explicitly want the command to block until authorization is confirmed. `xt status` is a probe-style check and returns `authorized: true` or `authorized: false` together with a reason such as `missing_token` or `expired_token`.
104
+ `xt login` opens the configured login URL in a Playwright-controlled browser, waits for the login `token` cookie, and stores that token for later API requests. `xt login --json` returns the login URL immediately and defaults to `authorized: false`; use `xt login --json --wait` when you explicitly want the command to block until the token is captured. `xt status` is a probe-style check and returns `authorized: true` or `authorized: false` together with a reason such as `missing_token` or `expired_token`.
74
105
 
75
106
  ## Command Groups
76
107
 
@@ -84,7 +115,9 @@ For agent workflows, do not use `xt tool run`. Treat `xt tool run` as the human-
84
115
  ### History
85
116
 
86
117
  - `xt history list`
118
+ - `xt history view`
87
119
  - `xt history download`
120
+ - `xt history save`
88
121
  - `xt history rename`
89
122
  - `xt history delete`
90
123
 
@@ -108,17 +141,21 @@ For agent workflows, do not use `xt tool run`. Treat `xt tool run` as the human-
108
141
 
109
142
  ## Notes
110
143
 
111
- For the common Xiantao tool product, `tool search`, `tool inspect`, `tool run`, `tool resolve`, and `tool menu` default `toolProductUuid` to `c0b6febb-52dd-4525-970a-61bbe9e263ff`. You can override it with `--toolProductUuid`, `XIANTAO_TOOL_PRODUCT_UUID`, or `~/.config/xtz/config.json` under `xiantao.toolProductUuid`.
144
+ For Xiantao tool commands that accept `--toolProductUuid`, the default value is `c0b6febb-52dd-4525-970a-61bbe9e263ff`. You can override it with `--toolProductUuid`, `XIANTAO_TOOL_PRODUCT_UUID`, or `~/.config/xtz/config.json` under `xiantao.toolProductUuid`.
145
+
146
+ The CLI also loads a project-root `.env` file on startup. You can set `XIANTAO_BASE_URL=https://agent.helixlife.cn` there to switch the API base URL without prefixing each command manually, and `XIANTAO_LOGIN_URL=https://www.helixlife.net/` to override the login page. The same values can be stored with `xt config set base-url ...` and `xt config set login-url ...`.
147
+
148
+ `xt tool search <keyword>` searches remote tool menus by tool id, title, path, and route. `xt tool inspect <tool_id>` prints resolved metadata together with the dynamic `args_main` schema, the full `args_data` payload in JSON mode, and the detected input source summary, including `XTCloud`, per-field `XTUpload`, and `XTRecord` defaults. `xt tool run <tool_id>` runs a Xiantao bioinformatics tool in the human-first path. `xt tool exec <tool_id>` is the agent-safe submit command and also supports `--download <path>` when a local artifact is needed. `xt tool resolve <tool_id>` remains available as the low-level UUID and route lookup. `xt tool menus` returns a concise catalog with each tool title, `module_id`, `path`, and `route`, which is useful when `tool search` finds nothing helpful or when you want to shortlist tools for recommendation.
112
149
 
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.
150
+ `xt tool cloud <tool_id>` fetches paginated cloud candidates and returns a machine-friendly payload when `--json` is used. `data.choices` contains the short selector list with 0-based `index`, `data_id`, and `label`; `records` contains the full records; `columns`, `filter`, `selected_record`, `pages_fetched`, and pagination metadata are included for callers that need the full context. Use `--page` to fetch one page, `--all` to merge every page, and `--argsKey` only when the module's cloud field cannot be auto-detected. `xt tool cloud` uses `--recordJson` / `--recordFile` for the current record seed, while `xt tool prepare` and `xt tool exec` use `--cloudRecordJson` / `--cloudRecordFile` for the final selected record.
114
151
 
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.
152
+ `--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. `--cloudRecordJson` / `--cloudRecordFile` cannot be combined with `--cloudFilter` / `--cloudDataId` / `--cloudIndex`, and cloud selection flags cannot be combined with `--demo` or `--file`. When a tool exposes multiple downloadable results, `--download <path>` uses the output file extension to select the matching artifact.
116
153
 
117
154
  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).
118
155
 
119
156
  `xt tool run <tool_id> ... --interactive` prompts for dynamic `args_main` values before the final submit, prints reusable `--set` flags, and supports `<` for the previous item plus `/skip` for the current section.
120
157
 
121
- `xt history list` lists the current profile's history records and shows the latest `fuid`, status, module, and time for each record. `xt history download <fuid> --device pdf` downloads an existing history artifact by `fuid`; when a record exposes multiple files, pass `--device` or use an `--output` path with a target extension. `xt history rename <fuid> <name>` renames a record, and `xt history delete <fuid>` deletes it.
158
+ `xt history list` lists the current profile's history records and shows the latest `fuid`, status, module, and time for each record. `xt history view <fuid>` lists the downloadable files for one history record. `xt history download <fuid> --device pdf` downloads an existing history artifact by `fuid`; when a record exposes multiple files, pass `--device`, `--item`, `--label`, or use an `--output` path with a target extension. `xt history save <fuid> <uuid> <module_id> <name>` saves a direct analysis result into history. `xt history rename <fuid> <name>` renames a record, and `xt history delete <fuid>` deletes it.
122
159
 
123
160
  ## Development
124
161
 
@@ -1,2 +1,3 @@
1
- import{Flags as s}from"@oclif/core";import{XtzCommand as h}from"../../base-command.js";import{globalFlags as u}from"../../lib/flags.js";import{loginAuth as d}from"../../lib/auth.js";import{loginAll as p}from"../../lib/login-flow.js";import{getTokenPath as f}from"../../lib/storage.js";class a extends h{static description="Authorize the current profile token";static flags={...u,open:s.boolean({allowNo:!0,default:!0,description:"Open the authorization link in the browser"}),wait:s.boolean({allowNo:!0,default:!0,description:"Wait until the browser authorization is confirmed before exiting"})};async run(){this.warnIfLegacyAuthCommand();const{flags:t}=await this.parse(a),o=await this.getProfile(t.profile),i=this.shouldWait(t),e=i?await p(o,t.open,({auth:n,phase:l})=>{if(!t.json){if(l==="auth_started"){this.log(n.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u6388\u6743\u94FE\u63A5\uFF0C\u7B49\u5F85\u6388\u6743\u5B8C\u6210...":`\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u6388\u6743\u94FE\u63A5: ${n.linkUrl}`);return}this.log("\u6388\u6743\u5DF2\u786E\u8BA4\u3002")}}):{auth:await d(o,t.open)},r=i;this.print(t,{agent:o,authorization_pending:!r,authorized:r,browser_opened:e.auth.browserOpened,link_url:e.auth.linkUrl,token_path:e.auth.tokenPath,wait:i},this.formatLoginText({agent:o,authorized:r,browserOpened:e.auth.browserOpened,linkUrl:e.auth.linkUrl}),{profile:o})}shouldWait(t){return this.hasExplicitWaitFlag()?t.wait:!t.json}hasExplicitWaitFlag(){return this.argv.includes("--wait")||this.argv.includes("--no-wait")}formatLoginText(t){const o=[`profile: ${t.agent}`,`token: ${f(t.agent)}`,`authorized: ${t.authorized}`];return t.authorized||o.push(t.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u6388\u6743\u94FE\u63A5\uFF0C\u8BF7\u5B8C\u6210\u6388\u6743\u540E\u8FD0\u884C `xt status`\u3002":`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t.linkUrl}`),o.join(`
2
- `)}}export{a as default};
1
+ import{Flags as u}from"@oclif/core";import{XtzCommand as w}from"../../base-command.js";import{globalFlags as g}from"../../lib/flags.js";import{formatTokenPreview as d,startLoginAuth as k}from"../../lib/auth.js";import{loginAll as p}from"../../lib/login-flow.js";import{getTokenPath as f}from"../../lib/storage.js";class n extends w{static description="Authorize and store the current profile token";static flags={...g,open:u.boolean({allowNo:!0,default:!0,description:"Open the login page in a Playwright browser"}),wait:u.boolean({allowNo:!0,default:!0,description:"Wait until the browser login token is captured before exiting"})};async run(){this.warnIfLegacyAuthCommand();const{flags:t}=await this.parse(n),e=await this.getProfile(t.profile),a=t.open&&this.shouldWait(t),o=a?await p(e,t.open,({auth:i,phase:l})=>{if(!t.json){if(l==="auth_started"){this.log(i.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u767B\u5F55\u9875\u9762\uFF0C\u7B49\u5F85\u767B\u5F55\u5B8C\u6210...":`\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u767B\u5F55\u9875\u9762: ${i.linkUrl}`);return}if(l==="token_saved"){const h=d(i.token);this.log(`\u5DF2\u8BB0\u5F55 token: ${i.tokenPath}${h?` (${h})`:""}`);return}this.log("\u767B\u5F55\u5DF2\u786E\u8BA4\u3002")}}):{auth:await k(e)},r=!!o.auth.token,s=d(o.auth.token);this.print(t,{agent:e,authorization_pending:!r,authorized:r,browser_opened:o.auth.browserOpened,link_url:o.auth.linkUrl,token_preview:s,token_path:o.auth.tokenPath,token_saved:r,wait:a},this.formatLoginText({agent:e,authorized:r,browserOpened:o.auth.browserOpened,linkUrl:o.auth.linkUrl,tokenPreview:s}),{profile:e})}shouldWait(t){return this.hasExplicitWaitFlag()?t.wait:!t.json}hasExplicitWaitFlag(){return this.argv.includes("--wait")||this.argv.includes("--no-wait")}formatLoginText(t){const e=[`profile: ${t.agent}`,`token: ${f(t.agent)}`,`authorized: ${t.authorized}`,`token_saved: ${t.authorized}`];return t.authorized?(t.tokenPreview&&e.push(`token_preview: ${t.tokenPreview}`),e.join(`
2
+ `)):(e.push(t.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u767B\u5F55\u9875\u9762\uFF0C\u8BF7\u5B8C\u6210\u767B\u5F55\u540E\u8FD0\u884C `xt status`\u3002":`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t.linkUrl}`),e.join(`
3
+ `))}}export{n as default};
@@ -1,2 +1,2 @@
1
- import{XtzCommand as n}from"../../base-command.js";import{XtzError as s}from"../../lib/errors.js";import{checkToken as h}from"../../lib/auth.js";import{globalFlags as u}from"../../lib/flags.js";import{getTokenPath as f,loadToken as l}from"../../lib/storage.js";class i extends n{static description="Show token auth status for the current profile";static flags={...u};async run(){this.warnIfLegacyAuthCommand();const{flags:e}=await this.parse(i),o=await this.getProfile(e.profile),t=f(o),r=await l(o),a=r?await this.resolveAuthorization(o,r):{authorized:!1,reason:"missing_token"};this.print(e,{agent:o,authorized:a.authorized,reason:a.reason,token_path:t},this.formatStatusText(o,t,a),{profile:o})}async resolveAuthorization(e,o){try{return await h(e,o),{authorized:!0,reason:null}}catch(t){if(!(t instanceof s)||!t.message.includes("\u6388\u6743\u5DF2\u8FC7\u671F"))throw t;return{authorized:!1,reason:"expired_token"}}}formatStatusText(e,o,t){const r=[`profile: ${e}`,`authorized: ${t.authorized}`,`token: ${o}`];return!t.authorized&&t.reason&&(r.push(`reason: ${t.reason}`),r.push(`run: xt login --profile ${e}`)),r.join(`
1
+ import{XtzCommand as s}from"../../base-command.js";import{XtzError as h}from"../../lib/errors.js";import{checkToken as u,formatTokenPreview as f}from"../../lib/auth.js";import{globalFlags as l}from"../../lib/flags.js";import{getTokenPath as c,loadToken as p}from"../../lib/storage.js";class i extends s{static description="Show token auth status for the current profile";static flags={...l};async run(){this.warnIfLegacyAuthCommand();const{flags:a}=await this.parse(i),t=await this.getProfile(a.profile),o=c(t),e=await p(t),n=f(e),r=e?await this.resolveAuthorization(t,e):{authorized:!1,reason:"missing_token"};this.print(a,{agent:t,authorized:r.authorized,reason:r.reason,token_preview:n,token_path:o,token_saved:!!e},this.formatStatusText(t,o,!!e,n,r),{profile:t})}async resolveAuthorization(a,t){try{return await u(a,t),{authorized:!0,reason:null}}catch(o){if(!(o instanceof h)||!o.message.includes("\u6388\u6743\u5DF2\u8FC7\u671F"))throw o;return{authorized:!1,reason:"expired_token"}}}formatStatusText(a,t,o,e,n){const r=[`profile: ${a}`,`authorized: ${n.authorized}`,`token: ${t}`,`token_saved: ${o}`];return e&&r.push(`token_preview: ${e}`),!n.authorized&&n.reason&&(r.push(`reason: ${n.reason}`),r.push(`run: xt login --profile ${a}`)),r.join(`
2
2
  `)}}export{i as default};
@@ -0,0 +1 @@
1
+ import{Args as i,Flags as o}from"@oclif/core";import{XtzCommand as r}from"../../base-command.js";import{resolveXiantaoConfigValue as n}from"../../lib/config.js";class t extends r{static description="Get a resolved config value";static args={key:i.string({description:"Config key, such as base-url or login-url",required:!0})};static flags={json:o.boolean({default:!1,description:"Output JSON"})};async run(){const{args:a,flags:e}=await this.parse(t),s=await n(a.key);this.print(e,s,s.value)}}export{t as default};
@@ -0,0 +1,2 @@
1
+ import{Args as i,Flags as n}from"@oclif/core";import{XtzCommand as u}from"../../base-command.js";import{resolveXiantaoConfigValue as l,setXiantaoConfigValue as c}from"../../lib/config.js";class s extends u{static description="Set a config value";static args={key:i.string({description:"Config key, such as base-url or login-url",required:!0}),value:i.string({description:"Config value",required:!0})};static flags={json:n.boolean({default:!1,description:"Output JSON"})};async run(){const{args:t,flags:e}=await this.parse(s),a=await c(t.key,t.value),o=await l(a.key),r={...a,active_source:o.source,active_value:o.value};this.print(e,r,this.formatSetText(a,o))}formatSetText(t,e){const a=[`${t.key}: ${t.value}`,`path: ${t.path}`];return(e.source!=="config"||e.value!==t.value)&&a.push(`active: ${e.value} (${e.source})`),a.join(`
2
+ `)}}export{s as default};
@@ -1 +1 @@
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
+ import{Args as c,Flags as n}from"@oclif/core";import{XtzCommand as u}from"../../base-command.js";import{getAuthContext as g}from"../../lib/auth.js";import{globalFlags as f}from"../../lib/flags.js";import{buildArgsMainFromSchema as m,buildArgsSpecificFromSchema as p}from"../../lib/plot-schema.js";import{fetchAllPlotArgs as h}from"../../lib/xiantao.js";class r extends u{static description="Fetch raw dynamic args for a Xiantao tool via public.args.fetch-all";static args={moduleId:c.string({description:"Tool id, e.g. violin_flat",required:!0})};static flags={...f,token:n.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"}),uuid:n.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 g(a,i.token),t=await h(l,{moduleId:s.moduleId,uuid:i.uuid}),d=m(t.args_main),o=t.args_specific??[],e={agent:a,args_data:t.args_data??[],args_main:t.args_main??[],args_main_defaults:d,args_specific:o,args_specific_defaults:p(o),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,2 +1,3 @@
1
- import{Flags as s}from"@oclif/core";import{XtzCommand as h}from"../../base-command.js";import{loginAuth as u}from"../../lib/auth.js";import{globalFlags as d}from"../../lib/flags.js";import{loginAll as p}from"../../lib/login-flow.js";import{getTokenPath as f}from"../../lib/storage.js";class a extends h{static description="Authorize the current profile token";static flags={...d,open:s.boolean({allowNo:!0,default:!0,description:"Open the authorization link in the browser"}),wait:s.boolean({allowNo:!0,default:!0,description:"Wait until the browser authorization is confirmed before exiting"})};async run(){this.warnIfLegacyPlotCommand();const{flags:t}=await this.parse(a),o=await this.getProfile(t.profile),i=this.shouldWait(t),e=i?await p(o,t.open,({auth:n,phase:l})=>{if(!t.json){if(l==="auth_started"){this.log(n.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u6388\u6743\u94FE\u63A5\uFF0C\u7B49\u5F85\u6388\u6743\u5B8C\u6210...":`\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u6388\u6743\u94FE\u63A5: ${n.linkUrl}`);return}this.log("\u6388\u6743\u5DF2\u786E\u8BA4\u3002")}}):{auth:await u(o,t.open)},r=i;this.print(t,{agent:o,authorization_pending:!r,authorized:r,browser_opened:e.auth.browserOpened,link_url:e.auth.linkUrl,token_path:e.auth.tokenPath,wait:i},this.formatLoginText({agent:o,authorized:r,browserOpened:e.auth.browserOpened,linkUrl:e.auth.linkUrl}),{profile:o})}shouldWait(t){return this.hasExplicitWaitFlag()?t.wait:!t.json}hasExplicitWaitFlag(){return this.argv.includes("--wait")||this.argv.includes("--no-wait")}formatLoginText(t){const o=[`profile: ${t.agent}`,`token: ${f(t.agent)}`,`authorized: ${t.authorized}`];return t.authorized||o.push(t.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u6388\u6743\u94FE\u63A5\uFF0C\u8BF7\u5B8C\u6210\u6388\u6743\u540E\u8FD0\u884C `xt status`\u3002":`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t.linkUrl}`),o.join(`
2
- `)}}export{a as default};
1
+ import{Flags as u}from"@oclif/core";import{XtzCommand as w}from"../../base-command.js";import{formatTokenPreview as d,startLoginAuth as g}from"../../lib/auth.js";import{globalFlags as k}from"../../lib/flags.js";import{loginAll as p}from"../../lib/login-flow.js";import{getTokenPath as f}from"../../lib/storage.js";class n extends w{static description="Authorize and store the current profile token";static flags={...k,open:u.boolean({allowNo:!0,default:!0,description:"Open the login page in a Playwright browser"}),wait:u.boolean({allowNo:!0,default:!0,description:"Wait until the browser login token is captured before exiting"})};async run(){this.warnIfLegacyPlotCommand();const{flags:t}=await this.parse(n),e=await this.getProfile(t.profile),a=t.open&&this.shouldWait(t),o=a?await p(e,t.open,({auth:i,phase:l})=>{if(!t.json){if(l==="auth_started"){this.log(i.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u767B\u5F55\u9875\u9762\uFF0C\u7B49\u5F85\u767B\u5F55\u5B8C\u6210...":`\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u767B\u5F55\u9875\u9762: ${i.linkUrl}`);return}if(l==="token_saved"){const h=d(i.token);this.log(`\u5DF2\u8BB0\u5F55 token: ${i.tokenPath}${h?` (${h})`:""}`);return}this.log("\u767B\u5F55\u5DF2\u786E\u8BA4\u3002")}}):{auth:await g(e)},r=!!o.auth.token,s=d(o.auth.token);this.print(t,{agent:e,authorization_pending:!r,authorized:r,browser_opened:o.auth.browserOpened,link_url:o.auth.linkUrl,token_preview:s,token_path:o.auth.tokenPath,token_saved:r,wait:a},this.formatLoginText({agent:e,authorized:r,browserOpened:o.auth.browserOpened,linkUrl:o.auth.linkUrl,tokenPreview:s}),{profile:e})}shouldWait(t){return this.hasExplicitWaitFlag()?t.wait:!t.json}hasExplicitWaitFlag(){return this.argv.includes("--wait")||this.argv.includes("--no-wait")}formatLoginText(t){const e=[`profile: ${t.agent}`,`token: ${f(t.agent)}`,`authorized: ${t.authorized}`,`token_saved: ${t.authorized}`];return t.authorized?(t.tokenPreview&&e.push(`token_preview: ${t.tokenPreview}`),e.join(`
2
+ `)):(e.push(t.browserOpened?"\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u767B\u5F55\u9875\u9762\uFF0C\u8BF7\u5B8C\u6210\u767B\u5F55\u540E\u8FD0\u884C `xt status`\u3002":`\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00: ${t.linkUrl}`),e.join(`
3
+ `))}}export{n as default};
@@ -1,9 +1,9 @@
1
- import{readFile as L}from"node:fs/promises";import{Args as S,Flags as h}from"@oclif/core";import{XtzCommand as X}from"../../base-command.js";import{getAuthContext as M}from"../../lib/auth.js";import{XIANTAO_HISTORY_UUID as N}from"../../lib/constants.js";import{downloadToPath as g}from"../../lib/download.js";import{XtzChoiceRequiredError as O,XtzError as a}from"../../lib/errors.js";import{globalFlags as B,toolCloudFlags as E}from"../../lib/flags.js";import{fetchXiantaoHistoryDownloadButtons as j,getXiantaoHistoryRecordStatus as K,waitForLatestXiantaoHistoryRecord as J,waitForXiantaoHistoryRecordCompletion as V}from"../../lib/history.js";import{deepMerge as p,isJsonObject as U}from"../../lib/json.js";import{confirmPlotArgsMain as q,promptPlotArgsMain as Q,promptPlotCloudRecordSelection as G,promptPlotFilePath as F,promptPlotInputSource as Y,promptPlotMenuSelection as W,promptPlotResultSelection as Z}from"../../lib/plot-interactive.js";import{uploadFile as ee}from"../../lib/plot.js";import{parseSetOverrides as oe,parseSpecificOverrides as te,plotOverrideFlags as ie}from"../../lib/plot-options.js";import{buildArgsMainFromSchema as P,buildArgsSpecificFromSchema as T}from"../../lib/plot-schema.js";import{loadPlotArgsMainConfig as de,resolveXiantaoToolProductUuid as ne}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as D,findDefaultXiantaoRecord as H,listXiantaoUploadFields as $}from"../../lib/tool-inputs.js";import{fetchXiantaoCloudData as z}from"../../lib/xiantao-cloud.js";import{buildSubmitArgsData as re,resolveXiantaoDownload as A,submitXiantaoPlot as le,verifyXiantaoPlotUpload as ae}from"../../lib/xiantao-plot.js";import{fetchAllPlotArgs as ue,fetchToolMenu as se,fetchToolMenus as ce,resolveToolMenuByCode as me,updatePlotArgs as he}from"../../lib/xiantao.js";class fe extends X{resolveToolFileInputs(e,o){if(e&&o&&o.length>0)throw new a("FILE \u4E0E `--file` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");return e?[e]:o??[]}async prepareToolRun(e,o,t){this.validateInputSourceFlags(o,t);const i=await this.getProfile(t.profile),d=await M(i,t.token),n=await this.resolveModule(e,t,d),{moduleId:l,route:r,toolProductUuid:u,uuid:s}=n,c=await ue(d,{moduleId:l,uuid:s}),f=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:o,interactive:t.interactive}),y=await de(l,t.config),R=p(y,oe(t.set)),x=te(t.specific);let w=c.args_main??[],_=c.args_specific??[],I=p(P(w),R),v=p(T(_),x),m=f.mode==="cloud"?await this.resolveCloudInput(c,t,l,d,s):f.mode==="demo"?this.resolveDemoInput(c,l):f.mode==="record"?this.resolveRecordInput(c,l):await this.uploadAndVerify(i,f.fileInputs??[],{argsMain:I,argsData:c.args_data??[],moduleId:l,uuid:s},d);if(m.schema.length&&(w=m.schema,I=p(P(w),R)),m.input.kind==="cloud"){const k=await he(d,{argsData:re(m.duid,m.input),argsKey:m.input.cloud.key,argsMain:I,argsSpecific:v,moduleId:l,uuid:s}),b=D(k.args_data??[]);b&&(m={...m,input:{kind:"cloud",cloud:{key:b.key,label:b.label,record:this.normalizeCloudRecord(b.record)}}}),w=k.args_main??w,_=k.args_specific??_,I=p(P(w),R),v=p(T(_),x)}return{agent:i,argsMain:I,argsSpecific:v,argsSpecificSchema:_,auth:d,duid:m.duid,input:m.input,inputMode:f.mode,inputSummary:this.summarizePreparedInput(m.input),moduleId:l,notice:c.notice??"",route:r,schema:w,toolProductUuid:u,uuid:s}}async executeToolRun(e,o,t){this.validateDownloadFlags(t);const i=await this.prepareToolRun(e,o,t);let d=i.argsMain;const n=i.argsSpecific;t.interactive&&(d=await Q(i.schema??[],d),await q(d));const l=Date.now(),r=await le(i.auth,{argsMain:d,argsSpecific:n,duid:i.duid,input:i.input,moduleId:i.moduleId,route:i.route,uuid:i.uuid});if(r.asyncSubmission)return this.resolveAsyncToolRun(i,d,n,t,l,r.message);const u=t.download?await this.downloadResult(i.auth,{downloadPath:t.download,downloadItem:t.downloadItem,downloadLabel:t.downloadLabel,downloads:r.downloads,file:r.file,moduleId:i.moduleId,uuid:i.uuid}):await this.downloadInteractiveResults(i.auth,{choice:t.interactive?await Z({downloads:r.downloads,hasFile:!!r.file}):{downloadFile:!1,downloads:[]},file:r.file,moduleId:i.moduleId,uuid:i.uuid}),s=u[0];return{data:{agent:i.agent,args_main:d,args_specific:n,body:r.body,download_path:s,download_paths:u,downloads:r.downloads,duid:i.duid,file:r.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:r.message,tool_product_uuid:i.toolProductUuid,uuid:i.uuid},text:this.formatResultText(r,u,t.interactive&&!t.download)}}async resolveAsyncToolRun(e,o,t,i,d,n){const l=await J(e.auth,{intervalMs:3e3,moduleId:e.moduleId,submittedAtMs:d,timeoutMs:i.download?6e4:12e3}),r=l?this.toHistorySummary(l,e.moduleId):null;if(!i.download)return{data:{agent:e.agent,args_main:o,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:e.duid,file:null,history:r,history_hint:this.buildHistoryHint(r),...e.inputSummary,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,result_source:"history",route:e.route,submission_message:n,tool_product_uuid:e.toolProductUuid,uuid:e.uuid},text:this.formatAsyncHistoryText(r,n)};if(!l?.fuid?.trim())return{data:{agent:e.agent,args_main:o,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:e.duid,file:null,history:r,history_hint:this.buildHistoryHint(r),...e.inputSummary,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,result_source:"history",route:e.route,submission_message:n,tool_product_uuid:e.toolProductUuid,uuid:e.uuid},text:this.formatAsyncHistoryText(r,`${n}\uFF0C\u4F46\u6682\u672A\u5B9A\u4F4D\u5230\u5386\u53F2\u8BB0\u5F55\u3002`)};const u=await V(e.auth,{fuid:l.fuid.trim(),intervalMs:3e3,timeoutMs:6e4}),s=u?this.toHistorySummary(u,e.moduleId):r;if(!u?.fuid?.trim())return{data:{agent:e.agent,args_main:o,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:e.duid,file:null,history:s,history_hint:this.buildHistoryHint(s),...e.inputSummary,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,result_source:"history",route:e.route,submission_message:`${n}\uFF0C\u4F46\u7B49\u5F85\u5386\u53F2\u8BB0\u5F55\u5B8C\u6210\u8D85\u65F6\u3002`,tool_product_uuid:e.toolProductUuid,uuid:e.uuid},text:this.formatAsyncHistoryText(s,`${n}\uFF0C\u4F46\u7B49\u5F85\u5386\u53F2\u8BB0\u5F55\u5B8C\u6210\u8D85\u65F6\u3002`)};const{body:c,downloads:f,paths:y}=await this.downloadAsyncHistoryResult(e.auth,{downloadPath:i.download,downloadItem:i.downloadItem,downloadLabel:i.downloadLabel,fuid:u.fuid.trim(),moduleId:e.moduleId});return{data:{agent:e.agent,args_main:o,args_specific:t,body:c,download_path:y[0],download_paths:y,downloads:f,duid:e.duid,file:null,history:s,history_hint:this.buildHistoryHint(s),...e.inputSummary,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,result_source:"history",route:e.route,submission_message:n,tool_product_uuid:e.toolProductUuid,uuid:e.uuid},text:this.formatAsyncHistoryDownloadText(s,y)}}async downloadAsyncHistoryResult(e,o){let t;for(let i=0;i<4;i+=1){const d=await j(e,{fuid:o.fuid});try{const n=await this.downloadResult(e,{downloadPath:o.downloadPath,downloadItem:o.downloadItem,downloadLabel:o.downloadLabel,downloads:d.downloads,moduleId:o.moduleId,uuid:N});return{body:d.body,downloads:d.downloads,paths:n}}catch(n){if(!(n instanceof a)||!this.isRetryableAsyncDownloadError(n)||i===3)throw n;t=n,await this.sleep(3e3)}}throw t??new a("\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5")}formatResultText(e,o,t){const i=[];if(e.file&&i.push(e.file),!e.file&&(e.downloads.length>0||e.body)&&i.push("\u5206\u6790\u5B8C\u6210"),!e.file&&!e.body&&e.downloads.length===0)return"\u63D0\u4EA4\u5B8C\u6210";if(e.downloads.length>0&&!t)for(const d of e.downloads)i.push(`${d.label} (${d.device})`);for(const d of o)i.push(d);return i.join(`
1
+ import{readFile as L}from"node:fs/promises";import{Args as x,Flags as h}from"@oclif/core";import{XtzCommand as X}from"../../base-command.js";import{getAuthContext as S}from"../../lib/auth.js";import{XIANTAO_HISTORY_UUID as N}from"../../lib/constants.js";import{downloadToPath as b}from"../../lib/download.js";import{XtzChoiceRequiredError as B,XtzError as a}from"../../lib/errors.js";import{globalFlags as O,toolCloudFlags as E}from"../../lib/flags.js";import{fetchXiantaoHistoryDownloadButtons as j,getXiantaoHistoryRecordStatus as K,waitForLatestXiantaoHistoryRecord as J,waitForXiantaoHistoryRecordCompletion as V}from"../../lib/history.js";import{deepMerge as g,isJsonObject as M}from"../../lib/json.js";import{confirmPlotArgsMain as q,promptPlotArgsMain as Q,promptPlotCloudRecordSelection as G,promptPlotFilePath as U,promptPlotInputSource as Y,promptPlotMenuSelection as W,promptPlotResultSelection as Z}from"../../lib/plot-interactive.js";import{uploadFile as ee}from"../../lib/plot.js";import{applySpecificOverrides as F,parseSetOverrides as oe,plotOverrideFlags as te}from"../../lib/plot-options.js";import{buildArgsMainFromSchema as P,buildArgsSpecificFromSchema as T}from"../../lib/plot-schema.js";import{loadPlotArgsMainConfig as ie,resolveXiantaoToolProductUuid as de}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as D,findDefaultXiantaoRecord as H,listXiantaoUploadFields as $}from"../../lib/tool-inputs.js";import{fetchXiantaoCloudData as z}from"../../lib/xiantao-cloud.js";import{buildSubmitArgsData as ne,resolveXiantaoDownload as A,submitXiantaoPlot as re,verifyXiantaoPlotUpload as le}from"../../lib/xiantao-plot.js";import{fetchAllPlotArgs as ae,fetchToolMenu as ue,fetchToolMenus as se,resolveToolMenuByCode as ce,updatePlotArgs as me}from"../../lib/xiantao.js";class he extends X{resolveToolFileInputs(e,o){if(e&&o&&o.length>0)throw new a("FILE \u4E0E `--file` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");return e?[e]:o??[]}async prepareToolRun(e,o,t){this.validateInputSourceFlags(o,t);const i=await this.getProfile(t.profile),d=await S(i,t.token),n=await this.resolveModule(e,t,d),{moduleId:l,route:r,toolProductUuid:u,uuid:s}=n,c=await ae(d,{moduleId:l,uuid:s}),f=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:o,interactive:t.interactive}),p=await ie(l,t.config),R=g(p,oe(t.set));let w=c.args_main??[],y=c.args_specific??[],_=g(P(w),R),v=F(T(y),t.specific),m=f.mode==="cloud"?await this.resolveCloudInput(c,t,l,d,s):f.mode==="demo"?this.resolveDemoInput(c,l):f.mode==="record"?this.resolveRecordInput(c,l):await this.uploadAndVerify(i,f.fileInputs??[],{argsMain:_,argsData:c.args_data??[],moduleId:l,uuid:s},d);if(m.schema.length&&(w=m.schema,_=g(P(w),R)),m.input.kind==="cloud"){const k=await me(d,{argsData:ne(m.duid,m.input),argsKey:m.input.cloud.key,argsMain:_,argsSpecific:v,moduleId:l,uuid:s}),I=D(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,y=k.args_specific??y,_=g(P(w),R),v=F(T(y),t.specific)}return{agent:i,argsMain:_,argsSpecific:v,argsSpecificSchema:y,auth:d,duid:m.duid,input:m.input,inputMode:f.mode,inputSummary:this.summarizePreparedInput(m.input),moduleId:l,notice:c.notice??"",route:r,schema:w,toolProductUuid:u,uuid:s}}async executeToolRun(e,o,t){this.validateDownloadFlags(t);const i=await this.prepareToolRun(e,o,t);let d=i.argsMain;const n=i.argsSpecific;t.interactive&&(d=await Q(i.schema??[],d),await q(d));const l=Date.now(),r=await re(i.auth,{argsMain:d,argsSpecific:n,duid:i.duid,input:i.input,moduleId:i.moduleId,route:i.route,uuid:i.uuid});if(r.asyncSubmission)return this.resolveAsyncToolRun(i,d,n,t,l,r.message);const u=t.download?await this.downloadResult(i.auth,{downloadPath:t.download,downloadItem:t.downloadItem,downloadLabel:t.downloadLabel,downloads:r.downloads,file:r.file,moduleId:i.moduleId,uuid:i.uuid}):await this.downloadInteractiveResults(i.auth,{choice:t.interactive?await Z({downloads:r.downloads,hasFile:!!r.file}):{downloadFile:!1,downloads:[]},file:r.file,moduleId:i.moduleId,uuid:i.uuid}),s=u[0];return{data:{agent:i.agent,args_main:d,args_specific:n,body:r.body,download_path:s,download_paths:u,downloads:r.downloads,duid:i.duid,file:r.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:r.message,tool_product_uuid:i.toolProductUuid,uuid:i.uuid},text:this.formatResultText(r,u,t.interactive&&!t.download)}}async resolveAsyncToolRun(e,o,t,i,d,n){const l=await J(e.auth,{intervalMs:3e3,moduleId:e.moduleId,submittedAtMs:d,timeoutMs:i.download?6e4:12e3}),r=l?this.toHistorySummary(l,e.moduleId):null;if(!i.download)return{data:{agent:e.agent,args_main:o,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:e.duid,file:null,history:r,history_hint:this.buildHistoryHint(r),...e.inputSummary,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,result_source:"history",route:e.route,submission_message:n,tool_product_uuid:e.toolProductUuid,uuid:e.uuid},text:this.formatAsyncHistoryText(r,n)};if(!l?.fuid?.trim())return{data:{agent:e.agent,args_main:o,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:e.duid,file:null,history:r,history_hint:this.buildHistoryHint(r),...e.inputSummary,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,result_source:"history",route:e.route,submission_message:n,tool_product_uuid:e.toolProductUuid,uuid:e.uuid},text:this.formatAsyncHistoryText(r,`${n}\uFF0C\u4F46\u6682\u672A\u5B9A\u4F4D\u5230\u5386\u53F2\u8BB0\u5F55\u3002`)};const u=await V(e.auth,{fuid:l.fuid.trim(),intervalMs:3e3,timeoutMs:6e4}),s=u?this.toHistorySummary(u,e.moduleId):r;if(!u?.fuid?.trim())return{data:{agent:e.agent,args_main:o,args_specific:t,body:"",download_path:void 0,download_paths:[],downloads:[],duid:e.duid,file:null,history:s,history_hint:this.buildHistoryHint(s),...e.inputSummary,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,result_source:"history",route:e.route,submission_message:`${n}\uFF0C\u4F46\u7B49\u5F85\u5386\u53F2\u8BB0\u5F55\u5B8C\u6210\u8D85\u65F6\u3002`,tool_product_uuid:e.toolProductUuid,uuid:e.uuid},text:this.formatAsyncHistoryText(s,`${n}\uFF0C\u4F46\u7B49\u5F85\u5386\u53F2\u8BB0\u5F55\u5B8C\u6210\u8D85\u65F6\u3002`)};const{body:c,downloads:f,paths:p}=await this.downloadAsyncHistoryResult(e.auth,{downloadPath:i.download,downloadItem:i.downloadItem,downloadLabel:i.downloadLabel,fuid:u.fuid.trim(),moduleId:e.moduleId});return{data:{agent:e.agent,args_main:o,args_specific:t,body:c,download_path:p[0],download_paths:p,downloads:f,duid:e.duid,file:null,history:s,history_hint:this.buildHistoryHint(s),...e.inputSummary,mode:e.inputMode,module_id:e.moduleId,notice:e.notice,result_source:"history",route:e.route,submission_message:n,tool_product_uuid:e.toolProductUuid,uuid:e.uuid},text:this.formatAsyncHistoryDownloadText(s,p)}}async downloadAsyncHistoryResult(e,o){let t;for(let i=0;i<4;i+=1){const d=await j(e,{fuid:o.fuid});try{const n=await this.downloadResult(e,{downloadPath:o.downloadPath,downloadItem:o.downloadItem,downloadLabel:o.downloadLabel,downloads:d.downloads,moduleId:o.moduleId,uuid:N});return{body:d.body,downloads:d.downloads,paths:n}}catch(n){if(!(n instanceof a)||!this.isRetryableAsyncDownloadError(n)||i===3)throw n;t=n,await this.sleep(3e3)}}throw t??new a("\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5")}formatResultText(e,o,t){const i=[];if(e.file&&i.push(e.file),!e.file&&(e.downloads.length>0||e.body)&&i.push("\u5206\u6790\u5B8C\u6210"),!e.file&&!e.body&&e.downloads.length===0)return"\u63D0\u4EA4\u5B8C\u6210";if(e.downloads.length>0&&!t)for(const d of e.downloads)i.push(`${d.label} (${d.device})`);for(const d of o)i.push(d);return i.join(`
2
2
  `)}formatAsyncHistoryText(e,o){const t=[o];return e&&t.push(`\u5386\u53F2\u8BB0\u5F55: ${e.fuid} (${e.status})`),t.push(this.buildHistoryHint(e)),t.join(`
3
3
  `)}formatAsyncHistoryDownloadText(e,o){const t=[];e&&t.push(`\u5386\u53F2\u8BB0\u5F55: ${e.fuid} (${e.status})`);for(const i of o)t.push(i);return t.join(`
4
- `)}async downloadResult(e,o){if(o.downloads.length>0){const t=this.pickDownloadItem(o.downloads,{item:o.downloadItem,label:o.downloadLabel,outputPath:o.downloadPath});if(!t)throw new a(this.buildMultipleDownloadsMessage(o.downloads));const i=await A(e,{item:t,moduleId:o.moduleId,uuid:o.uuid});return[await g(i.url,o.downloadPath)]}if(o.file)return[await g(o.file,o.downloadPath)];throw new a("\u5F53\u524D\u6A21\u5757\u672A\u8FD4\u56DE\u53EF\u4E0B\u8F7D\u6587\u4EF6\u3002")}pickDownloadItem(e,o){if(o.item!==void 0)return this.pickDownloadItemByIndex(e,o.item);if(o.label)return this.pickDownloadItemByLabel(e,o.label);const t=this.inferDownloadDevice(o.outputPath);if(t){const d=e.filter(n=>this.normalizeDevice(n.device)===t);if(d.length===1)return d[0];if(d.length>1)throw new a(`\u4E0B\u8F7D\u683C\u5F0F ${t} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--downloadItem\` \u6216 \`--downloadLabel\` \u7CBE\u786E\u9009\u62E9\u3002
4
+ `)}async downloadResult(e,o){if(o.downloads.length>0){const t=this.pickDownloadItem(o.downloads,{item:o.downloadItem,label:o.downloadLabel,outputPath:o.downloadPath});if(!t)throw new a(this.buildMultipleDownloadsMessage(o.downloads));const i=await A(e,{item:t,moduleId:o.moduleId,uuid:o.uuid});return[await b(i.url,o.downloadPath)]}if(o.file)return[await b(o.file,o.downloadPath)];throw new a("\u5F53\u524D\u6A21\u5757\u672A\u8FD4\u56DE\u53EF\u4E0B\u8F7D\u6587\u4EF6\u3002")}pickDownloadItem(e,o){if(o.item!==void 0)return this.pickDownloadItemByIndex(e,o.item);if(o.label)return this.pickDownloadItemByLabel(e,o.label);const t=this.inferDownloadDevice(o.outputPath);if(t){const d=e.filter(n=>this.normalizeDevice(n.device)===t);if(d.length===1)return d[0];if(d.length>1)throw new a(`\u4E0B\u8F7D\u683C\u5F0F ${t} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--downloadItem\` \u6216 \`--downloadLabel\` \u7CBE\u786E\u9009\u62E9\u3002
5
5
  ${this.buildMultipleDownloadsMessage(e)}`)}const i=e.filter(d=>d.endpoint==="public.output.download-result");if(i.length===1)return i[0];if(e.length===1)return e[0]}pickDownloadItemByIndex(e,o){if(!Number.isInteger(o)||o<1||o>e.length)throw new a(`\u4E0B\u8F7D\u9879\u5E8F\u53F7 ${o} \u65E0\u6548\uFF0C\u53EF\u9009\u8303\u56F4\u4E3A 1-${e.length}\u3002
6
6
  ${this.buildMultipleDownloadsMessage(e)}`);return e[o-1]}pickDownloadItemByLabel(e,o){const t=o.trim().toLowerCase();if(!t)return;const i=e.filter(d=>d.label.trim().toLowerCase()===t);if(i.length===1)return i[0];if(i.length>1)throw new a(`\u4E0B\u8F7D\u9879\u540D\u79F0 ${o} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--downloadItem\` \u7CBE\u786E\u9009\u62E9\u3002
7
7
  ${this.buildMultipleDownloadsMessage(e)}`)}inferDownloadDevice(e){if(!e)return;const o=e.trim().split(".").pop()?.toLowerCase();if(o)return this.normalizeDevice(o)}normalizeDevice(e){const o=e.trim().toLowerCase();return o==="tif"?"tiff":o==="jpg"?"jpeg":o}buildMultipleDownloadsMessage(e){const o=["\u5F53\u524D\u6A21\u5757\u8FD4\u56DE\u591A\u4E2A\u53EF\u4E0B\u8F7D\u6587\u4EF6\uFF0C\u8BF7\u4F7F\u7528 `--downloadItem`\u3001`--downloadLabel` \u6216\u5E26\u76EE\u6807\u6269\u5C55\u540D\u7684 `--download` \u8DEF\u5F84\u660E\u786E\u9009\u62E9\u3002","\u53EF\u9009\u4E0B\u8F7D\u9879\uFF1A"];return e.forEach((t,i)=>{o.push(`${i+1}. ${t.label} (device=${t.device}, endpoint=${t.endpoint})`)}),o.join(`
8
- `)}validateDownloadFlags(e){if(e.downloadItem!==void 0&&e.downloadLabel)throw new a("`--downloadItem` \u4E0E `--downloadLabel` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");if((e.downloadItem!==void 0||e.downloadLabel)&&!e.download)throw new a("`--downloadItem` \u548C `--downloadLabel` \u4EC5\u53EF\u4E0E `--download` \u4E00\u8D77\u4F7F\u7528\u3002")}toHistorySummary(e,o){const t=e.fuid?.trim();return t?{fuid:t,id:typeof e.id=="number"?e.id:null,module_id:e.module_id?.trim()||o,module_name:e.module_name?.trim()||"",name:e.name?.trim()||"",status:K(e),time:e.time?.trim()||"",type:e.type?.trim()||""}:null}buildHistoryHint(e){return e?`\u53EF\u4F7F\u7528 \`xt history download ${e.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(e,o){const t=[];for(const i of o.downloads){const d=await A(e,{item:i,moduleId:o.moduleId,uuid:o.uuid});t.push(await g(d.url,d.fileName))}return t}async downloadInteractiveResults(e,o){const t=[];return o.choice.downloadFile&&o.file&&t.push(await g(o.file)),o.choice.downloads.length>0&&t.push(...await this.downloadSelectedResults(e,{downloads:o.choice.downloads,moduleId:o.moduleId,uuid:o.uuid})),t}isRetryableAsyncDownloadError(e){return e.message.includes("\u4E0B\u8F7D\u5931\u8D25")||e.message.includes("\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5")}async sleep(e){await new Promise(o=>setTimeout(o,e))}async resolveInputMode(e,o){if(o.demo)return this.hasDemoInput(e)?{mode:"demo"}:this.hasRecordInput(e)?{mode:"record"}:this.hasCloudInput(e)?{mode:"cloud"}:{mode:"demo"};if(o.fileInputs.length>0)return{fileInputs:o.fileInputs,mode:"upload"};if(o.cloudRequested)return{mode:"cloud"};if(this.hasRecordInput(e))return{mode:"record"};if(this.hasCloudInput(e))return{mode:"cloud"};if(!o.interactive)return{mode:"upload"};if(!this.hasDemoInput(e))return{fileInputs:[await F()],mode:"upload"};const t=await Y();return t==="demo"?{mode:t}:{fileInputs:[await F()],mode:t}}resolveDemoInput(e,o){const t=e.id?.duid?.trim();if(!t)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE demo duid\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);const i=$(e.args_data??[]);if(!i.length||i.some(d=>!d.defaultUpload))throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE\u53EF\u7528\u7684 demo \u6587\u4EF6\u4FE1\u606F\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);return{duid: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(e){if(!e.id?.duid?.trim())return!1;const t=$(e.args_data??[]);return t.length>0&&t.every(i=>!!i.defaultUpload)}async resolveCloudInput(e,o,t,i,d){const n=D(e.args_data??[]),l=o.cloudKey?.trim()||n?.key||"";if(!l)throw new a(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u4E91\u7AEF\u6570\u636E\u53C2\u6570\uFF0C\u8BF7\u663E\u5F0F\u4F20\u5165 \`--cloudKey\`.`);const r=await this.resolveCloudRecord(i,o,{argsKey:l,defaultRecord:n?.record,moduleId:t,uuid:d});if(!r)throw new a(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE\u9ED8\u8BA4\u4E91\u7AEF\u6570\u636E\uFF0C\u8BF7\u4F20\u5165 \`--cloudRecordJson\` \u6216 \`--cloudRecordFile\`.`);return{duid:e.id?.duid?.trim()||"cloud",input:{kind:"cloud",cloud:{key:l,label:n?.label??"",record:this.normalizeCloudRecord(r)}},schema:[]}}resolveRecordInput(e,o){const t=e.id?.duid?.trim();if(!t)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE record duid\uFF0C\u65E0\u6CD5\u4F7F\u7528\u5386\u53F2\u8BB0\u5F55\u8F93\u5165\u3002`);const i=H(e.args_data??[]);if(!i)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u6570\u636E\u8BB0\u5F55\uFF0C\u65E0\u6CD5\u76F4\u63A5\u8FD0\u884C\u3002`);return{duid: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(e){return!!(e.id?.duid?.trim()&&H(e.args_data??[]))}hasCloudInput(e){return!!D(e.args_data??[])}async uploadAndVerify(e,o,t,i){const d=await this.uploadFiles(e,o,t.argsData??[],t.moduleId),n=await ae(i,{argsMain:t.argsMain,moduleId:t.moduleId,uploads:d,uuid:t.uuid});return{duid:n.duid,input:{kind:"upload",uploads:d},schema:n.schema}}summarizePreparedInput(e){if(e.kind==="cloud")return{file_name:null,file_oss:null,file_size:null,input_cloud:this.summarizeCloudInput(e.cloud),input_record:null,input_uploads:null};if(e.kind==="record")return{file_name:null,file_oss:null,file_size:null,input_cloud:null,input_record:{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},input_uploads:null};const o=e.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=o.length===1?o[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:o}}summarizeCloudInput(e){return{data_filter:this.readCloudOptionValue(e.record.data_filter),data_id:typeof e.record.data_id=="string"?e.record.data_id.trim():"",data_process:this.readCloudOptionValue(e.record.data_process),key:e.key,label:e.label,record:structuredClone(e.record),record_label:typeof e.record.label=="string"?e.record.label.trim():""}}readCloudOptionValue(e){return U(e)&&(typeof e.value=="string"?e.value.trim():"")||null}async resolveCloudRecord(e,o,t){return o.cloudRecordJson?this.parseCloudRecord(o.cloudRecordJson,"--cloudRecordJson"):o.cloudRecordFile?this.parseCloudRecord(await L(o.cloudRecordFile,"utf8"),"--cloudRecordFile"):o.cloudFilter?.trim()||o.cloudDataId?.trim()||typeof o.cloudIndex=="number"?this.resolveCloudRecordByQuery(e,o,t):t.defaultRecord}parseCloudRecord(e,o){let t;try{t=JSON.parse(e)}catch{throw new a(`${o} \u4E0D\u662F\u5408\u6CD5 JSON\u3002`)}if(!U(t))throw new a(`${o} \u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002`);return t}normalizeCloudRecord(e){const o={};for(const[t,i]of Object.entries(e))i!==void 0&&(o[t]=structuredClone(i));return(typeof o.type!="string"||!o.type.trim())&&(o.type="cloud"),o}validateInputSourceFlags(e,o){const t=!!(o.cloudRecordJson||o.cloudRecordFile),i=!!(o.cloudDataId?.trim()||o.cloudFilter?.trim()||typeof o.cloudIndex=="number"),d=t||i;if(o.cloudRecordJson&&o.cloudRecordFile)throw new a("`--cloudRecordJson` \u4E0E `--cloudRecordFile` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");if(t&&i)throw new a("\u663E\u5F0F\u4E91\u7AEF\u8BB0\u5F55\u53C2\u6570\u4E0D\u80FD\u4E0E `--cloudFilter` / `--cloudDataId` / `--cloudIndex` \u540C\u65F6\u4F7F\u7528\u3002");if(o.demo&&d)throw new a("`--demo` \u4E0D\u80FD\u4E0E\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u53C2\u6570\u540C\u65F6\u4F7F\u7528\u3002");if(e.length>0&&d)throw new a("`--file` \u4E0D\u80FD\u4E0E\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u53C2\u6570\u540C\u65F6\u4F7F\u7528\u3002")}async resolveCloudRecordByQuery(e,o,t){const i=await this.fetchCloudRecords(e,{argsKey:t.argsKey,filter:o.cloudFilter?.trim(),moduleId:t.moduleId,selectedRecord:t.defaultRecord,uuid:t.uuid});if(i.length===0){const n=o.cloudFilter?.trim();throw n?new a(`\u672A\u627E\u5230\u5339\u914D\u4E91\u7AEF\u6570\u636E: ${n}`):new a("\u5F53\u524D\u6A21\u5757\u6CA1\u6709\u53EF\u9009\u7684\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u3002")}const d=o.cloudDataId?.trim();if(d){const n=i.find(l=>(typeof l.data_id=="string"?l.data_id.trim():"")===d);if(!n)throw new a(`\u672A\u627E\u5230 data_id=${d} \u5BF9\u5E94\u7684\u4E91\u7AEF\u6570\u636E\u3002`);return n}if(typeof o.cloudIndex=="number"){const n=i[o.cloudIndex];if(!n)throw new a(`\u4E91\u7AEF\u6570\u636E\u7D22\u5F15\u8D85\u51FA\u8303\u56F4: ${o.cloudIndex}\uFF0C\u5F53\u524D\u5171\u6709 ${i.length} \u6761\u3002`);return n}if(i.length===1)return i[0];if(o.interactive)return this.normalizeCloudRecord(await G(i));throw new O(this.buildCloudSelectionHint(i,o.cloudFilter?.trim()),this.buildCloudSelectionData(i,o.cloudFilter?.trim()))}async fetchCloudRecords(e,o){const t=await z(e,{argsKey:o.argsKey,currentPage:1,filter:o.filter,moduleId:o.moduleId,selectedRecord:o.selectedRecord,uuid:o.uuid}),i=t.records.map(d=>this.normalizeCloudRecord(d));for(let d=t.currentPage+1;d<=t.lastPage;d+=1){const n=await z(e,{argsKey:o.argsKey,currentPage:d,filter:o.filter,moduleId:o.moduleId,selectedRecord:o.selectedRecord,uuid:o.uuid});i.push(...n.records.map(l=>this.normalizeCloudRecord(l)))}return i}buildCloudSelectionHint(e,o){const t=[o?`\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E: ${o}`:"\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E","\u8BF7\u4F7F\u7528 `--cloudIndex` \u6216 `--cloudDataId` \u6307\u5B9A\u5176\u4E2D\u4E00\u6761\uFF1A"];return e.forEach((i,d)=>{const n=typeof i.data_id=="string"?i.data_id.trim():"",l=typeof i.label=="string"?i.label.trim():"";t.push(` [${d}] ${l||n}`)}),t.join(`
9
- `)}buildCloudSelectionData(e,o){return{choices:e.map((t,i)=>{const d=typeof t.data_id=="string"?t.data_id.trim():"",n=typeof t.label=="string"?t.label.trim():"";return{data_id:d,index:i,label:n||d}}),filter:o??"",selection_type:"cloud_record"}}async uploadFiles(e,o,t,i){const d=$(t??[]),n=this.resolveUploadInputs(o,d,i),l=await M(e),r=[];for(const u of n){const s=await ee(l,u.filePath);r.push({key:u.key,label:u.label,upload:s})}return r}resolveUploadInputs(e,o,t){if(!o.length)throw new a(`\u6A21\u5757 ${t} \u672A\u68C0\u6D4B\u5230\u53EF\u4E0A\u4F20\u8F93\u5165\uFF0C\u4E0D\u80FD\u4F7F\u7528 \`--file\`\u3002`);if(!e.length)throw o.length===1?new a("\u901A\u7528\u6A21\u5F0F\u8BF7\u4F20\u5165 FILE / `--file <xlsx>`\uFF0C\u6216\u6539\u7528 `--demo`\u3002"):new a(`\u6A21\u5757 ${t} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(r=>r.key).join(", ")}`);const[i]=o;if(o.length===1&&e.length===1){const r=this.parseUploadFileInput(e[0]);if(r.key&&r.key!==i.key)throw new a(`\u6A21\u5757 ${t} \u4EC5\u652F\u6301\u4E0A\u4F20\u5B57\u6BB5 ${i.key}\uFF0C\u6536\u5230 ${r.key}\u3002`);return[{filePath:r.path,key:i.key,label:i.label}]}const d=new Map(o.map(r=>[r.key,r])),n=new Map;for(const r of e){const u=this.parseUploadFileInput(r);if(!u.key){if(o.length===1){if(n.has(i.key))throw new a(`\u6A21\u5757 ${t} \u4EC5\u9700\u8981 1 \u4E2A\u4E0A\u4F20\u6587\u4EF6\uFF0C\u6536\u5230\u91CD\u590D\u8F93\u5165\u3002`);n.set(i.key,u.path);continue}throw new a(`\u6A21\u5757 ${t} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(c=>c.key).join(", ")}`)}const s=d.get(u.key);if(!s)throw new a(`\u6A21\u5757 ${t} \u4E0D\u5B58\u5728\u4E0A\u4F20\u5B57\u6BB5 ${u.key}\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(c=>c.key).join(", ")}`);if(n.has(s.key))throw new a(`\u4E0A\u4F20\u5B57\u6BB5 ${s.key} \u91CD\u590D\u4F20\u5165\u3002`);n.set(s.key,u.path)}const l=o.filter(r=>r.required&&!n.has(r.key));if(l.length>0)throw new a(`\u6A21\u5757 ${t} \u7F3A\u5C11\u5FC5\u586B\u4E0A\u4F20\u5B57\u6BB5: ${l.map(r=>r.key).join(", ")}`);return o.flatMap(r=>{const u=n.get(r.key);return u?[{filePath:u,key:r.key,label:r.label}]:[]})}parseUploadFileInput(e){const o=e.trim();if(!o)throw new a("`--file` \u4E0D\u80FD\u4E3A\u7A7A\u3002");const t=o.indexOf("=");if(t<=0)return{path:o};const i=o.slice(0,t).trim(),d=o.slice(t+1).trim();if(!i||!d)throw new a("\u591A\u4E0A\u4F20\u6A21\u5757\u8BF7\u4F7F\u7528 `--file key=path`\u3002");return{key:i,path:d}}async resolveModule(e,o,t){const i=e?.trim(),d=o.route?.trim(),n=o.uuid?.trim(),l=await ne(o.toolProductUuid);if(!i){if(!o.interactive)throw new a("\u8BF7\u4F20\u5165 `module_id`\uFF0C\u6216\u4F7F\u7528 `--interactive --file <xlsx>` \u5148\u4ECE\u83DC\u5355\u9009\u62E9\u5DE5\u5177\u3002");const u=await W(this.sortTopLevelMenus(await ce(t,l)));return{moduleId:u.code,route:d??u.route,toolProductUuid:l,uuid:n??u.uuid}}if(d&&n)return{moduleId:i,route:d,toolProductUuid:l,uuid:n};const r=o.menuUuid?.trim();if(r&&l){const u=await se(t,r,l),s=d??this.requireMenuRoute(u),c=u.code?.trim();if(c&&c!==i)throw new a(`\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:n??r}}if(l){const u=await me(t,l,i);return{moduleId:i,route:d??u.route,toolProductUuid:l,uuid:n??u.uuid}}if(!n)throw new a("\u901A\u7528\u6A21\u5F0F\u9700\u8981\u4F20\u5165 `--uuid`\uFF0C\u6216\u4F7F\u7528\u9ED8\u8BA4/\u663E\u5F0F `toolProductUuid` \u81EA\u52A8\u89E3\u6790\u3002");if(!d)throw new a("\u901A\u7528\u6A21\u5F0F\u9700\u8981\u4F20\u5165 `--route`\uFF0C\u6216\u4F7F\u7528\u9ED8\u8BA4/\u663E\u5F0F `toolProductUuid` \u81EA\u52A8\u89E3\u6790\u3002");return{moduleId:i,route:d,toolProductUuid:l,uuid:n}}sortTopLevelMenus(e){const o=["\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(o.map((i,d)=>[i,d]));return[...e].sort((i,d)=>{const n=t.get(i.title?.trim()??"")??Number.MAX_SAFE_INTEGER,l=t.get(d.title?.trim()??"")??Number.MAX_SAFE_INTEGER;return n-l})}requireMenuRoute(e){const o=e.route;if(typeof o!="string"||!o.trim())throw new a("\u83DC\u5355\u672A\u8FD4\u56DE\u53EF\u7528 route\uFF0C\u8BF7\u6539\u7528 `--route` \u663E\u5F0F\u6307\u5B9A\u3002");return o.trim()}}class C extends fe{static description="Run a Xiantao bioinformatics tool";static args={tool:S.string({description:"Tool id; optional with --interactive to choose from menus"}),file:S.string({description:"Path to the local xlsx file; optional with --demo or --interactive"})};static flags={...B,...E,...ie,demo:h.boolean({default:!1,description:"Prefer the module default remote input returned by fetch-all instead of uploading a local file"}),file:h.string({description:"Path to the local xlsx file; repeat or use KEY=PATH for named upload fields",multiple:!0}),download:h.string({description:"Download the generated file or preferred analysis result to this local path after submission"}),downloadItem:h.integer({description:"Select a download item by its 1-based index when --download matches multiple results"}),downloadLabel:h.string({description:"Select a download item by its label when --download matches multiple results"}),interactive:h.boolean({default:!1,description:"Prompt for dynamic args before submitting the module"}),menuUuid:h.string({description:"Tool menu UUID from /products/apply/:toolProductUuid/analyse/:uuid"}),route:h.string({description:"Tool route like app1.violin_flat in generic mode"}),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 to auto-resolve module UUID and route in generic mode; defaults to the main Xiantao product UUID"}),uuid:h.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:e,flags:o}=await this.parse(C);if(o.interactive&&o.json)throw new a("`--interactive` \u4E0D\u80FD\u4E0E `--json` \u540C\u65F6\u4F7F\u7528\u3002");const t=this.resolveToolFileInputs(e.file,o.file),i=await this.executeToolRun(e.tool,t,o);this.print(o,i.data,i.text,{profile:i.data.agent})}}export{fe as ToolRunCommandBase,C as default};
8
+ `)}validateDownloadFlags(e){if(e.downloadItem!==void 0&&e.downloadLabel)throw new a("`--downloadItem` \u4E0E `--downloadLabel` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");if((e.downloadItem!==void 0||e.downloadLabel)&&!e.download)throw new a("`--downloadItem` \u548C `--downloadLabel` \u4EC5\u53EF\u4E0E `--download` \u4E00\u8D77\u4F7F\u7528\u3002")}toHistorySummary(e,o){const t=e.fuid?.trim();return t?{fuid:t,id:typeof e.id=="number"?e.id:null,module_id:e.module_id?.trim()||o,module_name:e.module_name?.trim()||"",name:e.name?.trim()||"",status:K(e),time:e.time?.trim()||"",type:e.type?.trim()||""}:null}buildHistoryHint(e){return e?`\u53EF\u4F7F\u7528 \`xt history download ${e.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(e,o){const t=[];for(const i of o.downloads){const d=await A(e,{item:i,moduleId:o.moduleId,uuid:o.uuid});t.push(await b(d.url,d.fileName))}return t}async downloadInteractiveResults(e,o){const t=[];return o.choice.downloadFile&&o.file&&t.push(await b(o.file)),o.choice.downloads.length>0&&t.push(...await this.downloadSelectedResults(e,{downloads:o.choice.downloads,moduleId:o.moduleId,uuid:o.uuid})),t}isRetryableAsyncDownloadError(e){return e.message.includes("\u4E0B\u8F7D\u5931\u8D25")||e.message.includes("\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5")}async sleep(e){await new Promise(o=>setTimeout(o,e))}async resolveInputMode(e,o){if(o.demo)return this.hasDemoInput(e)?{mode:"demo"}:this.hasRecordInput(e)?{mode:"record"}:this.hasCloudInput(e)?{mode:"cloud"}:{mode:"demo"};if(o.fileInputs.length>0)return{fileInputs:o.fileInputs,mode:"upload"};if(o.cloudRequested)return{mode:"cloud"};if(this.hasRecordInput(e))return{mode:"record"};if(this.hasCloudInput(e))return{mode:"cloud"};if(!o.interactive)return{mode:"upload"};if(!this.hasDemoInput(e))return{fileInputs:[await U()],mode:"upload"};const t=await Y();return t==="demo"?{mode:t}:{fileInputs:[await U()],mode:t}}resolveDemoInput(e,o){const t=e.id?.duid?.trim();if(!t)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE demo duid\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);const i=$(e.args_data??[]);if(!i.length||i.some(d=>!d.defaultUpload))throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE\u53EF\u7528\u7684 demo \u6587\u4EF6\u4FE1\u606F\uFF0C\u65E0\u6CD5\u4F7F\u7528 \`--demo\`\u3002`);return{duid: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(e){if(!e.id?.duid?.trim())return!1;const t=$(e.args_data??[]);return t.length>0&&t.every(i=>!!i.defaultUpload)}async resolveCloudInput(e,o,t,i,d){const n=D(e.args_data??[]),l=o.cloudKey?.trim()||n?.key||"";if(!l)throw new a(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u4E91\u7AEF\u6570\u636E\u53C2\u6570\uFF0C\u8BF7\u663E\u5F0F\u4F20\u5165 \`--cloudKey\`.`);const r=await this.resolveCloudRecord(i,o,{argsKey:l,defaultRecord:n?.record,moduleId:t,uuid:d});if(!r)throw new a(`\u6A21\u5757 ${t} \u672A\u8FD4\u56DE\u9ED8\u8BA4\u4E91\u7AEF\u6570\u636E\uFF0C\u8BF7\u4F20\u5165 \`--cloudRecordJson\` \u6216 \`--cloudRecordFile\`.`);return{duid:e.id?.duid?.trim()||"cloud",input:{kind:"cloud",cloud:{key:l,label:n?.label??"",record:this.normalizeCloudRecord(r)}},schema:[]}}resolveRecordInput(e,o){const t=e.id?.duid?.trim();if(!t)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE record duid\uFF0C\u65E0\u6CD5\u4F7F\u7528\u5386\u53F2\u8BB0\u5F55\u8F93\u5165\u3002`);const i=H(e.args_data??[]);if(!i)throw new a(`\u6A21\u5757 ${o} \u672A\u8FD4\u56DE\u53EF\u7528\u7684\u6570\u636E\u8BB0\u5F55\uFF0C\u65E0\u6CD5\u76F4\u63A5\u8FD0\u884C\u3002`);return{duid: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(e){return!!(e.id?.duid?.trim()&&H(e.args_data??[]))}hasCloudInput(e){return!!D(e.args_data??[])}async uploadAndVerify(e,o,t,i){const d=await this.uploadFiles(e,o,t.argsData??[],t.moduleId),n=await le(i,{argsMain:t.argsMain,moduleId:t.moduleId,uploads:d,uuid:t.uuid});return{duid:n.duid,input:{kind:"upload",uploads:d},schema:n.schema}}summarizePreparedInput(e){if(e.kind==="cloud")return{file_name:null,file_oss:null,file_size:null,input_cloud:this.summarizeCloudInput(e.cloud),input_record:null,input_uploads:null};if(e.kind==="record")return{file_name:null,file_oss:null,file_size:null,input_cloud:null,input_record:{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},input_uploads:null};const o=e.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=o.length===1?o[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:o}}summarizeCloudInput(e){return{data_filter:this.readCloudOptionValue(e.record.data_filter),data_id:typeof e.record.data_id=="string"?e.record.data_id.trim():"",data_process:this.readCloudOptionValue(e.record.data_process),key:e.key,label:e.label,record:structuredClone(e.record),record_label:typeof e.record.label=="string"?e.record.label.trim():""}}readCloudOptionValue(e){return M(e)&&(typeof e.value=="string"?e.value.trim():"")||null}async resolveCloudRecord(e,o,t){return o.cloudRecordJson?this.parseCloudRecord(o.cloudRecordJson,"--cloudRecordJson"):o.cloudRecordFile?this.parseCloudRecord(await L(o.cloudRecordFile,"utf8"),"--cloudRecordFile"):o.cloudFilter?.trim()||o.cloudDataId?.trim()||typeof o.cloudIndex=="number"?this.resolveCloudRecordByQuery(e,o,t):t.defaultRecord}parseCloudRecord(e,o){let t;try{t=JSON.parse(e)}catch{throw new a(`${o} \u4E0D\u662F\u5408\u6CD5 JSON\u3002`)}if(!M(t))throw new a(`${o} \u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002`);return t}normalizeCloudRecord(e){const o={};for(const[t,i]of Object.entries(e))i!==void 0&&(o[t]=structuredClone(i));return(typeof o.type!="string"||!o.type.trim())&&(o.type="cloud"),o}validateInputSourceFlags(e,o){const t=!!(o.cloudRecordJson||o.cloudRecordFile),i=!!(o.cloudDataId?.trim()||o.cloudFilter?.trim()||typeof o.cloudIndex=="number"),d=t||i;if(o.cloudRecordJson&&o.cloudRecordFile)throw new a("`--cloudRecordJson` \u4E0E `--cloudRecordFile` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\u3002");if(t&&i)throw new a("\u663E\u5F0F\u4E91\u7AEF\u8BB0\u5F55\u53C2\u6570\u4E0D\u80FD\u4E0E `--cloudFilter` / `--cloudDataId` / `--cloudIndex` \u540C\u65F6\u4F7F\u7528\u3002");if(o.demo&&d)throw new a("`--demo` \u4E0D\u80FD\u4E0E\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u53C2\u6570\u540C\u65F6\u4F7F\u7528\u3002");if(e.length>0&&d)throw new a("`--file` \u4E0D\u80FD\u4E0E\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u53C2\u6570\u540C\u65F6\u4F7F\u7528\u3002")}async resolveCloudRecordByQuery(e,o,t){const i=await this.fetchCloudRecords(e,{argsKey:t.argsKey,filter:o.cloudFilter?.trim(),moduleId:t.moduleId,selectedRecord:t.defaultRecord,uuid:t.uuid});if(i.length===0){const n=o.cloudFilter?.trim();throw n?new a(`\u672A\u627E\u5230\u5339\u914D\u4E91\u7AEF\u6570\u636E: ${n}`):new a("\u5F53\u524D\u6A21\u5757\u6CA1\u6709\u53EF\u9009\u7684\u4E91\u7AEF\u6570\u636E\u8BB0\u5F55\u3002")}const d=o.cloudDataId?.trim();if(d){const n=i.find(l=>(typeof l.data_id=="string"?l.data_id.trim():"")===d);if(!n)throw new a(`\u672A\u627E\u5230 data_id=${d} \u5BF9\u5E94\u7684\u4E91\u7AEF\u6570\u636E\u3002`);return n}if(typeof o.cloudIndex=="number"){const n=i[o.cloudIndex];if(!n)throw new a(`\u4E91\u7AEF\u6570\u636E\u7D22\u5F15\u8D85\u51FA\u8303\u56F4: ${o.cloudIndex}\uFF0C\u5F53\u524D\u5171\u6709 ${i.length} \u6761\u3002`);return n}if(i.length===1)return i[0];if(o.interactive)return this.normalizeCloudRecord(await G(i));throw new B(this.buildCloudSelectionHint(i,o.cloudFilter?.trim()),this.buildCloudSelectionData(i,o.cloudFilter?.trim()))}async fetchCloudRecords(e,o){const t=await z(e,{argsKey:o.argsKey,currentPage:1,filter:o.filter,moduleId:o.moduleId,selectedRecord:o.selectedRecord,uuid:o.uuid}),i=t.records.map(d=>this.normalizeCloudRecord(d));for(let d=t.currentPage+1;d<=t.lastPage;d+=1){const n=await z(e,{argsKey:o.argsKey,currentPage:d,filter:o.filter,moduleId:o.moduleId,selectedRecord:o.selectedRecord,uuid:o.uuid});i.push(...n.records.map(l=>this.normalizeCloudRecord(l)))}return i}buildCloudSelectionHint(e,o){const t=[o?`\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E: ${o}`:"\u5339\u914D\u5230\u591A\u4E2A\u4E91\u7AEF\u6570\u636E","\u8BF7\u4F7F\u7528 `--cloudIndex` \u6216 `--cloudDataId` \u6307\u5B9A\u5176\u4E2D\u4E00\u6761\uFF1A"];return e.forEach((i,d)=>{const n=typeof i.data_id=="string"?i.data_id.trim():"",l=typeof i.label=="string"?i.label.trim():"";t.push(` [${d}] ${l||n}`)}),t.join(`
9
+ `)}buildCloudSelectionData(e,o){return{choices:e.map((t,i)=>{const d=typeof t.data_id=="string"?t.data_id.trim():"",n=typeof t.label=="string"?t.label.trim():"";return{data_id:d,index:i,label:n||d}}),filter:o??"",selection_type:"cloud_record"}}async uploadFiles(e,o,t,i){const d=$(t??[]),n=this.resolveUploadInputs(o,d,i),l=await S(e),r=[];for(const u of n){const s=await ee(l,u.filePath);r.push({key:u.key,label:u.label,upload:s})}return r}resolveUploadInputs(e,o,t){if(!o.length)throw new a(`\u6A21\u5757 ${t} \u672A\u68C0\u6D4B\u5230\u53EF\u4E0A\u4F20\u8F93\u5165\uFF0C\u4E0D\u80FD\u4F7F\u7528 \`--file\`\u3002`);if(!e.length)throw o.length===1?new a("\u901A\u7528\u6A21\u5F0F\u8BF7\u4F20\u5165 FILE / `--file <xlsx>`\uFF0C\u6216\u6539\u7528 `--demo`\u3002"):new a(`\u6A21\u5757 ${t} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(r=>r.key).join(", ")}`);const[i]=o;if(o.length===1&&e.length===1){const r=this.parseUploadFileInput(e[0]);if(r.key&&r.key!==i.key)throw new a(`\u6A21\u5757 ${t} \u4EC5\u652F\u6301\u4E0A\u4F20\u5B57\u6BB5 ${i.key}\uFF0C\u6536\u5230 ${r.key}\u3002`);return[{filePath:r.path,key:i.key,label:i.label}]}const d=new Map(o.map(r=>[r.key,r])),n=new Map;for(const r of e){const u=this.parseUploadFileInput(r);if(!u.key){if(o.length===1){if(n.has(i.key))throw new a(`\u6A21\u5757 ${t} \u4EC5\u9700\u8981 1 \u4E2A\u4E0A\u4F20\u6587\u4EF6\uFF0C\u6536\u5230\u91CD\u590D\u8F93\u5165\u3002`);n.set(i.key,u.path);continue}throw new a(`\u6A21\u5757 ${t} \u9700\u8981\u591A\u4E2A\u4E0A\u4F20\u5B57\u6BB5\uFF0C\u8BF7\u4F7F\u7528 \`--file key=path\`\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(c=>c.key).join(", ")}`)}const s=d.get(u.key);if(!s)throw new a(`\u6A21\u5757 ${t} \u4E0D\u5B58\u5728\u4E0A\u4F20\u5B57\u6BB5 ${u.key}\u3002\u53EF\u7528\u5B57\u6BB5: ${o.map(c=>c.key).join(", ")}`);if(n.has(s.key))throw new a(`\u4E0A\u4F20\u5B57\u6BB5 ${s.key} \u91CD\u590D\u4F20\u5165\u3002`);n.set(s.key,u.path)}const l=o.filter(r=>r.required&&!n.has(r.key));if(l.length>0)throw new a(`\u6A21\u5757 ${t} \u7F3A\u5C11\u5FC5\u586B\u4E0A\u4F20\u5B57\u6BB5: ${l.map(r=>r.key).join(", ")}`);return o.flatMap(r=>{const u=n.get(r.key);return u?[{filePath:u,key:r.key,label:r.label}]:[]})}parseUploadFileInput(e){const o=e.trim();if(!o)throw new a("`--file` \u4E0D\u80FD\u4E3A\u7A7A\u3002");const t=o.indexOf("=");if(t<=0)return{path:o};const i=o.slice(0,t).trim(),d=o.slice(t+1).trim();if(!i||!d)throw new a("\u591A\u4E0A\u4F20\u6A21\u5757\u8BF7\u4F7F\u7528 `--file key=path`\u3002");return{key:i,path:d}}async resolveModule(e,o,t){const i=e?.trim(),d=o.route?.trim(),n=o.uuid?.trim(),l=await de(o.toolProductUuid);if(!i){if(!o.interactive)throw new a("\u8BF7\u4F20\u5165 `module_id`\uFF0C\u6216\u4F7F\u7528 `--interactive --file <xlsx>` \u5148\u4ECE\u83DC\u5355\u9009\u62E9\u5DE5\u5177\u3002");const u=await W(this.sortTopLevelMenus(await se(t,l)));return{moduleId:u.code,route:d??u.route,toolProductUuid:l,uuid:n??u.uuid}}if(d&&n)return{moduleId:i,route:d,toolProductUuid:l,uuid:n};const r=o.menuUuid?.trim();if(r&&l){const u=await ue(t,r,l),s=d??this.requireMenuRoute(u),c=u.code?.trim();if(c&&c!==i)throw new a(`\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:n??r}}if(l){const u=await ce(t,l,i);return{moduleId:i,route:d??u.route,toolProductUuid:l,uuid:n??u.uuid}}if(!n)throw new a("\u901A\u7528\u6A21\u5F0F\u9700\u8981\u4F20\u5165 `--uuid`\uFF0C\u6216\u4F7F\u7528\u9ED8\u8BA4/\u663E\u5F0F `toolProductUuid` \u81EA\u52A8\u89E3\u6790\u3002");if(!d)throw new a("\u901A\u7528\u6A21\u5F0F\u9700\u8981\u4F20\u5165 `--route`\uFF0C\u6216\u4F7F\u7528\u9ED8\u8BA4/\u663E\u5F0F `toolProductUuid` \u81EA\u52A8\u89E3\u6790\u3002");return{moduleId:i,route:d,toolProductUuid:l,uuid:n}}sortTopLevelMenus(e){const o=["\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(o.map((i,d)=>[i,d]));return[...e].sort((i,d)=>{const n=t.get(i.title?.trim()??"")??Number.MAX_SAFE_INTEGER,l=t.get(d.title?.trim()??"")??Number.MAX_SAFE_INTEGER;return n-l})}requireMenuRoute(e){const o=e.route;if(typeof o!="string"||!o.trim())throw new a("\u83DC\u5355\u672A\u8FD4\u56DE\u53EF\u7528 route\uFF0C\u8BF7\u6539\u7528 `--route` \u663E\u5F0F\u6307\u5B9A\u3002");return o.trim()}}class C extends he{static description="Run a Xiantao bioinformatics tool";static args={tool:x.string({description:"Tool id; optional with --interactive to choose from menus"}),file:x.string({description:"Path to the local xlsx file; optional with --demo or --interactive"})};static flags={...O,...E,...te,demo:h.boolean({default:!1,description:"Prefer the module default remote input returned by fetch-all instead of uploading a local file"}),file:h.string({description:"Path to the local xlsx file; repeat or use KEY=PATH for named upload fields",multiple:!0}),download:h.string({description:"Download the generated file or preferred analysis result to this local path after submission"}),downloadItem:h.integer({description:"Select a download item by its 1-based index when --download matches multiple results"}),downloadLabel:h.string({description:"Select a download item by its label when --download matches multiple results"}),interactive:h.boolean({default:!1,description:"Prompt for dynamic args before submitting the module"}),menuUuid:h.string({description:"Tool menu UUID from /products/apply/:toolProductUuid/analyse/:uuid"}),route:h.string({description:"Tool route like app1.violin_flat in generic mode"}),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 to auto-resolve module UUID and route in generic mode; defaults to the main Xiantao product UUID"}),uuid:h.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:e,flags:o}=await this.parse(C);if(o.interactive&&o.json)throw new a("`--interactive` \u4E0D\u80FD\u4E0E `--json` \u540C\u65F6\u4F7F\u7528\u3002");const t=this.resolveToolFileInputs(e.file,o.file),i=await this.executeToolRun(e.tool,t,o);this.print(o,i.data,i.text,{profile:i.data.agent})}}export{he as ToolRunCommandBase,C as default};
@@ -1,3 +1,3 @@
1
- import{Args as $,Flags as h}from"@oclif/core";import{XtzCommand as b}from"../../base-command.js";import{getAuthContext as y}from"../../lib/auth.js";import{globalFlags as 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
+ 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 F,buildArgsSpecificFromSchema as v}from"../../lib/plot-schema.js";import{resolveXiantaoToolProductUuid as x}from"../../lib/storage.js";import{findDefaultXiantaoCloudInput as B,findDefaultXiantaoRecord as A,listXiantaoUploadFields as C}from"../../lib/tool-inputs.js";import{fetchAllPlotArgs as S,resolveToolMenuByCode as I}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:o}=await this.parse(p),a=await this.getProfile(o.profile),n=await y(a,o.token),d=await x(o.toolProductUuid),u=await I(n,d,e.tool),i=await S(n,{moduleId:e.tool,uuid:u.uuid}),s=i.args_main??[],l=i.args_specific??[],c=this.summarizeInputs(i.args_data??[],i.id?.duid??""),r=this.summarizeSchema(s),t={agent:a,args_data:i.args_data??[],args_main:s,args_main_defaults:F(s),args_specific:l,args_specific_defaults:v(l),duid:i.id?.duid??"",inputs:c,module_id:e.tool,notice:i.notice??"",path:u.path,route:u.route,summary:r,title:u.title,tool_product_uuid:d,uuid:u.uuid};this.print(o,t,this.formatInspectText(t.module_id,t.title,t.path,t.route,t.uuid,t.notice,c,r,l,s),{profile:a})}formatInspectText(e,o,a,n,d,u,i,s,l,c){const r=[`${e} ${o}`,`path: ${a||"-"}`,`route: ${n}`,`uuid: ${d}`];u&&r.push(`notice: ${u}`),r.push("input:"),r.push(` cloud: ${i.cloud_available?this.formatCloudSummary(i.cloud_default):"unavailable"}`),r.push(` upload: ${i.upload_available?`${i.upload_fields.length} fields`:"not detected"}`);for(const t of i.upload_fields){const m=[t.label&&t.label!==t.key?t.label:void 0,t.required?"required":void 0,t.demo_upload?this.formatDemoSummary(t.demo_upload):"no demo default"].filter(Boolean);r.push(` - ${t.key}${m.length>0?` - ${m.join(", ")}`:""}`)}if(r.push(` demo: ${i.demo_available?"available":"unavailable"}`),r.push(` record: ${i.record_available?this.formatRecordSummary(i.record_default):"unavailable"}`),l.length>0){r.push(`args_specific: ${l.length} fields`);for(const t of l){const m=[this.formatFieldLabel(t),t.type?.trim(),t.required?"required":void 0,t.multiple?"multiple":void 0,this.formatDefaultValue(t.default_value)].filter(Boolean);r.push(` ${t.key}${m.length>0?` - ${m.join(", ")}`:""}`)}}else r.push("args_specific: none");if(c.length===0)return r.push("args_main: none"),r.join(`
2
+ `);r.push(`args_main: ${s.section_count} sections, ${s.field_count} fields, ${s.required_field_count} required`);for(const t of c){const m=t.form??[],g=m.filter(f=>f.required).length;r.push(`- ${t.label?.trim()||t.key} (${t.key}) - ${m.length} fields, ${g} required`);for(const f of t.form??[]){const _=[this.formatFieldLabel(f),f.type?.trim(),f.required?"required":void 0,f.multiple?"multiple":void 0,f.options?.length?`options:${f.options.length}`:void 0,this.formatDefaultValue(f.default_value)].filter(Boolean);r.push(` ${f.key}${_.length>0?` - ${_.join(", ")}`:""}`)}}return r.join(`
3
+ `)}summarizeInputs(e,o){const a=C(e),n=A(e),d=B(e),u=!!(o.trim()&&a.length>0&&a.every(l=>!!l.defaultUpload)),i=!!(o.trim()&&n),s=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:!!d,cloud_default:d?this.toCloudSummary(d.key,d.label,d.record):null,demo_available:u,record_available:i,record_default:s,upload_available:a.length>0,upload_fields:a.map(l=>({demo_upload:l.defaultUpload?{file_name:l.defaultUpload.fileName,file_oss:l.defaultUpload.fileOss,file_size:l.defaultUpload.fileSize,key:l.key,label:l.label}:null,key:l.key,label:l.label,required:l.required}))}}summarizeSchema(e){const o=e.flatMap(a=>a.form??[]);return{field_count:o.length,required_field_count:o.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 o=[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}${o.length>0?` (${o.join(", ")})`:""}`}toCloudSummary(e,o,a){const n=this.readCloudOptionValue(a.data_filter),d=this.readCloudOptionValue(a.data_process);return{data_filter:n,data_id:typeof a.data_id=="string"?a.data_id.trim():"",data_process:d,key:e,label:o,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`}formatFieldLabel(e){if(typeof e.label!="string")return;const o=e.label.trim();return o&&o!==e.key?o:void 0}formatDefaultValue(e){if(!(e==null||e===""))return typeof e=="string"?`default:${e}`:typeof e=="number"||typeof e=="boolean"?`default:${String(e)}`:Array.isArray(e)?e.length>0?`default:${e.length} items`:void 0:"default:object"}}export{p as default};
package/dist/lib/auth.js CHANGED
@@ -1 +1 @@
1
- import{AUTH_URL_ENDPOINT as k,CHECK_TOKEN_ENDPOINT as u}from"./constants.js";import{XtzError as a}from"./errors.js";import{openUrl as h}from"./open-url.js";import{requestJson as l}from"./http.js";import{loadToken as p,requireToken as w,saveToken as f}from"./storage.js";async function d(t){const e=await p(t),o=await l(k,{headers:i(e)},{agent:t}),r=new URL(o.data.link_url);return r.searchParams.set("source",t),{linkUrl:r.toString(),tokenKey:o.data.token_key}}async function _(t,e=!0){const{linkUrl:o,tokenKey:r}=await d(t),n=await f(t,r);return{browserOpened:e?await h(o):!1,linkUrl:o,token:r,tokenPath:n}}async function g(t,e){const o=e?.trim()||await w(t);return{agent:t,token:o}}async function N(t,e){const o=e??await w(t),r=new URL(u);return r.searchParams.set("token_key",o),(await l(r.toString(),{headers:i(o)},{agent:t})).data}async function O(t,e={}){const o=e.timeoutMs??12e4,r=e.intervalMs??1500,n=Date.now()+o;let s="";for(;Date.now()<n;){const c=await y(t);if(c.success)return;s=c.message?.trim()||s,await new Promise(m=>setTimeout(m,r))}throw new a(s?`\u7B49\u5F85\u6388\u6743\u5B8C\u6210\u8D85\u65F6: ${s}`:"\u7B49\u5F85\u6388\u6743\u5B8C\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C `xt login`\u3002")}async function y(t){const e=new URL(u);e.searchParams.set("token_key",t);let o;try{o=await fetch(e.toString(),{headers:i(t)})}catch{throw new a("\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}const r=await o.text();try{const n=JSON.parse(r);return{message:n.message,success:o.ok&&n.success!==!1}}catch{throw new a("\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002")}}function i(t){const e={platform:"pc",source:"PC"};return t?.trim()&&(e.Authorization=`Bearer ${t.trim()}`),e}export{N as checkToken,d as fetchAuthLink,g as getAuthContext,_ as loginAuth,O as waitForAuthorizedToken};
1
+ import{chromium as f}from"playwright";import{DEFAULT_XIANTAO_TOOL_PRODUCT_UUID as p}from"./constants.js";import{resolveXiantaoBaseUrl as k,resolveXiantaoLoginUrl as T,resolveXiantaoToolMenusEndpoint as g}from"./config.js";import{XtzError as d}from"./errors.js";import{requestJson as C}from"./http.js";import{getTokenPath as x,requireToken as m,saveToken as A}from"./storage.js";const y=["chrome","msedge"];async function U(e){return{browserOpened:!1,linkUrl:await T(),tokenPath:x(e)}}async function F(e,n=!0){const t=await U(e);return n?await B(e,t):t}async function B(e,n,t={}){let o,r;try{o=await _(),r=await o.newContext(),await(await r.newPage()).goto(n.linkUrl,{timeout:60*1e3,waitUntil:"domcontentloaded"});const s={...n,browserOpened:!0};t.onBrowserOpened?.(s);const c=await E(r,{timeoutMs:t.timeoutMs}),h=await A(e,c),l={...s,token:c,tokenPath:h};return t.onTokenCaptured?.(l),await r.close(),l}catch(i){throw w(i)?new d("\u672A\u627E\u5230\u53EF\u7528\u6D4F\u89C8\u5668\uFF0C\u8BF7\u5B89\u88C5 Google Chrome\uFF0C\u6216\u8FD0\u884C `npx playwright install chromium` \u540E\u91CD\u8BD5\u3002"):i}finally{await r?.close().catch(()=>{}),await o?.close().catch(()=>{})}}async function H(e,n){const t=a(n?.trim()||await m(e));return{agent:e,token:t}}function q(e){const n=e?a(e):"";if(n)return n.length<=18?n:`${n.slice(0,8)}...${n.slice(-6)}`}async function G(e,n){const t=a(n??await m(e)),o=new URL(await g());return o.searchParams.set("f",X({is_all:1,tool_product_uuid:p})),(await C(o.toString(),{headers:await z(t),method:"GET"},{agent:e})).data}async function E(e,n={}){const t=n.timeoutMs??3e5,o=n.intervalMs??1500,r=Date.now()+t;for(;Date.now()<r;){const i=L(await e.cookies());if(i)return i;await new Promise(s=>setTimeout(s,o))}throw new d("\u7B49\u5F85\u7F51\u9875\u767B\u5F55\u5B8C\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C `xt login`\u3002")}function L(e){const n=e.filter(o=>o.name==="token").map(o=>u(o.value,!1)).find(Boolean);if(n)return n;const t=e.filter(o=>M(o.name)).map(o=>u(o.value)).find(Boolean);return t||e.map(o=>u(o.value)).find(Boolean)}function M(e){const n=e.toLowerCase();return n.includes("token")&&!n.includes("csrf")&&!n.includes("xsrf")}function u(e,n=!0){const t=a(P(e).replace(/^"|"$/g,""));if(t&&v(t))return!n||O(t)?t:void 0}function a(e){return e.trim().replace(/^Bearer\s+/i,"")}function v(e){return e.length>=20&&!["deleted","false","null","true","undefined"].includes(e.toLowerCase())}function O(e){return/^\d+\|[A-Za-z0-9]{20,}$/.test(e)}function P(e){try{return decodeURIComponent(e)}catch{return e}}function w(e){return e instanceof Error?e.message.includes("Executable doesn't exist")||e.message.includes("is not found"):!1}async function _(){for(const e of y)try{return await f.launch({channel:e,headless:!1})}catch(n){if(!w(n))throw n}return await f.launch({headless:!1})}function b(e){const n={platform:"pc",source:"PC"};return e?.trim()&&(n.Authorization=`Bearer ${a(e)}`),n}async function z(e){const n=await k();return{...b(e),origin:n,referer:n}}function X(e){return encodeURIComponent(JSON.stringify(e))}export{G as checkToken,B as completeLoginAuth,q as formatTokenPreview,H as getAuthContext,F as loginAuth,U as startLoginAuth};
@@ -0,0 +1,2 @@
1
+ import{mkdir as d,readFile as v,writeFile as y}from"node:fs/promises";import A from"node:os";import l from"node:path";import{DEFAULT_XIANTAO_BASE_URL as U,DEFAULT_XIANTAO_LOGIN_URL as L,XIANTAO_CONFIG_PATH as N}from"./constants.js";import{XtzError as r}from"./errors.js";import{isJsonObject as X}from"./json.js";const s=["base-url","login-url"];function c(){return l.join(A.homedir(),N)}async function I(t,n){const o=g(t),e=w(o,n),i=c(),a=await p(i);return a[o]=e,await d(l.dirname(i),{recursive:!0}),await y(i,`${JSON.stringify(a,null,2)}
2
+ `,"utf8"),{key:o,path:i,value:e}}async function f(t){const n=g(t),o=c(),e=_(n);if(e)return{key:n,path:o,source:"environment",value:e};const a=(await p(o))[n]?.trim();return a?{key:n,path:o,source:"config",value:w(n,a)}:{key:n,path:o,source:"default",value:b(n)}}async function u(){return(await f("base-url")).value}async function V(){return(await f("login-url")).value}async function R(){return`${await u()}/api/v1/xiantaozi/bio-api`}async function F(){return`${await u()}/api/v1/xiantaozi/tool/menus`}async function B(){return`${await u()}/api/v1/agent/upload/config?type=bio&oss_type=bio`}async function p(t){try{const n=await v(t,"utf8"),o=JSON.parse(n);if(!X(o))throw new r(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u4E0D\u6B63\u786E: ${t}`);const e=o["base-url"];if(e!==void 0&&typeof e!="string")throw new r(`\u914D\u7F6E\u9879 base-url \u5FC5\u987B\u662F\u5B57\u7B26\u4E32: ${t}`);const i=o["login-url"];if(i!==void 0&&typeof i!="string")throw new r(`\u914D\u7F6E\u9879 login-url \u5FC5\u987B\u662F\u5B57\u7B26\u4E32: ${t}`);return o}catch(n){if(E(n)&&n.code==="ENOENT")return{};throw n}}function g(t){const n=t.trim().toLowerCase();if(s.includes(n))return n;throw new r(`\u4E0D\u652F\u6301\u7684\u914D\u7F6E\u9879 ${t}\uFF0C\u5F53\u524D\u652F\u6301: ${s.join(", ")}`)}function w(t,n){const o=n.trim();if(!o)throw new r(`\u914D\u7F6E\u9879 ${t} \u4E0D\u80FD\u4E3A\u7A7A`);return t==="base-url"?h(o):t==="login-url"?m(o):o}function _(t){if(t==="base-url"){const n=process.env.XIANTAO_BASE_URL?.trim();return n?h(n):void 0}if(t==="login-url"){const n=process.env.XIANTAO_LOGIN_URL?.trim();return n?m(n):void 0}}function b(t){if(t==="base-url")return U;if(t==="login-url")return L;throw new r(`\u4E0D\u652F\u6301\u7684\u914D\u7F6E\u9879 ${t}`)}function h(t){let n;try{n=new URL(t)}catch{throw new r("base-url \u5FC5\u987B\u662F\u6709\u6548\u7684\u7EDD\u5BF9 URL\uFF0C\u4F8B\u5982 https://vip.helixlife.cn")}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new r("base-url \u53EA\u652F\u6301 http \u6216 https");return t.replace(/\/+$/,"")}function m(t){let n;try{n=new URL(t)}catch{throw new r("login-url \u5FC5\u987B\u662F\u6709\u6548\u7684\u7EDD\u5BF9 URL\uFF0C\u4F8B\u5982 https://vip.helixlife.cn/")}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new r("login-url \u53EA\u652F\u6301 http \u6216 https");return t}function E(t){return t instanceof Error&&"code"in t}export{s as XIANTAO_CONFIG_KEYS,c as getXiantaoConfigPath,B as resolveUploadConfigEndpoint,u as resolveXiantaoBaseUrl,R as resolveXiantaoBioApiEndpoint,f as resolveXiantaoConfigValue,V as resolveXiantaoLoginUrl,F as resolveXiantaoToolMenusEndpoint,I as setXiantaoConfigValue};
@@ -1 +1 @@
1
- const t="opencode",e=".config/xtz/config.json",_=".config/xtz/update-check.json",o=(process.env.XIANTAO_BASE_URL?.trim()||"https://agent.helixlife.cn").replace(/\/+$/,""),n=`${o}/api/v1/agent/skills/auth-url`,p=`${o}/api/v1/agent/bio-api`,c=`${o}/api/v1/agent/tool/menus`,T="c0b6febb-52dd-4525-970a-61bbe9e263ff",s="2d491694-8c8d-11ee-9409-00163e118c99",A=`${o}/api/v1/agent/skills/check-token`,O=`${o}/api/v1/agent/upload/config?type=bio&oss_type=bio`,N=`${o}/api/v1/agent/bio-api`;export{n as AUTH_URL_ENDPOINT,N as BIO_API_ENDPOINT,A as CHECK_TOKEN_ENDPOINT,t as DEFAULT_AGENT,T as DEFAULT_XIANTAO_TOOL_PRODUCT_UUID,O as UPLOAD_CONFIG_ENDPOINT,o as XIANTAO_BASE_URL,p as XIANTAO_BIO_API_ENDPOINT,s as XIANTAO_HISTORY_UUID,c as XIANTAO_TOOL_MENUS_ENDPOINT,e as XTZ_CONFIG_PATH,_ as XTZ_UPDATE_CHECK_PATH};
1
+ const A="opencode",e=".config/xtz/config.json",t=".config/xtz/update-check.json",c=".config/xiantao/config.json",_="https://api.helixlife.cn"?.trim(),o="https://vip.helixlife.cn"?.trim(),T=(_||"https://vip.helixlife.cn").replace(/\/+$/,""),n=o||"https://vip.helixlife.cn",I="c0b6febb-52dd-4525-970a-61bbe9e263ff",U="2d491694-8c8d-11ee-9409-00163e118c99";export{A as DEFAULT_AGENT,T as DEFAULT_XIANTAO_BASE_URL,n as DEFAULT_XIANTAO_LOGIN_URL,I as DEFAULT_XIANTAO_TOOL_PRODUCT_UUID,c as XIANTAO_CONFIG_PATH,U as XIANTAO_HISTORY_UUID,e as XTZ_CONFIG_PATH,t as XTZ_UPDATE_CHECK_PATH};
@@ -0,0 +1,3 @@
1
+ const p=["DEBUG_MODE","DEBUGMODE","debugmode","debug_mode"],y=new Set(["1","true","yes","on"]);function o(){return p.some(t=>y.has(process.env[t]?.trim().toLowerCase()??""))}function D(t,e={}){o()&&f("request",{method:e.method?.toUpperCase()??"GET",url:t,payload:g(t,e.body)})}function U(t,e,r){o()&&f("response",{status:e.status,statusText:e.statusText,url:t,response:l(r)})}function R(t,e){o()&&f("error",{url:t,error:e instanceof Error?e.message:String(e)})}function g(t,e){if(e!=null)return h(e);const r=E(t);return Object.keys(r).length>0?r:null}function h(t){return typeof t=="string"?u(t):t instanceof URLSearchParams?d(t):t instanceof FormData?B(t):t instanceof Blob?a(t):t instanceof ArrayBuffer||ArrayBuffer.isView(t)?c(t):String(t)}function l(t){return typeof t=="string"?u(t):c(t)}function u(t){const e=t.trim();if(!e)return"";try{return JSON.parse(e)}catch{return t}}function E(t){const e={};let r;try{r=new URL(t).searchParams}catch{return e}for(const[n,m]of r)s(e,n,i(m));return e}function d(t){const e={};for(const[r,n]of t)s(e,r,i(n));return e}function i(t){try{return u(decodeURIComponent(t))}catch{return u(t)}}function B(t){const e={};for(const[r,n]of t)s(e,r,typeof n=="string"?u(n):a(n));return e}function a(t){const e=t,r={size:t.size};return t.type&&(r.type=t.type),typeof e.name=="string"&&e.name&&(r.name=e.name),r}function c(t){return`<binary ${t.byteLength} bytes>`}function s(t,e,r){const n=t[e];if(n===void 0){t[e]=r;return}if(Array.isArray(n)){n.push(r);return}t[e]=[n,r]}function f(t,e){process.stderr.write(`[xt debug] ${t}
2
+ ${JSON.stringify(e,null,2)}
3
+ `)}export{R as debugHttpError,D as debugHttpRequest,U as debugHttpResponse,o as isDebugMode};
@@ -1 +1 @@
1
- import a from"node:os";import n from"node:path";import{writeFile as m}from"node:fs/promises";import{XtzError as i}from"./errors.js";async function p(t,r){let o;try{o=await fetch(t)}catch{throw new i("\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002")}if(!o.ok)throw new i(`\u4E0B\u8F7D\u5931\u8D25 (${o.status})`);const e=r?n.resolve(r):w(t),f=Buffer.from(await o.arrayBuffer());return await m(e,f),e}function w(t){try{const r=new URL(t).pathname,o=decodeURIComponent(n.basename(r));return n.join(a.homedir(),"Downloads",o||"download.bin")}catch{return n.join(a.homedir(),"Downloads","download.bin")}}export{p as downloadToPath};
1
+ import f from"node:os";import e from"node:path";import{writeFile as d}from"node:fs/promises";import{debugHttpError as w,debugHttpRequest as p,debugHttpResponse as i,isDebugMode as c}from"./debug.js";import{XtzError as m}from"./errors.js";async function B(t,r){let o;p(t);try{o=await fetch(t)}catch(s){throw w(t,s),new m("\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002")}if(!o.ok)throw c()&&i(t,o,Buffer.from(await o.arrayBuffer())),new m(`\u4E0B\u8F7D\u5931\u8D25 (${o.status})`);const n=r?e.resolve(r):h(t),a=Buffer.from(await o.arrayBuffer());return i(t,o,a),await d(n,a),n}function h(t){try{const r=new URL(t).pathname,o=decodeURIComponent(e.basename(r));return e.join(f.homedir(),"Downloads",o||"download.bin")}catch{return e.join(f.homedir(),"Downloads","download.bin")}}export{B as downloadToPath};
@@ -1 +1 @@
1
- import{XIANTAO_BIO_API_ENDPOINT as s,XIANTAO_HISTORY_UUID as d}from"./constants.js";import{XtzError as m}from"./errors.js";import{requestJson as c}from"./http.js";import{buildXiantaoHeaders as u}from"./xiantao.js";async function l(t,e={}){const r=await c(s,{body:JSON.stringify({version:"v3",name:"public.records.fetch",args:{id:{uuid:d},current_page:e.currentPage??1}}),headers:u(t,!0),method:"POST"},{agent:t.agent});return{currentPage:r.data.current_page??e.currentPage??1,info:r.data.info?.trim()??"",lastPage:r.data.last_page??1,perPage:r.data.per_page??10,records:r.data.data_records??[],total:r.data.total??0}}async function T(t,e){const r=await c(s,{body:JSON.stringify({version:"v3",name:"public.records.download-buttons",args:{id:{fuid:e.fuid,uuid:d}}}),headers:u(t,!0),method:"POST"},{agent:t.agent});return{body:r.data.body??"",downloads:b(r.data.data??[])}}async function X(t,e){await c(s,{body:JSON.stringify({version:"v3",name:"public.records.rename",args:{id:{fuid:e.fuid,uuid:d},new_name:e.newName}}),headers:u(t,!0),method:"POST"},{agent:t.agent})}async function _(t,e){await c(s,{body:JSON.stringify({version:"v3",name:"public.records.delete",args:{id:{fuid:e.fuid,uuid:d}}}),headers:u(t,!0),method:"POST"},{agent:t.agent})}async function x(t,e){return(await c(s,{body:JSON.stringify({version:"v3",name:"public.records.modify-fetch",args:{id:{fuid:e.fuid,uuid:d}}}),headers:u(t,!0),method:"POST"},{agent:t.agent})).data}async function I(t,e){const r=Date.now()+e.timeoutMs;for(;Date.now()<=r;){const a=await l(t),n=w(a.records,e.moduleId,e.submittedAtMs);if(n)return n;await p(e.intervalMs)}return null}async function D(t,e){const r=e.trim();if(!r)return null;let a=1,n=1;do{const i=await l(t,{currentPage:a}),o=i.records.find(f=>f.fuid?.trim()===r);if(o)return o;a+=1,n=i.lastPage}while(a<=n);return null}async function M(t,e){const r=Date.now()+e.timeoutMs;for(;Date.now()<=r;){const n=(await l(t)).records.find(o=>o.fuid?.trim()===e.fuid);if(!n){await p(e.intervalMs);continue}const i=y(n);if(h(i))return n;if(v(i))throw new m(`\u5386\u53F2\u8BB0\u5F55\u4EFB\u52A1\u6267\u884C\u5931\u8D25\uFF1A${i}`);await p(e.intervalMs)}return null}function y(t){return H(t.status??"").trim()||"\u672A\u77E5"}function w(t,e,r){const a=e.trim(),n=r-12e4;return t.filter(o=>o.module_id?.trim()===a).sort((o,f)=>g(f.time)-g(o.time)).find(o=>g(o.time)>=n)}function b(t){return t.flatMap(e=>e.tag!=="download"||!e.device||!e.endpoint||!e.fuid||!e.label?[]:[{device:e.device,endpoint:e.endpoint,fuid:e.fuid,index:e.index,info:e.info,label:e.label,pos:e.pos,sign:e.sign}])}function g(t){const e=t?.trim();if(!e)return 0;const r=Date.parse(e.replace(" ","T"));return Number.isNaN(r)?0:r}function H(t){return t.replace(/<[^>]+>/g," ").replace(/\s+/g," ")}function h(t){return t.includes("\u5B8C\u6210")}function v(t){return["\u5931\u8D25","\u5F02\u5E38","\u53D6\u6D88","\u7EC8\u6B62"].some(e=>t.includes(e))}async function p(t){await new Promise(e=>setTimeout(e,t))}export{_ as deleteXiantaoHistoryRecord,T as fetchXiantaoHistoryDownloadButtons,x as fetchXiantaoHistoryModify,l as fetchXiantaoHistoryRecords,D as findXiantaoHistoryRecordByFuid,y as getXiantaoHistoryRecordStatus,X as renameXiantaoHistoryRecord,I as waitForLatestXiantaoHistoryRecord,M as waitForXiantaoHistoryRecordCompletion};
1
+ import{XIANTAO_HISTORY_UUID as s}from"./constants.js";import{resolveXiantaoBioApiEndpoint as d}from"./config.js";import{XtzError as m}from"./errors.js";import{requestJson as c}from"./http.js";import{buildXiantaoHeaders as u}from"./xiantao.js";async function l(e,t={}){const a=await c(await d(),{body:JSON.stringify({version:"v3",name:"public.records.fetch",args:{id:{uuid:s},current_page:t.currentPage??1}}),headers:await u(e,!0),method:"POST"},{agent:e.agent});return{currentPage:a.data.current_page??t.currentPage??1,info:a.data.info?.trim()??"",lastPage:a.data.last_page??1,perPage:a.data.per_page??10,records:a.data.data_records??[],total:a.data.total??0}}async function T(e,t){const a=await c(await d(),{body:JSON.stringify({version:"v3",name:"public.records.download-buttons",args:{id:{fuid:t.fuid,uuid:s}}}),headers:await u(e,!0),method:"POST"},{agent:e.agent});return{body:a.data.body??"",downloads:b(a.data.data??[])}}async function N(e,t){await c(await d(),{body:JSON.stringify({version:"v3",name:"public.records.rename",args:{id:{fuid:t.fuid,uuid:s},new_name:t.newName}}),headers:await u(e,!0),method:"POST"},{agent:e.agent})}async function _(e,t){await c(await d(),{body:JSON.stringify({version:"v3",name:"public.records.delete",args:{id:{fuid:t.fuid,uuid:s}}}),headers:await u(e,!0),method:"POST"},{agent:e.agent})}async function M(e,t){return(await c(await d(),{body:JSON.stringify({version:"v3",name:"public.records.modify-fetch",args:{id:{fuid:t.fuid,uuid:s}}}),headers:await u(e,!0),method:"POST"},{agent:e.agent})).data}async function R(e,t){const a=Date.now()+t.timeoutMs;for(;Date.now()<=a;){const o=await l(e),r=y(o.records,t.moduleId,t.submittedAtMs);if(r)return r;await g(t.intervalMs)}return null}async function D(e,t){const a=t.trim();if(!a)return null;let o=1,r=1;do{const i=await l(e,{currentPage:o}),n=i.records.find(f=>f.fuid?.trim()===a);if(n)return n;o+=1,r=i.lastPage}while(o<=r);return null}async function I(e,t){const a=Date.now()+t.timeoutMs;for(;Date.now()<=a;){const r=(await l(e)).records.find(n=>n.fuid?.trim()===t.fuid);if(!r){await g(t.intervalMs);continue}const i=w(r);if(H(i))return r;if(h(i))throw new m(`\u5386\u53F2\u8BB0\u5F55\u4EFB\u52A1\u6267\u884C\u5931\u8D25\uFF1A${i}`);await g(t.intervalMs)}return null}function w(e){return v(e.status??"").trim()||"\u672A\u77E5"}function y(e,t,a){const o=t.trim(),r=a-12e4;return e.filter(n=>n.module_id?.trim()===o).sort((n,f)=>p(f.time)-p(n.time)).find(n=>p(n.time)>=r)}function b(e){return e.flatMap(t=>t.tag!=="download"||!t.device||!t.endpoint||!t.fuid||!t.label?[]:[{device:t.device,endpoint:t.endpoint,fuid:t.fuid,index:t.index,info:t.info,label:t.label,pos:t.pos,sign:t.sign}])}function p(e){const t=e?.trim();if(!t)return 0;const a=Date.parse(t.replace(" ","T"));return Number.isNaN(a)?0:a}function v(e){return e.replace(/<[^>]+>/g," ").replace(/\s+/g," ")}function H(e){return e.includes("\u5B8C\u6210")}function h(e){return["\u5931\u8D25","\u5F02\u5E38","\u53D6\u6D88","\u7EC8\u6B62"].some(t=>e.includes(t))}async function g(e){await new Promise(t=>setTimeout(t,e))}export{_ as deleteXiantaoHistoryRecord,T as fetchXiantaoHistoryDownloadButtons,M as fetchXiantaoHistoryModify,l as fetchXiantaoHistoryRecords,D as findXiantaoHistoryRecordByFuid,w as getXiantaoHistoryRecordStatus,N as renameXiantaoHistoryRecord,R as waitForLatestXiantaoHistoryRecord,I as waitForXiantaoHistoryRecordCompletion};
package/dist/lib/http.js CHANGED
@@ -1 +1 @@
1
- import{XtzError as a,raiseApiError as c}from"./errors.js";async function f(e,t={},n={}){let r;try{r=await fetch(e,t)}catch{throw new a("\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}const s=await r.text(),o=i(r,s);return n.allowErrorPayload?.(o,r)||(!r.ok||o.success===!1)&&await c(o,n),o}function i(e,t){try{return JSON.parse(t)}catch{const n=[`HTTP ${e.status}`,e.headers.get("content-type")?.trim()].filter(Boolean).join(", "),r=l(t);throw new a(r?`\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\uFF08${n}\uFF09\uFF1A${r}`:`\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\uFF08${n}\uFF09\u3002`)}}function l(e){const t=e.trim().replace(/\s+/g," ");return t?t.length>160?`${t.slice(0,160)}...`:t:""}export{f as requestJson};
1
+ import{XtzError as a,raiseApiError as i}from"./errors.js";import{debugHttpError as p,debugHttpRequest as u,debugHttpResponse as f}from"./debug.js";async function y(e,t={},o={}){let r;u(e,t);try{r=await fetch(e,t)}catch(c){throw p(e,c),new a("\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}const s=await r.text();f(e,r,s);const n=l(r,s);return o.allowErrorPayload?.(n,r)||(!r.ok||n.success===!1)&&await i(n,o),n}function l(e,t){try{return JSON.parse(t)}catch{const o=[`HTTP ${e.status}`,e.headers.get("content-type")?.trim()].filter(Boolean).join(", "),r=m(t);throw new a(r?`\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\uFF08${o}\uFF09\uFF1A${r}`:`\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\uFF08${o}\uFF09\u3002`)}}function m(e){const t=e.trim().replace(/\s+/g," ");return t?t.length>160?`${t.slice(0,160)}...`:t:""}export{y as requestJson};
@@ -1 +1 @@
1
- import{loginAuth as i,waitForAuthorizedToken as n}from"./auth.js";async function u(o,e=!0,a){const t=await i(o,e);return a?.({auth:t,phase:"auth_started"}),await n(t.token),a?.({auth:t,phase:"auth_confirmed"}),{auth:t}}export{u as loginAll};
1
+ import{completeLoginAuth as o,startLoginAuth as i}from"./auth.js";async function p(u,n=!0,t){const a=await i(u);if(!n)return t?.({auth:a,phase:"auth_started"}),{auth:a};const h=await o(u,a,{onBrowserOpened:e=>t?.({auth:e,phase:"auth_started"}),onTokenCaptured:e=>t?.({auth:e,phase:"token_saved"})});return t?.({auth:h,phase:"auth_confirmed"}),{auth:h}}export{p as loginAll};
@@ -1,39 +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 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(`
1
+ import d from"node:readline/promises";import{stdin as m,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 tt(t,e){h();const n=d.createInterface({input:m,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<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(`
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=_(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 et(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 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(`
11
+ `);const e=d.createInterface({input:m,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 nt(t){if(h(),t.length===0)return[];const e=d.createInterface({input:m,output:s});try{return await v(e,t)}finally{e.close()}}async function rt(t){h();const e=t.filter(u=>D(u));if(e.length===0)throw new a("\u5F53\u524D\u4EA7\u54C1\u672A\u8FD4\u56DE\u53EF\u9009\u5DE5\u5177\u76EE\u5F55\u3002");const n=d.createInterface({input:m,output:s}),r=[];let i=e,o="\u9009\u62E9\u5927\u7C7B";try{for(;;){s.write(`
12
12
  [${o}]
13
13
  `),i.forEach((l,w)=>{const c=A(l),f=S(l).length>0?" >":` (${l.code?.trim()??"-"})`;s.write(` ${w+1}. ${c}${f}
14
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(`
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 H(c)}catch(l){if(!(l instanceof a))throw l;s.write(`${l.message}
16
+ `)}}}finally{n.close()}}async function it(){h();const t=d.createInterface({input:m,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 ot(){h();const t=d.createInterface({input:m,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 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(`
22
+ `)}}finally{t.close()}}async function st(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=d.createInterface({input:m,output:s});try{for(;;)try{s.write(`
23
23
  [\u4E91\u7AEF\u6570\u636E]
24
- `),t.forEach((i,o)=>{s.write(` ${o+1}. ${P(i)}
24
+ `),t.forEach((i,o)=>{s.write(` ${o+1}. ${M(i)}
25
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(`
26
+ `)}}finally{e.close()}}async function at(t){if(h(),!t.hasFile&&t.downloads.length===0)return{downloadFile:!1,downloads:[]};const e=X(t),n=d.createInterface({input:m,output:s});try{for(;;)try{s.write(`
27
27
  [\u7ED3\u679C\u5904\u7406]
28
28
  `),e.forEach((u,l)=>{s.write(` ${l+1}. ${u.label}
29
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}
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(`
30
+ `)}}finally{n.close()}}function h(){if(!m.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(`
31
31
  [\u4E0B\u8F7D\u7ED3\u679C]
32
32
  `),e.forEach((n,r)=>{s.write(` ${r+1}. ${n.label} (${n.device})
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}
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:
38
- `),n.forEach(r=>{const i=$(r);s.write(` ${j(i)} ${i}
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};
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?q(n,e.length).map(i=>e[i]):[]}catch(n){if(!(n instanceof a))throw n;s.write(`${n.message}
34
+ `)}}async function k(t,e,n){for(;;)try{const r=O(e),i="\u8F93\u5165 < \u8FD4\u56DE\u4E0A\u4E00\u9879\uFF0C/skip \u8DF3\u8FC7\u672C\u7EC4";if(e.options?.length){s.write(`${r}
35
+ `),R(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?J(f,e.options):F(f,e.options)}}if(e.type==="XTSwitch"){const c=(await t.question(`${r} (\u5F00/\u5173\uFF0C${i}) [${B(n)}]: `)).trim();if(!c)return{type:"value",value:n};const f=b(c);return f||{type:"value",value:I(c)}}if(e.type==="XTColor"){j(n);const c=(await t.question(`${r} (\u989C\u8272\u7528\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF0C${i}) [${L(n)}]: `)).trim();if(!c)return{type:"value",value:n};const f=b(c);return f||{type:"value",value:z(c,n)}}const o=e.placeholder?.trim()||e.tips?.trim()||E(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:P(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){return typeof t.label!="string"?t.key:t.label.trim()||t.key}function J(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 q(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 P(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 T(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){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 T(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 z(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 E(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 B(t){return t===!0?"\u5F00":"\u5173"}function L(t){return Array.isArray(t)?t.join(", "):g(t)}function R(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 _(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 D(t){return!!(t.title?.trim()||t.code?.trim())}function A(t){return t.title?.trim()||t.code?.trim()||"\u672A\u547D\u540D"}function H(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 X(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 j(t){const n=(Array.isArray(t)?t:[t]).filter(r=>typeof r=="string");n.length!==0&&(s.write(`\u5F53\u524D\u989C\u8272:
38
+ `),n.forEach(r=>{const i=$(r);s.write(` ${W(i)} ${i}
39
+ `)}))}function W(t){const e=Y(t);return e?`\x1B[48;2;${e.r};${e.g};${e.b}m \x1B[0m`:"[?]"}function Y(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{et as confirmPlotArgsMain,tt as promptPlotArgsMain,st as promptPlotCloudRecordSelection,nt as promptPlotDownloads,it as promptPlotFilePath,ot as promptPlotInputSource,rt as promptPlotMenuSelection,at as promptPlotResultSelection};
@@ -1 +1 @@
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};
1
+ import{Flags as u}from"@oclif/core";import{XtzError as f}from"./errors.js";import{isJsonObject as l}from"./json.js";const J={config:u.string({description:"Path to a JSON file with raw argsMain overrides"}),specific:u.string({description:"Override argsSpecific by key or dotted path, e.g. --specific genes=TP53 or --specific surv_list_nn.0.variable=...",multiple:!0}),set:u.string({description:"Override argsMain value by dotted path, e.g. --set title.title=My Title",multiple:!0})};function V(e){const r={};for(const n of e??[]){const t=n.indexOf("=");if(t<=0||t===n.length-1)throw new f(`--set \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${n}`);const i=n.slice(0,t).trim(),s=n.slice(t+1).trim(),o=i.split(".").filter(Boolean);if(o.length===0)throw new f(`--set \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${n}`);const c=o.at(-1)==="value"?o:[...o,"value"];g(r,c,d(s,"--set"))}return r}function b(e){return $({},e)}function $(e,r){const n=structuredClone(e);for(const t of r??[]){const i=t.indexOf("=");if(i<=0||i===t.length-1)throw new f(`--specific \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${t}`);const s=t.slice(0,i).trim(),o=t.slice(i+1).trim();if(!s)throw new f(`--specific \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${t}`);const c=s.split(".").filter(Boolean);if(c.length===0)throw new f(`--specific \u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E: ${t}`);if(c.length===1){n[c[0]]=d(o,"--specific");continue}v(n,c,d(o,"--specific"),"--specific")}return n}function P(e){const r=[];for(const[n,t]of Object.entries(e))if(l(t))for(const[i,s]of Object.entries(t)){if(!l(s)||!("value"in s))continue;const o=s.value,c=`${n}.${i}=${JSON.stringify(o)}`;r.push(`--set ${x(c)}`)}return r}function g(e,r,n){let t=e;for(const i of r.slice(0,-1)){const s=t[i];l(s)||(t[i]={}),t=t[i]}t[r.at(-1)]=n}function v(e,r,n,t){let i=e;for(let s=0;s<r.length-1;s+=1){const o=r[s],c=r[s+1],a=O(i,o,t);if(l(a)||Array.isArray(a)){i=a;continue}const p=y(c)?[]:{};h(i,o,p,t),i=p}h(i,r.at(-1),n,t)}function O(e,r,n){if(!Array.isArray(e))return e[r];const t=w(r,n);return e[t]}function h(e,r,n,t){if(!Array.isArray(e)){e[r]=n;return}const i=w(r,t);if(i>e.length)throw new f(`${t} \u6570\u7EC4\u7D22\u5F15\u8D85\u51FA\u8303\u56F4: ${r}`);e[i]=n}function w(e,r){if(!y(e))throw new f(`${r} \u6570\u7EC4\u8DEF\u5F84\u5FC5\u987B\u4F7F\u7528\u975E\u8D1F\u6574\u6570\u7D22\u5F15: ${e}`);return Number(e)}function y(e){return/^(0|[1-9]\d*)$/.test(e)}function d(e,r){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 f(`${r} \u53C2\u6570\u503C\u4E0D\u662F\u5408\u6CD5 JSON: ${e}`)}return e}function x(e){return`'${e.replaceAll("'","'\\''")}'`}export{$ as applySpecificOverrides,P as formatSetOverrides,V as parseSetOverrides,b as parseSpecificOverrides,J as plotOverrideFlags};
package/dist/lib/plot.js CHANGED
@@ -1 +1 @@
1
- import{basename as y}from"node:path";import{readFile as h,stat as _}from"node:fs/promises";import{BIO_API_ENDPOINT as m,UPLOAD_CONFIG_ENDPOINT as O}from"./constants.js";import{XtzError as c}from"./errors.js";import{requestJson as l}from"./http.js";import{deepMerge as S}from"./json.js";import{buildArgsMainFromSchema as b}from"./plot-schema.js";async function I(e,o){const t=await l(O,{headers:{Authorization:`Bearer ${e.token}`}},{agent:e.agent}),a=P(t.data),i=await h(o),s=await _(o),n=y(o),d=`${a.dir}/${n}`,r=new FormData;r.set("key",d),r.set("policy",a.policy),r.set("OSSAccessKeyId",a.access_id),r.set("success_action_status","200"),r.set("signature",a.signature),r.set("file",new Blob([i]),n);const u=await fetch(a.host,{body:r,headers:{"x-oss-object-acl":"public-read"},method:"POST"});if(!u.ok)throw new c(`\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25 (${u.status})`);return{fileName:n,fileOss:`${a.host.replace(/\/$/,"")}/${d}`,fileOssPath:d,fileSize:s.size,fileSizeForXiantao:Number((s.size/(1024*1024)).toFixed(2))}}async function f(e,o,t,a){const i=w({argsMain:a,definition:o,duid:"",upload:t});delete i.args.action,i.args.id.uuid="2d491694-8c8d-11ee-9409-00163e118c99";const s=await l(m,{body:JSON.stringify(i),headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json",origin:"https://www.xiantaozi.com",referer:"https://www.xiantaozi.com/",source:"PC"},method:"POST"},{agent:e.agent}),n=s.data.id?.duid;if(!n)throw new c(s.message??"\u672A\u83B7\u53D6\u5230 duid");return{duid:n,schema:s.data.args_main??[]}}async function p(e,o,t,a){return(await f(e,o,t,a)).duid}async function g(e,o,t,a){const i=w({argsMain:a,definition:o,duid:t.duid,upload:t.upload}),s=await l(m,{body:JSON.stringify(i),headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},method:"POST"},{agent:e.agent});if(!s.data.file)throw new c(s.message??"\u672A\u83B7\u53D6\u5230\u56FE\u7247\u94FE\u63A5");return s.data.file}async function B(e,o,t,a){const i=await p(e,o,t,a),s=await g(e,o,{duid:i,upload:t},a);return{duid:i,file:s}}async function T(e,o,t,a){const i=await f(e,o,t,o.seedArgsMain),s=S(b(i.schema),a),n=await p(e,o,t,s),d=await g(e,o,{duid:n,upload:t},s);return{argsMain:s,duid:n,file:d,schema:i.schema}}function w(e){return{version:"v3",name:"common.module",extra_args:{name:e.duid?e.definition.submitRoute:e.definition.verifyRoute},args:{action:"submit",id:{module_id:e.definition.moduleId,uuid:"agent_call"},args_data:{duid:e.duid,info:{main:{file_oss:e.upload.fileOss,file_name:e.upload.fileName,file_size:e.upload.fileSize,type:"upload"}}},args_main:e.argsMain}}}function P(e){const o=Buffer.from(e,"base64").toString("utf8"),t=decodeURIComponent(o.replaceAll("+"," "));return JSON.parse(t)}export{B as createPlot,T as createPlotFromSchema,f as inspectPlotUpload,g as submitPlot,I as uploadFile,p as verifyPlotUpload};
1
+ import{basename as S}from"node:path";import{readFile as x,stat as z}from"node:fs/promises";import{resolveUploadConfigEndpoint as _,resolveXiantaoBioApiEndpoint as p}from"./config.js";import{XtzError as l}from"./errors.js";import{requestJson as u}from"./http.js";import{debugHttpError as O,debugHttpRequest as P,debugHttpResponse as $}from"./debug.js";import{deepMerge as A}from"./json.js";import{buildArgsMainFromSchema as B}from"./plot-schema.js";async function J(e,o){const a=await u(await _(),{headers:{Authorization:`Bearer ${e.token}`}},{agent:e.agent}),t=C(a.data),i=await x(o),s=await z(o),r=S(o),d=`${t.dir}/${r}`,n=new FormData;n.set("key",d),n.set("policy",t.policy),n.set("OSSAccessKeyId",t.access_id),n.set("success_action_status","200"),n.set("signature",t.signature),n.set("file",new Blob([i]),r);const m={body:n,headers:{"x-oss-object-acl":"public-read"},method:"POST"};P(t.host,m);let c;try{c=await fetch(t.host,m)}catch(f){throw O(t.host,f),f}const b=await c.text();if($(t.host,c,b),!c.ok)throw new l(`\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25 (${c.status})`);return{fileName:r,fileOss:`${t.host.replace(/\/$/,"")}/${d}`,fileOssPath:d,fileSize:s.size,fileSizeForXiantao:Number((s.size/(1024*1024)).toFixed(2))}}async function g(e,o,a,t){const i=h({argsMain:t,definition:o,duid:"",upload:a});delete i.args.action,i.args.id.uuid="2d491694-8c8d-11ee-9409-00163e118c99";const s=await u(await p(),{body:JSON.stringify(i),headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json",origin:"https://www.xiantaozi.com",referer:"https://www.xiantaozi.com/",source:"PC"},method:"POST"},{agent:e.agent}),r=s.data.id?.duid;if(!r)throw new l(s.message??"\u672A\u83B7\u53D6\u5230 duid");return{duid:r,schema:s.data.args_main??[]}}async function w(e,o,a,t){return(await g(e,o,a,t)).duid}async function y(e,o,a,t){const i=h({argsMain:t,definition:o,duid:a.duid,upload:a.upload}),s=await u(await p(),{body:JSON.stringify(i),headers:{Authorization:`Bearer ${e.token}`,"Content-Type":"application/json"},method:"POST"},{agent:e.agent});if(!s.data.file)throw new l(s.message??"\u672A\u83B7\u53D6\u5230\u56FE\u7247\u94FE\u63A5");return s.data.file}async function M(e,o,a,t){const i=await w(e,o,a,t),s=await y(e,o,{duid:i,upload:a},t);return{duid:i,file:s}}async function j(e,o,a,t){const i=await g(e,o,a,o.seedArgsMain),s=A(B(i.schema),t),r=await w(e,o,a,s),d=await y(e,o,{duid:r,upload:a},s);return{argsMain:s,duid:r,file:d,schema:i.schema}}function h(e){return{version:"v3",name:"common.module",extra_args:{name:e.duid?e.definition.submitRoute:e.definition.verifyRoute},args:{action:"submit",id:{module_id:e.definition.moduleId,uuid:"agent_call"},args_data:{duid:e.duid,info:{main:{file_oss:e.upload.fileOss,file_name:e.upload.fileName,file_size:e.upload.fileSize,type:"upload"}}},args_main:e.argsMain}}}function C(e){const o=Buffer.from(e,"base64").toString("utf8"),a=decodeURIComponent(o.replaceAll("+"," "));return JSON.parse(a)}export{M as createPlot,j as createPlotFromSchema,g as inspectPlotUpload,y as submitPlot,J as uploadFile,w as verifyPlotUpload};
@@ -0,0 +1 @@
1
+ const r=new Set(["pair_plot_cloud","gene_diff","find_diff_cloud","heatmap_gene_clin","gene_cor","cor_point_gene","cor_point_rna_mirna","lollipop_cor_gene","coexpr_heatmap_gene","heatmap_cor_group_gene","lollipop_cor_immu","cor_point_immu","group_plot_immu","bar_stack_immu","group_plot_clin","baseline_cloud","roc_curve_status","roc_curve_cloud","logistic_binary_cloud_gene","km_plot_gene","km_plot_group","time_roc_gene","time_auc_gene","cox_analysis_cloud","nomogram_surv_cloud","calibration_surv_cloud","group_plot_pan","pair_plot_pan","forest_plot_pan","heatmap_cox_gene_pan","radar_plot_pan","heatmap_cor_gene_immu_pan"]),a={default_value:"ERBB2[ENSG00000141736.14]",key:"genes",label:"\u5206\u5B50",required:!0,type:"XTSearch"};function p(e,o){const _=o??[];return!r.has(e.trim())||_.some(n=>n.key==="genes")?_:[..._,{...a}]}export{p as withKnownArgsSpecific};
@@ -1,2 +1,2 @@
1
- import{mkdir as _,readFile as a,rm as A,writeFile as g}from"node:fs/promises";import T from"node:os";import u from"node:path";import{DEFAULT_AGENT as w,DEFAULT_XIANTAO_TOOL_PRODUCT_UUID as N,XTZ_CONFIG_PATH as l}from"./constants.js";import{XtzError as f}from"./errors.js";import{deepMerge as p}from"./json.js";import{isJsonObject as o}from"./json.js";function m(r){return u.join(T.homedir(),".config","helix",r,"token-key.txt")}async function I(r,t){const n=m(r);return await _(u.dirname(n),{recursive:!0}),await g(n,`${t.trim()}
2
- `,"utf8"),n}async function v(r){const t=m(r);try{return(await a(t,"utf8")).trim()||void 0}catch(n){if(O(n)&&n.code==="ENOENT")return;throw n}}async function L(r){const t=await v(r);if(t)return t;throw new f(`\u672A\u627E\u5230 ${r} \u7684 token\uFF0C\u8BF7\u5148\u8FD0\u884C \`xt login --profile ${r}\``)}async function G(r){const t=m(r);try{return await A(t),!0}catch(n){if(O(n)&&n.code==="ENOENT")return!1;throw n}}async function d(){const r=u.join(T.homedir(),l);try{const t=await a(r,"utf8"),n=JSON.parse(t);if(!o(n))throw new f(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u4E0D\u6B63\u786E: ${r}`);return n}catch(t){if(O(t)&&t.code==="ENOENT")return{};throw t}}async function X(r){const t=r?.trim();if(t)return t;const n=h();return n||(await d()).agent?.trim()||w}async function $(r){if(r?.trim())return r.trim();if(process.env.XIANTAO_TOOL_PRODUCT_UUID?.trim())return process.env.XIANTAO_TOOL_PRODUCT_UUID.trim();const n=(await d()).xiantao?.toolProductUuid?.trim();return n||N}async function F(r,t){const i=(await d()).plots?.[r],s=o(i)&&o(i.argsMain)?i.argsMain:{};if(!t)return s;const e=await C(t),c=(o(e.plots)?e.plots:void 0)?.[r];return o(c)&&o(c.argsMain)?p(s,c.argsMain):o(e.argsMain)?p(s,e.argsMain):p(s,e)}async function C(r){const t=await a(r,"utf8"),n=JSON.parse(t);if(!o(n))throw new f(`JSON \u914D\u7F6E\u683C\u5F0F\u4E0D\u6B63\u786E: ${r}`);return n}function O(r){return r instanceof Error&&"code"in r}function h(){const r=process.env.AGENT_NAME?.trim();if(r)return r;if(R())return"cursor";if(E("OPENCODE"))return"opencode";if(E("OPENCLAW"))return"openclaw"}function R(){return!!(process.env.CURSOR_TRACE_ID?.trim()||process.env.CURSOR_SESSION_ID?.trim()||process.env.CURSOR_AGENT?.trim()||process.env.VSCODE_GIT_ASKPASS_NODE?.includes("Cursor")||process.env.TERM_PROGRAM?.toLowerCase()==="cursor")}function E(r){return!!(process.env[r]?.trim()||process.env[`${r}_AGENT`]?.trim()||process.env[`${r}_SESSION_ID`]?.trim()||process.env.TERM_PROGRAM?.toLowerCase()===r.toLowerCase())}export{G as deleteToken,m as getTokenPath,F as loadPlotArgsMainConfig,v as loadToken,d as readXtzConfig,L as requireToken,X as resolveAgent,$ as resolveXiantaoToolProductUuid,I as saveToken};
1
+ import{mkdir as _,readFile as a,rm as g,writeFile as A}from"node:fs/promises";import T from"node:os";import u from"node:path";import{DEFAULT_AGENT as w,DEFAULT_XIANTAO_TOOL_PRODUCT_UUID as N,XTZ_CONFIG_PATH as l}from"./constants.js";import{XtzError as f}from"./errors.js";import{deepMerge as p}from"./json.js";import{isJsonObject as o}from"./json.js";function m(r){return u.join(T.homedir(),".config","helix","token-key.txt")}async function I(r,t){const n=m(r);return await _(u.dirname(n),{recursive:!0}),await A(n,`${t.trim()}
2
+ `,"utf8"),n}async function v(r){const t=m(r);try{return(await a(t,"utf8")).trim()||void 0}catch(n){if(O(n)&&n.code==="ENOENT")return;throw n}}async function L(r){const t=await v(r);if(t)return t;throw new f(`\u672A\u627E\u5230 ${r} \u7684 token\uFF0C\u8BF7\u5148\u8FD0\u884C \`xt login --profile ${r}\``)}async function G(r){const t=m(r);try{return await g(t),!0}catch(n){if(O(n)&&n.code==="ENOENT")return!1;throw n}}async function d(){const r=u.join(T.homedir(),l);try{const t=await a(r,"utf8"),n=JSON.parse(t);if(!o(n))throw new f(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u4E0D\u6B63\u786E: ${r}`);return n}catch(t){if(O(t)&&t.code==="ENOENT")return{};throw t}}async function X(r){const t=r?.trim();if(t)return t;const n=h();return n||(await d()).agent?.trim()||w}async function $(r){if(r?.trim())return r.trim();if(process.env.XIANTAO_TOOL_PRODUCT_UUID?.trim())return process.env.XIANTAO_TOOL_PRODUCT_UUID.trim();const n=(await d()).xiantao?.toolProductUuid?.trim();return n||N}async function F(r,t){const i=(await d()).plots?.[r],s=o(i)&&o(i.argsMain)?i.argsMain:{};if(!t)return s;const e=await C(t),c=(o(e.plots)?e.plots:void 0)?.[r];return o(c)&&o(c.argsMain)?p(s,c.argsMain):o(e.argsMain)?p(s,e.argsMain):p(s,e)}async function C(r){const t=await a(r,"utf8"),n=JSON.parse(t);if(!o(n))throw new f(`JSON \u914D\u7F6E\u683C\u5F0F\u4E0D\u6B63\u786E: ${r}`);return n}function O(r){return r instanceof Error&&"code"in r}function h(){const r=process.env.AGENT_NAME?.trim();if(r)return r;if(R())return"cursor";if(E("OPENCODE"))return"opencode";if(E("OPENCLAW"))return"openclaw"}function R(){return!!(process.env.CURSOR_TRACE_ID?.trim()||process.env.CURSOR_SESSION_ID?.trim()||process.env.CURSOR_AGENT?.trim()||process.env.VSCODE_GIT_ASKPASS_NODE?.includes("Cursor")||process.env.TERM_PROGRAM?.toLowerCase()==="cursor")}function E(r){return!!(process.env[r]?.trim()||process.env[`${r}_AGENT`]?.trim()||process.env[`${r}_SESSION_ID`]?.trim()||process.env.TERM_PROGRAM?.toLowerCase()===r.toLowerCase())}export{G as deleteToken,m as getTokenPath,F as loadPlotArgsMainConfig,v as loadToken,d as readXtzConfig,L as requireToken,X as resolveAgent,$ as resolveXiantaoToolProductUuid,I as saveToken};
@@ -1,2 +1,2 @@
1
- import{mkdir as C,readFile as A,writeFile as E}from"node:fs/promises";import w from"node:os";import d from"node:path";import{XTZ_UPDATE_CHECK_PATH as P}from"./constants.js";import{isJsonObject as m}from"./json.js";const h="@helixlife-ai/xiantao",V=`https://registry.npmjs.org/${encodeURIComponent(h)}/latest`,_=720*60*1e3,y=1200;async function D(e){try{const t=await T(),r=await k(t);return!r||U(r,e)<=0?void 0:`\u68C0\u6D4B\u5230\u65B0\u7248\u672C ${r}\uFF08\u5F53\u524D ${e}\uFF09\uFF0C\u53EF\u8FD0\u884C \`npm install -g ${h}@latest\` \u66F4\u65B0\u3002`}catch{return}}async function k(e){const t=Date.now(),r=e.lastCheckedAt?Date.parse(e.lastCheckedAt):Number.NaN;if(Number.isFinite(r)&&t-r<_)return e.latestVersion?.trim()||void 0;const n=await S();return await b({lastCheckedAt:new Date(t).toISOString(),latestVersion:n??e.latestVersion}),n??(e.latestVersion?.trim()||void 0)}async function S(){const e=await fetch(V,{headers:{accept:"application/json"},signal:AbortSignal.timeout(y)});if(!e.ok)return;const t=JSON.parse(await e.text());if(!(!m(t)||typeof t.version!="string"))return t.version.trim()||void 0}async function T(){const e=N();try{const t=await A(e,"utf8"),r=JSON.parse(t);return m(r)?{lastCheckedAt:typeof r.lastCheckedAt=="string"?r.lastCheckedAt:void 0,latestVersion:typeof r.latestVersion=="string"?r.latestVersion:void 0}:{}}catch(t){if(x(t)&&t.code==="ENOENT")return{};throw t}}async function b(e){const t=N();await C(d.dirname(t),{recursive:!0}),await E(t,`${JSON.stringify(e,null,2)}
2
- `,"utf8")}function U(e,t){const r=g(e),n=g(t);if(!r||!n)return e.localeCompare(t);const a=Math.max(r.core.length,n.core.length);for(let i=0;i<a;i+=1){const s=(r.core[i]??0)-(n.core[i]??0);if(s!==0)return s}if(r.prerelease.length===0&&n.prerelease.length===0)return 0;if(r.prerelease.length===0)return 1;if(n.prerelease.length===0)return-1;const o=Math.max(r.prerelease.length,n.prerelease.length);for(let i=0;i<o;i+=1){const s=r.prerelease[i],c=n.prerelease[i];if(s===void 0)return-1;if(c===void 0)return 1;const l=/^[0-9]+$/.test(s),f=/^[0-9]+$/.test(c);if(l&&f){const p=Number(s)-Number(c);if(p!==0)return p;continue}if(l)return-1;if(f)return 1;const u=s.localeCompare(c);if(u!==0)return u}return 0}function g(e){const t=e.trim().replace(/^v/,"");if(!t)return;const[r,n]=t.split("-",2),a=r.split(".").map(o=>Number.parseInt(o,10));if(!a.some(o=>Number.isNaN(o)))return{core:a,prerelease:n?n.split(".").filter(Boolean):[]}}function N(){return d.join(w.homedir(),P)}function x(e){return e instanceof Error&&"code"in e}export{D as getUpdateReminder};
1
+ import{mkdir as A,readFile as E,writeFile as w}from"node:fs/promises";import y from"node:os";import m from"node:path";import{XTZ_UPDATE_CHECK_PATH as b}from"./constants.js";import{debugHttpError as P,debugHttpRequest as V,debugHttpResponse as _}from"./debug.js";import{isJsonObject as h}from"./json.js";const g="@helixlife-ai/xiantao",l=`https://registry.npmjs.org/${encodeURIComponent(g)}/latest`,k=720*60*1e3,S=1200;async function j(r){try{const t=await x(),e=await T(t);return!e||L(e,r)<=0?void 0:`\u68C0\u6D4B\u5230\u65B0\u7248\u672C ${e}\uFF08\u5F53\u524D ${r}\uFF09\uFF0C\u53EF\u8FD0\u884C \`npm install -g ${g}@latest\` \u66F4\u65B0\u3002`}catch{return}}async function T(r){const t=Date.now(),e=r.lastCheckedAt?Date.parse(r.lastCheckedAt):Number.NaN;if(Number.isFinite(e)&&t-e<k)return r.latestVersion?.trim()||void 0;const n=await U();return await I({lastCheckedAt:new Date(t).toISOString(),latestVersion:n??r.latestVersion}),n??(r.latestVersion?.trim()||void 0)}async function U(){const r={headers:{accept:"application/json"},signal:AbortSignal.timeout(S)};V(l,r);let t;try{t=await fetch(l,r)}catch(s){throw P(l,s),s}const e=await t.text();if(_(l,t,e),!t.ok)return;const n=JSON.parse(e);if(!(!h(n)||typeof n.version!="string"))return n.version.trim()||void 0}async function x(){const r=C();try{const t=await E(r,"utf8"),e=JSON.parse(t);return h(e)?{lastCheckedAt:typeof e.lastCheckedAt=="string"?e.lastCheckedAt:void 0,latestVersion:typeof e.latestVersion=="string"?e.latestVersion:void 0}:{}}catch(t){if(M(t)&&t.code==="ENOENT")return{};throw t}}async function I(r){const t=C();await A(m.dirname(t),{recursive:!0}),await w(t,`${JSON.stringify(r,null,2)}
2
+ `,"utf8")}function L(r,t){const e=N(r),n=N(t);if(!e||!n)return r.localeCompare(t);const s=Math.max(e.core.length,n.core.length);for(let o=0;o<s;o+=1){const i=(e.core[o]??0)-(n.core[o]??0);if(i!==0)return i}if(e.prerelease.length===0&&n.prerelease.length===0)return 0;if(e.prerelease.length===0)return 1;if(n.prerelease.length===0)return-1;const a=Math.max(e.prerelease.length,n.prerelease.length);for(let o=0;o<a;o+=1){const i=e.prerelease[o],c=n.prerelease[o];if(i===void 0)return-1;if(c===void 0)return 1;const u=/^[0-9]+$/.test(i),f=/^[0-9]+$/.test(c);if(u&&f){const d=Number(i)-Number(c);if(d!==0)return d;continue}if(u)return-1;if(f)return 1;const p=i.localeCompare(c);if(p!==0)return p}return 0}function N(r){const t=r.trim().replace(/^v/,"");if(!t)return;const[e,n]=t.split("-",2),s=e.split(".").map(a=>Number.parseInt(a,10));if(!s.some(a=>Number.isNaN(a)))return{core:s,prerelease:n?n.split(".").filter(Boolean):[]}}function C(){return m.join(y.homedir(),b)}function M(r){return r instanceof Error&&"code"in r}export{j as getUpdateReminder};
@@ -1 +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};
1
+ import{resolveXiantaoBioApiEndpoint as r}from"./config.js";import{requestJson as o}from"./http.js";import{buildXiantaoHeaders as d}from"./xiantao.js";async function u(e,t){const a=await o(await r(),{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:i(t.argsKey,t.selectedRecord)}}),headers:await d(e,!0),method:"POST"},{agent:e.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 i(e,t){const a={};return t&&(a[e]=t),{duid:"cloud",info:a}}export{u as fetchXiantaoCloudData};
@@ -1 +1 @@
1
- import{XIANTAO_BIO_API_ENDPOINT as d}from"./constants.js";import{XtzError as m}from"./errors.js";import{requestJson as n}from"./http.js";import{buildXiantaoHeaders as s}from"./xiantao.js";async function I(o,e){const a=await n(d,{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:s(o,!0),method:"POST"},{agent:o.agent}),i=a.data.id?.duid;if(!i)throw new m(a.message??"\u672A\u83B7\u53D6\u5230 duid");return{duid:i,schema:a.data.args_main??[]}}async function h(o,e){const a=await n(d,{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:v(e.duid,e.input),args_main:e.argsMain,args_specific:e.argsSpecific}}),headers:s(o,!0),method:"POST"},{agent:o.agent,allowErrorPayload:u=>f(u.message)}),i=g(a.data.data),t=typeof a.data.file=="string"&&a.data.file.trim()?a.data.file.trim():void 0,l=a.data.body??"",r=a.message??"";if(!t&&!l&&i.length===0){if(f(r))return{asyncSubmission:!0,body:l,downloads:i,file:t,message:r};throw new m(r||"\u672A\u83B7\u53D6\u5230\u53EF\u7528\u7ED3\u679C")}return{asyncSubmission:!1,body:l,downloads:i,file:t,message:r}}async function x(o,e){const a=await n(d,{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:s(o,!0),method:"POST"},{agent:o.agent}),i=a.data.url?.trim();if(!i)throw new m(a.message??"\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5");return{fileName:a.data.file_name?.trim()||void 0,url:i}}function g(o){const e=[...o?.buttons??[]];for(const a of o?.tabs??[])for(const i of a.sections??[])e.push(...i.button??[]);return e.flatMap(a=>a.tag!=="download"||!a.device||!a.endpoint||!a.fuid||!a.label?[]:[{device:a.device,endpoint:a.endpoint,fuid:a.fuid,index:a.index,info:a.info,label:a.label,pos:a.pos,sign:a.sign}])}function y(o){return o.fileOssPath??o.fileOss}function _(o){return o.fileSizeForXiantao??o.fileSize}function v(o,e){return e.kind==="cloud"?{duid:o,info:{[e.cloud.key]:b(e.cloud.record)}}:e.kind==="record"?{duid:o,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:o,info:c(e.uploads)}}function b(o){const e=structuredClone(o);return(typeof e.type!="string"||!e.type.trim())&&(e.type="cloud"),e}function c(o){return Object.fromEntries(o.map(e=>[e.key,{file_oss:y(e.upload),file_name:e.upload.fileName,file_size:_(e.upload),type:"upload"}]))}async function N(o,e){await n(d,{body:JSON.stringify({version:"v3",name:"public.output.save",args:{tag:"msg-box",type:"all",name:"public.output.save",fuid:e.fuid,pos:"main",id:{uuid:e.uuid,module_id:e.moduleId},value:e.name}}),headers:s(o,!0),method:"POST"},{agent:o.agent})}function f(o){return!!o?.includes("\u4EFB\u52A1\u63D0\u4EA4\u6210\u529F")}export{v as buildSubmitArgsData,x as resolveXiantaoDownload,N as saveXiantaoOutput,h as submitXiantaoPlot,I as verifyXiantaoPlotUpload};
1
+ import{resolveXiantaoBioApiEndpoint as d}from"./config.js";import{XtzError as m}from"./errors.js";import{requestJson as n}from"./http.js";import{buildXiantaoHeaders as s}from"./xiantao.js";async function h(a,e){const o=await n(await d(),{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:await s(a,!0),method:"POST"},{agent:a.agent}),i=o.data.id?.duid;if(!i)throw new m(o.message??"\u672A\u83B7\u53D6\u5230 duid");return{duid:i,schema:o.data.args_main??[]}}async function x(a,e){const o=await n(await d(),{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:v(e.duid,e.input),args_main:e.argsMain,args_specific:e.argsSpecific}}),headers:await s(a,!0),method:"POST"},{agent:a.agent,allowErrorPayload:u=>f(u.message)}),i=g(o.data.data),t=typeof o.data.file=="string"&&o.data.file.trim()?o.data.file.trim():void 0,l=o.data.body??"",r=o.message??"";if(!t&&!l&&i.length===0){if(f(r))return{asyncSubmission:!0,body:l,downloads:i,file:t,message:r};throw new m(r||"\u672A\u83B7\u53D6\u5230\u53EF\u7528\u7ED3\u679C")}return{asyncSubmission:!1,body:l,downloads:i,file:t,message:r}}async function X(a,e){const o=await n(await d(),{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:await s(a,!0),method:"POST"},{agent:a.agent}),i=o.data.url?.trim();if(!i)throw new m(o.message??"\u672A\u83B7\u53D6\u5230\u4E0B\u8F7D\u94FE\u63A5");return{fileName:o.data.file_name?.trim()||void 0,url:i}}function g(a){const e=[...a?.buttons??[]];for(const o of a?.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(a){return a.fileOssPath??a.fileOss}function w(a){return a.fileSizeForXiantao??a.fileSize}function v(a,e){return e.kind==="cloud"?{duid:a,info:{[e.cloud.key]:p(e.cloud.record)}}:e.kind==="record"?{duid:a,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:a,info:c(e.uploads)}}function p(a){const e=structuredClone(a);return(typeof e.type!="string"||!e.type.trim())&&(e.type="cloud"),e}function c(a){return Object.fromEntries(a.map(e=>[e.key,{file_oss:y(e.upload),file_name:e.upload.fileName,file_size:w(e.upload),type:"upload"}]))}async function I(a,e){await n(await d(),{body:JSON.stringify({version:"v3",name:"public.output.save",args:{tag:"msg-box",type:"all",name:"public.output.save",fuid:e.fuid,pos:"main",id:{uuid:e.uuid,module_id:e.moduleId},value:e.name}}),headers:await s(a,!0),method:"POST"},{agent:a.agent})}function f(a){return!!a?.includes("\u4EFB\u52A1\u63D0\u4EA4\u6210\u529F")}export{v as buildSubmitArgsData,X as resolveXiantaoDownload,I as saveXiantaoOutput,x as submitXiantaoPlot,h as verifyXiantaoPlotUpload};
@@ -1 +1 @@
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};
1
+ import{resolveXiantaoBaseUrl as C,resolveXiantaoBioApiEndpoint as p,resolveXiantaoToolMenusEndpoint as h}from"./config.js";import{XtzError as u}from"./errors.js";import{requestJson as a}from"./http.js";async function b(e,t,o){const r=await h(),n=new URL(`${r}/${t}`);n.searchParams.set("f",_({tool_product_uuid:o}));try{return(await a(n.toString(),{headers:await c(e),method:"GET"},{agent:e.agent})).data}catch(i){if(!(i instanceof u)||!i.message.includes("\u5DF2\u4E0B\u67B6"))throw i;const s=T(await g(e,o),t);if(s)return s;throw i}}async function g(e,t){const o=new URL(await h());return o.searchParams.set("f",_({is_all:1,tool_product_uuid:t})),(await a(o.toString(),{headers:await c(e),method:"GET"},{agent:e.agent})).data}async function L(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 m(e){return l(e)}function B(e){return m(e).map(t=>({module_id:t.code,path:t.path,route:t.route,title:t.title,uuid:t.uuid}))}function E(e,t){const o=t.trim().toLowerCase();return m(e).filter(r=>[r.code,r.title,r.path,r.route].some(i=>i.toLowerCase().includes(o))).sort((r,n)=>M(n,o)-M(r,o))}async function P(e,t){return(await a(await p(),{body:JSON.stringify({args:{id:{module_id:t.moduleId,uuid:t.uuid}},name:"public.args.fetch-all",version:"v3"}),headers:await c(e,!0),method:"POST"},{agent:e.agent})).data}async function R(e,t){return(await a(await 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:await c(e,!0),method:"POST"},{agent:e.agent})).data}function w(e){return(e.children??[]).filter(t=>!!(t.title?.trim()||t.code?.trim()))}function y(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)&&y(r)){const s=r.route?.trim(),d=r.title?.trim(),f=r.uuid?.trim();n&&s&&d&&f&&o.push({code:n,path:r.path?.trim()??"",route:s,title:d,uuid:f})}const i=w(r);i.length>0&&o.push(...l(i,t))}return o}function T(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=w(r);if(n.length>0){const i=T(n,o);if(i)return i}}}function M(e,t){let o=0;const r=e.code.toLowerCase(),n=e.title.toLowerCase(),i=e.path.toLowerCase(),s=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),i.includes(t)&&(o+=80),s.includes(t)&&(o+=40),o}function _(e){return encodeURIComponent(JSON.stringify(e))}async function c(e,t=!1){const o=await C(),r={Authorization:`Bearer ${e.token}`,origin:o,platform:"pc",referer:o,source:"PC"};return t&&(r["Content-Type"]="application/json"),r}export{c as buildXiantaoHeaders,P as fetchAllPlotArgs,b as fetchToolMenu,g as fetchToolMenus,w as getBrowsableToolMenuChildren,y as isRunnableToolMenu,m as listResolvedToolMenus,B as listToolMenuSummaries,L as resolveToolMenuByCode,E as searchResolvedToolMenus,R as updatePlotArgs};
package/dist/xtz-help.js CHANGED
@@ -3,4 +3,4 @@ $ xt tool search violin
3
3
  $ xt tool inspect violin_flat
4
4
  $ xt tool run violin_flat ./data.xlsx`],["Interactive tool run","$ xt tool run --interactive"],["Agent automation",`$ xt tool prepare violin_flat --file ./data.xlsx --profile opencode --json
5
5
  $ xt tool exec violin_flat --file ./data.xlsx --profile opencode --json
6
- $ xt tool exec gsea_customize --file gene_set=./gene_set.gmt --file data=./rank.xlsx --profile opencode --json`]])),this.log(""),this.log(this.section("COMMON COMMANDS",this.renderCommandItems([{description:"Authorize the current profile token",id:"login"},{description:"Show token auth status for the current profile",id:"status"},{description:"Delete the stored token for the current profile",id:"logout"},{description:"List history records for the current profile",id:"history:list"},{description:"Download a file from a history record",id:"history:download"},{description:"Rename a history record",id:"history:rename"},{description:"Delete a history record",id:"history:delete"},{description:"Alias of xt login under the tool topic",id:"tool:login"},{description:"Search tools by keyword",id:"tool:search"},{description:"Inspect a tool and its dynamic inputs",id:"tool:inspect"},{description:"Run a tool in human-first mode; avoid this in agent workflows",id:"tool:run"},{description:"Execute a tool in agent mode with JSON envelope output; supports --download",id:"tool:exec"},{description:"Prepare a tool and return the final dynamic schema after upload verification",id:"tool:prepare"},{description:"Download a generated result to a local file",id:"tool:download"}]))),this.log(""),this.log(this.section("LOW-LEVEL AND COMPATIBILITY",[["xt tool --help","Show the full tool command set"],["xt history --help","Show the history command set"],["xt tool resolve","Resolve a tool id to UUID and route"],["xt tool menu","Fetch one raw tool menu by UUID"],["xt tool menus","List tool titles and ids for a product"],["xt tool menus-raw","Fetch all raw tool menus for a product"],["xt tool fetch-all","Fetch raw dynamic args for a tool"],["xt tool prepare","Resolve upload-dependent dynamic schema for agent workflows"],["xt auth ...","Legacy auth topic kept for compatibility"],["xt plot ...","Legacy plot topic kept for compatibility"]])),this.log("")}renderCommandItems(o){return o.flatMap(t=>{const e=this.findCommand(t.id);return e?[[n(e.id,this.config),t.description]]:[]})}findCommand(o){return this.config.findCommand(o)}}export{r as default};
6
+ $ xt tool exec gsea_customize --file gene_set=./gene_set.gmt --file data=./rank.xlsx --profile opencode --json`]])),this.log(""),this.log(this.section("COMMON COMMANDS",this.renderCommandItems([{description:"Log in and store the current profile token",id:"login"},{description:"Show token auth status for the current profile",id:"status"},{description:"Delete the stored token for the current profile",id:"logout"},{description:"List history records for the current profile",id:"history:list"},{description:"Download a file from a history record",id:"history:download"},{description:"Rename a history record",id:"history:rename"},{description:"Delete a history record",id:"history:delete"},{description:"Alias of xt login under the tool topic",id:"tool:login"},{description:"Search tools by keyword",id:"tool:search"},{description:"Inspect a tool and its dynamic inputs",id:"tool:inspect"},{description:"Run a tool in human-first mode; avoid this in agent workflows",id:"tool:run"},{description:"Execute a tool in agent mode with JSON envelope output; supports --download",id:"tool:exec"},{description:"Prepare a tool and return the final dynamic schema after upload verification",id:"tool:prepare"},{description:"Download a generated result to a local file",id:"tool:download"}]))),this.log(""),this.log(this.section("LOW-LEVEL AND COMPATIBILITY",[["xt tool --help","Show the full tool command set"],["xt history --help","Show the history command set"],["xt tool resolve","Resolve a tool id to UUID and route"],["xt tool menu","Fetch one raw tool menu by UUID"],["xt tool menus","List tool titles and ids for a product"],["xt tool menus-raw","Fetch all raw tool menus for a product"],["xt tool fetch-all","Fetch raw dynamic args for a tool"],["xt tool prepare","Resolve upload-dependent dynamic schema for agent workflows"],["xt auth ...","Legacy auth topic kept for compatibility"],["xt plot ...","Legacy plot topic kept for compatibility"]])),this.log("")}renderCommandItems(o){return o.flatMap(t=>{const e=this.findCommand(t.id);return e?[[n(e.id,this.config),t.description]]:[]})}findCommand(o){return this.config.findCommand(o)}}export{r as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helixlife-ai/xiantao",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "description": "CLI for Xiantao bioinformatics tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -49,6 +49,9 @@
49
49
  "auth": {
50
50
  "description": "Compatibility commands for the legacy auth topic"
51
51
  },
52
+ "config": {
53
+ "description": "Manage Xiantao CLI configuration"
54
+ },
52
55
  "tool": {
53
56
  "description": "Xiantao bioinformatics tool commands"
54
57
  },
@@ -62,7 +65,8 @@
62
65
  },
63
66
  "dependencies": {
64
67
  "@oclif/core": "^4.9.0",
65
- "@oclif/plugin-autocomplete": "^3.2.41"
68
+ "@oclif/plugin-autocomplete": "^3.2.41",
69
+ "playwright": "^1.61.0"
66
70
  },
67
71
  "devDependencies": {
68
72
  "@types/node": "^25.5.0",
@@ -1,9 +0,0 @@
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
- <html lang="zh-CN">
3
- <head><meta charset="utf-8"><title>\u767B\u5F55\u6210\u529F</title></head>
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>
5
- </html>`,P=`<!doctype html>
6
- <html lang="zh-CN">
7
- <head><meta charset="utf-8"><title>\u767B\u5F55\u5931\u8D25</title></head>
8
- <body><p>\u672A\u83B7\u53D6\u5230 token\uFF0C\u8BF7\u5173\u95ED\u6B64\u9875\u9762\u5E76\u56DE\u5230\u7EC8\u7AEF\u91CD\u8BD5\u3002</p></body>
9
- </html>`;export{T as bindUserWithStoredXiantaoToken,y as getXiantaoAuthContext,h as loadXiantaoAuthContext,C as loginXiantao};