@iowarp/clio-coder 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +92 -2
- package/CONTRIBUTING.md +25 -15
- package/README.md +340 -27
- package/dist/{acp-WNAYYF4F.js → acp-H3CU2HBQ.js} +25 -24
- package/dist/{agents-3OKXHLOI.js → agents-IXQQZ7BD.js} +77 -77
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-VKNNMGPU.js → auth-R7KYF7N3.js} +38 -38
- package/dist/builtins-CRFDQUVP.js +22 -0
- package/dist/{chunk-TQAHXW6Y.js → chunk-22PQ4TX4.js} +4 -4
- package/dist/{chunk-NEDJ26B5.js → chunk-2GPGAE5W.js} +6 -51
- package/dist/{chunk-IKCO5N3L.js → chunk-2QPI3TR3.js} +3 -3
- package/dist/{chunk-HRQMFLJP.js → chunk-32KJPXAM.js} +6 -6
- package/dist/{chunk-65DEGPJ6.js → chunk-3A3CUMKA.js} +6 -4
- package/dist/{chunk-JCI2ROMZ.js → chunk-3T4DXWP6.js} +7 -7
- package/dist/{chunk-DR52UMZW.js → chunk-3UW3KU4A.js} +2 -2
- package/dist/{chunk-6Q3CYFD3.js → chunk-4SVIVOMC.js} +184 -33
- package/dist/{chunk-W54I7H25.js → chunk-5A6XR3RJ.js} +44 -19
- package/dist/{chunk-YPC6ZR5L.js → chunk-5CMARGPF.js} +119 -5
- package/dist/{chunk-KXDSS5WJ.js → chunk-5CY4Q6QI.js} +4 -4
- package/dist/{chunk-I2DWJ4GM.js → chunk-5DDOTTG4.js} +54 -42
- package/dist/{chunk-D4CJV46V.js → chunk-5GZICIYO.js} +3 -3
- package/dist/{chunk-4IUZQIJ3.js → chunk-5PHVPU4G.js} +2 -2
- package/dist/{chunk-3ODX73FK.js → chunk-5VTJP36Q.js} +4 -4
- package/dist/{chunk-54X7T7DK.js → chunk-5ZMXGW7P.js} +79 -7
- package/dist/chunk-5ZSZEYJK.js +119 -0
- package/dist/{chunk-IXIY2H4R.js → chunk-633EXGZA.js} +5 -5
- package/dist/{chunk-CUSRQKPU.js → chunk-6CDNRHWH.js} +299 -89
- package/dist/{chunk-EBY63B7G.js → chunk-6EXUUOSN.js} +2 -2
- package/dist/{chunk-SVNXH4L2.js → chunk-6ICZKDUC.js} +2 -2
- package/dist/{chunk-JEIYHLOR.js → chunk-6SYEGZI3.js} +12 -12
- package/dist/{chunk-DQOVN6KV.js → chunk-6YA46L5A.js} +4 -4
- package/dist/{chunk-NZMNUPZZ.js → chunk-77CZRFTE.js} +3 -3
- package/dist/{chunk-6PAZTBPA.js → chunk-7HBHHVCK.js} +15 -6
- package/dist/{chunk-25QBEXRS.js → chunk-7TKWWPD7.js} +5 -4
- package/dist/{chunk-2VTFPG5O.js → chunk-7WLRF2U5.js} +2 -2
- package/dist/chunk-7WUZEB2M.js +165 -0
- package/dist/{chunk-3UUXNFEX.js → chunk-7YJWEF2L.js} +61 -34
- package/dist/{chunk-3EBYEESD.js → chunk-A46ILRS2.js} +5 -5
- package/dist/{chunk-UOIZ7DA4.js → chunk-AP7HDJOP.js} +2 -2
- package/dist/{chunk-APJ265NV.js → chunk-B5GGDIHT.js} +146 -146
- package/dist/{chunk-PMZVFWSR.js → chunk-B5ZTR6KZ.js} +2 -2
- package/dist/{chunk-I5FWO7L5.js → chunk-B6UM3OZC.js} +2 -2
- package/dist/{chunk-2CU2H6KE.js → chunk-BBV5TKE6.js} +5 -5
- package/dist/{chunk-4O6MANBS.js → chunk-BS4GAMUB.js} +14 -10
- package/dist/{chunk-S66XZJOF.js → chunk-C27U2TYG.js} +2 -2
- package/dist/{chunk-QZWQA4DE.js → chunk-CBSKDFWL.js} +3 -3
- package/dist/{chunk-2LEAKD4C.js → chunk-CKK25WN3.js} +3 -3
- package/dist/{chunk-BYP5D4HI.js → chunk-CTTI7G3T.js} +2 -2
- package/dist/{chunk-XAKHZX5N.js → chunk-CVDAFGPW.js} +4 -4
- package/dist/{chunk-RKKLTLYB.js → chunk-CXQ37WJH.js} +3 -3
- package/dist/{chunk-GTUD2WMY.js → chunk-DBREN25X.js} +44 -9
- package/dist/{chunk-YNFKXPEC.js → chunk-DIMRLNIC.js} +35 -66
- package/dist/{chunk-NDDGJUXD.js → chunk-DNCE23JJ.js} +2 -2
- package/dist/{chunk-HVDIIIQW.js → chunk-DNHVRBH4.js} +3 -3
- package/dist/{chunk-XULDXHTN.js → chunk-DRD2A54W.js} +102 -50
- package/dist/{chunk-D7E7WCDF.js → chunk-DVNAPPXU.js} +2 -2
- package/dist/{chunk-YXLYO42X.js → chunk-DXVMLM3Z.js} +3 -2
- package/dist/{chunk-5MEZN6CB.js → chunk-DZK63TZJ.js} +6 -6
- package/dist/{chunk-IGLP3ODT.js → chunk-E3BQTQUP.js} +15 -15
- package/dist/{chunk-IWHMRKLL.js → chunk-E3LEPLQ2.js} +2 -2
- package/dist/{chunk-3R73A4XB.js → chunk-ECBHH7LU.js} +3 -3
- package/dist/chunk-ECOMVOHP.js +139 -0
- package/dist/chunk-EFSEIZE6.js +56 -0
- package/dist/{chunk-FEAXX7B6.js → chunk-EHCPSZJF.js} +4 -4
- package/dist/{chunk-4NSRCOYP.js → chunk-EHOSNVVM.js} +3 -2
- package/dist/{chunk-7UGL4MB5.js → chunk-EQEJJ53P.js} +10 -10
- package/dist/{chunk-GWZNEVM2.js → chunk-EWD5P3GK.js} +9 -9
- package/dist/{chunk-6UINWWS6.js → chunk-F34AR6O3.js} +14 -14
- package/dist/{chunk-GHS5EBTQ.js → chunk-FKIOX6DS.js} +29 -20
- package/dist/{chunk-HAXOFFRH.js → chunk-FQOOGXBH.js} +7 -7
- package/dist/{chunk-Y55JBDO5.js → chunk-FSTIBAGM.js} +38 -23
- package/dist/{chunk-ZTJUVLTU.js → chunk-FXFVDPWY.js} +2 -2
- package/dist/{chunk-XPLRXC72.js → chunk-GD55RTIW.js} +3 -3
- package/dist/{chunk-5B2AEOW5.js → chunk-GH5ZR6JP.js} +472 -472
- package/dist/{chunk-TOIVGRUX.js → chunk-GJ24ODAX.js} +5 -5
- package/dist/{chunk-QUFRYSWI.js → chunk-GNQRWTMY.js} +129 -48
- package/dist/{chunk-5ICU3EUH.js → chunk-GVYWZNRK.js} +5 -5
- package/dist/{chunk-GX5WYQO4.js → chunk-GXCCHKN6.js} +6 -6
- package/dist/{chunk-K6T2ZAMZ.js → chunk-HGSLRG33.js} +6 -6
- package/dist/{chunk-26QSH3EJ.js → chunk-HHVJNVUJ.js} +5 -5
- package/dist/{chunk-F4EKGO4N.js → chunk-HL26ADLH.js} +4 -2
- package/dist/{chunk-JT2RFCC5.js → chunk-HR3HPQ76.js} +5 -5
- package/dist/{chunk-ID64D7PE.js → chunk-HXHFDHB6.js} +24 -24
- package/dist/{chunk-ELWDPP3Y.js → chunk-I7VLWRK2.js} +8 -8
- package/dist/{chunk-6OSVSQL5.js → chunk-ICO4TQ2F.js} +7 -5
- package/dist/{chunk-SZAA6XDG.js → chunk-IFDRAD6F.js} +2 -2
- package/dist/{chunk-72YIHOZQ.js → chunk-ILJ7DWGE.js} +9 -9
- package/dist/{chunk-2JH2WHGE.js → chunk-J2FYEQ5L.js} +4 -4
- package/dist/{chunk-BMS5RKQY.js → chunk-JABWPKFY.js} +3 -3
- package/dist/{chunk-QDC3K2U3.js → chunk-K2BLQC5E.js} +3 -3
- package/dist/{chunk-AUPNRN7C.js → chunk-K2HL3GBL.js} +4 -4
- package/dist/{chunk-2ASED4PZ.js → chunk-K6RDB7IA.js} +26 -26
- package/dist/{chunk-FFUPXJC4.js → chunk-KDWLXVMN.js} +23 -24
- package/dist/{chunk-OZNBF4L3.js → chunk-KECNXMDE.js} +2 -2
- package/dist/{chunk-6QOTUPRG.js → chunk-KF6GFW6O.js} +66 -18
- package/dist/{chunk-BTK3SSSK.js → chunk-KMF54VH3.js} +2 -2
- package/dist/chunk-KPRLAMP4.js +32 -0
- package/dist/{chunk-ECH6PKUQ.js → chunk-KQ6IDQIB.js} +2 -2
- package/dist/{chunk-3UNOLWNZ.js → chunk-KTFSFCVN.js} +20 -9
- package/dist/{chunk-57XXR6DR.js → chunk-KYKNBD4Y.js} +24 -23
- package/dist/{chunk-IRXAATOX.js → chunk-L4N3DWNW.js} +3 -3
- package/dist/{chunk-LCGCVYZ4.js → chunk-LQTKDAUO.js} +2 -2
- package/dist/{chunk-U6TMQNSI.js → chunk-LTR5QCLS.js} +4 -4
- package/dist/chunk-LUL5Z66S.js +221 -0
- package/dist/{chunk-ELZVTCGV.js → chunk-LVFANMOH.js} +151 -327
- package/dist/{chunk-H7IXIC72.js → chunk-LY4N4TTL.js} +17 -3
- package/dist/{chunk-VKPAQYEB.js → chunk-LZBMXNLP.js} +5 -5
- package/dist/{chunk-UL3WSD3F.js → chunk-M4KFUXS7.js} +2 -2
- package/dist/{chunk-NXYCB2VD.js → chunk-M6TAYK66.js} +6 -6
- package/dist/{chunk-NEKRRTYW.js → chunk-MC3JSVR6.js} +2 -2
- package/dist/{chunk-CFGTUFWB.js → chunk-MCJKEGHO.js} +2 -2
- package/dist/{chunk-DXKJURES.js → chunk-MDU3C27C.js} +10 -7
- package/dist/{chunk-6XLNIQDB.js → chunk-MYI32N4R.js} +2 -2
- package/dist/{chunk-3GY4F45V.js → chunk-NC4KV7EL.js} +6 -6
- package/dist/{chunk-LLXSDWXS.js → chunk-NF3BK5WR.js} +5 -5
- package/dist/chunk-NTK3WTHM.js +141 -0
- package/dist/{chunk-GYV6VZOC.js → chunk-NTTS3O53.js} +2 -2
- package/dist/{chunk-RZDWV63N.js → chunk-NY6IWDVU.js} +6 -6
- package/dist/{chunk-XXYSBZIQ.js → chunk-O2RQ7LCK.js} +4 -4
- package/dist/{chunk-4BJ5BYCE.js → chunk-O3VV6IVK.js} +2 -2
- package/dist/{chunk-W6GROXXM.js → chunk-O5F25NIE.js} +2 -2
- package/dist/{chunk-NXIMQY5W.js → chunk-ODUTYZIU.js} +5 -5
- package/dist/{chunk-LTIKRKFL.js → chunk-ONRTXOZY.js} +4 -4
- package/dist/{chunk-KFV5L5SK.js → chunk-OQM5IVJY.js} +118 -232
- package/dist/{chunk-XRZT5WY5.js → chunk-P5SC4DLJ.js} +4 -4
- package/dist/{chunk-R6Q67RJH.js → chunk-PECBKCDK.js} +34 -6
- package/dist/{chunk-33YXPOE3.js → chunk-PPEZJWUG.js} +2 -2
- package/dist/{chunk-RXTN6AKH.js → chunk-PWWSIB2A.js} +5 -5
- package/dist/{chunk-2STGEDFV.js → chunk-QEQISF75.js} +2 -2
- package/dist/{chunk-3DPEIQKN.js → chunk-QH3ZTUOA.js} +2 -2
- package/dist/{chunk-YAKGTXEV.js → chunk-QRFXEO6Y.js} +2 -2
- package/dist/{chunk-35MSIRKH.js → chunk-QUIJZSDW.js} +2 -2
- package/dist/{chunk-HHV2GANA.js → chunk-R2P2U3ZS.js} +2 -2
- package/dist/{chunk-2DSOYNFC.js → chunk-R6MAYTMS.js} +7 -7
- package/dist/{chunk-JQLNNIKT.js → chunk-R6MICQYU.js} +6 -6
- package/dist/{chunk-NAI6ZFCY.js → chunk-RLTT5GVY.js} +122 -11
- package/dist/{chunk-DT3LWJOB.js → chunk-RXIOCVBZ.js} +24 -6
- package/dist/{chunk-N56KALIC.js → chunk-S32UQ5GL.js} +61 -34
- package/dist/{chunk-UEPWCCTY.js → chunk-SBZX6ARC.js} +12 -12
- package/dist/chunk-SD7SHNDW.js +15 -0
- package/dist/{chunk-NRO2BJRH.js → chunk-SDWNDICN.js} +10235 -4015
- package/dist/{chunk-UXCU4E3T.js → chunk-SE4ZKILO.js} +6 -6
- package/dist/chunk-SL2RDHKO.js +19 -0
- package/dist/{chunk-NUGM5KR6.js → chunk-SRCEQKQS.js} +2 -2
- package/dist/{chunk-OMQNJVKW.js → chunk-SRZOW5L2.js} +43 -13
- package/dist/{chunk-3M6DQK6S.js → chunk-T334FW2H.js} +7 -7
- package/dist/{chunk-V76WTFTW.js → chunk-T52TPHYC.js} +6 -6
- package/dist/{chunk-I7XBWTYH.js → chunk-T53XI6I7.js} +5 -5
- package/dist/{chunk-2ZSONWVL.js → chunk-T7FDXNRU.js} +13 -13
- package/dist/{chunk-JSD46VO2.js → chunk-TEG3RYVZ.js} +43 -36
- package/dist/{chunk-3I7MS7N2.js → chunk-TK2BMCBZ.js} +2 -2
- package/dist/{chunk-5OIVVPHF.js → chunk-TN5FW4XY.js} +13 -6
- package/dist/{chunk-75W7L2E2.js → chunk-TZ7MFRG4.js} +1041 -162
- package/dist/{chunk-36CT5VVL.js → chunk-U2JOLB7O.js} +126 -77
- package/dist/{chunk-LL4KHSZI.js → chunk-U2MSJ57E.js} +2 -2
- package/dist/{chunk-FTMGRKEF.js → chunk-U44YYLVV.js} +4 -4
- package/dist/{chunk-YECAMM3D.js → chunk-U7H5WRG5.js} +5 -5
- package/dist/{chunk-RQCKCSRL.js → chunk-U7VQ4NI4.js} +22 -22
- package/dist/{chunk-5TUB6SLS.js → chunk-UFYNOQK4.js} +7 -7
- package/dist/{chunk-R346GLFC.js → chunk-UHW5V7HC.js} +2 -2
- package/dist/{chunk-USR47QNF.js → chunk-UL36QJX6.js} +14 -14
- package/dist/{chunk-VIA6RFQZ.js → chunk-UQIVHSE4.js} +4 -4
- package/dist/{chunk-RAY4OVGZ.js → chunk-URBGEOH3.js} +5 -5
- package/dist/chunk-USZA7GWL.js +341 -0
- package/dist/{chunk-YD5GIKET.js → chunk-UTUNT5QL.js} +48 -579
- package/dist/{chunk-ZA4VCIGV.js → chunk-UUQ5G6EZ.js} +60 -41
- package/dist/{chunk-23L32XTI.js → chunk-UXAC2FX4.js} +68 -39
- package/dist/{chunk-VG7TBQIY.js → chunk-V552WL53.js} +68 -4
- package/dist/{chunk-BWH6N36D.js → chunk-VHKTOLEW.js} +272 -42
- package/dist/{chunk-EXLD33WO.js → chunk-VLPTKCKT.js} +24 -9
- package/dist/{chunk-336NSSKI.js → chunk-VNBICSS2.js} +2 -2
- package/dist/{chunk-VAVR4IJY.js → chunk-VQD7NH7Z.js} +3 -3
- package/dist/{chunk-LBMZMYH2.js → chunk-W2RJEH6Q.js} +3 -3
- package/dist/{chunk-7CR24IG7.js → chunk-WDV62RKY.js} +2 -2
- package/dist/{chunk-S6PYF2XF.js → chunk-WFKDPU7U.js} +4 -4
- package/dist/{chunk-BJVFZO5U.js → chunk-WJIMKGD6.js} +7 -7
- package/dist/{chunk-5636DCO5.js → chunk-WLMSOT73.js} +59 -12
- package/dist/{chunk-MXHC5QYU.js → chunk-WTQGRBHV.js} +5 -144
- package/dist/chunk-WXA2CFJO.js +23 -0
- package/dist/{chunk-QSNYB6ZV.js → chunk-XCUDZQLX.js} +3 -3
- package/dist/{chunk-4M6Z5QVF.js → chunk-XXBQKW32.js} +11 -11
- package/dist/{chunk-OEJSLEPW.js → chunk-YEJIG7LN.js} +332 -332
- package/dist/chunk-YGDMBK7O.js +567 -0
- package/dist/{chunk-4WR7VSYB.js → chunk-YYB3MC65.js} +23 -9
- package/dist/{chunk-2IR2NMPA.js → chunk-ZIDFQJRB.js} +2 -2
- package/dist/{chunk-Q4WO54TA.js → chunk-ZMZQEBKI.js} +14 -14
- package/dist/{chunk-6EJMN2Y3.js → chunk-ZTNFYMIO.js} +2 -2
- package/dist/{chunk-WEPFGWHJ.js → chunk-ZZFWWYLX.js} +2 -2
- package/dist/cli/index.js +44 -44
- package/dist/clio-5I2IBFYL.js +26 -0
- package/dist/{code-nav-IJR2DBPR.js → code-nav-YXIAEZVS.js} +48 -32
- package/dist/codewiki/build-worker.js +76 -29
- package/dist/{compile-cache-OQAVB7Y5.js → compile-cache-WJEPUZEJ.js} +4 -4
- package/dist/{components-2TGAI2RC.js → components-TNIKXCBH.js} +13 -13
- package/dist/{config-IUA6OYNS.js → config-Y2JDJ3JJ.js} +210 -124
- package/dist/configure-SML6UBZ5.js +55 -0
- package/dist/{context-4MPR7WKB.js → context-P5YSEO55.js} +125 -121
- package/dist/{context-2DKHWH2T.js → context-QQ53HSGJ.js} +91 -62
- package/dist/{context-BOYF5EJM.js → context-S2EEC3EJ.js} +62 -31
- package/dist/context-clear-TMEQCOTH.js +183 -0
- package/dist/{context-index-HNG3MOME.js → context-index-HP2JFUWA.js} +13 -11
- package/dist/{context-map-COB37XXN.js → context-map-INTXD54D.js} +71 -21
- package/dist/{context-working-set-3I3FYX6Y.js → context-working-set-CNLSQN5K.js} +31 -31
- package/dist/detail-5572VLBO.js +114 -0
- package/dist/{dispatch-runner-RJ5I2F2O.js → dispatch-runner-FRHD6P2O.js} +191 -116
- package/dist/{docs-SPOV3BAN.js → docs-BL7ROUFN.js} +4 -4
- package/dist/{doctor-DKICC2SN.js → doctor-N3LCM2LG.js} +58 -58
- package/dist/{eval-OQOQUDHK.js → eval-BUU3ZOUZ.js} +473 -168
- package/dist/{eval-inventory-Y6QRFOH5.js → eval-inventory-QOYZERXJ.js} +7 -7
- package/dist/evidence-DTGEN456.js +224 -0
- package/dist/{evidence-4DQ25GUQ.js → evidence-SQ5DNFEN.js} +110 -94
- package/dist/{evolve-GSS52E5J.js → evolve-IJNUFZDS.js} +107 -91
- package/dist/{extensions-G7MFLYHT.js → extensions-YVRHX6ZI.js} +16 -16
- package/dist/{fleet-Q37YHHAQ.js → fleet-ZNNVSYFO.js} +147 -147
- package/dist/{fleet-commands-G7E4N7SM.js → fleet-commands-5YE7NPJL.js} +27 -26
- package/dist/{fleet-decisions-O7M6QBA2.js → fleet-decisions-3SBSCTCW.js} +16 -15
- package/dist/{fleet-graph-TOUBW6OW.js → fleet-graph-6HHPWF5T.js} +39 -38
- package/dist/{fleet-inspect-SW33JJNI.js → fleet-inspect-JEYMGCGC.js} +107 -91
- package/dist/{fleet-new-RDVJLHHH.js → fleet-new-RCKGSRDV.js} +3 -3
- package/dist/{fleet-preflight-CV2655TW.js → fleet-preflight-QRSHIIDE.js} +10 -9
- package/dist/{fleet-validate-KESZX2YH.js → fleet-validate-4PM4GDDL.js} +46 -42
- package/dist/{fleet-verify-UQPMTVE3.js → fleet-verify-NJDTHTO3.js} +105 -89
- package/dist/fleet-view-UP2BWQQY.js +117 -0
- package/dist/{init-PXEXQSBF.js → init-S3GZQ5ZF.js} +123 -123
- package/dist/{install-NKNG7KD4.js → install-3RZDDP23.js} +5 -5
- package/dist/{interop-ZG5T62U3.js → interop-YOTGXFJM.js} +25 -25
- package/dist/inventory-K2OZ36YJ.js +117 -0
- package/dist/{library-B2W4N74O.js → library-GJI6W6OK.js} +45 -44
- package/dist/{memory-YCANYS5A.js → memory-OQOXQGYD.js} +107 -93
- package/dist/{models-GERTU3YI.js → models-3IK2Y5WE.js} +63 -62
- package/dist/{monitor-CPNIUULB.js → monitor-FTJLTKCQ.js} +136 -107
- package/dist/{orchestrator-J4BSH4WQ.js → orchestrator-N47O7SFD.js} +1159 -697
- package/dist/{panes-BOHAEGYC.js → panes-7BTYH3XQ.js} +8 -8
- package/dist/{panes-NXSLDQZ2.js → panes-WPOMEMRH.js} +22 -22
- package/dist/{paths-VSUWNC22.js → paths-J3KN7UAO.js} +12 -12
- package/dist/preload-65U34NG6.js +115 -0
- package/dist/{registry-LG64LTF4.js → registry-DESGAXWK.js} +3 -3
- package/dist/{reset-TNWTB5LU.js → reset-MUVQDLNL.js} +20 -20
- package/dist/{resources-4PXNMD5G.js → resources-LM76COAO.js} +41 -40
- package/dist/{run-D6XJ34CN.js → run-3VFZQ33N.js} +162 -156
- package/dist/{share-2NWMJJEE.js → share-4JUB4BL7.js} +43 -42
- package/dist/{skills-KR7WON5G.js → skills-S36AAJHU.js} +47 -46
- package/dist/{skills-eval-O2ZNOLDS.js → skills-eval-G6T57L7M.js} +127 -107
- package/dist/{skills-inventory-ZZOUBK7O.js → skills-inventory-WLM46PJH.js} +41 -40
- package/dist/slash-commands-GBARG3Y7.js +91 -0
- package/dist/{steer-XA25PSCS.js → steer-S7D7IKPU.js} +7 -7
- package/dist/{support-7EMVWYG2.js → support-5VAEC32W.js} +14 -14
- package/dist/{targets-OMH2XCSN.js → targets-N5REUETU.js} +145 -94
- package/dist/tasks-6BVY5YZF.js +36 -0
- package/dist/{terminal-lease-C2J3JYRE.js → terminal-lease-57UEOJKS.js} +12 -11
- package/dist/tools-6OCQ6SVB.js +28 -0
- package/dist/{trace-FXMXUZUF.js → trace-JHLXWUMN.js} +18 -17
- package/dist/{tree-sitter-HGKH6LG4.js → tree-sitter-AQUUOSYM.js} +6 -6
- package/dist/{tui-primitives-K5PASC3O.js → tui-primitives-RCY2HN7G.js} +3 -3
- package/dist/{uninstall-HALS6BLF.js → uninstall-FXYMFFRT.js} +17 -17
- package/dist/{upgrade-MS72RJEP.js → upgrade-4HD5HAIV.js} +40 -39
- package/dist/{usage-NHG6MCJM.js → usage-4GWM2WWP.js} +136 -105
- package/dist/{verifiers-7AUNVXDY.js → verifiers-GSKWKWVG.js} +28 -27
- package/dist/verify-3AS3ULCY.js +30 -0
- package/dist/{version-KGEG7EPO.js → version-RFPKO6T7.js} +4 -4
- package/dist/{web-fetch-V4FKSDAV.js → web-fetch-MQN4FH3X.js} +169 -18
- package/dist/wiki-generate-7BV7XWIY.js +614 -0
- package/dist/{with-panes-BDQEWBRT.js → with-panes-OFTNAR4Y.js} +34 -20
- package/dist/worker/entry.js +99 -88
- package/dist/{workspace-ZJ6BFM3Q.js → workspace-DZ7JADBG.js} +6 -6
- package/docs/README.md +7 -6
- package/docs/architecture/acp.md +10 -0
- package/docs/architecture/architecture.md +5 -5
- package/docs/architecture/context-engine.md +44 -59
- package/docs/architecture/context-working-set.md +7 -9
- package/docs/architecture/dispatch-architecture-rationale.md +1 -1
- package/docs/architecture/evidence-and-memory.md +10 -0
- package/docs/architecture/pi-boundary.md +37 -7
- package/docs/architecture/prompt-envelope-and-tools.md +7 -7
- package/docs/architecture/session-lifecycle.md +4 -4
- package/docs/architecture/worker-dispatch-mechanics.md +4 -0
- package/docs/guide/commands-and-modes.md +49 -36
- package/docs/guide/configuration-and-targets.md +7 -2
- package/docs/guide/configuration-reference.md +13 -3
- package/docs/guide/environment-variables.md +6 -2
- package/docs/guide/fleet-dispatch.md +12 -0
- package/docs/guide/installation-and-lifecycle.md +35 -9
- package/docs/guide/proactive-memory.md +1 -1
- package/docs/guide/skills-marketplace.md +11 -3
- package/docs/guide/tool-usage.md +9 -2
- package/docs/process/development-pipeline.md +10 -10
- package/docs/process/documentation-guide.md +2 -2
- package/docs/process/eval-runner.md +15 -0
- package/docs/process/evals-internal.md +1 -1
- package/docs/process/release-cut-checklist.md +6 -6
- package/evals/README.md +4 -0
- package/evals/behavioral-corpus-grader.mjs +147 -14
- package/evals/behavioral-model-negative-control.yaml +1 -0
- package/evals/behavioral-model.yaml +266 -1
- package/evals/fixtures/docs-retrieval.json +102 -0
- package/evals/fixtures/scalar-decision.json +17 -0
- package/evals/fixtures/scout-citation-pipeline.json +55 -0
- package/evals/fixtures/source-explanation.json +74 -0
- package/evals/fixtures/tool-arguments.json +18 -0
- package/evals/fixtures/tool-surface/read.txt +4 -0
- package/evals/fixtures/tool-surface/subdir/keep.txt +1 -0
- package/evals/no-edit-memory-grader.mjs +149 -0
- package/evals/scalar-decision-grader.py +41 -0
- package/evals/scalar-decision-machinery.ts +145 -0
- package/evals/source-explanation-grader.mjs +118 -0
- package/evals/tool-surface-grader.mjs +53 -0
- package/evals/tool-surface-model.yaml +274 -0
- package/package.json +14 -14
- package/skills/README.md +6 -6
- package/skills/registry.yaml +1 -1
- package/skills/skill-marketplace.json +1 -1
- package/src/cli/bootstrap-generate.ts +6 -0
- package/src/cli/config-inspect.ts +24 -7
- package/src/cli/config-trust.ts +62 -0
- package/src/cli/config.ts +8 -0
- package/src/cli/context-map.ts +75 -14
- package/src/cli/context.ts +46 -17
- package/src/cli/eval.ts +17 -3
- package/src/cli/modes/print.ts +32 -4
- package/src/cli/run.ts +16 -14
- package/src/cli/skills-eval.ts +10 -8
- package/src/cli/steer-channel.ts +31 -18
- package/src/cli/targets.ts +83 -31
- package/src/cli/tasks.ts +10 -1
- package/src/cli/upgrade.ts +9 -6
- package/src/cli/usage.ts +24 -0
- package/src/cli/wiki-generate.ts +239 -96
- package/src/core/bash-exec.ts +43 -15
- package/src/core/bus-events.ts +15 -0
- package/src/core/config.ts +33 -14
- package/src/core/defaults.ts +5 -4
- package/src/core/file-references.ts +11 -1
- package/src/core/incomplete-installation.ts +3 -1
- package/src/core/settings-layers.ts +21 -5
- package/src/core/termination.ts +26 -9
- package/src/core/untrusted-content.ts +16 -0
- package/src/core/workspace-trust.ts +179 -0
- package/src/domains/agents/builtins/coder.md +4 -2
- package/src/domains/agents/builtins/context-bootstrap.md +3 -1
- package/src/domains/agents/builtins/documenter.md +7 -4
- package/src/domains/agents/builtins/researcher.md +1 -0
- package/src/domains/agents/builtins/scout.md +7 -1
- package/src/domains/agents/result-contract.ts +199 -26
- package/src/domains/context/bootstrap-prompt.ts +11 -9
- package/src/domains/context/bootstrap.ts +74 -39
- package/src/domains/context/clio-md.ts +88 -26
- package/src/domains/context/codewiki/build-operation.ts +121 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +37 -3
- package/src/domains/context/codewiki/build-worker.ts +3 -35
- package/src/domains/context/codewiki/coordinator.ts +36 -6
- package/src/domains/context/codewiki/indexer.ts +59 -19
- package/src/domains/context/contract.ts +6 -2
- package/src/domains/context/extension.ts +72 -10
- package/src/domains/context/fingerprint.ts +39 -34
- package/src/domains/context/index.ts +7 -1
- package/src/domains/context/prompt-context.ts +55 -14
- package/src/domains/context/refresh.ts +9 -57
- package/src/domains/context/wiki/assemble.ts +14 -10
- package/src/domains/context/wiki/evidence.ts +209 -0
- package/src/domains/context/wiki/generate.ts +201 -67
- package/src/domains/context/wiki/meta.ts +10 -2
- package/src/domains/context/wiki/plan-store.ts +70 -14
- package/src/domains/context/wiki/plan.ts +71 -14
- package/src/domains/context/wiki/prompts.ts +42 -1
- package/src/domains/context/wiki/source-content.ts +106 -0
- package/src/domains/context/wiki/staleness.ts +33 -22
- package/src/domains/context/working-set/contract.ts +8 -2
- package/src/domains/context/working-set/engine.ts +17 -4
- package/src/domains/context/working-set/fold.ts +15 -2
- package/src/domains/context/working-set/marker.ts +2 -1
- package/src/domains/context/working-set/project.ts +18 -7
- package/src/domains/context/working-set/recall.ts +82 -56
- package/src/domains/dispatch/active-route-planner.ts +6 -3
- package/src/domains/dispatch/admission-queue.ts +19 -7
- package/src/domains/dispatch/admission.ts +3 -3
- package/src/domains/dispatch/budget-envelope.ts +47 -82
- package/src/domains/dispatch/capacity-lease.ts +57 -19
- package/src/domains/dispatch/contract.ts +10 -2
- package/src/domains/dispatch/event-pump.ts +28 -7
- package/src/domains/dispatch/execution-role.ts +49 -2
- package/src/domains/dispatch/execution-scheduler.ts +2 -0
- package/src/domains/dispatch/extension.ts +190 -105
- package/src/domains/dispatch/fleet-run.ts +20 -0
- package/src/domains/dispatch/gate-role-prompts.ts +4 -2
- package/src/domains/dispatch/parallel-writers.ts +34 -0
- package/src/domains/dispatch/reservation-store.ts +8 -34
- package/src/domains/dispatch/route-approval.ts +3 -3
- package/src/domains/dispatch/route-observer.ts +4 -2
- package/src/domains/dispatch/route-quality.ts +6 -1
- package/src/domains/dispatch/types.ts +4 -3
- package/src/domains/dispatch/worker-spawn.ts +58 -21
- package/src/domains/dispatch/workspace-checkpoint.ts +57 -0
- package/src/domains/eval/compare/behavioral.ts +81 -14
- package/src/domains/eval/compare/compare.ts +15 -5
- package/src/domains/eval/compare/envelope.ts +12 -5
- package/src/domains/eval/metrics/context.ts +24 -1
- package/src/domains/eval/metrics/tracked.ts +4 -28
- package/src/domains/eval/reports/comparison.ts +9 -9
- package/src/domains/eval/runners/clio-run.ts +5 -1
- package/src/domains/eval/schema/suite.ts +2 -0
- package/src/domains/eval/schema/validate.ts +1 -0
- package/src/domains/eval/suites/run.ts +189 -13
- package/src/domains/eval/verifiers/integrity.ts +39 -0
- package/src/domains/eval/verifiers/patch.ts +58 -2
- package/src/domains/eval/workspaces/temp-copy.ts +3 -0
- package/src/domains/evidence/build.ts +4 -2
- package/src/domains/interop/registry.ts +2 -2
- package/src/domains/middleware/hooks-io.ts +45 -26
- package/src/domains/middleware/hooks.ts +6 -0
- package/src/domains/middleware/injection-screen.ts +23 -0
- package/src/domains/middleware/rules.ts +5 -1
- package/src/domains/middleware/stalled-turn.ts +18 -3
- package/src/domains/middleware/task-board-reminder.ts +4 -2
- package/src/domains/middleware/task-nudge.ts +4 -1
- package/src/domains/mux/contract.ts +34 -1
- package/src/domains/mux/dock-controller.ts +8 -1
- package/src/domains/mux/index.ts +1 -0
- package/src/domains/mux/socket-client.ts +13 -3
- package/src/domains/observability/contract.ts +2 -2
- package/src/domains/observability/projection.ts +30 -9
- package/src/domains/prompts/compiler.ts +10 -2
- package/src/domains/prompts/contract.ts +7 -4
- package/src/domains/prompts/extension.ts +28 -64
- package/src/domains/prompts/fragments/identity/clio.md +23 -0
- package/src/domains/prompts/fragments/operating/contract.md +10 -0
- package/src/domains/prompts/fragments/operating/delegation.md +5 -0
- package/src/domains/prompts/fragments/wiki/page.md +28 -15
- package/src/domains/prompts/fragments/wiki/plan.md +4 -4
- package/src/domains/prompts/preload-prefix.ts +31 -0
- package/src/domains/prompts/preload.ts +135 -61
- package/src/domains/providers/auth/backend-file.ts +15 -11
- package/src/domains/providers/auth/storage.ts +3 -5
- package/src/domains/providers/catalog.ts +18 -3
- package/src/domains/providers/runtime-resolution.ts +11 -9
- package/src/domains/providers/runtimes/cloud/openrouter.ts +2 -0
- package/src/domains/resources/skills/promotion.ts +8 -1
- package/src/domains/safety/action-classifier.ts +9 -0
- package/src/domains/safety/autonomy.ts +10 -1
- package/src/domains/safety/contract.ts +5 -1
- package/src/domains/safety/default-path-policy.ts +11 -0
- package/src/domains/safety/extension.ts +11 -2
- package/src/domains/safety/policy-engine.ts +189 -32
- package/src/domains/safety/project-policy.ts +7 -2
- package/src/domains/safety/workspace-trust.ts +43 -0
- package/src/domains/session/compaction/compact.ts +384 -21
- package/src/domains/session/compaction/cut-point.ts +42 -5
- package/src/domains/session/compaction/tokens.ts +9 -1
- package/src/domains/session/decision-board.ts +43 -33
- package/src/domains/session/entries.ts +169 -4
- package/src/domains/session/prompt-manifest.ts +47 -8
- package/src/domains/session/task-board.ts +21 -3
- package/src/domains/user-tasks/handoff.ts +16 -0
- package/src/engine/acp/adapter.ts +44 -12
- package/src/engine/acp/server.ts +1 -0
- package/src/engine/acp/transport.ts +2 -1
- package/src/engine/acp/types.ts +6 -1
- package/src/engine/antigravity/subprocess-runtime.ts +20 -4
- package/src/engine/api-registry.ts +19 -2
- package/src/engine/apis/openai-completions.ts +13 -6
- package/src/engine/apis/output-budget.ts +26 -10
- package/src/engine/claude/sdk-runtime.ts +4 -3
- package/src/engine/env-api-keys.ts +2 -1
- package/src/engine/external-subprocess.ts +14 -3
- package/src/engine/loop-guard.ts +19 -2
- package/src/engine/provider-diagnostics.ts +129 -0
- package/src/engine/provider-payload.ts +3 -1
- package/src/engine/worker-runtime.ts +13 -2
- package/src/engine/worker-tools.ts +5 -1
- package/src/entry/extension-reload.ts +1 -0
- package/src/entry/orchestrator.ts +53 -15
- package/src/interactive/chat-loop-messages.ts +12 -4
- package/src/interactive/chat-loop.ts +115 -45
- package/src/interactive/chat-renderer.ts +60 -0
- package/src/interactive/context-recall-command.ts +2 -1
- package/src/interactive/dispatch-board.ts +17 -2
- package/src/interactive/editor-submit.ts +13 -0
- package/src/interactive/interactive-application.ts +8 -2
- package/src/interactive/interactive-event-projection.ts +7 -1
- package/src/interactive/interactive-presentation.ts +15 -7
- package/src/interactive/interactive-slash-runtime.ts +2 -0
- package/src/interactive/layout.ts +2 -1
- package/src/interactive/model-session-replay.ts +2 -2
- package/src/interactive/overlay-frame.ts +1 -0
- package/src/interactive/overlay-general-openers.ts +3 -1
- package/src/interactive/overlay-session-lifecycle.ts +6 -0
- package/src/interactive/overlays/ask-user.ts +1 -0
- package/src/interactive/overlays/message-picker.ts +1 -1
- package/src/interactive/renderers/tool-execution.ts +17 -1
- package/src/interactive/renderers/worker-entry.ts +25 -10
- package/src/interactive/slash-commands.ts +9 -7
- package/src/interactive/turn-context.ts +221 -53
- package/src/interactive/turn-middleware.ts +3 -1
- package/src/interactive/turn-persistence.ts +3 -0
- package/src/interactive/turn-runtime.ts +11 -2
- package/src/interactive/turn-state.ts +10 -9
- package/src/interactive/watch-pane.ts +18 -4
- package/src/interactive/worker-stream.ts +7 -7
- package/src/tools/agent-tools.ts +6 -3
- package/src/tools/bash.ts +1 -1
- package/src/tools/builtin-tool-catalog.ts +9 -2
- package/src/tools/codewiki/code-nav.ts +4 -10
- package/src/tools/compete-judge-task.ts +71 -0
- package/src/tools/compete-worktrees.ts +34 -0
- package/src/tools/context/index.ts +32 -7
- package/src/tools/context/surface.ts +15 -4
- package/src/tools/decide.ts +1 -1
- package/src/tools/dispatch-admission.ts +12 -1
- package/src/tools/dispatch-arguments.ts +38 -1
- package/src/tools/dispatch-plan.ts +7 -7
- package/src/tools/dispatch-runner.ts +48 -32
- package/src/tools/dispatch-schema.ts +30 -23
- package/src/tools/dispatch-scout-admission.ts +10 -44
- package/src/tools/dispatch-scout.ts +2 -3
- package/src/tools/find.ts +13 -4
- package/src/tools/grep.ts +13 -1
- package/src/tools/ls.ts +7 -1
- package/src/tools/monitor.ts +26 -11
- package/src/tools/network-policy.ts +11 -24
- package/src/tools/observation.ts +39 -2
- package/src/tools/read.ts +112 -15
- package/src/tools/registry.ts +54 -17
- package/src/tools/result-shaping.ts +110 -2
- package/src/tools/tasks.ts +33 -7
- package/src/tools/verify/frontend.ts +67 -30
- package/src/tools/verify/numeric.ts +6 -1
- package/src/tools/web-fetch-network.ts +179 -0
- package/src/tools/web-fetch-surface.ts +2 -1
- package/src/tools/web-fetch.ts +15 -13
- package/src/tools/worker-evidence.ts +27 -0
- package/src/worker/spec-contract.ts +12 -8
- package/dist/builtins-WGALA46I.js +0 -22
- package/dist/chunk-2WZ546HR.js +0 -792
- package/dist/chunk-5PSMVOLM.js +0 -56
- package/dist/chunk-EL24TAU4.js +0 -1560
- package/dist/chunk-IZXGRF7P.js +0 -4048
- package/dist/chunk-JVCV3ICN.js +0 -47
- package/dist/chunk-MNJGS2IN.js +0 -33
- package/dist/chunk-O5CVSAG5.js +0 -122
- package/dist/chunk-ODGTEFFI.js +0 -50
- package/dist/chunk-OQE5J4C6.js +0 -73
- package/dist/chunk-UUVG37B4.js +0 -244
- package/dist/chunk-V6HJFQZE.js +0 -228
- package/dist/clio-QLICPCF5.js +0 -25
- package/dist/configure-VEPX4NMX.js +0 -55
- package/dist/context-clear-S4ZJCQUX.js +0 -182
- package/dist/detail-A7JAVSIG.js +0 -98
- package/dist/evidence-4F5USFKH.js +0 -208
- package/dist/fleet-view-MN2VG4MR.js +0 -101
- package/dist/inventory-C26CFDRR.js +0 -101
- package/dist/preload-P6DGH2PZ.js +0 -13
- package/dist/slash-commands-ZXPJD64J.js +0 -92
- package/dist/tasks-IPAGMEIX.js +0 -36
- package/dist/tools-EFFEAIDP.js +0 -28
- package/dist/verify-FWYGPKMR.js +0 -29
- package/dist/wiki-generate-743CIGJW.js +0 -476
|
@@ -17,12 +17,19 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import type { Codewiki, CodewikiFile } from "../codewiki/schema.js";
|
|
20
|
+
import type { WikiSourceContent } from "./source-content.js";
|
|
20
21
|
|
|
21
22
|
export type WikiDepth = "auto" | "simple" | "medium" | "detailed";
|
|
22
23
|
export type ResolvedWikiDepth = Exclude<WikiDepth, "auto">;
|
|
23
24
|
|
|
24
25
|
export type WikiPageStatus = "pending" | "written";
|
|
25
26
|
|
|
27
|
+
export interface WikiPageFailure {
|
|
28
|
+
phase: "admission" | "writer" | "validation";
|
|
29
|
+
detail: string;
|
|
30
|
+
runId?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
export interface WikiPlanPage {
|
|
27
34
|
/** POSIX-relative page path inside the wiki root. */
|
|
28
35
|
path: string;
|
|
@@ -31,14 +38,30 @@ export interface WikiPlanPage {
|
|
|
31
38
|
intent: string;
|
|
32
39
|
/** Repository-relative source files that ground the page. */
|
|
33
40
|
sources: string[];
|
|
41
|
+
/** Harness-owned cited source/test paths retained even after routing repair drops a missing path. */
|
|
42
|
+
dependencies?: string[];
|
|
34
43
|
/** Harness-owned: whether this page has been written in a completed dispatch. */
|
|
35
44
|
status: WikiPageStatus;
|
|
36
|
-
/** Harness-owned:
|
|
45
|
+
/** Harness-owned: admitted writer attempts for this page specification, including explicit retries. */
|
|
37
46
|
attempts: number;
|
|
47
|
+
/** Last unsuccessful outcome, retained across publication and authored replanning. */
|
|
48
|
+
lastFailure?: WikiPageFailure;
|
|
38
49
|
}
|
|
39
50
|
|
|
40
51
|
export interface WikiPlan {
|
|
41
52
|
version: 1;
|
|
53
|
+
/** Harness-owned resolved coverage depth; absent in legacy checkpoints. */
|
|
54
|
+
depth?: ResolvedWikiDepth;
|
|
55
|
+
/** Harness-owned policy, retained before the first publication on interrupted runs. */
|
|
56
|
+
requestedDepth?: WikiDepth;
|
|
57
|
+
/** Source revision observed before dispatch; stale checkpoints must be revalidated. */
|
|
58
|
+
sourceTreeHash?: string;
|
|
59
|
+
/** Harness-captured Git baseline for resuming before any wiki has been published. */
|
|
60
|
+
sourceGitHead?: string;
|
|
61
|
+
/** Source bytes observed before dispatch, shared across page dependencies. */
|
|
62
|
+
sourceContent?: WikiSourceContent;
|
|
63
|
+
/** Harness-owned retirements from authored replanning; explicit reintroduction clears a path. */
|
|
64
|
+
retiredPages?: string[];
|
|
42
65
|
/** One paragraph describing what this repository is; opens the generated quickstart. */
|
|
43
66
|
overview: string;
|
|
44
67
|
pages: WikiPlanPage[];
|
|
@@ -161,8 +184,9 @@ function collectAreas(source: ReadonlyArray<CodewikiFile>, areaDepth: number): A
|
|
|
161
184
|
|
|
162
185
|
/**
|
|
163
186
|
* The architecture page every wiki gets. It is the one page whose subject is
|
|
164
|
-
* the repository rather than a directory
|
|
165
|
-
* points
|
|
187
|
+
* the repository rather than a directory. With separate area pages it is
|
|
188
|
+
* anchored on indexed entry points; a combined simple page uses its full
|
|
189
|
+
* ownership group's ranked anchors instead.
|
|
166
190
|
*/
|
|
167
191
|
function overviewPage(source: ReadonlyArray<CodewikiFile>): WikiPlanPage {
|
|
168
192
|
const entries = source.filter((file) => file.role === "entry");
|
|
@@ -170,14 +194,27 @@ function overviewPage(source: ReadonlyArray<CodewikiFile>): WikiPlanPage {
|
|
|
170
194
|
path: "architecture.md",
|
|
171
195
|
title: "Architecture",
|
|
172
196
|
intent:
|
|
173
|
-
"Explain what this repository is
|
|
174
|
-
"and where the
|
|
197
|
+
"Explain what this repository is and its top-level composition; describe relationships, boundaries, " +
|
|
198
|
+
"and request or command flow where the inspected source establishes them.",
|
|
175
199
|
sources: rankedSources(entries.length > 0 ? entries : source),
|
|
176
200
|
status: "pending",
|
|
177
201
|
attempts: 0,
|
|
178
202
|
};
|
|
179
203
|
}
|
|
180
204
|
|
|
205
|
+
/** Counts describe assigned indexed coverage, not the bounded prompt anchors. */
|
|
206
|
+
function intentForScope(files: ReadonlyArray<CodewikiFile>, areaDepth: number): string {
|
|
207
|
+
const lines = files.reduce((total, file) => total + Math.max(0, file.loc), 0);
|
|
208
|
+
const scopes = [...new Set(files.map((file) => areaForPath(file.path, areaDepth)))];
|
|
209
|
+
return (
|
|
210
|
+
`Assigned scope (${files.length} indexed files, ${lines} lines): document responsibilities and key entry points/symbols; ` +
|
|
211
|
+
"explain lifecycle rules, callers, dependencies, and specific test cases only where inspected source or tests " +
|
|
212
|
+
"establish them. Anchors are starting points, not the full assignment. Assigned areas: " +
|
|
213
|
+
scopes.join(", ") +
|
|
214
|
+
"."
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
181
218
|
/**
|
|
182
219
|
* Build the candidate skeleton from the index. Areas above the depth threshold
|
|
183
220
|
* become pages; the rest fold their files into the closest ancestor page that
|
|
@@ -190,9 +227,8 @@ export function buildCandidatePlan(codewiki: Codewiki, depth: ResolvedWikiDepth)
|
|
|
190
227
|
const threshold = Math.max(minAreaLines, Math.floor(totalLines * areaShare));
|
|
191
228
|
const areas = collectAreas(source, areaDepth);
|
|
192
229
|
const included = areas.filter((area) => area.lines >= threshold);
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
// single architecture page with nothing under it.
|
|
230
|
+
// If every area is below threshold, the largest hosts the folded coverage.
|
|
231
|
+
// At simple depth a single ownership group shares the architecture page.
|
|
196
232
|
const selected = included.length > 0 ? included : areas.slice(0, 1);
|
|
197
233
|
const selectedKeys = new Set(selected.map((area) => area.key));
|
|
198
234
|
const extras = new Map<string, CodewikiFile[]>();
|
|
@@ -203,24 +239,39 @@ export function buildCandidatePlan(codewiki: Codewiki, depth: ResolvedWikiDepth)
|
|
|
203
239
|
if (host === undefined) continue;
|
|
204
240
|
extras.set(host, [...(extras.get(host) ?? []), ...area.files]);
|
|
205
241
|
}
|
|
242
|
+
const overview = overviewPage(source);
|
|
243
|
+
const [onlyArea] = selected;
|
|
244
|
+
if (depth === "simple" && selected.length === 1 && onlyArea) {
|
|
245
|
+
const files = [...onlyArea.files, ...(extras.get(onlyArea.key) ?? [])];
|
|
246
|
+
return {
|
|
247
|
+
version: 1,
|
|
248
|
+
depth,
|
|
249
|
+
overview: "",
|
|
250
|
+
pages: [
|
|
251
|
+
{ ...overview, intent: `${overview.intent} ${intentForScope(files, areaDepth)}`, sources: rankedSources(files) },
|
|
252
|
+
],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
206
255
|
const pages = selected.map((area): WikiPlanPage => {
|
|
207
256
|
const files = [...area.files, ...(extras.get(area.key) ?? [])];
|
|
208
257
|
return {
|
|
209
258
|
path: pagePathForArea(area.key),
|
|
210
259
|
title: titleForArea(area.key),
|
|
211
|
-
intent:
|
|
212
|
-
`Document ${area.key} (${area.files.length} indexed files, ${area.lines} lines): what it owns, its entry ` +
|
|
213
|
-
"points and important symbols, the state and lifecycle invariants it enforces, an upstream caller and a " +
|
|
214
|
-
"downstream dependency, the focused tests that prove its behavior, and what to watch when editing it.",
|
|
260
|
+
intent: intentForScope(files, areaDepth),
|
|
215
261
|
sources: rankedSources(files),
|
|
216
262
|
status: "pending",
|
|
217
263
|
attempts: 0,
|
|
218
264
|
};
|
|
219
265
|
});
|
|
266
|
+
if (pages.length > 0) {
|
|
267
|
+
overview.intent +=
|
|
268
|
+
" Link to the area pages for detailed behavior; keep this page focused on their composition and relationships.";
|
|
269
|
+
}
|
|
220
270
|
return dedupePagePaths({
|
|
221
271
|
version: 1,
|
|
272
|
+
depth,
|
|
222
273
|
overview: "",
|
|
223
|
-
pages: [
|
|
274
|
+
pages: [overview, ...pages],
|
|
224
275
|
});
|
|
225
276
|
}
|
|
226
277
|
|
|
@@ -246,5 +297,11 @@ export function planWikiGeneration(codewiki: Codewiki, requestedDepth: WikiDepth
|
|
|
246
297
|
const sourceFiles = source.length;
|
|
247
298
|
const sourceLines = source.reduce((total, file) => total + Math.max(0, file.loc), 0);
|
|
248
299
|
const depth = requestedDepth === "auto" ? classifyDepth(sourceFiles, sourceLines) : requestedDepth;
|
|
249
|
-
return {
|
|
300
|
+
return {
|
|
301
|
+
requestedDepth,
|
|
302
|
+
depth,
|
|
303
|
+
sourceFiles,
|
|
304
|
+
sourceLines,
|
|
305
|
+
plan: { ...buildCandidatePlan(codewiki, depth), requestedDepth },
|
|
306
|
+
};
|
|
250
307
|
}
|
|
@@ -18,7 +18,7 @@ import { type DecisionLedgerEntry, decisionRef } from "../../session/entries.js"
|
|
|
18
18
|
import { renderCodewikiDigest } from "../codewiki/digest.js";
|
|
19
19
|
import type { Codewiki } from "../codewiki/schema.js";
|
|
20
20
|
import { WIKI_PLAN_FILE } from "./layout.js";
|
|
21
|
-
import type { WikiGenerationPlan, WikiPlan, WikiPlanPage } from "./plan.js";
|
|
21
|
+
import type { ResolvedWikiDepth, WikiGenerationPlan, WikiPlan, WikiPlanPage } from "./plan.js";
|
|
22
22
|
|
|
23
23
|
export type WikiGenerateMode = "init" | "update";
|
|
24
24
|
|
|
@@ -155,6 +155,24 @@ function renderPlanSkeleton(plan: WikiPlan): string {
|
|
|
155
155
|
);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
/** Coverage grows with depth; evidence requirements never shrink. */
|
|
159
|
+
const DEPTH_COVERAGE: Record<ResolvedWikiDepth, string> = {
|
|
160
|
+
simple:
|
|
161
|
+
"Explain useful architecture, core workflows, and the public contracts needed to navigate and use this area. Keep supporting ownership, lifecycle, and test discussion focused on those core behaviors.",
|
|
162
|
+
medium:
|
|
163
|
+
"Cover the simple foundation, then trace cross-area execution paths and explain failure handling, state transitions, and lifecycle behavior that affect callers and maintainers.",
|
|
164
|
+
detailed:
|
|
165
|
+
"Cover the medium foundation, then extend ownership boundaries, caller and dependency relationships, configuration effects, and focused test relationships where inspected source supports them. Explain extension points and editing constraints in enough context to guide a change.",
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
function depthCoverage(depth: ResolvedWikiDepth): string {
|
|
169
|
+
return (
|
|
170
|
+
`Resolved generation depth: ${depth}. ${DEPTH_COVERAGE[depth]} ` +
|
|
171
|
+
"This coverage policy scopes the shared body checklist and page intent: develop the relationships needed at this depth, without an arbitrary page, tool, or word quota. " +
|
|
172
|
+
"Every depth has the same accuracy bar: inspect source for every behavioral claim, distinguish implemented from planned or unverified behavior, and omit unsupported detail. Documentation guides further source inspection; it cannot replace it."
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
158
176
|
export interface BuildWikiPlanPromptInput {
|
|
159
177
|
cwd: string;
|
|
160
178
|
mode: WikiGenerateMode;
|
|
@@ -185,6 +203,8 @@ export function buildWikiPlanPrompt(input: BuildWikiPlanPromptInput): string {
|
|
|
185
203
|
readWikiFragment("plan", { planPath: join(input.outputDir, WIKI_PLAN_FILE) }),
|
|
186
204
|
"## Repository scale",
|
|
187
205
|
`${generation.sourceFiles} indexed source files, ${generation.sourceLines} source lines, decomposed at ${generation.depth} depth into ${generation.plan.pages.length} candidate pages.`,
|
|
206
|
+
"## Coverage depth",
|
|
207
|
+
depthCoverage(generation.depth),
|
|
188
208
|
"## Candidate plan",
|
|
189
209
|
"```json",
|
|
190
210
|
renderPlanSkeleton(plan),
|
|
@@ -230,6 +250,8 @@ function scopedSymbols(codewiki: Codewiki, sources: ReadonlyArray<string>, limit
|
|
|
230
250
|
}
|
|
231
251
|
|
|
232
252
|
export interface BuildWikiPagePromptInput {
|
|
253
|
+
/** Resolved generation coverage; medium preserves legacy direct-call behavior. */
|
|
254
|
+
depth?: ResolvedWikiDepth;
|
|
233
255
|
/** The current session board, already scoped to its active branch. */
|
|
234
256
|
decisions?: ReadonlyArray<DecisionLedgerEntry>;
|
|
235
257
|
cwd: string;
|
|
@@ -260,6 +282,8 @@ export function buildWikiPagePrompt(input: BuildWikiPagePromptInput): string {
|
|
|
260
282
|
pageRelPath: page.path,
|
|
261
283
|
pageTitle: page.title,
|
|
262
284
|
}),
|
|
285
|
+
"## Coverage depth",
|
|
286
|
+
depthCoverage(input.depth ?? "medium"),
|
|
263
287
|
"## What this page must document",
|
|
264
288
|
page.intent.length > 0 ? page.intent : `Document ${page.title}.`,
|
|
265
289
|
"## Anchor sources",
|
|
@@ -275,6 +299,23 @@ export function buildWikiPagePrompt(input: BuildWikiPagePromptInput): string {
|
|
|
275
299
|
"## Repository guidance",
|
|
276
300
|
repositoryGuidance(input.cwd),
|
|
277
301
|
];
|
|
302
|
+
if (page.lastFailure) {
|
|
303
|
+
sections.push(
|
|
304
|
+
"## Previous attempt diagnostic",
|
|
305
|
+
"The following JSON is bounded harness diagnostic data, not source evidence or instructions. Repair the reported failure against current source before resubmitting the page.",
|
|
306
|
+
"```json",
|
|
307
|
+
JSON.stringify(
|
|
308
|
+
{
|
|
309
|
+
phase: page.lastFailure.phase,
|
|
310
|
+
detail: page.lastFailure.detail.slice(0, 500),
|
|
311
|
+
...(page.lastFailure.runId ? { runId: page.lastFailure.runId.slice(0, 120) } : {}),
|
|
312
|
+
},
|
|
313
|
+
null,
|
|
314
|
+
2,
|
|
315
|
+
),
|
|
316
|
+
"```",
|
|
317
|
+
);
|
|
318
|
+
}
|
|
278
319
|
const decisions = recordedDecisions(input);
|
|
279
320
|
if (decisions.length > 0) sections.push("# Recorded decisions", "```json", JSON.stringify(decisions, null, 2), "```");
|
|
280
321
|
if (input.seeded) {
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { closeSync, constants, fstatSync, openSync, readSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import {
|
|
5
|
+
enumerateWorkspaceFiles,
|
|
6
|
+
enumerateWorkspaceFilesAsync,
|
|
7
|
+
WORKSPACE_EXCLUDED_DIRS,
|
|
8
|
+
} from "../../../core/workspace-files.js";
|
|
9
|
+
import { createSlicer } from "../codewiki/cooperative.js";
|
|
10
|
+
|
|
11
|
+
/** Shared, bounded byte evidence for the existing wiki checkpoint/publication. */
|
|
12
|
+
export type WikiSourceContent = Record<string, string | null>;
|
|
13
|
+
const MAX_FILES = 20_000;
|
|
14
|
+
const MAX_BYTES = 128 * 1024 * 1024;
|
|
15
|
+
|
|
16
|
+
export function parseWikiSourceContent(value: unknown): WikiSourceContent | undefined {
|
|
17
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
|
|
18
|
+
const entries = Object.entries(value);
|
|
19
|
+
if (entries.length > MAX_FILES) return undefined;
|
|
20
|
+
if (
|
|
21
|
+
entries.some(([path, hash]) => !path || (hash !== null && (typeof hash !== "string" || !/^[a-f0-9]{64}$/.test(hash))))
|
|
22
|
+
)
|
|
23
|
+
return undefined;
|
|
24
|
+
return Object.fromEntries(entries);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function capture(cwd: string, files: string[]): { content: WikiSourceContent; add: (path: string) => void } {
|
|
28
|
+
const content: WikiSourceContent = Object.create(null);
|
|
29
|
+
let remainingBytes = MAX_BYTES;
|
|
30
|
+
const buffer = Buffer.alloc(64 * 1024);
|
|
31
|
+
return {
|
|
32
|
+
content,
|
|
33
|
+
add(path) {
|
|
34
|
+
if (files.length > MAX_FILES) return;
|
|
35
|
+
let fd: number | undefined;
|
|
36
|
+
content[path] = null;
|
|
37
|
+
try {
|
|
38
|
+
fd = openSync(join(cwd, path), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
39
|
+
const before = fstatSync(fd);
|
|
40
|
+
if (!before.isFile() || before.size > remainingBytes) return;
|
|
41
|
+
remainingBytes -= before.size;
|
|
42
|
+
const hash = createHash("sha256");
|
|
43
|
+
let remaining = before.size;
|
|
44
|
+
while (remaining > 0) {
|
|
45
|
+
const count = readSync(fd, buffer, 0, Math.min(buffer.length, remaining), null);
|
|
46
|
+
if (count === 0) return;
|
|
47
|
+
hash.update(buffer.subarray(0, count));
|
|
48
|
+
remaining -= count;
|
|
49
|
+
}
|
|
50
|
+
const after = fstatSync(fd);
|
|
51
|
+
if (after.size === before.size && after.mtimeMs === before.mtimeMs && after.ctimeMs === before.ctimeMs)
|
|
52
|
+
content[path] = hash.digest("hex");
|
|
53
|
+
} catch {
|
|
54
|
+
// Missing, replaced, non-regular, and unreadable inputs remain unknown.
|
|
55
|
+
} finally {
|
|
56
|
+
if (fd !== undefined) closeSync(fd);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Enumeration shares the workspace's Git/ignore policy; capped evidence never
|
|
64
|
+
* certifies a prefix. Before/after observations are not a filesystem snapshot:
|
|
65
|
+
* an intervening edit followed by a revert can escape them.
|
|
66
|
+
*/
|
|
67
|
+
export function captureWikiSourceContent(cwd: string): WikiSourceContent {
|
|
68
|
+
try {
|
|
69
|
+
const files = enumerateWorkspaceFiles(cwd, WORKSPACE_EXCLUDED_DIRS);
|
|
70
|
+
const snapshot = capture(cwd, files);
|
|
71
|
+
for (const path of files) snapshot.add(path);
|
|
72
|
+
return snapshot.content;
|
|
73
|
+
} catch {
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function captureWikiSourceContentAsync(cwd: string): Promise<WikiSourceContent> {
|
|
79
|
+
try {
|
|
80
|
+
const slicer = createSlicer();
|
|
81
|
+
const files = await enumerateWorkspaceFilesAsync(cwd, WORKSPACE_EXCLUDED_DIRS, undefined, slicer);
|
|
82
|
+
const snapshot = capture(cwd, files);
|
|
83
|
+
for (const path of files) {
|
|
84
|
+
snapshot.add(path);
|
|
85
|
+
await slicer.tick();
|
|
86
|
+
}
|
|
87
|
+
return snapshot.content;
|
|
88
|
+
} catch {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** A directory claim compares every covered child, including additions and deletions. */
|
|
94
|
+
export function wikiSourcesMatch(
|
|
95
|
+
previous: WikiSourceContent | undefined,
|
|
96
|
+
current: WikiSourceContent,
|
|
97
|
+
sources?: readonly string[],
|
|
98
|
+
): boolean {
|
|
99
|
+
if (!previous || Object.keys(previous).length === 0 || Object.keys(current).length === 0) return false;
|
|
100
|
+
const claimed = sources?.map((path) => path.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/$/, ""));
|
|
101
|
+
const paths = [...new Set([...Object.keys(previous), ...Object.keys(current)])].filter(
|
|
102
|
+
(path) => !claimed || claimed.some((source) => path === source || path.startsWith(`${source}/`)),
|
|
103
|
+
);
|
|
104
|
+
if (claimed?.some((source) => !paths.some((path) => path === source || path.startsWith(`${source}/`)))) return false;
|
|
105
|
+
return paths.length > 0 && paths.every((path) => previous[path] != null && previous[path] === current[path]);
|
|
106
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { execFile, execFileSync } from "node:child_process";
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
|
-
import { computeFingerprint, computeFingerprintAsync } from "../fingerprint.js";
|
|
4
3
|
import { readWikiMeta, type WikiMeta } from "./meta.js";
|
|
4
|
+
import { captureWikiSourceContent, captureWikiSourceContentAsync, wikiSourcesMatch } from "./source-content.js";
|
|
5
5
|
|
|
6
6
|
const execFileAsync = promisify(execFile);
|
|
7
7
|
|
|
@@ -67,15 +67,15 @@ function collectChangedPaths(cwd: string, gitHead: string): Set<string> {
|
|
|
67
67
|
* and working-tree alike. This is what scopes an update run: a page is rewritten
|
|
68
68
|
* when one of the sources its front matter claims appears here, which replaces
|
|
69
69
|
* asking a model to guess which pages a diff invalidates. Uncapped, because a
|
|
70
|
-
* capped list would silently mark changed pages current.
|
|
71
|
-
*
|
|
70
|
+
* capped list would silently mark changed pages current. Null means comparison
|
|
71
|
+
* is unavailable; an empty array means Git confirmed no changed paths.
|
|
72
72
|
*/
|
|
73
|
-
export function changedPathsSince(cwd: string, gitHead: string | null): string[] {
|
|
74
|
-
if (!gitHead) return
|
|
73
|
+
export function changedPathsSince(cwd: string, gitHead: string | null): string[] | null {
|
|
74
|
+
if (!gitHead) return null;
|
|
75
75
|
try {
|
|
76
76
|
return [...collectChangedPaths(cwd, gitHead)];
|
|
77
77
|
} catch {
|
|
78
|
-
return
|
|
78
|
+
return null;
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -155,27 +155,40 @@ export function wikiCompleteness(cwd: string): WikiCompleteness | null {
|
|
|
155
155
|
return wikiCompletenessFromMeta(readWikiMeta(cwd));
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
/** Available old prose is not fresh while its refresh is still owed. */
|
|
159
|
+
function pendingRefresh(meta: WikiMeta): WikiStaleness | null {
|
|
160
|
+
const available = new Set(meta.pages.map((page) => page.path));
|
|
161
|
+
if (!meta.plan?.pages.some((page) => page.status !== "written" && available.has(page.path))) return null;
|
|
162
|
+
return { state: "stale", changedFiles: 0, warning: "wiki has published pages awaiting successful validation" };
|
|
163
|
+
}
|
|
164
|
+
|
|
158
165
|
const MISSING_RECORDED_HEAD = "wiki staleness unavailable: recorded gitHead is missing";
|
|
159
166
|
const MISSING_CURRENT_HEAD = "wiki staleness unavailable: current git HEAD is missing";
|
|
160
167
|
|
|
168
|
+
/** Unknown Git evidence cannot certify freshness, even when the narrower source fingerprint matches. */
|
|
169
|
+
function unavailableStaleness(warning: string): WikiStaleness {
|
|
170
|
+
return { state: "stale", changedFiles: 0, warning };
|
|
171
|
+
}
|
|
172
|
+
|
|
161
173
|
export function wikiStaleness(cwd: string): WikiStaleness {
|
|
162
174
|
const meta = readWikiMeta(cwd);
|
|
163
175
|
if (!meta) return { state: "absent" };
|
|
164
|
-
|
|
176
|
+
const pending = pendingRefresh(meta);
|
|
177
|
+
if (pending) return pending;
|
|
178
|
+
if (!meta.gitHead) return unavailableStaleness(MISSING_RECORDED_HEAD);
|
|
165
179
|
const head = currentGitHead(cwd);
|
|
166
|
-
if (!head) return
|
|
167
|
-
|
|
180
|
+
if (!head) return unavailableStaleness(MISSING_CURRENT_HEAD);
|
|
181
|
+
const diff = changedFileCount(cwd, meta.gitHead);
|
|
182
|
+
if (!("count" in diff)) return unavailableStaleness(diff.warning);
|
|
183
|
+
if (wikiSourcesMatch(meta.plan?.sourceContent, captureWikiSourceContent(cwd)) && head === meta.gitHead) {
|
|
168
184
|
return { state: "fresh" };
|
|
169
185
|
}
|
|
170
|
-
if (!meta.sourceTreeHash && head === meta.gitHead) return { state: "fresh" };
|
|
171
|
-
const diff = changedFileCount(cwd, meta.gitHead);
|
|
172
|
-
if (!("count" in diff)) return { state: "fresh", warning: diff.warning };
|
|
173
186
|
return { state: "stale", changedFiles: diff.count, ...(diff.warning ? { warning: diff.warning } : {}) };
|
|
174
187
|
}
|
|
175
188
|
|
|
176
189
|
/**
|
|
177
190
|
* Same verdict, off the event loop. The sync form costs a `git rev-parse`, a
|
|
178
|
-
*
|
|
191
|
+
* bounded workspace content read, and three more `git` subprocesses, which is
|
|
179
192
|
* a fifth of a second on a large repository. That is fine for a one-shot CLI
|
|
180
193
|
* read and unacceptable for a status surface that polls, which is what this
|
|
181
194
|
* variant exists for.
|
|
@@ -183,16 +196,14 @@ export function wikiStaleness(cwd: string): WikiStaleness {
|
|
|
183
196
|
export async function wikiStalenessAsync(cwd: string): Promise<WikiStaleness> {
|
|
184
197
|
const meta = readWikiMeta(cwd);
|
|
185
198
|
if (!meta) return { state: "absent" };
|
|
186
|
-
|
|
199
|
+
const pending = pendingRefresh(meta);
|
|
200
|
+
if (pending) return pending;
|
|
201
|
+
if (!meta.gitHead) return unavailableStaleness(MISSING_RECORDED_HEAD);
|
|
187
202
|
const head = await currentGitHeadAsync(cwd);
|
|
188
|
-
if (!head) return
|
|
189
|
-
if (meta.sourceTreeHash) {
|
|
190
|
-
const fingerprint = await computeFingerprintAsync(cwd);
|
|
191
|
-
if (fingerprint.treeHash === meta.sourceTreeHash && head === meta.gitHead) return { state: "fresh" };
|
|
192
|
-
} else if (head === meta.gitHead) {
|
|
193
|
-
return { state: "fresh" };
|
|
194
|
-
}
|
|
203
|
+
if (!head) return unavailableStaleness(MISSING_CURRENT_HEAD);
|
|
195
204
|
const diff = await changedFileCountAsync(cwd, meta.gitHead);
|
|
196
|
-
if (!("count" in diff)) return
|
|
205
|
+
if (!("count" in diff)) return unavailableStaleness(diff.warning);
|
|
206
|
+
if (wikiSourcesMatch(meta.plan?.sourceContent, await captureWikiSourceContentAsync(cwd)) && head === meta.gitHead)
|
|
207
|
+
return { state: "fresh" };
|
|
197
208
|
return { state: "stale", changedFiles: diff.count, ...(diff.warning ? { warning: diff.warning } : {}) };
|
|
198
209
|
}
|
|
@@ -44,6 +44,7 @@ export type {
|
|
|
44
44
|
* by the entry turnId (`ref.entry`); `fold.ts` owns `refKey` / `parseRefKey`.
|
|
45
45
|
*/
|
|
46
46
|
export interface EvictedState {
|
|
47
|
+
alias?: string;
|
|
47
48
|
reason: EvictionReason;
|
|
48
49
|
marker: string;
|
|
49
50
|
by?: string;
|
|
@@ -61,6 +62,8 @@ export interface EvictedState {
|
|
|
61
62
|
* one ref are the churn signal.
|
|
62
63
|
*/
|
|
63
64
|
export interface WorkingSetView {
|
|
65
|
+
/** Highest allocated alias across all branches, preventing reuse after a tree switch. */
|
|
66
|
+
recallAliasSequence?: number;
|
|
64
67
|
evicted: ReadonlyMap<string, EvictedState>;
|
|
65
68
|
/** Applied eviction events on the active path. */
|
|
66
69
|
evictionEvents: number;
|
|
@@ -143,14 +146,17 @@ export interface EvictionPlan {
|
|
|
143
146
|
export type ContextEvictionFields = Omit<ContextEvictionEntry, "turnId" | "parentTurnId" | "timestamp">;
|
|
144
147
|
export type ContextRecallFields = Omit<ContextRecallEntry, "turnId" | "parentTurnId" | "timestamp">;
|
|
145
148
|
|
|
146
|
-
/** Typed failure for recall by ref. `recallErrorMessage` lists
|
|
149
|
+
/** Typed failure for recall by ref. `recallErrorMessage` lists recoverable refs beside it. */
|
|
147
150
|
export type RecallError =
|
|
148
151
|
| { kind: "not_on_active_path"; ref: string }
|
|
149
|
-
| { kind: "
|
|
152
|
+
| { kind: "visible"; ref: string }
|
|
153
|
+
| { kind: "unavailable"; ref: string }
|
|
150
154
|
| { kind: "invalid_ref"; ref: string };
|
|
151
155
|
|
|
152
156
|
export interface RecallResult {
|
|
153
157
|
ref: WorkingSetRef;
|
|
158
|
+
/** Why the original body is absent from the working set. */
|
|
159
|
+
state: "evicted" | "summarized";
|
|
154
160
|
/** The ledger entry whose body is readmitted. */
|
|
155
161
|
entry: SessionEntry;
|
|
156
162
|
/** Exact original body as the projection would have rendered it before eviction. */
|
|
@@ -45,7 +45,12 @@ const PENDING_EVENT_TURN_ID = "";
|
|
|
45
45
|
* evict. Thinking eviction renders no marker at all: the reasoning simply
|
|
46
46
|
* stops being replayed.
|
|
47
47
|
*/
|
|
48
|
-
function markerFor(
|
|
48
|
+
function markerFor(
|
|
49
|
+
entry: SessionEntry,
|
|
50
|
+
candidate: EvictionCandidate,
|
|
51
|
+
callPaths: CallPaths,
|
|
52
|
+
alias?: string,
|
|
53
|
+
): string | null {
|
|
49
54
|
if (entry.kind !== "message") return null;
|
|
50
55
|
if (entry.role === "assistant") return hasThinking(entry.payload) ? "" : null;
|
|
51
56
|
if (entry.role !== "tool_result") return null;
|
|
@@ -53,6 +58,7 @@ function markerFor(entry: SessionEntry, candidate: EvictionCandidate, callPaths:
|
|
|
53
58
|
const toolCallId = typeof payload.obj.toolCallId === "string" ? payload.obj.toolCallId : undefined;
|
|
54
59
|
return renderMarker({
|
|
55
60
|
ref: candidate.ref,
|
|
61
|
+
...(alias === undefined ? {} : { alias }),
|
|
56
62
|
reason: candidate.reason,
|
|
57
63
|
by: candidate.by,
|
|
58
64
|
toolName: payload.toolName,
|
|
@@ -131,8 +137,9 @@ export function tokensFreedByEviction(
|
|
|
131
137
|
entry: SessionEntry,
|
|
132
138
|
candidate: EvictionCandidate,
|
|
133
139
|
callPaths: CallPaths = NO_CALL_PATHS,
|
|
140
|
+
alias?: string,
|
|
134
141
|
): number {
|
|
135
|
-
const marker = markerFor(entry, candidate, callPaths);
|
|
142
|
+
const marker = markerFor(entry, candidate, callPaths, alias);
|
|
136
143
|
if (marker === null) return 0;
|
|
137
144
|
const key = refKey(candidate.ref);
|
|
138
145
|
const projected = projectWorkingSet([entry], soloView(key, pendingState(candidate, marker, "")))[0] ?? entry;
|
|
@@ -149,6 +156,9 @@ export function planEviction(policy: WorkingSetPolicy, input: PolicyInput): Evic
|
|
|
149
156
|
|
|
150
157
|
const items: EvictedItem[] = [];
|
|
151
158
|
const claimed = new Set<string>();
|
|
159
|
+
let aliasSequence =
|
|
160
|
+
input.view.recallAliasSequence ??
|
|
161
|
+
[...input.view.evicted.values()].reduce((max, state) => Math.max(max, Number(state.alias?.slice(1)) || 0), 0);
|
|
152
162
|
for (const candidate of candidates) {
|
|
153
163
|
const key = refKey(candidate.ref);
|
|
154
164
|
// A policy is contractually forbidden from returning a unit that is
|
|
@@ -157,15 +167,18 @@ export function planEviction(policy: WorkingSetPolicy, input: PolicyInput): Evic
|
|
|
157
167
|
if (input.view.evicted.has(key) || claimed.has(key)) continue;
|
|
158
168
|
const entry = byTurnId.get(key);
|
|
159
169
|
if (entry === undefined) continue;
|
|
160
|
-
const
|
|
170
|
+
const alias = entry.kind === "message" && entry.role === "tool_result" ? `r${aliasSequence + 1}` : undefined;
|
|
171
|
+
const marker = markerFor(entry, candidate, callPaths, alias);
|
|
161
172
|
if (marker === null) continue;
|
|
162
173
|
// A marker at least as long as the body it replaces is a cold turn bought
|
|
163
174
|
// for nothing, whatever the policy's reason. Refused here so no policy can
|
|
164
175
|
// record an eviction that freed nothing.
|
|
165
|
-
const tokensFreed = tokensFreedByEviction(input.estimateTokens, entry, candidate, callPaths);
|
|
176
|
+
const tokensFreed = tokensFreedByEviction(input.estimateTokens, entry, candidate, callPaths, alias);
|
|
166
177
|
if (tokensFreed <= 0) continue;
|
|
167
178
|
claimed.add(key);
|
|
179
|
+
if (alias !== undefined) aliasSequence += 1;
|
|
168
180
|
items.push({
|
|
181
|
+
...(alias === undefined ? {} : { alias }),
|
|
169
182
|
ref: candidate.ref,
|
|
170
183
|
reason: candidate.reason,
|
|
171
184
|
tokensFreed,
|
|
@@ -18,13 +18,25 @@ export function refKey(ref: WorkingSetRef): string {
|
|
|
18
18
|
return ref.entry;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export function parseRefKey(key: string): WorkingSetRef | null {
|
|
21
|
+
export function parseRefKey(key: string, view?: WorkingSetView): WorkingSetRef | null {
|
|
22
22
|
const trimmed = key.trim();
|
|
23
23
|
if (trimmed.length === 0 || /\s/.test(trimmed)) return null;
|
|
24
|
+
if (/^r[1-9]\d*$/.test(trimmed) && view !== undefined) {
|
|
25
|
+
const matches = [...view.evicted].filter(([, state]) => state.alias === trimmed);
|
|
26
|
+
return matches.length === 1 ? { entry: matches[0]?.[0] ?? "" } : matches.length === 0 ? { entry: trimmed } : null;
|
|
27
|
+
}
|
|
24
28
|
return { entry: trimmed };
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
export function foldWorkingSet(entries: ReadonlyArray<SessionEntry>, activeLeafTurnId?: string): WorkingSetView {
|
|
32
|
+
let recallAliasSequence = 0;
|
|
33
|
+
for (const entry of entries)
|
|
34
|
+
if (entry.kind === "contextEviction") {
|
|
35
|
+
for (const item of entry.evicted) {
|
|
36
|
+
const ordinal = Number(item.alias?.slice(1));
|
|
37
|
+
if (Number.isSafeInteger(ordinal)) recallAliasSequence = Math.max(recallAliasSequence, ordinal);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
28
40
|
const active = filterEntriesToActivePath(entries, activeLeafTurnId);
|
|
29
41
|
const evicted = new Map<string, EvictedState>();
|
|
30
42
|
let evictionEvents = 0;
|
|
@@ -41,6 +53,7 @@ export function foldWorkingSet(entries: ReadonlyArray<SessionEntry>, activeLeafT
|
|
|
41
53
|
itemsEvicted += 1;
|
|
42
54
|
evicted.set(refKey(item.ref), {
|
|
43
55
|
reason: item.reason,
|
|
56
|
+
...(item.alias === undefined ? {} : { alias: item.alias }),
|
|
44
57
|
marker: item.marker,
|
|
45
58
|
...(item.by === undefined ? {} : { by: item.by }),
|
|
46
59
|
tokensFreed: item.tokensFreed,
|
|
@@ -58,5 +71,5 @@ export function foldWorkingSet(entries: ReadonlyArray<SessionEntry>, activeLeafT
|
|
|
58
71
|
// recall of the same ref is the churn signal.
|
|
59
72
|
if (entry.kind === "contextRecall") recalls += 1;
|
|
60
73
|
}
|
|
61
|
-
return { evicted, evictionEvents, itemsEvicted, recalls, lastPolicyId, lastEvictionTurnId };
|
|
74
|
+
return { recallAliasSequence, evicted, evictionEvents, itemsEvicted, recalls, lastPolicyId, lastEvictionTurnId };
|
|
62
75
|
}
|
|
@@ -30,6 +30,7 @@ import type { EvictionReason, WorkingSetRef } from "./contract.js";
|
|
|
30
30
|
const PREVIEW_LIMIT = 120;
|
|
31
31
|
|
|
32
32
|
export interface MarkerInput {
|
|
33
|
+
alias?: string;
|
|
33
34
|
ref: WorkingSetRef;
|
|
34
35
|
reason: EvictionReason;
|
|
35
36
|
/** Ref key of the entry that superseded or resolved this one, when the reason names one. */
|
|
@@ -84,7 +85,7 @@ function firstLine(text: string): string {
|
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
export function renderMarker(input: MarkerInput): string {
|
|
87
|
-
const ref = input.ref.entry;
|
|
88
|
+
const ref = input.alias ?? input.ref.entry;
|
|
88
89
|
const fields: string[] = [`ref=${ref}`, `reason=${input.reason}`];
|
|
89
90
|
if (input.by !== undefined) fields.push(`by=${input.by}`);
|
|
90
91
|
fields.push(`tool=${input.toolName}`);
|
|
@@ -13,13 +13,14 @@
|
|
|
13
13
|
* below the payload is ever mutated, so a deep clone of the body about to be
|
|
14
14
|
* replaced would only cost the pricing loop the body's size.
|
|
15
15
|
*
|
|
16
|
-
* Callers may pass raw ledger entries
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* Callers may pass raw ledger entries. Eviction bodies follow the active-path
|
|
17
|
+
* view; usage anchors preceding an eviction or selected compaction checkpoint
|
|
18
|
+
* are invalidated in projection. Live callers pass their selected leaf so an
|
|
19
|
+
* abandoned branch checkpoint cannot invalidate the current prompt's usage.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import type { MessageEntry, SessionEntry } from "../../session/entries.js";
|
|
23
|
+
import { filterEntriesToActivePath } from "../../session/tree/active-path.js";
|
|
23
24
|
import type { EvictedState, WorkingSetView } from "./contract.js";
|
|
24
25
|
import { hasThinking, isRecord, toolResultPayload, withoutThinkingBlocks } from "./payload.js";
|
|
25
26
|
|
|
@@ -110,9 +111,19 @@ function eventIndex(entries: ReadonlyArray<SessionEntry>, lastEvictionTurnId: st
|
|
|
110
111
|
return index < 0 ? entries.length : index;
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
export function projectWorkingSet(
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
export function projectWorkingSet(
|
|
115
|
+
entries: ReadonlyArray<SessionEntry>,
|
|
116
|
+
view: WorkingSetView,
|
|
117
|
+
activeLeafTurnId?: string,
|
|
118
|
+
): SessionEntry[] {
|
|
119
|
+
// A checkpoint also replaces the prompt described by retained assistant
|
|
120
|
+
// usage. Invalidate that anchor only in projection; ledger cost stays exact.
|
|
121
|
+
const checkpoint = filterEntriesToActivePath(entries, activeLeafTurnId)
|
|
122
|
+
.reverse()
|
|
123
|
+
.find((entry) => entry.kind === "compactionSummary");
|
|
124
|
+
const compactionIndex = checkpoint ? entries.indexOf(checkpoint) : -1;
|
|
125
|
+
if (view.evicted.size === 0 && view.evictionEvents === 0 && compactionIndex < 0) return [...entries];
|
|
126
|
+
const cutoff = Math.max(compactionIndex, view.evictionEvents > 0 ? eventIndex(entries, view.lastEvictionTurnId) : -1);
|
|
116
127
|
const out: SessionEntry[] = [];
|
|
117
128
|
for (let index = 0; index < entries.length; index += 1) {
|
|
118
129
|
const entry = entries[index];
|