@tangle-network/sandbox-cli 0.22.123 → 0.22.124

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.
@@ -1 +1 @@
1
- import{findPackageJSON as e}from"node:module";import{canonicalCandidateDigest as t}from"@tangle-network/agent-interface";import{isAbsolute as n,join as r,relative as i,resolve as a}from"node:path";import{z as o}from"zod";import{readFile as s,realpath as c}from"node:fs/promises";import{HubVectorSearchProvider as l,KnowledgeImprovementCandidateRefSchema as u,SourceRecordSchema as d,assertKnowledgeRetrievalMatchesVisibilityArtifact as f,buildKnowledgeBrief as p,chunkMarkdown as m,createKnowledgeRetrievalReceipt as h,createKnowledgeTools as g,createKnowledgeVisibilitySnapshot as _,createRunScopedStores as v,decodeKnowledgeVisibilitySnapshot as y,encodeKnowledgeVisibilitySnapshot as b,hashKnowledgeBase as x,knowledgeVisibilityArtifactRef as S,loadSourceRegistry as C,originatedPages as w,parseKnowledgeWriteBlocks as T,promoteKnowledgeCandidate as E,restoreKnowledgeCandidateBaseline as D,sha256 as O,textSourceAdapter as k,textSourceId as A,verifyKnowledgeRetrievalReceipt as j}from"@tangle-network/agent-knowledge";const M=o.strictObject({sourceId:o.string().min(1),generation:o.string().regex(/^kg_[a-f0-9]{64}$/)}),N=o.discriminatedUnion(`kind`,[o.strictObject({kind:o.literal(`local`),root:o.string().refine(n),sourceDigest:o.string().regex(/^sha256:[a-f0-9]{64}$/)}),o.strictObject({kind:o.literal(`hub`),references:o.array(M).min(1)})]);async function P(e){let t=await c(e);return{kind:`local`,root:t,sourceDigest:`sha256:${await x(t)}`}}function F(e){throw Object.assign(Error(e),{code:`KNOWLEDGE_BACKEND_UNSUPPORTED`})}const I=o.strictObject({question:o.string().trim().min(1).max(16e3),limit:o.number().int().min(1).max(20).default(5)}),L=o.object({results:o.array(o.object({sourceId:o.string().min(1),generation:o.string().regex(/^kg_[a-f0-9]{64}$/),hits:o.array(o.object({id:o.string(),snippet:o.string()}).passthrough()),evidence:o.object({receipt:o.unknown(),visibility:o.unknown(),sources:o.array(o.object({id:o.string(),uri:o.string(),contentHash:o.string()}))})}).passthrough()),failures:o.array(o.unknown()),partial:o.boolean()}).passthrough();let R;function z(){return R??=(async()=>{let t=e(`@tangle-network/agent-knowledge`,import.meta.url);if(!t)throw Error(`Cannot identify the installed Knowledge retriever`);return JSON.parse(await s(t,`utf8`)).version})(),R}async function B(e){let t=_(w(e.corpus.pages,`shared`)),n=b(t);return{receipt:h({runId:e.context.runId,actorId:e.context.nodeId,profileDigest:e.context.profileDigest,query:e.query,retriever:{id:e.retrieval.brief.retrieverId,version:await z(),configDigest:e.retrieval.brief.retrieverConfigDigest},visibility:t,visibilityArtifact:S({uri:`knowledge-generation://${e.sourceId}/${e.generation}/${t.snapshotDigest.slice(7)}.json`,bytes:n}),results:e.retrieval.brief.results,attributes:{sourceId:e.sourceId,generation:e.generation}}),visibility:t,sources:e.corpus.sources.map(({id:e,uri:t,contentHash:n})=>({id:e,uri:t,contentHash:n}))}}async function V(e){let r=N.parse(e.binding),l=Object.freeze({...e.context});if(r.kind===`hub`){let n=e.queryHub;return n||F(`This backend has no owner-authorized Hub knowledge query binding`),[{name:`knowledge_search`,description:`Search the graph's exact owner-authorized knowledge generations and retain retrieval evidence.`,inputSchema:I,inputSchemaJson:o.toJSONSchema(I),handler:async t=>{let i=I.parse(t),a=await n({query:i.question,limit:i.limit,expectedReferences:r.references,context:l},e.signal),o=L.parse(a);if(!o.partial&&(o.results.length!==r.references.length||r.references.some(e=>o.results.filter(t=>t.sourceId===e.sourceId&&t.generation===e.generation).length!==1)))throw Error(`Hub knowledge omitted or duplicated a selected source generation`);let s=[],c=[];for(let t of o.results){let n=j(t.evidence.receipt),a=t.evidence.visibility,o=b(a);if(n.runId!==l.runId||n.actorId!==l.nodeId||n.profileDigest!==l.profileDigest||n.query!==i.question)throw Error(`Hub knowledge receipt does not match the trusted graph invocation`);if(n.attributes.sourceId!==t.sourceId||n.attributes.generation!==t.generation||!r.references.some(e=>e.sourceId===t.sourceId&&e.generation===t.generation))throw Error(`Hub knowledge receipt does not match an exact selected source generation`);if(t.hits.length!==n.results.length||t.hits.some((e,t)=>e.id!==n.results[t]?.pageId||e.snippet!==n.results[t]?.snippet))throw Error(`Hub knowledge hits do not match their retrieval receipt`);await f(n,()=>o),s.push(await e.record({context:l,binding:r,receipt:n,visibility:a,sources:t.evidence.sources})),c.push({sourceId:t.sourceId,generation:t.generation,hits:t.hits,retrievalReceiptDigest:n.receiptDigest})}return{partial:o.partial,failures:o.failures,results:c,retainedEvidence:s}}},{name:`knowledge_record`,description:`Retain an isolated knowledge proposal; it does not alter published source generations.`,inputSchema:o.strictObject({proposal:o.string().min(1)}),inputSchemaJson:{type:`object`,properties:{proposal:{type:`string`}},required:[`proposal`],additionalProperties:!1},handler:async n=>{let{proposal:i}=o.strictObject({proposal:o.string().min(1)}).parse(n);return T(i),{isolated:!0,evaluated:!1,artifact:await e.recordProposal({context:l,binding:r,proposal:i,digest:t({context:l,binding:r,proposal:i})}),activation:`unsupported-for-hub-generations`}}}]}let u=async()=>{if(`sha256:${await x(r.root)}`!==r.sourceDigest)throw Error(`The graph's pinned local knowledge changed`)};if(await u(),!e.storeRoot)throw Error(`Local graph Knowledge needs its private run-store root`);let d=await c(r.root),p=a(e.storeRoot),m=(e,t)=>{let r=i(e,t);return r===``||!r.startsWith(`..`)&&!n(r)};if(m(d,p)||m(p,d))throw Error(`Knowledge run stores must be separate from the curated corpus`);let h=v({root:p,sharedRoot:d});await h.init(l.runId);let _=new Map;return g({stores:h,runId:l.runId,actorId:l.nodeId,retrieverVersion:await z(),retainHistory:!0,recordRetrieval:async t=>{if(await u(),!t.visibility.artifact)throw Error(`Knowledge did not retain the visibility snapshot`);let n=await s(new URL(t.visibility.artifact.uri));await f(t,()=>n);let i=y(n),a=await C(r.root),o=new Set(i.entries.flatMap(e=>e.sourceIds)),c=Object.values(a.sources).filter(e=>o.has(e.id)).map(({id:e,uri:t,contentHash:n})=>({id:e,uri:t,contentHash:n}));_.set(t.receiptDigest,await e.record({context:l,binding:r,receipt:t,visibility:i,sources:c}))}}).map(t=>({...t,handler:async(n,r)=>{e.signal?.throwIfAborted(),await u();let i=await t.handler(n,r);return await u(),i&&typeof i==`object`&&`retrievalReceiptDigest`in i?{...i,retainedEvidence:_.get(String(i.retrievalReceiptDigest))}:i}}))}function H(e){return async t=>{if(!Object.entries(t.profile.tools??{}).some(([e,t])=>t===!0&&/_knowledge_(search|read|record|resolve)$/.test(e)))return[];if(!t.identity.profileDigest)throw Error(`Knowledge tools require Runtime's exact profile identity`);return(await V({...e,...e.storeRoot?{storeRoot:r(e.storeRoot,t.nodeId)}:{},context:{runId:t.runId,nodeId:t.nodeId,profileDigest:t.identity.profileDigest}})).map(e=>{if(!e.inputSchemaJson)throw Error(`Knowledge tool lacks its wire input schema`);return{name:e.name,description:e.description,inputSchema:e.inputSchemaJson,handler:t=>e.handler(t,{})}})}}async function U(e,t,n){let r=N.parse(e);r.kind!==`local`&&F(`Measured file-backed Knowledge candidates cannot activate Hub generations; use the source generation owner's publication path`);let i=u.parse(t);if(`sha256:${i.baseHash}`!==r.sourceDigest)throw Error(`Knowledge candidate does not match the graph's pinned baseline`);return n===`promote`?E({root:r.root,candidate:i}):D({root:r.root,candidate:i})}async function W(e,t){let n=[],r=[];for(let i of[...e].sort((e,t)=>e.uri.localeCompare(t.uri))){let e=O(i.text),a=A(i.uri,e),o=await k.load({uri:i.uri,text:i.text}),s=d.parse({id:a,uri:i.uri,contentHash:e,title:i.title,mediaType:i.mediaType,text:i.text,createdAt:t,lastVerifiedAt:t,metadata:{revision:i.revision},anchors:o.anchors?.map(e=>({...e,sourceId:a}))});n.push(s);for(let e of m(i.text))r.push({id:`${a}:${e.index}`,path:`${i.uri}#chunk-${e.index}`,title:i.title,text:e.text,sourceIds:[a],frontmatter:{revision:i.revision},tags:[],outLinks:[]})}return{sources:n,pages:r}}function G(e,t,n){return K(e,t,n).hits}function K(e,t,n){let r=new Map(e.sources.map(e=>[e.id,e])),i=p(w(e.pages,`shared`),t,{limit:n,excludeInvalidated:!1});return{hits:i.results.map(e=>({id:e.page.id,title:e.page.title,snippet:e.snippet,score:e.score,citations:e.page.sourceIds.map(e=>{let t=r.get(e);if(!t)throw Error(`Knowledge generation has an unregistered source`);return{sourceId:e,sourceUri:t.uri,...typeof t.metadata?.revision==`string`?{revision:t.metadata.revision}:{}}})})),brief:i}}async function q(e){return(await new l({provider:e.provider,connectionId:e.connectionId,indexName:e.indexName,namespace:e.namespace,properties:[e.textField,e.sourceUriField],hubUrl:`https://knowledge-hub.invalid`,apiKey:`in-process-transport`,embed:e.embed,fetchImpl:async(t,n)=>{let r=JSON.parse(String(n?.body)),i=await e.execute(r.path,r.input);return Response.json({success:!0,data:{result:i}})}}).search(e.query,{limit:e.limit})).flatMap(t=>{let n=t.metadata?.payload;if(!n||typeof n!=`object`||Array.isArray(n))return[];let r=n[e.textField];if(typeof r!=`string`||!r.trim())return[];if(e.corpus){let i=e.corpus.pages.find(e=>e.id===n.pageId),a=e.corpus.sources.find(e=>e.id===n.sourceId);if(!i||!a||!i.sourceIds.includes(a.id)||r!==i.text||n.sourceUri!==a.uri||n.revision!==a.metadata?.revision)throw Error(`Managed vector result does not match its published source generation`);return[{id:i.id,title:i.title,snippet:i.text.slice(0,4e3),score:t.score,citations:[{sourceId:a.id,sourceUri:a.uri,revision:String(a.metadata.revision)}]}]}let i=n[e.sourceUriField],a=[];if(typeof i==`string`)try{let e=new URL(i);[`https:`,`s3:`].includes(e.protocol)&&!e.username&&!e.password&&!e.search&&!e.hash&&a.push({sourceId:t.pageId,sourceUri:e.href})}catch{}return[{id:t.pageId,title:t.title??t.pageId,snippet:r.slice(0,4e3),score:t.score,citations:a}]})}export{V as createGraphKnowledgeTools,N as graphKnowledgeBindingSchema,B as graphKnowledgeCorpusEvidence,H as graphKnowledgeResolver,P as pinLocalGraphKnowledge,W as prepareKnowledgeCorpus,q as queryConnectedVectors,G as queryKnowledgeCorpus,K as retrieveKnowledgeCorpus,U as transitionGraphKnowledge};
1
+ import{findPackageJSON as e}from"node:module";import{canonicalCandidateDigest as t}from"@tangle-network/agent-interface";import{isAbsolute as n,join as r,relative as i,resolve as a}from"node:path";import{z as o}from"zod";import{readFile as s,realpath as c}from"node:fs/promises";import{HubVectorSearchProvider as l,KnowledgeImprovementCandidateRefSchema as u,SourceRecordSchema as d,assertKnowledgeRetrievalMatchesVisibilityArtifact as f,buildKnowledgeBrief as p,chunkMarkdown as m,createKnowledgeRetrievalReceipt as h,createKnowledgeTools as g,createKnowledgeVisibilitySnapshot as _,createRunScopedStores as v,decodeKnowledgeVisibilitySnapshot as y,encodeKnowledgeVisibilitySnapshot as b,hashKnowledgeBase as x,knowledgeVisibilityArtifactRef as S,loadSourceRegistry as C,originatedPages as w,parseKnowledgeWriteBlocks as T,promoteKnowledgeCandidate as E,restoreKnowledgeCandidateBaseline as D,sha256 as O,textSourceAdapter as k,textSourceId as A,verifyKnowledgeRetrievalReceipt as j}from"@tangle-network/agent-knowledge";const M=o.strictObject({sourceId:o.string().min(1),generation:o.string().regex(/^kg_[a-f0-9]{64}$/)}),N=o.discriminatedUnion(`kind`,[o.strictObject({kind:o.literal(`local`),root:o.string().refine(n),sourceDigest:o.string().regex(/^sha256:[a-f0-9]{64}$/)}),o.strictObject({kind:o.literal(`hub`),references:o.array(M).min(1)})]);async function P(e){let t=await c(e);return{kind:`local`,root:t,sourceDigest:`sha256:${await x(t)}`}}function F(e){throw Object.assign(Error(e),{code:`KNOWLEDGE_BACKEND_UNSUPPORTED`})}const I=o.strictObject({question:o.string().trim().min(1).max(16e3),limit:o.number().int().min(1).max(20).default(5)}),L=o.object({results:o.array(o.object({sourceId:o.string().min(1),generation:o.string().regex(/^kg_[a-f0-9]{64}$/),hits:o.array(o.object({id:o.string(),snippet:o.string()}).passthrough()),evidence:o.object({receipt:o.unknown(),visibility:o.unknown(),sources:o.array(o.object({id:o.string(),uri:o.string(),contentHash:o.string()}))})}).passthrough()),failures:o.array(o.unknown()),partial:o.boolean()}).passthrough();let R;function z(){return R??=(async()=>{let t=e(`@tangle-network/agent-knowledge`,import.meta.url);if(!t)throw Error(`Cannot identify the installed Knowledge retriever`);return JSON.parse(await s(t,`utf8`)).version})(),R}async function B(e){let t=_(w(e.corpus.pages,`shared`)),n=b(t);return{receipt:h({runId:e.context.runId,actorId:e.context.nodeId,profileDigest:e.context.profileDigest,query:e.query,retriever:{id:e.retrieval.brief.retrieverId,version:await z(),configDigest:e.retrieval.brief.retrieverConfigDigest},visibility:t,visibilityArtifact:S({uri:`knowledge-generation://${e.sourceId}/${e.generation}/${t.snapshotDigest.slice(7)}.json`,bytes:n}),results:e.retrieval.brief.results,attributes:{sourceId:e.sourceId,generation:e.generation}}),visibility:t,sources:e.corpus.sources.map(({id:e,uri:t,contentHash:n})=>({id:e,uri:t,contentHash:n}))}}async function V(e){let r=N.parse(e.binding),l=Object.freeze({...e.context});if(r.kind===`hub`){let n=e.queryHub;return n||F(`This backend has no owner-authorized Hub knowledge query binding`),[{name:`knowledge_search`,description:`Search the graph's exact owner-authorized knowledge generations and retain retrieval evidence.`,inputSchema:I,inputSchemaJson:o.toJSONSchema(I),handler:async t=>{let i=I.parse(t),a=await n({query:i.question,limit:i.limit,expectedReferences:r.references,context:l},e.signal),o=L.parse(a);if(!o.partial&&(o.results.length!==r.references.length||r.references.some(e=>o.results.filter(t=>t.sourceId===e.sourceId&&t.generation===e.generation).length!==1)))throw Error(`Hub knowledge omitted or duplicated a selected source generation`);let s=[],c=[];for(let t of o.results){let n=j(t.evidence.receipt),a=t.evidence.visibility,o=b(a);if(n.runId!==l.runId||n.actorId!==l.nodeId||n.profileDigest!==l.profileDigest||n.query!==i.question)throw Error(`Hub knowledge receipt does not match the trusted graph invocation`);if(n.attributes.sourceId!==t.sourceId||n.attributes.generation!==t.generation||!r.references.some(e=>e.sourceId===t.sourceId&&e.generation===t.generation))throw Error(`Hub knowledge receipt does not match an exact selected source generation`);if(t.hits.length!==n.results.length||t.hits.some((e,t)=>e.id!==n.results[t]?.pageId||e.snippet!==n.results[t]?.snippet))throw Error(`Hub knowledge hits do not match their retrieval receipt`);await f(n,()=>o),s.push(await e.record({context:l,binding:r,receipt:n,visibility:a,sources:t.evidence.sources})),c.push({sourceId:t.sourceId,generation:t.generation,hits:t.hits,retrievalReceiptDigest:n.receiptDigest})}return{partial:o.partial,failures:o.failures,results:c,retainedEvidence:s}}},{name:`knowledge_record`,description:`Retain an isolated knowledge proposal; it does not alter published source generations.`,inputSchema:o.strictObject({proposal:o.string().min(1)}),inputSchemaJson:{type:`object`,properties:{proposal:{type:`string`}},required:[`proposal`],additionalProperties:!1},handler:async n=>{let{proposal:i}=o.strictObject({proposal:o.string().min(1)}).parse(n);return T(i),{isolated:!0,evaluated:!1,artifact:await e.recordProposal({context:l,binding:r,proposal:i,digest:t({context:l,binding:r,proposal:i})}),activation:`unsupported-for-hub-generations`}}}]}let u=async()=>{if(`sha256:${await x(r.root)}`!==r.sourceDigest)throw Error(`The graph's pinned local knowledge changed`)};if(await u(),!e.storeRoot)throw Error(`Local graph Knowledge needs its private run-store root`);let d=await c(r.root),p=a(e.storeRoot),m=(e,t)=>{let r=i(e,t);return r===``||!r.startsWith(`..`)&&!n(r)};if(m(d,p)||m(p,d))throw Error(`Knowledge run stores must be separate from the curated corpus`);let h=v({root:p,sharedRoot:d});await h.init(l.runId);let _=new Map;return g({stores:h,runId:l.runId,actorId:l.nodeId,retrieverVersion:await z(),retainHistory:!0,recordRetrieval:async t=>{if(await u(),!t.visibility.artifact)throw Error(`Knowledge did not retain the visibility snapshot`);let n=await s(new URL(t.visibility.artifact.uri));await f(t,()=>n);let i=y(n),a=await C(r.root),o=new Set(i.entries.flatMap(e=>e.sourceIds)),c=Object.values(a.sources).filter(e=>o.has(e.id)).map(({id:e,uri:t,contentHash:n,metadata:r})=>({id:e,uri:typeof r?.originalUri==`string`?r.originalUri:t,contentHash:n}));_.set(t.receiptDigest,await e.record({context:l,binding:r,receipt:t,visibility:i,sources:c}))}}).map(t=>({...t,handler:async(n,r)=>{e.signal?.throwIfAborted(),await u();let i=await t.handler(n,r);return await u(),i&&typeof i==`object`&&`retrievalReceiptDigest`in i?{...i,retainedEvidence:_.get(String(i.retrievalReceiptDigest))}:i}}))}function H(e){return async t=>{if(!Object.entries(t.profile.tools??{}).some(([e,t])=>t===!0&&/_knowledge_(search|read|record|resolve)$/.test(e)))return[];if(!t.identity.profileDigest)throw Error(`Knowledge tools require Runtime's exact profile identity`);return(await V({...e,...e.storeRoot?{storeRoot:r(e.storeRoot,t.nodeId)}:{},context:{runId:t.runId,nodeId:t.nodeId,profileDigest:t.identity.profileDigest}})).map(e=>{if(!e.inputSchemaJson)throw Error(`Knowledge tool lacks its wire input schema`);return{name:e.name,description:e.description,inputSchema:e.inputSchemaJson,handler:t=>e.handler(t,{})}})}}async function U(e,t,n){let r=N.parse(e);r.kind!==`local`&&F(`Measured file-backed Knowledge candidates cannot activate Hub generations; use the source generation owner's publication path`);let i=u.parse(t);if(`sha256:${i.baseHash}`!==r.sourceDigest)throw Error(`Knowledge candidate does not match the graph's pinned baseline`);return n===`promote`?E({root:r.root,candidate:i}):D({root:r.root,candidate:i})}async function W(e,t){let n=[],r=[];for(let i of[...e].sort((e,t)=>e.uri.localeCompare(t.uri))){let e=O(i.text),a=A(i.uri,e),o=await k.load({uri:i.uri,text:i.text}),s=d.parse({id:a,uri:i.uri,contentHash:e,title:i.title,mediaType:i.mediaType,text:i.text,createdAt:t,lastVerifiedAt:t,metadata:{revision:i.revision},anchors:o.anchors?.map(e=>({...e,sourceId:a}))});n.push(s);for(let e of m(i.text))r.push({id:`${a}:${e.index}`,path:`${i.uri}#chunk-${e.index}`,title:i.title,text:e.text,sourceIds:[a],frontmatter:{revision:i.revision},tags:[],outLinks:[]})}return{sources:n,pages:r}}function G(e,t,n){return K(e,t,n).hits}function K(e,t,n){let r=new Map(e.sources.map(e=>[e.id,e])),i=p(w(e.pages,`shared`),t,{limit:n,excludeInvalidated:!1});return{hits:i.results.map(e=>({id:e.page.id,title:e.page.title,snippet:e.snippet,score:e.score,citations:e.page.sourceIds.map(e=>{let t=r.get(e);if(!t)throw Error(`Knowledge generation has an unregistered source`);return{sourceId:e,sourceUri:t.uri,...typeof t.metadata?.revision==`string`?{revision:t.metadata.revision}:{}}})})),brief:i}}async function q(e){return(await new l({provider:e.provider,connectionId:e.connectionId,indexName:e.indexName,namespace:e.namespace,properties:[e.textField,e.sourceUriField],hubUrl:`https://knowledge-hub.invalid`,apiKey:`in-process-transport`,embed:e.embed,fetchImpl:async(t,n)=>{let r=JSON.parse(String(n?.body)),i=await e.execute(r.path,r.input);return Response.json({success:!0,data:{result:i}})}}).search(e.query,{limit:e.limit})).flatMap(t=>{let n=t.metadata?.payload;if(!n||typeof n!=`object`||Array.isArray(n))return[];let r=n[e.textField];if(typeof r!=`string`||!r.trim())return[];if(e.corpus){let i=e.corpus.pages.find(e=>e.id===n.pageId),a=e.corpus.sources.find(e=>e.id===n.sourceId);if(!i||!a||!i.sourceIds.includes(a.id)||r!==i.text||n.sourceUri!==a.uri||n.revision!==a.metadata?.revision)throw Error(`Managed vector result does not match its published source generation`);return[{id:i.id,title:i.title,snippet:i.text.slice(0,4e3),score:t.score,citations:[{sourceId:a.id,sourceUri:a.uri,revision:String(a.metadata.revision)}]}]}let i=n[e.sourceUriField],a=[];if(typeof i==`string`)try{let e=new URL(i);[`https:`,`s3:`].includes(e.protocol)&&!e.username&&!e.password&&!e.search&&!e.hash&&a.push({sourceId:t.pageId,sourceUri:e.href})}catch{}return[{id:t.pageId,title:t.title??t.pageId,snippet:r.slice(0,4e3),score:t.score,citations:a}]})}export{V as createGraphKnowledgeTools,N as graphKnowledgeBindingSchema,B as graphKnowledgeCorpusEvidence,H as graphKnowledgeResolver,P as pinLocalGraphKnowledge,W as prepareKnowledgeCorpus,q as queryConnectedVectors,G as queryKnowledgeCorpus,K as retrieveKnowledgeCorpus,U as transitionGraphKnowledge};
package/dist/index.mjs CHANGED
@@ -144,7 +144,7 @@ await connect(new StdioServerTransport());`;case`claude-desktop`:return`// Add t
144
144
  Recommended actions:`);for(let e of a.insights.recommendedActions)console.log(` - ${e}`)}}),n.command(`cost <fleet-id>`).description(`Show the fleet's cost estimate`).action(async(t,n)=>{let{client:r}=G(n),i=f(`Estimating cost...`);i.start();let a=await r.fleets.cost(t);i.stop(),n.json?e(a):s({Plan:a.plan,Currency:a.currency,"Hourly (USD)":a.hourlyUsd,"Max lifetime (s)":a.maxLifetimeSeconds,"Estimated max lifetime (USD)":a.estimatedMaxLifetimeUsd,Machines:a.requestedResources.machines,"Total CPU":a.requestedResources.totalCpu,"Total memory (MB)":a.requestedResources.totalMemoryMb})})}function mo(e){return[...e.entries()].map(([e,t])=>({machineId:e,sandboxId:t.id,status:t.status}))}function ho(n){n.command(`list <fleet-id>`).description(`List the machines of one fleet (fleet id is required)`).option(`--status <status>`,`Filter machines by status`).action(async(n,r)=>{let{client:i}=G(r),a=f(`Fetching fleet...`);a.start();let o=await i.fleets.list({fleetId:n,status:r.status});a.stop();let s=mo(o.machines);r.json?e({fleetId:o.fleetId,machines:s}):t(s,[{key:`machineId`,header:`Machine`,width:20},{key:`sandboxId`,header:`Sandbox`,width:24},{key:`status`,header:`Status`,width:14}])}),n.command(`get <fleet-id>`).description(`Show one fleet's manifest (server record)`).action(async(n,r)=>{let{client:i}=G(r),a=f(`Fetching manifest...`);a.start();let o=await i.fleets.manifest(n);a.stop(),r.json?e(o):(s({"Fleet ID":o.fleetId??o.id,Machines:o.machines.length,"Workspace mode":o.workspace?.mode,"Workspace status":o.workspace?.status,"Max lifetime (s)":o.policy?.maxLifetimeSeconds,"Max spend (USD)":o.policy?.maxSpendUsd,Created:o.createdAt,Updated:o.updatedAt}),t(o.machines,[{key:`machineId`,header:`Machine`,width:20},{key:`sandboxId`,header:`Sandbox`,width:24},{key:`role`,header:`Role`,width:14},{key:`status`,header:`Status`,width:14}]))}),n.command(`delete <fleet-id>`).description(`Delete a fleet's machine sandboxes and its record`).option(`--continue-on-error`,`Keep deleting remaining machines if one delete fails`).action(async(t,n)=>{let{client:i}=G(n),a=f(`Deleting fleet...`);a.start(),await i.fleets.delete(t,{continueOnError:n.continueOnError}),a.stop(),n.json?e({success:!0,fleetId:t}):r(`Fleet deleted: ${t}`)}),n.command(`reap`).description(`TTL cleanup of all expired fleets (fleet-wide)`).option(`--dry-run`,`Report what would be reaped without deleting`).action(async n=>{let{client:r}=G(n),i=f(`Reaping expired fleets...`);i.start();let a=await r.fleets.reapExpired({dryRun:n.dryRun});i.stop(),n.json?e(a):(s({"Dry run":a.dryRun,Expired:a.expired,Deleted:a.deleted}),t(a.fleets,[{key:`fleetId`,header:`Fleet`,width:24},{key:`expiredAt`,header:`Expired`,width:18},{key:`deleted`,header:`Deleted`,width:10}]))}),n.command(`reconcile`).description(`Drop fleet records whose underlying sandboxes vanished`).option(`--dry-run`,`Report orphans without removing them`).action(async n=>{let{client:r}=G(n),i=f(`Reconciling fleets...`);i.start();let a=await r.fleets.reconcile({dryRun:n.dryRun});i.stop(),n.json?e(a):(s({"Dry run":a.dryRun,Checked:a.checked,Orphaned:a.orphaned,Removed:a.removed}),t(a.machines,[{key:`fleetId`,header:`Fleet`,width:24},{key:`machineId`,header:`Machine`,width:20},{key:`sandboxId`,header:`Sandbox`,width:24},{key:`removed`,header:`Removed`,width:10}]))})}async function go(e,t){let n=await Hn({apiKey:t.apiKey,baseUrl:t.baseUrl??_n()}),r=await fetch(`${n.baseUrl}/v1/agent-profiles/${encodeURIComponent(e)}`,{headers:{authorization:`Bearer ${n.token}`,accept:`application/json`}});if(!r.ok){let t=await r.text().catch(()=>``);throw r.status===404?Error(`profile '${e}' not found in the platform catalog (it may be a built-in, a stored profile you own, or neither — run 'tangle profile list' to see what is available)`):Error(`platform returned ${r.status}: ${t.slice(0,200)}`)}let i=await r.json();if(!i.definition||typeof i.definition!=`object`)throw Error(`profile '${e}' resolved but has no definition — the catalog entry is malformed`);return i.definition}async function _o(e){let t=typeof e.envVarName==`string`&&e.envVarName.length>0?e.envVarName:null,n=!!e.fromStdin;if(t&&n)throw Error(`Pass either ${e.flagPrefix}-env or ${e.flagPrefix}-stdin, not both`);if(t){let n=process.env[t];if(!n||n.length===0)throw Error(`${e.flagPrefix}-env points at ${t}, but that environment variable is empty or unset`);return n}if(n){let t=await or();if(t.length===0)throw Error(`${e.flagPrefix}-stdin received empty input on stdin`);return t}}function vo(e){if(e.secret===void 0)return;let t=e.backend===`claude-code`?`token`:e.backend===`codex`?`bundle`:void 0;if(!t)throw Error(`--cli-auth needs --backend claude-code or --backend codex`);if(e.apiKeyGiven)throw Error(`--cli-auth cannot be combined with --backend-api-key-env or --backend-api-key-stdin`);return{account:`cli`,secretEnv:e.secret,format:t}}function yo(e){if(e!==void 0)return e.map(e=>{if(e.includes(`@`)||e.includes(`:`))throw Error(`--secret ${e}: bare secret names only (box delivery). For proxy custody use --proxy-secret with a canonical binding`);return e})}function bo(e,t){let n={};return e.cpu!==void 0&&(n.cpuCores=so(e.cpu,`--cpu`)),e.memory!==void 0&&(n.memoryMB=so(e.memory,`--memory`)),e.disk!==void 0&&(n.diskGB=so(e.disk,`--disk`)),t&&(n.accelerator=t),Object.keys(n).length>0?n:void 0}function xo(e){let t=e.split(`/`);return t.length>=2?{provider:t[0],model:t.slice(1).join(`/`)}:{model:e}}function So(e){let t={};for(let n of e){let[e,...r]=n.split(`=`);if(!e||r.length===0)throw Error(`--metadata expects values in KEY=VALUE or KEY=JSON format`);t[e]=Co(r.join(`=`))}return t}function Co(e){try{return JSON.parse(e)}catch{return e}}function wo(e,t){if(!(!e.gitUrl&&!e.gitRef&&!e.gitDepth&&!e.gitSparse&&!t)){if(!e.gitUrl||typeof e.gitUrl!=`string`)throw Error(`--git-url is required when using git provisioning options`);return{url:e.gitUrl,ref:typeof e.gitRef==`string`?e.gitRef:void 0,depth:typeof e.gitDepth==`string`?so(e.gitDepth,`--git-depth`):void 0,sparse:Array.isArray(e.gitSparse)?e.gitSparse:void 0,auth:t?{token:t}:void 0}}}function To(e,t){if(!(!e.storageType&&!e.storageBucket&&!e.storageEndpoint&&!e.storageRegion&&!e.storagePrefix&&!e.storageAccessKeyId&&!t)){if(typeof e.storageType!=`string`||typeof e.storageBucket!=`string`||typeof e.storageAccessKeyId!=`string`||!t)throw Error(`Storage config requires --storage-type, --storage-bucket, --storage-access-key-id, and one of --storage-secret-access-key-env / --storage-secret-access-key-stdin`);return{type:Eo(e.storageType),bucket:e.storageBucket,endpoint:typeof e.storageEndpoint==`string`?e.storageEndpoint:void 0,region:typeof e.storageRegion==`string`?e.storageRegion:void 0,prefix:typeof e.storagePrefix==`string`?e.storagePrefix:void 0,credentials:{accessKeyId:e.storageAccessKeyId,secretAccessKey:t}}}}function Eo(e){if(e===`s3`||e===`gcs`||e===`r2`)return e;throw Error(`--storage-type must be one of s3, gcs, or r2`)}function Do(e){if(e===void 0)return;let t=[];for(let n of e){let e=n,r=`--proxy-secret <json>`;if(n.startsWith(`@`)){let t=n.slice(1);r=`--proxy-secret @${t}`;try{e=Ee(t,`utf8`)}catch{throw Error(`${r}: file could not be read`)}}let i;try{i=JSON.parse(e)}catch(e){throw Error(`${r}: not valid JSON (${e instanceof Error?e.message:String(e)})`)}if(Array.isArray(i))t.push(...i);else if(typeof i==`object`&&i)t.push(i);else throw Error(`${r}: expected a binding object or an array of bindings`)}let n=de.parse(t);return n.length>0?n:void 0}function Oo(e){l(` Status: ${e.status}`),l(` Provider: ${e.provider}`),l(` GPU: ${e.accelerator.kind} x ${e.accelerator.count}`),e.customerPricePerHourUsd!==void 0&&l(` Customer price: $${e.customerPricePerHourUsd}/hr`),e.estimatedCustomerCostUsd!==void 0&&l(` Max estimate: $${e.estimatedCustomerCostUsd}`),e.billing&&(l(` Billed seconds: ${e.billing.seconds}`),l(` Customer cost: $${e.billing.customerCostUsd}`))}function ko(e){e.result.stdout&&process.stdout.write(e.result.stdout),e.result.stderr&&process.stderr.write(e.result.stderr),l(`Exit code: ${e.result.exitCode}`)}function Ao(n){let i=n.command(`gpu`).description(`Manage on-demand GPU leases for a sandbox`);i.command(`providers <id-or-name>`).description(`List GPU clouds, whether each credential works, and current prices`).option(`--accelerator-kind <kind>`,`Price this GPU kind, for example nvidia-h100`).option(`--accelerator-count <count>`,`GPU device count`).option(`--accelerator-memory <gb>`,`Minimum memory per GPU in decimal GB`).action(async(n,r)=>{let{context:i,client:a}=G(r),o=f(`Checking GPU providers...`);o.start();let s=await(await q(a,i,n)).gpu.providers(r.acceleratorKind?{accelerator:eo({kind:r.acceleratorKind,count:r.acceleratorCount,memory:r.acceleratorMemory})}:{});if(o.stop(),r.json){e(s);return}t(s.statuses.map(e=>({provider:e.provider,state:e.state,gpu:e.estimate?.providerInstanceType??``,usdHr:e.estimate?e.estimate.customerPricePerHourUsd.toFixed(4):``,pricing:e.estimate?.pricingSource??``,needs:e.envVars.join(` `)})),[{key:`provider`,header:`Provider`},{key:`state`,header:`State`},{key:`gpu`,header:`GPU`},{key:`usdHr`,header:`$/hr`},{key:`pricing`,header:`Price`},{key:`needs`,header:`Needs`}]);for(let e of s.statuses){let t=e.state===`credential-invalid`?e.credential?.detail:e.estimateError;t&&l(`${e.provider}: ${t}`)}s.usable.length===0&&l(`No GPU provider is usable on this deployment: set the variables in Needs for one provider on the server.`)}),i.command(`attach <id-or-name>`).description(`Attach a temporary GPU worker to a sandbox`).requiredOption(`--accelerator-kind <kind>`,`GPU kind, for example nvidia-h100`).option(`--accelerator-count <count>`,`GPU device count`,`1`).option(`--accelerator-memory <gb>`,`Minimum memory per GPU in decimal GB`).option(`--provider <provider>`,`GPU cloud provider; omitted picks the cheapest configured provider`).option(`--image <image>`,`GPU worker image override`).option(`--env <vars...>`,`Environment variables for the GPU worker (KEY=VALUE)`).requiredOption(`--max-spend-usd <usd>`,`Maximum customer spend for this lease`).requiredOption(`--max-lifetime <seconds>`,`Maximum lease lifetime in seconds`).option(`--idle-timeout <seconds>`,`Destroy after this many idle seconds`).action(async(t,n)=>{let{context:i,client:a}=G(n),o=f(`Attaching GPU lease...`);o.start();let s=await(await q(a,i,t)).gpu.attach(no(n));o.stop(),n.json?e(s):(r(`GPU lease attached: ${s.id}`),Oo(s))}),i.command(`run <id-or-name> <command...>`).description(`Attach a GPU, run a command or script, then destroy it`).requiredOption(`--accelerator-kind <kind>`,`GPU kind, for example nvidia-h100`).option(`--accelerator-count <count>`,`GPU device count`,`1`).option(`--accelerator-memory <gb>`,`Minimum memory per GPU in decimal GB`).option(`--provider <provider>`,`GPU cloud provider; omitted picks the cheapest configured provider`).option(`--image <image>`,`GPU worker image override`).option(`--env <vars...>`,`Environment variables for the GPU worker and command (KEY=VALUE)`).requiredOption(`--max-spend-usd <usd>`,`Maximum customer spend for this lease`).requiredOption(`--max-lifetime <seconds>`,`Maximum lease lifetime in seconds`).option(`--idle-timeout <seconds>`,`Destroy after this many idle seconds`).option(`--timeout <ms>`,`Command timeout in milliseconds`).option(`--cwd <path>`,`Working directory`).action(async(t,n,i)=>{let a,o,s,c;try{let{context:e,client:r}=G(i),s=await q(r,e,t),c=f(`Attaching GPU lease...`);c.start(),a=await s.gpu.attach(no(i)),c.stop();let l=f(`Running GPU command...`);l.start(),o=await s.gpu.exec(a.id,{command:io(n),...ao(i),cwd:i.cwd}),l.stop(),i.json||ko(o)}catch(e){s=e}finally{if(a)try{let{context:e,client:n}=G(i);a=await(await q(n,e,t)).gpu.detach(a.id)}catch(e){c=e}}if(s){H(s),c&&H(c);return}if(c){H(c);return}i.json?e({lease:a,result:o}):a&&r(`GPU lease detached: ${a.id}`);let l=o?.result.exitCode;l&&l!==0&&(process.exitCode=l)}),i.command(`list <id-or-name>`).description(`List GPU leases attached to a sandbox`).action(async(n,r)=>{let{context:i,client:a}=G(r),o=f(`Fetching GPU leases...`);o.start();let s=await(await q(a,i,n)).gpu.list();o.stop(),r.json?e(s):s.length===0?l(`No GPU leases attached.`):t(s.map(e=>({id:e.id,status:e.status,provider:e.provider,accelerator:`${e.accelerator.kind}x${e.accelerator.count}`,customerUsdHr:e.customerPricePerHourUsd??``})),[{key:`id`,header:`ID`,width:28},{key:`status`,header:`Status`,width:12},{key:`provider`,header:`Provider`,width:12},{key:`accelerator`,header:`GPU`,width:24},{key:`customerUsdHr`,header:`$/hr`,width:10}])}),i.command(`exec <id-or-name> <lease-id> <command...>`).description(`Run a command or script on an attached GPU lease`).option(`--timeout <ms>`,`Command timeout in milliseconds`).option(`--cwd <path>`,`Working directory`).option(`--env <vars...>`,`Environment variables (KEY=VALUE)`).action(async(t,n,r,i)=>{let{context:a,client:o}=G(i),s=f(`Running GPU command...`);s.start();let c=await(await q(o,a,t)).gpu.exec(n,{command:io(r),...ao(i),cwd:i.cwd});s.stop(),i.json?e(c):ko(c)}),i.command(`detach <id-or-name> <lease-id>`).description(`Detach and destroy a GPU lease`).action(async(t,n,i)=>{let{context:a,client:o}=G(i),s=f(`Detaching GPU lease...`);s.start();let c=await(await q(o,a,t)).gpu.detach(n);s.stop(),i.json?e(c):(r(`GPU lease detached: ${c.id}`),Oo(c))})}function jo(t,n){if(n){e(t);return}if(!t.id){t.kind===`snapshot`&&t.result?.snapshot?r(`Snapshot created: ${t.result.snapshot.snapshotId}`):r(`Sandbox ${t.sandboxId} stopped.`);return}r(`${t.kind===`snapshot`?`Snapshot`:`Stop`} of sandbox ${t.sandboxId} accepted.`),l(`Operation: ${t.id}`),l(`Status: ${t.statusUrl}`)}function Mo(e){return`${e.name} (${e.id})`}async function No(e,t){if(t.startsWith(`team_`))return e.teams.get(t);let n=(await e.teams.list()).filter(e=>e.name.toLowerCase()===t.toLowerCase());if(n.length===0)throw Error(`Team not found: ${t}`);if(n.length>1)throw Error(`Team name is ambiguous: ${t}. Use a team id instead.`);return n[0]}async function Po(e,t,n){if(t)return No(e,t);let r=bn(n);if(!r.activeTeamId)throw Error("No active team. Run `tangle team switch <team>` or pass `--team <team>`.");return e.teams.get(r.activeTeamId)}function Fo(e,t){xn({id:e.id,name:e.name},t)}function Io(e){Sn(e)}async function Lo(e){if(e.explicitTeam&&e.personal)throw Error(`--team and --personal cannot be used together`);if(!e.personal)return e.explicitTeam?(await No(e.client,e.explicitTeam)).id:e.activeTeamId}async function Ro(e){if([!!e.explicitTeam,!!e.personal,!!e.allScopes].filter(Boolean).length>1)throw Error(`--team, --personal, and --all-scopes are mutually exclusive`);if(e.allScopes)return`all`;if(e.personal)return`personal`;if(e.explicitTeam)return`team:${(await No(e.client,e.explicitTeam)).id}`;if(e.activeTeamId)return`team:${e.activeTeamId}`}function zo(e){if(!e)return e;let t={...e};for(let e of[`authToken`,`execToken`])t[e]!==void 0&&(t[e]=`[REDACTED]`);return t}function Bo(n){n.command(`attestation <id-or-name>`).description(`Fetch TEE attestation evidence for a sandbox`).option(`--nonce <hex|auto>`,`Nonce to bind into a fresh attestation report; use auto to generate one`).action(async(t,n)=>{let{context:i,client:a}=G(n),o=n.nonce===`auto`?re():n.nonce,s=f(`Fetching TEE attestation...`);s.start();let c=await(await q(a,i,t)).getTeeAttestation(o?{attestationNonce:o}:void 0);s.stop(),n.json?e(c):(r(`Attestation fetched for ${t}`),console.log(`TEE type: ${c.attestation.tee_type}`),console.log(`Evidence bytes: ${c.attestation.evidence.length}`),console.log(`Measurement bytes: ${c.attestation.measurement.length}`),console.log(`Timestamp: ${c.attestation.timestamp}`),c.attestationNonce&&console.log(`Nonce: ${c.attestationNonce}`))}),n.command(`list`).description(`List all sandboxes`).option(`-s, --status <status>`,`Filter by status (running, stopped, all)`).option(`-l, --limit <n>`,`Limit results`,`50`).option(`--team <team>`,`List sandboxes for a team by id or name`).option(`--personal`,`List personal sandboxes`).option(`--all-scopes`,`List personal and team sandboxes`).action(async n=>{let{context:r,client:i}=G(n),a=f(`Fetching sandboxes...`);a.start();let o=await Ro({client:i,explicitTeam:n.team,personal:n.personal,allScopes:n.allScopes,activeTeamId:r.activeTeamId}),s=await i.list({status:n.status===`all`?void 0:n.status,limit:Number.parseInt(n.limit,10),scope:o});a.stop(),n.json?e(s):t(s.map(e=>({id:e.id,status:e.status,createdAt:e.createdAt,name:e.name??``})),[{key:`id`,header:`ID`,width:24},{key:`status`,header:`Status`,width:14},{key:`createdAt`,header:`Created`,width:16},{key:`name`,header:`Name`,width:20}])}),n.command(`get <id-or-name>`).description(`Get sandbox details`).option(`--profile`,`Show the active agent profile provenance (name, hash, skills)`).action(async(t,n)=>{let{context:r,client:i}=G(n),a=f(`Fetching sandbox...`);a.start();let o=await q(i,r,t);if(a.stop(),n.profile){let e=o.getProfileProvenance?.();e?(l(`Agent profile provenance:`),l(` Base profile: ${e.base.name??`(inline)`} (${e.base.sha256.slice(0,12)}...)`),l(` Effective: ${e.effective.name??`(inline)`} (${e.effective.sha256.slice(0,12)}...)`),l(` Materialized: ${e.materializedAt}`),e.base.sha256!==e.effective.sha256&&l(` ⚠ Profile changed since creation (base ≠ effective)`)):l(`No profile materialized (bare sandbox). Create with --profile <name> to install one.`);return}n.json?e(o):u({id:o.id,name:o.name,status:o.status,resources:o.resources,createdAt:o.createdAt?.toISOString(),expiresAt:o.expiresAt?.toISOString(),connection:o.connection})}),n.command(`shapes`).description(`List the named sandbox sizes, the default, and this account's ceiling`).action(async n=>{let{client:r}=G(n),i=await r.shapes();if(n.json){e(i);return}let a=e=>e.cpuCores<=i.ceiling.cpuCores&&e.memoryMB<=i.ceiling.memoryMB&&e.diskGB<=i.ceiling.diskGB;t(i.presets.map(e=>({name:e.name===i.default?`${e.name} (default)`:e.name,cpu:e.cpuCores,memory:`${e.memoryMB} MB`,disk:`${e.diskGB} GB`,available:a(e)?`yes`:e.name===i.default?`clamped to ceiling`:`above ceiling`})),[{key:`name`,header:`Shape`,width:18},{key:`cpu`,header:`vCPU`,width:6},{key:`memory`,header:`Memory`,width:10},{key:`disk`,header:`Disk`,width:8},{key:`available`,header:`Available`,width:14}]),l(`Ceiling for this account: ${o(i.ceiling)}`)}),n.command(`delete <id-or-name>`).description(`Delete a sandbox`).option(`-f, --force`,`Skip confirmation`).option(`--name`,`Treat the reference as a sandbox name`).addOption(new se(`--until <state>`,`Wait for physical removal`).choices([`removed`])).option(`--retry-cleanup`,`Retry server-side cleanup after the sandbox disappeared from get/list`).action(async(e,t)=>{if(!t.force&&!await ir(`Delete sandbox ${e}? [y/N] `,`--force`)){l(`Cancelled.`);return}let{context:n,client:i}=G(t),a=f(`Deleting sandbox...`);a.start();let o=await Zn(i,n,e,{retryCleanup:t.retryCleanup,name:t.name,until:t.until});a.stop(),r(o===`already_absent`?`Sandbox ${e} was already gone.`:`Sandbox ${e} deleted.`)}),n.command(`stop <id-or-name>`).description(`Stop a running sandbox`).option(`--name`,`Treat the reference as a sandbox name`).option(`--no-wait`,`Return once the stop is accepted and print the operation to poll`).action(async(e,t)=>{let{context:n,client:i}=G(t),a=f(`Stopping sandbox...`);a.start();let o=await q(i,n,e,{nameOnly:t.name});if(t.wait===!1){let e=await o.stop({wait:!1});a.stop(),jo(e.info,!!t.json);return}await o.stop(),a.stop(),r(`Sandbox ${e} stopped.`)}),n.command(`resume <id-or-name>`).description(`Resume a stopped sandbox`).option(`--wait`,`Wait for sandbox to be running`,!0).option(`-t, --timeout <ms>`,`Resume timeout in milliseconds; a cold resume re-provisions the sandbox, so this defaults higher than other commands (default 120000)`,`120000`).action(async(e,t)=>{let n=Number.parseInt(t.timeout,10);if(!Number.isFinite(n)||n<=0)throw Error(`--timeout must be a positive number of milliseconds`);let i=U({apiKey:t.apiKey,baseUrl:t.baseUrl,timeout:n}),a=W(i),o=f(`Resuming sandbox...`);o.start();let s=await q(a,i,e);await s.resume({timeoutMs:n}),t.wait&&(o.text=`Waiting for sandbox to start...`,await s.waitFor(`running`,{timeoutMs:n})),o.stop(),r(`Sandbox ${s.id} resumed.`)})}function Vo(t){t.command(`create`).option(`--cpu-features <flags>`,`Required Linux CPU flags, comma-separated`).description(`Create a new sandbox`).option(`-n, --name <name>`,`Sandbox name`).option(`-e, --environment <environment>`,Ho).addOption(Uo()).option(`--bare`,`Create a bare sandbox without the agent runtime`).option(`--ssh`,`Enable SSH access`).option(`--ssh-key <key>`,`SSH public key for authentication`).option(`--ssh-keys <names...>`,`Stored SSH key names or IDs for authentication`).option(`--ssh-key-file <paths...>`,`SSH public key file paths for authentication`).option(`--web-terminal`,`Enable web terminal`).option(`--env <vars...>`,`Environment variables (KEY=VALUE)`).option(`--secret <names...>`,`Secrets selected by bare name for box delivery (value in the sandbox env). For proxy custody use --proxy-secret`).option(`--proxy-secret <bindings...>`,`Canonical proxy custody binding(s): one binding as inline JSON, or @file with a JSON array. The value stays at the egress proxy and is redeemed only within the binding's scope (hosts/methods/paths/TTL); the box reads a placeholder. Repeatable`).option(`--metadata <entries...>`,`Metadata entries (KEY=VALUE or KEY=JSON)`).option(`--cpu <cores>`,"CPU cores (omit for the platform default; see `sandbox shapes`)").option(`--memory <mb>`,`Memory in MB (omit for the platform default)`).option(`--disk <gb>`,`Disk size in GB (omit for the platform default)`).option(`--accelerator-kind <kind>`,`Accelerator kind, for example nvidia-h100 or amd-mi300x`).option(`--accelerator-count <count>`,`Accelerator device count`,`1`).option(`--accelerator-memory <gb>`,`Minimum memory per GPU in decimal GB`).option(`--gpu-provider <provider>`,`GPU cloud provider; omitted picks the cheapest configured provider`).option(`--gpu-worker-image <image>`,`GPU worker image override`).option(`--gpu-env <vars...>`,`Environment variables for the GPU worker (KEY=VALUE)`).option(`--gpu-max-spend-usd <usd>`,`Maximum customer spend for the create-time GPU lease`).option(`--gpu-max-lifetime <seconds>`,`Maximum create-time GPU lease lifetime in seconds`).option(`--gpu-idle-timeout <seconds>`,`Destroy the create-time GPU lease after this many idle seconds`).option(`--lifetime <seconds>`,`Max wall-clock lifetime before the sandbox is suspended — stopped, not deleted; resume it within the cold window (default 3600 = 1h). Raise it for long sessions, e.g. --lifetime 7200`,`3600`).option(`--idle-timeout <seconds>`,"Idle time before the sandbox is stopped — not deleted (default 900 = 15m). Resume it later with `tangle sandbox resume <id-or-name>`, or it auto-resumes on next use. Raise it for demos, e.g. --idle-timeout 3600",`900`).option(`--from-snapshot <id>`,`Create the sandbox from a snapshot`).option(`--public-template <id-or-slug>`,`Create the sandbox from a published public template`).option(`--public-template-version <id>`,`Pin creation to a specific published public-template version`).option(`--billing-owner <userId>`,`Platform user that pays for the sandbox. The API accepts this only from a first-party service key that is listed as a billing delegate, and refuses such a key that names no payer.`).option(`--team <team>`,`Create in a team by id or name`).option(`--personal`,`Create a personal sandbox even when a team is active`).option(`--git-url <url>`,`Git repository URL to clone during provisioning`).option(`--git-ref <ref>`,`Git branch, tag, or commit to checkout`).option(`--git-depth <depth>`,`Git clone depth`).option(`--git-sparse <paths...>`,`Sparse checkout paths`).option(`--git-token-env <name>`,`Name of an environment variable containing the Git HTTPS auth token`).option(`--git-token-stdin`,`Read the Git HTTPS auth token from stdin`).option(`--storage-type <type>`,`BYOS3 storage type (s3, gcs, r2)`).option(`--storage-bucket <name>`,`BYOS3 bucket name`).option(`--storage-endpoint <url>`,`BYOS3 endpoint URL`).option(`--storage-region <region>`,`BYOS3 region`).option(`--storage-prefix <prefix>`,`BYOS3 path prefix`).option(`--storage-access-key-id <id>`,`BYOS3 access key ID`).option(`--storage-secret-access-key-env <name>`,`Name of an environment variable containing the BYOS3 secret access key`).option(`--storage-secret-access-key-stdin`,`Read the BYOS3 secret access key from stdin`).addOption(new se(`--driver <type>`,`Run on Tangle network operators instead of the platform's hosts (--tee needs it)`).choices([`tangle`])).option(`--backend <type>`,`Backend agent type (${y.join(`, `)})`).option(`--backend-model <model>`,`Model override (format: provider/model)`).addOption(new se(`--reasoning-effort <level>`,`Reasoning effort for the backend's model; overrides the profile's model.reasoningEffort`).choices(fe)).option(`--backend-api-key-env <name>`,`Name of an environment variable containing the BYOK backend API key`).option(`--backend-api-key-stdin`,`Read the BYOK backend API key from stdin`).option(`--cli-auth <secret>`,"Run --backend claude-code or codex on your own subscription: the stored secret holding a `claude setup-token` token or a Codex auth.json (see `tangle secret create`)").option(`--profile <path>`,`Path to an AgentProfile JSON file to install as the sandbox's backend profile (carries skills, tools, MCP, model). Use with --backend; the profile's inline skills materialize into the harness's native skill directory on first turn`).option(`--profile-stdin`,`Read the AgentProfile JSON from stdin instead of a file (use with --profile)`).option(`--tee <type>`,`Require a TEE backend (any, tdx, nitro, sev-snp, phala-dstack)`).option(`--sealed`,`Request TEE sealed-secret support`).option(`--attestation-nonce <hex|auto>`,`Deploy-time attestation nonce; use auto to generate one`).option(`--attestation-refresh`,`Generate a fresh deploy-time attestation nonce when --tee is set`).option(`--require-attestation`,`Fail unless TEE attestation evidence is returned`).option(`--wait`,`Wait for sandbox to be running`,!0).option(`--timeout <ms>`,`HTTP timeout in milliseconds`,`30000`).action(async t=>{let n=await _o({envVarName:t.gitTokenEnv,fromStdin:t.gitTokenStdin,flagPrefix:`--git-token`}),i=await _o({envVarName:t.storageSecretAccessKeyEnv,fromStdin:t.storageSecretAccessKeyStdin,flagPrefix:`--storage-secret-access-key`}),a=await _o({envVarName:t.backendApiKeyEnv,fromStdin:t.backendApiKeyStdin,flagPrefix:`--backend-api-key`}),o=vo({secret:t.cliAuth,backend:t.backend,apiKeyGiven:a!==void 0}),s;if(t.profileStdin){let e=await or(`--profile-stdin`,`the AgentProfile JSON`);try{s=JSON.parse(e)}catch{H(Error(`--profile-stdin: the input is not valid JSON`));return}}else if(t.profile){let e=String(t.profile);if(e.startsWith(`.`)||e.startsWith(`/`)||e.endsWith(`.json`))try{s=JSON.parse(Ee(e,`utf8`))}catch(t){H(Error(`--profile ${e}: ${t.message}`));return}else try{s=await go(e,t)}catch(t){H(Error(`--profile ${e}: ${t.message}`));return}}s=Go(s,t.reasoningEffort);let c=U({apiKey:t.apiKey,baseUrl:t.baseUrl,timeout:t.timeout?Number.parseInt(t.timeout,10):void 0}),l=W(c),d=f(`Creating sandbox...`);d.start();let p=await Lo({client:l,explicitTeam:t.team,personal:t.personal,activeTeamId:c.activeTeamId}),m=oo(t.env??[],`--env`,`env`),h=t.metadata?So(t.metadata):void 0,g=wo(t,n),_=To(t,i),v=t.acceleratorKind?eo({kind:String(t.acceleratorKind),count:String(t.acceleratorCount),memory:typeof t.acceleratorMemory==`string`?t.acceleratorMemory:void 0}):void 0,y=to({provider:typeof t.gpuProvider==`string`?t.gpuProvider:void 0,image:typeof t.gpuWorkerImage==`string`?t.gpuWorkerImage:void 0,env:Array.isArray(t.gpuEnv)?t.gpuEnv:void 0,maxSpendUsd:typeof t.gpuMaxSpendUsd==`string`?t.gpuMaxSpendUsd:void 0,maxLifetime:typeof t.gpuMaxLifetime==`string`?t.gpuMaxLifetime:void 0,idleTimeout:typeof t.gpuIdleTimeout==`string`?t.gpuIdleTimeout:void 0},!!v,`Create-time GPU lease flags require --accelerator-kind`),b=t.driver?{type:`tangle`}:void 0,x=t.backend||t.backendModel||s?{...t.backend?{type:ie(t.backend)}:{},...s?{profile:s}:{},model:t.backendModel||a||o?{...t.backendModel?xo(t.backendModel):{},apiKey:a,...o?{cliAuth:o}:{}}:void 0}:void 0,S=yo(t.secret),C=o?[...new Set([...S??[],o.secretEnv])]:S,w=Do(t.proxySecret),T=bo(t,v),ee=t.sshKeyFile??(t.ssh&&!t.sshKey&&!t.sshKeys?.length?[Wo()]:[]),E=[...t.sshKey?[t.sshKey]:[],...ee.map(e=>Ee(e,`utf8`).trim())],D={name:t.name,environment:t.environment,runtime:t.runtime,cpuFeatures:t.cpuFeatures?.split(`,`).map(e=>e.trim()),bare:t.bare||void 0,sshEnabled:t.ssh||!!t.sshKey||E.length>0||!!t.sshKeys?.length,sshPublicKeys:E.length>0?E:void 0,sshKeyIds:t.sshKeys,webTerminalEnabled:t.webTerminal,env:Object.keys(m).length>0?m:void 0,git:g,...T?{resources:T}:{},gpuLease:y,maxLifetimeSeconds:Number.parseInt(t.lifetime,10),idleTimeoutSeconds:Number.parseInt(t.idleTimeout,10),storage:_,fromSnapshot:t.fromSnapshot,publicTemplateId:t.publicTemplate,publicTemplateVersionId:t.publicTemplateVersion,teamId:p,...t.billingOwner?{billingOwnerId:t.billingOwner}:{},secrets:C,...w?{proxySecrets:w}:{},metadata:h,driver:b,backend:x},O=t.tee?{tee:t.tee,sealed:t.sealed||void 0,attestationRefresh:t.attestationRefresh||t.attestationNonce===`auto`||void 0}:void 0,k=O?await ne(l,{...D,confidential:O,attestationNonce:t.attestationNonce??(t.attestationRefresh?`auto`:void 0),requireAttestation:t.requireAttestation??!0}):void 0,A=k?.sandbox??await l.create(D);t.wait&&(d.text=`Waiting for sandbox to start...`,await A.waitFor(`running`,{timeoutMs:12e4}),await A.refresh()),d.stop(),t.json?e({id:A.id,name:A.name,status:A.status,resources:A.resources,createdAt:A.createdAt,expiresAt:A.expiresAt,connection:zo(A.connection),teamId:p,gpuLease:A.gpuLease,confidential:O,attestation:k?.attestation,attestationNonce:k?.attestationNonce}):(r(`Sandbox created: ${A.id}`),u({id:A.id,name:A.name,status:A.status,resources:A.resources,createdAt:A.createdAt?.toISOString(),expiresAt:A.expiresAt?.toISOString(),connection:A.connection}),p&&console.log(`Team: ${p}`),A.gpuLease&&(console.log(`GPU lease: ${A.gpuLease.id}`),Oo(A.gpuLease)),O&&(console.log(`TEE: ${O.tee}`),console.log(`Attestation: ${k?.attestation?`present`:`not returned`}`),k?.attestationNonce&&console.log(`Attestation nonce: ${k.attestationNonce}`)))})}const Ho="A catalog environment, a container image reference, or a built image ID. Firecracker runs only images pinned by repository@sha256 that the cell's Firecracker hosts carry; `environments list` shows each image's runtimes";function Uo(){return new se(`--runtime <runtime>`,`Isolation on the platform's hosts: docker runs a container on the host kernel, firecracker a microVM with its own kernel. Omit for the platform default`).choices(T)}function Wo(){let e=[`id_ed25519`,`id_ecdsa`,`id_rsa`].map(e=>`${F()}/.ssh/${e}.pub`),t=e.find(e=>we(e));if(!t)throw Error(`--ssh needs a public key and found none at ${e.join(`, `)}. Run ssh-keygen -t ed25519, or pass --ssh-key-file.`);return t}function Go(e,t){if(!t)return e;let n=e?.model??{};return{...e,model:{...n,reasoningEffort:t}}}function Ko(e){if(e.spec){let t=JSON.parse(Ee(e.spec,`utf8`));return{base:{fleetId:e.fleetId,defaults:t.defaults,policy:t.policy,workspace:t.workspace,metadata:t.metadata},machines:t.machines??[]}}let t=Yo(e),n=Xo(e,!!t?.accelerator),r={...e.environment?{environment:e.environment}:{},...t?{resources:t}:{},...e.runtime?{runtime:e.runtime}:{},...n?{gpuLease:n}:{},...e.backend?{backend:{type:e.backend}}:{}},i=Zo(e),a=Math.max(1,Number(e.count)||1),o=Array.from({length:a},(e,t)=>({machineId:`worker-${t+1}`}));return{base:{fleetId:e.fleetId,defaults:Object.keys(r).length>0?r:void 0,policy:i,workspace:{mode:e.workspace}},machines:o}}function qo(e){let{base:t,machines:n}=Ko(e);return{...t,machines:n}}function Jo(e){let{base:t,machines:n}=Ko(e);return{...t,workers:n}}function Yo(e){let t={};if(e.cpu&&(t.cpuCores=Number(e.cpu)),e.memory&&(t.memoryMB=Number(e.memory)),e.disk&&(t.diskGB=Number(e.disk)),e.acceleratorKind)t.accelerator=eo({kind:e.acceleratorKind,count:e.acceleratorCount,memory:e.acceleratorMemory});else if(e.acceleratorCount||e.acceleratorMemory)throw Error(`--accelerator-count and --accelerator-memory require --accelerator-kind`);return Object.keys(t).length>0?t:void 0}function Xo(e,t){return to({provider:e.gpuProvider,image:e.gpuWorkerImage,env:e.gpuEnv,maxSpendUsd:e.gpuMaxSpendUsd,maxLifetime:e.gpuMaxLifetime,idleTimeout:e.gpuIdleTimeout},t,`Fleet GPU lease flags require --accelerator-kind`)}function Zo(e){let t={};return e.maxSpendUsd&&(t.maxSpendUsd=Number(e.maxSpendUsd)),e.maxLifetime&&(t.maxLifetimeSeconds=Number(e.maxLifetime)),Object.keys(t).length>0?t:void 0}function Qo(n){n.command(`create`).description(`Create a sandbox fleet`).option(`--fleet-id <id>`,`Stable fleet id (generated when omitted)`).option(`--count <n>`,`Number of worker machines`,`1`).option(`--environment <environment>`,Ho).addOption(Uo()).option(`--cpu <cores>`,`CPU cores per machine`).option(`--memory <mb>`,`Memory in MB per machine`).option(`--disk <gb>`,`Disk in GB per machine`).option(`--accelerator-kind <kind>`,`Accelerator kind per machine, for example nvidia-l4 or nvidia-h100`).option(`--accelerator-count <count>`,`Accelerator devices per machine`).option(`--accelerator-memory <gb>`,`Minimum memory per GPU in decimal GB`).option(`--gpu-provider <provider>`,`GPU cloud provider per machine; omitted picks the cheapest configured provider`).option(`--gpu-worker-image <image>`,`GPU worker image override`).option(`--gpu-env <vars...>`,`Environment variables for each GPU worker (KEY=VALUE)`).option(`--gpu-max-spend-usd <usd>`,`Maximum spend per machine GPU lease`).option(`--gpu-max-lifetime <seconds>`,`Maximum GPU lease lifetime per machine in seconds`).option(`--gpu-idle-timeout <seconds>`,`Destroy each GPU lease after this many idle seconds`).option(`--backend <id>`,`Agent backend type`).option(`--workspace <mode>`,`Workspace mode: isolated (no driver supports shared yet)`,`isolated`).option(`--max-spend-usd <n>`,`Fleet spend cap in USD (policy)`).option(`--max-lifetime <s>`,`Max machine lifetime in seconds (policy)`).option(`--spec <file.json>`,`Path to a JSON file describing the fleet (overrides synthesized machines)`).option(`--coordinator`,`Create a coordinator + workers fleet (routes to createWithCoordinator)`).action(async n=>{let{client:i}=G(n),a=f(`Creating fleet...`);a.start();let o=n.coordinator?await i.fleets.createWithCoordinator(Jo(n)):await i.fleets.create(qo(n));a.stop();let s=mo(o.machines);n.json?e({fleetId:o.fleetId,machines:s}):(r(`Fleet created: ${o.fleetId}`),t(s,[{key:`machineId`,header:`Machine`,width:20},{key:`sandboxId`,header:`Sandbox`,width:24},{key:`status`,header:`Status`,width:14}]))})}function $o(n){n.command(`exec <fleet-id> <command>`).description(`Run a shell command across the fleet's machines`).option(`--machine <id...>`,`Restrict to a subset of machine ids (default: all)`).option(`--cwd <dir>`,`Working directory for the command`).option(`--timeout <ms>`,`Per-machine timeout in milliseconds`).option(`--max-concurrent <n>`,`Max concurrent dispatches`).action(async(n,r,i)=>{let{client:a}=G(i),o=f(`Dispatching command...`);o.start();let s=await(await a.fleets.list({fleetId:n})).dispatchExecDetailed(r,{machines:i.machine,cwd:i.cwd,timeoutMs:i.timeout?Number(i.timeout):void 0,maxConcurrent:i.maxConcurrent?Number(i.maxConcurrent):void 0});if(o.stop(),i.json)e(s);else{t(s.results.map(e=>({machineId:e.machineId,ok:e.ok,exitCode:e.result?.exitCode,durationMs:e.durationMs})),[{key:`machineId`,header:`Machine`,width:20},{key:`ok`,header:`OK`,width:6},{key:`exitCode`,header:`Exit`,width:8},{key:`durationMs`,header:`Duration(ms)`,width:14}]);for(let e of s.results){let t=e.result?.stdout,n=e.result?.stderr;t&&(console.log(`\n[${e.machineId}] stdout:`),console.log(t)),n&&(console.log(`\n[${e.machineId}] stderr:`),console.log(n)),e.error&&console.log(`\n[${e.machineId}] error: ${e.error.message}`)}}s.results.some(e=>e.ok===!1)&&(process.exitCode=1)}),n.command(`run [prompt]`).description(`Create a fleet of agents, run one turn on every agent, print each result, then delete the fleet`).requiredOption(`--agents <n|file>`,`Number of agents, or a JSON file with an array of agent specs (agentId, harness, model, profile or { profileId, revision }, task)`).option(`--placement <mode>`,`auto (pack by sandbox memory), dedicated (one sandbox per agent), or a number of agents per sandbox`,`auto`).option(`--model <id>`,`Model every agent runs, e.g. gpt-4.1-mini`).option(`--memory <mb>`,`Memory in MB per sandbox; auto placement packs by it`).option(`--environment <environment>`,`Environment for each sandbox`).option(`--max-spend-usd <usd>`,`Budget for the fleet in USD, enforced by the Platform on the fleet's own key`).option(`--timeout <ms>`,`Per-agent turn timeout in milliseconds`).option(`--fleet-id <id>`,`Stable fleet id (generated when omitted)`).option(`--parent-fleet <id>`,`Fleet that spawns this one; its cap must cover this cap`).option(`--parent-agent <id>`,`Agent of --parent-fleet that spawns this one`).option(`--keep`,`Keep the fleet after the run instead of deleting it`).action(async(t,n)=>{let i=/^\d+$/.test(n.agents)?Number(n.agents):JSON.parse(Ee(n.agents,`utf8`));if(!Array.isArray(i)&&t===void 0)throw Error(`A prompt is required unless --agents names a file whose agents carry tasks`);let{client:a}=G(n);if(!!n.parentFleet!=!!n.parentAgent)throw Error(`--parent-fleet and --parent-agent go together`);let o=n.placement===`auto`||n.placement===`dedicated`?n.placement:{agentsPerSandbox:Number(n.placement)},c=n.maxSpendUsd?Number(n.maxSpendUsd):void 0,l=f(`Creating fleet...`);l.start();let u=Date.now(),d=await a.fleets.create({fleetId:n.fleetId,agents:i,placement:o,defaults:{...n.environment?{environment:n.environment}:{},...n.memory?{resources:{memoryMB:Number(n.memory)}}:{},...n.model?{backend:{type:`opencode`,model:{model:n.model}}}:{}},...c===void 0?{}:{budgetUsd:c},...n.parentFleet?{parent:{fleetId:n.parentFleet,agentId:n.parentAgent}}:{}}),p=Date.now()-u;l.stop(),n.json||r(`Fleet ${d.fleetId}: ${d.agents.length} agents on ${d.machines.size} sandboxes in ${p} ms`);let m=[],h;try{for await(let e of d.run(t,{timeoutMs:n.timeout?Number(n.timeout):void 0})){if(e.type===`agent.finished`&&!n.json){let t=e.result;console.log(`[${t.agentId}] ${t.harness??`default`}/${t.model??`default`} ${t.status} ${t.durationMs}ms ${t.costUsd===void 0?`no cost reported`:`$${t.costUsd.toFixed(5)}`} ${t.result?.response??t.error??``}`)}e.type===`fleet.finished`&&(m=e.results,h=e.spend)}}finally{n.keep||await d.delete({continueOnError:!0})}n.json?e({fleetId:d.fleetId,createMs:p,sandboxes:d.machines.size,results:m,spend:h,deleted:!n.keep}):s({fleetId:d.fleetId,completed:m.filter(e=>e.status===`completed`).length,agents:m.length,spend:JSON.stringify(h),deleted:!n.keep}),m.some(e=>e.status!==`completed`)&&(process.exitCode=1)}),n.command(`cancel <fleet-id>`).description(`Interrupt every agent of a fleet and cancel its child fleets; sandboxes keep running`).action(async(t,n)=>{let{client:i}=G(n),a=await(await i.fleets.list({fleetId:t})).cancel();n.json?e({fleetId:t,...a}):r(`Fleet ${t}: interrupted ${a.interrupted} agents, cancelled ${a.children} child fleets`)})}const es=[`list`,`create`,`delete`,`exec`,`prompt`,`read`,`write`];function ts(e){if(!(!e||e.length===0)){for(let t of e)if(!es.includes(t))throw Error(`Invalid token action '${t}'. Allowed: ${es.join(`, `)}`);return e}}function ns(e){return e.length<=12?`****`:`${e.slice(0,6)}...${e.slice(-4)} (masked — use --json for full value)`}function rs(t){t.command(`token <fleet-id>`).description(`Mint a scoped fleet bearer token (treated as a secret)`).option(`--action <a...>`,`Allowed actions: list create delete exec prompt read write (prompt grants nothing since fleet prompt dispatch was removed)`).option(`--ttl-minutes <n>`,`Token lifetime in minutes`).action(async(t,n)=>{let{client:r}=G(n),i=f(`Minting fleet token...`);i.start();let a=await r.fleets.createToken(t,{actions:ts(n.action),ttlMinutes:n.ttlMinutes?Number(n.ttlMinutes):void 0});i.stop(),n.json?e(a):(s({"Fleet ID":a.fleetId,Token:ns(a.token),"Expires at":new Date(a.expiresAt).toISOString(),Actions:a.actions.join(`, `)}),console.log(`
