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.
- package/README.md +125 -120
- package/bundle/cli.js +8 -5
- 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
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
#
|
|
82
|
-
oioxo
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
#
|
|
87
|
-
oioxo
|
|
88
|
-
|
|
89
|
-
oioxo
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
oioxo
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
oioxo
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
oioxo
|
|
101
|
-
oioxo
|
|
102
|
-
|
|
103
|
-
#
|
|
104
|
-
oioxo
|
|
105
|
-
oioxo
|
|
106
|
-
oioxo
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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> run — reads ~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:"
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
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
|
+
}
|