@counterfact-labs/cli 0.2.10 → 0.2.11

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 (118) hide show
  1. package/README.md +4 -5
  2. package/bundle/client-release.json +1 -1
  3. package/dist/adapters/analysis-results.js +10 -5
  4. package/dist/adapters/completion.js +75 -41
  5. package/dist/adapters/config-directory.js +5 -0
  6. package/dist/adapters/files.js +25 -10
  7. package/dist/adapters/legacy-reports.js +48 -0
  8. package/dist/adapters/output-paths.js +85 -5
  9. package/dist/adapters/result-receipt.js +78 -0
  10. package/dist/adapters/results.js +5 -8
  11. package/dist/adapters/settings.js +10 -4
  12. package/dist/adapters/storage-identity.js +27 -0
  13. package/dist/analysis-core/analysis/code-agents/skipped-files.js +1 -1
  14. package/dist/analysis-core/analysis/file-analysis-plan.js +1 -1
  15. package/dist/analysis-core/analysis/file-dependencies.js +1 -1
  16. package/dist/analysis-core/analysis/finding-quality/policy.js +1 -1
  17. package/dist/analysis-core/analysis/folder-analysis-plan.js +1 -1
  18. package/dist/analysis-core/analysis/passes/full-file-passes.js +1 -1
  19. package/dist/analysis-core/analysis/schemas.js +1 -1
  20. package/dist/analysis-core/chunks/{5VQ4VYIP.js → 2IQN26TC.js} +1 -1
  21. package/dist/analysis-core/chunks/{N2L4JMJE.js → 2J3PWUPG.js} +1 -1
  22. package/dist/analysis-core/chunks/{3GUKUEEJ.js → 5JG3ZRNJ.js} +1 -1
  23. package/dist/analysis-core/chunks/{LFJQ4YLP.js → 6E4K7JTI.js} +1 -1
  24. package/dist/analysis-core/chunks/{66JRJPJC.js → 6W6B7VSP.js} +1 -1
  25. package/dist/analysis-core/chunks/{P253B344.js → AIS3FHQR.js} +7 -7
  26. package/dist/analysis-core/chunks/{YWL52FVW.js → EJ2IZUN2.js} +2 -2
  27. package/dist/analysis-core/chunks/{5UWDUYHF.js → GOBOE2SC.js} +1 -1
  28. package/dist/analysis-core/chunks/GYXDN5W4.js +1 -0
  29. package/dist/analysis-core/chunks/GZSUTDGX.js +1 -0
  30. package/dist/analysis-core/chunks/HB5BTGTI.js +6 -0
  31. package/dist/analysis-core/chunks/HH3HDT5K.js +73 -0
  32. package/dist/analysis-core/chunks/{TA2NIQAY.js → I5F7S63K.js} +1 -1
  33. package/dist/analysis-core/chunks/ICJV6KIZ.js +11 -0
  34. package/dist/analysis-core/chunks/{2CWULBP2.js → JCVB6IC4.js} +1 -1
  35. package/dist/analysis-core/chunks/{DHVEGIU6.js → JLW44GIU.js} +1 -1
  36. package/dist/analysis-core/chunks/JS6HTVYX.js +1 -0
  37. package/dist/analysis-core/chunks/{UKX3A6AX.js → JWQXG5RB.js} +1 -1
  38. package/dist/analysis-core/chunks/LOODGUMW.js +1 -0
  39. package/dist/analysis-core/chunks/{XVGLY4EO.js → NWYNJHY4.js} +1 -1
  40. package/dist/analysis-core/chunks/{KBTM5MBC.js → OHDC3L6V.js} +1 -1
  41. package/dist/analysis-core/chunks/OXGKALKM.js +1 -0
  42. package/dist/analysis-core/chunks/{MJGB25S5.js → P5FCHJ7W.js} +1 -1
  43. package/dist/analysis-core/chunks/PISOGSJF.js +1 -0
  44. package/dist/analysis-core/chunks/{6VHZNBII.js → QENYFKG3.js} +8 -8
  45. package/dist/analysis-core/chunks/{W73WF226.js → QY57UR6E.js} +1 -1
  46. package/dist/analysis-core/chunks/QYYN4YKB.js +35 -0
  47. package/dist/analysis-core/chunks/UYG422QR.js +0 -0
  48. package/dist/analysis-core/chunks/V7GZHSVR.js +1 -0
  49. package/dist/analysis-core/chunks/{VWRFSVLI.js → VBGQKYIT.js} +1 -1
  50. package/dist/analysis-core/chunks/{5BTATES5.js → VVSHUUWX.js} +1 -1
  51. package/dist/analysis-core/chunks/{JKWTHRUR.js → YDSB7UOR.js} +1 -1
  52. package/dist/analysis-core/chunks/ZLUI3EHB.js +1 -0
  53. package/dist/analysis-core/contracts/execution-request.js +1 -1
  54. package/dist/analysis-core/contracts/model-errors.js +1 -0
  55. package/dist/analysis-core/contracts/relay-analysis.js +1 -1
  56. package/dist/analysis-core/contracts/requests.js +1 -1
  57. package/dist/analysis-core/conventions/analysis-fit.js +1 -1
  58. package/dist/analysis-core/conventions/file-admission.js +1 -1
  59. package/dist/analysis-core/errors.js +1 -1
  60. package/dist/analysis-core/import/calls/modules.js +1 -1
  61. package/dist/analysis-core/import/entry-selection.js +1 -1
  62. package/dist/analysis-core/import/outside-loader-sources.js +1 -1
  63. package/dist/analysis-core/index.js +1 -1
  64. package/dist/analysis-core/llm/cache-policy.js +1 -1
  65. package/dist/analysis-core/llm/cost.js +1 -1
  66. package/dist/analysis-core/llm/structured-output-error.js +1 -1
  67. package/dist/analysis-core/requests/frame-budget.js +1 -0
  68. package/dist/analysis-core/requests/local-plan.js +1 -1
  69. package/dist/analysis-core/requests/planned-limits.js +1 -1
  70. package/dist/analysis-core/requests/registry.js +1 -1
  71. package/dist/analysis-core/requests/template-version.js +1 -1
  72. package/dist/analysis-core/requests/tools.js +1 -1
  73. package/dist/analysis-core/settings.js +1 -1
  74. package/dist/analysis-core/stages/engine-entry.js +1 -1
  75. package/dist/analysis-core/wording.js +1 -0
  76. package/dist/cli/analysis-preview.js +22 -0
  77. package/dist/cli/analysis-selection.js +6 -8
  78. package/dist/cli/commands/analyze.js +27 -21
  79. package/dist/cli/commands/login.js +5 -0
  80. package/dist/cli/compatibility.js +39 -0
  81. package/dist/cli/completion-delivery.js +4 -3
  82. package/dist/cli/completion-recovery.js +25 -23
  83. package/dist/cli/credentials.js +3 -2
  84. package/dist/cli/finding-display.js +3 -2
  85. package/dist/cli/git.js +5 -2
  86. package/dist/cli/main.js +8 -2
  87. package/dist/cli/mcp.js +35 -10
  88. package/dist/cli/prior-completion.js +1 -1
  89. package/dist/cli/relay-check.js +85 -23
  90. package/dist/cli/relay-failure.js +19 -11
  91. package/dist/cli/relay-preparation.js +6 -3
  92. package/dist/cli/scope-choices.js +5 -4
  93. package/dist/cli/skipped-files.js +2 -1
  94. package/dist/cli/suggested-email.js +6 -1
  95. package/dist/cli/summary.js +2 -1
  96. package/dist/contract/agent-choice.js +2 -0
  97. package/dist/contract/cli-refusals.js +105 -9
  98. package/dist/contract/cli-version.js +1 -1
  99. package/dist/contract/console.js +2 -1
  100. package/dist/contract/email-sign-in-messages.js +2 -1
  101. package/dist/contract/scope-choice.js +4 -1
  102. package/dist/gatekeeper/client.js +11 -2
  103. package/dist/gatekeeper/connection-exchange.js +19 -4
  104. package/dist/gatekeeper/connection.js +15 -6
  105. package/dist/gatekeeper/console.js +8 -4
  106. package/dist/gatekeeper/model.js +13 -3
  107. package/package.json +1 -1
  108. package/dist/adapters/gitignore-output.js +0 -41
  109. package/dist/analysis-core/chunks/2M55DR2J.js +0 -35
  110. package/dist/analysis-core/chunks/34NVU26H.js +0 -1
  111. package/dist/analysis-core/chunks/C77LGCKF.js +0 -1
  112. package/dist/analysis-core/chunks/HCPO6QPU.js +0 -1
  113. package/dist/analysis-core/chunks/J4AXGE5W.js +0 -1
  114. package/dist/analysis-core/chunks/M5YWJY7P.js +0 -1
  115. package/dist/analysis-core/chunks/NCW5LJ5O.js +0 -6
  116. package/dist/analysis-core/chunks/QPIBHTON.js +0 -67
  117. package/dist/analysis-core/chunks/SJESFYBA.js +0 -10
  118. package/dist/analysis-core/chunks/VC3PYT2B.js +0 -1
