@synadia-ai/agent-fabric-pi 0.3.1 → 0.3.2
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/dist/fabric.js +4 -4
- package/package.json +1 -1
package/BUILD
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
plugin @synadia-ai/nats-pi-channel 0.5.6
|
|
2
|
-
synadia-agents
|
|
3
|
-
agent-fabric-sdk
|
|
4
|
-
built 2026-10-
|
|
2
|
+
synadia-agents ed9aefb
|
|
3
|
+
agent-fabric-sdk 983c4c3
|
|
4
|
+
built 2026-10-27T21:00:10.639Z
|
package/dist/fabric.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as et,b as tr,d as rr,e as tt,g as rt,h as fe,t as nt,u as te}from"./chunk-9jcwbjk5.js";import{AsyncLocalStorage as nr}from"node:async_hooks";var or=et(tr(),1),yr=et(rr(),1);import{execFile as ir}from"node:child_process";import{createHash as ot,randomUUID as Me}from"node:crypto";import{mkdir as ar,realpath as sr}from"node:fs/promises";import{tmpdir as cr,platform as pe,arch as ge,homedir as Ue}from"node:os";import{join as he,resolve as He}from"node:path";import{mkdirSync as ur,statSync as dr,accessSync as lr,constants as ie,readFileSync as fr,writeFileSync as hr,renameSync as pr,openSync as gr,fstatSync as mr,readSync as Dr,closeSync as vr,lstatSync as ko,realpathSync as xo,fsyncSync as To}from"node:fs";var Fr=1,it="TRACE.edges",at="thread_id",st="root_id",br="X-Synadia-Thread-ID",wr="X-Synadia-Root-ID",Er=/[\u0000-\u0020\u007f\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/;function Ar(e){if(e===void 0)return;let t=e.edgeSubject;if(t===void 0||t===null)return;let r=(n)=>{throw new tt(`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(Er.test(n))r("must not contain whitespace or control characters");if(n.includes("*")||n.includes(">"))r("must not contain wildcards")}}var _r=Symbol.for("@synadia-ai/agent-fabric:trace-record-counts"),ae=(()=>{let e=globalThis;return e[_r]??={published:0,dropped:0}})();function Cr(){ae.published+=1}function Ve(){ae.dropped+=1}function Sr(){return Object.freeze({published:ae.published,dropped:ae.dropped})}var Rr=Symbol.for("@synadia-ai/agent-fabric:trace-scope"),ct=(()=>{let e=globalThis;return e[Rr]??=new nr})();function ne(e,t){return ct.run(e,t)}function H(){return ct.getStore()}function ut(){let e=H();if(e===void 0)return{};return e.turnCountHint+=1,{[br]:e.threadId,[wr]:e.rootId}}var _e=32,Br=new RegExp(`^[0-9a-f]{${_e}}$`);function ye(e){return Br.test(e)}function Ce(){let e=new Uint8Array(_e/2);crypto.getRandomValues(e);let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}function Se(){let e=Ce();return{threadId:e,rootId:e,turnCountHint:0}}var kr=256,xr=/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;function Re(e){if(xr.test(e))return!1;let t=Array.from(e).length;return t>0&&t<=kr}function Tr(e,t,r,n,o,i){let a=Ce(),s={version:Fr,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 Or="toolCallId";function dt(e={}){Ar(e);let t=e.edgeSubject===void 0?it:e.edgeSubject;return{promptInterceptor:Ir(t),requestInterceptor:qr,heartbeatExtras:t===null?()=>({}):()=>{let r=Sr();return{records_published:r.published,records_dropped:r.dropped}}}}function Ir(e){return{beforePrompt(t){let r=t.context[Or],n=typeof r==="string"&&Re(r)?r:null,o={...Nr(),toolCallId:n};return{fields:{[at]:o.threadId,[st]:o.rootId},state:o}},async beforePublish(t,r){let n=r?.state;if(e===null||n===void 0)return;await jr(t,e,n)}}}function Nr(){let e=Ce(),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 jr(e,t,r){if(!e.identity.canSign){Pr(e.connection),Ve();return}try{let n=await e.identity.selfId(),o=Tr(n,r.threadId,r.parentId,r.rootId,r.toolCallId,r.turnCountHint);await e.identity.publishSigned(t,o.payload,{nonce:o.recordId}),Cr()}catch(n){Ve(),console.warn(`@synadia-ai/agent-fabric: failed to publish edge record on ${t}`,n)}}var Ge=new WeakSet;function Pr(e){if(Ge.has(e))return;Ge.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 qr={async aroundRequest(e,t){await ne($r(e.envelope.extras??{}),t)}},Lr="envelope `thread_id` and `root_id` must be given together";function $r(e){let t=Xe(e,at),r=Xe(e,st);if(t===void 0!==(r===void 0))throw new te(400,Lr);if(t!==void 0&&r!==void 0)return{threadId:t,rootId:r,turnCountHint:0};return Se()}function Xe(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 te(400,`envelope \`${t}\` must be a string`);if(r==="")return;if(!ye(r))throw new te(400,`envelope \`${t}\` must be ${_e} lowercase hex characters`);return r}var Mr=class extends Error{constructor(e,t){super(t);this.reason=e,this.name="FabricCallerError"}reason},Oo=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get subject(){return this.#e.subject}cancel(){this.#t.reject(ze("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(ze("its stream ended first"))}}};function ze(e){return new Mr("not-sent",`the prompt never went out, so it has no root: ${e}`)}var se="sp-ref:";var lt=/sp-(?:ref|r1):[A-Za-z0-9_-]+/g,Be="scratchpad_refs_ok";function ce(e){return e.match(lt)??[]}function Fe(e,t){return e.replace(lt,(r)=>t===void 0||t.includes(r)?"":r).replace(/[ \t]+$/gm,"").replace(/\n{3,}/g,`
|
|
2
2
|
|
|
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=
|
|
5
|
-
`).join(""),{mode:384}),
|
|
3
|
+
`).trim()}function Ur(e){if(!e.startsWith(se))return;let t;try{t=JSON.parse(Buffer.from(e.slice(se.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 be(e){return e[Be]==="true"}function re(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 ft="sp-grant",Hr=1e4,me="agents.prompt.",Vr=`agents.${ft}.`;function ht(e){if(!e.startsWith(me)||e===me)throw Error(`not a prompt address: ${e}`);return Vr+e.slice(me.length)}function Gr(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 Xr(e){return JSON.stringify(e.granted?{granted:!0}:{granted:!1,reason:e.reason})}async function zr(e,t,r,n={}){let o;try{let s=await e.requestSigned(ht(t),Gr(r),{timeoutMs:n.timeoutMs??Hr});o=JSON.parse(s.string())}catch(s){return T(`no answer from ${t}: ${ue(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 Jr(e,t,r,n=fe){let o=Yr(t);if(o===void 0)return T("not a grant request");let i,a;try{i=re(e),a=re(o.grantee)}catch{return T("grantee is not an agent identity")}let s=o.trace,d=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:ue(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,d,s?.tool_call_id,"on-request")}catch(v){return n.error("grant request: the grant failed",{error:ue(v)}),T("the grant could not be made")}return n.info("grant request: granted",{grantee:o.grantee,requester:e}),{granted:!0}}function Wr(e){let{scratchPad:t}=e,r=e.logger??fe,n=new nt({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 Jr(s.id,i.string(),t,r)}return{name:ft,subject:ht(e.promptAddress),queue:"agents",handler:(i,a)=>{if(i)return;o(a).catch((s)=>(r.error("grant request failed",{error:ue(s)}),T("the grant could not be made"))).then((s)=>{if(!s.granted)r.info("grant request refused",{reason:s.reason});a.respond(Xr(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"||!ye(i)||!ye(a))return{reference:r,grantee:n};return{reference:r,grantee:n,trace:{thread_id:i,root_id:a,...typeof s==="string"&&Re(s)?{tool_call_id:s}:{}}}}function T(e){return{granted:!1,reason:e}}function ue(e){return e instanceof Error?e.message:String(e)}var pt="reads_scratchpad_references",Kr=class{requestInterceptor;#e;#t;#r;#n;#i=new Set;#o=new Map;constructor(e){this.#e=e.scratchPad,this.#t=e.agents,this.#r=e.discoverTimeoutMs,this.#n=e.grantRequestTimeoutMs,this.requestInterceptor={aroundRequest:(t,r)=>(this.remember(t.envelope.prompt),r())}}remember(e){for(let t of ce(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,re(t.id),Je(),void 0,"first-hand"),!0}discoveryFields(e){return this.#a(e),{[pt]:be(e.metadata)}}async beforePrompt(e){let{address:t,target:r}=e,n=ce(e.prompt);if(n.length===0)return;if(!be(r.metadata)){let p=Fe(e.prompt);if(p==="")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:p,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((p)=>!this.#i.has(p));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=re(r.identity),s=Je(),d=e.toolCallId!==void 0&&Re(e.toolCallId)?e.toolCallId:void 0,l=[],h="";for(let p of o){try{if(await this.#e.owns(p)){await this.#e.grantRead(p,a,s,d,"first-hand");continue}}catch(m){return{error:`could not grant "${t}" read on ${p.slice(0,32)}…: ${Qr(m)}; the prompt was not sent`}}let g=await this.#s(p,t,r.identity,s,d);if(!g.granted)l.push(p),h=g.reason}if(l.length===0)return;let v=n.filter((p)=>l.includes(p)).length,_=Fe(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=Ur(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 zr(this.#t,i,s,this.#n!==void 0?{timeoutMs:this.#n}:{})}async#c(e){let t=this.#o.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.#o.get(e)}#a(e){let t=this.#o.get(e.promptSubject);if(t===void 0||e.idSigVerified||!t.idSigVerified)this.#o.set(e.promptSubject,e)}};function Zr(e){return new Kr(e)}function Je(){let e=H();return e!==void 0?{threadId:e.threadId,rootId:e.rootId}:void 0}function Qr(e){return e instanceof Error?e.message:String(e)}var gt=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 mt(e,t){return new gt("invalid",e,{local:!0,cause:t})}var en=/[\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 tn=524288,Dt=921600;var rn=8192,nn=128,on=16384,an=131072;var sn=tn;var cn=4294967295,un=8,vt=8,dn=16,ln=3600,fn="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";var Io=Object.freeze({object_bytes:Dt,read_bytes:sn,control_bytes:on,reply_bytes:an,writers:un,retentions:vt,grants:dn,grant_seconds:ln});function D(e,t){if(!e)throw mt(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 yt(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 we(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 d=0;d<8;d++)a=(a<<1^(a&32768?4129:0))&65535}D(i[33]===(a&255)&&i[34]===a>>>8,"NKEY checksum differs")}function hn(e){let t=M(e,["account","user"]);we(t.account,"account"),we(t.user,"user")}function Ft(e){L(e,255,1),D(e!=="."&&e!==".."&&!/[\x00-\x1f\x7f/]/.test(e),"forbidden entry name"),D(pn(e)===e,"entry name is not NFC")}function pn(e){let t="",r="";for(let n of e)if(en.test(n))t+=r.normalize("NFC")+n,r="";else r+=n;return t+r.normalize("NFC")}function gn(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<=nn,"path exceeds its depth bound");for(let n of r)Ft(n)}function bt(e){D(typeof e==="string"&&/^[0-9A-Za-z]{1,64}$/.test(e),"invalid volume name")}function wt(e){let t=M(e,["volume","creation_id"]);bt(t.volume),D(typeof t.creation_id==="string"&&/^[0-9a-f]{32}$/.test(t.creation_id),"invalid volume creation identity")}function mn(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 Et(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"),mn(t.trace)}function Dn(e){let t=M(e,["slot","generation"]);V(t.slot,vt-1),V(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 vn(e){let t=M(e,["slot","generation","operation_id"]);V(t.slot,cn),V(t.generation,void 0,1),Et({operation_id:t.operation_id,trace:{}})}function yn(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 Fn(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 p=Object.create(null);if(n[o]==="}")return o++,p;for(;;){D(n[o]==='"',"JSON key must be a string");let g=a();i(),D(!Object.hasOwn(p,g),"duplicate JSON key"),D(n[o++]===":","missing JSON colon"),p[g]=s(l+1),i();let m=n[o++];if(m==="}")return p;D(m===",","invalid JSON object separator"),i()}}if(h==="["){o++,i();let p=[];if(n[o]==="]")return o++,p;for(;;){p.push(s(l+1)),i();let g=n[o++];if(g==="]")return p;D(g===",","invalid JSON array separator"),i()}}for(let[p,g]of[["true",!0],["false",!1],["null",null]])if(n.startsWith(p,o))return o+=p.length,g;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"),_},d=s(0);return i(),D(o===n.length,"trailing JSON data"),d}var bn=class extends Error{constructor(e,t){super(t);this.reason=e,this.name="CodecError"}reason};function I(e,t){throw new bn(e,t)}function wn(e,t){return ot("sha256").update(e).update("\x00").update(t).digest("base64url")}function En(e){return wn("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 An(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 _n(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{Ft(e)}catch{I("not-nfc","entry name is not NFC")}}function Cn(e){if(_n(e.name),e.type==="symlink"){if(e.executable||e.object!==void 0&&e.object!==fn)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(yt(e.object),e.linkTarget||e.type==="directory"&&e.executable)I("type-invalid","entry has fields of another type")}}function Sn(e){for(let o of e)Cn(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>rn)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"),An(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>Dt)I("node-size","tree node byte count exceeds bound");r.push(...i)}return Buffer.concat(r)}En(Sn([]));function _t(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),we(t.account,"account"),wt(t.target),yt(t.root),V(t.generation,void 0,1),gn(t.path,256),Dn(t.retention),V(t.expires_at,void 0,1)}function Rn(e){_t(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(yn(t,!1)).toString("base64url");return D(Buffer.byteLength(r)<=16384,"reference exceeds byte bound"),r}var Ee="sp-r1:",de=66;function Ct(e){L(e,de,de),D(/^sp-r1:[A-Za-z0-9_-]{60}$/.test(e),"malformed short reference");let t=Buffer.from(e.slice(Ee.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 wt({volume:"Reference",creation_id:n.creation_id}),n}function Bn(e,t){return ot("sha256").update(`scratchpad-reference-volume-v1\x00${e}\x00${t}`).digest().subarray(0,8).toString("hex")}function kn(e){let t=M(e,["short","expanded"]);L(t.short,de,de);let r=Ct(t.short);_t(t.expanded),D(r.route===Bn(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 Ae=4096;function xn(e){let t=M(Fn(e,Ae),["version","principal","volume","admission","creation"]);return D(t.version===1,"unsupported ScratchPad bootstrap version"),hn(t.principal),bt(t.volume),vn(t.admission),Et(t.creation),t}function St(e){D(typeof e==="string"&&e.length>0,"bootstrap file path is required");let t;try{t=gr(e,ie.O_RDONLY|ie.O_NONBLOCK|(ie.O_NOFOLLOW??0));let r=mr(t);D(r.isFile(),"bootstrap must be a regular file"),D(r.size<=Ae,"bootstrap exceeds its byte bound");let n=Buffer.alloc(Ae+1),o=0;while(o<n.length){let i=Dr(t,n,o,n.length-o,o);if(i===0)break;o+=i}return xn(n.subarray(0,o))}catch(r){if(r instanceof gt)throw r;throw mt("cannot read ScratchPad bootstrap file",r)}finally{if(t!==void 0)vr(t)}}var Tn="sp",On=600,We=600,In=5,Ye=16,Nn=16384,Rt=16777216,jn=Math.ceil(Rt/3)*4+65536,Pn=262144,qn=65536,Bt=/^A[A-Z2-7]{55}$/,kt=/^[0-9A-Za-z]{1,64}$/,Ln=/^[0-9a-f]{32}$/,$n=/^[A-Za-z0-9_-]{43}$/,Mn=/^[A-Za-z0-9_-]+$/,Un=/^[A-Za-z0-9+/]*={0,2}$/,b=class extends Error{constructor(e,t,r){super(e);this.code=t,this.unknown=r,this.name="ScratchPadError"}code;unknown},x=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),le=(e,t)=>Object.keys(e).length===t.length&&t.every((r)=>(r in e)),ee=(e)=>Number.isSafeInteger(e)&&e>0,xt=(e)=>Buffer.byteLength(e,"utf8");function Tt(e){return x(e)&&le(e,["volume","creation_id"])&&typeof e.volume==="string"&&kt.test(e.volume)&&typeof e.creation_id==="string"&&Ln.test(e.creation_id)}function Hn(e){if(typeof e!=="string"||!e.startsWith("/")||xt(e)>256)return!1;if(e==="/")return!0;return e.slice(1).split("/").every((t)=>t!==""&&t!=="."&&t!=="..")}function De(e){let t=(a)=>{throw Error(`malformed ScratchPad reference: ${a}`)};if(typeof e!=="string"||!e.startsWith(se))t("no sp-ref: prefix");if(e.length>Nn)t("longer than 16 KiB");let r=e.slice(se.length);if(!Mn.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(!x(n)||!le(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||xt(n.creator)>512||typeof n.account!=="string"||!Bt.test(n.account)||!Tt(n.target)||typeof n.root!=="string"||!$n.test(n.root)||!ee(n.generation)||!Hn(n.path)||!x(i)||!le(i,["slot","generation"])||!Number.isSafeInteger(i.slot)||i.slot<0||i.slot>7||!ee(i.generation)||!ee(n.expires_at))t("a field is out of shape");return n}var G=()=>Math.floor(Date.now()/1000),Ke=8,Vn=16,Gn=["close","apply","release","grant"],Xn=["workspace","not_found"],z=(e)=>Number.isSafeInteger(e)&&e>=0;function zn(e){let t=(l)=>{throw new b(`sp describe: ${l}`,"malformed_reply",!1)};if(!x(e)||!x(e.volume))return t("the reply names no volume");let{volume:r,control:n}=e,o;if(n!==null&&n!==void 0){if(!x(n)||typeof n.kind!=="string"||!Gn.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!==Ke)return t("not eight retention slots");if(!Array.isArray(a)||a.length!==Vn)return t("not sixteen grant slots");let s=i.map((l)=>{if(!x(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(!x(h)||!z(h.until)||typeof h.root!=="string")return t("a retention pin is out of shape");return{generation:l.generation,until:h.until}}),d=[];for(let l of a){if(!x(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=x(h)?h.retention:void 0;if(!x(h)||!z(h.until)||!x(v)||!z(v.slot)||v.slot>=Ke||!ee(v.generation))return t("a grant is out of shape");d.push({slot:v.slot,generation:v.generation,until:h.until})}return{closed:r.closed,control:o,retentions:s,grants:d}}function Jn(e){let t=(o)=>{throw new b(`sp spool-remove: ${o}`,"malformed_reply",!1)};if(!x(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(!le(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 Wn(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 Yn(e){let t=e.bootstrapFile===void 0?void 0:St(e.bootstrapFile),r=e.volume??t?.volume;if(!r||!kt.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??Tn,a=e.dir??he(cr(),`scratchpad-${n}`),s=Math.min(e.grantTtlS??We,We),d,l,h=Promise.resolve(),v=!0,_,p=new Map;function g(c){let f=h.then(c);return h=f.catch(()=>{return}),f}let m=new Map;async function C(c,f){if(!c.startsWith(Ee))return De(c);Ct(c);let u=m.get(c);if(u&&u.expires_at>G())return structuredClone(u);let y=await F("resolve",["--ref",c],{trace:f}),S={short:c,expanded:y?.reference};if(kn(S),y.full_reference!==Rn(S.expanded))throw new b("sp resolve: expanded token differs from descriptor","malformed_reply",!1);let w=De(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 R(){return d??=(async()=>(await ar(a,{recursive:!0,mode:448}),sr(a)))(),d}async function F(c,f,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 R(),...S,...w,...f,...y],P=u.maxStdout??Pn,{code:E,stdout:q,stderr:B}=await new Promise((O)=>{ir(i,j,{maxBuffer:Math.max(P,qn),encoding:"utf8"},(Zt,Qt,er)=>{let Z=Zt;O({code:Z===null?0:typeof Z.code==="number"?Z.code:null,stdout:Qt??"",stderr:er||(Z!==null&&typeof Z.code==="string"?Z.message:"")})}).stdin?.end(u.stdin??"")});if(E===null&&/^spawn .*(ENOENT|EACCES)/m.test(B))throw new b(`sp ${c}: ${B.trim()}`,"spawn_failed",!1);if(E===0&&q.length<=P)try{return JSON.parse(q)}catch{}let k={code:E===0?"malformed_reply":"failed",message:B.trim().slice(0,512)||`exit ${E??"by signal"}`,unknown:u.mutation===!0};if(E!==0)try{let O=JSON.parse(B).error;if(x(O)&&typeof O.code==="string")k={code:O.code,message:typeof O.message==="string"?O.message:"",unknown:O.unknown===!0||u.mutation===!0&&typeof O.unknown!=="boolean"}}catch{}throw new b(`sp ${c}: ${k.code}${k.unknown?" (outcome unknown)":""}: ${k.message}`,k.code,k.unknown)}function Y(c,f){let u=c,y=u?.principal?.account;if(typeof y!=="string"||!Bt.test(y)||!Tt(u.target))throw new b(`sp ${f}: the reply names no principal and target`,"malformed_reply",!1);if(u.target.volume!==n)throw new b(`sp ${f}: 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 oe(c){return l??=Y(await F("init",[],{trace:c,mutation:!0}),"init"),l}async function K(c){if(l!==void 0)return l;try{l=Y(await F("describe",[],{trace:c}),"describe")}catch(f){if(f instanceof b&&Xn.includes(f.code))return;throw f}return l}let N=(c,f)=>f!==void 0&&c.account===f.account&&c.target.volume===f.target.volume&&c.target.creation_id===f.target.creation_id,je=(c,f)=>JSON.stringify([c.account,c.target.volume,c.target.creation_id,c.root,c.path,f.account,f.user]);function Xt(){let c=G();for(let[f,u]of p)if(Math.max(u["first-hand"]??0,u["on-request"]??0)<=c)p.delete(f)}function Pe(c,f,u){p.set(c,{...p.get(c),[f]:u})}function zt(c,f){let u=c;if(!x(u)||!x(u.handle)||!ee(u.expires_at))throw new b("sp grant: the reply names no handle and expiry","malformed_reply",!0);return Math.min(u.expires_at,f.expires_at)}async function qe(c,f,u,y){return F("publish-file",["--source","-","--path",f,"--operation-id",u,"--creator",e.creator,"--ttl-seconds",String(On)],{trace:y,stdin:c,mutation:!0})}async function Le(c){if(!v)return;try{await F("recover",[],{trace:c,mutation:!0})}catch(f){if(!(f instanceof b)||f.unknown)throw f}v=!1}async function Jt(c,f){let u;try{let y=Jn(await F("spool-remove",["--apply"],{trace:f,mutation:!0}));if(!y.present||y.applied)return;u="the refused publication's spool is protected"}catch(y){if(y instanceof b&&y.unknown)throw y;u=`its spool was not removed: ${y.message}`}throw v=!0,new b(`${c.message}; cleanup not started: ${u}`,c.code,!1)}async function Wt(c){return zn(await F("describe",[],{trace:c}))}async function Yt(c,f,u){if(e.creator===void 0)throw Error("ScratchPad: a reference names its creator; this ScratchPad was made without one");let y=await oe(u);await Le(u);let S=Me(),w;try{w=await qe(c,f,S,u)}catch(E){if(E instanceof b&&E.unknown)v=!0;if(!(E instanceof b)||E.code!=="capacity"||E.unknown)throw E;await Jt(E,u);let q;try{q=Wn(await Wt(u))}catch(B){throw new b(`${E.message}; cleanup not started: ${B.message}`,E.code,!1)}if(q!==void 0)throw new b(`${E.message}; cleanup not started: ${q}`,E.code,!1);try{await F("maintain",["--apply"],{trace:u,mutation:!0})}catch(B){v=!0;let k=!(B instanceof b)||B.unknown;throw new b(`${E.message}; cleanup: ${B.message}`,k&&B instanceof b?B.code:k?"failed":E.code,k)}try{w=await qe(c,f,S,u)}catch(B){if(B instanceof b&&B.unknown)v=!0;throw B}}let j=w?.reference;if(typeof j!=="string"||!x(w.receipt))throw v=!0,new b("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!==f||P.creator!==e.creator)throw new b("sp publish-file: the reference names another volume, path or creator","malformed_reply",!1);return j}async function $e(c,f,u,y){return zt(await F("grant",c,{trace:f,toolCallId:u,mutation:!0}),y)}async function Kt(c,f,u,y,S){let w=await C(c,u);if(!N(w,await K(u)))throw Error("the reference points into another agent's volume; only its creator can grant read on it");if(await Le(u),_!==void 0){let k=_;try{Pe(k.key,k.kind,await $e(k.args,void 0,void 0,k.ref)),_=void 0}catch(O){if(!(O instanceof b)||O.unknown)throw O;_=void 0}}let j=w.expires_at-G()-In,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=je(w,f);if(Xt(),!p.has(E)&&p.size>=Ye)throw Error(`this agent already holds ${Ye} 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 B=["--ref",c,"--grantee-account",f.account,"--grantee-user",f.user,"--operation-id",Me(),"--ttl-seconds",String(P)];try{Pe(E,S,await $e(B,u,y,w))}catch(k){if(k instanceof b&&k.unknown)_={args:[...B,...q],key:E,kind:S,ref:w};throw k}}return{commit(c,f,u){return g(()=>Yt(c,f,u))},async read(c,f){if((await C(c,f)).expires_at<=G())throw Error("the reference has expired");let y=await F("read",["--ref",c],{trace:f,maxStdout:jn}),{data_base64:S,bytes:w}=y??{};if(typeof S!=="string"||!Un.test(S)||!Number.isSafeInteger(w)||w>Rt)throw new b("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 b("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 f;try{f=await C(c)}catch{return!1}return N(f,await K(H()))},grantRead(c,f,u,y,S="first-hand"){return g(()=>Kt(c,f,u,y,S))},granted(c,f){let u=(y)=>{if(!N(y,l))return;let S=p.get(je(y,f)),w=G();if((S?.["first-hand"]??0)>w)return"first-hand";if((S?.["on-request"]??0)>w)return"on-request";return};if(c.startsWith(Ee))return C(c).then(u,()=>{return});try{return u(De(c))}catch{return}}}}var Kn="SCRATCHPAD_VOLUME",Zn="SCRATCHPAD_BOOTSTRAP_FILE",J="SCRATCHPAD_BIN",Qn="SCRATCHPAD_DIR";var eo=409;function to(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 ro(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 no(e){return(typeof e==="object"||typeof e==="function")&&e!==null&&typeof e.then==="function"}function Ot(){let e=new Map,t=new Map,r=(a)=>{let s=t.get(a);if(s===void 0)return!1;for(let d of s)if(d.waiting)return!0;return!1},n=(a,s)=>{e.set(a,s);let d=t.get(s.rootId);if(d===void 0)t.set(s.rootId,d=new Set);d.add(s)},o=(a,s)=>{if(e.get(a)===s)e.delete(a);let d=t.get(s.rootId);if(d===void 0)return;if(d.delete(s),d.size===0)t.delete(s.rootId)},i=(a,s,d)=>{a.running-=1;let l=s?ro(d):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 d=H();if(d===void 0){await s();return}let{rootId:l}=d;if(r(l))throw new te(eo,to(l));let h={rootId:l,waiting:!1,running:0,open:0};n(d,h);try{await s()}finally{o(d,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 d=a===void 0?void 0:e.get(a);if(d===void 0)return s();d.running+=1;let l;try{l=s()}catch(h){throw i(d,!1),h}if(no(l))l.then((h)=>i(d,!0,h),()=>i(d,!1));else i(d,!0,l);return l},open(a){let s={rootId:a.rootId,waiting:!1,running:0,open:0};n(a,s);let d=!1;return()=>{if(d)return;d=!0,o(a,s)}},serving:(a)=>t.has(a),waiting:r}}var oo=Symbol.for("synadia.fabric.scratchpad.workspace-owners.v1"),io=globalThis,No=io[oo]??=new Set;var Ze="edgeSubject",ao="SYNADIA_FABRIC_EDGE_SUBJECT";function It(e,t=process.env){if(Object.hasOwn(e,Ze))return e[Ze];let r=t[ao];if(r!==void 0)return r;return it}var Nt="scratchpad",A={url:"SP_NATS_URL",creds:"SP_NATS_CREDS",dir:Qn,volume:Kn,bootstrapFile:Zn,creator:"SP_CREATOR",threadId:"SP_THREAD_ID",rootId:"SP_ROOT_ID",callerAccount:"SP_CALLER_ACCOUNT",callerUser:"SP_CALLER_USER",grants:"SP_GRANTS_FILE"},so=["NATS_CREDS","NATS_CREDENTIALS"];async function ke(e,t,r={}){let n=e.logger,o=e.options[Nt],i=o!==null&&typeof o==="object"?o:{},a=(R)=>{let F=i[R];return typeof F==="string"&&F!==""?F:void 0},s=(R)=>{let F=t[R];return F===void 0||F===""?void 0:F},d=(R,F)=>a(R)??s(F),l=d("bootstrapFile",A.bootstrapFile),h=l===void 0?void 0:He(ve(l)),v=h===void 0?void 0:St(h),_=d("volume",A.volume)??v?.volume;if(_===void 0)return;if(v&&v.volume!==_)throw Error("ScratchPad bootstrap differs from the configured volume");let p=a("url"),g=a("creds");if(p===void 0||g===void 0){let R=s("NATS_URL"),F;for(let N of r.credsVariables??so)if(F=s(N),F!==void 0)break;let Y=t.NATS_CONTEXT,oe=Y!==void 0||R!==void 0||F!==void 0,K=Y?Y:oe?void 0:Q(e.settings.config.context);if(K!==void 0)try{let{fields:N}=await rt(K);p??=Q(N.url),g??=Q(N.creds)}catch(N){n.warn(`agent-fabric: ScratchPad is off: the NATS context "${K}" could not be read (${String(N)})`);return}else if(oe)p??=R,g??=F}if(p??=Q(e.settings.config.url),g??=Q(e.settings.config.credentials),p===void 0||g===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=d("dir",A.dir);if(m===void 0&&e.settings.stateDir!==void 0)m=he(e.settings.stateDir,"scratchpad");if(v&&m===void 0)throw Error("ScratchPad bootstrap requires a persistent workspace directory");if(m!==void 0){m=He(ve(m));try{ur(m,{recursive:!0,mode:448})}catch(R){n.warn(`agent-fabric: ScratchPad workspace ${m} could not be created (${String(R)})`)}}let C=m!==void 0?`${m}.grants`:void 0;if(C!==void 0)lo(C,n);return{url:p,creds:ve(g),volume:_,...h===void 0?{}:{bootstrapFile:h},...m!==void 0?{dir:m}:{},...C!==void 0?{grants:C}:{}}}function xe(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 Te=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=re(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 Oe(e,t){let r=[],n,o=e[J];if(o===void 0||o==="")r.push(`${J} is not set`);else{let h=Qe(o);if(h===void 0)return{bin:o,tried:r};n=`${o} ${h}`,r.push(`${J} ${n}`)}let i=(h)=>({bin:h,tried:r,...n!==void 0?{passedOver:n}:{}}),a=pe()==="darwin"?"darwin":pe()==="linux"?"linux":void 0,s=ge()==="arm64"?"arm64":ge()==="x64"?"amd64":void 0;if(a===void 0||s===void 0)return r.push(`no sp is shipped for ${pe()} ${ge()}`),i(void 0);let d=he(t,"bin",`sp-${a}-${s}`),l=Qe(d);if(l===void 0)return i(d);return r.push(`${d} ${l}`),i(void 0)}function Qe(e){try{if(!dr(e).isFile())return"is not a file"}catch{return"does not exist"}try{lr(e,ie.X_OK)}catch{return"is not executable"}return}function jt(e,t){return Oe(e,t).bin}function Pt(e,t){if(t.passedOver===void 0)return;return`${e}: ${J} ${t.passedOver}, so it is passed over`+(t.bin!==void 0?` and the add-on runs ${t.bin}`:"")+`; the skill's scripts/sp takes ${J} as it is and refuses every call until it names an executable sp or is unset`}function qt(e,t){return`${e}: no sp for the add-on's own ScratchPad steps (${t.tried.join("; ")}); set ${J} to the path of an sp binary. Until then nothing is granted: references in prompt_agent are removed with a note, and grant requests are not answered`}var Ie=class{#e;#t;#r=!1;#n=[];requestInterceptor={aroundRequest:(e,t)=>{if(this.#e!==void 0)this.#e.remember(e.envelope.prompt);else if(!this.#r)this.#n.push(e.envelope.prompt);return t()}};start(e){let{scratchPad:t,agents:r,service:n}=e;this.#t=t,this.#e=Zr({scratchPad:t,agents:r});for(let a of this.#n.splice(0))this.#e.remember(a);if(n===void 0)return;let o=e.logger??fe,i=Wr({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)}`)}}startWithoutScratchPad(){this.#r=!0,this.#n.length=0}discoveryFields(e){return this.#e?.discoveryFields(e)??{[pt]:be(e.metadata)}}async beforePrompt(e){let t=this.#e,r=this.#t;if(t===void 0||r===void 0){let n=ce(e.prompt);if(n.length===0)return;if(this.#r)return co(e.address,e.prompt,n.length);return{error:"the prompt was not sent: ScratchPad is not ready yet; try again in a moment"}}for(let n of new Set(ce(e.prompt)))if(await r.owns(n))t.remember(n);return t.beforePrompt(e)}afterReply(e){this.#e?.afterReply(e)}};function co(e,t,r){let n=`this agent has no sp of its own to grant read with (${J} names one)`,o=Fe(t);if(o==="")return{error:`the prompt was not sent: ${n}, and the prompt held nothing but references; put the content they point at into the prompt itself`};return{prompt:o,fields:{references_removed:r,note:`${n}: ${r} reference(s) were removed from your prompt, "${e}" got only the text, and nothing was granted`}}}function Lt(e,t,r,n){let o=jt(r,n);if(o===void 0)return;let i=Yn({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?fo(i,e.grants):i}var uo=/^(\d+) (\S+) (\S+) (sp-(?:ref|r1):[A-Za-z0-9_-]+)$/;function $t(e){let t;try{t=fr(e,"utf8")}catch{return[]}let r=[];for(let n of t.split(`
|
|
4
|
+
`)){let o=uo.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 lo(e,t){let r=Math.floor(Date.now()/1000),n=$t(e).filter((o)=>o.expiresAt>r);try{let o=`${e}.${process.pid}.tmp`;hr(o,n.map((i)=>`${i.expiresAt} ${i.grantee.account} ${i.grantee.user} ${i.reference}
|
|
5
|
+
`).join(""),{mode:384}),pr(o,e)}catch(o){t.warn(`agent-fabric: ScratchPad grants file ${e} could not be written (${String(o)})`)}}function fo(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 $t(t).some((d)=>d.reference===n&&d.grantee.account===o.account&&d.grantee.user===o.user&&d.expiresAt>a)?"first-hand":i}}}function Q(e){return typeof e==="string"&&e!==""?e:void 0}function ve(e){if(e==="~")return Ue();if(e.startsWith("~/"))return he(Ue(),e.slice(2));return e}import{fileURLToPath as ho}from"node:url";var Mt=ho(new URL("../skill/scratchpad",import.meta.url));function Ut(e){return Oe(e,Mt)}function Ht(e,t,r){return Lt(e,t,r,Mt)}var W="agent-fabric",Vt=`${W}: 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 Ne(e,t=process.env){return Gt(e,t,await ke(e,t))}function Gt(e,t=process.env,r){let n=It(e.options,t),o=dt({edgeSubject:n}),i=Ot(),a=e.logger,s=new Map,d=(g)=>g===void 0?void 0:s.get(g.id),l=new Map,h=!1,v=r!==void 0,_=new Te(t);if(r!==void 0)xe(r,t);let p=r!==void 0?new Ie:void 0;return{name:W,requestInterceptors:[o.requestInterceptor,i.requestInterceptor,...p!==void 0?[p.requestInterceptor]:[]],promptInterceptors:[o.promptInterceptor,i.promptInterceptor],heartbeatExtras:o.heartbeatExtras,...p!==void 0?{toolExtensions:[p],metadata:{[Be]:"true"}}:{},started({agents:g,service:m}){if(e.settings.senderIdentity!=="signed"&&!h)h=!0,a.warn(Vt);if(a.info(`${W}: tracing ${m.subject.prompt}`+(n===null?" (propagate-only: lineage forwarded, no edge record published)":`, edge records on ${n}`)),r!==void 0&&p!==void 0){t[A.creator]=m.subject.prompt;let C=Ht(r,m.subject.prompt,t),R=Ut(t),F=Pt(W,R);if(F!==void 0)a.warn(F);if(C!==void 0)p.start({scratchPad:C,agents:g,service:m,logger:a});else p.startWithoutScratchPad(),a.warn(qt(W,R));a.info(`${W}: ScratchPad volume ${r.volume}`+(r.dir!==void 0?`, workspace ${r.dir}`:", no workspace")+", for the skill's scripts/sp")}},events:{promptAccepted(g){let m=H();if(m!==void 0)s.set(g.id,m)},promptEnded(g){s.delete(g.id),_.leave(g)},localTurnStarted(g){l.get(g.id)?.();let m=Se();if(s.set(g.id,m),l.set(g.id,i.open(m)),v)_.enter(g,m)},localTurnEnded(g){s.delete(g.id),l.get(g.id)?.(),l.delete(g.id),_.leave(g)},aroundInject(g,m){let C=s.get(g.id);if(v)_.enter(g,C);return C===void 0?m():ne(C,m)},providerHeaders(g){let m=s.get(g.id);return m===void 0?void 0:ne(m,ut)},aroundToolCall(g,m,C){let R=d(g);return R===void 0?C():ne(R,()=>i.aroundToolCall(R,C))}}}}export{Ne as default};
|
package/package.json
CHANGED