oioxo-mcp 0.5.53 → 0.5.55

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.
Files changed (2) hide show
  1. package/bundle/cli.js +4 -4
  2. package/package.json +1 -1
package/bundle/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var XXe=Object.create;var N8=Object.defineProperty;var YXe=Object.getOwnPropertyDescriptor;var JXe=Object.getOwnPropertyNames;var QXe=Object.getPrototypeOf,eYe=Object.prototype.hasOwnProperty;var Kr=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var ce=(t,e)=>()=>(t&&(e=t(t=0)),e);var L=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),yi=(t,e)=>{for(var r in e)N8(t,r,{get:e[r],enumerable:!0})},kfe=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of JXe(e))!eYe.call(t,i)&&i!==r&&N8(t,i,{get:()=>e[i],enumerable:!(n=YXe(e,i))||n.enumerable});return t};var an=(t,e,r)=>(r=t!=null?XXe(QXe(t)):{},kfe(e||!t||!t.__esModule?N8(r,"default",{value:t,enumerable:!0}):r,t)),He=t=>kfe(N8({},"__esModule",{value:!0}),t);import{promises as i1}from"node:fs";import*as TA from"node:path";import*as Dfe from"node:os";import{randomBytes as tYe}from"node:crypto";import{execFile as rYe}from"node:child_process";import{promisify as nYe}from"node:util";async function Gh(){let t=process.env.OIOXO_TOKEN?.trim();if(t)return{token:t,expiresAt:Number.MAX_SAFE_INTEGER,device:process.env.OIOXO_DEVICE_ID||"env"};try{let e=JSON.parse(await i1.readFile(B8,"utf8"));return e?.token?e:null}catch{return null}}async function sYe(t){if(process.platform!=="win32")return;let e=process.env.USERNAME||process.env.USER;if(e)try{await iYe("icacls",[t,"/inheritance:r","/grant:r",`${e}:F`],{windowsHide:!0})}catch{}}async function Ife(t){await i1.mkdir(EA,{recursive:!0}),await i1.writeFile(B8,JSON.stringify(t,null,2),{encoding:"utf8",mode:384}),await sYe(B8)}async function Ffe(){try{await i1.unlink(B8)}catch{}}async function kA(){let t=await Gh();if(t?.device)return t.device;try{let r=await i1.readFile(TA.join(EA,"device"),"utf8");if(r.trim())return r.trim()}catch{}let e=tYe(16).toString("base64url");return await i1.mkdir(EA,{recursive:!0}),await i1.writeFile(TA.join(EA,"device"),e,"utf8"),e}function aYe(){return`cli-${process.platform==="win32"?"windows":process.platform==="darwin"?"mac":"linux"}`}function oYe(){if(process.env.OIOXO_DESKTOP_CLIENT_KEY)return process.env.OIOXO_DESKTOP_CLIENT_KEY;try{return""}catch{}return""}async function YL(){let t=await Gh(),e=await kA(),r={"content-type":"application/json","x-oioxo-client":aYe(),"x-oioxo-device":e},n=oYe();return n&&(r["x-oioxo-desktop-key"]=n),t?.token&&t.expiresAt>Date.now()&&(r.authorization=`Bearer ${t.token}`),r}async function bo(t,e){try{let r=await fetch(`${Us}/api/usage/save`,{method:"POST",headers:await YL(),body:JSON.stringify(t==="report"?{action:t,savedTokens:e}:{action:t})});return r.ok?await r.json():null}catch{return null}}async function Kc(){let t=await Gh();return!!t&&t.expiresAt>Date.now()}async function s1(t=!0){if(!await Kc())return{ok:!1,message:`OIOXO: sign in to use the coding agent. ${CA}
2
+ var XXe=Object.create;var N8=Object.defineProperty;var YXe=Object.getOwnPropertyDescriptor;var JXe=Object.getOwnPropertyNames;var QXe=Object.getPrototypeOf,eYe=Object.prototype.hasOwnProperty;var Kr=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var ce=(t,e)=>()=>(t&&(e=t(t=0)),e);var L=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),yi=(t,e)=>{for(var r in e)N8(t,r,{get:e[r],enumerable:!0})},kfe=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of JXe(e))!eYe.call(t,i)&&i!==r&&N8(t,i,{get:()=>e[i],enumerable:!(n=YXe(e,i))||n.enumerable});return t};var an=(t,e,r)=>(r=t!=null?XXe(QXe(t)):{},kfe(e||!t||!t.__esModule?N8(r,"default",{value:t,enumerable:!0}):r,t)),He=t=>kfe(N8({},"__esModule",{value:!0}),t);import{promises as i1}from"node:fs";import*as TA from"node:path";import*as Dfe from"node:os";import{randomBytes as tYe}from"node:crypto";import{execFile as rYe}from"node:child_process";import{promisify as nYe}from"node:util";async function Gh(){let t=process.env.OIOXO_TOKEN?.trim();if(t)return{token:t,expiresAt:Number.MAX_SAFE_INTEGER,device:process.env.OIOXO_DEVICE_ID||"env"};try{let e=JSON.parse(await i1.readFile(B8,"utf8"));return e?.token?e:null}catch{return null}}async function sYe(t){if(process.platform!=="win32")return;let e=process.env.USERNAME||process.env.USER;if(e)try{await iYe("icacls",[t,"/inheritance:r","/grant:r",`${e}:F`],{windowsHide:!0})}catch{}}async function Ife(t){await i1.mkdir(EA,{recursive:!0}),await i1.writeFile(B8,JSON.stringify(t,null,2),{encoding:"utf8",mode:384}),await sYe(B8)}async function Ffe(){try{await i1.unlink(B8)}catch{}}async function kA(){let t=await Gh();if(t?.device)return t.device;try{let r=await i1.readFile(TA.join(EA,"device"),"utf8");if(r.trim())return r.trim()}catch{}let e=tYe(16).toString("base64url");return await i1.mkdir(EA,{recursive:!0}),await i1.writeFile(TA.join(EA,"device"),e,"utf8"),e}function aYe(){return`cli-${process.platform==="win32"?"windows":process.platform==="darwin"?"mac":"linux"}`}function oYe(){if(process.env.OIOXO_DESKTOP_CLIENT_KEY)return process.env.OIOXO_DESKTOP_CLIENT_KEY;try{return"oioxo_fp_iIZcl4DsGORBvNab2v9OAsufqXKfJ6SlyU26mrohmS8"}catch{}return""}async function YL(){let t=await Gh(),e=await kA(),r={"content-type":"application/json","x-oioxo-client":aYe(),"x-oioxo-device":e},n=oYe();return n&&(r["x-oioxo-desktop-key"]=n),t?.token&&t.expiresAt>Date.now()&&(r.authorization=`Bearer ${t.token}`),r}async function bo(t,e){try{let r=await fetch(`${Us}/api/usage/save`,{method:"POST",headers:await YL(),body:JSON.stringify(t==="report"?{action:t,savedTokens:e}:{action:t})});return r.ok?await r.json():null}catch{return null}}async function Kc(){let t=await Gh();return!!t&&t.expiresAt>Date.now()}async function s1(t=!0){if(!await Kc())return{ok:!1,message:`OIOXO: sign in to use the coding agent. ${CA}
3
3
  Free accounts include a monthly allowance; OIOXO Pro is unlimited \u2192 ${Vh}`};let e=await bo("check");return e?e.tier==="anon"?{ok:!1,message:`Your OIOXO session expired. ${CA}`}:t&&!e.optimize?{ok:!1,message:`You've used your monthly OIOXO allowance. OIOXO Pro is unlimited \u2192 ${Vh}`}:{ok:!0,state:e}:t?{ok:!1,message:"OIOXO could not verify your plan (oioxo.com unreachable). The coding agent is paused until the connection returns."}:{ok:!0,state:null}}var iYe,Us,EA,B8,Vh,CA,_l=ce(()=>{"use strict";iYe=nYe(rYe),Us=process.env.OIOXO_CONTROL_PLANE?.replace(/\/$/,"")||"https://oioxo.com",EA=process.env.OIOXO_HOME||TA.join(Dfe.homedir(),".oioxo"),B8=TA.join(EA,"credentials.json");Vh="https://oioxo.com/?upgrade=pro",CA="Run `oioxo login` in a terminal to connect your OIOXO account."});import*as Pfe from"node:http";import{randomBytes as cYe}from"node:crypto";import{spawn as JL}from"node:child_process";function QL(t){let e=process.platform;e==="win32"?JL("explorer.exe",[t],{detached:!0,stdio:"ignore"}).unref():e==="darwin"?JL("open",[t],{detached:!0,stdio:"ignore"}).unref():JL("xdg-open",[t],{detached:!0,stdio:"ignore"}).unref()}async function U8(){let t=cYe(24).toString("base64url"),e=await kA(),r=new Promise((a,c)=>{let d=Pfe.createServer((h,p)=>{let x=new URL(Us).origin;if(p.setHeader("Access-Control-Allow-Origin",x),p.setHeader("Access-Control-Allow-Methods","POST, OPTIONS"),p.setHeader("Access-Control-Allow-Headers","content-type"),p.setHeader("Access-Control-Allow-Private-Network","true"),h.method==="OPTIONS"){p.writeHead(204).end();return}if(h.method!=="POST"||h.url!=="/oioxo/token"){p.writeHead(404).end();return}let y="";h.on("data",v=>{y+=v,y.length>64e3&&h.destroy()}),h.on("end",()=>{try{let v=h.headers["content-type"]??"",_;if(v.includes("application/json"))_=JSON.parse(y);else{let A=new URLSearchParams(y);_={state:A.get("state")??void 0,token:A.get("token")??void 0,expiresInSeconds:A.get("expiresInSeconds")?Number(A.get("expiresInSeconds")):void 0}}if(_.state!==t||!_.token){p.writeHead(400,{"content-type":"text/html"}).end("<p>OIOXO: invalid or expired login request. Run <code>oioxo login</code> again.</p>"),d.close(),c(new Error("Invalid or expired login request"));return}p.writeHead(200,{"content-type":"text/html"}).end(lYe),d.close(),a({token:_.token,expiresInSeconds:_.expiresInSeconds})}catch{p.writeHead(400).end(),d.close(),c(new Error("Failed to parse login response"))}}),h.on("error",()=>{d.close(),c(new Error("Connection lost during login"))})});d.on("error",c),d.listen(0,"127.0.0.1",()=>{let h=d.address(),p=typeof h=="object"&&h?h.port:0,x=`${Us}/cli-auth?port=${p}&state=${t}`;console.log(`
4
4
  OIOXO \u2014 connect your account`),console.log(`Opening ${x}`),console.log(`If the browser does not open, paste the URL yourself.
5
5
  `),process.env.OIOXO_NO_BROWSER!=="1"&&QL(x)}),setTimeout(()=>{d.close(),c(new Error("timeout"))},uYe).unref()}),{token:n,expiresInSeconds:i}=await r;await Ife({token:n,expiresAt:Date.now()+(i??720*3600)*1e3,device:e});let s=await bo("check");if(s?.tier==="pro")console.log("Connected \u2014 OIOXO Pro: unlimited context engine. \u2713");else if(s?.tier==="free"){let a=s.remainingTokens?.toLocaleString()??"\u2014";console.log(`Connected \u2014 OIOXO Free: ${a} saved-tokens remaining this month. Pro is unlimited \u2192 https://oioxo.com/?upgrade=pro \u2713`)}else console.log("Connected. \u2713")}var uYe,lYe,M8=ce(()=>{"use strict";_l();uYe=5*6e4,lYe=`<!doctype html><html><head><meta charset="utf-8"><title>OIOXO CLI connected</title></head>
@@ -681,8 +681,8 @@ Tools:
681
681
  - done {"summary":"..."} \u2192 the task is genuinely complete and verified
682
682
 
683
683
  How to work, like a real IDE:
684
- 1. FIRST, make a plan: call the plan tool with the concrete steps this task needs (each file to build, the tests, the final verify). Then readFile PROGRESS.md (if it exists) and listFiles. Each turn, look at the PLAN and do the FIRST unchecked step; check it off when done. This is how you finish a multi-file project without losing track.
685
- 2. Build the project FILE BY FILE: writeFile a new file with real, complete code (not a stub); for changes to existing files, editFile with a small patch. The files on disk are your memory \u2014 you don't hold everything in your head.
684
+ 1. Just START BUILDING. For a multi-file task, your FIRST action should usually be writeFile of the first real file \u2014 don't burn a turn explaining or restating the goal. (For a big/unfamiliar task you MAY call the plan tool once to set a todo list, then immediately do the first step the same way \u2014 but planning is optional and never the whole turn.) When changing existing code, readFile/listFiles first to see what's there.
685
+ 2. Build the project FILE BY FILE: writeFile a new file with real, complete code (not a stub); for changes to existing files, editFile with a small patch. The files on disk are your memory \u2014 you don't hold everything in your head. Keep going file by file until every file exists \u2014 never stop after only describing what you'll do.
686
686
  FOLDERS ARE IMPLICIT \u2014 there is NO createFolder/mkdir tool. To make a package folder, just writeFile a file with that path, e.g. writeFile "taskflow/__init__.py" or "taskflow/storage.py" and the "taskflow/" folder is created automatically. Never try to create a directory as a separate step.
687
687
  3. After writing code, verify it (typecheck / runTests / open the app) and FIX what's broken.
688
688
  4. Keep the PROGRESS note current. Work one concrete thing at a time.
@@ -1250,7 +1250,7 @@ ${T.snippet}`:""}`).join(`
1250
1250
  `);return Gs(A||"No results.")}catch(v){return Gs(`web_search failed: ${v instanceof Error?v.message:"error"}`)}}),e.tool("fetch_url","Fetch a web page (http/https only) and return its readable text. Use to read a doc/article \u2014 typically a URL found via web_search.",{url:ao.string().describe("The full http(s) URL.")},async({url:x})=>{let y=await VS();if(!y.ok)return HS(y.message);try{let _=await(await fetch(`${Us}/tools/fetch?url=${encodeURIComponent(x)}`,{signal:AbortSignal.timeout(12e3)})).json();return Gs(_.error?`fetch_url failed: ${_.error}`:_.text??"(empty)")}catch(v){return Gs(`fetch_url failed: ${v instanceof Error?v.message:"error"}`)}});let c=null,d=!1,h=async x=>{if(d=x,c)return c;let{makePlaywrightBackend:y}=await Promise.resolve().then(()=>(mce(),pce)),{BrowserController:v}=await Promise.resolve().then(()=>(RM(),QMe)),_=await y({headless:!1});return c=new v(_,{confirmNavigate:async()=>d,allowEvaluate:!1}),c};e.tool("browser",'Drive a REAL browser on this machine to see and test web pages \u2014 navigate, read a numbered snapshot of clickable elements, click/type by ref, screenshot. Runs LOCALLY (the page never leaves the device). Local URLs (localhost) are always allowed; set allow_external:true to permit other sites. Call one verb at a time; after navigate the result lists elements like [3] button "Sign in" \u2014 click by that ref.',{verb:ao.enum(["navigate","snapshot","screenshot","click","type","waitFor","scrollTo","back","reload","close"]).describe("The action."),url:ao.string().optional().describe("For navigate: the URL."),ref:ao.number().optional().describe("For click/type/scrollTo: element number from the latest snapshot."),text:ao.string().optional().describe("For type: text to enter. For click: visible text to match. For waitFor: text to wait for."),selector:ao.string().optional().describe("Optional CSS selector (prefer ref)."),submit:ao.boolean().optional().describe("For type: press Enter after typing."),allow_external:ao.boolean().optional().describe("Permit navigating to non-local sites (privacy gate; default false).")},async({verb:x,url:y,ref:v,text:_,selector:A,submit:T,allow_external:k})=>{let C=await VS();if(!C.ok)return HS(C.message);try{let E=await h(!!k);if(x==="close")return await E.dispose(),c=null,Gs("Browser closed.");let I=await E.run({verb:x,url:y,ref:v,text:_,selector:A,submit:T});if(!I.ok)return Gs(`browser ${x} failed: ${I.error??"unknown error"}`);let R=`${I.title||""} \u2014 ${I.url}`.trim(),B=I.snapshot?`
1251
1251
  ${I.snapshot}`:"",U=I.consoleErrors?.length?`
1252
1252
  console errors: ${I.consoleErrors.slice(0,3).join(" | ")}`:"",H=I.screenshot?`
1253
- (screenshot captured: ${I.screenshot.length} bytes \u2014 not shown as text)`:"";return Gs(`${R}${B}${U}${H}`.trim()||"OK")}catch(E){return Gs(`browser failed: ${E instanceof Error?E.message:"error"}`)}});let p=new FM;await e.connect(p)}L8();$8();_l();var kce=(()=>{try{return"0.5.53"}catch{}try{return _Le(import.meta.url)("../../package.json").version}catch{return"0.0.0"}})(),_It=`OIOXO ${kce} \u2014 context engine + terminal coding agent (https://oioxo.com)
1253
+ (screenshot captured: ${I.screenshot.length} bytes \u2014 not shown as text)`:"";return Gs(`${R}${B}${U}${H}`.trim()||"OK")}catch(E){return Gs(`browser failed: ${E instanceof Error?E.message:"error"}`)}});let p=new FM;await e.connect(p)}L8();$8();_l();var kce=(()=>{try{return"0.5.55"}catch{}try{return _Le(import.meta.url)("../../package.json").version}catch{return"0.0.0"}})(),_It=`OIOXO ${kce} \u2014 context engine + terminal coding agent (https://oioxo.com)
1254
1254
 
1255
1255
  Private, on your device. Cut your AI bill by up to ~90% in Copilot, Cursor & Claude,
1256
1256
  and code from your terminal \u2014 nothing leaves your machine.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oioxo-mcp",
3
- "version": "0.5.53",
3
+ "version": "0.5.55",
4
4
  "description": "OIOXO — cut your AI bill by up to ~90%: it feeds Claude Code, Copilot, Cursor and any MCP agent only the relevant slice of your codebase instead of whole files. Also a private terminal coding agent (`oioxo code`, on-device with --local or any key). Runs on your device; your own devices can build together over Wi-Fi.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "type": "module",