@@ -1,4 +1,4 @@
1
- import{a as yr,d as J,e as br,f as Fr}from"./chunks/66JRJPJC.js";import{$ as _e,I as xr,J as Er,K as wr,L as Ar,M as Rr,N as Cr,O as ye,P as xe,Q as B,R as j,S as Ee,T as we,U as D,W as Ae,X as Re,Y as W,Z as Ce,_ as be,aa as Y,ba as _r,ca as ve,da as Fe,ea as ke,fa as Ie,ga as Oe,ha as Te,ka as vr,qa as kr,sa as Ir,ua as Or,wa as Tr,ya as Lr}from"./chunks/QPIBHTON.js";import{a as X}from"./chunks/5VQ4VYIP.js";import{a as hr,d as Se,k as gr,l as Sr}from"./chunks/KBTM5MBC.js";import"./chunks/Y7JGSUOA.js";import"./chunks/3MTXB4MK.js";import"./chunks/N2L4JMJE.js";import"./chunks/6JTHFDH3.js";import"./chunks/HTLIRVP7.js";import"./chunks/N7U5N42V.js";import{a as $}from"./chunks/QDYMR6KS.js";import{b as ur}from"./chunks/E7TFIHC5.js";import"./chunks/4F6ZIHXU.js";import"./chunks/VGYWI4X2.js";import"./chunks/57M4OQJM.js";import"./chunks/J4AXGE5W.js";import"./chunks/IBCFGUHI.js";import"./chunks/DZZBQDGO.js";import{a as dr,b as fr,c as pr}from"./chunks/C77LGCKF.js";import"./chunks/XVGLY4EO.js";import{l as mr}from"./chunks/6VHZNBII.js";import{f as ge,u as nr,v as ir,w as cr,x as ar,y as lr}from"./chunks/LFJQ4YLP.js";import{a as U}from"./chunks/326F4XNG.js";import{a as or,b as tr,c as sr}from"./chunks/UKX3A6AX.js";import"./chunks/KU5DINLW.js";import{a as We,c as Ye,f as Ge,g as Qe,h as Ve,i as Ze,k as er}from"./chunks/SP6XFHNH.js";import{a as rr}from"./chunks/PBHHWFR6.js";import{b as k}from"./chunks/HCPO6QPU.js";import"./chunks/NCW5LJ5O.js";import"./chunks/DHVEGIU6.js";import"./chunks/2CWULBP2.js";import{a as he}from"./chunks/5UWDUYHF.js";import{a as je,c as z,g as De,h as Z}from"./chunks/VC3PYT2B.js";import{r as pe}from"./chunks/P253B344.js";import{d as ue}from"./chunks/W73WF226.js";import"./chunks/6YCABS5T.js";import"./chunks/M5YWJY7P.js";import"./chunks/M6HYSTQD.js";import{a as b,d as me}from"./chunks/4H23CSUM.js";import"./chunks/VWRFSVLI.js";import"./chunks/VX6LYNXV.js";import{c as C}from"./chunks/MJGB25S5.js";import"./chunks/TA2NIQAY.js";import"./chunks/34NVU26H.js";import"./chunks/CNQZLSAP.js";import"./chunks/QVXARKP7.js";import{Fb as L,Jb as fe,Kb as I,Lb as M,Ma as ce,Ra as ae,Ya as le,ab as de,i as ee,p as te,r as se}from"./chunks/2M55DR2J.js";import"./chunks/74FPPPIG.js";import{a as re}from"./chunks/MKYLK6DB.js";import"./chunks/5TATKWLG.js";import{f as T,i as ne,n as ie}from"./chunks/JKWTHRUR.js";import{a as Je,b as q}from"./chunks/3GUKUEEJ.js";import"./chunks/JAPVLU4Z.js";import"./chunks/I4F56VMG.js";import"./chunks/33EUZF25.js";import"./chunks/YUY436SM.js";import{a as oe,c as O}from"./chunks/C6X5GDG4.js";import{b as V}from"./chunks/724WZMYW.js";import"./chunks/YWL52FVW.js";import{i as $e,j as Xe}from"./chunks/SJESFYBA.js";import{a as He,b as Ke,c as ze,d as qe,e as Ue}from"./chunks/RUVMFAST.js";import"./chunks/S27VIQMZ.js";import"./chunks/INVTU73D.js";import"./chunks/A7WJJMRY.js";import"./chunks/Q5WR6B2H.js";import"./chunks/VDUFPTDD.js";function Mr(o){return o?.fromProposal===0&&o.rejected>0}var Nr=new Set;function Pr(o,e={}){let s=oe(e.dir),a=e.limits??re.archive,t=e.listing??Nr,n={commit:null,files:new Map,skipped:[]},f=new Set,y=0,h=0;function m(c){let d=c.replace(/\/$/,"").split("/");return!c.startsWith("/")&&!c.includes("\\")&&!/^[a-z]:/i.test(c)&&!d.some(u=>u===".."||u==="."||!u)}function l(c,d,u,r=t){if(!u||!m(c)||!Number.isSafeInteger(d)||d<0)return"refused";let i=L(o,{path:c,size:d},{purpose:"archive",route:"github",root:s});return i.admitted?e.exampleFolders?.some(E=>c.startsWith(E))||se(c,{root:s,listing:r})?"example":null:i.reason==="excluded"&&te(o,c,s)?"example":i.reason==="excluded"||i.reason==="wrong-type"?"excluded":"refused"}function p(c,d){f.has(c)||(f.add(c),n.skipped.push({path:c,reason:d}))}function g(c,d=t){let u=c.split("/");for(let r=1;r<=u.length;r++){let i=u.slice(0,r).join("/");if(i===s||s.startsWith(`${i}/`))continue;if(O(i,s)===null)return!1;let E=l(`${i}/`,0,!0,d);if(E)return p(`${i}/`,E),!1}return!0}function S(c,d,u=!0){if(O(c,s)===null)return!1;if(!m(c))return p(c,"refused"),!1;let r=c.split("/");if(r.length>1&&!g(r.slice(0,-1).join("/")))return!1;let i=l(c,d,u);return i?(p(c,i),!1):h>=a.files||d>a.bytes-y?(p(c,"over-limit"),!1):(y+=d,h++,!0)}return{result:n,accept:S,enterFolder:g}}function Le(o){return o.CF_MODEL_READER!=="0"}async function Br(o,e,s,a){s=I(o,s);let t=structuredClone(e);for(t.files??={},t.cursor=0;;){let n=await D(o,t,s,a);if(n){t=n;continue}let f=t.selected??[];if((t.cursor??0)>=f.length)return t;let y=f.slice(t.cursor).filter(l=>!Object.hasOwn(t.files,l.path)),h=[],m=await U(y,4,async l=>{try{return{path:l.path,text:await B(l,p=>s.read(p),h,t.refused)}}catch(p){return{error:p}}});for(let l of m){if("error"in l)throw l.error;l.text!==null&&(t.files[l.path]=l.text)}h.length&&(t.refused=k(t.refused,h)),t.cursor=f.length}}async function Me(o,e,s,a){let{codeFindingNote:t}=Se(a),n={deriveBytes:0,codeEvidence:[]};if(!e.findingQuality?.config.switches.codeInputs||!e.projectAgents?.enabled)return n;let f=e.projectAgents,y=(e.repos??[]).filter(r=>[...f.byRepo[r.key]??[],...f.codeByRepo?.[r.key]??[]].some(i=>i.codeInputsJson&&(i.codeInputsJson.tools.length||i.codeInputsJson.contextInputs.length))),m=(await U(y,1,async r=>{try{let i=s.find(E=>E.repoKey===r.key);if(!i)throw new Error("Source reader is missing.");return{repo:await Br(o,r,i,e.modelReader??!1)}}catch(i){return{error:i}}})).map(r=>{if("error"in r)throw r.error;return r.repo}),l=m.map(r=>{let i=Ae(o,r,j(o,e),e.modelReader,f);return Object.assign(r.files,i.virtualFiles),i.fragment}),p=Object.fromEntries(m.map(r=>[r.key,r.files??{}])),S=Re({...e,repos:m,mapped:l}).findingQuality?.codeEvidence?.filter(r=>Object.keys(r.input.files).length)??[];if(!S.length)return n;let c=S.map(r=>({repo:r.repo,unitKey:r.unitKey,enabled:!0,inputs:[r.input],files:p[r.repo]}));return{deriveBytes:[...new Map(S.flatMap(r=>Object.entries(r.input.files).map(([i,E])=>[JSON.stringify([r.repo,i]),{path:i,text:E}]))).values()].reduce((r,{path:i,text:E})=>r+Buffer.byteLength(`### ${i}
1
+ import{a as yr,d as J,e as br,f as Fr}from"./chunks/6W6B7VSP.js";import{$ as _e,I as xr,J as Er,K as wr,L as Ar,M as Rr,N as Cr,O as ye,P as xe,Q as B,R as j,S as Ee,T as we,U as D,W as Ae,X as Re,Y as W,Z as Ce,_ as be,aa as Y,ba as _r,ca as ve,da as Fe,ea as ke,fa as Ie,ga as Oe,ha as Te,ka as vr,qa as kr,sa as Ir,ua as Or,wa as Tr,ya as Lr}from"./chunks/HH3HDT5K.js";import{a as X}from"./chunks/2IQN26TC.js";import{a as hr,d as Se,k as gr,l as Sr}from"./chunks/OHDC3L6V.js";import"./chunks/Y7JGSUOA.js";import"./chunks/3MTXB4MK.js";import"./chunks/2J3PWUPG.js";import"./chunks/UYG422QR.js";import"./chunks/6JTHFDH3.js";import"./chunks/HTLIRVP7.js";import"./chunks/GYXDN5W4.js";import"./chunks/N7U5N42V.js";import{a as $}from"./chunks/QDYMR6KS.js";import{b as ur}from"./chunks/E7TFIHC5.js";import"./chunks/NWYNJHY4.js";import{l as mr}from"./chunks/QENYFKG3.js";import"./chunks/4F6ZIHXU.js";import"./chunks/VGYWI4X2.js";import"./chunks/57M4OQJM.js";import"./chunks/IBCFGUHI.js";import"./chunks/DZZBQDGO.js";import{a as dr,b as fr,c as pr}from"./chunks/V7GZHSVR.js";import{f as ge,u as nr,v as ir,w as cr,x as ar,y as lr}from"./chunks/6E4K7JTI.js";import{a as U}from"./chunks/326F4XNG.js";import{a as or,b as tr,c as sr}from"./chunks/JWQXG5RB.js";import"./chunks/KU5DINLW.js";import{a as We,c as Ye,f as Ge,g as Qe,h as Ve,i as Ze,k as er}from"./chunks/SP6XFHNH.js";import{a as rr}from"./chunks/PBHHWFR6.js";import{b as k}from"./chunks/PISOGSJF.js";import"./chunks/HB5BTGTI.js";import"./chunks/JLW44GIU.js";import"./chunks/JCVB6IC4.js";import{a as he}from"./chunks/GOBOE2SC.js";import{r as pe}from"./chunks/AIS3FHQR.js";import{d as ue}from"./chunks/QY57UR6E.js";import"./chunks/6YCABS5T.js";import"./chunks/GZSUTDGX.js";import"./chunks/M6HYSTQD.js";import{a as b,d as me}from"./chunks/4H23CSUM.js";import"./chunks/VBGQKYIT.js";import"./chunks/VX6LYNXV.js";import{c as C}from"./chunks/P5FCHJ7W.js";import"./chunks/I5F7S63K.js";import"./chunks/QVXARKP7.js";import{Fb as L,Jb as fe,Kb as I,Lb as M,Ma as ce,Ra as ae,Ya as le,ab as de,i as ee,p as te,r as se}from"./chunks/QYYN4YKB.js";import"./chunks/74FPPPIG.js";import{c as je,e as z,k as De,l as Z}from"./chunks/LOODGUMW.js";import{a as re}from"./chunks/MKYLK6DB.js";import"./chunks/5TATKWLG.js";import{f as T,i as ne,n as ie}from"./chunks/YDSB7UOR.js";import{a as Je,b as q}from"./chunks/5JG3ZRNJ.js";import"./chunks/ZLUI3EHB.js";import"./chunks/JAPVLU4Z.js";import"./chunks/OXGKALKM.js";import"./chunks/CNQZLSAP.js";import"./chunks/I4F56VMG.js";import"./chunks/33EUZF25.js";import"./chunks/YUY436SM.js";import{a as oe,c as O}from"./chunks/C6X5GDG4.js";import{b as V}from"./chunks/724WZMYW.js";import"./chunks/JS6HTVYX.js";import"./chunks/EJ2IZUN2.js";import{j as $e,k as Xe}from"./chunks/ICJV6KIZ.js";import{a as He,b as Ke,c as ze,d as qe,e as Ue}from"./chunks/RUVMFAST.js";import"./chunks/S27VIQMZ.js";import"./chunks/INVTU73D.js";import"./chunks/A7WJJMRY.js";import"./chunks/Q5WR6B2H.js";import"./chunks/VDUFPTDD.js";function Mr(o){return o?.fromProposal===0&&o.rejected>0}var Nr=new Set;function Pr(o,e={}){let s=oe(e.dir),a=e.limits??re.archive,t=e.listing??Nr,n={commit:null,files:new Map,skipped:[]},f=new Set,y=0,h=0;function m(c){let d=c.replace(/\/$/,"").split("/");return!c.startsWith("/")&&!c.includes("\\")&&!/^[a-z]:/i.test(c)&&!d.some(u=>u===".."||u==="."||!u)}function l(c,d,u,r=t){if(!u||!m(c)||!Number.isSafeInteger(d)||d<0)return"refused";let i=L(o,{path:c,size:d},{purpose:"archive",route:"github",root:s});return i.admitted?e.exampleFolders?.some(E=>c.startsWith(E))||se(c,{root:s,listing:r})?"example":null:i.reason==="excluded"&&te(o,c,s)?"example":i.reason==="excluded"||i.reason==="wrong-type"?"excluded":"refused"}function p(c,d){f.has(c)||(f.add(c),n.skipped.push({path:c,reason:d}))}function g(c,d=t){let u=c.split("/");for(let r=1;r<=u.length;r++){let i=u.slice(0,r).join("/");if(i===s||s.startsWith(`${i}/`))continue;if(O(i,s)===null)return!1;let E=l(`${i}/`,0,!0,d);if(E)return p(`${i}/`,E),!1}return!0}function S(c,d,u=!0){if(O(c,s)===null)return!1;if(!m(c))return p(c,"refused"),!1;let r=c.split("/");if(r.length>1&&!g(r.slice(0,-1).join("/")))return!1;let i=l(c,d,u);return i?(p(c,i),!1):h>=a.files||d>a.bytes-y?(p(c,"over-limit"),!1):(y+=d,h++,!0)}return{result:n,accept:S,enterFolder:g}}function Le(o){return o.CF_MODEL_READER!=="0"}async function Br(o,e,s,a){s=I(o,s);let t=structuredClone(e);for(t.files??={},t.cursor=0;;){let n=await D(o,t,s,a);if(n){t=n;continue}let f=t.selected??[];if((t.cursor??0)>=f.length)return t;let y=f.slice(t.cursor).filter(l=>!Object.hasOwn(t.files,l.path)),h=[],m=await U(y,4,async l=>{try{return{path:l.path,text:await B(l,p=>s.read(p),h,t.refused)}}catch(p){return{error:p}}});for(let l of m){if("error"in l)throw l.error;l.text!==null&&(t.files[l.path]=l.text)}h.length&&(t.refused=k(t.refused,h)),t.cursor=f.length}}async function Me(o,e,s,a){let{codeFindingNote:t}=Se(a),n={deriveBytes:0,codeEvidence:[]};if(!e.findingQuality?.config.switches.codeInputs||!e.projectAgents?.enabled)return n;let f=e.projectAgents,y=(e.repos??[]).filter(r=>[...f.byRepo[r.key]??[],...f.codeByRepo?.[r.key]??[]].some(i=>i.codeInputsJson&&(i.codeInputsJson.tools.length||i.codeInputsJson.contextInputs.length))),m=(await U(y,1,async r=>{try{let i=s.find(E=>E.repoKey===r.key);if(!i)throw new Error("Source reader is missing.");return{repo:await Br(o,r,i,e.modelReader??!1)}}catch(i){return{error:i}}})).map(r=>{if("error"in r)throw r.error;return r.repo}),l=m.map(r=>{let i=Ae(o,r,j(o,e),e.modelReader,f);return Object.assign(r.files,i.virtualFiles),i.fragment}),p=Object.fromEntries(m.map(r=>[r.key,r.files??{}])),S=Re({...e,repos:m,mapped:l}).findingQuality?.codeEvidence?.filter(r=>Object.keys(r.input.files).length)??[];if(!S.length)return n;let c=S.map(r=>({repo:r.repo,unitKey:r.unitKey,enabled:!0,inputs:[r.input],files:p[r.repo]}));return{deriveBytes:[...new Map(S.flatMap(r=>Object.entries(r.input.files).map(([i,E])=>[JSON.stringify([r.repo,i]),{path:i,text:E}]))).values()].reduce((r,{path:i,text:E})=>r+Buffer.byteLength(`### ${i}
2
2
  \`\`\`
3
3
  ${ae(E)}
4
4
  \`\`\`
@@ -1 +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};
1
+ import{a,b,c,d,e}from"../chunks/P5FCHJ7W.js";import"../chunks/YDSB7UOR.js";import"../chunks/5JG3ZRNJ.js";import"../chunks/ZLUI3EHB.js";export{b as applyCacheBreakpoints,d as captureAllowanceMultiplier,e as promptCacheEnabled,c as promptCacheEstimateLine,a as promptCachePolicy};
@@ -1 +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};
1
+ import{a,b,c,d,e,f,g,h,i,j,k,l,m,n}from"../chunks/YDSB7UOR.js";import"../chunks/5JG3ZRNJ.js";import"../chunks/ZLUI3EHB.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};
@@ -1 +1 @@
1
- import{a}from"../chunks/J4AXGE5W.js";export{a as StructuredOutputError};
1
+ import"../chunks/UYG422QR.js";import{b as a}from"../chunks/ZLUI3EHB.js";export{a as StructuredOutputError};
@@ -0,0 +1 @@
1
+ import{a,b,c,d,e,f}from"../chunks/GYXDN5W4.js";import"../chunks/GZSUTDGX.js";import"../chunks/5JG3ZRNJ.js";import"../chunks/ZLUI3EHB.js";export{c as FINDING_TEMPLATE_BYTES,b as FRAME_ROUTING_BYTES,a as FRAME_SAFETY_BYTES,e as assertExecutionFrameBytes,d as assertFrameBytes,f as plannedFrameFits};
@@ -1 +1 @@
1
- import{a,b}from"../chunks/5BTATES5.js";import"../chunks/QPIBHTON.js";import"../chunks/5VQ4VYIP.js";import"../chunks/KBTM5MBC.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/N2L4JMJE.js";import"../chunks/6JTHFDH3.js";import"../chunks/HTLIRVP7.js";import"../chunks/N7U5N42V.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/4F6ZIHXU.js";import"../chunks/VGYWI4X2.js";import"../chunks/57M4OQJM.js";import"../chunks/J4AXGE5W.js";import"../chunks/IBCFGUHI.js";import"../chunks/DZZBQDGO.js";import"../chunks/6VHZNBII.js";import"../chunks/LFJQ4YLP.js";import"../chunks/326F4XNG.js";import"../chunks/KU5DINLW.js";import"../chunks/SP6XFHNH.js";import"../chunks/HCPO6QPU.js";import"../chunks/NCW5LJ5O.js";import"../chunks/2CWULBP2.js";import"../chunks/5UWDUYHF.js";import"../chunks/VC3PYT2B.js";import"../chunks/P253B344.js";import"../chunks/W73WF226.js";import"../chunks/6YCABS5T.js";import"../chunks/M5YWJY7P.js";import"../chunks/M6HYSTQD.js";import"../chunks/4H23CSUM.js";import"../chunks/VWRFSVLI.js";import"../chunks/VX6LYNXV.js";import"../chunks/MJGB25S5.js";import"../chunks/TA2NIQAY.js";import"../chunks/34NVU26H.js";import"../chunks/CNQZLSAP.js";import"../chunks/QVXARKP7.js";import"../chunks/2M55DR2J.js";import"../chunks/74FPPPIG.js";import"../chunks/MKYLK6DB.js";import"../chunks/5TATKWLG.js";import"../chunks/JKWTHRUR.js";import"../chunks/3GUKUEEJ.js";import"../chunks/JAPVLU4Z.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/YUY436SM.js";import"../chunks/C6X5GDG4.js";import"../chunks/724WZMYW.js";import"../chunks/YWL52FVW.js";import"../chunks/SJESFYBA.js";import"../chunks/RUVMFAST.js";import"../chunks/S27VIQMZ.js";import"../chunks/INVTU73D.js";import"../chunks/A7WJJMRY.js";import"../chunks/Q5WR6B2H.js";import"../chunks/VDUFPTDD.js";export{a as localCallPlan,b as localSourcePlan};
1
+ import{a,b}from"../chunks/VVSHUUWX.js";import"../chunks/HH3HDT5K.js";import"../chunks/2IQN26TC.js";import"../chunks/OHDC3L6V.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/2J3PWUPG.js";import"../chunks/UYG422QR.js";import"../chunks/6JTHFDH3.js";import"../chunks/HTLIRVP7.js";import"../chunks/GYXDN5W4.js";import"../chunks/N7U5N42V.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/QENYFKG3.js";import"../chunks/4F6ZIHXU.js";import"../chunks/VGYWI4X2.js";import"../chunks/57M4OQJM.js";import"../chunks/IBCFGUHI.js";import"../chunks/DZZBQDGO.js";import"../chunks/6E4K7JTI.js";import"../chunks/326F4XNG.js";import"../chunks/KU5DINLW.js";import"../chunks/SP6XFHNH.js";import"../chunks/PISOGSJF.js";import"../chunks/HB5BTGTI.js";import"../chunks/JCVB6IC4.js";import"../chunks/GOBOE2SC.js";import"../chunks/AIS3FHQR.js";import"../chunks/QY57UR6E.js";import"../chunks/6YCABS5T.js";import"../chunks/GZSUTDGX.js";import"../chunks/M6HYSTQD.js";import"../chunks/4H23CSUM.js";import"../chunks/VBGQKYIT.js";import"../chunks/VX6LYNXV.js";import"../chunks/P5FCHJ7W.js";import"../chunks/I5F7S63K.js";import"../chunks/QVXARKP7.js";import"../chunks/QYYN4YKB.js";import"../chunks/74FPPPIG.js";import"../chunks/LOODGUMW.js";import"../chunks/MKYLK6DB.js";import"../chunks/5TATKWLG.js";import"../chunks/YDSB7UOR.js";import"../chunks/5JG3ZRNJ.js";import"../chunks/ZLUI3EHB.js";import"../chunks/JAPVLU4Z.js";import"../chunks/OXGKALKM.js";import"../chunks/CNQZLSAP.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/YUY436SM.js";import"../chunks/C6X5GDG4.js";import"../chunks/724WZMYW.js";import"../chunks/JS6HTVYX.js";import"../chunks/EJ2IZUN2.js";import"../chunks/ICJV6KIZ.js";import"../chunks/RUVMFAST.js";import"../chunks/S27VIQMZ.js";import"../chunks/INVTU73D.js";import"../chunks/A7WJJMRY.js";import"../chunks/Q5WR6B2H.js";import"../chunks/VDUFPTDD.js";export{a as localCallPlan,b as localSourcePlan};
@@ -1 +1 @@
1
- import{a,b,c,d}from"../chunks/M5YWJY7P.js";export{b as PLANNED_CALL_COUNT,a as PLANNED_INPUT_BYTES,c as PLANNED_INPUT_TOKENS,d as PLANNED_OUTPUT_TOKENS};
1
+ import{a,b,c,d,e}from"../chunks/GZSUTDGX.js";export{b as PLANNED_CALL_COUNT,a as PLANNED_INPUT_BYTES,c as PLANNED_INPUT_TOKENS,d as PLANNED_OUTPUT_TOKENS,e as RELAY_MAX_FRAME_BYTES};
@@ -1 +1 @@
1
- import{k as a,l as b,m as c,n as d}from"../chunks/KBTM5MBC.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/6JTHFDH3.js";import"../chunks/HTLIRVP7.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/VC3PYT2B.js";import"../chunks/6YCABS5T.js";import"../chunks/VWRFSVLI.js";import"../chunks/VX6LYNXV.js";import"../chunks/MJGB25S5.js";import"../chunks/TA2NIQAY.js";import"../chunks/34NVU26H.js";import"../chunks/CNQZLSAP.js";import"../chunks/QVXARKP7.js";import"../chunks/74FPPPIG.js";import"../chunks/JKWTHRUR.js";import"../chunks/3GUKUEEJ.js";import"../chunks/JAPVLU4Z.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/INVTU73D.js";import"../chunks/A7WJJMRY.js";import"../chunks/VDUFPTDD.js";export{a as InputBudgetError,d as buildAnalysisCall,c as callInputBytes,b as createRequestRegistry};
1
+ import{k as a,l as b,m as c,n as d}from"../chunks/OHDC3L6V.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/6JTHFDH3.js";import"../chunks/HTLIRVP7.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/6YCABS5T.js";import"../chunks/VBGQKYIT.js";import"../chunks/VX6LYNXV.js";import"../chunks/P5FCHJ7W.js";import"../chunks/I5F7S63K.js";import"../chunks/QVXARKP7.js";import"../chunks/74FPPPIG.js";import"../chunks/LOODGUMW.js";import"../chunks/YDSB7UOR.js";import"../chunks/5JG3ZRNJ.js";import"../chunks/ZLUI3EHB.js";import"../chunks/JAPVLU4Z.js";import"../chunks/OXGKALKM.js";import"../chunks/CNQZLSAP.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/INVTU73D.js";import"../chunks/A7WJJMRY.js";import"../chunks/VDUFPTDD.js";export{a as InputBudgetError,d as buildAnalysisCall,c as callInputBytes,b as createRequestRegistry};
@@ -1 +1 @@
1
- import{a}from"../chunks/N2L4JMJE.js";import"../chunks/E7TFIHC5.js";import"../chunks/VC3PYT2B.js";import"../chunks/34NVU26H.js";import"../chunks/CNQZLSAP.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/INVTU73D.js";export{a as createTemplateVersion};
1
+ import{a}from"../chunks/2J3PWUPG.js";import"../chunks/E7TFIHC5.js";import"../chunks/LOODGUMW.js";import"../chunks/OXGKALKM.js";import"../chunks/CNQZLSAP.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/INVTU73D.js";export{a as createTemplateVersion};
@@ -1 +1 @@
1
- import{a}from"../chunks/5VQ4VYIP.js";import"../chunks/KBTM5MBC.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/N2L4JMJE.js";import"../chunks/6JTHFDH3.js";import"../chunks/HTLIRVP7.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/VC3PYT2B.js";import"../chunks/6YCABS5T.js";import"../chunks/VWRFSVLI.js";import"../chunks/VX6LYNXV.js";import"../chunks/MJGB25S5.js";import"../chunks/TA2NIQAY.js";import"../chunks/34NVU26H.js";import"../chunks/CNQZLSAP.js";import"../chunks/QVXARKP7.js";import"../chunks/74FPPPIG.js";import"../chunks/JKWTHRUR.js";import"../chunks/3GUKUEEJ.js";import"../chunks/JAPVLU4Z.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/INVTU73D.js";import"../chunks/A7WJJMRY.js";import"../chunks/VDUFPTDD.js";export{a as createRequestTools};
1
+ import{a}from"../chunks/2IQN26TC.js";import"../chunks/OHDC3L6V.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/2J3PWUPG.js";import"../chunks/6JTHFDH3.js";import"../chunks/HTLIRVP7.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/6YCABS5T.js";import"../chunks/VBGQKYIT.js";import"../chunks/VX6LYNXV.js";import"../chunks/P5FCHJ7W.js";import"../chunks/I5F7S63K.js";import"../chunks/QVXARKP7.js";import"../chunks/74FPPPIG.js";import"../chunks/LOODGUMW.js";import"../chunks/YDSB7UOR.js";import"../chunks/5JG3ZRNJ.js";import"../chunks/ZLUI3EHB.js";import"../chunks/JAPVLU4Z.js";import"../chunks/OXGKALKM.js";import"../chunks/CNQZLSAP.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/INVTU73D.js";import"../chunks/A7WJJMRY.js";import"../chunks/VDUFPTDD.js";export{a as createRequestTools};
@@ -1 +1 @@
1
- import{a,b,c,d,e,f,g,h,i,j}from"./chunks/VC3PYT2B.js";import"./chunks/34NVU26H.js";import"./chunks/CNQZLSAP.js";import"./chunks/I4F56VMG.js";import"./chunks/33EUZF25.js";export{a as fileScopeEnabled,c as findingHeadlinesEnabled,i as folderPartsEnabled,j as followupSettings,b as multiEntryEnabled,e as outsideLoadersEnabled,f as promptAgreementEnabled,d as resultSafetyCheckEnabled,h as skippedFilesEnabled,g as snapshotSettings};
1
+ import{a,b,c,d,e,f,g,h,i,j,k,l,m,n}from"./chunks/LOODGUMW.js";import"./chunks/OXGKALKM.js";import"./chunks/CNQZLSAP.js";import"./chunks/I4F56VMG.js";import"./chunks/33EUZF25.js";export{i as codePromptSentEnabled,f as codeScanPriorityEnabled,c as fileScopeEnabled,e as findingHeadlinesEnabled,m as folderPartsEnabled,n as followupSettings,a as historyContextEnabled,d as multiEntryEnabled,h as outsideLoadersEnabled,j as promptAgreementEnabled,b as repositoryProjectsEnabled,g as resultSafetyCheckEnabled,l as skippedFilesEnabled,k as snapshotSettings};
@@ -1 +1 @@
1
- import{a as Y,b as C}from"../chunks/F3R4J3ND.js";import{b as X}from"../chunks/5BTATES5.js";import{b as z,c as _,d as H,e as S,f as j}from"../chunks/66JRJPJC.js";import{O as Q,ba as D,ia as T,qa as B,sa as G,ta as V,ua as J,wa as U,ya as W}from"../chunks/QPIBHTON.js";import"../chunks/5VQ4VYIP.js";import"../chunks/KBTM5MBC.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/N2L4JMJE.js";import"../chunks/6JTHFDH3.js";import"../chunks/HTLIRVP7.js";import{c as N}from"../chunks/N7U5N42V.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/4F6ZIHXU.js";import"../chunks/VGYWI4X2.js";import"../chunks/57M4OQJM.js";import"../chunks/J4AXGE5W.js";import"../chunks/IBCFGUHI.js";import"../chunks/DZZBQDGO.js";import"../chunks/XVGLY4EO.js";import"../chunks/6VHZNBII.js";import"../chunks/LFJQ4YLP.js";import"../chunks/326F4XNG.js";import{c as M}from"../chunks/UKX3A6AX.js";import"../chunks/KU5DINLW.js";import"../chunks/SP6XFHNH.js";import"../chunks/PBHHWFR6.js";import"../chunks/HCPO6QPU.js";import{h as q}from"../chunks/NCW5LJ5O.js";import"../chunks/DHVEGIU6.js";import"../chunks/2CWULBP2.js";import{a as K}from"../chunks/5UWDUYHF.js";import{c as I}from"../chunks/VC3PYT2B.js";import"../chunks/P253B344.js";import"../chunks/W73WF226.js";import"../chunks/6YCABS5T.js";import"../chunks/M5YWJY7P.js";import"../chunks/M6HYSTQD.js";import"../chunks/4H23CSUM.js";import"../chunks/VWRFSVLI.js";import"../chunks/VX6LYNXV.js";import"../chunks/MJGB25S5.js";import"../chunks/TA2NIQAY.js";import{o as k}from"../chunks/34NVU26H.js";import"../chunks/CNQZLSAP.js";import"../chunks/QVXARKP7.js";import{Ib as E,Ka as v}from"../chunks/2M55DR2J.js";import"../chunks/74FPPPIG.js";import"../chunks/MKYLK6DB.js";import"../chunks/5TATKWLG.js";import"../chunks/JKWTHRUR.js";import{b as O}from"../chunks/3GUKUEEJ.js";import"../chunks/JAPVLU4Z.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/YUY436SM.js";import{e as P}from"../chunks/C6X5GDG4.js";import"../chunks/724WZMYW.js";import"../chunks/YWL52FVW.js";import"../chunks/SJESFYBA.js";import"../chunks/RUVMFAST.js";import"../chunks/S27VIQMZ.js";import"../chunks/INVTU73D.js";import"../chunks/A7WJJMRY.js";import"../chunks/Q5WR6B2H.js";import"../chunks/VDUFPTDD.js";function Z(r,s){return D(r,s,{codeInputs:!1,recall:!1,secondOpinion:!1})}function L(r,s,a,d){let n=s.findingQuality,w={...a.findingCheck?.state?.result??{kept:s.findings,dropped:[],warnings:[]}};n?.assessments&&w.qualityAudit&&(w.qualityAudit={coverage:n.coverage??[],verdicts:n.verdicts??[],assessments:n.assessments,...n.shadow?{shadow:n.shadow}:{}});let e=V(s.findings,s.structures,s.findingHeadlines??[],s.findingHeadlineDiagnostics),m=new Map(e.rows.filter(t=>t.target==="finding").map(t=>[t.index,{headline:t.headline,ifLeft:t.ifLeft}])),y=new Map(e.rows.filter(t=>t.target==="structure").map(t=>[t.index,{headline:t.headline,ifLeft:t.ifLeft}])),x=y.size?s.structures.map((t,c)=>y.has(c)?{...t,...y.get(c)}:t):s.structures,b=m.size?s.findings.map((t,c)=>m.has(c)?{...t,...m.get(c)}:t):s.findings,i=a.findingQuality?.config.switches.ranking?q(b,n?.assessments??[]):void 0,g=v(b),A=i?.ordered??[...g.active,...g.notActive],o=s.structuralFindingCount===void 0?void 0:b.slice(0,s.structuralFindingCount),p=v(o??[]),f=o&&(i?q(o,n?.assessments??[]).ordered:[...p.active,...p.notActive]),u=f?T(x,f.map(t=>A.indexOf(t))):x;return{repoKey:r,findings:A,structures:u,graph:s.graph,warnings:s.warnings,...d?{proposalCounts:d}:{},...e.diagnostics?{findingHeadlineDiagnostics:e.diagnostics}:{},skippedFiles:a.inspectPlan?.skipped??[],passes:a.inspectPlan?.passes.length??1,findingCheck:w,...i?{ranking:{defaultIds:i.defaultIds,hiddenIds:i.hiddenIds,emptyMessage:i.emptyMessage}}:{}}}async function $(r,s,a,d=Y){let n={...a.state,repos:a.repos,mapped:a.fragments.map(({fragment:e})=>e),findingsRaw:a.findings,warnings:a.state?.warnings??[],splitCheckPriced:!0,splitFindingsPriced:!0},w=C(s,d);for(;;){let e=await W({phase:"structuring",state:n,settings:r,execution:{scopeConcurrency:4,forLocal:!0}},w);if(n=S(n,e),e.next==="persisting")return{state:n,structures:n.structuresRaw??[],warnings:n.warnings??[]}}}function te(r,s){I(s)&&r.requestTools.headlinePlan(N([]))}async function ee(r,s,a={}){let{settings:d,qualityConfig:n}=r;te(s,d);let w=Q(d);if(!Object.keys(r.files).length)throw new O("empty_folder","No admitted source files were found.");let e={repos:[{key:r.repoKey,kind:"fs",files:r.files,...r.root!==void 0?{root:r.root}:{},...r.mechanicalInventory?{mechanicalInventory:r.mechanicalInventory}:{},...r.skippedFiles?.length?{refused:r.skippedFiles}:{}}],warnings:r.warnings??[],...r.fragment?{mapped:[r.fragment]}:{}},m=C(s,s.progress);for(;;){let i=await j({phase:"mapping",state:e,settings:d,execution:{scopeConcurrency:4,forLocal:!0,preparation:{capUsd:20,confirmPrice:!1,qualityConfig:n}}},m);if(e=S(e,i),i.next!=="mapping")break}e={...e,analysisFlags:{...w,sourceNotes:!a.findingsOnly&&w.sourceNotes},findingQuality:{config:n},warnings:[...e.warnings??[],...n.diagnostics]};let y="inspecting";for(m.progress.checkpoint=async(i,g)=>{e={...e,...i,...g?{passResults:{...e.passResults,[g.index]:g.result}}:{}},await s.progress.checkpoint(i,g)};y!=="structuring";){let g=await(y==="inspecting"?B:G)({phase:y,state:e,settings:d,execution:{scopeConcurrency:4,passConcurrency:4,forLocal:!0}},m);e=S(e,g),y=g.next}let x=(i=!0)=>J({phase:"persisting",state:e,settings:d,execution:{scopeConcurrency:4}},{mechanical:i});if(!a.findingsOnly){let i=L(r.repoKey,x(!1),e,r.proposalCounts),g=e.findingsRaw;e={...(await $(d,s,{repos:e.repos,fragments:[{repoKey:r.repoKey,fragment:e.mapped[0]}],graph:i.graph,findings:i.findings,state:e},m.progress)).state,findingsRaw:g}}e=S(e,await U({phase:"persisting",state:e,settings:d,execution:{scopeConcurrency:4,forLocal:!0}},m));let b=x();return await a.resultSink?.(b),L(r.repoKey,b,e,r.proposalCounts)}import{createHash as se}from"node:crypto";async function re(r,s,a){let d=new Map,n=new Map,w=[],e,m=[],y=()=>{if(a.signal?.throwIfAborted(),e)throw k(e)},x=async o=>{y();try{return await a.list(o)}catch{throw a.signal?.throwIfAborted(),k("unavailable")}},b=async o=>{let p=[],f=new Set,u=new Set,t=new Set,c=o;for(;;){if(y(),c.snapshot!==s.manifest.snapshot||c.commit!==s.manifest.commit)throw k("bad_request");for(let h of c.files){let F=d.get(h.id);if(f.has(h.path)||u.has(h.id)||F&&(F.hash!==h.hash||F.size!==h.size))throw k("bad_request");f.add(h.path),u.add(h.id);let l={...h};d.set(h.id,l),p.push(l)}if(c.complete)return p;if(!c.cursor||t.has(c.cursor))throw k("bad_request");t.add(c.cursor),c=await x(c.cursor)}},i=o=>o.map(({id:p,path:f,size:u})=>({path:f,size:u,ref:p})),g=_(async o=>{if(a.signal?.throwIfAborted(),e)return o.map(()=>null);let p=[...new Set(o.map(f=>f.ref))].filter(f=>!n.has(f)).map(f=>d.get(f));if(p.length){let f;try{f=await a.read(p)}catch{return a.signal?.throwIfAborted(),e="unavailable",o.map(()=>null)}a.signal?.throwIfAborted();let u=new Map(p.map(t=>[t.id,t]));for(let t of f){let c=u.get(t.id);if(!c||t.text!==null&&!t.refusal&&(Buffer.byteLength(t.text)!==c.size||se("sha256").update(t.text).digest("hex")!==c.hash)){e="bad_request";break}u.delete(t.id),n.set(t.id,{text:t.refusal?null:t.text,bytesRead:t.bytesRead,...t.refusal?{refusal:t.refusal}:{}})}if(u.size&&(e="bad_request"),e)return o.map(()=>null)}return o.map(f=>n.get(f.ref)?.text??null)}),A=async o=>{let p=await g(o);return p===null?null:E(r,o,async()=>p)};try{let o=await b(s.manifest),p=M(r,z(r,i(o)),{paths:K(r)}),f=await H(r,{repoKey:s.repoKey,entries:i(o),read:A,localListing:!0,...s.proposal?{proposal:s.proposal}:{},repository:{context:async()=>s.selectedRoot===null?null:{selectedRoot:s.selectedRoot},list:async()=>{let l=await x(null),R=await b(l);return w=R,{entries:i(R),truncated:l.truncated,entriesVisited:l.entriesVisited}},read:async l=>(await A(l),n.get(l.ref)??{text:null,bytesRead:0})}});y();let u={repoKey:s.repoKey,...f},t=new Map(o.map(l=>[P(l.path,u.root),l]));u.root!==void 0&&w.forEach(l=>t.set(l.path,l));let c=Object.keys(u.files).map(l=>{let R=t.get(l);if(!R)throw k("bad_request");return{source:{...R},resultPath:l}}),h=c.map(({source:l,resultPath:R})=>({...l,path:R})),{calls:F}=X(r,u);return m=h.map(l=>l.id),{source:u,finalFiles:h,calls:F,finalFileMapping:c,analysisSize:p}}finally{n.clear(),d.clear(),a.finish?.(m)}}async function He(r,s,a={}){let d=r.settings,n=Z(d,s.requestTools);return ee({...r,settings:d,qualityConfig:n},s,a)}export{re as prepareRelayAnalysis,He as runEngineAnalysis};
1
+ import{a as Y,b as C}from"../chunks/F3R4J3ND.js";import{b as X}from"../chunks/VVSHUUWX.js";import{b as z,c as _,d as H,e as S,f as j}from"../chunks/6W6B7VSP.js";import{O as Q,ba as D,ia as T,qa as B,sa as G,ta as V,ua as J,wa as U,ya as W}from"../chunks/HH3HDT5K.js";import"../chunks/2IQN26TC.js";import"../chunks/OHDC3L6V.js";import"../chunks/Y7JGSUOA.js";import"../chunks/3MTXB4MK.js";import"../chunks/2J3PWUPG.js";import"../chunks/UYG422QR.js";import"../chunks/6JTHFDH3.js";import"../chunks/HTLIRVP7.js";import"../chunks/GYXDN5W4.js";import{c as N}from"../chunks/N7U5N42V.js";import"../chunks/QDYMR6KS.js";import"../chunks/E7TFIHC5.js";import"../chunks/NWYNJHY4.js";import"../chunks/QENYFKG3.js";import"../chunks/4F6ZIHXU.js";import"../chunks/VGYWI4X2.js";import"../chunks/57M4OQJM.js";import"../chunks/IBCFGUHI.js";import"../chunks/DZZBQDGO.js";import"../chunks/6E4K7JTI.js";import"../chunks/326F4XNG.js";import{c as M}from"../chunks/JWQXG5RB.js";import"../chunks/KU5DINLW.js";import"../chunks/SP6XFHNH.js";import"../chunks/PBHHWFR6.js";import"../chunks/PISOGSJF.js";import{h as q}from"../chunks/HB5BTGTI.js";import"../chunks/JLW44GIU.js";import"../chunks/JCVB6IC4.js";import{a as K}from"../chunks/GOBOE2SC.js";import"../chunks/AIS3FHQR.js";import"../chunks/QY57UR6E.js";import"../chunks/6YCABS5T.js";import"../chunks/GZSUTDGX.js";import"../chunks/M6HYSTQD.js";import"../chunks/4H23CSUM.js";import"../chunks/VBGQKYIT.js";import"../chunks/VX6LYNXV.js";import"../chunks/P5FCHJ7W.js";import"../chunks/I5F7S63K.js";import"../chunks/QVXARKP7.js";import{Ib as E,Ka as v}from"../chunks/QYYN4YKB.js";import"../chunks/74FPPPIG.js";import{e as I}from"../chunks/LOODGUMW.js";import"../chunks/MKYLK6DB.js";import"../chunks/5TATKWLG.js";import"../chunks/YDSB7UOR.js";import{b as O}from"../chunks/5JG3ZRNJ.js";import"../chunks/ZLUI3EHB.js";import"../chunks/JAPVLU4Z.js";import{o as k}from"../chunks/OXGKALKM.js";import"../chunks/CNQZLSAP.js";import"../chunks/I4F56VMG.js";import"../chunks/33EUZF25.js";import"../chunks/YUY436SM.js";import{e as P}from"../chunks/C6X5GDG4.js";import"../chunks/724WZMYW.js";import"../chunks/JS6HTVYX.js";import"../chunks/EJ2IZUN2.js";import"../chunks/ICJV6KIZ.js";import"../chunks/RUVMFAST.js";import"../chunks/S27VIQMZ.js";import"../chunks/INVTU73D.js";import"../chunks/A7WJJMRY.js";import"../chunks/Q5WR6B2H.js";import"../chunks/VDUFPTDD.js";function Z(r,s){return D(r,s,{codeInputs:!1,recall:!1,secondOpinion:!1})}function L(r,s,a,d){let n=s.findingQuality,w={...a.findingCheck?.state?.result??{kept:s.findings,dropped:[],warnings:[]}};n?.assessments&&w.qualityAudit&&(w.qualityAudit={coverage:n.coverage??[],verdicts:n.verdicts??[],assessments:n.assessments,...n.shadow?{shadow:n.shadow}:{}});let e=V(s.findings,s.structures,s.findingHeadlines??[],s.findingHeadlineDiagnostics),m=new Map(e.rows.filter(t=>t.target==="finding").map(t=>[t.index,{headline:t.headline,ifLeft:t.ifLeft}])),y=new Map(e.rows.filter(t=>t.target==="structure").map(t=>[t.index,{headline:t.headline,ifLeft:t.ifLeft}])),x=y.size?s.structures.map((t,c)=>y.has(c)?{...t,...y.get(c)}:t):s.structures,b=m.size?s.findings.map((t,c)=>m.has(c)?{...t,...m.get(c)}:t):s.findings,i=a.findingQuality?.config.switches.ranking?q(b,n?.assessments??[]):void 0,g=v(b),A=i?.ordered??[...g.active,...g.notActive],o=s.structuralFindingCount===void 0?void 0:b.slice(0,s.structuralFindingCount),p=v(o??[]),f=o&&(i?q(o,n?.assessments??[]).ordered:[...p.active,...p.notActive]),u=f?T(x,f.map(t=>A.indexOf(t))):x;return{repoKey:r,findings:A,structures:u,graph:s.graph,warnings:s.warnings,...d?{proposalCounts:d}:{},...e.diagnostics?{findingHeadlineDiagnostics:e.diagnostics}:{},skippedFiles:a.inspectPlan?.skipped??[],passes:a.inspectPlan?.passes.length??1,findingCheck:w,...i?{ranking:{defaultIds:i.defaultIds,hiddenIds:i.hiddenIds,emptyMessage:i.emptyMessage}}:{}}}async function $(r,s,a,d=Y){let n={...a.state,repos:a.repos,mapped:a.fragments.map(({fragment:e})=>e),findingsRaw:a.findings,warnings:a.state?.warnings??[],splitCheckPriced:!0,splitFindingsPriced:!0},w=C(s,d);for(;;){let e=await W({phase:"structuring",state:n,settings:r,execution:{scopeConcurrency:4,forLocal:!0}},w);if(n=S(n,e),e.next==="persisting")return{state:n,structures:n.structuresRaw??[],warnings:n.warnings??[]}}}function te(r,s){I(s)&&r.requestTools.headlinePlan(N([]))}async function ee(r,s,a={}){let{settings:d,qualityConfig:n}=r;te(s,d);let w=Q(d);if(!Object.keys(r.files).length)throw new O("empty_folder","No admitted source files were found.");let e={repos:[{key:r.repoKey,kind:"fs",files:r.files,...r.root!==void 0?{root:r.root}:{},...r.mechanicalInventory?{mechanicalInventory:r.mechanicalInventory}:{},...r.skippedFiles?.length?{refused:r.skippedFiles}:{}}],warnings:r.warnings??[],...r.fragment?{mapped:[r.fragment]}:{}},m=C(s,s.progress);for(;;){let i=await j({phase:"mapping",state:e,settings:d,execution:{scopeConcurrency:4,forLocal:!0,preparation:{capUsd:20,confirmPrice:!1,qualityConfig:n}}},m);if(e=S(e,i),i.next!=="mapping")break}e={...e,analysisFlags:{...w,sourceNotes:!a.findingsOnly&&w.sourceNotes},findingQuality:{config:n},warnings:[...e.warnings??[],...n.diagnostics]};let y="inspecting";for(m.progress.checkpoint=async(i,g)=>{e={...e,...i,...g?{passResults:{...e.passResults,[g.index]:g.result}}:{}},await s.progress.checkpoint(i,g)};y!=="structuring";){let g=await(y==="inspecting"?B:G)({phase:y,state:e,settings:d,execution:{scopeConcurrency:4,passConcurrency:4,forLocal:!0}},m);e=S(e,g),y=g.next}let x=(i=!0)=>J({phase:"persisting",state:e,settings:d,execution:{scopeConcurrency:4}},{mechanical:i});if(!a.findingsOnly){let i=L(r.repoKey,x(!1),e,r.proposalCounts),g=e.findingsRaw;e={...(await $(d,s,{repos:e.repos,fragments:[{repoKey:r.repoKey,fragment:e.mapped[0]}],graph:i.graph,findings:i.findings,state:e},m.progress)).state,findingsRaw:g}}e=S(e,await U({phase:"persisting",state:e,settings:d,execution:{scopeConcurrency:4,forLocal:!0}},m));let b=x();return await a.resultSink?.(b),L(r.repoKey,b,e,r.proposalCounts)}import{createHash as se}from"node:crypto";async function re(r,s,a){let d=new Map,n=new Map,w=[],e,m=[],y=()=>{if(a.signal?.throwIfAborted(),e)throw k(e)},x=async o=>{y();try{return await a.list(o)}catch{throw a.signal?.throwIfAborted(),k("unavailable")}},b=async o=>{let p=[],f=new Set,u=new Set,t=new Set,c=o;for(;;){if(y(),c.snapshot!==s.manifest.snapshot||c.commit!==s.manifest.commit)throw k("bad_request");for(let h of c.files){let F=d.get(h.id);if(f.has(h.path)||u.has(h.id)||F&&(F.hash!==h.hash||F.size!==h.size))throw k("bad_request");f.add(h.path),u.add(h.id);let l={...h};d.set(h.id,l),p.push(l)}if(c.complete)return p;if(!c.cursor||t.has(c.cursor))throw k("bad_request");t.add(c.cursor),c=await x(c.cursor)}},i=o=>o.map(({id:p,path:f,size:u})=>({path:f,size:u,ref:p})),g=_(async o=>{if(a.signal?.throwIfAborted(),e)return o.map(()=>null);let p=[...new Set(o.map(f=>f.ref))].filter(f=>!n.has(f)).map(f=>d.get(f));if(p.length){let f;try{f=await a.read(p)}catch{return a.signal?.throwIfAborted(),e="unavailable",o.map(()=>null)}a.signal?.throwIfAborted();let u=new Map(p.map(t=>[t.id,t]));for(let t of f){let c=u.get(t.id);if(!c||t.text!==null&&!t.refusal&&(Buffer.byteLength(t.text)!==c.size||se("sha256").update(t.text).digest("hex")!==c.hash)){e="bad_request";break}u.delete(t.id),n.set(t.id,{text:t.refusal?null:t.text,bytesRead:t.bytesRead,...t.refusal?{refusal:t.refusal}:{}})}if(u.size&&(e="bad_request"),e)return o.map(()=>null)}return o.map(f=>n.get(f.ref)?.text??null)}),A=async o=>{let p=await g(o);return p===null?null:E(r,o,async()=>p)};try{let o=await b(s.manifest),p=M(r,z(r,i(o)),{paths:K(r)}),f=await H(r,{repoKey:s.repoKey,entries:i(o),read:A,localListing:!0,...s.proposal?{proposal:s.proposal}:{},repository:{context:async()=>s.selectedRoot===null?null:{selectedRoot:s.selectedRoot},list:async()=>{let l=await x(null),R=await b(l);return w=R,{entries:i(R),truncated:l.truncated,entriesVisited:l.entriesVisited}},read:async l=>(await A(l),n.get(l.ref)??{text:null,bytesRead:0})}});y();let u={repoKey:s.repoKey,...f},t=new Map(o.map(l=>[P(l.path,u.root),l]));u.root!==void 0&&w.forEach(l=>t.set(l.path,l));let c=Object.keys(u.files).map(l=>{let R=t.get(l);if(!R)throw k("bad_request");return{source:{...R},resultPath:l}}),h=c.map(({source:l,resultPath:R})=>({...l,path:R})),{calls:F}=X(r,u);return m=h.map(l=>l.id),{source:u,finalFiles:h,calls:F,finalFileMapping:c,analysisSize:p}}finally{n.clear(),d.clear(),a.finish?.(m)}}async function He(r,s,a={}){let d=r.settings,n=Z(d,s.requestTools);return ee({...r,settings:d,qualityConfig:n},s,a)}export{re as prepareRelayAnalysis,He as runEngineAnalysis};
@@ -0,0 +1 @@
1
+ import{a}from"./chunks/JS6HTVYX.js";export{a as countForm};
@@ -0,0 +1,22 @@
1
+ import { countForm } from "../analysis-core/wording.js";
2
+ import { readAnalysisSource } from "../adapters/selection.js";
3
+ import { readLocalFolder } from "../adapters/files.js";
4
+ import { AgentChoiceError } from "../contract/agent-choice.js";
5
+ /** Selection and file admission stay with the same owner used by analysis. */
6
+ export async function previewAnalysis(settings, folder, options = {}) {
7
+ options.signal?.throwIfAborted();
8
+ const { source } = await readAnalysisSource(settings, folder, { ...options,
9
+ readFolder: () => readLocalFolder(settings, folder, {}, { captureSnapshot: true, proposal: options.proposal }),
10
+ });
11
+ options.signal?.throwIfAborted();
12
+ if (source.agentChoice)
13
+ throw new AgentChoiceError(source.agentChoice);
14
+ return { files: Object.keys(source.files).sort().map(path => ({ path,
15
+ bytes: source.snapshot[path].length,
16
+ })), warnings: source.warnings };
17
+ }
18
+ export function formatAnalysisPreview(preview) {
19
+ return ["Local file preview", "This preview uploads no file contents and reserves no funds. Analysis reads the folder again and may select additional files.",
20
+ "Files selected locally:", ...preview.files.map(file => `- ${JSON.stringify(file.path)} (${file.bytes} ${countForm(file.bytes, "byte")})`),
21
+ ...preview.warnings, ""].join("\n");
22
+ }
@@ -1,13 +1,14 @@
1
1
  import { fileScopeOf } from "../analysis-core/analysis/file-analysis-plan.js";
2
2
  import { createHash } from "node:crypto";
3
3
  import { realpath, stat } from "node:fs/promises";
4
- import { dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
4
+ import { dirname, isAbsolute, parse, relative, resolve, sep } from "node:path";
5
5
  import { ANALYSIS_SELECTION_LIMITS, analysisScopeSchema, analysisSelectionRequestSchema } from "../analysis-core/contracts/analysis-selection.js";
6
6
  import { fileScopeEnabled, fileScopeRequested, multiEntryEnabled, selectionModeEnabled } from "../adapters/settings.js";
7
7
  import { resolveFolderPath } from "../adapters/folder-path.js";
8
8
  import { INVALID_SCOPE_MESSAGE, INVALID_SELECTION_MESSAGE } from "../contract/scope-choice.js";
9
9
  import { cliRefusals } from "../contract/cli-refusals.js";
10
10
  import { mapLimit } from "../analysis-core/map-limit.js";
11
+ import { reportDirectory } from "../adapters/output-paths.js";
11
12
  function within(root, path) {
12
13
  const rel = relative(root, path);
13
14
  return rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
@@ -54,8 +55,7 @@ export async function resolveAnalysisSelection(path, cwd, settings, scope) {
54
55
  if (!request.success)
55
56
  throw new Error(INVALID_SCOPE_MESSAGE);
56
57
  const identity = JSON.stringify([first.launchRoot, entries, chosen ? [chosen.snapshot, chosen.entry, chosen.imports] : null]);
57
- const hash = createHash("sha256").update(JSON.stringify(entries)).digest("hex");
58
- return { ...first, outputAnchor: first.launchRoot, outputDir: join(first.launchRoot, ".counterfact/files", hash),
58
+ return { ...first, outputAnchor: first.launchRoot, outputDir: await reportDirectory(first.launchRoot, entries),
59
59
  selectionKey: `files:${createHash("sha256").update(identity).digest("hex")}`, request: request.data };
60
60
  }
61
61
  path = paths[0];
@@ -107,11 +107,10 @@ export async function resolveAnalysisSelection(path, cwd, settings, scope) {
107
107
  if (!request.success)
108
108
  throw new Error(INVALID_SELECTION_MESSAGE);
109
109
  const outputAnchor = dirname(selected);
110
- const entryHash = createHash("sha256").update(entryPath).digest("hex");
111
110
  const selectionKey = `file:${createHash("sha256").update(JSON.stringify([launchRoot, entryPath,
112
111
  chosen ? [chosen.snapshot, chosen.imports] : null])).digest("hex")}`;
113
112
  return { kind: "file", path: selected, launchRoot, entryPath, outputAnchor,
114
- outputDir: join(outputAnchor, ".counterfact/files", entryHash), factsFolder: launchRoot, selectionKey, request: request.data };
113
+ outputDir: await reportDirectory(outputAnchor, entryPath), factsFolder: launchRoot, selectionKey, request: request.data };
115
114
  }
116
115
  /** Entry points resolve coordinates once; downstream stages reuse the same captured description. */
117
116
  export async function resolveRunSelection(path, cwd, settings, options = {}) {
@@ -127,7 +126,6 @@ export async function resolveRunSelection(path, cwd, settings, options = {}) {
127
126
  throw new Error(INVALID_SCOPE_MESSAGE);
128
127
  return selection;
129
128
  }
130
- export function analysisSaveOptions(selection, outputDir) {
131
- return { defaultFileOutput: selection?.kind === "file" && outputDir === undefined,
132
- scope: selection?.request?.kind === "file" ? selection.request.scope : undefined };
129
+ export function analysisSaveOptions(selection) {
130
+ return { scope: selection?.request?.kind === "file" ? selection.request.scope : undefined };
133
131
  }
@@ -1,14 +1,14 @@
1
+ import { previewAnalysis, formatAnalysisPreview } from "../analysis-preview.js";
1
2
  import { formatSavedResults } from "../saved-results.js";
2
3
  import { skipped } from "./skipped.js";
3
4
  import { loadDevelopmentRelay } from "../development-relay.js";
4
5
  import { loadInstalledRelease } from "../../adapters/release.js";
5
6
  import { cliRefusals, START_FAILURE_MESSAGE } from "../../contract/cli-refusals.js";
6
- import { CLI_VERSION } from "../../contract/cli-version.js";
7
+ import { requireMinimumCliVersion } from "../compatibility.js";
7
8
  import { cliApiMessages } from "../../contract/cli-api-messages.js";
8
9
  import { ApiError } from "../api.js";
9
10
  import { resolveAgentFolder } from "../agent-folder.js";
10
11
  import { runRelayCheck } from "../relay-check.js";
11
- import { GITIGNORE_OUTPUT_NOTICE } from "../../adapters/gitignore-output.js";
12
12
  import { readFile } from "node:fs/promises";
13
13
  import { resolve } from "node:path";
14
14
  import { loadAgentProposal } from "../../contract/agent-proposal.js";
@@ -21,17 +21,10 @@ import { progressLine } from "../../contract/scope-choice.js";
21
21
  // Only a real pause says "paused"; an unreviewed release or an upload-only server cannot start.
22
22
  const unavailable = START_FAILURE_MESSAGE;
23
23
  function requireLocal(value) {
24
- if (!value || typeof value !== "object" || !("mode" in value) || !("minimumLocalCliVersion" in value)
25
- || typeof value.minimumLocalCliVersion !== "string" || !/^\d+\.\d+\.\d+$/.test(value.minimumLocalCliVersion)) {
24
+ if (!value || typeof value !== "object" || !("mode" in value)) {
26
25
  throw new Error(cliApiMessages.invalid_response);
27
26
  }
28
- const current = CLI_VERSION.split(".").map(BigInt), minimum = value.minimumLocalCliVersion.split(".").map(BigInt);
29
- for (let i = 0; i < current.length; i++) {
30
- if (minimum[i] > current[i])
31
- throw new ApiError(426, "cli_update_required", cliRefusals.cli_update_required);
32
- if (minimum[i] < current[i])
33
- break;
34
- }
27
+ requireMinimumCliVersion(value);
35
28
  if (value.mode === "paused")
36
29
  throw new ApiError(503, "local_checks_paused", cliRefusals.local_checks_paused);
37
30
  // A local-capable client never falls back to sending source files to the hosted upload API.
@@ -39,14 +32,18 @@ function requireLocal(value) {
39
32
  throw new ApiError(503, "unavailable", unavailable);
40
33
  return "skippedFiles" in value && value.skippedFiles === true;
41
34
  }
42
- export function parseAnalyzeOptions(args, choices = false, multiple = false) {
35
+ export function parseAnalyzeOptions(args, choices = false, multiple = false, previewEnabled = true) {
43
36
  let path, proposalFile, scopeFile;
44
37
  let skipped;
38
+ let preview = false;
45
39
  let scope;
46
40
  const paths = [];
47
41
  for (let index = 0; index < args.length; index++) {
48
42
  const arg = args[index];
49
- if (["--skipped", "--skipped-plan", "--show-skipped"].includes(arg) && skipped === undefined) {
43
+ if (arg === "--preview" && previewEnabled && !preview) {
44
+ preview = true;
45
+ }
46
+ else if (["--skipped", "--skipped-plan", "--show-skipped"].includes(arg) && skipped === undefined) {
50
47
  skipped = arg === "--skipped" ? "analyze" : arg === "--skipped-plan" ? "plan" : "files";
51
48
  }
52
49
  else if (arg === "--proposal" && proposalFile === undefined) {
@@ -71,14 +68,18 @@ export function parseAnalyzeOptions(args, choices = false, multiple = false) {
71
68
  else
72
69
  throw new Error();
73
70
  }
71
+ if (preview && skipped)
72
+ throw new Error();
74
73
  if (skipped && (paths.length > 1 || proposalFile || scope !== undefined || scopeFile !== undefined))
75
74
  throw new Error();
76
- return { path: path ?? ".", options: { ...(paths.length > 1 ? { paths } : {}), ...(scope === undefined ? {} : { scope }), ...(proposalFile === undefined ? {} : { proposalFile }), ...(scopeFile === undefined ? {} : { scopeFile }), ...(skipped ? { skipped } : {}) } };
75
+ return { path: path ?? ".", options: { ...(preview ? { preview: true } : {}), ...(paths.length > 1 ? { paths } : {}), ...(scope === undefined ? {} : { scope }), ...(proposalFile === undefined ? {} : { proposalFile }), ...(scopeFile === undefined ? {} : { scopeFile }), ...(skipped ? { skipped } : {}) } };
77
76
  }
78
77
  export async function analyze(path, options, ctx) {
79
78
  if (Array.isArray(options.scope) && (options.proposal !== undefined || options.proposalFile !== undefined)) {
80
79
  throw new ApiError(400, "invalid_body", cliRefusals.invalid_body);
81
80
  }
81
+ if (options.preview && options.skipped)
82
+ throw new ApiError(400, "invalid_body", cliRefusals.invalid_body);
82
83
  if (options.skipped)
83
84
  return skipped(path, options.skipped, ctx, analyze, options.surface);
84
85
  const startup = ctx.startup;
@@ -99,6 +100,17 @@ export async function analyze(path, options, ctx) {
99
100
  const scope = Array.isArray(options.scope) ? undefined : options.scope;
100
101
  const proposal = await loadAgentProposal(async () => options.proposalFile === undefined ? options.proposal
101
102
  : JSON.parse(await readFile(resolve(ctx.cwd ?? process.cwd(), options.proposalFile), "utf8")), startup.settings);
103
+ if (options.preview) {
104
+ if (startup.transport.CF_FILES_PREVIEW === "0" || options.skipped || options.addToAnalysisId || options.retryUpload) {
105
+ throw new ApiError(400, "invalid_body", cliRefusals.invalid_body);
106
+ }
107
+ const selection = await resolveRunSelection(path, ctx.cwd ?? process.cwd(), settings, { ...options, scope });
108
+ const folder = selection?.path ?? resolveAgentFolder(path, ctx.cwd);
109
+ const preview = await previewAnalysis(settings, folder, { selection, proposal, signal: ctx.signal,
110
+ provider: ctx.relayRuntime?.selectionProvider });
111
+ ctx.write(formatAnalysisPreview(preview));
112
+ return 0;
113
+ }
102
114
  const mode = await (ctx.consoleMode?.() ?? ctx.api.request("checks/mode"));
103
115
  const skippedFilesSupported = requireLocal(mode);
104
116
  const development = startup.transport.CF_RELAY_DEV === "1" ? await loadDevelopmentRelay(startup.transport) : undefined;
@@ -125,7 +137,7 @@ export async function analyze(path, options, ctx) {
125
137
  try {
126
138
  const code = await (ctx.relayRuntime?.run ?? runRelayCheck)(folder, {
127
139
  analyzedFolder: options.analyzedFolder ?? path,
128
- settings: captureArchitectureSettings(settings, config), config, release, skippedFilesSupported, consoleSupportsActivity: !!mode && typeof mode === "object" && "findingActivity" in mode && mode.findingActivity === true, cwd: ctx.cwd, connect: development?.connect ?? ctx.relayRuntime?.connect,
140
+ settings: captureArchitectureSettings(settings, config), config, release, skippedFilesSupported, consoleSupportsFailureReason: !!mode && typeof mode === "object" && "failureReason" in mode && mode.failureReason === true, consoleSupportsActivity: !!mode && typeof mode === "object" && "findingActivity" in mode && mode.findingActivity === true, cwd: ctx.cwd, connect: development?.connect ?? ctx.relayRuntime?.connect,
129
141
  ...(ctx.relayRuntime?.selectionProvider ? { selectionProvider: ctx.relayRuntime.selectionProvider } : {}),
130
142
  ...(proposal ? { proposal } : {}),
131
143
  ...(selection ? { selection } : {}), ...(scope ? { scope } : {}),
@@ -141,12 +153,6 @@ export async function analyze(path, options, ctx) {
141
153
  } } : {}),
142
154
  onNotice: message => { clearProgress(); ctx.write(`${message}\n`); },
143
155
  onSaving: () => { clearProgress(); ctx.write("\r\u001b[2KSaving the results…"); progressShown = true; },
144
- onLocalSaved: result => {
145
- if (result.ignoreAdded) {
146
- clearProgress();
147
- ctx.write(GITIGNORE_OUTPUT_NOTICE);
148
- }
149
- },
150
156
  onError: failure => {
151
157
  ctx.onCheckFailure?.(failure);
152
158
  if (failure.agentChoice)
@@ -1,6 +1,7 @@
1
1
  import { emailSignInMessages } from "../../contract/email-sign-in-messages.js";
2
2
  import { EMAIL_SIGN_IN_TERMS, normalizeSignInEmail, signInWithCode, startEmailSignIn } from "../email-sign-in.js";
3
3
  import { startSignIn } from "../sign-in.js";
4
+ import { checkSignInVersion } from "../compatibility.js";
4
5
  export function parseLoginOptions(args) {
5
6
  // The router supplies usage for syntax errors without repeating private arguments.
6
7
  const options = {};
@@ -25,6 +26,7 @@ export async function login(ctx, options = {}) {
25
26
  const email = normalizeSignInEmail(options.email);
26
27
  if (!email)
27
28
  throw new Error(emailSignInMessages.invalid_email);
29
+ await checkSignInVersion(ctx);
28
30
  ctx.write(EMAIL_SIGN_IN_TERMS + "\n");
29
31
  let code = options.code;
30
32
  if (code === undefined) {
@@ -39,13 +41,16 @@ export async function login(ctx, options = {}) {
39
41
  throw new Error(emailSignInMessages.cancelled);
40
42
  }
41
43
  await signInWithCode(ctx, email, code);
44
+ await checkSignInVersion(ctx);
42
45
  ctx.write("Signed in.\n");
43
46
  return 0;
44
47
  }
48
+ await checkSignInVersion(ctx);
45
49
  const flow = await startSignIn(ctx);
46
50
  ctx.write(`1. Open ${flow.verificationUri}. If asked, sign in with the code we email you.\n`
47
51
  + `2. Then enter this code on that page: ${flow.userCode}\n`);
48
52
  await flow.done;
53
+ await checkSignInVersion(ctx);
49
54
  ctx.write("Signed in.\n");
50
55
  return 0;
51
56
  }
@@ -0,0 +1,39 @@
1
+ import { cliRefusals } from "../contract/cli-refusals.js";
2
+ import { CLI_VERSION } from "../contract/cli-version.js";
3
+ import { cliApiMessages } from "../contract/cli-api-messages.js";
4
+ import { ApiError, SavedSignInError } from "./api.js";
5
+ const SIGN_IN_VERSION_TIMEOUT_MS = 2_000;
6
+ export function requireMinimumCliVersion(value) {
7
+ if (!value || typeof value !== "object" || !("minimumLocalCliVersion" in value)
8
+ || typeof value.minimumLocalCliVersion !== "string" || !/^\d+\.\d+\.\d+$/.test(value.minimumLocalCliVersion)) {
9
+ throw new Error(cliApiMessages.invalid_response);
10
+ }
11
+ const current = CLI_VERSION.split(".").map(BigInt), minimum = value.minimumLocalCliVersion.split(".").map(BigInt);
12
+ for (let i = 0; i < current.length; i++) {
13
+ if (minimum[i] > current[i])
14
+ throw new ApiError(426, "cli_update_required", cliRefusals.cli_update_required);
15
+ if (minimum[i] < current[i])
16
+ break;
17
+ }
18
+ }
19
+ export async function checkSignInVersion(ctx) {
20
+ if (!ctx.startup.signInVersionCheck)
21
+ return;
22
+ try {
23
+ const signedIn = Boolean(await ctx.token?.());
24
+ const options = { timeoutMs: SIGN_IN_VERSION_TIMEOUT_MS };
25
+ const mode = await ctx.api.request("checks/mode", undefined, signedIn, options).catch(error => {
26
+ // A broken saved token must not prevent replacing it through sign-in.
27
+ if (error instanceof SavedSignInError)
28
+ return ctx.api.request("checks/mode", undefined, false, options);
29
+ throw error;
30
+ });
31
+ requireMinimumCliVersion(mode);
32
+ }
33
+ catch (error) {
34
+ ctx.signal?.throwIfAborted();
35
+ // Only an explicit version refusal should interrupt local status or a pending sign-in.
36
+ if (error instanceof ApiError && (error.code === "cli_version_too_old" || error.code === "cli_update_required"))
37
+ throw error;
38
+ }
39
+ }
@@ -1,5 +1,6 @@
1
1
  import { OutputPathError } from "../adapters/output-paths.js";
2
- import { FINISH_FAILURE_MESSAGE } from "../contract/cli-refusals.js";
2
+ import { CompletionBusyError } from "../adapters/completion-lock.js";
3
+ import { COMPLETION_STORAGE_MESSAGE, LOCAL_REPORT_WRITE_MESSAGE } from "../contract/cli-refusals.js";
3
4
  import { completionRecoveryDecision, observedCompletionTiming } from "./completion-recovery.js";
4
5
  import { ResultsUploadError } from "./results-upload.js";
5
6
  /** Keep delivery ahead of report writes, including when private storage is unavailable. */
@@ -33,10 +34,10 @@ export async function deliverCompletedResults(operations) {
33
34
  result.paths = await operations.saveReports();
34
35
  }
35
36
  catch {
36
- result.localErrorMessage = "The local report couldn't be written.";
37
+ result.localErrorMessage = LOCAL_REPORT_WRITE_MESSAGE;
37
38
  }
38
39
  if (storageError) {
39
- const message = storageError instanceof OutputPathError ? storageError.message : FINISH_FAILURE_MESSAGE;
40
+ const message = storageError instanceof OutputPathError || storageError instanceof CompletionBusyError ? storageError.message : COMPLETION_STORAGE_MESSAGE;
40
41
  result.localErrorMessage = result.localErrorMessage ? `${message}\n${result.localErrorMessage}` : message;
41
42
  }
42
43
  result.error = storageError ?? uploadError ?? (result.localErrorMessage ? new Error(result.localErrorMessage) : undefined);
@@ -1,4 +1,4 @@
1
- import { cliRefusals, NOT_ALLOWED_MESSAGE, SIGN_IN_EXPIRED_MESSAGE, CHECK_CONFLICT_MESSAGE, PENDING_RESULTS_MESSAGE, UNSAVED_RESULTS_MESSAGE } from "../contract/cli-refusals.js";
1
+ import { cliRefusals, NOT_ALLOWED_MESSAGE, SIGN_IN_EXPIRED_MESSAGE, CHECK_CONFLICT_MESSAGE, PENDING_RESULTS_MESSAGE, RETAINED_RESULTS_MESSAGE, UNSAVED_RESULTS_MESSAGE } from "../contract/cli-refusals.js";
2
2
  export const OTHER_SETUP_RESULTS_MESSAGE = "A saved result from another Counterfact setup was left untouched.";
3
3
  export const COMPLETION_SETTINGS_MISMATCH_MESSAGE = "This folder has a saved result for a different Counterfact project or address. Run the analysis again with the original settings to save it.";
4
4
  export const matchesCheck = (status, identity) => status.checkId === identity.checkId && status.projectId === identity.projectId;
@@ -20,6 +20,19 @@ export function completionRetryDeadline(timing, lookup, payload, outcome) {
20
20
  /** HTTP status owns certainty; proxy text and unfamiliar server codes cannot discard paid work. */
21
21
  export function completionRecoveryDecision(input) {
22
22
  const { statusLookup, uploadOutcome, payload, retryEnabled, timing = {}, now = Date.now() } = input;
23
+ const kept = Boolean(input.completionStored || input.reportStored) && input.keepLocalResults !== false;
24
+ const giveUp = (code) => {
25
+ // Guidance and machine-readable reasons describe the same local storage fact.
26
+ const messages = {
27
+ check_conflict: CHECK_CONFLICT_MESSAGE, not_allowed: NOT_ALLOWED_MESSAGE, unauthorized: SIGN_IN_EXPIRED_MESSAGE,
28
+ invalid_body: cliRefusals.invalid_body, cli_update_required: cliRefusals.cli_update_required, local_checks_paused: cliRefusals.local_checks_paused,
29
+ };
30
+ const guidance = code && Object.hasOwn(messages, code) ? messages[code] : undefined;
31
+ const results = kept ? RETAINED_RESULTS_MESSAGE : UNSAVED_RESULTS_MESSAGE;
32
+ return { action: "give-up", ...(code === undefined ? {} : { code }),
33
+ message: code === "check_conflict" ? guidance : guidance ? `${guidance}\n${results}` : results,
34
+ ...(input.completionStored === undefined ? {} : { kept, reason: kept ? "results_kept" : "results_discarded" }) };
35
+ };
23
36
  const uploadSaved = uploadOutcome.kind === "saved" || uploadOutcome.kind === "decided" && uploadOutcome.decision.action === "saved";
24
37
  if (input.localMismatch)
25
38
  return !retryEnabled ? { action: "retry", automatic: false, message: COMPLETION_SETTINGS_MISMATCH_MESSAGE }
@@ -36,11 +49,12 @@ export function completionRecoveryDecision(input) {
36
49
  return matching && status.uploadState === "missing" && ["closed", "expired"].includes(status.state)
37
50
  ? { action: "give-up" } : { action: "retry", automatic: false };
38
51
  if (uploadOutcome.kind === "decided" && uploadOutcome.decision.action === "give-up")
39
- return uploadOutcome.decision;
52
+ return input.completionStored === undefined
53
+ ? uploadOutcome.decision : giveUp(uploadOutcome.decision.code);
40
54
  if (status && !matching)
41
- return { action: "give-up", code: "check_conflict", message: CHECK_CONFLICT_MESSAGE };
55
+ return giveUp("check_conflict");
42
56
  if (now >= completionDeadline(timing, statusLookup, payload, uploadOutcome)) {
43
- return { action: "give-up", message: UNSAVED_RESULTS_MESSAGE };
57
+ return giveUp();
44
58
  }
45
59
  const refusals = [uploadOutcome.kind === "refused" ? uploadOutcome : undefined]
46
60
  .filter(value => value !== undefined);
@@ -49,24 +63,12 @@ export function completionRecoveryDecision(input) {
49
63
  : httpStatus === 408 || httpStatus === 429 || httpStatus >= 500 && httpStatus <= 599 || httpStatus === 409 && code === "reservation_closing"
50
64
  || httpStatus < 400 || httpStatus >= 600);
51
65
  const refusal = refusals.find(value => !uncertain(value));
52
- if (refusal) {
53
- // Guidance is explicit per code; copy edits never decide whether results survive.
54
- const messages = {
55
- check_conflict: CHECK_CONFLICT_MESSAGE,
56
- not_allowed: NOT_ALLOWED_MESSAGE,
57
- unauthorized: SIGN_IN_EXPIRED_MESSAGE,
58
- invalid_body: cliRefusals.invalid_body,
59
- cli_update_required: cliRefusals.cli_update_required,
60
- local_checks_paused: cliRefusals.local_checks_paused,
61
- };
62
- return { action: "give-up", code: refusal.code, message: Object.hasOwn(messages, refusal.code)
63
- ? refusal.code === "check_conflict" ? messages[refusal.code] : `${messages[refusal.code]}\n${UNSAVED_RESULTS_MESSAGE}`
64
- : UNSAVED_RESULTS_MESSAGE };
65
- }
66
+ if (refusal)
67
+ return giveUp(refusal.code);
66
68
  if (matching && status.uploadState === "missing" && status.settlement === "released")
67
- return { action: "give-up",
68
- code: status.state === "expired" ? "reservation_expired" : "reservation_closed", message: UNSAVED_RESULTS_MESSAGE };
69
- if (uploadOutcome.kind === "decided")
70
- return uploadOutcome.decision;
71
- return { action: "retry", automatic: now < completionRetryDeadline(timing, statusLookup, payload, uploadOutcome) && refusals.some(value => uncertain(value)), message: PENDING_RESULTS_MESSAGE };
69
+ return giveUp(status.state === "expired" ? "reservation_expired" : "reservation_closed");
70
+ const retry = uploadOutcome.kind === "decided" ? uploadOutcome.decision : {
71
+ action: "retry", automatic: now < completionRetryDeadline(timing, statusLookup, payload, uploadOutcome) && refusals.some(value => uncertain(value)), message: PENDING_RESULTS_MESSAGE
72
+ };
73
+ return retry.action === "retry" && input.completionStored ? { ...retry, reason: "results_pending" } : retry;
72
74
  }
@@ -2,7 +2,8 @@ import { constants } from "node:fs";
2
2
  import { mkdir, open, rename, rm } from "node:fs/promises";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { join } from "node:path";
5
- function credentialsPath(homeDir) { return join(homeDir, ".config/counterfact-labs/credentials"); }
5
+ import { configDirectory } from "../adapters/config-directory.js";
6
+ function credentialsPath(homeDir) { return join(configDirectory(homeDir), "credentials"); }
6
7
  function missing(error) { return error.code === "ENOENT"; }
7
8
  export async function readCredentials(homeDir, baseUrl) {
8
9
  try {
@@ -24,7 +25,7 @@ export async function readCredentials(homeDir, baseUrl) {
24
25
  }
25
26
  }
26
27
  export async function saveCredentials(homeDir, baseUrl, token) {
27
- const directory = join(homeDir, ".config/counterfact-labs");
28
+ const directory = configDirectory(homeDir);
28
29
  await mkdir(directory, { recursive: true, mode: 0o700 });
29
30
  const temporary = join(directory, `.credentials-${randomUUID()}`);
30
31
  try {
@@ -1,7 +1,8 @@
1
+ import { countForm } from "../analysis-core/wording.js";
1
2
  import { stripVTControlCharacters } from "node:util";
2
3
  import { groupByActivity, groupByAudience } from "../analysis-core/analysis/schemas.js";
3
4
  export const TEAM_WORKFLOW_HEADING = "Team workflow";
4
- export const notActiveCountLine = (count) => `${count} more ${count === 1 ? "finding is" : "findings are"} about code that doesn't run today (not active)`;
5
+ export const notActiveCountLine = (count) => `${count} more ${countForm(count, "finding is", "findings are")} about code that doesn't run today (not active)`;
5
6
  export const activityAdvice = (activity) => activity.state === "dead" ? "Remove it (cleanup)."
6
7
  : `Fix this before turning on ${activity.gate}, or remove it if you don't plan to use it.`;
7
8
  export const formatFindingNumber = (seq) => `F-${seq}`;
@@ -119,7 +120,7 @@ export function presentSavedFindings(result, options) {
119
120
  function overflowLine(count, next, options) {
120
121
  const guidance = options.surface === "mcp" ? `Next: get_finding(${JSON.stringify(findingDetailReference(next, options.projectId))}); follow nextFinding for the rest.`
121
122
  : `Run counterfact-labs finding ${next.id} for the next one, or open Full results below.`;
122
- return `${count} more ${count === 1 ? "finding" : "findings"}. ${guidance}\n`;
123
+ return `${count} more ${countForm(count, "finding")}. ${guidance}\n`;
123
124
  }
124
125
  export function formatSavedFindings(result, options) {
125
126
  return presentSavedFindings(result, options).text;
package/dist/cli/git.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { realpath } from "node:fs/promises";
1
2
  import { basename, relative, resolve, sep } from "node:path";
2
3
  import { gitRepositoryRoot } from "../adapters/repository-root.js";
3
4
  import { runGit } from "../adapters/git.js";
@@ -10,7 +11,9 @@ export async function userEmail(folder, git = async (args) => (await runGit(fold
10
11
  }
11
12
  }
12
13
  export async function repositoryFacts(root, git = async (args) => (await runGit(root, args)).toString("utf8")) {
13
- const folderName = basename(resolve(root));
14
+ // Git reports the physical checkout root, so resolve aliases before deriving its selected folder.
15
+ const selected = await realpath(root).catch(() => resolve(root));
16
+ const folderName = basename(selected);
14
17
  const repoRoot = await gitRepositoryRoot(git);
15
18
  if (repoRoot === null)
16
19
  return { remoteUrl: null, relPath: "", folderName, branch: null, commit: null, dirty: null };
@@ -34,6 +37,6 @@ export async function repositoryFacts(root, git = async (args) => (await runGit(
34
37
  // Include new files even when Git hides them, and exclude sibling folders.
35
38
  read(["status", "--porcelain=v2", "--no-renames", "--ignore-submodules=all", "--untracked-files=normal", "--", "."]),
36
39
  ]);
37
- return { repoRoot, remoteUrl, relPath: relative(repoRoot, root).split(sep).join("/"), folderName,
40
+ return { repoRoot, remoteUrl, relPath: relative(repoRoot, selected).split(sep).join("/"), folderName,
38
41
  branch: branch === "HEAD" ? null : branch || null, commit: commit || null, dirty: status === null ? null : status.length > 0 };
39
42
  }