@counterfact-labs/cli 0.1.3 → 0.2.4
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/README.md +176 -42
- package/bundle/client-release.json +7 -0
- package/bundle/sealed.json +908 -0
- package/dist/adapters/anthropic.js +151 -0
- package/dist/adapters/completion.js +112 -0
- package/dist/adapters/durable-write.js +34 -0
- package/dist/adapters/files.js +144 -0
- package/dist/adapters/folder-path.js +6 -0
- package/dist/adapters/git-ignore.js +49 -0
- package/dist/adapters/git.js +44 -0
- package/dist/adapters/ignored-files.js +36 -0
- package/dist/adapters/instructions.js +35 -0
- package/dist/adapters/models.js +51 -0
- package/dist/adapters/output-paths.js +92 -0
- package/dist/adapters/prompt-cache.js +28 -0
- package/dist/adapters/public-instructions.js +36 -0
- package/dist/adapters/quality.js +6 -0
- package/dist/adapters/relay-plan.js +15 -0
- package/dist/adapters/release.js +62 -0
- package/dist/adapters/report.js +29 -0
- package/dist/adapters/repository-files.js +199 -0
- package/dist/adapters/repository-root.js +120 -0
- package/dist/adapters/results.js +9 -0
- package/dist/adapters/settings.js +26 -0
- package/dist/adapters/snapshot.js +68 -0
- package/dist/analysis-core/analysis/analysis-flags.js +1 -0
- package/dist/analysis-core/analysis/code-agents/skipped-files.js +1 -0
- package/dist/analysis-core/analysis/finding-quality/config.js +1 -0
- package/dist/analysis-core/analysis/finding-quality/policy.js +1 -0
- package/dist/analysis-core/analysis/headlines/attachment.js +1 -0
- package/dist/analysis-core/analysis/headlines/input.js +1 -0
- package/dist/analysis-core/analysis/headlines/types.js +1 -0
- package/dist/analysis-core/analysis/schemas.js +1 -0
- package/dist/analysis-core/analysis/source-notes/types.js +1 -0
- package/dist/analysis-core/chunks/2PSNOSJ2.js +1 -0
- package/dist/analysis-core/chunks/3227KXHF.js +1 -0
- package/dist/analysis-core/chunks/326F4XNG.js +1 -0
- package/dist/analysis-core/chunks/3CKW5JIF.js +1 -0
- package/dist/analysis-core/chunks/3GUKUEEJ.js +1 -0
- package/dist/analysis-core/chunks/3MTXB4MK.js +6 -0
- package/dist/analysis-core/chunks/4F6ZIHXU.js +1 -0
- package/dist/analysis-core/chunks/57M4OQJM.js +1 -0
- package/dist/analysis-core/chunks/6YCABS5T.js +1 -0
- package/dist/analysis-core/chunks/724WZMYW.js +2 -0
- package/dist/analysis-core/chunks/74FPPPIG.js +1 -0
- package/dist/analysis-core/chunks/7OYIBWX3.js +1 -0
- package/dist/analysis-core/chunks/D6AWHLRI.js +1 -0
- package/dist/analysis-core/chunks/DRGDIIFA.js +1 -0
- package/dist/analysis-core/chunks/E7TFIHC5.js +1 -0
- package/dist/analysis-core/chunks/EH3QQ3T4.js +1 -0
- package/dist/analysis-core/chunks/FSLWD2PE.js +1 -0
- package/dist/analysis-core/chunks/FTODBFQW.js +1 -0
- package/dist/analysis-core/chunks/HPIAEQHE.js +37 -0
- package/dist/analysis-core/chunks/HTLIRVP7.js +1 -0
- package/dist/analysis-core/chunks/IBCFGUHI.js +1 -0
- package/dist/analysis-core/chunks/IVDDV6CU.js +14 -0
- package/dist/analysis-core/chunks/J4AXGE5W.js +1 -0
- package/dist/analysis-core/chunks/JF4GYMOZ.js +1 -0
- package/dist/analysis-core/chunks/JKWTHRUR.js +1 -0
- package/dist/analysis-core/chunks/K5OTWBTT.js +22 -0
- package/dist/analysis-core/chunks/KU5DINLW.js +1 -0
- package/dist/analysis-core/chunks/MJGB25S5.js +1 -0
- package/dist/analysis-core/chunks/MXXNED6N.js +7 -0
- package/dist/analysis-core/chunks/NCWEOJVJ.js +6 -0
- package/dist/analysis-core/chunks/O652FQQH.js +1 -0
- package/dist/analysis-core/chunks/OFBJNHC6.js +1 -0
- package/dist/analysis-core/chunks/PYKAERZZ.js +1 -0
- package/dist/analysis-core/chunks/QDYMR6KS.js +1 -0
- package/dist/analysis-core/chunks/QMIXCT62.js +1 -0
- package/dist/analysis-core/chunks/QV2EOS7U.js +1 -0
- package/dist/analysis-core/chunks/SL27GMEN.js +1 -0
- package/dist/analysis-core/chunks/STZOC7LN.js +1 -0
- package/dist/analysis-core/chunks/T2SAP7OV.js +60 -0
- package/dist/analysis-core/chunks/T5TREZCQ.js +1 -0
- package/dist/analysis-core/chunks/T66VDFXF.js +1 -0
- package/dist/analysis-core/chunks/TDNTU4TF.js +1 -0
- package/dist/analysis-core/chunks/U5HOEVPE.js +1 -0
- package/dist/analysis-core/chunks/UEWL3GMQ.js +1 -0
- package/dist/analysis-core/chunks/V7BFUTM7.js +1 -0
- package/dist/analysis-core/chunks/VGYWI4X2.js +1 -0
- package/dist/analysis-core/chunks/Y7JGSUOA.js +1 -0
- package/dist/analysis-core/chunks/ZAA44GPI.js +1 -0
- package/dist/analysis-core/contracts/requests.js +1 -0
- package/dist/analysis-core/conventions/analysis-fit.js +1 -0
- package/dist/analysis-core/conventions/file-admission.js +1 -0
- package/dist/analysis-core/data/finding-types.js +1 -0
- package/dist/analysis-core/errors.js +1 -0
- package/dist/analysis-core/findings/presentation.js +1 -0
- package/dist/analysis-core/github/repo-key.js +1 -0
- package/dist/analysis-core/import/outside-loader-sources.js +1 -0
- package/dist/analysis-core/index.js +6 -0
- package/dist/analysis-core/llm/cache-policy.js +1 -0
- package/dist/analysis-core/llm/cost.js +1 -0
- package/dist/analysis-core/llm/execution.js +1 -0
- package/dist/analysis-core/llm/output-limit.js +1 -0
- package/dist/analysis-core/llm/slots.js +1 -0
- package/dist/analysis-core/llm/stable-json.js +1 -0
- package/dist/analysis-core/llm/structured-output-error.js +1 -0
- package/dist/analysis-core/map-limit.js +1 -0
- package/dist/analysis-core/requests/answer-formats.js +1 -0
- package/dist/analysis-core/requests/check-diagnostics.js +1 -0
- package/dist/analysis-core/requests/headline-request.js +1 -0
- package/dist/analysis-core/requests/instruction-text.js +1 -0
- package/dist/analysis-core/requests/local-plan.js +1 -0
- package/dist/analysis-core/requests/registry.js +1 -0
- package/dist/analysis-core/requests/schema-descriptions.js +1 -0
- package/dist/analysis-core/requests/shape-finding-input.js +1 -0
- package/dist/analysis-core/requests/template-version.js +1 -0
- package/dist/analysis-core/requests/tools.js +1 -0
- package/dist/analysis-core/settings.js +1 -0
- package/dist/bundle/seal/deserialise.js +75 -0
- package/dist/bundle/seal/encryption.js +25 -0
- package/dist/bundle/seal/metadata.js +69 -0
- package/dist/bundle/seal/open.js +38 -0
- package/dist/bundle/seal/planned-calls.js +20 -0
- package/dist/bundle/seal/signature.js +51 -0
- package/dist/cli/agent-folder.js +17 -0
- package/dist/cli/api-types.js +2 -0
- package/dist/cli/api.js +1 -0
- package/dist/{claude-code-permission.js → cli/claude-code-permission.js} +4 -3
- package/dist/cli/commands/analyze.js +75 -0
- package/dist/cli/commands/login.js +51 -0
- package/dist/cli/completion-recovery.js +18 -0
- package/dist/{context.js → cli/context.js} +8 -14
- package/dist/cli/development-relay.js +34 -0
- package/dist/cli/email-sign-in.js +56 -0
- package/dist/{git.js → cli/git.js} +12 -8
- package/dist/cli/intake-payload.js +18 -0
- package/dist/{main.js → cli/main.js} +23 -12
- package/dist/{mcp.js → cli/mcp.js} +109 -40
- package/dist/cli/output.js +10 -0
- package/dist/cli/relay-check.js +239 -0
- package/dist/cli/relay-preparation.js +33 -0
- package/dist/cli/sign-in-input.js +97 -0
- package/dist/{sign-in.js → cli/sign-in.js} +2 -1
- package/dist/cli/suggested-email.js +10 -0
- package/dist/cli/summary.js +30 -0
- package/dist/contract/cli-api-messages.js +5 -0
- package/dist/contract/cli-refusals.js +24 -0
- package/dist/contract/cli-version.js +1 -0
- package/dist/contract/console-url.js +8 -0
- package/dist/contract/console.js +131 -0
- package/dist/contract/email-sign-in-messages.js +18 -0
- package/dist/contract/messages.js +252 -0
- package/dist/contract/release-key.js +2 -0
- package/dist/contract/runtime-environment.js +37 -0
- package/dist/core/analysis/finding-quality/config.js +4 -0
- package/dist/core/analysis/run-to-end.js +55 -0
- package/dist/core/analysis/structural-run.js +16 -0
- package/dist/gatekeeper/attestation.js +67 -0
- package/dist/gatekeeper/certificate-algorithms.js +18 -0
- package/dist/gatekeeper/certificate-path.js +99 -0
- package/dist/gatekeeper/cli-api.js +174 -0
- package/dist/gatekeeper/client.js +76 -0
- package/dist/gatekeeper/connection-exchange.js +61 -0
- package/dist/gatekeeper/connection.js +140 -0
- package/dist/gatekeeper/console.js +175 -0
- package/dist/gatekeeper/loopback.js +5 -0
- package/dist/gatekeeper/model.js +70 -0
- package/dist/gatekeeper/production-attestation.js +149 -0
- package/dist/gatekeeper/trust/hardware.js +21 -0
- package/dist/gatekeeper/trust/policy.js +42 -0
- package/dist/gatekeeper/trust/production.json +25 -0
- package/dist/setup-pings/client.js +31 -0
- package/dist/setup-pings/contract.js +2 -0
- package/dist/setup-pings/policy.js +3 -0
- package/dist/setup-pings/state.js +261 -0
- package/dist/setup-pings/worker.js +95 -0
- package/dist/transport/base64url.js +9 -0
- package/dist/transport/http-response.js +89 -0
- package/dist/transport/tls-exporter.js +5 -0
- package/package.json +57 -11
- package/LICENSE +0 -1
- package/dist/api-types.js +0 -2
- package/dist/api.js +0 -97
- package/dist/commands/check.js +0 -104
- package/dist/commands/login.js +0 -9
- package/dist/files.js +0 -99
- package/dist/gitignore.js +0 -70
- package/dist/output.js +0 -23
- package/dist/secret-files.js +0 -5
- /package/dist/{browser.js → cli/browser.js} +0 -0
- /package/dist/{commands → cli/commands}/balance.js +0 -0
- /package/dist/{commands → cli/commands}/finding.js +0 -0
- /package/dist/{commands → cli/commands}/logout.js +0 -0
- /package/dist/{credentials.js → cli/credentials.js} +0 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{$ as Ar,A as Fr,B as Rr,C as he,D as q,E as At,F as _t,G as ge,H as Mt,I as ke,J as Bt,K as Ce,L as Tt,M as It,N as Lt,O as Nt,P as jt,Q as Kt,R as Ht,S as vr,T as Dt,U as zt,V as Ut,W as qt,Y as Or,_ as Cr,a as wt,b as Y,ba as _r,c as St,d as fe,da as Mr,e as U,f as Pt,g as Q,h as bt,i as V,j as Z,k as ee,l as yt,m as Et,n as xt,o as te,p as Ft,q as Rt,r as vt,s as me,t as Ot,u as ue,v as Ct,w as ve,x as Oe,y as Er,z as xr}from"./chunks/T2SAP7OV.js";import{a as J}from"./chunks/QMIXCT62.js";import"./chunks/T66VDFXF.js";import"./chunks/J4AXGE5W.js";import{a as Pr,d as kt,k as br,l as yr}from"./chunks/IVDDV6CU.js";import"./chunks/Y7JGSUOA.js";import"./chunks/3MTXB4MK.js";import{i as gt}from"./chunks/TDNTU4TF.js";import"./chunks/HTLIRVP7.js";import{a as D}from"./chunks/QDYMR6KS.js";import{b as Sr}from"./chunks/E7TFIHC5.js";import{a as ht}from"./chunks/D6AWHLRI.js";import{C as wr,d as pe,e as pt,f as ft,t as ut}from"./chunks/K5OTWBTT.js";import{a as L}from"./chunks/326F4XNG.js";import{a as Re,b as mt,d as kr}from"./chunks/V7BFUTM7.js";import"./chunks/4F6ZIHXU.js";import"./chunks/VGYWI4X2.js";import"./chunks/PYKAERZZ.js";import{a as lt,b as mr,c as ur,d as hr,e as gr}from"./chunks/QV2EOS7U.js";import{a as nt,d as at,g as it,h as ct,i as dt,o as le}from"./chunks/7OYIBWX3.js";import{h as X}from"./chunks/NCWEOJVJ.js";import{b as B,c as ae}from"./chunks/2PSNOSJ2.js";import{b as He,c as De,k as st,o as Fe,q as fr}from"./chunks/DRGDIIFA.js";import"./chunks/6YCABS5T.js";import"./chunks/SL27GMEN.js";import"./chunks/3CKW5JIF.js";import"./chunks/STZOC7LN.js";import{c as _}from"./chunks/MJGB25S5.js";import"./chunks/UEWL3GMQ.js";import{a as Le,c as se}from"./chunks/OFBJNHC6.js";import"./chunks/MXXNED6N.js";import"./chunks/U5HOEVPE.js";import"./chunks/FTODBFQW.js";import"./chunks/ZAA44GPI.js";import{a as M,b as Ke}from"./chunks/3227KXHF.js";import"./chunks/O652FQQH.js";import"./chunks/57M4OQJM.js";import"./chunks/IBCFGUHI.js";import"./chunks/KU5DINLW.js";import{G as I,H as Ge,I as de,Ja as Ve,L as We,M as Xe,e as Ee,eb as Ze,fa as F,ia as Je,ib as et,ka as z,la as H,ma as Ye,mb as tt,o as v,p as Ue,r as qe,u as $e,ub as rt,v as xe,ya as Qe,zb as ot}from"./chunks/HPIAEQHE.js";import"./chunks/74FPPPIG.js";import"./chunks/EH3QQ3T4.js";import{f as K,i as ie,j as Ne,m as je,n as ce}from"./chunks/JKWTHRUR.js";import"./chunks/FSLWD2PE.js";import"./chunks/JF4GYMOZ.js";import{a as pr,b as ye}from"./chunks/3GUKUEEJ.js";import{a as ze,c as C,e as W}from"./chunks/T5TREZCQ.js";import{b as ne}from"./chunks/724WZMYW.js";function $(r,e,o,s){let t=new Set(o.map(c=>C(c.path,s))),n=r.CF_READING_NOTE_AGENT_ONLY!=="0"&&nt(r),l=new Set(e.agents),u=c=>!t.has(c)&&(!n||l.has(c)),g=e.instruction.filter(u),h=e.code.filter(u),p=e.agents.filter(c=>!t.has(c)),f=new Set(ct(p)),w=[...g,...h].every(c=>f.has(c)),b=g.length,i=h.length,m=[!w&&b>0&&`${b} instruction file${b===1?"":"s"} left out by the ${Math.round(v.sourceFetch.instructionBytes/1e3)}KB instruction budget`,!w&&i>0&&`${i} analyzable file${i===1?"":"s"} left out by the ${Math.round(v.sourceFetch.codeBytes/1e3)}KB/${v.sourceFetch.codeFiles}-file code budget \u2014 the analysis reads the most agent-shaped files first`,dt(p,n)].filter(Boolean),a=o.filter(c=>c.readBytes!==void 0).map(c=>C(c.path,s));return a.length&&m.push(`${a.join(", ")}: only the first ${v.sourceFetch.codeFileBytes/1e3} KB was read`),m.length?m.map((c,d)=>d<m.length-1?String(c).replace(/\.$/,""):c).join("; "):void 0}function we(r,e,o){let{descriptions:s,priority:t,declarations:n}=lt(r,e,{root:o}),l=[],u=s.flatMap(d=>d.admission.admitted?[{entry:d.readEntry,rel:d.rel,score:d.score,size:d.readEntry.size,pool:d.pool,...d.tier===void 0?{}:{tier:d.tier}}]:(l.push({path:d.entry.path,reason:d.admission.reason}),[])),g=u.filter(({score:d})=>d===0).sort(le),h=u.filter(({score:d})=>d>0).sort(le),p=[],f={instruction:0,code:0},w={instruction:[],code:[]},b=0,i=(t.enabled?[...u].sort(le):[...g,...h]).sort((d,k)=>Number(n.has(k.entry.path))-Number(n.has(d.entry.path)));for(let{entry:d,rel:k,pool:P}of i){let y=P==="instruction"?v.sourceFetch.instructionBytes:v.sourceFetch.codeBytes;if(f[P]+d.size>y||P==="code"&&b>=v.sourceFetch.codeFiles){w[P].push(k),l.push({path:d.path,reason:f[P]+d.size>y?"total":"allowance"});continue}p.push(d),f[P]+=d.size,P==="code"&&(b+=1)}let m=it(t,l.flatMap(d=>{let k=C(d.path,o);return k===null?[]:[{...d,path:k}]})),a={...w,agents:m},c=$(r,a,p,o);return{selected:p,totalBytes:f.instruction+f.code,refused:l,...c?{skippedNote:c}:{},...t.enabled&&c?{readingNotes:a}:{}}}var $t=(r,e)=>{let{markerToRead:o}=fe(e.settings,{paths:r.map(({path:s})=>s),root:e.dir??void 0,scanFlag:e.flags.scan,marker:null});return o?{strength:"partial",wants:[o]}:null};function Gt(r,e,o="bare"){let{scan:s}=fe(e.settings,{paths:r.map(({path:t})=>t),root:e.dir??void 0,scanFlag:e.flags.scan,marker:o});return s?{strength:"partial",wants:[]}:null}var Br=2e3;function Wt(r,e,o,s={}){let t=e.filter(S=>C(S.path,o)!=null),n={},l=[],u=new Map,g=s.mode!=="core"&&Qe(r),h=X(r,t.map(S=>S.path),o,{mode:g?"all":"core"}),p=new Set([...h.ignoredPaths,...h.ignoredImportPaths]),f=new Map(h.files.filter(S=>S.role!=="reference").map(S=>[S.path,S])),w=new Map(h.scopes.map(S=>[S.key,v.conventionImport.totalBytes])),b=v.conventionImport.skillBytes,i=Ee(r)?v.codeAgent.importBytes:1/0,m=0,a=S=>C(S.path,h.ownerOf(S.path).folder)??S.path,c=(S,E)=>{u.set(S.path,{path:S.path,reason:E})},d=(S,E)=>{let x=F(r,S,{purpose:E,route:"github",root:o});return x.admitted?!0:(c(S,x.reason),!1)},k=S=>{if(n[S.path])return;let E=g&&f.get(S.path)?.role==="skill"?"skill":"core",x=h.ownerOf(S.path),A=E==="skill"?b:w.get(x.key),T=S.size??0;if(E==="skill"&&m>=v.conventionImport.skillFiles){c(S,"allowance");return}if(T>A||T>i){c(S,"total");return}n[S.path]=S.ref,l.push(S.path),i-=T,E==="skill"?(b-=T,m++):w.set(x.key,A-T)},P=t.filter(S=>f.has(S.path));for(let S of P)d(S,We(f.get(S.path).role))&&k(S);let y=0;if(pe(r))for(let S of pt(new Set(t.map(E=>E.path)))){let E=t.find(x=>x.path===S);if(y>=v.conventionImport.extractionFiles){c(E,"allowance");continue}if(d(E,"source")&&d(E,"definition")){let x=l.length;k(E),l.length>x&&y++}}let R=h.needsExtraction;if(R){let S=t.flatMap(x=>{if(p.has(x.path)||n[x.path]||g&&$e(a(x)))return[];if(!d(x,"extraction"))return[];let A=Ye(a(x));return A===null?[]:[{entry:x,rank:A}]}).sort((x,A)=>x.rank-A.rank||(x.entry.size??0)-(A.entry.size??0)),E=y;for(let{entry:x}of S){if(E>=v.conventionImport.extractionFiles){c(x,"allowance");continue}let A=l.length;k(x),l.length>A&&E++}}if(g&&s.files){let S=Ae(r,{entries:e,selected:t.filter(E=>Object.hasOwn(n,E.path)),files:s.files,root:o});for(let E of S.paths)Object.hasOwn(n,E)||(l.push(E),n[E]=t.find(x=>x.path===E).ref);for(let E of S.refused)u.set(E.path,E)}return{...Ee(r)&&P.some(S=>!Object.hasOwn(n,S.path))?{definitionsOmitted:!0}:{},selectedPaths:l,shaByPath:n,treeListing:t.slice(0,Br).map(S=>S.path),needsExtraction:R,refused:[...u.values()]}}function Ae(r,e){let o=new Set(e.selected.map(n=>n.path)),s=X(r,e.entries.map(n=>n.path),e.root).files.filter(n=>n.role==="skill"&&o.has(n.path)).map(n=>n.path),t=ft(r,{skillPaths:s,paths:e.entries.map(n=>n.path),files:e.files,sizes:new Map(e.entries.map(n=>[n.path,n.size])),selected:e.selected,root:e.root,admission:e.admission,referencePaths:e.referencePaths});return{paths:[...new Set(t?.flatMap(n=>n.files.map(l=>l.path))??[])],refused:t?.flatMap(n=>n.refused)??[]}}var Xt=(r,e)=>{let o=Wt(e.settings,r,e.dir??void 0,{mode:e.mode});return{strength:"partial",wants:o.selectedPaths,state:{needsExtraction:o.needsExtraction,treeListing:o.treeListing,shaByPath:o.shaByPath,refused:o.refused,...o.definitionsOmitted?{definitionsOmitted:!0}:{}}}};var Jt=["marker","code-scan","conventions"];var Tr={marker:$t,"code-scan":Gt,conventions:Xt};function Se(r,e,o,s,t=Tr){let n={...o,settings:r},l={readers:[]};for(let u of Jt)if(!(s&&!s.includes(u)))try{let g=t[u]?.(e,n);g&&l.readers.push({id:u,claim:g,done:!1})}catch{}return l}function Ir(r){return{readers:r.readers.map(({id:e,done:o})=>({id:e,done:o}))}}function _e(r){let e=r.readers.find(({id:o})=>o==="conventions").claim;return{selectedPaths:e.wants,...e.state}}function Me(r,e){let o={dir:e.root??null,mode:e.profile==="hosted-import"?e.mode??"all":"all",flags:e.profile==="hosted-import"?e.flags??ee(r):ee(r)};if(e.profile==="hosted-import"){let n=Se(r,e.listing,o);return{profile:e.profile,...n,selection:_e(n)}}let s=e.listing.filter(n=>F(r,n,{purpose:"pointer",route:"github",root:e.root}).admitted),t=Se(r,s,o,["marker","code-scan"]);return{profile:e.profile,...t,listing:s,selection:e.selection??we(r,e.listing,e.root),context:o}}var G=20;function re(r,e,o,s){e.requestedPaths.push(...o);let t=ue(r,e.selected,o,s);e.selected=t.selected,e.refused.push(...t.refused)}function Pe(r,e,o){let s=r.hosted;if(!s)return;let t=new Set(e),n=r.selected.filter(l=>t.has(l.path));o==="code"?s.codePaths&&(s.codePaths=[...new Set([...s.codePaths,...n.map(l=>l.path)])]):s.weakCodeFallback&&(r.conventionPaths=[...new Set([...r.conventionPaths,...n.map(l=>l.path)])],s.fallback={...s.fallback,selectedPaths:[...new Set([...s.fallback.selectedPaths,...n.map(l=>l.path)])],shaByPath:{...s.fallback.shaByPath,...Object.fromEntries(n.map(l=>[l.path,l.ref]))}})}function be(r,e){let o=new Set(r.conventionPaths);if(r.decision.kind==="settled"&&r.decision.scanPaths&&r.markerKind&&r.markerKind!=="bare")for(let t of r.selected)o.add(t.path);let s=new Map(e.map(t=>[t.path,t]));for(let t of r.selected)o.has(t.path)&&!s.has(t.path)&&s.set(t.path,t);r.selected=[...s.values()],r.cursor=0,r.hosted&&(r.hosted.codeMode=!0,r.hosted.needsExtraction=!1)}function Yt(r,e=Pt(r.ranked,r.scan)){return e.agents.length>0}function Qt(r,e){if(r.hosted&&(r.hosted.codePaths=e.map(s=>s.path)),!r.hosted?.weakCodeFallback||r.hosted.codeMode||Yt(r)){be(r,e);return}let o=new Map(r.selected.map(s=>[s.path,s]));for(let s of e)o.has(s.path)||o.set(s.path,s);r.selected=[...o.values()],r.cursor=0}function Vt(r,e){let o=r.hosted;if(!o?.weakCodeFallback||!o.codePaths||r.markerKind&&r.markerKind!=="bare")return;let s=new Map([...r.entries,...r.selected].map(n=>[n.path,n]));Yt(r,e)?be(r,o.codePaths.map(n=>s.get(n))):(r.selected=o.fallback.selectedPaths.map(n=>s.get(n)),r.cursor=0,o.codeMode=!1,o.needsExtraction=o.fallback.needsExtraction);let t=new Set(r.selected.map(n=>n.path));r.files=Object.fromEntries(Object.entries(r.files).filter(([n])=>t.has(n)))}function Be(r,e){if(!I(r))return;let o=new Set(e.entries.map(n=>n.path)),s=Object.fromEntries(Object.entries(e.files).filter(([n])=>e.selected.some(l=>l.path===n&&l.readBytes===void 0))),t=new Set(de(r,[...o],s));for(let[n,l]of Object.entries(e.files)){let u=F(r,{path:n,text:l},{...e.admission,purpose:"override",route:"github",root:e.root,listing:o,managedFiles:e.files});(!u.admitted||t.has(n))&&(delete e.files[n],e.refused.push({path:n,reason:u.admitted?"unreadable":u.reason}))}}function N(r,e,o){Be(r,e);let s=e.selected.filter(u=>e.files[u.path]!==void 0),t=new Set(s.filter(u=>u.readBytes===void 0).map(u=>u.path)),n=new Set(e.requestedPaths),l=B(e.selectionRefused.filter(u=>!n.has(u.path)),e.refused).filter(u=>!t.has(u.path));return{state:e,requestedReads:o,files:e.files,settled:s,refused:l,treeTruncated:e.treeTruncated}}async function Zt(r,e,o){e.manifestReadPaths??=e.selected.slice(0,e.cursor).filter(a=>a.readBytes===void 0).map(a=>a.path);let s=new Set(e.selected.filter(a=>a.readBytes===void 0).map(a=>a.path)),t=Object.fromEntries(Object.entries(e.files).filter(([a])=>s.has(a))),n=new Map(e.entries.map(a=>[a.path,a.size])),l=new Map(Object.entries(e.files).map(([a,c])=>[a,Buffer.byteLength(c)]));for(let[a,c]of Object.entries(t))n.set(a,Buffer.byteLength(c));let u=Y(r,e.ranked,n,l,{files:t,root:e.root}),g=new Set(e.manifestReadPaths),h=u.paths.filter(a=>t[a]===void 0&&!g.has(a)),p=new Map(e.selected.filter(a=>a.readBytes!==void 0).map(a=>[a.path,a]));e.requestedPaths.push(...h.filter(a=>p.has(a))),re(r,e,h.filter(a=>!p.has(a)),e.entries);let f=new Set(h),w=new Map(e.entries.map(a=>[a.path,a])),b=e.selected.filter(a=>f.has(a.path)).map(a=>p.has(a.path)?w.get(a.path):a).slice(0,G);if(b.length){let a=await L(b,4,async y=>{let R=F(r,y,{...e.admission,purpose:"pointer",route:"github",root:e.root});return R.admitted?o(y):(e.refused.push({path:y.path,reason:R.reason}),null)});e.manifestReadPaths=[...e.manifestReadPaths,...b.map(y=>y.path)];let c=new Map(n);b.forEach((y,R)=>{a[R]!==null&&c.set(y.path,Buffer.byteLength(a[R]))});let d=new Map(b.filter((y,R)=>p.has(y.path)&&a[R]!==null).map(y=>[y.path,l.get(y.path)])),k=Y(r,e.ranked,c,l,{files:t,root:e.root,replacementBytes:d}),P=new Set(k.paths);b.forEach((y,R)=>{a[R]!==null&&(P.has(y.path)?(e.files[y.path]=a[R],e.selected=e.selected.map(S=>S.path===y.path?y:S)):e.refused.push(k.refused.find(S=>S.path===y.path)??{path:y.path,reason:"total"}))});return}let i=new Map((u.manifests??[]).map(a=>{let d=a.files.filter(k=>t[k.path]===void 0).map(k=>e.refused.find(P=>P.path===k.path)??{path:k.path,reason:"missing"});return[a.agentId,{...a,files:a.files.filter(k=>t[k.path]!==void 0),refused:[...a.refused,...d]}]})),m=a=>{let c=i.get(Ve(a.prompt));return c?{...a,manifest:c}:a};e.ranked={...e.ranked,strong:e.ranked.strong.map(m),possible:e.ranked.possible.map(m)},Pe(e,[...i.values()].flatMap(a=>a.files.map(c=>c.path)),"code"),e.refused.push(...[...i.values()].flatMap(wt)),e.phase="done"}async function er(r,e,o){if(!I(r))return!1;let s=Ge(r,e.entries.map(f=>f.path));if(!s.length)return!1;let t=new Set(s.flatMap(f=>f.agents)),n=new Map(e.selected.map(f=>[f.path,f])),l=new Set(e.selected.filter(f=>f.readBytes===void 0&&e.files[f.path]!==void 0).map(f=>f.path));e.managedReadPaths||(e.managedReadPaths=[],(e.scan||e.ranked)&&(delete e.scan,delete e.ranked,delete e.manifestReadPaths,e.phase!=="marker"&&(e.phase="scan")));let u=new Set([...e.managedReadPaths,...l]),g=e.entries.filter(f=>t.has(f.path)&&n.has(f.path)&&!u.has(f.path)),h=g.slice(0,G);if(!h.length)return!1;let p=await L(h,4,async f=>{let w=F(r,f,{...e.admission,purpose:"pointer",route:"github",root:e.root});return w.admitted?o(f):(e.refused.push({path:f.path,reason:w.reason}),null)});if(h.forEach((f,w)=>{p[w]!==null&&(e.files[f.path]=p[w],e.selected=e.selected.map(b=>b.path===f.path?f:b))}),e.managedReadPaths.push(...h.map(f=>f.path)),g.length>h.length){for(let f of Object.keys(e.files))!t.has(f)&&s.some(w=>C(f,w.folder)!==null)&&delete e.files[f];e.cursor=0,(e.phase==="done"||e.phase==="manifest")&&(e.phase="files")}return!0}function tr(r,e){let{plan:o,entries:s}=e,t=o.profile==="local-analysis"?o.context.dir??"":e.root??"",n=o.readers.find(p=>p.id==="marker")?.claim.wants[0],l=o.readers.some(p=>p.id==="code-scan"),u=new Map(s.map(p=>[p.path,p])),g=o.profile==="local-analysis"?o.selection.selected:o.selection.selectedPaths.flatMap(p=>u.has(p)?[u.get(p)]:[]),h=St(r)?U(r,{phase:"start",root:t,paths:s.map(p=>p.path),scanFlag:!!n||l}):void 0;return{version:1,profile:o.profile,root:t,entries:s,selected:[...g],conventionPaths:o.profile==="hosted-import"?X(r,s.map(p=>p.path),t).files.filter(p=>p.role!=="reference").map(p=>p.path):[],...e.admission?{admission:e.admission}:{},selectionRefused:o.selection.refused,requestedPaths:[],refused:[],files:{},cursor:0,treeTruncated:e.treeTruncated??!1,...o.profile==="hosted-import"?{hosted:{fallback:structuredClone(o.selection),weakCodeFallback:r.CF_IMPORT_WEAK_CODE_FALLBACK!=="0",codeMode:!1,needsExtraction:o.selection.needsExtraction}}:{},decision:h??(n?{kind:"marker",markerPath:n,scanIfBare:l}:{kind:"settled",markerPath:null,markerKind:null,scan:l}),phase:n?"marker":l?"scan":"files"}}function Lr(r,e){e.ranked??=me(r,e.scan,new Map);let o=Y(r,e.ranked,vt(e.scan.plan),new Map),s=[...o.refused,...e.ranked.skippedFiles??[]];if(e.requestedPaths.push(...s.map(t=>t.path)),e.refused.push(...s),e.profile==="hosted-import"&&o.paths.length){let t=ue(r,[],o.paths,e.scan.plan);e.refused.push(...t.refused),Qt(e,t.selected)}else re(r,e,o.paths,e.scan.plan);e.phase=e.selected.length?"files":"done"}async function rr(r,e,o){if(e.version!==1)throw new Error("unsupported-import-checkpoint");let s=e.profile==="hosted-import"?{...r,CF_IMPORT_CALLS:"0"}:r,t={...e,selected:[...e.selected],files:{...e.files},requestedPaths:[...e.requestedPaths],refused:[...e.refused],...e.hosted?{hosted:{...e.hosted}}:{},...e.managedReadPaths?{managedReadPaths:[...e.managedReadPaths]}:{}},n=new Set(t.entries.map(i=>i.path)),l=Object.fromEntries(Object.entries(t.files).filter(([i])=>t.selected.some(m=>m.path===i&&m.readBytes===void 0))),u=new Set(de(s,[...n],l)),g=[],h=new Set,p=async i=>{if(u.has(i.path)||t.managedReadPaths?.includes(i.path)&&t.files[i.path]===void 0)return t.refused.push({path:i.path,reason:"unreadable"}),null;g.push(i);try{let m=await o.read(i);if(m!==null){if(h.has(i.path)){let a=F(s,{path:i.path,size:Buffer.byteLength(m),text:m},{...t.admission,purpose:"skill",route:"github",root:t.root,listing:n,managedFiles:t.files});if(!a.admitted)return t.refused.push({path:i.path,reason:a.reason}),null}if(I(s)||ne(s)){let a=F(s,{path:i.path,text:m},{...t.admission,purpose:"override",route:"github",root:t.root,listing:n,managedFiles:t.files});if(!a.admitted)return t.refused.push({path:i.path,reason:a.reason}),null}if(t.phase==="manifest"){let a=F(s,{path:i.path,size:Buffer.byteLength(m)},{...t.admission,purpose:"pointer",route:"github",root:t.root});if(!a.admitted)return t.refused.push({path:i.path,reason:a.reason}),null}return m}}catch(m){if(m instanceof Xe&&(m.reason==="secret-content"||I(s)||h.has(i.path)))return t.refused.push({path:i.path,reason:m.reason}),null;if(t.profile==="hosted-import"&&!h.has(i.path))throw m}return t.refused.push({path:i.path,reason:"unreadable"}),null};if(await er(s,t,p))return N(s,t,g);if(Be(s,t),t.phase==="done")return o.resolvedCode&&Vt(t,o.resolvedCode),N(s,t,g);if(t.phase==="manifest")return await Zt(s,t,p),N(s,t,g);if(t.phase==="marker"&&t.decision.kind==="marker"){let i=t.decision,m=i.markerPath,a=t.entries.find(d=>d.path===m);if(t.profile==="hosted-import"){let d=F(s,a,{purpose:"pointer",route:"github",root:t.root});if(!d.admitted)return t.refused.push({path:m,reason:d.reason}),t.decision={kind:"settled",markerPath:null,markerKind:null,scan:i.scanIfBare},t.phase=i.scanIfBare?"scan":"files",N(s,t,g)}re(s,t,[m],t.entries);let c=await p(a);if(c!==null&&(t.files[m]=c),t.decision=U(s,{phase:"read",pending:i,text:c}),t.markerPath=m,t.markerKind=t.decision.markerKind,t.markerKind!=="bare"){let d=t.profile==="hosted-import"?await o.listing():{entries:t.entries,truncated:!1};t.treeTruncated||=d.truncated;let k=await Ct(s,{config:ut(c).config,markerDir:m.split("/").slice(0,-1).join("/"),selected:t.profile==="hosted-import"?[]:t.selected,admission:{...t.admission,root:t.root||void 0},modelReader:!1,priorRefused:t.refused,refusalMode:"append",requestedMode:"kept-and-refused",listing:async()=>d.entries});t.requestedPaths.push(...k.requestedPaths),t.refused=k.refused,t.profile==="hosted-import"?be(t,k.selected??[]):k.selected&&(t.selected=k.selected)}if(t.phase=t.decision.scan?"scan":"files",t.profile!=="hosted-import"||t.markerKind!=="bare"||t.decision.scan)return N(s,t,g)}if(t.phase==="scan"){if(!t.scan){let i=xt(s,t.entries,t.root,!0,t.decision.kind==="settled"?t.decision.scanPaths:void 0);t.scan=i.state,t.refused.push(...i.refused)}if(!te(t.scan)){let i=await Ot(s,t.scan,p,{modelReader:!1,alreadyRead:new Map,size:{batch:yt,parallel:4}});t.scan=i.scan,i.selection&&(t.ranked=i.selection.ranked)}return te(t.scan)&&Lr(s,t),N(s,t,g)}xe(s)&&(h=new Set(t.skillReferencePaths));let f=t.selected.slice(t.cursor,t.cursor+G),w=f.filter(i=>t.files[i.path]===void 0),b=await L(w,4,p);if(w.forEach((i,m)=>{b[m]!==null&&(t.files[i.path]=b[m])}),t.cursor+=f.length,xe(s)){let i=Object.fromEntries(Object.entries(t.files).filter(([P])=>t.selected.some(y=>y.path===P&&y.readBytes===void 0))),m=Ae(s,{entries:t.entries,selected:t.selected,files:i,root:t.root,admission:t.admission,referencePaths:t.skillReferencePaths});t.refused=B(t.refused,m.refused);for(let P of m.refused)h.has(P.path)&&delete t.files[P.path];if(t.cursor<t.selected.length)return N(s,t,g);let a=new Map(t.selected.map(P=>[P.path,P])),c=m.paths.filter(P=>!a.has(P)||a.get(P).readBytes!==void 0),d=new Set(c.filter(P=>a.has(P)));t.cursor-=t.selected.slice(0,t.cursor).filter(P=>d.has(P.path)).length,t.selected=t.selected.filter(P=>!d.has(P.path));for(let P of d)delete t.files[P];t.requestedPaths.push(...c),c.length&&(t.skillReferencePaths=[...t.skillReferencePaths??[],...c]);let k=new Map(t.entries.map(P=>[P.path,P]));t.selected.push(...c.map(P=>{let y=k.get(P);return{path:P,size:y.size,ref:y.ref}})),Pe(t,c,"fallback")}return t.cursor>=t.selected.length&&(t.phase=pe(s)&&t.ranked?"manifest":"done"),N(s,t,g)}async function or(r,e){let o=tr(r,e),s;do s=await rr(r,o,{listing:async()=>({entries:e.entries,truncated:!1}),read:e.read}),o=s.state;while(o.phase!=="done");let t={};return o.markerPath!==void 0&&(t.markerPath=o.markerPath,t.markerKind=o.markerKind),o.ranked!==void 0&&(t.ranked=o.ranked,t.scan=o.scan),{files:s.files,settled:s.settled,skippedFiles:s.refused,...t}}async function Te(r,e){let o=Me(r,{profile:"local-analysis",listing:e.entries,selection:e.selection}),{files:s,settled:t,skippedFiles:n,...l}=await or(r,{entries:e.entries,read:e.read,admission:e.admission,plan:o}),u=s,g=t,h=n,p=Q({key:e.repoKey,files:u,...l},o.context.flags,void 0,{markerPolicy:"any-read"}),{selection:f}=o,w;if(mt(r)&&e.repository){let a=await ht(r,{selected:{files:u,listedPaths:e.entries.map(d=>d.path),fallbackName:bt(e),skills:!0},selection:f,codeAgentsFound:(p?.resolved?.agents.length??0)>0,port:e.repository}),c=new Set(Object.keys(u).map(d=>W(d,a.root)));if(u=a.files,f=a.selection,w=a.root,w!==void 0){h=h.map(k=>({...k,path:W(k.path,w)})),g=g.map(k=>({...k,path:W(k.path,w)}));let d=new Set(g.map(k=>k.path));g.push(...f.selected.filter(k=>!d.has(k.path)&&Object.hasOwn(u,k.path)))}h=B(h,a.skippedFiles).filter(d=>c.has(d.path)||!Object.hasOwn(u,d.path))}let b={repoKey:e.repoKey,files:u,listedPaths:e.entries.map(a=>W(a.path,w)),...w!==void 0?{root:w}:{},forLocal:!0,code:p},i=Z(r,V(r,b)),m=f.readingNotes?$(r,f.readingNotes,g):f.skippedNote;return{...i,files:u,...w!==void 0?{root:w}:{},skippedFiles:h,warnings:[...new Set([...i.warnings,...m?[m]:[],...ae(h)])],selection:f}}var Nr=new Set;function jr(r,e={}){let o=ze(e.dir),s=e.limits??v.archive,t=e.listing??Nr,n={commit:null,files:new Map,skipped:[]},l=new Set,u=0,g=0;function h(i){let m=i.replace(/\/$/,"").split("/");return!i.startsWith("/")&&!i.includes("\\")&&!/^[a-z]:/i.test(i)&&!m.some(a=>a===".."||a==="."||!a)}function p(i,m,a,c=t){if(!a||!h(i)||!Number.isSafeInteger(m)||m<0)return"refused";let d=F(r,{path:i,size:m},{purpose:"archive",route:"github",root:o});return d.admitted?e.exampleFolders?.some(k=>i.startsWith(k))||qe(i,{root:o,listing:c})?"example":null:d.reason==="excluded"&&Ue(r,i,o)?"example":d.reason==="excluded"||d.reason==="wrong-type"?"excluded":"refused"}function f(i,m){l.has(i)||(l.add(i),n.skipped.push({path:i,reason:m}))}function w(i,m=t){let a=i.split("/");for(let c=1;c<=a.length;c++){let d=a.slice(0,c).join("/");if(d===o||o.startsWith(`${d}/`))continue;if(C(d,o)===null)return!1;let k=p(`${d}/`,0,!0,m);if(k)return f(`${d}/`,k),!1}return!0}function b(i,m,a=!0){if(C(i,o)===null)return!1;if(!h(i))return f(i,"refused"),!1;let c=i.split("/");if(c.length>1&&!w(c.slice(0,-1).join("/")))return!1;let d=p(i,m,a);return d?(f(i,d),!1):g>=s.files||m>s.bytes-u?(f(i,"over-limit"),!1):(u+=m,g++,!0)}return{result:n,accept:b,enterFolder:w}}var Kr=new Set(ve);function Hr(r,e){for(let s of[...Object.keys(e.set),...e.clear])if(!Kr.has(s))throw new Error(`Unknown analysis field: ${s}`);let o={...r,...e.set};for(let s of e.clear)o[s]=void 0;return o}function sr(r){return r.CF_MODEL_READER!=="0"}async function Dr(r,e,o,s){o=z(r,o);let t=structuredClone(e);for(t.files??={},t.cursor=0;;){let n=await ge(r,t,o,s);if(n){t=n;continue}let l=t.selected??[];if((t.cursor??0)>=l.length)return t;let u=l.slice(t.cursor).filter(p=>!Object.hasOwn(t.files,p.path)),g=[],h=await L(u,4,async p=>{try{return{path:p.path,text:await he(p,f=>o.read(f),g,t.refused)}}catch(f){return{error:f}}});for(let p of h){if("error"in p)throw p.error;p.text!==null&&(t.files[p.path]=p.text)}g.length&&(t.refused=B(t.refused,g)),t.cursor=l.length}}async function nr(r,e,o,s){let{codeFindingNote:t}=kt(s),n={deriveBytes:0,codeEvidence:[]};if(!e.findingQuality?.config.switches.codeInputs||!e.projectAgents?.enabled)return n;let l=e.projectAgents,u=(e.repos??[]).filter(c=>[...l.byRepo[c.key]??[],...l.codeByRepo?.[c.key]??[]].some(d=>d.codeInputsJson&&(d.codeInputsJson.tools.length||d.codeInputsJson.contextInputs.length))),h=(await L(u,1,async c=>{try{let d=o.find(k=>k.repoKey===c.key);if(!d)throw new Error("Source reader is missing.");return{repo:await Dr(r,c,d,e.modelReader??!1)}}catch(d){return{error:d}}})).map(c=>{if("error"in c)throw c.error;return c.repo}),p=h.map(c=>{let d=ke(r,c,q(r,e),e.modelReader,l);return Object.assign(c.files,d.virtualFiles),d.fragment}),f=Object.fromEntries(h.map(c=>[c.key,c.files??{}])),b=Bt({...e,repos:h,mapped:p}).findingQuality?.codeEvidence?.filter(c=>Object.keys(c.input.files).length)??[];if(!b.length)return n;let i=b.map(c=>({repo:c.repo,unitKey:c.unitKey,enabled:!0,inputs:[c.input],files:f[c.repo]}));return{deriveBytes:[...new Map(b.flatMap(c=>Object.entries(c.input.files).map(([d,k])=>[JSON.stringify([c.repo,d]),{path:d,text:k}]))).values()].reduce((c,{path:d,text:k})=>c+Buffer.byteLength(`### ${d}
|
|
2
|
+
\`\`\`
|
|
3
|
+
${ot(k)}
|
|
4
|
+
\`\`\`
|
|
5
|
+
|
|
6
|
+
`),0)+Buffer.byteLength(t(b.flatMap(c=>c.input.sources))),codeEvidence:i}}function cr(r,e,o,s,t){let n=e.analysisFlags,l=[],u=new Set,g=0,h=0;for(let d of e.repos??[]){h+=(d.selected??[]).reduce((P,y)=>P+(y.readBytes??y.size),0),l.push(...(d.selected??[]).map(P=>({path:C(P.path,d.root)??P.path,size:P.size})));let k=et(e.projectAgents,d.key,{nodes:[],edges:[],warnings:[]},t);for(let[P,y]of Object.entries(k.files)){let R=at(y).length;g+=R,l.push({path:P,size:R}),u.add(P)}}g+=h;let p=Nt(l,n.multiPass,u),f=p>1?24:rt,w=(u.size?g:Math.min(g,15e4))+s.deriveBytes,b=Fe("derive",r,o),i=Array.from({length:p},(d,k)=>_(r,{template:b},p>1?`Derive findings (part ${k+1} of ${p})`:"Derive findings",M.generate,K(w+jt(g,p))+4e3,Ke)),m=n.multiPass&&u.size?h:Math.min(h,15e4);i.push(_(r,{template:"derive-structure"},"Structural pass",M.generate,K(m)+4e3,12e3));let a=Math.ceil(f/He)*(1+De);i.push(_(r,{template:"scope-findings"},"Scope check",o.switches.enabled?o.models.scope:M.mechanical,a*(4e3+K(s.scopeBytes)),a*1e3));let c=st(r,f,n.findingCheck??!0,Fe("check",r,o),o.switches.fullContext?"whole-file":"legacy");return c&&i.push(c),(n.sourceNotes??!0)&&i.push(_(r,{template:"explain-sources"},"Explain sources",Tt,K(Lt)*f,It*f)),e.codeAgents?.model&&e.repos?.some(d=>d.scanNeeded)&&i.push(_(r,{template:"judge-code-prompt"},"Check possible agents in code",M.mechanical,6*3e3,1200)),i.push(...Kt(Re(r),r)),i}var $r=async(r,e)=>{if(e.progress.assertHeld(),e.progress.signal?.throwIfAborted(),!e.model)throw new ye("llm","Analysis needs a live model; no provider key is configured.");if(!e.readers.length)throw new ye("not_found","This project has no analyzable repository.");let o=r.execution.preparation;if(!o)throw new Error("Preparation options are required for estimation.");let{state:s,settings:t}=r;await H(t,s,e.readers),await e.context.refreshStructureParts?.().catch(()=>{});let n=D(await e.instructions()),l=J(n),u=n.bundleText("model-reader-runtime-prompt"),g=[...s.warnings??[]],h=q(t,s),p=s.modelReader??sr(t),f=s.analysisFlags?se(t,s):Le(t),w=s.findingQuality??{config:o.qualityConfig},b=await Ze(t,s.projectAgents,e.context.loadProjectAgents,void 0,w.config.switches.codeInputs),i=[],m=[],a=e.readers.map(O=>z(t,O));for(let O of a){e.progress.assertHeld(),e.progress.signal?.throwIfAborted();let oe=await O.head(),Ie=await O.list(),j=we(t,Ie,O.root);!j.readingNotes&&j.skippedNote&&g.push(`${O.repoKey}: ${j.skippedNote}`),m.push({key:O.repoKey,kind:"github",root:O.root,selected:j.selected}),i.push({key:O.repoKey,...O.source??{kind:O.repoKey.startsWith("local:")?"fs":"github"},headSha:oe.sha,branch:oe.branch,selected:j.selected,...j.readingNotes?{sourceReadNotes:j.readingNotes}:{},cursor:0,files:{},...O.root?{root:O.root}:{},...At(t,Ie,j.selected,O.root,h,p)})}let c={...s,repos:i,projectAgents:b,codeAgents:h,modelReader:p,analysisFlags:f,findingQuality:w};await H(t,c,a);let d=await nr(t,c,a,n),{sources:k,files:P}=Ce({qualityConfig:w.config,codeEvidence:d.codeEvidence}),y=l.enrichRequestInputs("scope-findings",{codeSources:k,codeFiles:P},t),R=Buffer.byteLength(String(y.code))+Math.max(0,Buffer.byteLength(String(y.system))-Buffer.byteLength(l.RULE)),S=[...o.uploadReadingAllowance?[o.uploadReadingAllowance]:[],...cr(t,{...c,repos:m},w.config,{deriveBytes:d.deriveBytes,scopeBytes:R},u)],E=await e.context.loadOpenStructures?.()??[],x=(await e.context.loadPendingRechecks?.().catch(()=>[])??[]).reduce((O,oe)=>O+oe.children.length,0);x&&S.push(_(t,{template:"structure-recheck"},"Post-merge re-check",M.mechanical,x*3e3,x*300));let A=await e.context.chatFindingCount?.().catch(()=>(e.progress.log({level:"warn",code:"chat.count_failed"}),0))??0;A&&S.push(_(t,{},"Re-check chat findings",M.mechanical,A*3e3,A*300));let T=ie(S,o.capUsd);return ce(T,e.progress.log),{next:o.confirmPrice?"awaiting_confirm":"fetching_files",clear:[],estimate:T,set:{repos:i,warnings:g,openStructures:E,codeAgents:h,modelReader:p,analysisFlags:f,projectAgents:b,findingQuality:w,...f.splitCheck?{splitEstimateBase:T}:{}}}};var Gr=async({state:r,settings:e},o)=>{o.progress.assertHeld(),o.progress.signal?.throwIfAborted();let s=[...r.repos??[]];await H(e,r,o.readers);let t=r.repoCursor??0;if(t>=s.length)return{next:"mapping",set:{repoCursor:0},clear:[]};let n=structuredClone(s[t]),l=o.readers.find(m=>m.repoKey===n.key);if(!l)throw new Error(`no reader for ${n.key}`);let u=z(e,l),g=await ge(e,n,u,r.modelReader??!1);if(g)return s[t]=g,{next:"fetching_files",set:{repos:s},clear:[]};let h=n.selected??[],p=n.cursor??0,f=h.slice(p,p+20),w={...n.files??{}},b=[];for(let m of f){if(o.progress.assertHeld(),o.progress.signal?.throwIfAborted(),w[m.path]!==void 0)continue;let a=await he(m,c=>u.read(c),b,n.refused);a!==null&&(w[m.path]=a)}b.length&&(n.refused=B(n.refused,b)),n.files=w,n.cursor=p+f.length,s[t]=n;let i=n.cursor>=h.length&&!_t(n);return{next:"fetching_files",set:{repos:s,repoCursor:i?t+1:t},clear:[]}};async function Wr(r,e){let o=e.admission?.exclusions?.length?e.entries.filter(n=>F(r,n,{purpose:"override",route:"github",...e.admission}).admitted):e.entries,s=I(r)?new Set(o.map(n=>n.path)):void 0,t=!e.admission?.exclusions?.length&&!ne(r)?e.read:n=>Je(r,n,e.read,{...e.admission,...s?{listing:s}:{}});return Te(r,{...e,entries:o,read:t})}async function Xr(r,e,o){let s=Object.entries(e).map(([n,l])=>({path:n,size:Buffer.byteLength(l),ref:n})),t=Et(r,s,o.root,!1,o.scanPaths);for(;!te(t);)t=await Ft(t,async n=>e[n.path]??null);return{scan:me(r,t),summary:Rt(t)}}async function dr(r,e,o){let{repoKey:s,root:t,codingGuides:n,forLocal:l}=o,u=o.flags??ee(r),g=Object.keys(e),h=U(r,{phase:"start",paths:g,root:t,scanFlag:u.scan}),p=h.kind==="marker"?U(r,{phase:"read",pending:h,text:e[h.markerPath]??null}):h,f=p.kind==="off"?null:p.markerPath,w=p.kind==="off"?null:p.markerKind;if(p.kind==="off"||!p.scan){let d=Q({key:s,files:e,markerPath:f,markerKind:w},u,void 0,{markerPolicy:"any-read"});return{...Z(r,V(r,{repoKey:s,files:e,root:t,codingGuides:n,forLocal:l,code:d})),scanned:!1,resolved:null}}let{scan:b,summary:i}=await Xr(r,e,{repoKey:s,root:t,scanPaths:p.scanPaths}),m=Q({key:s,files:e,ranked:b,scan:i,markerPath:f,markerKind:w},u,void 0,{markerPolicy:"any-read"});return{...Z(r,V(r,{repoKey:s,files:e,root:t,codingGuides:n,forLocal:l,code:m})),scanned:!0,resolved:m.resolved}}async function lr(r,e){let{state:o,settings:s}=r;if(!se(s,o).splitCheck||!o.splitEstimateBase)return{next:"inspecting",set:{repoCursor:0},clear:[]};let n=r.execution.preparation?.capUsd??o.splitEstimateBase.capUsd,l={...o.splitEstimateBase,capUsd:n};ce(l,e.progress.log);let u=Ht(s,o),g={next:"inspecting",set:{repoCursor:0,splitCheckPriced:!0,splitFindingsPriced:!0},clear:["splitEstimateBase"]};if(!u.length)return g;let h=J(D(await e.instructions())),p=u.reduce((m,{inventory:a})=>m+K(Buffer.byteLength(zt({tools:h},{...a,findings:[]}).prompt))+K(h.SHAPE_FINDINGS_INPUT_BYTES),0),f=l.lines.find(m=>m.label==="Scope check"),w=_(s,{template:"scope-findings"},"Scope check",M.mechanical,(f?.inputTokens??0)+u.length*qt,(f?.outputTokens??0)+u.length*Ut),b=l.lines.map(m=>m.label==="Scope check"?w:m);f||b.push(w),b.push(_(s,{template:"derive-shape"},"Split check",Dt,p,u.length*gt));let i=ie(b,n);return Ne(i)?(g.estimate=l,g.clear.push("splitCheckPriced","splitFindingsPriced"),delete g.set.splitCheckPriced,delete g.set.splitFindingsPriced,e.progress.log({level:"warn",code:"analysis.split_check_over_cap",counts:{totalUsd:i.totalUsd,capUsd:i.capUsd}}),g.set.warnings=[...o.warnings??[],je]):g.estimate=i,g}var Jr=async(r,e)=>{e.progress.assertHeld(),e.progress.signal?.throwIfAborted();let{state:o,settings:s}=r,t=o.repos??[];await H(s,o,e.readers);let n=o.repoCursor??0;if(n>=t.length)return lr(r,e);let l=t[n],u=r.execution.forLocal,g=u?o.mapped?.[n]?{fragment:Oe(o,n),warnings:[]}:await dr(s,l.files??{},{repoKey:l.key,root:l.root,forLocal:!0}):void 0,h=g?(()=>{let i=tt(g.fragment,l.key);return{...i,warnings:[...g.warnings,...i.warnings]}})():ke(s,l,q(s,o),o.modelReader??!1,o.projectAgents,D(await e.instructions()).bundleText("model-reader-runtime-prompt")),p=!u&&l.sourceReadNotes?$(s,l.sourceReadNotes,l.selected??[],l.root):void 0,f=u?[]:ae((l.refused??[]).filter(i=>i.reason==="secret-content")),w="virtualFiles"in h?h.virtualFiles:void 0,b=[...o.mapped??[]];return b[n]=h.fragment,{next:"mapping",clear:[],set:{...w?{repos:t.map((i,m)=>m===n?{...i,files:{...i.files,...w}}:i)}:{},mapped:b,warnings:[...o.warnings??[],...p?[`${l.key}: ${p}`]:[],...f,...h.warnings,...Mt(l)],repoCursor:n+1}}};function Yr(r,e){let o=e?.findingHeadlineDiagnostics??(r.findingHeadlines?.version===2?r.findingHeadlines.diagnostics:r.findingHeadlineDiagnostics);return{set:{...o?{findingHeadlineDiagnostics:o}:{},repos:(r.repos??[]).map(s=>({...s,files:{},selected:[],scan:void 0,ranked:void 0})),...r.projectAgents?{projectAgents:{enabled:r.projectAgents.enabled,byRepo:{}}}:{}},clear:["passResults","sourceNotes","findingHeadlines","findingsRaw","structuresRaw","loadModes","rechecks","recheckedChangeIds","readPaths","inspectPlan","passFindings","codeChecks","newVerdicts",...r.shapeFindings?["shapeFindings"]:[]]}}export{ve as ANALYSIS_FIELDS,pr as FOLDER_TOO_LARGE_MESSAGE,br as InputBudgetError,M as MODELS,F as admitFile,Rr as analysisFieldsOf,vr as analysisRuntime,mr as analysisSizeLimits,Hr as applyAnalysisDelta,hr as assessAnalysisSize,Ar as buildAnalysisResult,Pr as buildRequest,D as createInstructionText,yr as createRequestRegistry,J as createRequestTools,Te as discoverLocalSources,Se as discoverReaders,$r as estimateStage,Wr as fetchLocalSources,Gr as fetchStage,Fr as fetchedPathsOf,Re as findingHeadlinesEnabled,Yr as finishAnalysis,_r as headlinesStage,Or as inspectStage,Jr as mapStage,gr as measureAnalysisSize,ur as parseAnalysisSize,Ir as planForJob,Me as planImport,fr as readFindingQualityConfig,Sr as render,jr as repoCollector,wr as resolveAgents,Oe as savedFragmentAt,xr as savedFragmentsOf,Ce as scopeCodeContext,_e as selectionOfPlan,kr as snapshotSettings,Cr as sourceNotesStage,Mr as structureStage,Er as trySavedFragmentAt};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b,c,d,e}from"../chunks/MJGB25S5.js";import"../chunks/JKWTHRUR.js";import"../chunks/3GUKUEEJ.js";export{b as applyCacheBreakpoints,d as captureAllowanceMultiplier,e as promptCacheEnabled,c as promptCacheEstimateLine,a as promptCachePolicy};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b,c,d,e,f,g,h,i,j,k,l,m,n}from"../chunks/JKWTHRUR.js";import"../chunks/3GUKUEEJ.js";export{l as ANALYSIS_TOO_LARGE,a as ANTHROPIC_CACHE_READ_RATE,b as CACHE_WRITE_MULTIPLIERS,d as FALLBACK_MODEL,c as PRICE_PER_MTOK,m as SPLIT_CHECK_TOO_LARGE,n as assertEstimateWithinCap,e as cacheWriteMultiplier,f as estimateTokensFromBytes,g as estimateUsd,k as formatUsd,h as line,j as overCap,i as sumEstimate};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/4F6ZIHXU.js";export{a as executeStructuredRequest};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b,c}from"../chunks/SL27GMEN.js";import"../chunks/3227KXHF.js";export{a as NONSTREAM_MAX_TOKENS,c as anthropicStructuredLimit,b as supportsReasoningControls};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/VGYWI4X2.js";export{a as retryCalls};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b}from"../chunks/57M4OQJM.js";export{a as stableClone,b as stableStringify};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/J4AXGE5W.js";export{a as StructuredOutputError};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"./chunks/326F4XNG.js";export{a as mapLimit};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as a}from"../chunks/TDNTU4TF.js";import"../chunks/STZOC7LN.js";import"../chunks/UEWL3GMQ.js";import"../chunks/U5HOEVPE.js";import"../chunks/EH3QQ3T4.js";import"../chunks/FSLWD2PE.js";import"../chunks/JF4GYMOZ.js";export{a as answerFormats};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/HTLIRVP7.js";export{a as checkDiagnosticsText};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b,c}from"../chunks/ZAA44GPI.js";import"../chunks/3227KXHF.js";export{a as FINDING_HEADLINES_MODEL,b as FINDING_HEADLINES_OUTPUT_TOKENS,c as headlineRequest};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";export{a as createInstructionText};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{X as o,Z as p,aa as e,ca as m}from"../chunks/T2SAP7OV.js";import"../chunks/QMIXCT62.js";import"../chunks/T66VDFXF.js";import"../chunks/J4AXGE5W.js";import"../chunks/IVDDV6CU.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/TDNTU4TF.js";import"../chunks/HTLIRVP7.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/K5OTWBTT.js";import"../chunks/326F4XNG.js";import"../chunks/V7BFUTM7.js";import"../chunks/4F6ZIHXU.js";import"../chunks/VGYWI4X2.js";import"../chunks/PYKAERZZ.js";import"../chunks/7OYIBWX3.js";import"../chunks/NCWEOJVJ.js";import"../chunks/2PSNOSJ2.js";import"../chunks/DRGDIIFA.js";import"../chunks/6YCABS5T.js";import"../chunks/SL27GMEN.js";import"../chunks/3CKW5JIF.js";import"../chunks/STZOC7LN.js";import"../chunks/MJGB25S5.js";import"../chunks/UEWL3GMQ.js";import"../chunks/OFBJNHC6.js";import"../chunks/MXXNED6N.js";import"../chunks/U5HOEVPE.js";import"../chunks/FTODBFQW.js";import"../chunks/ZAA44GPI.js";import"../chunks/3227KXHF.js";import"../chunks/O652FQQH.js";import"../chunks/57M4OQJM.js";import"../chunks/IBCFGUHI.js";import"../chunks/KU5DINLW.js";import"../chunks/HPIAEQHE.js";import"../chunks/74FPPPIG.js";import"../chunks/EH3QQ3T4.js";import"../chunks/JKWTHRUR.js";import"../chunks/FSLWD2PE.js";import"../chunks/JF4GYMOZ.js";import"../chunks/3GUKUEEJ.js";import"../chunks/T5TREZCQ.js";import"../chunks/724WZMYW.js";function i(l,r,a={}){let n=o(l,r,a.structureState);return[...n.calls,...p(l,n.findings),...m(l,r,a),...e(l)]}export{i as localCallPlan};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{k as a,l as b,m as c,n as d}from"../chunks/IVDDV6CU.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/TDNTU4TF.js";import"../chunks/HTLIRVP7.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/V7BFUTM7.js";import"../chunks/6YCABS5T.js";import"../chunks/3CKW5JIF.js";import"../chunks/STZOC7LN.js";import"../chunks/MJGB25S5.js";import"../chunks/UEWL3GMQ.js";import"../chunks/U5HOEVPE.js";import"../chunks/74FPPPIG.js";import"../chunks/EH3QQ3T4.js";import"../chunks/JKWTHRUR.js";import"../chunks/FSLWD2PE.js";import"../chunks/JF4GYMOZ.js";import"../chunks/3GUKUEEJ.js";export{a as InputBudgetError,d as buildAnalysisCall,c as callInputBytes,b as createRequestRegistry};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/Y7JGSUOA.js";export{a as createSchemaDescriptions};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b,c,d}from"../chunks/3MTXB4MK.js";export{a as SHAPE_FINDINGS_INPUT_BYTES,c as assertShapeFindingBytes,d as createShapeFindingInput,b as shapeFindingData};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/T66VDFXF.js";import"../chunks/E7TFIHC5.js";import"../chunks/V7BFUTM7.js";import"../chunks/3CKW5JIF.js";import"../chunks/STZOC7LN.js";import"../chunks/MJGB25S5.js";import"../chunks/UEWL3GMQ.js";import"../chunks/EH3QQ3T4.js";import"../chunks/JKWTHRUR.js";import"../chunks/FSLWD2PE.js";import"../chunks/JF4GYMOZ.js";import"../chunks/3GUKUEEJ.js";export{a as createTemplateVersion};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a}from"../chunks/QMIXCT62.js";import"../chunks/T66VDFXF.js";import"../chunks/IVDDV6CU.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/TDNTU4TF.js";import"../chunks/HTLIRVP7.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/V7BFUTM7.js";import"../chunks/6YCABS5T.js";import"../chunks/3CKW5JIF.js";import"../chunks/STZOC7LN.js";import"../chunks/MJGB25S5.js";import"../chunks/UEWL3GMQ.js";import"../chunks/U5HOEVPE.js";import"../chunks/74FPPPIG.js";import"../chunks/EH3QQ3T4.js";import"../chunks/JKWTHRUR.js";import"../chunks/FSLWD2PE.js";import"../chunks/JF4GYMOZ.js";import"../chunks/3GUKUEEJ.js";export{a as createRequestTools};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a,b,c,d}from"./chunks/V7BFUTM7.js";import"./chunks/3CKW5JIF.js";import"./chunks/STZOC7LN.js";import"./chunks/MJGB25S5.js";import"./chunks/UEWL3GMQ.js";import"./chunks/EH3QQ3T4.js";import"./chunks/JKWTHRUR.js";import"./chunks/FSLWD2PE.js";import"./chunks/JF4GYMOZ.js";import"./chunks/3GUKUEEJ.js";export{a as findingHeadlinesEnabled,b as outsideLoadersEnabled,c as promptAgreementEnabled,d as snapshotSettings};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { zodOutputFormat } from "@anthropic-ai/sdk/helpers/zod";
|
|
3
|
+
import { answerFormats } from "../../analysis-core/requests/answer-formats.js";
|
|
4
|
+
import { createInstructionText } from "../../analysis-core/requests/instruction-text.js";
|
|
5
|
+
import { createSchemaDescriptions } from "../../analysis-core/requests/schema-descriptions.js";
|
|
6
|
+
const registryPayload = z.object({
|
|
7
|
+
templates: z.record(z.string(), z.object({
|
|
8
|
+
prompt: z.string(), system: z.string().optional(), route: z.string().optional(),
|
|
9
|
+
promptBlocks: z.array(z.object({ text: z.string(), cache: z.literal(true).optional() }).strict()).optional(),
|
|
10
|
+
}).strict()),
|
|
11
|
+
includes: z.record(z.string(), z.string()),
|
|
12
|
+
answerFormats: z.record(z.string(), z.object({ schema: z.string(), source: z.string() }).strict()),
|
|
13
|
+
descriptions: z.record(z.string(), z.string()),
|
|
14
|
+
}).strict();
|
|
15
|
+
function restoreFormat(saved, local) {
|
|
16
|
+
const source = z.record(z.string(), z.unknown()).parse(JSON.parse(saved.source));
|
|
17
|
+
// Validate the provider shape while leaving defaults, catches and cleanup to the local core.
|
|
18
|
+
const provider = z.record(z.string(), z.unknown()).parse(JSON.parse(saved.schema));
|
|
19
|
+
const validator = z.fromJSONSchema(provider);
|
|
20
|
+
const constraints = local ?? z.fromJSONSchema(source);
|
|
21
|
+
// A fresh root keeps Zod's refinement parent metadata out of the schema hook.
|
|
22
|
+
const format = z.unknown().pipe(z.json().superRefine((value, context) => {
|
|
23
|
+
if (!validator.safeParse(value).success || !constraints.safeParse(value).success) {
|
|
24
|
+
context.addIssue({ code: "custom", message: "Invalid answer format" });
|
|
25
|
+
}
|
|
26
|
+
}));
|
|
27
|
+
// Zod's schema hook preserves the compiler input without rebuilding a stricter validator.
|
|
28
|
+
format._zod.toJSONSchema = () => structuredClone(source);
|
|
29
|
+
if (JSON.stringify(zodOutputFormat(format).schema) !== saved.schema)
|
|
30
|
+
throw new Error("Incompatible answer format");
|
|
31
|
+
return format;
|
|
32
|
+
}
|
|
33
|
+
export function deserialiseRegistry(bytes) {
|
|
34
|
+
try {
|
|
35
|
+
const payload = registryPayload.parse(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)));
|
|
36
|
+
const text = createInstructionText({
|
|
37
|
+
templates: payload.includes, descriptions: payload.descriptions,
|
|
38
|
+
});
|
|
39
|
+
const formats = answerFormats(undefined, name => Object.hasOwn(payload.descriptions, name) ? text.description(name) : undefined);
|
|
40
|
+
const { withDescriptions } = createSchemaDescriptions(text);
|
|
41
|
+
return { ...payload, answerFormats: Object.fromEntries(Object.entries(payload.answerFormats).map(([name, schema]) => {
|
|
42
|
+
let format;
|
|
43
|
+
if (Object.hasOwn(formats, name)) {
|
|
44
|
+
// Decrypted wording hydrates the same enumeration used by the source registry.
|
|
45
|
+
format = withDescriptions(formats[name]);
|
|
46
|
+
if (JSON.stringify(z.toJSONSchema(format, { reused: "ref" })) !== schema.source)
|
|
47
|
+
throw new Error();
|
|
48
|
+
}
|
|
49
|
+
return [name, restoreFormat(schema, format)];
|
|
50
|
+
})) };
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// JSON and schema errors can quote decrypted instructions; callers only need the failure category.
|
|
54
|
+
throw new Error("Invalid registry payload");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const sealedRegistryPayload = z.object({
|
|
58
|
+
registry: registryPayload,
|
|
59
|
+
fingerprintKey: z.string(),
|
|
60
|
+
policy: z.record(z.string(), z.object({
|
|
61
|
+
role: z.enum(["required", "optional"]), answerFormats: z.array(z.string().min(1)).min(1),
|
|
62
|
+
}).strict()),
|
|
63
|
+
}).strict();
|
|
64
|
+
export function deserialiseSealedRegistry(bytes) {
|
|
65
|
+
try {
|
|
66
|
+
const payload = sealedRegistryPayload.parse(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)));
|
|
67
|
+
const fingerprintKey = Buffer.from(payload.fingerprintKey, "base64");
|
|
68
|
+
if (fingerprintKey.length !== 32 || fingerprintKey.toString("base64") !== payload.fingerprintKey)
|
|
69
|
+
throw new Error();
|
|
70
|
+
return { registry: deserialiseRegistry(Buffer.from(JSON.stringify(payload.registry))), fingerprintKey, policy: payload.policy };
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
throw new Error("Invalid registry payload");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
2
|
+
function decode(value) {
|
|
3
|
+
const bytes = Buffer.from(value, "base64");
|
|
4
|
+
if (bytes.toString("base64") !== value)
|
|
5
|
+
throw new Error("Invalid base64 encoding");
|
|
6
|
+
return bytes;
|
|
7
|
+
}
|
|
8
|
+
export function encrypt(plaintext, key) {
|
|
9
|
+
const iv = randomBytes(12);
|
|
10
|
+
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
11
|
+
// The contract has no separate tag field; keep the tag with the ciphertext it authenticates.
|
|
12
|
+
const sealed = Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()]);
|
|
13
|
+
return { sealed: sealed.toString("base64"), iv: iv.toString("base64") };
|
|
14
|
+
}
|
|
15
|
+
export function decrypt(sealed, iv, key) {
|
|
16
|
+
const bytes = decode(sealed);
|
|
17
|
+
const nonce = decode(iv);
|
|
18
|
+
if (nonce.length !== 12 || bytes.length < 16)
|
|
19
|
+
throw new Error("Invalid encrypted payload");
|
|
20
|
+
// The payload length check and subarray(-16) enforce a 16-byte authentication tag.
|
|
21
|
+
// nosemgrep: javascript.node-crypto.security.gcm-no-tag-length.gcm-no-tag-length
|
|
22
|
+
const decipher = createDecipheriv("aes-256-gcm", key, nonce);
|
|
23
|
+
decipher.setAuthTag(bytes.subarray(-16));
|
|
24
|
+
return Buffer.concat([decipher.update(bytes.subarray(0, -16)), decipher.final()]);
|
|
25
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createHmac } from "node:crypto";
|
|
2
|
+
import { stableStringify } from "../../analysis-core/llm/stable-json.js";
|
|
3
|
+
import { createInstructionText } from "../../analysis-core/requests/instruction-text.js";
|
|
4
|
+
import { requestPolicy } from "../../analysis-core/contracts/requests.js";
|
|
5
|
+
import { bundleMetadata } from "../../contract/messages.js";
|
|
6
|
+
import { buildAnalysisCall, callInputBytes } from "../../analysis-core/requests/registry.js";
|
|
7
|
+
import { headlineRequest } from "../../analysis-core/requests/headline-request.js";
|
|
8
|
+
import { HEADLINE_RESULT_VERSION } from "../../analysis-core/analysis/headlines/types.js";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
import { createRequestTools } from "../../analysis-core/requests/tools.js";
|
|
11
|
+
export function sameNames(names, values) {
|
|
12
|
+
const actual = Object.keys(values).sort();
|
|
13
|
+
return names.length === actual.length && [...names].sort().every((name, index) => name === actual[index]);
|
|
14
|
+
}
|
|
15
|
+
export function createBundleMetadata(registry, key, policy) {
|
|
16
|
+
if (key.byteLength !== 32 || !sameNames(Object.keys(policy), registry.templates))
|
|
17
|
+
throw new Error("Invalid bundle policy");
|
|
18
|
+
function asset(kind, name, value) {
|
|
19
|
+
return { size: Buffer.byteLength(value), fingerprint: createHmac("sha256", key)
|
|
20
|
+
.update(stableStringify([kind, name, value])).digest("hex") };
|
|
21
|
+
}
|
|
22
|
+
const known = requestPolicy();
|
|
23
|
+
const text = createInstructionText({ templates: registry.includes ?? {}, descriptions: registry.descriptions });
|
|
24
|
+
let headlinePlan;
|
|
25
|
+
if (Object.hasOwn(registry.templates, "finding-headlines")) {
|
|
26
|
+
const request = headlineRequest([]);
|
|
27
|
+
const call = buildAnalysisCall({ ...request, inputs: { data: request.inputs, settings: {} } }, registry);
|
|
28
|
+
const probe = headlineRequest([{ key: "f0", kind: "finding", impact: "correctness", structure: null,
|
|
29
|
+
cause: "", category: null, question: null, site: null, excerpt: null, otherSites: [], fixSummaries: [] }]);
|
|
30
|
+
const probeCall = buildAnalysisCall({ ...probe, inputs: { data: probe.inputs, settings: {} } }, registry);
|
|
31
|
+
// Evidence enters the renderer as one JSON scalar. Measure its copies through the renderer, including includes.
|
|
32
|
+
const evidenceCopies = (callInputBytes(probeCall) - callInputBytes(call)) / (Buffer.byteLength(JSON.stringify(probe.inputs.evidence)) - 2);
|
|
33
|
+
const inputOverheadBytes = callInputBytes(call) - evidenceCopies * 2;
|
|
34
|
+
if (!Number.isSafeInteger(evidenceCopies) || evidenceCopies < 0 || inputOverheadBytes < 0)
|
|
35
|
+
throw new Error("Invalid bundle policy");
|
|
36
|
+
headlinePlan = { ...asset("headline-plan", "finding-headlines", stableStringify({ system: call.system, prompt: call.prompt,
|
|
37
|
+
schema: z.toJSONSchema(call.schema, { reused: "ref" }), fallbackQuestion: createRequestTools(text).headlineFallbackQuestion() })),
|
|
38
|
+
inputOverheadBytes, evidenceCopies, resultVersion: HEADLINE_RESULT_VERSION };
|
|
39
|
+
}
|
|
40
|
+
return bundleMetadata.parse({
|
|
41
|
+
templates: Object.fromEntries(Object.entries(registry.templates).map(([name, template]) => {
|
|
42
|
+
const item = policy[name];
|
|
43
|
+
if (Object.hasOwn(known, name) && stableStringify(item) !== stableStringify(known[name]))
|
|
44
|
+
throw new Error("Invalid bundle policy");
|
|
45
|
+
if (!item || new Set(item.answerFormats).size !== item.answerFormats.length ||
|
|
46
|
+
item.answerFormats.some(format => !Object.hasOwn(registry.answerFormats, format)))
|
|
47
|
+
throw new Error("Invalid bundle policy");
|
|
48
|
+
return [name, { ...asset("template", name, stableStringify(template)), role: item.role, answerFormats: [...item.answerFormats].sort() }];
|
|
49
|
+
})),
|
|
50
|
+
includes: Object.fromEntries(Object.entries(registry.includes ?? {}).map(([name, value]) => {
|
|
51
|
+
const expanded = asset("expanded-include", name, text.templateText(name));
|
|
52
|
+
return [name, { ...asset("include", name, value), expandedSize: expanded.size, expandedFingerprint: expanded.fingerprint }];
|
|
53
|
+
})),
|
|
54
|
+
descriptions: Object.fromEntries(Object.entries(registry.descriptions).map(([name, value]) => [name, asset("description", name, value)])),
|
|
55
|
+
...(headlinePlan ? { headlinePlan } : {}),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export function verifyBundleMetadata(metadata, registry, key, policy) {
|
|
59
|
+
const supplied = bundleMetadata.parse(metadata);
|
|
60
|
+
const expected = createBundleMetadata(registry, key, policy);
|
|
61
|
+
// Older releases remain readable; their metadata cannot enable sealed headline planning.
|
|
62
|
+
if (!supplied.headlinePlan)
|
|
63
|
+
delete expected.headlinePlan;
|
|
64
|
+
else if (supplied.headlinePlan.resultVersion === undefined && expected.headlinePlan)
|
|
65
|
+
delete expected.headlinePlan.resultVersion;
|
|
66
|
+
if (stableStringify(supplied) !== stableStringify(expected)) {
|
|
67
|
+
throw new Error("Invalid bundle metadata");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { sealedBundle } from "../../contract/messages.js";
|
|
2
|
+
import { decrypt } from "./encryption.js";
|
|
3
|
+
import { deserialiseSealedRegistry } from "./deserialise.js";
|
|
4
|
+
import { sameNames, verifyBundleMetadata } from "./metadata.js";
|
|
5
|
+
import { verifyCompatibleRelease } from "./signature.js";
|
|
6
|
+
const authenticated = new WeakSet();
|
|
7
|
+
export function isOpenedBundle(registry) { return authenticated.has(registry); }
|
|
8
|
+
function freezeData(data) {
|
|
9
|
+
if (data && typeof data === "object") {
|
|
10
|
+
for (const child of Object.values(data))
|
|
11
|
+
freezeData(child);
|
|
12
|
+
Object.freeze(data);
|
|
13
|
+
}
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
16
|
+
export async function openBundle(value, options) {
|
|
17
|
+
const parsed = sealedBundle.safeParse(value);
|
|
18
|
+
if (!parsed.success)
|
|
19
|
+
throw new Error("Invalid sealed bundle");
|
|
20
|
+
const bundle = parsed.data;
|
|
21
|
+
verifyCompatibleRelease(bundle, options.verificationKey, options.relayVersion);
|
|
22
|
+
try {
|
|
23
|
+
const key = await options.keyService.unwrapKey(bundle.wrappedKey);
|
|
24
|
+
const { registry, fingerprintKey, policy } = deserialiseSealedRegistry(decrypt(bundle.sealed, bundle.iv, key));
|
|
25
|
+
if (Buffer.from(key).equals(fingerprintKey) || !sameNames(bundle.templates, registry.templates) || !sameNames(bundle.answerFormats, registry.answerFormats)) {
|
|
26
|
+
throw new Error();
|
|
27
|
+
}
|
|
28
|
+
verifyBundleMetadata(bundle.metadata, registry, fingerprintKey, policy);
|
|
29
|
+
const opened = Object.freeze({ ...registry, templates: freezeData(registry.templates), includes: freezeData(registry.includes),
|
|
30
|
+
descriptions: freezeData(registry.descriptions), answerFormats: Object.freeze(registry.answerFormats),
|
|
31
|
+
policy: freezeData(policy), bundleMetadata: freezeData(bundle) });
|
|
32
|
+
authenticated.add(opened);
|
|
33
|
+
return opened;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
throw new Error("Unable to open bundle");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { stableStringify } from "../../analysis-core/llm/stable-json.js";
|
|
2
|
+
import { id } from "../../contract/console.js";
|
|
3
|
+
/** Authenticated bundle metadata owns which planned templates and formats are available. */
|
|
4
|
+
export function checkPlannedCallsAgainstBundle(bundle, calls, policy) {
|
|
5
|
+
for (const { templateId, answerFormatId } of calls) {
|
|
6
|
+
id.parse(templateId);
|
|
7
|
+
id.parse(answerFormatId);
|
|
8
|
+
const template = Object.hasOwn(bundle.metadata.templates, templateId) ? bundle.metadata.templates[templateId] : undefined;
|
|
9
|
+
if (!bundle.templates.includes(templateId) || !bundle.answerFormats.includes(answerFormatId)
|
|
10
|
+
|| !template?.answerFormats.includes(answerFormatId))
|
|
11
|
+
throw new Error("Unsupported planned template or format");
|
|
12
|
+
if (policy !== undefined) {
|
|
13
|
+
const rule = Object.hasOwn(policy, templateId) ? policy[templateId] : undefined;
|
|
14
|
+
if (!rule || rule.role !== template.role || !rule.answerFormats.includes(answerFormatId)
|
|
15
|
+
|| stableStringify([...new Set(rule.answerFormats)].sort()) !== stableStringify([...new Set(template.answerFormats)].sort())) {
|
|
16
|
+
throw new Error("Runtime and sealed policy differ");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createHash, createPublicKey, sign, verify } from "node:crypto";
|
|
2
|
+
import { stableStringify } from "../../analysis-core/llm/stable-json.js";
|
|
3
|
+
export const RELEASE_SIGNING_INPUT_LIMIT = 64 * 1024;
|
|
4
|
+
/** Billing identifies the encrypted payload; publication receipts separately identify the full JSON file. */
|
|
5
|
+
export function bundleContentHash(sealed) {
|
|
6
|
+
return createHash("sha256").update(Buffer.from(sealed, "base64")).digest("hex");
|
|
7
|
+
}
|
|
8
|
+
function signingBytes(bundle) {
|
|
9
|
+
// One encoding serves both release tooling and the relay, independent of JSON key order on disk.
|
|
10
|
+
const fields = Object.fromEntries(Object.entries(bundle).filter(([name]) => name !== "signature"));
|
|
11
|
+
// The release key signs a fixed-size fingerprint, because the production key service signs at most 64 KiB
|
|
12
|
+
// and a sealed bundle is larger. The label keeps these signatures from being valid for anything else.
|
|
13
|
+
return createHash("sha256").update("counterfact sealed release v1\n").update(stableStringify(fields), "utf8").digest();
|
|
14
|
+
}
|
|
15
|
+
function checkKey(key) {
|
|
16
|
+
if (key.asymmetricKeyType !== "ed25519")
|
|
17
|
+
throw new Error("Expected an Ed25519 release key");
|
|
18
|
+
}
|
|
19
|
+
export function signRelease(bundle, key) {
|
|
20
|
+
checkKey(key);
|
|
21
|
+
return sign(null, signingBytes(bundle), key).toString("base64");
|
|
22
|
+
}
|
|
23
|
+
export function localReleaseSigner(key) {
|
|
24
|
+
checkKey(key);
|
|
25
|
+
return { publicKey: createPublicKey(key), async sign(bytes) { return sign(null, bytes, key); } };
|
|
26
|
+
}
|
|
27
|
+
export async function signReleaseWithSigner(release, signer) {
|
|
28
|
+
checkKey(signer.publicKey);
|
|
29
|
+
// Strict console metadata JSON cannot be a 32-byte bundle fingerprint, so the two formats cannot share a signature.
|
|
30
|
+
const bytes = Buffer.isBuffer(release) ? Buffer.from(release) : signingBytes(release);
|
|
31
|
+
if (bytes.byteLength > RELEASE_SIGNING_INPUT_LIMIT)
|
|
32
|
+
throw new Error("Release signing input exceeds 64 KiB");
|
|
33
|
+
const signature = await signer.sign(Buffer.from(bytes));
|
|
34
|
+
// A remote key reference can point at a different release key; catch that before publishing a bundle.
|
|
35
|
+
if (signature.byteLength !== 64 || !verify(null, bytes, signer.publicKey, signature))
|
|
36
|
+
throw new Error("Invalid release signature");
|
|
37
|
+
return signature.toString("base64");
|
|
38
|
+
}
|
|
39
|
+
export function verifyRelease(bundle, key) {
|
|
40
|
+
checkKey(key);
|
|
41
|
+
const signature = Buffer.from(bundle.signature, "base64");
|
|
42
|
+
if (signature.toString("base64") !== bundle.signature || !verify(null, signingBytes(bundle), key, signature)) {
|
|
43
|
+
throw new Error("Invalid bundle signature");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export function verifyCompatibleRelease(bundle, key, relayVersion) {
|
|
47
|
+
// Authenticate the advertised compatibility list before any caller relies on it or releases a key.
|
|
48
|
+
verifyRelease(bundle, key);
|
|
49
|
+
if (!bundle.relayVersions.includes(relayVersion))
|
|
50
|
+
throw new Error("Unsupported relay version");
|
|
51
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { resolveFolderPath } from "../adapters/folder-path.js";
|
|
2
|
+
import { START_FAILURE_MESSAGE } from "../contract/cli-refusals.js";
|
|
3
|
+
import { isAbsolute, parse, relative, resolve, sep } from "node:path";
|
|
4
|
+
export function resolveAgentFolder(path, cwd) {
|
|
5
|
+
return resolve(cwd ?? process.cwd(), path);
|
|
6
|
+
}
|
|
7
|
+
/** The MCP launch tree is the user's boundary for unattended paid work. */
|
|
8
|
+
export async function resolveMcpAgentFolder(path, cwd, homeDir) {
|
|
9
|
+
const [folder, launch, home] = await Promise.all([
|
|
10
|
+
resolveFolderPath(resolveAgentFolder(path, cwd)), resolveFolderPath(cwd), resolveFolderPath(homeDir),
|
|
11
|
+
]).catch(() => { throw new Error(START_FAILURE_MESSAGE); });
|
|
12
|
+
const rel = relative(launch, folder);
|
|
13
|
+
if (folder === parse(folder).root || folder === home || rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
|
|
14
|
+
throw new Error(START_FAILURE_MESSAGE);
|
|
15
|
+
}
|
|
16
|
+
return folder;
|
|
17
|
+
}
|
package/dist/cli/api.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ApiClient, ApiError, DEFAULT_URL, errorCode, errorText } from "../gatekeeper/cli-api.js";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
const servers = ["mcp__plugin_counterfact_counterfact", "mcp__counterfact"];
|
|
4
|
-
export const
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
export const ANALYZE_TOOL_NAME = "analyze_agent";
|
|
5
|
+
export const ANALYZE_TOOL_RULE = `${servers[0]}__${ANALYZE_TOOL_NAME}`;
|
|
6
|
+
const allowedRules = new Set(servers.flatMap(server => [server, `${server}__*`, `${server}__${ANALYZE_TOOL_NAME}`]));
|
|
7
|
+
export async function analyzeToolAllowed(homeDir, cwd) {
|
|
7
8
|
const paths = [join(homeDir, ".claude/settings.json"), join(cwd, ".claude/settings.json"), join(cwd, ".claude/settings.local.json")];
|
|
8
9
|
const matches = await Promise.all(paths.map(async (path) => {
|
|
9
10
|
try {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { loadDevelopmentRelay } from "../development-relay.js";
|
|
2
|
+
import { loadInstalledRelease } from "../../adapters/release.js";
|
|
3
|
+
import { cliRefusals, START_FAILURE_MESSAGE } from "../../contract/cli-refusals.js";
|
|
4
|
+
import { CLI_VERSION } from "../../contract/cli-version.js";
|
|
5
|
+
import { cliApiMessages } from "../../contract/cli-api-messages.js";
|
|
6
|
+
import { ApiError } from "../api.js";
|
|
7
|
+
import { resolveAgentFolder } from "../agent-folder.js";
|
|
8
|
+
import { runRelayCheck } from "../relay-check.js";
|
|
9
|
+
// Only a real pause says "paused"; an unreviewed release or an upload-only server cannot start.
|
|
10
|
+
const unavailable = START_FAILURE_MESSAGE;
|
|
11
|
+
function requireLocal(value) {
|
|
12
|
+
if (!value || typeof value !== "object" || !("mode" in value) || !("minimumLocalCliVersion" in value)
|
|
13
|
+
|| typeof value.minimumLocalCliVersion !== "string" || !/^\d+\.\d+\.\d+$/.test(value.minimumLocalCliVersion)) {
|
|
14
|
+
throw new Error(cliApiMessages.invalid_response);
|
|
15
|
+
}
|
|
16
|
+
const current = CLI_VERSION.split(".").map(BigInt), minimum = value.minimumLocalCliVersion.split(".").map(BigInt);
|
|
17
|
+
for (let i = 0; i < current.length; i++) {
|
|
18
|
+
if (minimum[i] > current[i])
|
|
19
|
+
throw new ApiError(426, "cli_update_required", cliRefusals.cli_update_required);
|
|
20
|
+
if (minimum[i] < current[i])
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
if (value.mode === "paused")
|
|
24
|
+
throw new ApiError(503, "local_checks_paused", cliRefusals.local_checks_paused);
|
|
25
|
+
// A local-capable client never falls back to sending source files to the hosted upload API.
|
|
26
|
+
if (value.mode !== "local")
|
|
27
|
+
throw new ApiError(503, "unavailable", unavailable);
|
|
28
|
+
}
|
|
29
|
+
export async function analyze(path, _options, ctx) {
|
|
30
|
+
const startup = ctx.startup;
|
|
31
|
+
requireLocal(await ctx.api.request("checks/mode"));
|
|
32
|
+
const development = startup.transport.CF_RELAY_DEV === "1" ? await loadDevelopmentRelay(startup.transport) : undefined;
|
|
33
|
+
const release = development?.release ?? ctx.relayRuntime?.release ?? await loadInstalledRelease();
|
|
34
|
+
if (release.projectContext !== "checks")
|
|
35
|
+
throw new Error(unavailable);
|
|
36
|
+
const token = await ctx.token?.();
|
|
37
|
+
if (!token)
|
|
38
|
+
throw new Error("Not signed in. Run counterfact-labs login.");
|
|
39
|
+
const folder = resolveAgentFolder(path, ctx.cwd);
|
|
40
|
+
const config = Object.freeze({ ...startup.transport, CF_RELAY_URL: startup.transport.CF_RELAY_URL ?? release.relayUrl,
|
|
41
|
+
CF_LOCAL_RELAY: "1", CF_CONSOLE_URL: ctx.api.baseUrl, CF_CONSOLE_TOKEN: token });
|
|
42
|
+
const controller = new AbortController();
|
|
43
|
+
const cancel = () => controller.abort();
|
|
44
|
+
process.once("SIGINT", cancel);
|
|
45
|
+
process.once("SIGTERM", cancel);
|
|
46
|
+
let progressShown = false;
|
|
47
|
+
const clearProgress = () => { if (progressShown) {
|
|
48
|
+
ctx.write("\r\u001b[2K");
|
|
49
|
+
progressShown = false;
|
|
50
|
+
} };
|
|
51
|
+
try {
|
|
52
|
+
return await (ctx.relayRuntime?.run ?? runRelayCheck)(folder, {
|
|
53
|
+
settings: startup.settings, config, release, connect: development?.connect ?? ctx.relayRuntime?.connect,
|
|
54
|
+
signal: ctx.signal ? AbortSignal.any([controller.signal, ctx.signal]) : controller.signal,
|
|
55
|
+
stdout() { }, stderr() { },
|
|
56
|
+
onStart: () => { ctx.onCheckStart?.(); ctx.write("\r\u001b[2KAnalyzing the agent…"); progressShown = true; },
|
|
57
|
+
onError: failure => {
|
|
58
|
+
clearProgress();
|
|
59
|
+
ctx.write(`${failure.message}\n`);
|
|
60
|
+
},
|
|
61
|
+
onSaved: result => {
|
|
62
|
+
clearProgress();
|
|
63
|
+
ctx.onCheckComplete?.(result);
|
|
64
|
+
if (result.findingIds?.length)
|
|
65
|
+
ctx.write(`Finding ids: ${result.findingIds.join(", ")}\n`);
|
|
66
|
+
ctx.write(`Full results: ${result.url}\n`);
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
clearProgress();
|
|
72
|
+
process.removeListener("SIGINT", cancel);
|
|
73
|
+
process.removeListener("SIGTERM", cancel);
|
|
74
|
+
}
|
|
75
|
+
}
|