@helixlife-ai/xiantao 0.1.32 → 0.1.34
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 +8 -1
- package/dist/base-command.js +1 -1
- package/dist/commands/config/get.js +1 -0
- package/dist/commands/config/set.js +2 -0
- package/dist/hooks/init/update.js +2 -0
- 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/encrypt.js +1 -0
- package/dist/lib/history.js +1 -1
- package/dist/lib/http.js +1 -1
- package/dist/lib/plot.js +1 -1
- 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 +8 -1
package/README.md
CHANGED
|
@@ -104,6 +104,13 @@ For agent workflows, do not use `xt tool run`. Treat `xt tool run` as the human-
|
|
|
104
104
|
- `xt logout`
|
|
105
105
|
- `xt tool login`
|
|
106
106
|
|
|
107
|
+
### Config
|
|
108
|
+
|
|
109
|
+
- `xt config get base-url`
|
|
110
|
+
- `xt config set base-url https://agent.helixlife.cn`
|
|
111
|
+
- `xt config get login-url`
|
|
112
|
+
- `xt config set login-url https://www.helixlife.net/`
|
|
113
|
+
|
|
107
114
|
### History
|
|
108
115
|
|
|
109
116
|
- `xt history list`
|
|
@@ -135,7 +142,7 @@ For agent workflows, do not use `xt tool run`. Treat `xt tool run` as the human-
|
|
|
135
142
|
|
|
136
143
|
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`.
|
|
137
144
|
|
|
138
|
-
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.
|
|
145
|
+
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 resolved login page value. The same values can be stored with `xt config set base-url ...` and `xt config set login-url ...`; environment variables take precedence over `~/.config/xiantao/config.json`. Set `DEBUG_MODE=1` to print HTTP request and response debug payloads to stderr.
|
|
139
146
|
|
|
140
147
|
`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.
|
|
141
148
|
|
package/dist/base-command.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Command as n}from"@oclif/core";import{createErrorEnvelope as s,createSuccessEnvelope as o}from"./lib/envelope.js";import{XtzError as a}from"./lib/errors.js";import{resolveAgent as l}from"./lib/storage.js";
|
|
1
|
+
import{Command as n}from"@oclif/core";import{createErrorEnvelope as s,createSuccessEnvelope as o}from"./lib/envelope.js";import{XtzError as a}from"./lib/errors.js";import{resolveAgent as l}from"./lib/storage.js";class u extends n{async getProfile(t){return l(t)}async getAgent(t){return this.getProfile(t)}print(t,e,i,r){if(t.json){if(r){this.log(JSON.stringify(o(r.profile,r.command??this.getCommandName(),e),null,2));return}this.log(JSON.stringify(e,null,2));return}this.log(i)}async catch(t){if(this.isJsonOutputRequested()){const e=await this.getProfile(this.readProfileFlagFromArgv());this.log(JSON.stringify(s(e,this.getCommandName(),t),null,2)),this.exit(1)}throw t instanceof a&&this.error(t.message,{exit:1}),t}warnIfLegacyPlotCommand(){if(!this.id?.startsWith("plot:")||this.argv.includes("--json"))return;const t=this.id.replaceAll(":"," "),e=t.replace(/^plot\b/,"tool");this.warn(`\`xt ${t}\` \u5DF2\u517C\u5BB9\u4FDD\u7559\uFF0C\u5EFA\u8BAE\u6539\u7528 \`xt ${e}\``)}warnIfLegacyAuthCommand(){if(!this.id?.startsWith("auth:")||this.argv.includes("--json"))return;const t=this.id.replaceAll(":"," "),e=t.replace(/^auth /,"");this.warn(`\`xt ${t}\` \u5DF2\u517C\u5BB9\u4FDD\u7559\uFF0C\u5EFA\u8BAE\u6539\u7528 \`xt ${e}\``)}getCommandName(){return this.id?.replaceAll(":"," ")??"unknown"}isJsonOutputRequested(){return this.argv.includes("--json")}readProfileFlagFromArgv(){for(let t=0;t<this.argv.length;t+=1){const e=this.argv[t];if((e==="--profile"||e==="--agent")&&this.argv[t+1])return this.argv[t+1];if(e.startsWith("--profile="))return e.slice(10);if(e.startsWith("--agent="))return e.slice(8)}}}export{u as XtzCommand};
|
|
@@ -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,2 @@
|
|
|
1
|
+
import{spawn as m}from"node:child_process";import{stdin as c,stdout as a}from"node:process";import u from"node:readline/promises";import{getAvailableUpdate as p}from"../../lib/update.js";const f=async function({argv:t,config:o}){if(t.includes("--json")||!c.isTTY||!a.isTTY)return;const e=await p(o.version);if(!e)return;a.write(`\u68C0\u6D4B\u5230\u65B0\u7248\u672C ${e.latestVersion}\uFF08\u5F53\u524D ${e.currentVersion}\uFF09\u3002
|
|
2
|
+
`);const r=u.createInterface({input:c,output:a});let n;try{n=(await r.question("\u662F\u5426\u7ACB\u5373\u5B89\u88C5\u6700\u65B0\u7248? [y/N] ")).trim().toLowerCase()}finally{r.close()}if(n!=="y"&&n!=="yes")return;const[i,...l]=e.installCommand,s=await d(i,l);s!==0&&this.error(`\u66F4\u65B0\u5B89\u88C5\u5931\u8D25\uFF0C\u9000\u51FA\u7801 ${s}\u3002`,{exit:s}),this.log("\u66F4\u65B0\u5B89\u88C5\u5B8C\u6210\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C\u547D\u4EE4\u3002"),this.exit(0)};async function d(t,o){return new Promise((e,r)=>{const n=m(w(t),o,{stdio:"inherit"});n.on("error",r),n.on("close",i=>e(i??1))})}function w(t){return process.platform==="win32"&&t==="npm"?"npm.cmd":t}var T=f;export{T as default};
|
package/dist/lib/auth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{debugHttpError as m,debugHttpRequest as k,debugHttpResponse as h}from"./debug.js";import{resolveAuthUrlEndpoint as d,resolveCheckTokenEndpoint as u}from"./config.js";import{XtzError as a}from"./errors.js";import{openUrl as f}from"./open-url.js";import{requestJson as l}from"./http.js";import{loadToken as y,requireToken as w,saveToken as g}from"./storage.js";async function T(t){const e=await y(t),o=await l(await d(),{headers:i(e)},{agent:t}),r=new URL(o.data.link_url);return r.searchParams.set("source",t),{linkUrl:r.toString(),tokenKey:o.data.token_key}}async function M(t,e=!0){const{linkUrl:o,tokenKey:r}=await T(t),s=await g(t,r);return{browserOpened:e?await f(o):!1,linkUrl:o,token:r,tokenPath:s}}async function R(t,e){const o=e?.trim()||await w(t);return{agent:t,token:o}}async function q(t,e){const o=e??await w(t),r=new URL(await u());return r.searchParams.set("token_key",o),(await l(r.toString(),{headers:i(o)},{agent:t})).data}async function z(t,e={}){const o=e.timeoutMs??12e4,r=e.intervalMs??1500,s=Date.now()+o;let n="";for(;Date.now()<s;){const c=await x(t);if(c.success)return;n=c.message?.trim()||n,await new Promise(p=>setTimeout(p,r))}throw new a(n?`\u7B49\u5F85\u6388\u6743\u5B8C\u6210\u8D85\u65F6: ${n}`:"\u7B49\u5F85\u6388\u6743\u5B8C\u6210\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C `xt login`\u3002")}async function x(t){const e=new URL(await u());e.searchParams.set("token_key",t);const o={headers:i(t)};let r;k(e.toString(),o);try{r=await fetch(e.toString(),o)}catch(n){throw m(e.toString(),n),new a("\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}const s=await r.text();h(e.toString(),r,s);try{const n=JSON.parse(s);return{message:n.message,success:r.ok&&n.success!==!1}}catch{throw new a("\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002")}}function i(t){const e={platform:"pc",source:"PC"};return t?.trim()&&(e.Authorization=`Bearer ${t.trim()}`),e}export{q as checkToken,T as fetchAuthLink,R as getAuthContext,M as loginAuth,z as waitForAuthorizedToken};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{mkdir as m,readFile as v,writeFile as U}from"node:fs/promises";import y from"node:os";import l from"node:path";import{DEFAULT_XIANTAO_BASE_URL as A,DEFAULT_XIANTAO_LOGIN_URL as E,XIANTAO_CONFIG_PATH as L}from"./constants.js";import{XtzError as r}from"./errors.js";import{isJsonObject as b}from"./json.js";const s=["base-url","login-url"];function c(){return l.join(y.homedir(),L)}async function V(t,n){const e=g(t),o=h(e,n),i=c(),a=await p(i);return a[e]=o,await m(l.dirname(i),{recursive:!0}),await U(i,`${JSON.stringify(a,null,2)}
|
|
2
|
+
`,"utf8"),{key:e,path:i,value:o}}async function f(t){const n=g(t),e=c(),o=X(n);if(o)return{key:n,path:e,source:"environment",value:o};const a=(await p(e))[n]?.trim();return a?{key:n,path:e,source:"config",value:h(n,a)}:{key:n,path:e,source:"default",value:_(n)}}async function N(){return(await f("base-url")).value}async function z(){return(await f("login-url")).value}async function B(){return u("agent/skills/auth-url")}async function F(){return u("agent/skills/check-token")}async function S(){return u("agent/bio-api")}async function k(){return u("agent/tool/menus")}async function K(){const t=new URL(await u("agent/upload/config"));return t.searchParams.set("type","bio"),t.searchParams.set("oss_type","bio"),t.toString()}async function u(t){const n=await N();return`${n.endsWith("/api/v1")?n:`${n}/api/v1`}/${t}`}async function p(t){try{const n=await v(t,"utf8"),e=JSON.parse(n);if(!b(e))throw new r(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u4E0D\u6B63\u786E: ${t}`);const o=e["base-url"];if(o!==void 0&&typeof o!="string")throw new r(`\u914D\u7F6E\u9879 base-url \u5FC5\u987B\u662F\u5B57\u7B26\u4E32: ${t}`);const i=e["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 e}catch(n){if(O(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 h(t,n){const e=n.trim();if(!e)throw new r(`\u914D\u7F6E\u9879 ${t} \u4E0D\u80FD\u4E3A\u7A7A`);return t==="base-url"?w(e):t==="login-url"?d(e):e}function X(t){if(t==="base-url"){const n=process.env.XIANTAO_BASE_URL?.trim();return n?w(n):void 0}if(t==="login-url"){const n=process.env.XIANTAO_LOGIN_URL?.trim();return n?d(n):void 0}}function _(t){if(t==="base-url")return A;if(t==="login-url")return E;throw new r(`\u4E0D\u652F\u6301\u7684\u914D\u7F6E\u9879 ${t}`)}function w(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://agent.helixlife.cn")}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new r("base-url \u53EA\u652F\u6301 http \u6216 https");return t.replace(/\/+$/,"")}function d(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://www.helixlife.net/")}if(n.protocol!=="http:"&&n.protocol!=="https:")throw new r("login-url \u53EA\u652F\u6301 http \u6216 https");return t}function O(t){return t instanceof Error&&"code"in t}export{s as XIANTAO_CONFIG_KEYS,c as getXiantaoConfigPath,B as resolveAuthUrlEndpoint,F as resolveCheckTokenEndpoint,K as resolveUploadConfigEndpoint,N as resolveXiantaoBaseUrl,S as resolveXiantaoBioApiEndpoint,f as resolveXiantaoConfigValue,z as resolveXiantaoLoginUrl,k as resolveXiantaoToolMenusEndpoint,V as setXiantaoConfigValue};
|
package/dist/lib/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e="opencode",
|
|
1
|
+
const e="opencode",t=".config/xtz/config.json",A=".config/xtz/update-check.json",c=".config/xiantao/config.json",_="https://agent.helixlife.cn"?.trim(),o=process.env.XTZ_BUILD_XIANTAO_LOGIN_URL?.trim(),n=(_||"https://agent.helixlife.cn").replace(/\/+$/,""),T=o||"https://agent.helixlife.cn/",I="c0b6febb-52dd-4525-970a-61bbe9e263ff",U="2d491694-8c8d-11ee-9409-00163e118c99";export{e as DEFAULT_AGENT,n as DEFAULT_XIANTAO_BASE_URL,T as DEFAULT_XIANTAO_LOGIN_URL,I as DEFAULT_XIANTAO_TOOL_PRODUCT_UUID,c as XIANTAO_CONFIG_PATH,U as XIANTAO_HISTORY_UUID,t as XTZ_CONFIG_PATH,A 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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Buffer as e}from"node:buffer";const n={encryption(r){return e.from(encodeURI(JSON.stringify(r)),"utf8").toString("base64").replace(/=/g,"")}};export{n as encrypt};
|
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/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{debugHttpError as _,debugHttpRequest as O,debugHttpResponse as P}from"./debug.js";import{resolveUploadConfigEndpoint as $,resolveXiantaoBioApiEndpoint as p}from"./config.js";import{XtzError as l}from"./errors.js";import{requestJson as u}from"./http.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"};O(t.host,m);let c;try{c=await fetch(t.host,m)}catch(f){throw _(t.host,f),f}const b=await c.text();if(P(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};
|
package/dist/lib/update.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{mkdir as C,readFile as A,writeFile as E}from"node:fs/promises";import w from"node:os";import d from"node:path";import{XTZ_UPDATE_CHECK_PATH as P}from"./constants.js";import{isJsonObject as m}from"./json.js";const h="@helixlife-ai/xiantao",V=`https://registry.npmjs.org/${encodeURIComponent(h)}/latest`,_=720*60*1e3,y=1200;async function D(e){try{const t=await
|
|
2
|
-
`,"utf8")}function U(e,t){const r=g(e),n=g(t);if(!r||!n)return e.localeCompare(t);const
|
|
1
|
+
import{mkdir as C,readFile as A,writeFile as E}from"node:fs/promises";import w from"node:os";import d from"node:path";import{XTZ_UPDATE_CHECK_PATH as P}from"./constants.js";import{isJsonObject as m}from"./json.js";const h="@helixlife-ai/xiantao",V=`https://registry.npmjs.org/${encodeURIComponent(h)}/latest`,_=720*60*1e3,y=1200;async function D(e){try{const t=await b(),r=await k(t);return!r||U(r,e)<=0?void 0:{currentVersion:e,installCommand:["npm","install","-g",`${h}@latest`],latestVersion:r}}catch{return}}async function k(e){const t=Date.now(),r=e.lastCheckedAt?Date.parse(e.lastCheckedAt):Number.NaN;if(Number.isFinite(r)&&t-r<_)return e.latestVersion?.trim()||void 0;const n=await S();return await T({lastCheckedAt:new Date(t).toISOString(),latestVersion:n??e.latestVersion}),n??(e.latestVersion?.trim()||void 0)}async function S(){const e=await fetch(V,{headers:{accept:"application/json"},signal:AbortSignal.timeout(y)});if(!e.ok)return;const t=JSON.parse(await e.text());if(!(!m(t)||typeof t.version!="string"))return t.version.trim()||void 0}async function b(){const e=N();try{const t=await A(e,"utf8"),r=JSON.parse(t);return m(r)?{lastCheckedAt:typeof r.lastCheckedAt=="string"?r.lastCheckedAt:void 0,latestVersion:typeof r.latestVersion=="string"?r.latestVersion:void 0}:{}}catch(t){if(x(t)&&t.code==="ENOENT")return{};throw t}}async function T(e){const t=N();await C(d.dirname(t),{recursive:!0}),await E(t,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,"utf8")}function U(e,t){const r=g(e),n=g(t);if(!r||!n)return e.localeCompare(t);const o=Math.max(r.core.length,n.core.length);for(let a=0;a<o;a+=1){const i=(r.core[a]??0)-(n.core[a]??0);if(i!==0)return i}if(r.prerelease.length===0&&n.prerelease.length===0)return 0;if(r.prerelease.length===0)return 1;if(n.prerelease.length===0)return-1;const s=Math.max(r.prerelease.length,n.prerelease.length);for(let a=0;a<s;a+=1){const i=r.prerelease[a],c=n.prerelease[a];if(i===void 0)return-1;if(c===void 0)return 1;const l=/^[0-9]+$/.test(i),f=/^[0-9]+$/.test(c);if(l&&f){const p=Number(i)-Number(c);if(p!==0)return p;continue}if(l)return-1;if(f)return 1;const u=i.localeCompare(c);if(u!==0)return u}return 0}function g(e){const t=e.trim().replace(/^v/,"");if(!t)return;const[r,n]=t.split("-",2),o=r.split(".").map(s=>Number.parseInt(s,10));if(!o.some(s=>Number.isNaN(s)))return{core:o,prerelease:n?n.split(".").filter(Boolean):[]}}function N(){return d.join(w.homedir(),P)}function x(e){return e instanceof Error&&"code"in e}export{D as getAvailableUpdate};
|
|
@@ -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 y,resolveXiantaoBioApiEndpoint as p,resolveXiantaoToolMenusEndpoint as h}from"./config.js";import{encrypt as C}from"./encrypt.js";import{XtzError as l}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 l)||!i.message.includes("\u5DF2\u4E0B\u67B6"))throw i;const s=T(await m(e,o),t);if(s)return s;throw i}}async function m(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 E(e,t,o){const r=o.trim(),n=u(await m(e,t),r);if(n.length===0)throw new l(`\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 l(`\u6A21\u5757 ${r} \u5339\u914D\u5230\u591A\u4E2A\u7ED3\u679C\uFF0C\u8BF7\u6539\u7528 \`--uuid\` \u663E\u5F0F\u6307\u5B9A\u3002`);return n[0]}function g(e){return u(e)}function P(e){return g(e).map(t=>({module_id:t.code,path:t.path,route:t.route,title:t.title}))}function z(e,t){const o=t.trim().toLowerCase();return g(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 A(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 x(e){return!!(e.code?.trim()&&e.route?.trim()&&e.title?.trim()&&e.uuid?.trim())}function u(e,t){const o=[];for(const r of e){const n=r.code?.trim();if((!t||n===t)&&x(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(...u(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 C.encryption(e)}async function c(e,t=!1){const o=await y(),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,A as fetchAllPlotArgs,B as fetchToolMenu,m as fetchToolMenus,w as getBrowsableToolMenuChildren,x as isRunnableToolMenu,g as listResolvedToolMenus,P as listToolMenuSummaries,E as resolveToolMenuByCode,z as searchResolvedToolMenus,R as updatePlotArgs};
|
package/dist/xtz-help.js
CHANGED
|
@@ -3,4 +3,4 @@ $ xt tool search violin
|
|
|
3
3
|
$ xt tool inspect violin_flat
|
|
4
4
|
$ xt tool run violin_flat ./data.xlsx`],["Interactive tool run","$ xt tool run --interactive"],["Agent automation",`$ xt tool prepare violin_flat --file ./data.xlsx --profile opencode --json
|
|
5
5
|
$ xt tool exec violin_flat --file ./data.xlsx --profile opencode --json
|
|
6
|
-
$ xt tool exec gsea_customize --file gene_set=./gene_set.gmt --file data=./rank.xlsx --profile opencode --json`]])),this.log(""),this.log(this.section("COMMON COMMANDS",this.renderCommandItems([{description:"Authorize the current profile token",id:"login"},{description:"Show token auth status for the current profile",id:"status"},{description:"Delete the stored token for the current profile",id:"logout"},{description:"List history records for the current profile",id:"history:list"},{description:"Download a file from a history record",id:"history:download"},{description:"Rename a history record",id:"history:rename"},{description:"Delete a history record",id:"history:delete"},{description:"Alias of xt login under the tool topic",id:"tool:login"},{description:"Search tools by keyword",id:"tool:search"},{description:"Inspect a tool and its dynamic inputs",id:"tool:inspect"},{description:"Run a tool in human-first mode; avoid this in agent workflows",id:"tool:run"},{description:"Execute a tool in agent mode with JSON envelope output; supports --download",id:"tool:exec"},{description:"Prepare a tool and return the final dynamic schema after upload verification",id:"tool:prepare"},{description:"Download a generated result to a local file",id:"tool:download"}]))),this.log(""),this.log(this.section("LOW-LEVEL AND COMPATIBILITY",[["xt tool --help","Show the full tool command set"],["xt history --help","Show the history command set"],["xt tool resolve","Resolve a tool id to UUID and route"],["xt tool menu","Fetch one raw tool menu by UUID"],["xt tool menus","List tool titles and ids for a product"],["xt tool menus-raw","Fetch all raw tool menus for a product"],["xt tool fetch-all","Fetch raw dynamic args for a tool"],["xt tool prepare","Resolve upload-dependent dynamic schema for agent workflows"],["xt auth ...","Legacy auth topic kept for compatibility"],["xt plot ...","Legacy plot topic kept for compatibility"]])),this.log("")}renderCommandItems(o){return o.flatMap(t=>{const e=this.findCommand(t.id);return e?[[n(e.id,this.config),t.description]]:[]})}findCommand(o){return this.config.findCommand(o)}}export{r as default};
|
|
6
|
+
$ xt tool exec gsea_customize --file gene_set=./gene_set.gmt --file data=./rank.xlsx --profile opencode --json`]])),this.log(""),this.log(this.section("COMMON COMMANDS",this.renderCommandItems([{description:"Authorize the current profile token",id:"login"},{description:"Show token auth status for the current profile",id:"status"},{description:"Delete the stored token for the current profile",id:"logout"},{description:"Get a resolved Xiantao config value",id:"config:get"},{description:"Set a Xiantao config value",id:"config:set"},{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.34",
|
|
4
4
|
"description": "CLI for Xiantao bioinformatics tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -40,6 +40,9 @@
|
|
|
40
40
|
],
|
|
41
41
|
"dirname": "xiantao",
|
|
42
42
|
"helpClass": "./dist/xtz-help.js",
|
|
43
|
+
"hooks": {
|
|
44
|
+
"init": "./dist/hooks/init/update.js"
|
|
45
|
+
},
|
|
43
46
|
"topicSeparator": " ",
|
|
44
47
|
"commands": {
|
|
45
48
|
"strategy": "pattern",
|
|
@@ -49,6 +52,9 @@
|
|
|
49
52
|
"auth": {
|
|
50
53
|
"description": "Compatibility commands for the legacy auth topic"
|
|
51
54
|
},
|
|
55
|
+
"config": {
|
|
56
|
+
"description": "Manage Xiantao CLI configuration"
|
|
57
|
+
},
|
|
52
58
|
"tool": {
|
|
53
59
|
"description": "Xiantao bioinformatics tool commands"
|
|
54
60
|
},
|
|
@@ -61,6 +67,7 @@
|
|
|
61
67
|
}
|
|
62
68
|
},
|
|
63
69
|
"dependencies": {
|
|
70
|
+
"@helixlife-ai/xiantao": "^0.1.24",
|
|
64
71
|
"@oclif/core": "^4.9.0",
|
|
65
72
|
"@oclif/plugin-autocomplete": "^3.2.41"
|
|
66
73
|
},
|