@ours.network/mcp 0.5.0 → 0.7.0

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/cli.js CHANGED
@@ -39,12 +39,12 @@ ${ae}`,_++}else hc(y,x,D)?z=y.slice(y.charCodeAt(x+6)===Ne?x+7:x+6,S)||void 0:G(
39
39
  `,x)}return y.slice(x)}for(;x<y.length;){let S=y.indexOf("\r",x),D=y.indexOf(`
40
40
  `,x),H=-1;if(S!==-1&&D!==-1?H=S<D?S:D:S!==-1?S===y.length-1?H=-1:H=S:D!==-1&&(H=D),H===-1)break;G(y,x,H),x=H+1,y.charCodeAt(x-1)===Ld&&y.charCodeAt(x)===mc&&x++}return y.slice(x)}function G(y,x,S){if(x===S){$();return}let D=y.charCodeAt(x);if(fc(y,x,D)){let de=y.charCodeAt(x+5)===Ne?x+6:x+5,Me=y.slice(de,S);h=_===0?Me:`${h}
41
41
  ${Me}`,_++;return}if(hc(y,x,D)){z=y.slice(y.charCodeAt(x+6)===Ne?x+7:x+6,S)||void 0;return}if(D===105&&y.charCodeAt(x+1)===100&&y.charCodeAt(x+2)===58){let de=y.slice(y.charCodeAt(x+3)===Ne?x+4:x+3,S);p=de.includes("\0")?void 0:de;return}if(D===58){if(n){let de=y.slice(x,S);n(de.slice(y.charCodeAt(x+1)===Ne?2:1))}return}let H=y.slice(x,S),ae=H.indexOf(":");if(ae===-1){A(H,"",H);return}let De=H.slice(0,ae),gr=H.charCodeAt(ae+1)===Ne?2:1,it=H.slice(ae+gr);A(De,it,H)}function A(y,x,S){switch(y){case"event":z=x||void 0;break;case"data":h=_===0?x:`${h}
42
- ${x}`,_++;break;case"id":p=x.includes("\0")?void 0:x;break;case"retry":/^\d+$/.test(x)?o(parseInt(x,10)):r(new Ct(`Invalid \`retry\` value: "${x}"`,{type:"invalid-retry",value:x,line:S}));break;default:r(new Ct(`Unknown field "${y.length>20?`${y.slice(0,20)}\u2026`:y}"`,{type:"unknown-field",field:y,value:x,line:S}));break}}function $(){_>0&&t({id:p,event:z,data:h}),p=void 0,h="",_=0,z=void 0}function O(y={}){if(y.consume&&s.length>0){let x=s.join("");G(x,0,x.length)}l=!0,p=void 0,h="",_=0,z=void 0,s.length=0,c=0,m=!1}return{feed:k,reset:O}}function fc(e,t,r){return r===100&&e.charCodeAt(t+1)===97&&e.charCodeAt(t+2)===116&&e.charCodeAt(t+3)===97&&e.charCodeAt(t+4)===58}function hc(e,t,r){return r===101&&e.charCodeAt(t+1)===118&&e.charCodeAt(t+2)===101&&e.charCodeAt(t+3)===110&&e.charCodeAt(t+4)===116&&e.charCodeAt(t+5)===58}var ur=class extends TransformStream{constructor({onError:t,onRetry:r,onComment:o,maxBufferSize:n}={}){let i;super({start(s){i=gc({onEvent:c=>{s.enqueue(c)},onError(c){typeof t=="function"&&t(c),(t==="terminate"||c.type==="max-buffer-size-exceeded")&&s.error(c)},onRetry:r,onComment:o,maxBufferSize:n})},transform(s){i.feed(s)}})}};var Dd={initialReconnectionDelay:1e3,maxReconnectionDelay:3e4,reconnectionDelayGrowFactor:1.5,maxRetries:2},Re=class extends Error{constructor(t,r){super(`Streamable HTTP error: ${r}`),this.code=t}},lr=class{constructor(t,r){this._hasCompletedAuthFlow=!1,this._url=t,this._resourceMetadataUrl=void 0,this._scope=void 0,this._requestInit=r?.requestInit,this._authProvider=r?.authProvider,this._fetch=r?.fetch,this._fetchWithInit=Xa(r?.fetch,r?.requestInit),this._sessionId=r?.sessionId,this._reconnectionOptions=r?.reconnectionOptions??Dd}async _authThenStart(){if(!this._authProvider)throw new Se("No auth provider");let t;try{t=await Et(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})}catch(r){throw this.onerror?.(r),r}if(t!=="AUTHORIZED")throw new Se;return await this._startOrAuthSse({resumptionToken:void 0})}async _commonHeaders(){let t={};if(this._authProvider){let o=await this._authProvider.tokens();o&&(t.Authorization=`Bearer ${o.access_token}`)}this._sessionId&&(t["mcp-session-id"]=this._sessionId),this._protocolVersion&&(t["mcp-protocol-version"]=this._protocolVersion);let r=cr(this._requestInit?.headers);return new Headers({...t,...r})}async _startOrAuthSse(t){let{resumptionToken:r}=t;try{let o=await this._commonHeaders();o.set("Accept","text/event-stream"),r&&o.set("last-event-id",r);let n=await(this._fetch??fetch)(this._url,{method:"GET",headers:o,signal:this._abortController?.signal});if(!n.ok){if(await n.body?.cancel(),n.status===401&&this._authProvider)return await this._authThenStart();if(n.status===405)return;throw new Re(n.status,`Failed to open SSE stream: ${n.statusText}`)}this._handleSseStream(n.body,t,!0)}catch(o){throw this.onerror?.(o),o}}_getNextReconnectionDelay(t){if(this._serverRetryMs!==void 0)return this._serverRetryMs;let r=this._reconnectionOptions.initialReconnectionDelay,o=this._reconnectionOptions.reconnectionDelayGrowFactor,n=this._reconnectionOptions.maxReconnectionDelay;return Math.min(r*Math.pow(o,t),n)}_scheduleReconnection(t,r=0){let o=this._reconnectionOptions.maxRetries;if(r>=o){this.onerror?.(new Error(`Maximum reconnection attempts (${o}) exceeded.`));return}let n=this._getNextReconnectionDelay(r);this._reconnectionTimeout=setTimeout(()=>{this._startOrAuthSse(t).catch(i=>{this.onerror?.(new Error(`Failed to reconnect SSE stream: ${i instanceof Error?i.message:String(i)}`)),this._scheduleReconnection(t,r+1)})},n)}_handleSseStream(t,r,o){if(!t)return;let{onresumptiontoken:n,replayMessageId:i}=r,s,c=!1,l=!1;(async()=>{try{let h=t.pipeThrough(new TextDecoderStream).pipeThrough(new ur({onRetry:m=>{this._serverRetryMs=m}})).getReader();for(;;){let{value:m,done:k}=await h.read();if(k)break;if(m.id&&(s=m.id,c=!0,n?.(m.id)),!!m.data&&(!m.event||m.event==="message"))try{let P=Ye.parse(JSON.parse(m.data));ka(P)&&(l=!0,i!==void 0&&(P.id=i)),this.onmessage?.(P)}catch(P){this.onerror?.(P)}}(o||c)&&!l&&this._abortController&&!this._abortController.signal.aborted&&this._scheduleReconnection({resumptionToken:s,onresumptiontoken:n,replayMessageId:i},0)}catch(h){if(this.onerror?.(new Error(`SSE stream disconnected: ${h}`)),(o||c)&&!l&&this._abortController&&!this._abortController.signal.aborted)try{this._scheduleReconnection({resumptionToken:s,onresumptiontoken:n,replayMessageId:i},0)}catch(m){this.onerror?.(new Error(`Failed to reconnect: ${m instanceof Error?m.message:String(m)}`))}}})()}async start(){if(this._abortController)throw new Error("StreamableHTTPClientTransport already started! If using Client class, note that connect() calls start() automatically.");this._abortController=new AbortController}async finishAuth(t){if(!this._authProvider)throw new Se("No auth provider");if(await Et(this._authProvider,{serverUrl:this._url,authorizationCode:t,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})!=="AUTHORIZED")throw new Se("Failed to authorize")}async close(){this._reconnectionTimeout&&(clearTimeout(this._reconnectionTimeout),this._reconnectionTimeout=void 0),this._abortController?.abort(),this.onclose?.()}async send(t,r){try{let{resumptionToken:o,onresumptiontoken:n}=r||{};if(o){this._startOrAuthSse({resumptionToken:o,replayMessageId:$a(t)?t.id:void 0}).catch(z=>this.onerror?.(z));return}let i=await this._commonHeaders();i.set("content-type","application/json"),i.set("accept","application/json, text/event-stream");let s={...this._requestInit,method:"POST",headers:i,body:JSON.stringify(t),signal:this._abortController?.signal},c=await(this._fetch??fetch)(this._url,s),l=c.headers.get("mcp-session-id");if(l&&(this._sessionId=l),!c.ok){let z=await c.text().catch(()=>null);if(c.status===401&&this._authProvider){if(this._hasCompletedAuthFlow)throw new Re(401,"Server returned 401 after successful authentication");let{resourceMetadataUrl:m,scope:k}=Co(c);if(this._resourceMetadataUrl=m,this._scope=k,await Et(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})!=="AUTHORIZED")throw new Se;return this._hasCompletedAuthFlow=!0,this.send(t)}if(c.status===403&&this._authProvider){let{resourceMetadataUrl:m,scope:k,error:P}=Co(c);if(P==="insufficient_scope"){let ee=c.headers.get("WWW-Authenticate");if(this._lastUpscopingHeader===ee)throw new Re(403,"Server returned 403 after trying upscoping");if(k&&(this._scope=k),m&&(this._resourceMetadataUrl=m),this._lastUpscopingHeader=ee??void 0,await Et(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetch})!=="AUTHORIZED")throw new Se;return this.send(t)}}throw new Re(c.status,`Error POSTing to endpoint: ${z}`)}if(this._hasCompletedAuthFlow=!1,this._lastUpscopingHeader=void 0,c.status===202){await c.body?.cancel(),Oa(t)&&this._startOrAuthSse({resumptionToken:void 0}).catch(z=>this.onerror?.(z));return}let h=(Array.isArray(t)?t:[t]).filter(z=>"method"in z&&"id"in z&&z.id!==void 0).length>0,_=c.headers.get("content-type");if(h)if(_?.includes("text/event-stream"))this._handleSseStream(c.body,{onresumptiontoken:n},!1);else if(_?.includes("application/json")){let z=await c.json(),m=Array.isArray(z)?z.map(k=>Ye.parse(k)):[Ye.parse(z)];for(let k of m)this.onmessage?.(k)}else throw await c.body?.cancel(),new Re(-1,`Unexpected content type: ${_}`);else await c.body?.cancel()}catch(o){throw this.onerror?.(o),o}}get sessionId(){return this._sessionId}async terminateSession(){if(this._sessionId)try{let t=await this._commonHeaders(),r={...this._requestInit,method:"DELETE",headers:t,signal:this._abortController?.signal},o=await(this._fetch??fetch)(this._url,r);if(await o.body?.cancel(),!o.ok&&o.status!==405)throw new Re(o.status,`Failed to terminate session: ${o.statusText}`);this._sessionId=void 0}catch(t){throw this.onerror?.(t),t}}setProtocolVersion(t){this._protocolVersion=t}get protocolVersion(){return this._protocolVersion}async resumeStream(t,r){await this._startOrAuthSse({resumptionToken:t,onresumptiontoken:r?.onresumptiontoken})}};function _c(e){let{selfVersion:t,daemonVersion:r}=e;return!r||r===t?null:`ours: version mismatch \u2014 this plugin/connector is v${t}, the running daemon is v${r}. Everything still works; for the best experience run matching versions. The daemon is a shared singleton and is never restarted automatically, so when no other session is mid-task run \`ours-mcp stop\` (the next session starts the daemon at the new version) \u2014 or update the lagging side to match. No action is required; this is advisory.`}import{mkdirSync as Md,writeFileSync as Fd,readFileSync as Vd,readdirSync as qd,statSync as xc,unlinkSync as Bd,chmodSync as zc}from"node:fs";import{join as pr}from"node:path";import{homedir as Wd}from"node:os";var Jd="0.5.0",Hd=new Set(["choose_identity","create_identity","create_root_identity"]),yc=e=>new Promise(t=>setTimeout(t,e)),Gd=e=>typeof e?.method=="string"&&e.id!==void 0&&e.id!==null,Kd=e=>e&&typeof e=="object"&&!("method"in e)&&e.id!==void 0&&e.id!==null,vc=e=>{let t=e.result;return!!e.error||!!(t&&t.isError)},bc=Number(process.env.OURS_RESTORE_TTL_MS)>0?Number(process.env.OURS_RESTORE_TTL_MS):7*24*60*60*1e3,wc=["1","true","yes","on"].includes((process.env.OURS_NO_AUTORESTORE??"").trim().toLowerCase());async function $c(e){let t=new URL(e.url),r=(...b)=>process.stderr.write(`[ours-proxy] ${b.join(" ")}
42
+ ${x}`,_++;break;case"id":p=x.includes("\0")?void 0:x;break;case"retry":/^\d+$/.test(x)?o(parseInt(x,10)):r(new Ct(`Invalid \`retry\` value: "${x}"`,{type:"invalid-retry",value:x,line:S}));break;default:r(new Ct(`Unknown field "${y.length>20?`${y.slice(0,20)}\u2026`:y}"`,{type:"unknown-field",field:y,value:x,line:S}));break}}function $(){_>0&&t({id:p,event:z,data:h}),p=void 0,h="",_=0,z=void 0}function O(y={}){if(y.consume&&s.length>0){let x=s.join("");G(x,0,x.length)}l=!0,p=void 0,h="",_=0,z=void 0,s.length=0,c=0,m=!1}return{feed:k,reset:O}}function fc(e,t,r){return r===100&&e.charCodeAt(t+1)===97&&e.charCodeAt(t+2)===116&&e.charCodeAt(t+3)===97&&e.charCodeAt(t+4)===58}function hc(e,t,r){return r===101&&e.charCodeAt(t+1)===118&&e.charCodeAt(t+2)===101&&e.charCodeAt(t+3)===110&&e.charCodeAt(t+4)===116&&e.charCodeAt(t+5)===58}var ur=class extends TransformStream{constructor({onError:t,onRetry:r,onComment:o,maxBufferSize:n}={}){let i;super({start(s){i=gc({onEvent:c=>{s.enqueue(c)},onError(c){typeof t=="function"&&t(c),(t==="terminate"||c.type==="max-buffer-size-exceeded")&&s.error(c)},onRetry:r,onComment:o,maxBufferSize:n})},transform(s){i.feed(s)}})}};var Dd={initialReconnectionDelay:1e3,maxReconnectionDelay:3e4,reconnectionDelayGrowFactor:1.5,maxRetries:2},Re=class extends Error{constructor(t,r){super(`Streamable HTTP error: ${r}`),this.code=t}},lr=class{constructor(t,r){this._hasCompletedAuthFlow=!1,this._url=t,this._resourceMetadataUrl=void 0,this._scope=void 0,this._requestInit=r?.requestInit,this._authProvider=r?.authProvider,this._fetch=r?.fetch,this._fetchWithInit=Xa(r?.fetch,r?.requestInit),this._sessionId=r?.sessionId,this._reconnectionOptions=r?.reconnectionOptions??Dd}async _authThenStart(){if(!this._authProvider)throw new Se("No auth provider");let t;try{t=await Et(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})}catch(r){throw this.onerror?.(r),r}if(t!=="AUTHORIZED")throw new Se;return await this._startOrAuthSse({resumptionToken:void 0})}async _commonHeaders(){let t={};if(this._authProvider){let o=await this._authProvider.tokens();o&&(t.Authorization=`Bearer ${o.access_token}`)}this._sessionId&&(t["mcp-session-id"]=this._sessionId),this._protocolVersion&&(t["mcp-protocol-version"]=this._protocolVersion);let r=cr(this._requestInit?.headers);return new Headers({...t,...r})}async _startOrAuthSse(t){let{resumptionToken:r}=t;try{let o=await this._commonHeaders();o.set("Accept","text/event-stream"),r&&o.set("last-event-id",r);let n=await(this._fetch??fetch)(this._url,{method:"GET",headers:o,signal:this._abortController?.signal});if(!n.ok){if(await n.body?.cancel(),n.status===401&&this._authProvider)return await this._authThenStart();if(n.status===405)return;throw new Re(n.status,`Failed to open SSE stream: ${n.statusText}`)}this._handleSseStream(n.body,t,!0)}catch(o){throw this.onerror?.(o),o}}_getNextReconnectionDelay(t){if(this._serverRetryMs!==void 0)return this._serverRetryMs;let r=this._reconnectionOptions.initialReconnectionDelay,o=this._reconnectionOptions.reconnectionDelayGrowFactor,n=this._reconnectionOptions.maxReconnectionDelay;return Math.min(r*Math.pow(o,t),n)}_scheduleReconnection(t,r=0){let o=this._reconnectionOptions.maxRetries;if(r>=o){this.onerror?.(new Error(`Maximum reconnection attempts (${o}) exceeded.`));return}let n=this._getNextReconnectionDelay(r);this._reconnectionTimeout=setTimeout(()=>{this._startOrAuthSse(t).catch(i=>{this.onerror?.(new Error(`Failed to reconnect SSE stream: ${i instanceof Error?i.message:String(i)}`)),this._scheduleReconnection(t,r+1)})},n)}_handleSseStream(t,r,o){if(!t)return;let{onresumptiontoken:n,replayMessageId:i}=r,s,c=!1,l=!1;(async()=>{try{let h=t.pipeThrough(new TextDecoderStream).pipeThrough(new ur({onRetry:m=>{this._serverRetryMs=m}})).getReader();for(;;){let{value:m,done:k}=await h.read();if(k)break;if(m.id&&(s=m.id,c=!0,n?.(m.id)),!!m.data&&(!m.event||m.event==="message"))try{let P=Ye.parse(JSON.parse(m.data));ka(P)&&(l=!0,i!==void 0&&(P.id=i)),this.onmessage?.(P)}catch(P){this.onerror?.(P)}}(o||c)&&!l&&this._abortController&&!this._abortController.signal.aborted&&this._scheduleReconnection({resumptionToken:s,onresumptiontoken:n,replayMessageId:i},0)}catch(h){if(this.onerror?.(new Error(`SSE stream disconnected: ${h}`)),(o||c)&&!l&&this._abortController&&!this._abortController.signal.aborted)try{this._scheduleReconnection({resumptionToken:s,onresumptiontoken:n,replayMessageId:i},0)}catch(m){this.onerror?.(new Error(`Failed to reconnect: ${m instanceof Error?m.message:String(m)}`))}}})()}async start(){if(this._abortController)throw new Error("StreamableHTTPClientTransport already started! If using Client class, note that connect() calls start() automatically.");this._abortController=new AbortController}async finishAuth(t){if(!this._authProvider)throw new Se("No auth provider");if(await Et(this._authProvider,{serverUrl:this._url,authorizationCode:t,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})!=="AUTHORIZED")throw new Se("Failed to authorize")}async close(){this._reconnectionTimeout&&(clearTimeout(this._reconnectionTimeout),this._reconnectionTimeout=void 0),this._abortController?.abort(),this.onclose?.()}async send(t,r){try{let{resumptionToken:o,onresumptiontoken:n}=r||{};if(o){this._startOrAuthSse({resumptionToken:o,replayMessageId:$a(t)?t.id:void 0}).catch(z=>this.onerror?.(z));return}let i=await this._commonHeaders();i.set("content-type","application/json"),i.set("accept","application/json, text/event-stream");let s={...this._requestInit,method:"POST",headers:i,body:JSON.stringify(t),signal:this._abortController?.signal},c=await(this._fetch??fetch)(this._url,s),l=c.headers.get("mcp-session-id");if(l&&(this._sessionId=l),!c.ok){let z=await c.text().catch(()=>null);if(c.status===401&&this._authProvider){if(this._hasCompletedAuthFlow)throw new Re(401,"Server returned 401 after successful authentication");let{resourceMetadataUrl:m,scope:k}=Co(c);if(this._resourceMetadataUrl=m,this._scope=k,await Et(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})!=="AUTHORIZED")throw new Se;return this._hasCompletedAuthFlow=!0,this.send(t)}if(c.status===403&&this._authProvider){let{resourceMetadataUrl:m,scope:k,error:P}=Co(c);if(P==="insufficient_scope"){let ee=c.headers.get("WWW-Authenticate");if(this._lastUpscopingHeader===ee)throw new Re(403,"Server returned 403 after trying upscoping");if(k&&(this._scope=k),m&&(this._resourceMetadataUrl=m),this._lastUpscopingHeader=ee??void 0,await Et(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetch})!=="AUTHORIZED")throw new Se;return this.send(t)}}throw new Re(c.status,`Error POSTing to endpoint: ${z}`)}if(this._hasCompletedAuthFlow=!1,this._lastUpscopingHeader=void 0,c.status===202){await c.body?.cancel(),Oa(t)&&this._startOrAuthSse({resumptionToken:void 0}).catch(z=>this.onerror?.(z));return}let h=(Array.isArray(t)?t:[t]).filter(z=>"method"in z&&"id"in z&&z.id!==void 0).length>0,_=c.headers.get("content-type");if(h)if(_?.includes("text/event-stream"))this._handleSseStream(c.body,{onresumptiontoken:n},!1);else if(_?.includes("application/json")){let z=await c.json(),m=Array.isArray(z)?z.map(k=>Ye.parse(k)):[Ye.parse(z)];for(let k of m)this.onmessage?.(k)}else throw await c.body?.cancel(),new Re(-1,`Unexpected content type: ${_}`);else await c.body?.cancel()}catch(o){throw this.onerror?.(o),o}}get sessionId(){return this._sessionId}async terminateSession(){if(this._sessionId)try{let t=await this._commonHeaders(),r={...this._requestInit,method:"DELETE",headers:t,signal:this._abortController?.signal},o=await(this._fetch??fetch)(this._url,r);if(await o.body?.cancel(),!o.ok&&o.status!==405)throw new Re(o.status,`Failed to terminate session: ${o.statusText}`);this._sessionId=void 0}catch(t){throw this.onerror?.(t),t}}setProtocolVersion(t){this._protocolVersion=t}get protocolVersion(){return this._protocolVersion}async resumeStream(t,r){await this._startOrAuthSse({resumptionToken:t,onresumptiontoken:r?.onresumptiontoken})}};function _c(e){let{selfVersion:t,daemonVersion:r}=e;return!r||r===t?null:`ours: version mismatch \u2014 this plugin/connector is v${t}, the running daemon is v${r}. Everything still works; for the best experience run matching versions. The daemon is a shared singleton and is never restarted automatically, so when no other session is mid-task run \`ours-mcp stop\` (the next session starts the daemon at the new version) \u2014 or update the lagging side to match. No action is required; this is advisory.`}import{mkdirSync as Md,writeFileSync as Fd,readFileSync as Vd,readdirSync as qd,statSync as xc,unlinkSync as Bd,chmodSync as zc}from"node:fs";import{join as pr}from"node:path";import{homedir as Wd}from"node:os";var Jd="0.7.0",Hd=new Set(["choose_identity","create_identity","create_root_identity"]),yc=e=>new Promise(t=>setTimeout(t,e)),Gd=e=>typeof e?.method=="string"&&e.id!==void 0&&e.id!==null,Kd=e=>e&&typeof e=="object"&&!("method"in e)&&e.id!==void 0&&e.id!==null,vc=e=>{let t=e.result;return!!e.error||!!(t&&t.isError)},bc=Number(process.env.OURS_RESTORE_TTL_MS)>0?Number(process.env.OURS_RESTORE_TTL_MS):7*24*60*60*1e3,wc=["1","true","yes","on"].includes((process.env.OURS_NO_AUTORESTORE??"").trim().toLowerCase());async function $c(e){let t=new URL(e.url),r=(...b)=>process.stderr.write(`[ours-proxy] ${b.join(" ")}
43
43
  `),o=b=>Number.isInteger(b)&&b>1,n=Number(process.env.OURS_CLIENT_PID),i=o(n)?n:o(process.ppid)?process.ppid:process.pid,s=(process.env.CLAUDE_CODE_SESSION_ID??"").trim()||`client:${i}`,c=null,l=null,p,h=null,_=new Map,z=null,m=wc?null:(process.env.CLAUDE_CODE_SESSION_ID??"").trim()||null,k=e.stateDir??process.env.OURS_STATE_DIR??pr(Wd(),".ours"),P=pr(k,"session-restore"),ee=m&&/^[A-Za-z0-9._-]{1,200}$/.test(m)?m:null,G=ee?pr(P,`${ee}.json`):null,A=!1,$=null;function O(b){if(G)try{Md(P,{recursive:!0,mode:448}),Fd(G,JSON.stringify({claudeSessionId:m,identity:b,boundAt:new Date().toISOString()}),{mode:384}),zc(P,448),zc(G,384)}catch(I){r("restore persist failed (non-fatal):",String(I))}}function y(){if(!G)return null;try{if(Date.now()-xc(G).mtimeMs>bc)return null;let b=JSON.parse(Vd(G,"utf8"));return(typeof b.identity=="string"?b.identity.trim():"")||null}catch{return null}}function x(){try{let b=Date.now();for(let I of qd(P)){if(!I.endsWith(".json"))continue;let E=pr(P,I);try{b-xc(E).mtimeMs>bc&&(Bd(E),r("session-restore: pruned expired record",I))}catch{}}}catch{}}let S=null,D=!1,H=!1,ae=!1,De=[],gr="__ours_proxy_init__",it=0,de=new Set,Me=new Set,Ie=new ar;Ie.onmessage=b=>{let I=[],E=!1;for(let he of Sc(b)){let Y=he;if(Y.method==="notifications/initialized"&&(E=!0),Gd(Y)){if(Y.method==="initialize"&&(c=Y,l)){r("absorbed re-initialize locally \u2014 upstream session kept stable"),Ie.send({jsonrpc:"2.0",id:Y.id,result:l}).catch(te=>r("local initialize reply failed:",String(te)));continue}if(Y.method==="tools/call"){let te=Y.params;te&&Hd.has(te.name??"")&&typeof te.arguments?.name=="string"&&_.set(Y.id,te.arguments.name)}}I.push(Y)}if(I.length){let he=Array.isArray(b)?I:I[0];Bo(he)}E&&Lc()},Ie.onclose=()=>void _r(0),Ie.onerror=b=>r("downstream error:",String(b));function Lc(){if(A||!h)return;A=!0;let b=`__ours_proxy_restore_${++it}__`;de.add(b),$=b,r("session-restore: self-recovering bound identity",`"${h}"`),Bo({jsonrpc:"2.0",id:b,method:"tools/call",params:{name:"choose_identity",arguments:{name:h}}})}function Bo(b){if(D&&S){let I=S;S.send(b).catch(E=>{r("upstream send failed:",String(E)),De.push(b),Wo(I,"send failed")})}else De.push(b)}function Wo(b,I){if(H||ae||S!==null&&b!==S)return;r(`upstream dropped (${I}) \u2014 reconnecting`),D=!1;let E=S;S=null;try{E?.close?.()}catch{}Mc()}function Dc(b){b.onmessage=I=>{let E=[];for(let he of Sc(I)){let Y=he;if(Kd(Y)){let te=Y.id,xr=Y.result?.protocolVersion;if(xr&&(Me.has(te)||Jo(te))){p=xr;try{S?.setProtocolVersion?.(xr)}catch{}if(l==null&&Jo(te)&&!de.has(te)){let ye=Y.result??null;ye&&z&&(ye.instructions=`${ye.instructions?ye.instructions+`
44
44
 
45
45
  `:""}${z}`),l=ye}Me.delete(te)}if(de.has(te)){de.delete(te),te===$&&($=null,vc(Y)&&(h=null,r("session-restore: re-bind refused (identity live elsewhere) \u2014 staying unbound")));continue}if(_.has(te)){let ye=_.get(te);_.delete(te),vc(Y)||(h=ye,r("bound identity tracked:",ye),O(ye))}}E.push(Y)}if(E.length){let he=Array.isArray(I)?E:E[0];Ie.send(he).catch(Y=>r("downstream send failed:",String(Y)))}},b.onerror=I=>r("upstream error:",String(I)),b.onclose=()=>Wo(b,"closed")}let Jo=b=>c!=null&&c.id===b;async function Ho(){e.ensureDaemon&&await e.ensureDaemon().catch(I=>r("ensureDaemon:",String(I)));let b=new lr(t,{requestInit:{headers:{"x-ours-lease-token":s,"x-ours-client-pid":String(i),...e.apiToken?{"x-ours-api-token":e.apiToken}:{}}}});if(Dc(b),await b.start(),p)try{b.setProtocolVersion?.(p)}catch{}S=b}async function Go(b,I){I&&b.id!==void 0&&de.add(b.id),await S.send(b)}async function Mc(){if(ae||H)return;ae=!0;let b=500;for(;;){if(H){ae=!1;return}try{if(await Ho(),c){let E=`${gr}${it}`;Me.add(E),await Go({...c,id:E},!0),await S.send({jsonrpc:"2.0",method:"notifications/initialized"})}if(h){let E=`__ours_proxy_rebind_${++it}__`;await Go({jsonrpc:"2.0",id:E,method:"tools/call",params:{name:"choose_identity",arguments:{name:h}}},!0)}D=!0;let I=De.splice(0);for(let E of I)await S.send(E).catch(he=>r("flush failed:",String(he)));r("upstream reconnected",h?`(re-bound "${h}")`:""),ae=!1;return}catch(I){r("reconnect attempt failed:",String(I)),await yc(b),b=Math.min(Math.floor(b*1.5),1e4)}}}async function _r(b){if(!H){H=!0;try{await S?.close()}catch{}try{await Ie.close()}catch{}process.exit(b)}}process.on("SIGINT",()=>void _r(0)),process.on("SIGTERM",()=>void _r(0));async function Fc(){let b=new URL(t.href);b.pathname="/state-dir";let I;try{I=await(await fetch(b,{signal:AbortSignal.timeout(3e3)})).json()}catch(E){r("compat handshake: could not read daemon /state-dir, proceeding:",String(E));return}z=_c({selfVersion:Jd,daemonVersion:typeof I?.version=="string"?I.version:null}),z&&r(z)}if((async()=>{e.ensureDaemon&&await e.ensureDaemon().catch(E=>r("ensureDaemon:",String(E))),await Fc();let b=500;for(;;)try{await Ho();break}catch(E){r("initial upstream connect failed, retrying:",String(E)),await yc(b),b=Math.min(Math.floor(b*1.5),1e4)}D=!0;let I=De.splice(0);for(let E of I)await S.send(E).catch(he=>r("flush failed:",String(he)));r(`upstream ready \u2014 stdio \u21C4 ${t.href}`)})(),m){x();let b=y();b&&(h=b,r("session-restore: found prior binding for this session \u2014 will self-recover",`"${b}"`))}else wc&&r("session-restore: disabled via OURS_NO_AUTORESTORE \u2014 pure in-memory binding");await Ie.start(),r("proxy started (stdio transport up)")}function Sc(e){return Array.isArray(e)?e:[e]}var tt=br(),ue=tt.stateDir,J=tt.port,Do=Xo(tt,{generate:!1})?.token??null,qo=()=>Do?{"x-ours-api-token":Do}:{},rt=tt.brokerUrl,Le=$e(ue,"daemon.pid"),je=$e(ue,"daemon.log"),nt=Xd(import.meta.url),d=(...e)=>process.stdout.write(`${e.join(" ")}
46
46
  `),V=(...e)=>process.stderr.write(`${e.join(" ")}
47
- `),Qe="0.5.0";async function Mo(){for(let e of["/version","/state-dir"])try{let t=new AbortController,r=setTimeout(()=>t.abort(),1500),o=await fetch(`http://127.0.0.1:${J}${e}`,{signal:t.signal});if(clearTimeout(r),o.ok){let n=await o.json();if(n&&typeof n.version=="string")return n}}catch{}return null}function Rc(e){if(d(` cli: v${Qe}`),e?.version){let t=e.version!==Qe;d(` daemon: v${e.version}${e.compat?` (compat ${e.compat})`:""}`+(t?` \u26A0 differs from CLI \u2014 \`ours-mcp restart\` to load v${Qe}`:""))}else d(" daemon: version unknown (running build predates /version \u2014 restart to update)")}var hr=e=>new Promise(t=>setTimeout(t,e));function em(){try{let e=parseInt(R.readFileSync(Le,"utf8").trim(),10);return Number.isFinite(e)?e:null}catch{return null}}function Fo(e){try{return process.kill(e,0),!0}catch{return!1}}function Ut(){let e=em();if(e&&Fo(e))return e;if(e)try{R.rmSync(Le,{force:!0})}catch{}return null}function ot(e,t=1e3){return new Promise(r=>{let o=Yd({host:"127.0.0.1",port:e}),n=i=>{o.destroy(),r(i)};o.setTimeout(t),o.once("connect",()=>n(!0)),o.once("timeout",()=>n(!1)),o.once("error",()=>n(!1))})}async function Cc(e,t=3e4){let r=Date.now()+t;for(;Date.now()<r;){if(await ot(e))return!0;await hr(400)}return!1}async function Pc(){let e=Ut();if(e){d(`ours-mcp is already running (pid ${e}, port ${J}).`);return}R.mkdirSync(ue,{recursive:!0});let t=R.openSync(je,"a"),r=Zc(process.execPath,[nt,"serve"],{detached:!0,stdio:["ignore",t,t],env:{...process.env,OURS_TRANSPORT:"http",OURS_PORT:String(J),OURS_BROKER_URL:rt,OURS_STATE_DIR:ue}});r.unref(),r.pid||(V("failed to spawn the daemon."),process.exit(1)),R.writeFileSync(Le,String(r.pid)),d(`starting ours-mcp (pid ${r.pid})\u2026`),await Cc(J)?(d(`ours-mcp is up on http://localhost:${J}/mcp`),d(` broker: ${rt}`),d(` state: ${ue}`),d(` logs: ${je}`)):(V(`daemon started (pid ${r.pid}) but port ${J} did not open within 30s \u2014 check ${je}.`),process.exit(1))}async function tm(){if(!await ot(J)){if(!Ut()){R.mkdirSync(ue,{recursive:!0});let e=R.openSync(je,"a"),t=Zc(process.execPath,[nt,"serve"],{detached:!0,stdio:["ignore",e,e],env:{...process.env,OURS_TRANSPORT:"http",OURS_PORT:String(J),OURS_BROKER_URL:rt,OURS_STATE_DIR:ue}});if(t.unref(),t.pid)try{R.writeFileSync(Le,String(t.pid))}catch{}}await Cc(J)}}async function mr(){let e=Ut();if(!e){d("ours-mcp is not running.");return}d(`stopping ours-mcp (pid ${e})\u2026`);try{process.kill(e,"SIGTERM")}catch(t){V(`failed to signal pid ${e}: ${String(t)}`)}for(let t=0;t<25&&Fo(e);t++)await hr(200);if(Fo(e)){V(`pid ${e} did not exit; sending SIGKILL.`);try{process.kill(e,"SIGKILL")}catch{}}try{R.rmSync(Le,{force:!0})}catch{}d("stopped.")}async function rm(){let e=Ut();if(!e){if(await ot(J)){let o=await Mo();d("ours-mcp: running (no pidfile \u2014 likely a stale process or external launcher)"),d(` url: http://localhost:${J}/mcp (reachable)`),Rc(o);return}d("ours-mcp: stopped"),d(` cli: v${Qe}`),process.exitCode=1;return}let t=await ot(J),r=t?await Mo():null;d("ours-mcp: running"),d(` pid: ${e}`),d(` url: http://localhost:${J}/mcp ${t?"(reachable)":"(port not answering!)"}`),d(` broker: ${rt}`),d(` state: ${ue}`),d(` logs: ${je}`),Rc(r)}async function om(){if(d(`ours-mcp v${Qe}`),await ot(J)){let e=await Mo();e?.version?d(`running daemon: v${e.version}`+(e.version!==Qe?" (differs \u2014 restart to update)":"")):d("running daemon: version unknown (predates /version)")}else d("daemon: not running")}async function nm(){let e=br(),t=Lt();d(`ours-mcp setup \u2014 ${t}`),d("Enter a value, or press Enter to keep the current [bracketed] one."),d("");let r=dr({input:process.stdin,output:process.stdout}),o;try{let p=async(O,y)=>{let x=(await r.question(` ${O} [${y}]: `)).trim();return x===""?y:x},h=await p("broker URL",e.brokerUrl),_=await p("HTTP port",String(e.port)),z=await p("state dir",e.stateDir),m=await p("GC interval (ms)",String(e.gcIntervalMs)),k=await p("proxy auto-starts daemon (true/false)",String(e.autoStart)),P=await p("HTTP visibility (owner=same-user only / shared=cross-user w/ token / open=all local users)",e.apiVisibility),ee=parseInt(_,10);(!Number.isFinite(ee)||ee<=0)&&(V(`invalid port: ${_}`),process.exit(1));let G=parseInt(m,10);(!Number.isFinite(G)||G<=0)&&(V(`invalid GC interval: ${m}`),process.exit(1));let A=k.toLowerCase()==="true"||k==="1",$=P.trim().toLowerCase();st.includes($)||(V(`invalid visibility: ${P} (expected one of ${st.join(", ")})`),process.exit(1)),o={brokerUrl:h,port:ee,stateDir:Ec(z),gcIntervalMs:G,autoStart:A,apiVisibility:$,...e.apiToken?{apiToken:e.apiToken}:{}}}finally{r.close()}Qo(o),d(""),d(`wrote ${t} (mode 0600):`),d(JSON.stringify(o,null,2));let n=["OURS_BROKER_URL","OURS_PORT","OURS_STATE_DIR","OURS_GC_INTERVAL_MS","OURS_AUTOSTART","OURS_API_VISIBILITY","OURS_API_TOKEN"].filter(p=>process.env[p]!==void 0);n.length&&(d(""),d(`note: these env vars are set and OVERRIDE the file at runtime: ${n.join(", ")}`));let i=Ut();if(!i)return;let s=dr({input:process.stdin,output:process.stdout}),c=!1;try{let p=(await s.question(`
47
+ `),Qe="0.7.0";async function Mo(){for(let e of["/version","/state-dir"])try{let t=new AbortController,r=setTimeout(()=>t.abort(),1500),o=await fetch(`http://127.0.0.1:${J}${e}`,{signal:t.signal});if(clearTimeout(r),o.ok){let n=await o.json();if(n&&typeof n.version=="string")return n}}catch{}return null}function Rc(e){if(d(` cli: v${Qe}`),e?.version){let t=e.version!==Qe;d(` daemon: v${e.version}${e.compat?` (compat ${e.compat})`:""}`+(t?` \u26A0 differs from CLI \u2014 \`ours-mcp restart\` to load v${Qe}`:""))}else d(" daemon: version unknown (running build predates /version \u2014 restart to update)")}var hr=e=>new Promise(t=>setTimeout(t,e));function em(){try{let e=parseInt(R.readFileSync(Le,"utf8").trim(),10);return Number.isFinite(e)?e:null}catch{return null}}function Fo(e){try{return process.kill(e,0),!0}catch{return!1}}function Ut(){let e=em();if(e&&Fo(e))return e;if(e)try{R.rmSync(Le,{force:!0})}catch{}return null}function ot(e,t=1e3){return new Promise(r=>{let o=Yd({host:"127.0.0.1",port:e}),n=i=>{o.destroy(),r(i)};o.setTimeout(t),o.once("connect",()=>n(!0)),o.once("timeout",()=>n(!1)),o.once("error",()=>n(!1))})}async function Cc(e,t=3e4){let r=Date.now()+t;for(;Date.now()<r;){if(await ot(e))return!0;await hr(400)}return!1}async function Pc(){let e=Ut();if(e){d(`ours-mcp is already running (pid ${e}, port ${J}).`);return}R.mkdirSync(ue,{recursive:!0});let t=R.openSync(je,"a"),r=Zc(process.execPath,[nt,"serve"],{detached:!0,stdio:["ignore",t,t],env:{...process.env,OURS_TRANSPORT:"http",OURS_PORT:String(J),OURS_BROKER_URL:rt,OURS_STATE_DIR:ue}});r.unref(),r.pid||(V("failed to spawn the daemon."),process.exit(1)),R.writeFileSync(Le,String(r.pid)),d(`starting ours-mcp (pid ${r.pid})\u2026`),await Cc(J)?(d(`ours-mcp is up on http://localhost:${J}/mcp`),d(` broker: ${rt}`),d(` state: ${ue}`),d(` logs: ${je}`)):(V(`daemon started (pid ${r.pid}) but port ${J} did not open within 30s \u2014 check ${je}.`),process.exit(1))}async function tm(){if(!await ot(J)){if(!Ut()){R.mkdirSync(ue,{recursive:!0});let e=R.openSync(je,"a"),t=Zc(process.execPath,[nt,"serve"],{detached:!0,stdio:["ignore",e,e],env:{...process.env,OURS_TRANSPORT:"http",OURS_PORT:String(J),OURS_BROKER_URL:rt,OURS_STATE_DIR:ue}});if(t.unref(),t.pid)try{R.writeFileSync(Le,String(t.pid))}catch{}}await Cc(J)}}async function mr(){let e=Ut();if(!e){d("ours-mcp is not running.");return}d(`stopping ours-mcp (pid ${e})\u2026`);try{process.kill(e,"SIGTERM")}catch(t){V(`failed to signal pid ${e}: ${String(t)}`)}for(let t=0;t<25&&Fo(e);t++)await hr(200);if(Fo(e)){V(`pid ${e} did not exit; sending SIGKILL.`);try{process.kill(e,"SIGKILL")}catch{}}try{R.rmSync(Le,{force:!0})}catch{}d("stopped.")}async function rm(){let e=Ut();if(!e){if(await ot(J)){let o=await Mo();d("ours-mcp: running (no pidfile \u2014 likely a stale process or external launcher)"),d(` url: http://localhost:${J}/mcp (reachable)`),Rc(o);return}d("ours-mcp: stopped"),d(` cli: v${Qe}`),process.exitCode=1;return}let t=await ot(J),r=t?await Mo():null;d("ours-mcp: running"),d(` pid: ${e}`),d(` url: http://localhost:${J}/mcp ${t?"(reachable)":"(port not answering!)"}`),d(` broker: ${rt}`),d(` state: ${ue}`),d(` logs: ${je}`),Rc(r)}async function om(){if(d(`ours-mcp v${Qe}`),await ot(J)){let e=await Mo();e?.version?d(`running daemon: v${e.version}`+(e.version!==Qe?" (differs \u2014 restart to update)":"")):d("running daemon: version unknown (predates /version)")}else d("daemon: not running")}async function nm(){let e=br(),t=Lt();d(`ours-mcp setup \u2014 ${t}`),d("Enter a value, or press Enter to keep the current [bracketed] one."),d("");let r=dr({input:process.stdin,output:process.stdout}),o;try{let p=async(O,y)=>{let x=(await r.question(` ${O} [${y}]: `)).trim();return x===""?y:x},h=await p("broker URL",e.brokerUrl),_=await p("HTTP port",String(e.port)),z=await p("state dir",e.stateDir),m=await p("GC interval (ms)",String(e.gcIntervalMs)),k=await p("proxy auto-starts daemon (true/false)",String(e.autoStart)),P=await p("HTTP visibility (owner=same-user only / shared=cross-user w/ token / open=all local users)",e.apiVisibility),ee=parseInt(_,10);(!Number.isFinite(ee)||ee<=0)&&(V(`invalid port: ${_}`),process.exit(1));let G=parseInt(m,10);(!Number.isFinite(G)||G<=0)&&(V(`invalid GC interval: ${m}`),process.exit(1));let A=k.toLowerCase()==="true"||k==="1",$=P.trim().toLowerCase();st.includes($)||(V(`invalid visibility: ${P} (expected one of ${st.join(", ")})`),process.exit(1)),o={brokerUrl:h,port:ee,stateDir:Ec(z),gcIntervalMs:G,autoStart:A,apiVisibility:$,...e.apiToken?{apiToken:e.apiToken}:{}}}finally{r.close()}Qo(o),d(""),d(`wrote ${t} (mode 0600):`),d(JSON.stringify(o,null,2));let n=["OURS_BROKER_URL","OURS_PORT","OURS_STATE_DIR","OURS_GC_INTERVAL_MS","OURS_AUTOSTART","OURS_API_VISIBILITY","OURS_API_TOKEN"].filter(p=>process.env[p]!==void 0);n.length&&(d(""),d(`note: these env vars are set and OVERRIDE the file at runtime: ${n.join(", ")}`));let i=Ut();if(!i)return;let s=dr({input:process.stdin,output:process.stdout}),c=!1;try{let p=(await s.question(`
48
48
  daemon is running (pid ${i}); restart now to apply? [y/N]: `)).trim().toLowerCase();c=p==="y"||p==="yes"}finally{s.close()}if(!c){d("not restarting \u2014 changes apply on the next `ours-mcp restart`.");return}await mr();let l=fr(process.execPath,[nt,"start"],{stdio:"inherit"});l.status!==0&&process.exit(l.status??1)}function No(e,t,r){return e.includes(r)?{value:!1,set:!0}:e.includes(t)?{value:!0,set:!0}:{value:void 0,set:!1}}function jo(e,t){let r=e.indexOf(t);return r>=0&&r+1<e.length?e[r+1]:void 0}async function im(e){let t=jo(e,"--name"),r=No(e,"--force-bind","--no-force-bind"),o=No(e,"--local-book","--no-local-book"),n=No(e,"--auto-accept-local","--no-auto-accept-local"),i=e.includes("--overwrite"),s=e.includes("--print"),c=jo(e,"--path")??jo(e,"--dir")??process.cwd(),l=t!==void 0||r.set||o.set||n.set||s,p;if(l?((!t||!t.trim())&&(V("define-local-identity-file: --name is required in non-interactive mode."),process.exit(1)),p={name:t.trim(),force:r.value??!1,exposeLocal:o.value??!0,localAutoAccept:n.value??!0}):p=await sm(),s){d(JSON.stringify(Dt(p),null,2));return}let h=wr(c);if(!i&&R.existsSync(h)){l&&(V(`define-local-identity-file: ${h} already exists \u2014 pass --overwrite to replace it.`),process.exit(1));let z=dr({input:process.stdin,output:process.stdout}),m=!1;try{let k=(await z.question(`
49
49
  ${h} already exists \u2014 overwrite? [y/N]: `)).trim().toLowerCase();m=k==="y"||k==="yes"}finally{z.close()}if(!m){d("aborted \u2014 nothing written.");return}}let _=en(c,p,!0);d(""),d(`wrote ${_}:`),d(JSON.stringify(Dt(p),null,2))}async function sm(){d("ours-mcp define-local-identity-file \u2014 interactive"),d(`Answer the prompts; the result is written to ${$e(process.cwd(),Nt)}.`),d("");let e=dr({input:process.stdin,output:process.stdout});try{let t=async(s,c)=>{let l=c?"Y/n":"y/N",p=(await e.question(` ${s} [${l}]: `)).trim().toLowerCase();return p===""?c:p==="y"||p==="yes"},r="";for(;!r;)r=(await e.question(" Identity name: ")).trim(),r||d(" (name is required)");let o=await t("Force-bind (pin pre-authorizes evicting another session)?",!1),n=await t("Add to the host-local contact book?",!0),i=await t("Auto-accept local invites/introductions?",!0);return{name:r,force:o,exposeLocal:n,localAutoAccept:i}}finally{e.close()}}function Ac(e,t){t.event==="local_contact_request"?d(`[${e}] pending local introduction from ${t.from??"?"} \u2014 respond_to_introduction to approve/reject`):t.event==="pending_message"?d(`[${e}] ${t.from??"?"} queued a message awaiting introduction approval (${t.queued??"?"} queued)`):d(`[${e}] new message from ${t.from??"?"}`+(t.msg_id!==void 0?` (#${t.msg_id})`:"")+(t.date?` (${t.date})`:""))}function Pe(e){V(`ours-mcp watch: ${e}`),process.exit(1)}async function am(){try{let e=new AbortController,t=setTimeout(()=>e.abort(),1500),r=await fetch(`http://127.0.0.1:${J}/state-dir`,{signal:e.signal});if(clearTimeout(t),r.ok){let o=await r.json();return typeof o.stateDir=="string"&&o.stateDir?Ec(o.stateDir):ue}}catch{}return null}var cm=e=>`http://127.0.0.1:${J}/identities/${encodeURIComponent(e)}/notifications`;async function Ic(e){let t=async n=>{let i=new AbortController,s=setTimeout(()=>i.abort(),35e3),c;try{c=await fetch(`${cm(e)}?since=${n}`,{headers:qo(),signal:i.signal})}finally{clearTimeout(s)}if(c.status===401&&Pe(`daemon rejected the API token (401) for identity "${e}". Set OURS_API_TOKEN to the daemon's token (shared mode) or run watch as the daemon owner (owner mode).`),!c.ok)throw new Error(`daemon returned HTTP ${c.status}`);return await c.json()},r=(await t("tip")).cursor??0,o=0;for(;;)try{let n=await t(String(r));if(o=0,Array.isArray(n.events))for(let i of n.events)Ac(e,i);typeof n.cursor=="number"&&(r=n.cursor)}catch(n){o=Math.min(o+1e3,5e3),V(`ours-mcp watch: notifications stream for "${e}" hiccupped (${String(n?.message??n)}), retrying\u2026`),await hr(o)}}async function um(e){if(e){await Ic(e);return}let t=new Set;for(;;){try{let r=await fetch(`http://127.0.0.1:${J}/identities`,{headers:qo()});if(r.status===401&&Pe("daemon rejected the API token (401). Set OURS_API_TOKEN or run watch as the daemon owner."),r.ok){let o=await r.json();for(let n of o.identities??[]){let i=typeof n?.name=="string"?n.name:void 0;i&&!t.has(i)&&(t.add(i),Ic(i))}}}catch{}await hr(3e3)}}var Lo=e=>{let t=e?.code;return t==="EACCES"||t==="EPERM"};function lm(e,t){try{R.readdirSync(e)}catch(s){Pe(`cannot watch \u2014 the daemon API is unreachable AND ${e} is not readable (${s?.code??s}). On a multi-user host, run watch as the daemon owner, or enable the daemon API (start the daemon) so watch can stream over HTTP.`)}if(t)try{R.readdirSync($e(e,t))}catch(s){Pe(`cannot watch identity "${t}" \u2014 ${$e(e,t)} is not readable (${s?.code??s}). Is the daemon running and the name correct?`)}let r=new Map,o=s=>{let c;try{c=R.readdirSync(e,{withFileTypes:!0}).filter(l=>l.isDirectory()).map(l=>l.name)}catch(l){Lo(l)&&Pe(`lost read access to ${e} (${l.code}) \u2014 cannot watch.`);return}for(let l of c){if(t&&l!==t)continue;let p=$e(e,l,"notifications.log"),h;try{h=R.statSync(p).size}catch(m){Lo(m)&&Pe(`cannot read ${p} (${m.code}) \u2014 cannot watch identity "${l}".`);continue}let _=r.get(p);if(_===void 0&&(_=s?h:0,r.set(p,_),s))continue;if(h<=_){h<_&&r.set(p,h);continue}let z;try{let m=R.openSync(p,"r"),k=Buffer.alloc(h-_);R.readSync(m,k,0,k.length,_),R.closeSync(m),z=k.toString("utf8")}catch(m){Lo(m)&&Pe(`cannot read ${p} (${m.code}) \u2014 cannot watch identity "${l}".`);continue}r.set(p,h);for(let m of z.split(`
50
50
  `))if(m.trim())try{Ac(l,JSON.parse(m))}catch{}}};V(`ours-mcp watch: daemon API unreachable \u2014 falling back to file poll of ${e} (Ctrl-C to stop)`),o(!0);let n=setInterval(()=>o(!1),1e3),i=()=>{clearInterval(n),process.exit(0)};process.on("SIGINT",i),process.on("SIGTERM",i)}async function pm(){try{let e=await fetch(`http://127.0.0.1:${J}/identities`,{headers:qo()});return e.status===401&&Pe("daemon rejected the API token (401). Set OURS_API_TOKEN to the daemon's token (shared mode) or run watch as the daemon owner (owner mode)."),e.status===404?"file":e.ok?"api":"file"}catch{return"file"}}async function dm(e){let t=()=>process.exit(0);if(process.on("SIGINT",t),process.on("SIGTERM",t),await am()!==null&&await pm()==="api"){V(`ours-mcp watch: streaming ${e?`identity "${e}"`:"all identities"} from the daemon API on port ${J} (Ctrl-C to stop)`),await um(e);return}lm(ue,e)}var At="ours.service",Uc="solutions.adaptframework.ours";function Nc(){return $e(Oc(),".config","systemd","user",At)}function jc(){return $e(Oc(),"Library","LaunchAgents",`${Uc}.plist`)}function et(e,t){return fr(e,t,{stdio:"inherit"}).status===0}function mm(){let e=Nc();R.mkdirSync(Vo(e),{recursive:!0});let t=`[Unit]
package/dist/index.js CHANGED
@@ -53,7 +53,7 @@ data:
53
53
 
54
54
  `,e.enqueue(r.encode(s)),!0}catch(s){return this.onerror?.(s),!1}}handleUnsupportedRequest(){return this.onerror?.(new Error("Method not allowed.")),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}),{status:405,headers:{Allow:"GET, POST, DELETE","Content-Type":"application/json"}})}async handlePostRequest(e,r){try{let n=e.headers.get("accept");if(!n?.includes("application/json")||!n.includes("text/event-stream"))return this.onerror?.(new Error("Not Acceptable: Client must accept both application/json and text/event-stream")),this.createJsonErrorResponse(406,-32e3,"Not Acceptable: Client must accept both application/json and text/event-stream");let o=e.headers.get("content-type");if(!o||!o.includes("application/json"))return this.onerror?.(new Error("Unsupported Media Type: Content-Type must be application/json")),this.createJsonErrorResponse(415,-32e3,"Unsupported Media Type: Content-Type must be application/json");let s={headers:Object.fromEntries(e.headers.entries()),url:new URL(e.url)},i;if(r?.parsedBody!==void 0)i=r.parsedBody;else try{i=await e.json()}catch{return this.onerror?.(new Error("Parse error: Invalid JSON")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON")}let a;try{Array.isArray(i)?a=i.map(_=>lo.parse(_)):a=[lo.parse(i)]}catch{return this.onerror?.(new Error("Parse error: Invalid JSON-RPC message")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON-RPC message")}let c=a.some(fo);if(c){if(this._initialized&&this.sessionId!==void 0)return this.onerror?.(new Error("Invalid Request: Server already initialized")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Server already initialized");if(a.length>1)return this.onerror?.(new Error("Invalid Request: Only one initialization request is allowed")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Only one initialization request is allowed");this.sessionId=this.sessionIdGenerator?.(),this._initialized=!0,this.sessionId&&this._onsessioninitialized&&await Promise.resolve(this._onsessioninitialized(this.sessionId))}if(!c){let _=this.validateSession(e);if(_)return _;let b=this.validateProtocolVersion(e);if(b)return b}if(!a.some(er)){for(let _ of a)this.onmessage?.(_,{authInfo:r?.authInfo,requestInfo:s});return new Response(null,{status:202})}let l=crypto.randomUUID(),d=a.find(_=>fo(_)),f=d?d.params.protocolVersion:e.headers.get("mcp-protocol-version")??km;if(this._enableJsonResponse)return new Promise(_=>{this._streamMapping.set(l,{resolveJson:_,cleanup:()=>{this._streamMapping.delete(l)}});for(let b of a)er(b)&&this._requestToStreamMapping.set(b.id,l);for(let b of a)this.onmessage?.(b,{authInfo:r?.authInfo,requestInfo:s})});let m=new TextEncoder,p,h=new ReadableStream({start:_=>{p=_},cancel:()=>{this._streamMapping.delete(l)}}),g={"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"};this.sessionId!==void 0&&(g["mcp-session-id"]=this.sessionId);for(let _ of a)er(_)&&(this._streamMapping.set(l,{controller:p,encoder:m,cleanup:()=>{this._streamMapping.delete(l);try{p.close()}catch{}}}),this._requestToStreamMapping.set(_.id,l));await this.writePrimingEvent(p,m,l,f);for(let _ of a){let b,w;er(_)&&this._eventStore&&f>="2025-11-25"&&(b=()=>{this.closeSSEStream(_.id)},w=()=>{this.closeStandaloneSSEStream()}),this.onmessage?.(_,{authInfo:r?.authInfo,requestInfo:s,closeSSEStream:b,closeStandaloneSSEStream:w})}return new Response(h,{status:200,headers:g})}catch(n){return this.onerror?.(n),this.createJsonErrorResponse(400,-32700,"Parse error",{data:String(n)})}}async handleDeleteRequest(e){let r=this.validateSession(e);if(r)return r;let n=this.validateProtocolVersion(e);return n||(await Promise.resolve(this._onsessionclosed?.(this.sessionId)),await this.close(),new Response(null,{status:200}))}validateSession(e){if(this.sessionIdGenerator===void 0)return;if(!this._initialized)return this.onerror?.(new Error("Bad Request: Server not initialized")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Server not initialized");let r=e.headers.get("mcp-session-id");if(!r)return this.onerror?.(new Error("Bad Request: Mcp-Session-Id header is required")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Mcp-Session-Id header is required");if(r!==this.sessionId)return this.onerror?.(new Error("Session not found")),this.createJsonErrorResponse(404,-32001,"Session not found")}validateProtocolVersion(e){let r=e.headers.get("mcp-protocol-version");if(r!==null&&!mn.includes(r))return this.onerror?.(new Error(`Bad Request: Unsupported protocol version: ${r} (supported versions: ${mn.join(", ")})`)),this.createJsonErrorResponse(400,-32e3,`Bad Request: Unsupported protocol version: ${r} (supported versions: ${mn.join(", ")})`)}async close(){this._streamMapping.forEach(({cleanup:e})=>{e()}),this._streamMapping.clear(),this._requestResponseMap.clear(),this.onclose?.()}closeSSEStream(e){let r=this._requestToStreamMapping.get(e);if(!r)return;let n=this._streamMapping.get(r);n&&n.cleanup()}closeStandaloneSSEStream(){let e=this._streamMapping.get(this._standaloneSseStreamId);e&&e.cleanup()}async send(e,r){let n=r?.relatedRequestId;if((Dt(e)||hn(e))&&(n=e.id),n===void 0){if(Dt(e)||hn(e))throw new Error("Cannot send a response on a standalone SSE stream unless resuming a previous client request");let i;this._eventStore&&(i=await this._eventStore.storeEvent(this._standaloneSseStreamId,e));let a=this._streamMapping.get(this._standaloneSseStreamId);if(a===void 0)return;a.controller&&a.encoder&&this.writeSSEEvent(a.controller,a.encoder,e,i);return}let o=this._requestToStreamMapping.get(n);if(!o)throw new Error(`No connection established for request ID: ${String(n)}`);let s=this._streamMapping.get(o);if(!this._enableJsonResponse&&s?.controller&&s?.encoder){let i;this._eventStore&&(i=await this._eventStore.storeEvent(o,e)),this.writeSSEEvent(s.controller,s.encoder,e,i)}if(Dt(e)||hn(e)){this._requestResponseMap.set(n,e);let i=Array.from(this._requestToStreamMapping.entries()).filter(([c,u])=>u===o).map(([c])=>c);if(i.every(c=>this._requestResponseMap.has(c))){if(!s)throw new Error(`No connection established for request ID: ${String(n)}`);if(this._enableJsonResponse&&s.resolveJson){let c={"Content-Type":"application/json"};this.sessionId!==void 0&&(c["mcp-session-id"]=this.sessionId);let u=i.map(l=>this._requestResponseMap.get(l));u.length===1?s.resolveJson(new Response(JSON.stringify(u[0]),{status:200,headers:c})):s.resolveJson(new Response(JSON.stringify(u),{status:200,headers:c}))}else s.cleanup();for(let c of i)this._requestResponseMap.delete(c),this._requestToStreamMapping.delete(c)}}}};var ea=class{constructor(e={}){this._requestContext=new WeakMap,this._webStandardTransport=new Xi(e),this._requestListener=Qd(async r=>{let n=this._requestContext.get(r);return this._webStandardTransport.handleRequest(r,{authInfo:n?.authInfo,parsedBody:n?.parsedBody})},{overrideGlobalObjects:!1})}get sessionId(){return this._webStandardTransport.sessionId}set onclose(e){this._webStandardTransport.onclose=e}get onclose(){return this._webStandardTransport.onclose}set onerror(e){this._webStandardTransport.onerror=e}get onerror(){return this._webStandardTransport.onerror}set onmessage(e){this._webStandardTransport.onmessage=e}get onmessage(){return this._webStandardTransport.onmessage}async start(){return this._webStandardTransport.start()}async close(){return this._webStandardTransport.close()}async send(e,r){return this._webStandardTransport.send(e,r)}async handleRequest(e,r,n){let o=e.auth;await Qd(async i=>this._webStandardTransport.handleRequest(i,{authInfo:o,parsedBody:n}),{overrideGlobalObjects:!1})(e,r)}closeSSEStream(e){this._webStandardTransport.closeSSEStream(e)}closeStandaloneSSEStream(){this._webStandardTransport.closeStandaloneSSEStream()}};import{resolve as mE,join as Ce,dirname as hE,isAbsolute as gE,basename as yE}from"node:path";import{fileURLToPath as _E}from"node:url";import{randomBytes as nv,randomInt as ov,randomUUID as vE,timingSafeEqual as bE}from"node:crypto";import{createServer as wE}from"node:http";import{brotliCompressSync as $E,brotliDecompressSync as xE}from"node:zlib";import*as j from"node:fs";import{readFile as kE,mkdir as SE,writeFile as zE}from"node:fs/promises";import{adapt_wrapper as RE}from"@adapt-toolkit/sdk/executables";import{PacketWrapperConfigurator as TE}from"@adapt-toolkit/sdk/wrappers";import{object_to_adapt_value as sv}from"@adapt-toolkit/sdk/wrapper";import{AdaptObjectLifetime as _p}from"@adapt-toolkit/sdk/common";import*as nt from"node:fs";import{randomBytes as rE}from"node:crypto";import{homedir as A_}from"node:os";import{resolve as ta,join as Xd,dirname as j_,basename as nE}from"node:path";var Z_=["owner","shared","open"],Vn={brokerUrl:"wss://broker1.ours.network",port:3050,stateDir:ta(A_(),".ours"),gcIntervalMs:36e5,autoStart:!1,apiVisibility:"owner"};function oE(){return process.env.OURS_CONFIG??Xd(A_(),".ours","config.json")}function sE(){let t;try{t=nt.readFileSync(oE(),"utf8")}catch{return{}}let e;try{e=JSON.parse(t)}catch{return{}}let r={};return typeof e.brokerUrl=="string"&&(r.brokerUrl=e.brokerUrl),typeof e.port=="number"&&Number.isFinite(e.port)&&(r.port=e.port),typeof e.stateDir=="string"&&(r.stateDir=ta(e.stateDir)),typeof e.gcIntervalMs=="number"&&Number.isFinite(e.gcIntervalMs)&&(r.gcIntervalMs=e.gcIntervalMs),typeof e.autoStart=="boolean"&&(r.autoStart=e.autoStart),typeof e.apiVisibility=="string"&&Z_.includes(e.apiVisibility)&&(r.apiVisibility=e.apiVisibility),typeof e.apiToken=="string"&&e.apiToken.trim()&&(r.apiToken=e.apiToken.trim()),r}function iE(){let t=process.env.OURS_API_VISIBILITY?.trim().toLowerCase();return t&&Z_.includes(t)?t:void 0}function aE(t){let e=process.env[t];if(e!==void 0)return e==="1"||e.toLowerCase()==="true"}function N_(t){let e=process.env[t];if(e===void 0)return;let r=parseInt(e,10);return Number.isNaN(r)?void 0:r}function M_(){let t=sE();return{brokerUrl:process.env.OURS_BROKER_URL??t.brokerUrl??Vn.brokerUrl,port:N_("OURS_PORT")??t.port??Vn.port,stateDir:ta(process.env.OURS_STATE_DIR??t.stateDir??Vn.stateDir),gcIntervalMs:N_("OURS_GC_INTERVAL_MS")??t.gcIntervalMs??Vn.gcIntervalMs,autoStart:aE("OURS_AUTOSTART")??t.autoStart??Vn.autoStart,apiVisibility:iE()??t.apiVisibility??Vn.apiVisibility,apiToken:process.env.OURS_API_TOKEN?.trim()||t.apiToken}}var cE="daemon-token";function ep(t){return Xd(t.stateDir,cE)}function q_(t){let e=process.env.OURS_API_TOKEN?.trim();return e||t.apiToken?.trim()||void 0}function D_(t,e={}){let r=process.env.OURS_API_TOKEN?.trim();if(r)return{token:r,source:"env"};let n=t.apiToken?.trim();if(n)return{token:n,source:"config"};let o=ep(t);try{let i=nt.readFileSync(o,"utf8").trim();if(i)return{token:i,source:"file"}}catch{}if(!e.generate)return null;let s=rE(32).toString("hex");try{nt.mkdirSync(j_(o),{recursive:!0}),nt.writeFileSync(o,s+`
55
55
  `,{mode:384}),nt.chmodSync(o,384)}catch{}return{token:s,source:"generated"}}var C_=".ours-identity";function tp(t){if(!t.name.trim())throw new Error("identity name must not be empty");let e={identity:t.name.trim()};return t.force&&(e.force=!0),e.expose_local=t.exposeLocal??!0,e.local_auto_accept=t.localAutoAccept??!0,e}function uE(t){let e=ta(t);return nE(e)===C_?e:Xd(e,C_)}function L_(t,e,r=!1){let n=tp(e),o=uE(t);if(!r&&nt.existsSync(o))throw new Error(`${o} already exists \u2014 pass overwrite to replace it`);return nt.mkdirSync(j_(o),{recursive:!0}),nt.writeFileSync(o,JSON.stringify(n,null,2)+`
56
- `),o}import{basename as lE,extname as dE}from"node:path";var pE={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".bmp":"image/bmp",".ico":"image/x-icon",".pdf":"application/pdf",".txt":"text/plain",".md":"text/markdown",".json":"application/json",".csv":"text/csv",".html":"text/html",".xml":"application/xml",".zip":"application/zip",".gz":"application/gzip",".tar":"application/x-tar",".mp3":"audio/mpeg",".wav":"audio/wav",".mp4":"video/mp4",".mov":"video/quicktime"};function V_(t){return pE[dE(t).toLowerCase()]??"application/octet-stream"}function U_(t){let e=lE(t).replace(/[^A-Za-z0-9._-]/g,"_");return e.length?e.slice(0,200):"file"}function fE(t){let{selfVersion:e,daemonVersion:r}=t;return!r||r===e?null:`ours: version mismatch \u2014 this plugin/connector is v${e}, the running daemon is v${r}. Everything still works; for the best experience run matching versions. The daemon is a shared singleton and is never restarted automatically, so when no other session is mid-task run \`ours-mcp stop\` (the next session starts the daemon at the new version) \u2014 or update the lagging side to match. No action is required; this is advisory.`}var es="0.5.0",fr=M_(),Qe=fr.stateDir,ia=fr.brokerUrl,PE=process.env.OURS_TRANSPORT??"http",rp=fr.port,B_=fr.gcIntervalMs,lp=fr.apiVisibility,I=(...t)=>process.stderr.write(`ours: ${t.join(" ")}
56
+ `),o}import{basename as lE,extname as dE}from"node:path";var pE={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".bmp":"image/bmp",".ico":"image/x-icon",".pdf":"application/pdf",".txt":"text/plain",".md":"text/markdown",".json":"application/json",".csv":"text/csv",".html":"text/html",".xml":"application/xml",".zip":"application/zip",".gz":"application/gzip",".tar":"application/x-tar",".mp3":"audio/mpeg",".wav":"audio/wav",".mp4":"video/mp4",".mov":"video/quicktime"};function V_(t){return pE[dE(t).toLowerCase()]??"application/octet-stream"}function U_(t){let e=lE(t).replace(/[^A-Za-z0-9._-]/g,"_");return e.length?e.slice(0,200):"file"}function fE(t){let{selfVersion:e,daemonVersion:r}=t;return!r||r===e?null:`ours: version mismatch \u2014 this plugin/connector is v${e}, the running daemon is v${r}. Everything still works; for the best experience run matching versions. The daemon is a shared singleton and is never restarted automatically, so when no other session is mid-task run \`ours-mcp stop\` (the next session starts the daemon at the new version) \u2014 or update the lagging side to match. No action is required; this is advisory.`}var es="0.7.0",fr=M_(),Qe=fr.stateDir,ia=fr.brokerUrl,PE=process.env.OURS_TRANSPORT??"http",rp=fr.port,B_=fr.gcIntervalMs,lp=fr.apiVisibility,I=(...t)=>process.stderr.write(`ours: ${t.join(" ")}
57
57
  `);function EE(){if(lp==="open")return null;if(lp==="shared"){let t=q_(fr);if(!t)throw new Error(`apiVisibility=shared requires an operator-supplied token so it can be distributed to cross-user agents \u2014 set OURS_API_TOKEN or "apiToken" in config (${ep(fr)} is not used for shared mode). Use apiVisibility=owner for a same-user-only auto-token, or =open to disable auth.`);return t}return D_(fr,{generate:!0}).token}var H_=EE();function IE(t){let e=t.headers["x-ours-api-token"];if(typeof e=="string"&&e)return e;let r=t.headers.authorization;if(typeof r=="string"){let n=/^Bearer\s+(.+)$/i.exec(r.trim());if(n)return n[1]}}function OE(t){if(H_===null)return!0;let e=IE(t);if(!e)return!1;let r=Buffer.from(e),n=Buffer.from(H_);return r.length===n.length&&bE(r,n)}function np(t,e){return OE(t)?!0:(e.writeHead(401,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"unauthorized"})),!1)}var NE=/^[A-Za-z0-9 _.@-]{1,64}$/,aa="contact-book";function dp(t){return NE.test(t)?t==="."||t===".."||t.includes("/")||t.includes("\\")?"invalid name":t===aa?`"${aa}" is reserved for the local contact book`:t==="root.json"||t==="bindings.json"?`"${t}" is reserved for daemon bookkeeping`:null:"name must be 1-64 chars of letters, digits, space, _ . @ or -"}function CE(){let t=hE(_E(import.meta.url)),e=process.env.OURS_UNIT_DIR,r=e?[mE(e)]:[Ce(t,"mufl_code"),Ce(t,"..","mufl_code")];for(let n of r){if(!j.existsSync(n))continue;let o=j.readdirSync(n).find(s=>s.endsWith(".muflo"));if(o){let s=o.slice(0,-6),i=new Uint8Array(j.readFileSync(Ce(n,o)));return{dir:n,hash:s,contents:i}}}throw new Error(`no compiled .muflo packet found (looked in: ${r.join(", ")})`)}var ts,rs,G=new Map,mt=null,pp=null,Re=new Map,la=new Set,kt=new Map;function J_(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch(e){return e.code==="EPERM"}}function iv(t){for(let e of Re.values())if(e.token===t)return e}var G_=()=>Ce(Qe,"bindings.json");function is(){try{j.mkdirSync(Qe,{recursive:!0});let t=`${G_()}.tmp`;j.writeFileSync(t,JSON.stringify({pid:process.pid,bound:[...Re.keys()],holders:[...Re.values()].map(e=>({identity:e.identity,pid:e.pid}))})),j.renameSync(t,G_())}catch(t){I("failed to persist bindings snapshot:",String(t))}}var av=t=>Ce(Qe,t),vp=t=>Ce(t,"identity.key"),Yr=t=>Ce(t,"state_data.bin"),cv=t=>Ce(t,"notifications.log"),K_=t=>Ce(t,"unread.json"),AE=t=>Ce(t.dir,"files");function jE(){return j.existsSync(Qe)?j.readdirSync(Qe,{withFileTypes:!0}).filter(t=>t.isDirectory()&&j.existsSync(vp(Ce(Qe,t.name)))).map(t=>t.name):[]}var os=()=>Ce(Qe,aa),W_=()=>Ce(os(),"registrar.key"),fp=()=>Ce(os(),"book.json");function da(){try{let t=JSON.parse(j.readFileSync(fp(),"utf8"));return t&&typeof t.entries=="object"?t.entries:{}}catch{return{}}}function uv(t){j.mkdirSync(os(),{recursive:!0});let e=`${fp()}.tmp`;j.writeFileSync(e,JSON.stringify({v:1,entries:t},null,2),{mode:384}),j.renameSync(e,fp())}function Fn(t){return Xe(e=>Buffer.from(xe(t,"::actor::export_address_document",e).GetBinary()))}function lv(t){return Xe(e=>Buffer.from(xe(t,"::actor::export_signing_secret",e).Serialize()).toString("hex"))}async function dv(t){if(!mt)throw new Error("registrar is not available");let e=Fn(t),r=await X(async o=>{let s=await U(mt,"::actor::sign_book_entry",{name:t.name,ad:mt.pw.packet.NewBinaryFromBuffer(e).Attach(o)},o);return Buffer.from(s.Reduce("sig").GetBinary()).toString("base64url")}),n=da();n[t.name]={v:1,name:t.name,container_id:t.cid,address_document:e.toString("base64url"),published_at:new Date().toISOString(),registrar_sig:r},uv(n),I(`[${t.name}] published to the local contact book`)}function pv(t){let e=da();t in e&&(delete e[t],uv(e),I(`[${t}] removed from the local contact book`))}async function fv(t){if(!pp)throw new Error("registrar is not available");await X(async e=>{await U(t,"::actor::pin_registrar",{registrar_ad:t.pw.packet.NewBinaryFromBuffer(pp).Attach(e)},e)})}var ca=()=>Ce(Qe,"root.json"),le=null;function ZE(){try{let t=JSON.parse(j.readFileSync(ca(),"utf8"));return typeof t.name=="string"?t.name:null}catch{return null}}function ME(t){j.mkdirSync(Qe,{recursive:!0});let e=`${ca()}.tmp`;j.writeFileSync(e,JSON.stringify({v:1,name:t})),j.renameSync(e,ca())}function mv(){j.rmSync(ca(),{force:!0})}function St(t){return Xe(e=>{let r=xe(t,"::actor::describe_identity",e);return{bio:r.Reduce("bio").Visualize(),persona:r.Reduce("persona").Visualize(),roleId:r.Reduce("role_id").Visualize(),rootCid:r.Reduce("root_cid").Visualize(),rootName:r.Reduce("root_name").Visualize(),monitoringEnabled:r.Reduce("monitoring_enabled").GetBoolean()}})}async function ra(t,e){await X(async r=>{let n=Fn(e),o=await U(t,"::actor::sign_delegation",{role_ad:t.pw.packet.NewBinaryFromBuffer(n).Attach(r),role_id:e.name},r),s=Buffer.from(o.Reduce("cert").GetBinary()),i=await U(t,"::actor::export_root_profile",{},r),a=Buffer.from(i.Reduce("profile").GetBinary()),c=Fn(t);await U(e,"::actor::set_delegation",{cert:e.pw.packet.NewBinaryFromBuffer(s).Attach(r),root_ad:e.pw.packet.NewBinaryFromBuffer(c).Attach(r),root_profile:e.pw.packet.NewBinaryFromBuffer(a).Attach(r)},r)}),I(`[${e.name}] delegated as a role under root "${t.name}"`)}function qE(t,e){if(!le||!G.has(le))return null;let r=G.get(e)??[...G.values()].find(o=>o.cid===e);if(!r||r.name===t.name)return null;let n=o=>o.name===le||St(o).roleId!=="";return n(t)&&n(r)?r:null}async function DE(t,e,r){let n=Fn(e);return await X(async o=>{await U(t,"::actor::connect_sibling",{name:e.name,target_ad:t.pw.packet.NewBinaryFromBuffer(n).Attach(o),text:r},o)}),`"${e.name}" was not a contact yet \u2014 connected as an intra-root sibling (delegation-cert auto-accept) and delivered the message.`}async function LE(t,e,r){if(!mt)throw new Error(`"${e}" is not a contact, and the local contact book is unavailable.`);let n=da(),o=n[e]??Object.values(n).find(c=>c.container_id===e);if(!o)throw new Error(`"${e}" is not a contact and has no local contact-book entry. Use generate_invite/add_contact for remote peers, or list_local_contact_book to see local ones.`);if(o.container_id===t.cid)throw new Error("that contact-book entry is this identity itself.");let s=Buffer.from(o.address_document,"base64url"),i=Buffer.from(o.registrar_sig,"base64url"),a=Fn(t);return await X(async c=>{let u=await U(mt,"::actor::mint_introduction",{joiner_ad:mt.pw.packet.NewBinaryFromBuffer(a).Attach(c),target_ad:mt.pw.packet.NewBinaryFromBuffer(s).Attach(c)},c),l=Buffer.from(u.Reduce("intro").GetBinary());await U(t,"::actor::connect_local",{name:o.name,target_ad:t.pw.packet.NewBinaryFromBuffer(s).Attach(c),intro:t.pw.packet.NewBinaryFromBuffer(l).Attach(c),entry_sig:t.pw.packet.NewBinaryFromBuffer(i).Attach(c),text:r},c)}),`"${o.name}" was not a contact yet \u2014 connected via the local contact book and sent the message with the introduction. If "${o.name}" requires approval for local introductions, delivery completes once they approve.`}function as(t){return Xe(e=>{let r=xe(t,"::a2a_messaging::get_monitoring_status",e),n=xe(t,"::actor::get_monitoring_status",e);return{enabled:r.Reduce("monitored").GetBoolean(),proxyCid:r.Reduce("proxy_cid").Visualize(),proxyPending:r.Reduce("proxy_pending").GetBoolean(),copiesQueued:parseInt(n.Reduce("copies_queued").Visualize(),10)||0,controlQueued:parseInt(n.Reduce("control_queued").Visualize(),10)||0}})}async function ns(t,e,r){await X(async n=>{await U(t,"::a2a_control::send_control",{contact:e,payload:JSON.stringify(r)},n)})}function hv(t){try{return Xe(e=>{let r=xe(t,"::a2a_capabilities::get_manifest",e).Reduce("capabilities");return r.IsNil()?[]:[...r.GetKeys()].map(n=>typeof n=="string"?n:n.Visualize())})}catch{return[]}}function VE(t){let e="",r="",n="",o="",s=[];try{Xe(i=>{let a=xe(t,"::a2a_capabilities::get_manifest",i),c=l=>{let d=a.Reduce(l);return d.IsNil()?"":d.Visualize()};e=c("app_id"),r=c("name"),n=c("description"),o=c("version");let u=a.Reduce("capabilities");u.IsNil()||(s=[...u.GetKeys()].map(l=>typeof l=="string"?l:l.Visualize()))})}catch{}return{app_id:e,name:r,description:n,version:o,capabilities:s,monitoring_status:as(t).proxyCid?"bound":"unbound"}}function UE(t){let e=[];for(let r of G.values()){if(r.name===t.name)continue;let n=St(r);n.rootCid===t.cid&&e.push({name:r.name,cid:r.cid,role_id:n.roleId,bio:n.bio,monitoring:n.monitoringEnabled,capabilities:hv(r)})}return e}function gv(t){try{rs.remove_packet(t.cid)}catch(e){I(`remove_packet(${t.cid}) failed:`,String(e))}G.delete(t.name);try{pv(t.name)}catch(e){I(`failed to unpublish "${t.name}" from the contact book:`,String(e))}Re.has(t.name)&&(Re.delete(t.name),is()),t.name===le&&(le=null,mv());try{j.rmSync(t.dir,{recursive:!0,force:!0})}catch(e){return`deleting ${t.dir} failed: ${String(e)}`}return null}var bp=!0,yv=bp?2:1,FE=6e5,mp=new Map,hp=(t,e)=>`${t}:${e}`;function _v(t,e,r){e&&mp.set(hp(t,e),{response:r,at:Date.now()})}function BE(t,e){if(!e)return;let r=mp.get(hp(t,e));if(r){if(Date.now()-r.at>FE){mp.delete(hp(t,e));return}return r.response}}async function HE(t,e,r){let n=ss(r);if(!n||typeof n!="object")return;let o=n,s=o.result;if(s&&typeof s=="object"&&s.pending===!0)return;let i=String(o.req_id??"");i&&(await ns(t,e,o),_v(e,i,o))}async function JE(t,e,r,n,o,s){let i;try{let d=JSON.parse(o);if(!d||typeof d!="object")throw new Error("not an object");i=d}catch{I(`[${t.name}] dropping unparseable control payload from ${n}`);return}if(i.v===1){i.t==="get_manifest"?await ns(t,r,{v:1,t:"res",id:i.id??null,ok:!0,manifest:{...VE(t),protocol_version:yv}}):await ns(t,r,{v:1,t:"res",id:i.id??null,error:{code:"protocol_upgraded",message:"This host now speaks the ours control-envelope protocol (v2). Refresh / cache-bust the control plane."}});return}let a=String(i.req_id??""),c=BE(r,a);if(c){await ns(t,r,c);return}let u=i.args&&typeof i.args=="object"?i.args:{},l={cap:String(i.cap??""),verb:String(i.verb??""),args:u,req_id:a};await X(async d=>{let f;try{f=await U(t,"::actor::process_control_envelope",{sender_id:e,sender_name:n,envelope:l,date:s},d)}catch(m){I(`[${t.name}] dispatch of "${l.cap}.${l.verb}" from ${n} failed:`,String(m));return}if(await HE(t,r,f),l.cap==="core.monitoring"&&l.verb==="bind")try{let m=ss(f);m&&(m.ok===!0||m.$ok===!0)&&XE(t,r)}catch{}})}async function GE(t){for(;;)if(await X(async r=>{let o=(await U(t,"::actor::get_control_requests",{},r)).Reduce("requests"),s=o.GetKeys();if(s.length===0)return!0;for(let i=0;i<s.length;i++){let a=o.Reduce(i),c=a.Reduce("sender_cid");await JE(t,c,c.Visualize(),a.Reduce("sender_name").Visualize(),a.Reduce("payload").Visualize(),a.Reduce("date"))}return!1}))return}function KE(){return String(ov(0,1e6)).padStart(6,"0")}var Qr=new Map;function pa(t){return[...G.values()].find(e=>e.cid===t)}async function cs(t,e){let r=e.Reduce("target").Visualize(),n=ss(e.Reduce("response"));if(!n||typeof n!="object")return;await ns(t,r,n);let o=String(n.req_id??"");o&&_v(r,o,n)}async function WE(t,e,r,n){try{if(G.has(e)){I(`[${t.name}] host_provision_child("${e}") rejected: name exists (settles via sweep timeout)`);return}let o=await yp(e);await X(async s=>{r&&await U(o,"::a2a_messaging::set_my_bio",{bio:r},s),await ra(t,o);let i=St(o).roleId,a=xe(o,"::actor::export_address_document_native",s),c=await U(t,"::a2a_cluster::register_provisioned_child",{pending_handle:n,role_id:i,child_ad:a},s);await cs(t,c)})}catch(o){I(`[${t.name}] host_provision_child("${e}") failed (settles via sweep timeout):`,String(o))}}async function YE(t,e,r){try{let n=pa(e.Visualize());if(n){let o=gv(n);o&&I(`[${t.name}] host_destroy_child teardown warning:`,o)}Qr.delete(e.Visualize()),await X(async o=>{let s=await U(t,"::a2a_cluster::confirm_child_destroyed",{pending_handle:r,cid:e},o);await cs(t,s)})}catch(n){I(`[${t.name}] host_destroy_child failed (settles via sweep timeout):`,String(n))}}async function QE(t,e,r){try{let n=pa(e.Visualize());if(!n){I(`[${t.name}] host_mint_child_invite: unknown child ${e.Visualize()} (settles via sweep timeout)`);return}await X(async o=>{let s=await U(n,"::a2a_messaging::generate_invite",{},o),i=t.pw.packet.NewBinaryFromBuffer(Buffer.from(s.Reduce("invite").GetBinary())).Attach(o),a=await U(t,"::a2a_cluster::register_child_invite",{pending_handle:r,invite:i},o);await cs(t,a)})}catch(n){I(`[${t.name}] host_mint_child_invite failed (settles via sweep timeout):`,String(n))}}async function gp(t,e,r,n){await X(async o=>{if(e){n&&await U(t,"::a2a_messaging::host_register_monitoring_cp",{cp_ad:n},o);let s=KE();await U(t,"::a2a_messaging::set_proxy_pending",{code:s,proxy:r},o),await U(t,"::a2a_messaging::verify_proxy_code",{code:s,sender:r},o),Qr.set(t.cid,r??"")}else await U(t,"::a2a_messaging::host_clear_child_monitoring",{},o),Qr.delete(t.cid)})}async function Y_(t,e,r,n,o,s){try{let i=pa(e.Visualize());if(!i){I(`[${t.name}] host_set_child_monitoring: unknown child ${e.Visualize()} (settles via sweep timeout)`);return}r?await gp(i,!0,o?.Visualize(),s):await gp(i,!1),await X(async a=>{let c=await U(t,"::a2a_cluster::confirm_child_monitoring",{pending_handle:n,cid:e,enabled:r},a);await cs(t,c)})}catch(i){I(`[${t.name}] host_set_child_monitoring failed (settles via sweep timeout):`,String(i))}}async function XE(t,e){for(let[r,n]of[...Qr.entries()]){if(n===e)continue;let o=pa(r);if(!o){Qr.delete(r);continue}await gp(o,!1).catch(s=>I(`[${t.name}] CP-rebind clear of child ${r} failed:`,String(s)))}}function eI(t,e){let r=[];for(let n of G.values()){if(n.name===t.name)continue;let o=St(n);if(o.rootCid!==t.cid)continue;let s=xe(n,"::actor::export_address_document_native",e);r.push({cid:s.Reduce("identity").Reduce("container_id"),role_id:o.roleId,name:n.name,bio:o.bio,persona:o.persona,caps:hv(n),child_ad:s})}return r}var op=new Set;async function vv(t){if(!op.has(t.name)){op.add(t.name);try{await X(async e=>{await U(t,"::a2a_cluster::reconcile",{pending_handle:"",children:eI(t,e)},e);let n=(await U(t,"::a2a_cluster::sweep_and_settle",{},e)).Reduce("settled"),o=n.GetKeys();for(let s=0;s<o.length;s++)await cs(t,n.Reduce(s))})}catch(e){I(`[${t.name}] cluster sweep failed:`,String(e))}finally{op.delete(t.name)}}}var tI=6e4;function rI(){setInterval(()=>{if(bp)for(let t of G.values())St(t).roleId===""&&vv(t)},tI).unref()}function nI(){for(let t of G.values())if(St(t).roleId!=="")try{let e=as(t).proxyCid;e&&Qr.set(t.cid,e)}catch(e){Qr.set(t.cid,""),I(`[${t.name}] monitoredChildren rebuild read failed (added clear-on-repoint):`,String(e))}}var sp=new Set;async function wp(t){if(!sp.has(t.name)){sp.add(t.name);try{await GE(t)}catch(e){I(`[${t.name}] control dispatch failed:`,String(e))}finally{sp.delete(t.name)}if(G.has(t.name)&&as(t).controlQueued>0)return wp(t)}}async function oI(){j.mkdirSync(os(),{recursive:!0});let t;try{t=j.readFileSync(W_(),"utf8").trim()}catch{}let e=nv(24).toString("hex");mt=await $p(aa,e,os(),!1,t),t||j.writeFileSync(W_(),lv(mt),{mode:384}),pp=Fn(mt),I(`contact-book registrar ready (${mt.cid})`)}function sI(t){try{return j.existsSync(Yr(t))&&j.statSync(Yr(t)).size>0}catch{return!1}}function ua(t){try{let e=Xe(n=>Buffer.from(xe(t,"::actor::export_state",n).Serialize()));j.mkdirSync(t.dir,{recursive:!0});let r=`${Yr(t.dir)}.tmp`;j.writeFileSync(r,e),j.renameSync(r,Yr(t.dir))}catch(e){I(`[${t.name}] failed to save state:`,String(e))}}function iI(t){let e=[],r=t.Reduce("degraded");if(r.IsNil())return e;for(let n=0;;n++){let o=r.Reduce(n);if(o.IsNil())break;e.push({cid:o.Reduce("container_id").Visualize(),name:o.Reduce("name").Visualize(),attempts:Number(o.Reduce("attempts").Visualize()),queued:Number(o.Reduce("queued").Visualize())})}return e}function aI(t){let e=[],r=t.Reduce("queues");if(r.IsNil())return e;for(let n=0;;n++){let o=r.Reduce(n);if(o.IsNil())break;e.push({cid:o.Reduce("container_id").Visualize(),queued:Number(o.Reduce("queued").Visualize()),degraded:o.Reduce("degraded").GetBoolean()})}return e}async function bv(t,e){try{let r=await X(async n=>{let o=await U(t,"::a2a_messaging::flush_deferred",{contact:e},n);return Number(o.Reduce("flushed").Visualize())});r>0&&I(`[${t.name}] flushed ${r} deferred message(s) to ${e.slice(0,12)}\u2026`)}catch(r){I(`[${t.name}] deferred flush to ${e.slice(0,12)}\u2026 failed:`,String(r))}}async function wv(t){try{let e=await X(async n=>{let o=await U(t,"::a2a_messaging::restore_degraded_contacts",{},n);return Number(o.Reduce("requested").Visualize())});e>0&&I(`[${t.name}] contact restore requested for ${e} degraded contact(s)`);let r=Xe(n=>aI(xe(t,"::a2a_messaging::list_deferred_queues",n)));for(let n of r)n.degraded||await bv(t,n.cid)}catch(e){I(`[${t.name}] contact-restore sweep failed:`,String(e))}}var na=new Map;function cI(t){let e=na.get(t);if(!(!e||e.size===0))for(let r of[...e])try{r()}catch{}}function uI(t,e){return new Promise(r=>{let n=na.get(t);n||(n=new Set,na.set(t,n));let o=!1,s=()=>{o||(o=!0,n.delete(i),n.size===0&&na.delete(t),clearTimeout(a),r())},i=s,a=setTimeout(s,e);n.add(i)})}function pr(t,e){try{j.mkdirSync(t.dir,{recursive:!0}),j.appendFileSync(cv(t.dir),JSON.stringify(e)+`
58
58
  `)}catch(r){I(`[${t.name}] failed to append notifications.log:`,String(r))}cI(t.name)}var lI=Number(process.env.OURS_NOTIFY_LONGPOLL_MS)>0?Number(process.env.OURS_NOTIFY_LONGPOLL_MS):25e3,dI=250;function ip(t){try{return j.statSync(t).size}catch{return 0}}function pI(t,e,r){if(r<=e)return{events:[],cursor:e};let n=Buffer.alloc(r-e),o=0;try{let c=j.openSync(t,"r");try{o=j.readSync(c,n,0,n.length,e)}finally{j.closeSync(c)}}catch{return{events:[],cursor:e}}let s=n.subarray(0,o),i=s.lastIndexOf(10);if(i===-1)return{events:[],cursor:e};let a=[];for(let c of s.subarray(0,i+1).toString("utf8").split(`
59
59
  `))if(c.trim())try{a.push(JSON.parse(c))}catch{}return{events:a,cursor:e+i+1}}async function fI(t,e,r,n){let o=cv(Ce(Qe,r)),s=(u,l)=>{e.writableEnded||(e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify({cursor:u,events:l})))};if(n===null||n==="tip"){s(ip(o),[]);return}let i=parseInt(n,10);if(!Number.isFinite(i)||i<0){e.writableEnded||(e.writeHead(400,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"invalid since cursor"})));return}let a=!1;t.on("close",()=>{a=!0});let c=Date.now()+lI;for(;!a;){let u=ip(o);if(i>u&&(i=0),u>i){let{events:l,cursor:d}=pI(o,i,u);if(l.length>0){s(d,l);return}i=d}if(Date.now()>=c)break;await uI(r,Math.min(dI,c-Date.now()))}a||s(ip(o),[])}function Wr(t){try{let{unread:e,unreadFiles:r}=Xe(s=>{let a=sa(xe(t,"::actor::list_incoming_messages",s)).filter(l=>l.status==="unread"),c=xe(t,"::actor::list_incoming_files",s),u=[];if(!c.IsNil())for(let l=0;;l++){let d=c.Reduce(l);if(d.IsNil())break;d.Reduce("status").Visualize()==="unread"&&u.push({file_id:d.Reduce("file_id").Visualize(),from:d.Reduce("sender_name").Visualize(),filename:d.Reduce("filename").Visualize(),mime:d.Reduce("mime").Visualize(),wire_id:d.Reduce("wire_id").Visualize()})}return{unread:a,unreadFiles:u}}),n={count:e.length,recent:e.slice(-10).map(s=>({from:s.sender_name,msg_id:s.msg_id,date:s.date})),files:r.length,unread_files:r.slice(-10)};j.mkdirSync(t.dir,{recursive:!0});let o=`${K_(t.dir)}.tmp`;j.writeFileSync(o,JSON.stringify(n)),j.renameSync(o,K_(t.dir))}catch(e){I(`[${t.name}] failed to refresh unread snapshot:`,String(e))}}var oa=new Map,$v=t=>`ours://inbox/${encodeURIComponent(t)}`;function dr(t,e){I(`[${t}] notify:`,e);let r=Re.get(t)?.sid;if(!r)return;let n=oa.get(r);if(n){try{n.sendLoggingMessage({level:"info",logger:"ours",data:e})}catch(o){I("sendLoggingMessage failed:",String(o))}try{n.server.sendResourceUpdated({uri:$v(t)})}catch{}}}function Xe(t){let e=new _p;try{return t(e)}finally{e.Finalize()}}async function X(t){let e=new _p;try{return await t(e)}finally{e.Finalize()}}function xe(t,e,r){let n=sv({name:e,targ:void 0}),o=t.pw.packet.ExecuteTransaction(n);return n.Destroy(),r?o.Attach(r):o}async function mI(t,e){let r=t.lock,n;t.lock=new Promise(o=>n=o),await r;try{return await e()}finally{n()}}function hI(t,e,r=25e3){return new Promise((n,o)=>{let s=setTimeout(()=>{let i=t.pending.findIndex(a=>a.timer===s);i>=0&&t.pending.splice(i,1),o(new Error("timed out waiting for the transaction result"))},r);t.pending.push({resolve:n,reject:o,timer:s}),t.pw.add_client_message(e)})}function U(t,e,r,n,o){let s=sv({name:e,targ:r});return mI(t,()=>hI(t,s,o)).then(i=>(s.Destroy(),n?i.Attach(n):i),i=>{try{s.Destroy()}catch{}throw i})}function gI(t){t.pw.on_return_data=e=>{let r=new _p;e.Attach(r);try{let n=e.Reduce("kind").Visualize();if(n==="save_state"){ua(t);return}if(n==="notify_agent"){let s=e.Reduce("payload"),i=s.Reduce("event").Visualize();if(i==="message_received"){let a=s.Reduce("sender_name").Visualize(),c=s.Reduce("msg_id").Visualize(),u=s.Reduce("date").Visualize();pr(t,{event:"message_received",from:a,msg_id:c,date:u}),Wr(t),process.nextTick(()=>dr(t.name,`[${t.name}] new message from ${a} (#${c})`))}else if(i==="file_received"){let a=s.Reduce("sender_name").Visualize(),c=s.Reduce("file_id").Visualize(),u=s.Reduce("filename").Visualize(),l=s.Reduce("mime").Visualize(),d=s.Reduce("bytes").Visualize(),f=s.Reduce("date").Visualize();pr(t,{event:"file_received",from:a,file_id:c,filename:u,mime:l,bytes:d,date:f}),Wr(t),process.nextTick(()=>dr(t.name,`[${t.name}] new file ${u} (${d} B) from ${a} (#${c})`))}else if(i==="contact_accepted"){let a=s.Reduce("name").Visualize(),c=s.Reduce("container_id").Visualize();process.nextTick(()=>dr(t.name,`[${t.name}] contact "${a}" (${c}) accepted your invite.`))}else if(i==="local_contact_added"){let a=s.Reduce("name").Visualize(),c=s.Reduce("container_id").Visualize();process.nextTick(()=>dr(t.name,`[${t.name}] local contact "${a}" (${c}) connected via the contact book.`))}else if(i==="sibling_contact_added"){let a=s.Reduce("name").Visualize(),c=s.Reduce("container_id").Visualize();pr(t,{event:"sibling_contact_added",from:a}),process.nextTick(()=>dr(t.name,`[${t.name}] sibling "${a}" (${c}) connected (intra-root auto-accept).`))}else if(i==="local_contact_request"){let a=s.Reduce("name").Visualize(),c=s.Reduce("container_id").Visualize();pr(t,{event:"local_contact_request",from:a}),process.nextTick(()=>dr(t.name,`[${t.name}] pending local introduction from "${a}" (${c}) \u2014 approve or reject with respond_to_introduction.`))}else if(i==="pending_message"){let a=s.Reduce("sender_name").Visualize(),c=s.Reduce("queued").Visualize();pr(t,{event:"pending_message",from:a,queued:c}),process.nextTick(()=>dr(t.name,`[${t.name}] "${a}" queued a message awaiting introduction approval (${c} queued).`))}else if(i==="contact_restored"){let a=s.Reduce("name").Visualize(),c=s.Reduce("container_id").Visualize();pr(t,{event:"contact_restored",from:a}),I(`[${t.name}] contact "${a}" restored (re-keyed)`),process.nextTick(()=>void bv(t,String(c)))}else if(i==="control_request"){let a=s.Reduce("sender_name").Visualize();I(`[${t.name}] control request queued by ${a}`),process.nextTick(()=>void wp(t))}else if(i==="host_provision_child"){let a=s.Reduce("name").Visualize(),c=s.Reduce("bio").Visualize(),u=s.Reduce("pending_handle").Visualize();process.nextTick(()=>void WE(t,a,c,u))}else if(i==="host_destroy_child"){let a=s.Reduce("cid").Detach(),c=s.Reduce("pending_handle").Visualize();process.nextTick(()=>void YE(t,a,c).finally(()=>a.Destroy()))}else if(i==="host_mint_child_invite"){let a=s.Reduce("cid").Detach(),c=s.Reduce("pending_handle").Visualize();process.nextTick(()=>void QE(t,a,c).finally(()=>a.Destroy()))}else if(i==="host_set_child_monitoring"){let a=s.Reduce("cid").Detach(),c=s.Reduce("enabled").GetBoolean(),u=s.Reduce("pending_handle").Visualize();if(c){let l=s.Reduce("cp_cid").Detach(),d=s.Reduce("cp_ad").Detach();process.nextTick(()=>void Y_(t,a,!0,u,l,d).finally(()=>{a.Destroy(),l.Destroy(),d.Destroy()}))}else process.nextTick(()=>void Y_(t,a,!1,u).finally(()=>a.Destroy()))}return}let o=t.pending.shift();if(!o)return;clearTimeout(o.timer),o.resolve(e.Reduce("payload").Detach())}finally{r.Finalize()}},t.pw.on_transaction_failure=e=>{let r=t.pending.shift();r?(clearTimeout(r.timer),r.reject(new Error(e))):(I(`[${t.name}] inbound transaction rejected:`,e),pr(t,{event:"inbound_error",message:e}),process.nextTick(()=>dr(t.name,`[${t.name}] inbound transaction rejected: ${e}`)))}}function $p(t,e,r,n=!0,o){let s=new TE,i=["--unit_hash",ts.hash,"--seed_phrase",e,"--unit_dir_path",ts.dir];return o&&i.push("--init_trn_argument",JSON.stringify(o)),s.process_arguments(i),new Promise((a,c)=>{let u=setTimeout(()=>c(new Error(`packet creation for "${t}" timed out`)),3e4);rs.packet_manager.create_packet(s,l=>{clearTimeout(u);let d={name:t,cid:Xe(f=>l.packet.GetContainerID().Attach(f).Visualize()),pw:l,dir:r,pending:[],lock:Promise.resolve()};gI(d),n&&G.set(t,d),I(`[${t}] packet created \u2014 container id ${d.cid}`),a(d)},ts.contents)})}async function yp(t,e={exposeLocal:!0,localAutoAccept:!0}){let r=av(t);j.mkdirSync(r,{recursive:!0});let n=nv(24).toString("hex"),o=await $p(t,n,r);return j.writeFileSync(vp(r),lv(o),{mode:384}),await X(async s=>{await U(o,"::a2a_messaging::set_my_name",{name:t},s)}),await fv(o),e.localAutoAccept||await X(async s=>{await U(o,"::actor::set_local_policy",{auto_accept:!1},s)}),e.exposeLocal&&await dv(o),ua(o),o}async function yI(t){let e=av(t),r=j.readFileSync(vp(e),"utf8").trim(),n=await $p(t,"",e,!0,r);if(sI(e))try{let o=j.readFileSync(Yr(e));await X(async s=>{let i=n.pw.packet.ParseValue(new Uint8Array(o)).Attach(s);await U(n,"::actor::import_state",i,s)})}catch(o){I(`[${t}] FAILED TO IMPORT SAVED STATE \u2014 continuing with the reseeded identity; surviving contacts (if the blob was partially migrated) self-heal via contact restore:`,String(o)),pr(n,{event:"state_import_failed",error:String(o).slice(0,300)});try{j.renameSync(Yr(e),`${Yr(e)}.failed-${Date.now()}`),I(`[${t}] unreadable state blob preserved as state_data.bin.failed-*`)}catch{}}return await wv(n),Wr(n),n}async function Q_(){ts=CE();let t=["--broker_address",ia,"--test_mode","--logger_config","--level","INFO","--stdout","stderr","--logger_config_end"];I(`booting wrapper (unit ${ts.hash.slice(0,12)}\u2026, broker ${ia})`),rs=await RE.start(t),rs.on_packet_created_cb=n=>I(`wrapper: packet ready ${n.slice(0,12)}\u2026`),rs.start();try{await oI()}catch(n){I("failed to start the contact-book registrar (local contact book disabled):",String(n))}let e=jE();if(e.length===0)I("no persisted identities \u2014 start with create_identity");else{I(`restoring ${e.length} identit${e.length===1?"y":"ies"}: ${e.join(", ")}`);for(let n of e)try{let o=await yI(n);mt&&await fv(o)}catch(o){I(`failed to restore "${n}":`,String(o))}}nI(),rI(),le=ZE(),le&&!G.has(le)&&(I(`root marker names a missing identity "${le}" \u2014 clearing it`),le=null,mv()),le&&I(`root identity: ${le}`);let r=le?G.get(le):void 0;if(r)try{as(r).controlQueued>0&&wp(r)}catch(n){I("boot-time monitoring/control drain failed:",String(n))}is()}function X_(t){let e=kt.get(t)?.token;if(!e)return{error:"No identity bound to this session. Call choose_identity (or create_identity) first."};if(la.has(e))return{error:"Your identity binding was reassigned to another session. Call choose_identity again to continue."};let r=iv(e);if(!r)return{error:"No identity bound to this session. Call choose_identity (or create_identity) first."};let n=G.get(r.identity);if(!n)return Re.delete(r.identity),is(),{error:`The bound identity "${r.identity}" no longer exists. Choose another with choose_identity.`};r.sid=t;let o=kt.get(t)?.pid;return o&&(r.pid=o),{id:n}}function ap(t,e){let r=kt.get(t),n=r?.token;if(!n)return;for(let[s,i]of[...Re])i.token===n&&s!==e&&Re.delete(s);let o=Re.get(e)?.epoch??0;Re.set(e,{identity:e,token:n,pid:r?.pid??0,sid:t,epoch:o+1,boundAt:Date.now()}),la.delete(n),is()}function _I(t){let e=[];if(t.IsNil())return e;for(let r of t.GetKeys()){let n=t.Reduce(r);n.IsNil()||e.push({name:n.Reduce("name").Visualize(),container_id:n.Reduce("container_id").Visualize()})}return e}function sa(t){let e=[];if(t.IsNil())return e;for(let r=0;;r++){let n=t.Reduce(r);if(n.IsNil())break;let o=n.Reduce("reply_to"),s=null;if(!o.IsNil()){s={wire_id:o.Reduce("wire_id").Visualize()};let i=o.Reduce("sentence");i.IsNil()||(s.sentence=parseInt(i.Visualize(),10))}e.push({msg_id:parseInt(n.Reduce("msg_id").Visualize(),10),sender_id:n.Reduce("sender_id").Visualize(),sender_name:n.Reduce("sender_name").Visualize(),text:n.Reduce("text").Visualize(),date:n.Reduce("date").Visualize(),status:n.Reduce("status").Visualize(),wire_id:n.Reduce("wire_id").Visualize(),reply_to:s})}return e}function vI(t){if(t.IsNil())return"No files received.";let e=[];for(let r=0;;r++){let n=t.Reduce(r);if(n.IsNil())break;let o=n.Reduce("filename").Visualize(),s=n.Reduce("mime").Visualize(),i=n.Reduce("sender_name").Visualize(),a=n.Reduce("status").Visualize(),c=n.Reduce("wire_id").Visualize();e.push(` \u2022 ${o} (${s||"application/octet-stream"}) from ${i} [${a}] {${c}}`)}return e.length===0?"No files received.":`${e.length} file(s):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/mcp",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "MCP server daemon for ours — one native ADAPT wrapper hosting N self-sovereign identities, exposing secure agent-to-agent messaging tools over HTTP (Streamable HTTP). Run `ours-mcp start`.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",