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.
28 lines (26 loc) • 5.17 kB
JavaScript
import{accessSync as m,constants as u,readFileSync as d,statSync as p}from"node:fs";import l from"node:os";import{dirname as f,join as c}from"node:path";import{parseArgs as g}from"node:util";function w(){return["Usage:"," node scripts/survey_host_readiness.js [--ollama-host <url>] [--json]","","Options:"," --ollama-host <url> Ollama host to probe (default http://127.0.0.1:11434)"," --json Emit JSON instead of a readable report"].join(`
`)}function h(){return process.platform==="win32"?"Windows":process.platform==="darwin"?"Darwin":process.platform==="linux"?"Linux":process.platform}function b(){if(process.platform==="win32")return"windows-native";if(process.platform==="darwin")return"macos-native";if(process.platform==="linux"){const e=l.release().toLowerCase();if(e.includes("microsoft")||e.includes("wsl"))return"wsl";try{if(d("/proc/version","utf8").toLowerCase().includes("microsoft"))return"wsl"}catch{}return"linux-native"}return"unknown"}function x(e){try{return p(e).isFile()?(process.platform==="win32"||m(e,u.X_OK),!0):!1}catch{return!1}}function _(e){const n=e.trim();if(!n)return[];const s=[],t=["/usr/local/bin","/opt/homebrew/bin","/usr/bin","/bin"];if(n==="node"&&s.push(process.execPath),n==="npm"){const o=f(process.execPath);process.platform==="win32"?s.push(c(o,"npm.cmd"),c(o,"npm.exe")):s.push(c(o,"npm"))}if(process.platform==="win32")return n==="ollama"&&s.push("C:\\\\Program Files\\\\Ollama\\\\ollama.exe","C:\\\\Program Files (x86)\\\\Ollama\\\\ollama.exe"),n==="node"&&s.push("C:\\\\Program Files\\\\nodejs\\\\node.exe","C:\\\\Program Files (x86)\\\\nodejs\\\\node.exe"),n==="npm"&&s.push("C:\\\\Program Files\\\\nodejs\\\\npm.cmd","C:\\\\Program Files (x86)\\\\nodejs\\\\npm.cmd"),n==="openclaw"&&s.push("C:\\\\Program Files\\\\OpenClaw\\\\openclaw.exe","C:\\\\Program Files (x86)\\\\OpenClaw\\\\openclaw.exe"),s;for(const o of t)s.push(c(o,n));return s}function y(e){for(const n of _(e))if(x(n))return n;return null}function C(e,n){return n&&e==="node"?process.version:null}function v(e){return e===null?["embeddinggemma:300m-qat-q8_0","nomic-embed-text:latest","qwen3-embedding:0.6b"]:e<8?["nomic-embed-text:latest","embeddinggemma:300m-qat-q8_0"]:e<32?["embeddinggemma:300m-qat-q8_0","nomic-embed-text:latest","qwen3-embedding:0.6b"]:["embeddinggemma:300m-qat-q8_0","nomic-embed-text:latest","qwen3-embedding:0.6b","qwen3-embedding:latest"]}async function $(e,n){const s=new AbortController,t=setTimeout(()=>s.abort(),n);try{return await fetch(e,{signal:s.signal})}finally{clearTimeout(t)}}async function O(e){const n=e.replace(/\/+$/,"")+"/api/tags";try{const s=await $(n,5e3);if(!s.ok)return{reachable:!1,models:[]};const t=await s.text(),o=JSON.parse(t);return{reachable:!0,models:(Array.isArray(o.models)?o.models:[]).map(r=>r&&typeof r=="object"?r.name:void 0).filter(r=>typeof r=="string")}}catch{return{reachable:!1,models:[]}}}async function P(e){const n=l.totalmem()?l.totalmem()/1024/1024/1024:null,s={},t={};for(const a of["ollama","openclaw","node","npm"]){const r=y(a);s[a]=r,t[a]=C(a,r)}s.openclaw_management=s.openclaw,t.openclaw_management=t.openclaw;const o=await O(e),i=h();return{os:i,release:l.release(),arch:l.arch(),shell_context:b(),cpu_count:l.cpus().length,memory_gib:n===null?null:Math.round(n*100)/100,commands:s,versions:t,ollama_api:o,recommended_candidates:v(n===null?null:n),openclaw_install_note:i==="Windows"?"Use Mac or Linux directly; use WSL on Windows for current official OpenClaw setup.":"Use the official Ollama OpenClaw launch flow."}}function j(e,n){process.stdout.write(`System
`),process.stdout.write(` OS: ${e.os} ${e.release}
`),process.stdout.write(` Context: ${e.shell_context}
`),process.stdout.write(` Arch: ${e.arch}
`),process.stdout.write(` CPUs: ${e.cpu_count}
`),process.stdout.write(` RAM GiB: ${e.memory_gib??"unknown"}
`),process.stdout.write(`Commands
`);for(const[s,t]of Object.entries(e.commands)){const o=e.versions[s]??null,i=s==="openclaw_management"?"openclaw management":s;if(t){const a=o?` (${o})`:"";process.stdout.write(` ${i}: ${t}${a}
`)}else process.stdout.write(` ${i}: missing
`)}process.stdout.write(`
Ollama API
`),e.ollama_api.reachable?(process.stdout.write(` ${n}: reachable
`),process.stdout.write(` Models: ${e.ollama_api.models.length?e.ollama_api.models.join(", "):"none pulled"}
`)):process.stdout.write(` ${n}: unreachable
`),process.stdout.write(`
Recommended candidates
`);for(const s of e.recommended_candidates)process.stdout.write(` - ${s}
`);process.stdout.write(`
OpenClaw install note
${e.openclaw_install_note}
`)}async function R(){const e=g({args:process.argv.slice(2),options:{"ollama-host":{type:"string",default:"http://127.0.0.1:11434"},json:{type:"boolean",default:!1},help:{type:"boolean",default:!1}}});if(e.values.help)return process.stdout.write(`${w()}
`),0;const n=String(e.values["ollama-host"]??"").trim()||"http://127.0.0.1:11434",s=await P(n);return e.values.json?process.stdout.write(`${JSON.stringify(s,null,2)}
`):j(s,n),0}R().then(e=>{process.exitCode=e}).catch(e=>{const n=e instanceof Error?e.message:String(e);process.stderr.write(`${n}
`),process.exitCode=1});