agentic-qe 3.14.7 → 3.14.8
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/.claude/helpers/.helpers-version +1 -1
- package/.claude/helpers/auto-memory-hook.mjs +18 -9
- package/.claude/helpers/helpers.manifest.json +6 -5
- package/.claude/helpers/hook-handler.cjs +40 -12
- package/.claude/helpers/memory.cjs +86 -0
- package/.claude/helpers/router.cjs +105 -0
- package/.claude/helpers/session.cjs +166 -0
- package/.claude/helpers/statusline.cjs +73 -621
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +130 -0
- package/assets/skills/skills-manifest.json +1 -1
- package/dist/adapters/a2a/notifications/retry-queue.js +5 -0
- package/dist/adapters/claude-flow/pretrain-bridge.js +3 -2
- package/dist/agents/claim-verifier/verifiers/file-verifier.js +3 -2
- package/dist/cli/bundle.js +6 -6
- package/dist/cli/chunks/adapter-XYCOXQCC.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-AK2W76RG.js → agent-booster-wasm-67OKGDGZ.js} +2 -2
- package/dist/cli/chunks/{agent-handler-MGZCWHIY.js → agent-handler-4HZEQ3WQ.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-JZ54MCSP.js → agent-memory-branch-IBHZQSRN.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-DTJCROTG.js +2 -0
- package/dist/cli/chunks/{arena-CUVH3V7H.js → arena-EJBIGSF4.js} +2 -2
- package/dist/cli/chunks/{arena-YSWTKBCL.js → arena-LCLRGUIK.js} +4 -4
- package/dist/cli/chunks/{audit-LVU76QGA.js → audit-PY4JNDQQ.js} +3 -3
- package/dist/cli/chunks/base-5TQ34GMD.js +2 -0
- package/dist/cli/chunks/{better-sqlite3-DB3LOJQU.js → better-sqlite3-2JG5K6XT.js} +2 -2
- package/dist/cli/chunks/{brain-handler-SD63KOQ6.js → brain-handler-3UYK55GA.js} +4 -4
- package/dist/cli/chunks/{branch-enumerator-4MNOPUC7.js → branch-enumerator-GOSWOX46.js} +2 -2
- package/dist/cli/chunks/{browser-OLPNTWQE.js → browser-DC2JV47Z.js} +2 -2
- package/dist/cli/chunks/browser-workflow-KWX4ESTJ.js +2 -0
- package/dist/cli/chunks/{chunk-QQFQDEUE.js → chunk-25EEIAHS.js} +2 -2
- package/dist/cli/chunks/{chunk-DOBKEXMJ.js → chunk-3576QGPP.js} +1 -1
- package/dist/cli/chunks/{chunk-3M7J4U74.js → chunk-3EKG7HFV.js} +4 -4
- package/dist/cli/chunks/{chunk-DYTQHRUS.js → chunk-3FCHH4VP.js} +1 -1
- package/dist/cli/chunks/{chunk-EJ6MMYLK.js → chunk-3S5IIK32.js} +1 -1
- package/dist/cli/chunks/{chunk-NOHWJOBS.js → chunk-3X2JSW3R.js} +1 -1
- package/dist/cli/chunks/{chunk-7EZ2Z2CK.js → chunk-4HXFPBAA.js} +1 -1
- package/dist/cli/chunks/{chunk-XBYQ2BS4.js → chunk-4PY44TKH.js} +2 -2
- package/dist/cli/chunks/{chunk-5FSLMYAC.js → chunk-4RNCVSVN.js} +2 -2
- package/dist/cli/chunks/{chunk-X7ADKL7T.js → chunk-56M4QNXU.js} +2 -2
- package/dist/cli/chunks/{chunk-JHJUSSAU.js → chunk-5X4HDW5W.js} +2 -2
- package/dist/cli/chunks/{chunk-7MIOK72I.js → chunk-673XJBGW.js} +7 -7
- package/dist/cli/chunks/{chunk-77QZHIVX.js → chunk-6F7MFHTY.js} +2 -2
- package/dist/cli/chunks/{chunk-Q6NTEICT.js → chunk-6GJWT2OY.js} +2 -2
- package/dist/cli/chunks/{chunk-GV4DYPJP.js → chunk-6GNWVPMR.js} +2 -2
- package/dist/cli/chunks/{chunk-V5AK56DA.js → chunk-6VTC3OHD.js} +2 -2
- package/dist/cli/chunks/{chunk-MM56VPNE.js → chunk-775WGWLL.js} +3 -3
- package/dist/cli/chunks/{chunk-A3DK3XNZ.js → chunk-77WL5HQW.js} +1 -1
- package/dist/cli/chunks/chunk-7STWD4KJ.js +3 -0
- package/dist/cli/chunks/{chunk-RC2A4JZ5.js → chunk-7TNCEVWX.js} +2 -2
- package/dist/cli/chunks/{chunk-XL5KIYE3.js → chunk-7X3LMTRA.js} +2 -2
- package/dist/cli/chunks/{chunk-VW6FRMLW.js → chunk-A53MMSGC.js} +2 -2
- package/dist/cli/chunks/{chunk-UFSVUBTR.js → chunk-A5CLVZC3.js} +2 -2
- package/dist/cli/chunks/{chunk-4INST4ZL.js → chunk-AEYJ4ZLA.js} +1 -1
- package/dist/cli/chunks/{chunk-5U6N4V5M.js → chunk-AJ5PCJQ2.js} +4 -4
- package/dist/cli/chunks/{chunk-OAZX6WFU.js → chunk-AJMAKUS3.js} +2 -2
- package/dist/cli/chunks/{chunk-74IOEOMH.js → chunk-AOD2ES44.js} +2 -2
- package/dist/cli/chunks/chunk-AR2S4DOB.js +2 -0
- package/dist/cli/chunks/{chunk-PYKY22GC.js → chunk-AUFV2G2J.js} +5 -5
- package/dist/cli/chunks/{chunk-KD2BLA5Y.js → chunk-B2QKBQYD.js} +1 -1
- package/dist/cli/chunks/{chunk-6EGS77BB.js → chunk-BCCSV3RH.js} +1 -1
- package/dist/cli/chunks/{chunk-JOZ47MV6.js → chunk-BFIXUKOR.js} +1 -1
- package/dist/cli/chunks/chunk-BHPTHC5O.js +4 -0
- package/dist/cli/chunks/{chunk-OIDWDGLG.js → chunk-BITFGVZ4.js} +2 -2
- package/dist/cli/chunks/{chunk-ONR2NXXD.js → chunk-BL6273KR.js} +3 -3
- package/dist/cli/chunks/{chunk-BLG7SH4A.js → chunk-BOIUENWW.js} +1 -1
- package/dist/cli/chunks/{chunk-T77GZF4B.js → chunk-BT3MI2BW.js} +1 -1
- package/dist/cli/chunks/{chunk-UYUJT6QO.js → chunk-BTBJ2NLH.js} +2 -2
- package/dist/cli/chunks/{chunk-YMW57PEL.js → chunk-BUVJIVFG.js} +1 -1
- package/dist/cli/chunks/{chunk-QUORH2MG.js → chunk-BZIPW2PA.js} +8 -8
- package/dist/cli/chunks/{chunk-GVVFTFMB.js → chunk-C647D42G.js} +2 -2
- package/dist/cli/chunks/{chunk-AJUBT4NP.js → chunk-CBWM5NOO.js} +3 -3
- package/dist/cli/chunks/{chunk-F2OPFVQH.js → chunk-CIEXUYY7.js} +1 -1
- package/dist/cli/chunks/{chunk-QGOWNVVG.js → chunk-CLUHGBLN.js} +4 -4
- package/dist/cli/chunks/{chunk-WOV6XI3A.js → chunk-CQEWL32R.js} +1 -1
- package/dist/cli/chunks/{chunk-3QJU4Q4R.js → chunk-CXUC7YKA.js} +2 -2
- package/dist/cli/chunks/{chunk-HZY42OVU.js → chunk-D2Y36V5J.js} +2 -2
- package/dist/cli/chunks/{chunk-WF6UISKW.js → chunk-DSJJHPPS.js} +4 -4
- package/dist/cli/chunks/{chunk-FYPX5WBJ.js → chunk-DZHXCOSK.js} +1 -1
- package/dist/cli/chunks/{chunk-TXSPBLBT.js → chunk-EBV3WFIR.js} +2 -2
- package/dist/cli/chunks/{chunk-Y6AKKQIQ.js → chunk-EKO5QL2B.js} +1 -1
- package/dist/cli/chunks/{chunk-MZB2UV2O.js → chunk-EMOZ5O5S.js} +1 -1
- package/dist/cli/chunks/{chunk-23CX7JNL.js → chunk-ES7TAJRJ.js} +2 -2
- package/dist/cli/chunks/{chunk-Z4Q5PCRZ.js → chunk-EXQGHTPD.js} +4 -4
- package/dist/cli/chunks/{chunk-A2VUCUTT.js → chunk-F2WAB4WK.js} +2 -2
- package/dist/cli/chunks/{chunk-CQNMGK6Y.js → chunk-F57FTFWS.js} +2 -2
- package/dist/cli/chunks/{chunk-OEPNNLR4.js → chunk-F6JJNBE5.js} +1 -1
- package/dist/cli/chunks/{chunk-UBJG3IHT.js → chunk-FRC7AFB4.js} +2 -2
- package/dist/cli/chunks/{chunk-2G63VIJE.js → chunk-G36RZF2Y.js} +1 -1
- package/dist/cli/chunks/{chunk-YRHTQZU4.js → chunk-G3C7Z6FO.js} +2 -2
- package/dist/cli/chunks/{chunk-B4I43GE2.js → chunk-GA63ESNT.js} +2 -2
- package/dist/cli/chunks/{chunk-7QYOTUOX.js → chunk-GHMJFICO.js} +2 -2
- package/dist/cli/chunks/{chunk-HYOPJHHW.js → chunk-GK5WLUX3.js} +1 -1
- package/dist/cli/chunks/{chunk-A5MA7A23.js → chunk-GQJ4QDEN.js} +6 -6
- package/dist/cli/chunks/{chunk-UA7TDVL7.js → chunk-GVLRE3BV.js} +4 -4
- package/dist/cli/chunks/{chunk-25P6JA6V.js → chunk-H5UH234L.js} +1 -1
- package/dist/cli/chunks/{chunk-BE4KALTE.js → chunk-HBAFXWSO.js} +1 -1
- package/dist/cli/chunks/{chunk-EGOIIUBD.js → chunk-HE3BDBAO.js} +2 -2
- package/dist/cli/chunks/{chunk-P2UPYSDJ.js → chunk-HHANMCD2.js} +1 -1
- package/dist/cli/chunks/{chunk-ZUOVNFXK.js → chunk-HPVYJ6JH.js} +2 -2
- package/dist/cli/chunks/{chunk-RKI3IQKQ.js → chunk-I6NZFBT3.js} +3 -3
- package/dist/cli/chunks/{chunk-QVH5Y7AP.js → chunk-ISBOHF6Y.js} +1 -1
- package/dist/cli/chunks/{chunk-IWFFO6VT.js → chunk-J24AJEDE.js} +2 -2
- package/dist/cli/chunks/{chunk-5GFKTJ65.js → chunk-J5HTQHJK.js} +2 -2
- package/dist/cli/chunks/{chunk-LY7MFGBD.js → chunk-JDOVO4E4.js} +150 -149
- package/dist/cli/chunks/chunk-JQAJUXRE.js +2 -0
- package/dist/cli/chunks/{chunk-HXXHMLJ5.js → chunk-JRK5GX56.js} +1 -1
- package/dist/cli/chunks/{chunk-36VKMAMN.js → chunk-JRLZ7LZ3.js} +2 -2
- package/dist/cli/chunks/{chunk-6PJPQGF4.js → chunk-JTOFLDU7.js} +2 -2
- package/dist/cli/chunks/{chunk-CVOQ6ESD.js → chunk-K6EOHGKS.js} +2 -2
- package/dist/cli/chunks/{chunk-LU2EDWQK.js → chunk-KKXH25IH.js} +2 -2
- package/dist/cli/chunks/{chunk-EYXE2XKP.js → chunk-KNSQWM2E.js} +2 -2
- package/dist/cli/chunks/{chunk-IEJ7ZV3M.js → chunk-L5T32SRF.js} +1 -1
- package/dist/cli/chunks/{chunk-BEFTQVEW.js → chunk-LKFBW2QM.js} +2 -2
- package/dist/cli/chunks/{chunk-C3FXFU2T.js → chunk-LMAI74EP.js} +1 -1
- package/dist/cli/chunks/{chunk-P7XSPP5D.js → chunk-LQVS5IWH.js} +2 -2
- package/dist/cli/chunks/{chunk-4EKV7PHB.js → chunk-LRGTPUJA.js} +2 -2
- package/dist/cli/chunks/{chunk-MT7UNBZ7.js → chunk-LTHV4PIG.js} +2 -2
- package/dist/cli/chunks/{chunk-B2YGVSOP.js → chunk-M7QKCHLQ.js} +2 -2
- package/dist/cli/chunks/{chunk-H5RQPO3X.js → chunk-N3ASALOL.js} +2 -2
- package/dist/cli/chunks/{chunk-MQZ53OR3.js → chunk-NEXBTLN6.js} +2 -2
- package/dist/cli/chunks/{chunk-BD7FEUN3.js → chunk-NJEEKYEP.js} +3 -3
- package/dist/cli/chunks/{chunk-UOI6ULCH.js → chunk-NWUFTLSF.js} +2 -2
- package/dist/cli/chunks/{chunk-RT6O2HW2.js → chunk-O4QB2GFL.js} +2 -2
- package/dist/cli/chunks/{chunk-MZMG6CUJ.js → chunk-OA75C4HY.js} +2 -2
- package/dist/cli/chunks/{chunk-HYFQUWNB.js → chunk-OVMG6EEF.js} +2 -2
- package/dist/cli/chunks/{chunk-FSSR6WBE.js → chunk-OX7MJFLC.js} +2 -2
- package/dist/cli/chunks/{chunk-ENK44A6Q.js → chunk-OZJQN7YE.js} +2 -2
- package/dist/cli/chunks/{chunk-LXZMP3VX.js → chunk-PFXCRRR6.js} +25 -25
- package/dist/cli/chunks/{chunk-WIH522AP.js → chunk-PVJLQ2YZ.js} +1 -1
- package/dist/cli/chunks/{chunk-ZUB5YOCM.js → chunk-QDRFLM77.js} +2 -2
- package/dist/cli/chunks/{chunk-NHUGHAY6.js → chunk-QH7C4PTX.js} +1 -1
- package/dist/cli/chunks/{chunk-VXKWNRGA.js → chunk-QKM4XT2F.js} +2 -2
- package/dist/cli/chunks/{chunk-ON2UTP2U.js → chunk-QP7EKLWU.js} +2 -2
- package/dist/cli/chunks/{chunk-KUHLTVWC.js → chunk-QPACHVDI.js} +1 -1
- package/dist/cli/chunks/{chunk-PCJQCEBA.js → chunk-QQVE65ER.js} +2 -2
- package/dist/cli/chunks/{chunk-Q3NSU24F.js → chunk-QYCZYJH7.js} +2 -2
- package/dist/cli/chunks/{chunk-AEUEMVJK.js → chunk-R6I5I724.js} +2 -2
- package/dist/cli/chunks/{chunk-5D7ZFWDS.js → chunk-RJJIPTVH.js} +2 -2
- package/dist/cli/chunks/{chunk-ZWEKAEEV.js → chunk-RM6OC35G.js} +1 -1
- package/dist/cli/chunks/{chunk-ZELWDJXT.js → chunk-RTD4U7IW.js} +2 -2
- package/dist/cli/chunks/{chunk-O5V7RHVG.js → chunk-SKJQKOFJ.js} +2 -2
- package/dist/cli/chunks/{chunk-6RD44SCE.js → chunk-SMBGK7XI.js} +1 -1
- package/dist/cli/chunks/{chunk-ND4QTZOL.js → chunk-SPS472C5.js} +2 -2
- package/dist/cli/chunks/{chunk-TFK2AYIN.js → chunk-SUNXA2UR.js} +2 -2
- package/dist/cli/chunks/{chunk-RDGPXENG.js → chunk-SVP3BP52.js} +2 -2
- package/dist/cli/chunks/{chunk-NBLDBVAW.js → chunk-T4WQPE77.js} +1 -1
- package/dist/cli/chunks/{chunk-ZS4XVJGV.js → chunk-T53ZN4NO.js} +2 -2
- package/dist/cli/chunks/chunk-T6W2EYHC.js +2 -0
- package/dist/cli/chunks/{chunk-JZT7BU44.js → chunk-T7YCNOW5.js} +2 -2
- package/dist/cli/chunks/{chunk-EADSQN5T.js → chunk-TCQWVVSR.js} +1 -1
- package/dist/cli/chunks/{chunk-XYLQZWF6.js → chunk-TGRHO4ES.js} +2 -2
- package/dist/cli/chunks/{chunk-QPLSYEWJ.js → chunk-TP7L4EX6.js} +2 -2
- package/dist/cli/chunks/{chunk-N5XOXPHZ.js → chunk-TT45RCLN.js} +2 -2
- package/dist/cli/chunks/{chunk-OZGIOKEA.js → chunk-TUZNWRYC.js} +1 -1
- package/dist/cli/chunks/{chunk-53BXTTRO.js → chunk-U2QTL5T2.js} +3 -3
- package/dist/cli/chunks/chunk-U64QORFO.js +2 -0
- package/dist/cli/chunks/{chunk-SRPLERER.js → chunk-UHLZKH6B.js} +4 -4
- package/dist/cli/chunks/{chunk-HPWWYT67.js → chunk-UIWXKRTK.js} +2 -2
- package/dist/cli/chunks/{chunk-XWYELBZS.js → chunk-UNFE4RPV.js} +1 -1
- package/dist/cli/chunks/{chunk-FW4DJ4FJ.js → chunk-UQGIC5OX.js} +1 -1
- package/dist/cli/chunks/{chunk-GLGKQX2V.js → chunk-VAXTPLO3.js} +2 -2
- package/dist/cli/chunks/{chunk-VYDVI6FZ.js → chunk-VCSNNLWL.js} +2 -2
- package/dist/cli/chunks/{chunk-J7AQZLIH.js → chunk-VSPNIDQK.js} +4 -4
- package/dist/cli/chunks/{chunk-EIGRV3J6.js → chunk-VV2JVYOI.js} +2 -2
- package/dist/cli/chunks/{chunk-CBONQM5D.js → chunk-VW7AXJQS.js} +2 -2
- package/dist/cli/chunks/{chunk-O6MO5KMR.js → chunk-W7JUD4EZ.js} +2 -2
- package/dist/cli/chunks/{chunk-QFETNCNN.js → chunk-WFKE7NZ5.js} +2 -2
- package/dist/cli/chunks/{chunk-ROVZSZCS.js → chunk-WVEHKAIH.js} +3 -3
- package/dist/cli/chunks/{chunk-YO4ESCB4.js → chunk-XAESN54Q.js} +1 -1
- package/dist/cli/chunks/{chunk-RKUAWQOF.js → chunk-XECZYQT5.js} +2 -2
- package/dist/cli/chunks/{chunk-RLW25X66.js → chunk-XFT4FYTC.js} +2 -2
- package/dist/cli/chunks/{chunk-SM2YJ2AL.js → chunk-YHX74M7C.js} +2 -2
- package/dist/cli/chunks/chunk-YIWBJ637.js +2 -0
- package/dist/cli/chunks/{chunk-IAENZ2DR.js → chunk-Z5UZOYQS.js} +2 -2
- package/dist/cli/chunks/{chunk-G367W7XR.js → chunk-Z6G3QVZ4.js} +12 -12
- package/dist/cli/chunks/ci-5LIV2HW5.js +82 -0
- package/dist/cli/chunks/{ci-output-RLS32FUY.js → ci-output-UO5BDFU4.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-MRCC7WCM.js → circuit-breaker-UQDPXYRD.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-LIZCEKDF.js → claude-flow-setup-62QES3QX.js} +2 -2
- package/dist/cli/chunks/client-AJZKCP4I.js +2 -0
- package/dist/cli/chunks/{cline-installer-T7H6R2RC.js → cline-installer-X7VZTSZG.js} +2 -2
- package/dist/cli/chunks/{code-XMBLI7OF.js → code-H3BF4L4H.js} +3 -3
- package/dist/cli/chunks/{code-index-extractor-QS7BYLEX.js → code-index-extractor-BJGFZGGL.js} +2 -2
- package/dist/cli/chunks/{codex-installer-6PGT5FM6.js → codex-installer-KVZWKU6S.js} +2 -2
- package/dist/cli/chunks/{completions-2A3WRXY2.js → completions-YMILE6V7.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-23HOOGJ7.js → complexity-analyzer-J26N2PWG.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-4FSF7B3N.js → continuedev-installer-MAR42OV7.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-A5GRQQUU.js → copilot-installer-CVOJF6OT.js} +2 -2
- package/dist/cli/chunks/core-handlers-MQHEMGDV.js +2 -0
- package/dist/cli/chunks/{cost-tracker-Z4STQ5VB.js → cost-tracker-SXLWXE55.js} +2 -2
- package/dist/cli/chunks/{coverage-NUPP6KZZ.js → coverage-D7HCHFP3.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-3QNMZV5R.js +2 -0
- package/dist/cli/chunks/{cursor-installer-FVJ7ROPJ.js → cursor-installer-X37VHIKW.js} +2 -2
- package/dist/cli/chunks/{daemon-D662EX5N.js → daemon-JN7SOH6F.js} +4 -4
- package/dist/cli/chunks/{daemon-7ZZA2MMN.js → daemon-LIW47IDM.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-IB4TQ2KA.js → dag-attention-scheduler-QCHHIZBT.js} +2 -2
- package/dist/cli/chunks/{detect-LGLBZN4I.js → detect-WRFCWAX5.js} +2 -2
- package/dist/cli/chunks/{dist-node-Z3OL42YE.js → dist-node-6FWT4XZO.js} +2 -2
- package/dist/cli/chunks/{domain-handler-L3CLNL7U.js → domain-handler-SNFPNMRT.js} +2 -2
- package/dist/cli/chunks/{domain-plugins-GQ3V5X6L.js → domain-plugins-MXKHH62P.js} +2 -2
- package/dist/cli/chunks/domain-transfer-47UJNERX.js +2 -0
- package/dist/cli/chunks/dream-OSWAITPT.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-UGD6USYH.js → embed-and-insert-pattern-LZFAUNBQ.js} +2 -2
- package/dist/cli/chunks/{eval-3B7UIYGY.js → eval-AMUXTMJB.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-3RQ4NYY3.js → experience-capture-middleware-3D65TR2C.js} +4 -4
- package/dist/cli/chunks/{fast-paths-QOSAEPYD.js → fast-paths-Y7BBMM56.js} +2 -2
- package/dist/cli/chunks/{feature-flags-TLF4NKOH.js → feature-flags-JMQQ7JW4.js} +2 -2
- package/dist/cli/chunks/{feature-flags-3S5TH6P4.js → feature-flags-VESRRQ6V.js} +2 -2
- package/dist/cli/chunks/{file-discovery-AEVMJRNB.js → file-discovery-JJKQQUV6.js} +2 -2
- package/dist/cli/chunks/{fleet-E6WTXWFL.js → fleet-WIGHICJF.js} +4 -4
- package/dist/cli/chunks/{gnn-wrapper-MCKH3AUU.js → gnn-wrapper-BFNPETTT.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-U7XENHRR.js → heartbeat-handler-HDXKTGUI.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-BVRVVIE2.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-MZTHXULS.js +2 -0
- package/dist/cli/chunks/hnsw-index-KHEX4VDG.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-5GW4SAEI.js → hnsw-legacy-bridge-6A7OTAPT.js} +2 -2
- package/dist/cli/chunks/{hnswlib-node-7BLZBK5T.js → hnswlib-node-LKV2H47B.js} +2 -2
- package/dist/cli/chunks/{hooks-F3O2SB6H.js → hooks-KDSFYQQG.js} +10 -10
- package/dist/cli/chunks/hybrid-backend-2B3LCLR4.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-PV4EKXHB.js → hypergraph-engine-GDLPEPUC.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-VOWO5ZTW.js → hypergraph-handler-4UMFA2EW.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-4R4VWOGQ.js +2 -0
- package/dist/cli/chunks/{init-handler-ENJ5ONJX.js → init-handler-4GCHPQHD.js} +6 -6
- package/dist/cli/chunks/init-wizard-TAOPXHHD.js +2 -0
- package/dist/cli/chunks/kernel-6I6VZUWY.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-HNNJOOPE.js → kilocode-installer-HJZMT2G5.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-UZBIQ3IC.js → kiro-installer-WUPY67HG.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-KFMTTUR5.js +2 -0
- package/dist/cli/chunks/{learning-YMLCVFUT.js → learning-AXKIS7IG.js} +4 -4
- package/dist/cli/chunks/{llm-router-YWTARCCT.js → llm-router-HUDPNZLJ.js} +4 -4
- package/dist/cli/chunks/llm-router-service-2D74XVM3.js +2 -0
- package/dist/cli/chunks/{load-DKE3F3IP.js → load-RM44POD7.js} +2 -2
- package/dist/cli/chunks/load-test-53FWOWNS.js +2 -0
- package/dist/cli/chunks/{mcp-5PSGIUCW.js → mcp-5JVQRBOP.js} +2 -2
- package/dist/cli/chunks/{memory-3L3O6JMM.js → memory-VGZ2V6PL.js} +5 -5
- package/dist/cli/chunks/memory-backend-KFJDDPEZ.js +2 -0
- package/dist/cli/chunks/memory-handlers-EI537Z32.js +2 -0
- package/dist/cli/chunks/{multi-model-executor-AEEO7IA4.js → multi-model-executor-WPRKCSCM.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-ABBO355U.js → opencode-installer-YAJMRCQO.js} +2 -2
- package/dist/cli/chunks/{orchestrator-E36Q7MKE.js → orchestrator-MUGWBUYP.js} +6 -6
- package/dist/cli/chunks/pattern-null-store-7DMU5CJ4.js +2 -0
- package/dist/cli/chunks/{pattern-usage-recorder-H4XKSID4.js → pattern-usage-recorder-ZQJJ2YNG.js} +2 -2
- package/dist/cli/chunks/{pipeline-BGFEHXIN.js → pipeline-F4DXDUDC.js} +2 -2
- package/dist/cli/chunks/{platform-GK7ZVDJI.js → platform-HI3A3OWF.js} +2 -2
- package/dist/cli/chunks/{plugin-CAH2CKI6.js → plugin-XRITPTR7.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-M5EYRONA.js → prime-radiant-advanced-wasm-HHNJP7CQ.js} +2 -2
- package/dist/cli/chunks/{project-root-BSNZC243.js → project-root-2VN4WO2A.js} +2 -2
- package/dist/cli/chunks/protocol-executor-2EMTBTMG.js +2 -0
- package/dist/cli/chunks/{protocol-handler-JDSSC2SF.js → protocol-handler-ZEVHSEBG.js} +2 -2
- package/dist/cli/chunks/{prove-ANPTOZJE.js → prove-C4BLZWBS.js} +2 -2
- package/dist/cli/chunks/qe-reasoning-bank-VZHZZPHE.js +2 -0
- package/dist/cli/chunks/{quality-SXWGYRQR.js → quality-M3DTE4KK.js} +2 -2
- package/dist/cli/chunks/quality-gate-V6KS7ML3.js +7 -0
- package/dist/cli/chunks/queen-coordinator-7MYTTUHI.js +2 -0
- package/dist/cli/chunks/{real-embeddings-WSRYAOZM.js → real-embeddings-YWSE3IRT.js} +2 -2
- package/dist/cli/chunks/{ref-validation-AZ3LRWEK.js → ref-validation-ZWOTFA3T.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-2QKGFIEU.js → roocode-installer-GJBIWETD.js} +2 -2
- package/dist/cli/chunks/router-ZD4LXAWA.js +2 -0
- package/dist/cli/chunks/routing-feedback-FSLMDVGD.js +2 -0
- package/dist/cli/chunks/{routing-handler-UYDC5MMD.js → routing-handler-CFYLGNAR.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-QXADPVEY.js → ruvector-commands-EDKG456B.js} +2 -2
- package/dist/cli/chunks/rvf-dual-writer-LTKTDRFS.js +2 -0
- package/dist/cli/chunks/rvf-migration-adapter-IF24EVC5.js +2 -0
- package/dist/cli/chunks/{rvf-migration-coordinator-GD4NBFKT.js → rvf-migration-coordinator-ZMEYMAI6.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-E6JNBKMZ.js +2 -0
- package/dist/cli/chunks/{rvf-store-integrity-7SXG66IL.js → rvf-store-integrity-AH6PNJP6.js} +2 -2
- package/dist/cli/chunks/safe-db-F6TRB5KZ.js +2 -0
- package/dist/cli/chunks/schedule-HBD4BYTE.js +2 -0
- package/dist/cli/chunks/scheduler-6FYWPMQC.js +2 -0
- package/dist/cli/chunks/{security-YKB622PK.js → security-ZU2GW3ZM.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-KMLAV7JK.js → shared-rvf-adapter-5FOVSL3T.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-OYY27DFV.js → shared-rvf-dual-writer-IO4DC4XV.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-DOU72F5Z.js +2 -0
- package/dist/cli/chunks/{standalone-memory-2DOABVLC.js → standalone-memory-3UXDZ7HI.js} +2 -2
- package/dist/cli/chunks/{status-handler-EXRKETV7.js → status-handler-264CHTWS.js} +2 -2
- package/dist/cli/chunks/{structural-health-2SKK6DU6.js → structural-health-E2QPUOZE.js} +2 -2
- package/dist/cli/chunks/{sync-UW7SX7GO.js → sync-2ACMWM7D.js} +2 -2
- package/dist/cli/chunks/{sync-DQ2YUNI6.js → sync-N2L2OST4.js} +2 -2
- package/dist/cli/chunks/{task-handler-LYQ6WYUY.js → task-handler-IB5CVOTY.js} +2 -2
- package/dist/cli/chunks/{task-handlers-DIJO232S.js → task-handlers-QBMYNJHE.js} +3 -3
- package/dist/cli/chunks/{test-WRHZMUCW.js → test-7RGLRDSP.js} +6 -6
- package/dist/cli/chunks/{test-scheduling-HI23RXFK.js → test-scheduling-RJABJT2W.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-23SA6SWZ.js → token-bootstrap-JVHMHB72.js} +2 -2
- package/dist/cli/chunks/{token-usage-M7RRDPXO.js → token-usage-3ECHQVCY.js} +2 -2
- package/dist/cli/chunks/{transformers-4TC35KKS.js → transformers-KJH3IJWI.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-F4LTKAWD.js → tree-sitter-wasm-parser-XN6PFI32.js} +2 -2
- package/dist/cli/chunks/{types-NBXV6LXQ.js → types-5BAPXOLS.js} +2 -2
- package/dist/cli/chunks/unified-memory-GHAYAXWZ.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-CCC63YXT.js +2 -0
- package/dist/cli/chunks/unified-persistence-HKRHI5PG.js +2 -0
- package/dist/cli/chunks/{upgrade-4BGOU5RM.js → upgrade-S5NFQZID.js} +2 -2
- package/dist/cli/chunks/{validate-EDWAR63H.js → validate-BIBWOLJD.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-VI72CPR7.js → validate-swarm-WAA3LBHH.js} +2 -2
- package/dist/cli/chunks/visual-security-APOXJ3Q3.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-Y5XBRQXF.js → web-tree-sitter-OTBQTHAV.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-VEX23WAF.js → windsurf-installer-NNQ22EW6.js} +2 -2
- package/dist/cli/chunks/witness-chain-7IP5IJGT.js +2 -0
- package/dist/cli/chunks/{witness-chain-3YNL6YGY.js → witness-chain-E7MUBOJW.js} +2 -2
- package/dist/cli/chunks/{witness-chain-repair-MJZGZRWT.js → witness-chain-repair-FW4QSN4C.js} +2 -2
- package/dist/cli/chunks/{witness-chain-verifier-TTJYXTBE.js → witness-chain-verifier-YMROEBVL.js} +2 -2
- package/dist/cli/chunks/{witness-key-manager-EM6YXYOY.js → witness-key-manager-4CGRNDMJ.js} +2 -2
- package/dist/cli/chunks/{workflow-2RBDOM7V.js → workflow-4VRSTRAN.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-2HNW5ZMQ.js +2 -0
- package/dist/cli/chunks/{wrappers-5OTAVVOV.js → wrappers-4M4UTGEU.js} +2 -2
- package/dist/cli/commands/ci.js +17 -6
- package/dist/cli/commands/quality-gate.js +6 -1
- package/dist/cli/index.js +7 -2
- package/dist/cli/process-store-cleanup.d.ts +7 -0
- package/dist/cli/process-store-cleanup.js +27 -0
- package/dist/cli/utils/ci-config.d.ts +3 -3
- package/dist/cli/utils/ci-config.js +202 -68
- package/dist/domains/quality-assessment/quality-evidence.d.ts +3 -1
- package/dist/domains/quality-assessment/quality-evidence.js +7 -2
- package/dist/domains/test-execution/services/retry-handler.js +32 -13
- package/dist/domains/test-execution/services/test-executor.d.ts +3 -3
- package/dist/domains/test-execution/services/test-executor.js +66 -22
- package/dist/init/fleet-integration.js +3 -2
- package/dist/init/init-wizard-steps.js +3 -2
- package/dist/init/phases/06-code-intelligence.js +6 -4
- package/dist/integrations/ruvector/sona-persistence.d.ts +1 -0
- package/dist/integrations/ruvector/sona-persistence.js +74 -20
- package/dist/integrations/ruvector/sona-wrapper.d.ts +2 -0
- package/dist/integrations/ruvector/sona-wrapper.js +13 -0
- package/dist/kernel/memory-backend.js +5 -4
- package/dist/kernel/unified-memory.js +3 -2
- package/dist/learning/aqe-learning-engine.js +3 -2
- package/dist/mcp/bundle.js +440 -439
- package/dist/mcp/connection-pool.d.ts +2 -0
- package/dist/mcp/connection-pool.js +13 -2
- package/dist/mcp/handlers/memory-handlers.d.ts +1 -0
- package/dist/mcp/handlers/memory-handlers.js +16 -6
- package/dist/mcp/protocol-server.js +29 -8
- package/dist/mcp/types.d.ts +2 -0
- package/dist/optimization/session-cache.js +13 -11
- package/dist/plugins/cache.js +10 -3
- package/dist/shared/embeddings/embedding-cache.js +4 -4
- package/dist/shared/llm/cache.js +7 -10
- package/dist/shared/retry-engine.js +4 -0
- package/dist/shared/test-runner-process.d.ts +10 -0
- package/dist/shared/test-runner-process.js +210 -0
- package/dist/validation/quality-verdict.js +3 -2
- package/dist/workers/quality-daemon/priority-queue.js +4 -1
- package/package.json +4 -4
- package/dist/cli/chunks/adapter-TVQKH65T.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-ULGTVVWE.js +0 -2
- package/dist/cli/chunks/base-W42BURDL.js +0 -2
- package/dist/cli/chunks/browser-workflow-HKGHFFFT.js +0 -2
- package/dist/cli/chunks/chunk-2IMSJ7IO.js +0 -2
- package/dist/cli/chunks/chunk-FBZC4IGB.js +0 -2
- package/dist/cli/chunks/chunk-MNQN7UZX.js +0 -4
- package/dist/cli/chunks/chunk-OXHF3L2T.js +0 -2
- package/dist/cli/chunks/chunk-PELENDDQ.js +0 -2
- package/dist/cli/chunks/chunk-TW3SR4TS.js +0 -2
- package/dist/cli/chunks/chunk-V6RE4YRQ.js +0 -2
- package/dist/cli/chunks/chunk-ZQZD55MN.js +0 -3
- package/dist/cli/chunks/ci-J3TDK5RA.js +0 -81
- package/dist/cli/chunks/client-3BD2DI4N.js +0 -2
- package/dist/cli/chunks/core-handlers-C3H2ZCS2.js +0 -2
- package/dist/cli/chunks/cross-domain-router-JCQ7SWDP.js +0 -2
- package/dist/cli/chunks/domain-transfer-MFCI76IY.js +0 -2
- package/dist/cli/chunks/dream-FTP33IJB.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-HXBJVJL2.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-TU6WG2ME.js +0 -2
- package/dist/cli/chunks/hnsw-index-MS5KODD7.js +0 -2
- package/dist/cli/chunks/hybrid-backend-HT45LBHC.js +0 -2
- package/dist/cli/chunks/impact-analyzer-AP4AGTG5.js +0 -2
- package/dist/cli/chunks/init-wizard-I5DFZUQL.js +0 -2
- package/dist/cli/chunks/kernel-MISPSPPA.js +0 -2
- package/dist/cli/chunks/knowledge-graph-L26JESGE.js +0 -2
- package/dist/cli/chunks/llm-router-service-MWGC43ZA.js +0 -2
- package/dist/cli/chunks/load-test-H5ISNNM5.js +0 -2
- package/dist/cli/chunks/memory-backend-HWDNOBKW.js +0 -2
- package/dist/cli/chunks/memory-handlers-ZFDVQZM5.js +0 -2
- package/dist/cli/chunks/pattern-null-store-GQP6ICWK.js +0 -2
- package/dist/cli/chunks/protocol-executor-AD5A4DAI.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-W3Z2PKTR.js +0 -2
- package/dist/cli/chunks/quality-gate-GYNCA4ZY.js +0 -7
- package/dist/cli/chunks/queen-coordinator-HQRHLIJX.js +0 -2
- package/dist/cli/chunks/router-MTP5LH4H.js +0 -2
- package/dist/cli/chunks/routing-feedback-GWETVB4L.js +0 -2
- package/dist/cli/chunks/rvf-dual-writer-4UE5S7WP.js +0 -2
- package/dist/cli/chunks/rvf-migration-adapter-PHH3HF4Q.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-KTLZBUWV.js +0 -2
- package/dist/cli/chunks/safe-db-FWWGAPVE.js +0 -2
- package/dist/cli/chunks/schedule-TPA4V4D5.js +0 -2
- package/dist/cli/chunks/scheduler-5ZTEPNDD.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-HPTT624C.js +0 -2
- package/dist/cli/chunks/unified-memory-OVFEPRPS.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-KKRSCZHR.js +0 -2
- package/dist/cli/chunks/unified-persistence-7GLR4RI3.js +0 -2
- package/dist/cli/chunks/visual-security-2FUM5GLI.js +0 -2
- package/dist/cli/chunks/witness-chain-MH6GA5L6.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-H6G65YKU.js +0 -2
|
@@ -1,619 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/* ruflo-seg:BEGIN */
|
|
3
|
-
function rufloStatuslineDebug(stage, error){
|
|
4
|
-
if (!process || !process.env || process.env.AK_STATUSLINE_DEBUG !== "1") return;
|
|
5
|
-
if (error && error.code === "ENOENT") return; // optional source genuinely absent
|
|
6
|
-
try {
|
|
7
|
-
var fs = require("fs"), path = require("path"), os = require("os");
|
|
8
|
-
var root = process.env.XDG_STATE_HOME || path.join(os.homedir(), ".local", "state");
|
|
9
|
-
var file = process.env.AK_STATUSLINE_DEBUG_FILE || path.join(root, "agentic-kit", "statusline-debug.log");
|
|
10
|
-
var safeStage = String(stage || "unknown").replace(/[^a-z0-9._-]/gi, "_").slice(0, 64);
|
|
11
|
-
var safeName = String(error && error.name || "Error").replace(/[^A-Za-z0-9_-]/g, "").slice(0, 40) || "Error";
|
|
12
|
-
var safeCode = String(error && (error.code || error.errcode) || "unknown").replace(/[^A-Za-z0-9_-]/g, "").slice(0, 40) || "unknown";
|
|
13
|
-
var line = new Date().toISOString() + " stage=" + safeStage + " name=" + safeName + " code=" + safeCode + "\n";
|
|
14
|
-
fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
15
|
-
var size = 0; try { size = fs.statSync(file).size; } catch(_missing){}
|
|
16
|
-
if (size >= 65536) fs.writeFileSync(file, line, { mode: 0o600 });
|
|
17
|
-
else fs.appendFileSync(file, line, { mode: 0o600 });
|
|
18
|
-
try { fs.chmodSync(file, 0o600); } catch(_mode){}
|
|
19
|
-
} catch(_debugFailure) { /* diagnostics must never break the renderer */ }
|
|
20
|
-
}
|
|
21
|
-
function rufloActivationSegments(cwd){
|
|
22
|
-
try {
|
|
23
|
-
var fs = require("fs"), path = require("path"), cp = require("child_process");
|
|
24
|
-
var RED = "\x1b[1;31m"; // alarm-only segments (aidefence OFF) — matches ruflo's own brightRed
|
|
25
|
-
var DIM = "[2m", G = "[1;32m", Y = "[1;33m", C = "[1;36m", R = "[0m";
|
|
26
|
-
// ── quota tee (ADR-0010): Claude Code pushes plan utilization into every
|
|
27
|
-
// statusline invocation (rate_limits: five_hour/seven_day used_percentage +
|
|
28
|
-
// reset epochs — code.claude.com/docs/en/statusline.md). This is the ONLY
|
|
29
|
-
// supported channel for those numbers on a Pro/Max plan, and it is push-
|
|
30
|
-
// only, so the kit persists the latest payload for the dashboard's Limits
|
|
31
|
-
// view to read (quota.mjs). Throttled to one write/min (the statusline
|
|
32
|
-
// refreshes every ~5s); atomic tmp+rename at 0600 — account utilization is
|
|
33
|
-
// the user's own business. Failure is silent by design: a broken tee must
|
|
34
|
-
// never cost a statusline render.
|
|
35
|
-
try {
|
|
36
|
-
if (typeof getStdinData === "function") {
|
|
37
|
-
var _qsd = getStdinData();
|
|
38
|
-
if (_qsd && _qsd.rate_limits && typeof _qsd.rate_limits === "object") {
|
|
39
|
-
var _qdir = path.join(process.env.XDG_CONFIG_HOME || path.join(require("os").homedir(), ".config"), "agentic-kit");
|
|
40
|
-
var _qf = path.join(_qdir, "claude-rate-limits.json");
|
|
41
|
-
var _qold = 0;
|
|
42
|
-
try { _qold = fs.statSync(_qf).mtimeMs; } catch(e){ rufloStatuslineDebug("quota-cache-stat", e); }
|
|
43
|
-
if (Date.now() - _qold > 60000) {
|
|
44
|
-
fs.mkdirSync(_qdir, { recursive: true });
|
|
45
|
-
var _qtmp = _qf + "." + process.pid + ".tmp";
|
|
46
|
-
fs.writeFileSync(_qtmp, JSON.stringify({
|
|
47
|
-
teedAt: Date.now(),
|
|
48
|
-
session_id: _qsd.session_id || null,
|
|
49
|
-
model: (_qsd.model && _qsd.model.id) || null,
|
|
50
|
-
rate_limits: _qsd.rate_limits,
|
|
51
|
-
context_window: _qsd.context_window || null,
|
|
52
|
-
cost: _qsd.cost || null
|
|
53
|
-
}), { mode: 0o600 });
|
|
54
|
-
fs.renameSync(_qtmp, _qf);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
} catch(e){ rufloStatuslineDebug("quota-tee", e); }
|
|
59
|
-
function bar(n, max){ n = Math.max(0, Math.min(max, n)); return "[" + "●".repeat(n) + "○".repeat(max - n) + "]"; }
|
|
60
|
-
// ── self-learning (SONA): own line with a volume bar (patterns/traj/HNSW) plus a
|
|
61
|
-
// LIVE micro-LoRA adaptation field (Δ‖W‖, appended further below). The Δ‖W‖ tracker
|
|
62
|
-
// is maintained inline in this same function — see the "micro-LoRA LIVE adaptation"
|
|
63
|
-
// block after the route-Q segment.
|
|
64
|
-
var learn = "";
|
|
65
|
-
try {
|
|
66
|
-
var sp = path.join(cwd, ".claude-flow", "neural", "stats.json");
|
|
67
|
-
if (fs.existsSync(sp)) {
|
|
68
|
-
var s = JSON.parse(fs.readFileSync(sp, "utf8"));
|
|
69
|
-
var pn = s.patternsLearned || 0, tj = s.trajectoriesRecorded || 0, parts = [];
|
|
70
|
-
if (pn > 0 || tj > 0) {
|
|
71
|
-
if (pn > 0) parts.push(pn + " patterns");
|
|
72
|
-
if (tj > 0) parts.push(tj + " traj");
|
|
73
|
-
if (fs.existsSync(path.join(cwd, ".swarm", "hnsw.index"))) parts.push(G + "⚡ HNSW" + R);
|
|
74
|
-
var dots = Math.max(0, Math.min(5, Math.round(pn / 10))); // volume gauge: ~10 patterns per dot
|
|
75
|
-
learn = C + "🧠 SONA" + R + " " + DIM + bar(dots, 5) + R + " " + parts.join(DIM + " · " + R);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
} catch(e){ rufloStatuslineDebug("sona-stats", e); }
|
|
79
|
-
// ── micro-LoRA LIVE adaptation: Δ‖W‖<cum> +<session> <trend> n<count> ──
|
|
80
|
-
// Shows the model ACTUALLY ADAPTING FROM YOUR WORK, live. ruflo's own micro-LoRA is
|
|
81
|
-
// per-process scratch ("resets per process", intelligence.js) — every hook reinits it
|
|
82
|
-
// (random A, B=0), applies that call's signals, then DISCARDS the weights; only
|
|
83
|
-
// patterns.json / stats.json persist. So the kit persists what ruflo throws away: a
|
|
84
|
-
// single cumulative micro-LoRA in lora-live.json, advanced HERE (inline, mtime+TTL
|
|
85
|
-
// gated) by feeding each NEW distilled pattern ruflo has learned from your work
|
|
86
|
-
// (.claude-flow/neural/patterns.json) through the genuine @ruvector/ruvllm 2.5.6
|
|
87
|
-
// gradient path (real since F4 fixed), weighted by ruflo's OWN per-pattern confidence
|
|
88
|
-
// (no fabricated reward). The init RNG is seeded and weights are restored each tick, so
|
|
89
|
-
// the result is DETERMINISTIC (no 41%-CV random-init noise) and cumulative.
|
|
90
|
-
// Δ‖W‖ = ‖scaling·(A·B)‖_F (federated-LoRA's standard adaptation-magnitude monitor)
|
|
91
|
-
// +<session> = growth since this session began (the live "from your work" signal)
|
|
92
|
-
// n = distinct patterns fed (REINFORCE updates). Gate: cum norm > 0.
|
|
93
|
-
// Honest scope: a kit-persisted MIRROR of ruflo's discarded adapter, fed ruflo's real
|
|
94
|
-
// confidence-weighted patterns. NOT shown: amplification factor (no frozen base W) and
|
|
95
|
-
// a live reward curve (neural-train's WASM path records trajectories, not signals → 0).
|
|
96
|
-
try {
|
|
97
|
-
var nd = path.join(cwd, ".claude-flow", "neural");
|
|
98
|
-
var pPath = path.join(nd, "patterns.json"), sPath = path.join(nd, "lora-live.json");
|
|
99
|
-
if (fs.existsSync(pPath)) {
|
|
100
|
-
var st = null; try { st = JSON.parse(fs.readFileSync(sPath, "utf8")); } catch(e){ rufloStatuslineDebug("lora-state-read", e); }
|
|
101
|
-
var nowS = Math.floor(Date.now() / 1000);
|
|
102
|
-
var pMtimeMs = fs.statSync(pPath).mtimeMs; // ms precision: same-second writes still detected
|
|
103
|
-
var TTL = Number(process.env.RUFLO_LORA_TTL_S || 60);
|
|
104
|
-
// Session boundary: prefer Claude Code's real session_id (piped on stdin) so the
|
|
105
|
-
// +<session> delta resets exactly when YOU start a new session — not on a clock.
|
|
106
|
-
// getStdinData() is the host statusline's cached single-read of that JSON; guard the
|
|
107
|
-
// call so the segment still works on a template that lacks it, or run standalone.
|
|
108
|
-
var sid = "";
|
|
109
|
-
try { if (typeof getStdinData === "function") { var _sd = getStdinData(); sid = (_sd && (_sd.session_id || _sd.sessionId)) || ""; } } catch(e){ rufloStatuslineDebug("lora-session-input", e); }
|
|
110
|
-
// Refresh when: no state yet, the session changed (reset the +session baseline even
|
|
111
|
-
// with no new patterns), or patterns changed and the TTL has elapsed.
|
|
112
|
-
var sidChanged = !!(sid && st && (st.sessionId || "") !== sid);
|
|
113
|
-
var stale = !st || sidChanged || (pMtimeMs > (st.pms || 0) && (nowS - (st.ts || 0)) >= TTL);
|
|
114
|
-
if (stale) {
|
|
115
|
-
// Resolve the installed ruvllm SonaCoordinator (same global layout as the version probe).
|
|
116
|
-
var SC = null;
|
|
117
|
-
try {
|
|
118
|
-
var sj = path.join(path.dirname(process.execPath), "..", "lib", "node_modules", "ruflo",
|
|
119
|
-
"node_modules", "@ruvector", "ruvllm", "dist", "cjs", "sona.js");
|
|
120
|
-
if (fs.existsSync(sj)) SC = require(sj).SonaCoordinator;
|
|
121
|
-
} catch(e){ rufloStatuslineDebug("lora-module-load", e); }
|
|
122
|
-
if (SC) {
|
|
123
|
-
var pats = JSON.parse(fs.readFileSync(pPath, "utf8"));
|
|
124
|
-
// Seed Math.random so the first-ever loraA init is deterministic; restore after ctor.
|
|
125
|
-
var seed = 0x9e3779b9, orig = Math.random;
|
|
126
|
-
Math.random = function(){ seed = (seed * 1103515245 + 12345) & 0x7fffffff; return seed / 0x7fffffff; };
|
|
127
|
-
var coord = new SC({ backgroundLoopEnabled: false });
|
|
128
|
-
Math.random = orig;
|
|
129
|
-
var applied = new Set((st && st.appliedIds) || []);
|
|
130
|
-
var n = (st && st.n) || 0;
|
|
131
|
-
if (st && st.loraA) { try { coord.microLora.setWeights({ loraA: st.loraA, loraB: st.loraB, scaling: st.scaling }); } catch(e){ rufloStatuslineDebug("lora-weight-restore", e); } }
|
|
132
|
-
var prevSid = st ? (st.sessionId || "") : "";
|
|
133
|
-
var newSession;
|
|
134
|
-
if (sid) {
|
|
135
|
-
newSession = !st || prevSid !== sid; // real per-session boundary
|
|
136
|
-
} else {
|
|
137
|
-
newSession = !st || (nowS - (st.ts || 0) > 1800); // no id (manual run): idle fallback
|
|
138
|
-
sid = prevSid; // preserve the session we're in
|
|
139
|
-
}
|
|
140
|
-
var sessionBase = newSession ? (st ? (st.deltaNorm || 0) : 0) : (st.sessionBase || 0);
|
|
141
|
-
var sessionTs = newSession ? nowS : (st.sessionTs || nowS);
|
|
142
|
-
for (var i = 0; i < (Array.isArray(pats) ? pats.length : 0); i++) {
|
|
143
|
-
var p = pats[i], id = String(p.id || i);
|
|
144
|
-
if (applied.has(id)) continue;
|
|
145
|
-
var conf = (typeof p.confidence === "number") ? p.confidence : Number(p.confidence);
|
|
146
|
-
coord.recordSignal({ requestId: id, type: p.type || "pattern",
|
|
147
|
-
quality: (conf >= 0 && conf <= 1) ? conf : 0.7, correction: String(p.content || id) });
|
|
148
|
-
applied.add(id); n++;
|
|
149
|
-
}
|
|
150
|
-
var w = coord.microLora.getWeights(), nm = coord.stats().microLora.deltaNorm;
|
|
151
|
-
var rec = { loraA: w.loraA, loraB: w.loraB, scaling: w.scaling, appliedIds: Array.from(applied),
|
|
152
|
-
n: n, deltaNorm: nm, sessionBase: sessionBase, sessionTs: sessionTs, sessionId: sid,
|
|
153
|
-
pms: pMtimeMs, ts: nowS };
|
|
154
|
-
try { var tmp = sPath + ".tmp"; fs.writeFileSync(tmp, JSON.stringify(rec)); fs.renameSync(tmp, sPath); } catch(e){ rufloStatuslineDebug("lora-state-write", e); }
|
|
155
|
-
st = rec;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
if (st && typeof st.deltaNorm === "number" && st.deltaNorm > 0) {
|
|
159
|
-
var sess = st.deltaNorm - (st.sessionBase || 0);
|
|
160
|
-
var trend = "";
|
|
161
|
-
if (Math.abs(sess) / st.deltaNorm < 0.005) trend = DIM + "→" + R;
|
|
162
|
-
else trend = sess > 0 ? (G + "▲" + R) : (Y + "▼" + R);
|
|
163
|
-
var sessStr = (Math.abs(sess) / st.deltaNorm >= 0.005)
|
|
164
|
-
? (" " + (sess > 0 ? G : Y) + (sess > 0 ? "+" : "") + sess.toFixed(4) + R) : "";
|
|
165
|
-
var dseg = C + "Δ‖W‖" + st.deltaNorm.toFixed(4) + R + sessStr + trend + DIM + " n" + st.n + R;
|
|
166
|
-
if (learn) { learn += DIM + " · " + R + dseg; }
|
|
167
|
-
else { learn = C + "🧠 Δ LoRA" + R + " " + dseg; }
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
} catch(e){ rufloStatuslineDebug("lora-segment", e); }
|
|
171
|
-
// ── route Q-learner (📈 RL): live agent-routing metrics, fs-only, honesty-gated ──
|
|
172
|
-
// F3 (ruvnet/ruflo#2239) is fixed in ruflo 3.10.11 (FNV-1a lossless fold) — the
|
|
173
|
-
// state encoder no longer collapses keyword-distinct tasks, so |Q| is a
|
|
174
|
-
// real task-diversity count. Source the persisted Q-model directly; never the broken
|
|
175
|
-
// `route stats` CLI. Gate hard: render ONLY when the learner has actually run
|
|
176
|
-
// (updateCount>0), else emit nothing — no zero-state noise.
|
|
177
|
-
var route = "";
|
|
178
|
-
try {
|
|
179
|
-
var qp = path.join(cwd, ".swarm", "q-learning-model.json");
|
|
180
|
-
if (fs.existsSync(qp)) {
|
|
181
|
-
var qm = JSON.parse(fs.readFileSync(qp, "utf8"));
|
|
182
|
-
var st = qm.stats || {};
|
|
183
|
-
var upd = st.updateCount || 0;
|
|
184
|
-
if (upd > 0) {
|
|
185
|
-
var eps = typeof st.epsilon === "number" ? st.epsilon : null;
|
|
186
|
-
var td = typeof st.avgTDError === "number" ? st.avgTDError : null;
|
|
187
|
-
var qn = qm.qTable && typeof qm.qTable === "object" ? Object.keys(qm.qTable).length : 0;
|
|
188
|
-
var rp = [];
|
|
189
|
-
if (eps !== null) rp.push("ε" + eps.toFixed(2) + DIM + "↓" + R);
|
|
190
|
-
if (td !== null) rp.push("δ̄" + td.toFixed(3) + DIM + "↓" + R);
|
|
191
|
-
if (qn > 0) rp.push("|Q|" + qn);
|
|
192
|
-
rp.push("upd" + upd);
|
|
193
|
-
route = C + "📈 RL" + R + " " + rp.join(DIM + " · " + R);
|
|
194
|
-
}
|
|
195
|
-
} else {
|
|
196
|
-
// Fallback: ruflo's metrics surface (no broken route-stats CLI). Only when it
|
|
197
|
-
// reflects real routing decisions.
|
|
198
|
-
var lp = path.join(cwd, ".claude-flow", "metrics", "learning.json");
|
|
199
|
-
if (fs.existsSync(lp)) {
|
|
200
|
-
var lj = JSON.parse(fs.readFileSync(lp, "utf8"));
|
|
201
|
-
var rt = lj.routing || {};
|
|
202
|
-
if ((rt.decisions || 0) > 0) {
|
|
203
|
-
var rp2 = [];
|
|
204
|
-
if (typeof rt.accuracy === "number") rp2.push("acc" + Math.round(rt.accuracy * 100) + "%");
|
|
205
|
-
rp2.push("dec" + rt.decisions);
|
|
206
|
-
route = C + "📈 RL" + R + " " + rp2.join(DIM + " · " + R);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
} catch(e){ rufloStatuslineDebug("route-learning", e); }
|
|
211
|
-
// ── proof verdict (self-improvement eval): ALARM-ONLY, fs-only ──
|
|
212
|
-
// Sources the most recent ruflo-improvement-eval run (.claude-flow/improvement.json):
|
|
213
|
-
// a pre-registered causal test (one-sided permutation p + Cohen's d + above-chance)
|
|
214
|
-
// that the route Q-learner self-improves vs a no-learning ablation. It is a SYNTHETIC
|
|
215
|
-
// proof-of-mechanism (its own reward env), NOT a live measure of real routing — that
|
|
216
|
-
// is what the 📈 RL line above is. So PASS is the expected state and is rendered
|
|
217
|
-
// SILENTLY; only a FAIL (a real regression worth a look) surfaces, as ◷ proof FAIL.
|
|
218
|
-
// The run age (im.ts) is appended so a stale FAIL reads honestly. Never a fabricated
|
|
219
|
-
// source. Fields per #8: Δpp · CI · p · d · age. (#8 — alarm-only per user decision.)
|
|
220
|
-
var proof = "";
|
|
221
|
-
try {
|
|
222
|
-
var ip = path.join(cwd, ".claude-flow", "improvement.json");
|
|
223
|
-
if (fs.existsSync(ip)) {
|
|
224
|
-
var im = JSON.parse(fs.readFileSync(ip, "utf8"));
|
|
225
|
-
if (im && im.verdict === "FAIL") {
|
|
226
|
-
var pp = [];
|
|
227
|
-
if (typeof im.deltaPP === "number") pp.push("Δ" + (im.deltaPP >= 0 ? "+" : "") + im.deltaPP + "pp");
|
|
228
|
-
if (typeof im.ci95 === "number") pp.push("CI±" + im.ci95);
|
|
229
|
-
if (typeof im.pValue === "number") pp.push("p" + (im.pValue < 0.001 ? "<.001" : "=" + im.pValue.toFixed(3)));
|
|
230
|
-
if (typeof im.cohensD === "number") pp.push("d" + (im.cohensD >= 999 ? "∞" : im.cohensD));
|
|
231
|
-
if (typeof im.ts === "number") {
|
|
232
|
-
var ageSec = Math.floor(Date.now() / 1000) - im.ts;
|
|
233
|
-
if (ageSec >= 86400) pp.push(Math.floor(ageSec / 86400) + "d ago");
|
|
234
|
-
else if (ageSec >= 3600) pp.push(Math.floor(ageSec / 3600) + "h ago");
|
|
235
|
-
}
|
|
236
|
-
proof = Y + "◷ proof FAIL" + R + (pp.length ? " " + DIM + pp.join(" · ") + R : "");
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
} catch(e){ rufloStatuslineDebug("proof-verdict", e); }
|
|
240
|
-
// ── AI defense (AIMDS) — ALARM-ONLY: renders only when it is MISSING ────────
|
|
241
|
-
// Was a permanent green "🛡 aidefence on". Two reasons it inverted:
|
|
242
|
-
// 1. Issue #8's rule, already law for the proof segment below: the expected state
|
|
243
|
-
// is rendered SILENTLY, only a regression surfaces, no static green badge. A
|
|
244
|
-
// constant "on" carries no information after the first glance — unlike SONA/QE,
|
|
245
|
-
// whose counts move — so it was the one pure binary badge in this footer.
|
|
246
|
-
// 2. Glyph collision: ruflo's line 2 uses 🛡 for the SCAN state, a different
|
|
247
|
-
// concern entirely (`security scan` audits your SOURCE; this is `security
|
|
248
|
-
// defend` / AIMDS screening PROMPTS for injection, jailbreak and PII). Two
|
|
249
|
-
// shields meaning different things read as one duplicated thing. The alarm
|
|
250
|
-
// carries no 🛡 at all, so it can never be confused with the scan shield.
|
|
251
|
-
//
|
|
252
|
-
// Still load-bearing, not decoration: @claude-flow/aidefence is NOT a declared
|
|
253
|
-
// dependency of ruflo or @claude-flow/cli (verified still true on 3.32.0) while
|
|
254
|
-
// `security defend` imports it (ruvnet/ruflo#2670). It is present ONLY because the
|
|
255
|
-
// kit's healAidefence npm-installs it into rufloRoot(). A plain `npm i -g ruflo`
|
|
256
|
-
// can therefore silently remove your injection defense — and under the old polarity
|
|
257
|
-
// that catastrophe was signalled by a line quietly VANISHING, which is ambiguous
|
|
258
|
-
// (off? probe threw? forgot to look?). Now the dangerous state is the loud one.
|
|
259
|
-
//
|
|
260
|
-
// FAIL-SAFE POLARITY (the reason for the two-step probe): alarm only on POSITIVE
|
|
261
|
-
// evidence of absence — we located a ruflo install AND aidefence is not inside it.
|
|
262
|
-
// If ruflo itself cannot be found (custom npm prefix, or the statusline running
|
|
263
|
-
// under a different node than the one that installed it), we cannot know, so we say
|
|
264
|
-
// NOTHING. Inverting a signal also inverts its failure mode: a probe miss used to
|
|
265
|
-
// fail silent, and would now fail LOUD and WRONG. Claiming "your defense is off"
|
|
266
|
-
// when it is on is the same crime as the fabricated CVE counter overlaid above.
|
|
267
|
-
// Probe + verdict live in rufloAidefenceState/rufloFindRufloRoot (below) so the
|
|
268
|
-
// three-state logic is unit-testable against fixture trees — it cannot be exercised
|
|
269
|
-
// from here, where it depends on the real process.execPath.
|
|
270
|
-
var sec = "";
|
|
271
|
-
try {
|
|
272
|
-
if (rufloAidefenceState(rufloFindRufloRoot()) === "off") {
|
|
273
|
-
sec = RED + "⚠ aidefence OFF" + R + DIM + " — no prompt-injection defense · ak sync restores it" + R;
|
|
274
|
-
}
|
|
275
|
-
} catch(e){ rufloStatuslineDebug("aidefence-state", e); }
|
|
276
|
-
// ── daemon visibility (⚙): GLOBAL count of running ruflo daemons, so no daemon
|
|
277
|
-
// is ever invisible (token-burn incident lesson). Machine-global, not per-project,
|
|
278
|
-
// so it is cached in tmpdir and shared across every project's statusline — one
|
|
279
|
-
// pgrep per TTL window, not per render. Daemons are default-on (local-only
|
|
280
|
-
// workers, budget-governed AI workers) since the 3.28 baseline, so one per active
|
|
281
|
-
// project is the EXPECTED steady state: dim up to 3, YELLOW at >=4 (more daemons
|
|
282
|
-
// than you're plausibly working projects — ruflo-daemon-gc to inspect; upstream
|
|
283
|
-
// TTL + kit auto-reap will also converge it). Opt out: RUFLO_DAEMON_STATUSLINE=0.
|
|
284
|
-
var daemon = "";
|
|
285
|
-
try {
|
|
286
|
-
if (process.env.RUFLO_DAEMON_STATUSLINE !== "0") {
|
|
287
|
-
var os = require("os");
|
|
288
|
-
var dCache = path.join(os.tmpdir(), "ruflo-daemon-count.json");
|
|
289
|
-
var dTtl = Number(process.env.RUFLO_DAEMON_STATUSLINE_TTL_MS || 30000);
|
|
290
|
-
var dCount = null;
|
|
291
|
-
try { var dc = JSON.parse(fs.readFileSync(dCache, "utf8")); if (dc && typeof dc.n === "number" && dTtl > 0 && (Date.now() - dc.ts) < dTtl) dCount = dc.n; } catch(e){ rufloStatuslineDebug("daemon-cache-read", e); }
|
|
292
|
-
if (dCount === null) {
|
|
293
|
-
try {
|
|
294
|
-
var pg = cp.execFileSync("pgrep", ["-f", "cli.js daemon start"], {stdio:["ignore","pipe","ignore"], timeout:1500}).toString().trim();
|
|
295
|
-
dCount = pg ? pg.split("\n").filter(Boolean).length : 0;
|
|
296
|
-
} catch(e){ dCount = 0; } // pgrep exits 1 (=> throws) when nothing matches
|
|
297
|
-
try { fs.writeFileSync(dCache, JSON.stringify({ts: Date.now(), n: dCount})); } catch(e){ rufloStatuslineDebug("daemon-cache-write", e); }
|
|
298
|
-
}
|
|
299
|
-
if (dCount > 0) {
|
|
300
|
-
var dCol = dCount >= 4 ? Y : DIM;
|
|
301
|
-
daemon = dCol + "⚙ " + dCount + " ruflo daemon" + (dCount === 1 ? "" : "s") + R
|
|
302
|
-
+ (dCount >= 4 ? DIM + " — ruflo-daemon-gc to inspect" + R : "");
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
} catch(e){ rufloStatuslineDebug("daemon-segment", e); }
|
|
306
|
-
// ── RuvNet Brain (🧿): offline rUv-stack knowledge base — honesty-gated, fs-only ──
|
|
307
|
-
// The brain is NOT an npm package — `npx github:stuinfla/ruvnet-brain` drops a
|
|
308
|
-
// ~2GB offline knowledge base at ~/.cache/ruvnet-brain/kb (honors RUVNET_BRAIN_KB)
|
|
309
|
-
// and wires a user-scope Claude Code plugin. Presence probe MIRRORS
|
|
310
|
-
// src/lib/ruvnet-brain.mjs exactly: existence of the KB's forge-mcp-all.mjs
|
|
311
|
-
// entrypoint. Render NOTHING when absent — never a fabricated row. The KB is a flat
|
|
312
|
-
// dir of data files, so the true size is a shallow sum of its top-level files
|
|
313
|
-
// (the __MACOSX zip-artifact dir is a directory, so isFile() correctly excludes it);
|
|
314
|
-
// that sum is TTL-cached machine-globally in tmpdir (like the ⚙ daemon / 🎓 QE
|
|
315
|
-
// chips) so ~600 stat() calls run at most once per window, not per render. The 💾
|
|
316
|
-
// chip reuses the QE size formatting. The plugin semver (marketplace manifest,
|
|
317
|
-
// best-effort) rides next to the label like "RuFlo V<x>" / "Agentic QE V<x>".
|
|
318
|
-
var brain = "";
|
|
319
|
-
try {
|
|
320
|
-
var os2 = require("os");
|
|
321
|
-
var kbDir = process.env.RUVNET_BRAIN_KB || path.join(os2.homedir(), ".cache", "ruvnet-brain", "kb");
|
|
322
|
-
if (fs.existsSync(path.join(kbDir, "forge-mcp-all.mjs"))) {
|
|
323
|
-
// Version — best-effort, empty on any failure (never blocks the row).
|
|
324
|
-
// RELEASE-tag namespace (what `ak status` shows, e.g. 3.3.1), never the
|
|
325
|
-
// plugin.json SEMVER (e.g. 0.5.0-dev) — different namespaces for the same
|
|
326
|
-
// install; showing the semver here confused users (it disagreed with
|
|
327
|
-
// `ak status`). Three-namespace gotcha; see MAINTAINER.md. Resolution
|
|
328
|
-
// order MIRRORS drift() in src/lib/ruvnet-brain.mjs so this row and
|
|
329
|
-
// `ak status` can never disagree:
|
|
330
|
-
// 1) the bundle's own on-disk stamp (SOURCE.json.releaseTag) — ground
|
|
331
|
-
// truth, current even when the KB changed outside ak (e.g. a manual
|
|
332
|
-
// forge-update.mjs run);
|
|
333
|
-
// 2) ak's kit.json record of the release it last installed;
|
|
334
|
-
// 3) plugin semver — last resort for manual/pre-stamping installs.
|
|
335
|
-
var bver = "";
|
|
336
|
-
try {
|
|
337
|
-
var relTag = null;
|
|
338
|
-
try {
|
|
339
|
-
var srcJ = JSON.parse(fs.readFileSync(path.join(kbDir, "SOURCE.json"), "utf8"));
|
|
340
|
-
var rawTag = String(srcJ.releaseTag || "");
|
|
341
|
-
if (/^[A-Za-z0-9._-]{1,32}$/.test(rawTag)) relTag = rawTag;
|
|
342
|
-
} catch(e){ rufloStatuslineDebug("brain-source-stamp", e); }
|
|
343
|
-
if (!relTag) try {
|
|
344
|
-
var kitCfg = path.join(os2.homedir(), ".config", "agentic-kit", "kit.json");
|
|
345
|
-
var kj = JSON.parse(fs.readFileSync(kitCfg, "utf8"));
|
|
346
|
-
if (kj && kj.versionCheck && kj.versionCheck.ruvnetBrain) relTag = kj.versionCheck.ruvnetBrain.installedRelease;
|
|
347
|
-
} catch(e){ rufloStatuslineDebug("brain-kit-stamp", e); }
|
|
348
|
-
if (relTag) {
|
|
349
|
-
bver = " V" + String(relTag).replace(/^v/, "");
|
|
350
|
-
} else {
|
|
351
|
-
var bpkg = path.join(os2.homedir(), ".claude", "plugins", "marketplaces",
|
|
352
|
-
"ruvnet-brain", "plugin", ".claude-plugin", "plugin.json");
|
|
353
|
-
var bv = JSON.parse(fs.readFileSync(bpkg, "utf8")).version;
|
|
354
|
-
if (bv) bver = " V" + String(bv).replace(/^v/, "");
|
|
355
|
-
}
|
|
356
|
-
} catch(e){ rufloStatuslineDebug("brain-version", e); }
|
|
357
|
-
// KB size — TTL-cached shallow sum of top-level files, keyed on kbDir so an
|
|
358
|
-
// env-overridden path (or a moved KB) never serves a stale foreign size.
|
|
359
|
-
var bBytes = null;
|
|
360
|
-
try {
|
|
361
|
-
var bCache = path.join(os2.tmpdir(), "ruvnet-brain-kb-size.json");
|
|
362
|
-
var bTtl = Number(process.env.RUVNET_BRAIN_KB_TTL_MS || 300000);
|
|
363
|
-
try {
|
|
364
|
-
var bc = JSON.parse(fs.readFileSync(bCache, "utf8"));
|
|
365
|
-
if (bc && bc.dir === kbDir && typeof bc.bytes === "number" && bTtl > 0 && (Date.now() - bc.ts) < bTtl) bBytes = bc.bytes;
|
|
366
|
-
} catch(e){ rufloStatuslineDebug("brain-size-cache-read", e); }
|
|
367
|
-
if (bBytes === null) {
|
|
368
|
-
var sum = 0;
|
|
369
|
-
fs.readdirSync(kbDir).forEach(function(f){
|
|
370
|
-
try { var s = fs.statSync(path.join(kbDir, f)); if (s.isFile()) sum += s.size; } catch(e){ rufloStatuslineDebug("brain-size-entry", e); }
|
|
371
|
-
});
|
|
372
|
-
bBytes = sum;
|
|
373
|
-
try { fs.writeFileSync(bCache, JSON.stringify({ts: Date.now(), dir: kbDir, bytes: sum})); } catch(e){ rufloStatuslineDebug("brain-size-cache-write", e); }
|
|
374
|
-
}
|
|
375
|
-
} catch(e){ rufloStatuslineDebug("brain-size", e); }
|
|
376
|
-
var bp = [];
|
|
377
|
-
if (bBytes && bBytes > 0) {
|
|
378
|
-
var bkb = Math.round(bBytes / 1024);
|
|
379
|
-
bp.push("💾 " + (bkb >= 1024 ? (bkb/1024).toFixed(1) + "MB" : bkb + "KB"));
|
|
380
|
-
}
|
|
381
|
-
brain = C + "🧿 RuvNet Brain" + bver + R + " " + (bp.length ? bp.join(DIM + " · " + R) : G + "✓" + R);
|
|
382
|
-
}
|
|
383
|
-
} catch(e){ rufloStatuslineDebug("brain-segment", e); }
|
|
384
|
-
// ── agentic-qe — TTL-cached; one sqlite3 spawn only on a cache miss (issue #3) ──
|
|
385
|
-
var qe = "";
|
|
386
|
-
try {
|
|
387
|
-
var db = path.join(cwd, ".agentic-qe", "memory.db");
|
|
388
|
-
if (fs.existsSync(db)) {
|
|
389
|
-
var cacheDir = path.join(cwd, ".claude-flow", "cache");
|
|
390
|
-
var cacheFile = path.join(cacheDir, "qe-statusline.json");
|
|
391
|
-
var ttl = Number(process.env.RUFLO_QE_STATUSLINE_TTL_MS || 60000);
|
|
392
|
-
var cachedLine = null;
|
|
393
|
-
try {
|
|
394
|
-
var cc = JSON.parse(fs.readFileSync(cacheFile, "utf8"));
|
|
395
|
-
if (cc && typeof cc.line === "string" && ttl > 0 && (Date.now() - cc.ts) < ttl) cachedLine = cc.line;
|
|
396
|
-
} catch(e){ rufloStatuslineDebug("qe-cache-read", e); }
|
|
397
|
-
if (cachedLine !== null) {
|
|
398
|
-
qe = cachedLine; // hit: zero sqlite3 spawns
|
|
399
|
-
} else {
|
|
400
|
-
// miss: ONE sqlite3 call. SQL on stdin + ".bail off" so a missing vector
|
|
401
|
-
// table (name varies by aqe version) doesn't abort the batch. sqlite3 still
|
|
402
|
-
// exits non-zero on the error, so execFileSync throws — recover e.stdout.
|
|
403
|
-
var sql = ".bail off\n"
|
|
404
|
-
+ "SELECT 'pat',COUNT(*) FROM qe_patterns;\n"
|
|
405
|
-
+ "SELECT 'vec',COUNT(*) FROM qe_pattern_embeddings;\n"
|
|
406
|
-
+ "SELECT 'vec',COUNT(*) FROM vectors;\n"
|
|
407
|
-
+ "SELECT 'vec',COUNT(*) FROM embeddings;\n"
|
|
408
|
-
+ "SELECT 'traj',COUNT(*) FROM qe_trajectories;\n";
|
|
409
|
-
var raw = "";
|
|
410
|
-
try { raw = cp.execFileSync("sqlite3", [db], {input: sql, stdio:["pipe","pipe","ignore"], timeout:1500}).toString(); }
|
|
411
|
-
catch(e){ rufloStatuslineDebug("qe-sqlite-query", e); raw = (e && e.stdout) ? e.stdout.toString() : ""; }
|
|
412
|
-
var pat = 0, qtj = 0, qv = 0;
|
|
413
|
-
raw.split("\n").forEach(function(ln){
|
|
414
|
-
var i = ln.indexOf("|"); if (i < 0) return;
|
|
415
|
-
var k = ln.slice(0, i), v = Number(ln.slice(i + 1)) || 0;
|
|
416
|
-
if (k === "pat") pat = v; else if (k === "traj") qtj = v; else if (k === "vec" && qv === 0) qv = v;
|
|
417
|
-
});
|
|
418
|
-
var qp = [];
|
|
419
|
-
if (pat > 0) qp.push("🎓 " + pat + " patterns");
|
|
420
|
-
if (qtj > 0) qp.push("🧭 " + qtj + " traj");
|
|
421
|
-
if (qv > 0) qp.push("🧬 " + qv + " vec" + G + "⚡" + R);
|
|
422
|
-
try { var kb = Math.round(fs.statSync(db).size / 1024); qp.push("💾 " + (kb >= 1024 ? (kb/1024).toFixed(1) + "MB" : kb + "KB")); } catch(e){ rufloStatuslineDebug("qe-db-stat", e); }
|
|
423
|
-
// Installed agentic-qe version — shown next to the label, mirroring "RuFlo V<x>"
|
|
424
|
-
// in ruflo's native header. Prefer the global install (matches the aidefence
|
|
425
|
-
// probe above); fall back to a project-local node_modules copy.
|
|
426
|
-
var qver = "";
|
|
427
|
-
try {
|
|
428
|
-
var qpkg = path.join(path.dirname(process.execPath), "..", "lib", "node_modules", "agentic-qe", "package.json");
|
|
429
|
-
if (!fs.existsSync(qpkg)) qpkg = path.join(cwd, "node_modules", "agentic-qe", "package.json");
|
|
430
|
-
var qv2 = JSON.parse(fs.readFileSync(qpkg, "utf8")).version;
|
|
431
|
-
if (qv2) qver = " V" + qv2;
|
|
432
|
-
} catch(e){ rufloStatuslineDebug("qe-version", e); }
|
|
433
|
-
qe = Y + "🎓 Agentic QE" + qver + R + " " + (qp.length ? qp.join(DIM + " · " + R) : "on");
|
|
434
|
-
try { fs.mkdirSync(cacheDir, {recursive:true}); fs.writeFileSync(cacheFile, JSON.stringify({ts: Date.now(), line: qe})); } catch(e){ rufloStatuslineDebug("qe-cache-write", e); }
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
} catch(e){ rufloStatuslineDebug("qe-segment", e); }
|
|
438
|
-
// ── assemble: one ruflo feature per line (SONA, 📈 RL, ◷ proof FAIL alarm,
|
|
439
|
-
// ⚠ aidefence OFF alarm), then a divider, then the agentic-qe line. The two alarms
|
|
440
|
-
// are silent in the healthy case, so a well-configured machine shows only the live
|
|
441
|
-
// metrics. Each segment renders on its
|
|
442
|
-
// OWN line so the live route metrics and the security state are individually scannable
|
|
443
|
-
// and don't wrap. No rule above the SONA line — these are ruflo features and sit flush
|
|
444
|
-
// under ruflo's native lines. The divider matches ruflo's native header width
|
|
445
|
-
// ('─'.repeat(53) in statusline.cjs) so the two rules line up.
|
|
446
|
-
var out = [];
|
|
447
|
-
if (learn) out.push(learn);
|
|
448
|
-
if (route) out.push(route);
|
|
449
|
-
if (proof) out.push(proof);
|
|
450
|
-
if (sec) out.push(sec);
|
|
451
|
-
if (daemon) out.push(daemon);
|
|
452
|
-
if (brain) out.push(brain);
|
|
453
|
-
if (out.length && qe) out.push(DIM + "─".repeat(53) + R);
|
|
454
|
-
if (qe) out.push(qe);
|
|
455
|
-
if (!out.length) return "";
|
|
456
|
-
return "\n" + out.join("\n");
|
|
457
|
-
} catch(e){ rufloStatuslineDebug("renderer", e); return ""; }
|
|
458
|
-
}
|
|
459
|
-
// ── AI-defense probe (companion to the alarm-only segment above) ─────────────
|
|
460
|
-
// Locates the global ruflo install WITHOUT spawning npm (this runs on every render).
|
|
461
|
-
// Returns "" when no candidate resolves — the caller must treat that as "unknown",
|
|
462
|
-
// never as "off".
|
|
463
|
-
function rufloFindRufloRoot(){
|
|
464
|
-
try {
|
|
465
|
-
var fs = require("fs"), path = require("path"), os = require("os");
|
|
466
|
-
var binDir = path.dirname(process.execPath);
|
|
467
|
-
var cands = [
|
|
468
|
-
path.join(binDir, "..", "lib", "node_modules", "ruflo"), // nvm / mise layout
|
|
469
|
-
path.join(binDir, "node_modules", "ruflo"), // Windows layout
|
|
470
|
-
];
|
|
471
|
-
// A custom npm prefix (~/.npm-global, npm_config_prefix) is decoupled from the node
|
|
472
|
-
// binary, so the execPath-derived probes above all miss it — same gap as upstream #2221.
|
|
473
|
-
var prefixes = [process.env.npm_config_prefix, process.env.PREFIX, path.join(os.homedir(), ".npm-global")];
|
|
474
|
-
for (var pi = 0; pi < prefixes.length; pi++) {
|
|
475
|
-
if (prefixes[pi]) cands.push(path.join(prefixes[pi], "lib", "node_modules", "ruflo"));
|
|
476
|
-
}
|
|
477
|
-
for (var ci = 0; ci < cands.length; ci++) {
|
|
478
|
-
if (fs.existsSync(path.join(cands[ci], "package.json"))) return cands[ci];
|
|
479
|
-
}
|
|
480
|
-
return "";
|
|
481
|
-
} catch(e){ rufloStatuslineDebug("ruflo-root-probe", e); return ""; }
|
|
482
|
-
}
|
|
483
|
-
// ── real CLI bins (companion to the ruflo-bin wrapper) ──────────────────────
|
|
484
|
-
// Upstream's resolveCliBinCandidates looks for `ruflo/bin/cli.js`, but the ruflo
|
|
485
|
-
// package ships `bin/ruflo.js` (package.json bin: {"ruflo": "bin/ruflo.js"}) —
|
|
486
|
-
// a filename that never exists. @claude-flow/cli DOES ship bin/cli.js, but it is
|
|
487
|
-
// ruflo's nested dependency, not a global top-level install, so that candidate
|
|
488
|
-
// misses too. Every candidate therefore fails and the statusline silently falls
|
|
489
|
-
// through to `npx --prefer-offline @claude-flow/cli`, which serves whatever stale
|
|
490
|
-
// version happens to sit in the npx cache — that is how a machine running a fixed
|
|
491
|
-
// ruflo 3.32.2 still rendered the FABRICATED "⚠ 1 CVE" from a cached 3.28.0.
|
|
492
|
-
// Returns only paths that exist; [] means "nothing found", never a guess.
|
|
493
|
-
function rufloRealCliBins(cwd){
|
|
494
|
-
try {
|
|
495
|
-
var fs = require("fs"), path = require("path");
|
|
496
|
-
var roots = [], out = [];
|
|
497
|
-
var g = rufloFindRufloRoot();
|
|
498
|
-
if (g) roots.push(g);
|
|
499
|
-
if (cwd) roots.push(path.join(cwd, "node_modules", "ruflo"));
|
|
500
|
-
for (var i = 0; i < roots.length; i++) {
|
|
501
|
-
out.push(path.join(roots[i], "bin", "ruflo.js"));
|
|
502
|
-
out.push(path.join(roots[i], "node_modules", "@claude-flow", "cli", "bin", "cli.js"));
|
|
503
|
-
}
|
|
504
|
-
return out.filter(function(p){ try { return fs.existsSync(p); } catch(e){ rufloStatuslineDebug("ruflo-bin-entry", e); return false; } });
|
|
505
|
-
} catch(e){ rufloStatuslineDebug("ruflo-bin-probe", e); return []; }
|
|
506
|
-
}
|
|
507
|
-
// Three states, not two — the distinction IS the fail-safe. "off" is asserted only on
|
|
508
|
-
// positive evidence: a real ruflo install that does not contain aidefence. Anything we
|
|
509
|
-
// cannot verify is "unknown" and stays silent, because a false "your injection defense
|
|
510
|
-
// is off" would be exactly the fabricated-alarm bug this footer exists to correct.
|
|
511
|
-
// @claude-flow/security is auth/validation primitives, not detection — probing it
|
|
512
|
-
// instead would overstate, so only aidefence counts.
|
|
513
|
-
function rufloAidefenceState(rufloRoot){
|
|
514
|
-
try {
|
|
515
|
-
var fs = require("fs"), path = require("path");
|
|
516
|
-
if (!rufloRoot || !fs.existsSync(path.join(rufloRoot, "package.json"))) return "unknown";
|
|
517
|
-
var ad = path.join(rufloRoot, "node_modules", "@claude-flow", "aidefence", "package.json");
|
|
518
|
-
return fs.existsSync(ad) ? "on" : "off";
|
|
519
|
-
} catch(e){ rufloStatuslineDebug("aidefence-probe", e); return "unknown"; }
|
|
520
|
-
}
|
|
521
|
-
// ── security overlay: replaces ruflo's FABRICATED CVE counter with the real scan ──
|
|
522
|
-
// Upstream (@claude-flow/cli dist/src/funnel/local-signals.js, getSecurityStatus) does:
|
|
523
|
-
// let cvesFixed = 0; const totalCves = 3;
|
|
524
|
-
// cvesFixed = Math.min(totalCves, scans.length); // counts FILES, not findings
|
|
525
|
-
// Two independent defects. (1) `totalCves = 3` is a hardcoded constant referring to
|
|
526
|
-
// ruflo's OWN v3 remediation roadmap — CVE-1/2/3 in .claude/agents/v3/v3-security-architect.md
|
|
527
|
-
// are an outdated @anthropic-ai/claude-code dep + SHA-256 hashing + hardcoded creds in
|
|
528
|
-
// THEIR api/auth-service.ts. They are not public CVE IDs and have nothing to do with the
|
|
529
|
-
// project being rendered, so every clean repo is told it has 3 CVEs. (2) `cvesFixed`
|
|
530
|
-
// counts .json files in .claude/security-scans/, so running the very scan the warning
|
|
531
|
-
// tells you to run "fixes" a CVE by writing a file. The counter converges to CLEAN
|
|
532
|
-
// without anything being scanned, let alone fixed. Upstream: ruvnet/ruflo#2694.
|
|
533
|
-
//
|
|
534
|
-
// This overlay reports what the newest scan ACTUALLY found, and never invents a CVE:
|
|
535
|
-
// totalCves/cvesFixed are pinned to 0 so the "⚠ N CVEs" branch can never fire again;
|
|
536
|
-
// real state is carried in `status`, which ruflo's own renderer prints verbatim.
|
|
537
|
-
// no scan yet → PENDING → "🛡 scan pending" (honest unknown, not green)
|
|
538
|
-
// findings > 0 → "N ISSUES" → red "🛡 n issues" (real count from the scan)
|
|
539
|
-
// clean + fresh → CLEAN → "🛡 ✓"
|
|
540
|
-
// clean + stale >7d → STALE → "🛡 scan stale"
|
|
541
|
-
// Returns `upstream` untouched on any unexpected error — a wrong overlay would be worse
|
|
542
|
-
// than the bug, so the failure mode is "no worse than ruflo".
|
|
543
|
-
function rufloLocalSecurity(cwd, upstream){
|
|
544
|
-
try {
|
|
545
|
-
var fs = require("fs"), path = require("path");
|
|
546
|
-
var dir = path.join(cwd, ".claude", "security-scans");
|
|
547
|
-
var newest = null;
|
|
548
|
-
try {
|
|
549
|
-
fs.readdirSync(dir).forEach(function(f){
|
|
550
|
-
if (f.slice(-5) !== ".json") return;
|
|
551
|
-
try {
|
|
552
|
-
var j = JSON.parse(fs.readFileSync(path.join(dir, f), "utf8"));
|
|
553
|
-
// Prefer the scan's own timestamp; fall back to mtime so a hand-written or
|
|
554
|
-
// older-format scan file still orders correctly instead of sorting to epoch 0.
|
|
555
|
-
var t = Date.parse(j && j.timestamp);
|
|
556
|
-
if (!t) { try { t = fs.statSync(path.join(dir, f)).mtimeMs; } catch(e){ rufloStatuslineDebug("security-scan-stat", e); t = 0; } }
|
|
557
|
-
if (!newest || t > newest.t) newest = { t: t, j: j };
|
|
558
|
-
} catch(e){ rufloStatuslineDebug("security-scan-file", e); } // unreadable/!JSON scan file: ignore, never let it break the render
|
|
559
|
-
});
|
|
560
|
-
} catch(e){ rufloStatuslineDebug("security-scan-directory", e); } // no directory => never scanned
|
|
561
|
-
if (!newest) return { status: "PENDING", cvesFixed: 0, totalCves: 0 };
|
|
562
|
-
var s = newest.j.summary || {};
|
|
563
|
-
var n = typeof s.total === "number" ? s.total
|
|
564
|
-
: (Array.isArray(newest.j.findings) ? newest.j.findings.length : 0);
|
|
565
|
-
if (n > 0) return { status: n + " ISSUE" + (n === 1 ? "" : "S"), cvesFixed: 0, totalCves: 0 };
|
|
566
|
-
var staleMs = Number(process.env.RUFLO_SCAN_STALE_MS || 7 * 24 * 3600 * 1000);
|
|
567
|
-
if (staleMs > 0 && newest.t && (Date.now() - newest.t) > staleMs) {
|
|
568
|
-
return { status: "STALE", cvesFixed: 0, totalCves: 0 };
|
|
569
|
-
}
|
|
570
|
-
return { status: "CLEAN", cvesFixed: 0, totalCves: 0 };
|
|
571
|
-
} catch(e){ rufloStatuslineDebug("security-overlay", e); return upstream; }
|
|
572
|
-
}
|
|
573
|
-
// ── insight-row companion to rufloLocalSecurity ──────────────────────────────
|
|
574
|
-
// The fabricated count reaches the render through a SECOND, independent path: the
|
|
575
|
-
// CLI builds the line-3 insight itself (funnel/insights.js securityInsight →
|
|
576
|
-
// `pending = s.totalCves - s.cvesFixed`) and ships it as pre-rendered promo TEXT.
|
|
577
|
-
// Overlaying data.security cannot fix that — the sentence is already baked, so a
|
|
578
|
-
// repo with a clean scan still gets "⚠ 1 CVE pending". This rebuilds that one
|
|
579
|
-
// sentence from the real scan, or drops it when there is nothing to say.
|
|
580
|
-
// Matched on TEXT, not id: promo.js reduces the insight to {text, kind} and throws
|
|
581
|
-
// the id away, so `insight-cves-pending` is not observable by the time we see it.
|
|
582
|
-
// Only ever touches a CVE-worded insight — every other insight/tip/promo passes
|
|
583
|
-
// through untouched, so the funnel rotation is preserved.
|
|
584
|
-
function rufloHonestInsight(promo, sec){
|
|
585
|
-
try {
|
|
586
|
-
if (!promo || promo.kind !== "insight" || typeof promo.text !== "string") return promo;
|
|
587
|
-
if (!/\bCVEs?\b/.test(promo.text)) return promo; // a different insight — not ours to touch
|
|
588
|
-
if (!sec) return null;
|
|
589
|
-
if (sec.status === "PENDING") return { text: "🛡 Security scan pending — Run ruflo security scan --depth full", kind: "insight" };
|
|
590
|
-
if (sec.status === "STALE") return { text: "🛡 Security scan stale — Run ruflo security scan --depth full", kind: "insight" };
|
|
591
|
-
var m = /^(\d+) ISSUE/.exec(sec.status || "");
|
|
592
|
-
if (m) {
|
|
593
|
-
var n = Number(m[1]);
|
|
594
|
-
return { text: "⚠ " + n + " security issue" + (n === 1 ? "" : "s") + " found — see .claude/security-scans", kind: "insight" };
|
|
595
|
-
}
|
|
596
|
-
return null; // CLEAN: say nothing. The slot falls blank rather than nagging about a lie.
|
|
597
|
-
} catch(e){ rufloStatuslineDebug("security-insight", e); return promo; }
|
|
598
|
-
}
|
|
599
|
-
/* ruflo-seg:END */
|
|
600
|
-
/* ruflo-bin:BEGIN */
|
|
601
|
-
try {
|
|
602
|
-
if (typeof resolveCliBinCandidates === "function") {
|
|
603
|
-
var _rufloOrigResolveCliBins = resolveCliBinCandidates;
|
|
604
|
-
resolveCliBinCandidates = function(){
|
|
605
|
-
var orig = [];
|
|
606
|
-
try { orig = _rufloOrigResolveCliBins.apply(this, arguments) || []; } catch(e){}
|
|
607
|
-
try {
|
|
608
|
-
var cwd = process.cwd();
|
|
609
|
-
try { if (typeof CWD === "string" && CWD) cwd = CWD; } catch(e){}
|
|
610
|
-
var real = (typeof rufloRealCliBins === "function") ? rufloRealCliBins(cwd) : [];
|
|
611
|
-
return real.concat(orig.filter(function(p){ return real.indexOf(p) === -1; }));
|
|
612
|
-
} catch(e){ return orig; }
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
} catch(e){}
|
|
616
|
-
/* ruflo-bin:END */
|
|
617
2
|
/**
|
|
618
3
|
* RuFlo V3 Statusline — delegation build (#2195)
|
|
619
4
|
*
|
|
@@ -1171,6 +556,68 @@ function getLocalSecurity(cliSecurity) {
|
|
|
1171
556
|
return base;
|
|
1172
557
|
}
|
|
1173
558
|
|
|
559
|
+
// Cached pattern count. The store is routinely >10MB (14.5MB / 1277 patterns on
|
|
560
|
+
// the machine this was diagnosed on, costing 53ms to read+parse), and the
|
|
561
|
+
// statusline re-renders on every prompt, so the parse is keyed on the file's
|
|
562
|
+
// mtime+size and reused until the store actually changes.
|
|
563
|
+
const PATTERN_COUNT_CACHE = path.join(os.tmpdir(), 'ruflo-statusline-patterns-' + require('crypto').createHash('md5').update(CWD).digest('hex').slice(0, 8) + '.json');
|
|
564
|
+
|
|
565
|
+
function countPatternsCached(file) {
|
|
566
|
+
let stat;
|
|
567
|
+
try { stat = fs.statSync(file); } catch { return 0; }
|
|
568
|
+
const key = stat.mtimeMs + ':' + stat.size;
|
|
569
|
+
|
|
570
|
+
try {
|
|
571
|
+
const memo = JSON.parse(fs.readFileSync(PATTERN_COUNT_CACHE, 'utf-8'));
|
|
572
|
+
if (memo && memo[file] && memo[file].key === key) return memo[file].count;
|
|
573
|
+
} catch { /* no memo yet, or unreadable — fall through and recount */ }
|
|
574
|
+
|
|
575
|
+
let count = 0;
|
|
576
|
+
try {
|
|
577
|
+
const raw = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
578
|
+
if (Array.isArray(raw)) count = raw.length;
|
|
579
|
+
else if (raw && Array.isArray(raw.patterns)) count = raw.patterns.length;
|
|
580
|
+
else if (raw && typeof raw === 'object') count = Object.keys(raw).length;
|
|
581
|
+
} catch { return 0; }
|
|
582
|
+
|
|
583
|
+
try {
|
|
584
|
+
let memo = {};
|
|
585
|
+
try { memo = JSON.parse(fs.readFileSync(PATTERN_COUNT_CACHE, 'utf-8')) || {}; } catch { /* start fresh */ }
|
|
586
|
+
memo[file] = { key, count };
|
|
587
|
+
fs.writeFileSync(PATTERN_COUNT_CACHE, JSON.stringify(memo));
|
|
588
|
+
} catch { /* cache is an optimisation, never a requirement */ }
|
|
589
|
+
|
|
590
|
+
return count;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// `system` is nominally CLI-populated, but the pattern store is on disk, so a
|
|
594
|
+
// dead CLI must not render as "no learning". Without this, every candidate in
|
|
595
|
+
// resolveCliBinCandidates() failing (a source-only marketplace checkout, or an
|
|
596
|
+
// npx fetch that dies in a workspace root) silently degraded the brain to a
|
|
597
|
+
// hardcoded 0% while the overlaid segments beside it kept showing live data —
|
|
598
|
+
// indistinguishable from a genuine zero. Same reasoning as getLocalAgentDB(),
|
|
599
|
+
// which had to start reading locally after the statusline reported "Vectors 0"
|
|
600
|
+
// on a database holding thousands.
|
|
601
|
+
function getLocalIntelligence(current) {
|
|
602
|
+
const base = (current && typeof current === 'object') ? current : {};
|
|
603
|
+
if (typeof base.intelligencePct === 'number' && base.intelligencePct > 0) return base;
|
|
604
|
+
|
|
605
|
+
for (const file of [
|
|
606
|
+
path.join(CWD, '.claude-flow', 'neural', 'patterns.json'),
|
|
607
|
+
path.join(os.homedir(), '.claude-flow', 'neural', 'patterns.json'),
|
|
608
|
+
]) {
|
|
609
|
+
const n = countPatternsCached(file);
|
|
610
|
+
if (n > 0) {
|
|
611
|
+
base.intelligencePct = Math.min(100, Math.floor(n / 10));
|
|
612
|
+
return base;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// No CLI value and no local store: unknown, which is not the same as zero.
|
|
617
|
+
base.intelligencePct = null;
|
|
618
|
+
return base;
|
|
619
|
+
}
|
|
620
|
+
|
|
1174
621
|
// Overlay every locally-derived block onto the CLI data (mutates in place).
|
|
1175
622
|
function applyLocalOverlays(data) {
|
|
1176
623
|
data.adrs = getLocalADRCount();
|
|
@@ -1181,6 +628,7 @@ function applyLocalOverlays(data) {
|
|
|
1181
628
|
// Security overlay: recompute freshness from disk on every render so cached
|
|
1182
629
|
// CLI JSON can never freeze the pill at PENDING. See getLocalSecurity() above.
|
|
1183
630
|
data.security = getLocalSecurity(data.security);
|
|
631
|
+
data.system = getLocalIntelligence(data.system);
|
|
1184
632
|
return data;
|
|
1185
633
|
}
|
|
1186
634
|
|
|
@@ -1194,7 +642,7 @@ function buildLocalFallback() {
|
|
|
1194
642
|
v3Progress: { domainsCompleted: 0, totalDomains: 5, dddProgress: 0, patternsLearned: 0, sessionsCompleted: 0 },
|
|
1195
643
|
security: { status: 'NONE', findings: 0, cvesFixed: 0, totalCves: 0 },
|
|
1196
644
|
swarm: { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false },
|
|
1197
|
-
system: { memoryMB: memMB, contextPct: 0, intelligencePct:
|
|
645
|
+
system: { memoryMB: memMB, contextPct: 0, intelligencePct: null, subAgents: 0 },
|
|
1198
646
|
lastUpdated: new Date().toISOString(),
|
|
1199
647
|
});
|
|
1200
648
|
}
|
|
@@ -1451,7 +899,7 @@ function getPkgVersion() {
|
|
|
1451
899
|
// version (see generateStatuslineScript()'s doc comment) — correct even
|
|
1452
900
|
// when this renders via a pure npx invocation with no local install for
|
|
1453
901
|
// the candidate scan below to find.
|
|
1454
|
-
let ver = "3.
|
|
902
|
+
let ver = "3.32.8";
|
|
1455
903
|
try {
|
|
1456
904
|
const home = os.homedir();
|
|
1457
905
|
const pkgPaths = [
|
|
@@ -1556,7 +1004,11 @@ function generateStatusline() {
|
|
|
1556
1004
|
const activeAgents = swarm.activeAgents || 0;
|
|
1557
1005
|
const maxAgents = swarm.maxAgents || CONFIG.maxAgents;
|
|
1558
1006
|
const coordinationActive = swarm.coordinationActive || false;
|
|
1559
|
-
|
|
1007
|
+
// null/undefined means "no source answered", which must not collapse to 0 --
|
|
1008
|
+
// that is exactly the ambiguity this segment used to present.
|
|
1009
|
+
const intelligencePct = (typeof system.intelligencePct === 'number')
|
|
1010
|
+
? system.intelligencePct
|
|
1011
|
+
: null;
|
|
1560
1012
|
const memoryMB = system.memoryMB || 0;
|
|
1561
1013
|
const subAgents = system.subAgents || 0;
|
|
1562
1014
|
const findings = Math.max(0, security.findings || 0);
|
|
@@ -1612,14 +1064,14 @@ function generateStatusline() {
|
|
|
1612
1064
|
// do next; diagnostic detail moves to `ruflo status --verbose`.
|
|
1613
1065
|
const agentsColor = activeAgents > 0 ? c.brightGreen : c.dim;
|
|
1614
1066
|
const hooksColor = hooksEnabled > 0 ? c.brightGreen : c.dim;
|
|
1615
|
-
const intellColor = intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
|
|
1067
|
+
const intellColor = intelligencePct === null ? c.dim : intelligencePct >= 80 ? c.brightGreen : intelligencePct >= 40 ? c.brightYellow : c.dim;
|
|
1616
1068
|
const swarmInd = coordinationActive ? c.brightGreen + '◉' + c.reset + ' ' : c.dim + '○' + c.reset + ' ';
|
|
1617
1069
|
const healthAllGreen = (secStatus === 'CLEAN' || secStatus === 'NONE') && findings === 0;
|
|
1618
1070
|
const opsParts = [];
|
|
1619
1071
|
opsParts.push(c.cyan + 'Swarm ' + swarmInd + agentsColor + activeAgents + c.reset + '/' + c.brightWhite + maxAgents + c.reset);
|
|
1620
1072
|
if (subAgents > 0) opsParts.push(c.brightPurple + '👥 ' + subAgents + c.reset);
|
|
1621
1073
|
opsParts.push(c.cyan + 'Hooks ' + hooksColor + hooksEnabled + c.reset + '/' + c.brightWhite + hooksTotal + c.reset);
|
|
1622
|
-
opsParts.push(intellColor + '🧠 ' + intelligencePct + '%' + c.reset);
|
|
1074
|
+
opsParts.push(intellColor + '🧠 ' + (intelligencePct === null ? '—' : intelligencePct + '%') + c.reset);
|
|
1623
1075
|
opsParts.push(c.brightCyan + '💾 ' + memoryMB + 'MB' + c.reset);
|
|
1624
1076
|
// Health: one glyph when green, terse copy when there's something to act on.
|
|
1625
1077
|
if (healthAllGreen) {
|
|
@@ -1834,5 +1286,5 @@ if (process.argv.includes('--json')) {
|
|
|
1834
1286
|
} else if (process.argv.includes('--compact')) {
|
|
1835
1287
|
console.log(JSON.stringify(generateJSON()));
|
|
1836
1288
|
} else {
|
|
1837
|
-
console.log(generateStatusline()
|
|
1289
|
+
console.log(generateStatusline());
|
|
1838
1290
|
}
|