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.

5 lines (4 loc) 3.79 kB
import{execFile as h}from"node:child_process";import{join as c}from"node:path";import{promisify as v}from"node:util";import{log as o}from"../log/logger.js";const u=v(h),m=5e3;function f(e){const t=e.replace(/^[^0-9]*/,"").split(".");return[parseInt(t[0]??"0",10)||0,parseInt(t[1]??"0",10)||0]}function g(e,n){const[t,r]=f(e),[i,s]=f(n);return t>i||t===i&&r>=s}async function a(e,n=["--version"]){try{const{stdout:t}=await u(e,n,{timeout:m,encoding:"utf-8"});return{found:!0,version:(t||"").trim().split(` `)[0]?.trim()||null}}catch{return{found:!1,version:null}}}async function w(){const e=await a("node",["--version"]);return e.version?{found:!0,version:e.version.replace(/^v/,"")}:e}async function b(){if(process.platform==="win32"){o.info("preflight","[npm-detect] Starting Windows npm detection");const e=["npm",c(process.env.ProgramFiles||"C:\\Program Files","nodejs","npm.cmd"),c(process.env.APPDATA||"","npm","npm.cmd")];try{o.info("preflight","[npm-detect] Trying to locate node.exe via where.exe");const{stdout:n}=await u("where.exe",["node"],{timeout:m,encoding:"utf-8"}),t=c(n.trim().split(` `)[0],".."),r=c(t,"npm.cmd");e.push(r),o.info("preflight",`[npm-detect] Inferred npm path from node: ${r}`)}catch(n){o.warn("preflight",`[npm-detect] Failed to locate node.exe: ${n instanceof Error?n.message:String(n)}`)}o.info("preflight",`[npm-detect] Will try ${e.length} paths: ${e.join(", ")}`);for(const n of e)try{o.info("preflight",`[npm-detect] Trying: ${n}`);const{stdout:t}=await u("cmd.exe",["/c",n,"--version"],{timeout:m,encoding:"utf-8"}),r=t.trim();return o.info("preflight",`[npm-detect] SUCCESS at ${n}, version: ${r}`),{found:!0,version:r}}catch(t){o.warn("preflight",`[npm-detect] Failed at ${n}: ${t instanceof Error?t.message:String(t)}`)}return o.error("preflight","[npm-detect] All paths failed, npm not found"),{found:!1,version:null}}return a("npm",["--version"])}async function P(){const e=await a("curl",["--version"]);return e.version?{found:!0,version:e.version.split(" ")[0]?.trim()??null}:e}async function y(){if(process.platform==="win32"){const n=["gh",c(process.env.ProgramFiles||"C:\\Program Files","GitHub CLI","gh.exe"),c(process.env["ProgramFiles(x86)"]||"C:\\Program Files (x86)","GitHub CLI","gh.exe")];for(const t of n)try{const{stdout:r}=await u(t,["--version"],{timeout:m,encoding:"utf-8"}),i=(r||"").trim();return{found:!0,version:i.match(/(\d+\.\d+\.\d+)/)?.[1]??(i.split(` `)[0]?.trim()||null)}}catch{}return{found:!1,version:null}}const e=await a("gh",["--version"]);return e.version?{found:!0,version:e.version.match(/(\d+\.\d+\.\d+)/)?.[1]??e.version}:e}async function x(){const e=await a("brew",["--version"]);return e.version?{found:!0,version:e.version.match(/(\d+\.\d+\.\d+)/)?.[1]??e.version}:e}function C(e){return[{id:"node",label:"Node.js",minVersion:"18.0",detect:w},{id:"npm",label:"npm",minVersion:"9.0",detect:b},{id:"curl",label:"curl",minVersion:null,detect:P},{id:"gh",label:"GitHub CLI (gh)",minVersion:null,detect:y},...e!=="windows"?[{id:"brew",label:"Homebrew",minVersion:null,detect:x}]:[]]}async function I(e,n){const r=C(n).find(p=>p.id===e);if(!r)return{id:e,label:e,met:!1,version:null,minVersion:null,autoInstallable:!1};const{found:i,version:s}=await r.detect();let l=i;l&&r.minVersion&&s&&(l=g(s,r.minVersion));const d=V(e,n);return{id:e,label:r.label,met:l,version:s,minVersion:r.minVersion,autoInstallable:l?!1:d}}async function S(e,n){return await Promise.all(e.map(r=>I(r,n)))}function A(e){return e.every(n=>n.met)}function M(e){return e.filter(n=>!n.met)}function V(e,n){switch(e){case"node":case"npm":return!0;case"curl":return!0;case"gh":return!0;case"brew":return n==="macos";default:return!1}}export{A as allPrerequisitesMet,I as checkPrerequisite,S as checkPrerequisites,M as getMissingPrerequisites};