@helixlife-ai/xiantao 0.1.27 → 0.1.28

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.
@@ -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";import{getUpdateReminder as h}from"./lib/update.js";class f extends n{async init(){await super.init(),await this.warnIfUpdateAvailable()}async getProfile(t){return l(t)}async getAgent(t){return this.getProfile(t)}print(t,e,r,i){if(t.json){if(i){this.log(JSON.stringify(o(i.profile,i.command??this.getCommandName(),e),null,2));return}this.log(JSON.stringify(e,null,2));return}this.log(r)}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}\``)}async warnIfUpdateAvailable(){if(this.argv.includes("--json")||!process.stdout.isTTY||this.shouldSkipUpdateReminder())return;const t=await h(this.config.version);t&&this.warn(t)}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)}}shouldSkipUpdateReminder(){const t=this.id??"";return["login","logout","status","auth:login","auth:logout","auth:status","plot:login","plot:run","tool:exec","tool:login","tool:prepare","tool:run"].includes(t)}}export{f as XtzCommand};
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{promptForUpdate as r}from"../../lib/update.js";const e=async({argv:s,config:t,context:o})=>{if(s.includes("--json")||!process.stdin.isTTY||!process.stdout.isTTY||!process.stderr.isTTY)return;await r(t.version)==="updated"&&o.exit(0)};var d=e;export{d as default};
@@ -1,2 +1,14 @@
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
+ import{spawn as N}from"node:child_process";import{mkdir as C,readFile as S,writeFile as P}from"node:fs/promises";import U from"node:os";import g from"node:path";import{stdin as $,stderr as o}from"node:process";import b from"node:readline/promises";import{XTZ_UPDATE_CHECK_PATH as _}from"./constants.js";import{debugHttpError as x,debugHttpRequest as T,debugHttpResponse as v}from"./debug.js";import{XtzError as k}from"./errors.js";import{isJsonObject as A}from"./json.js";const u="@helixlife-ai/xiantao",l=`https://registry.npmjs.org/${encodeURIComponent(u)}/latest`,O="https://github.com/helixlife-ai/xiantao-cli/releases/latest",I=1200,f=`npm install -g ${u}`;async function ee(n){const e=await L(n);if(!e)return;const t=await R(n,e.latestVersion);return t==="skip"?"skipped":t==="skip-version"?(await E({lastCheckedAt:e.lastCheckedAt,latestVersion:e.latestVersion,skippedVersion:e.latestVersion}),"skipped"):(await H(),o.write(`
2
+ Update complete. Please run xt again.
3
+ `),"updated")}async function L(n){try{const e=await D(),t=new Date().toISOString(),r=await M();return await E({lastCheckedAt:t,latestVersion:r??e.latestVersion,skippedVersion:e.skippedVersion}),!r||j(r,n)<=0||e.skippedVersion===r?void 0:{lastCheckedAt:t,latestVersion:r}}catch{return}}async function M(){const n={headers:{accept:"application/json"},signal:AbortSignal.timeout(I)};T(l,n);let e;try{e=await fetch(l,n)}catch(i){throw x(l,i),i}const t=await e.text();if(v(l,e,t),!e.ok)return;const r=JSON.parse(t);if(!(!A(r)||typeof r.version!="string"))return r.version.trim()||void 0}async function R(n,e){const t=b.createInterface({input:$,output:o});try{for(o.write(`
4
+ \u2728 Update available! ${n} -> ${e}
5
+
6
+ `),o.write(` Release notes: ${O}
7
+
8
+ `),o.write(`\u203A 1. Update now (runs \`${f}\`)
9
+ `),o.write(` 2. Skip
10
+ `),o.write(` 3. Skip until next version
11
+
12
+ `);;){const r=(await t.question("Select an option: ")).trim();if(r==="1")return"update";if(r===""||r==="2")return"skip";if(r==="3")return"skip-version";o.write(`Invalid option: ${r}
13
+ `)}}finally{t.close()}}async function H(){const n=process.platform==="win32"?"npm.cmd":"npm",e=N(n,["install","-g",u],{stdio:"inherit"});await new Promise((t,r)=>{e.on("error",i=>{r(new k(`\u66F4\u65B0\u5931\u8D25: \u65E0\u6CD5\u6267\u884C \`${f}\`: ${i.message}`))}),e.on("close",(i,a)=>{if(i===0){t();return}r(new k(`\u66F4\u65B0\u5931\u8D25: \`${f}\` ${J(i,a)}`))})})}async function D(){const n=y();try{const e=await S(n,"utf8"),t=JSON.parse(e);return A(t)?{lastCheckedAt:typeof t.lastCheckedAt=="string"?t.lastCheckedAt:void 0,latestVersion:typeof t.latestVersion=="string"?t.latestVersion:void 0,skippedVersion:typeof t.skippedVersion=="string"?t.skippedVersion:void 0}:{}}catch(e){if(q(e)&&e.code==="ENOENT")return{};throw e}}async function E(n){const e=y();await C(g.dirname(e),{recursive:!0}),await P(e,`${JSON.stringify(n,null,2)}
14
+ `,"utf8")}function J(n,e){return n!==null?`\u9000\u51FA\u7801 ${n}`:e?`\u88AB ${e} \u7EC8\u6B62`:"\u672A\u6B63\u5E38\u7ED3\u675F"}function j(n,e){const t=V(n),r=V(e);if(!t||!r)return n.localeCompare(e);const i=Math.max(t.core.length,r.core.length);for(let s=0;s<i;s+=1){const c=(t.core[s]??0)-(r.core[s]??0);if(c!==0)return c}if(t.prerelease.length===0&&r.prerelease.length===0)return 0;if(t.prerelease.length===0)return 1;if(r.prerelease.length===0)return-1;const a=Math.max(t.prerelease.length,r.prerelease.length);for(let s=0;s<a;s+=1){const c=t.prerelease[s],p=r.prerelease[s];if(c===void 0)return-1;if(p===void 0)return 1;const d=/^[0-9]+$/.test(c),m=/^[0-9]+$/.test(p);if(d&&m){const w=Number(c)-Number(p);if(w!==0)return w;continue}if(d)return-1;if(m)return 1;const h=c.localeCompare(p);if(h!==0)return h}return 0}function V(n){const e=n.trim().replace(/^v/,"");if(!e)return;const[t,r]=e.split("-",2),i=t.split(".").map(a=>Number.parseInt(a,10));if(!i.some(a=>Number.isNaN(a)))return{core:i,prerelease:r?r.split(".").filter(Boolean):[]}}function y(){return g.join(U.homedir(),_)}function q(n){return n instanceof Error&&"code"in n}export{ee as promptForUpdate};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helixlife-ai/xiantao",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
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",