@synadia-ai/agent-fabric-pi 0.2.0 → 0.3.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/BUILD +3 -3
- package/README.md +4 -1
- package/dist/chunk-9jcwbjk5.js +37 -0
- package/dist/fabric.js +4 -4
- package/dist/nats-channel.js +4 -4
- package/package.json +1 -1
- package/skill/scratchpad/SKILL.md +87 -6
- package/skill/scratchpad/scripts/sp +13 -7
- package/dist/chunk-sjpe67s3.js +0 -37
package/dist/fabric.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as Ke,b as Jt,d as Wt,e as Ze,g as Qe,h as de,t as et,u as ee}from"./chunk-9jcwbjk5.js";import{AsyncLocalStorage as Yt}from"node:async_hooks";var Kt=Ke(Jt(),1),dr=Ke(Wt(),1);import{execFile as Zt}from"node:child_process";import{createHash as tt,randomUUID as je}from"node:crypto";import{mkdir as Qt,realpath as er}from"node:fs/promises";import{tmpdir as tr,platform as Pe,arch as qe,homedir as Le}from"node:os";import{join as le,resolve as $e}from"node:path";import{mkdirSync as rr,readFileSync as nr,writeFileSync as or,renameSync as ir,openSync as ar,constants as fe,fstatSync as sr,readSync as cr,closeSync as ur,lstatSync as wo,realpathSync as Eo,fsyncSync as Ao}from"node:fs";var lr=1,rt="TRACE.edges",nt="thread_id",ot="root_id",fr="X-Synadia-Thread-ID",hr="X-Synadia-Root-ID",pr=/[\u0000-\u0020\u007f\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/;function gr(e){if(e===void 0)return;let t=e.edgeSubject;if(t===void 0||t===null)return;let r=(n)=>{throw new Ze(`trace.edgeSubject ${JSON.stringify(t)}: ${n}`)};if(typeof t!=="string")r("must be a string or null");if(t.length===0)r("must not be empty");for(let n of t.split(".")){if(n.length===0)r("must not contain an empty token");if(pr.test(n))r("must not contain whitespace or control characters");if(n.includes("*")||n.includes(">"))r("must not contain wildcards")}}var mr=Symbol.for("@synadia-ai/agent-fabric:trace-record-counts"),oe=(()=>{let e=globalThis;return e[mr]??={published:0,dropped:0}})();function Dr(){oe.published+=1}function Me(){oe.dropped+=1}function vr(){return Object.freeze({published:oe.published,dropped:oe.dropped})}var yr=Symbol.for("@synadia-ai/agent-fabric:trace-scope"),it=(()=>{let e=globalThis;return e[yr]??=new Yt})();function re(e,t){return it.run(e,t)}function H(){return it.getStore()}function at(){let e=H();if(e===void 0)return{};return e.turnCountHint+=1,{[fr]:e.threadId,[hr]:e.rootId}}var be=32,Fr=new RegExp(`^[0-9a-f]{${be}}$`);function me(e){return Fr.test(e)}function we(){let e=new Uint8Array(be/2);crypto.getRandomValues(e);let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}function Ee(){let e=we();return{threadId:e,rootId:e,turnCountHint:0}}var br=256,wr=/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;function Ae(e){if(wr.test(e))return!1;let t=Array.from(e).length;return t>0&&t<=br}function Er(e,t,r,n,o,i){let a=we(),s={version:lr,kind:"edge",record_id:a,ts:Math.floor(Date.now()/1000),agent:e,thread_id:t,parent_id:r,root_id:n,tool_call_id:o,turn_count_hint:i};return{recordId:a,payload:new TextEncoder().encode(JSON.stringify(s))}}var Ar="toolCallId";function st(e={}){gr(e);let t=e.edgeSubject===void 0?rt:e.edgeSubject;return{promptInterceptor:_r(t),requestInterceptor:Br,heartbeatExtras:t===null?()=>({}):()=>{let r=vr();return{records_published:r.published,records_dropped:r.dropped}}}}function _r(e){return{beforePrompt(t){let r=t.context[Ar],n=typeof r==="string"&&Ae(r)?r:null,o={...Cr(),toolCallId:n};return{fields:{[nt]:o.threadId,[ot]:o.rootId},state:o}},async beforePublish(t,r){let n=r?.state;if(e===null||n===void 0)return;await Sr(t,e,n)}}}function Cr(){let e=we(),t=H();if(t===void 0)return{threadId:e,parentId:null,rootId:e,turnCountHint:0};return{threadId:e,parentId:t.threadId,rootId:t.rootId,turnCountHint:t.turnCountHint}}async function Sr(e,t,r){if(!e.identity.canSign){Rr(e.connection),Me();return}try{let n=await e.identity.selfId(),o=Er(n,r.threadId,r.parentId,r.rootId,r.toolCallId,r.turnCountHint);await e.identity.publishSigned(t,o.payload,{nonce:o.recordId}),Dr()}catch(n){Me(),console.warn(`@synadia-ai/agent-fabric: failed to publish edge record on ${t}`,n)}}var Ue=new WeakSet;function Rr(e){if(Ue.has(e))return;Ue.add(e),console.warn("@synadia-ai/agent-fabric: tracing is enabled but no identity signer is configured; edge records are not published (consumers ignore unsigned records). Pass identity: { signer } to sign them.")}var Br={async aroundRequest(e,t){await re(xr(e.envelope.extras??{}),t)}},kr="envelope `thread_id` and `root_id` must be given together";function xr(e){let t=He(e,nt),r=He(e,ot);if(t===void 0!==(r===void 0))throw new ee(400,kr);if(t!==void 0&&r!==void 0)return{threadId:t,rootId:r,turnCountHint:0};return Ee()}function He(e,t){let r=Object.hasOwn(e,t)?e[t]:void 0;if(r===void 0||r===null)return;if(typeof r!=="string")throw new ee(400,`envelope \`${t}\` must be a string`);if(r==="")return;if(!me(r))throw new ee(400,`envelope \`${t}\` must be ${be} lowercase hex characters`);return r}var Tr=class extends Error{constructor(e,t){super(t);this.reason=e,this.name="FabricCallerError"}reason},_o=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get subject(){return this.#e.subject}cancel(){this.#t.reject(Ve("it was cancelled")),this.#e.cancel()}async*[Symbol.asyncIterator](){try{for await(let e of this.#e)yield e}catch(e){throw this.#t.reject(e),e}finally{this.#t.reject(Ve("its stream ended first"))}}};function Ve(e){return new Tr("not-sent",`the prompt never went out, so it has no root: ${e}`)}var ie="sp-ref:";var ct=/sp-(?:ref|r1):[A-Za-z0-9_-]+/g,_e="scratchpad_refs_ok";function ae(e){return e.match(ct)??[]}function Ge(e,t){return e.replace(ct,(r)=>t===void 0||t.includes(r)?"":r).replace(/[ \t]+$/gm,"").replace(/\n{3,}/g,`
|
|
2
2
|
|
|
3
|
-
`).trim()}function fr(e){if(!e.startsWith(Q))return;let t;try{t=JSON.parse(Buffer.from(e.slice(Q.length),"base64url").toString("utf8"))}catch{return}if(typeof t!=="object"||t===null)return;let r=t.creator;return typeof r==="string"&&r!==""?r:void 0}function de(e){return e[De]==="true"}function z(e){let t=e.indexOf(".");if(t<=0||t===e.length-1)throw Error(`not an agent identity: ${e}`);return{account:e.slice(0,t),user:e.slice(t+1)}}var Ze="sp-grant",hr=1e4,se="agents.prompt.",pr=`agents.${Ze}.`;function Qe(e){if(!e.startsWith(se)||e===se)throw Error(`not a prompt address: ${e}`);return pr+e.slice(se.length)}function Dr(e){let{trace:t}=e;return JSON.stringify({reference:e.reference,grantee:e.grantee,...t!==void 0?{trace:{thread_id:t.thread_id,root_id:t.root_id,...t.tool_call_id!==void 0?{tool_call_id:t.tool_call_id}:{}}}:{}})}function gr(e){return JSON.stringify(e.granted?{granted:!0}:{granted:!1,reason:e.reason})}async function mr(e,t,r,n={}){let o;try{let s=await e.requestSigned(Qe(t),Dr(r),{timeoutMs:n.timeoutMs??hr});o=JSON.parse(s.string())}catch(s){return R(`no answer from ${t}: ${te(s)}`)}if(typeof o!=="object"||o===null)return R("refused without a reason");let{granted:i,reason:a}=o;if(i===!0)return{granted:!0};return R(typeof a==="string"?a:"refused without a reason")}async function vr(e,t,r,n=oe){let o=yr(t);if(o===void 0)return R("not a grant request");let i,a;try{i=z(e),a=z(o.grantee)}catch{return R("grantee is not an agent identity")}let s=o.trace,h=s!==void 0?{threadId:s.thread_id,rootId:s.root_id}:void 0,l=!1;try{l=await r.owns(o.reference)}catch{}if(!l)return R("the reference does not point into this agent's volume");let p;try{p=await r.granted(o.reference,i)}catch(g){return n.error("grant request: the ledger could not be read",{error:te(g)}),R("the grant could not be made")}if(p===void 0)return R("this agent holds no live read grant it made to the requester on that reference");if(p!=="first-hand")return R("the requester's own grant was made at another agent's request; only an agent this agent handed the reference itself may ask for another");if(a.account===i.account&&a.user===i.user)return R("a grant request is for another agent, not for the requester");try{await r.grantRead(o.reference,a,h,s?.tool_call_id,"on-request")}catch(g){return n.error("grant request: the grant failed",{error:te(g)}),R("the grant could not be made")}return n.info("grant request: granted",{grantee:o.grantee,requester:e}),{granted:!0}}function Fr(e){let{scratchPad:t}=e,r=e.logger??oe,n=new He({minSenderTrust:"signed",logger:r});async function o(i){let a=await n.admitPrompt(i);if(!a.ok)return R(a.description);let s=a.sender;if(s?.trust!=="verified")return R("a grant request must be signed");return vr(s.id,i.string(),t,r)}return{name:Ze,subject:Qe(e.promptAddress),queue:"agents",handler:(i,a)=>{if(i)return;o(a).catch((s)=>(r.error("grant request failed",{error:te(s)}),R("the grant could not be made"))).then((s)=>{if(!s.granted)r.info("grant request refused",{reason:s.reason});a.respond(gr(s))})}}}function yr(e){let t;try{t=JSON.parse(e)}catch{return}if(typeof t!=="object"||t===null||Array.isArray(t))return;let{reference:r,grantee:n,trace:o}=t;if(typeof r!=="string"||typeof n!=="string")return;if(typeof o!=="object"||o===null)return{reference:r,grantee:n};let{thread_id:i,root_id:a,tool_call_id:s}=o;if(typeof i!=="string"||typeof a!=="string"||!ce(i)||!ce(a))return{reference:r,grantee:n};return{reference:r,grantee:n,trace:{thread_id:i,root_id:a,...typeof s==="string"&&pe(s)?{tool_call_id:s}:{}}}}function R(e){return{granted:!1,reason:e}}function te(e){return e instanceof Error?e.message:String(e)}var et="reads_scratchpad_references",Er=class{requestInterceptor;#e;#t;#r;#o;#i=new Set;#n=new Map;constructor(e){this.#e=e.scratchPad,this.#t=e.agents,this.#r=e.discoverTimeoutMs,this.#o=e.grantRequestTimeoutMs,this.requestInterceptor={aroundRequest:(t,r)=>(this.remember(t.envelope.prompt),r())}}remember(e){for(let t of ee(e))this.#i.add(t)}async grantCaller(e,t){if(this.remember(e),t?.trust!=="verified")return!1;if(!await this.#e.owns(e))throw Error("the reference points into another agent's volume; only its creator grants");return await this.#e.grantRead(e,z(t.id),Ne(),void 0,"first-hand"),!0}discoveryFields(e){return this.#a(e),{[et]:de(e.metadata)}}async beforePrompt(e){let{address:t,target:r}=e,n=ee(e.prompt);if(n.length===0)return;if(!de(r.metadata)){let f=Oe(e.prompt);if(f==="")return{error:`the prompt was not sent: "${t}" does not read ScratchPad references (discover_agents: reads_scratchpad_references is false), and the prompt held nothing but references; put the content they point at into the prompt itself`};return{prompt:f,fields:{references_removed:n.length,note:`"${t}" does not read ScratchPad references: ${n.length} reference(s) were removed from your prompt, it got only the text, and nothing was granted`}}}let o=[...new Set(n)],i=o.filter((f)=>!this.#i.has(f));if(i.length>0)return{error:`the prompt was not sent: ${i.length} of its ScratchPad references (${i[0].slice(0,24)}…) is not one you were given. Copy each reference exactly as you received it, the whole token, or leave it out.`};if(r.identity===void 0||!r.idSigVerified)return{error:`cannot hand a ScratchPad reference to "${t}": its identity is not verified, so no read grant can be issued; put the content in the prompt instead`};let a=z(r.identity),s=Ne(),h=e.toolCallId!==void 0&&pe(e.toolCallId)?e.toolCallId:void 0,l=[],p="";for(let f of o){try{if(await this.#e.owns(f)){await this.#e.grantRead(f,a,s,h,"first-hand");continue}}catch(b){return{error:`could not grant "${t}" read on ${f.slice(0,32)}…: ${wr(b)}; the prompt was not sent`}}let F=await this.#s(f,t,r.identity,s,h);if(!F.granted)l.push(f),p=F.reason}if(l.length===0)return;let g=n.filter((f)=>l.includes(f)).length,v=Oe(e.prompt,l);if(v==="")return{error:`the prompt was not sent: it held nothing but references, and their creator did not grant "${t}" read (${p}); put the content they point at into the prompt itself`};return{prompt:v,fields:{references_removed:g,note:`${g} reference(s) were removed from your prompt, and "${t}" got only the text: you did not create that content, and its creator did not grant "${t}" read (${p}). If it needs the content, put the content itself in a prompt`}}}afterReply(e){this.remember(e.text)}async#s(e,t,r,n,o){let i=fr(e);if(i===void 0&&this.#e.resolveReference)try{i=(await this.#e.resolveReference(e,n)).creator}catch{return{granted:!1,reason:"the reference could not be resolved"}}if(i===void 0)return{granted:!1,reason:"the reference does not name its creator"};if(i===t)return{granted:!0};let a=await this.#u(i);if(a===void 0||!a.idSigVerified)return{granted:!1,reason:`its creator, ${i}, is not on the fabric with a verified identity`};let s={reference:e,grantee:r,...n!==void 0?{trace:{thread_id:n.threadId,root_id:n.rootId,...o!==void 0?{tool_call_id:o}:{}}}:{}};return mr(this.#t,i,s,this.#o!==void 0?{timeoutMs:this.#o}:{})}async#u(e){let t=this.#n.get(e);if(t!==void 0)return t;try{let r=await this.#t.discover(this.#r!==void 0?{timeoutMs:this.#r}:{});for(let n of r)this.#a(n)}catch{}return this.#n.get(e)}#a(e){let t=this.#n.get(e.promptSubject);if(t===void 0||e.idSigVerified||!t.idSigVerified)this.#n.set(e.promptSubject,e)}};function br(e){return new Er(e)}function Ne(){let e=N();return e!==void 0?{threadId:e.threadId,rootId:e.rootId}:void 0}function wr(e){return e instanceof Error?e.message:String(e)}var Ar=class extends Error{code;unknown;local;constructor(e,t,r={}){super(t,r.cause===void 0?void 0:{cause:r.cause});this.name="NativeScratchPadError",this.code=e,this.unknown=r.unknown??!1,this.local=r.local??!1}};function Cr(e,t){return new Ar("invalid",e,{local:!0,cause:t})}var _r=/[\u0378\u0379\u0380-\u0383\u038B\u038D\u03A2\u0530\u0557\u0558\u058B\u058C\u0590\u05C8-\u05CF\u05EB-\u05EE\u05F5-\u05FF\u070E\u074B\u074C\u07B2-\u07BF\u07FB\u07FC\u082E\u082F\u083F\u085C\u085D\u085F\u086B-\u086F\u088F\u0892-\u0897\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A77-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0BFF\u0C0D\u0C11\u0C29\u0C3A\u0C3B\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B\u0C5C\u0C5E\u0C5F\u0C64\u0C65\u0C70-\u0C76\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDC\u0CDF\u0CE4\u0CE5\u0CF0\u0CF4-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D50-\u0D53\u0D64\u0D65\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F6\u13F7\u13FE\u13FF\u169D-\u169F\u16F9-\u16FF\u1716-\u171E\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE\u1AAF\u1ACF-\u1AFF\u1B4D-\u1B4F\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C89-\u1C8F\u1CBB\u1CBC\u1CC8-\u1CCF\u1CFB-\u1CFF\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u2065\u2072\u2073\u208F\u209D-\u209F\u20C1-\u20CF\u20F1-\u20FF\u218C-\u218F\u2427-\u243F\u244B-\u245F\u2B74\u2B75\u2B96\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E5E-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u3130\u318F\u31E4-\u31EF\u321F\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA6F8-\uA6FF\uA7CB-\uA7CF\uA7D2\uA7D4\uA7DA-\uA7F1\uA82D-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C6-\uA8CD\uA8DA-\uA8DF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB6C-\uAB6F\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC3-\uFBD2\uFD90\uFD91\uFDC8-\uFDCE\uFDD0-\uFDEF\uFE1A-\uFE1F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD\uFEFE\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFF8\uFFFE\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8F\uDD9D-\uDD9F\uDDA1-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEFC-\uDEFF\uDF24-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDD6E\uDD7B\uDD8B\uDD93\uDD96\uDDA2\uDDB2\uDDBA\uDDBD-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDF7F\uDF86\uDFB1\uDFBB-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC9F-\uDCA6\uDCB0-\uDCDF\uDCF3\uDCF6-\uDCFA\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBB\uDDD0\uDDD1\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE49-\uDE4F\uDE59-\uDE5F\uDEA0-\uDEBF\uDEE7-\uDEEA\uDEF7-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF92-\uDF98\uDF9D-\uDFA8\uDFB0-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCF9\uDD28-\uDD2F\uDD3A-\uDE5F\uDE7F\uDEAA\uDEAE\uDEAF\uDEB2-\uDEFC\uDF28-\uDF2F\uDF5A-\uDF6F\uDF8A-\uDFAF\uDFCC-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC4E-\uDC51\uDC76-\uDC7E\uDCC3-\uDCCC\uDCCE\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD48-\uDD4F\uDD77-\uDD7F\uDDE0\uDDF5-\uDDFF\uDE12\uDE42-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEAA-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC5C\uDC62-\uDC7F\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDDE-\uDDFF\uDE45-\uDE4F\uDE5A-\uDE5F\uDE6D-\uDE7F\uDEBA-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF47-\uDFFF]|\uD806[\uDC3C-\uDC9F\uDCF3-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD47-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE5-\uDDFF\uDE48-\uDE4F\uDEA3-\uDEAF\uDEF9-\uDEFF\uDF0A-\uDFFF]|\uD807[\uDC09\uDC37\uDC46-\uDC4F\uDC6D-\uDC6F\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF9-\uDEFF\uDF11\uDF3B-\uDF3D\uDF5A-\uDFAF\uDFB1-\uDFBF\uDFF2-\uDFFE]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F\uDC75-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80E-\uD810\uD812-\uD819\uD824-\uD82A\uD82D\uD82E\uD830-\uD832\uD83F\uD87B-\uD87D\uD87F\uD889-\uDB3F\uDB41-\uDB7F][\uDC00-\uDFFF]|\uD80B[\uDC00-\uDF8F\uDFF3-\uDFFF]|\uD80D[\uDC56-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDE6D\uDEBF\uDECA-\uDECF\uDEEE\uDEEF\uDEF6-\uDEFF\uDF46-\uDF4F\uDF5A\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE9B-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82B[\uDC00-\uDFEF\uDFF4\uDFFC\uDFFF]|\uD82C[\uDD23-\uDD31\uDD33-\uDD4F\uDD53\uDD54\uDD56-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A\uDC9B\uDCA4-\uDFFF]|\uD833[\uDC00-\uDEFF\uDF2E\uDF2F\uDF47-\uDF4F\uDFC4-\uDFFF]|\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDDEB-\uDDFF\uDE46-\uDEBF\uDED4-\uDEDF\uDEF4-\uDEFF\uDF57-\uDF5F\uDF79-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD836[\uDE8C-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD837[\uDC00-\uDEFF\uDF1F-\uDF24\uDF2B-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDC2F\uDC6E-\uDC8E\uDC90-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD50-\uDE8F\uDEAF-\uDEBF\uDEFA-\uDEFE\uDF00-\uDFFF]|\uD839[\uDC00-\uDCCF\uDCFA-\uDFDF\uDFE7\uDFEC\uDFEF\uDFFF]|\uD83A[\uDCC5\uDCC6\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDD5D\uDD60-\uDFFF]|\uD83B[\uDC00-\uDC70\uDCB5-\uDD00\uDD3E-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCC0\uDCD0\uDCF6-\uDCFF\uDDAE-\uDDE5\uDE03-\uDE0F\uDE3C-\uDE3F\uDE49-\uDE4F\uDE52-\uDE5F\uDE66-\uDEFF]|\uD83D[\uDED8-\uDEDB\uDEED-\uDEEF\uDEFD-\uDEFF\uDF77-\uDF7A\uDFDA-\uDFDF\uDFEC-\uDFEF\uDFF1-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE\uDCAF\uDCB2-\uDCFF\uDE54-\uDE5F\uDE6E\uDE6F\uDE7D-\uDE7F\uDE89-\uDE8F\uDEBE\uDEC6-\uDECD\uDEDC-\uDEDF\uDEE9-\uDEEF\uDEF9-\uDEFF\uDF93\uDFCB-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEE0-\uDEFF]|\uD86D[\uDF3A-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDF4F]|\uD888[\uDFB0-\uDFFF]|\uDB40[\uDC00\uDC02-\uDC1F\uDC80-\uDCFF\uDDF0-\uDFFF]|[\uDBBF\uDBFF][\uDFFE\uDFFF]/;var Sr=524288,tt=921600;var Br=8192,Rr=128,xr=16384,kr=131072;var Tr=Sr;var Ir=8,rt=8,Or=16,Nr=3600,jr="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";var Zn=Object.freeze({object_bytes:tt,read_bytes:Tr,control_bytes:xr,reply_bytes:kr,writers:Ir,retentions:rt,grants:Or,grant_seconds:Nr});function E(e,t){if(!e)throw Cr(t)}function ae(e,t,r=[]){E(typeof e==="object"&&e!==null&&!Array.isArray(e),"expected JSON object");let n=e;return E(t.every((o)=>Object.hasOwn(n,o)),"required field is absent"),E(Object.keys(n).every((o)=>t.includes(o)||r.includes(o)),"unknown field"),n}function U(e,t=Number.MAX_SAFE_INTEGER,r=0){E(typeof e==="number"&&Number.isSafeInteger(e)&&e>=r&&e<=t,"integer outside its bound")}function W(e,t,r=0){E(typeof e==="string"&&Buffer.from(e).toString("utf8")===e,"invalid Unicode text"),E(Buffer.byteLength(e)<=t&&Buffer.byteLength(e)>=r,"text outside its byte bound")}function nt(e){E(typeof e==="string"&&/^[A-Za-z0-9_-]{43}$/.test(e),"invalid content identity");let t=Buffer.from(e,"base64url");E(t.length===32&&t.toString("base64url")===e,"noncanonical content identity")}function Pr(e,t){E(typeof e==="string"&&/^[A-Z2-7]{56}$/.test(e),"invalid public NKEY");let r="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",n=0,o=0,i=[];for(let s of e)if(o=o<<5|r.indexOf(s),n+=5,n>=8)n-=8,i.push(o>>>n&255);E(i.length===35&&i[0]===(t==="account"?0:160),"wrong NKEY kind");let a=0;for(let s of i.slice(0,33)){a^=s<<8;for(let h=0;h<8;h++)a=(a<<1^(a&32768?4129:0))&65535}E(i[33]===(a&255)&&i[34]===a>>>8,"NKEY checksum differs")}function ot(e){W(e,255,1),E(e!=="."&&e!==".."&&!/[\x00-\x1f\x7f/]/.test(e),"forbidden entry name"),E(Lr(e)===e,"entry name is not NFC")}function Lr(e){let t="",r="";for(let n of e)if(_r.test(n))t+=r.normalize("NFC")+n,r="";else r+=n;return t+r.normalize("NFC")}function qr(e,t=4096){if(W(e,t,1),E(e.startsWith("/"),"path must be absolute"),e==="/")return;let r=e.slice(1).split("/");E(r.length<=Rr,"path exceeds its depth bound");for(let n of r)ot(n)}function $r(e){E(typeof e==="string"&&/^[0-9A-Za-z]{1,64}$/.test(e),"invalid volume name")}function it(e){let t=ae(e,["volume","creation_id"]);$r(t.volume),E(typeof t.creation_id==="string"&&/^[0-9a-f]{32}$/.test(t.creation_id),"invalid volume creation identity")}function Mr(e){let t=ae(e,["slot","generation"]);U(t.slot,rt-1),U(t.generation,void 0,1)}function at(e,t){if(e===t)return!0;if(!e||!t||typeof e!=="object"||typeof t!=="object")return!1;let r=e,n=t;return Object.keys(r).length===Object.keys(n).length&&Object.keys(r).every((o)=>Object.hasOwn(n,o)&&at(r[o],n[o]))}function Ur(e,t=!0){let r=JSON.stringify(e);return E(r!==void 0,"value cannot be encoded as JSON"),r=r.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029"),t?r.replace(/</g,"\\u003c").replace(/>/g,"\\u003e").replace(/&/g,"\\u0026"):r}var Hr=class extends Error{constructor(e,t){super(t);this.reason=e,this.name="CodecError"}reason};function T(e,t){throw new Hr(e,t)}function Gr(e,t){return Ge("sha256").update(e).update("\x00").update(t).digest("base64url")}function Vr(e){return Gr("scratchpad:v1:tree",e)}function P(e,t){if(U(t),t<24)return Buffer.from([e<<5|t]);if(t<=255)return Buffer.from([e<<5|24,t]);if(t<=65535){let n=Buffer.alloc(3);return n[0]=e<<5|25,n.writeUInt16BE(t,1),n}if(t<=4294967295){let n=Buffer.alloc(5);return n[0]=e<<5|26,n.writeUInt32BE(t,1),n}let r=Buffer.alloc(9);return r[0]=e<<5|27,r.writeBigUInt64BE(BigInt(t),1),r}function Xr(e){return Buffer.concat([P(2,e.length),e])}function O(e){let t=Buffer.from(e);return Buffer.concat([P(3,t.length),t])}function zr(e){if(typeof e!=="string"||Buffer.from(e).toString("utf8")!==e)T("utf8","invalid entry name UTF-8");if(Buffer.byteLength(e)===0||Buffer.byteLength(e)>255)T("name-length","entry name length exceeds bound");if(e==="."||e===".."||/[\x00-\x1f\x7f/]/.test(e))T("name-forbidden","forbidden entry name");try{ot(e)}catch{T("not-nfc","entry name is not NFC")}}function Jr(e){if(zr(e.name),e.type==="symlink"){if(e.executable||e.object!==void 0&&e.object!==jr)T("type-invalid","symlink has file fields");let t=e.linkTarget??"";if(typeof t!=="string"||Buffer.from(t).toString("utf8")!==t)T("utf8","invalid symlink UTF-8");if(Buffer.byteLength(t)===0||Buffer.byteLength(t)>4096||t.includes("\x00"))T("target-invalid","invalid symlink target")}else{if(e.type!=="file"&&e.type!=="directory")T("type-invalid","unknown entry type");if(nt(e.object),e.linkTarget||e.type==="directory"&&e.executable)T("type-invalid","entry has fields of another type")}}function Wr(e){for(let o of e)Jr(o);let t=[...e].sort((o,i)=>Buffer.compare(Buffer.from(o.name),Buffer.from(i.name)));for(let o=1;o<t.length;o++)if(t[o].name===t[o-1].name)T("duplicate-name","duplicate tree entry");if(e.length>Br)T("entry-count","tree entry count exceeds bound");let r=[P(5,1),O("e"),P(4,e.length)],n=r.reduce((o,i)=>o+i.length,0);for(let o of t){let i=[P(5,o.executable?4:3)];if(o.type==="symlink")i.push(O("l"),O(o.linkTarget));else i.push(O("i"),Xr(Buffer.from(o.object,"base64url")));if(i.push(O("n"),O(o.name),O("t"),P(0,o.type==="file"?0:o.type==="directory"?1:2)),o.executable)i.push(O("x"),P(0,1));if(n+=i.reduce((a,s)=>a+s.length,0),n>tt)T("node-size","tree node byte count exceeds bound");r.push(...i)}return Buffer.concat(r)}Vr(Wr([]));function st(e){let t=ae(e,["version","creator","account","target","root","generation","path","retention","expires_at"]);E(t.version===2,"reference version must be two"),W(t.creator,512,1),Pr(t.account,"account"),it(t.target),nt(t.root),U(t.generation,void 0,1),qr(t.path,256),Mr(t.retention),U(t.expires_at,void 0,1)}function Yr(e){st(e);let t={version:2,creator:e.creator,account:e.account,target:{volume:e.target.volume,creation_id:e.target.creation_id},root:e.root,generation:e.generation,path:e.path,retention:{slot:e.retention.slot,generation:e.retention.generation},expires_at:e.expires_at},r="sp-ref:"+Buffer.from(Ur(t,!1)).toString("base64url");return E(Buffer.byteLength(r)<=16384,"reference exceeds byte bound"),r}var le="sp-r1:",re=66;function ut(e){W(e,re,re),E(/^sp-r1:[A-Za-z0-9_-]{60}$/.test(e),"malformed short reference");let t=Buffer.from(e.slice(le.length),"base64url");E(t.length===45&&t[32]<64,"invalid short reference slots");let r=Number(t.readBigUInt64BE(24));U(r,void 0,1);let n={route:t.subarray(0,8).toString("hex"),creation_id:t.subarray(8,24).toString("hex"),retention:{slot:t[32]>>3,generation:r},path_index:t[32]&7};return it({volume:"Reference",creation_id:n.creation_id}),n}function Kr(e,t){return Ge("sha256").update(`scratchpad-reference-volume-v1\x00${e}\x00${t}`).digest().subarray(0,8).toString("hex")}function Zr(e){let t=ae(e,["short","expanded"]);W(t.short,re,re);let r=ut(t.short);st(t.expanded),E(r.route===Kr(t.expanded.account,t.expanded.target.volume)&&r.creation_id===t.expanded.target.creation_id&&at(r.retention,t.expanded.retention),"short reference binding differs")}var Qr="sp",en=600,je=600,tn=5,Pe=16,rn=16384,ct=16777216,nn=Math.ceil(ct/3)*4+65536,on=262144,an=65536,dt=/^A[A-Z2-7]{55}$/,sn=/^[0-9A-Za-z]{1,64}$/,un=/^[0-9a-f]{32}$/,cn=/^[A-Za-z0-9_-]{43}$/,dn=/^[A-Za-z0-9_-]+$/,ln=/^[A-Za-z0-9+/]*={0,2}$/,m=class extends Error{constructor(e,t,r){super(e);this.code=t,this.unknown=r,this.name="ScratchPadError"}code;unknown},B=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),ne=(e,t)=>Object.keys(e).length===t.length&&t.every((r)=>(r in e)),V=(e)=>Number.isSafeInteger(e)&&e>0,lt=(e)=>Buffer.byteLength(e,"utf8");function ft(e){return B(e)&&ne(e,["volume","creation_id"])&&typeof e.volume==="string"&&sn.test(e.volume)&&typeof e.creation_id==="string"&&un.test(e.creation_id)}function fn(e){if(typeof e!=="string"||!e.startsWith("/")||lt(e)>256)return!1;if(e==="/")return!0;return e.slice(1).split("/").every((t)=>t!==""&&t!=="."&&t!=="..")}function ue(e){let t=(a)=>{throw Error(`malformed ScratchPad reference: ${a}`)};if(typeof e!=="string"||!e.startsWith(Q))t("no sp-ref: prefix");if(e.length>rn)t("longer than 16 KiB");let r=e.slice(Q.length);if(!dn.test(r)||r.length%4===1)t("not unpadded base64url");let n;try{n=JSON.parse(Buffer.from(r,"base64url").toString("utf8"))}catch{t("not JSON")}let o=["version","creator","account","target","root","generation","path","retention","expires_at"];if(!B(n)||!ne(n,o))return t("not the version 2 fields");let i=n.retention;if(n.version!==2||typeof n.creator!=="string"||n.creator.length===0||lt(n.creator)>512||typeof n.account!=="string"||!dt.test(n.account)||!ft(n.target)||typeof n.root!=="string"||!cn.test(n.root)||!V(n.generation)||!fn(n.path)||!B(i)||!ne(i,["slot","generation"])||!Number.isSafeInteger(i.slot)||i.slot<0||i.slot>7||!V(i.generation)||!V(n.expires_at))t("a field is out of shape");return n}var j=()=>Math.floor(Date.now()/1000),Le=8,hn=16,pn=["close","apply","release","grant"],Dn=["workspace","not_found"],L=(e)=>Number.isSafeInteger(e)&&e>=0;function gn(e){let t=(l)=>{throw new m(`sp describe: ${l}`,"malformed_reply",!1)};if(!B(e)||!B(e.volume))return t("the reply names no volume");let{volume:r,control:n}=e,o;if(n!==null&&n!==void 0){if(!B(n)||typeof n.kind!=="string"||!pn.includes(n.kind))return t("the saved control request is out of shape");o=n.kind}if(typeof r.closed!=="boolean")return t("the volume names no closed state");let{retentions:i,grants:a}=r;if(!Array.isArray(i)||i.length!==Le)return t("not eight retention slots");if(!Array.isArray(a)||a.length!==hn)return t("not sixteen grant slots");let s=i.map((l)=>{if(!B(l)||!L(l.generation))return t("a retention slot is out of shape");let p=l.pin;if(p===void 0||p===null)return{generation:l.generation,until:void 0};if(!B(p)||!L(p.until)||typeof p.root!=="string")return t("a retention pin is out of shape");return{generation:l.generation,until:p.until}}),h=[];for(let l of a){if(!B(l)||!L(l.generation))return t("a grant slot is out of shape");let p=l.grant;if(p===void 0||p===null)continue;let g=B(p)?p.retention:void 0;if(!B(p)||!L(p.until)||!B(g)||!L(g.slot)||g.slot>=Le||!V(g.generation))return t("a grant is out of shape");h.push({slot:g.slot,generation:g.generation,until:p.until})}return{closed:r.closed,control:o,retentions:s,grants:h}}function mn(e){let t=(o)=>{throw new m(`sp spool-remove: ${o}`,"malformed_reply",!1)};if(!B(e)||typeof e.present!=="boolean")return t("the reply says no spool state");let r=e.present,n=["present","files","bytes","removable","applied"];if(r)n.push("phase");if(!ne(e,n)||r&&(typeof e.phase!=="string"||e.phase==="")||!L(e.files)||!L(e.bytes)||typeof e.removable!=="boolean"||typeof e.applied!=="boolean")return t("the spool state is out of shape");return{present:r,removable:e.removable,applied:e.applied}}function vn(e,t=j()){let r=e.control==="close"||e.control==="apply";if(e.closed&&!r)return"the volume is closed, and no cleanup of this agent's is saved";if(r)return;return e.retentions.some((o,i)=>o.until===void 0||o.until!==0&&o.until<=t&&!e.grants.some((a)=>a.slot===i&&a.generation===o.generation&&a.until>t))?void 0:"every retention slot holds a live pin"}function Fn(e){if(!("creds"in e.nats)||e.nats.creds===void 0)throw Error("ScratchPad: the sp CLI needs NATS_URL and NATS_CREDS; a NATS context or an nkey seed alone is not supported");let t=["--url",e.nats.url,"--creds",e.nats.creds],r=e.bin??Qr,n=e.dir??ie(Lt(),`scratchpad-${e.volume}`),o=Math.min(e.grantTtlS??je,je),i,a,s=Promise.resolve(),h=!0,l,p=new Map;function g(u){let d=s.then(u);return s=d.catch(()=>{return}),d}let v=new Map;async function f(u,d){if(!u.startsWith(le))return ue(u);ut(u);let c=v.get(u);if(c&&c.expires_at>j())return structuredClone(c);let D=await b("resolve",["--ref",u],{trace:d}),C={short:u,expanded:D?.reference};if(Zr(C),D.full_reference!==Yr(C.expanded))throw new m("sp resolve: expanded token differs from descriptor","malformed_reply",!1);let y=ue(D.full_reference);if(y.expires_at<=j())throw Error("the reference has expired");if(v.delete(u),v.set(u,y),v.size>64)v.delete(v.keys().next().value);return structuredClone(y)}async function F(){return i??=(async()=>(await jt(n,{recursive:!0,mode:448}),Pt(n)))(),i}async function b(u,d,c={}){let D=c.trace?["--thread-id",c.trace.threadId,"--root-id",c.trace.rootId]:[];if(c.trace&&c.toolCallId!==void 0)D.push("--tool-call-id",c.toolCallId);let C=["read","resolve"].includes(u)?[]:["--volume",e.volume],y=[u,...t,"--dir",await F(),...C,...d,...D],x=c.maxStdout??on,{code:k,stdout:_,stderr:I}=await new Promise((w)=>{Nt(r,y,{maxBuffer:Math.max(x,an),encoding:"utf8"},(Rt,xt,kt)=>{let M=Rt;w({code:M===null?0:typeof M.code==="number"?M.code:null,stdout:xt??"",stderr:kt||(M!==null&&typeof M.code==="string"?M.message:"")})}).stdin?.end(c.stdin??"")});if(k===null&&/^spawn .*(ENOENT|EACCES)/m.test(I))throw new m(`sp ${u}: ${I.trim()}`,"spawn_failed",!1);if(k===0&&_.length<=x)try{return JSON.parse(_)}catch{}let A={code:k===0?"malformed_reply":"failed",message:I.trim().slice(0,512)||`exit ${k??"by signal"}`,unknown:c.mutation===!0};if(k!==0)try{let w=JSON.parse(I).error;if(B(w)&&typeof w.code==="string")A={code:w.code,message:typeof w.message==="string"?w.message:"",unknown:w.unknown===!0||c.mutation===!0&&typeof w.unknown!=="boolean"}}catch{}throw new m(`sp ${u}: ${A.code}${A.unknown?" (outcome unknown)":""}: ${A.message}`,A.code,A.unknown)}function q(u,d){let c=u,D=c?.principal?.account;if(typeof D!=="string"||!dt.test(D)||!ft(c.target))throw new m(`sp ${d}: the reply names no principal and target`,"malformed_reply",!1);if(c.target.volume!==e.volume)throw new m(`sp ${d}: the workspace is bound to another volume`,"invalid",!1);return{account:D,target:{volume:c.target.volume,creation_id:c.target.creation_id}}}async function bt(u){return a??=q(await b("init",[],{trace:u,mutation:!0}),"init"),a}async function Ee(u){if(a!==void 0)return a;try{a=q(await b("describe",[],{trace:u}),"describe")}catch(d){if(d instanceof m&&Dn.includes(d.code))return;throw d}return a}let Y=(u,d)=>d!==void 0&&u.account===d.account&&u.target.volume===d.target.volume&&u.target.creation_id===d.target.creation_id,be=(u,d)=>JSON.stringify([u.account,u.target.volume,u.target.creation_id,u.root,u.path,d.account,d.user]);function wt(){let u=j();for(let[d,c]of p)if(Math.max(c["first-hand"]??0,c["on-request"]??0)<=u)p.delete(d)}function we(u,d,c){p.set(u,{...p.get(u),[d]:c})}function At(u,d){let c=u;if(!B(c)||!B(c.handle)||!V(c.expires_at))throw new m("sp grant: the reply names no handle and expiry","malformed_reply",!0);return Math.min(c.expires_at,d.expires_at)}async function Ae(u,d,c,D){return b("publish-file",["--source","-","--path",d,"--operation-id",c,"--creator",e.creator,"--ttl-seconds",String(en)],{trace:D,stdin:u,mutation:!0})}async function Ce(u){if(!h)return;try{await b("recover",[],{trace:u,mutation:!0})}catch(d){if(!(d instanceof m)||d.unknown)throw d}h=!1}async function Ct(u,d){let c;try{let D=mn(await b("spool-remove",["--apply"],{trace:d,mutation:!0}));if(!D.present||D.applied)return;c="the refused publication's spool is protected"}catch(D){if(D instanceof m&&D.unknown)throw D;c=`its spool was not removed: ${D.message}`}throw h=!0,new m(`${u.message}; cleanup not started: ${c}`,u.code,!1)}async function _t(u){return gn(await b("describe",[],{trace:u}))}async function St(u,d,c){if(e.creator===void 0)throw Error("ScratchPad: a reference names its creator; this ScratchPad was made without one");let D=await bt(c);await Ce(c);let C=Se(),y;try{y=await Ae(u,d,C,c)}catch(_){if(_ instanceof m&&_.unknown)h=!0;if(!(_ instanceof m)||_.code!=="capacity"||_.unknown)throw _;await Ct(_,c);let I;try{I=vn(await _t(c))}catch(A){throw new m(`${_.message}; cleanup not started: ${A.message}`,_.code,!1)}if(I!==void 0)throw new m(`${_.message}; cleanup not started: ${I}`,_.code,!1);try{await b("maintain",["--apply"],{trace:c,mutation:!0})}catch(A){h=!0;let w=!(A instanceof m)||A.unknown;throw new m(`${_.message}; cleanup: ${A.message}`,w&&A instanceof m?A.code:w?"failed":_.code,w)}try{y=await Ae(u,d,C,c)}catch(A){if(A instanceof m&&A.unknown)h=!0;throw A}}let x=y?.reference;if(typeof x!=="string"||!B(y.receipt))throw h=!0,new m("sp publish-file: the reply names no receipt and reference","malformed_reply",!0);let k=await f(x,c);if(!Y(k,D)||k.path!==d||k.creator!==e.creator)throw new m("sp publish-file: the reference names another volume, path or creator","malformed_reply",!1);return x}async function _e(u,d,c,D){return At(await b("grant",u,{trace:d,toolCallId:c,mutation:!0}),D)}async function Bt(u,d,c,D,C){let y=await f(u,c);if(!Y(y,await Ee(c)))throw Error("the reference points into another agent's volume; only its creator can grant read on it");if(await Ce(c),l!==void 0){let w=l;try{we(w.key,w.kind,await _e(w.args,void 0,void 0,w.ref)),l=void 0}catch(K){if(!(K instanceof m)||K.unknown)throw K;l=void 0}}let x=y.expires_at-j()-tn,k=Math.floor(Math.min(o,x));if(k<1)throw Error("the reference has expired, or is about to; there is nothing left to grant on");let _=be(y,d);if(wt(),!p.has(_)&&p.size>=Pe)throw Error(`this agent already holds ${Pe} live grants; try again when one expires`);let I=c?["--thread-id",c.threadId,"--root-id",c.rootId]:[];if(c&&D!==void 0)I.push("--tool-call-id",D);let A=["--ref",u,"--grantee-account",d.account,"--grantee-user",d.user,"--operation-id",Se(),"--ttl-seconds",String(k)];try{we(_,C,await _e(A,c,D,y))}catch(w){if(w instanceof m&&w.unknown)l={args:[...A,...I],key:_,kind:C,ref:y};throw w}}return{commit(u,d,c){return g(()=>St(u,d,c))},async read(u,d){if((await f(u,d)).expires_at<=j())throw Error("the reference has expired");let D=await b("read",["--ref",u],{trace:d,maxStdout:nn}),{data_base64:C,bytes:y}=D??{};if(typeof C!=="string"||!ln.test(C)||!Number.isSafeInteger(y)||y>ct)throw new m("sp read: the reply carries no data","malformed_reply",!1);let x=Buffer.from(C,"base64");if(x.length!==y||x.toString("base64")!==C)throw new m("sp read: the data does not match its length","malformed_reply",!1);try{return new TextDecoder("utf-8",{fatal:!0}).decode(x)}catch{throw Error("the referenced file is not UTF-8 text")}},resolveReference:f,async owns(u){let d;try{d=await f(u)}catch{return!1}return Y(d,await Ee(N()))},grantRead(u,d,c,D,C="first-hand"){return g(()=>Bt(u,d,c,D,C))},granted(u,d){let c=(D)=>{if(!Y(D,a))return;let C=p.get(be(D,d)),y=j();if((C?.["first-hand"]??0)>y)return"first-hand";if((C?.["on-request"]??0)>y)return"on-request";return};if(u.startsWith(le))return f(u).then(c,()=>{return});try{return c(ue(u))}catch{return}}}}var yn="SCRATCHPAD_VOLUME",En="SCRATCHPAD_BIN",bn="SCRATCHPAD_DIR";var wn=409;function An(e){return`the agent's model is waiting inside a prompt of this tree (root ${e}); a prompt of the same tree cannot be served until that call returns`}function Cn(e){if(typeof e!=="object"||e===null||Array.isArray(e))return;let t=e.open_calls;if(t===void 0)return 0;return typeof t==="number"&&Number.isInteger(t)&&t>=0?t:void 0}function _n(e){return(typeof e==="object"||typeof e==="function")&&e!==null&&typeof e.then==="function"}function ht(){let e=new Map,t=new Map,r=(o)=>{let i=t.get(o);if(i===void 0)return!1;for(let a of i)if(a.waiting)return!0;return!1},n=(o,i,a)=>{o.running-=1;let s=i?Cn(a):void 0;if(s===void 0)return;if(o.open=s,o.running===0&&o.open===0)o.waiting=!1};return{requestInterceptor:{async aroundRequest(o,i){let a=N();if(a===void 0){await i();return}let{rootId:s}=a;if(r(s))throw new X(wn,An(s));let h={rootId:s,waiting:!1,running:0,open:0};e.set(a,h);let l=t.get(s);if(l===void 0)t.set(s,l=new Set);l.add(h);try{await i()}finally{if(e.delete(a),l.delete(h),l.size===0)t.delete(s)}}},promptInterceptor:{beforePrompt(){let o=N(),i=o===void 0?void 0:e.get(o);if(i!==void 0)i.waiting=!0}},aroundToolCall(o,i){let a=o===void 0?void 0:e.get(o);if(a===void 0)return i();a.running+=1;let s;try{s=i()}catch(h){throw n(a,!1),h}if(_n(s))s.then((h)=>n(a,!0,h),()=>n(a,!1));else n(a,!0,s);return s},serving:(o)=>t.has(o),waiting:r}}var Sn=Symbol.for("synadia.fabric.scratchpad.workspace-owners.v1"),Bn=globalThis,Qn=Bn[Sn]??=new Set;var qe="edgeSubject",Rn="SYNADIA_FABRIC_EDGE_SUBJECT";function pt(e,t=process.env){if(Object.hasOwn(e,qe))return e[qe];let r=t[Rn];if(r!==void 0)return r;return Ve}var Dt="scratchpad",S={url:"SP_NATS_URL",creds:"SP_NATS_CREDS",dir:bn,volume:yn,creator:"SP_CREATOR",threadId:"SP_THREAD_ID",rootId:"SP_ROOT_ID",callerAccount:"SP_CALLER_ACCOUNT",callerUser:"SP_CALLER_USER",grants:"SP_GRANTS_FILE"};async function ge(e,t){let r=e.logger,n=e.options[Dt],o=n!==null&&typeof n==="object"?n:{},i=(g,v)=>{let f=o[g];if(typeof f==="string"&&f!=="")return f;let F=t[v];return F===void 0||F===""?void 0:F},a=i("volume",S.volume);if(a===void 0)return;let s=i("url","NATS_URL"),h=i("creds","NATS_CREDS");if(s===void 0||h===void 0){let g=t.NATS_CONTEXT||G(e.settings.config.context);if(g!==void 0)try{let{fields:v}=await Ue(g);s??=G(v.url),h??=G(v.creds)}catch(v){r.warn(`agent-fabric: ScratchPad is off: the NATS context "${g}" could not be read (${String(v)})`);return}}if(s??=G(e.settings.config.url),h??=G(e.settings.config.credentials),s===void 0||h===void 0){r.warn("agent-fabric: ScratchPad is off: sp needs a NATS URL and a credentials file (options.scratchpad, NATS_URL and NATS_CREDS, a NATS context with both, or url and credentials in the plugin's configuration)");return}let l=i("dir",S.dir);if(l===void 0&&e.settings.stateDir!==void 0)l=ie(e.settings.stateDir,"scratchpad");if(l!==void 0){l=qt($e(l));try{Mt(l,{recursive:!0,mode:448})}catch(g){r.warn(`agent-fabric: ScratchPad workspace ${l} could not be created (${String(g)})`)}}let p=l!==void 0?`${l}.grants`:void 0;if(p!==void 0)kn(p,r);return{url:s,creds:$e(h),volume:a,...l!==void 0?{dir:l}:{},...p!==void 0?{grants:p}:{}}}function me(e,t){if(t[S.url]=e.url,t[S.creds]=e.creds,t[S.volume]=e.volume,e.dir!==void 0)t[S.dir]=e.dir;if(e.grants!==void 0)t[S.grants]=e.grants}var ve=class{constructor(e){this.env=e}env;#e;enter(e,t){if(this.#t(),this.#e=e.id,t!==void 0)this.env[S.threadId]=t.threadId,this.env[S.rootId]=t.rootId;if(e.caller!==void 0)try{let r=z(e.caller);this.env[S.callerAccount]=r.account,this.env[S.callerUser]=r.user}catch{}}leave(e){if(this.#e===e.id)this.#t(),this.#e=void 0}#t(){delete this.env[S.threadId],delete this.env[S.rootId],delete this.env[S.callerAccount],delete this.env[S.callerUser]}};function gt(e,t){let r=e[En];if(r!==void 0&&r!=="")return r;let n=Be()==="darwin"?"darwin":Be()==="linux"?"linux":void 0,o=Re()==="arm64"?"arm64":Re()==="x64"?"amd64":void 0;if(n===void 0||o===void 0)return;return ie(t,"bin",`sp-${n}-${o}`)}var Fe=class{#e;#t;#r=[];requestInterceptor={aroundRequest:(e,t)=>{if(this.#e===void 0)this.#r.push(e.envelope.prompt);else this.#e.remember(e.envelope.prompt);return t()}};start(e){let{scratchPad:t,agents:r,service:n}=e;this.#t=t,this.#e=br({scratchPad:t,agents:r});for(let a of this.#r.splice(0))this.#e.remember(a);if(n===void 0)return;let o=e.logger??oe,i=Fr({promptAddress:n.subject.prompt,scratchPad:t,logger:o});try{n.service.addEndpoint(i.name,{subject:i.subject,...i.queue!==void 0?{queue:i.queue}:{},handler:i.handler})}catch(a){o.warn(`agent-fabric: grant requests are not answered: ${String(a)}`)}}discoveryFields(e){return this.#e?.discoveryFields(e)??{[et]:de(e.metadata)}}async beforePrompt(e){let t=this.#e,r=this.#t;if(t===void 0||r===void 0){if(ee(e.prompt).length===0)return;return{error:"the prompt was not sent: ScratchPad is not ready yet; try again in a moment"}}for(let n of new Set(ee(e.prompt)))if(await r.owns(n))t.remember(n);return t.beforePrompt(e)}afterReply(e){this.#e?.afterReply(e)}};function mt(e,t,r,n){let o=gt(r,n);if(o===void 0)return;let i=Fn({volume:e.volume,nats:{url:e.url,creds:e.creds},bin:o,creator:t,...e.dir!==void 0?{dir:e.dir}:{}});return e.grants!==void 0?Tn(i,e.grants):i}var xn=/^(\d+) (\S+) (\S+) (sp-(?:ref|r1):[A-Za-z0-9_-]+)$/;function vt(e){let t;try{t=Ut(e,"utf8")}catch{return[]}let r=[];for(let n of t.split(`
|
|
4
|
-
`)){let o=
|
|
5
|
-
`).join(""),{mode:384}),
|
|
3
|
+
`).trim()}function Or(e){if(!e.startsWith(ie))return;let t;try{t=JSON.parse(Buffer.from(e.slice(ie.length),"base64url").toString("utf8"))}catch{return}if(typeof t!=="object"||t===null)return;let r=t.creator;return typeof r==="string"&&r!==""?r:void 0}function De(e){return e[_e]==="true"}function te(e){let t=e.indexOf(".");if(t<=0||t===e.length-1)throw Error(`not an agent identity: ${e}`);return{account:e.slice(0,t),user:e.slice(t+1)}}var ut="sp-grant",Ir=1e4,he="agents.prompt.",Nr=`agents.${ut}.`;function dt(e){if(!e.startsWith(he)||e===he)throw Error(`not a prompt address: ${e}`);return Nr+e.slice(he.length)}function jr(e){let{trace:t}=e;return JSON.stringify({reference:e.reference,grantee:e.grantee,...t!==void 0?{trace:{thread_id:t.thread_id,root_id:t.root_id,...t.tool_call_id!==void 0?{tool_call_id:t.tool_call_id}:{}}}:{}})}function Pr(e){return JSON.stringify(e.granted?{granted:!0}:{granted:!1,reason:e.reason})}async function qr(e,t,r,n={}){let o;try{let s=await e.requestSigned(dt(t),jr(r),{timeoutMs:n.timeoutMs??Ir});o=JSON.parse(s.string())}catch(s){return T(`no answer from ${t}: ${se(s)}`)}if(typeof o!=="object"||o===null)return T("refused without a reason");let{granted:i,reason:a}=o;if(i===!0)return{granted:!0};return T(typeof a==="string"?a:"refused without a reason")}async function Lr(e,t,r,n=de){let o=Mr(t);if(o===void 0)return T("not a grant request");let i,a;try{i=te(e),a=te(o.grantee)}catch{return T("grantee is not an agent identity")}let s=o.trace,f=s!==void 0?{threadId:s.thread_id,rootId:s.root_id}:void 0,l=!1;try{l=await r.owns(o.reference)}catch{}if(!l)return T("the reference does not point into this agent's volume");let h;try{h=await r.granted(o.reference,i)}catch(v){return n.error("grant request: the ledger could not be read",{error:se(v)}),T("the grant could not be made")}if(h===void 0)return T("this agent holds no live read grant it made to the requester on that reference");if(h!=="first-hand")return T("the requester's own grant was made at another agent's request; only an agent this agent handed the reference itself may ask for another");if(a.account===i.account&&a.user===i.user)return T("a grant request is for another agent, not for the requester");try{await r.grantRead(o.reference,a,f,s?.tool_call_id,"on-request")}catch(v){return n.error("grant request: the grant failed",{error:se(v)}),T("the grant could not be made")}return n.info("grant request: granted",{grantee:o.grantee,requester:e}),{granted:!0}}function $r(e){let{scratchPad:t}=e,r=e.logger??de,n=new et({minSenderTrust:"signed",logger:r});async function o(i){let a=await n.admitPrompt(i);if(!a.ok)return T(a.description);let s=a.sender;if(s?.trust!=="verified")return T("a grant request must be signed");return Lr(s.id,i.string(),t,r)}return{name:ut,subject:dt(e.promptAddress),queue:"agents",handler:(i,a)=>{if(i)return;o(a).catch((s)=>(r.error("grant request failed",{error:se(s)}),T("the grant could not be made"))).then((s)=>{if(!s.granted)r.info("grant request refused",{reason:s.reason});a.respond(Pr(s))})}}}function Mr(e){let t;try{t=JSON.parse(e)}catch{return}if(typeof t!=="object"||t===null||Array.isArray(t))return;let{reference:r,grantee:n,trace:o}=t;if(typeof r!=="string"||typeof n!=="string")return;if(typeof o!=="object"||o===null)return{reference:r,grantee:n};let{thread_id:i,root_id:a,tool_call_id:s}=o;if(typeof i!=="string"||typeof a!=="string"||!me(i)||!me(a))return{reference:r,grantee:n};return{reference:r,grantee:n,trace:{thread_id:i,root_id:a,...typeof s==="string"&&Ae(s)?{tool_call_id:s}:{}}}}function T(e){return{granted:!1,reason:e}}function se(e){return e instanceof Error?e.message:String(e)}var lt="reads_scratchpad_references",Ur=class{requestInterceptor;#e;#t;#r;#o;#i=new Set;#n=new Map;constructor(e){this.#e=e.scratchPad,this.#t=e.agents,this.#r=e.discoverTimeoutMs,this.#o=e.grantRequestTimeoutMs,this.requestInterceptor={aroundRequest:(t,r)=>(this.remember(t.envelope.prompt),r())}}remember(e){for(let t of ae(e))this.#i.add(t)}async grantCaller(e,t){if(this.remember(e),t?.trust!=="verified")return!1;if(!await this.#e.owns(e))throw Error("the reference points into another agent's volume; only its creator grants");return await this.#e.grantRead(e,te(t.id),Xe(),void 0,"first-hand"),!0}discoveryFields(e){return this.#a(e),{[lt]:De(e.metadata)}}async beforePrompt(e){let{address:t,target:r}=e,n=ae(e.prompt);if(n.length===0)return;if(!De(r.metadata)){let g=Ge(e.prompt);if(g==="")return{error:`the prompt was not sent: "${t}" does not read ScratchPad references (discover_agents: reads_scratchpad_references is false), and the prompt held nothing but references; put the content they point at into the prompt itself`};return{prompt:g,fields:{references_removed:n.length,note:`"${t}" does not read ScratchPad references: ${n.length} reference(s) were removed from your prompt, it got only the text, and nothing was granted`}}}let o=[...new Set(n)],i=o.filter((g)=>!this.#i.has(g));if(i.length>0)return{error:`the prompt was not sent: ${i.length} of its ScratchPad references (${i[0].slice(0,24)}…) is not one you were given. Copy each reference exactly as you received it, the whole token, or leave it out.`};if(r.identity===void 0||!r.idSigVerified)return{error:`cannot hand a ScratchPad reference to "${t}": its identity is not verified, so no read grant can be issued; put the content in the prompt instead`};let a=te(r.identity),s=Xe(),f=e.toolCallId!==void 0&&Ae(e.toolCallId)?e.toolCallId:void 0,l=[],h="";for(let g of o){try{if(await this.#e.owns(g)){await this.#e.grantRead(g,a,s,f,"first-hand");continue}}catch(m){return{error:`could not grant "${t}" read on ${g.slice(0,32)}…: ${Vr(m)}; the prompt was not sent`}}let p=await this.#s(g,t,r.identity,s,f);if(!p.granted)l.push(g),h=p.reason}if(l.length===0)return;let v=n.filter((g)=>l.includes(g)).length,_=Ge(e.prompt,l);if(_==="")return{error:`the prompt was not sent: it held nothing but references, and their creator did not grant "${t}" read (${h}); put the content they point at into the prompt itself`};return{prompt:_,fields:{references_removed:v,note:`${v} reference(s) were removed from your prompt, and "${t}" got only the text: you did not create that content, and its creator did not grant "${t}" read (${h}). If it needs the content, put the content itself in a prompt`}}}afterReply(e){this.remember(e.text)}async#s(e,t,r,n,o){let i=Or(e);if(i===void 0&&this.#e.resolveReference)try{i=(await this.#e.resolveReference(e,n)).creator}catch{return{granted:!1,reason:"the reference could not be resolved"}}if(i===void 0)return{granted:!1,reason:"the reference does not name its creator"};if(i===t)return{granted:!0};let a=await this.#c(i);if(a===void 0||!a.idSigVerified)return{granted:!1,reason:`its creator, ${i}, is not on the fabric with a verified identity`};let s={reference:e,grantee:r,...n!==void 0?{trace:{thread_id:n.threadId,root_id:n.rootId,...o!==void 0?{tool_call_id:o}:{}}}:{}};return qr(this.#t,i,s,this.#o!==void 0?{timeoutMs:this.#o}:{})}async#c(e){let t=this.#n.get(e);if(t!==void 0)return t;try{let r=await this.#t.discover(this.#r!==void 0?{timeoutMs:this.#r}:{});for(let n of r)this.#a(n)}catch{}return this.#n.get(e)}#a(e){let t=this.#n.get(e.promptSubject);if(t===void 0||e.idSigVerified||!t.idSigVerified)this.#n.set(e.promptSubject,e)}};function Hr(e){return new Ur(e)}function Xe(){let e=H();return e!==void 0?{threadId:e.threadId,rootId:e.rootId}:void 0}function Vr(e){return e instanceof Error?e.message:String(e)}var ft=class extends Error{code;unknown;local;constructor(e,t,r={}){super(t,r.cause===void 0?void 0:{cause:r.cause});this.name="NativeScratchPadError",this.code=e,this.unknown=r.unknown??!1,this.local=r.local??!1}};function ht(e,t){return new ft("invalid",e,{local:!0,cause:t})}var Gr=/[\u0378\u0379\u0380-\u0383\u038B\u038D\u03A2\u0530\u0557\u0558\u058B\u058C\u0590\u05C8-\u05CF\u05EB-\u05EE\u05F5-\u05FF\u070E\u074B\u074C\u07B2-\u07BF\u07FB\u07FC\u082E\u082F\u083F\u085C\u085D\u085F\u086B-\u086F\u088F\u0892-\u0897\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A77-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0BFF\u0C0D\u0C11\u0C29\u0C3A\u0C3B\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B\u0C5C\u0C5E\u0C5F\u0C64\u0C65\u0C70-\u0C76\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDC\u0CDF\u0CE4\u0CE5\u0CF0\u0CF4-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D50-\u0D53\u0D64\u0D65\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F6\u13F7\u13FE\u13FF\u169D-\u169F\u16F9-\u16FF\u1716-\u171E\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE\u1AAF\u1ACF-\u1AFF\u1B4D-\u1B4F\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C89-\u1C8F\u1CBB\u1CBC\u1CC8-\u1CCF\u1CFB-\u1CFF\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u2065\u2072\u2073\u208F\u209D-\u209F\u20C1-\u20CF\u20F1-\u20FF\u218C-\u218F\u2427-\u243F\u244B-\u245F\u2B74\u2B75\u2B96\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E5E-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u3130\u318F\u31E4-\u31EF\u321F\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA6F8-\uA6FF\uA7CB-\uA7CF\uA7D2\uA7D4\uA7DA-\uA7F1\uA82D-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C6-\uA8CD\uA8DA-\uA8DF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB6C-\uAB6F\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC3-\uFBD2\uFD90\uFD91\uFDC8-\uFDCE\uFDD0-\uFDEF\uFE1A-\uFE1F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD\uFEFE\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFF8\uFFFE\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8F\uDD9D-\uDD9F\uDDA1-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEFC-\uDEFF\uDF24-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDD6E\uDD7B\uDD8B\uDD93\uDD96\uDDA2\uDDB2\uDDBA\uDDBD-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDF7F\uDF86\uDFB1\uDFBB-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC9F-\uDCA6\uDCB0-\uDCDF\uDCF3\uDCF6-\uDCFA\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBB\uDDD0\uDDD1\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE49-\uDE4F\uDE59-\uDE5F\uDEA0-\uDEBF\uDEE7-\uDEEA\uDEF7-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF92-\uDF98\uDF9D-\uDFA8\uDFB0-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCF9\uDD28-\uDD2F\uDD3A-\uDE5F\uDE7F\uDEAA\uDEAE\uDEAF\uDEB2-\uDEFC\uDF28-\uDF2F\uDF5A-\uDF6F\uDF8A-\uDFAF\uDFCC-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC4E-\uDC51\uDC76-\uDC7E\uDCC3-\uDCCC\uDCCE\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD48-\uDD4F\uDD77-\uDD7F\uDDE0\uDDF5-\uDDFF\uDE12\uDE42-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEAA-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC5C\uDC62-\uDC7F\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDDE-\uDDFF\uDE45-\uDE4F\uDE5A-\uDE5F\uDE6D-\uDE7F\uDEBA-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF47-\uDFFF]|\uD806[\uDC3C-\uDC9F\uDCF3-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD47-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE5-\uDDFF\uDE48-\uDE4F\uDEA3-\uDEAF\uDEF9-\uDEFF\uDF0A-\uDFFF]|\uD807[\uDC09\uDC37\uDC46-\uDC4F\uDC6D-\uDC6F\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF9-\uDEFF\uDF11\uDF3B-\uDF3D\uDF5A-\uDFAF\uDFB1-\uDFBF\uDFF2-\uDFFE]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F\uDC75-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80E-\uD810\uD812-\uD819\uD824-\uD82A\uD82D\uD82E\uD830-\uD832\uD83F\uD87B-\uD87D\uD87F\uD889-\uDB3F\uDB41-\uDB7F][\uDC00-\uDFFF]|\uD80B[\uDC00-\uDF8F\uDFF3-\uDFFF]|\uD80D[\uDC56-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDE6D\uDEBF\uDECA-\uDECF\uDEEE\uDEEF\uDEF6-\uDEFF\uDF46-\uDF4F\uDF5A\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE9B-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82B[\uDC00-\uDFEF\uDFF4\uDFFC\uDFFF]|\uD82C[\uDD23-\uDD31\uDD33-\uDD4F\uDD53\uDD54\uDD56-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A\uDC9B\uDCA4-\uDFFF]|\uD833[\uDC00-\uDEFF\uDF2E\uDF2F\uDF47-\uDF4F\uDFC4-\uDFFF]|\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDDEB-\uDDFF\uDE46-\uDEBF\uDED4-\uDEDF\uDEF4-\uDEFF\uDF57-\uDF5F\uDF79-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD836[\uDE8C-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD837[\uDC00-\uDEFF\uDF1F-\uDF24\uDF2B-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDC2F\uDC6E-\uDC8E\uDC90-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD50-\uDE8F\uDEAF-\uDEBF\uDEFA-\uDEFE\uDF00-\uDFFF]|\uD839[\uDC00-\uDCCF\uDCFA-\uDFDF\uDFE7\uDFEC\uDFEF\uDFFF]|\uD83A[\uDCC5\uDCC6\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDD5D\uDD60-\uDFFF]|\uD83B[\uDC00-\uDC70\uDCB5-\uDD00\uDD3E-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCC0\uDCD0\uDCF6-\uDCFF\uDDAE-\uDDE5\uDE03-\uDE0F\uDE3C-\uDE3F\uDE49-\uDE4F\uDE52-\uDE5F\uDE66-\uDEFF]|\uD83D[\uDED8-\uDEDB\uDEED-\uDEEF\uDEFD-\uDEFF\uDF77-\uDF7A\uDFDA-\uDFDF\uDFEC-\uDFEF\uDFF1-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE\uDCAF\uDCB2-\uDCFF\uDE54-\uDE5F\uDE6E\uDE6F\uDE7D-\uDE7F\uDE89-\uDE8F\uDEBE\uDEC6-\uDECD\uDEDC-\uDEDF\uDEE9-\uDEEF\uDEF9-\uDEFF\uDF93\uDFCB-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEE0-\uDEFF]|\uD86D[\uDF3A-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDF4F]|\uD888[\uDFB0-\uDFFF]|\uDB40[\uDC00\uDC02-\uDC1F\uDC80-\uDCFF\uDDF0-\uDFFF]|[\uDBBF\uDBFF][\uDFFE\uDFFF]/;var Xr=524288,pt=921600;var zr=8192,Jr=128,Wr=16384,Yr=131072;var Kr=Xr;var Zr=4294967295,Qr=8,gt=8,en=16,tn=3600,rn="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";var Co=Object.freeze({object_bytes:pt,read_bytes:Kr,control_bytes:Wr,reply_bytes:Yr,writers:Qr,retentions:gt,grants:en,grant_seconds:tn});function D(e,t){if(!e)throw ht(t)}function M(e,t,r=[]){D(typeof e==="object"&&e!==null&&!Array.isArray(e),"expected JSON object");let n=e;return D(t.every((o)=>Object.hasOwn(n,o)),"required field is absent"),D(Object.keys(n).every((o)=>t.includes(o)||r.includes(o)),"unknown field"),n}function V(e,t=Number.MAX_SAFE_INTEGER,r=0){D(typeof e==="number"&&Number.isSafeInteger(e)&&e>=r&&e<=t,"integer outside its bound")}function L(e,t,r=0){D(typeof e==="string"&&Buffer.from(e).toString("utf8")===e,"invalid Unicode text"),D(Buffer.byteLength(e)<=t&&Buffer.byteLength(e)>=r,"text outside its byte bound")}function mt(e){D(typeof e==="string"&&/^[A-Za-z0-9_-]{43}$/.test(e),"invalid content identity");let t=Buffer.from(e,"base64url");D(t.length===32&&t.toString("base64url")===e,"noncanonical content identity")}function ve(e,t){D(typeof e==="string"&&/^[A-Z2-7]{56}$/.test(e),"invalid public NKEY");let r="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",n=0,o=0,i=[];for(let s of e)if(o=o<<5|r.indexOf(s),n+=5,n>=8)n-=8,i.push(o>>>n&255);D(i.length===35&&i[0]===(t==="account"?0:160),"wrong NKEY kind");let a=0;for(let s of i.slice(0,33)){a^=s<<8;for(let f=0;f<8;f++)a=(a<<1^(a&32768?4129:0))&65535}D(i[33]===(a&255)&&i[34]===a>>>8,"NKEY checksum differs")}function nn(e){let t=M(e,["account","user"]);ve(t.account,"account"),ve(t.user,"user")}function Dt(e){L(e,255,1),D(e!=="."&&e!==".."&&!/[\x00-\x1f\x7f/]/.test(e),"forbidden entry name"),D(on(e)===e,"entry name is not NFC")}function on(e){let t="",r="";for(let n of e)if(Gr.test(n))t+=r.normalize("NFC")+n,r="";else r+=n;return t+r.normalize("NFC")}function an(e,t=4096){if(L(e,t,1),D(e.startsWith("/"),"path must be absolute"),e==="/")return;let r=e.slice(1).split("/");D(r.length<=Jr,"path exceeds its depth bound");for(let n of r)Dt(n)}function vt(e){D(typeof e==="string"&&/^[0-9A-Za-z]{1,64}$/.test(e),"invalid volume name")}function yt(e){let t=M(e,["volume","creation_id"]);vt(t.volume),D(typeof t.creation_id==="string"&&/^[0-9a-f]{32}$/.test(t.creation_id),"invalid volume creation identity")}function sn(e){let t=M(e,[],["thread_id","root_id","tool_call_id"]);for(let r of["thread_id","root_id"])if(t[r]!==void 0)L(t[r],32);if(t.tool_call_id!==void 0)L(t.tool_call_id,1024),D([...t.tool_call_id].length<=256,"tool-call label is too long");if(!t.thread_id&&!t.root_id&&!t.tool_call_id)return;D(typeof t.thread_id==="string"&&/^[0-9a-f]{32}$/.test(t.thread_id),"invalid trace thread"),D(typeof t.root_id==="string"&&/^[0-9a-f]{32}$/.test(t.root_id),"invalid trace root")}function Ft(e){let t=M(e,["operation_id","trace"]);L(t.operation_id,256,1),D([...t.operation_id].length<=64,"operation identity is too long"),sn(t.trace)}function cn(e){let t=M(e,["slot","generation"]);V(t.slot,gt-1),V(t.generation,void 0,1)}function bt(e,t){if(e===t)return!0;if(!e||!t||typeof e!=="object"||typeof t!=="object")return!1;let r=e,n=t;return Object.keys(r).length===Object.keys(n).length&&Object.keys(r).every((o)=>Object.hasOwn(n,o)&&bt(r[o],n[o]))}function un(e){let t=M(e,["slot","generation","operation_id"]);V(t.slot,Zr),V(t.generation,void 0,1),Ft({operation_id:t.operation_id,trace:{}})}function dn(e,t=!0){let r=JSON.stringify(e);return D(r!==void 0,"value cannot be encoded as JSON"),r=r.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029"),t?r.replace(/</g,"\\u003c").replace(/>/g,"\\u003e").replace(/&/g,"\\u0026"):r}function ln(e,t){let r=typeof e==="string"?Buffer.from(e):Buffer.from(e);D(r.length<=t,"JSON exceeds its byte bound");let n=new TextDecoder("utf-8",{fatal:!0}).decode(r),o=0,i=()=>{while(/[\t\n\r ]/.test(n[o]??"!"))o++},a=()=>{let l=o++;for(;;){D(o<n.length,"unterminated JSON string");let v=n[o++];if(v==="\\"){o++;continue}if(v==='"')break}let h=JSON.parse(n.slice(l,o));return L(h,t),h},s=(l)=>{D(l<=64,"JSON nesting exceeds bound"),i();let h=n[o];if(h==='"')return a();if(h==="{"){o++,i();let g=Object.create(null);if(n[o]==="}")return o++,g;for(;;){D(n[o]==='"',"JSON key must be a string");let p=a();i(),D(!Object.hasOwn(g,p),"duplicate JSON key"),D(n[o++]===":","missing JSON colon"),g[p]=s(l+1),i();let m=n[o++];if(m==="}")return g;D(m===",","invalid JSON object separator"),i()}}if(h==="["){o++,i();let g=[];if(n[o]==="]")return o++,g;for(;;){g.push(s(l+1)),i();let p=n[o++];if(p==="]")return g;D(p===",","invalid JSON array separator"),i()}}for(let[g,p]of[["true",!0],["false",!1],["null",null]])if(n.startsWith(g,o))return o+=g.length,p;let v=/^-?(?:0|[1-9][0-9]*)/.exec(n.slice(o));D(v,"invalid JSON value"),o+=v[0].length;let _=Number(v[0]);return D(Number.isSafeInteger(_)&&!Object.is(_,-0),"unsafe or noncanonical JSON integer"),_},f=s(0);return i(),D(o===n.length,"trailing JSON data"),f}var fn=class extends Error{constructor(e,t){super(t);this.reason=e,this.name="CodecError"}reason};function I(e,t){throw new fn(e,t)}function hn(e,t){return tt("sha256").update(e).update("\x00").update(t).digest("base64url")}function pn(e){return hn("scratchpad:v1:tree",e)}function X(e,t){if(V(t),t<24)return Buffer.from([e<<5|t]);if(t<=255)return Buffer.from([e<<5|24,t]);if(t<=65535){let n=Buffer.alloc(3);return n[0]=e<<5|25,n.writeUInt16BE(t,1),n}if(t<=4294967295){let n=Buffer.alloc(5);return n[0]=e<<5|26,n.writeUInt32BE(t,1),n}let r=Buffer.alloc(9);return r[0]=e<<5|27,r.writeBigUInt64BE(BigInt(t),1),r}function gn(e){return Buffer.concat([X(2,e.length),e])}function U(e){let t=Buffer.from(e);return Buffer.concat([X(3,t.length),t])}function mn(e){if(typeof e!=="string"||Buffer.from(e).toString("utf8")!==e)I("utf8","invalid entry name UTF-8");if(Buffer.byteLength(e)===0||Buffer.byteLength(e)>255)I("name-length","entry name length exceeds bound");if(e==="."||e===".."||/[\x00-\x1f\x7f/]/.test(e))I("name-forbidden","forbidden entry name");try{Dt(e)}catch{I("not-nfc","entry name is not NFC")}}function Dn(e){if(mn(e.name),e.type==="symlink"){if(e.executable||e.object!==void 0&&e.object!==rn)I("type-invalid","symlink has file fields");let t=e.linkTarget??"";if(typeof t!=="string"||Buffer.from(t).toString("utf8")!==t)I("utf8","invalid symlink UTF-8");if(Buffer.byteLength(t)===0||Buffer.byteLength(t)>4096||t.includes("\x00"))I("target-invalid","invalid symlink target")}else{if(e.type!=="file"&&e.type!=="directory")I("type-invalid","unknown entry type");if(mt(e.object),e.linkTarget||e.type==="directory"&&e.executable)I("type-invalid","entry has fields of another type")}}function vn(e){for(let o of e)Dn(o);let t=[...e].sort((o,i)=>Buffer.compare(Buffer.from(o.name),Buffer.from(i.name)));for(let o=1;o<t.length;o++)if(t[o].name===t[o-1].name)I("duplicate-name","duplicate tree entry");if(e.length>zr)I("entry-count","tree entry count exceeds bound");let r=[X(5,1),U("e"),X(4,e.length)],n=r.reduce((o,i)=>o+i.length,0);for(let o of t){let i=[X(5,o.executable?4:3)];if(o.type==="symlink")i.push(U("l"),U(o.linkTarget));else i.push(U("i"),gn(Buffer.from(o.object,"base64url")));if(i.push(U("n"),U(o.name),U("t"),X(0,o.type==="file"?0:o.type==="directory"?1:2)),o.executable)i.push(U("x"),X(0,1));if(n+=i.reduce((a,s)=>a+s.length,0),n>pt)I("node-size","tree node byte count exceeds bound");r.push(...i)}return Buffer.concat(r)}pn(vn([]));function wt(e){let t=M(e,["version","creator","account","target","root","generation","path","retention","expires_at"]);D(t.version===2,"reference version must be two"),L(t.creator,512,1),ve(t.account,"account"),yt(t.target),mt(t.root),V(t.generation,void 0,1),an(t.path,256),cn(t.retention),V(t.expires_at,void 0,1)}function yn(e){wt(e);let t={version:2,creator:e.creator,account:e.account,target:{volume:e.target.volume,creation_id:e.target.creation_id},root:e.root,generation:e.generation,path:e.path,retention:{slot:e.retention.slot,generation:e.retention.generation},expires_at:e.expires_at},r="sp-ref:"+Buffer.from(dn(t,!1)).toString("base64url");return D(Buffer.byteLength(r)<=16384,"reference exceeds byte bound"),r}var ye="sp-r1:",ce=66;function Et(e){L(e,ce,ce),D(/^sp-r1:[A-Za-z0-9_-]{60}$/.test(e),"malformed short reference");let t=Buffer.from(e.slice(ye.length),"base64url");D(t.length===45&&t[32]<64,"invalid short reference slots");let r=Number(t.readBigUInt64BE(24));V(r,void 0,1);let n={route:t.subarray(0,8).toString("hex"),creation_id:t.subarray(8,24).toString("hex"),retention:{slot:t[32]>>3,generation:r},path_index:t[32]&7};return yt({volume:"Reference",creation_id:n.creation_id}),n}function Fn(e,t){return tt("sha256").update(`scratchpad-reference-volume-v1\x00${e}\x00${t}`).digest().subarray(0,8).toString("hex")}function bn(e){let t=M(e,["short","expanded"]);L(t.short,ce,ce);let r=Et(t.short);wt(t.expanded),D(r.route===Fn(t.expanded.account,t.expanded.target.volume)&&r.creation_id===t.expanded.target.creation_id&&bt(r.retention,t.expanded.retention),"short reference binding differs")}var Fe=4096;function wn(e){let t=M(ln(e,Fe),["version","principal","volume","admission","creation"]);return D(t.version===1,"unsupported ScratchPad bootstrap version"),nn(t.principal),vt(t.volume),un(t.admission),Ft(t.creation),t}function At(e){D(typeof e==="string"&&e.length>0,"bootstrap file path is required");let t;try{t=ar(e,fe.O_RDONLY|fe.O_NONBLOCK|(fe.O_NOFOLLOW??0));let r=sr(t);D(r.isFile(),"bootstrap must be a regular file"),D(r.size<=Fe,"bootstrap exceeds its byte bound");let n=Buffer.alloc(Fe+1),o=0;while(o<n.length){let i=cr(t,n,o,n.length-o,o);if(i===0)break;o+=i}return wn(n.subarray(0,o))}catch(r){if(r instanceof ft)throw r;throw ht("cannot read ScratchPad bootstrap file",r)}finally{if(t!==void 0)ur(t)}}var En="sp",An=600,ze=600,_n=5,Je=16,Cn=16384,_t=16777216,Sn=Math.ceil(_t/3)*4+65536,Rn=262144,Bn=65536,Ct=/^A[A-Z2-7]{55}$/,St=/^[0-9A-Za-z]{1,64}$/,kn=/^[0-9a-f]{32}$/,xn=/^[A-Za-z0-9_-]{43}$/,Tn=/^[A-Za-z0-9_-]+$/,On=/^[A-Za-z0-9+/]*={0,2}$/,F=class extends Error{constructor(e,t,r){super(e);this.code=t,this.unknown=r,this.name="ScratchPadError"}code;unknown},k=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),ue=(e,t)=>Object.keys(e).length===t.length&&t.every((r)=>(r in e)),Q=(e)=>Number.isSafeInteger(e)&&e>0,Rt=(e)=>Buffer.byteLength(e,"utf8");function Bt(e){return k(e)&&ue(e,["volume","creation_id"])&&typeof e.volume==="string"&&St.test(e.volume)&&typeof e.creation_id==="string"&&kn.test(e.creation_id)}function In(e){if(typeof e!=="string"||!e.startsWith("/")||Rt(e)>256)return!1;if(e==="/")return!0;return e.slice(1).split("/").every((t)=>t!==""&&t!=="."&&t!=="..")}function pe(e){let t=(a)=>{throw Error(`malformed ScratchPad reference: ${a}`)};if(typeof e!=="string"||!e.startsWith(ie))t("no sp-ref: prefix");if(e.length>Cn)t("longer than 16 KiB");let r=e.slice(ie.length);if(!Tn.test(r)||r.length%4===1)t("not unpadded base64url");let n;try{n=JSON.parse(Buffer.from(r,"base64url").toString("utf8"))}catch{t("not JSON")}let o=["version","creator","account","target","root","generation","path","retention","expires_at"];if(!k(n)||!ue(n,o))return t("not the version 2 fields");let i=n.retention;if(n.version!==2||typeof n.creator!=="string"||n.creator.length===0||Rt(n.creator)>512||typeof n.account!=="string"||!Ct.test(n.account)||!Bt(n.target)||typeof n.root!=="string"||!xn.test(n.root)||!Q(n.generation)||!In(n.path)||!k(i)||!ue(i,["slot","generation"])||!Number.isSafeInteger(i.slot)||i.slot<0||i.slot>7||!Q(i.generation)||!Q(n.expires_at))t("a field is out of shape");return n}var G=()=>Math.floor(Date.now()/1000),We=8,Nn=16,jn=["close","apply","release","grant"],Pn=["workspace","not_found"],z=(e)=>Number.isSafeInteger(e)&&e>=0;function qn(e){let t=(l)=>{throw new F(`sp describe: ${l}`,"malformed_reply",!1)};if(!k(e)||!k(e.volume))return t("the reply names no volume");let{volume:r,control:n}=e,o;if(n!==null&&n!==void 0){if(!k(n)||typeof n.kind!=="string"||!jn.includes(n.kind))return t("the saved control request is out of shape");o=n.kind}if(typeof r.closed!=="boolean")return t("the volume names no closed state");let{retentions:i,grants:a}=r;if(!Array.isArray(i)||i.length!==We)return t("not eight retention slots");if(!Array.isArray(a)||a.length!==Nn)return t("not sixteen grant slots");let s=i.map((l)=>{if(!k(l)||!z(l.generation))return t("a retention slot is out of shape");let h=l.pin;if(h===void 0||h===null)return{generation:l.generation,until:void 0};if(!k(h)||!z(h.until)||typeof h.root!=="string")return t("a retention pin is out of shape");return{generation:l.generation,until:h.until}}),f=[];for(let l of a){if(!k(l)||!z(l.generation))return t("a grant slot is out of shape");let h=l.grant;if(h===void 0||h===null)continue;let v=k(h)?h.retention:void 0;if(!k(h)||!z(h.until)||!k(v)||!z(v.slot)||v.slot>=We||!Q(v.generation))return t("a grant is out of shape");f.push({slot:v.slot,generation:v.generation,until:h.until})}return{closed:r.closed,control:o,retentions:s,grants:f}}function Ln(e){let t=(o)=>{throw new F(`sp spool-remove: ${o}`,"malformed_reply",!1)};if(!k(e)||typeof e.present!=="boolean")return t("the reply says no spool state");let r=e.present,n=["present","files","bytes","removable","applied"];if(r)n.push("phase");if(!ue(e,n)||r&&(typeof e.phase!=="string"||e.phase==="")||!z(e.files)||!z(e.bytes)||typeof e.removable!=="boolean"||typeof e.applied!=="boolean")return t("the spool state is out of shape");return{present:r,removable:e.removable,applied:e.applied}}function $n(e,t=G()){let r=e.control==="close"||e.control==="apply";if(e.closed&&!r)return"the volume is closed, and no cleanup of this agent's is saved";if(r)return;return e.retentions.some((o,i)=>o.until===void 0||o.until!==0&&o.until<=t&&!e.grants.some((a)=>a.slot===i&&a.generation===o.generation&&a.until>t))?void 0:"every retention slot holds a live pin"}function Mn(e){let t=e.bootstrapFile===void 0?void 0:At(e.bootstrapFile),r=e.volume??t?.volume;if(!r||!St.test(r))throw Error("ScratchPad: a valid volume or bootstrap file is required");let n=r;if(t&&t.volume!==n)throw Error("ScratchPad: bootstrap differs from the configured volume");if(t&&!e.dir)throw Error("ScratchPad: bootstrap import requires a persistent dir");if(!("creds"in e.nats)||e.nats.creds===void 0)throw Error("ScratchPad: the sp CLI needs NATS_URL and NATS_CREDS; a NATS context or an nkey seed alone is not supported");let o=["--url",e.nats.url,"--creds",e.nats.creds],i=e.bin??En,a=e.dir??le(tr(),`scratchpad-${n}`),s=Math.min(e.grantTtlS??ze,ze),f,l,h=Promise.resolve(),v=!0,_,g=new Map;function p(c){let d=h.then(c);return h=d.catch(()=>{return}),d}let m=new Map;async function C(c,d){if(!c.startsWith(ye))return pe(c);Et(c);let u=m.get(c);if(u&&u.expires_at>G())return structuredClone(u);let y=await b("resolve",["--ref",c],{trace:d}),S={short:c,expanded:y?.reference};if(bn(S),y.full_reference!==yn(S.expanded))throw new F("sp resolve: expanded token differs from descriptor","malformed_reply",!1);let w=pe(y.full_reference);if(w.expires_at<=G())throw Error("the reference has expired");if(m.delete(c),m.set(c,w),m.size>64)m.delete(m.keys().next().value);return structuredClone(w)}async function x(){return f??=(async()=>(await Qt(a,{recursive:!0,mode:448}),er(a)))(),f}async function b(c,d,u={}){let y=u.trace?["--thread-id",u.trace.threadId,"--root-id",u.trace.rootId]:[];if(u.trace&&u.toolCallId!==void 0)y.push("--tool-call-id",u.toolCallId);let S=["read","resolve"].includes(c)?[]:["--volume",n],w=c==="init"&&e.bootstrapFile?["--bootstrap-file",e.bootstrapFile]:[],j=[c,...o,"--dir",await x(),...S,...w,...d,...y],P=u.maxStdout??Rn,{code:E,stdout:q,stderr:R}=await new Promise((O)=>{Zt(i,j,{maxBuffer:Math.max(P,Bn),encoding:"utf8"},(Gt,Xt,zt)=>{let Y=Gt;O({code:Y===null?0:typeof Y.code==="number"?Y.code:null,stdout:Xt??"",stderr:zt||(Y!==null&&typeof Y.code==="string"?Y.message:"")})}).stdin?.end(u.stdin??"")});if(E===null&&/^spawn .*(ENOENT|EACCES)/m.test(R))throw new F(`sp ${c}: ${R.trim()}`,"spawn_failed",!1);if(E===0&&q.length<=P)try{return JSON.parse(q)}catch{}let B={code:E===0?"malformed_reply":"failed",message:R.trim().slice(0,512)||`exit ${E??"by signal"}`,unknown:u.mutation===!0};if(E!==0)try{let O=JSON.parse(R).error;if(k(O)&&typeof O.code==="string")B={code:O.code,message:typeof O.message==="string"?O.message:"",unknown:O.unknown===!0||u.mutation===!0&&typeof O.unknown!=="boolean"}}catch{}throw new F(`sp ${c}: ${B.code}${B.unknown?" (outcome unknown)":""}: ${B.message}`,B.code,B.unknown)}function J(c,d){let u=c,y=u?.principal?.account;if(typeof y!=="string"||!Ct.test(y)||!Bt(u.target))throw new F(`sp ${d}: the reply names no principal and target`,"malformed_reply",!1);if(u.target.volume!==n)throw new F(`sp ${d}: the workspace is bound to another volume`,"invalid",!1);return{account:y,target:{volume:u.target.volume,creation_id:u.target.creation_id}}}async function ne(c){return l??=J(await b("init",[],{trace:c,mutation:!0}),"init"),l}async function W(c){if(l!==void 0)return l;try{l=J(await b("describe",[],{trace:c}),"describe")}catch(d){if(d instanceof F&&Pn.includes(d.code))return;throw d}return l}let N=(c,d)=>d!==void 0&&c.account===d.account&&c.target.volume===d.target.volume&&c.target.creation_id===d.target.creation_id,xe=(c,d)=>JSON.stringify([c.account,c.target.volume,c.target.creation_id,c.root,c.path,d.account,d.user]);function Lt(){let c=G();for(let[d,u]of g)if(Math.max(u["first-hand"]??0,u["on-request"]??0)<=c)g.delete(d)}function Te(c,d,u){g.set(c,{...g.get(c),[d]:u})}function $t(c,d){let u=c;if(!k(u)||!k(u.handle)||!Q(u.expires_at))throw new F("sp grant: the reply names no handle and expiry","malformed_reply",!0);return Math.min(u.expires_at,d.expires_at)}async function Oe(c,d,u,y){return b("publish-file",["--source","-","--path",d,"--operation-id",u,"--creator",e.creator,"--ttl-seconds",String(An)],{trace:y,stdin:c,mutation:!0})}async function Ie(c){if(!v)return;try{await b("recover",[],{trace:c,mutation:!0})}catch(d){if(!(d instanceof F)||d.unknown)throw d}v=!1}async function Mt(c,d){let u;try{let y=Ln(await b("spool-remove",["--apply"],{trace:d,mutation:!0}));if(!y.present||y.applied)return;u="the refused publication's spool is protected"}catch(y){if(y instanceof F&&y.unknown)throw y;u=`its spool was not removed: ${y.message}`}throw v=!0,new F(`${c.message}; cleanup not started: ${u}`,c.code,!1)}async function Ut(c){return qn(await b("describe",[],{trace:c}))}async function Ht(c,d,u){if(e.creator===void 0)throw Error("ScratchPad: a reference names its creator; this ScratchPad was made without one");let y=await ne(u);await Ie(u);let S=je(),w;try{w=await Oe(c,d,S,u)}catch(E){if(E instanceof F&&E.unknown)v=!0;if(!(E instanceof F)||E.code!=="capacity"||E.unknown)throw E;await Mt(E,u);let q;try{q=$n(await Ut(u))}catch(R){throw new F(`${E.message}; cleanup not started: ${R.message}`,E.code,!1)}if(q!==void 0)throw new F(`${E.message}; cleanup not started: ${q}`,E.code,!1);try{await b("maintain",["--apply"],{trace:u,mutation:!0})}catch(R){v=!0;let B=!(R instanceof F)||R.unknown;throw new F(`${E.message}; cleanup: ${R.message}`,B&&R instanceof F?R.code:B?"failed":E.code,B)}try{w=await Oe(c,d,S,u)}catch(R){if(R instanceof F&&R.unknown)v=!0;throw R}}let j=w?.reference;if(typeof j!=="string"||!k(w.receipt))throw v=!0,new F("sp publish-file: the reply names no receipt and reference","malformed_reply",!0);let P=await C(j,u);if(!N(P,y)||P.path!==d||P.creator!==e.creator)throw new F("sp publish-file: the reference names another volume, path or creator","malformed_reply",!1);return j}async function Ne(c,d,u,y){return $t(await b("grant",c,{trace:d,toolCallId:u,mutation:!0}),y)}async function Vt(c,d,u,y,S){let w=await C(c,u);if(!N(w,await W(u)))throw Error("the reference points into another agent's volume; only its creator can grant read on it");if(await Ie(u),_!==void 0){let B=_;try{Te(B.key,B.kind,await Ne(B.args,void 0,void 0,B.ref)),_=void 0}catch(O){if(!(O instanceof F)||O.unknown)throw O;_=void 0}}let j=w.expires_at-G()-_n,P=Math.floor(Math.min(s,j));if(P<1)throw Error("the reference has expired, or is about to; there is nothing left to grant on");let E=xe(w,d);if(Lt(),!g.has(E)&&g.size>=Je)throw Error(`this agent already holds ${Je} live grants; try again when one expires`);let q=u?["--thread-id",u.threadId,"--root-id",u.rootId]:[];if(u&&y!==void 0)q.push("--tool-call-id",y);let R=["--ref",c,"--grantee-account",d.account,"--grantee-user",d.user,"--operation-id",je(),"--ttl-seconds",String(P)];try{Te(E,S,await Ne(R,u,y,w))}catch(B){if(B instanceof F&&B.unknown)_={args:[...R,...q],key:E,kind:S,ref:w};throw B}}return{commit(c,d,u){return p(()=>Ht(c,d,u))},async read(c,d){if((await C(c,d)).expires_at<=G())throw Error("the reference has expired");let y=await b("read",["--ref",c],{trace:d,maxStdout:Sn}),{data_base64:S,bytes:w}=y??{};if(typeof S!=="string"||!On.test(S)||!Number.isSafeInteger(w)||w>_t)throw new F("sp read: the reply carries no data","malformed_reply",!1);let j=Buffer.from(S,"base64");if(j.length!==w||j.toString("base64")!==S)throw new F("sp read: the data does not match its length","malformed_reply",!1);try{return new TextDecoder("utf-8",{fatal:!0}).decode(j)}catch{throw Error("the referenced file is not UTF-8 text")}},resolveReference:C,async owns(c){let d;try{d=await C(c)}catch{return!1}return N(d,await W(H()))},grantRead(c,d,u,y,S="first-hand"){return p(()=>Vt(c,d,u,y,S))},granted(c,d){let u=(y)=>{if(!N(y,l))return;let S=g.get(xe(y,d)),w=G();if((S?.["first-hand"]??0)>w)return"first-hand";if((S?.["on-request"]??0)>w)return"on-request";return};if(c.startsWith(ye))return C(c).then(u,()=>{return});try{return u(pe(c))}catch{return}}}}var Un="SCRATCHPAD_VOLUME",Hn="SCRATCHPAD_BOOTSTRAP_FILE",Vn="SCRATCHPAD_BIN",Gn="SCRATCHPAD_DIR";var Xn=409;function zn(e){return`the agent's model is waiting inside a prompt of this tree (root ${e}); a prompt of the same tree cannot be served until that call returns`}function Jn(e){if(typeof e!=="object"||e===null||Array.isArray(e))return;let t=e.open_calls;if(t===void 0)return 0;return typeof t==="number"&&Number.isInteger(t)&&t>=0?t:void 0}function Wn(e){return(typeof e==="object"||typeof e==="function")&&e!==null&&typeof e.then==="function"}function kt(){let e=new Map,t=new Map,r=(a)=>{let s=t.get(a);if(s===void 0)return!1;for(let f of s)if(f.waiting)return!0;return!1},n=(a,s)=>{e.set(a,s);let f=t.get(s.rootId);if(f===void 0)t.set(s.rootId,f=new Set);f.add(s)},o=(a,s)=>{if(e.get(a)===s)e.delete(a);let f=t.get(s.rootId);if(f===void 0)return;if(f.delete(s),f.size===0)t.delete(s.rootId)},i=(a,s,f)=>{a.running-=1;let l=s?Jn(f):void 0;if(l===void 0)return;if(a.open=l,a.running===0&&a.open===0)a.waiting=!1};return{requestInterceptor:{async aroundRequest(a,s){let f=H();if(f===void 0){await s();return}let{rootId:l}=f;if(r(l))throw new ee(Xn,zn(l));let h={rootId:l,waiting:!1,running:0,open:0};n(f,h);try{await s()}finally{o(f,h)}}},promptInterceptor:{beforePrompt(){let a=H(),s=a===void 0?void 0:e.get(a);if(s!==void 0)s.waiting=!0}},aroundToolCall(a,s){let f=a===void 0?void 0:e.get(a);if(f===void 0)return s();f.running+=1;let l;try{l=s()}catch(h){throw i(f,!1),h}if(Wn(l))l.then((h)=>i(f,!0,h),()=>i(f,!1));else i(f,!0,l);return l},open(a){let s={rootId:a.rootId,waiting:!1,running:0,open:0};n(a,s);let f=!1;return()=>{if(f)return;f=!0,o(a,s)}},serving:(a)=>t.has(a),waiting:r}}var Yn=Symbol.for("synadia.fabric.scratchpad.workspace-owners.v1"),Kn=globalThis,So=Kn[Yn]??=new Set;var Ye="edgeSubject",Zn="SYNADIA_FABRIC_EDGE_SUBJECT";function xt(e,t=process.env){if(Object.hasOwn(e,Ye))return e[Ye];let r=t[Zn];if(r!==void 0)return r;return rt}var Tt="scratchpad",A={url:"SP_NATS_URL",creds:"SP_NATS_CREDS",dir:Gn,volume:Un,bootstrapFile:Hn,creator:"SP_CREATOR",threadId:"SP_THREAD_ID",rootId:"SP_ROOT_ID",callerAccount:"SP_CALLER_ACCOUNT",callerUser:"SP_CALLER_USER",grants:"SP_GRANTS_FILE"},Qn=["NATS_CREDS","NATS_CREDENTIALS"];async function Ce(e,t,r={}){let n=e.logger,o=e.options[Tt],i=o!==null&&typeof o==="object"?o:{},a=(x)=>{let b=i[x];return typeof b==="string"&&b!==""?b:void 0},s=(x)=>{let b=t[x];return b===void 0||b===""?void 0:b},f=(x,b)=>a(x)??s(b),l=f("bootstrapFile",A.bootstrapFile),h=l===void 0?void 0:$e(ge(l)),v=h===void 0?void 0:At(h),_=f("volume",A.volume)??v?.volume;if(_===void 0)return;if(v&&v.volume!==_)throw Error("ScratchPad bootstrap differs from the configured volume");let g=a("url"),p=a("creds");if(g===void 0||p===void 0){let x=s("NATS_URL"),b;for(let N of r.credsVariables??Qn)if(b=s(N),b!==void 0)break;let J=t.NATS_CONTEXT,ne=J!==void 0||x!==void 0||b!==void 0,W=J?J:ne?void 0:Z(e.settings.config.context);if(W!==void 0)try{let{fields:N}=await Qe(W);g??=Z(N.url),p??=Z(N.creds)}catch(N){n.warn(`agent-fabric: ScratchPad is off: the NATS context "${W}" could not be read (${String(N)})`);return}else if(ne)g??=x,p??=b}if(g??=Z(e.settings.config.url),p??=Z(e.settings.config.credentials),g===void 0||p===void 0){n.warn("agent-fabric: ScratchPad is off: sp needs a NATS URL and a credentials file (options.scratchpad; else NATS_CONTEXT naming a context with both; else NATS_URL and NATS_CREDS or NATS_CREDENTIALS; else the plugin's NATS context with both; or url and credentials in the plugin's configuration)");return}let m=f("dir",A.dir);if(m===void 0&&e.settings.stateDir!==void 0)m=le(e.settings.stateDir,"scratchpad");if(v&&m===void 0)throw Error("ScratchPad bootstrap requires a persistent workspace directory");if(m!==void 0){m=$e(ge(m));try{rr(m,{recursive:!0,mode:448})}catch(x){n.warn(`agent-fabric: ScratchPad workspace ${m} could not be created (${String(x)})`)}}let C=m!==void 0?`${m}.grants`:void 0;if(C!==void 0)to(C,n);return{url:g,creds:ge(p),volume:_,...h===void 0?{}:{bootstrapFile:h},...m!==void 0?{dir:m}:{},...C!==void 0?{grants:C}:{}}}function Se(e,t){if(t[A.url]=e.url,t[A.creds]=e.creds,e.bootstrapFile!==void 0)t[A.bootstrapFile]=e.bootstrapFile,delete t[A.volume];else t[A.volume]=e.volume,delete t[A.bootstrapFile];if(e.dir!==void 0)t[A.dir]=e.dir;if(e.grants!==void 0)t[A.grants]=e.grants}var Re=class{constructor(e){this.env=e}env;#e;enter(e,t){if(this.#t(),this.#e=e.id,t!==void 0)this.env[A.threadId]=t.threadId,this.env[A.rootId]=t.rootId;if(e.caller!==void 0)try{let r=te(e.caller);this.env[A.callerAccount]=r.account,this.env[A.callerUser]=r.user}catch{}}leave(e){if(this.#e===e.id)this.#t(),this.#e=void 0}#t(){delete this.env[A.threadId],delete this.env[A.rootId],delete this.env[A.callerAccount],delete this.env[A.callerUser]}};function Ot(e,t){let r=e[Vn];if(r!==void 0&&r!=="")return r;let n=Pe()==="darwin"?"darwin":Pe()==="linux"?"linux":void 0,o=qe()==="arm64"?"arm64":qe()==="x64"?"amd64":void 0;if(n===void 0||o===void 0)return;return le(t,"bin",`sp-${n}-${o}`)}var Be=class{#e;#t;#r=[];requestInterceptor={aroundRequest:(e,t)=>{if(this.#e===void 0)this.#r.push(e.envelope.prompt);else this.#e.remember(e.envelope.prompt);return t()}};start(e){let{scratchPad:t,agents:r,service:n}=e;this.#t=t,this.#e=Hr({scratchPad:t,agents:r});for(let a of this.#r.splice(0))this.#e.remember(a);if(n===void 0)return;let o=e.logger??de,i=$r({promptAddress:n.subject.prompt,scratchPad:t,logger:o});try{n.service.addEndpoint(i.name,{subject:i.subject,...i.queue!==void 0?{queue:i.queue}:{},handler:i.handler})}catch(a){o.warn(`agent-fabric: grant requests are not answered: ${String(a)}`)}}discoveryFields(e){return this.#e?.discoveryFields(e)??{[lt]:De(e.metadata)}}async beforePrompt(e){let t=this.#e,r=this.#t;if(t===void 0||r===void 0){if(ae(e.prompt).length===0)return;return{error:"the prompt was not sent: ScratchPad is not ready yet; try again in a moment"}}for(let n of new Set(ae(e.prompt)))if(await r.owns(n))t.remember(n);return t.beforePrompt(e)}afterReply(e){this.#e?.afterReply(e)}};function It(e,t,r,n){let o=Ot(r,n);if(o===void 0)return;let i=Mn({volume:e.volume,...e.bootstrapFile===void 0?{}:{bootstrapFile:e.bootstrapFile},nats:{url:e.url,creds:e.creds},bin:o,creator:t,...e.dir!==void 0?{dir:e.dir}:{}});return e.grants!==void 0?ro(i,e.grants):i}var eo=/^(\d+) (\S+) (\S+) (sp-(?:ref|r1):[A-Za-z0-9_-]+)$/;function Nt(e){let t;try{t=nr(e,"utf8")}catch{return[]}let r=[];for(let n of t.split(`
|
|
4
|
+
`)){let o=eo.exec(n);if(o===null)continue;r.push({expiresAt:Number(o[1]),grantee:{account:o[2],user:o[3]},reference:o[4]})}return r}function to(e,t){let r=Math.floor(Date.now()/1000),n=Nt(e).filter((o)=>o.expiresAt>r);try{let o=`${e}.${process.pid}.tmp`;or(o,n.map((i)=>`${i.expiresAt} ${i.grantee.account} ${i.grantee.user} ${i.reference}
|
|
5
|
+
`).join(""),{mode:384}),ir(o,e)}catch(o){t.warn(`agent-fabric: ScratchPad grants file ${e} could not be written (${String(o)})`)}}function ro(e,t,r=()=>Date.now()/1000){return{...e.resolveReference?{resolveReference:(n,o)=>e.resolveReference(n,o)}:{},owns:(n)=>e.owns(n),grantRead:(n,o,i,a,s)=>e.grantRead(n,o,i,a,s),async granted(n,o){let i=await e.granted(n,o);if(i==="first-hand")return i;let a=r();return Nt(t).some((f)=>f.reference===n&&f.grantee.account===o.account&&f.grantee.user===o.user&&f.expiresAt>a)?"first-hand":i}}}function Z(e){return typeof e==="string"&&e!==""?e:void 0}function ge(e){if(e==="~")return Le();if(e.startsWith("~/"))return le(Le(),e.slice(2));return e}import{fileURLToPath as no}from"node:url";var oo=no(new URL("../skill/scratchpad",import.meta.url));function jt(e,t,r){return It(e,t,r,oo)}var K="agent-fabric",Pt=`${K}: senderIdentity is off; trace records are signed, so none will be published and each counts as dropped on the heartbeat. Set senderIdentity to signed.`;async function ke(e,t=process.env){return qt(e,t,await Ce(e,t))}function qt(e,t=process.env,r){let n=xt(e.options,t),o=st({edgeSubject:n}),i=kt(),a=e.logger,s=new Map,f=(p)=>p===void 0?void 0:s.get(p.id),l=new Map,h=!1,v=r!==void 0,_=new Re(t);if(r!==void 0)Se(r,t);let g=r!==void 0?new Be:void 0;return{name:K,requestInterceptors:[o.requestInterceptor,i.requestInterceptor,...g!==void 0?[g.requestInterceptor]:[]],promptInterceptors:[o.promptInterceptor,i.promptInterceptor],heartbeatExtras:o.heartbeatExtras,...g!==void 0?{toolExtensions:[g],metadata:{[_e]:"true"}}:{},started({agents:p,service:m}){if(e.settings.senderIdentity!=="signed"&&!h)h=!0,a.warn(Pt);if(a.info(`${K}: tracing ${m.subject.prompt}`+(n===null?" (propagate-only: lineage forwarded, no edge record published)":`, edge records on ${n}`)),r!==void 0&&g!==void 0){t[A.creator]=m.subject.prompt;let C=jt(r,m.subject.prompt,t);if(C!==void 0)g.start({scratchPad:C,agents:p,service:m,logger:a});else a.warn(`${K}: no sp for this platform (set SCRATCHPAD_BIN); references in prompt_agent are not handed on, and grant requests not answered`);a.info(`${K}: ScratchPad volume ${r.volume}`+(r.dir!==void 0?`, workspace ${r.dir}`:", no workspace")+", for the skill's scripts/sp")}},events:{promptAccepted(p){let m=H();if(m!==void 0)s.set(p.id,m)},promptEnded(p){s.delete(p.id),_.leave(p)},localTurnStarted(p){l.get(p.id)?.();let m=Ee();if(s.set(p.id,m),l.set(p.id,i.open(m)),v)_.enter(p,m)},localTurnEnded(p){s.delete(p.id),l.get(p.id)?.(),l.delete(p.id),_.leave(p)},aroundInject(p,m){let C=s.get(p.id);if(v)_.enter(p,C);return C===void 0?m():re(C,m)},providerHeaders(p){let m=s.get(p.id);return m===void 0?void 0:re(m,at)},aroundToolCall(p,m,C){let x=f(p);return x===void 0?C():re(x,()=>i.aroundToolCall(x,C))}}}}export{ke as default};
|
package/dist/nats-channel.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{a as Qe,b as Q,c as K,d as lt,e as Ut,h as ze,k as le,l as fe,m as be,n as Ke,o as Ve,p as qe,q as Me,r as Ye,s as de,t as Ge,u as ce,x as Je,y as Xe,z as We}from"./chunk-sjpe67s3.js";var z=Q(function(U){var ft=U&&U.__createBinding||(Object.create?function(e,t,n,r){if(r===void 0)r=n;var o=Object.getOwnPropertyDescriptor(t,n);if(!o||("get"in o?!t.__esModule:o.writable||o.configurable))o={enumerable:!0,get:function(){return t[n]}};Object.defineProperty(e,r,o)}:function(e,t,n,r){if(r===void 0)r=n;e[r]=t[n]}),pt=U&&U.__exportStar||function(e,t){for(var n in e)if(n!=="default"&&!Object.prototype.hasOwnProperty.call(t,n))ft(t,e,n)};Object.defineProperty(U,"__esModule",{value:!0});pt(lt(),U)});var Ee=Q(function(me){Object.defineProperty(me,"__esModule",{value:!0});me.version=void 0;me.version="3.4.0"});var we=Q(function(O){var gt=O&&O.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(O,"__esModule",{value:!0});O.NodeTransport=O.VERSION=void 0;O.nodeResolveHost=vt;var E=z(),yt=K("node:net"),re=K("node:tls"),mt=K("node:path"),Te=K("node:fs"),ht=gt(K("node:dns")),Et=Ee();O.VERSION=Et.version;var Tt="nats.js";class ve{socket;version;lang;yields=[];signal=(0,E.deferred)();closedNotification=(0,E.deferred)();options;connected=!1;tlsName="";done=!1;closeError;constructor(){this.lang=Tt,this.version=O.VERSION}async connect(e,t){this.tlsName=e.tlsName,this.options=t;let{tls:n}=this.options,{handshakeFirst:r}=n||{};try{if(r===!0)this.socket=await this.tlsFirst(e);else this.socket=await this.dial(e);if(this.done)this.socket?.destroy();let o=await this.peekInfo();(0,E.checkOptions)(o,t);let{tls_required:s,tls_available:f}=o,c=f===!0&&t.tls!==null;if(!r&&(s||c))this.socket=await this.startTLS();if(this.done)this.socket?.destroy();if(s&&this.socket.encrypted!==!0)throw E.errors.InvalidArgumentError.format("tls","is not available on this server");return this.connected=!0,this.setupHandlers(),this.signal.resolve(),Promise.resolve()}catch(o){let s=o;if(!s)s=new E.errors.ConnectionError("error connecting - node provided an undefined error");let{code:f}=s,c=f==="ECONNREFUSED"?new E.errors.ConnectionError("connection refused",{cause:s}):s;throw this.socket?.destroy(),c}}dial(e){let t=(0,E.deferred)(),n,r=(0,yt.createConnection)(e.port,e.hostname,()=>{t.resolve(r),r.removeAllListeners()});return r.on("error",(o)=>{n=o}),r.on("close",()=>{r.removeAllListeners(),t.reject(n)}),r.setNoDelay(!0),t}get isClosed(){return this.done}close(e){return this._closed(e,!1)}peekInfo(){let e=(0,E.deferred)(),t;return this.socket.on("data",(n)=>{this.yields.push(n);let r=E.DataBuffer.concat(...this.yields),o=(0,E.extractProtocolMessage)(r);if(o!=="")try{let s=E.INFO.exec(o);if(!s)throw Error("unexpected response from server");let f=JSON.parse(s[1]);e.resolve(f)}catch(s){e.reject(s)}finally{this.socket.removeAllListeners()}}),this.socket.on("error",(n)=>{t=n}),this.socket.on("close",()=>{this.socket.removeAllListeners(),e.reject(t)}),e}loadFile(e){if(!e)return Promise.resolve();let t=(0,E.deferred)();try{if(e=(0,mt.resolve)(e),!(0,Te.existsSync)(e))t.reject(Error(`${e} doesn't exist`));(0,Te.readFile)(e,(n,r)=>{if(n)return t.reject(n);t.resolve(r)})}catch(n){t.reject(n)}return t}async loadClientCerts(){let e={},{certFile:t,cert:n,caFile:r,ca:o,keyFile:s,key:f}=this.options.tls;try{if(t){let c=await this.loadFile(t);if(c)e.cert=c}else if(n)e.cert=n;if(s){let c=await this.loadFile(s);if(c)e.key=c}else if(f)e.key=f;if(r){let c=await this.loadFile(r);if(c)e.ca=[c]}else if(o)e.ca=o;return Promise.resolve(e)}catch(c){return Promise.reject(c)}}async tlsFirst(e){let t,n={servername:this.tlsName,rejectUnauthorized:!0};if(this.socket)n.socket=this.socket;if(typeof this.options.tls==="object")try{let o=await this.loadClientCerts()||{};n=(0,E.extend)(n,this.options.tls,o)}catch(o){return Promise.reject(new E.errors.ConnectionError(o.message,{cause:o}))}let r=(0,E.deferred)();try{let o=(0,re.connect)(e.port,e.hostname,n,()=>{o.removeAllListeners(),r.resolve(o)});o.on("error",(s)=>{t=s}),o.on("secureConnect",()=>{if(n.rejectUnauthorized===!1)return;if(!o.authorized)throw o.authorizationError}),o.on("close",()=>{r.reject(t),o.removeAllListeners()}),o.setNoDelay(!0)}catch(o){r.reject(new E.errors.ConnectionError(o.message,{cause:o}))}return r}async startTLS(){let e,t={socket:this.socket,servername:this.tlsName,rejectUnauthorized:!0};if(typeof this.options.tls==="object")try{let r=await this.loadClientCerts()||{};t=(0,E.extend)(t,this.options.tls,r)}catch(r){return Promise.reject(new E.errors.ConnectionError(r.message,{cause:r}))}let n=(0,E.deferred)();try{let r=(0,re.connect)(t,()=>{r.removeAllListeners(),n.resolve(r)});r.on("error",(o)=>{e=o}),r.on("secureConnect",()=>{if(t.rejectUnauthorized===!1)return;if(!r.authorized)throw r.authorizationError}),r.on("close",()=>{n.reject(e),r.removeAllListeners()})}catch(r){n.reject(new E.errors.ConnectionError(r.message,{cause:r}))}return n}setupHandlers(){let e;this.socket.on("data",(t)=>(this.yields.push(t),this.signal.resolve())),this.socket.on("error",(t)=>{e=t}),this.socket.on("end",()=>{if(this.socket?.destroyed)return;this.socket?.write(new Uint8Array(0),()=>{this.socket?.end()})}),this.socket.on("close",()=>{this._closed(e,!1)})}[Symbol.asyncIterator](){return this.iterate()}async*iterate(){while(!0){if(this.yields.length===0)await this.signal;let e=this.yields;this.yields=[];for(let t=0;t<e.length;t++){if(this.options.debug)console.info(`> ${(0,E.render)(e[t])}`);yield e[t]}if(this.done)break;else if(this.yields.length===0)e.length=0,this.yields=e,this.signal=(0,E.deferred)()}}discard(){if(this.done=!0,this.socket)try{this.socket.removeAllListeners(),this.socket.destroy()}catch{}}disconnect(){this._closed(void 0,!0).then().catch()}isEncrypted(){return this.socket instanceof re.TLSSocket}_send(e){if(this.isClosed||this.socket===void 0)return Promise.resolve();if(this.options.debug)console.info(`< ${(0,E.render)(e)}`);let t=(0,E.deferred)();try{this.socket.write(e,(n)=>{if(n){if(this.options.debug)console.error(`!!! ${(0,E.render)(e)}: ${n}`);return t.reject(n)}return t.resolve()})}catch(n){if(this.options.debug)console.error(`!!! ${(0,E.render)(e)}: ${n}`);t.reject(n)}return t}send(e){this._send(e).catch((n)=>{})}async _closed(e,t=!0){if(!this.connected)return;if(this.done){this.socket?.destroy();return}if(this.closeError=e,!e&&this.socket&&t)try{await this._send(new TextEncoder().encode(""))}catch(n){if(this.options.debug)console.log("transport close terminated with an error",n)}try{if(this.socket)this.socket.removeAllListeners(),this.socket?.destroy(),this.socket=void 0}catch(n){console.log(n)}this.done=!0,this.closedNotification.resolve(this.closeError)}closed(){return this.closedNotification}}O.NodeTransport=ve;function vt(e){let t=(0,E.deferred)();return ht.default.lookup(e,{all:!0},(n,r)=>{if(n){t.reject(n);return}let o=[];for(let s of r)o.push(s.address);if(o.length===0)o.push(e);t.resolve(o)}),t}});var _e=Q(function(Ne){Object.defineProperty(Ne,"__esModule",{value:!0});Ne.connect=wt;var Se=we(),Ae=z(),xe=z();function wt(e={}){if((0,xe.hasWsProtocol)(e))return Promise.reject(xe.errors.InvalidArgumentError.format("servers","node client doesn't support websockets, use the 'wsconnect' function instead"));return(0,Ae.setTransportFactory)({factory:()=>new Se.NodeTransport,dnsResolveFn:Se.nodeResolveHost}),Ae.NatsConnectionImpl.connect(e)}});var Pe=Q(function(M){var At=M&&M.__createBinding||(Object.create?function(e,t,n,r){if(r===void 0)r=n;var o=Object.getOwnPropertyDescriptor(t,n);if(!o||("get"in o?!t.__esModule:o.writable||o.configurable))o={enumerable:!0,get:function(){return t[n]}};Object.defineProperty(e,r,o)}:function(e,t,n,r){if(r===void 0)r=n;e[r]=t[n]}),xt=M&&M.__exportStar||function(e,t){for(var n in e)if(n!=="default"&&!Object.prototype.hasOwnProperty.call(t,n))At(t,e,n)};Object.defineProperty(M,"__esModule",{value:!0});M.connect=void 0;var Nt=_e();Object.defineProperty(M,"connect",{enumerable:!0,get:function(){return Nt.connect}});xt(z(),M)});var nt=Qe(Pe(),1),rt=Qe(Ut(),1);import{mkdirSync as Ze,readFileSync as et,rmSync as Ht,writeFileSync as tt}from"node:fs";import{homedir as Ft}from"node:os";import{basename as Bt,join as B}from"node:path";import{randomUUID as Qt}from"node:crypto";import{existsSync as se,readFileSync as _t,statSync as Pt}from"node:fs";import{isAbsolute as Rt,join as J}from"node:path";import{pathToFileURL as $t}from"node:url";var bt="SYNADIA_PI_EXTENSIONS",It="SYNADIA_AGENT_EXTENSIONS",oe=Object.freeze({});function F(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Ie(e,t=process.env,n=()=>{return}){for(let o of[bt,It]){let s=t[o];if(s===void 0)continue;let f=s.split(",").map((c)=>c.trim()).filter((c)=>c.length>0).map((c)=>({module:c,options:oe}));return{source:o,entries:f}}if(e===void 0||e===null)return{source:"none",entries:[]};if(!Array.isArray(e))return n("extensions: the config field must be an array of module specifiers or { module, options } objects; ignored"),{source:"none",entries:[]};let r=[];return e.forEach((o,s)=>{if(typeof o==="string"){let f=o.trim();if(f.length===0){n(`extensions[${s}]: empty specifier; ignored`);return}r.push({module:f,options:oe});return}if(F(o)&&typeof o.module==="string"){let f=o.module.trim();if(f.length===0){n(`extensions[${s}]: empty "module"; ignored`);return}let c=o.options;if(c!==void 0&&!F(c)){n(`extensions[${s}]: "options" must be an object; ignored`);return}r.push({module:f,options:c===void 0?oe:Object.freeze({...c})});return}n(`extensions[${s}]: expected a module specifier or { module, options }; ignored`)}),{source:"config",entries:r}}function kt(e){let t=e.trim();if(t.length===0)throw Error("empty module specifier");if(Rt(t)){if(!se(t))throw Error(`${t}: no such file or directory`);return $t(Pt(t).isDirectory()?Ct(t):t).href}if(t.startsWith(".")||t.startsWith("~")||/^[A-Za-z]:[\\/]/.test(t))throw Error(`${t}: relative paths are refused; name a package or give an absolute path`);return t}function Ct(e){let t=J(e,"package.json");if(!se(t))throw Error(`${e}: a directory must hold a package.json`);let n;try{n=JSON.parse(_t(t,"utf8"))}catch(o){throw Error(`${t}: ${o.message}`)}let r=jt(n.exports)??Ot(n.main);if(r!==void 0)return J(e,r);for(let o of["index.js","index.mjs","index.cjs"])if(se(J(e,o)))return J(e,o);throw Error(`${e}: package.json names no entry (exports or main)`)}function Ot(e){return typeof e==="string"&&e.length>0?e:void 0}function jt(e){if(e===void 0)return;let t=(n)=>{if(typeof n==="string")return n;if(!F(n))return;return t(n.import)??t(n.default)};if(typeof e==="string")return e;if(!F(e))return;if("."in e)return t(e["."]);return t(e)}async function ke(e,t,n){let r=[];for(let o of e)try{let c=(await import(kt(o.module))).default;if(typeof c!=="function")throw Error("the module has no default export function");let T=await c({...t,options:o.options});if(!F(T))throw Error("the factory returned no extension object");let w=typeof T.name==="string"&&T.name.length>0?T.name:o.module;r.push({module:o.module,name:w,extension:T})}catch(s){n.error(`extension "${o.module}" not loaded: ${H(s)}`)}return r}var qt=5000,Re=new Set(["agent","owner","protocol_version","session",...Object.values(be)]),Mt=/^[A-Za-z0-9_.-]+$/;class X extends Error{name="ExtensionMetadataError"}function H(e){return e instanceof Error?e.message:String(e)}function $e(e){return(typeof e==="object"||typeof e==="function")&&e!==null&&typeof e.then==="function"}function Lt(e,t,n){let r={},o=new Map;for(let s of e){let f=s.extension.metadata;if(f===void 0)continue;if(!F(f))throw new X(`extension "${s.name}": metadata must be an object of string values`);for(let[c,T]of Object.entries(f)){if(!Mt.test(c))throw new X(`extension "${s.name}": metadata key ${JSON.stringify(c)} is invalid; a key is one or more of A-Z, a-z, 0-9, "_", "-" and "."`);if(typeof T!=="string")throw new X(`extension "${s.name}": metadata ${JSON.stringify(c)} must be a string, got ${T===null?"null":typeof T}`);if(Re.has(c)||t.has(c)){n.warn(`extension "${s.name}": metadata ${JSON.stringify(c)} is set by the ${Re.has(c)?"protocol":"plugin"}; the extension's value is ignored`);continue}let w=o.get(c);if(w!==void 0)n.warn(`extension "${s.name}": metadata ${JSON.stringify(c)} replaces the value of extension "${w}"`);r[c]=T,o.set(c,s.name)}}return Object.freeze(r)}function ie(e,t,n={}){let r=n.hookTimeoutMs??qt,o=new Set,s=(a,l)=>{if(o.has(a))return;o.add(a),t.warn(l)},f=(a)=>e.filter((l)=>typeof l.extension.events?.[a]==="function"),c=(a,l)=>{for(let h of f(a))try{l(h.extension.events[a])}catch(g){s(`${h.name}:${a}`,`extension "${h.name}" ${a} failed: ${H(g)}`)}},T=(a,l,h,g)=>{let m=`${l.name}:${a}`,x=!1,S,k=!1,C,R=()=>{if(x){if(s(`${m}:twice`,`extension "${l.name}" ${a} called run more than once, or after the plugin had run the step itself; the extra call was ignored`),k)throw C;return S}x=!0;try{return S=g(),S}catch(N){throw k=!0,C=N,N}},v;try{v=h(R)}catch(N){if(k&&N===C)throw N;if(s(m,`extension "${l.name}" ${a} failed: ${H(N)}`),!x)return R();if(k)throw C;return S}if(k)throw C;if(!x)return s(m,`extension "${l.name}" ${a} returned without calling run; the plugin ran the step itself`),R();if(!$e(S)&&!$e(v)&&v!==S)s(`${m}:value`,`extension "${l.name}" ${a} did not return run's value; the plugin used run's`);return S},w=(a,l,h)=>{let g=h,m=f(a);for(let x=m.length-1;x>=0;x--){let S=m[x],k=g;g=()=>T(a,S,(C)=>l(S,C),k)}return g()},j=async(a,l,h)=>{let g;try{await Promise.race([Promise.resolve().then(h),new Promise((m)=>{g=setTimeout(()=>{s(`${a.name}:${l}:timeout`,`extension "${a.name}" ${l}() did not finish within ${r} ms; continuing without it`),m()},r),g.unref?.()})])}catch(m){s(`${a.name}:${l}`,`extension "${a.name}" ${l}() failed: ${H(m)}`)}finally{if(g!==void 0)clearTimeout(g)}},D=e.filter((a)=>typeof a.extension.heartbeatExtras==="function"),Y=D.length===0?void 0:()=>{let a={};for(let l of D)try{Object.assign(a,l.extension.heartbeatExtras())}catch(h){s(`${l.name}:heartbeatExtras`,`extension "${l.name}" heartbeatExtras failed: ${H(h)}`)}return a},q=Lt(e,new Set(n.pluginMetadataKeys??[]),t);return{loaded:e,names:e.map((a)=>a.name),promptInterceptors:e.flatMap((a)=>[...a.extension.promptInterceptors??[]]),requestInterceptors:e.flatMap((a)=>[...a.extension.requestInterceptors??[]]),heartbeatExtras:Y,toolExtensions:e.flatMap((a)=>[...a.extension.toolExtensions??[]]),metadata:q,async started(a){await Promise.all(e.filter((l)=>typeof l.extension.started==="function").map((l)=>j(l,"started",()=>l.extension.started(a))))},async stopping(){await Promise.all(e.filter((a)=>typeof a.extension.stopping==="function").map((a)=>j(a,"stopping",()=>a.extension.stopping())))},events:{promptAccepted(a){c("promptAccepted",(l)=>l(a))},promptEnded(a,l,h){c("promptEnded",(g)=>g(a,l,h))},aroundInject(a,l){return w("aroundInject",(h,g)=>h.extension.events.aroundInject(a,g),l)},providerHeaders(a){let l={};for(let h of f("providerHeaders"))try{let g=h.extension.events.providerHeaders(a);if(!g)continue;for(let[m,x]of Object.entries(g))if(typeof x==="string")l[m]=x}catch(g){s(`${h.name}:providerHeaders`,`extension "${h.name}" providerHeaders failed: ${H(g)}`)}return l},aroundToolCall(a,l,h){return w("aroundToolCall",(g,m)=>g.extension.events.aroundToolCall(a,l,m),h)}}}}class ae{#t=new Map;#n=[];#e=null;#o=0;get size(){return this.#t.size}get queuedCount(){return this.#n.filter((e)=>this.#t.has(e)).length}get active(){return this.#e===null?void 0:this.#t.get(this.#e)}enqueue(e,t,n=Date.now()){let r=String(++this.#o),o,s,f=new Promise((j,D)=>{o=j,s=D}),c=t.sender,T=Object.freeze({id:r,extras:Object.freeze({...e.extras??{}}),...c?.trust==="verified"?{caller:String(c.id)}:{}}),w={id:r,prompt:e.prompt,attachments:e.attachments??[],response:t,createdAt:n,completion:f,served:T,settled:!1,resolve:o,reject:s};return this.#t.set(r,w),this.#n.push(r),w}takeNext(){if(this.#e!==null)return;while(this.#n.length>0){let e=this.#n.shift(),t=this.#t.get(e);if(!t)continue;return this.#e=e,t}return}requeueActive(){if(this.#e===null)return;let e=this.#e;if(this.#e=null,this.#t.has(e))this.#n.unshift(e)}completeActive(){if(this.#e===null)return;let e=this.#t.get(this.#e);if(this.#t.delete(this.#e),this.#e=null,e)this.#s(e);return e}failActive(e){if(this.#e===null)return;let t=this.#t.get(this.#e);if(this.#t.delete(this.#e),this.#e=null,t)this.#r(t,e);return t}expireQueued(e){let t=[];for(let[n,r]of this.#t){if(n===this.#e||r.createdAt>=e)continue;this.#t.delete(n),this.#r(r,Error("PI prompt expired while waiting in the local queue")),t.push(r)}return t}failAll(e){let t=[...this.#t.values()];this.#t.clear(),this.#n.length=0,this.#e=null;for(let n of t)this.#r(n,Error(e));return t}#s(e){if(e.settled)return;e.settled=!0,e.resolve()}#r(e,t){if(e.settled)return;e.settled=!0,e.reject(t)}}function V(e){return e.replace(/[^a-zA-Z0-9_-]/g,"-").toLowerCase().replace(/^-+|-+$/g,"")}function Ce(...e){return V(e.find((t)=>t!=null)??"unknown")||"unknown"}var Oe=["blocking","all","off"],je="NATS_AGENT_TOOLS";function Le(e,t=process.env){let n=t[je]??e.agentTools;if(n===void 0||n==="")return"blocking";if(Oe.includes(n))return n;throw Error(`${je}/agentTools must be one of ${Oe.join(", ")}; got ${JSON.stringify(n)}`)}function De(e){switch(e){case"blocking":return Me;case"all":return qe;case"off":return}}function Dt(e){let t=e.replace(/_/g," ");return t.charAt(0).toUpperCase()+t.slice(1)}function Ue(e,t,n){let r=[];for(let o of t.definitions){let s=o.name;e.registerTool({name:s,label:Dt(s),description:o.description,parameters:o.parameters,async execute(f,c,T){let w=await n.aroundToolCall(n.activeRequest(),s,()=>t.execute(s,c,{toolCallId:f,...T?{signal:T}:{}}));return{content:[{type:"text",text:JSON.stringify(w)}],details:w}}}),r.push(s)}return r}var He="0.4.0",zt="@synadia-ai/nats-pi-channel",Kt=Vt();function Vt(){try{let e=JSON.parse(et(new URL("../package.json",import.meta.url),"utf8"));return typeof e.version==="string"?e.version:"unknown"}catch{return"unknown"}}var Yt=5,ue="pi",Gt=["cwd"],Jt=ze(Xe),Xt=20,Wt=1800000,Z=B(Ft(),".pi","agent"),ot=B(Z,"nats-channel.json"),Fe=B(Z,"attachments"),Zt="demo.nats.io";function W(e,t,n,r){if(t===void 0||t==="")return n;if(r.includes(t))return t;throw Error(`${e} must be one of ${r.join(", ")}; got ${JSON.stringify(t)}`)}function en(e,t=process.env){let n=t.NATS_CONTEXT??e.context,r=t.NATS_URL,o=t.NATS_CREDS||t.NATS_CREDENTIALS;if(!n&&o&&!r)throw Error("NATS_CREDS/NATS_CREDENTIALS is set without NATS_URL: set NATS_URL to the server the credentials are for");return{source:n?{context:n}:o?{url:r,creds:o}:{url:r||Zt},contextLabel:n??(r?"$NATS_URL":"default"),senderIdentity:W("NATS_SENDER_IDENTITY/senderIdentity",t.NATS_SENDER_IDENTITY??e.senderIdentity,"off",["off","signed"]),minSenderTrust:W("NATS_MIN_SENDER_TRUST/minSenderTrust",t.NATS_MIN_SENDER_TRUST??e.minSenderTrust,"any",["any","signed"])}}function Be(){try{return JSON.parse(et(ot,"utf8"))}catch{return{}}}function tn(e){Ze(Z,{recursive:!0}),tt(ot,`${JSON.stringify(e,null,2)}
|
|
2
|
-
`,"utf8")}function
|
|
3
|
-
${
|
|
1
|
+
import{a as Re,b as un,c as cn,f as $e,i as se,j as ie,k as fe,l as Pe,m as Ie,n as he,o as Ee,p as _e,q as te,r as Ce,s as re,v as be,w as Oe,x as ke}from"./chunk-9jcwbjk5.js";var je=Re(un(),1),De=Re(cn(),1);import{mkdirSync as Le,readFileSync as Me,rmSync as ln,writeFileSync as qe}from"node:fs";import{homedir as fn}from"node:os";import{basename as pn,join as M}from"node:path";import{randomUUID as gn}from"node:crypto";import{existsSync as W,readFileSync as Ge,statSync as Je}from"node:fs";import{isAbsolute as Ve,join as F}from"node:path";import{pathToFileURL as Xe}from"node:url";var We="SYNADIA_PI_EXTENSIONS",Ze="SYNADIA_AGENT_EXTENSIONS",X=Object.freeze({});function U(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function pe(e,n=process.env,r=()=>{return}){for(let u of[We,Ze]){let s=n[u];if(s===void 0)continue;let p=s.split(",").map((f)=>f.trim()).filter((f)=>f.length>0).map((f)=>({module:f,options:X}));return{source:u,entries:p}}if(e===void 0||e===null)return{source:"none",entries:[]};if(!Array.isArray(e))return r("extensions: the config field must be an array of module specifiers or { module, options } objects; ignored"),{source:"none",entries:[]};let a=[];return e.forEach((u,s)=>{if(typeof u==="string"){let p=u.trim();if(p.length===0){r(`extensions[${s}]: empty specifier; ignored`);return}a.push({module:p,options:X});return}if(U(u)&&typeof u.module==="string"){let p=u.module.trim();if(p.length===0){r(`extensions[${s}]: empty "module"; ignored`);return}let f=u.options;if(f!==void 0&&!U(f)){r(`extensions[${s}]: "options" must be an object; ignored`);return}a.push({module:p,options:f===void 0?X:Object.freeze({...f})});return}r(`extensions[${s}]: expected a module specifier or { module, options }; ignored`)}),{source:"config",entries:a}}function en(e){let n=e.trim();if(n.length===0)throw Error("empty module specifier");if(Ve(n)){if(!W(n))throw Error(`${n}: no such file or directory`);return Xe(Je(n).isDirectory()?nn(n):n).href}if(n.startsWith(".")||n.startsWith("~")||/^[A-Za-z]:[\\/]/.test(n))throw Error(`${n}: relative paths are refused; name a package or give an absolute path`);return n}function nn(e){let n=F(e,"package.json");if(!W(n))throw Error(`${e}: a directory must hold a package.json`);let r;try{r=JSON.parse(Ge(n,"utf8"))}catch(u){throw Error(`${n}: ${u.message}`)}let a=rn(r.exports)??tn(r.main);if(a!==void 0)return F(e,a);for(let u of["index.js","index.mjs","index.cjs"])if(W(F(e,u)))return F(e,u);throw Error(`${e}: package.json names no entry (exports or main)`)}function tn(e){return typeof e==="string"&&e.length>0?e:void 0}function rn(e){if(e===void 0)return;let n=(r)=>{if(typeof r==="string")return r;if(!U(r))return;return n(r.import)??n(r.default)};if(typeof e==="string")return e;if(!U(e))return;if("."in e)return n(e["."]);return n(e)}async function ge(e,n,r){let a=[];for(let u of e)try{let f=(await import(en(u.module))).default;if(typeof f!=="function")throw Error("the module has no default export function");let h=await f({...n,options:u.options});if(!U(h))throw Error("the factory returned no extension object");let S=typeof h.name==="string"&&h.name.length>0?h.name:u.module;a.push({module:u.module,name:S,extension:h})}catch(s){r.error(`extension "${u.module}" not loaded: ${D(s)}`)}return a}var on=5000,ce=new Set(["agent","owner","protocol_version","session",...Object.values(fe)]),sn=/^[A-Za-z0-9_.-]+$/;class K extends Error{name="ExtensionMetadataError"}function D(e){return e instanceof Error?e.message:String(e)}function le(e){return(typeof e==="object"||typeof e==="function")&&e!==null&&typeof e.then==="function"}function an(e,n,r){let a={},u=new Map;for(let s of e){let p=s.extension.metadata;if(p===void 0)continue;if(!U(p))throw new K(`extension "${s.name}": metadata must be an object of string values`);for(let[f,h]of Object.entries(p)){if(!sn.test(f))throw new K(`extension "${s.name}": metadata key ${JSON.stringify(f)} is invalid; a key is one or more of A-Z, a-z, 0-9, "_", "-" and "."`);if(typeof h!=="string")throw new K(`extension "${s.name}": metadata ${JSON.stringify(f)} must be a string, got ${h===null?"null":typeof h}`);if(ce.has(f)||n.has(f)){r.warn(`extension "${s.name}": metadata ${JSON.stringify(f)} is set by the ${ce.has(f)?"protocol":"plugin"}; the extension's value is ignored`);continue}let S=u.get(f);if(S!==void 0)r.warn(`extension "${s.name}": metadata ${JSON.stringify(f)} replaces the value of extension "${S}"`);a[f]=h,u.set(f,s.name)}}return Object.freeze(a)}function Z(e,n,r={}){let a=r.hookTimeoutMs??on,u=new Set,s=(o,c)=>{if(u.has(o))return;u.add(o),n.warn(c)},p=(o)=>e.filter((c)=>typeof c.extension.events?.[o]==="function"),f=(o,c)=>{for(let T of p(o))try{c(T.extension.events[o])}catch(g){s(`${T.name}:${o}`,`extension "${T.name}" ${o} failed: ${D(g)}`)}},h=(o,c,T,g)=>{let y=`${c.name}:${o}`,v=!1,A,C=!1,b,P=()=>{if(v){if(s(`${y}:twice`,`extension "${c.name}" ${o} called run more than once, or after the plugin had run the step itself; the extra call was ignored`),C)throw b;return A}v=!0;try{return A=g(),A}catch(x){throw C=!0,b=x,x}},E;try{E=T(P)}catch(x){if(C&&x===b)throw x;if(s(y,`extension "${c.name}" ${o} failed: ${D(x)}`),!v)return P();if(C)throw b;return A}if(C)throw b;if(!v)return s(y,`extension "${c.name}" ${o} returned without calling run; the plugin ran the step itself`),P();if(!le(A)&&!le(E)&&E!==A)s(`${y}:value`,`extension "${c.name}" ${o} did not return run's value; the plugin used run's`);return A},S=(o,c,T)=>{let g=T,y=p(o);for(let v=y.length-1;v>=0;v--){let A=y[v],C=g;g=()=>h(o,A,(b)=>c(A,b),C)}return g()},O=async(o,c,T)=>{let g;try{await Promise.race([Promise.resolve().then(T),new Promise((y)=>{g=setTimeout(()=>{s(`${o.name}:${c}:timeout`,`extension "${o.name}" ${c}() did not finish within ${a} ms; continuing without it`),y()},a),g.unref?.()})])}catch(y){s(`${o.name}:${c}`,`extension "${o.name}" ${c}() failed: ${D(y)}`)}finally{if(g!==void 0)clearTimeout(g)}},q=e.filter((o)=>typeof o.extension.heartbeatExtras==="function"),Q=q.length===0?void 0:()=>{let o={};for(let c of q)try{Object.assign(o,c.extension.heartbeatExtras())}catch(T){s(`${c.name}:heartbeatExtras`,`extension "${c.name}" heartbeatExtras failed: ${D(T)}`)}return o},k=an(e,new Set(r.pluginMetadataKeys??[]),n);return{loaded:e,names:e.map((o)=>o.name),promptInterceptors:e.flatMap((o)=>[...o.extension.promptInterceptors??[]]),requestInterceptors:e.flatMap((o)=>[...o.extension.requestInterceptors??[]]),heartbeatExtras:Q,toolExtensions:e.flatMap((o)=>[...o.extension.toolExtensions??[]]),metadata:k,async started(o){await Promise.all(e.filter((c)=>typeof c.extension.started==="function").map((c)=>O(c,"started",()=>c.extension.started(o))))},async stopping(){await Promise.all(e.filter((o)=>typeof o.extension.stopping==="function").map((o)=>O(o,"stopping",()=>o.extension.stopping())))},events:{promptAccepted(o){f("promptAccepted",(c)=>c(o))},promptEnded(o,c,T){f("promptEnded",(g)=>g(o,c,T))},localTurnStarted(o,c){f("localTurnStarted",(T)=>T(o,c))},localTurnEnded(o,c,T){f("localTurnEnded",(g)=>g(o,c,T))},aroundInject(o,c){return S("aroundInject",(T,g)=>T.extension.events.aroundInject(o,g),c)},providerHeaders(o){let c={};for(let T of p("providerHeaders"))try{let g=T.extension.events.providerHeaders(o);if(!g)continue;for(let[y,v]of Object.entries(g))if(typeof v==="string")c[y]=v}catch(g){s(`${T.name}:providerHeaders`,`extension "${T.name}" providerHeaders failed: ${D(g)}`)}return c},aroundToolCall(o,c,T){return S("aroundToolCall",(g,y)=>g.extension.events.aroundToolCall(o,c,y),T)}}}}class ee{#n;#t;#e=0;constructor(e){this.#n=e}get open(){return this.#t}start(){if(this.#t!==void 0||this.#n()!==void 0)return;let e=Object.freeze({id:`local-${++this.#e}`,local:!0});return this.#t=e,e}end(){let e=this.#t;return this.#t=void 0,e}current(){return this.#n()??this.#t}}class ne{#n=new Map;#t=[];#e=null;#o=0;get size(){return this.#n.size}get queuedCount(){return this.#t.filter((e)=>this.#n.has(e)).length}get active(){return this.#e===null?void 0:this.#n.get(this.#e)}enqueue(e,n,r=Date.now()){let a=String(++this.#o),u,s,p=new Promise((O,q)=>{u=O,s=q}),f=n.sender,h=Object.freeze({id:a,extras:Object.freeze({...e.extras??{}}),...f?.trust==="verified"?{caller:String(f.id)}:{}}),S={id:a,prompt:e.prompt,attachments:e.attachments??[],response:n,createdAt:r,completion:p,served:h,settled:!1,resolve:u,reject:s};return this.#n.set(a,S),this.#t.push(a),S}takeNext(){if(this.#e!==null)return;while(this.#t.length>0){let e=this.#t.shift(),n=this.#n.get(e);if(!n)continue;return this.#e=e,n}return}requeueActive(){if(this.#e===null)return;let e=this.#e;if(this.#e=null,this.#n.has(e))this.#t.unshift(e)}completeActive(){if(this.#e===null)return;let e=this.#n.get(this.#e);if(this.#n.delete(this.#e),this.#e=null,e)this.#s(e);return e}failActive(e){if(this.#e===null)return;let n=this.#n.get(this.#e);if(this.#n.delete(this.#e),this.#e=null,n)this.#r(n,e);return n}expireQueued(e){let n=[];for(let[r,a]of this.#n){if(r===this.#e||a.createdAt>=e)continue;this.#n.delete(r),this.#r(a,Error("PI prompt expired while waiting in the local queue")),n.push(a)}return n}failAll(e){let n=[...this.#n.values()];this.#n.clear(),this.#t.length=0,this.#e=null;for(let r of n)this.#r(r,Error(e));return n}#s(e){if(e.settled)return;e.settled=!0,e.resolve()}#r(e,n){if(e.settled)return;e.settled=!0,e.reject(n)}}function H(e){return e.replace(/[^a-zA-Z0-9_-]/g,"-").toLowerCase().replace(/^-+|-+$/g,"")}function me(...e){return H(e.find((n)=>n!=null)??"unknown")||"unknown"}var ye=["blocking","all","off"],Te="NATS_AGENT_TOOLS";function Se(e,n=process.env){let r=n[Te]??e.agentTools;if(r===void 0||r==="")return"blocking";if(ye.includes(r))return r;throw Error(`${Te}/agentTools must be one of ${ye.join(", ")}; got ${JSON.stringify(r)}`)}function Ae(e){switch(e){case"blocking":return Ee;case"all":return he;case"off":return}}function dn(e){let n=e.replace(/_/g," ");return n.charAt(0).toUpperCase()+n.slice(1)}function we(e,n,r){let a=[];for(let u of n.definitions){let s=u.name;e.registerTool({name:s,label:dn(s),description:u.description,parameters:u.parameters,async execute(p,f,h){let S=await r.aroundToolCall(r.activeRequest(),s,()=>n.execute(s,f,{toolCallId:p,...h?{signal:h}:{}}));return{content:[{type:"text",text:JSON.stringify(S)}],details:S}}}),a.push(s)}return a}var ve="0.4.0",mn="@synadia-ai/nats-pi-channel",yn=Tn();function Tn(){try{let e=JSON.parse(Me(new URL("../package.json",import.meta.url),"utf8"));return typeof e.version==="string"?e.version:"unknown"}catch{return"unknown"}}var hn=5,oe="pi",En=["cwd"],Sn=$e(Oe),An=20,wn=1800000,Ue=M(".pi","agent"),Y=M(fn(),Ue),He=M(Y,"nats-channel.json"),vn=M("~",Ue,"nats-channel.json"),xe=M(Y,"attachments"),xn="demo.nats.io";function z(e,n,r,a){if(n===void 0||n==="")return r;if(a.includes(n))return n;throw Error(`${e} must be one of ${a.join(", ")}; got ${JSON.stringify(n)}`)}function Nn(e,n=process.env){let r=n.NATS_URL||void 0,a=n.NATS_CREDS||n.NATS_CREDENTIALS||void 0,u=r!==void 0||a!==void 0,s=n.NATS_CONTEXT!==void 0,p=s?n.NATS_CONTEXT||void 0:u?void 0:e.context||void 0,f=s?"NATS_CONTEXT":vn;if(!p&&a&&!r)throw Error("invalid NATS_CREDS/NATS_CREDENTIALS: set without NATS_URL; set NATS_URL to the server the credentials are for");return{source:p?{context:p}:a?{url:r,creds:a}:{url:r??xn},contextLabel:p?`context ${p} from ${f}${s&&u?", NATS_URL unused":""}`:r?"$NATS_URL":"default",senderIdentity:z("NATS_SENDER_IDENTITY/senderIdentity",n.NATS_SENDER_IDENTITY??e.senderIdentity,"off",["off","signed"]),minSenderTrust:z("NATS_MIN_SENDER_TRUST/minSenderTrust",n.NATS_MIN_SENDER_TRUST??e.minSenderTrust,"any",["any","signed"])}}function Ne(){try{return JSON.parse(Me(He,"utf8"))}catch{return{}}}function Rn(e){Le(Y,{recursive:!0}),qe(He,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,"utf8")}function $n(e){let n=(r,a)=>a&&Object.keys(a).length>0?`NATS: ${r} ${JSON.stringify(a)}`:`NATS: ${r}`;return{debug:()=>{return},info:(r,a)=>e.ui.notify(n(r,a),"info"),warn:(r,a)=>e.ui.notify(n(r,a),"warning"),error:(r,a)=>e.ui.notify(n(r,a),"error")}}async function Pn(e,n,r){let u=new De.Svcm(e).client({strategy:"stall",maxWait:1000,maxMessages:50}),s=new Set;try{let h=await u.info(se);for await(let S of h)for(let O of S.endpoints??[])s.add(O.subject)}catch{}let p=n,f=2;while(s.has(ie.new(oe,r,p).prompt))p=`${n}-${f++}`;return p}function In(e){let n,r,a,u,s,p,f,h,S,O="off",q="any",Q=Sn,k,o,c,T,g,y,v,A,C="blocking",b=[],P,E=Z([],{debug:()=>{return},info:()=>{return},warn:()=>{return},error:()=>{return}}),x=!1,I=new ne,j=new ee(()=>I.active?.served),ae=setInterval(()=>{let l=Date.now();for(let t of I.expireQueued(l-wn))E.events.promptEnded(t.served,"timeout",l)},60000);ae.unref();async function Qe(l,t){if(t.length===0)return;for(let d of be(t,Q,{reserveBytes:256}))await l.response.send({type:"response",text:d})}function G(){if(I.active)return;if(j.open)return;if(!h||!h.isIdle())return;while(I.queuedCount>0){let l=I.takeNext();if(!l)return;let t;try{t=Be(l.prompt,l.attachments)}catch(d){let i=I.failActive(Error(`attachment staging failed: ${d.message}`));if(i)E.events.promptEnded(i.served,"error",Date.now());continue}try{E.events.aroundInject(l.served,()=>e.sendUserMessage(t));return}catch(d){if(I.requeueActive(),h.ui.notify(`NATS: deferred injection (${d.message})`,"warning"),k)clearTimeout(k);k=setTimeout(G,250),k.unref?.();return}}}function Be(l,t){if(t.length===0)return l;if(!s)throw Error("session not initialized");let d=M(xe,s,gn());Le(d,{recursive:!0});let i=[];for(let w of t){let m=M(d,w.filename);qe(m,w.content),i.push(m)}return`[Attachments available at the following absolute paths]
|
|
3
|
+
${i.map((w)=>`- ${w}`).join(`
|
|
4
4
|
`)}
|
|
5
5
|
|
|
6
|
-
${
|
|
6
|
+
${l}`}async function Fe(l,t){try{for await(let d of l.status())switch(d.type){case"disconnect":t.ui.setStatus("nats","NATS: reconnecting…"),t.ui.notify(`NATS disconnected from ${d.server} — retrying…`,"warning");break;case"reconnect":if(u)t.ui.setStatus("nats",`NATS: ${u}`);t.ui.notify(`NATS reconnected to ${d.server}`,"info");break;case"error":t.ui.notify(`NATS error: ${d.error.message}`,"error");break;case"close":if(x)break;t.ui.setStatus("nats","NATS: disconnected"),t.ui.notify("NATS connection closed — agent is off-bus until restart","warning");break}}catch{}}function Ke(){if(x)return Promise.resolve();return new Promise((l)=>{let t=!1,d=()=>{if(t)return;if(t=!0,o)clearTimeout(o);o=void 0,c=void 0,l()};c=d,o=setTimeout(d,2000),o.unref?.()})}async function B(l,t){try{await l.drain()}catch{try{await l.close()}catch{return!1}}return t.wipe(),!0}async function J(l={}){if(x=!0,c?.(),k)clearTimeout(k),k=void 0;if(l.waitForConnectTask!==!1)await T?.catch(()=>{return});let t=Date.now();for(let d of I.failAll("PI session shut down before the prompt completed"))E.events.promptEnded(d.served,"error",t);if(await Promise.resolve(),r)await E.stopping();if(n)try{await n.flush()}catch{}if(r){try{await r.stop()}catch{}r=void 0}if(A){try{await A.close()}catch{}A=void 0}if(b=[],v){try{await v.close()}catch{}v=void 0}if(n&&a){let d=n,i=a;if(await B(d,i)){if(n===d)n=void 0;if(a===i)a=void 0}}else if(n)try{await n.drain(),n=void 0}catch{}if(g&&y){let d=g,i=y;if(await B(d,i)){if(g===d)g=void 0;if(y===i)y=void 0}}else if(!g&&y&&!T)y.wipe(),y=void 0;if(clearInterval(ae),s)try{ln(M(xe,s),{recursive:!0,force:!0})}catch{}h?.ui.setStatus("nats",void 0)}async function ze(l,t,d){let i,R=!1;while(!x&&!i){let m;try{if(m=await te(l.source,{identity:l.senderIdentity}),x){m.wipe();return}y=m;let N=await je.connect(Ce({...m.connectionOptions,name:`pi-${p}`,waitOnFirstConnect:!1,timeout:2000}));if(g=N,x){if(await B(N,m))g=void 0,y=void 0;return}if(i=N,n=N,a=m,g=void 0,y=void 0,i.info?.max_payload)Q=i.info.max_payload}catch(N){if(g&&y){if(!await B(g,y))return;g=void 0,y=void 0}else if(y)y.wipe(),y=void 0;if(x)return;if(!R)t.ui.notify(`NATS connection failed (${S}): ${N.message}; retrying`,"warning"),R=!0;t.ui.setStatus("nats","NATS: connecting…"),await Ke()}}if(!i||x||n!==i)return;try{if(s=await Pn(i,d,p),x||n!==i)return}catch(m){t.ui.notify(`NATS: session name resolution failed: ${m.message}`,"error"),await J({waitForConnectTask:!1});return}let w;try{let m=a?.signer;if(l.senderIdentity==="signed"&&!m)throw Error("signed sender identity resolved without a connection-bound signer");let N=ie.new(oe,p,s).prompt;v=new Pe({nc:i,...P?{logger:P}:{},...m?{identity:{signer:m}}:{},interceptors:E.promptInterceptors});let _=Ae(C);if(_)A=new _e({agents:v,tools:_,selfAddress:N,extensions:E.toolExtensions,...P?{logger:P}:{}});let V=[...E.requestInterceptors,...A?[A.requestInterceptor]:[]],L=new ke({nc:i,agent:oe,owner:p,name:s,session:s,version:ve,description:`PI agent (${s}) in ${t.cwd}`,attachmentsOk:!0,heartbeatIntervalS:hn,keepaliveIntervalS:An,minSenderTrust:l.minSenderTrust,...m?{identity:{signer:m}}:{},...P?{logger:P}:{},interceptors:V,...E.heartbeatExtras?{heartbeatExtras:E.heartbeatExtras}:{},extraMetadata:{...E.metadata,cwd:t.cwd}});if(w=L,L.onPrompt((de,Ye)=>{let ue=I.enqueue(de,Ye);return E.events.promptAccepted(ue.served),G(),ue.completion}),await L.start(),x||n!==i){await L.stop();return}if(r=L,u=L.subject.prompt,f=L.instanceId,A)b=we(e,A,{activeRequest:()=>j.current(),aroundToolCall:E.events.aroundToolCall});await E.started({agents:v,service:L})}catch(m){try{await w?.stop()}catch{}t.ui.notify(`NATS: service registration failed: ${m.message}`,"error"),await J({waitForConnectTask:!1});return}t.ui.setStatus("nats",`NATS: ${u}`),t.ui.notify(`Connected to NATS (${S}) as ${u} (sender_identity=${l.senderIdentity}, min_sender_trust=${l.minSenderTrust}, agent_tools=${C}, extensions=${E.names.join(",")||"none"})`,"info"),Fe(i,t)}e.on("session_start",async(l,t)=>{h=t;let d=Ne(),i;try{i=Nn(d)}catch(_){t.ui.notify(`NATS: ${_.message}`,"error"),t.ui.setStatus("nats","NATS: disconnected");return}S=i.contextLabel,O=i.senderIdentity,q=i.minSenderTrust;try{C=Se(d)}catch(_){t.ui.notify(`NATS: ${_.message}`,"error"),t.ui.setStatus("nats","NATS: disconnected");return}P=$n(t),p=me(process.env.SYNADIA_PI_OWNER,process.env.SYNADIA_OWNER,process.env.NATS_PI_OWNER,d.owner,process.env.USER);let R=H(process.env.SYNADIA_PI_NAME??process.env.SYNADIA_NAME??process.env.NATS_SESSION_NAME??d.sessionName??pn(t.cwd))||"pi",w=pe(d.extensions,process.env,(_)=>P.warn(_));if(w.entries.length>0){let _=await ge(w.entries,{harness:"pi",plugin:{name:mn,version:yn},settings:{owner:p,name:R,senderIdentity:i.senderIdentity,minSenderTrust:i.minSenderTrust,stateDir:Y,config:Object.freeze({...d})},logger:P},P);try{E=Z(_,P,{pluginMetadataKeys:En})}catch(V){t.ui.notify(`NATS: ${V.message}`,"error"),t.ui.setStatus("nats","NATS: disconnected");return}if(x)return}t.ui.setStatus("nats","NATS: connecting…");let m=ze(i,t,R);T=m;let N=()=>{if(T===m)T=void 0};m.then(N,N)}),e.on("message_update",async(l)=>{if(!n)return;let t=l.assistantMessageEvent;if(t.type!=="text_delta"||!t.delta)return;let d=I.active;if(!d)return;try{await Qe(d,t.delta)}catch(i){h?.ui.notify(`NATS: publish failed: ${i.message}`,"warning")}}),e.on("agent_settled",async()=>{let l=j.end();if(l)E.events.localTurnEnded(l,"ok",Date.now());let t=I.completeActive();if(t)E.events.promptEnded(t.served,"ok",Date.now());if(await Promise.resolve(),n)try{await n.flush()}catch{}G()}),e.on("agent_start",()=>{let l=j.start();if(l)E.events.localTurnStarted(l,Date.now())}),e.on("before_provider_headers",(l)=>{let t=j.current();if(!t)return;let d=E.events.providerHeaders(t);for(let[i,R]of Object.entries(d))l.headers[i]=R}),e.on("session_shutdown",async()=>{let l=j.end();if(l)E.events.localTurnEnded(l,"ok",Date.now());await J()}),e.registerCommand("nats-status",{description:"Show NATS channel status",handler:async(l,t)=>{if(!n||!u){t.ui.notify("NATS: not connected","warning");return}let d=I.active,i=[`Connection: ${S}`,`Subject: ${u}`,`Service: ${se} v${ve}`,`Protocol: ${re.major}.${re.minor}`,`Instance: ${f??"?"}`,`Session: ${s}`,`Owner: ${p}`,`Sender identity: ${O}${r?.identity?` (${r.identity})`:""}`,`Minimum sender trust: ${q}`,`Agent tools: ${C}${b.length>0?` (${b.join(", ")})`:""}`,`Extensions: ${E.names.length>0?E.names.join(", "):"none"}`,`Pending: ${I.size}`,`Queued: ${I.queuedCount}`,`Active: ${d?.id??"none"}`,`Active sender: ${d?Ie(d.response.sender):"none"}`].filter(Boolean).join(" • ");t.ui.notify(i,"info")}}),e.registerCommand("nats-configure",{description:"Show or update NATS channel configuration (usage: /nats-configure [ <context> | session <name|clear> | owner <name|clear> | identity <off|signed> | trust <any|signed> ])",handler:async(l,t)=>{let d=Ne(),i=l.trim().split(/\s+/).filter(Boolean);if(i.length===0){let m=[`Context: ${d.context??"(default: demo.nats.io)"}`,`Owner: ${d.owner??"(default: $USER)"}`,`Session: ${d.sessionName??"(auto from cwd)"}`,`Sender identity: ${d.senderIdentity??"off"}`,`Minimum sender trust: ${d.minSenderTrust??"any"}`,`Agent tools: ${d.agentTools??"blocking"}`,`Extensions: ${Array.isArray(d.extensions)&&d.extensions.length>0?d.extensions.map((N)=>typeof N==="string"?N:N.module).join(", "):"(none)"}`];t.ui.notify(`NATS config — ${m.join(" • ")}`,"info");return}let R={...d},w=!1;if(i[0]==="session")if(i[1]==="clear")delete R.sessionName,w=!0;else if(i[1])R.sessionName=H(i[1]),w=!0;else{t.ui.notify("Usage: /nats-configure session <name|clear>","warning");return}else if(i[0]==="owner")if(i[1]==="clear")delete R.owner,w=!0;else if(i[1])R.owner=H(i[1]),w=!0;else{t.ui.notify("Usage: /nats-configure owner <name|clear>","warning");return}else if(i[0]==="identity"){if(!i[1]){t.ui.notify("Usage: /nats-configure identity <off|signed>","warning");return}try{R.senderIdentity=z("senderIdentity",i[1],"off",["off","signed"]),w=!0}catch(m){t.ui.notify(`NATS: ${m.message}`,"warning");return}}else if(i[0]==="trust"){if(!i[1]){t.ui.notify("Usage: /nats-configure trust <any|signed>","warning");return}try{R.minSenderTrust=z("minSenderTrust",i[1],"any",["any","signed"]),w=!0}catch(m){t.ui.notify(`NATS: ${m.message}`,"warning");return}}else{let m=i[0],N;try{N=await te({context:m})}catch(_){t.ui.notify(`NATS: ${_.message}`,"error");return}finally{N?.wipe()}R.context=m,w=!0}if(!w){t.ui.notify("NATS: no changes","info");return}try{Rn(R)}catch(m){t.ui.notify(`NATS: failed to save config: ${m.message}`,"error");return}t.ui.notify("NATS config updated. Restart PI for changes to take effect.","info")}})}export{hn as HEARTBEAT_INTERVAL_S,In as default,Nn as resolveConnectionSettings};
|
package/package.json
CHANGED
|
@@ -25,7 +25,7 @@ shell command can then allow `scripts/sp` by its path, and does not ask.
|
|
|
25
25
|
the NATS server, this agent's credentials, its workspace, its volume on
|
|
26
26
|
`init`, the trace of the prompt you are serving, your address as the
|
|
27
27
|
creator of what you publish, and the agent that prompted you as the grantee
|
|
28
|
-
of a grant. Never pass `--url`, `--creds`, `--dir`, `--volume`,
|
|
28
|
+
of a grant. Never pass `--url`, `--creds`, `--dir`, `--volume`, `--bootstrap-file`,
|
|
29
29
|
`--thread-id`, `--root-id`, `--creator`, `--grantee-account` or
|
|
30
30
|
`--grantee-user` yourself; `scripts/sp` refuses them.
|
|
31
31
|
|
|
@@ -38,8 +38,8 @@ The workspace is private to this agent and persists across restarts.
|
|
|
38
38
|
Each successful command prints JSON.
|
|
39
39
|
Read the returned receipt before reporting that publication succeeded.
|
|
40
40
|
An upload alone does not publish a checkpoint.
|
|
41
|
-
Retention preserves the root
|
|
42
|
-
|
|
41
|
+
Retention preserves the root for its recorded promise.
|
|
42
|
+
A finite deadline permits later cleanup by the client or the private lifecycle worker.
|
|
43
43
|
A grant separately permits one authenticated principal to read that root and path.
|
|
44
44
|
Do not print credential contents.
|
|
45
45
|
|
|
@@ -67,13 +67,27 @@ An expired reference or refused grant does not authorize another identity or pat
|
|
|
67
67
|
|
|
68
68
|
```sh
|
|
69
69
|
scripts/sp info
|
|
70
|
-
scripts/sp init
|
|
70
|
+
scripts/sp init
|
|
71
71
|
scripts/sp describe
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
`info` returns this agent's authenticated principal, owned scope allowances, and request limits.
|
|
75
75
|
It needs no initialized workspace and changes no recovery state.
|
|
76
76
|
The scope byte and object figures are configured allowances; `describe` shows current usage.
|
|
77
|
+
|
|
78
|
+
### Import the configured bootstrap
|
|
79
|
+
|
|
80
|
+
When `SCRATCHPAD_BOOTSTRAP_FILE` is configured, the wrapper supplies it on `init`.
|
|
81
|
+
The public file selects one volume, admission binding, and complete saved creation Action.
|
|
82
|
+
It contains no credentials and supplies no authentication authority.
|
|
83
|
+
Run `scripts/sp init` without inventing a creation operation identifier.
|
|
84
|
+
Keep both the file and the private workspace across restarts.
|
|
85
|
+
An exact matching import preserves existing commands, writer state, and unknown outcomes.
|
|
86
|
+
A different creation request refuses; an `exists` result never permits adoption.
|
|
87
|
+
Saved creation recovery uses the owner's connection and does not need admin ensure.
|
|
88
|
+
An expiry or closed refusal alone does not settle an earlier possibly sent creation.
|
|
89
|
+
An explicit later admission needs a separate workspace; never erase the earlier one to continue.
|
|
90
|
+
A configured custom volume must match the file. Unsupported command lines refuse the import.
|
|
77
91
|
An empty scope list needs an operator admission check before this agent can publish.
|
|
78
92
|
Volumes readable through another owner's grant are not listed; their granted references can still be read.
|
|
79
93
|
If `info` reports an unknown command, an older binary was selected; continue with the existing commands and ask the operator for the allowances.
|
|
@@ -82,6 +96,10 @@ If `info` reports an unknown command, an older binary was selected; continue wit
|
|
|
82
96
|
Rerun the saved creation action after an unknown outcome.
|
|
83
97
|
An established writer whose journal disappeared requires an explicit reset.
|
|
84
98
|
Initialization cannot silently reset that writer.
|
|
99
|
+
For a reusable lifetime, `info` also returns its admission binding.
|
|
100
|
+
`init` saves that binding before its first creation request and reuses it after a restart.
|
|
101
|
+
A saved creation cannot adopt a later admission with the same volume name.
|
|
102
|
+
Preserve the workspace after a refusal; do not erase it to bypass lifetime fencing.
|
|
85
103
|
|
|
86
104
|
## Publish a file and share it with the agent that prompted you
|
|
87
105
|
|
|
@@ -193,9 +211,12 @@ scripts/sp maintain --apply
|
|
|
193
211
|
```
|
|
194
212
|
|
|
195
213
|
The first command reports the proposed maintenance.
|
|
196
|
-
The second releases unprotected expired pins
|
|
214
|
+
The second releases unprotected expired pins and closes a collection interval.
|
|
215
|
+
On a reusable deployment, private maintenance traces retained dependencies,
|
|
216
|
+
collects unreachable objects and reopens that interval. The client observes its completion.
|
|
217
|
+
On an existing deployment, the client performs that collection.
|
|
197
218
|
Maintenance does not scrub retained file payloads.
|
|
198
|
-
If interrupted, recover the saved request
|
|
219
|
+
If interrupted, recover the saved request. A newer collection interval fences that request.
|
|
199
220
|
Capacity refusal requires maintenance or an explicit operator decision; it never permits eviction of retained content.
|
|
200
221
|
|
|
201
222
|
## Capacity
|
|
@@ -206,3 +227,63 @@ Objects include chunks, file metadata, and directories.
|
|
|
206
227
|
Retained results and unfinished uploads consume the same allowance.
|
|
207
228
|
Replacing unique content needs room for both versions until old retention is released and collection completes.
|
|
208
229
|
Local spools also need enough private disk space for the prepared artifact.
|
|
230
|
+
|
|
231
|
+
### Choose what to remove at capacity
|
|
232
|
+
|
|
233
|
+
On a reusable volume, `describe` includes `lifetime` with the lease, grace period,
|
|
234
|
+
recovery-read state and reserved metadata allowance.
|
|
235
|
+
Choose a path from the current head to remove. The service never chooses a live
|
|
236
|
+
file to evict because the volume is full.
|
|
237
|
+
|
|
238
|
+
```sh
|
|
239
|
+
scripts/sp remove --path "$ARTIFACT_PATH" --operation-id "$REMOVE_ID"
|
|
240
|
+
scripts/sp remove --path "$ARTIFACT_PATH" --operation-id "$REMOVE_ID" --apply
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The first command reports a plan without changing the head.
|
|
244
|
+
Applying saves the exact command and uses reserved metadata space within the reported bounds.
|
|
245
|
+
The receipt confirms the new head. Retention or grants can still protect the removed content.
|
|
246
|
+
Private maintenance returns space after that content is no longer protected.
|
|
247
|
+
After an unknown result, use `recover`; do not change the saved path or operation identifier.
|
|
248
|
+
Older binaries or deployments can refuse this command; that refusal does not permit eviction.
|
|
249
|
+
|
|
250
|
+
### Keep or end a reusable lifetime
|
|
251
|
+
|
|
252
|
+
A volume with `lifetime.expires_at` equal to zero is durable.
|
|
253
|
+
For a managed lease, request one absolute Unix deadline in seconds:
|
|
254
|
+
|
|
255
|
+
```sh
|
|
256
|
+
scripts/sp renew --until "$UNTIL"
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Save and retry the same deadline. Renewal must win before retirement begins.
|
|
260
|
+
An already achieved renewal can still recover after that deadline passes.
|
|
261
|
+
If recovery reports definite `expired` for an unachieved saved deadline, only the
|
|
262
|
+
renewal intent is cleared. Request a new absolute deadline if the same lifetime is
|
|
263
|
+
still renewable, then recover the unchanged ordinary pending operation.
|
|
264
|
+
An unknown result keeps the saved renewal pending; do not replace its deadline.
|
|
265
|
+
During recorded grace, recovery reads can remain available while ordinary writes are closed.
|
|
266
|
+
Do not infer disposal authority from an agent disconnect, an idle volume, or full quota.
|
|
267
|
+
|
|
268
|
+
Whole-volume retirement ends all head, retention, grant and access promises in its plan.
|
|
269
|
+
It can permanently delete every artifact. Use it only when the user has authorized
|
|
270
|
+
ending those promises and any required export has been restored and checked.
|
|
271
|
+
|
|
272
|
+
```sh
|
|
273
|
+
scripts/sp retire --operation-id "$RETIRE_ID"
|
|
274
|
+
scripts/sp retire --operation-id "$RETIRE_ID" --end-promises --apply
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Review the first result before applying. The exact terminal operation persists for recovery.
|
|
278
|
+
If recovery proves a strictly newer nonterminal plan for the same incarnation,
|
|
279
|
+
slot, generation, target, and saved request, it clears only the old release intent
|
|
280
|
+
and reports `fenced`. The lifetime remains nonterminal. Inspect the reported
|
|
281
|
+
lifetime and renew before ordinary work if needed. Review a new plan before
|
|
282
|
+
applying again; this refusal does not mean that artifacts were disposed or capacity returned.
|
|
283
|
+
Unknown or mismatched evidence and an already accepted terminal fence stay pending.
|
|
284
|
+
`disposed` reports physical disposal; only `capacity_returned` confirms admission capacity is free.
|
|
285
|
+
If a successor generation proves the old lifetime ended but this workspace never
|
|
286
|
+
observed its own release fence, recovery also reports `acceptance_unknown: true`.
|
|
287
|
+
That result confirms capacity return while leaving the original operation's acceptance unknown.
|
|
288
|
+
Preserve the old workspace through completion. A later admission is a different lifetime,
|
|
289
|
+
and old references and receipts do not select it.
|