145
145
  Re-run with --json to print the full token value.`))})}function is(){let n=new M(`workspace`).description(`Manage a fleet's shared workspace`);return n.command(`snapshot <fleet-id>`).description(`Snapshot the fleet's shared workspace`).action(async(t,n)=>{let{client:i}=G(n),a=f(`Creating workspace snapshot...`);a.start();let o=await i.fleets.createWorkspaceSnapshot(t);a.stop(),n.json?e(o):r(`Workspace snapshot created: ${o.snapshotId??o.id}`)}),n.command(`restore <fleet-id> <snapshot-id>`).description(`Restore the fleet's shared workspace from a snapshot`).action(async(t,n,i)=>{let{client:a}=G(i),o=f(`Restoring workspace...`);o.start();let s=await a.fleets.restoreWorkspaceSnapshot(t,n);o.stop(),i.json?e(s):r(`Workspace restored from ${s.snapshotId??n}`)}),n.command(`reconcile <fleet-id>`).description(`Re-mount the shared workspace on all fleet machines`).action(async(n,r)=>{let{client:i}=G(r),a=f(`Reconciling workspace...`);a.start();let o=await i.fleets.reconcileWorkspace(n);a.stop(),r.json?e(o):(s({"Fleet ID":o.fleetId,Checked:o.checked,"Orphaned mounts":o.orphanedMounts}),t(o.machines,[{key:`machineId`,header:`Machine`,width:20},{key:`sandboxId`,header:`Sandbox`,width:24},{key:`mounted`,header:`Mounted`,width:10}]))}),n}function as(){let e=new M(`fleet`).description(`Manage sandbox fleets`);return Qo(e),ho(e),e.addCommand(is()),$o(e),po(e),rs(e),e}function os(){let t=new M(`fs`).description(`File system operations on sandboxes`);return t.command(`upload`).description(`Upload a file to a sandbox`).argument(`<sandbox-id-or-name>`,`Sandbox ID or name`).argument(`<local-path>`,`Local file path`).argument(`<remote-path>`,`Remote destination path`).action(async(t,n,r,i)=>{let{context:a,client:o}=G(i),s=await q(o,a,t);if(s=await J(s),!xe.existsSync(n))throw Error(`Local file not found: ${n}`);let c=xe.statSync(n),l=Date.now();i.json||console.error(`Uploading ${n} to ${r}...`),await s.fs.upload(n,r,{onProgress:e=>{if(i.json)return;let t=e.percentage.toFixed(1);process.stderr.write(`\rProgress: ${t}% (${e.bytesUploaded}/${e.totalBytes} bytes)`)}});let u=Date.now()-l;i.json||console.error(``),i.json?e({success:!0,localPath:n,remotePath:r,size:c.size,durationMs:u}):console.log(`✓ Uploaded ${c.size} bytes in ${u}ms`)}),t.command(`download`).description(`Download a file from a sandbox`).argument(`<sandbox-id-or-name>`,`Sandbox ID or name`).argument(`<remote-path>`,`Remote file path`).argument(`<local-path>`,`Local destination path`).action(async(t,n,r,i)=>{let{context:a,client:o}=G(i),s=await q(o,a,t);s=await J(s);let c=Date.now();i.json||console.error(`Downloading ${n} to ${r}...`),await s.fs.download(n,r,{onProgress:e=>{if(i.json)return;let t=e.percentage.toFixed(1);process.stderr.write(`\rProgress: ${t}% (${e.bytesDownloaded}/${e.totalBytes} bytes)`)}});let l=Date.now()-c,u=xe.statSync(r);i.json||console.error(``),i.json?e({success:!0,remotePath:n,localPath:r,size:u.size,durationMs:l}):console.log(`✓ Downloaded ${u.size} bytes in ${l}ms`)}),t.command(`ls`).description(`List directory contents`).argument(`<sandbox-id-or-name>`,`Sandbox ID or name`).argument(`[path]`,`Directory path`,`.`).option(`-l, --long`,`Show detailed information`).option(`-a, --all`,`Include hidden files`).action(async(t,n,r)=>{let{context:a,client:o}=G(r),s=await q(o,a,t);s=await J(s);let c=await s.fs.list(n,{all:r.all,long:r.long});if(r.json)e(c);else if(r.long)i([`Mode`,`Owner`,`Group`,`Size`,`Modified`,`Name`],c.map(e=>{let t=e.isDir?`d`:e.isSymlink?`l`:`-`,n=ss(e.permissions),r=e.isDir?`<DIR>`:cs(e.size),i=e.modTime.toLocaleDateString();return[t+n,e.owner,e.group,r,i,e.name]}));else{let e=c.map(e=>e.isDir?`${e.name}/`:e.name);console.log(e.join(` `))}}),t.command(`stat`).description(`Get file or directory information`).argument(`<sandbox-id-or-name>`,`Sandbox ID or name`).argument(`<path>`,`Path to file or directory`).action(async(t,n,r)=>{let{context:i,client:a}=G(r),o=await q(a,i,t);o=await J(o);let s=await o.fs.stat(n);r.json?e(s):(console.log(` File: ${s.name}`),console.log(` Path: ${s.path}`),console.log(` Size: ${cs(s.size)} (${s.size} bytes)`),console.log(` Type: ${s.isDir?`directory`:s.isSymlink?`symlink`:`file`}`),console.log(` Mode: ${ss(s.permissions)} (${s.permissions.toString(8)})`),console.log(` Owner: ${s.owner}`),console.log(` Group: ${s.group}`),console.log(` Modified: ${s.modTime.toISOString()}`),console.log(` Accessed: ${s.accessTime.toISOString()}`))}),t.command(`cat`).description(`Print file contents`).argument(`<sandbox-id-or-name>`,`Sandbox ID or name`).argument(`<path>`,`Path to file`).action(async(t,n,r)=>{let{context:i,client:a}=G(r),o=await q(a,i,t);o=await J(o);let s=await o.read(n);r.json?e({path:n,content:s}):console.log(s)}),t.command(`rm`).description(`Delete a file or directory`).argument(`<sandbox-id-or-name>`,`Sandbox ID or name`).argument(`<path>`,`Path to delete`).option(`-r, --recursive`,`Delete directories recursively`).action(async(t,n,r)=>{let{context:i,client:a}=G(r),o=await q(a,i,t);o=await J(o),await o.fs.delete(n,{recursive:r.recursive}),r.json?e({success:!0,path:n,deleted:!0}):console.log(`✓ Deleted: ${n}`)}),t.command(`mkdir`).description(`Create a directory`).argument(`<sandbox-id-or-name>`,`Sandbox ID or name`).argument(`<path>`,`Directory path to create`).option(`-p, --parents`,`Create parent directories as needed`).action(async(t,n,r)=>{let{context:i,client:a}=G(r),o=await q(a,i,t);o=await J(o),await o.fs.mkdir(n,{recursive:r.parents}),r.json?e({success:!0,path:n,created:!0}):console.log(`✓ Created: ${n}`)}),t.command(`exists`).description(`Check if a path exists`).argument(`<sandbox-id-or-name>`,`Sandbox ID or name`).argument(`<path>`,`Path to check`).action(async(t,n,r)=>{let{context:i,client:a}=G(r),o=await q(a,i,t);o=await J(o);let s=await o.fs.exists(n);r.json?e({path:n,exists:s}):(console.log(s?`exists`:`not found`),process.exit(+!s))}),t}function ss(e){let t=[`r`,`w`,`x`],n=``;for(let r=2;r>=0;r--){let i=r*3;for(let r=0;r<3;r++)n+=e>>i+(2-r)&1?t[r]:`-`}return n}function cs(e){let t=[`B`,`KB`,`MB`,`GB`,`TB`],n=e,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r++;return r===0?`${n}${t[r]}`:`${n.toFixed(1)}${t[r]}`}function ls(){let t=new M(`git`).description(`Git operations in a sandbox workspace`);return t.command(`status`).description(`Show git repository status`).argument(`<id-or-name>`,`Sandbox ID or name`).action(async(t,n)=>{let{context:r,client:i}=G(n),a=f(`Fetching status...`);n.json||a.start();let o=await q(i,r,t);o=await J(o);let s=await o.git.status();if(a.stop(),n.json)e(s);else if(!s.isRepo)console.log(`No git repository in the sandbox workspace.`);else{if(console.log(`Branch: ${s.branch??`unknown`}`),console.log(`HEAD: ${s.head.slice(0,7)||`(no commits)`}`),console.log(`Dirty: ${s.isDirty?`yes`:`no`}`),s.ahead&&console.log(`Ahead: ${s.ahead}`),s.behind&&console.log(`Behind: ${s.behind}`),s.staged.length>0){console.log(`\nStaged (${s.staged.length}):`);for(let e of s.staged)console.log(` + ${e}`)}if(s.modified.length>0){console.log(`\nModified (${s.modified.length}):`);for(let e of s.modified)console.log(` M ${e}`)}if(s.untracked.length>0){console.log(`\nUntracked (${s.untracked.length}):`);for(let e of s.untracked)console.log(` ? ${e}`)}}}),t.command(`log`).description(`Show commit log`).argument(`<id-or-name>`,`Sandbox ID or name`).option(`-n, --limit <count>`,`Max commits to show`,`10`).action(async(t,n)=>{let{context:r,client:i}=G(n),a=f(`Fetching log...`);n.json||a.start();let o=await q(i,r,t);o=await J(o);let s=await o.git.log(Number.parseInt(n.limit,10));if(a.stop(),n.json)e(s);else if(s.length===0)console.log(`No commits found`);else for(let e of s)console.log(`${e.shortSha} ${e.message.split(`
