@ours.network/mcp 1.2.0-nightly.7 → 1.2.0-nightly.8

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/dist/container.js CHANGED
@@ -1,6 +1,6 @@
1
- var C=Object.defineProperty;var b=(e,t)=>()=>(e&&(t=e(e=0)),t);var $=(e,t)=>{for(var i in t)C(e,i,{get:t[i],enumerable:!0})};var O={};$(O,{APPLICATION_IDENTITIES_ENV:()=>v,APPLICATION_IDENTITIES_VERSION:()=>w,ApplicationIdentityStore:()=>g,applicationIdentityConfigPath:()=>E,filterApplicationIdentities:()=>K});import{randomUUID as k}from"node:crypto";import{chmod as D,mkdir as x,readFile as L,rename as J,unlink as j,writeFile as M}from"node:fs/promises";import{homedir as F}from"node:os";import{dirname as G,resolve as f}from"node:path";function E(e=process.env){let t=(e[v]??"").trim();return f(t||f(F(),".ours-mcp","config.json"))}function I(e,t,i,n){if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`Invalid ours-mcp application identity config at ${t}: "${i}s" must be an object.`);let r={};for(let[a,o]of Object.entries(e)){if(!o||typeof o!="object"||Array.isArray(o))throw new Error(`Invalid ours-mcp application identity config at ${t}: ${i} ${JSON.stringify(a)} must be an object.`);let s=o;if(!Array.isArray(s.identities)||s.identities.some(p=>typeof p!="string"||p.length===0))throw new Error(`Invalid ours-mcp application identity config at ${t}: ${i} ${JSON.stringify(a)} has an invalid identity list.`);r[n(a)]={identities:[...new Set(s.identities)].sort()}}return r}function W(e,t){let i;try{i=JSON.parse(e)}catch(o){throw new Error(`Invalid ours-mcp application identity config at ${t}: ${String(o)}`)}if(!i||typeof i!="object"||Array.isArray(i))throw new Error(`Invalid ours-mcp application identity config at ${t}: expected an object.`);let n=i;if(n.version!==w)throw new Error(`Unsupported ours-mcp application identity config version at ${t}: expected ${w}, found ${String(n.version)}.`);let r=I(n.daemons,t,"daemon",f),a=n.instances===void 0?{}:I(n.instances,t,"instance",o=>{if(!S.test(o))throw new Error(`Invalid ours-mcp application identity config at ${t}: instance ${JSON.stringify(o)} must be a lowercase UUID.`);return o});return{version:1,daemons:r,instances:a}}async function y(e){try{return W(await L(e,"utf8"),e)}catch(t){if(t.code==="ENOENT")return V();throw t}}async function h(e,t){let i=G(e);await x(i,{recursive:!0,mode:448});let n=`${e}.${process.pid}.${k()}.tmp`;try{await M(n,`${JSON.stringify(t,null,2)}
2
- `,{mode:384,flag:"wx"}),await J(n,e),await D(e,384)}catch(r){try{await j(n)}catch{}throw r}}async function K(e,t){let i=new Set(await e.list());return t.filter(n=>i.has(n.name))}var w,v,S,V,g,A=b(()=>{"use strict";w=1,v="OURS_MCP_CONFIG",S=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,V=()=>({version:1,daemons:{},instances:{}});g=class{stateDir;instanceId;path;constructor(t,i={}){if(typeof t=="string")this.stateDir=f(t),this.instanceId=null;else{if(!t||!S.test(t.instanceId))throw new Error("Application identity instanceId must be a lowercase UUID.");this.stateDir=null,this.instanceId=t.instanceId}this.path=f(i.path??E(i.env))}rows(t){return this.instanceId===null?t.daemons:t.instances}key(){return this.instanceId??this.stateDir}async list(){let t=await y(this.path);return[...this.rows(t)[this.key()]?.identities??[]]}async has(t){return(await this.list()).includes(t)}async add(t){if(!t)throw new Error("Cannot add an empty identity name to ours-mcp.");let i=await y(this.path),n=this.rows(i),r=this.key(),a=n[r]?.identities??[];a.includes(t)||(n[r]={identities:[...a,t].sort()},await h(this.path,i))}async remove(t){let i=await y(this.path),n=this.rows(i),r=this.key(),a=n[r];if(!a?.identities.includes(t))return;let o=a.identities.filter(s=>s!==t);o.length===0?delete n[r]:n[r]={identities:o},await h(this.path,i)}}});import{readFileSync as Y,createReadStream as q,createWriteStream as z,mkdirSync as N,rmSync as R}from"node:fs";import{basename as B,join as l}from"node:path";import{pipeline as P}from"node:stream/promises";import{randomUUID as H}from"node:crypto";import{fileURLToPath as Q}from"node:url";var[m,c="proxy",...d]=process.argv.slice(2);if(!m||m!==process.env.OURS_DAEMON_ID)throw new Error("MCP target does not match the selected daemon");var u=l(process.env.OURS_STATE_DIR||"/var/lib/ours",".mcp"),T=l(u,"profile.json"),U=JSON.parse(Y(T,"utf8"));if(U.expectedInstanceId!==m)throw new Error("MCP profile does not match the selected daemon");for(let e of["OURS_API_TOKEN","OURS_PORT","OURS_STATE_DIR","OURS_DAEMON_ID","OURS_CLIENT_PID","OURS_AUTOSTART"])delete process.env[e];process.env.OURS_CONFIG=T;process.env.OURS_MCP_CONFIG=l(u,"config.json");process.env.OURS_FILES_ALWAYS_PROMPT="1";var _=new URL("./cli.js",import.meta.url),X=Q(_);if(["file-stage","file-target","file-read","file-remove"].includes(c)){let[e,t]=d;if(!/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(e??""))throw new Error("Invalid file transfer ID");if(d.length!==(c==="file-stage"?2:1))throw new Error("Invalid file transfer arguments");let i=l(u,"transfers"),n=l(i,e);if(c==="file-remove")R(n,{recursive:!0,force:!0});else if(c==="file-read")await P(q(l(n,"file")),process.stdout);else{if(c==="file-stage"&&(!t||B(t)!==t||[".",".."].includes(t)))throw new Error("Invalid transfer filename");N(i,{recursive:!0,mode:448}),N(n,{mode:448});let r=l(n,c==="file-stage"?t:"file");try{c==="file-stage"&&await P(process.stdin,z(r,{flags:"wx",mode:384})),process.stdout.write(JSON.stringify({path:r})+`
3
- `)}catch(a){throw R(n,{recursive:!0,force:!0}),a}}}else if(["proxy","session-end","version"].includes(c))process.argv=[process.execPath,X,c,...d],await import(_.href);else if(["application-identities","hook-state","watch"].includes(c)){let{ApplicationIdentityStore:e}=await Promise.resolve().then(()=>(A(),O)),i=await new e({instanceId:m}).list();if(c==="application-identities")process.stdout.write(JSON.stringify(i)+`
4
- `);else{let{attachOursClient:n}=await import("@ours.network/sdk"),r=await n({...U,sessionMode:"external",leaseToken:H(),env:{}});try{if(c==="hook-state"){let a=await r.listIdentities(),o=await r.unread();process.stdout.write(JSON.stringify({identities:a.map(s=>s.name),bindings:a.filter(s=>"session"in s&&(s.session==="mine"||s.session==="other-live")).map(s=>s.name),unread:{identities:o.identities.filter(s=>typeof s.name=="string"&&i.includes(s.name))}})+`
1
+ var U=Object.defineProperty;var $=(e,t)=>()=>(e&&(t=e(e=0)),t);var k=(e,t)=>{for(var i in t)U(e,i,{get:t[i],enumerable:!0})};var N={};k(N,{APPLICATION_IDENTITIES_ENV:()=>v,APPLICATION_IDENTITIES_VERSION:()=>y,ApplicationIdentityStore:()=>g,applicationIdentityConfigPath:()=>E,filterApplicationIdentities:()=>W});import{randomUUID as T}from"node:crypto";import{chmod as x,mkdir as _,readFile as D,rename as L,unlink as J,writeFile as j}from"node:fs/promises";import{homedir as M}from"node:os";import{dirname as F,resolve as f}from"node:path";function E(e=process.env){let t=(e[v]??"").trim();return f(t||f(M(),".ours-mcp","config.json"))}function I(e,t,i,n){if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`Invalid ours-mcp application identity config at ${t}: "${i}s" must be an object.`);let r={};for(let[a,o]of Object.entries(e)){if(!o||typeof o!="object"||Array.isArray(o))throw new Error(`Invalid ours-mcp application identity config at ${t}: ${i} ${JSON.stringify(a)} must be an object.`);let s=o;if(!Array.isArray(s.identities)||s.identities.some(p=>typeof p!="string"||p.length===0))throw new Error(`Invalid ours-mcp application identity config at ${t}: ${i} ${JSON.stringify(a)} has an invalid identity list.`);r[n(a)]={identities:[...new Set(s.identities)].sort()}}return r}function V(e,t){let i;try{i=JSON.parse(e)}catch(o){throw new Error(`Invalid ours-mcp application identity config at ${t}: ${String(o)}`)}if(!i||typeof i!="object"||Array.isArray(i))throw new Error(`Invalid ours-mcp application identity config at ${t}: expected an object.`);let n=i;if(n.version!==y)throw new Error(`Unsupported ours-mcp application identity config version at ${t}: expected ${y}, found ${String(n.version)}.`);let r=I(n.daemons,t,"daemon",f),a=n.instances===void 0?{}:I(n.instances,t,"instance",o=>{if(!S.test(o))throw new Error(`Invalid ours-mcp application identity config at ${t}: instance ${JSON.stringify(o)} must be a lowercase UUID.`);return o});return{version:1,daemons:r,instances:a}}async function m(e){try{return V(await D(e,"utf8"),e)}catch(t){if(t.code==="ENOENT")return G();throw t}}async function h(e,t){let i=F(e);await _(i,{recursive:!0,mode:448});let n=`${e}.${process.pid}.${T()}.tmp`;try{await j(n,`${JSON.stringify(t,null,2)}
2
+ `,{mode:384,flag:"wx"}),await L(n,e),await x(e,384)}catch(r){try{await J(n)}catch{}throw r}}async function W(e,t){let i=new Set(await e.list());return t.filter(n=>i.has(n.name))}var y,v,S,G,g,O=$(()=>{"use strict";y=1,v="OURS_MCP_CONFIG",S=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,G=()=>({version:1,daemons:{},instances:{}});g=class{stateDir;instanceId;path;constructor(t,i={}){if(typeof t=="string")this.stateDir=f(t),this.instanceId=null;else{if(!t||!S.test(t.instanceId))throw new Error("Application identity instanceId must be a lowercase UUID.");this.stateDir=null,this.instanceId=t.instanceId}this.path=f(i.path??E(i.env))}rows(t){return this.instanceId===null?t.daemons:t.instances}key(){return this.instanceId??this.stateDir}async list(){let t=await m(this.path);return[...this.rows(t)[this.key()]?.identities??[]]}async has(t){return(await this.list()).includes(t)}async add(t){if(!t)throw new Error("Cannot add an empty identity name to ours-mcp.");let i=await m(this.path),n=this.rows(i),r=this.key(),a=n[r]?.identities??[];a.includes(t)||(n[r]={identities:[...a,t].sort()},await h(this.path,i))}async remove(t){let i=await m(this.path),n=this.rows(i),r=this.key(),a=n[r];if(!a?.identities.includes(t))return;let o=a.identities.filter(s=>s!==t);o.length===0?delete n[r]:n[r]={identities:o},await h(this.path,i)}}});import{createReadStream as H,createWriteStream as Y,mkdirSync as A,rmSync as C}from"node:fs";import{basename as q,dirname as z,join as l}from"node:path";import{homedir as B}from"node:os";import{pipeline as P}from"node:stream/promises";import{randomUUID as K}from"node:crypto";import{readGatewayClientProfile as Q}from"@ours.network/sdk/client";import{fileURLToPath as X}from"node:url";var[w,c="proxy",...d]=process.argv.slice(2),u=Q(process.env);if(!w||u.expectedInstanceId!==w)throw new Error("MCP target does not match the selected gateway profile");var R=process.env.OURS_MCP_CONFIG?z(process.env.OURS_MCP_CONFIG):l(process.env.HOME||B(),".ours-mcp");process.env.OURS_CONFIG=u.configPath;process.env.OURS_MCP_CONFIG=l(R,"config.json");process.env.OURS_FILES_ALWAYS_PROMPT="1";var b=new URL("./cli.js",import.meta.url),Z=X(b);if(["file-stage","file-target","file-read","file-remove"].includes(c)){let[e,t]=d;if(!/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(e??""))throw new Error("Invalid file transfer ID");if(d.length!==(c==="file-stage"?2:1))throw new Error("Invalid file transfer arguments");let i=l(R,"transfers"),n=l(i,e);if(c==="file-remove")C(n,{recursive:!0,force:!0});else if(c==="file-read")await P(H(l(n,"file")),process.stdout);else{if(c==="file-stage"&&(!t||q(t)!==t||[".",".."].includes(t)))throw new Error("Invalid transfer filename");A(i,{recursive:!0,mode:448}),A(n,{mode:448});let r=l(n,c==="file-stage"?t:"file");try{c==="file-stage"&&await P(process.stdin,Y(r,{flags:"wx",mode:384})),process.stdout.write(JSON.stringify({path:r})+`
3
+ `)}catch(a){throw C(n,{recursive:!0,force:!0}),a}}}else if(["proxy","session-end","version"].includes(c))process.argv=[process.execPath,Z,c,...d],await import(b.href);else if(["application-identities","hook-state","watch"].includes(c)){let{ApplicationIdentityStore:e}=await Promise.resolve().then(()=>(O(),N)),i=await new e({instanceId:w}).list();if(c==="application-identities")process.stdout.write(JSON.stringify(i)+`
4
+ `);else{let{attachOursClient:n}=await import("@ours.network/sdk"),r=await n({...u,sessionMode:"external",leaseToken:K(),env:{}});try{if(c==="hook-state"){let a=await r.listIdentities(),o=await r.unread();process.stdout.write(JSON.stringify({identities:a.map(s=>s.name),bindings:a.filter(s=>"session"in s&&(s.session==="mine"||s.session==="other-live")).map(s=>s.name),unread:{identities:o.identities.filter(s=>typeof s.name=="string"&&i.includes(s.name))}})+`
5
5
  `)}else{if(d.length>1||d[0]?.startsWith("-"))throw new Error("Usage: watch [identity]");let a=d.length?[d[0]]:i,o=new AbortController;process.stdin.once("end",()=>o.abort()),process.stdin.resume();for(let s of["SIGINT","SIGTERM"])process.once(s,()=>o.abort());await Promise.all(a.map(async s=>{for await(let p of r.watchNotifications(s,{kinds:["inbound"],signal:o.signal}))process.stdout.write(JSON.stringify({identity:s,...p})+`
6
6
  `)}))}}finally{await r.close()}}}else throw new Error("Unsupported container MCP operation");
@@ -1,2 +1,2 @@
1
- import{existsSync as L,lstatSync as O,readFileSync as F}from"node:fs";import{homedir as N}from"node:os";import{resolve as u}from"node:path";import{normalizeDaemonEndpoint as q}from"@ours.network/sdk/client";var v=["endpoint","expectedInstanceId","credentialPath"],G=["port","stateDir","apiToken","apiVisibility"],M=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,V=["OURS_API_TOKEN","OURS_PORT","OURS_STATE_DIR","OURS_DAEMON_ID"];function a(t){return new Error(`Invalid external host profile: ${t}`)}function f(t){if(!t||typeof t!="object"||Array.isArray(t))throw a("expected a complete host profile object.");let n=t;if(v.filter(d=>Object.hasOwn(n,d)).length!==v.length)throw a("expected a complete host profile tuple: endpoint, expectedInstanceId, credentialPath.");let r=G.filter(d=>Object.hasOwn(n,d));if(r.length)throw a(`legacy selection keys cannot be mixed with a host profile (${r.join(", ")}).`);let i=n.endpoint,o=n.expectedInstanceId,s=n.credentialPath;if(typeof i!="string"||i.trim()!==i||i==="")throw a("endpoint must be a non-empty HTTP or HTTPS base URL.");if(typeof o!="string"||!M.test(o))throw a("expectedInstanceId must be a lowercase UUID.");if(typeof s!="string"||s===""||!s.startsWith("/")||u(s)!==s)throw a("credentialPath must be a normalized absolute path.");let c;try{c=new URL(i)}catch{throw a("endpoint must be an HTTP or HTTPS base URL.")}if(c.protocol!=="http:"&&c.protocol!=="https:"||c.username||c.password||/[\s\\?#]/.test(i)||c.search||c.hash)throw a("endpoint must be an HTTP or HTTPS base URL without credentials, query, or fragment.");return{endpoint:q(i),expectedInstanceId:o,credentialPath:s}}function z(t){let n;try{n=F(t,"utf8")}catch{throw new Error(`Cannot read host profile ${JSON.stringify(t)}.`)}let e;try{e=JSON.parse(n)}catch{throw a(`config ${JSON.stringify(t)} is not valid JSON.`)}if(!e||typeof e!="object"||Array.isArray(e))throw a(`config ${JSON.stringify(t)} must be an object.`);return e}function W(t){let n;try{n=O(t)}catch{throw new Error(`Cannot read host profile ${JSON.stringify(t)}.`)}if(!n.isFile())throw a(`config ${JSON.stringify(t)} must be a regular file.`);let e=process.getuid?.();if(e===void 0||n.uid!==e)throw a(`config ${JSON.stringify(t)} must be owned by the current user.`);if(n.mode&63)throw a(`config ${JSON.stringify(t)} must have private permissions.`)}function I(t){let n=z(t);return v.filter(r=>Object.hasOwn(n,r)).length===0?null:(W(t),f(n))}function Y(t,n){return(t[n]??"").trim()!==""}function P(t=process.env){let n=(t.OURS_CONFIG??"").trim(),e=u(t.HOME||N(),".ours-client","profile.json"),r=n;if(!r)try{O(e),r=e}catch(s){if(s.code!=="ENOENT")throw new Error(`Cannot read host profile ${JSON.stringify(e)}.`);if(r=u(N(),".ours","config.json"),!L(r))return null}let i=I(r);if(i===null){if(u(r)===e)throw a("managed client config must contain a complete host profile tuple.");return null}let o=V.filter(s=>Y(t,s));if(o.length)throw a(`${o.join(", ")} conflicts with host-profile mode.`);return{profile:i,configPath:r}}function b(t=process.env){return P(t)?.profile??null}import{createHash as rt,randomUUID as U}from"node:crypto";import{chmod as A,mkdir as it,readFile as ot,rename as st,unlink as at,writeFile as ct}from"node:fs/promises";import{dirname as dt,join as lt,resolve as ft}from"node:path";import{attachOursClient as pt}from"@ours.network/sdk";import{createHash as K}from"node:crypto";import{openSync as X,closeSync as B,lstatSync as S,mkdirSync as Q,chmodSync as Z,constants as m}from"node:fs";import{join as x}from"node:path";import{createRequire as R}from"node:module";var tt=5e3,p=null,C=!1;function et(){if(p)return p;if(C)throw new Error("No SQLite implementation available for native session guard");C=!0;try{return p=R(import.meta.url)("node:sqlite").DatabaseSync,p}catch{try{let t=R(import.meta.url)("better-sqlite3");return p=t.default??t,p}catch{throw new Error("Native session guard requires node:sqlite (Node >=22.13) or better-sqlite3")}}}function nt(t){try{let e=X(t,m.O_RDWR|m.O_CREAT|m.O_EXCL|m.O_NOFOLLOW,384);B(e)}catch(e){if(e.code!=="EEXIST")throw e}let n=S(t);if(!n.isFile()||n.uid!==process.getuid()||n.mode&63||n.nlink!==1)throw new Error("Native session guard file must be an owner-only regular file")}function $(t){let n=process.getuid(),e=x(`/tmp/ours-${n}`,"session-guards");Q(e,{recursive:!0,mode:448});try{Z(e,448)}catch{}let r=K("sha256").update(t).digest("hex"),i=x(e,`${r}.guard`);nt(i);let o=S(i),s=et(),c=new s(i);try{let d=S(i);if(o.dev!==d.dev||o.ino!==d.ino||o.mode!==d.mode||o.uid!==d.uid)throw new Error("Native session guard file changed during acquisition");return c.exec(`PRAGMA busy_timeout=${tt}; BEGIN EXCLUSIVE`),()=>{try{c.close()}catch{}}}catch(d){try{c.close()}catch{}throw d}}var w=1,D=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,l=new Map,g=new Map;function ut(t){if(typeof t!="string"||t.length===0||t.length>4096||t.trim()!==t||t.includes("\0"))throw new Error("Native session metadata is missing or invalid for this host-profile tool call.");return t}function h(t,n,e){if(!t||!t.startsWith("/")||ft(t)!==t)throw new Error("Native session host record root must be a normalized absolute path.");if(!D.test(n))throw new Error("Native session daemon instance must be a lowercase UUID.");let r=rt("sha256").update(ut(e),"utf8").digest("hex");return lt(t,"sessions",n,`${r}.json`)}function mt(t,n){let e;try{e=JSON.parse(t)}catch(o){throw new Error(`Invalid native session record at ${n}: ${String(o)}`)}if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`Invalid native session record at ${n}: expected an object.`);let r=e;if(Object.keys(r).sort().join(",")!=="ownerInstanceId,state,version"||r.version!==w||typeof r.ownerInstanceId!="string"||!D.test(r.ownerInstanceId)||!["active","pending","ended"].includes(String(r.state)))throw new Error(`Invalid native session record at ${n}.`);return r}async function y(t){try{return mt(await ot(t,"utf8"),t)}catch(n){if(n.code==="ENOENT")return null;throw n}}async function E(t,n){let e=dt(t);await it(e,{recursive:!0,mode:448}),await A(e,448);let r=`${t}.${process.pid}.${U()}.tmp`;try{await ct(r,`${JSON.stringify(n,null,2)}
2
- `,{mode:384,flag:"wx"}),await st(r,t),await A(t,384)}catch(i){try{await at(r)}catch{}throw i}}async function k(t,n){let e=g.get(t)??Promise.resolve(),r,i=new Promise(c=>{r=c}),o=e.catch(()=>{}).then(()=>i);g.set(t,o),await e.catch(()=>{});let s;try{return s=$(t),await n()}finally{try{s?.()}finally{r(),g.get(t)===o&&g.delete(t)}}}function H(t,n){return pt({endpoint:t.endpoint,expectedInstanceId:t.expectedInstanceId,credentialPath:t.credentialPath,sessionMode:"external",leaseToken:n,env:{}})}function T(t,n,e){let r=l.get(t);if(r?.ownerInstanceId===e)return r.promise;r&&(l.delete(t),r.promise.then(s=>s.close()).catch(()=>{}));let i=H(n,e),o={ownerInstanceId:e,promise:i};return l.set(t,o),i.catch(()=>{l.get(t)===o&&l.delete(t)}),i}async function gt(t,n,e){let r=l.get(t),i=r?.ownerInstanceId===e?await r.promise:await H(n,e);try{await i.releaseLease()}finally{r?.ownerInstanceId!==e&&await i.close()}}async function j(t,n,e){await gt(t,n,e);let r=await y(t);r?.state==="pending"&&r.ownerInstanceId===e&&await E(t,{version:w,ownerInstanceId:e,state:"ended"});let i=l.get(t);i?.ownerInstanceId===e&&(l.delete(t),i.promise.then(o=>o.close()).catch(()=>{}))}async function _(t,n,e){let r=f(t),i=h(e,r.expectedInstanceId,n);return k(i,async()=>{let o=await y(i);if(o?.state==="pending"&&(await j(i,r,o.ownerInstanceId),o=await y(i)),o?.state==="active")return T(i,r,o.ownerInstanceId);let s=U();return await E(i,{version:w,ownerInstanceId:s,state:"active"}),T(i,r,s)})}async function J(t,n,e){let r=f(t),i=h(e,r.expectedInstanceId,n);await k(i,async()=>{let o=await y(i);o===null||o.state==="ended"||(o.state==="active"&&(o={version:w,ownerInstanceId:o.ownerInstanceId,state:"pending"},await E(i,o)),await j(i,r,o.ownerInstanceId))})}export{J as endNativeSessionAtRoot,b as hostProfileFromEnv,P as hostProfileSelectionFromEnv,_ as nativeClientForAtRoot,h as nativeSessionRecordPath,I as readHostProfile,f as validateHostProfile};
1
+ import{readGatewayClientProfile as I,validateGatewayClientProfile as P}from"@ours.network/sdk/client";var f=P;function E(t){return P(I({OURS_CONFIG:t}))}function w(t=process.env){let{configPath:i,...e}=I(t);return{profile:e,configPath:i}}function S(t=process.env){return w(t).profile}import{createHash as V,randomUUID as b}from"node:crypto";import{chmod as A,mkdir as W,readFile as X,rename as z,unlink as B,writeFile as Q}from"node:fs/promises";import{dirname as Y,join as K,resolve as Z}from"node:path";import{attachOursClient as tt}from"@ours.network/sdk";import{createHash as F}from"node:crypto";import{openSync as j,closeSync as _,lstatSync as v,mkdirSync as L,chmodSync as J,constants as p}from"node:fs";import{join as N}from"node:path";import{createRequire as C}from"node:module";var G=5e3,d=null,x=!1;function q(){if(d)return d;if(x)throw new Error("No SQLite implementation available for native session guard");x=!0;try{return d=C(import.meta.url)("node:sqlite").DatabaseSync,d}catch{try{let t=C(import.meta.url)("better-sqlite3");return d=t.default??t,d}catch{throw new Error("Native session guard requires node:sqlite (Node >=22.13) or better-sqlite3")}}}function M(t){try{let e=j(t,p.O_RDWR|p.O_CREAT|p.O_EXCL|p.O_NOFOLLOW,384);_(e)}catch(e){if(e.code!=="EEXIST")throw e}let i=v(t);if(!i.isFile()||i.uid!==process.getuid()||i.mode&63||i.nlink!==1)throw new Error("Native session guard file must be an owner-only regular file")}function O(t){let i=process.getuid(),e=N(`/tmp/ours-${i}`,"session-guards");L(e,{recursive:!0,mode:448});try{J(e,448)}catch{}let n=F("sha256").update(t).digest("hex"),r=N(e,`${n}.guard`);M(r);let o=v(r),s=q(),l=new s(r);try{let c=v(r);if(o.dev!==c.dev||o.ino!==c.ino||o.mode!==c.mode||o.uid!==c.uid)throw new Error("Native session guard file changed during acquisition");return l.exec(`PRAGMA busy_timeout=${G}; BEGIN EXCLUSIVE`),()=>{try{l.close()}catch{}}}catch(c){try{l.close()}catch{}throw c}}var g=1,$=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,a=new Map,u=new Map;function et(t){if(typeof t!="string"||t.length===0||t.length>4096||t.trim()!==t||t.includes("\0"))throw new Error("Native session metadata is missing or invalid for this host-profile tool call.");return t}function y(t,i,e){if(!t||!t.startsWith("/")||Z(t)!==t)throw new Error("Native session host record root must be a normalized absolute path.");if(!$.test(i))throw new Error("Native session daemon instance must be a lowercase UUID.");let n=V("sha256").update(et(e),"utf8").digest("hex");return K(t,"sessions",i,`${n}.json`)}function nt(t,i){let e;try{e=JSON.parse(t)}catch(o){throw new Error(`Invalid native session record at ${i}: ${String(o)}`)}if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`Invalid native session record at ${i}: expected an object.`);let n=e;if(Object.keys(n).sort().join(",")!=="ownerInstanceId,state,version"||n.version!==g||typeof n.ownerInstanceId!="string"||!$.test(n.ownerInstanceId)||!["active","pending","ended"].includes(String(n.state)))throw new Error(`Invalid native session record at ${i}.`);return n}async function m(t){try{return nt(await X(t,"utf8"),t)}catch(i){if(i.code==="ENOENT")return null;throw i}}async function h(t,i){let e=Y(t);await W(e,{recursive:!0,mode:448}),await A(e,448);let n=`${t}.${process.pid}.${b()}.tmp`;try{await Q(n,`${JSON.stringify(i,null,2)}
2
+ `,{mode:384,flag:"wx"}),await z(n,t),await A(t,384)}catch(r){try{await B(n)}catch{}throw r}}async function k(t,i){let e=u.get(t)??Promise.resolve(),n,r=new Promise(l=>{n=l}),o=e.catch(()=>{}).then(()=>r);u.set(t,o),await e.catch(()=>{});let s;try{return s=O(t),await i()}finally{try{s?.()}finally{n(),u.get(t)===o&&u.delete(t)}}}function D(t,i){return tt({endpoint:t.endpoint,expectedInstanceId:t.expectedInstanceId,credentialPath:t.credentialPath,sessionMode:"external",leaseToken:i,env:{}})}function R(t,i,e){let n=a.get(t);if(n?.ownerInstanceId===e)return n.promise;n&&(a.delete(t),n.promise.then(s=>s.close()).catch(()=>{}));let r=D(i,e),o={ownerInstanceId:e,promise:r};return a.set(t,o),r.catch(()=>{a.get(t)===o&&a.delete(t)}),r}async function it(t,i,e){let n=a.get(t),r=n?.ownerInstanceId===e?await n.promise:await D(i,e);try{await r.releaseLease()}finally{n?.ownerInstanceId!==e&&await r.close()}}async function T(t,i,e){await it(t,i,e);let n=await m(t);n?.state==="pending"&&n.ownerInstanceId===e&&await h(t,{version:g,ownerInstanceId:e,state:"ended"});let r=a.get(t);r?.ownerInstanceId===e&&(a.delete(t),r.promise.then(o=>o.close()).catch(()=>{}))}async function H(t,i,e){let n=f(t),r=y(e,n.expectedInstanceId,i);return k(r,async()=>{let o=await m(r);if(o?.state==="pending"&&(await T(r,n,o.ownerInstanceId),o=await m(r)),o?.state==="active")return R(r,n,o.ownerInstanceId);let s=b();return await h(r,{version:g,ownerInstanceId:s,state:"active"}),R(r,n,s)})}async function U(t,i,e){let n=f(t),r=y(e,n.expectedInstanceId,i);await k(r,async()=>{let o=await m(r);o===null||o.state==="ended"||(o.state==="active"&&(o={version:g,ownerInstanceId:o.ownerInstanceId,state:"pending"},await h(r,o)),await T(r,n,o.ownerInstanceId))})}export{U as endNativeSessionAtRoot,S as hostProfileFromEnv,w as hostProfileSelectionFromEnv,H as nativeClientForAtRoot,y as nativeSessionRecordPath,E as readHostProfile,f as validateHostProfile};
@@ -1 +1 @@
1
- import{existsSync as h,lstatSync as u,readFileSync as m}from"node:fs";import{homedir as d}from"node:os";import{resolve as l}from"node:path";import{normalizeDaemonEndpoint as g}from"@ours.network/sdk/client";var p=["endpoint","expectedInstanceId","credentialPath"],w=["port","stateDir","apiToken","apiVisibility"],y=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,O=["OURS_API_TOKEN","OURS_PORT","OURS_STATE_DIR","OURS_DAEMON_ID"];function n(t){return new Error(`Invalid external host profile: ${t}`)}function S(t){if(!t||typeof t!="object"||Array.isArray(t))throw n("expected a complete host profile object.");let e=t;if(p.filter(f=>Object.hasOwn(e,f)).length!==p.length)throw n("expected a complete host profile tuple: endpoint, expectedInstanceId, credentialPath.");let o=w.filter(f=>Object.hasOwn(e,f));if(o.length)throw n(`legacy selection keys cannot be mixed with a host profile (${o.join(", ")}).`);let i=e.endpoint,a=e.expectedInstanceId,s=e.credentialPath;if(typeof i!="string"||i.trim()!==i||i==="")throw n("endpoint must be a non-empty HTTP or HTTPS base URL.");if(typeof a!="string"||!y.test(a))throw n("expectedInstanceId must be a lowercase UUID.");if(typeof s!="string"||s===""||!s.startsWith("/")||l(s)!==s)throw n("credentialPath must be a normalized absolute path.");let c;try{c=new URL(i)}catch{throw n("endpoint must be an HTTP or HTTPS base URL.")}if(c.protocol!=="http:"&&c.protocol!=="https:"||c.username||c.password||/[\s\\?#]/.test(i)||c.search||c.hash)throw n("endpoint must be an HTTP or HTTPS base URL without credentials, query, or fragment.");return{endpoint:g(i),expectedInstanceId:a,credentialPath:s}}function E(t){let e;try{e=m(t,"utf8")}catch{throw new Error(`Cannot read host profile ${JSON.stringify(t)}.`)}let r;try{r=JSON.parse(e)}catch{throw n(`config ${JSON.stringify(t)} is not valid JSON.`)}if(!r||typeof r!="object"||Array.isArray(r))throw n(`config ${JSON.stringify(t)} must be an object.`);return r}function b(t){let e;try{e=u(t)}catch{throw new Error(`Cannot read host profile ${JSON.stringify(t)}.`)}if(!e.isFile())throw n(`config ${JSON.stringify(t)} must be a regular file.`);let r=process.getuid?.();if(r===void 0||e.uid!==r)throw n(`config ${JSON.stringify(t)} must be owned by the current user.`);if(e.mode&63)throw n(`config ${JSON.stringify(t)} must have private permissions.`)}function P(t){let e=E(t);return p.filter(o=>Object.hasOwn(e,o)).length===0?null:(b(t),S(e))}function I(t,e){return(t[e]??"").trim()!==""}function N(t=process.env){let e=(t.OURS_CONFIG??"").trim(),r=l(t.HOME||d(),".ours-client","profile.json"),o=e;if(!o)try{u(r),o=r}catch(s){if(s.code!=="ENOENT")throw new Error(`Cannot read host profile ${JSON.stringify(r)}.`);if(o=l(d(),".ours","config.json"),!h(o))return null}let i=P(o);if(i===null){if(l(o)===r)throw n("managed client config must contain a complete host profile tuple.");return null}let a=O.filter(s=>I(t,s));if(a.length)throw n(`${a.join(", ")} conflicts with host-profile mode.`);return{profile:i,configPath:o}}function H(t=process.env){return N(t)?.profile??null}export{H as hostProfileFromEnv,N as hostProfileSelectionFromEnv,P as readHostProfile,S as validateHostProfile};
1
+ import{readGatewayClientProfile as o,validateGatewayClientProfile as r}from"@ours.network/sdk/client";var l=r;function f(e){return r(o({OURS_CONFIG:e}))}function i(e=process.env){let{configPath:t,...n}=o(e);return{profile:n,configPath:t}}function a(e=process.env){return i(e).profile}export{a as hostProfileFromEnv,i as hostProfileSelectionFromEnv,f as readHostProfile,l as validateHostProfile};
@@ -1,2 +1,2 @@
1
- import{createHash as K,randomUUID as R}from"node:crypto";import{chmod as x,mkdir as X,readFile as B,rename as Q,unlink as Z,writeFile as tt}from"node:fs/promises";import{dirname as I,join as et,resolve as nt}from"node:path";import{attachOursClient as rt}from"@ours.network/sdk";import{homedir as k}from"node:os";import{dirname as ft,resolve as E}from"node:path";var _="OURS_MCP_CONFIG";function w(t=process.env){let e=(t[_]??"").trim();return E(e||E(k(),".ours-mcp","config.json"))}import{resolve as j}from"node:path";import{normalizeDaemonEndpoint as J}from"@ours.network/sdk/client";var S=["endpoint","expectedInstanceId","credentialPath"],H=["port","stateDir","apiToken","apiVisibility"],L=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;function d(t){return new Error(`Invalid external host profile: ${t}`)}function y(t){if(!t||typeof t!="object"||Array.isArray(t))throw d("expected a complete host profile object.");let e=t;if(S.filter(c=>Object.hasOwn(e,c)).length!==S.length)throw d("expected a complete host profile tuple: endpoint, expectedInstanceId, credentialPath.");let r=H.filter(c=>Object.hasOwn(e,c));if(r.length)throw d(`legacy selection keys cannot be mixed with a host profile (${r.join(", ")}).`);let i=e.endpoint,o=e.expectedInstanceId,s=e.credentialPath;if(typeof i!="string"||i.trim()!==i||i==="")throw d("endpoint must be a non-empty HTTP or HTTPS base URL.");if(typeof o!="string"||!L.test(o))throw d("expectedInstanceId must be a lowercase UUID.");if(typeof s!="string"||s===""||!s.startsWith("/")||j(s)!==s)throw d("credentialPath must be a normalized absolute path.");let a;try{a=new URL(i)}catch{throw d("endpoint must be an HTTP or HTTPS base URL.")}if(a.protocol!=="http:"&&a.protocol!=="https:"||a.username||a.password||/[\s\\?#]/.test(i)||a.search||a.hash)throw d("endpoint must be an HTTP or HTTPS base URL without credentials, query, or fragment.");return{endpoint:J(i),expectedInstanceId:o,credentialPath:s}}import{createHash as F}from"node:crypto";import{openSync as q,closeSync as G,lstatSync as h,mkdirSync as M,chmodSync as V,constants as p}from"node:fs";import{join as P}from"node:path";import{createRequire as N}from"node:module";var z=5e3,f=null,O=!1;function W(){if(f)return f;if(O)throw new Error("No SQLite implementation available for native session guard");O=!0;try{return f=N(import.meta.url)("node:sqlite").DatabaseSync,f}catch{try{let t=N(import.meta.url)("better-sqlite3");return f=t.default??t,f}catch{throw new Error("Native session guard requires node:sqlite (Node >=22.13) or better-sqlite3")}}}function Y(t){try{let n=q(t,p.O_RDWR|p.O_CREAT|p.O_EXCL|p.O_NOFOLLOW,384);G(n)}catch(n){if(n.code!=="EEXIST")throw n}let e=h(t);if(!e.isFile()||e.uid!==process.getuid()||e.mode&63||e.nlink!==1)throw new Error("Native session guard file must be an owner-only regular file")}function b(t){let e=process.getuid(),n=P(`/tmp/ours-${e}`,"session-guards");M(n,{recursive:!0,mode:448});try{V(n,448)}catch{}let r=F("sha256").update(t).digest("hex"),i=P(n,`${r}.guard`);Y(i);let o=h(i),s=W(),a=new s(i);try{let c=h(i);if(o.dev!==c.dev||o.ino!==c.ino||o.mode!==c.mode||o.uid!==c.uid)throw new Error("Native session guard file changed during acquisition");return a.exec(`PRAGMA busy_timeout=${z}; BEGIN EXCLUSIVE`),()=>{try{a.close()}catch{}}}catch(c){try{a.close()}catch{}throw c}}var g=1,$=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,l=new Map,u=new Map;function it(t){if(typeof t!="string"||t.length===0||t.length>4096||t.trim()!==t||t.includes("\0"))throw new Error("Native session metadata is missing or invalid for this host-profile tool call.");return t}function T(t,e,n){if(!t||!t.startsWith("/")||nt(t)!==t)throw new Error("Native session host record root must be a normalized absolute path.");if(!$.test(e))throw new Error("Native session daemon instance must be a lowercase UUID.");let r=K("sha256").update(it(n),"utf8").digest("hex");return et(t,"sessions",e,`${r}.json`)}function ot(t,e){let n;try{n=JSON.parse(t)}catch(o){throw new Error(`Invalid native session record at ${e}: ${String(o)}`)}if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`Invalid native session record at ${e}: expected an object.`);let r=n;if(Object.keys(r).sort().join(",")!=="ownerInstanceId,state,version"||r.version!==g||typeof r.ownerInstanceId!="string"||!$.test(r.ownerInstanceId)||!["active","pending","ended"].includes(String(r.state)))throw new Error(`Invalid native session record at ${e}.`);return r}async function m(t){try{return ot(await B(t,"utf8"),t)}catch(e){if(e.code==="ENOENT")return null;throw e}}async function v(t,e){let n=I(t);await X(n,{recursive:!0,mode:448}),await x(n,448);let r=`${t}.${process.pid}.${R()}.tmp`;try{await tt(r,`${JSON.stringify(e,null,2)}
2
- `,{mode:384,flag:"wx"}),await Q(r,t),await x(t,384)}catch(i){try{await Z(r)}catch{}throw i}}async function A(t,e){let n=u.get(t)??Promise.resolve(),r,i=new Promise(a=>{r=a}),o=n.catch(()=>{}).then(()=>i);u.set(t,o),await n.catch(()=>{});let s;try{return s=b(t),await e()}finally{try{s?.()}finally{r(),u.get(t)===o&&u.delete(t)}}}function U(t,e){return rt({endpoint:t.endpoint,expectedInstanceId:t.expectedInstanceId,credentialPath:t.credentialPath,sessionMode:"external",leaseToken:e,env:{}})}function C(t,e,n){let r=l.get(t);if(r?.ownerInstanceId===n)return r.promise;r&&(l.delete(t),r.promise.then(s=>s.close()).catch(()=>{}));let i=U(e,n),o={ownerInstanceId:n,promise:i};return l.set(t,o),i.catch(()=>{l.get(t)===o&&l.delete(t)}),i}async function st(t,e,n){let r=l.get(t),i=r?.ownerInstanceId===n?await r.promise:await U(e,n);try{await i.releaseLease()}finally{r?.ownerInstanceId!==n&&await i.close()}}async function D(t,e,n){await st(t,e,n);let r=await m(t);r?.state==="pending"&&r.ownerInstanceId===n&&await v(t,{version:g,ownerInstanceId:n,state:"ended"});let i=l.get(t);i?.ownerInstanceId===n&&(l.delete(t),i.promise.then(o=>o.close()).catch(()=>{}))}async function Ct(t,e,n=process.env){return at(t,e,I(w(n)))}async function at(t,e,n){let r=y(t),i=T(n,r.expectedInstanceId,e);return A(i,async()=>{let o=await m(i);if(o?.state==="pending"&&(await D(i,r,o.ownerInstanceId),o=await m(i)),o?.state==="active")return C(i,r,o.ownerInstanceId);let s=R();return await v(i,{version:g,ownerInstanceId:s,state:"active"}),C(i,r,s)})}async function Rt(t,e,n=process.env){return ct(t,e,I(w(n)))}async function ct(t,e,n){let r=y(t),i=T(n,r.expectedInstanceId,e);await A(i,async()=>{let o=await m(i);o===null||o.state==="ended"||(o.state==="active"&&(o={version:g,ownerInstanceId:o.ownerInstanceId,state:"pending"},await v(i,o)),await D(i,r,o.ownerInstanceId))})}export{Rt as endNativeSession,ct as endNativeSessionAtRoot,Ct as nativeClientFor,at as nativeClientForAtRoot,T as nativeSessionRecordPath};
1
+ import{createHash as M,randomUUID as b}from"node:crypto";import{chmod as C,mkdir as V,readFile as W,rename as X,unlink as z,writeFile as B}from"node:fs/promises";import{dirname as v,join as Q,resolve as Y}from"node:path";import{attachOursClient as K}from"@ours.network/sdk";import{homedir as D}from"node:os";import{dirname as st,resolve as I}from"node:path";var T="OURS_MCP_CONFIG";function g(t=process.env){let n=(t[T]??"").trim();return I(n||I(D(),".ours-mcp","config.json"))}import{readGatewayClientProfile as dt,validateGatewayClientProfile as U}from"@ours.network/sdk/client";var y=U;import{createHash as _}from"node:crypto";import{openSync as L,closeSync as j,lstatSync as w,mkdirSync as J,chmodSync as H,constants as f}from"node:fs";import{join as P}from"node:path";import{createRequire as E}from"node:module";var F=5e3,d=null,S=!1;function G(){if(d)return d;if(S)throw new Error("No SQLite implementation available for native session guard");S=!0;try{return d=E(import.meta.url)("node:sqlite").DatabaseSync,d}catch{try{let t=E(import.meta.url)("better-sqlite3");return d=t.default??t,d}catch{throw new Error("Native session guard requires node:sqlite (Node >=22.13) or better-sqlite3")}}}function q(t){try{let e=L(t,f.O_RDWR|f.O_CREAT|f.O_EXCL|f.O_NOFOLLOW,384);j(e)}catch(e){if(e.code!=="EEXIST")throw e}let n=w(t);if(!n.isFile()||n.uid!==process.getuid()||n.mode&63||n.nlink!==1)throw new Error("Native session guard file must be an owner-only regular file")}function N(t){let n=process.getuid(),e=P(`/tmp/ours-${n}`,"session-guards");J(e,{recursive:!0,mode:448});try{H(e,448)}catch{}let i=_("sha256").update(t).digest("hex"),r=P(e,`${i}.guard`);q(r);let o=w(r),s=G(),l=new s(r);try{let c=w(r);if(o.dev!==c.dev||o.ino!==c.ino||o.mode!==c.mode||o.uid!==c.uid)throw new Error("Native session guard file changed during acquisition");return l.exec(`PRAGMA busy_timeout=${F}; BEGIN EXCLUSIVE`),()=>{try{l.close()}catch{}}}catch(c){try{l.close()}catch{}throw c}}var m=1,x=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,a=new Map,u=new Map;function Z(t){if(typeof t!="string"||t.length===0||t.length>4096||t.trim()!==t||t.includes("\0"))throw new Error("Native session metadata is missing or invalid for this host-profile tool call.");return t}function $(t,n,e){if(!t||!t.startsWith("/")||Y(t)!==t)throw new Error("Native session host record root must be a normalized absolute path.");if(!x.test(n))throw new Error("Native session daemon instance must be a lowercase UUID.");let i=M("sha256").update(Z(e),"utf8").digest("hex");return Q(t,"sessions",n,`${i}.json`)}function tt(t,n){let e;try{e=JSON.parse(t)}catch(o){throw new Error(`Invalid native session record at ${n}: ${String(o)}`)}if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`Invalid native session record at ${n}: expected an object.`);let i=e;if(Object.keys(i).sort().join(",")!=="ownerInstanceId,state,version"||i.version!==m||typeof i.ownerInstanceId!="string"||!x.test(i.ownerInstanceId)||!["active","pending","ended"].includes(String(i.state)))throw new Error(`Invalid native session record at ${n}.`);return i}async function p(t){try{return tt(await W(t,"utf8"),t)}catch(n){if(n.code==="ENOENT")return null;throw n}}async function h(t,n){let e=v(t);await V(e,{recursive:!0,mode:448}),await C(e,448);let i=`${t}.${process.pid}.${b()}.tmp`;try{await B(i,`${JSON.stringify(n,null,2)}
2
+ `,{mode:384,flag:"wx"}),await X(i,t),await C(t,384)}catch(r){try{await z(i)}catch{}throw r}}async function A(t,n){let e=u.get(t)??Promise.resolve(),i,r=new Promise(l=>{i=l}),o=e.catch(()=>{}).then(()=>r);u.set(t,o),await e.catch(()=>{});let s;try{return s=N(t),await n()}finally{try{s?.()}finally{i(),u.get(t)===o&&u.delete(t)}}}function R(t,n){return K({endpoint:t.endpoint,expectedInstanceId:t.expectedInstanceId,credentialPath:t.credentialPath,sessionMode:"external",leaseToken:n,env:{}})}function O(t,n,e){let i=a.get(t);if(i?.ownerInstanceId===e)return i.promise;i&&(a.delete(t),i.promise.then(s=>s.close()).catch(()=>{}));let r=R(n,e),o={ownerInstanceId:e,promise:r};return a.set(t,o),r.catch(()=>{a.get(t)===o&&a.delete(t)}),r}async function et(t,n,e){let i=a.get(t),r=i?.ownerInstanceId===e?await i.promise:await R(n,e);try{await r.releaseLease()}finally{i?.ownerInstanceId!==e&&await r.close()}}async function k(t,n,e){await et(t,n,e);let i=await p(t);i?.state==="pending"&&i.ownerInstanceId===e&&await h(t,{version:m,ownerInstanceId:e,state:"ended"});let r=a.get(t);r?.ownerInstanceId===e&&(a.delete(t),r.promise.then(o=>o.close()).catch(()=>{}))}async function St(t,n,e=process.env){return nt(t,n,v(g(e)))}async function nt(t,n,e){let i=y(t),r=$(e,i.expectedInstanceId,n);return A(r,async()=>{let o=await p(r);if(o?.state==="pending"&&(await k(r,i,o.ownerInstanceId),o=await p(r)),o?.state==="active")return O(r,i,o.ownerInstanceId);let s=b();return await h(r,{version:m,ownerInstanceId:s,state:"active"}),O(r,i,s)})}async function Nt(t,n,e=process.env){return it(t,n,v(g(e)))}async function it(t,n,e){let i=y(t),r=$(e,i.expectedInstanceId,n);await A(r,async()=>{let o=await p(r);o===null||o.state==="ended"||(o.state==="active"&&(o={version:m,ownerInstanceId:o.ownerInstanceId,state:"pending"},await h(r,o)),await k(r,i,o.ownerInstanceId))})}export{Nt as endNativeSession,it as endNativeSessionAtRoot,St as nativeClientFor,nt as nativeClientForAtRoot,$ as nativeSessionRecordPath};
@@ -1,13 +1,19 @@
1
- export type HostProfile = Readonly<{
1
+ import { validateGatewayClientProfile } from '@ours.network/sdk/client';
2
+ export type { GatewayClientProfile as HostProfile } from '@ours.network/sdk/client';
3
+ export declare const validateHostProfile: typeof validateGatewayClientProfile;
4
+ export declare function readHostProfile(configPath: string): import("@ours.network/sdk").GatewayClientProfile;
5
+ export declare function hostProfileSelectionFromEnv(env?: NodeJS.ProcessEnv): {
6
+ profile: {
7
+ serverUrl: string;
8
+ endpoint: string;
9
+ expectedInstanceId: string;
10
+ credentialPath: string;
11
+ };
12
+ configPath: string;
13
+ };
14
+ export declare function hostProfileFromEnv(env?: NodeJS.ProcessEnv): {
15
+ serverUrl: string;
2
16
  endpoint: string;
3
17
  expectedInstanceId: string;
4
18
  credentialPath: string;
5
- }>;
6
- export declare function validateHostProfile(value: unknown): HostProfile;
7
- export declare function readHostProfile(configPath: string): HostProfile | null;
8
- /** Select only host-client profiles; daemon configuration resolution is unchanged. */
9
- export declare function hostProfileSelectionFromEnv(env?: NodeJS.ProcessEnv): {
10
- profile: HostProfile;
11
- configPath: string;
12
- } | null;
13
- export declare function hostProfileFromEnv(env?: NodeJS.ProcessEnv): HostProfile | null;
19
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/mcp",
3
- "version": "1.2.0-nightly.7",
3
+ "version": "1.2.0-nightly.8",
4
4
  "description": "MCP adapter for the shared ours daemon, with application-local identity bookkeeping and secure agent-to-agent messaging tools over stdio.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",
@@ -54,11 +54,11 @@
54
54
  "dev": "tsx src/cli.ts proxy",
55
55
  "prepublishOnly": "node build.mjs",
56
56
  "typecheck": "tsc -p tsconfig.json --noEmit",
57
- "test": "node --test test/managed-server.test.mjs && node test/application-identities.test.mjs && node test/local-files.test.mjs && node test/cli-delegation.test.mjs && node test/inbox-push.test.mjs && node test/contact-lines.test.mjs && node test/env-bind-identity.test.mjs && node test/proxy-exit-on-stdin-eof.test.mjs && node test/proxy-dead-stderr.test.mjs && node test/session-end-temp-cleanup.test.mjs && node test/host-profile.test.mjs && node test/container.test.mjs && node test/native-profile-session.test.mjs",
57
+ "test": "node --test test/managed-server.test.mjs && node test/application-identities.test.mjs && node test/local-files.test.mjs && node test/cli-delegation.test.mjs && node test/inbox-push.test.mjs && node test/contact-lines.test.mjs && node test/proxy-exit-on-stdin-eof.test.mjs && node test/proxy-dead-stderr.test.mjs && node test/host-profile.test.mjs && node test/container.test.mjs && node test/native-profile-session.test.mjs",
58
58
  "test:external-profile": "node test/native-profile-session.test.mjs && node test/external-profile-stdio-refresh.test.mjs"
59
59
  },
60
60
  "dependencies": {
61
- "@ours.network/sdk": "3.8.1-nightly.11",
61
+ "@ours.network/sdk": "3.8.1-nightly.13",
62
62
  "@modelcontextprotocol/sdk": "^1.0.4",
63
63
  "zod": "^3.23.8"
64
64
  },
@@ -67,7 +67,7 @@
67
67
  "esbuild": "^0.24.2",
68
68
  "tsx": "^4.19.0",
69
69
  "typescript": "^5.5.4",
70
- "@ours.network/cli": "2.8.1-nightly.9",
71
- "@ours.network/daemon": "3.8.1-nightly.3"
70
+ "@ours.network/cli": "2.8.1-nightly.11",
71
+ "@ours.network/daemon": "3.8.1-nightly.5"
72
72
  }
73
73
  }