UNPKG

grix-connector

Version:

Connect local AI coding agents (Claude, Codex, Gemini, Qwen, DeepSeek, Cursor, OpenCode, Pi, OpenHuman, Reasonix) to the Grix scheduling platform. Also serves as an OpenClaw plugin for Grix channel transport.

3 lines (2 loc) 3.24 kB
import{execFileSync as p}from"node:child_process";import{existsSync as s,readFileSync as m,renameSync as _,unlinkSync as S,writeFileSync as E}from"node:fs";import{join as u}from"node:path";import{GRIX_PATHS as f}from"../log/index.js";import{appendRotatingFileSync as N}from"../log/rotation.js";import{resolveClientVersion as I}from"../util/client-version.js";import{npmInstallWithMirror as w}from"../installer/npm-registry.js";class i extends Error{code;constructor(r,n){super(n),this.name="UpgradeError",this.code=r}}function d(){return u(f.log,"upgrade.log")}function a(){return u(f.data,"upgrade-pending.json")}function P(){return s(a())}function k(){const e=a();if(!s(e))return null;try{return JSON.parse(m(e,"utf-8"))}catch{return null}}function T(e,r){const n={from_version:e,target_version:r,upgraded_at:new Date().toISOString(),crash_count:0},c=a(),o=c+".tmp";E(o,JSON.stringify(n),"utf-8"),_(o,c)}function $(){const e=a();if(s(e))try{S(e)}catch{}}function l(e){const r=`[${new Date().toISOString()}] ${e} `;try{N(d(),r)}catch{}}function O(e=4096){const r=d();if(!s(r))return"";try{const n=m(r,"utf-8");return n.length<=e?n:n.slice(-e)}catch{return""}}function g(){try{const e=process.platform==="win32";return p(e?"cmd.exe":"npm",e?["/c","npm","--version"]:["--version"],{encoding:"utf-8",timeout:1e4}).trim()}catch{throw new i("NPM_NOT_FOUND","npm is not available or timed out")}}function h(){let e;try{const r=process.platform==="win32";e=p(r?"cmd.exe":"npm",r?["/c","npm","prefix","-g"]:["prefix","-g"],{encoding:"utf-8",timeout:1e4}).trim()}catch{return Number.MAX_SAFE_INTEGER}return Number.MAX_SAFE_INTEGER}function D(){let e;try{e=g()}catch(n){return{ok:!1,errorCode:"NPM_NOT_FOUND",errorMsg:n instanceof Error?n.message:"npm not available"}}const r=h();return r<100?{ok:!1,errorCode:"DISK_FULL",errorMsg:`Only ${r}MB free disk space (need >= 100MB)`,npmVersion:e,diskFreeMb:r}:{ok:!0,npmVersion:e,diskFreeMb:r}}function b(){let e="";try{e=g()}catch{}let r=Number.MAX_SAFE_INTEGER;try{r=h()}catch{}return{npm_version:e,node_version:process.version,disk_free_mb:r,platform:process.platform,arch:process.arch}}async function U(e,r,n=12e4){const c=`${e}@${r}`;l(`npm install -g ${c} starting (with mirror fallback)`);try{const{registry:o}=await w(c,n,10485760);l(`npm install succeeded via ${o}`)}catch(o){const t=o instanceof Error?o.message:String(o);throw l(`npm install failed: ${t}`),/timed out|ETIMEDOUT/i.test(t)?new i("NPM_TIMEOUT",`npm install timed out after ${n/1e3}s (tried all mirrors): ${t}`):t.includes("EACCES")||t.includes("permission denied")?new i("NPM_INSTALL_FAILED",`Permission denied: ${t}`):t.includes("ENOSPC")||t.includes("no space left")?new i("DISK_FULL",`Disk full: ${t}`):t.includes("404")||t.includes("not found")?new i("NPM_INSTALL_FAILED",`Package not found: ${t}`):new i("NPM_INSTALL_FAILED",t)}}function C(e){const r=I();if(r!==e)throw new i("VERSION_MISMATCH",`Installed version ${r} does not match expected ${e}`);return r}export{i as UpgradeError,h as checkDiskSpace,g as checkNpmAvailable,b as collectEnvInfo,O as getUpgradeLogTail,U as npmInstall,P as pendingExists,D as preflightCheck,k as readPending,$ as removePending,l as upgradeLog,C as verifyInstalledVersion,T as writePending};