146
146
  `)[0]} (${e.author}, ${e.date.toLocaleDateString()})`)}),t.command(`diff`).description(`Show diff`).argument(`<id-or-name>`,`Sandbox ID or name`).option(`--ref <ref>`,`Ref to diff against`).action(async(t,n)=>{let{context:r,client:i}=G(n),a=f(`Fetching diff...`);n.json||a.start();let o=await q(i,r,t);o=await J(o);let s=await o.git.diff(n.ref);a.stop(),n.json?e(s):s.raw?console.log(s.raw):console.log(`${s.additions} additions, ${s.deletions} deletions across ${s.files.length} files`)}),t.command(`add`).description(`Stage files`).argument(`<id-or-name>`,`Sandbox ID or name`).argument(`<paths...>`,`Paths to stage`).action(async(e,t,n)=>{let{context:i,client:a}=G(n),o=await q(a,i,e);o=await J(o),await o.git.add(t),r(`Staged: ${t.join(`, `)}`)}),t.command(`commit`).description(`Create a commit`).argument(`<id-or-name>`,`Sandbox ID or name`).requiredOption(`-m, --message <msg>`,`Commit message`).option(`--amend`,`Amend the previous commit`).action(async(t,n)=>{let{context:i,client:a}=G(n),o=await q(a,i,t);o=await J(o);let s=await o.git.commit(n.message,{amend:n.amend});n.json?e(s):r(`Committed: ${s.shortSha} ${s.message}`)}),t.command(`push`).description(`Push to remote`).argument(`<id-or-name>`,`Sandbox ID or name`).option(`--force`,`Force push`).action(async(e,t)=>{let{context:n,client:i}=G(t),a=f(`Pushing...`);a.start();let o=await q(i,n,e);o=await J(o),await o.git.push({force:t.force}),a.stop(),r(`Pushed to remote`)}),t.command(`pull`).description(`Pull from remote`).argument(`<id-or-name>`,`Sandbox ID or name`).option(`--rebase`,`Rebase instead of merge`).action(async(e,t)=>{let{context:n,client:i}=G(t),a=f(`Pulling...`);a.start();let o=await q(i,n,e);o=await J(o),await o.git.pull({rebase:t.rebase}),a.stop(),r(`Pulled from remote`)}),t.command(`branches`).description(`List branches`).argument(`<id-or-name>`,`Sandbox ID or name`).action(async(t,n)=>{let{context:r,client:a}=G(n),o=f(`Fetching branches...`);n.json||o.start();let s=await q(a,r,t);s=await J(s);let c=await s.git.branches();o.stop(),n.json?e(c):c.length===0?console.log(`No branches found`):i([`Name`,`Current`,`Remote`],c.map(e=>[e.name,e.current?`* `:` `,e.upstream??`-`]))}),t.command(`checkout`).description(`Checkout a branch or ref`).argument(`<id-or-name>`,`Sandbox ID or name`).argument(`<ref>`,`Branch name or ref`).option(`-b, --create`,`Create a new branch`).action(async(e,t,n)=>{let{context:i,client:a}=G(n),o=await q(a,i,e);o=await J(o),await o.git.checkout(t,{create:n.create}),r(`Checked out: ${t}${n.create?` (new)`:``}`)}),t}function us(e,t=16){if(!Number.isInteger(t)||t<=0||t>64)throw TypeError(`stableHashHex: lengthHex must be in [1, 64] (got ${t})`);let n=typeof e==`string`?e:JSON.stringify(e,(e,t)=>{if(t&&typeof t==`object`&&!Array.isArray(t)){let e={},n=t;for(let t of Object.keys(n).sort())e[t]=n[t];return e}return t});return ce(`sha256`).update(n).digest(`hex`).slice(0,t)}Object.freeze([`HS256`]),Object.freeze([`RS256`]);async function ds(e,t,n=`tangle --help`){let r=new AbortController,i=e??r.signal,a=()=>{r.abort(),process.stderr.write(`Stopping…
147
- `)};e||(process.once(`SIGINT`,a),process.once(`SIGTERM`,a));try{return i.throwIfAborted(),await t(i)}catch(e){if(!i.aborted||e instanceof B&&e.code===`RUN_STOPPED`)throw e;let t=new B(`RUN_STOPPED`,`Command interrupted`,`A stop request ended this execution`,n);throw e instanceof Error&&`runId`in e&&typeof e.runId==`string`&&Object.assign(t,{runId:e.runId}),t}finally{e||(process.off(`SIGINT`,a),process.off(`SIGTERM`,a))}}function fs(e,t){for(let[n,r]of Object.entries(t)){let t=e.gates?.find(e=>e.id===n);if(!t||!t.choices.includes(r))throw new B(`GATE_CHOICE_INVALID`,`Invalid choice for gate '${n}'`,t?`Choose one of: ${t.choices.join(`, `)}`:`The graph does not declare this gate`,`tangle graph run --help`)}}function ps(e,t){let n=t.signal;return async r=>{let i=Object.hasOwn(e,r.gate)?e[r.gate]:void 0,a=`--param ${ot(`gate.${r.gate}=<choice>`)}`,o=`${r.question} Choose one of: ${r.choices.join(`, `)}`,s=()=>new B(`GATE_ANSWER_REQUIRED`,`Gate '${r.gate}' needs an answer. ${o}. Pass ${a}`,o,`tangle graph run <graph> ${a}`);if(i!==void 0)return{kind:`choose`,choice:i,by:`cli:param`};if(t.json||!process.stdin.isTTY)throw s();let c;try{c=await ar(`${r.question} [${r.choices.join(` / `)}]`,void 0,n)}catch{if(n.aborted)return{kind:`stop`,reason:`Gate input interrupted or timed out`,by:`cli:terminal`};throw s()}if(!r.choices.includes(c))throw s();return{kind:`choose`,choice:c,by:`cli:terminal`}}}const ms=()=>import(`./dist-BFxZmL_S.mjs`);async function hs(e,t,n,r){if(e==null)return;let{graphKnowledgeBindingSchema:i,graphKnowledgeResolver:a}=await ms(),o=i.parse(e);if(o.kind!==`local`)throw Error(`A local graph needs a pinned local Knowledge binding; Hub generations require the hosted workflow owner`);return a({binding:o,storeRoot:P(t,`knowledge`),signal:r,record:async e=>n.put({executionId:e.context.nodeId,purpose:`executor-native-evidence`,bytes:Buffer.from(JSON.stringify(e))}),recordProposal:async e=>n.put({executionId:e.context.nodeId,purpose:`task-output`,bytes:Buffer.from(JSON.stringify(e))})})}function gs(t){let n=t.command(`knowledge`).description(`Exact measured Knowledge candidate transitions`);n.command(`bind <root>`).description(`Identify exact bytes of an existing local Knowledge store`).action(async t=>e(await(await ms()).pinLocalGraphKnowledge(t)));for(let t of[`promote`,`restore`])n.command(`${t} <binding> <candidate>`).description(`${t} the exact measured local Knowledge candidate through its owner`).action(async(n,r)=>{let{graphKnowledgeBindingSchema:i,transitionGraphKnowledge:a}=await ms(),o=i.parse(JSON.parse(await L(n,`utf8`))),s=await a(o,JSON.parse(await L(r,`utf8`)),t);e({...s,nextBinding:{...o,sourceDigest:`sha256:${s.mutation.afterHash}`}})})}const _s=()=>new se(`--mcp-secret <key=variable>`,`Private local MCP secret reference binding; repeatable, values are never recorded`).argParser((e,t)=>[...t,e]).default([]);function vs(e=[]){let t=new Map;for(let n of e){let e=n.indexOf(`=`),r=n.slice(0,e).trim(),i=n.slice(e+1).trim();if(e<1||!r||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)||t.has(r)&&t.get(r)!==i)throw new B(`GRAPH_MCP_SECRET_BINDING`,`Invalid private MCP credential binding`,`Use one unambiguous key=ENVIRONMENT_VARIABLE per declared secret reference`,`tangle graph run --help`);t.set(r,i)}return Object.fromEntries(t)}async function ys(e){try{return He.parse(JSON.parse(await L(e,`utf8`)))}catch(e){throw new B(`GRAPH_MCP_POLICY_INVALID`,`The graph MCP policy is invalid`,e instanceof Error?e.message:String(e),`tangle graph run --help`)}}const bs=[`claude-code`,`opencode`,`codex`,`kimi-code`,`prime`],xs=process.env.TANGLE_ROUTER_URL??`https://router.tangle.tools/v1`;function Ss(e){let t=ve(e);if(t)return t;throw Error(`--model '${e}' has no provider. Pass a canonical id, for example 'google/${e}'.`)}function Cs(e){let t=e.harness??`claude-code`;if(!bs.includes(t))throw Error(`Unknown --harness '${t}'. Supported: ${bs.join(`, `)}.`);let n=ws(e.maxTokens,2e5,`--max-tokens`),r=ws(e.maxIterations,50,`--max-iterations`),i=e.maxWorkers===void 0?void 0:ws(e.maxWorkers,0,`--max-workers`);return{harness:t,...e.model?{model:e.model}:{},maxTokens:n,maxIterations:r,...i===void 0?{}:{maxWorkers:i}}}function ws(e,t,n){if(e===void 0)return t;let r=Number.parseInt(e,10);if(!Number.isFinite(r)||r<=0)throw Error(`${n} must be a positive integer, got '${e}'.`);return r}function Ts(e){let t={maxTokens:e.maxTokens,maxIterations:e.maxIterations};return e.maxWorkers===void 0?{budget:t}:{budget:t,perWorker:{maxTokens:Math.max(1,Math.floor(e.maxTokens/e.maxWorkers)),maxIterations:Math.max(1,Math.floor(e.maxIterations/e.maxWorkers))}}}function Es(e){let t=e.spentTotal,n=e.kind===`no-winner`?``:e.out;return{text:typeof n==`string`?n:typeof n==`object`&&n&&`content`in n&&typeof n.content==`string`?n.content:JSON.stringify(n),tokenUsage:{input:t.tokensKnown===!1?null:t.tokens.input,output:t.tokensKnown===!1?null:t.tokens.output},costUsd:t.usdKnown===!1?null:t.usd,status:e.kind===`no-winner`?`no-winner (${e.reason})`:`winner`}}let Ds=null;function Os(){return Ds??=import(`@tangle-network/agent-runtime/kernel`).catch(e=>{throw Ds=null,e?.code===`ERR_MODULE_NOT_FOUND`?new B(`RUNTIME_UNAVAILABLE`,`Agent Runtime could not be loaded`,e.message,`npm install -g @tangle-network/sandbox-cli@latest`):e}),Ds}async function ks(e,t,n){let r=U({apiKey:n.apiKey,baseUrl:n.baseUrl}),i=W(r),{budget:a,perWorker:o}=Ts(t),s=[],c={async create(e){let{TANGLE_API_KEY:t,...r}=e?.env??{},a=await i.create(e?.env?{...e,env:r}:e);return s.push({id:a.id,status:`spawned`}),n.json||l(`worker ${a.id} spawned`),a}},u=await Os(),d=u.workerFromBackend({backend:`sandbox`,sandboxClient:c,maxIterations:1}),f=(e,n)=>d({...e,harness:t.harness},n),p={name:`supervisor`,harness:`cli-base`,model:{default:t.model??`gemini-3.5-flash-lite`,provider:t.model?Ss(t.model):`google`},tools:{agent_runtime_coordination_spawn_worker:!0,agent_runtime_coordination_observe_agent:!0}},m={routerBaseUrl:xs,routerKey:r.apiKey},h=Es(await u.supervise(p,{goal:e},{budget:a,makeWorkerAgent:f,router:m,...o?{perWorker:o}:{},...t.model?{allowedModels:[t.model]}:{},runId:`supervise-${ue()}`})),g=h.status===`winner`?`settled`:`failed`;for(let e of s)e.status=g,n.json||l(`worker ${e.id} settled (${e.status})`);return{task:e,result:h.text,workers:s,tokenUsage:h.tokenUsage,costUsd:h.costUsd,status:h.status}}function As(){let t=new M(`supervise`);return t.description(`Run a budget-conserving supervisor that spawns isolated sandbox workers to deliver a task.`).argument(`<task>`,`What the supervisor should accomplish`).option(`--harness <name>`,`Worker harness (${bs.join(` | `)})`,`claude-code`).option(`--model <id>`,`Model for the supervisor + workers`).option(`--max-tokens <n>`,`Conserved token budget for the whole run`,`200000`).option(`--max-iterations <n>`,`Conserved iteration budget for the whole run`,`50`).option(`--max-workers <n>`,`Bound the fanout; each worker reserves floor(max-tokens / n) tokens and floor(max-iterations / n) iterations`).action(async(t,n)=>{let r=Cs({harness:n.harness,model:n.model,maxTokens:n.maxTokens,maxIterations:n.maxIterations,maxWorkers:n.maxWorkers});n.json||(l(`Supervising: ${t}`),l(`harness=${r.harness} budget=${r.maxTokens}tok/${r.maxIterations}it`),console.log());let i=await ks(t,r,{apiKey:n.apiKey,baseUrl:n.baseUrl,json:n.json});if(n.json){e(i),i.status!==`winner`&&(process.exitCode=1);return}if(console.log(),i.result&&(console.log(i.result),console.log()),s({"Input Tokens":i.tokenUsage.input??`Unavailable`,"Output Tokens":i.tokenUsage.output??`Unavailable`,Cost:i.costUsd===null?`Unavailable`:`$${i.costUsd.toFixed(4)}`}),i.status!==`winner`)throw Error(`Supervisor finished without a winner: ${i.status}`)}),t}function js(e,t){let n=Pe(e,t);return n!==`..`&&!n.startsWith(`..${Ie}`)&&!Ne(n)}const Ms=()=>import(`@tangle-network/agent-eval/campaign`),Ns=()=>import(`@tangle-network/agent-runtime/candidate-execution`),Ps=`graph-task-workspaces`,Fs=I.number().int().positive().max(2**53-1),Is=I.strictObject({maxArchiveBytes:Fs.optional(),maxEmbeddedArtifactBytes:Fs.optional(),maxFiles:Fs.optional(),maxFileBytes:Fs.optional(),maxTotalFileBytes:Fs.optional(),maxPathBytes:Fs.optional(),maxRepositoryBundleBytes:Fs.optional()}),Ls=me.shape,Rs=I.strictObject({snapshot:I.strictObject({kind:Ls.kind,digest:Ls.digest,manifest:pe,archive:pe}).superRefine((e,t)=>{(e.digest!==e.manifest.sha256||!e.manifest.byteLength||!e.archive.byteLength)&&t.addIssue({code:`custom`,message:`The canonical workspace manifest, digest and archive must agree`})}),capture:I.strictObject({mode:I.literal(`git-working-tree`),runtimeVersion:I.string().min(1),limits:Is}),gaps:I.tuple([I.literal(`environment-and-toolchain-not-snapshotted`),I.literal(`git-ignored-files-excluded`)])}),zs=e=>N(Rs.parse(e));function Bs(e){for(let t of[e.snapshot.manifest,e.snapshot.archive])if(t.locator.kind!==`private-cas`||t.locator.namespace!==Ps)throw Error(`Task workspace artifacts require their original local private CAS; cross-backend activation is unsupported`)}async function Vs(){let e=P(F(),`.tangle`);return await ct(e,{recursive:!0,mode:448}),R(e)}const Hs=async e=>(await import(`@tangle-network/agent-runtime/kernel`)).createPrivateCasArtifactPort(P(e,`artifacts`),Ps);async function Us(e){let t=await ut(Fe(e),Ce.O_RDONLY|Ce.O_NOFOLLOW);try{if(!(await t.stat()).isFile())throw Error(`Task workspace reference must be a regular file`);let e=Rs.parse(JSON.parse(await t.readFile(`utf8`)));return Bs(e),e}finally{await t.close()}}async function Ws(e,t={}){t.signal?.throwIfAborted();let n=Fe(e),r=await st(n);if(!r.isDirectory()||r.isSymbolicLink())throw Error(`Task workspace must be one real repository root`);let i=await R(n),a=await R(F()),o=await Vs();if(i===a||i===je(i)||js(o,i)||js(i,o))throw Error(`Task workspace capture cannot include the home, filesystem or private evidence root`);let{release:s}=(await Ms()).acquireSingleRunLock({lockPath:`${i}.graph-workspace.lock`});try{let e=Is.parse(t.limits??{}),n=await(await Ns()).captureAgentWorkspaceSnapshot(i,{includeRepository:!0,repositoryContents:`working-tree`,limits:e,artifactPersistence:{executionId:ue(),outputArtifacts:await Hs(o),signal:t.signal}}),r=v(`@tangle-network/agent-runtime`,import.meta.url);if(!r)throw Error(`Cannot identify the Runtime workspace archive owner`);let a=JSON.parse(await L(r,`utf8`));return Rs.parse({snapshot:n,capture:{mode:`git-working-tree`,runtimeVersion:a.version,limits:e},gaps:[`environment-and-toolchain-not-snapshotted`,`git-ignored-files-excluded`]})}finally{s()}}async function Gs(e,t){let n=I.uuid().parse(t.runId),r=Rs.parse(e);Bs(r);let i=await Vs(),a=P(i,`workspaces`);if(await ct(a,{recursive:!0,mode:448}),await R(a)!==a)throw Error(`Task workspace allocation root redirects elsewhere`);let o=P(a,n),{release:s}=(await Ms()).acquireSingleRunLock({lockPath:`${o}.lock`});try{t.signal?.throwIfAborted();let e=`${o}.task-workspace.json`,a;try{a=JSON.parse(await L(e,`utf8`))}catch(e){if(e.code!==`ENOENT`)throw e}let c=zs(r);if(a!==void 0){let e=I.strictObject({runId:I.uuid(),identity:I.string()}).parse(a);if(e.runId!==n||e.identity!==c||t.resumeCwd!==void 0&&Fe(t.resumeCwd)!==o||await R(o)!==o||!(await st(o)).isDirectory())throw Error(`The retained task workspace no longer names this exact native run allocation`)}else{if(t.resumeCwd!==void 0)throw Error(`The retained task workspace allocation receipt is missing`);await(await Ns()).materializeAgentWorkspaceSnapshot({snapshot:r.snapshot,artifacts:await Hs(i),destination:o,limits:r.capture.limits,signal:t.signal}),await z(e,JSON.stringify({runId:n,identity:c}),{flag:`wx`,mode:384,flush:!0})}if(!t.validationOnly||a!==void 0)return{cwd:o,release:s};let l=await Promise.all([st(o,{bigint:!0}),st(e,{bigint:!0})]);return{cwd:o,release:async()=>{try{for(let[t,r]of[o,e].entries()){let e=await st(r,{bigint:!0});if(!(t===0?e.isDirectory():e.isFile())||e.dev!==l[t]?.dev||e.ino!==l[t]?.ino||await R(r)!==r)throw Error(`Validation allocation ${n} changed; retained`)}if(N(JSON.parse(await L(e,`utf8`)))!==N({runId:n,identity:c}))throw Error(`Validation allocation ${n} receipt changed; retained`);try{throw await st(P(i,`runs`,n)),Error(`Validation allocation ${n} has run state; retained`)}catch(e){if(e.code!==`ENOENT`)throw e}await dt(o,{recursive:!0}),await dt(e)}finally{s()}}}}catch(e){throw s(),e}}function Ks(t){t.command(`workspace`).description(`Capture immutable local task files for graph replay`).command(`capture <repository>`).description(`Capture Git HEAD, index, tracked and unignored files into private local artifacts`).requiredOption(`--output <file>`,`New reference file outside the source repository`).option(`--limits <file>`,`JSON overrides for the maintained Runtime archive limits`).action(async(t,n)=>{let r=await R(Fe(t)),i=P(await R(je(Fe(n.output))),Ae(Fe(n.output)));if(js(r,i))throw Error(`The task reference must be written outside the original workspace`);try{throw await st(i),Error(`Task workspace reference already exists; choose a new output file`)}catch(e){if(e.code!==`ENOENT`)throw e}let a=await Ws(r,{limits:n.limits?Is.parse(JSON.parse(await L(n.limits,`utf8`))):void 0});await z(i,JSON.stringify(a),{flag:`wx`,mode:384,flush:!0}),e(a)})}const qs=I.string().regex(/^[a-f0-9]{64}$/),Js=I.strictObject({version:I.literal(1),runId:I.uuid(),file:I.string().refine(Ne),cwd:I.string().refine(Ne),sourceDigest:qs,source:I.string().optional(),graphDigest:qs,params:I.record(I.string(),I.unknown()),trigger:I.record(I.string(),I.unknown()).optional(),gateChoices:I.record(I.string(),I.string()).optional(),startedAt:I.iso.datetime(),seat:I.string().optional(),mcpPolicy:Ue.optional(),taskWorkspace:Rs.optional()});async function Ys(e){let t=await Os(),n=t.graphRegistry(P(F(),`.tangle`,`graph-registry`)),r=await t.loadGraph(n,e.graphDigest);if(!r)throw Error(`Retained execution graph is unavailable; configuration is unknown`);let i=t.validateStoredGraph(r);if(i.digest!==e.graphDigest)throw Error(`Retained execution graph changed its identity`);return N({mcpPolicy:Ue.parse(e.mcpPolicy??{}),nodes:i.nodes.map(({id:e,profile:t})=>({id:e,harness:t.harness??null,model:t.model??null,seats:t.seats??null,connections:t.connections??null}))})}function Y(e){throw new B(`GRAPH_RESUME_REFUSED`,`The graph run cannot be resumed`,e,`tangle graph run --help`)}async function Xs(e){I.uuid().safeParse(e).success||Y(`Use a recorded graph run ID`);let t;try{let n=P(await R(P(F(),`.tangle`)),`runs`,e);await R(n)!==n&&Y(`The run directory redirects elsewhere`),t=await ut(P(n,`input.json`),Ce.O_RDONLY|Ce.O_NOFOLLOW),(await t.stat()).isFile()||Y(`The run input is not a regular file`);let r=Js.parse(JSON.parse(await t.readFile(`utf8`)));return r.runId!==e&&Y(`The recorded run identity changed`),r.source!==void 0&&Qs(r,r.source),r}catch(e){if(e instanceof B)throw e;return Y(`The private recorded run input is missing or invalid`)}finally{await t?.close()}}async function Zs(e,t){let n=t.source??await L(t.file,`utf8`);Qs(t,n),await z(P(e,`input.json`),JSON.stringify({...t,source:n}),{flag:`wx`,mode:384,flush:!0})}function Qs(e,t){return ce(`sha256`).update(t).digest(`hex`)!==e.sourceDigest&&Y(`The retained graph source does not match this run`),t}async function $s(e){return Qs(e,e.source??await L(e.file,`utf8`))}function ec(e,t,n,r,i={}){e.sourceDigest!==n&&Y(`The authored graph source changed`),t.cloud&&Y(`A local run cannot move to cloud execution`),Object.entries(r).some(([t,n])=>!Object.hasOwn(e.params,t)||N(n)!==N(e.params[t]))&&Y(`A recorded graph parameter changed`),Object.entries(i).some(([t,n])=>e.gateChoices?.[t]!==n)&&Y(`A recorded gate choice changed`),t.seat!==void 0&&t.seat!==e.seat&&Y(`The recorded graph seat override changed`),t.mcpPolicy!==void 0&&(e.mcpPolicy===void 0||N(t.mcpPolicy)!==N(e.mcpPolicy))&&Y(`The recorded graph MCP policy changed`)}const tc=e=>Object.entries(e).map(([e,t])=>`${e}=${typeof t==`string`?t:JSON.stringify(t)}`),nc=`claude,codex,kimi,opencode,gemini,pi`;function rc(e,t){let n;return async(r,{node:i,lastCandidate:a})=>{t.throwIfAborted();let o;try{o=r===void 0?void 0:ye(r)}catch(e){throw e instanceof Error&&Object.assign(e,{node:i,seat:r,fixCommand:`tangle graph run --help`}),e}n??=import(`cli-bridge`).then(({listLocalModels:n,loadConfig:r})=>n({cwd:e,signal:t,config:r({...process.env,BRIDGE_BACKENDS:nc,BRIDGE_SUBSCRIPTIONS_ONLY:`1`})}));let s=await n;t.throwIfAborted();let c=e=>e.authentication?.status===`authenticated`&&e.authentication.authMode===`subscription`,l=o?.harness??s.find(e=>e.provider&&c(e))?.backend,u=s.filter(e=>e.backend===l),d=u.filter(c),f=o?u.find(e=>e.id===`${o.harness}/${o.model}`)??d.find(e=>e.provider===o.provider):d.find(e=>e.default)??d.find(e=>e.recommended)??d[0];if(!f||!c(f)){if(a===!1)return;let e=f?.authentication??u[0]?.authentication??(o?void 0:s.find(e=>e.authentication?.fix)?.authentication);throw Object.assign(new B(o?`SEAT_NOT_LOGGED_IN`:`SEAT_NONE_DETECTED`,`Node '${i}' has no available subscription${o?` for ${o.harness}`:``}`,e?`Selected provider: ${e.status} (${e.authMode})`:`No authenticated subscription route was detected`,e?.fix??`tangle graph run --help`),{node:i,seat:r})}let p=o?.harness??ye(f.id).harness,m=o?.provider??f.provider,h=o?.model??f.id.slice(p.length+1);if(!m||!h)throw new B(`MODEL_PROVIDER_MISMATCH`,`Node '${i}' has an unresolved model provider`,`Bridge has no configured provider for ${r??p}`,`tangle graph run --help`);return{harness:p,provider:m,model:h,selector:{kind:`all-eligible`},...o?.reasoningEffort===void 0?{}:{reasoningEffort:o.reasoningEffort}}}}const ic=ft(ze);function ac(e,t,n=`tangle graph run --help`){throw new B(`SEAT_NONE_DETECTED`,e,t,n)}function oc(e){let t=[];for(let n of e.nodes)for(let e of n.check?.egress??[]){let n=e.trim().toLowerCase();if(n){if(/[\s*]|\/|:\/\//u.test(n))throw new B(`GRAPH_EGRESS_HOST`,`Graph egress host "${e.trim()}" is not a DNS hostname`,`A check egress entry has whitespace, a wildcard, or a URL`,`tangle graph run --help`);t.includes(n)||t.push(n)}}return t.length>0?t.join(`,`):void 0}function sc(e){return e.some(e=>(e.profile?.seats?.length??0)>0)}function cc(e){let t=e?.trim();if(t)return/\s/u.test(t)&&ac(`A seat account, command, or credential must be a single token`,`The seat command is an executable path, not a shell line`),t}function lc(e){let t=cc(e.seatAccount),n=cc(e.seatCommand),r=cc(e.seatCredential);return r&&!n&&!t&&ac(`A seat credential needs a seat command`,`The credential is an argument to the configured command`,`tangle graph run --seat-command <program>`),{...t?{account:t}:{},...n?{command:n}:{},...r?{credential:r}:{}}}async function uc(e,t,n){if(e.account)return e.account;e.command||ac(`This graph needs a seat account or a seat command`,`No account was authored and no seat command is configured`,`tangle graph run --seat-account <account>`);let r=``;try{r=(await ic(e.command,[t,...e.credential?[e.credential]:[]],{timeout:3e4,maxBuffer:4096,signal:n,encoding:`utf8`})).stdout}catch(e){n.throwIfAborted();let t=e.code===`ENOENT`;ac(t?`The seat command was not found`:`The seat command failed`,t?`The configured executable is not on PATH`:`The seat command exited without an account id`)}let i=r.trim();return(!i||/\s/u.test(i))&&ac(`The seat command did not print an account id`,`The command must print one account id and nothing else`),i}function dc(e,t,n){let r=new Map;return async i=>{n.throwIfAborted();let a=i.stage.harness,o=i.stage.selector.kind===`seat`?i.stage.selector.id.trim():``,s=`${a}\0${t.credential??``}`,c=o||t.account||r.get(s)||await uc(t,a,n);!o&&!t.account&&r.set(s,c),(!c||/\s/u.test(c)||i.resumeSeatId!==void 0&&i.resumeSeatId!==c)&&ac(`Node '${i.nodeId}' has no seat account`,`The authored seat, account flag, or seat command did not yield one`);let{createCliBridgeProvider:l}=await import(`@tangle-network/agent-provider-cli-bridge`);return{seat:c,backend:{backend:`provider`,provider:l({baseUrl:e.bridgeUrl,bearerToken:e.bridgeBearer}),defaults:{workspace:{cwd:{base:`host`,path:e.cwd}}},runtime:`cli`,outputFormat:`json`,destroyOnSettle:!0,requireTerminalEvent:!0}}}}function X(e){return Kn({signal:e.signal,...e.apiKey===void 0?{}:{apiKey:e.apiKey},...e.baseUrl===void 0?{}:{baseUrl:e.baseUrl}})}const fc=I.object({version:I.literal(1),type:I.enum([`state`,`ack`,`error`,`event`]),requestId:I.string().optional(),operationId:I.string().optional(),command:I.string().optional(),code:I.string().optional(),message:I.string().optional(),result:I.unknown().optional()}).passthrough(),pc=I.object({state:I.object({runConfiguration:I.unknown()}),view:I.object({capabilities:I.record(I.string(),I.object({available:I.boolean(),reason:I.string().optional()}))})}),mc=I.object({status:I.enum([`completed`,`failed`,`cancelled`]),analysis:I.object({id:I.string().min(1)}).passthrough(),source:I.object({runtimeRun:I.unknown()}).passthrough()}).passthrough(),hc=`TANGLE_GRAPH_ANALYSIS_SOURCE`;async function gc(e,t,n){if(!e.startsWith(`wfrun_`)){let t=P(await R(P(F(),`.tangle`)),`runs`,e);if(await R(t)!==t)throw new B(`RUN_NOT_FOUND`,`The run directory redirects elsewhere`,`Use the recorded local run directory`,`tangle graph inspect --help`);return{source:`runtime:${e}@${t}`,env:{},schema:I.object({runId:I.literal(e),runDir:I.literal(t)})}}let r={signal:n,...t.apiKey===void 0?{}:{apiKey:t.apiKey},...t.baseUrl===void 0?{}:{baseUrl:t.baseUrl}},i=await X(r),a=I.object({id:I.literal(e),workflowId:I.string(),revUsed:I.number().int(),execution:I.object({kind:I.literal(`graph`),sourceSha:I.string(),authoredGraphDigest:I.string(),graphDigest:I.string()}),runtime:I.object({snapshot:I.object({supervisors:I.tuple([I.object({id:I.string()})])})})}).parse(await i.workflows.getRun(e,{signal:n})),o=a.runtime.snapshot.supervisors[0];if(!o)throw new B(`BRAID_RPC_FAILED`,`The cloud run has no retained Runtime root`,`Wait for execution evidence before analysis`,`tangle graph inspect ${e}`);let s=await Hn(r);if(new URL(s.baseUrl.replace(/\/+$/,``)).href!==new URL(i.baseUrl.replace(/\/+$/,``)).href)throw new B(`AUTH_REQUIRED`,`The analysis source origin changed`,`Use the same authenticated platform origin`,`tangle auth status --json`);return{source:`runtime:${e}@${hc}`,env:{[hc]:JSON.stringify({url:`${s.baseUrl.replace(/\/+$/,``)}/v1/workflows/runs/${encodeURIComponent(e)}`,headers:{Authorization:`Bearer ${s.token}`}})},schema:I.object({runId:I.literal(e),remoteEndpointEnv:I.literal(hc),checkpoint:I.object({workflowId:I.literal(a.workflowId),runtimeRunId:I.literal(o.id),revUsed:I.literal(a.revUsed),sourceSha:I.literal(a.execution.sourceSha),authoredGraphDigest:I.literal(a.execution.authoredGraphDigest),graphDigest:I.literal(a.execution.graphDigest)})})}}async function _c(e,t){if(!e.startsWith(`wfrun_`)&&!I.uuid().safeParse(e).success)throw new B(`RUN_NOT_FOUND`,`Use a recorded graph run ID`,`The run identifier is invalid`,`tangle graph inspect --help`);if(!Number.isSafeInteger(t.timeout)||t.timeout<1)throw new B(`INVALID_TIMEOUT`,`Use a positive analysis timeout`,`The timeout must be an integer number of milliseconds`,`tangle graph analyze --help`);let n=t.profile;if(!n?.trim())throw new B(`USAGE_INVALID`,`Select the canonical analysis profile`,`Graph analysis requires an existing canonical AgentProfile reference`,`tangle graph analyze `+e+` --profile <name|path>`);let r=/^(?:\.\.?)[/\\]/.test(n)?Fe(process.cwd(),n):n;return ds(t.signal,async n=>{let i=await gc(e,t,n),a=i.source;return Bl({signal:n,errorRunId:e},async n=>{let o=await n.bridge(),s=await lt(P(n.runDir,`analysis-`)),c=P(s,`config.json`),l=P(s,`database.key`),u=P(s,`state.sqlite`),d=`connection-owned-graph-bridge`,f=new Date().toISOString();await z(l,le(32),{mode:384,flag:`wx`}),await z(c,JSON.stringify({format:`braid-startup-config`,schemaVersion:2,profile:r,connectionId:d,connections:[{id:d,name:`Graph analysis`,kind:`cli-bridge`,endpoint:o.bridgeUrl,providerOptions:{transport:`local`},createdAt:f,updatedAt:f,lastHealth:{status:`unknown`}}]}),{mode:384,flag:`wx`});let p=n.signal,m=`op-${ue()}`,h=`op-${ue()}`,g=`${m}:initialize`,_=`${m}:analyze`,v=`${m}:shutdown`,y={version:1,requestId:g,command:`initialize`,params:{workspace:n.cwd,subscribe:!1}},b={version:1,requestId:_,operationId:m,command:`analyze`,params:{source:a,recipe:`all`,totalTimeoutMs:t.timeout}},x={version:1,requestId:v,operationId:h,command:`shutdown`,params:{mode:`wait`}},S,C,w,T,ee={transform:e=>{let t=fc.parse(e);return t.type===`error`||t.type===`state`&&t.requestId===g||t.type===`ack`&&[_,v].includes(t.requestId??``)?t:null},onError:e=>{T??=e},onEvent:e=>{e.type===`error`&&(T??=new B(e.code??`BRAID_RPC_FAILED`,`Braid refused graph analysis`,e.message??`The RPC response omitted its cause`,`tangle graph analyze --help`)),e.requestId===g&&e.type===`state`&&(S??=e),e.requestId===_&&e.type===`ack`&&(C??=e),e.requestId===v&&e.type===`ack`&&(w??=e)}},E=await at({command:process.env.BRAID_BIN??`braid`,args:[`rpc`,`--workspace`,n.cwd,`--config`,c,`--profile`,r,`--database-key-file`,l],cwd:n.cwd,env:{...i.env,BRAID_STATE_PATH:u,BRAID_CLI_BRIDGE_ENDPOINT:o.bridgeUrl,BRAID_CLI_BRIDGE_AUTH:o.bridgeBearer},timeoutMs:t.timeout,signal:p,ownProcessGroup:!0},ee,{stdin:[y,...t.dryRun?[]:[b],x].map(e=>JSON.stringify(e)).join(`
147
+ `)};e||(process.once(`SIGINT`,a),process.once(`SIGTERM`,a));try{return i.throwIfAborted(),await t(i)}catch(e){if(!i.aborted||e instanceof B&&e.code===`RUN_STOPPED`)throw e;let t=new B(`RUN_STOPPED`,`Command interrupted`,`A stop request ended this execution`,n);throw e instanceof Error&&`runId`in e&&typeof e.runId==`string`&&Object.assign(t,{runId:e.runId}),t}finally{e||(process.off(`SIGINT`,a),process.off(`SIGTERM`,a))}}function fs(e,t){for(let[n,r]of Object.entries(t)){let t=e.gates?.find(e=>e.id===n);if(!t||!t.choices.includes(r))throw new B(`GATE_CHOICE_INVALID`,`Invalid choice for gate '${n}'`,t?`Choose one of: ${t.choices.join(`, `)}`:`The graph does not declare this gate`,`tangle graph run --help`)}}function ps(e,t){let n=t.signal;return async r=>{let i=Object.hasOwn(e,r.gate)?e[r.gate]:void 0,a=`--param ${ot(`gate.${r.gate}=<choice>`)}`,o=`${r.question} Choose one of: ${r.choices.join(`, `)}`,s=()=>new B(`GATE_ANSWER_REQUIRED`,`Gate '${r.gate}' needs an answer. ${o}. Pass ${a}`,o,`tangle graph run <graph> ${a}`);if(i!==void 0)return{kind:`choose`,choice:i,by:`cli:param`};if(t.json||!process.stdin.isTTY)throw s();let c;try{c=await ar(`${r.question} [${r.choices.join(` / `)}]`,void 0,n)}catch{if(n.aborted)return{kind:`stop`,reason:`Gate input interrupted or timed out`,by:`cli:terminal`};throw s()}if(!r.choices.includes(c))throw s();return{kind:`choose`,choice:c,by:`cli:terminal`}}}const ms=()=>import(`./dist-szenDGSN.mjs`);async function hs(e,t,n,r){if(e==null)return;let{graphKnowledgeBindingSchema:i,graphKnowledgeResolver:a}=await ms(),o=i.parse(e);if(o.kind!==`local`)throw Error(`A local graph needs a pinned local Knowledge binding; Hub generations require the hosted workflow owner`);return a({binding:o,storeRoot:P(t,`knowledge`),signal:r,record:async e=>n.put({executionId:e.context.nodeId,purpose:`executor-native-evidence`,bytes:Buffer.from(JSON.stringify(e))}),recordProposal:async e=>n.put({executionId:e.context.nodeId,purpose:`task-output`,bytes:Buffer.from(JSON.stringify(e))})})}function gs(t){let n=t.command(`knowledge`).description(`Exact measured Knowledge candidate transitions`);n.command(`bind <root>`).description(`Identify exact bytes of an existing local Knowledge store`).action(async t=>e(await(await ms()).pinLocalGraphKnowledge(t)));for(let t of[`promote`,`restore`])n.command(`${t} <binding> <candidate>`).description(`${t} the exact measured local Knowledge candidate through its owner`).action(async(n,r)=>{let{graphKnowledgeBindingSchema:i,transitionGraphKnowledge:a}=await ms(),o=i.parse(JSON.parse(await L(n,`utf8`))),s=await a(o,JSON.parse(await L(r,`utf8`)),t);e({...s,nextBinding:{...o,sourceDigest:`sha256:${s.mutation.afterHash}`}})})}const _s=()=>new se(`--mcp-secret <key=variable>`,`Private local MCP secret reference binding; repeatable, values are never recorded`).argParser((e,t)=>[...t,e]).default([]);function vs(e=[]){let t=new Map;for(let n of e){let e=n.indexOf(`=`),r=n.slice(0,e).trim(),i=n.slice(e+1).trim();if(e<1||!r||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)||t.has(r)&&t.get(r)!==i)throw new B(`GRAPH_MCP_SECRET_BINDING`,`Invalid private MCP credential binding`,`Use one unambiguous key=ENVIRONMENT_VARIABLE per declared secret reference`,`tangle graph run --help`);t.set(r,i)}return Object.fromEntries(t)}async function ys(e){try{return He.parse(JSON.parse(await L(e,`utf8`)))}catch(e){throw new B(`GRAPH_MCP_POLICY_INVALID`,`The graph MCP policy is invalid`,e instanceof Error?e.message:String(e),`tangle graph run --help`)}}const bs=[`claude-code`,`opencode`,`codex`,`kimi-code`,`prime`],xs=process.env.TANGLE_ROUTER_URL??`https://router.tangle.tools/v1`;function Ss(e){let t=ve(e);if(t)return t;throw Error(`--model '${e}' has no provider. Pass a canonical id, for example 'google/${e}'.`)}function Cs(e){let t=e.harness??`claude-code`;if(!bs.includes(t))throw Error(`Unknown --harness '${t}'. Supported: ${bs.join(`, `)}.`);let n=ws(e.maxTokens,2e5,`--max-tokens`),r=ws(e.maxIterations,50,`--max-iterations`),i=e.maxWorkers===void 0?void 0:ws(e.maxWorkers,0,`--max-workers`);return{harness:t,...e.model?{model:e.model}:{},maxTokens:n,maxIterations:r,...i===void 0?{}:{maxWorkers:i}}}function ws(e,t,n){if(e===void 0)return t;let r=Number.parseInt(e,10);if(!Number.isFinite(r)||r<=0)throw Error(`${n} must be a positive integer, got '${e}'.`);return r}function Ts(e){let t={maxTokens:e.maxTokens,maxIterations:e.maxIterations};return e.maxWorkers===void 0?{budget:t}:{budget:t,perWorker:{maxTokens:Math.max(1,Math.floor(e.maxTokens/e.maxWorkers)),maxIterations:Math.max(1,Math.floor(e.maxIterations/e.maxWorkers))}}}function Es(e){let t=e.spentTotal,n=e.kind===`no-winner`?``:e.out;return{text:typeof n==`string`?n:typeof n==`object`&&n&&`content`in n&&typeof n.content==`string`?n.content:JSON.stringify(n),tokenUsage:{input:t.tokensKnown===!1?null:t.tokens.input,output:t.tokensKnown===!1?null:t.tokens.output},costUsd:t.usdKnown===!1?null:t.usd,status:e.kind===`no-winner`?`no-winner (${e.reason})`:`winner`}}let Ds=null;function Os(){return Ds??=import(`@tangle-network/agent-runtime/kernel`).catch(e=>{throw Ds=null,e?.code===`ERR_MODULE_NOT_FOUND`?new B(`RUNTIME_UNAVAILABLE`,`Agent Runtime could not be loaded`,e.message,`npm install -g @tangle-network/sandbox-cli@latest`):e}),Ds}async function ks(e,t,n){let r=U({apiKey:n.apiKey,baseUrl:n.baseUrl}),i=W(r),{budget:a,perWorker:o}=Ts(t),s=[],c={async create(e){let{TANGLE_API_KEY:t,...r}=e?.env??{},a=await i.create(e?.env?{...e,env:r}:e);return s.push({id:a.id,status:`spawned`}),n.json||l(`worker ${a.id} spawned`),a}},u=await Os(),d=u.workerFromBackend({backend:`sandbox`,sandboxClient:c,maxIterations:1}),f=(e,n)=>d({...e,harness:t.harness},n),p={name:`supervisor`,harness:`cli-base`,model:{default:t.model??`gemini-3.5-flash-lite`,provider:t.model?Ss(t.model):`google`},tools:{agent_runtime_coordination_spawn_worker:!0,agent_runtime_coordination_observe_agent:!0}},m={routerBaseUrl:xs,routerKey:r.apiKey},h=Es(await u.supervise(p,{goal:e},{budget:a,makeWorkerAgent:f,router:m,...o?{perWorker:o}:{},...t.model?{allowedModels:[t.model]}:{},runId:`supervise-${ue()}`})),g=h.status===`winner`?`settled`:`failed`;for(let e of s)e.status=g,n.json||l(`worker ${e.id} settled (${e.status})`);return{task:e,result:h.text,workers:s,tokenUsage:h.tokenUsage,costUsd:h.costUsd,status:h.status}}function As(){let t=new M(`supervise`);return t.description(`Run a budget-conserving supervisor that spawns isolated sandbox workers to deliver a task.`).argument(`<task>`,`What the supervisor should accomplish`).option(`--harness <name>`,`Worker harness (${bs.join(` | `)})`,`claude-code`).option(`--model <id>`,`Model for the supervisor + workers`).option(`--max-tokens <n>`,`Conserved token budget for the whole run`,`200000`).option(`--max-iterations <n>`,`Conserved iteration budget for the whole run`,`50`).option(`--max-workers <n>`,`Bound the fanout; each worker reserves floor(max-tokens / n) tokens and floor(max-iterations / n) iterations`).action(async(t,n)=>{let r=Cs({harness:n.harness,model:n.model,maxTokens:n.maxTokens,maxIterations:n.maxIterations,maxWorkers:n.maxWorkers});n.json||(l(`Supervising: ${t}`),l(`harness=${r.harness} budget=${r.maxTokens}tok/${r.maxIterations}it`),console.log());let i=await ks(t,r,{apiKey:n.apiKey,baseUrl:n.baseUrl,json:n.json});if(n.json){e(i),i.status!==`winner`&&(process.exitCode=1);return}if(console.log(),i.result&&(console.log(i.result),console.log()),s({"Input Tokens":i.tokenUsage.input??`Unavailable`,"Output Tokens":i.tokenUsage.output??`Unavailable`,Cost:i.costUsd===null?`Unavailable`:`$${i.costUsd.toFixed(4)}`}),i.status!==`winner`)throw Error(`Supervisor finished without a winner: ${i.status}`)}),t}function js(e,t){let n=Pe(e,t);return n!==`..`&&!n.startsWith(`..${Ie}`)&&!Ne(n)}const Ms=()=>import(`@tangle-network/agent-eval/campaign`),Ns=()=>import(`@tangle-network/agent-runtime/candidate-execution`),Ps=`graph-task-workspaces`,Fs=I.number().int().positive().max(2**53-1),Is=I.strictObject({maxArchiveBytes:Fs.optional(),maxEmbeddedArtifactBytes:Fs.optional(),maxFiles:Fs.optional(),maxFileBytes:Fs.optional(),maxTotalFileBytes:Fs.optional(),maxPathBytes:Fs.optional(),maxRepositoryBundleBytes:Fs.optional()}),Ls=me.shape,Rs=I.strictObject({snapshot:I.strictObject({kind:Ls.kind,digest:Ls.digest,manifest:pe,archive:pe}).superRefine((e,t)=>{(e.digest!==e.manifest.sha256||!e.manifest.byteLength||!e.archive.byteLength)&&t.addIssue({code:`custom`,message:`The canonical workspace manifest, digest and archive must agree`})}),capture:I.strictObject({mode:I.literal(`git-working-tree`),runtimeVersion:I.string().min(1),limits:Is}),gaps:I.tuple([I.literal(`environment-and-toolchain-not-snapshotted`),I.literal(`git-ignored-files-excluded`)])}),zs=e=>N(Rs.parse(e));function Bs(e){for(let t of[e.snapshot.manifest,e.snapshot.archive])if(t.locator.kind!==`private-cas`||t.locator.namespace!==Ps)throw Error(`Task workspace artifacts require their original local private CAS; cross-backend activation is unsupported`)}async function Vs(){let e=P(F(),`.tangle`);return await ct(e,{recursive:!0,mode:448}),R(e)}const Hs=async e=>(await import(`@tangle-network/agent-runtime/kernel`)).createPrivateCasArtifactPort(P(e,`artifacts`),Ps);async function Us(e){let t=await ut(Fe(e),Ce.O_RDONLY|Ce.O_NOFOLLOW);try{if(!(await t.stat()).isFile())throw Error(`Task workspace reference must be a regular file`);let e=Rs.parse(JSON.parse(await t.readFile(`utf8`)));return Bs(e),e}finally{await t.close()}}async function Ws(e,t={}){t.signal?.throwIfAborted();let n=Fe(e),r=await st(n);if(!r.isDirectory()||r.isSymbolicLink())throw Error(`Task workspace must be one real repository root`);let i=await R(n),a=await R(F()),o=await Vs();if(i===a||i===je(i)||js(o,i)||js(i,o))throw Error(`Task workspace capture cannot include the home, filesystem or private evidence root`);let{release:s}=(await Ms()).acquireSingleRunLock({lockPath:`${i}.graph-workspace.lock`});try{let e=Is.parse(t.limits??{}),n=await(await Ns()).captureAgentWorkspaceSnapshot(i,{includeRepository:!0,repositoryContents:`working-tree`,limits:e,artifactPersistence:{executionId:ue(),outputArtifacts:await Hs(o),signal:t.signal}}),r=v(`@tangle-network/agent-runtime`,import.meta.url);if(!r)throw Error(`Cannot identify the Runtime workspace archive owner`);let a=JSON.parse(await L(r,`utf8`));return Rs.parse({snapshot:n,capture:{mode:`git-working-tree`,runtimeVersion:a.version,limits:e},gaps:[`environment-and-toolchain-not-snapshotted`,`git-ignored-files-excluded`]})}finally{s()}}async function Gs(e,t){let n=I.uuid().parse(t.runId),r=Rs.parse(e);Bs(r);let i=await Vs(),a=P(i,`workspaces`);if(await ct(a,{recursive:!0,mode:448}),await R(a)!==a)throw Error(`Task workspace allocation root redirects elsewhere`);let o=P(a,n),{release:s}=(await Ms()).acquireSingleRunLock({lockPath:`${o}.lock`});try{t.signal?.throwIfAborted();let e=`${o}.task-workspace.json`,a;try{a=JSON.parse(await L(e,`utf8`))}catch(e){if(e.code!==`ENOENT`)throw e}let c=zs(r);if(a!==void 0){let e=I.strictObject({runId:I.uuid(),identity:I.string()}).parse(a);if(e.runId!==n||e.identity!==c||t.resumeCwd!==void 0&&Fe(t.resumeCwd)!==o||await R(o)!==o||!(await st(o)).isDirectory())throw Error(`The retained task workspace no longer names this exact native run allocation`)}else{if(t.resumeCwd!==void 0)throw Error(`The retained task workspace allocation receipt is missing`);await(await Ns()).materializeAgentWorkspaceSnapshot({snapshot:r.snapshot,artifacts:await Hs(i),destination:o,limits:r.capture.limits,signal:t.signal}),await z(e,JSON.stringify({runId:n,identity:c}),{flag:`wx`,mode:384,flush:!0})}if(!t.validationOnly||a!==void 0)return{cwd:o,release:s};let l=await Promise.all([st(o,{bigint:!0}),st(e,{bigint:!0})]);return{cwd:o,release:async()=>{try{for(let[t,r]of[o,e].entries()){let e=await st(r,{bigint:!0});if(!(t===0?e.isDirectory():e.isFile())||e.dev!==l[t]?.dev||e.ino!==l[t]?.ino||await R(r)!==r)throw Error(`Validation allocation ${n} changed; retained`)}if(N(JSON.parse(await L(e,`utf8`)))!==N({runId:n,identity:c}))throw Error(`Validation allocation ${n} receipt changed; retained`);try{throw await st(P(i,`runs`,n)),Error(`Validation allocation ${n} has run state; retained`)}catch(e){if(e.code!==`ENOENT`)throw e}await dt(o,{recursive:!0}),await dt(e)}finally{s()}}}}catch(e){throw s(),e}}function Ks(t){t.command(`workspace`).description(`Capture immutable local task files for graph replay`).command(`capture <repository>`).description(`Capture Git HEAD, index, tracked and unignored files into private local artifacts`).requiredOption(`--output <file>`,`New reference file outside the source repository`).option(`--limits <file>`,`JSON overrides for the maintained Runtime archive limits`).action(async(t,n)=>{let r=await R(Fe(t)),i=P(await R(je(Fe(n.output))),Ae(Fe(n.output)));if(js(r,i))throw Error(`The task reference must be written outside the original workspace`);try{throw await st(i),Error(`Task workspace reference already exists; choose a new output file`)}catch(e){if(e.code!==`ENOENT`)throw e}let a=await Ws(r,{limits:n.limits?Is.parse(JSON.parse(await L(n.limits,`utf8`))):void 0});await z(i,JSON.stringify(a),{flag:`wx`,mode:384,flush:!0}),e(a)})}const qs=I.string().regex(/^[a-f0-9]{64}$/),Js=I.strictObject({version:I.literal(1),runId:I.uuid(),file:I.string().refine(Ne),cwd:I.string().refine(Ne),sourceDigest:qs,source:I.string().optional(),graphDigest:qs,params:I.record(I.string(),I.unknown()),trigger:I.record(I.string(),I.unknown()).optional(),gateChoices:I.record(I.string(),I.string()).optional(),startedAt:I.iso.datetime(),seat:I.string().optional(),mcpPolicy:Ue.optional(),taskWorkspace:Rs.optional()});async function Ys(e){let t=await Os(),n=t.graphRegistry(P(F(),`.tangle`,`graph-registry`)),r=await t.loadGraph(n,e.graphDigest);if(!r)throw Error(`Retained execution graph is unavailable; configuration is unknown`);let i=t.validateStoredGraph(r);if(i.digest!==e.graphDigest)throw Error(`Retained execution graph changed its identity`);return N({mcpPolicy:Ue.parse(e.mcpPolicy??{}),nodes:i.nodes.map(({id:e,profile:t})=>({id:e,harness:t.harness??null,model:t.model??null,seats:t.seats??null,connections:t.connections??null}))})}function Y(e){throw new B(`GRAPH_RESUME_REFUSED`,`The graph run cannot be resumed`,e,`tangle graph run --help`)}async function Xs(e){I.uuid().safeParse(e).success||Y(`Use a recorded graph run ID`);let t;try{let n=P(await R(P(F(),`.tangle`)),`runs`,e);await R(n)!==n&&Y(`The run directory redirects elsewhere`),t=await ut(P(n,`input.json`),Ce.O_RDONLY|Ce.O_NOFOLLOW),(await t.stat()).isFile()||Y(`The run input is not a regular file`);let r=Js.parse(JSON.parse(await t.readFile(`utf8`)));return r.runId!==e&&Y(`The recorded run identity changed`),r.source!==void 0&&Qs(r,r.source),r}catch(e){if(e instanceof B)throw e;return Y(`The private recorded run input is missing or invalid`)}finally{await t?.close()}}async function Zs(e,t){let n=t.source??await L(t.file,`utf8`);Qs(t,n),await z(P(e,`input.json`),JSON.stringify({...t,source:n}),{flag:`wx`,mode:384,flush:!0})}function Qs(e,t){return ce(`sha256`).update(t).digest(`hex`)!==e.sourceDigest&&Y(`The retained graph source does not match this run`),t}async function $s(e){return Qs(e,e.source??await L(e.file,`utf8`))}function ec(e,t,n,r,i={}){e.sourceDigest!==n&&Y(`The authored graph source changed`),t.cloud&&Y(`A local run cannot move to cloud execution`),Object.entries(r).some(([t,n])=>!Object.hasOwn(e.params,t)||N(n)!==N(e.params[t]))&&Y(`A recorded graph parameter changed`),Object.entries(i).some(([t,n])=>e.gateChoices?.[t]!==n)&&Y(`A recorded gate choice changed`),t.seat!==void 0&&t.seat!==e.seat&&Y(`The recorded graph seat override changed`),t.mcpPolicy!==void 0&&(e.mcpPolicy===void 0||N(t.mcpPolicy)!==N(e.mcpPolicy))&&Y(`The recorded graph MCP policy changed`)}const tc=e=>Object.entries(e).map(([e,t])=>`${e}=${typeof t==`string`?t:JSON.stringify(t)}`),nc=`claude,codex,kimi,opencode,gemini,pi`;function rc(e,t){let n;return async(r,{node:i,lastCandidate:a})=>{t.throwIfAborted();let o;try{o=r===void 0?void 0:ye(r)}catch(e){throw e instanceof Error&&Object.assign(e,{node:i,seat:r,fixCommand:`tangle graph run --help`}),e}n??=import(`cli-bridge`).then(({listLocalModels:n,loadConfig:r})=>n({cwd:e,signal:t,config:r({...process.env,BRIDGE_BACKENDS:nc,BRIDGE_SUBSCRIPTIONS_ONLY:`1`})}));let s=await n;t.throwIfAborted();let c=e=>e.authentication?.status===`authenticated`&&e.authentication.authMode===`subscription`,l=o?.harness??s.find(e=>e.provider&&c(e))?.backend,u=s.filter(e=>e.backend===l),d=u.filter(c),f=o?u.find(e=>e.id===`${o.harness}/${o.model}`)??d.find(e=>e.provider===o.provider):d.find(e=>e.default)??d.find(e=>e.recommended)??d[0];if(!f||!c(f)){if(a===!1)return;let e=f?.authentication??u[0]?.authentication??(o?void 0:s.find(e=>e.authentication?.fix)?.authentication);throw Object.assign(new B(o?`SEAT_NOT_LOGGED_IN`:`SEAT_NONE_DETECTED`,`Node '${i}' has no available subscription${o?` for ${o.harness}`:``}`,e?`Selected provider: ${e.status} (${e.authMode})`:`No authenticated subscription route was detected`,e?.fix??`tangle graph run --help`),{node:i,seat:r})}let p=o?.harness??ye(f.id).harness,m=o?.provider??f.provider,h=o?.model??f.id.slice(p.length+1);if(!m||!h)throw new B(`MODEL_PROVIDER_MISMATCH`,`Node '${i}' has an unresolved model provider`,`Bridge has no configured provider for ${r??p}`,`tangle graph run --help`);return{harness:p,provider:m,model:h,selector:{kind:`all-eligible`},...o?.reasoningEffort===void 0?{}:{reasoningEffort:o.reasoningEffort}}}}const ic=ft(ze);function ac(e,t,n=`tangle graph run --help`){throw new B(`SEAT_NONE_DETECTED`,e,t,n)}function oc(e){let t=[];for(let n of e.nodes)for(let e of n.check?.egress??[]){let n=e.trim().toLowerCase();if(n){if(/[\s*]|\/|:\/\//u.test(n))throw new B(`GRAPH_EGRESS_HOST`,`Graph egress host "${e.trim()}" is not a DNS hostname`,`A check egress entry has whitespace, a wildcard, or a URL`,`tangle graph run --help`);t.includes(n)||t.push(n)}}return t.length>0?t.join(`,`):void 0}function sc(e){return e.some(e=>(e.profile?.seats?.length??0)>0)}function cc(e){let t=e?.trim();if(t)return/\s/u.test(t)&&ac(`A seat account, command, or credential must be a single token`,`The seat command is an executable path, not a shell line`),t}function lc(e){let t=cc(e.seatAccount),n=cc(e.seatCommand),r=cc(e.seatCredential);return r&&!n&&!t&&ac(`A seat credential needs a seat command`,`The credential is an argument to the configured command`,`tangle graph run --seat-command <program>`),{...t?{account:t}:{},...n?{command:n}:{},...r?{credential:r}:{}}}async function uc(e,t,n){if(e.account)return e.account;e.command||ac(`This graph needs a seat account or a seat command`,`No account was authored and no seat command is configured`,`tangle graph run --seat-account <account>`);let r=``;try{r=(await ic(e.command,[t,...e.credential?[e.credential]:[]],{timeout:3e4,maxBuffer:4096,signal:n,encoding:`utf8`})).stdout}catch(e){n.throwIfAborted();let t=e.code===`ENOENT`;ac(t?`The seat command was not found`:`The seat command failed`,t?`The configured executable is not on PATH`:`The seat command exited without an account id`)}let i=r.trim();return(!i||/\s/u.test(i))&&ac(`The seat command did not print an account id`,`The command must print one account id and nothing else`),i}function dc(e,t,n){let r=new Map;return async i=>{n.throwIfAborted();let a=i.stage.harness,o=i.stage.selector.kind===`seat`?i.stage.selector.id.trim():``,s=`${a}\0${t.credential??``}`,c=o||t.account||r.get(s)||await uc(t,a,n);!o&&!t.account&&r.set(s,c),(!c||/\s/u.test(c)||i.resumeSeatId!==void 0&&i.resumeSeatId!==c)&&ac(`Node '${i.nodeId}' has no seat account`,`The authored seat, account flag, or seat command did not yield one`);let{createCliBridgeProvider:l}=await import(`@tangle-network/agent-provider-cli-bridge`);return{seat:c,backend:{backend:`provider`,provider:l({baseUrl:e.bridgeUrl,bearerToken:e.bridgeBearer}),defaults:{workspace:{cwd:{base:`host`,path:e.cwd}}},runtime:`cli`,outputFormat:`json`,destroyOnSettle:!0,requireTerminalEvent:!0}}}}function X(e){return Kn({signal:e.signal,...e.apiKey===void 0?{}:{apiKey:e.apiKey},...e.baseUrl===void 0?{}:{baseUrl:e.baseUrl}})}const fc=I.object({version:I.literal(1),type:I.enum([`state`,`ack`,`error`,`event`]),requestId:I.string().optional(),operationId:I.string().optional(),command:I.string().optional(),code:I.string().optional(),message:I.string().optional(),result:I.unknown().optional()}).passthrough(),pc=I.object({state:I.object({runConfiguration:I.unknown()}),view:I.object({capabilities:I.record(I.string(),I.object({available:I.boolean(),reason:I.string().optional()}))})}),mc=I.object({status:I.enum([`completed`,`failed`,`cancelled`]),analysis:I.object({id:I.string().min(1)}).passthrough(),source:I.object({runtimeRun:I.unknown()}).passthrough()}).passthrough(),hc=`TANGLE_GRAPH_ANALYSIS_SOURCE`;async function gc(e,t,n){if(!e.startsWith(`wfrun_`)){let t=P(await R(P(F(),`.tangle`)),`runs`,e);if(await R(t)!==t)throw new B(`RUN_NOT_FOUND`,`The run directory redirects elsewhere`,`Use the recorded local run directory`,`tangle graph inspect --help`);return{source:`runtime:${e}@${t}`,env:{},schema:I.object({runId:I.literal(e),runDir:I.literal(t)})}}let r={signal:n,...t.apiKey===void 0?{}:{apiKey:t.apiKey},...t.baseUrl===void 0?{}:{baseUrl:t.baseUrl}},i=await X(r),a=I.object({id:I.literal(e),workflowId:I.string(),revUsed:I.number().int(),execution:I.object({kind:I.literal(`graph`),sourceSha:I.string(),authoredGraphDigest:I.string(),graphDigest:I.string()}),runtime:I.object({snapshot:I.object({supervisors:I.tuple([I.object({id:I.string()})])})})}).parse(await i.workflows.getRun(e,{signal:n})),o=a.runtime.snapshot.supervisors[0];if(!o)throw new B(`BRAID_RPC_FAILED`,`The cloud run has no retained Runtime root`,`Wait for execution evidence before analysis`,`tangle graph inspect ${e}`);let s=await Hn(r);if(new URL(s.baseUrl.replace(/\/+$/,``)).href!==new URL(i.baseUrl.replace(/\/+$/,``)).href)throw new B(`AUTH_REQUIRED`,`The analysis source origin changed`,`Use the same authenticated platform origin`,`tangle auth status --json`);return{source:`runtime:${e}@${hc}`,env:{[hc]:JSON.stringify({url:`${s.baseUrl.replace(/\/+$/,``)}/v1/workflows/runs/${encodeURIComponent(e)}`,headers:{Authorization:`Bearer ${s.token}`}})},schema:I.object({runId:I.literal(e),remoteEndpointEnv:I.literal(hc),checkpoint:I.object({workflowId:I.literal(a.workflowId),runtimeRunId:I.literal(o.id),revUsed:I.literal(a.revUsed),sourceSha:I.literal(a.execution.sourceSha),authoredGraphDigest:I.literal(a.execution.authoredGraphDigest),graphDigest:I.literal(a.execution.graphDigest)})})}}async function _c(e,t){if(!e.startsWith(`wfrun_`)&&!I.uuid().safeParse(e).success)throw new B(`RUN_NOT_FOUND`,`Use a recorded graph run ID`,`The run identifier is invalid`,`tangle graph inspect --help`);if(!Number.isSafeInteger(t.timeout)||t.timeout<1)throw new B(`INVALID_TIMEOUT`,`Use a positive analysis timeout`,`The timeout must be an integer number of milliseconds`,`tangle graph analyze --help`);let n=t.profile;if(!n?.trim())throw new B(`USAGE_INVALID`,`Select the canonical analysis profile`,`Graph analysis requires an existing canonical AgentProfile reference`,`tangle graph analyze `+e+` --profile <name|path>`);let r=/^(?:\.\.?)[/\\]/.test(n)?Fe(process.cwd(),n):n;return ds(t.signal,async n=>{let i=await gc(e,t,n),a=i.source;return Bl({signal:n,errorRunId:e},async n=>{let o=await n.bridge(),s=await lt(P(n.runDir,`analysis-`)),c=P(s,`config.json`),l=P(s,`database.key`),u=P(s,`state.sqlite`),d=`connection-owned-graph-bridge`,f=new Date().toISOString();await z(l,le(32),{mode:384,flag:`wx`}),await z(c,JSON.stringify({format:`braid-startup-config`,schemaVersion:2,profile:r,connectionId:d,connections:[{id:d,name:`Graph analysis`,kind:`cli-bridge`,endpoint:o.bridgeUrl,providerOptions:{transport:`local`},createdAt:f,updatedAt:f,lastHealth:{status:`unknown`}}]}),{mode:384,flag:`wx`});let p=n.signal,m=`op-${ue()}`,h=`op-${ue()}`,g=`${m}:initialize`,_=`${m}:analyze`,v=`${m}:shutdown`,y={version:1,requestId:g,command:`initialize`,params:{workspace:n.cwd,subscribe:!1}},b={version:1,requestId:_,operationId:m,command:`analyze`,params:{source:a,recipe:`all`,totalTimeoutMs:t.timeout}},x={version:1,requestId:v,operationId:h,command:`shutdown`,params:{mode:`wait`}},S,C,w,T,ee={transform:e=>{let t=fc.parse(e);return t.type===`error`||t.type===`state`&&t.requestId===g||t.type===`ack`&&[_,v].includes(t.requestId??``)?t:null},onError:e=>{T??=e},onEvent:e=>{e.type===`error`&&(T??=new B(e.code??`BRAID_RPC_FAILED`,`Braid refused graph analysis`,e.message??`The RPC response omitted its cause`,`tangle graph analyze --help`)),e.requestId===g&&e.type===`state`&&(S??=e),e.requestId===_&&e.type===`ack`&&(C??=e),e.requestId===v&&e.type===`ack`&&(w??=e)}},E=await at({command:process.env.BRAID_BIN??`braid`,args:[`rpc`,`--workspace`,n.cwd,`--config`,c,`--profile`,r,`--database-key-file`,l],cwd:n.cwd,env:{...i.env,BRAID_STATE_PATH:u,BRAID_CLI_BRIDGE_ENDPOINT:o.bridgeUrl,BRAID_CLI_BRIDGE_AUTH:o.bridgeBearer},timeoutMs:t.timeout,signal:p,ownProcessGroup:!0},ee,{stdin:[y,...t.dryRun?[]:[b],x].map(e=>JSON.stringify(e)).join(`
148
148
  `)+`
149
149
  `});if(T)throw T;let D=E.exit;if(!D.success||!S||!w||w.operationId!==h||w.command!==`shutdown`)throw new B(`BRAID_RPC_FAILED`,`Braid graph analysis did not finish`,D.spawnError??D.timeoutDiagnostic??D.stdinError??D.processGroupError??D.captureError??D.terminateError??(E.stderr||`Exit ${D.code}, signal ${D.signal}; complete shutdown acknowledgement: ${!!w}`),`npm install --global @tangle-network/braid`);let O=pc.parse(S),k=O.view.capabilities[`analysis.recipe`];if(t.dryRun)return{source:a,statePath:u,configuration:O.state.runConfiguration,capability:k};if(!C||C.operationId!==m||C.command!==`analyze`)throw Error(`Braid did not acknowledge this analysis operation`);let A=mc.parse(C.result);if(!i.schema.safeParse(A.source.runtimeRun).success)throw new B(`BRAID_RPC_FAILED`,`Braid returned analysis of another source`,`Its saved run or immutable checkpoint identity does not match this request`,`tangle graph inspect ${e}`);return{...A,statePath:u}})},`tangle graph analyze ${e}`)}function vc(t){t.command(`analyze <run>`).description(`Analyze retained graph evidence through Braid`).addHelpText(`after`,`
150
150
  Requires the Braid companion CLI: npm install --global @tangle-network/braid.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-cli",
3
- "version": "0.22.123",
3
+ "version": "0.22.124",
4
4
  "description": "CLI for Tangle Sandbox operations",
5
5
  "type": "module",
6
6
  "engines": {
@@ -61,9 +61,9 @@
61
61
  "typescript": "^6.0.3",
62
62
  "vitest": "^4.1.12",
63
63
  "@repo/shared": "0.0.0",
64
- "@tangle-network/sdk-session-persistence": "0.7.0",
64
+ "@tangle-network/runtime-contracts": "0.20.0",
65
65
  "@repo/knowledge-host": "0.0.0",
66
- "@tangle-network/runtime-contracts": "0.20.0"
66
+ "@tangle-network/sdk-session-persistence": "0.7.0"
67
67
  },
68
68
  "publishConfig": {
69
69
  "access": "public",
@@ -87,8 +87,8 @@
87
87
  "author": "Tangle Network",
88
88
  "license": "MIT",
89
89
  "tangleRelease": {
90
- "sourceSha": "278355cbc34c02c5966ceba182ee5aca65975895",
91
- "mergedAt": "2026-11-14T00:02:35-08:00"
90
+ "sourceSha": "e123558965373e5c32e25ab7c7ddc75a40046cc7",
91
+ "mergedAt": "2026-11-14T00:23:42-08:00"
92
92
  },
93
93
  "scripts": {
94
94
  "build": "tsdown",