@tangle-network/sandbox-cli 0.22.38 → 0.22.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +4 -4
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -151,7 +151,7 @@ Re-run with --json to print the full token value.`))})}function $s(){let e=new b
|
|
|
151
151
|
`});if(w)throw w;let D=E.exit;if(!D.success||!b||!S||S.operationId!==h||S.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: ${!!S}`),`npm install --global @tangle-network/braid`);let re=Ec.parse(b),ie=re.view.capabilities[`analysis.recipe`];if(t.dryRun)return{source:a,statePath:u,configuration:re.state.runConfiguration,capability:ie};if(!x||x.operationId!==m||x.command!==`analyze`)throw Error(`Braid did not acknowledge this analysis operation`);let ae=Dc.parse(x.result);if(!i.schema.safeParse(ae.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{...ae,statePath:u}})},`tangle graph analyze ${e}`)}function jc(e){e.command(`analyze <run>`).description(`Analyze retained graph evidence through Braid`).addHelpText(`after`,`
|
|
152
152
|
Requires the Braid companion CLI: npm install --global @tangle-network/braid.
|
|
153
153
|
BRAID_BIN may select its installed executable. Select an existing canonical AgentProfile with --profile. Analysis uses the owned subscription-only Bridge.
|
|
154
|
-
`).requiredOption(`--profile <name|path>`,`Use a canonical analysis AgentProfile, distinct from the Tangle account profile`).option(`--dry-run`,`Inspect Braid's selected analysis configuration without dispatch`).option(`--timeout <ms>`,`Bound the analysis process in milliseconds`,Number,3e5).action(async(e,t)=>{let n=await Ac(e,t);F(n),`status`in n&&n.status!==`completed`&&(process.exitCode=1)})}const Mc=1e3;function Nc(e,t){return[...t,e]}function Pc(e,t=`input`,n){if(n===void 0&&!e?.length)return;let r={};if(n!==void 0)try{if(r=JSON.parse(de(n,`utf8`)),!r||typeof r!=`object`||Array.isArray(r)||Object.entries(r).some(([e,t])=>!e.length||typeof t!=`string`))throw Error(`Invalid input map`)}catch{throw new B(`WORKFLOW_INPUT_FILE_INVALID`,`Could not load --input-file '${n}'`,`Expected a readable JSON object with nonempty keys and string values`,`tangle workflows run --help`)}let i=Object.entries(r);for(let n of e??[]){let e=n.indexOf(`=`);if(e<=0)throw Error(`Invalid --${t} "${n}": expected key=value (e.g. pull_request.number=123)`);i.push([n.slice(0,e),n.slice(e+1)])}return Object.fromEntries(i)}function Fc(e){P(e.map(e=>({id:e.id,status:e.status,attempts:e.attempts,created:e.createdAt,completed:e.completedAt??``})),[{key:`id`,header:`Run ID`},{key:`status`,header:`Status`},{key:`attempts`,header:`Attempts`},{key:`created`,header:`Created`},{key:`completed`,header:`Completed`}])}function Ic(e){if(z({"Run ID":e.id,Workflow:e.workflowId,Status:e.status,Error:e.error??``,Attempts:e.attempts,Created:e.createdAt,Started:e.startedAt??``,Completed:e.completedAt??``}),e.actionResults.length>0){L(`Actions`);let t=e.actionResults.some(e=>e.nodeId!==void 0||e.visit!==void 0);P(e.actionResults.map(e=>({index:e.index,...t?{node:e.nodeId??``,visit:e.visit??``}:{},kind:e.kind,status:e.status,error:e.error??``,cost:e.costUsd??``})),[{key:`index`,header:`#`},...t?[{key:`node`,header:`Node`},{key:`visit`,header:`Visit`}]:[],{key:`kind`,header:`Kind`},{key:`status`,header:`Status`},{key:`error`,header:`Error`},{key:`cost`,header:`Cost (USD)`}])}e.graph&&(L(`Graph`),z({Nodes:e.graph.nodes.length,Edges:e.graph.edges.length,"Max node visits":e.graph.maxNodeVisits}),P(e.graph.edges.map(e=>({from:e.from,to:e.to,guard:e.when===void 0?``:JSON.stringify(e.when)})),[{key:`from`,header:`From`},{key:`to`,header:`To`},{key:`guard`,header:`Guard`}])),e.edgeVerdicts&&e.edgeVerdicts.length>0&&(L(`Edge verdicts`),P(e.edgeVerdicts.flatMap(e=>Object.entries(e.verdicts).map(([t,n])=>({node:e.nodeId,edge:t,verdict:n?`taken`:`not taken`}))),[{key:`node`,header:`Node`},{key:`edge`,header:`Edge`},{key:`verdict`,header:`Verdict`}]))}function Lc(e){if(e.status===`cancelled`){L(`Cancelled run ${e.runId}.`);return}if(e.signalled){L(`Cancelling run ${e.runId} — signalled the worker; it will stop shortly.`);return}L(`Requested cancellation of run ${e.runId}, but couldn't confirm it — the run may have just finished, or it's running on another instance and will stop on its own.`)}function Rc(e){switch(e.type){case`snapshot`:L(`snapshot: ${e.run.status} (${e.run.actionResults.length} action(s))`);break;case`action.started`:console.log(`→ action[${e.index}] ${e.kind} started`);break;case`action.finished`:{let t=e.status===`succeeded`?`✓`:e.status===`skipped`?`⊘`:`✗`;console.log(`${t} action[${e.index}] ${e.kind} ${e.status}${e.error?`: ${e.error}`:``}`);break}case`iteration.started`:console.log(` · action[${e.actionIndex}] iteration ${e.iterationIndex} started`);break;case`iteration.ended`:console.log(` · action[${e.actionIndex}] iteration ${e.iterationIndex} ${e.status}`);break;case`token`:typeof e.delta==`string`&&process.stdout.write(e.delta);break;case`ping`:break;case`run.done`:console.log(`\nrun.done: ${e.status}${e.error?`: ${e.error}`:``}`);break;case`run.waiting`:console.log(`\nrun.waiting: parked on a human decision (${e.decisionId}) — resolve it to resume`);break}}function zc(e){e.command(`run`).description(`Trigger an immediate run of a workflow`).argument(`<id>`,`Workflow ID`).option(`--input-file <file>`,`Trigger inputs from a flat JSON string map; --input overrides its keys`).option(`--input <key=value>`,`Trigger input as key=value (e.g. pull_request.number=123). Repeatable.`,Nc,[]).option(`--wait`,`Wait for the run to finish and print its result`).option(`--timeout <ms>`,`With --wait, fail if the run has not finished after this many milliseconds`).option(`--poll-interval <ms>`,`With --wait, how often to poll for completion (default 2000)`).action(async(e,t)=>{let n=Pc(t.input,`input`,t.inputFile),r=t.timeout===void 0?void 0:oo(t.timeout,`--timeout`),i=t.pollInterval===void 0?void 0:oo(t.pollInterval,`--poll-interval`),a=await X(t),{runId:o}=await a.workflows.run(e,n);if(!t.wait){if(t.json)return F({runId:o});L(`Started run ${o} for workflow ${e}.`),L(`Inspect it with: tangle workflows run-detail ${e} ${o}`);return}let s=t.json?null:R(`Waiting for run ${o} to finish...`).start(),c;try{c=await a.workflows.waitForRun(e,o,{...r===void 0?{}:{timeoutMs:r},...i===void 0?{}:{pollIntervalMs:i}})}finally{s?.stop()}if(c.status===`failed`&&(process.exitCode=1),t.json)return F(c);Ic(c)}),e.command(`runs`).description(`List a workflow's run history (newest first)`).argument(`<id>`,`Workflow ID`).option(`--limit <n>`,`Runs per page (1-100)`).option(`--cursor <cursor>`,`Pagination cursor from a previous page`).option(`--all`,`Fetch every page, not just the first`).action(async(e,t)=>{let n=await X(t),r=t.limit===void 0?void 0:oo(t.limit,`--limit`);if(t.all){let i=[],a=t.cursor,o=0,s=null;for(;;){let c=await n.workflows.listRuns(e,{...r===void 0?{}:{limit:r},...a===void 0?{}:{cursor:a}});if(i.push(...c.runs),o+=1,!c.nextCursor)break;if(o>=Mc){s=c.nextCursor,t.json||L(`Stopped after ${Mc} pages (${i.length} runs); more may exist — resume with --cursor ${c.nextCursor}`);break}a=c.nextCursor}if(t.json)return F({runs:i,nextCursor:s});Fc(i);return}let i=await n.workflows.listRuns(e,{...r===void 0?{}:{limit:r},...t.cursor===void 0?{}:{cursor:t.cursor}});if(t.json)return F(i);Fc(i.runs),i.nextCursor&&L(`More runs available — next page: --cursor ${i.nextCursor}`)}),e.command(`run-detail`).description(`Show a single run's detail (per-action output and errors)`).argument(`<id>`,`Workflow ID`).argument(`<runId>`,`Run ID`).action(async(e,t,n)=>{let r=await(await X(n)).workflows.getRun(e,t);if(n.json)return F(r);Ic(r)}),e.command(`cancel`).description(`Cancel a queued or in-progress run`).argument(`<id>`,`Workflow ID`).argument(`<runId>`,`Run ID`).action(async(e,t,n)=>{let r=await(await X(n)).workflows.cancel(e,t);if(n.json)return F(r);Lc(r)}),e.command(`retry`).description(`Re-run a failed or cancelled run (a fresh run with the same trigger context)`).argument(`<id>`,`Workflow ID`).argument(`<runId>`,`Run ID of the failed/cancelled run to retry`).option(`--wait`,`Wait for the new run to finish and print its result`).option(`--timeout <ms>`,`With --wait, fail if the run has not finished after this many milliseconds`).option(`--poll-interval <ms>`,`With --wait, how often to poll for completion (default 2000)`).action(async(e,t,n)=>{let r=n.timeout===void 0?void 0:oo(n.timeout,`--timeout`),i=n.pollInterval===void 0?void 0:oo(n.pollInterval,`--poll-interval`),a=await X(n),o=await a.workflows.retryRun(e,t);if(!n.wait){if(n.json)return F(o);L(`Started run ${o.runId} (retry of ${t}).`),L(`Inspect it with: tangle workflows run-detail ${e} ${o.runId}`);return}let s=n.json?null:R(`Waiting for run ${o.runId} to finish...`).start(),c;try{c=await a.workflows.waitForRun(e,o.runId,{...r===void 0?{}:{timeoutMs:r},...i===void 0?{}:{pollIntervalMs:i}})}finally{s?.stop()}if(c.status===`failed`&&(process.exitCode=1),n.json)return F(c);Ic(c)}),e.command(`events`).description(`Tail a run's live progress events until it finishes`).argument(`<id>`,`Workflow ID`).argument(`<runId>`,`Run ID`).action(async(e,t,n)=>{let r=await X(n);for await(let i of r.workflows.watchRun(e,t))n.json?console.log(JSON.stringify(i)):Rc(i),i.type===`run.done`&&i.status===`failed`&&(process.exitCode=1)})}async function Bc(e,t,n,r){let i=await X({...n,signal:r}),a=ql(t),o=Pc(n.param,`param`),s={name:me(e).replace(/(\.graph)?\.(yaml|yml|json)$/i,``),...o?{params:o}:{},...n.seat?{seat:n.seat}:{}},c,l;if(n.resume){let e=await i.workflows.getRun(n.resume,{signal:r});e.id!==n.resume&&Y(`The cloud owner returned another run identity`);let t=e.execution;if((t?.kind!==`graph`||t.sourceSha!==a)&&Y(`The authored cloud graph source changed`),Object.entries(o??{}).some(([e,n])=>!Object.hasOwn(t.params,e)||ie(t.params[e])!==ie(n))&&Y(`A recorded cloud graph parameter changed`),n.seat!==void 0&&n.seat!==t.deploy.seat&&Y(`The recorded cloud seat override changed`),n.dryRun)return{run:e};if((e.status===`cancelled`||e.status===`failed`)&&Y(`The cloud run is terminal: ${e.status}`),e.status===`succeeded`)return e.graphResult||Y(`The settled cloud run has no retained Runtime result`),{workflowId:e.workflowId,runId:e.id,sourceDigest:a,result:e.graphResult,replayed:!0,viewerUrl:`${i.baseUrl}/app/workflows/${encodeURIComponent(e.workflowId)}/runs/${encodeURIComponent(e.id)}`};if(e.recovery?.state===`running`)return{workflowId:e.workflowId,runId:e.id,sourceDigest:a,run:e,attached:!0,viewerUrl:`${i.baseUrl}/app/workflows/${encodeURIComponent(e.workflowId)}/runs/${encodeURIComponent(e.id)}`};e.recovery?.state!==`queued`&&e.recovery?.state!==`recoverable`&&Y(`The owner has not confirmed recovery eligibility`),c=e.workflowId,l=e.revUsed??Y(`The captured cloud revision is unavailable`)}else{if(n.dryRun)return i.workflows.validate(t,{format:`graph`,deploy:s});let e=await i.workflows.create(t,{format:`graph`,deploy:s});c=e.id,l=e.headRev??Y(`The cloud workflow has no retained revision`)}r.throwIfAborted();let u=await i.workflows.run(c,void 0,{signal:r,sourceSha:a,expectedRev:l,...n.resume?{resumeRunId:n.resume}:{}});return n.resume&&u.runId!==n.resume&&Y(`The cloud owner recovered another run identity`),{...u,workflowId:c,sourceDigest:a,viewerUrl:`${i.baseUrl}/app/workflows/${encodeURIComponent(c)}/runs/${encodeURIComponent(u.runId)}`}}const Vc=[`claude-code`,`opencode`,`codex`,`kimi-code`,`prime`],Hc=process.env.TANGLE_ROUTER_URL??`https://router.tangle.tools/v1`;function Uc(e){let t=ae(e);if(t)return t;throw Error(`--model '${e}' has no provider. Pass a canonical id, for example 'google/${e}'.`)}function Wc(e){let t=e.harness??`claude-code`;if(!Vc.includes(t))throw Error(`Unknown --harness '${t}'. Supported: ${Vc.join(`, `)}.`);let n=Gc(e.maxTokens,2e5,`--max-tokens`),r=Gc(e.maxIterations,50,`--max-iterations`),i=e.maxWorkers===void 0?void 0:Gc(e.maxWorkers,0,`--max-workers`);return{harness:t,...e.model?{model:e.model}:{},maxTokens:n,maxIterations:r,...i===void 0?{}:{maxWorkers:i}}}function Gc(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 Kc(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 qc(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 Jc=null;function Yc(){return Jc??=import(`@tangle-network/agent-runtime/kernel`).catch(e=>{throw Jc=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}),Jc}async function Xc(e,t,n){let r=U({apiKey:n.apiKey,baseUrl:n.baseUrl}),i=W(r),{budget:a,perWorker:o}=Kc(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}},l=await Yc(),u=l.workerFromBackend({backend:`sandbox`,sandboxClient:c,maxIterations:1}),d=(e,n)=>u({...e,harness:t.harness},n),f={name:`supervisor`,harness:`cli-base`,model:{default:t.model??`gemini-3.5-flash-lite`,provider:t.model?Uc(t.model):`google`},tools:{agent_runtime_coordination_spawn_worker:!0,agent_runtime_coordination_observe_agent:!0}},p={routerBaseUrl:Hc,routerKey:r.apiKey},m=qc(await l.supervise(f,{goal:e},{budget:a,makeWorkerAgent:d,router:p,...o?{perWorker:o}:{},...t.model?{allowedModels:[t.model]}:{},runId:`supervise-${C()}`})),h=m.status===`winner`?`settled`:`failed`;for(let e of s)e.status=h,n.json||L(`worker ${e.id} settled (${e.status})`);return{task:e,result:m.text,workers:s,tokenUsage:m.tokenUsage,costUsd:m.costUsd,status:m.status}}function Zc(){let e=new b(`supervise`);return e.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 (${Vc.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(e,t)=>{let n=Wc({harness:t.harness,model:t.model,maxTokens:t.maxTokens,maxIterations:t.maxIterations,maxWorkers:t.maxWorkers});t.json||(L(`Supervising: ${e}`),L(`harness=${n.harness} budget=${n.maxTokens}tok/${n.maxIterations}it`),console.log());let r=await Xc(e,n,{apiKey:t.apiKey,baseUrl:t.baseUrl,json:t.json});if(t.json){F(r),r.status!==`winner`&&(process.exitCode=1);return}if(console.log(),r.result&&(console.log(r.result),console.log()),z({"Input Tokens":r.tokenUsage.input??`Unavailable`,"Output Tokens":r.tokenUsage.output??`Unavailable`,Cost:r.costUsd===null?`Unavailable`:`$${r.costUsd.toFixed(4)}`}),r.status!==`winner`)throw Error(`Supervisor finished without a winner: ${r.status}`)}),e}const Qc=Ze(Ce),$c=async(e,...t)=>(await Qc(`bash`,[`-ec`,e,`graph-improve`,...t],{maxBuffer:1<<28})).stdout,el=A(j(),`.tangle`,`graph-improve`,`v5`),tl=A(j(),`.tangle`,`workspaces`),nl=e=>({inputTokens:0,outputTokens:e,usageUnknown:!0}),rl=e=>!!e&&e.owner!==`work`&&e.code!==`budget-exhausted`;async function il(e){for(let t of[`bin`,`remotes`])await He(A(e,t));let t=`#!/bin/sh
|
|
154
|
+
`).requiredOption(`--profile <name|path>`,`Use a canonical analysis AgentProfile, distinct from the Tangle account profile`).option(`--dry-run`,`Inspect Braid's selected analysis configuration without dispatch`).option(`--timeout <ms>`,`Bound the analysis process in milliseconds`,Number,3e5).action(async(e,t)=>{let n=await Ac(e,t);F(n),`status`in n&&n.status!==`completed`&&(process.exitCode=1)})}const Mc=1e3;function Nc(e,t){return[...t,e]}function Pc(e,t=`input`,n){if(n===void 0&&!e?.length)return;let r={};if(n!==void 0)try{if(r=JSON.parse(de(n,`utf8`)),!r||typeof r!=`object`||Array.isArray(r)||Object.entries(r).some(([e,t])=>!e.length||typeof t!=`string`))throw Error(`Invalid input map`)}catch{throw new B(`WORKFLOW_INPUT_FILE_INVALID`,`Could not load --input-file '${n}'`,`Expected a readable JSON object with nonempty keys and string values`,`tangle workflows run --help`)}let i=Object.entries(r);for(let n of e??[]){let e=n.indexOf(`=`);if(e<=0)throw Error(`Invalid --${t} "${n}": expected key=value (e.g. pull_request.number=123)`);i.push([n.slice(0,e),n.slice(e+1)])}return Object.fromEntries(i)}function Fc(e){P(e.map(e=>({id:e.id,status:e.status,attempts:e.attempts,created:e.createdAt,completed:e.completedAt??``})),[{key:`id`,header:`Run ID`},{key:`status`,header:`Status`},{key:`attempts`,header:`Attempts`},{key:`created`,header:`Created`},{key:`completed`,header:`Completed`}])}function Ic(e){if(z({"Run ID":e.id,Workflow:e.workflowId,Status:e.status,Error:e.error??``,Attempts:e.attempts,Created:e.createdAt,Started:e.startedAt??``,Completed:e.completedAt??``}),e.actionResults.length>0){L(`Actions`);let t=e.actionResults.some(e=>e.nodeId!==void 0||e.visit!==void 0);P(e.actionResults.map(e=>({index:e.index,...t?{node:e.nodeId??``,visit:e.visit??``}:{},kind:e.kind,status:e.status,error:e.error??``,cost:e.costUsd??``})),[{key:`index`,header:`#`},...t?[{key:`node`,header:`Node`},{key:`visit`,header:`Visit`}]:[],{key:`kind`,header:`Kind`},{key:`status`,header:`Status`},{key:`error`,header:`Error`},{key:`cost`,header:`Cost (USD)`}])}e.graph&&(L(`Graph`),z({Nodes:e.graph.nodes.length,Edges:e.graph.edges.length,"Max node visits":e.graph.maxNodeVisits}),P(e.graph.edges.map(e=>({from:e.from,to:e.to,guard:e.when===void 0?``:JSON.stringify(e.when)})),[{key:`from`,header:`From`},{key:`to`,header:`To`},{key:`guard`,header:`Guard`}])),e.edgeVerdicts&&e.edgeVerdicts.length>0&&(L(`Edge verdicts`),P(e.edgeVerdicts.flatMap(e=>Object.entries(e.verdicts).map(([t,n])=>({node:e.nodeId,edge:t,verdict:n?`taken`:`not taken`}))),[{key:`node`,header:`Node`},{key:`edge`,header:`Edge`},{key:`verdict`,header:`Verdict`}]))}function Lc(e){if(e.status===`cancelled`){L(`Cancelled run ${e.runId}.`);return}if(e.signalled){L(`Cancelling run ${e.runId} — signalled the worker; it will stop shortly.`);return}L(`Requested cancellation of run ${e.runId}, but couldn't confirm it — the run may have just finished, or it's running on another instance and will stop on its own.`)}function Rc(e){switch(e.type){case`snapshot`:L(`snapshot: ${e.run.status} (${e.run.actionResults.length} action(s))`);break;case`action.started`:console.log(`→ action[${e.index}] ${e.kind} started`);break;case`action.finished`:{let t=e.status===`succeeded`?`✓`:e.status===`skipped`?`⊘`:`✗`;console.log(`${t} action[${e.index}] ${e.kind} ${e.status}${e.error?`: ${e.error}`:``}`);break}case`iteration.started`:console.log(` · action[${e.actionIndex}] iteration ${e.iterationIndex} started`);break;case`iteration.ended`:console.log(` · action[${e.actionIndex}] iteration ${e.iterationIndex} ${e.status}`);break;case`token`:typeof e.delta==`string`&&process.stdout.write(e.delta);break;case`ping`:break;case`run.done`:console.log(`\nrun.done: ${e.status}${e.error?`: ${e.error}`:``}`);break;case`run.waiting`:console.log(`\nrun.waiting: parked on a human decision (${e.decisionId}) — resolve it to resume`);break}}function zc(e){e.command(`run`).description(`Trigger an immediate run of a workflow`).argument(`<id>`,`Workflow ID`).option(`--input-file <file>`,`Trigger inputs from a flat JSON string map; --input overrides its keys`).option(`--input <key=value>`,`Trigger input as key=value (e.g. pull_request.number=123). Repeatable.`,Nc,[]).option(`--wait`,`Wait for the run to finish and print its result`).option(`--timeout <ms>`,`With --wait, fail if the run has not finished after this many milliseconds`).option(`--poll-interval <ms>`,`With --wait, how often to poll for completion (default 2000)`).action(async(e,t)=>{let n=Pc(t.input,`input`,t.inputFile),r=t.timeout===void 0?void 0:oo(t.timeout,`--timeout`),i=t.pollInterval===void 0?void 0:oo(t.pollInterval,`--poll-interval`),a=await X(t),{runId:o}=await a.workflows.run(e,n);if(!t.wait){if(t.json)return F({runId:o});L(`Started run ${o} for workflow ${e}.`),L(`Inspect it with: tangle workflows run-detail ${e} ${o}`);return}let s=t.json?null:R(`Waiting for run ${o} to finish...`).start(),c;try{c=await a.workflows.waitForRun(e,o,{...r===void 0?{}:{timeoutMs:r},...i===void 0?{}:{pollIntervalMs:i}})}finally{s?.stop()}if(c.status===`failed`&&(process.exitCode=1),t.json)return F(c);Ic(c)}),e.command(`runs`).description(`List a workflow's run history (newest first)`).argument(`<id>`,`Workflow ID`).option(`--limit <n>`,`Runs per page (1-100)`).option(`--cursor <cursor>`,`Pagination cursor from a previous page`).option(`--all`,`Fetch every page, not just the first`).action(async(e,t)=>{let n=await X(t),r=t.limit===void 0?void 0:oo(t.limit,`--limit`);if(t.all){let i=[],a=t.cursor,o=0,s=null;for(;;){let c=await n.workflows.listRuns(e,{...r===void 0?{}:{limit:r},...a===void 0?{}:{cursor:a}});if(i.push(...c.runs),o+=1,!c.nextCursor)break;if(o>=Mc){s=c.nextCursor,t.json||L(`Stopped after ${Mc} pages (${i.length} runs); more may exist — resume with --cursor ${c.nextCursor}`);break}a=c.nextCursor}if(t.json)return F({runs:i,nextCursor:s});Fc(i);return}let i=await n.workflows.listRuns(e,{...r===void 0?{}:{limit:r},...t.cursor===void 0?{}:{cursor:t.cursor}});if(t.json)return F(i);Fc(i.runs),i.nextCursor&&L(`More runs available — next page: --cursor ${i.nextCursor}`)}),e.command(`run-detail`).description(`Show a single run's detail (per-action output and errors)`).argument(`<id>`,`Workflow ID`).argument(`<runId>`,`Run ID`).action(async(e,t,n)=>{let r=await(await X(n)).workflows.getRun(e,t);if(n.json)return F(r);Ic(r)}),e.command(`cancel`).description(`Cancel a queued or in-progress run`).argument(`<id>`,`Workflow ID`).argument(`<runId>`,`Run ID`).action(async(e,t,n)=>{let r=await(await X(n)).workflows.cancel(e,t);if(n.json)return F(r);Lc(r)}),e.command(`retry`).description(`Re-run a failed or cancelled run (a fresh run with the same trigger context)`).argument(`<id>`,`Workflow ID`).argument(`<runId>`,`Run ID of the failed/cancelled run to retry`).option(`--wait`,`Wait for the new run to finish and print its result`).option(`--timeout <ms>`,`With --wait, fail if the run has not finished after this many milliseconds`).option(`--poll-interval <ms>`,`With --wait, how often to poll for completion (default 2000)`).action(async(e,t,n)=>{let r=n.timeout===void 0?void 0:oo(n.timeout,`--timeout`),i=n.pollInterval===void 0?void 0:oo(n.pollInterval,`--poll-interval`),a=await X(n),o=await a.workflows.retryRun(e,t);if(!n.wait){if(n.json)return F(o);L(`Started run ${o.runId} (retry of ${t}).`),L(`Inspect it with: tangle workflows run-detail ${e} ${o.runId}`);return}let s=n.json?null:R(`Waiting for run ${o.runId} to finish...`).start(),c;try{c=await a.workflows.waitForRun(e,o.runId,{...r===void 0?{}:{timeoutMs:r},...i===void 0?{}:{pollIntervalMs:i}})}finally{s?.stop()}if(c.status===`failed`&&(process.exitCode=1),n.json)return F(c);Ic(c)}),e.command(`events`).description(`Tail a run's live progress events until it finishes`).argument(`<id>`,`Workflow ID`).argument(`<runId>`,`Run ID`).action(async(e,t,n)=>{let r=await X(n);for await(let i of r.workflows.watchRun(e,t))n.json?console.log(JSON.stringify(i)):Rc(i),i.type===`run.done`&&i.status===`failed`&&(process.exitCode=1)})}async function Bc(e,t,n,r){let i=await X({...n,signal:r}),a=ql(t),o=Pc(n.param,`param`),s={name:me(e).replace(/(\.graph)?\.(yaml|yml|json)$/i,``),...o?{params:o}:{},...n.seat?{seat:n.seat}:{}},c,l;if(n.resume){let e=await i.workflows.getRun(n.resume,{signal:r});e.id!==n.resume&&Y(`The cloud owner returned another run identity`);let t=e.execution;if((t?.kind!==`graph`||t.sourceSha!==a)&&Y(`The authored cloud graph source changed`),Object.entries(o??{}).some(([e,n])=>!Object.hasOwn(t.params,e)||ie(t.params[e])!==ie(n))&&Y(`A recorded cloud graph parameter changed`),n.seat!==void 0&&n.seat!==t.deploy.seat&&Y(`The recorded cloud seat override changed`),n.dryRun)return{run:e};if((e.status===`cancelled`||e.status===`failed`)&&Y(`The cloud run is terminal: ${e.status}`),e.status===`succeeded`)return e.graphResult||Y(`The settled cloud run has no retained Runtime result`),{workflowId:e.workflowId,runId:e.id,sourceDigest:a,result:e.graphResult,replayed:!0,viewerUrl:`${i.baseUrl}/app/workflows/${encodeURIComponent(e.workflowId)}/runs/${encodeURIComponent(e.id)}`};if(e.recovery?.state===`running`)return{workflowId:e.workflowId,runId:e.id,sourceDigest:a,run:e,attached:!0,viewerUrl:`${i.baseUrl}/app/workflows/${encodeURIComponent(e.workflowId)}/runs/${encodeURIComponent(e.id)}`};e.recovery?.state!==`queued`&&e.recovery?.state!==`recoverable`&&Y(`The owner has not confirmed recovery eligibility`),c=e.workflowId,l=e.revUsed??Y(`The captured cloud revision is unavailable`)}else{if(n.dryRun)return i.workflows.validate(t,{format:`graph`,deploy:s});let e=await i.workflows.create(t,{format:`graph`,deploy:s});c=e.id,l=e.headRev??Y(`The cloud workflow has no retained revision`)}r.throwIfAborted();let u=await i.workflows.run(c,void 0,{signal:r,sourceSha:a,expectedRev:l,...n.resume?{resumeRunId:n.resume}:{}});return n.resume&&u.runId!==n.resume&&Y(`The cloud owner recovered another run identity`),{...u,workflowId:c,sourceDigest:a,viewerUrl:`${i.baseUrl}/app/workflows/${encodeURIComponent(c)}/runs/${encodeURIComponent(u.runId)}`}}const Vc=[`claude-code`,`opencode`,`codex`,`kimi-code`,`prime`],Hc=process.env.TANGLE_ROUTER_URL??`https://router.tangle.tools/v1`;function Uc(e){let t=ae(e);if(t)return t;throw Error(`--model '${e}' has no provider. Pass a canonical id, for example 'google/${e}'.`)}function Wc(e){let t=e.harness??`claude-code`;if(!Vc.includes(t))throw Error(`Unknown --harness '${t}'. Supported: ${Vc.join(`, `)}.`);let n=Gc(e.maxTokens,2e5,`--max-tokens`),r=Gc(e.maxIterations,50,`--max-iterations`),i=e.maxWorkers===void 0?void 0:Gc(e.maxWorkers,0,`--max-workers`);return{harness:t,...e.model?{model:e.model}:{},maxTokens:n,maxIterations:r,...i===void 0?{}:{maxWorkers:i}}}function Gc(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 Kc(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 qc(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 Jc=null;function Yc(){return Jc??=import(`@tangle-network/agent-runtime/kernel`).catch(e=>{throw Jc=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}),Jc}async function Xc(e,t,n){let r=U({apiKey:n.apiKey,baseUrl:n.baseUrl}),i=W(r),{budget:a,perWorker:o}=Kc(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}},l=await Yc(),u=l.workerFromBackend({backend:`sandbox`,sandboxClient:c,maxIterations:1}),d=(e,n)=>u({...e,harness:t.harness},n),f={name:`supervisor`,harness:`cli-base`,model:{default:t.model??`gemini-3.5-flash-lite`,provider:t.model?Uc(t.model):`google`},tools:{agent_runtime_coordination_spawn_worker:!0,agent_runtime_coordination_observe_agent:!0}},p={routerBaseUrl:Hc,routerKey:r.apiKey},m=qc(await l.supervise(f,{goal:e},{budget:a,makeWorkerAgent:d,router:p,...o?{perWorker:o}:{},...t.model?{allowedModels:[t.model]}:{},runId:`supervise-${C()}`})),h=m.status===`winner`?`settled`:`failed`;for(let e of s)e.status=h,n.json||L(`worker ${e.id} settled (${e.status})`);return{task:e,result:m.text,workers:s,tokenUsage:m.tokenUsage,costUsd:m.costUsd,status:m.status}}function Zc(){let e=new b(`supervise`);return e.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 (${Vc.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(e,t)=>{let n=Wc({harness:t.harness,model:t.model,maxTokens:t.maxTokens,maxIterations:t.maxIterations,maxWorkers:t.maxWorkers});t.json||(L(`Supervising: ${e}`),L(`harness=${n.harness} budget=${n.maxTokens}tok/${n.maxIterations}it`),console.log());let r=await Xc(e,n,{apiKey:t.apiKey,baseUrl:t.baseUrl,json:t.json});if(t.json){F(r),r.status!==`winner`&&(process.exitCode=1);return}if(console.log(),r.result&&(console.log(r.result),console.log()),z({"Input Tokens":r.tokenUsage.input??`Unavailable`,"Output Tokens":r.tokenUsage.output??`Unavailable`,Cost:r.costUsd===null?`Unavailable`:`$${r.costUsd.toFixed(4)}`}),r.status!==`winner`)throw Error(`Supervisor finished without a winner: ${r.status}`)}),e}const Qc=Ze(Ce),$c=async(e,...t)=>(await Qc(`bash`,[`-ec`,e,`gi`,...t],{maxBuffer:3e8})).stdout,el=A(j(),`.tangle`,`graph-improve`,`v5`),tl=A(j(),`.tangle`,`workspaces`),nl=e=>({inputTokens:0,outputTokens:e,usageUnknown:!0}),rl=e=>!!e&&e.owner!==`work`&&e.code!==`budget-exhausted`;async function il(e){let[t,n]=[A(e,`bin`),A(e,`remotes`)];for(let e of[t,n])await He(e);let r=`#!/bin/sh
|
|
155
155
|
[ "$1 $2" = "issue view" ] || { echo "gh: offline replay; only 'gh issue view <n>' answers" >&2; exit 1; }
|
|
156
156
|
shift 2; n=; repo=; prev=
|
|
157
157
|
for a; do
|
|
@@ -160,12 +160,12 @@ for a; do
|
|
|
160
160
|
prev=$a
|
|
161
161
|
done
|
|
162
162
|
exec cat "${e}/remotes/$repo.git/tangle-issue-$n.json"
|
|
163
|
-
`;for(let
|
|
164
|
-
`).map(e=>JSON.parse(e)),m=new Map(p.map(e=>[e.id,e])),h=e=>m.get(e.split(`:`).pop()??e),g=e=>`graph-improve-js::${h(e).upstream}`,_=e=>o.deterministicSplit(g(e),`agent-eval-v1`,[.32,.38]),v=(e,t)=>[`issue=https://github.com/${e.upstream}/issues/${e.issue}`,...[`deliver=branch`,`base=main`,`test=${e.test}`],`verify_image=${t}`,`agent_tools={"websearch":false,"webfetch":false}`],ee=v(p[0],`none`),y=[];for(let e of l){let t=await Ql(e,{param:ee,dryRun:!0});if(!(`graph`in t))throw Error(`${e} did not load locally`);let n=t.graph.nodes.filter(({check:e,profile:{tools:t}})=>!e&&(t?.websearch!==!1||t?.webfetch!==!1));if(n.length)throw Error(`${n.map(e=>e.id)} can use web tools; refusing`);let r=t.graph.budget?.maxTokens;if(!r)throw Error(`${e} sets no budget.maxTokens to book at`);y.push({file:e,digest:t.graph.digest,cap:r})}let te=await Ue(A(Se(),`tangle-graph-improve-`));await il(te);let b=n.dockerHost;b&&(process.env.DOCKER_HOST=`ssh://${b}`);let x=o.createHarborBenchmarkAdapter({id:`graph-improve-js`,datasetDir:t,tasks:[...m.keys()].filter(e=>_(e)===d).sort(),source:{name:`js-issues`,revision:ql(f).slice(0,12)},
|
|
163
|
+
`;for(let t of[`gh`,`gh-drew`])await Je(A(e,`bin`,t),r,{mode:493});let i=`[url "${e}/remotes/"]\n\tinsteadOf = https://github.com/\n[user]\n\tname = graph-improve\n\temail = gi@local\n`;await Je(A(e,`bin`,`gitconfig`),i);for(let e of Object.keys(process.env))/(^|_)(GH|GITHUB)\w*_(TOKEN|PAT)$|_PAT$/i.test(e)&&delete process.env[e];Object.assign(process.env,{GITHUB_TOKEN:`replay-placeholder`,GIT_CONFIG_NOSYSTEM:`1`,PATH:`${t}:${process.env.PATH}`,BRIDGE_JAIL_RO_PATHS:t,GIT_CONFIG_GLOBAL:A(t,`gitconfig`),BRIDGE_JAIL_RW_PATHS:n})}async function al(e,t,n){let{decidePairedPromotion:r,runCampaign:i,wilson:a}=await import(`@tangle-network/agent-eval`),o=await import(`@tangle-network/agent-eval/benchmarks`),{durableRunToolSpans:s,readSettleRecord:c}=await import(`@tangle-network/agent-runtime/durable`),l=[e,...n.arm],u=n.split===`test`;if(u?l.length!==2||!n.unseal:n.split!==`train`)throw Error(`--split is train, or test with one --arm and --unseal`);let d=u?`holdout`:`search`,f=await Ge(A(t,`cases.jsonl.gz`)),p=et(f).toString().trim().split(`
|
|
164
|
+
`).map(e=>JSON.parse(e)),m=new Map(p.map(e=>[e.id,e])),h=e=>m.get(e.split(`:`).pop()??e),g=e=>`graph-improve-js::${h(e).upstream}`,_=e=>o.deterministicSplit(g(e),`agent-eval-v1`,[.32,.38]),v=(e,t)=>[`issue=https://github.com/${e.upstream}/issues/${e.issue}`,...[`deliver=branch`,`base=main`,`test=${e.test}`],`verify_image=${t}`,`agent_tools={"websearch":false,"webfetch":false}`],ee=v(p[0],`none`),y=[];for(let e of l){let t=await Ql(e,{param:ee,dryRun:!0});if(!(`graph`in t))throw Error(`${e} did not load locally`);let n=t.graph.nodes.filter(({check:e,profile:{tools:t}})=>!e&&(t?.websearch!==!1||t?.webfetch!==!1));if(n.length)throw Error(`${n.map(e=>e.id)} can use web tools; refusing`);let r=t.graph.budget?.maxTokens;if(!r)throw Error(`${e} sets no budget.maxTokens to book at`);y.push({file:e,digest:t.graph.digest,cap:r})}let te=await Ue(A(Se(),`tangle-graph-improve-`));await il(te);let b=n.dockerHost;b&&(process.env.DOCKER_HOST=`ssh://${b}`);let x=o.createHarborBenchmarkAdapter({id:`graph-improve-js`,datasetDir:t,assignSplit:_,tasks:[...m.keys()].filter(e=>_(e)===d).sort(),source:{name:`js-issues`,revision:ql(f).slice(0,12)},grade:o.gradeHarborPatch({jobsDir:A(el,`jobs`)})}),S=new AbortController,ne=async(e,t,{seat:n,signal:r})=>{let i=await o.prepareCaseEnvironment(t,{host:b,signal:r}),a=A(el,`remotes`,`${t.id}.git`);await $c(`[ -d "$2/refs" ] && exit; g=$(mktemp -d); trap 'rm -rf "$g"' EXIT
|
|
165
165
|
docker run --rm --network none "$1" tar -C /app/.git -c . | tar -x -C "$g"
|
|
166
166
|
c=$(git -c user.name=graph-improve -c user.email=gi@local --git-dir "$g" commit-tree 'HEAD^{tree}' -m Base)
|
|
167
167
|
git init -q --bare -b main "$2.partial" && git --git-dir "$g" push -q "$2.partial" "$c:refs/heads/main"
|
|
168
|
-
mv "$2.partial" "$2"`,i,a);let l=h(t.id),u=A(te,`remotes`,`${l.upstream}.git`),{issueTitle:d,issueBodyClean:f}=l,p=`https://github.com/${l.upstream}/issues/${l.issue}`,m=JSON.stringify({title:d,body:f,url:p,state:`OPEN`}),g,_;try{await $c(`rm -rf "$2" && git clone -q --bare "$1" "$2" && printf %s "$4" > "$2/tangle-issue-$3.json"`,a,u,`${l.issue}`,m);try{let t={param:v(l,i),json:!0,...n&&{seat:n}},a=await Ql(e.file,t,{signal:r});g=`runId`in a?a.runId:void 0;let o=JSON.parse(`text`in a?a.text:`{}`);_=Object.values(o).find(e=>e?.json?.branch)?.json?.branch}catch(e){let n=e;if(n.code!==`GRAPH_RUN_FAILED`)throw e;if(e.runtimeFailures?.some(({failure:e})=>rl(e)))throw new tt(t.id,{cause:e});g=n.runId}let o=A(j(),`.tangle`,`runs`,`${g}`),d=(await s(o)).map(e=>e.toolName).find(e=>/web.?(search|fetch)/i.test(e));if(d)throw S.abort(Error(`Replay ${g} called ${d}: not offline`)),S.signal.reason;let f=_?await $c(`b=$(git --git-dir "$1" rev-parse main); git --git-dir "$2" diff --binary "$b" "$3"`,a,u,_):``,p=await c(o),h=p&&qc(p).tokenUsage;return{patch:f,tokens:h?.input!=null&&h.output!=null?{inputTokens:h.input??0,outputTokens:h.output??0}:nl(e.cap),...g&&{runId:g}}}finally{let e=g&&(await dc(g)).cwd;await qe(u,{recursive:!0,force:!0}),e?.startsWith(`${tl}/`)&&await qe(e,{recursive:!0})}},C=await o.benchmarkScenarios(x,[d]),w=new Set(C.slice(0,n.probe).map(e=>e.id)),T=n.reps??1,E=[...Array(T).keys()],D=[...w].flatMap(e=>E.flatMap(t=>y.map((n,r)=>`${r}|${e}:${t}`))),re=new Map,ie=new Map(D.map(e=>[e,new Promise(t=>re.set(e,t))])),ae=new Map([...w].map(e=>[e,T*y.length])),oe=y.map(async(e,r)=>{let a=`${e.digest}:${n.seat.join(`,`)}`,s=A(el,`base`,ql(`${t}:${d}:${a}`));if(d===`holdout`){await He(s,{recursive:!0});let e={at:new Date,reason:n.unseal,arms:l};await Je(A(s,`holdout-access.jsonl`),`${JSON.stringify(e)}\n`,{flag:`a`})}return i({scenarios:C,reps:T,runDir:s,resumable:!0,dispatchRef:a,cellFilter:e=>w.has(e.scenario.id),judges:[o.benchmarkJudge(x)],maxConcurrency:3,signal:S.signal,dispatchTimeoutMs:4*36e5,onCellSettled:async(e,{id:t,item:n})=>{e.cached&&re.get(`${r}|${e.cellId}`)?.(),ae.set(t,(ae.get(t)??1)-1),ae.get(t)||await o.releaseCaseEnvironment(n,{host:b})},dispatch:async(t,i)=>{let a=D.indexOf(`${r}|${i.cellId}`),o=n.seat[a%n.seat.length],s=o??`graph-default`;try{await Promise.all(D.slice(0,a).map(e=>ie.get(e)));let n=await i.cost.runPaidCall({actor:e.file,model:s,signal:i.signal,maximumCharge:{model:s,inputTokens:0,outputTokens:e.cap},execute:n=>ne(e,t.item,{seat:o,signal:n}),receipt:({tokens:e})=>({model:s,...e}),receiptFromError:()=>({model:s,...nl(e.cap)})});if(!n.succeeded)throw n.error;return n.value}finally{re.get(`${r}|${i.cellId}`)?.()}}})}),O=await Promise.all(oe);if(S.signal.aborted)throw S.signal.reason;let se=e=>e.reduce((e,t)=>e+t,0)/e.length,ce=O.map((e,t)=>{let n=e.cells.filter(e=>!e.error),r=e=>Object.values(e.judgeScores)[0]?.composite??0,i=n.filter(e=>e.rep===0),o=i.filter(e=>r(e)>=1).length,s=e.cells.filter(e=>e.error),{inputTokens:c,outputTokens:u,usageComplete:d}=e.aggregates.cost;return{graph:l[t],resolved:o,n:i.length,runDir:e.runDir,wilson95:a(o,i.length),unmeasured:s.map(e=>`${e.cellId}: ${e.error}`),tokens:c+u,usageComplete:d,rewards:Object.fromEntries(n.map(e=>[e.cellId,r(e)]))}}),le=({rewards:e},t)=>E.flatMap(n=>e[`${t}:${n}`]??[]),[ue,...de]=ce,fe=de.map((e,t)=>{let n=[...w].filter(t=>le(ue,t).length&&le(e,t).length),i=[...new Set(n.map(e=>h(e).upstream))],a=i.map(e=>n.filter(t=>h(t).upstream===e)),o=e=>a.map(t=>se(t.map(t=>se(le(e,t))))),[s,c]=[o(ue),o(e)],u=r(s,c,{continuous:!0});return{arm:l[t+1],cases:n.length,repos:i.length,rates:[se(s),se(c)],delta:u.delta,method:u.method,interval95:[u.low,u.high],sufficient:u.sufficient,decision:u.promote?`promote`:`hold`}});F({split:n.split,arms:ce,paired:fe})}function ol(e){let t=(e,t)=>[...t,e];e.command(`improve <graph> [dataset]`).description(`Measure graph arms on js-issues by offline replay`).option(`--arm <graph>`,`Another arm, interleaved; repeatable`,t,[]).option(`--split <split>`,`train, or test (needs --unseal)`,`train`).option(`--unseal <reason>`,`Read the sealed test split, logging why`).option(`--probe <n>`,`Stop after the first n cases`,Number).option(`--reps <n>`,`Reps of every case per arm (default 1)`,Number).option(`--seat <seat>`,`Replay seat; repeatable, one per replay`,t,[]).option(`--docker-host <ssh>`,`Build, verify and grade on this ssh host`).action((e,t,n)=>al(e,t??A(el,`js-issues`),n))}const sl=1e5;function Z(e){throw new B(`GRAPH_INVALID`,`Graph creation failed`,e,`tangle graph new --help`)}function cl(e){return typeof e==`string`&&/^[a-z0-9][a-z0-9-]{0,62}$/i.test(e)}const ll={maxBarren:2,failures:`verbatim`,panel:`off`,bar:`on`,profile:{id:`graph-new-v1`,opening:`The graph has not passed its outside check.`,plan:`Repair the concrete diagnostics with write_graph, run the saved file and submit the actual evidence.`,rules:`Completion requires a successful host run and unchanged YAML. Retain working graph content when blocked.`,headings:{failures:`Failures`,protected:`Passing checks`,changed:`Changes`,findings:`Findings`,bar:`Acceptance`,plan:`Next`,rules:`Rules`}}};var ul=class{owned;lastFailure;pending=Promise.resolve();revision=0;sealed=!1;constructor(e,t,n){this.directory=e,this.options=t,this.cwd=n}async digest(e=this.owned){e||Z(`No graph file was saved`);let t=await We(e.file,ce.O_RDONLY|ce.O_NOFOLLOW);try{let[n,r]=await Promise.all([t.stat(),e.handle.stat()]);return(!n.isFile()||n.dev!==r.dev||n.ino!==r.ino)&&Z(`The owned graph file was replaced`),ql(await t.readFile())}finally{await t.close()}}enqueue(e){let t=++this.revision,n=this.pending.then(()=>e(t));return this.pending=n.then(()=>void 0,()=>void 0),n}check=()=>this.enqueue(async e=>{let t=this.owned;if(!t?.result)return!1;let{digest:n,result:r}=t,i=await this.digest(t),a=this.revision===e&&this.owned===t&&t.digest===n&&t.result===r&&i===n;return a&&(this.sealed=!0),a});receipt(){this.owned?.result||Z(`No successful graph run was recorded`);let{file:e,digest:t,result:n}=this.owned;return{file:e,digest:t,result:n}}invoke(e,t){return this.sealed&&Z(`The graph is accepted; submit its recorded successful run`),this.enqueue(()=>this.write(e,t)).catch(e=>(this.lastFailure=e,{ok:!1,diagnostic:en(e)}))}async write(e,t){t.throwIfAborted(),this.lastFailure=void 0;let n=e;(!n||!cl(n.name)||typeof n.source!=`string`||typeof n.run!=`boolean`||Object.keys(n).some(e=>![`name`,`source`,`run`].includes(e)))&&Z(`Expected only name, source and boolean run`),this.options.name!==void 0&&n.name!==this.options.name&&Z(`The graph name must match --name`),this.owned&&(this.owned.result=void 0);let r=A(this.directory,`${n.name}.yaml`);if(this.owned&&this.owned.file!==r&&Z(`This invocation owns one named graph file`),!this.owned)try{this.owned={file:r,handle:await We(r,ce.O_RDWR|ce.O_CREAT|ce.O_EXCL|ce.O_NOFOLLOW,384),digest:ql(``)}}catch(e){throw e.code===`EEXIST`&&Z(`Graph already exists: ${r}; choose another --name`),e}let i=this.owned;await this.digest()!==i.digest&&Z(`The owned graph was changed`);let a=Buffer.from(n.source);for(let e=0;e<a.length;){let{bytesWritten:t}=await i.handle.write(a,e,a.length-e,e);if(!t)throw Error(`Graph file write made no progress`);e+=t}await i.handle.truncate(a.length),await i.handle.sync(),i.digest=ql(a);let o={...this.options,param:[]},s={cwd:this.cwd,signal:t,source:n.source},c=await Ql(r,{...o,dryRun:!0},{...s,connectNeeds:!0});`graph`in c||Z(`No canonical graph was returned`),c.graph.deliverable.checkRef===`command`&&Z(`Host command checks need a jailed verifier node`);let{nodes:l,edges:u,budget:d}=c.graph,f=u.reduce((e,t)=>e+(`maxTraversals`in t?(t.maxTraversals??1)-1:0),l.length),p=(f+1)*sl;if(d?.maxTokens!==void 0&&d.maxTokens<p&&Z(`budget.maxTokens ${d.maxTokens} is below ${p}: ${f} agent spawns plus one reservation at ${sl} tokens per native turn`),await this.digest()!==i.digest&&Z(`Graph changed during validation`),!n.run)return{file:r,graphDigest:c.graph.digest,validated:!0};let m=await Ql(r,o,{...s,graphDigest:c.graph.digest});return(!(`status`in m)||m.status!==`winner`||m.graphDigest!==c.graph.digest||await this.digest()!==i.digest)&&Z(`The graph must succeed with unchanged YAML`),i.result=m,this.receipt()}async close(){await this.pending,await this.owned?.handle.close()}};async function dl(e,t,n){let{runId:r,runDir:i,cwd:a,bridge:o,signal:s}=e,c=await o(),l=A(await Ke(A(j(),`.tangle`)),`graphs`);(Jl(a,l)||Jl(l,a))&&Z(`The graph store must be outside the agent workspace; choose another working directory`);try{await He(l,{mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}await Ke(l)!==l&&Z(`The graph store redirects outside its canonical location`);let u=n.seat??Gn().seat,d=await hc(a,s)(u,{node:`graph-designer`,cwd:a,signal:s,lastCandidate:!0});d||Z(`No authenticated native subscription is available`);let{graphDesignerProfile:f}=await import(`@tangle-network/agent-runtime/profiles`),{supervisePursuit:p}=await import(`@tangle-network/agent-runtime/durable`),m=f({profile:{name:`graph-designer`,harness:d.harness,model:{provider:d.provider,default:d.model,...d.reasoningEffort===void 0?{}:{reasoningEffort:d.reasoningEffort}},prompt:{instructions:[`You are the sole graph designer. Author a canonical YAML graph for the requested intent, then qualify and run it using write_graph. Its nodes are complete AgentProfiles with a real independent verifier and declarative route/data outside check. Command checks execute on the host and are refused here; put executable verification in the verifier node's normal native tools. Read the supplied skills and preserve the user's task and authority.`,`Call write_graph with name, complete YAML source and run:false to validate; repair its concrete diagnostics, then call it with the identical source and run:true. The graph schema and executor are owned by the installed loader. Supply defaults for parameters needed by the first run. Only a real successful host run of the unchanged saved file passes. Submit that evidence using submit_result; explain concrete blockers using report_blocked.`]},tools:{agent_runtime_coordination_write_graph:!0,agent_runtime_coordination_submit_result:!0,agent_runtime_coordination_read_continuation:!0,agent_runtime_coordination_report_blocked:!0}}}),h=re(m),g=new ul(l,{...n,seat:u},a),_={maxIterations:6,maxTokens:2e6,deadlineMs:9e5};try{let e=await p(m,{intent:t,name:n.name},{pursuitId:r,runId:r,runDir:i,signal:s,backend:{...c,timeoutMs:_.deadlineMs},budget:_,maxDepth:0,coordination:{authentication:!0,requestTimeoutMs:_.deadlineMs},deliverable:{describe:`The saved graph succeeds with unchanged YAML`,check:g.check,checkState:g.check},continuation:ll,resolveSupervisorTools:e=>e.runId!==r||e.nodeId!==r||e.depth!==0||e.identity.profileDigest!==h?[]:[{name:`write_graph`,description:`Save, validate and run this graph.`,inputSchema:{type:`object`,properties:{name:{type:`string`},source:{type:`string`},run:{type:`boolean`}},required:[`name`,`source`,`run`],additionalProperties:!1},handler:(t,n)=>((n.nodeId!==e.nodeId||n.ownerId!==e.ownerId||n.runId!==e.runId)&&Z(`Wrong graph tool owner`),g.invoke(t,n.signal))}]});if(e.result.kind===`no-winner`||!await g.check()){if(g.lastFailure)throw g.lastFailure;let t=e.result.kind===`no-winner`?e.result.error?.message??e.result.reason:`The graph file changed after its successful run`;throw Object.assign(new B(`GRAPH_DESIGN_FAILED`,`Graph design did not finish`,t,`tangle graph new --help`),{runId:r,node:`graph-designer`})}return g.receipt()}finally{await g.close()}}function fl(e){e.command(`new <intent>`).description(`Design, validate and run one portable graph`).option(`--seat <seat>`,`Use harness/model@effort for the designer and graph`).option(`--name <name>`,`Save this graph name`).action(async(e,t)=>{process.env.BRIDGE_JAIL_RW_PATHS?.trim()&&Z(`Remove BRIDGE_JAIL_RW_PATHS before graph new; extra native write roots cannot contain its host store`),t.name!==void 0&&!cl(t.name)&&Z(`Use letters, numbers and hyphens in --name`);let n=await Xl({},n=>dl(n,e,t));t.json?F(n):L(`Created ${n.file} · run ${n.result.runId}`)})}const pl=e=>e===void 0?[]:(Array.isArray(e)?e:[e]).map(String),ml=(e=``)=>{let t=e.replace(/\s+/g,` `).trim(),n=t.match(/^.+?[.!?](?=\s|$)/)?.[0]??t;return n.length>90?`${n.slice(0,89)}…`:n},hl=e=>e&&(e.all??[e]).map(e=>{let t=`equals`in e?`= ${JSON.stringify(e.equals)}`:`in`in e?`∈ ${JSON.stringify(e.in)}`:e.exists===!1?`absent`:`exists`;return`${e.node??``}${e.pointer||`/`} ${t}`}).join(` and `);function gl(e,t){try{let n=it(t,{uniqueKeys:!0,strict:!0}),r=[...n.errors,...n.warnings][0];if(r)throw r;let i=ge(e)===`.json`?JSON.parse(t):n.toJS();if(Array.isArray(i?.nodes)&&Array.isArray(i.edges))return i;throw Error(`A graph needs nodes and edges lists`)}catch(t){throw new B(`GRAPH_INVALID`,`Graph file ${e} cannot be read`,t.message,`tangle graph show --help`)}}function _l(e,t){let n=gl(e,t),r=e=>{let t=String(e).match(/^\$\{params\.([\w-]+)\}$/)?.[1];return t?`${n.params?.[t]?.default??`?`} (params.${t})`:e},i=n.nodes.map(e=>{if(e.check){let t=String(e.check.command??``),n=t.match(RegExp(`#\\s*${e.id}:\\s*(.+)`))?.[1],r=t.split(`
|
|
168
|
+
mv "$2.partial" "$2"`,i,a);let l=h(t.id),u=A(te,`remotes`,`${l.upstream}.git`),{issueTitle:d,issueBodyClean:f}=l,p=`https://github.com/${l.upstream}/issues/${l.issue}`,m=JSON.stringify({title:d,body:f,url:p,state:`OPEN`}),[g,_]=[];try{await $c(`rm -rf "$2" && git clone -q --bare "$1" "$2" && printf %s "$4" > "$2/tangle-issue-$3.json"`,a,u,`${l.issue}`,m);try{let t={param:v(l,i),json:!0,...n&&{seat:n}},a=await Ql(e.file,t,{signal:r});g=`runId`in a?a.runId:void 0;let o=JSON.parse(`text`in a?a.text:`{}`);_=Object.values(o).find(e=>e?.json?.branch)?.json?.branch}catch(e){let n=e;if(n.code!==`GRAPH_RUN_FAILED`)throw e;if(e.runtimeFailures?.some(({failure:e})=>rl(e)))throw new tt(t.id,{cause:e});g=n.runId}let o=A(j(),`.tangle`,`runs`,`${g}`),d=(await s(o)).map(e=>e.toolName).find(e=>/web.?(search|fetch)/i.test(e));d&&S.abort(Error(`${g} called ${d}: not offline`)),S.signal.throwIfAborted();let f=_?await $c(`b=$(git --git-dir "$1" rev-parse main); git --git-dir "$2" diff --binary "$b" "$3"`,a,u,_):``,p=await c(o),h=p&&qc(p).tokenUsage;return{patch:f,tokens:h?.input!=null&&h.output!=null?{inputTokens:h.input??0,outputTokens:h.output??0}:nl(e.cap),...g&&{runId:g}}}finally{let e=g&&(await dc(g)).cwd;await qe(u,{recursive:!0,force:!0}),e?.startsWith(`${tl}/`)&&await qe(e,{recursive:!0})}},C=await o.benchmarkScenarios(x,[d]),w=new Set(C.slice(0,n.probe).map(e=>e.id)),T=n.reps??1,E=[...Array(T).keys()],D=[...w].flatMap(e=>E.flatMap(t=>y.map((n,r)=>`${r}|${e}:${t}`))),re=new Map,ie=new Map(D.map(e=>[e,new Promise(t=>re.set(e,t))])),ae=new Map([...w].map(e=>[e,T*y.length])),oe=y.map(async(e,r)=>{let a=`${e.digest}:${n.seat.join(`,`)}`,s=A(el,`base`,ql(`${t}:${d}:${a}`));if(d===`holdout`){await He(s,{recursive:!0});let e={at:new Date,reason:n.unseal,arms:l};await Je(A(s,`holdout-access.jsonl`),`${JSON.stringify(e)}\n`,{flag:`a`})}return i({scenarios:C,reps:T,runDir:s,resumable:!0,dispatchRef:a,cellFilter:e=>w.has(e.scenario.id),judges:[o.benchmarkJudge(x)],maxConcurrency:3,signal:S.signal,dispatchTimeoutMs:4*36e5,onCellSettled:async(e,{id:t,item:n})=>{e.cached&&re.get(`${r}|${e.cellId}`)?.(),ae.set(t,(ae.get(t)??1)-1),ae.get(t)||await o.releaseCaseEnvironment(n,{host:b})},dispatch:async(t,i)=>{let a=D.indexOf(`${r}|${i.cellId}`),o=n.seat[a%n.seat.length],s=o??`graph-default`;try{await Promise.all(D.slice(0,a).map(e=>ie.get(e)));let n=await i.cost.runPaidCall({actor:e.file,model:s,signal:i.signal,maximumCharge:{model:s,inputTokens:0,outputTokens:e.cap},execute:n=>ne(e,t.item,{seat:o,signal:n}),receipt:({tokens:e})=>({model:s,...e}),receiptFromError:()=>({model:s,...nl(e.cap)})});if(!n.succeeded)throw n.error;return n.value}finally{re.get(`${r}|${i.cellId}`)?.()}}})}),O=await Promise.all(oe);if(S.signal.aborted)throw S.signal.reason;let se=e=>e.reduce((e,t)=>e+t,0)/e.length,ce=O.map((e,t)=>{let n=e.cells.filter(e=>!e.error),r=e=>Object.values(e.judgeScores)[0]?.composite??0,i=n.filter(e=>e.rep===0),o=i.filter(e=>r(e)>=1).length,s=e.cells.filter(e=>e.error),{inputTokens:c,outputTokens:u,usageComplete:d}=e.aggregates.cost;return{graph:l[t],resolved:o,n:i.length,runDir:e.runDir,wilson95:a(o,i.length),unmeasured:s.map(e=>`${e.cellId}: ${e.error}`),tokens:c+u,usageComplete:d,rewards:Object.fromEntries(n.map(e=>[e.cellId,r(e)]))}}),le=({rewards:e},t)=>E.flatMap(n=>e[`${t}:${n}`]??[]),[ue,...de]=ce,fe=de.map((e,t)=>{let n=[...w].filter(t=>le(ue,t).length&&le(e,t).length),i=[...new Set(n.map(e=>h(e).upstream))],a=i.map(e=>n.filter(t=>h(t).upstream===e)),o=e=>a.map(t=>se(t.map(t=>se(le(e,t))))),[s,c]=[o(ue),o(e)],u=r(s,c,{continuous:!0}),{n:d,minimumPairs:f,low:p,threshold:m}=u,g=u.promote?void 0:!u.sufficient&&`insufficient pairs: n ${d} < minimumPairs ${f}`||p<=m&&`interval low ${p} ≤ threshold ${m}`||u.exactTestVetoes&&`McNemar exact test vetoes`||`indeterminate interval`;return{arm:l[t+1],cases:n.length,repos:i.length,rates:[se(s),se(c)],delta:u.delta,method:u.method,interval95:[u.low,u.high],sufficient:u.sufficient,decision:u.promote?`promote`:`hold`,why:g}});F({split:n.split,arms:ce,paired:fe})}function ol(e){let t=(e,t)=>[...t,e];e.command(`improve <graph> [dataset]`).description(`Measure graph arms on js-issues by offline replay`).option(`--arm <graph>`,`Another arm, interleaved; repeatable`,t,[]).option(`--split <split>`,`train, or test (needs --unseal)`,`train`).option(`--unseal <reason>`,`Read the sealed test split, logging why`).option(`--probe <n>`,`Stop after the first n cases`,Number).option(`--reps <n>`,`Reps of every case per arm (default 1)`,Number).option(`--seat <seat>`,`Replay seat; repeatable, one per replay`,t,[]).option(`--docker-host <ssh>`,`Build, verify and grade on this ssh host`).action((e,t,n)=>al(e,t??A(el,`js-issues`),n))}const sl=1e5;function Z(e){throw new B(`GRAPH_INVALID`,`Graph creation failed`,e,`tangle graph new --help`)}function cl(e){return typeof e==`string`&&/^[a-z0-9][a-z0-9-]{0,62}$/i.test(e)}const ll={maxBarren:2,failures:`verbatim`,panel:`off`,bar:`on`,profile:{id:`graph-new-v1`,opening:`The graph has not passed its outside check.`,plan:`Repair the concrete diagnostics with write_graph, run the saved file and submit the actual evidence.`,rules:`Completion requires a successful host run and unchanged YAML. Retain working graph content when blocked.`,headings:{failures:`Failures`,protected:`Passing checks`,changed:`Changes`,findings:`Findings`,bar:`Acceptance`,plan:`Next`,rules:`Rules`}}};var ul=class{owned;lastFailure;pending=Promise.resolve();revision=0;sealed=!1;constructor(e,t,n){this.directory=e,this.options=t,this.cwd=n}async digest(e=this.owned){e||Z(`No graph file was saved`);let t=await We(e.file,ce.O_RDONLY|ce.O_NOFOLLOW);try{let[n,r]=await Promise.all([t.stat(),e.handle.stat()]);return(!n.isFile()||n.dev!==r.dev||n.ino!==r.ino)&&Z(`The owned graph file was replaced`),ql(await t.readFile())}finally{await t.close()}}enqueue(e){let t=++this.revision,n=this.pending.then(()=>e(t));return this.pending=n.then(()=>void 0,()=>void 0),n}check=()=>this.enqueue(async e=>{let t=this.owned;if(!t?.result)return!1;let{digest:n,result:r}=t,i=await this.digest(t),a=this.revision===e&&this.owned===t&&t.digest===n&&t.result===r&&i===n;return a&&(this.sealed=!0),a});receipt(){this.owned?.result||Z(`No successful graph run was recorded`);let{file:e,digest:t,result:n}=this.owned;return{file:e,digest:t,result:n}}invoke(e,t){return this.sealed&&Z(`The graph is accepted; submit its recorded successful run`),this.enqueue(()=>this.write(e,t)).catch(e=>(this.lastFailure=e,{ok:!1,diagnostic:en(e)}))}async write(e,t){t.throwIfAborted(),this.lastFailure=void 0;let n=e;(!n||!cl(n.name)||typeof n.source!=`string`||typeof n.run!=`boolean`||Object.keys(n).some(e=>![`name`,`source`,`run`].includes(e)))&&Z(`Expected only name, source and boolean run`),this.options.name!==void 0&&n.name!==this.options.name&&Z(`The graph name must match --name`),this.owned&&(this.owned.result=void 0);let r=A(this.directory,`${n.name}.yaml`);if(this.owned&&this.owned.file!==r&&Z(`This invocation owns one named graph file`),!this.owned)try{this.owned={file:r,handle:await We(r,ce.O_RDWR|ce.O_CREAT|ce.O_EXCL|ce.O_NOFOLLOW,384),digest:ql(``)}}catch(e){throw e.code===`EEXIST`&&Z(`Graph already exists: ${r}; choose another --name`),e}let i=this.owned;await this.digest()!==i.digest&&Z(`The owned graph was changed`);let a=Buffer.from(n.source);for(let e=0;e<a.length;){let{bytesWritten:t}=await i.handle.write(a,e,a.length-e,e);if(!t)throw Error(`Graph file write made no progress`);e+=t}await i.handle.truncate(a.length),await i.handle.sync(),i.digest=ql(a);let o={...this.options,param:[]},s={cwd:this.cwd,signal:t,source:n.source},c=await Ql(r,{...o,dryRun:!0},{...s,connectNeeds:!0});`graph`in c||Z(`No canonical graph was returned`),c.graph.deliverable.checkRef===`command`&&Z(`Host command checks need a jailed verifier node`);let{nodes:l,edges:u,budget:d}=c.graph,f=u.reduce((e,t)=>e+(`maxTraversals`in t?(t.maxTraversals??1)-1:0),l.length),p=(f+1)*sl;if(d?.maxTokens!==void 0&&d.maxTokens<p&&Z(`budget.maxTokens ${d.maxTokens} is below ${p}: ${f} agent spawns plus one reservation at ${sl} tokens per native turn`),await this.digest()!==i.digest&&Z(`Graph changed during validation`),!n.run)return{file:r,graphDigest:c.graph.digest,validated:!0};let m=await Ql(r,o,{...s,graphDigest:c.graph.digest});return(!(`status`in m)||m.status!==`winner`||m.graphDigest!==c.graph.digest||await this.digest()!==i.digest)&&Z(`The graph must succeed with unchanged YAML`),i.result=m,this.receipt()}async close(){await this.pending,await this.owned?.handle.close()}};async function dl(e,t,n){let{runId:r,runDir:i,cwd:a,bridge:o,signal:s}=e,c=await o(),l=A(await Ke(A(j(),`.tangle`)),`graphs`);(Jl(a,l)||Jl(l,a))&&Z(`The graph store must be outside the agent workspace; choose another working directory`);try{await He(l,{mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}await Ke(l)!==l&&Z(`The graph store redirects outside its canonical location`);let u=n.seat??Gn().seat,d=await hc(a,s)(u,{node:`graph-designer`,cwd:a,signal:s,lastCandidate:!0});d||Z(`No authenticated native subscription is available`);let{graphDesignerProfile:f}=await import(`@tangle-network/agent-runtime/profiles`),{supervisePursuit:p}=await import(`@tangle-network/agent-runtime/durable`),m=f({profile:{name:`graph-designer`,harness:d.harness,model:{provider:d.provider,default:d.model,...d.reasoningEffort===void 0?{}:{reasoningEffort:d.reasoningEffort}},prompt:{instructions:[`You are the sole graph designer. Author a canonical YAML graph for the requested intent, then qualify and run it using write_graph. Its nodes are complete AgentProfiles with a real independent verifier and declarative route/data outside check. Command checks execute on the host and are refused here; put executable verification in the verifier node's normal native tools. Read the supplied skills and preserve the user's task and authority.`,`Call write_graph with name, complete YAML source and run:false to validate; repair its concrete diagnostics, then call it with the identical source and run:true. The graph schema and executor are owned by the installed loader. Supply defaults for parameters needed by the first run. Only a real successful host run of the unchanged saved file passes. Submit that evidence using submit_result; explain concrete blockers using report_blocked.`]},tools:{agent_runtime_coordination_write_graph:!0,agent_runtime_coordination_submit_result:!0,agent_runtime_coordination_read_continuation:!0,agent_runtime_coordination_report_blocked:!0}}}),h=re(m),g=new ul(l,{...n,seat:u},a),_={maxIterations:6,maxTokens:2e6,deadlineMs:9e5};try{let e=await p(m,{intent:t,name:n.name},{pursuitId:r,runId:r,runDir:i,signal:s,backend:{...c,timeoutMs:_.deadlineMs},budget:_,maxDepth:0,coordination:{authentication:!0,requestTimeoutMs:_.deadlineMs},deliverable:{describe:`The saved graph succeeds with unchanged YAML`,check:g.check,checkState:g.check},continuation:ll,resolveSupervisorTools:e=>e.runId!==r||e.nodeId!==r||e.depth!==0||e.identity.profileDigest!==h?[]:[{name:`write_graph`,description:`Save, validate and run this graph.`,inputSchema:{type:`object`,properties:{name:{type:`string`},source:{type:`string`},run:{type:`boolean`}},required:[`name`,`source`,`run`],additionalProperties:!1},handler:(t,n)=>((n.nodeId!==e.nodeId||n.ownerId!==e.ownerId||n.runId!==e.runId)&&Z(`Wrong graph tool owner`),g.invoke(t,n.signal))}]});if(e.result.kind===`no-winner`||!await g.check()){if(g.lastFailure)throw g.lastFailure;let t=e.result.kind===`no-winner`?e.result.error?.message??e.result.reason:`The graph file changed after its successful run`;throw Object.assign(new B(`GRAPH_DESIGN_FAILED`,`Graph design did not finish`,t,`tangle graph new --help`),{runId:r,node:`graph-designer`})}return g.receipt()}finally{await g.close()}}function fl(e){e.command(`new <intent>`).description(`Design, validate and run one portable graph`).option(`--seat <seat>`,`Use harness/model@effort for the designer and graph`).option(`--name <name>`,`Save this graph name`).action(async(e,t)=>{process.env.BRIDGE_JAIL_RW_PATHS?.trim()&&Z(`Remove BRIDGE_JAIL_RW_PATHS before graph new; extra native write roots cannot contain its host store`),t.name!==void 0&&!cl(t.name)&&Z(`Use letters, numbers and hyphens in --name`);let n=await Xl({},n=>dl(n,e,t));t.json?F(n):L(`Created ${n.file} · run ${n.result.runId}`)})}const pl=e=>e===void 0?[]:(Array.isArray(e)?e:[e]).map(String),ml=(e=``)=>{let t=e.replace(/\s+/g,` `).trim(),n=t.match(/^.+?[.!?](?=\s|$)/)?.[0]??t;return n.length>90?`${n.slice(0,89)}…`:n},hl=e=>e&&(e.all??[e]).map(e=>{let t=`equals`in e?`= ${JSON.stringify(e.equals)}`:`in`in e?`∈ ${JSON.stringify(e.in)}`:e.exists===!1?`absent`:`exists`;return`${e.node??``}${e.pointer||`/`} ${t}`}).join(` and `);function gl(e,t){try{let n=it(t,{uniqueKeys:!0,strict:!0}),r=[...n.errors,...n.warnings][0];if(r)throw r;let i=ge(e)===`.json`?JSON.parse(t):n.toJS();if(Array.isArray(i?.nodes)&&Array.isArray(i.edges))return i;throw Error(`A graph needs nodes and edges lists`)}catch(t){throw new B(`GRAPH_INVALID`,`Graph file ${e} cannot be read`,t.message,`tangle graph show --help`)}}function _l(e,t){let n=gl(e,t),r=e=>{let t=String(e).match(/^\$\{params\.([\w-]+)\}$/)?.[1];return t?`${n.params?.[t]?.default??`?`} (params.${t})`:e},i=n.nodes.map(e=>{if(e.check){let t=String(e.check.command??``),n=t.match(RegExp(`#\\s*${e.id}:\\s*(.+)`))?.[1],r=t.split(`
|
|
169
169
|
`).find(e=>e.trim()&&!/^\s*#/.test(e));return{id:e.id,kind:`check`,detail:ml(n??`$ ${r}`)}}let t=[e.profile?.harness,e.profile?.model?.default],n=pl(e.seat).join(` › `)||t.filter(Boolean).join(` · `),r=ml(e.profile?.prompt?.systemPrompt),i=[n||`default seat`,r].filter(Boolean).join(`
|
|
170
170
|
`);return{id:e.id,kind:`agent`,detail:i}});for(let e of n.gates??[]){let t=pl(e.choices).join(` | `);i.push({id:e.id,kind:`gate`,detail:`${t}\n${e.question}`})}let a=pl(n.entry?.map(e=>e.node??e)),o=[];if(a.length){i.unshift({id:`start`,kind:`start`,detail:``});let e=a.length>1?`fork`:``;o.push({from:[`start`],to:a,label:e,loop:!1})}for(let e of n.edges){let t=e.to?.finish===void 0?`stop`:`finish`,a=e.to?.[t]===void 0?void 0:`${t}:${e.to[t]}`,s=a===void 0?pl(e.to??e.join):[a];a&&!i.some(e=>e.id===a)&&i.push({id:a,kind:t,detail:``});let c=pl(e.kind===`analyzes`?e.over:e.from),l=n.edges.some(t=>!e.when&&t.when&&pl(t.from).join()===c.join()),u=e.maxTraversals!==void 0,d=[hl(e.when)??(l?`otherwise`:e.kind?.replace(`routes`,``)),c.length>1&&`join`,s.length>1&&`fork`,u&&`↺ loop ≤${r(e.maxTraversals)}`];o.push({from:c,to:s,label:d.filter(Boolean).join(` · `),loop:u})}let s=n.check??{},c=[[`params`,Object.entries(n.params??{}).map(([e,t])=>`${e}${`default`in t?`=${JSON.stringify(t.default)}`:` (required)`}`).join(`, `)],[`workspace`,n.workspace],[`done when`,s.command?.command??s.command??hl(s.all||s.pointer?s:void 0)],[``,s.describe]];return{name:n.graph??e.replace(/^.*\/|(\.graph)?\.(ya?ml|json)$/g,``),describe:n.describe?.trim(),facts:c.filter(e=>e[1]),nodes:i,edges:o}}const vl={start:[`▶`,y.green],agent:[`●`,y.cyan.bold],check:[`▣`,y.yellow.bold],gate:[`◇`,y.magenta.bold],finish:[`✓`,y.green.bold],stop:[`■`,y.red.bold]};function yl(e){let t=t=>e.nodes.find(e=>e.id===t)?.kind??`agent`,n=e=>{let[n,r]=vl[t(e)];return r(`${n} ${e.replace(/^(finish|stop):/,``)}`)},r=Math.max(...e.nodes.map(e=>e.id.length))+4,i=[`${y.bold(`◆ ${e.name}`)}`,...e.describe?[` ${e.describe}`]:[],``];for(let[t,n]of e.facts)i.push(` ${y.dim(t.padEnd(10))} ${n}`);i.push(``,y.bold(`NODES`));for(let t of e.nodes.filter(e=>[`agent`,`check`,`gate`].includes(e.kind))){let[e,...a]=t.detail.split(`
|
|
171
171
|
`);i.push(` ${n(t.id)}${` `.repeat(Math.max(1,r-t.id.length))}${e}`);for(let e of a)i.push(`${` `.repeat(r+4)}${y.dim(e)}`)}i.push(``,y.bold(`FLOW`));for(let t of e.edges){let e=` ${t.from.map(n).join(y.dim(` + `))} ${y.dim(`─▶`)} ${t.to.map(n).join(y.dim(` ∥ `))}`,r=t.loop?y.magenta(t.label):y.blue(t.label);i.push(...t.label.length+Qe(e).length>100?[e,` ${r}`]:[`${e} ${r}`])}return i.join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/sandbox-cli",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.39",
|
|
4
4
|
"description": "CLI for Tangle Sandbox operations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@tangle-network/agent-core": "^1.0.3",
|
|
23
23
|
"@tangle-network/agent-eval": "1.0.29",
|
|
24
|
-
"@tangle-network/agent-interface": "^5.10.
|
|
24
|
+
"@tangle-network/agent-interface": "^5.10.21",
|
|
25
25
|
"@tangle-network/agent-provider-cli-bridge": "2.0.12",
|
|
26
26
|
"@tangle-network/agent-runtime": "^9.0.2",
|
|
27
27
|
"@tangle-network/harness-sessions": "^1.0.2",
|
|
28
|
-
"@tangle-network/hub-sdk": "1.0.
|
|
29
|
-
"@tangle-network/sandbox": "^1.0.
|
|
28
|
+
"@tangle-network/hub-sdk": "1.0.23",
|
|
29
|
+
"@tangle-network/sandbox": "^1.0.312",
|
|
30
30
|
"@tangle-network/sdk-cli-runner": "^0.3.10",
|
|
31
31
|
"chalk": "^5.6.2",
|
|
32
32
|
"cli-bridge": "https://github.com/drewstone/cli-bridge/archive/4e386c9bacba1a3d6f879fe1f9a877ea5ee74681.tar.gz",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"author": "Tangle Network",
|
|
81
81
|
"license": "MIT",
|
|
82
82
|
"tangleRelease": {
|
|
83
|
-
"sourceSha": "
|
|
84
|
-
"mergedAt": "2026-11-
|
|
83
|
+
"sourceSha": "626df9b2daf2f6ead9dbac643fa7f11cf5c052d3",
|
|
84
|
+
"mergedAt": "2026-11-08T08:44:50-08:00"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"build": "tsdown",
|