wyrm-mcp 9.3.0 → 9.3.1
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/dist/license-refresh.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFileSync as C,writeFileSync as X,mkdirSync as q,existsSync as I,chmodSync as Q}from"fs";import{createHash as le}from"crypto";import{homedir as fe}from"os";import{join as L,dirname as de}from"path";import{fileURLToPath as pe}from"url";import{getLicenseInfo as N,activateLicense as Z,reconcileLicenseState as he,applyLoadedLicense as ee,loadLicense as te,verifyLicense as me,tierRank as O,PAID_TIERS as x}from"./license.js";import{refreshRevocations as ke}from"./revocations.js";const ye=336*60*60*1e3,we=720*60*60*1e3;function P(){return process.env.WYRM_HOME??L(fe(),".wyrm")}function ne(){return L(P(),"account-token")}function Ce(e){const t=P();I(t)||q(t,{recursive:!0});const o=ne();X(o,e,{encoding:"utf-8",mode:384}),Q(o,384)}function H(){try{const e=ne();if(!I(e))return null;const t=C(e,"utf-8").trim();return t.length>0?t:null}catch{return null}}async function ge(e,t,o,i){const u=new AbortController;let r,d=!1;const s=new Promise((l,f)=>{r=setTimeout(()=>{d=!0,u.abort(),f(new Error("Wyrm: request timed out"))},i),r.unref?.()});s.catch(()=>{});let c;try{c=await Promise.race([e(t,{...o,signal:u.signal}),s])}catch(l){throw clearTimeout(r),l}return{res:c,readJson:async()=>{try{if(typeof c.text=="function"){const l=await Promise.race([c.text(),s]);if(l.length>1e6)throw new Error("Wyrm: response body too large");return JSON.parse(l)}return await Promise.race([c.json(),s])}finally{clearTimeout(r)}}}}function ve(){try{const e=de(pe(import.meta.url));return JSON.parse(C(L(e,"..","package.json"),"utf-8")).version??"unknown"}catch{return"unknown"}}function b(e,t){if(e===null)return!1;const o=new Date(e).getTime();if(Number.isNaN(o))return!1;const i=o-t;return i>=0?i<=ye:-i<=we}function re(e){return/^(0|false|no|off)$/i.test(e??"")}function $e(e){return re(e.flag)?!1:e.hasKey||e.hasToken}function He(){if(!$e({hasKey:!!N().key,hasToken:H()!==null,flag:process.env.WYRM_LICENSE_REFRESH}))return!1;const t=()=>Promise.all([N().key?ke():Promise.resolve(null),Ee()]).catch(()=>{});return t(),Ae(),T=setInterval(()=>{t()},J),T.unref?.(),!0}let T=null;function Ae(){T&&clearInterval(T),T=null}const J=1440*60*1e3,ie=J,se=7*J;function oe(){return L(P(),"license-refresh.json")}function D(){try{const e=oe();if(!I(e))return null;const t=JSON.parse(C(e,"utf-8"));return typeof t.last_attempt_at!="string"||typeof t.last_result!="string"?null:t}catch{return null}}function Je(){return D()}function _e(e){try{const t=P();I(t)||q(t,{recursive:!0});const o=oe();X(o,JSON.stringify(e),{encoding:"utf-8",mode:384}),Q(o,384)}catch{}}function F(e){return le("sha256").update(e).digest("hex").slice(0,16)}function y(e,t,o,i,u){const r=u??(e&&e.token_fp===i?e.account:void 0);_e({last_attempt_at:t,last_result:o,token_fp:i,...r?{account:r}:{}})}function xe(e,t,o){if(!e)return!0;if(e.last_result==="unauthorized"&&e.token_fp===o)return!1;const i=Date.parse(e.last_attempt_at);if(Number.isNaN(i)||i>t)return!0;const u=e.last_result==="no_entitlement"?se:ie;return t-i>=u}function Se(e,t,o){if(!e||e.token_fp!==o)return!0;if(e.last_result==="unauthorized")return!1;const i=Date.parse(e.last_attempt_at);if(Number.isNaN(i)||i>t)return!0;const u=e.last_result==="kept"?se:ie;return t-i>=u}function U(e,t){return!e||!t?!1:e.trim().toLowerCase()===t.trim().toLowerCase()}const ae="Wyrm: your account sign-in has expired; run `wyrm login` to renew it.";function ce(e){return(e??process.env.WYRM_ACCOUNT_URL??"https://account.ghosts.lk").replace(/\/$/,"")}async function W(e,t,o,i,u){let r,d;try{({res:r,readJson:d}=await ge(e,`${t}${o}`,{method:"POST",headers:{authorization:`Bearer ${i}`,"x-wyrm-version":ve()}},u))}catch{return{kind:"offline"}}if(r.ok)try{return{kind:"ok",json:await d()}}catch{return{kind:"offline"}}let s={};try{const l=await d();l&&typeof l=="object"&&(s=l)}catch{}const c=typeof s.error=="string"?s.error:void 0,n=typeof s.hint=="string"?s.hint:void 0;return r.status===429||r.status>=500?{kind:"transient",status:r.status,error:c,hint:n}:{kind:"refused",status:r.status,error:c,hint:n}}function Y(e,t){return e.kind==="ok"?t?"restored":"offline":e.kind==="refused"?e.status===401?"unauthorized":e.error==="no_active_entitlement"?"no_entitlement":"refused":"offline"}const z="/api/v1/license/refresh",Te="/api/v1/license/free";async function Ee(e={}){const t=e.activateLicenseImpl??Z,o=e.reconcileLicenseStateImpl??he,i=u=>{if(u!=="not-needed"&&u!=="no-token")try{o()}catch{}return u};try{const u=e.getLicenseInfoImpl??N,r=e.now??Date.now(),d=e.timeoutMs??4e3,s=e.fetchImpl??globalThis.fetch,c=ce(e.baseUrl),n=u();if(!x.includes(n.tier)||n.valid===!1&&!b(n.expiresAt,r))return await Le({fetchImpl:s,base:c,timeoutMs:d,now:r,activate:t,reload:e.reloadLicenseImpl,finish:i,loadedTier:n.tier});if(!b(n.expiresAt,r))return"not-needed";const f=H();return f?await Ie({fetchImpl:s,base:c,timeoutMs:d,now:r,token:f,info:n,activate:t,reload:e.reloadLicenseImpl,finish:i}):"no-token"}catch{return i("offline")}}function Re(){const e=te();if(!e)return{tier:"free",valid:!1,expiresAt:null,issuedTo:null};const t=me(e);return t.valid&&x.includes(t.tier)&&ee(e),{tier:t.tier,valid:t.valid,expiresAt:t.expiresAt,issuedTo:e.license.issued_to??null}}async function Ie(e){const t=(e.reload??Re)(),o=t.valid&&x.includes(t.tier);if(o&&!b(t.expiresAt??null,e.now))return"not-needed";const i=o?t:e.info,u=o||e.info.valid!==!1,r=F(e.token),d=D();if(!Se(d,e.now,r))return"not-needed";const s=new Date(e.now).toISOString();y(d,s,"pending",r);const c=await W(e.fetchImpl,e.base,z,e.token,e.timeoutMs);if(c.kind==="ok"){const n=M(c.json),l=u&&U(i.issuedTo,n);let f=null;try{f=e.activate(JSON.stringify(c.json),{force:l})}catch{f=null}if(f?.valid)return y(d,s,"renewed",r,n),u&&O(f.tier)<O(i.tier)&&console.error(`Wyrm: your account's plan is ${f.tier}, so the renewal replaced your ${i.tier} license (${m(f.expiresAt)}).`),e.finish("refreshed");if(f?.code==="downgrade_refused"){if(y(d,s,"kept",r,n),d?.last_result!=="kept"){const v=f.loaded?.issuedTo??i.issuedTo??null,$=f.loaded?.tier??i.tier,j=n?` (${n})`:"",E=v?` Run \`wyrm login\` with ${v} to renew it.`:"";console.error(`Wyrm: kept your ${$} license${v?` issued to ${v}`:""}: the signed-in account${j} has a ${f.tier} plan, a lower tier.${E}`)}return e.finish("refused")}return y(d,s,"offline",r,n),e.finish("offline")}return y(d,s,Y(c,!1),r),c.kind==="refused"&&c.status===401?(console.error(ae),e.finish("refused")):c.kind==="refused"&&c.status===403?(console.error("Wyrm: license refresh refused (account or entitlement inactive)"),e.finish("refused")):e.finish("offline")}async function Le(e){if(re(process.env.WYRM_LICENSE_REFRESH))return"not-needed";const t=H();if(!t)return"not-needed";const o=e.reload??(()=>{const f=ee(te());return{tier:f.tier,valid:f.valid}}),i=o();if(i.valid&&x.includes(i.tier))return"not-needed";const u=F(t),r=D();if(!xe(r,e.now,u))return"not-needed";const d=new Date(e.now).toISOString();y(r,d,"pending",u);const s=await W(e.fetchImpl,e.base,z,t,e.timeoutMs),c=s.kind==="ok"?M(s.json):null;let n=null;if(s.kind==="ok")try{n=e.activate(JSON.stringify(s.json))}catch{n=null}if(n?.code==="downgrade_refused"){y(r,d,"kept",u,c);try{o()}catch{}return"not-needed"}const l=Y(s,n?.valid===!0);return y(r,d,l,u,c),l!==r?.last_result&&(l==="restored"?console.error(`Wyrm: fetched your account's ${n.tier} license (${m(n.expiresAt)}).`):l==="unauthorized"&&x.includes(e.loadedTier)&&console.error(ae)),l==="restored"?e.finish("restored"):s.kind==="refused"?e.finish("refused"):e.finish("offline")}const w=e=>e.charAt(0).toUpperCase()+e.slice(1),m=e=>e?`valid until ${e.slice(0,10)}`:"no expiry";function M(e){const t=e?.license?.issued_to;return typeof t=="string"&&t.length>0?t:null}function Ne(e){try{return new URL(e).hostname}catch{return e}}async function Fe(e,t={}){const o=t.getLicenseInfoImpl??N,i=t.activateLicenseImpl??Z,u=t.fetchImpl??globalThis.fetch,r=t.now??Date.now(),d=t.timeoutMs??15e3,s=ce(t.baseUrl),c=Ne(s);let n;try{n=o()}catch{n={tier:"free",expiresAt:null,valid:!1}}const l=n.issuedTo??null,f=n.valid&&x.includes(n.tier),v=l?` issued to ${l}`:"",$=a=>({outcome:"kept",tier:n.tier,expiresAt:n.expiresAt,ok:!0,message:`${w(n.tier)} tier active: kept your license${v} (${m(n.expiresAt)}); ${a}.`}),j=n.valid?`${n.tier} tier, ${m(n.expiresAt)}`:"free tier",E=()=>({outcome:"offline",tier:n.valid?n.tier:"free",expiresAt:n.valid?n.expiresAt:null,ok:!1,message:`Could not reach ${c} to fetch your license; kept what is installed (${j}). Run \`wyrm login\` again when you are online.`});if(f&&!b(n.expiresAt,r))return $(l?"signing in never replaces a paid license, and it renews from that email's account":"signing in never replaces a paid license");const B=new Date(r).toISOString(),G=F(e),K=D(),k=await W(u,s,z,e,d),A=k.kind==="ok"?M(k.json):null;let p=null;try{k.kind==="ok"&&(p=i(JSON.stringify(k.json),{force:f&&U(l,A)}))}catch{p=null}const V=p?.valid?f?"renewed":"restored":p?.code==="downgrade_refused"?"kept":Y(k,!1);y(K,B,V,G,A);const S=A?` (${A})`:"";if(p?.valid){const a=w(p.tier);if(!f)return{outcome:"paid",tier:p.tier,expiresAt:p.expiresAt,ok:!0,message:`${a} tier active: fetched the license on your account${S}, ${m(p.expiresAt)}.`};const _=O(p.tier)<O(n.tier)?`${a} tier active: your account's plan${S} is ${a}, so the renewal replaced your ${w(n.tier)} license; ${m(p.expiresAt)}.`:l&&A&&!U(l,A)?`${a} tier active: renewed from your account${S}, ${m(p.expiresAt)}; it replaces the license issued to ${l}.`:`${a} tier active: renewed from your account${S}, ${m(p.expiresAt)}.`;return{outcome:"renewed",tier:p.tier,expiresAt:p.expiresAt,ok:!0,message:_}}if(p?.code==="downgrade_refused"){const a=p.loaded??{tier:n.tier,expiresAt:n.expiresAt,issuedTo:l},_=a.issuedTo?` issued to ${a.issuedTo}`:"",ue=a.issuedTo&&a.expiresAt?` Sign in with ${a.issuedTo} to renew it.`:"";return{outcome:"kept",tier:a.tier,expiresAt:a.expiresAt,ok:!0,message:`${w(a.tier)} tier active: kept your license${_} (${m(a.expiresAt)}); the account you signed in with${S} has a ${w(p.tier)} plan, a lower tier, so it was not applied.${ue}`}}if(k.kind==="offline")return f?$(`could not reach ${c} to renew it, Wyrm will try again`):E();const R=k.kind==="transient"&&k.status>=500?k.status:null;if(R!==null&&f)return $(`${c} answered ${R} when asked to renew it, Wyrm will try again`);if(f){const a=k.kind!=="ok"&&k.error==="no_active_entitlement"?"the account has no active paid plan to renew it from":"the account did not renew it";return $(a)}const g=await W(u,s,Te,e,d);if(g.kind==="offline")return E();if(g.kind!=="ok")return{outcome:"failed",tier:n.valid?n.tier:"free",expiresAt:n.valid?n.expiresAt:null,ok:!1,message:`Activation failed (${g.status}): ${g.hint||g.error||"unknown error"}`};let h;try{h=i(JSON.stringify(g.json))}catch(a){h={valid:!1,tier:"free",features:[],expiresAt:null,error:a instanceof Error?a.message:"unknown error"}}if(h.valid){const a=M(g.json);a&&y(K,B,V,G,a);const _=a?`the account ${a}`:"this account";return{outcome:"free",tier:h.tier,expiresAt:h.expiresAt,ok:!0,message:R!==null?`${w(h.tier)} tier active on ${_} (${m(h.expiresAt)}): ${c} answered ${R} when asked for a paid license, so Wyrm will ask again within a day.`:`${w(h.tier)} tier active: no paid plan on ${_} (${m(h.expiresAt)}); if your license was issued to another email, run \`wyrm login\` again and sign in with that one.`}}if(h.code==="downgrade_refused"&&h.loaded){const a=h.loaded.issuedTo?` issued to ${h.loaded.issuedTo}`:"";return{outcome:"kept",tier:h.loaded.tier,expiresAt:h.loaded.expiresAt,ok:!0,message:`${w(h.loaded.tier)} tier active: kept your license${a} (${m(h.loaded.expiresAt)}); signing in never replaces a paid license.`}}return{outcome:"failed",tier:n.valid?n.tier:"free",expiresAt:n.valid?n.expiresAt:null,ok:!1,message:`Activation failed: ${h.error??"unknown error"}`}}export{ne as ACCOUNT_TOKEN_PATH,oe as LICENSE_REFRESH_STATE_PATH,Je as lastLicenseRefreshAttempt,$e as licenseRefreshEnabled,H as loadAccountToken,b as needsRefresh,Ee as refreshLicenseIfNeeded,Ce as saveAccountToken,Fe as settleLicenseAfterLogin,He as startLicenseChecks,Ae as stopLicenseChecks};
|
|
1
|
+
import{readFileSync as H,writeFileSync as q,mkdirSync as Q,existsSync as I,chmodSync as Z}from"fs";import{createHash as le}from"crypto";import{homedir as fe}from"os";import{join as L,dirname as de}from"path";import{fileURLToPath as pe}from"url";import{getLicenseInfo as N,activateLicense as ee,reconcileLicenseState as he,applyLoadedLicense as te,loadLicense as ne,verifyLicense as me,tierRank as O,PAID_TIERS as x}from"./license.js";import{refreshRevocations as ke}from"./revocations.js";const ye=336*60*60*1e3,we=720*60*60*1e3;function P(){return process.env.WYRM_HOME??L(fe(),".wyrm")}function re(){return L(P(),"account-token")}function He(e){const t=P();I(t)||Q(t,{recursive:!0});const o=re();q(o,e,{encoding:"utf-8",mode:384}),Z(o,384)}function j(){try{const e=re();if(!I(e))return null;const t=H(e,"utf-8").trim();return t.length>0?t:null}catch{return null}}async function ge(e,t,o,i){const u=new AbortController;let r,d=!1;const s=new Promise((l,f)=>{r=setTimeout(()=>{d=!0,u.abort(),f(new Error("Wyrm: request timed out"))},i),r.unref?.()});s.catch(()=>{});let c;try{c=await Promise.race([e(t,{...o,signal:u.signal}),s])}catch(l){throw clearTimeout(r),l}return{res:c,readJson:async()=>{try{if(typeof c.text=="function"){const l=await Promise.race([c.text(),s]);if(l.length>1e6)throw new Error("Wyrm: response body too large");return JSON.parse(l)}return await Promise.race([c.json(),s])}finally{clearTimeout(r)}}}}function ve(){try{const e=de(pe(import.meta.url));return JSON.parse(H(L(e,"..","package.json"),"utf-8")).version??"unknown"}catch{return"unknown"}}function b(e,t){if(e===null)return!1;const o=new Date(e).getTime();if(Number.isNaN(o))return!1;const i=o-t;return i>=0?i<=ye:-i<=we}function J(e){return/^(0|false|no|off)$/i.test(e??"")}function $e(e){return J(e.flag)?!1:e.hasKey||e.hasToken}function je(){if(!$e({hasKey:!!N().key,hasToken:j()!==null,flag:process.env.WYRM_LICENSE_REFRESH}))return!1;const t=()=>Promise.all([N().key?ke():Promise.resolve(null),Ee()]).catch(()=>{});return t(),Ae(),T=setInterval(()=>{t()},F),T.unref?.(),!0}let T=null;function Ae(){T&&clearInterval(T),T=null}const F=1440*60*1e3,ie=F,se=7*F;function oe(){return L(P(),"license-refresh.json")}function D(){try{const e=oe();if(!I(e))return null;const t=JSON.parse(H(e,"utf-8"));return typeof t.last_attempt_at!="string"||typeof t.last_result!="string"?null:t}catch{return null}}function Je(){return D()}function _e(e){try{const t=P();I(t)||Q(t,{recursive:!0});const o=oe();q(o,JSON.stringify(e),{encoding:"utf-8",mode:384}),Z(o,384)}catch{}}function U(e){return le("sha256").update(e).digest("hex").slice(0,16)}function y(e,t,o,i,u){const r=u??(e&&e.token_fp===i?e.account:void 0);_e({last_attempt_at:t,last_result:o,token_fp:i,...r?{account:r}:{}})}function xe(e,t,o){if(!e)return!0;if(e.last_result==="unauthorized"&&e.token_fp===o)return!1;const i=Date.parse(e.last_attempt_at);if(Number.isNaN(i)||i>t)return!0;const u=e.last_result==="no_entitlement"?se:ie;return t-i>=u}function Se(e,t,o){if(!e||e.token_fp!==o)return!0;if(e.last_result==="unauthorized")return!1;const i=Date.parse(e.last_attempt_at);if(Number.isNaN(i)||i>t)return!0;const u=e.last_result==="kept"?se:ie;return t-i>=u}function Y(e,t){return!e||!t?!1:e.trim().toLowerCase()===t.trim().toLowerCase()}const ae="Wyrm: your account sign-in has expired; run `wyrm login` to renew it.";function ce(e){return(e??process.env.WYRM_ACCOUNT_URL??"https://account.ghosts.lk").replace(/\/$/,"")}async function W(e,t,o,i,u){let r,d;try{({res:r,readJson:d}=await ge(e,`${t}${o}`,{method:"POST",headers:{authorization:`Bearer ${i}`,"x-wyrm-version":ve()}},u))}catch{return{kind:"offline"}}if(r.ok)try{return{kind:"ok",json:await d()}}catch{return{kind:"offline"}}let s={};try{const l=await d();l&&typeof l=="object"&&(s=l)}catch{}const c=typeof s.error=="string"?s.error:void 0,n=typeof s.hint=="string"?s.hint:void 0;return r.status===429||r.status>=500?{kind:"transient",status:r.status,error:c,hint:n}:{kind:"refused",status:r.status,error:c,hint:n}}function z(e,t){return e.kind==="ok"?t?"restored":"offline":e.kind==="refused"?e.status===401?"unauthorized":e.error==="no_active_entitlement"?"no_entitlement":"refused":"offline"}const B="/api/v1/license/refresh",Te="/api/v1/license/free";async function Ee(e={}){if(J(process.env.WYRM_LICENSE_REFRESH))return"not-needed";const t=e.activateLicenseImpl??ee,o=e.reconcileLicenseStateImpl??he,i=u=>{if(u!=="not-needed"&&u!=="no-token")try{o()}catch{}return u};try{const u=e.getLicenseInfoImpl??N,r=e.now??Date.now(),d=e.timeoutMs??4e3,s=e.fetchImpl??globalThis.fetch,c=ce(e.baseUrl),n=u();if(!x.includes(n.tier)||n.valid===!1&&!b(n.expiresAt,r))return await Le({fetchImpl:s,base:c,timeoutMs:d,now:r,activate:t,reload:e.reloadLicenseImpl,finish:i,loadedTier:n.tier});if(!b(n.expiresAt,r))return"not-needed";const f=j();return f?await Ie({fetchImpl:s,base:c,timeoutMs:d,now:r,token:f,info:n,activate:t,reload:e.reloadLicenseImpl,finish:i}):"no-token"}catch{return i("offline")}}function Re(){const e=ne();if(!e)return{tier:"free",valid:!1,expiresAt:null,issuedTo:null};const t=me(e);return t.valid&&x.includes(t.tier)&&te(e),{tier:t.tier,valid:t.valid,expiresAt:t.expiresAt,issuedTo:e.license.issued_to??null}}async function Ie(e){const t=(e.reload??Re)(),o=t.valid&&x.includes(t.tier);if(o&&!b(t.expiresAt??null,e.now))return"not-needed";const i=o?t:e.info,u=o||e.info.valid!==!1,r=U(e.token),d=D();if(!Se(d,e.now,r))return"not-needed";const s=new Date(e.now).toISOString();y(d,s,"pending",r);const c=await W(e.fetchImpl,e.base,B,e.token,e.timeoutMs);if(c.kind==="ok"){const n=M(c.json),l=u&&Y(i.issuedTo,n);let f=null;try{f=e.activate(JSON.stringify(c.json),{force:l})}catch{f=null}if(f?.valid)return y(d,s,"renewed",r,n),u&&O(f.tier)<O(i.tier)&&console.error(`Wyrm: your account's plan is ${f.tier}, so the renewal replaced your ${i.tier} license (${m(f.expiresAt)}).`),e.finish("refreshed");if(f?.code==="downgrade_refused"){if(y(d,s,"kept",r,n),d?.last_result!=="kept"){const v=f.loaded?.issuedTo??i.issuedTo??null,$=f.loaded?.tier??i.tier,C=n?` (${n})`:"",E=v?` Run \`wyrm login\` with ${v} to renew it.`:"";console.error(`Wyrm: kept your ${$} license${v?` issued to ${v}`:""}: the signed-in account${C} has a ${f.tier} plan, a lower tier.${E}`)}return e.finish("refused")}return y(d,s,"offline",r,n),e.finish("offline")}return y(d,s,z(c,!1),r),c.kind==="refused"&&c.status===401?(console.error(ae),e.finish("refused")):c.kind==="refused"&&c.status===403?(console.error("Wyrm: license refresh refused (account or entitlement inactive)"),e.finish("refused")):e.finish("offline")}async function Le(e){if(J(process.env.WYRM_LICENSE_REFRESH))return"not-needed";const t=j();if(!t)return"not-needed";const o=e.reload??(()=>{const f=te(ne());return{tier:f.tier,valid:f.valid}}),i=o();if(i.valid&&x.includes(i.tier))return"not-needed";const u=U(t),r=D();if(!xe(r,e.now,u))return"not-needed";const d=new Date(e.now).toISOString();y(r,d,"pending",u);const s=await W(e.fetchImpl,e.base,B,t,e.timeoutMs),c=s.kind==="ok"?M(s.json):null;let n=null;if(s.kind==="ok")try{n=e.activate(JSON.stringify(s.json))}catch{n=null}if(n?.code==="downgrade_refused"){y(r,d,"kept",u,c);try{o()}catch{}return"not-needed"}const l=z(s,n?.valid===!0);return y(r,d,l,u,c),l!==r?.last_result&&(l==="restored"?console.error(`Wyrm: fetched your account's ${n.tier} license (${m(n.expiresAt)}).`):l==="unauthorized"&&x.includes(e.loadedTier)&&console.error(ae)),l==="restored"?e.finish("restored"):s.kind==="refused"?e.finish("refused"):e.finish("offline")}const w=e=>e.charAt(0).toUpperCase()+e.slice(1),m=e=>e?`valid until ${e.slice(0,10)}`:"no expiry";function M(e){const t=e?.license?.issued_to;return typeof t=="string"&&t.length>0?t:null}function Ne(e){try{return new URL(e).hostname}catch{return e}}async function Fe(e,t={}){const o=t.getLicenseInfoImpl??N,i=t.activateLicenseImpl??ee,u=t.fetchImpl??globalThis.fetch,r=t.now??Date.now(),d=t.timeoutMs??15e3,s=ce(t.baseUrl),c=Ne(s);let n;try{n=o()}catch{n={tier:"free",expiresAt:null,valid:!1}}const l=n.issuedTo??null,f=n.valid&&x.includes(n.tier),v=l?` issued to ${l}`:"",$=a=>({outcome:"kept",tier:n.tier,expiresAt:n.expiresAt,ok:!0,message:`${w(n.tier)} tier active: kept your license${v} (${m(n.expiresAt)}); ${a}.`}),C=n.valid?`${n.tier} tier, ${m(n.expiresAt)}`:"free tier",E=()=>({outcome:"offline",tier:n.valid?n.tier:"free",expiresAt:n.valid?n.expiresAt:null,ok:!1,message:`Could not reach ${c} to fetch your license; kept what is installed (${C}). Run \`wyrm login\` again when you are online.`});if(f&&!b(n.expiresAt,r))return $(l?"signing in never replaces a paid license, and it renews from that email's account":"signing in never replaces a paid license");const G=new Date(r).toISOString(),K=U(e),V=D(),k=await W(u,s,B,e,d),A=k.kind==="ok"?M(k.json):null;let p=null;try{k.kind==="ok"&&(p=i(JSON.stringify(k.json),{force:f&&Y(l,A)}))}catch{p=null}const X=p?.valid?f?"renewed":"restored":p?.code==="downgrade_refused"?"kept":z(k,!1);y(V,G,X,K,A);const S=A?` (${A})`:"";if(p?.valid){const a=w(p.tier);if(!f)return{outcome:"paid",tier:p.tier,expiresAt:p.expiresAt,ok:!0,message:`${a} tier active: fetched the license on your account${S}, ${m(p.expiresAt)}.`};const _=O(p.tier)<O(n.tier)?`${a} tier active: your account's plan${S} is ${a}, so the renewal replaced your ${w(n.tier)} license; ${m(p.expiresAt)}.`:l&&A&&!Y(l,A)?`${a} tier active: renewed from your account${S}, ${m(p.expiresAt)}; it replaces the license issued to ${l}.`:`${a} tier active: renewed from your account${S}, ${m(p.expiresAt)}.`;return{outcome:"renewed",tier:p.tier,expiresAt:p.expiresAt,ok:!0,message:_}}if(p?.code==="downgrade_refused"){const a=p.loaded??{tier:n.tier,expiresAt:n.expiresAt,issuedTo:l},_=a.issuedTo?` issued to ${a.issuedTo}`:"",ue=a.issuedTo&&a.expiresAt?` Sign in with ${a.issuedTo} to renew it.`:"";return{outcome:"kept",tier:a.tier,expiresAt:a.expiresAt,ok:!0,message:`${w(a.tier)} tier active: kept your license${_} (${m(a.expiresAt)}); the account you signed in with${S} has a ${w(p.tier)} plan, a lower tier, so it was not applied.${ue}`}}if(k.kind==="offline")return f?$(`could not reach ${c} to renew it, Wyrm will try again`):E();const R=k.kind==="transient"&&k.status>=500?k.status:null;if(R!==null&&f)return $(`${c} answered ${R} when asked to renew it, Wyrm will try again`);if(f){const a=k.kind!=="ok"&&k.error==="no_active_entitlement"?"the account has no active paid plan to renew it from":"the account did not renew it";return $(a)}const g=await W(u,s,Te,e,d);if(g.kind==="offline")return E();if(g.kind!=="ok")return{outcome:"failed",tier:n.valid?n.tier:"free",expiresAt:n.valid?n.expiresAt:null,ok:!1,message:`Activation failed (${g.status}): ${g.hint||g.error||"unknown error"}`};let h;try{h=i(JSON.stringify(g.json))}catch(a){h={valid:!1,tier:"free",features:[],expiresAt:null,error:a instanceof Error?a.message:"unknown error"}}if(h.valid){const a=M(g.json);a&&y(V,G,X,K,a);const _=a?`the account ${a}`:"this account";return{outcome:"free",tier:h.tier,expiresAt:h.expiresAt,ok:!0,message:R!==null?`${w(h.tier)} tier active on ${_} (${m(h.expiresAt)}): ${c} answered ${R} when asked for a paid license, so Wyrm will ask again within a day.`:`${w(h.tier)} tier active: no paid plan on ${_} (${m(h.expiresAt)}); if your license was issued to another email, run \`wyrm login\` again and sign in with that one.`}}if(h.code==="downgrade_refused"&&h.loaded){const a=h.loaded.issuedTo?` issued to ${h.loaded.issuedTo}`:"";return{outcome:"kept",tier:h.loaded.tier,expiresAt:h.loaded.expiresAt,ok:!0,message:`${w(h.loaded.tier)} tier active: kept your license${a} (${m(h.loaded.expiresAt)}); signing in never replaces a paid license.`}}return{outcome:"failed",tier:n.valid?n.tier:"free",expiresAt:n.valid?n.expiresAt:null,ok:!1,message:`Activation failed: ${h.error??"unknown error"}`}}export{re as ACCOUNT_TOKEN_PATH,oe as LICENSE_REFRESH_STATE_PATH,Je as lastLicenseRefreshAttempt,$e as licenseRefreshEnabled,j as loadAccountToken,b as needsRefresh,Ee as refreshLicenseIfNeeded,He as saveAccountToken,Fe as settleLicenseAfterLogin,je as startLicenseChecks,Ae as stopLicenseChecks};
|
package/dist/tool-manifest.json
CHANGED
package/dist/wyrm-manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wyrm-mcp",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.1",
|
|
4
4
|
"mcpName": "lk.ghosts/wyrm",
|
|
5
5
|
"description": "Local-first persistent memory for AI agents over MCP. Ground truths, a failure firewall that blocks repeated mistakes (negative learning), and hybrid recall, stored in SQLite on your machine. No cloud or LLM required. Proprietary license.",
|
|
6
6
|
"type": "module",
|