oioxo-mcp 0.5.6 → 0.5.7

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 (3) hide show
  1. package/README.md +125 -120
  2. package/bundle/cli.js +8 -5
  3. package/package.json +62 -62
package/README.md CHANGED
@@ -1,120 +1,125 @@
1
- # OIOXO — cut your AI bill ~90%, and code privately from the terminal
2
-
3
- **Your AI tools read far more of your code than they need — and you pay for every word.**
4
-
5
- OIOXO fixes that from one command-line tool. It does two things:
6
- 1. **Makes Copilot, Cursor & Claude ~90% cheaper.** It sits between your project and your AI tools and hands them only the small, relevant slice — instead of letting them read whole files. Same answers, a fraction of the cost.
7
- 2. **Codes for you, privately.** `oioxo code "<task>"` plans, edits, and checks the work right in your repo — using your own key **or a local model** — so nothing leaves your machine. See [Code in your terminal](#code-in-your-terminal--oioxo-code).
8
-
9
- **~90% fewer words per question** (measured on a real codebase). A question that would cost ~50,000 words comes back as ~5,000 — same answer, a fraction of the cost.
10
-
11
- ## Quick start
12
-
13
- ```bash
14
- npm install -g oioxo-mcp
15
-
16
- oioxo login # connect your OIOXO account (opens the browser)
17
- oioxo init # wire OIOXO into the agents in this project
18
- ```
19
-
20
- Restart your agent. From the next prompt on, it calls OIOXO before reading files.
21
-
22
- Prefer zero terminal? Install the [OIOXO VS Code extension](https://marketplace.visualstudio.com/items?itemName=oioxo.oioxo-vscode) — it wires every workspace automatically and shows your live savings in the status bar.
23
-
24
- ## Code in your terminal — `oioxo code`
25
-
26
- OIOXO isn't only a context engine for *other* agents — it's a coding agent in its own right. `oioxo code` plans, edits, and **verifies on your machine** (runs your tests / typecheck), then shows the diff and asks before writing any file.
27
-
28
- ```bash
29
- # with your own key (BYOK)the capsule means even a frontier model reads ~10× fewer tokens
30
- OPENAI_API_KEY=… oioxo code "add a --json flag to the status command"
31
- ANTHROPIC_API_KEY=… oioxo code "fix the failing test" --verify "npm test"
32
-
33
- # local Ollama private, zero API tokens, nothing leaves your machine
34
- OIOXO_PROVIDER=ollama OIOXO_MODEL=qwen2.5-coder oioxo code "add input validation to the signup form"
35
- ```
36
-
37
- - **Verified, not vibes** — every change runs through your tests/typecheck on a shadow copy; a red result is fed back and repaired. Your real files are touched only after you approve the diff.
38
- - **Bring any model** — OpenAI, Anthropic, Groq, Mistral, Together, local Ollama, or any OpenAI-compatible base (`OIOXO_PROVIDER` / `OIOXO_BASE_URL` / `OIOXO_MODEL` / `OIOXO_API_KEY`).
39
- - **Or fully local, no key** — point it at [Ollama](https://ollama.com) (`OIOXO_PROVIDER=ollama OIOXO_MODEL=qwen2.5-coder`) and nothing leaves your machine. Or run the built-in on-device coder with **`oioxo code --local`** (open model via llama.cpp; one-time `npm i -g node-llama-cpp`) — no key, nothing uploaded.
40
-
41
- Flags: `--verify "<cmd>"` (override the test command) · `--yes` (apply without the prompt) · `--max-iters N` · `--local` (built-in on-device coder, no key — one-time `npm i -g node-llama-cpp`).
42
-
43
- ## Let your devices build together
44
-
45
- Put two of your own devices on the **same Wi-Fi** and they work as one — this machine can lend
46
- its power to another device's build (so your phone or a thin laptop builds on *this* machine's
47
- GPU), or borrow power the other way. Start it with `oioxo invite` (or `oioxo join`); pairing is
48
- just a short code (a QR or a string), with nothing going through our servers. Lend power and you
49
- earn **free coding time** for it. *(Feature name: Compute Mesh.)*
50
-
51
- ## Why developers use it
52
-
53
- - 💸 **Your AI costs drop ~90%** Copilot premium requests, Claude limits, and API keys all last several times longer.
54
- - **Better answers, too** focused context beats 50k words of noise. Your AI gets the exact code in play, plus the parts it actually depends on.
55
- - 🔒 **100% on your device** — your code is read and searched locally, never uploaded. Only the *amount* you saved is counted.
56
- - 🪄 **One command** — `init` finds Claude Code, VS Code/Copilot, Cursor, Windsurf, Gemini CLI and Codex, and sets them up without touching your other tools.
57
-
58
- ## How it works (for you)
59
-
60
- 1. **Point it at your project** — `oioxo init` wires your agents in one command.
61
- 2. **Ask your agent normally** — it calls OIOXO first, gets just the relevant slice, and answers.
62
- 3. **Watch the savings add up** — `oioxo-mcp status` shows tokens saved; nothing about your code leaves your machine.
63
-
64
- ## Tools your agent gets
65
-
66
- | Tool | What it does |
67
- |---|---|
68
- | `get_context` | The minimal relevant slice of the codebase for any task |
69
- | `get_impact` | Blast radius — everything a change might break, before refactoring |
70
- | `get_skeleton` | A file's full API surface at ~10% of its token cost |
71
- | `remember` / `recall` | Durable project memory in `.oioxo/`, shared with the OIOXO IDEs |
72
-
73
- ## Commands
74
-
75
- ```
76
- # Code
77
- oioxo code "<task>" code in this repo: capsule-grounded, verified, then asks
78
- before writing (--verify "<cmd>" · --yes · --max-iters · --local)
79
- --local runs the built-in on-device coder, no key
80
-
81
- # Account
82
- oioxo login | logout connect / disconnect your OIOXO account
83
- oioxo whoami | usage who you're signed in as · your saved-token allowance
84
- oioxo status plan, savings and on-device index stats
85
-
86
- # Devices (Compute Mesh) — build together on the same Wi-Fi, one account
87
- oioxo invite show a code; the device that HAS the project scans it,
88
- and this machine lends its coder to that build
89
- oioxo join scan/paste the code from the device that has the project,
90
- and lend this machine's compute to it
91
- oioxo devices find your other same-account devices on this Wi-Fi
92
- oioxo stop-helping how to stop lending (Ctrl+C in the helper's terminal)
93
-
94
- # AI / model
95
- oioxo model list | use <p> [m] show providers / pin one (and a model)
96
- oioxo config set|get|list|unset persist provider/model/baseUrl/apiKey
97
-
98
- # Agents (MCP)
99
- oioxo init [--all] wire OIOXO into the AI agents in this project
100
- oioxo mcp list show which agents OIOXO is wired into
101
- oioxo serve run the MCP server over stdio (agents call this)
102
-
103
- # Maintenance
104
- oioxo doctor check creds, connection, coder config, agent wiring
105
- oioxo update how to update the CLI
106
- oioxo --version | --help
107
- ```
108
-
109
- > The binary is published as `oioxo-mcp`; `oioxo …` and `oioxo-mcp …` are the same command.
110
-
111
- ## Pricing
112
-
113
- - **Free** — a generous monthly saved-tokens allowance with any OIOXO account.
114
- - **OIOXO Pro $3.99/mo** unlimited, across every agent, project and machine. [oioxo.com](https://oioxo.com/?upgrade=pro)
115
-
116
- ---
117
-
118
- *From the makers of the [OIOXO IDE](https://oioxo.com) the AI editor that runs its models in your browser.*
119
-
120
- © OIOXO · [oioxo.com](https://oioxo.com) · [Docs](https://oioxo.com/docs) · License: see LICENSE.md
1
+ # OIOXO — cut your AI bill up to ~90%, and code privately from the terminal
2
+
3
+ **Your AI tools read far more of your code than they need — and you pay for every word.**
4
+
5
+ OIOXO fixes that from one command-line tool. It does two things:
6
+ 1. **Makes Copilot, Cursor & Claude up to ~90% cheaper.** It sits between your project and your AI tools and hands them only the small, relevant slice — instead of letting them read whole files. Same answers, a fraction of the cost.
7
+ 2. **Codes for you, privately.** `oioxo code "<task>"` plans, edits, and checks the work right in your repo — using your own key **or a local model** — so nothing leaves your machine. See [Code in your terminal](#code-in-your-terminal--oioxo-code).
8
+
9
+ **Up to ~90% fewer words per question** (measured on a real codebase). A question that would cost ~50,000 words can come back as ~5,000 — same answer, a fraction of the cost.
10
+
11
+ ## Quick start
12
+
13
+ ```bash
14
+ npm install -g oioxo-mcp
15
+
16
+ oioxo login # connect your OIOXO account (opens the browser)
17
+ oioxo init # wire OIOXO into the agents in this project
18
+ ```
19
+
20
+ Restart your agent. From the next prompt on, it calls OIOXO before reading files.
21
+
22
+ Prefer zero terminal? Install the [OIOXO VS Code extension](https://marketplace.visualstudio.com/items?itemName=oioxo.oioxo-vscode) — it wires every workspace automatically and shows your live savings in the status bar.
23
+
24
+ ## Code in your terminal — `oioxo code`
25
+
26
+ OIOXO isn't only a context engine for *other* agents — it's a coding agent in its own right. `oioxo code` plans, edits, and **verifies on your machine** (runs your tests / typecheck), then shows the diff and asks before writing any file.
27
+
28
+ <p align="center"><img src="https://aradsoftca.github.io/OIOXO/assets/terminal.gif" alt="oioxo code — reads only the slice it needs, plans, writes, runs your tests, then asks before writing" width="640"></p>
29
+ <p align="center"><sub><em>A real <code>oioxo code</code> runreads ~5,000 words not 50,000, writes, runs your tests, and asks before it touches a file.</em></sub></p>
30
+
31
+ ```bash
32
+ # with your own key (BYOK) — the capsule means even a frontier model reads ~10× fewer tokens
33
+ OPENAI_API_KEY=… oioxo code "add a --json flag to the status command"
34
+ ANTHROPIC_API_KEY=… oioxo code "fix the failing test" --verify "npm test"
35
+
36
+ # local Ollama — private, zero API tokens, nothing leaves your machine
37
+ OIOXO_PROVIDER=ollama OIOXO_MODEL=qwen2.5-coder oioxo code "add input validation to the signup form"
38
+ ```
39
+
40
+ - **Verified, not vibes** — every change runs through your tests/typecheck on a shadow copy; a red result is fed back and repaired. Your real files are touched only after you approve the diff.
41
+ - **Bring any model** OpenAI, Anthropic, Groq, Mistral, Together, local Ollama, or any OpenAI-compatible base (`OIOXO_PROVIDER` / `OIOXO_BASE_URL` / `OIOXO_MODEL` / `OIOXO_API_KEY`).
42
+ - **Or fully local, no key** — point it at [Ollama](https://ollama.com) (`OIOXO_PROVIDER=ollama OIOXO_MODEL=qwen2.5-coder`) and nothing leaves your machine. Or run the built-in on-device coder with **`oioxo code --local`** (open model via llama.cpp; one-time `npm i -g node-llama-cpp`) — no key, nothing uploaded.
43
+
44
+ Flags: `--verify "<cmd>"` (override the test command) · `--yes` (apply without the prompt) · `--max-iters N` · `--local` (built-in on-device coder, no key — one-time `npm i -g node-llama-cpp`).
45
+
46
+ ## Let your devices build together
47
+
48
+ <p align="center"><img src="https://aradsoftca.github.io/OIOXO/assets/mesh.gif" alt="Compute Mesh your phone borrows your laptop's power over Wi-Fi" width="620"></p>
49
+
50
+ Put two of your own devices on the **same Wi-Fi** and they work as one — this machine can lend
51
+ its power to another device's build (so your phone or a thin laptop builds on *this* machine's
52
+ GPU), or borrow power the other way. Start it with `oioxo invite` (or `oioxo join`); pairing is
53
+ just a short code (a QR or a string), with nothing going through our servers. Lend power and you
54
+ earn **free coding time** for it. *(Feature name: Compute Mesh.)*
55
+
56
+ ## Why developers use it
57
+
58
+ - 💸 **Your AI costs drop by up to ~90%** — Copilot premium requests, Claude limits, and API keys all last several times longer.
59
+ - ⚡ **Better answers, too** — focused context beats 50k words of noise. Your AI gets the exact code in play, plus the parts it actually depends on.
60
+ - 🔒 **100% on your device** — your code is read and searched locally, never uploaded. Only the *amount* you saved is counted.
61
+ - 🪄 **One command** — `init` finds Claude Code, VS Code/Copilot, Cursor, Windsurf, Gemini CLI and Codex, and sets them up without touching your other tools.
62
+
63
+ ## How it works (for you)
64
+
65
+ 1. **Point it at your project** — `oioxo init` wires your agents in one command.
66
+ 2. **Ask your agent normally** — it calls OIOXO first, gets just the relevant slice, and answers.
67
+ 3. **Watch the savings add up** — `oioxo-mcp status` shows tokens saved; nothing about your code leaves your machine.
68
+
69
+ ## Tools your agent gets
70
+
71
+ | Tool | What it does |
72
+ |---|---|
73
+ | `get_context` | The minimal relevant slice of the codebase for any task |
74
+ | `get_impact` | Blast radius — everything a change might break, before refactoring |
75
+ | `get_skeleton` | A file's full API surface at ~10% of its token cost |
76
+ | `remember` / `recall` | Durable project memory in `.oioxo/`, shared with the OIOXO IDEs |
77
+
78
+ ## Commands
79
+
80
+ ```
81
+ # Code
82
+ oioxo code "<task>" code in this repo: capsule-grounded, verified, then asks
83
+ before writing (--verify "<cmd>" · --yes · --max-iters · --local)
84
+ --local runs the built-in on-device coder, no key
85
+
86
+ # Account
87
+ oioxo login | logout connect / disconnect your OIOXO account
88
+ oioxo whoami | usage who you're signed in as · your saved-token allowance
89
+ oioxo status plan, savings and on-device index stats
90
+
91
+ # Devices (Compute Mesh) build together on the same Wi-Fi, one account
92
+ oioxo invite show a code; the device that HAS the project scans it,
93
+ and this machine lends its coder to that build
94
+ oioxo join scan/paste the code from the device that has the project,
95
+ and lend this machine's compute to it
96
+ oioxo devices find your other same-account devices on this Wi-Fi
97
+ oioxo stop-helping how to stop lending (Ctrl+C in the helper's terminal)
98
+
99
+ # AI / model
100
+ oioxo model list | use <p> [m] show providers / pin one (and a model)
101
+ oioxo config set|get|list|unset persist provider/model/baseUrl/apiKey
102
+
103
+ # Agents (MCP)
104
+ oioxo init [--all] wire OIOXO into the AI agents in this project
105
+ oioxo mcp list show which agents OIOXO is wired into
106
+ oioxo serve run the MCP server over stdio (agents call this)
107
+
108
+ # Maintenance
109
+ oioxo doctor check creds, connection, coder config, agent wiring
110
+ oioxo update how to update the CLI
111
+ oioxo --version | --help
112
+ ```
113
+
114
+ > The binary is published as `oioxo-mcp`; `oioxo …` and `oioxo-mcp …` are the same command.
115
+
116
+ ## Pricing
117
+
118
+ - **Free**a generous monthly saved-tokens allowance with any OIOXO account.
119
+ - **OIOXO Pro — $3.99/mo** — unlimited, across every agent, project and machine. → [oioxo.com](https://oioxo.com/?upgrade=pro)
120
+
121
+ ---
122
+
123
+ *From the makers of the [OIOXO IDE](https://oioxo.com) — the AI editor that runs its models in your browser.*
124
+
125
+ © OIOXO · [oioxo.com](https://oioxo.com) · [Docs](https://oioxo.com/docs) · License: see LICENSE.md
package/bundle/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  var hre=Object.create;var w_=Object.defineProperty;var pre=Object.getOwnPropertyDescriptor;var mre=Object.getOwnPropertyNames;var gre=Object.getPrototypeOf,yre=Object.prototype.hasOwnProperty;var on=(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 mr=(t,e)=>()=>(t&&(e=t(t=0)),e);var v=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),La=(t,e)=>{for(var r in e)w_(t,r,{get:e[r],enumerable:!0})},RB=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of mre(e))!yre.call(t,s)&&s!==r&&w_(t,s,{get:()=>e[s],enumerable:!(n=pre(e,s))||n.enumerable});return t};var vt=(t,e,r)=>(r=t!=null?hre(gre(t)):{},RB(e||!t||!t.__esModule?w_(r,"default",{value:t,enumerable:!0}):r,t)),H=t=>RB(w_({},"__esModule",{value:!0}),t);import{promises as vl}from"node:fs";import*as Im from"node:path";import*as NB from"node:os";import{randomBytes as xre}from"node:crypto";import{execFile as bre}from"node:child_process";import{promisify as _re}from"node:util";async function Ua(){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 vl.readFile(S_,"utf8"));return e?.token?e:null}catch{return null}}async function wre(t){if(process.platform!=="win32")return;let e=process.env.USERNAME||process.env.USER;if(e)try{await vre("icacls",[t,"/inheritance:r","/grant:r",`${e}:F`],{windowsHide:!0})}catch{}}async function BB(t){await vl.mkdir(Tm,{recursive:!0}),await vl.writeFile(S_,JSON.stringify(t,null,2),{encoding:"utf8",mode:384}),await wre(S_)}async function $B(){try{await vl.unlink(S_)}catch{}}async function Om(){let t=await Ua();if(t?.device)return t.device;try{let r=await vl.readFile(Im.join(Tm,"device"),"utf8");if(r.trim())return r.trim()}catch{}let e=xre(16).toString("base64url");return await vl.mkdir(Tm,{recursive:!0}),await vl.writeFile(Im.join(Tm,"device"),e,"utf8"),e}function Sre(){return`cli-${process.platform==="win32"?"windows":process.platform==="darwin"?"mac":"linux"}`}function Are(){if(process.env.OIOXO_DESKTOP_CLIENT_KEY)return process.env.OIOXO_DESKTOP_CLIENT_KEY;try{return""}catch{}return""}async function WC(){let t=await Ua(),e=await Om(),r={"content-type":"application/json","x-oioxo-client":Sre(),"x-oioxo-device":e},n=Are();return n&&(r["x-oioxo-desktop-key"]=n),t?.token&&t.expiresAt>Date.now()&&(r.authorization=`Bearer ${t.token}`),r}async function Dn(t,e){try{let r=await fetch(`${hn}/api/usage/save`,{method:"POST",headers:await WC(),body:JSON.stringify(t==="report"?{action:t,savedTokens:e}:{action:t})});return r.ok?await r.json():null}catch{return null}}async function vi(){let t=await Ua();return!!t&&t.expiresAt>Date.now()}async function MB(){if(!await vi())return{ok:!1,message:`OIOXO: sign in to use the coding agent. ${Pm}
3
- Free accounts include a monthly allowance; OIOXO Pro is unlimited \u2192 ${Da}`};let t=await Dn("check");return t?t.optimize?{ok:!0,state:t}:t.tier==="anon"?{ok:!1,message:`Your OIOXO session expired. ${Pm}`}:{ok:!1,message:`You've used your monthly OIOXO allowance. OIOXO Pro is unlimited \u2192 ${Da}`}:{ok:!1,message:"OIOXO could not verify your plan (oioxo.com unreachable). The coding agent is paused until the connection returns."}}var vre,hn,Tm,S_,Da,Pm,zo=mr(()=>{"use strict";vre=_re(bre),hn=process.env.OIOXO_CONTROL_PLANE?.replace(/\/$/,"")||"https://oioxo.com",Tm=process.env.OIOXO_HOME||Im.join(NB.homedir(),".oioxo"),S_=Im.join(Tm,"credentials.json");Da="https://oioxo.com/?upgrade=pro",Pm="Run `oioxo login` in a terminal to connect your OIOXO account."});import VB from"node:os";function wl(){return nh}async function KB(){let t=ZB();try{let e=await fetch(`${hn}/api/models?platform=${t}`,{headers:{"x-oioxo-client":t}});if(!e.ok)return nh;let r=await e.json();r.selection&&(nh=r.selection)}catch{}return nh}function ZB(){let t=process.platform;return`cli-${t==="darwin"?"mac":t==="win32"?"windows":"linux"}`}async function ine(){try{let{getLlama:t}=await import("node-llama-cpp");return!!(await t()).gpu}catch{return!1}}async function GB(t=()=>{}){let e=ZB(),r,n;try{let m=await fetch(`${hn}/api/models?platform=${e}`,{headers:{"x-oioxo-client":e}});if(!m.ok)return null;let y=await m.json();r=y.models??[],n=y.selection??{},nh=n}catch{return null}let s=r.filter(m=>m.kind==="generic"||m.kind==="desktop").sort((m,y)=>m.approxMB-y.approxMB);if(!s.length)return null;let i=VB.totalmem()/1024**3,o=await ine(),a=n.budgetFracOfTotalRam??.45,c=n.nativeDesktopCapMB??12e3,u=Math.min(i*1024*a,c);if(n.defaultAssetId){let m=s.find(y=>y.assetId===n.defaultAssetId);if(m&&m.approxMB<=u)return{...HB(m),reason:`admin-pinned ${m.name} fits (${FB(i)} RAM, gpu=${o})`}}let l=[...s].reverse().find(m=>m.approxMB<=u),d=s.find(m=>m.assetId===n.floorAssetId),f=l??d??s[0],p=l?`largest fitting tier (${FB(i)} RAM \xD7 ${a} \u2192 ${Math.round(u)}MB, gpu=${o})`:`device below floor \u2014 using ${f.name}`;return{...HB(f),reason:p}}function HB(t){return{assetId:t.assetId,name:t.name,manifestUrl:t.manifestUrl,approxMB:t.approxMB}}function FB(t){return`${t.toFixed(1)}GB`}function sk(){let t=VB.totalmem()/1073741824,e=[{gb:2,uri:"hf:Qwen/Qwen2.5-Coder-0.5B-Instruct-GGUF/qwen2.5-coder-0.5b-instruct-q4_k_m.gguf",label:"Qwen2.5-Coder-0.5B"},{gb:4,uri:"hf:Qwen/Qwen2.5-Coder-1.5B-Instruct-GGUF/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf",label:"Qwen2.5-Coder-1.5B"},{gb:10,uri:"hf:Qwen/Qwen2.5-Coder-7B-Instruct-GGUF/qwen2.5-coder-7b-instruct-q4_k_m.gguf",label:"Qwen2.5-Coder-7B"}],r=t*(nh?.budgetFracOfTotalRam??.45),n=e[0];for(let s of e)(s.gb*.45<=r||s.gb<=t*.9)&&(n=s);return t>=16?n=e[2]:t>=6?n=e[1]:n=e[0],{uri:process.env.OIOXO_LOCAL_MODEL||n.uri,label:n.label}}var nh,T_=mr(()=>{"use strict";zo();nh=null});function QB(){return sh}async function e$(){if(JB&&sh)return sh;JB=!0;try{let t=await fetch(`${hn}/api/app-config`);if(!t.ok)return sh;let e=await t.json();e.coder&&(sh=e.coder)}catch{}return sh}var sh,JB,t$=mr(()=>{"use strict";zo();sh=null,JB=!1});function yne(t){let e=t.length%4?"=".repeat(4-t.length%4):"",r=atob(t.replace(/-/g,"+").replace(/_/g,"/")+e),n=new Uint8Array(r.length);for(let s=0;s<r.length;s++)n[s]=r.charCodeAt(s);return n}function r$(t){let e=t.indexOf(".");if(e<1)return null;try{return JSON.parse(gne.decode(yne(t.slice(0,e))))}catch{return null}}var ECe,gne,ok=mr(()=>{"use strict";ECe=new TextEncoder,gne=new TextDecoder});function n$(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e.length;n++)r[n]=e.charCodeAt(n);return r}async function xne(t,e){return crypto.subtle.importKey("raw",ak(t),{name:"AES-GCM"},!1,e)}async function s$(t,e){let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:ak(n$(t.iv))},await xne(e,["decrypt"]),ak(n$(t.ct)));return new Uint8Array(r)}var kCe,ak,i$=mr(()=>{"use strict";kCe=new TextEncoder,ak=t=>t});function bne(t){let e="";for(let r of t)e+=String.fromCharCode(r);return btoa(e)}function _ne(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e.length;n++)r[n]=e.charCodeAt(n);return r}async function vne(){let t=await crypto.subtle.generateKey({name:"ECDH",namedCurve:"P-256"},!1,["deriveBits"]),e=new Uint8Array(await crypto.subtle.exportKey("raw",t.publicKey));return{publicKeyB64:bne(e),privateKey:t.privateKey}}async function wne(t){return crypto.subtle.importKey("raw",a$(_ne(t)),{name:"ECDH",namedCurve:"P-256"},!1,[])}async function Sne(t,e,r){let n=new Uint8Array(await crypto.subtle.deriveBits({name:"ECDH",public:await wne(e)},t,256)),s=await crypto.subtle.importKey("raw",a$(n),"HKDF",!1,["deriveBits"]),i=await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:o$.encode("oioxo:unlock"),info:o$.encode(r)},s,256);return new Uint8Array(i)}async function Ane(t,e,r,n){let s=`${r}|${n}|${e.assetId}|${t.publicKeyB64}|${e.serverPubB64}`,i=await Sne(t.privateKey,e.serverPubB64,s);return s$(e.wrapped,i)}async function c$(t,e){let r=e.fetchImpl??globalThis.fetch,n=await vne(),s=new AbortController,i=setTimeout(()=>s.abort(),e.timeoutMs??15e3),o;try{o=await r(t,{method:"POST",headers:{"content-type":"application/json",...e.extraHeaders??{}},cache:"no-store",body:JSON.stringify({entitlement:e.entitlement,device:e.device,assetId:e.assetId,clientPubB64:n.publicKeyB64}),signal:s.signal})}catch(c){throw c.name==="AbortError"?new Error("unlock timed out"):c}finally{clearTimeout(i)}if(o.status===403){let c=await o.json().catch(()=>({}));throw new Error("unlock denied: "+(c.reason??"forbidden"))}if(!o.ok)throw new Error("unlock unavailable ("+o.status+")");let a=await o.json();return Ane(n,a,e.sub,e.device)}var o$,a$,u$=mr(()=>{"use strict";i$();ok();o$=new TextEncoder,a$=t=>t});import{homedir as Ene}from"node:os";import l$ from"node:path";import{promises as Bm,createReadStream as Cne,createWriteStream as kne}from"node:fs";import{createHash as d$,createDecipheriv as Tne}from"node:crypto";function Ine(t,e){return/^https?:\/\//i.test(e)?e:t.slice(0,t.lastIndexOf("/")+1)+e.replace(/^\.?\//,"")}async function f$(t,e){let r=wl(),n=e??r?.fetchRetryTries??4,s=r?.fetchRetryBackoffMs??600,i;for(let o=0;o<n;o++){try{let a=await fetch(t);if(a.ok)return a;if(i=new Error(`HTTP ${a.status}`),a.status>=400&&a.status<500&&a.status!==429)break}catch(a){i=a}o<n-1&&await new Promise(a=>setTimeout(a,s*(o+1)))}throw new Error(`fetch failed after ${n} tries: ${i instanceof Error?i.message:String(i)}`)}async function Pne(t){let e=await Om(),r=await WC(),n=await fetch(`${hn}/api/entitlement`,{method:"POST",headers:r,body:JSON.stringify({device:e})});if(!n.ok)throw new Error(`entitlement failed (${n.status}) \u2014 sign in with \`oioxo login\`.`);let{entitlement:s}=await n.json(),i=s?r$(s):null;if(!s||!i)throw new Error("could not establish a session");if(!i.sub||i.sub==="anon")throw new Error("this model is Pro-only \u2014 your account did not unlock it (free entitlement).");return c$(`${hn}/api/code-key`,{entitlement:s,sub:i.sub,device:e,assetId:t,extraHeaders:r,timeoutMs:wl()?.unlockTimeoutMs})}async function h$(t,e,r=()=>{}){let n=l$.join(Ene(),".oioxo","models");await Bm.mkdir(n,{recursive:!0});let s=await(await f$(e)).json();if(!s?.chunks?.length||!s.sha256)throw new Error("OIOXO manifest is malformed");let i=l$.join(n,`${t}-${s.release}.gguf`);try{if((await Bm.stat(i)).size===s.totalBytes){let p=d$("sha256"),m=Cne(i);for await(let y of m)p.update(y);if(p.digest("hex")===s.sha256)return r(`\xB7 OIOXO model cached: ${s.fileName}`),i}}catch{}r(`\xB7 unlocking ${t} (device-bound handshake)\u2026`);let o=Buffer.from(await Pne(t)),a=i+".part",c=kne(a),u=d$("sha256"),l=0,d=[...s.chunks].sort((f,p)=>f.index-p.index);try{for(let f of d){let p=Buffer.from(await(await f$(Ine(e,f.url))).arrayBuffer()),m=Buffer.from(f.iv,"base64"),y=p.subarray(p.length-16),_=p.subarray(0,p.length-16),S=Tne("aes-256-gcm",o,m);S.setAuthTag(y);let C=Buffer.concat([S.update(_),S.final()]);u.update(C),c.write(C)||await new Promise(E=>c.once("drain",()=>E())),l+=C.byteLength,r(`\xB7 decrypting OIOXO model\u2026 ${Math.round(l/s.totalBytes*100)}%`)}}finally{await new Promise((f,p)=>c.end(m=>m?p(m):f()))}if(l!==s.totalBytes)throw await Bm.rm(a,{force:!0}),new Error("OIOXO assembled size mismatch");if(u.digest("hex")!==s.sha256)throw await Bm.rm(a,{force:!0}),new Error("OIOXO integrity check failed");return await Bm.rename(a,i),r(`\xB7 OIOXO model ready: ${s.fileName} (decrypted, private \u2014 never leaves this machine)`),i}var p$=mr(()=>{"use strict";zo();ok();u$();T_()});var g$={};La(g$,{DeviceCoderLocal:()=>ck});import{homedir as One}from"node:os";import m$ from"node:path";import{mkdir as Rne}from"node:fs/promises";function Bne(){return QB()?.cliSystemPrompt||Nne}function $ne(t){let e=[`TASK:
3
+ Free accounts include a monthly allowance; OIOXO Pro is unlimited \u2192 ${Da}`};let t=await Dn("check");return t?t.optimize?{ok:!0,state:t}:t.tier==="anon"?{ok:!1,message:`Your OIOXO session expired. ${Pm}`}:{ok:!1,message:`You've used your monthly OIOXO allowance. OIOXO Pro is unlimited \u2192 ${Da}`}:{ok:!1,message:"OIOXO could not verify your plan (oioxo.com unreachable). The coding agent is paused until the connection returns."}}var vre,hn,Tm,S_,Da,Pm,zo=mr(()=>{"use strict";vre=_re(bre),hn=process.env.OIOXO_CONTROL_PLANE?.replace(/\/$/,"")||"https://oioxo.com",Tm=process.env.OIOXO_HOME||Im.join(NB.homedir(),".oioxo"),S_=Im.join(Tm,"credentials.json");Da="https://oioxo.com/?upgrade=pro",Pm="Run `oioxo login` in a terminal to connect your OIOXO account."});import VB from"node:os";function wl(){return nh}async function KB(){let t=ZB();try{let e=await fetch(`${hn}/api/models?platform=${t}`,{headers:{"x-oioxo-client":t}});if(!e.ok)return nh;let r=await e.json();r.selection&&(nh=r.selection)}catch{}return nh}function ZB(){let t=process.platform;return`cli-${t==="darwin"?"mac":t==="win32"?"windows":"linux"}`}async function ine(){try{let{getLlama:t}=await import("node-llama-cpp");return!!(await t()).gpu}catch{return!1}}async function GB(t=()=>{}){let e=ZB(),r,n;try{let m=await fetch(`${hn}/api/models?platform=${e}`,{headers:{"x-oioxo-client":e}});if(!m.ok)return null;let y=await m.json();r=y.models??[],n=y.selection??{},nh=n}catch{return null}let s=r.filter(m=>m.kind==="generic"||m.kind==="desktop").sort((m,y)=>m.approxMB-y.approxMB);if(!s.length)return null;let i=VB.totalmem()/1024**3,o=await ine(),a=n.budgetFracOfTotalRam??.45,c=n.nativeDesktopCapMB??12e3,u=Math.min(i*1024*a,c);if(n.defaultAssetId){let m=s.find(y=>y.assetId===n.defaultAssetId);if(m&&m.approxMB<=u)return{...HB(m),reason:`admin-pinned ${m.name} fits (${FB(i)} RAM, gpu=${o})`}}let l=[...s].reverse().find(m=>m.approxMB<=u),d=s.find(m=>m.assetId===n.floorAssetId),f=l??d??s[0],p=l?`largest fitting tier (${FB(i)} RAM \xD7 ${a} \u2192 ${Math.round(u)}MB, gpu=${o})`:`device below floor \u2014 using ${f.name}`;return{...HB(f),reason:p}}function HB(t){return{assetId:t.assetId,name:t.name,manifestUrl:t.manifestUrl,approxMB:t.approxMB}}function FB(t){return`${t.toFixed(1)}GB`}function sk(){let t=VB.totalmem()/1073741824,e=[{gb:2,uri:"hf:Qwen/Qwen2.5-Coder-0.5B-Instruct-GGUF/qwen2.5-coder-0.5b-instruct-q4_k_m.gguf",label:"OIOXO Basic"},{gb:4,uri:"hf:Qwen/Qwen2.5-Coder-1.5B-Instruct-GGUF/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf",label:"OIOXO Light"},{gb:10,uri:"hf:Qwen/Qwen2.5-Coder-7B-Instruct-GGUF/qwen2.5-coder-7b-instruct-q4_k_m.gguf",label:"OIOXO Prime"}],r=t*(nh?.budgetFracOfTotalRam??.45),n=e[0];for(let s of e)(s.gb*.45<=r||s.gb<=t*.9)&&(n=s);return t>=16?n=e[2]:t>=6?n=e[1]:n=e[0],{uri:process.env.OIOXO_LOCAL_MODEL||n.uri,label:n.label}}var nh,T_=mr(()=>{"use strict";zo();nh=null});function QB(){return sh}async function e$(){if(JB&&sh)return sh;JB=!0;try{let t=await fetch(`${hn}/api/app-config`);if(!t.ok)return sh;let e=await t.json();e.coder&&(sh=e.coder)}catch{}return sh}var sh,JB,t$=mr(()=>{"use strict";zo();sh=null,JB=!1});function yne(t){let e=t.length%4?"=".repeat(4-t.length%4):"",r=atob(t.replace(/-/g,"+").replace(/_/g,"/")+e),n=new Uint8Array(r.length);for(let s=0;s<r.length;s++)n[s]=r.charCodeAt(s);return n}function r$(t){let e=t.indexOf(".");if(e<1)return null;try{return JSON.parse(gne.decode(yne(t.slice(0,e))))}catch{return null}}var ECe,gne,ok=mr(()=>{"use strict";ECe=new TextEncoder,gne=new TextDecoder});function n$(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e.length;n++)r[n]=e.charCodeAt(n);return r}async function xne(t,e){return crypto.subtle.importKey("raw",ak(t),{name:"AES-GCM"},!1,e)}async function s$(t,e){let r=await crypto.subtle.decrypt({name:"AES-GCM",iv:ak(n$(t.iv))},await xne(e,["decrypt"]),ak(n$(t.ct)));return new Uint8Array(r)}var kCe,ak,i$=mr(()=>{"use strict";kCe=new TextEncoder,ak=t=>t});function bne(t){let e="";for(let r of t)e+=String.fromCharCode(r);return btoa(e)}function _ne(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e.length;n++)r[n]=e.charCodeAt(n);return r}async function vne(){let t=await crypto.subtle.generateKey({name:"ECDH",namedCurve:"P-256"},!1,["deriveBits"]),e=new Uint8Array(await crypto.subtle.exportKey("raw",t.publicKey));return{publicKeyB64:bne(e),privateKey:t.privateKey}}async function wne(t){return crypto.subtle.importKey("raw",a$(_ne(t)),{name:"ECDH",namedCurve:"P-256"},!1,[])}async function Sne(t,e,r){let n=new Uint8Array(await crypto.subtle.deriveBits({name:"ECDH",public:await wne(e)},t,256)),s=await crypto.subtle.importKey("raw",a$(n),"HKDF",!1,["deriveBits"]),i=await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:o$.encode("oioxo:unlock"),info:o$.encode(r)},s,256);return new Uint8Array(i)}async function Ane(t,e,r,n){let s=`${r}|${n}|${e.assetId}|${t.publicKeyB64}|${e.serverPubB64}`,i=await Sne(t.privateKey,e.serverPubB64,s);return s$(e.wrapped,i)}async function c$(t,e){let r=e.fetchImpl??globalThis.fetch,n=await vne(),s=new AbortController,i=setTimeout(()=>s.abort(),e.timeoutMs??15e3),o;try{o=await r(t,{method:"POST",headers:{"content-type":"application/json",...e.extraHeaders??{}},cache:"no-store",body:JSON.stringify({entitlement:e.entitlement,device:e.device,assetId:e.assetId,clientPubB64:n.publicKeyB64}),signal:s.signal})}catch(c){throw c.name==="AbortError"?new Error("unlock timed out"):c}finally{clearTimeout(i)}if(o.status===403){let c=await o.json().catch(()=>({}));throw new Error("unlock denied: "+(c.reason??"forbidden"))}if(!o.ok)throw new Error("unlock unavailable ("+o.status+")");let a=await o.json();return Ane(n,a,e.sub,e.device)}var o$,a$,u$=mr(()=>{"use strict";i$();ok();o$=new TextEncoder,a$=t=>t});import{homedir as Ene}from"node:os";import l$ from"node:path";import{promises as Bm,createReadStream as Cne,createWriteStream as kne}from"node:fs";import{createHash as d$,createDecipheriv as Tne}from"node:crypto";function Ine(t,e){return/^https?:\/\//i.test(e)?e:t.slice(0,t.lastIndexOf("/")+1)+e.replace(/^\.?\//,"")}async function f$(t,e){let r=wl(),n=e??r?.fetchRetryTries??4,s=r?.fetchRetryBackoffMs??600,i;for(let o=0;o<n;o++){try{let a=await fetch(t);if(a.ok)return a;if(i=new Error(`HTTP ${a.status}`),a.status>=400&&a.status<500&&a.status!==429)break}catch(a){i=a}o<n-1&&await new Promise(a=>setTimeout(a,s*(o+1)))}throw new Error(`fetch failed after ${n} tries: ${i instanceof Error?i.message:String(i)}`)}async function Pne(t){let e=await Om(),r=await WC(),n=await fetch(`${hn}/api/entitlement`,{method:"POST",headers:r,body:JSON.stringify({device:e})});if(!n.ok)throw new Error(`entitlement failed (${n.status}) \u2014 sign in with \`oioxo login\`.`);let{entitlement:s}=await n.json(),i=s?r$(s):null;if(!s||!i)throw new Error("could not establish a session");if(!i.sub||i.sub==="anon")throw new Error("this model is Pro-only \u2014 your account did not unlock it (free entitlement).");return c$(`${hn}/api/code-key`,{entitlement:s,sub:i.sub,device:e,assetId:t,extraHeaders:r,timeoutMs:wl()?.unlockTimeoutMs})}async function h$(t,e,r=()=>{}){let n=l$.join(Ene(),".oioxo","models");await Bm.mkdir(n,{recursive:!0});let s=await(await f$(e)).json();if(!s?.chunks?.length||!s.sha256)throw new Error("OIOXO manifest is malformed");let i=l$.join(n,`${t}-${s.release}.gguf`);try{if((await Bm.stat(i)).size===s.totalBytes){let p=d$("sha256"),m=Cne(i);for await(let y of m)p.update(y);if(p.digest("hex")===s.sha256)return r(`\xB7 OIOXO model cached: ${s.fileName}`),i}}catch{}r(`\xB7 unlocking ${t} (device-bound handshake)\u2026`);let o=Buffer.from(await Pne(t)),a=i+".part",c=kne(a),u=d$("sha256"),l=0,d=[...s.chunks].sort((f,p)=>f.index-p.index);try{for(let f of d){let p=Buffer.from(await(await f$(Ine(e,f.url))).arrayBuffer()),m=Buffer.from(f.iv,"base64"),y=p.subarray(p.length-16),_=p.subarray(0,p.length-16),S=Tne("aes-256-gcm",o,m);S.setAuthTag(y);let C=Buffer.concat([S.update(_),S.final()]);u.update(C),c.write(C)||await new Promise(E=>c.once("drain",()=>E())),l+=C.byteLength,r(`\xB7 decrypting OIOXO model\u2026 ${Math.round(l/s.totalBytes*100)}%`)}}finally{await new Promise((f,p)=>c.end(m=>m?p(m):f()))}if(l!==s.totalBytes)throw await Bm.rm(a,{force:!0}),new Error("OIOXO assembled size mismatch");if(u.digest("hex")!==s.sha256)throw await Bm.rm(a,{force:!0}),new Error("OIOXO integrity check failed");return await Bm.rename(a,i),r(`\xB7 OIOXO model ready: ${s.fileName} (decrypted, private \u2014 never leaves this machine)`),i}var p$=mr(()=>{"use strict";zo();ok();u$();T_()});var g$={};La(g$,{DeviceCoderLocal:()=>ck});import{homedir as One}from"node:os";import m$ from"node:path";import{mkdir as Rne}from"node:fs/promises";function Bne(){return QB()?.cliSystemPrompt||Nne}function $ne(t){let e=[`TASK:
4
4
  ${t.task}`,`
5
5
  CONTEXT (OIOXO capsule):
6
6
  ${t.grounding}`];return t.error&&e.push(`
@@ -43,7 +43,7 @@ Return the changed files now, each as a FILE: block.`),e.join(`
43
43
  `);E.trim()&&r.push({path:C,content:E})}if(r.length)return r}let m=o.filter(y=>!d(y.body)&&y.body.trim());if(m.length===1&&e.length===1){let y=Gc(e[0]);y&&r.push({path:y,content:m[0].body})}return r}function P_(t={}){if(t.local||process.env.OIOXO_LOCAL==="1")return{coder:new lk(t.onNote)};let e=t.config??{},r=process.env.OIOXO_PROVIDER||e.provider,n=process.env.OIOXO_MODEL||e.model,s=process.env.OIOXO_API_KEY||e.apiKey,i=process.env.OIOXO_BASE_URL||e.baseUrl;return r&&n?{coder:new ih({provider:r,model:n,key:s,baseUrl:i})}:process.env.OPENAI_API_KEY?{coder:new ih({provider:"openai",model:process.env.OIOXO_MODEL||"gpt-4.1",key:process.env.OPENAI_API_KEY})}:process.env.ANTHROPIC_API_KEY?{coder:new ih({provider:"anthropic",model:process.env.OIOXO_MODEL||"claude-sonnet-4-6",key:process.env.ANTHROPIC_API_KEY})}:process.env.GROQ_API_KEY?{coder:new ih({provider:"groq",model:process.env.OIOXO_MODEL||"llama-3.3-70b-versatile",key:process.env.GROQ_API_KEY})}:{error:`No coder configured. Either:
44
44
  \u2022 set a key: OPENAI_API_KEY / ANTHROPIC_API_KEY / GROQ_API_KEY (optionally OIOXO_MODEL)
45
45
  \u2022 or any OpenAI-compatible base: OIOXO_PROVIDER=custom OIOXO_BASE_URL=\u2026 OIOXO_MODEL=\u2026 OIOXO_API_KEY=\u2026
46
- \u2022 or local Ollama: OIOXO_PROVIDER=ollama OIOXO_MODEL=qwen2.5-coder (no key)
46
+ \u2022 or your local Ollama: OIOXO_PROVIDER=ollama OIOXO_MODEL=<your-model> (no key)
47
47
  \u2022 or fully on-device: oioxo code --local (private; one-time \`npm i -g node-llama-cpp\`, then no key)`}}var x$,b$,ih,lk,I_=mr(()=>{"use strict";x$=`You are OIOXO, a precise coding agent. You are given a TASK and a CONTEXT capsule
48
48
  (the minimal relevant slice of the user's repository \u2014 full excerpts for the key files,
49
49
  signatures only for their neighbors). Make the SMALLEST change that satisfies the task.
@@ -287,7 +287,7 @@ Usage:
287
287
  `);let u=(await t({accountKey:s,verify:a,ms:3e3})).filter(l=>l.deviceId!==r.deviceId);if(!u.length){console.log("No other OIOXO devices found on this network yet."),console.log("Make sure the other device is on the same Wi-Fi with OIOXO open, then try again,"),console.log("or pair manually with `oioxo invite` / `oioxo join`.");return}console.log(`Found ${u.length} device${u.length===1?"":"s"}:
288
288
  `);for(let l of u){let d=l.trusted?"\u2713":"\u2022",f=l.host?` ${l.host}:${l.port}`:"";console.log(` ${d} ${l.label} (${l.os})${f}${l.trusted?"":" \u2014 confirm at pair time"}`)}console.log("\nTo lend your compute to one of them, run `oioxo join` and pair with its code.")}function QW(){let t=nE.size;return console.log(`
289
289
  Helping ${t} device${t===1?"":"s"} \u2014 your OIOXO coder is lending power. Ctrl+C to stop helping.`),process.on("SIGINT",()=>{for(let e of nE)try{e.close()}catch{}console.log(`
290
- Stopped helping. Goodbye.`),process.exit(0)}),new Promise(()=>{})}zo();import*as W5 from"node:os";var rX=process.env.NO_COLOR||process.env.TERM==="dumb"?!1:process.env.FORCE_COLOR&&process.env.FORCE_COLOR!=="0"?!0:!!process.stdout.isTTY,yf=(t,e)=>r=>rX?`\x1B[${t}m${r}\x1B[${e}m`:r,Gn={enabled:rX,bold:yf(1,22),dim:yf(2,22),green:yf(32,39),red:yf(31,39),yellow:yf(33,39),cyan:yf(36,39),gold:yf(33,39)};var G5=[{id:"openai",note:"set OPENAI_API_KEY or config apiKey"},{id:"anthropic",note:"set ANTHROPIC_API_KEY or config apiKey"},{id:"groq",note:"set GROQ_API_KEY or config apiKey"},{id:"mistral",note:"config apiKey"},{id:"together",note:"config apiKey"},{id:"ollama",note:"local, no key \u2014 config model qwen2.5-coder"},{id:"custom",note:"any OpenAI-compatible base \u2014 config baseUrl + apiKey"}];async function nX(t){let[e,...r]=t;if(!e||e==="list"){console.log(`
290
+ Stopped helping. Goodbye.`),process.exit(0)}),new Promise(()=>{})}zo();import*as W5 from"node:os";var rX=process.env.NO_COLOR||process.env.TERM==="dumb"?!1:process.env.FORCE_COLOR&&process.env.FORCE_COLOR!=="0"?!0:!!process.stdout.isTTY,yf=(t,e)=>r=>rX?`\x1B[${t}m${r}\x1B[${e}m`:r,Gn={enabled:rX,bold:yf(1,22),dim:yf(2,22),green:yf(32,39),red:yf(31,39),yellow:yf(33,39),cyan:yf(36,39),gold:yf(33,39)};var G5=[{id:"openai",note:"set OPENAI_API_KEY or config apiKey"},{id:"anthropic",note:"set ANTHROPIC_API_KEY or config apiKey"},{id:"groq",note:"set GROQ_API_KEY or config apiKey"},{id:"mistral",note:"config apiKey"},{id:"together",note:"config apiKey"},{id:"ollama",note:"local, no key \u2014 config your model"},{id:"custom",note:"any OpenAI-compatible base \u2014 config baseUrl + apiKey"}];async function nX(t){let[e,...r]=t;if(!e||e==="list"){console.log(`
291
291
  OIOXO coding agent \u2014 how to run it:
292
292
  `),console.log(" Providers (bring your own key):");for(let o of G5)console.log(` ${o.id.padEnd(10)} ${o.note}`);console.log(`
293
293
  Local & private:`),console.log(" ollama keyless, on your machine"),console.log(" --local built-in on-device coder (private; needs node-llama-cpp)");let n=await Lo(),s=process.env.OIOXO_PROVIDER||n.provider,i=process.env.OIOXO_MODEL||n.model;if(s||i){let o=process.env.OIOXO_PROVIDER?"env":"config";console.log(`
@@ -360,7 +360,10 @@ ${f.map(m=>` ${m}`).join(`
360
360
 
361
361
  IMPORTED BY (changing ${l} may break these):
362
362
  ${p.map(m=>` ${m}`).join(`
363
- `)||" (none \u2014 no in-project callers)"}`)}),e.tool("remember","Save one durable fact about THIS project to .oioxo/memory.md (on-device, shared with the OIOXO IDEs). Use for decisions, conventions, gotchas worth keeping.",{fact:Bf.string().describe("The fact, one concise sentence.")},async({fact:c})=>(await ure(t,c),ja("Saved to .oioxo/memory.md."))),e.tool("recall","This project's rules and learned memory from .oioxo/ (same files the OIOXO IDEs maintain). Call when starting work in an unfamiliar repo.",{},async()=>{let c=TB(await kB(t));return ja(c||"No .oioxo/rules.md or memory.md in this project yet.")});let a=new VC;await e.connect(a)}zo();var PB=(()=>{try{return"0.5.6"}catch{}try{return fre(import.meta.url)("../../package.json").version}catch{return"0.0.0"}})(),DEe=`OIOXO ${PB} \u2014 context engine + terminal coding agent (https://oioxo.com)
363
+ `)||" (none \u2014 no in-project callers)"}`)}),e.tool("remember","Save one durable fact about THIS project to .oioxo/memory.md (on-device, shared with the OIOXO IDEs). Use for decisions, conventions, gotchas worth keeping.",{fact:Bf.string().describe("The fact, one concise sentence.")},async({fact:c})=>(await ure(t,c),ja("Saved to .oioxo/memory.md."))),e.tool("recall","This project's rules and learned memory from .oioxo/ (same files the OIOXO IDEs maintain). Call when starting work in an unfamiliar repo.",{},async()=>{let c=TB(await kB(t));return ja(c||"No .oioxo/rules.md or memory.md in this project yet.")});let a=new VC;await e.connect(a)}zo();var PB=(()=>{try{return"0.5.7"}catch{}try{return fre(import.meta.url)("../../package.json").version}catch{return"0.0.0"}})(),DEe=`OIOXO ${PB} \u2014 context engine + terminal coding agent (https://oioxo.com)
364
+
365
+ Private, on your device. Cut your AI bill by up to ~90% in Copilot, Cursor & Claude,
366
+ and code from your terminal \u2014 nothing leaves your machine.
364
367
 
365
368
  Usage: oioxo <command> [options]
366
369
 
@@ -368,7 +371,7 @@ Code:
368
371
  code "<task>" Build/fix in this repo: capsule-grounded, verified on a shadow copy,
369
372
  then asks before writing. Flags: --verify "<cmd>" \xB7 --yes \xB7 --max-iters N \xB7 --local
370
373
  --local runs the built-in on-device coder, no key (one-time: npm i -g node-llama-cpp).
371
- (Or use a local Ollama server: OIOXO_PROVIDER=ollama OIOXO_MODEL=qwen2.5-coder)
374
+ (Or use your local Ollama server: OIOXO_PROVIDER=ollama OIOXO_MODEL=<your-model>)
372
375
 
373
376
  Account:
374
377
  login Connect your OIOXO account (opens the browser)
package/package.json CHANGED
@@ -1,62 +1,62 @@
1
- {
2
- "name": "oioxo-mcp",
3
- "version": "0.5.6",
4
- "description": "OIOXO — cut your AI bill by ~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
- "license": "SEE LICENSE IN LICENSE.md",
6
- "type": "module",
7
- "bin": {
8
- "oioxo": "bundle/cli.js",
9
- "oioxo-mcp": "bundle/cli.js"
10
- },
11
- "files": [
12
- "bundle",
13
- "README.md",
14
- "LICENSE.md"
15
- ],
16
- "engines": {
17
- "node": ">=18.17"
18
- },
19
- "repository": {
20
- "type": "git",
21
- "url": "git+https://github.com/aradsoftca/oioxo-mcp.git"
22
- },
23
- "scripts": {
24
- "prepublishOnly": "npm run test && npm run bundle",
25
- "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
26
- "build": "npm run clean && tsc -p tsconfig.json",
27
- "bundle": "node scripts/bundle.mjs",
28
- "test": "npm run build && node --test dist/test/core.test.js dist/test/e2e.test.js dist/test/coder.test.js dist/test/discovery.test.js",
29
- "serve": "node dist/cli/index.js serve"
30
- },
31
- "keywords": [
32
- "mcp",
33
- "model-context-protocol",
34
- "context-engine",
35
- "claude-code",
36
- "copilot",
37
- "cursor",
38
- "oioxo",
39
- "token-saver",
40
- "code-agent",
41
- "on-device",
42
- "local-llm",
43
- "compute-mesh",
44
- "private-ai"
45
- ],
46
- "homepage": "https://oioxo.com",
47
- "dependencies": {
48
- "@modelcontextprotocol/sdk": "^1.12.0",
49
- "jsqr": "^1.4.0",
50
- "werift": "^0.23.0",
51
- "zod": "^3.23.8"
52
- },
53
- "devDependencies": {
54
- "@types/node": "^20.14.0",
55
- "esbuild": "^0.28.0",
56
- "typescript": "^5.5.0"
57
- },
58
- "optionalDependencies": {
59
- "node-llama-cpp": "^3.18.1",
60
- "bonjour-service": "^1.2.1"
61
- }
62
- }
1
+ {
2
+ "name": "oioxo-mcp",
3
+ "version": "0.5.7",
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
+ "license": "SEE LICENSE IN LICENSE.md",
6
+ "type": "module",
7
+ "bin": {
8
+ "oioxo": "bundle/cli.js",
9
+ "oioxo-mcp": "bundle/cli.js"
10
+ },
11
+ "files": [
12
+ "bundle",
13
+ "README.md",
14
+ "LICENSE.md"
15
+ ],
16
+ "engines": {
17
+ "node": ">=18.17"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/aradsoftca/oioxo-mcp.git"
22
+ },
23
+ "scripts": {
24
+ "prepublishOnly": "npm run test && npm run bundle",
25
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
26
+ "build": "npm run clean && tsc -p tsconfig.json",
27
+ "bundle": "node scripts/bundle.mjs",
28
+ "test": "npm run build && node --test dist/test/core.test.js dist/test/e2e.test.js dist/test/coder.test.js dist/test/discovery.test.js",
29
+ "serve": "node dist/cli/index.js serve"
30
+ },
31
+ "keywords": [
32
+ "mcp",
33
+ "model-context-protocol",
34
+ "context-engine",
35
+ "claude-code",
36
+ "copilot",
37
+ "cursor",
38
+ "oioxo",
39
+ "token-saver",
40
+ "code-agent",
41
+ "on-device",
42
+ "local-llm",
43
+ "compute-mesh",
44
+ "private-ai"
45
+ ],
46
+ "homepage": "https://oioxo.com",
47
+ "dependencies": {
48
+ "@modelcontextprotocol/sdk": "^1.12.0",
49
+ "jsqr": "^1.4.0",
50
+ "werift": "^0.23.0",
51
+ "zod": "^3.23.8"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^20.14.0",
55
+ "esbuild": "^0.28.0",
56
+ "typescript": "^5.5.0"
57
+ },
58
+ "optionalDependencies": {
59
+ "node-llama-cpp": "^3.18.1",
60
+ "bonjour-service": "^1.2.1"
61
+ }
62
+ }