@synadia-ai/agent-fabric-claude-code 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +4 -4
- package/.mcp.json +14 -0
- package/BUILD +4 -0
- package/LICENSE +18 -17
- package/README.md +54 -441
- package/hooks/hooks.json +53 -0
- package/hooks/session-event.js +14 -0
- package/package.json +23 -72
- package/runtime/chunk-5ke4ws7r.js +38 -0
- package/runtime/fabric.js +7 -0
- package/runtime/server.js +66 -0
- package/skills/configure/SKILL.md +190 -0
- package/skills/configure/list-contexts.sh +22 -0
- package/skills/scratchpad/SKILL.md +87 -6
- package/skills/scratchpad/scripts/sp +13 -7
- package/CHANGELOG.md +0 -18
- package/dist/index.cjs +0 -277
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -63
- package/dist/index.d.ts +0 -63
- package/dist/index.js +0 -248
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{a as ut,d as sr,e as ar,f as Fe,i as dt,k as lt,l as be,v as ft,w as fe}from"./chunk-5ke4ws7r.js";import{AsyncLocalStorage as cr}from"async_hooks";var ur=ut(sr(),1),wr=ut(ar(),1);import{execFile as dr}from"child_process";import{createHash as ht,randomUUID as We}from"crypto";import{mkdir as lr,realpath as fr}from"fs/promises";import{tmpdir as hr,platform as Ye,arch as Ke,homedir as Ze}from"os";import{join as we,resolve as Qe}from"path";import{mkdirSync as pr,readFileSync as gr,writeFileSync as mr,renameSync as vr,openSync as Dr,constants as Ae,fstatSync as yr,readSync as Fr,closeSync as br,lstatSync as Jo,realpathSync as Wo,fsyncSync as Yo}from"fs";var Er=1,je="TRACE.edges",pt="thread_id",gt="root_id";var mt=/[\u0000-\u0020\u007f\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/;function _r(e){if(e===void 0)return;let t=e.edgeSubject;if(t===void 0||t===null)return;let r=(n)=>{throw new Fe(`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(mt.test(n))r("must not contain whitespace or control characters");if(n.includes("*")||n.includes(">"))r("must not contain wildcards")}}var Ar=Symbol.for("@synadia-ai/agent-fabric:trace-record-counts"),pe=(()=>{let e=globalThis;return e[Ar]??={published:0,dropped:0}})();function vt(){pe.published+=1}function Be(){pe.dropped+=1}function Cr(){return Object.freeze({published:pe.published,dropped:pe.dropped})}var Sr=Symbol.for("@synadia-ai/agent-fabric:trace-scope"),Dt=(()=>{let e=globalThis;return e[Sr]??=new cr})();function Pe(e,t){return Dt.run(e,t)}function ne(){return Dt.getStore()}var qe=32,Rr=new RegExp(`^[0-9a-f]{${qe}}$`);function ke(e){return Rr.test(e)}function Ee(){let e=new Uint8Array(qe/2);crypto.getRandomValues(e);let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}function Le(){let e=Ee();return{threadId:e,rootId:e,turnCountHint:0}}var Br=256,yt=/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;function $e(e){if(yt.test(e))return!1;let t=Array.from(e).length;return t>0&&t<=Br}function kr(e,t,r,n,o,i){let s=Ee(),a={version:Er,kind:"edge",record_id:s,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:s,payload:new TextEncoder().encode(JSON.stringify(a))}}var xr="toolCallId";function Ft(e={}){_r(e);let t=e.edgeSubject===void 0?je:e.edgeSubject;return{promptInterceptor:Tr(t),requestInterceptor:jr,heartbeatExtras:t===null?()=>({}):()=>{let r=Cr();return{records_published:r.published,records_dropped:r.dropped}}}}function Tr(e){return{beforePrompt(t){let r=t.context[xr],n=typeof r==="string"&&$e(r)?r:null,o={...Ir(),toolCallId:n};return{fields:{[pt]:o.threadId,[gt]:o.rootId},state:o}},async beforePublish(t,r){let n=r?.state;if(e===null||n===void 0)return;await Or(t,e,n)}}}function Ir(){let e=Ee(),t=ne();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 Or(e,t,r){if(!e.identity.canSign){Nr(e.connection),Be();return}try{let n=await e.identity.selfId(),o=kr(n,r.threadId,r.parentId,r.rootId,r.toolCallId,r.turnCountHint);await e.identity.publishSigned(t,o.payload,{nonce:o.recordId}),vt()}catch(n){Be(),console.warn(`@synadia-ai/agent-fabric: failed to publish edge record on ${t}`,n)}}var et=new WeakSet;function Nr(e){if(et.has(e))return;et.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 jr={async aroundRequest(e,t){await Pe(qr(e.envelope.extras??{}),t)}},Pr="envelope `thread_id` and `root_id` must be given together";function qr(e){let t=tt(e,pt),r=tt(e,gt);if(t===void 0!==(r===void 0))throw new fe(400,Pr);if(t!==void 0&&r!==void 0)return{threadId:t,rootId:r,turnCountHint:0};return Le()}function tt(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 fe(400,`envelope \`${t}\` must be a string`);if(r==="")return;if(!ke(r))throw new fe(400,`envelope \`${t}\` must be ${qe} lowercase hex characters`);return r}var Lr=class extends Error{constructor(e,t){super(t);this.reason=e,this.name="FabricCallerError"}reason},Ko=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get subject(){return this.#e.subject}cancel(){this.#t.reject(rt("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(rt("its stream ended first"))}}};function rt(e){return new Lr("not-sent",`the prompt never went out, so it has no root: ${e}`)}var $r=1,Mr=2,Ur=new Set(["claude","openclaw"]),Vr=new Set(["start","end"]),Hr=new Set(["ok","error","timeout"]),Gr=new Set(["final_text","no_reply","shutdown","delivery","expired"]),Xr=256;function bt(e){if(typeof e!=="string"||e.length===0)return!1;if(mt.test(e))return!1;if(yt.test(e))return!1;return Array.from(e).length<=Xr}function xe(){return Math.floor(Date.now()/1000)}function zr(e,t,r,n,o,i,s,a=xe(),c){if(!Ur.has(n))throw Error(`buildServedRecord: harness must be "claude" or "openclaw", got ${n}`);if(!Vr.has(i))throw Error(`buildServedRecord: phase must be "start" or "end", got ${i}`);if(i==="end"&&s===void 0)throw Error("buildServedRecord: an end record needs a status");if(i==="start"&&s!==void 0)throw Error("buildServedRecord: a start record carries no status");if(s!==void 0&&!Hr.has(s))throw Error(`buildServedRecord: status must be "ok", "error" or "timeout", got ${s}`);if(i==="start"&&c!==void 0)throw Error("buildServedRecord: a start record carries no reason");if(c!==void 0&&!Gr.has(c))throw Error(`buildServedRecord: reason must be "final_text", "no_reply", "shutdown", "delivery" or "expired", got ${c}`);if(!bt(o))throw Error("buildServedRecord: harnessThreadId is not a usable harness thread id");if(!Number.isInteger(a)||a<0)throw Error("buildServedRecord: ts must be a non-negative integer of unix seconds");let l=Ee(),h={version:c!==void 0?Mr:$r,kind:"served",record_id:l,ts:a,agent:e,thread_id:t,root_id:r,harness:n,harness_thread_id:o,phase:i,...s!==void 0?{status:s}:{},...c!==void 0?{reason:c}:{}};return{recordId:l,payload:new TextEncoder().encode(JSON.stringify(h))}}var Jr=()=>({debug:()=>{return},info:()=>{return},warn:(e,t)=>console.warn(`@synadia-ai/agent-fabric: ${e}`,t??""),error:(e,t)=>console.error(`@synadia-ai/agent-fabric: ${e}`,t??"")}),Wr=class{#e;#t;#r;#n=!1;#o=Promise.resolve();constructor(e){this.#e=e.agents,this.#t=e.subject??je,this.#r=e.logger??Jr()}get subject(){return this.#t}beginTurn(e,t,r){let n=r===void 0?xe():Math.floor(r/1000),o,i=!1;return{bind:(s)=>{if(i){this.#r.warn("served: harness thread id bound after the turn ended; no served record");return}if(o!==void 0){if(s!==o)this.#r.warn("served: harness thread id already bound for this prompt; ignored");return}if(!bt(s)){this.#r.warn("served: unusable harness thread id bound; no served record");return}o=s,this.publish(e,t,s,"start",void 0,n)},settle:(s,a,c)=>{if(i)return;if(i=!0,o===void 0)return;let l=a===void 0?xe():Math.floor(a/1000);this.publish(e,t,o,"end",s,l,c)}}}publish(e,t,r,n,o,i,s){let a=this.#o.then(()=>this.#i(e,t,r,n,o,i,s));return this.#o=a,a}flush(){return this.#o}async#i(e,t,r,n,o,i,s){try{let a=await this.#e.selfId(),c=zr(a,e.threadId,e.rootId,t,r,n,o,i,s);await this.#e.publishSigned(this.#t,c.payload,{nonce:c.recordId}),vt()}catch(a){if(Be(),Yr(a)){if(this.#n)return;this.#n=!0,this.#r.warn("served: no identity signer is configured; served records are not published (consumers ignore unsigned records). Pass identity: { signer } to sign them.");return}this.#r.warn("served: failed to publish served record",{subject:this.#t,phase:n,reason:a instanceof Error?a.message:String(a)})}}};function Yr(e){return e instanceof dt||e instanceof Error&&e.name==="SenderSignatureRequiredError"}function wt(e){return new Wr(e)}var ge="sp-ref:";var Et=/sp-(?:ref|r1):[A-Za-z0-9_-]+/g,Me="scratchpad_refs_ok";function me(e){return e.match(Et)??[]}function nt(e,t){return e.replace(Et,(r)=>t===void 0||t.includes(r)?"":r).replace(/[ \t]+$/gm,"").replace(/\n{3,}/g,`
|
|
3
|
+
|
|
4
|
+
`).trim()}function Kr(e){if(!e.startsWith(ge))return;let t;try{t=JSON.parse(Buffer.from(e.slice(ge.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 Te(e){return e[Me]==="true"}function he(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 _t="sp-grant",Zr=1e4,Ce="agents.prompt.",Qr=`agents.${_t}.`;function At(e){if(!e.startsWith(Ce)||e===Ce)throw Error(`not a prompt address: ${e}`);return Qr+e.slice(Ce.length)}function en(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 tn(e){return JSON.stringify(e.granted?{granted:!0}:{granted:!1,reason:e.reason})}async function rn(e,t,r,n={}){let o;try{let a=await e.requestSigned(At(t),en(r),{timeoutMs:n.timeoutMs??Zr});o=JSON.parse(a.string())}catch(a){return q(`no answer from ${t}: ${ve(a)}`)}if(typeof o!=="object"||o===null)return q("refused without a reason");let{granted:i,reason:s}=o;if(i===!0)return{granted:!0};return q(typeof s==="string"?s:"refused without a reason")}async function nn(e,t,r,n=be){let o=sn(t);if(o===void 0)return q("not a grant request");let i,s;try{i=he(e),s=he(o.grantee)}catch{return q("grantee is not an agent identity")}let a=o.trace,c=a!==void 0?{threadId:a.thread_id,rootId:a.root_id}:void 0,l=!1;try{l=await r.owns(o.reference)}catch{}if(!l)return q("the reference does not point into this agent's volume");let h;try{h=await r.granted(o.reference,i)}catch(y){return n.error("grant request: the ledger could not be read",{error:ve(y)}),q("the grant could not be made")}if(h===void 0)return q("this agent holds no live read grant it made to the requester on that reference");if(h!=="first-hand")return q("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(s.account===i.account&&s.user===i.user)return q("a grant request is for another agent, not for the requester");try{await r.grantRead(o.reference,s,c,a?.tool_call_id,"on-request")}catch(y){return n.error("grant request: the grant failed",{error:ve(y)}),q("the grant could not be made")}return n.info("grant request: granted",{grantee:o.grantee,requester:e}),{granted:!0}}function on(e){let{scratchPad:t}=e,r=e.logger??be,n=new ft({minSenderTrust:"signed",logger:r});async function o(i){let s=await n.admitPrompt(i);if(!s.ok)return q(s.description);let a=s.sender;if(a?.trust!=="verified")return q("a grant request must be signed");return nn(a.id,i.string(),t,r)}return{name:_t,subject:At(e.promptAddress),queue:"agents",handler:(i,s)=>{if(i)return;o(s).catch((a)=>(r.error("grant request failed",{error:ve(a)}),q("the grant could not be made"))).then((a)=>{if(!a.granted)r.info("grant request refused",{reason:a.reason});s.respond(tn(a))})}}}function sn(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:s,tool_call_id:a}=o;if(typeof i!=="string"||typeof s!=="string"||!ke(i)||!ke(s))return{reference:r,grantee:n};return{reference:r,grantee:n,trace:{thread_id:i,root_id:s,...typeof a==="string"&&$e(a)?{tool_call_id:a}:{}}}}function q(e){return{granted:!1,reason:e}}function ve(e){return e instanceof Error?e.message:String(e)}var Ct="reads_scratchpad_references",an=class{requestInterceptor;#e;#t;#r;#n;#o=new Set;#i=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 me(e))this.#o.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,he(t.id),ot(),void 0,"first-hand"),!0}discoveryFields(e){return this.#s(e),{[Ct]:Te(e.metadata)}}async beforePrompt(e){let{address:t,target:r}=e,n=me(e.prompt);if(n.length===0)return;if(!Te(r.metadata)){let v=nt(e.prompt);if(v==="")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:v,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((v)=>!this.#o.has(v));if(i.length>0)return{error:`the prompt was not sent: ${i.length} of its ScratchPad references (${i[0].slice(0,24)}\u2026) 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 s=he(r.identity),a=ot(),c=e.toolCallId!==void 0&&$e(e.toolCallId)?e.toolCallId:void 0,l=[],h="";for(let v of o){try{if(await this.#e.owns(v)){await this.#e.grantRead(v,s,a,c,"first-hand");continue}}catch(E){return{error:`could not grant "${t}" read on ${v.slice(0,32)}\u2026: ${un(E)}; the prompt was not sent`}}let _=await this.#a(v,t,r.identity,a,c);if(!_.granted)l.push(v),h=_.reason}if(l.length===0)return;let y=n.filter((v)=>l.includes(v)).length,A=nt(e.prompt,l);if(A==="")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:A,fields:{references_removed:y,note:`${y} 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#a(e,t,r,n,o){let i=Kr(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 s=await this.#c(i);if(s===void 0||!s.idSigVerified)return{granted:!1,reason:`its creator, ${i}, is not on the fabric with a verified identity`};let a={reference:e,grantee:r,...n!==void 0?{trace:{thread_id:n.threadId,root_id:n.rootId,...o!==void 0?{tool_call_id:o}:{}}}:{}};return rn(this.#t,i,a,this.#n!==void 0?{timeoutMs:this.#n}:{})}async#c(e){let t=this.#i.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.#s(n)}catch{}return this.#i.get(e)}#s(e){let t=this.#i.get(e.promptSubject);if(t===void 0||e.idSigVerified||!t.idSigVerified)this.#i.set(e.promptSubject,e)}};function cn(e){return new an(e)}function ot(){let e=ne();return e!==void 0?{threadId:e.threadId,rootId:e.rootId}:void 0}function un(e){return e instanceof Error?e.message:String(e)}var St=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 Rt(e,t){return new St("invalid",e,{local:!0,cause:t})}var dn=/[\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 ln=524288,Bt=921600;var fn=8192,hn=128,pn=16384,gn=131072;var mn=ln;var vn=4294967295,Dn=8,kt=8,yn=16,Fn=3600,bn="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";var Zo=Object.freeze({object_bytes:Bt,read_bytes:mn,control_bytes:pn,reply_bytes:gn,writers:Dn,retentions:kt,grants:yn,grant_seconds:Fn});function D(e,t){if(!e)throw Rt(t)}function K(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 Q(e,t=Number.MAX_SAFE_INTEGER,r=0){D(typeof e==="number"&&Number.isSafeInteger(e)&&e>=r&&e<=t,"integer outside its bound")}function Y(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 xt(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 Ie(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 a of e)if(o=o<<5|r.indexOf(a),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 s=0;for(let a of i.slice(0,33)){s^=a<<8;for(let c=0;c<8;c++)s=(s<<1^(s&32768?4129:0))&65535}D(i[33]===(s&255)&&i[34]===s>>>8,"NKEY checksum differs")}function wn(e){let t=K(e,["account","user"]);Ie(t.account,"account"),Ie(t.user,"user")}function Tt(e){Y(e,255,1),D(e!=="."&&e!==".."&&!/[\x00-\x1f\x7f/]/.test(e),"forbidden entry name"),D(En(e)===e,"entry name is not NFC")}function En(e){let t="",r="";for(let n of e)if(dn.test(n))t+=r.normalize("NFC")+n,r="";else r+=n;return t+r.normalize("NFC")}function _n(e,t=4096){if(Y(e,t,1),D(e.startsWith("/"),"path must be absolute"),e==="/")return;let r=e.slice(1).split("/");D(r.length<=hn,"path exceeds its depth bound");for(let n of r)Tt(n)}function It(e){D(typeof e==="string"&&/^[0-9A-Za-z]{1,64}$/.test(e),"invalid volume name")}function Ot(e){let t=K(e,["volume","creation_id"]);It(t.volume),D(typeof t.creation_id==="string"&&/^[0-9a-f]{32}$/.test(t.creation_id),"invalid volume creation identity")}function An(e){let t=K(e,[],["thread_id","root_id","tool_call_id"]);for(let r of["thread_id","root_id"])if(t[r]!==void 0)Y(t[r],32);if(t.tool_call_id!==void 0)Y(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 Nt(e){let t=K(e,["operation_id","trace"]);Y(t.operation_id,256,1),D([...t.operation_id].length<=64,"operation identity is too long"),An(t.trace)}function Cn(e){let t=K(e,["slot","generation"]);Q(t.slot,kt-1),Q(t.generation,void 0,1)}function jt(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)&&jt(r[o],n[o]))}function Sn(e){let t=K(e,["slot","generation","operation_id"]);Q(t.slot,vn),Q(t.generation,void 0,1),Nt({operation_id:t.operation_id,trace:{}})}function Rn(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 Bn(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++},s=()=>{let l=o++;for(;;){D(o<n.length,"unterminated JSON string");let y=n[o++];if(y==="\\"){o++;continue}if(y==='"')break}let h=JSON.parse(n.slice(l,o));return Y(h,t),h},a=(l)=>{D(l<=64,"JSON nesting exceeds bound"),i();let h=n[o];if(h==='"')return s();if(h==="{"){o++,i();let v=Object.create(null);if(n[o]==="}")return o++,v;for(;;){D(n[o]==='"',"JSON key must be a string");let _=s();i(),D(!Object.hasOwn(v,_),"duplicate JSON key"),D(n[o++]===":","missing JSON colon"),v[_]=a(l+1),i();let E=n[o++];if(E==="}")return v;D(E===",","invalid JSON object separator"),i()}}if(h==="["){o++,i();let v=[];if(n[o]==="]")return o++,v;for(;;){v.push(a(l+1)),i();let _=n[o++];if(_==="]")return v;D(_===",","invalid JSON array separator"),i()}}for(let[v,_]of[["true",!0],["false",!1],["null",null]])if(n.startsWith(v,o))return o+=v.length,_;let y=/^-?(?:0|[1-9][0-9]*)/.exec(n.slice(o));D(y,"invalid JSON value"),o+=y[0].length;let A=Number(y[0]);return D(Number.isSafeInteger(A)&&!Object.is(A,-0),"unsafe or noncanonical JSON integer"),A},c=a(0);return i(),D(o===n.length,"trailing JSON data"),c}var kn=class extends Error{constructor(e,t){super(t);this.reason=e,this.name="CodecError"}reason};function M(e,t){throw new kn(e,t)}function xn(e,t){return ht("sha256").update(e).update("\x00").update(t).digest("base64url")}function Tn(e){return xn("scratchpad:v1:tree",e)}function te(e,t){if(Q(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 In(e){return Buffer.concat([te(2,e.length),e])}function Z(e){let t=Buffer.from(e);return Buffer.concat([te(3,t.length),t])}function On(e){if(typeof e!=="string"||Buffer.from(e).toString("utf8")!==e)M("utf8","invalid entry name UTF-8");if(Buffer.byteLength(e)===0||Buffer.byteLength(e)>255)M("name-length","entry name length exceeds bound");if(e==="."||e===".."||/[\x00-\x1f\x7f/]/.test(e))M("name-forbidden","forbidden entry name");try{Tt(e)}catch{M("not-nfc","entry name is not NFC")}}function Nn(e){if(On(e.name),e.type==="symlink"){if(e.executable||e.object!==void 0&&e.object!==bn)M("type-invalid","symlink has file fields");let t=e.linkTarget??"";if(typeof t!=="string"||Buffer.from(t).toString("utf8")!==t)M("utf8","invalid symlink UTF-8");if(Buffer.byteLength(t)===0||Buffer.byteLength(t)>4096||t.includes("\x00"))M("target-invalid","invalid symlink target")}else{if(e.type!=="file"&&e.type!=="directory")M("type-invalid","unknown entry type");if(xt(e.object),e.linkTarget||e.type==="directory"&&e.executable)M("type-invalid","entry has fields of another type")}}function jn(e){for(let o of e)Nn(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)M("duplicate-name","duplicate tree entry");if(e.length>fn)M("entry-count","tree entry count exceeds bound");let r=[te(5,1),Z("e"),te(4,e.length)],n=r.reduce((o,i)=>o+i.length,0);for(let o of t){let i=[te(5,o.executable?4:3)];if(o.type==="symlink")i.push(Z("l"),Z(o.linkTarget));else i.push(Z("i"),In(Buffer.from(o.object,"base64url")));if(i.push(Z("n"),Z(o.name),Z("t"),te(0,o.type==="file"?0:o.type==="directory"?1:2)),o.executable)i.push(Z("x"),te(0,1));if(n+=i.reduce((s,a)=>s+a.length,0),n>Bt)M("node-size","tree node byte count exceeds bound");r.push(...i)}return Buffer.concat(r)}Tn(jn([]));function Pt(e){let t=K(e,["version","creator","account","target","root","generation","path","retention","expires_at"]);D(t.version===2,"reference version must be two"),Y(t.creator,512,1),Ie(t.account,"account"),Ot(t.target),xt(t.root),Q(t.generation,void 0,1),_n(t.path,256),Cn(t.retention),Q(t.expires_at,void 0,1)}function Pn(e){Pt(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(Rn(t,!1)).toString("base64url");return D(Buffer.byteLength(r)<=16384,"reference exceeds byte bound"),r}var Oe="sp-r1:",De=66;function qt(e){Y(e,De,De),D(/^sp-r1:[A-Za-z0-9_-]{60}$/.test(e),"malformed short reference");let t=Buffer.from(e.slice(Oe.length),"base64url");D(t.length===45&&t[32]<64,"invalid short reference slots");let r=Number(t.readBigUInt64BE(24));Q(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 Ot({volume:"Reference",creation_id:n.creation_id}),n}function qn(e,t){return ht("sha256").update(`scratchpad-reference-volume-v1\x00${e}\x00${t}`).digest().subarray(0,8).toString("hex")}function Ln(e){let t=K(e,["short","expanded"]);Y(t.short,De,De);let r=qt(t.short);Pt(t.expanded),D(r.route===qn(t.expanded.account,t.expanded.target.volume)&&r.creation_id===t.expanded.target.creation_id&&jt(r.retention,t.expanded.retention),"short reference binding differs")}var Ne=4096;function $n(e){let t=K(Bn(e,Ne),["version","principal","volume","admission","creation"]);return D(t.version===1,"unsupported ScratchPad bootstrap version"),wn(t.principal),It(t.volume),Sn(t.admission),Nt(t.creation),t}function Lt(e){D(typeof e==="string"&&e.length>0,"bootstrap file path is required");let t;try{t=Dr(e,Ae.O_RDONLY|Ae.O_NONBLOCK|(Ae.O_NOFOLLOW??0));let r=yr(t);D(r.isFile(),"bootstrap must be a regular file"),D(r.size<=Ne,"bootstrap exceeds its byte bound");let n=Buffer.alloc(Ne+1),o=0;while(o<n.length){let i=Fr(t,n,o,n.length-o,o);if(i===0)break;o+=i}return $n(n.subarray(0,o))}catch(r){if(r instanceof St)throw r;throw Rt("cannot read ScratchPad bootstrap file",r)}finally{if(t!==void 0)br(t)}}var Mn="sp",Un=600,it=600,Vn=5,st=16,Hn=16384,$t=16777216,Gn=Math.ceil($t/3)*4+65536,Xn=262144,zn=65536,Mt=/^A[A-Z2-7]{55}$/,Ut=/^[0-9A-Za-z]{1,64}$/,Jn=/^[0-9a-f]{32}$/,Wn=/^[A-Za-z0-9_-]{43}$/,Yn=/^[A-Za-z0-9_-]+$/,Kn=/^[A-Za-z0-9+/]*={0,2}$/,C=class extends Error{constructor(e,t,r){super(e);this.code=t,this.unknown=r,this.name="ScratchPadError"}code;unknown},O=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),ye=(e,t)=>Object.keys(e).length===t.length&&t.every((r)=>(r in e)),le=(e)=>Number.isSafeInteger(e)&&e>0,Vt=(e)=>Buffer.byteLength(e,"utf8");function Ht(e){return O(e)&&ye(e,["volume","creation_id"])&&typeof e.volume==="string"&&Ut.test(e.volume)&&typeof e.creation_id==="string"&&Jn.test(e.creation_id)}function Zn(e){if(typeof e!=="string"||!e.startsWith("/")||Vt(e)>256)return!1;if(e==="/")return!0;return e.slice(1).split("/").every((t)=>t!==""&&t!=="."&&t!=="..")}function Se(e){let t=(s)=>{throw Error(`malformed ScratchPad reference: ${s}`)};if(typeof e!=="string"||!e.startsWith(ge))t("no sp-ref: prefix");if(e.length>Hn)t("longer than 16 KiB");let r=e.slice(ge.length);if(!Yn.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(!O(n)||!ye(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||Vt(n.creator)>512||typeof n.account!=="string"||!Mt.test(n.account)||!Ht(n.target)||typeof n.root!=="string"||!Wn.test(n.root)||!le(n.generation)||!Zn(n.path)||!O(i)||!ye(i,["slot","generation"])||!Number.isSafeInteger(i.slot)||i.slot<0||i.slot>7||!le(i.generation)||!le(n.expires_at))t("a field is out of shape");return n}var ee=()=>Math.floor(Date.now()/1000),at=8,Qn=16,eo=["close","apply","release","grant"],to=["workspace","not_found"],re=(e)=>Number.isSafeInteger(e)&&e>=0;function ro(e){let t=(l)=>{throw new C(`sp describe: ${l}`,"malformed_reply",!1)};if(!O(e)||!O(e.volume))return t("the reply names no volume");let{volume:r,control:n}=e,o;if(n!==null&&n!==void 0){if(!O(n)||typeof n.kind!=="string"||!eo.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:s}=r;if(!Array.isArray(i)||i.length!==at)return t("not eight retention slots");if(!Array.isArray(s)||s.length!==Qn)return t("not sixteen grant slots");let a=i.map((l)=>{if(!O(l)||!re(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(!O(h)||!re(h.until)||typeof h.root!=="string")return t("a retention pin is out of shape");return{generation:l.generation,until:h.until}}),c=[];for(let l of s){if(!O(l)||!re(l.generation))return t("a grant slot is out of shape");let h=l.grant;if(h===void 0||h===null)continue;let y=O(h)?h.retention:void 0;if(!O(h)||!re(h.until)||!O(y)||!re(y.slot)||y.slot>=at||!le(y.generation))return t("a grant is out of shape");c.push({slot:y.slot,generation:y.generation,until:h.until})}return{closed:r.closed,control:o,retentions:a,grants:c}}function no(e){let t=(o)=>{throw new C(`sp spool-remove: ${o}`,"malformed_reply",!1)};if(!O(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(!ye(e,n)||r&&(typeof e.phase!=="string"||e.phase==="")||!re(e.files)||!re(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 oo(e,t=ee()){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((s)=>s.slot===i&&s.generation===o.generation&&s.until>t))?void 0:"every retention slot holds a live pin"}function io(e){let t=e.bootstrapFile===void 0?void 0:Lt(e.bootstrapFile),r=e.volume??t?.volume;if(!r||!Ut.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??Mn,s=e.dir??we(hr(),`scratchpad-${n}`),a=Math.min(e.grantTtlS??it,it),c,l,h=Promise.resolve(),y=!0,A,v=new Map;function _(u){let f=h.then(u);return h=f.catch(()=>{return}),f}let E=new Map;async function P(u,f){if(!u.startsWith(Oe))return Se(u);qt(u);let d=E.get(u);if(d&&d.expires_at>ee())return structuredClone(d);let F=await w("resolve",["--ref",u],{trace:f}),x={short:u,expanded:F?.reference};if(Ln(x),F.full_reference!==Pn(x.expanded))throw new C("sp resolve: expanded token differs from descriptor","malformed_reply",!1);let B=Se(F.full_reference);if(B.expires_at<=ee())throw Error("the reference has expired");if(E.delete(u),E.set(u,B),E.size>64)E.delete(E.keys().next().value);return structuredClone(B)}async function S(){return c??=(async()=>(await lr(s,{recursive:!0,mode:448}),fr(s)))(),c}async function w(u,f,d={}){let F=d.trace?["--thread-id",d.trace.threadId,"--root-id",d.trace.rootId]:[];if(d.trace&&d.toolCallId!==void 0)F.push("--tool-call-id",d.toolCallId);let x=["read","resolve"].includes(u)?[]:["--volume",n],B=u==="init"&&e.bootstrapFile?["--bootstrap-file",e.bootstrapFile]:[],H=[u,...o,"--dir",await S(),...x,...B,...f,...F],J=d.maxStdout??Xn,{code:k,stdout:W,stderr:T}=await new Promise((L)=>{dr(i,H,{maxBuffer:Math.max(J,zn),encoding:"utf8"},(nr,or,ir)=>{let se=nr;L({code:se===null?0:typeof se.code==="number"?se.code:null,stdout:or??"",stderr:ir||(se!==null&&typeof se.code==="string"?se.message:"")})}).stdin?.end(d.stdin??"")});if(k===null&&/^spawn .*(ENOENT|EACCES)/m.test(T))throw new C(`sp ${u}: ${T.trim()}`,"spawn_failed",!1);if(k===0&&W.length<=J)try{return JSON.parse(W)}catch{}let I={code:k===0?"malformed_reply":"failed",message:T.trim().slice(0,512)||`exit ${k??"by signal"}`,unknown:d.mutation===!0};if(k!==0)try{let L=JSON.parse(T).error;if(O(L)&&typeof L.code==="string")I={code:L.code,message:typeof L.message==="string"?L.message:"",unknown:L.unknown===!0||d.mutation===!0&&typeof L.unknown!=="boolean"}}catch{}throw new C(`sp ${u}: ${I.code}${I.unknown?" (outcome unknown)":""}: ${I.message}`,I.code,I.unknown)}function G(u,f){let d=u,F=d?.principal?.account;if(typeof F!=="string"||!Mt.test(F)||!Ht(d.target))throw new C(`sp ${f}: the reply names no principal and target`,"malformed_reply",!1);if(d.target.volume!==n)throw new C(`sp ${f}: the workspace is bound to another volume`,"invalid",!1);return{account:F,target:{volume:d.target.volume,creation_id:d.target.creation_id}}}async function U(u){return l??=G(await w("init",[],{trace:u,mutation:!0}),"init"),l}async function V(u){if(l!==void 0)return l;try{l=G(await w("describe",[],{trace:u}),"describe")}catch(f){if(f instanceof C&&to.includes(f.code))return;throw f}return l}let N=(u,f)=>f!==void 0&&u.account===f.account&&u.target.volume===f.target.volume&&u.target.creation_id===f.target.creation_id,oe=(u,f)=>JSON.stringify([u.account,u.target.volume,u.target.creation_id,u.root,u.path,f.account,f.user]);function _e(){let u=ee();for(let[f,d]of v)if(Math.max(d["first-hand"]??0,d["on-request"]??0)<=u)v.delete(f)}function X(u,f,d){v.set(u,{...v.get(u),[f]:d})}function p(u,f){let d=u;if(!O(d)||!O(d.handle)||!le(d.expires_at))throw new C("sp grant: the reply names no handle and expiry","malformed_reply",!0);return Math.min(d.expires_at,f.expires_at)}async function m(u,f,d,F){return w("publish-file",["--source","-","--path",f,"--operation-id",d,"--creator",e.creator,"--ttl-seconds",String(Un)],{trace:F,stdin:u,mutation:!0})}async function g(u){if(!y)return;try{await w("recover",[],{trace:u,mutation:!0})}catch(f){if(!(f instanceof C)||f.unknown)throw f}y=!1}async function b(u,f){let d;try{let F=no(await w("spool-remove",["--apply"],{trace:f,mutation:!0}));if(!F.present||F.applied)return;d="the refused publication's spool is protected"}catch(F){if(F instanceof C&&F.unknown)throw F;d=`its spool was not removed: ${F.message}`}throw y=!0,new C(`${u.message}; cleanup not started: ${d}`,u.code,!1)}async function j(u){return ro(await w("describe",[],{trace:u}))}async function ie(u,f,d){if(e.creator===void 0)throw Error("ScratchPad: a reference names its creator; this ScratchPad was made without one");let F=await U(d);await g(d);let x=We(),B;try{B=await m(u,f,x,d)}catch(k){if(k instanceof C&&k.unknown)y=!0;if(!(k instanceof C)||k.code!=="capacity"||k.unknown)throw k;await b(k,d);let W;try{W=oo(await j(d))}catch(T){throw new C(`${k.message}; cleanup not started: ${T.message}`,k.code,!1)}if(W!==void 0)throw new C(`${k.message}; cleanup not started: ${W}`,k.code,!1);try{await w("maintain",["--apply"],{trace:d,mutation:!0})}catch(T){y=!0;let I=!(T instanceof C)||T.unknown;throw new C(`${k.message}; cleanup: ${T.message}`,I&&T instanceof C?T.code:I?"failed":k.code,I)}try{B=await m(u,f,x,d)}catch(T){if(T instanceof C&&T.unknown)y=!0;throw T}}let H=B?.reference;if(typeof H!=="string"||!O(B.receipt))throw y=!0,new C("sp publish-file: the reply names no receipt and reference","malformed_reply",!0);let J=await P(H,d);if(!N(J,F)||J.path!==f||J.creator!==e.creator)throw new C("sp publish-file: the reference names another volume, path or creator","malformed_reply",!1);return H}async function ce(u,f,d,F){return p(await w("grant",u,{trace:f,toolCallId:d,mutation:!0}),F)}async function ue(u,f,d,F,x){let B=await P(u,d);if(!N(B,await V(d)))throw Error("the reference points into another agent's volume; only its creator can grant read on it");if(await g(d),A!==void 0){let I=A;try{X(I.key,I.kind,await ce(I.args,void 0,void 0,I.ref)),A=void 0}catch(L){if(!(L instanceof C)||L.unknown)throw L;A=void 0}}let H=B.expires_at-ee()-Vn,J=Math.floor(Math.min(a,H));if(J<1)throw Error("the reference has expired, or is about to; there is nothing left to grant on");let k=oe(B,f);if(_e(),!v.has(k)&&v.size>=st)throw Error(`this agent already holds ${st} live grants; try again when one expires`);let W=d?["--thread-id",d.threadId,"--root-id",d.rootId]:[];if(d&&F!==void 0)W.push("--tool-call-id",F);let T=["--ref",u,"--grantee-account",f.account,"--grantee-user",f.user,"--operation-id",We(),"--ttl-seconds",String(J)];try{X(k,x,await ce(T,d,F,B))}catch(I){if(I instanceof C&&I.unknown)A={args:[...T,...W],key:k,kind:x,ref:B};throw I}}return{commit(u,f,d){return _(()=>ie(u,f,d))},async read(u,f){if((await P(u,f)).expires_at<=ee())throw Error("the reference has expired");let F=await w("read",["--ref",u],{trace:f,maxStdout:Gn}),{data_base64:x,bytes:B}=F??{};if(typeof x!=="string"||!Kn.test(x)||!Number.isSafeInteger(B)||B>$t)throw new C("sp read: the reply carries no data","malformed_reply",!1);let H=Buffer.from(x,"base64");if(H.length!==B||H.toString("base64")!==x)throw new C("sp read: the data does not match its length","malformed_reply",!1);try{return new TextDecoder("utf-8",{fatal:!0}).decode(H)}catch{throw Error("the referenced file is not UTF-8 text")}},resolveReference:P,async owns(u){let f;try{f=await P(u)}catch{return!1}return N(f,await V(ne()))},grantRead(u,f,d,F,x="first-hand"){return _(()=>ue(u,f,d,F,x))},granted(u,f){let d=(F)=>{if(!N(F,l))return;let x=v.get(oe(F,f)),B=ee();if((x?.["first-hand"]??0)>B)return"first-hand";if((x?.["on-request"]??0)>B)return"on-request";return};if(u.startsWith(Oe))return P(u).then(d,()=>{return});try{return d(Se(u))}catch{return}}}}var so="SCRATCHPAD_VOLUME",ao="SCRATCHPAD_BOOTSTRAP_FILE",co="SCRATCHPAD_BIN",uo="SCRATCHPAD_DIR";var lo=409;function fo(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 ho(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 po(e){return(typeof e==="object"||typeof e==="function")&&e!==null&&typeof e.then==="function"}function Gt(){let e=new Map,t=new Map,r=(s)=>{let a=t.get(s);if(a===void 0)return!1;for(let c of a)if(c.waiting)return!0;return!1},n=(s,a)=>{e.set(s,a);let c=t.get(a.rootId);if(c===void 0)t.set(a.rootId,c=new Set);c.add(a)},o=(s,a)=>{if(e.get(s)===a)e.delete(s);let c=t.get(a.rootId);if(c===void 0)return;if(c.delete(a),c.size===0)t.delete(a.rootId)},i=(s,a,c)=>{s.running-=1;let l=a?ho(c):void 0;if(l===void 0)return;if(s.open=l,s.running===0&&s.open===0)s.waiting=!1};return{requestInterceptor:{async aroundRequest(s,a){let c=ne();if(c===void 0){await a();return}let{rootId:l}=c;if(r(l))throw new fe(lo,fo(l));let h={rootId:l,waiting:!1,running:0,open:0};n(c,h);try{await a()}finally{o(c,h)}}},promptInterceptor:{beforePrompt(){let s=ne(),a=s===void 0?void 0:e.get(s);if(a!==void 0)a.waiting=!0}},aroundToolCall(s,a){let c=s===void 0?void 0:e.get(s);if(c===void 0)return a();c.running+=1;let l;try{l=a()}catch(h){throw i(c,!1),h}if(po(l))l.then((h)=>i(c,!0,h),()=>i(c,!1));else i(c,!0,l);return l},open(s){let a={rootId:s.rootId,waiting:!1,running:0,open:0};n(s,a);let c=!1;return()=>{if(c)return;c=!0,o(s,a)}},serving:(s)=>t.has(s),waiting:r}}var go=Symbol.for("synadia.fabric.scratchpad.workspace-owners.v1"),mo=globalThis,Qo=mo[go]??=new Set;var ct="edgeSubject",vo="SYNADIA_FABRIC_EDGE_SUBJECT";function Xt(e,t=process.env){if(Object.hasOwn(e,ct))return e[ct];let r=t[vo];if(r!==void 0)return r;return je}var zt="scratchpad",R={url:"SP_NATS_URL",creds:"SP_NATS_CREDS",dir:uo,volume:so,bootstrapFile:ao,creator:"SP_CREATOR",threadId:"SP_THREAD_ID",rootId:"SP_ROOT_ID",callerAccount:"SP_CALLER_ACCOUNT",callerUser:"SP_CALLER_USER",grants:"SP_GRANTS_FILE"},Do=["NATS_CREDS","NATS_CREDENTIALS"];async function Ue(e,t,r={}){let n=e.logger,o=e.options[zt],i=o!==null&&typeof o==="object"?o:{},s=(S)=>{let w=i[S];return typeof w==="string"&&w!==""?w:void 0},a=(S)=>{let w=t[S];return w===void 0||w===""?void 0:w},c=(S,w)=>s(S)??a(w),l=c("bootstrapFile",R.bootstrapFile),h=l===void 0?void 0:Qe(Re(l)),y=h===void 0?void 0:Lt(h),A=c("volume",R.volume)??y?.volume;if(A===void 0)return;if(y&&y.volume!==A)throw Error("ScratchPad bootstrap differs from the configured volume");let v=s("url"),_=s("creds");if(v===void 0||_===void 0){let S=a("NATS_URL"),w;for(let N of r.credsVariables??Do)if(w=a(N),w!==void 0)break;let G=t.NATS_CONTEXT,U=G!==void 0||S!==void 0||w!==void 0,V=G?G:U?void 0:de(e.settings.config.context);if(V!==void 0)try{let{fields:N}=await lt(V);v??=de(N.url),_??=de(N.creds)}catch(N){n.warn(`agent-fabric: ScratchPad is off: the NATS context "${V}" could not be read (${String(N)})`);return}else if(U)v??=S,_??=w}if(v??=de(e.settings.config.url),_??=de(e.settings.config.credentials),v===void 0||_===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 E=c("dir",R.dir);if(E===void 0&&e.settings.stateDir!==void 0)E=we(e.settings.stateDir,"scratchpad");if(y&&E===void 0)throw Error("ScratchPad bootstrap requires a persistent workspace directory");if(E!==void 0){E=Qe(Re(E));try{pr(E,{recursive:!0,mode:448})}catch(S){n.warn(`agent-fabric: ScratchPad workspace ${E} could not be created (${String(S)})`)}}let P=E!==void 0?`${E}.grants`:void 0;if(P!==void 0)Fo(P,n);return{url:v,creds:Re(_),volume:A,...h===void 0?{}:{bootstrapFile:h},...E!==void 0?{dir:E}:{},...P!==void 0?{grants:P}:{}}}function Ve(e,t){if(t[R.url]=e.url,t[R.creds]=e.creds,e.bootstrapFile!==void 0)t[R.bootstrapFile]=e.bootstrapFile,delete t[R.volume];else t[R.volume]=e.volume,delete t[R.bootstrapFile];if(e.dir!==void 0)t[R.dir]=e.dir;if(e.grants!==void 0)t[R.grants]=e.grants}var He=class{constructor(e){this.env=e}env;#e;enter(e,t){if(this.#t(),this.#e=e.id,t!==void 0)this.env[R.threadId]=t.threadId,this.env[R.rootId]=t.rootId;if(e.caller!==void 0)try{let r=he(e.caller);this.env[R.callerAccount]=r.account,this.env[R.callerUser]=r.user}catch{}}leave(e){if(this.#e===e.id)this.#t(),this.#e=void 0}#t(){delete this.env[R.threadId],delete this.env[R.rootId],delete this.env[R.callerAccount],delete this.env[R.callerUser]}};function Jt(e,t){let r=e[co];if(r!==void 0&&r!=="")return r;let n=Ye()==="darwin"?"darwin":Ye()==="linux"?"linux":void 0,o=Ke()==="arm64"?"arm64":Ke()==="x64"?"amd64":void 0;if(n===void 0||o===void 0)return;return we(t,"bin",`sp-${n}-${o}`)}var Ge=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=cn({scratchPad:t,agents:r});for(let s of this.#r.splice(0))this.#e.remember(s);if(n===void 0)return;let o=e.logger??be,i=on({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(s){o.warn(`agent-fabric: grant requests are not answered: ${String(s)}`)}}discoveryFields(e){return this.#e?.discoveryFields(e)??{[Ct]:Te(e.metadata)}}async beforePrompt(e){let t=this.#e,r=this.#t;if(t===void 0||r===void 0){if(me(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(me(e.prompt)))if(await r.owns(n))t.remember(n);return t.beforePrompt(e)}afterReply(e){this.#e?.afterReply(e)}};function Wt(e,t,r,n){let o=Jt(r,n);if(o===void 0)return;let i=io({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?bo(i,e.grants):i}var yo=/^(\d+) (\S+) (\S+) (sp-(?:ref|r1):[A-Za-z0-9_-]+)$/;function Yt(e){let t;try{t=gr(e,"utf8")}catch{return[]}let r=[];for(let n of t.split(`
|
|
5
|
+
`)){let o=yo.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 Fo(e,t){let r=Math.floor(Date.now()/1000),n=Yt(e).filter((o)=>o.expiresAt>r);try{let o=`${e}.${process.pid}.tmp`;mr(o,n.map((i)=>`${i.expiresAt} ${i.grantee.account} ${i.grantee.user} ${i.reference}
|
|
6
|
+
`).join(""),{mode:384}),vr(o,e)}catch(o){t.warn(`agent-fabric: ScratchPad grants file ${e} could not be written (${String(o)})`)}}function bo(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,s,a)=>e.grantRead(n,o,i,s,a),async granted(n,o){let i=await e.granted(n,o);if(i==="first-hand")return i;let s=r();return Yt(t).some((c)=>c.reference===n&&c.grantee.account===o.account&&c.grantee.user===o.user&&c.expiresAt>s)?"first-hand":i}}}function de(e){return typeof e==="string"&&e!==""?e:void 0}function Re(e){if(e==="~")return Ze();if(e.startsWith("~/"))return we(Ze(),e.slice(2));return e}import{mkdirSync as wo,renameSync as Eo,rmSync as _o,writeFileSync as Ao}from"fs";import{dirname as Co,join as So}from"path";import{fileURLToPath as Ro}from"url";var Bo=Ro(new URL("../skills/scratchpad",import.meta.url));function Kt(e,t,r){return Wt(e,t,r,Bo)}function Zt(e,t,r=process.ppid){let n=t.CLAUDE_PID;return So(e,"agent-fabric",`${n!==void 0&&/^\d+$/.test(n)?n:String(r)}.env`)}var ko=new Set(Object.values(R));class Xe{path;vars={};constructor(e){this.path=e}write(){let e="";for(let[r,n]of Object.entries(this.vars)){if(!ko.has(r)||n===void 0||/[\r\n]/.test(n))continue;e+=`${r}=${n}
|
|
7
|
+
`}wo(Co(this.path),{recursive:!0,mode:448});let t=`${this.path}.${process.pid}.tmp`;Ao(t,e,{mode:384}),Eo(t,this.path)}remove(){_o(this.path,{force:!0})}}var z="agent-fabric",ze="claude",Qt=120000,er=`${z}: senderIdentity is off; trace records are signed, so none will be published and each counts as dropped on the heartbeat. Set senderIdentity to signed.`,tr=`${z}: no Claude Code session id known for this prompt, so no served pair; its model calls stand as a harness thread of their own. Are the plugin's hooks registered?`,xo=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;function ae(e){return typeof e==="string"&&xo.test(e)}function To(e){let t=e.stopWaitMs;if(t===void 0)return Qt;if(typeof t!=="number"||!Number.isFinite(t)||t<0)throw new Fe(`${z}: options.stopWaitMs must be a number of ms \u2265 0`);return t}async function Je(e,t=process.env){return rr(e,t,await Ue(e,t))}function rr(e,t=process.env,r){let n=Xt(e.options,t),o=To(e.options),i=Ft({edgeSubject:n}),s=Gt(),a=e.logger,c,l,h=new Map,y=0,A=new Map,v=[],_=[],E=(p)=>{let m=_.indexOf(p);if(m>=0)_.splice(m,1);clearTimeout(p.timer)},P=!1,S;if(r!==void 0)if(e.settings.stateDir!==void 0)S=new Xe(Zt(e.settings.stateDir,t));else a.warn(`${z}: the plugin names no state directory, so the skill's scripts/sp gets no ScratchPad settings`);let w=()=>{if(S===void 0)return;try{S.write()}catch(p){a.warn(`${z}: ScratchPad's settings for scripts/sp: ${String(p)}`)}};if(r!==void 0&&S!==void 0)Ve(r,S.vars),w();let G=S!==void 0?new He(S.vars):void 0,U=r!==void 0?new Ge:void 0,V,N=()=>{if(G===void 0)return;let p=[...A.values()].at(-1),m;for(let b of h.values())if(b.started!==void 0&&(m===void 0||b.started>m.started))m=b;let g=p!==void 0?{holder:p.turn,scope:p.scope}:m!==void 0?{holder:m.request,scope:m.scope}:void 0;if(g?.holder.id===V)return;if(g!==void 0)G.enter(g.holder,g.scope);else if(V!==void 0)G.leave({id:V});V=g?.holder.id,w()},oe=(p,m,g)=>{if(!ae(m)){a.warn(tr);return}let b=c?.beginTurn(p,ze,g);return b?.bind(m),{turn:b,sessionId:m}},_e=()=>A.size>0||_.length>0||[...h.values()].some((p)=>p.started!==void 0),X=(p,m=!1)=>{if(v.length===0||!m&&_e())return;for(let{entry:g,outcome:b,reason:j}of v.splice(0))oe(g.scope,g.acceptedSession,p)?.turn?.settle(b,p,j)};return{name:z,requestInterceptors:[i.requestInterceptor,s.requestInterceptor,...U!==void 0?[U.requestInterceptor]:[]],promptInterceptors:[i.promptInterceptor,s.promptInterceptor],heartbeatExtras:i.heartbeatExtras,...U!==void 0?{toolExtensions:[U],metadata:{[Me]:"true"}}:{},started({agents:p,service:m}){if(e.settings.senderIdentity!=="signed"&&!P)P=!0,a.warn(er);if(n!==null)c=wt({agents:p,subject:n,logger:a});if(a.info(`${z}: tracing ${m.subject.prompt}`+(n===null?" (propagate-only: lineage forwarded, no edge or served record published)":`, edge and served records on ${n}`)),r!==void 0&&U!==void 0){if(S!==void 0)S.vars[R.creator]=m.subject.prompt,w();let g=Kt(r,m.subject.prompt,t);if(g!==void 0)U.start({scratchPad:g,agents:p,service:m,logger:a});else a.warn(`${z}: no sp for this platform (set SCRATCHPAD_BIN); references in prompt_agent are not handed on, and grant requests not answered`);a.info(`${z}: ScratchPad volume ${r.volume}`+(r.dir!==void 0?`, workspace ${r.dir}`:", no workspace")+(S!==void 0?`, for the skill's scripts/sp through ${S.path}`:""))}},async stopping(){let p=Date.now();for(let[m,g]of A)A.delete(m),g.pair?.settle("ok",p),g.close();X(p,!0);for(let m of[..._])E(m),m.turn.settle("ok",m.repliedAtMs);for(let[m,g]of h)if(h.delete(m),g.started!==void 0)g.turn?.settle("error",void 0,"shutdown");else oe(g.scope,g.acceptedSession,p)?.turn?.settle("error",p,"shutdown");S?.remove(),await c?.flush()},events:{sessionStarted(p){if(ae(p))l=p},promptAccepted(p){let m=ne();if(m===void 0)return;let g=p.sessionId??l;h.set(p.id,{request:p,scope:m,acceptedSession:ae(g)?g:void 0,started:void 0,sessionId:void 0,turn:void 0})},promptStarted(p,m,g){let b=h.get(p.id);if(b===void 0||b.started!==void 0)return;b.started=++y;let j=oe(b.scope,ae(g)?g:b.acceptedSession,m);b.turn=j?.turn,b.sessionId=j?.sessionId,N()},promptEnded(p,m,g,b){let j=h.get(p.id);if(h.delete(p.id),N(),j===void 0)return;if(j.started===void 0){v.push({entry:j,outcome:m,reason:b}),X(g);return}let{turn:ie,sessionId:ce}=j;if(ie===void 0||ce===void 0){X(g);return}if(m!=="ok"||b==="final_text"){ie.settle(m,g,b),X(g);return}let ue={sessionId:ce,turn:ie,repliedAtMs:g,timer:setTimeout(()=>{E(ue),ie.settle("ok",g),X(g)},o)};ue.timer.unref?.(),_.push(ue)},turnStopped(p,m){for(let g of[..._]){if(p!==void 0&&g.sessionId!==p)continue;if(g.repliedAtMs>=m)continue;E(g),g.turn.settle("ok",m)}X(m)},localTurnStarted(p,m){if(A.has(p.id))return;let g=Le(),b=s.open(g),j;if(ae(p.sessionId))j=c?.beginTurn(g,ze,m),j?.bind(p.sessionId);A.set(p.id,{turn:p,scope:g,close:b,pair:j}),N()},localTurnEnded(p,m,g){let b=A.get(p.id);if(b===void 0)return;A.delete(p.id),b.pair?.settle(m,g),b.close(),X(g),N()},aroundToolCall(p,m,g){let b=p===void 0?void 0:A.get(p.id)?.scope??h.get(p.id)?.scope;return b===void 0?g():Pe(b,()=>s.aroundToolCall(b,g))}}}}export{Je as default};
|