@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.
Files changed (186) hide show
  1. package/README.md +176 -42
  2. package/bundle/client-release.json +7 -0
  3. package/bundle/sealed.json +908 -0
  4. package/dist/adapters/anthropic.js +151 -0
  5. package/dist/adapters/completion.js +112 -0
  6. package/dist/adapters/durable-write.js +34 -0
  7. package/dist/adapters/files.js +144 -0
  8. package/dist/adapters/folder-path.js +6 -0
  9. package/dist/adapters/git-ignore.js +49 -0
  10. package/dist/adapters/git.js +44 -0
  11. package/dist/adapters/ignored-files.js +36 -0
  12. package/dist/adapters/instructions.js +35 -0
  13. package/dist/adapters/models.js +51 -0
  14. package/dist/adapters/output-paths.js +92 -0
  15. package/dist/adapters/prompt-cache.js +28 -0
  16. package/dist/adapters/public-instructions.js +36 -0
  17. package/dist/adapters/quality.js +6 -0
  18. package/dist/adapters/relay-plan.js +15 -0
  19. package/dist/adapters/release.js +62 -0
  20. package/dist/adapters/report.js +29 -0
  21. package/dist/adapters/repository-files.js +199 -0
  22. package/dist/adapters/repository-root.js +120 -0
  23. package/dist/adapters/results.js +9 -0
  24. package/dist/adapters/settings.js +26 -0
  25. package/dist/adapters/snapshot.js +68 -0
  26. package/dist/analysis-core/analysis/analysis-flags.js +1 -0
  27. package/dist/analysis-core/analysis/code-agents/skipped-files.js +1 -0
  28. package/dist/analysis-core/analysis/finding-quality/config.js +1 -0
  29. package/dist/analysis-core/analysis/finding-quality/policy.js +1 -0
  30. package/dist/analysis-core/analysis/headlines/attachment.js +1 -0
  31. package/dist/analysis-core/analysis/headlines/input.js +1 -0
  32. package/dist/analysis-core/analysis/headlines/types.js +1 -0
  33. package/dist/analysis-core/analysis/schemas.js +1 -0
  34. package/dist/analysis-core/analysis/source-notes/types.js +1 -0
  35. package/dist/analysis-core/chunks/2PSNOSJ2.js +1 -0
  36. package/dist/analysis-core/chunks/3227KXHF.js +1 -0
  37. package/dist/analysis-core/chunks/326F4XNG.js +1 -0
  38. package/dist/analysis-core/chunks/3CKW5JIF.js +1 -0
  39. package/dist/analysis-core/chunks/3GUKUEEJ.js +1 -0
  40. package/dist/analysis-core/chunks/3MTXB4MK.js +6 -0
  41. package/dist/analysis-core/chunks/4F6ZIHXU.js +1 -0
  42. package/dist/analysis-core/chunks/57M4OQJM.js +1 -0
  43. package/dist/analysis-core/chunks/6YCABS5T.js +1 -0
  44. package/dist/analysis-core/chunks/724WZMYW.js +2 -0
  45. package/dist/analysis-core/chunks/74FPPPIG.js +1 -0
  46. package/dist/analysis-core/chunks/7OYIBWX3.js +1 -0
  47. package/dist/analysis-core/chunks/D6AWHLRI.js +1 -0
  48. package/dist/analysis-core/chunks/DRGDIIFA.js +1 -0
  49. package/dist/analysis-core/chunks/E7TFIHC5.js +1 -0
  50. package/dist/analysis-core/chunks/EH3QQ3T4.js +1 -0
  51. package/dist/analysis-core/chunks/FSLWD2PE.js +1 -0
  52. package/dist/analysis-core/chunks/FTODBFQW.js +1 -0
  53. package/dist/analysis-core/chunks/HPIAEQHE.js +37 -0
  54. package/dist/analysis-core/chunks/HTLIRVP7.js +1 -0
  55. package/dist/analysis-core/chunks/IBCFGUHI.js +1 -0
  56. package/dist/analysis-core/chunks/IVDDV6CU.js +14 -0
  57. package/dist/analysis-core/chunks/J4AXGE5W.js +1 -0
  58. package/dist/analysis-core/chunks/JF4GYMOZ.js +1 -0
  59. package/dist/analysis-core/chunks/JKWTHRUR.js +1 -0
  60. package/dist/analysis-core/chunks/K5OTWBTT.js +22 -0
  61. package/dist/analysis-core/chunks/KU5DINLW.js +1 -0
  62. package/dist/analysis-core/chunks/MJGB25S5.js +1 -0
  63. package/dist/analysis-core/chunks/MXXNED6N.js +7 -0
  64. package/dist/analysis-core/chunks/NCWEOJVJ.js +6 -0
  65. package/dist/analysis-core/chunks/O652FQQH.js +1 -0
  66. package/dist/analysis-core/chunks/OFBJNHC6.js +1 -0
  67. package/dist/analysis-core/chunks/PYKAERZZ.js +1 -0
  68. package/dist/analysis-core/chunks/QDYMR6KS.js +1 -0
  69. package/dist/analysis-core/chunks/QMIXCT62.js +1 -0
  70. package/dist/analysis-core/chunks/QV2EOS7U.js +1 -0
  71. package/dist/analysis-core/chunks/SL27GMEN.js +1 -0
  72. package/dist/analysis-core/chunks/STZOC7LN.js +1 -0
  73. package/dist/analysis-core/chunks/T2SAP7OV.js +60 -0
  74. package/dist/analysis-core/chunks/T5TREZCQ.js +1 -0
  75. package/dist/analysis-core/chunks/T66VDFXF.js +1 -0
  76. package/dist/analysis-core/chunks/TDNTU4TF.js +1 -0
  77. package/dist/analysis-core/chunks/U5HOEVPE.js +1 -0
  78. package/dist/analysis-core/chunks/UEWL3GMQ.js +1 -0
  79. package/dist/analysis-core/chunks/V7BFUTM7.js +1 -0
  80. package/dist/analysis-core/chunks/VGYWI4X2.js +1 -0
  81. package/dist/analysis-core/chunks/Y7JGSUOA.js +1 -0
  82. package/dist/analysis-core/chunks/ZAA44GPI.js +1 -0
  83. package/dist/analysis-core/contracts/requests.js +1 -0
  84. package/dist/analysis-core/conventions/analysis-fit.js +1 -0
  85. package/dist/analysis-core/conventions/file-admission.js +1 -0
  86. package/dist/analysis-core/data/finding-types.js +1 -0
  87. package/dist/analysis-core/errors.js +1 -0
  88. package/dist/analysis-core/findings/presentation.js +1 -0
  89. package/dist/analysis-core/github/repo-key.js +1 -0
  90. package/dist/analysis-core/import/outside-loader-sources.js +1 -0
  91. package/dist/analysis-core/index.js +6 -0
  92. package/dist/analysis-core/llm/cache-policy.js +1 -0
  93. package/dist/analysis-core/llm/cost.js +1 -0
  94. package/dist/analysis-core/llm/execution.js +1 -0
  95. package/dist/analysis-core/llm/output-limit.js +1 -0
  96. package/dist/analysis-core/llm/slots.js +1 -0
  97. package/dist/analysis-core/llm/stable-json.js +1 -0
  98. package/dist/analysis-core/llm/structured-output-error.js +1 -0
  99. package/dist/analysis-core/map-limit.js +1 -0
  100. package/dist/analysis-core/requests/answer-formats.js +1 -0
  101. package/dist/analysis-core/requests/check-diagnostics.js +1 -0
  102. package/dist/analysis-core/requests/headline-request.js +1 -0
  103. package/dist/analysis-core/requests/instruction-text.js +1 -0
  104. package/dist/analysis-core/requests/local-plan.js +1 -0
  105. package/dist/analysis-core/requests/registry.js +1 -0
  106. package/dist/analysis-core/requests/schema-descriptions.js +1 -0
  107. package/dist/analysis-core/requests/shape-finding-input.js +1 -0
  108. package/dist/analysis-core/requests/template-version.js +1 -0
  109. package/dist/analysis-core/requests/tools.js +1 -0
  110. package/dist/analysis-core/settings.js +1 -0
  111. package/dist/bundle/seal/deserialise.js +75 -0
  112. package/dist/bundle/seal/encryption.js +25 -0
  113. package/dist/bundle/seal/metadata.js +69 -0
  114. package/dist/bundle/seal/open.js +38 -0
  115. package/dist/bundle/seal/planned-calls.js +20 -0
  116. package/dist/bundle/seal/signature.js +51 -0
  117. package/dist/cli/agent-folder.js +17 -0
  118. package/dist/cli/api-types.js +2 -0
  119. package/dist/cli/api.js +1 -0
  120. package/dist/{claude-code-permission.js → cli/claude-code-permission.js} +4 -3
  121. package/dist/cli/commands/analyze.js +75 -0
  122. package/dist/cli/commands/login.js +51 -0
  123. package/dist/cli/completion-recovery.js +18 -0
  124. package/dist/{context.js → cli/context.js} +8 -14
  125. package/dist/cli/development-relay.js +34 -0
  126. package/dist/cli/email-sign-in.js +56 -0
  127. package/dist/{git.js → cli/git.js} +12 -8
  128. package/dist/cli/intake-payload.js +18 -0
  129. package/dist/{main.js → cli/main.js} +23 -12
  130. package/dist/{mcp.js → cli/mcp.js} +109 -40
  131. package/dist/cli/output.js +10 -0
  132. package/dist/cli/relay-check.js +239 -0
  133. package/dist/cli/relay-preparation.js +33 -0
  134. package/dist/cli/sign-in-input.js +97 -0
  135. package/dist/{sign-in.js → cli/sign-in.js} +2 -1
  136. package/dist/cli/suggested-email.js +10 -0
  137. package/dist/cli/summary.js +30 -0
  138. package/dist/contract/cli-api-messages.js +5 -0
  139. package/dist/contract/cli-refusals.js +24 -0
  140. package/dist/contract/cli-version.js +1 -0
  141. package/dist/contract/console-url.js +8 -0
  142. package/dist/contract/console.js +131 -0
  143. package/dist/contract/email-sign-in-messages.js +18 -0
  144. package/dist/contract/messages.js +252 -0
  145. package/dist/contract/release-key.js +2 -0
  146. package/dist/contract/runtime-environment.js +37 -0
  147. package/dist/core/analysis/finding-quality/config.js +4 -0
  148. package/dist/core/analysis/run-to-end.js +55 -0
  149. package/dist/core/analysis/structural-run.js +16 -0
  150. package/dist/gatekeeper/attestation.js +67 -0
  151. package/dist/gatekeeper/certificate-algorithms.js +18 -0
  152. package/dist/gatekeeper/certificate-path.js +99 -0
  153. package/dist/gatekeeper/cli-api.js +174 -0
  154. package/dist/gatekeeper/client.js +76 -0
  155. package/dist/gatekeeper/connection-exchange.js +61 -0
  156. package/dist/gatekeeper/connection.js +140 -0
  157. package/dist/gatekeeper/console.js +175 -0
  158. package/dist/gatekeeper/loopback.js +5 -0
  159. package/dist/gatekeeper/model.js +70 -0
  160. package/dist/gatekeeper/production-attestation.js +149 -0
  161. package/dist/gatekeeper/trust/hardware.js +21 -0
  162. package/dist/gatekeeper/trust/policy.js +42 -0
  163. package/dist/gatekeeper/trust/production.json +25 -0
  164. package/dist/setup-pings/client.js +31 -0
  165. package/dist/setup-pings/contract.js +2 -0
  166. package/dist/setup-pings/policy.js +3 -0
  167. package/dist/setup-pings/state.js +261 -0
  168. package/dist/setup-pings/worker.js +95 -0
  169. package/dist/transport/base64url.js +9 -0
  170. package/dist/transport/http-response.js +89 -0
  171. package/dist/transport/tls-exporter.js +5 -0
  172. package/package.json +57 -11
  173. package/LICENSE +0 -1
  174. package/dist/api-types.js +0 -2
  175. package/dist/api.js +0 -97
  176. package/dist/commands/check.js +0 -104
  177. package/dist/commands/login.js +0 -9
  178. package/dist/files.js +0 -99
  179. package/dist/gitignore.js +0 -70
  180. package/dist/output.js +0 -23
  181. package/dist/secret-files.js +0 -5
  182. /package/dist/{browser.js → cli/browser.js} +0 -0
  183. /package/dist/{commands → cli/commands}/balance.js +0 -0
  184. /package/dist/{commands → cli/commands}/finding.js +0 -0
  185. /package/dist/{commands → cli/commands}/logout.js +0 -0
  186. /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
+ }
@@ -0,0 +1,2 @@
1
+ // Keep the copied command API contract self-contained.
2
+ export const CLI_BODY_LIMIT = 2 * 1024 * 1024;
@@ -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 CHECK_TOOL_RULE = `${servers[0]}__check_agent`;
5
- const allowedRules = new Set(servers.flatMap(server => [server, `${server}__*`, `${server}__check_agent`]));
6
- export async function checkToolAllowed(homeDir, cwd) {
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
+ }