@helixlife-ai/xiantao 0.1.23 → 0.1.25
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 +46 -9
- package/dist/commands/auth/login.js +3 -2
- package/dist/commands/auth/status.js +1 -1
- package/dist/commands/config/get.js +1 -0
- package/dist/commands/config/set.js +2 -0
- package/dist/commands/history/save.js +1 -0
- package/dist/commands/plot/fetch-all.js +1 -1
- package/dist/commands/plot/login.js +3 -2
- package/dist/commands/plot/run.js +4 -4
- package/dist/commands/tool/inspect.js +3 -3
- package/dist/lib/auth.js +1 -1
- package/dist/lib/config.js +2 -0
- package/dist/lib/constants.js +1 -1
- package/dist/lib/debug.js +3 -0
- package/dist/lib/download.js +1 -1
- package/dist/lib/history.js +1 -1
- package/dist/lib/http.js +1 -1
- package/dist/lib/login-flow.js +1 -1
- package/dist/lib/plot-interactive.js +18 -18
- package/dist/lib/plot-options.js +1 -1
- package/dist/lib/plot.js +1 -1
- package/dist/lib/special-args.js +1 -0
- package/dist/lib/storage.js +2 -2
- package/dist/lib/update.js +2 -2
- package/dist/lib/xiantao-cloud.js +1 -1
- package/dist/lib/xiantao-plot.js +1 -1
- package/dist/lib/xiantao.js +1 -1
- package/dist/xtz-help.js +1 -1
- package/package.json +6 -2
- package/dist/lib/xiantao-auth.js +0 -9
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
|
|
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
|
|
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
|
|
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
|
|
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`
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
2
|
-
`)
|
|
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
|
|
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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Args as e,Flags as n}from"@oclif/core";import{XtzCommand as d}from"../../base-command.js";import{getAuthContext as u}from"../../lib/auth.js";import{globalFlags as l}from"../../lib/flags.js";import{saveXiantaoOutput as m}from"../../lib/xiantao-plot.js";class a extends d{static description="Save a direct analysis result to history";static args={fuid:e.string({description:"Result fuid returned by tool exec",required:!0}),uuid:e.string({description:"Tool UUID used in the analysis",required:!0}),moduleId:e.string({description:"Module id, e.g. gokegg_analysis",required:!0}),name:e.string({description:"Name to save the record as",required:!0})};static flags={...l,token:n.string({description:"Bearer token for agent.helixlife.cn xiantao APIs; falls back to the stored agent token"})};async run(){const{args:t,flags:i}=await this.parse(a),r=await this.getProfile(i.profile),o=await u(r,i.token);await m(o,{fuid:t.fuid,moduleId:t.moduleId,name:t.name,uuid:t.uuid});const s={agent:r,fuid:t.fuid,module_id:t.moduleId,name:t.name,uuid:t.uuid};this.print(i,s,`\u5DF2\u4FDD\u5B58: ${t.name}`,{command:"history save",profile:r})}}export{a as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Args as
|
|
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
|
|
2
|
-
`)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2
|
-
`);
|
|
3
|
-
`)}summarizeInputs(e,
|
|
1
|
+
import{Args as $,Flags as h}from"@oclif/core";import{XtzCommand as b}from"../../base-command.js";import{getAuthContext as y}from"../../lib/auth.js";import{globalFlags as k}from"../../lib/flags.js";import{isJsonObject as q}from"../../lib/json.js";import{buildArgsMainFromSchema as 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{
|
|
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};
|
package/dist/lib/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const A="opencode",e=".config/xtz/config.json",t=".config/xtz/update-check.json",c=".config/xiantao/config.json",_="https://vip.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};
|
package/dist/lib/download.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
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};
|
package/dist/lib/history.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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
|
|
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};
|
package/dist/lib/login-flow.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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
|
|
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=
|
|
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
|
|
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=
|
|
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
|
|
16
|
-
`)}}}finally{n.close()}}async function
|
|
17
|
-
\u8F93\u5165\u5F85\u4E0A\u4F20\u7684 xlsx \u6587\u4EF6\u8DEF\u5F84\uFF0C\u56DE\u8F66\u53D6\u6D88: `)).trim();if(!e)throw new a("\u5DF2\u53D6\u6D88\u6587\u4EF6\u9009\u62E9\u3002");return e}}finally{t.close()}}async function
|
|
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
|
|
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}. ${
|
|
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
|
|
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(!
|
|
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?
|
|
34
|
-
`)}}async function k(t,e,n){for(;;)try{const r=e
|
|
35
|
-
`),
|
|
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
|
|
37
|
-
`)})}function b(t){if(t==="<")return{type:"back"};if(t==="/skip")return{type:"skip"}}function
|
|
38
|
-
`),n.forEach(r=>{const i=$(r);s.write(` ${
|
|
39
|
-
`)}))}function
|
|
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};
|
package/dist/lib/plot-options.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Flags as
|
|
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
|
|
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};
|
package/dist/lib/storage.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{mkdir as _,readFile as a,rm as
|
|
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
|
|
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};
|
package/dist/lib/update.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{mkdir as
|
|
2
|
-
`,"utf8")}function
|
|
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{
|
|
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};
|
package/dist/lib/xiantao-plot.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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};
|
package/dist/lib/xiantao.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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:"
|
|
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.
|
|
3
|
+
"version": "0.1.25",
|
|
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",
|
package/dist/lib/xiantao-auth.js
DELETED
|
@@ -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};
|