ohwow 0.4.3 → 0.4.4

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.
@@ -1,5 +1,5 @@
1
1
  import { createRequire } from 'module'; const require = createRequire(import.meta.url);
2
- import{McpServer as Q}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as X}from"@modelcontextprotocol/sdk/server/stdio.js";import{readFileSync as f,existsSync as C}from"fs";import{join as x}from"path";import{homedir as H}from"os";var g=class n{constructor(o,t,e){this.baseUrl=`http://127.0.0.1:${o}`,this.token=t,this.tokenPath=e}static async create(){let o=x(H(),".ohwow"),t=x(o,"config.json"),e=x(o,"data","daemon.token"),r=7700;if(C(t))try{let c=f(t,"utf-8"),a=JSON.parse(c);a.port&&(r=a.port)}catch{}if(!C(e))throw new Error("OHWOW daemon is not running. Start it with: ohwow");let s=f(e,"utf-8").trim();if(!s)throw new Error("Couldn't authenticate with OHWOW daemon. Try: ohwow restart");let i=new n(r,s,e);try{await i.get("/health")}catch{throw new Error("OHWOW daemon is not running. Start it with: ohwow")}return i}refreshToken(){try{let o=f(this.tokenPath,"utf-8").trim();if(o&&o!==this.token)return this.token=o,!0}catch{}return!1}authHeaders(){return{Authorization:`Bearer ${this.token}`}}async fetchWithRetry(o,t){let e=await fetch(o,t);if(e.status===401&&this.refreshToken()){let r={...t.headers,...this.authHeaders()};e=await fetch(o,{...t,headers:r})}return e}async get(o){let t=await this.fetchWithRetry(`${this.baseUrl}${o}`,{headers:this.authHeaders()});if(!t.ok)throw new Error(`ohwow daemon error on GET ${o}: ${t.status}. Check daemon with: ohwow logs`);return t.json()}async post(o,t){let e=await this.fetchWithRetry(`${this.baseUrl}${o}`,{method:"POST",headers:{...this.authHeaders(),"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok)throw new Error(`ohwow daemon error on POST ${o}: ${e.status}. Check daemon with: ohwow logs`);return e.json()}async postSSE(o,t,e=12e4){let r=new AbortController,s=setTimeout(()=>r.abort(),e),i=[],c=async()=>fetch(`${this.baseUrl}${o}`,{method:"POST",headers:{...this.authHeaders(),"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(t),signal:r.signal});try{let a=await c();if(a.status===401&&this.refreshToken()&&(a=await c()),!a.ok)throw new Error(`Daemon API error: ${a.status} ${a.statusText}`);if(!a.body)throw new Error("No response body from daemon");let p=a.body.getReader(),b=new TextDecoder,m="";for(;;){let{done:w,value:L}=await p.read();if(w)break;m+=b.decode(L,{stream:!0});let R=m.split(`
2
+ import{McpServer as Z}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as tt}from"@modelcontextprotocol/sdk/server/stdio.js";import{readFileSync as f,existsSync as C}from"fs";import{join as x}from"path";import{homedir as H}from"os";var g=class n{constructor(o,t,e){this.baseUrl=`http://127.0.0.1:${o}`,this.token=t,this.tokenPath=e}static async create(){let o=x(H(),".ohwow"),t=x(o,"config.json"),e=x(o,"data","daemon.token"),r=7700;if(C(t))try{let c=f(t,"utf-8"),a=JSON.parse(c);a.port&&(r=a.port)}catch{}if(!C(e))throw new Error("OHWOW daemon is not running. Start it with: ohwow");let s=f(e,"utf-8").trim();if(!s)throw new Error("Couldn't authenticate with OHWOW daemon. Try: ohwow restart");let i=new n(r,s,e);try{await i.get("/health")}catch{throw new Error("OHWOW daemon is not running. Start it with: ohwow")}return i}refreshToken(){try{let o=f(this.tokenPath,"utf-8").trim();if(o&&o!==this.token)return this.token=o,!0}catch{}return!1}authHeaders(){return{Authorization:`Bearer ${this.token}`}}async fetchWithRetry(o,t){let e=await fetch(o,t);if(e.status===401&&this.refreshToken()){let r={...t.headers,...this.authHeaders()};e=await fetch(o,{...t,headers:r})}return e}async get(o){let t=await this.fetchWithRetry(`${this.baseUrl}${o}`,{headers:this.authHeaders()});if(!t.ok)throw new Error(`ohwow daemon error on GET ${o}: ${t.status}. Check daemon with: ohwow logs`);return t.json()}async post(o,t){let e=await this.fetchWithRetry(`${this.baseUrl}${o}`,{method:"POST",headers:{...this.authHeaders(),"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok)throw new Error(`ohwow daemon error on POST ${o}: ${e.status}. Check daemon with: ohwow logs`);return e.json()}async postSSE(o,t,e=12e4){let r=new AbortController,s=setTimeout(()=>r.abort(),e),i=[],c=async()=>fetch(`${this.baseUrl}${o}`,{method:"POST",headers:{...this.authHeaders(),"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(t),signal:r.signal});try{let a=await c();if(a.status===401&&this.refreshToken()&&(a=await c()),!a.ok)throw new Error(`Daemon API error: ${a.status} ${a.statusText}`);if(!a.body)throw new Error("No response body from daemon");let p=a.body.getReader(),b=new TextDecoder,m="";for(;;){let{done:w,value:L}=await p.read();if(w)break;m+=b.decode(L,{stream:!0});let R=m.split(`
3
3
  `);m=R.pop()||"";for(let T of R){if(!T.startsWith("data: "))continue;let O=T.slice(6).trim();if(O!=="[DONE]")try{let u=JSON.parse(O);if(u.type==="text"&&u.content)i.push(u.content);else if(u.type==="tool_start")i.push(`
4
4
  [Using tool: ${u.name}]
5
5
  `);else if(u.type==="error")i.push(`
@@ -59,7 +59,7 @@ A2A protocol, PDF forms, media generation, automation creation, and
59
59
  anything not listed above.
60
60
  `;import{createServer as F}from"http";import{writeFileSync as G,unlinkSync as z,existsSync as K}from"fs";import{join as B}from"path";import{homedir as V}from"os";var S=B(V(),".ohwow","data","mcp-sampling.port");function J(n){let o=null,t=F(async(r,s)=>{if(r.method!=="POST"||r.url!=="/sampling"){s.writeHead(404),s.end("Not found");return}let i="";for await(let a of r)i+=a;let c;try{c=JSON.parse(i)}catch{s.writeHead(400),s.end(JSON.stringify({error:"Invalid JSON"}));return}if(!c.messages?.length){s.writeHead(400),s.end(JSON.stringify({error:"messages array is required"}));return}try{let a=c.messages.map(w=>({role:w.role,content:{type:"text",text:w.content}})),p=await n.server.createMessage({messages:a,systemPrompt:c.systemPrompt,maxTokens:c.maxTokens||4096,temperature:c.temperature}),m={content:Array.isArray(p.content)?p.content.filter(w=>w.type==="text").map(w=>w.text).join(""):typeof p.content=="object"&&"text"in p.content?p.content.text:String(p.content),model:p.model,stopReason:p.stopReason??void 0};s.writeHead(200,{"Content-Type":"application/json"}),s.end(JSON.stringify(m))}catch(a){let p=a instanceof Error?a.message:"Sampling failed";s.writeHead(500),s.end(JSON.stringify({error:p}))}});return o=t,t.listen(0,"127.0.0.1",()=>{let r=t.address();if(r&&typeof r=="object"){let s=r.port;try{G(S,String(s)),process.stderr.write(`[ohwow-mcp] Sampling bridge listening on port ${s}
61
61
  `)}catch{process.stderr.write(`[ohwow-mcp] Could not write sampling port file
62
- `)}}}),{cleanup:()=>{o&&(o.close(),o=null);try{K(S)&&z(S)}catch{}}}}var E="0.2.0";async function Jt(){let n;try{n=await g.create()}catch(s){process.stderr.write(`[ohwow-mcp] ${s instanceof Error?s.message:"Unknown error"}
63
- `),process.exit(1)}let o=new Q({name:"ohwow",version:E});I(o,n),P(o,n);let t=new X,e=null,r=async()=>{e?.();try{await o.close()}catch{}process.exit(0)};process.on("SIGTERM",r),process.on("SIGINT",r);try{await o.connect(t),process.stderr.write(`[ohwow-mcp] Connected (v${E})
62
+ `)}}}),{cleanup:()=>{o&&(o.close(),o=null);try{K(S)&&z(S)}catch{}}}}import{createRequire as Q}from"module";var X=Q(import.meta.url),Y=X("../package.json"),E=Y.version;async function Ft(){let n;try{n=await g.create()}catch(s){process.stderr.write(`[ohwow-mcp] ${s instanceof Error?s.message:"Unknown error"}
63
+ `),process.exit(1)}let o=new Z({name:"ohwow",version:E});I(o,n),P(o,n);let t=new tt,e=null,r=async()=>{e?.();try{await o.close()}catch{}process.exit(0)};process.on("SIGTERM",r),process.on("SIGINT",r);try{await o.connect(t),process.stderr.write(`[ohwow-mcp] Connected (v${E})
64
64
  `),e=J(o).cleanup}catch(s){process.stderr.write(`[ohwow-mcp] Failed to connect: ${s instanceof Error?s.message:"Unknown error"}
65
- `),process.exit(1)}}export{Jt as startMcpServer};
65
+ `),process.exit(1)}}export{Ft as startMcpServer};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohwow",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Local-first AI business operating system. Put your business ops on autopilot with AI agents that learn, remember, and coordinate.",
5
5
  "license": "MIT",
6
6
  "author": "Jesus David Oñoro Delgado <ogsus@ohwow.fun>",
@@ -91,7 +91,6 @@
91
91
  "ink-spinner": "^5.0.0",
92
92
  "ink-text-input": "^6.0.0",
93
93
  "jose": "^6.1.3",
94
- "node-pty": "^1.1.0",
95
94
  "pdf-lib": "^1.17.1",
96
95
  "pino": "^10.3.1",
97
96
  "pino-pretty": "^13.1.3",
@@ -102,6 +101,7 @@
102
101
  "zod": "^4.3.6"
103
102
  },
104
103
  "optionalDependencies": {
104
+ "node-pty": "^1.1.0",
105
105
  "@browserbasehq/stagehand": "^3.2.0",
106
106
  "@nut-tree-fork/nut-js": "^4.2.6",
107
107
  "sharp": "^0.34.5"