agentic-qe 3.11.0 → 3.11.1
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/commands/agents/README.md +50 -0
- package/.claude/commands/agents/agent-capabilities.md +140 -0
- package/.claude/commands/agents/agent-coordination.md +28 -0
- package/.claude/commands/agents/agent-spawning.md +28 -0
- package/.claude/commands/agents/agent-types.md +216 -0
- package/.claude/commands/agents/health.md +139 -0
- package/.claude/commands/agents/list.md +100 -0
- package/.claude/commands/agents/logs.md +130 -0
- package/.claude/commands/agents/metrics.md +122 -0
- package/.claude/commands/agents/pool.md +127 -0
- package/.claude/commands/agents/spawn.md +140 -0
- package/.claude/commands/agents/status.md +115 -0
- package/.claude/commands/agents/stop.md +102 -0
- package/.claude/commands/claude-flow-help.md +1 -1
- package/.claude/commands/coordination/README.md +9 -0
- package/.claude/commands/coordination/agent-spawn.md +25 -0
- package/.claude/commands/coordination/init.md +44 -0
- package/.claude/commands/coordination/orchestrate.md +43 -0
- package/.claude/commands/coordination/spawn.md +45 -0
- package/.claude/commands/coordination/swarm-init.md +85 -0
- package/.claude/commands/coordination/task-orchestrate.md +25 -0
- package/.claude/commands/github/code-review-swarm.md +1 -1
- package/.claude/commands/github/issue-tracker.md +3 -3
- package/.claude/commands/github/release-manager.md +5 -3
- package/.claude/commands/github/release-swarm.md +1 -1
- package/.claude/commands/github/repo-architect.md +2 -2
- package/.claude/commands/github/swarm-issue.md +4 -1
- package/.claude/commands/github/swarm-pr.md +6 -3
- package/.claude/commands/github/sync-coordinator.md +3 -1
- package/.claude/commands/github/workflow-automation.md +2 -2
- package/.claude/commands/hive-mind/README.md +17 -0
- package/.claude/commands/hive-mind/hive-mind-consensus.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-init.md +18 -0
- package/.claude/commands/hive-mind/hive-mind-memory.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-metrics.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-resume.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-sessions.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-spawn.md +21 -0
- package/.claude/commands/hive-mind/hive-mind-status.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-stop.md +8 -0
- package/.claude/commands/hive-mind/hive-mind-wizard.md +8 -0
- package/.claude/commands/hive-mind/hive-mind.md +27 -0
- package/.claude/commands/memory/README.md +9 -0
- package/.claude/commands/memory/memory-persist.md +25 -0
- package/.claude/commands/memory/memory-search.md +25 -0
- package/.claude/commands/memory/memory-usage.md +25 -0
- package/.claude/commands/memory/neural.md +47 -0
- package/.claude/commands/swarm/README.md +15 -0
- package/.claude/commands/swarm/analysis.md +95 -0
- package/.claude/commands/swarm/development.md +96 -0
- package/.claude/commands/swarm/examples.md +168 -0
- package/.claude/commands/swarm/maintenance.md +102 -0
- package/.claude/commands/swarm/optimization.md +117 -0
- package/.claude/commands/swarm/research.md +136 -0
- package/.claude/commands/swarm/swarm-analysis.md +8 -0
- package/.claude/commands/swarm/swarm-background.md +8 -0
- package/.claude/commands/swarm/swarm-init.md +19 -0
- package/.claude/commands/swarm/swarm-modes.md +8 -0
- package/.claude/commands/swarm/swarm-monitor.md +8 -0
- package/.claude/commands/swarm/swarm-spawn.md +19 -0
- package/.claude/commands/swarm/swarm-status.md +8 -0
- package/.claude/commands/swarm/swarm-strategies.md +8 -0
- package/.claude/commands/swarm/swarm.md +87 -0
- package/.claude/commands/swarm/testing.md +131 -0
- package/.claude/commands/workflows/README.md +9 -0
- package/.claude/commands/workflows/development.md +78 -0
- package/.claude/commands/workflows/research.md +63 -0
- package/.claude/commands/workflows/workflow-create.md +25 -0
- package/.claude/commands/workflows/workflow-execute.md +25 -0
- package/.claude/commands/workflows/workflow-export.md +25 -0
- package/.claude/helpers/auto-commit.sh +1 -1
- package/.claude/helpers/auto-memory-hook.mjs +37 -4
- package/.claude/helpers/github-safe.js +90 -40
- package/.claude/helpers/github-setup.sh +30 -13
- package/.claude/helpers/hook-handler.cjs +68 -49
- package/.claude/helpers/intelligence.cjs +156 -27
- package/.claude/helpers/post-commit +1 -1
- package/.claude/helpers/pre-commit +1 -1
- package/.claude/helpers/quick-start.sh +4 -4
- package/.claude/helpers/router.js +70 -31
- package/.claude/helpers/ruflo-hook.cjs +59 -0
- package/.claude/helpers/session.js +28 -6
- package/.claude/helpers/setup-mcp.sh +3 -3
- package/.claude/helpers/statusline.cjs +584 -468
- package/.claude/helpers/statusline.js +47 -11
- package/.claude/skills/github-code-review/SKILL.md +2 -17
- package/.claude/skills/github-multi-repo/SKILL.md +4 -16
- package/.claude/skills/github-project-management/SKILL.md +18 -33
- package/.claude/skills/github-release-management/SKILL.md +4 -21
- package/.claude/skills/github-workflow-automation/SKILL.md +8 -26
- package/.claude/skills/pair-programming/SKILL.md +2 -2
- package/.claude/skills/reasoningbank-intelligence/SKILL.md +2 -2
- package/.claude/skills/skill-builder/SKILL.md +0 -103
- package/.claude/skills/skills-manifest.json +1 -1
- package/.claude/skills/sparc-methodology/SKILL.md +2 -11
- package/.claude/skills/stream-chain/SKILL.md +0 -3
- package/.claude/skills/swarm-advanced/SKILL.md +2 -5
- package/.claude/skills/swarm-orchestration/SKILL.md +1 -1
- package/.claude/skills/verification-quality/SKILL.md +121 -93
- package/CHANGELOG.md +49 -0
- package/assets/skills/pair-programming/SKILL.md +2 -2
- package/assets/skills/verification-quality/SKILL.md +121 -93
- package/dist/audit/witness-chain.d.ts +1 -1
- package/dist/audit/witness-findings.d.ts +50 -0
- package/dist/audit/witness-findings.js +41 -0
- package/dist/cli/bundle.js +5 -5
- package/dist/cli/chunks/adapter-A6GCBONS.js +2 -0
- package/dist/cli/chunks/{agent-booster-wasm-5CSKQB4O.js → agent-booster-wasm-3OJAT664.js} +2 -2
- package/dist/cli/chunks/{agent-handler-EBV3OKTE.js → agent-handler-6TCTI5AT.js} +2 -2
- package/dist/cli/chunks/{agent-memory-branch-RZ53YM2U.js → agent-memory-branch-FAWCYEGJ.js} +2 -2
- package/dist/cli/chunks/aqe-learning-engine-FRCSXNMG.js +2 -0
- package/dist/cli/chunks/{arena-UCP74DRO.js → arena-O2TCUQBF.js} +4 -4
- package/dist/cli/chunks/{arena-QWYTIQ6I.js → arena-UVYIGYUF.js} +2 -2
- package/dist/cli/chunks/{audit-M4FNIX47.js → audit-AYESKHAJ.js} +2 -2
- package/dist/cli/chunks/base-CZ3EHBU5.js +2 -0
- package/dist/cli/chunks/{hnswlib-node-HMZC5TXM.js → better-sqlite3-MJNUEPYB.js} +2 -2
- package/dist/cli/chunks/{brain-handler-OY6Q2GY5.js → brain-handler-KSJBVTHZ.js} +3 -3
- package/dist/cli/chunks/{branch-enumerator-TQWN4NIX.js → branch-enumerator-4O3S42EG.js} +2 -2
- package/dist/cli/chunks/{browser-2EH3RXJ2.js → browser-5VXK323P.js} +2 -2
- package/dist/cli/chunks/browser-workflow-EKTGQQBQ.js +2 -0
- package/dist/cli/chunks/{chunk-SQPDGRYR.js → chunk-22FHOXEE.js} +1 -1
- package/dist/cli/chunks/{chunk-ZEUUVLS2.js → chunk-2RE32VOF.js} +1 -1
- package/dist/cli/chunks/{chunk-ITRUZ3WE.js → chunk-3D4HNUZM.js} +2 -2
- package/dist/cli/chunks/{chunk-6VQKNPGY.js → chunk-3DS7ZHA7.js} +2 -2
- package/dist/cli/chunks/{chunk-Z45QDDZQ.js → chunk-3G25ZBQ6.js} +1 -1
- package/dist/cli/chunks/{chunk-ETGEGMYS.js → chunk-3IMEDZIS.js} +3 -3
- package/dist/cli/chunks/{chunk-BEOGI5FC.js → chunk-3V5DAM37.js} +2 -2
- package/dist/cli/chunks/{chunk-UFMW25MS.js → chunk-3XCEFSUK.js} +2 -2
- package/dist/cli/chunks/{chunk-QYXTESM3.js → chunk-437XL5VZ.js} +2 -2
- package/dist/cli/chunks/{chunk-XVQUVCFR.js → chunk-44HXRFOP.js} +2 -2
- package/dist/cli/chunks/{chunk-VGYUVMSN.js → chunk-4565IIF6.js} +2 -2
- package/dist/cli/chunks/{chunk-IFTEM672.js → chunk-4BMPFEEG.js} +2 -2
- package/dist/cli/chunks/{chunk-MKLLB4PM.js → chunk-4G4GTF36.js} +4 -4
- package/dist/cli/chunks/{chunk-R7FHQQAV.js → chunk-4OYC5TIZ.js} +2 -2
- package/dist/cli/chunks/{chunk-LFT7WYHW.js → chunk-4RUS5E3Q.js} +2 -2
- package/dist/cli/chunks/{chunk-IKNDGXZZ.js → chunk-4S3UIY3G.js} +2 -2
- package/dist/cli/chunks/{chunk-JQM64WJ2.js → chunk-4UHWZ47M.js} +1 -1
- package/dist/cli/chunks/{chunk-NBTKI2TX.js → chunk-56PICCZN.js} +2 -2
- package/dist/cli/chunks/chunk-57WGS6BI.js +2 -0
- package/dist/cli/chunks/{chunk-MDYI4IIW.js → chunk-5LDUW2FD.js} +1 -1
- package/dist/cli/chunks/{chunk-RPYYS6BX.js → chunk-5PSIKJL5.js} +2 -2
- package/dist/cli/chunks/{chunk-Y7UJC5OL.js → chunk-5QFZEEJ2.js} +3 -3
- package/dist/cli/chunks/{chunk-HNSZDIQU.js → chunk-5Y7GXQOM.js} +2 -2
- package/dist/cli/chunks/{chunk-DV7662EZ.js → chunk-6CH7476R.js} +1 -1
- package/dist/cli/chunks/{chunk-N52ZBTPM.js → chunk-6WNYBIPS.js} +2 -2
- package/dist/cli/chunks/{chunk-WBQEOACC.js → chunk-6YNXH6H4.js} +2 -2
- package/dist/cli/chunks/{chunk-SLWJNHCR.js → chunk-6ZAUNPAI.js} +2 -2
- package/dist/cli/chunks/{chunk-4OTA6KYJ.js → chunk-72UPBNVF.js} +2 -2
- package/dist/cli/chunks/{chunk-KOOY72E3.js → chunk-76UVJLPM.js} +2 -2
- package/dist/cli/chunks/{chunk-YR44KQUK.js → chunk-7DQLYWLR.js} +1 -1
- package/dist/cli/chunks/{chunk-I2HQLBWG.js → chunk-7GP7ZG3K.js} +2 -2
- package/dist/cli/chunks/{chunk-GGSXHGWD.js → chunk-7OAKIXNM.js} +2 -2
- package/dist/cli/chunks/{chunk-3GWSHRDA.js → chunk-7QICU44H.js} +2 -2
- package/dist/cli/chunks/{chunk-ACV2WVMX.js → chunk-7SRSOZMP.js} +1 -1
- package/dist/cli/chunks/{chunk-X2L4POJE.js → chunk-7WQKKYYG.js} +1 -1
- package/dist/cli/chunks/{chunk-ZFP3O5FM.js → chunk-AEZMNFXM.js} +1 -1
- package/dist/cli/chunks/{chunk-2TUVBEWK.js → chunk-AG4BYKUV.js} +2 -2
- package/dist/cli/chunks/{chunk-FTOICJQG.js → chunk-AL54LED5.js} +2 -2
- package/dist/cli/chunks/{chunk-IQSPL2H4.js → chunk-ATQTTGSE.js} +2 -2
- package/dist/cli/chunks/{chunk-3J6LYF6I.js → chunk-B5EE63VE.js} +2 -2
- package/dist/cli/chunks/{chunk-JN3IQB4L.js → chunk-B6U56VWG.js} +1 -1
- package/dist/cli/chunks/{chunk-3LP5GPGU.js → chunk-BOQNPFO5.js} +1 -1
- package/dist/cli/chunks/{chunk-G25YZ7Z6.js → chunk-BR4ERWVD.js} +2 -2
- package/dist/cli/chunks/{chunk-PJ4HSXH3.js → chunk-BVFNF3RW.js} +1 -1
- package/dist/cli/chunks/{chunk-KZE5UR4T.js → chunk-BXLWERBR.js} +3 -3
- package/dist/cli/chunks/{chunk-7MBF3S25.js → chunk-C27UV6DO.js} +1 -1
- package/dist/cli/chunks/{chunk-453UDYD2.js → chunk-C7FYDE5F.js} +161 -154
- package/dist/cli/chunks/{chunk-HMSPPGUF.js → chunk-CIDTFU3C.js} +2 -2
- package/dist/cli/chunks/{chunk-HHSEIPSQ.js → chunk-CII57TME.js} +1 -1
- package/dist/cli/chunks/{chunk-DCJIXDO6.js → chunk-CN2HMHIY.js} +2 -2
- package/dist/cli/chunks/{chunk-5ASPEVVF.js → chunk-CXIFCN6G.js} +1 -1
- package/dist/cli/chunks/{chunk-GBFAQ4DW.js → chunk-CZU5G6J4.js} +1 -1
- package/dist/cli/chunks/{chunk-JQSA6EMI.js → chunk-D4DAZ3P2.js} +2 -2
- package/dist/cli/chunks/{chunk-73EWPVBJ.js → chunk-D6MPGK7R.js} +2 -2
- package/dist/cli/chunks/{chunk-CERSTEAJ.js → chunk-DZT4A7R3.js} +2 -2
- package/dist/cli/chunks/{chunk-UEH6C5JA.js → chunk-EFRIMR74.js} +1 -1
- package/dist/cli/chunks/{chunk-PC3VIR2A.js → chunk-EJSDQQZH.js} +2 -2
- package/dist/cli/chunks/{chunk-XMZ2DHUL.js → chunk-EQYDPF52.js} +1 -1
- package/dist/cli/chunks/{chunk-QCJ7YOVN.js → chunk-EZBXCEBV.js} +2 -2
- package/dist/cli/chunks/{chunk-FGOVDO3R.js → chunk-FBOPSWF6.js} +2 -2
- package/dist/cli/chunks/{chunk-TGLEREP5.js → chunk-FK3XYV3A.js} +2 -2
- package/dist/cli/chunks/{chunk-RKDNLPZM.js → chunk-FOD6JEEU.js} +2 -2
- package/dist/cli/chunks/{chunk-ETZ62NFD.js → chunk-GUSW3OGX.js} +1 -1
- package/dist/cli/chunks/{chunk-VVJXQ4FR.js → chunk-H4V6WCF7.js} +2 -2
- package/dist/cli/chunks/{chunk-IOQYSR5S.js → chunk-H5GCRC2D.js} +2 -2
- package/dist/cli/chunks/{chunk-ISVBO4XO.js → chunk-HMVL55QX.js} +2 -2
- package/dist/cli/chunks/{chunk-2BBKA5J4.js → chunk-HOFEAA4R.js} +1 -1
- package/dist/cli/chunks/{chunk-OZQIDDXB.js → chunk-HYT5EMES.js} +2 -2
- package/dist/cli/chunks/{chunk-KBVXKFDI.js → chunk-IAHJ62JS.js} +4 -4
- package/dist/cli/chunks/{chunk-AYOTODUV.js → chunk-IIX5Y7BO.js} +1 -1
- package/dist/cli/chunks/{chunk-YSTWLDVD.js → chunk-ILZHECWZ.js} +3 -3
- package/dist/cli/chunks/{chunk-T6KT63NC.js → chunk-IUVAWWQG.js} +2 -2
- package/dist/cli/chunks/{chunk-ZK56THZT.js → chunk-IVZVVZZ3.js} +3 -3
- package/dist/cli/chunks/{chunk-FMULOSBL.js → chunk-J2LAYCYZ.js} +1 -1
- package/dist/cli/chunks/{chunk-7Q6CMSMD.js → chunk-JGHEGMLD.js} +3 -3
- package/dist/cli/chunks/{chunk-72QNONO6.js → chunk-K3BBLIWW.js} +2 -2
- package/dist/cli/chunks/{chunk-XSG4XKGO.js → chunk-K7XPKGOL.js} +2 -2
- package/dist/cli/chunks/{chunk-YRP73HO4.js → chunk-KIBP3LGY.js} +1 -1
- package/dist/cli/chunks/{chunk-SHW43QQV.js → chunk-KRUKMGPF.js} +2 -2
- package/dist/cli/chunks/{chunk-WP6XUSVW.js → chunk-L2QHZFC3.js} +1 -1
- package/dist/cli/chunks/{chunk-AVKGDS6F.js → chunk-LNV76GGB.js} +2 -2
- package/dist/cli/chunks/{chunk-IHNBZ5XG.js → chunk-LOPM3YIO.js} +2 -2
- package/dist/cli/chunks/{chunk-JNX7IRSI.js → chunk-LSZLXLZA.js} +2 -2
- package/dist/cli/chunks/{chunk-NI7O3GKZ.js → chunk-MILWEZSZ.js} +3 -3
- package/dist/cli/chunks/{chunk-7PTA7AVW.js → chunk-MX6M2VPB.js} +1 -1
- package/dist/cli/chunks/{chunk-YQIMO7VJ.js → chunk-N4OWZLH5.js} +2 -2
- package/dist/cli/chunks/{chunk-7BD7DZCB.js → chunk-N52WQO3G.js} +2 -2
- package/dist/cli/chunks/{chunk-Y7TBCHW4.js → chunk-N6NSZG7Z.js} +2 -2
- package/dist/cli/chunks/{chunk-C33BMWYZ.js → chunk-N6RSJGTW.js} +5 -5
- package/dist/cli/chunks/{chunk-G5VE3HQW.js → chunk-NKCL6RAF.js} +2 -2
- package/dist/cli/chunks/{chunk-LTH6XARD.js → chunk-NVJIOCS5.js} +2 -2
- package/dist/cli/chunks/{chunk-P3NV6KN3.js → chunk-NYWK7ZSX.js} +1 -1
- package/dist/cli/chunks/{chunk-5DG6H553.js → chunk-O5NF6BBD.js} +1 -1
- package/dist/cli/chunks/{chunk-J425SQFE.js → chunk-O75SVMMB.js} +2 -2
- package/dist/cli/chunks/{chunk-XKRG2U3V.js → chunk-OHBZON7T.js} +1 -1
- package/dist/cli/chunks/{chunk-NQD4CMXC.js → chunk-OUBYADPD.js} +2 -2
- package/dist/cli/chunks/{chunk-7E5NYLJT.js → chunk-OUSD2RWO.js} +2 -2
- package/dist/cli/chunks/{chunk-VHON5NDM.js → chunk-OX2PGDUM.js} +3 -3
- package/dist/cli/chunks/{chunk-PUTRXS5I.js → chunk-P7CMWL7Y.js} +2 -2
- package/dist/cli/chunks/{chunk-R3YO3Z7I.js → chunk-PY4YQDBM.js} +4 -4
- package/dist/cli/chunks/{chunk-BA4WZIAQ.js → chunk-QEDS3MOJ.js} +2 -2
- package/dist/cli/chunks/{chunk-X2TUDGFL.js → chunk-QMN563LV.js} +10 -10
- package/dist/cli/chunks/{chunk-SKL225P5.js → chunk-QOR4YAZY.js} +2 -2
- package/dist/cli/chunks/{chunk-F6Y7DTHR.js → chunk-QUTKELAS.js} +2 -2
- package/dist/cli/chunks/{chunk-HJFQVKPI.js → chunk-QXDZN2WX.js} +1 -1
- package/dist/cli/chunks/{chunk-RVQW6CBF.js → chunk-S456W64P.js} +2 -2
- package/dist/cli/chunks/{chunk-F62ZQZQQ.js → chunk-S7IHSELP.js} +2 -2
- package/dist/cli/chunks/{chunk-FMKALHT3.js → chunk-S7ZHD6VN.js} +2 -2
- package/dist/cli/chunks/{chunk-AURDGQNB.js → chunk-SU4YXUVK.js} +2 -2
- package/dist/cli/chunks/{chunk-MTSMFEWK.js → chunk-SZPTUV3B.js} +2 -2
- package/dist/cli/chunks/{chunk-O6FN53HB.js → chunk-T7PUM6OY.js} +1 -1
- package/dist/cli/chunks/{chunk-JZFA2PWY.js → chunk-TCKBICJ3.js} +2 -2
- package/dist/cli/chunks/{chunk-DDQWW22L.js → chunk-TOQJWLJV.js} +2 -2
- package/dist/cli/chunks/{chunk-2WVLFT2I.js → chunk-TUEDIQHY.js} +1 -1
- package/dist/cli/chunks/{chunk-QGBXENIP.js → chunk-U5GCSSYX.js} +1 -1
- package/dist/cli/chunks/{chunk-N3R3JGUY.js → chunk-UDLN2THT.js} +1 -1
- package/dist/cli/chunks/{chunk-N7MKF4F4.js → chunk-V6YDM37M.js} +1 -1
- package/dist/cli/chunks/{chunk-B4QA3YN6.js → chunk-VGR65B4Y.js} +1 -1
- package/dist/cli/chunks/{chunk-LCDRRAES.js → chunk-VRHLHGKR.js} +2 -2
- package/dist/cli/chunks/{chunk-XW5OXBVV.js → chunk-VS2G6LX5.js} +2 -2
- package/dist/cli/chunks/{chunk-L7GQKJLV.js → chunk-W6RS5S4Q.js} +2 -2
- package/dist/cli/chunks/{chunk-LYV7WJWA.js → chunk-WEPZOCN7.js} +1 -1
- package/dist/cli/chunks/{chunk-2ZC7S4UG.js → chunk-WIC5UZCQ.js} +2 -2
- package/dist/cli/chunks/{chunk-ZT4NPTML.js → chunk-X2OVUBF6.js} +2 -2
- package/dist/cli/chunks/{chunk-D3S4SRSA.js → chunk-X4GKYSOH.js} +2 -2
- package/dist/cli/chunks/{chunk-V6WJVFRN.js → chunk-XEVUW4QL.js} +2 -2
- package/dist/cli/chunks/{chunk-PVBJUANU.js → chunk-XMDZRULK.js} +2 -2
- package/dist/cli/chunks/{chunk-5OJXVVTI.js → chunk-YFY35CSD.js} +2 -2
- package/dist/cli/chunks/{chunk-TYS77XHV.js → chunk-Z6ADE3KJ.js} +2 -2
- package/dist/cli/chunks/{chunk-QZQGYSDG.js → chunk-ZKPOKMJZ.js} +2 -2
- package/dist/cli/chunks/{chunk-2QU6C3OS.js → chunk-ZRWAFMM7.js} +2 -2
- package/dist/cli/chunks/{ci-4JK2NFCD.js → ci-KTWY7BZT.js} +2 -2
- package/dist/cli/chunks/{ci-output-LCGTJQWC.js → ci-output-WOX6QBMS.js} +2 -2
- package/dist/cli/chunks/{circuit-breaker-EJF7D3L4.js → circuit-breaker-6XKOSFIF.js} +2 -2
- package/dist/cli/chunks/{claude-flow-setup-3RUC6OB4.js → claude-flow-setup-5JA4MNE4.js} +2 -2
- package/dist/cli/chunks/client-X3KUJ6R5.js +2 -0
- package/dist/cli/chunks/{cline-installer-6LY5C5QH.js → cline-installer-Z2ANHEKW.js} +2 -2
- package/dist/cli/chunks/{code-MPDG4UHS.js → code-NO4ZKNDU.js} +2 -2
- package/dist/cli/chunks/{code-index-extractor-OY5GQJBM.js → code-index-extractor-VV4OEPG7.js} +2 -2
- package/dist/cli/chunks/{codex-installer-BO7E2ZVA.js → codex-installer-BP7Y2NYR.js} +2 -2
- package/dist/cli/chunks/{completions-VGL3KJ2R.js → completions-YULJQUF4.js} +2 -2
- package/dist/cli/chunks/{complexity-analyzer-5DPUK7IL.js → complexity-analyzer-D7XYPQ76.js} +2 -2
- package/dist/cli/chunks/{continuedev-installer-LFDG2D42.js → continuedev-installer-E3L7UF72.js} +2 -2
- package/dist/cli/chunks/{copilot-installer-SEMMMIZH.js → copilot-installer-5TRUMJC5.js} +2 -2
- package/dist/cli/chunks/core-handlers-A2EQB3UH.js +2 -0
- package/dist/cli/chunks/{cost-tracker-OPBC6FQM.js → cost-tracker-QTYSJMSV.js} +2 -2
- package/dist/cli/chunks/{coverage-CFDUSRKU.js → coverage-D5DKZ3XT.js} +3 -3
- package/dist/cli/chunks/cross-domain-router-OKZ2PDHT.js +2 -0
- package/dist/cli/chunks/{cursor-installer-6TXUUVY4.js → cursor-installer-UDBHGUIG.js} +2 -2
- package/dist/cli/chunks/{daemon-7BDBPPAF.js → daemon-2GXYN7F7.js} +3 -3
- package/dist/cli/chunks/{daemon-5KO46YQR.js → daemon-IVWUMQKL.js} +4 -4
- package/dist/cli/chunks/{dag-attention-scheduler-6DQKZOUW.js → dag-attention-scheduler-PWXR4QTU.js} +2 -2
- package/dist/cli/chunks/{detect-R2QAYDPI.js → detect-C6P7ONFB.js} +2 -2
- package/dist/cli/chunks/{dist-node-3POCIJ4N.js → dist-node-2BUFM2JK.js} +2 -2
- package/dist/cli/chunks/{domain-handler-KW63CHUH.js → domain-handler-Q2GWZLDM.js} +2 -2
- package/dist/cli/chunks/{domain-transfer-2QPOJCUD.js → domain-transfer-GMUBAM3J.js} +2 -2
- package/dist/cli/chunks/dream-ZBP4Z5C3.js +2 -0
- package/dist/cli/chunks/{embed-and-insert-pattern-OIDJZQEP.js → embed-and-insert-pattern-EFUERRM2.js} +2 -2
- package/dist/cli/chunks/{eval-UGEKTTAQ.js → eval-24FIC43F.js} +2 -2
- package/dist/cli/chunks/{experience-capture-middleware-3BIM2TT7.js → experience-capture-middleware-R4UP2Q2M.js} +3 -3
- package/dist/cli/chunks/{fast-paths-HCJQXB7W.js → fast-paths-RQCGGTXB.js} +2 -2
- package/dist/cli/chunks/{feature-flags-GDGJKLN4.js → feature-flags-APTWWVNQ.js} +2 -2
- package/dist/cli/chunks/{feature-flags-W4JSFBMV.js → feature-flags-SOXVYIBN.js} +2 -2
- package/dist/cli/chunks/{file-discovery-JMUZ4MUH.js → file-discovery-66KRMXVF.js} +2 -2
- package/dist/cli/chunks/{fleet-YNNK2CKW.js → fleet-EMBNKO5Q.js} +3 -3
- package/dist/cli/chunks/{gnn-wrapper-R2ZY6CDD.js → gnn-wrapper-6TKDWFJF.js} +2 -2
- package/dist/cli/chunks/{heartbeat-handler-OZX2EJHQ.js → heartbeat-handler-4ODKJ75H.js} +4 -4
- package/dist/cli/chunks/heartbeat-scheduler-6JUWQXWG.js +2 -0
- package/dist/cli/chunks/hnsw-adapter-JT4BU7XJ.js +2 -0
- package/dist/cli/chunks/hnsw-index-JC5YELJX.js +2 -0
- package/dist/cli/chunks/{hnsw-legacy-bridge-3S6TYCG3.js → hnsw-legacy-bridge-25KFCLUC.js} +2 -2
- package/dist/cli/chunks/{better-sqlite3-RIBLRHJL.js → hnswlib-node-FUWQTM2D.js} +2 -2
- package/dist/cli/chunks/{hooks-KM7WR35T.js → hooks-JIDA2COE.js} +10 -10
- package/dist/cli/chunks/hybrid-router-SLTXHUFG.js +2 -0
- package/dist/cli/chunks/{hypergraph-engine-RX53A73M.js → hypergraph-engine-3YDFDPE3.js} +2 -2
- package/dist/cli/chunks/{hypergraph-handler-3QQB3H3Z.js → hypergraph-handler-VWZX2OJX.js} +3 -3
- package/dist/cli/chunks/impact-analyzer-JXHCMZXY.js +2 -0
- package/dist/cli/chunks/{init-handler-Y62RH4ZI.js → init-handler-DH7VQAMF.js} +6 -6
- package/dist/cli/chunks/init-wizard-EX37TYOG.js +2 -0
- package/dist/cli/chunks/kernel-JPHAG27D.js +2 -0
- package/dist/cli/chunks/{kilocode-installer-26R253L2.js → kilocode-installer-2W2KZCGH.js} +2 -2
- package/dist/cli/chunks/{kiro-installer-PFA5QPZZ.js → kiro-installer-E5KP7OMD.js} +2 -2
- package/dist/cli/chunks/knowledge-graph-5QJZIRYB.js +2 -0
- package/dist/cli/chunks/{learning-CQLM5ANX.js → learning-XJRUVPLF.js} +3 -3
- package/dist/cli/chunks/{llm-router-QZ5PG4PF.js → llm-router-AEEKEMF5.js} +4 -4
- package/dist/cli/chunks/llm-router-service-SE2RO4P5.js +2 -0
- package/dist/cli/chunks/{load-UPA6LPHM.js → load-PZ4YOTBJ.js} +2 -2
- package/dist/cli/chunks/load-test-LOTBWIIS.js +2 -0
- package/dist/cli/chunks/{mcp-LSWTLAJ4.js → mcp-IVA6LC2S.js} +2 -2
- package/dist/cli/chunks/{memory-VGEYYGCG.js → memory-Y3DHXFQE.js} +5 -5
- package/dist/cli/chunks/memory-backend-BSDKTFAN.js +2 -0
- package/dist/cli/chunks/{memory-handlers-QBURG7NA.js → memory-handlers-V5PXEJWL.js} +2 -2
- package/dist/cli/chunks/{multi-model-executor-VZVFBIKC.js → multi-model-executor-646G4S4Y.js} +2 -2
- package/dist/cli/chunks/{opencode-installer-PBQAXNLV.js → opencode-installer-P6KOOTUS.js} +2 -2
- package/dist/cli/chunks/{orchestrator-YND7JB5O.js → orchestrator-T2GVKYMX.js} +5 -5
- package/dist/cli/chunks/pattern-null-store-LRSXCZWM.js +2 -0
- package/dist/cli/chunks/{pipeline-GM5RRUES.js → pipeline-CK2ON45P.js} +2 -2
- package/dist/cli/chunks/{platform-L7OGGRSL.js → platform-OQNSD3A3.js} +2 -2
- package/dist/cli/chunks/{plugin-N4YAE6H5.js → plugin-UOG6RNRM.js} +2 -2
- package/dist/cli/chunks/{prime-radiant-advanced-wasm-7D67XV6Z.js → prime-radiant-advanced-wasm-37UE6TG5.js} +2 -2
- package/dist/cli/chunks/protocol-executor-WPUVJEL7.js +2 -0
- package/dist/cli/chunks/{protocol-handler-V2WTFU7N.js → protocol-handler-V722S6YH.js} +2 -2
- package/dist/cli/chunks/{prove-33DS5Z3N.js → prove-ANGY6W3W.js} +2 -2
- package/dist/cli/chunks/provider-manager-EVPWSH3E.js +2 -0
- package/dist/cli/chunks/qe-reasoning-bank-IH63FG33.js +2 -0
- package/dist/cli/chunks/{quality-WCSEA5GH.js → quality-KG4ALI2L.js} +2 -2
- package/dist/cli/chunks/queen-coordinator-TTCAGYQO.js +2 -0
- package/dist/cli/chunks/{real-embeddings-OQ5F37DG.js → real-embeddings-GUZDO5UN.js} +2 -2
- package/dist/cli/chunks/{roocode-installer-II7LIR2X.js → roocode-installer-WROAR6MJ.js} +2 -2
- package/dist/cli/chunks/router-64Q4ILOQ.js +2 -0
- package/dist/cli/chunks/routing-feedback-KCZV4XXC.js +2 -0
- package/dist/cli/chunks/{routing-handler-6OFHARIY.js → routing-handler-UFPSSS5D.js} +2 -2
- package/dist/cli/chunks/{ruvector-commands-GD5JTR4M.js → ruvector-commands-XJQMKDRM.js} +2 -2
- package/dist/cli/chunks/{rvf-dual-writer-HSK6BYZV.js → rvf-dual-writer-QPRMDKYX.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-adapter-554SMF5S.js → rvf-migration-adapter-SOHBK23K.js} +2 -2
- package/dist/cli/chunks/{rvf-migration-coordinator-OFDBCAYE.js → rvf-migration-coordinator-MTWUSPEJ.js} +2 -2
- package/dist/cli/chunks/rvf-native-adapter-GNJKMURU.js +2 -0
- package/dist/cli/chunks/safe-db-6VBZQIJI.js +2 -0
- package/dist/cli/chunks/schedule-4V7O5IPX.js +2 -0
- package/dist/cli/chunks/scheduler-CQDMHEHN.js +2 -0
- package/dist/cli/chunks/{security-GN4J6DSS.js → security-5MAMQKP6.js} +3 -3
- package/dist/cli/chunks/{shared-rvf-adapter-Q4PM3QCN.js → shared-rvf-adapter-YEUBSRNN.js} +2 -2
- package/dist/cli/chunks/{shared-rvf-dual-writer-R5WK5BXQ.js → shared-rvf-dual-writer-DBQJHG42.js} +2 -2
- package/dist/cli/chunks/sqlite-persistence-7DHUFTHL.js +2 -0
- package/dist/cli/chunks/{status-handler-AHS5WVMG.js → status-handler-ZUB2UKQZ.js} +2 -2
- package/dist/cli/chunks/{structural-health-5KUKNLHZ.js → structural-health-B2GHENWX.js} +2 -2
- package/dist/cli/chunks/{sync-PUMM3SR6.js → sync-7VMXJTR2.js} +2 -2
- package/dist/cli/chunks/{sync-TQLGD5HX.js → sync-YCUUW3IP.js} +2 -2
- package/dist/cli/chunks/{task-handler-D7VXV4AF.js → task-handler-N7LJTXZM.js} +2 -2
- package/dist/cli/chunks/{task-handlers-QMN4SWUG.js → task-handlers-GDHNJV2E.js} +3 -3
- package/dist/cli/chunks/{test-HEWZR6YQ.js → test-6COGC5KI.js} +4 -4
- package/dist/cli/chunks/{test-scheduling-VTMLBEPA.js → test-scheduling-CUERHJMF.js} +3 -3
- package/dist/cli/chunks/{token-bootstrap-IYBG7PQ6.js → token-bootstrap-JTGSL6PP.js} +2 -2
- package/dist/cli/chunks/{token-usage-C7H27BFZ.js → token-usage-LSG3JYGX.js} +2 -2
- package/dist/cli/chunks/{transformers-5ZJVC6NB.js → transformers-ODIITRCT.js} +2 -2
- package/dist/cli/chunks/{tree-sitter-wasm-parser-EARBJG2H.js → tree-sitter-wasm-parser-KSP7ZZ5H.js} +2 -2
- package/dist/cli/chunks/{types-3IHE42PZ.js → types-6N6SUU2O.js} +2 -2
- package/dist/cli/chunks/unified-memory-MQA72NLP.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-K7HA3CWV.js +2 -0
- package/dist/cli/chunks/unified-persistence-2DXB4OE4.js +2 -0
- package/dist/cli/chunks/{upgrade-YP3VFSXO.js → upgrade-7SCVOCPS.js} +2 -2
- package/dist/cli/chunks/{validate-VSBNKPN6.js → validate-762ISH2Y.js} +2 -2
- package/dist/cli/chunks/{validate-swarm-GOCJVWXE.js → validate-swarm-R6WYYXGO.js} +2 -2
- package/dist/cli/chunks/{vibium-U6YKCLDF.js → vibium-5GZYSUDQ.js} +2 -2
- package/dist/cli/chunks/visual-security-UD6CARIJ.js +2 -0
- package/dist/cli/chunks/{web-tree-sitter-TSNVGWSN.js → web-tree-sitter-VYYVAJTY.js} +2 -2
- package/dist/cli/chunks/{windsurf-installer-2VKMEFSD.js → windsurf-installer-RRIOR3B6.js} +2 -2
- package/dist/cli/chunks/witness-chain-LWALPPMC.js +2 -0
- package/dist/cli/chunks/{witness-chain-BWZCW52H.js → witness-chain-SRVBEKDB.js} +2 -2
- package/dist/cli/chunks/{workflow-J6SCYLU3.js → workflow-XNUDHGEC.js} +4 -4
- package/dist/cli/chunks/workflow-orchestrator-QU652FLH.js +2 -0
- package/dist/cli/chunks/{wrappers-M5C7DONW.js → wrappers-3STST7QW.js} +2 -2
- package/dist/domains/requirements-validation/coordinator.d.ts +16 -2
- package/dist/domains/requirements-validation/coordinator.js +112 -7
- package/dist/domains/requirements-validation/plugin.js +20 -1
- package/dist/domains/test-generation/coordinator.d.ts +3 -1
- package/dist/domains/test-generation/coordinator.js +15 -33
- package/dist/integrations/darwin/types.d.ts +10 -3
- package/dist/integrations/darwin/types.js +10 -3
- package/dist/mcp/bundle.js +366 -359
- package/dist/mcp/tool-scoping.d.ts +8 -2
- package/dist/mcp/tool-scoping.js +13 -0
- package/dist/routing/free-tier/coordinator-support.d.ts +90 -0
- package/dist/routing/free-tier/coordinator-support.js +78 -0
- package/dist/routing/free-tier/executor.d.ts +43 -1
- package/dist/routing/free-tier/executor.js +69 -26
- package/dist/routing/free-tier/index.d.ts +1 -0
- package/dist/routing/free-tier/index.js +1 -0
- package/dist/routing/value-score.d.ts +49 -0
- package/dist/routing/value-score.js +54 -0
- package/dist/shared/optional-module.d.ts +23 -0
- package/dist/shared/optional-module.js +46 -0
- package/dist/verification/adversarial-verify/calibrate.d.ts +32 -0
- package/dist/verification/adversarial-verify/calibrate.js +33 -0
- package/dist/verification/adversarial-verify/gate.d.ts +38 -0
- package/dist/verification/adversarial-verify/gate.js +32 -0
- package/dist/verification/adversarial-verify/index.d.ts +20 -0
- package/dist/verification/adversarial-verify/index.js +6 -0
- package/dist/verification/adversarial-verify/prompts.d.ts +14 -0
- package/dist/verification/adversarial-verify/prompts.js +17 -0
- package/dist/verification/adversarial-verify/synthesize.d.ts +18 -0
- package/dist/verification/adversarial-verify/synthesize.js +35 -0
- package/dist/verification/adversarial-verify/types.d.ts +59 -0
- package/dist/verification/adversarial-verify/types.js +10 -0
- package/dist/verification/adversarial-verify/verify.d.ts +20 -0
- package/dist/verification/adversarial-verify/verify.js +34 -0
- package/package.json +10 -1
- package/dist/cli/chunks/adapter-WLFT5VMV.js +0 -2
- package/dist/cli/chunks/aqe-learning-engine-JBH4GZUM.js +0 -2
- package/dist/cli/chunks/base-A7JGM473.js +0 -2
- package/dist/cli/chunks/browser-workflow-TIDJWULK.js +0 -2
- package/dist/cli/chunks/chunk-C4OYHUJV.js +0 -2
- package/dist/cli/chunks/client-ZLJ3JMBC.js +0 -2
- package/dist/cli/chunks/core-handlers-EM7FUYTI.js +0 -2
- package/dist/cli/chunks/cross-domain-router-DYGHQ6P5.js +0 -2
- package/dist/cli/chunks/dream-DBE5D5BD.js +0 -2
- package/dist/cli/chunks/heartbeat-scheduler-NFHAANNL.js +0 -2
- package/dist/cli/chunks/hnsw-adapter-HMPCZFBY.js +0 -2
- package/dist/cli/chunks/hnsw-index-KRIWSXX4.js +0 -2
- package/dist/cli/chunks/hybrid-router-BAB32B2W.js +0 -2
- package/dist/cli/chunks/impact-analyzer-3D6XHWQE.js +0 -2
- package/dist/cli/chunks/init-wizard-LLU3WVGC.js +0 -2
- package/dist/cli/chunks/kernel-ZFHAYHHJ.js +0 -2
- package/dist/cli/chunks/knowledge-graph-ETZ65KOY.js +0 -2
- package/dist/cli/chunks/llm-router-service-R6CTGF5I.js +0 -2
- package/dist/cli/chunks/load-test-UOWIJUCH.js +0 -2
- package/dist/cli/chunks/memory-backend-E3ZQKW7A.js +0 -2
- package/dist/cli/chunks/pattern-null-store-OUOJO2RH.js +0 -2
- package/dist/cli/chunks/protocol-executor-KHAPG5CP.js +0 -2
- package/dist/cli/chunks/provider-manager-FGPPW7T4.js +0 -2
- package/dist/cli/chunks/qe-reasoning-bank-TS7XOJDA.js +0 -2
- package/dist/cli/chunks/queen-coordinator-J35FNFQ3.js +0 -2
- package/dist/cli/chunks/router-AFTKPDI5.js +0 -2
- package/dist/cli/chunks/routing-feedback-SABZUJTF.js +0 -2
- package/dist/cli/chunks/rvf-native-adapter-57MDDSFQ.js +0 -2
- package/dist/cli/chunks/safe-db-2HR6MVYM.js +0 -2
- package/dist/cli/chunks/schedule-KLVAN6XI.js +0 -2
- package/dist/cli/chunks/scheduler-WYZ6BC5Y.js +0 -2
- package/dist/cli/chunks/sqlite-persistence-2CGU5INO.js +0 -2
- package/dist/cli/chunks/unified-memory-PMYRQC5K.js +0 -2
- package/dist/cli/chunks/unified-memory-hnsw-7TRL2K5Q.js +0 -2
- package/dist/cli/chunks/unified-persistence-S4BNJK4S.js +0 -2
- package/dist/cli/chunks/visual-security-RPMZ3J7L.js +0 -2
- package/dist/cli/chunks/witness-chain-BTDZSQ6P.js +0 -2
- package/dist/cli/chunks/workflow-orchestrator-42B62D3V.js +0 -2
|
@@ -25,6 +25,10 @@ const PENDING_PATH = path.join(DATA_DIR, 'pending-insights.jsonl');
|
|
|
25
25
|
const SESSION_DIR = path.join(process.cwd(), '.claude-flow', 'sessions');
|
|
26
26
|
const SESSION_FILE = path.join(SESSION_DIR, 'current.json');
|
|
27
27
|
|
|
28
|
+
// ── Safety limits (fixes #1530, #1531) ─────────────────────────────────────
|
|
29
|
+
const MAX_DATA_FILE_SIZE = 10 * 1024 * 1024; // 10 MB — skip files larger than this
|
|
30
|
+
const MAX_GRAPH_NODES = 5000; // skip PageRank if graph exceeds this
|
|
31
|
+
|
|
28
32
|
// ── Stop words for trigram matching ──────────────────────────────────────────
|
|
29
33
|
|
|
30
34
|
const STOP_WORDS = new Set([
|
|
@@ -46,6 +50,14 @@ function ensureDataDir() {
|
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
function readJSON(filePath) {
|
|
53
|
+
// Safety: skip files exceeding MAX_DATA_FILE_SIZE (#1531)
|
|
54
|
+
try {
|
|
55
|
+
const stat = fs.statSync(filePath);
|
|
56
|
+
if (stat.size > MAX_DATA_FILE_SIZE) {
|
|
57
|
+
process.stderr.write("[INTELLIGENCE] WARN: Skipping " + path.basename(filePath) + " (" + Math.round(stat.size / 1048576) + "MB exceeds 10MB limit)\n");
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
} catch { /* file may not exist yet */ }
|
|
49
61
|
try {
|
|
50
62
|
if (fs.existsSync(filePath)) return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
51
63
|
} catch { /* corrupt file — start fresh */ }
|
|
@@ -80,6 +92,63 @@ function jaccardSimilarity(setA, setB) {
|
|
|
80
92
|
return intersection / (setA.size + setB.size - intersection);
|
|
81
93
|
}
|
|
82
94
|
|
|
95
|
+
// ── Deduplication helper (fixes #1518) ──────────────────────────────────────
|
|
96
|
+
|
|
97
|
+
function deduplicateById(entries) {
|
|
98
|
+
if (!entries || !Array.isArray(entries)) return entries;
|
|
99
|
+
const seen = new Map();
|
|
100
|
+
for (const entry of entries) {
|
|
101
|
+
const id = entry.id || entry.key;
|
|
102
|
+
if (id) {
|
|
103
|
+
seen.set(id, entry);
|
|
104
|
+
} else {
|
|
105
|
+
seen.set(`__no_id_${seen.size}`, entry);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return Array.from(seen.values());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ADR-095 G6 — content-hash dedup. The April audit measured 5,706 entries
|
|
112
|
+
// in the auto-memory store with only ~20 unique by content; 5,686 dupes
|
|
113
|
+
// were the same MEMORY.md sections imported from sibling project dirs
|
|
114
|
+
// with different IDs. deduplicateById can't catch these (the IDs really
|
|
115
|
+
// are different); we need a content fingerprint.
|
|
116
|
+
//
|
|
117
|
+
// Fast non-cryptographic fingerprint — collisions on 64-bit FNV-1a are
|
|
118
|
+
// vanishingly rare for human prose at the scale of an auto-memory store.
|
|
119
|
+
// Whitespace-normalized so trivially-different formatting doesn't bypass dedup.
|
|
120
|
+
function fingerprintContent(text) {
|
|
121
|
+
if (typeof text !== 'string' || text.length === 0) return '0';
|
|
122
|
+
const norm = text.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
123
|
+
// FNV-1a 64-bit (split into 32-bit halves to stay within Number safe int)
|
|
124
|
+
let h1 = 0x811c9dc5, h2 = 0xcbf29ce4;
|
|
125
|
+
for (let i = 0; i < norm.length; i++) {
|
|
126
|
+
const c = norm.charCodeAt(i);
|
|
127
|
+
h1 ^= c; h1 = Math.imul(h1, 0x01000193) >>> 0;
|
|
128
|
+
h2 ^= c; h2 = Math.imul(h2, 0x100000001b3 & 0xffffffff) >>> 0;
|
|
129
|
+
}
|
|
130
|
+
return `${h1.toString(16)}_${h2.toString(16)}_${norm.length}`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function deduplicateByContent(entries) {
|
|
134
|
+
if (!entries || !Array.isArray(entries)) return entries;
|
|
135
|
+
const seen = new Map();
|
|
136
|
+
for (const entry of entries) {
|
|
137
|
+
const content = entry.content || entry.summary || entry.value || '';
|
|
138
|
+
const fp = fingerprintContent(typeof content === 'string' ? content : JSON.stringify(content));
|
|
139
|
+
if (!seen.has(fp)) {
|
|
140
|
+
seen.set(fp, entry);
|
|
141
|
+
} else {
|
|
142
|
+
// Keep the entry with the higher accessCount or earlier createdAt
|
|
143
|
+
const existing = seen.get(fp);
|
|
144
|
+
const existingAccess = existing.accessCount || 0;
|
|
145
|
+
const candidateAccess = entry.accessCount || 0;
|
|
146
|
+
if (candidateAccess > existingAccess) seen.set(fp, entry);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return Array.from(seen.values());
|
|
150
|
+
}
|
|
151
|
+
|
|
83
152
|
// ── Session state helpers ────────────────────────────────────────────────────
|
|
84
153
|
|
|
85
154
|
function sessionGet(key) {
|
|
@@ -189,14 +258,24 @@ function buildEdges(entries) {
|
|
|
189
258
|
}
|
|
190
259
|
}
|
|
191
260
|
|
|
192
|
-
// Similarity edges within categories (Jaccard > 0.3)
|
|
261
|
+
// Similarity edges within categories (Jaccard > 0.3).
|
|
262
|
+
// ADR-095 G6 perf: hoist the trigram computation outside the inner
|
|
263
|
+
// loop. Previously we re-tokenized + re-trigrammed group[j] for every
|
|
264
|
+
// i — O(n²) extra work for nothing. Now compute once per entry.
|
|
193
265
|
for (const cat of Object.keys(byCategory)) {
|
|
194
266
|
const group = byCategory[cat];
|
|
267
|
+
if (group.length < 2) continue;
|
|
268
|
+
|
|
269
|
+
// Cache trigram sets for every entry in the group.
|
|
270
|
+
const triCache = new Array(group.length);
|
|
195
271
|
for (let i = 0; i < group.length; i++) {
|
|
196
|
-
|
|
272
|
+
triCache[i] = trigrams(tokenize(group[i].content || group[i].summary || ''));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
for (let i = 0; i < group.length; i++) {
|
|
276
|
+
const triA = triCache[i];
|
|
197
277
|
for (let j = i + 1; j < group.length; j++) {
|
|
198
|
-
const
|
|
199
|
-
const sim = jaccardSimilarity(triA, triB);
|
|
278
|
+
const sim = jaccardSimilarity(triA, triCache[j]);
|
|
200
279
|
if (sim > 0.3) {
|
|
201
280
|
edges.push({
|
|
202
281
|
sourceId: group[i].id,
|
|
@@ -236,15 +315,17 @@ function bootstrapFromMemoryFiles() {
|
|
|
236
315
|
for (const base of candidates) {
|
|
237
316
|
if (!fs.existsSync(base)) continue;
|
|
238
317
|
|
|
239
|
-
// For the projects dir,
|
|
318
|
+
// For the projects dir, scope to CURRENT project only (not all 51+ dirs)
|
|
240
319
|
if (base.endsWith('projects')) {
|
|
241
320
|
try {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
321
|
+
// Match Claude Code's project-dir slug: every non-alphanumeric char -> '-'
|
|
322
|
+
// (e.g. "G:\\My Drive\\TJ_Vault" -> "G--My-Drive-TJ-Vault"). The old version
|
|
323
|
+
// only handled POSIX '/', so on Windows the slug kept ':' and '\\' and never
|
|
324
|
+
// matched the real <projects>/<slug>/memory dir — bootstrap found nothing (FIX 5).
|
|
325
|
+
const projectSlug = cwd.replace(/[^a-zA-Z0-9]/g, '-');
|
|
326
|
+
const memDir = path.join(base, projectSlug, 'memory');
|
|
327
|
+
if (fs.existsSync(memDir)) {
|
|
328
|
+
parseMemoryDir(memDir, entries);
|
|
248
329
|
}
|
|
249
330
|
} catch { /* skip */ }
|
|
250
331
|
} else if (fs.existsSync(base)) {
|
|
@@ -255,6 +336,16 @@ function bootstrapFromMemoryFiles() {
|
|
|
255
336
|
return entries;
|
|
256
337
|
}
|
|
257
338
|
|
|
339
|
+
// Truncation transparency (FIX 4): mark the cut with an ellipsis and warn under
|
|
340
|
+
// debug, so later reasoning isn't silently built on severed text.
|
|
341
|
+
const CLIP_DEBUG = !!(process.env.RUFLO_DEBUG || process.env.DEBUG);
|
|
342
|
+
function clip(text, max, label) {
|
|
343
|
+
text = text == null ? '' : String(text);
|
|
344
|
+
if (text.length <= max) return text;
|
|
345
|
+
if (CLIP_DEBUG) process.stderr.write(`[INTELLIGENCE] WARN: truncated ${label || 'value'} from ${text.length} to ${max} chars\n`);
|
|
346
|
+
return text.slice(0, max - 1) + '…';
|
|
347
|
+
}
|
|
348
|
+
|
|
258
349
|
function parseMemoryDir(dir, entries) {
|
|
259
350
|
try {
|
|
260
351
|
const files = fs.readdirSync(dir).filter(f => f.endsWith('.md'));
|
|
@@ -265,17 +356,18 @@ function parseMemoryDir(dir, entries) {
|
|
|
265
356
|
|
|
266
357
|
// Parse markdown sections as separate entries
|
|
267
358
|
const sections = content.split(/^##?\s+/m).filter(Boolean);
|
|
268
|
-
for (
|
|
359
|
+
for (let sIdx = 0; sIdx < sections.length; sIdx++) {
|
|
360
|
+
const section = sections[sIdx];
|
|
269
361
|
const lines = section.trim().split('\n');
|
|
270
362
|
const title = lines[0].trim();
|
|
271
363
|
const body = lines.slice(1).join('\n').trim();
|
|
272
364
|
if (!body || body.length < 10) continue;
|
|
273
365
|
|
|
274
|
-
const id = `mem-${file.replace('.md', '')}-${title.replace(/[^a-z0-9]/gi, '-').toLowerCase().slice(0, 30)}`;
|
|
366
|
+
const id = `mem-${file.replace('.md', '')}-${title.replace(/[^a-z0-9]/gi, '-').toLowerCase().slice(0, 30)}-${sIdx}`;
|
|
275
367
|
entries.push({
|
|
276
368
|
id,
|
|
277
369
|
key: title.toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 50),
|
|
278
|
-
content: body
|
|
370
|
+
content: clip(body, 500, 'memory content'),
|
|
279
371
|
summary: title,
|
|
280
372
|
namespace: file === 'MEMORY.md' ? 'core' : file.replace('.md', ''),
|
|
281
373
|
type: 'semantic',
|
|
@@ -312,8 +404,27 @@ function init() {
|
|
|
312
404
|
}
|
|
313
405
|
}
|
|
314
406
|
|
|
407
|
+
// Deduplicate store entries by ID (fixes #1518 — 194MB → ~79KB)
|
|
408
|
+
let deduped = deduplicateById(store);
|
|
409
|
+
// ADR-095 G6: also dedupe by content fingerprint. The April audit
|
|
410
|
+
// measured 5,706 entries with only ~20 unique by content because the
|
|
411
|
+
// same MEMORY.md sections get imported from sibling project dirs with
|
|
412
|
+
// different IDs. deduplicateById can't catch that; deduplicateByContent
|
|
413
|
+
// can. Cuts the graph from O(n²) over near-identical duplicates down
|
|
414
|
+
// to O(unique²), which is the difference between a 100MB graph-state
|
|
415
|
+
// and a kilobytes-scale one for typical workloads.
|
|
416
|
+
const beforeContentDedup = deduped.length;
|
|
417
|
+
deduped = deduplicateByContent(deduped);
|
|
418
|
+
if (deduped.length < store.length) {
|
|
419
|
+
process.stderr.write(
|
|
420
|
+
`[INTELLIGENCE] Deduped store: ${store.length} -> ${deduped.length} entries ` +
|
|
421
|
+
`(by-id: ${store.length - beforeContentDedup} dropped, by-content: ${beforeContentDedup - deduped.length} dropped)\n`
|
|
422
|
+
);
|
|
423
|
+
writeJSON(STORE_PATH, deduped);
|
|
424
|
+
}
|
|
425
|
+
|
|
315
426
|
// Skip rebuild if graph is fresh and store hasn't changed
|
|
316
|
-
if (graphState && graphState.nodeCount ===
|
|
427
|
+
if (graphState && graphState.nodeCount === deduped.length) {
|
|
317
428
|
const age = Date.now() - (graphState.updatedAt || 0);
|
|
318
429
|
if (age < 60000) {
|
|
319
430
|
return {
|
|
@@ -324,9 +435,9 @@ function init() {
|
|
|
324
435
|
}
|
|
325
436
|
}
|
|
326
437
|
|
|
327
|
-
// Build nodes
|
|
438
|
+
// Build nodes from deduped entries
|
|
328
439
|
const nodes = {};
|
|
329
|
-
for (const entry of
|
|
440
|
+
for (const entry of deduped) {
|
|
330
441
|
const id = entry.id || entry.key || `entry-${Math.random().toString(36).slice(2, 8)}`;
|
|
331
442
|
nodes[id] = {
|
|
332
443
|
id,
|
|
@@ -340,10 +451,17 @@ function init() {
|
|
|
340
451
|
}
|
|
341
452
|
|
|
342
453
|
// Build edges
|
|
343
|
-
const edges = buildEdges(
|
|
344
|
-
|
|
345
|
-
// Compute PageRank
|
|
346
|
-
const
|
|
454
|
+
const edges = buildEdges(deduped);
|
|
455
|
+
|
|
456
|
+
// Compute PageRank (skip if graph too large — #1531)
|
|
457
|
+
const nodeCount = Object.keys(nodes).length;
|
|
458
|
+
let pageRanks = {};
|
|
459
|
+
if (nodeCount > MAX_GRAPH_NODES) {
|
|
460
|
+
process.stderr.write("[INTELLIGENCE] WARN: Graph has " + nodeCount + " nodes (>" + MAX_GRAPH_NODES + "), skipping PageRank\n");
|
|
461
|
+
for (const id of Object.keys(nodes)) pageRanks[id] = 1 / nodeCount;
|
|
462
|
+
} else {
|
|
463
|
+
pageRanks = computePageRank(nodes, edges, 0.85, 30);
|
|
464
|
+
}
|
|
347
465
|
|
|
348
466
|
// Write graph state
|
|
349
467
|
const graph = {
|
|
@@ -357,7 +475,7 @@ function init() {
|
|
|
357
475
|
writeJSON(GRAPH_PATH, graph);
|
|
358
476
|
|
|
359
477
|
// Build ranked context for fast lookup
|
|
360
|
-
const rankedEntries =
|
|
478
|
+
const rankedEntries = deduped.map(entry => {
|
|
361
479
|
const id = entry.id;
|
|
362
480
|
const content = entry.content || entry.value || '';
|
|
363
481
|
const summary = entry.summary || entry.key || '';
|
|
@@ -515,11 +633,15 @@ function boostConfidence(ids, amount) {
|
|
|
515
633
|
function consolidate() {
|
|
516
634
|
ensureDataDir();
|
|
517
635
|
|
|
518
|
-
|
|
636
|
+
let store = readJSON(STORE_PATH);
|
|
519
637
|
if (!store || !Array.isArray(store)) {
|
|
520
638
|
return { entries: 0, edges: 0, newEntries: 0, message: 'No store to consolidate' };
|
|
521
639
|
}
|
|
522
640
|
|
|
641
|
+
// Deduplicate store entries by ID before processing (fixes #1518)
|
|
642
|
+
const preDedupCount = store.length;
|
|
643
|
+
store = deduplicateById(store);
|
|
644
|
+
|
|
523
645
|
// 1. Process pending insights
|
|
524
646
|
let newEntries = 0;
|
|
525
647
|
if (fs.existsSync(PENDING_PATH)) {
|
|
@@ -595,8 +717,15 @@ function consolidate() {
|
|
|
595
717
|
};
|
|
596
718
|
}
|
|
597
719
|
|
|
598
|
-
// 5. Recompute PageRank
|
|
599
|
-
const
|
|
720
|
+
// 5. Recompute PageRank (skip if graph too large — #1531)
|
|
721
|
+
const nodeCount = Object.keys(nodes).length;
|
|
722
|
+
let pageRanks = {};
|
|
723
|
+
if (nodeCount > MAX_GRAPH_NODES) {
|
|
724
|
+
process.stderr.write("[INTELLIGENCE] WARN: Graph has " + nodeCount + " nodes (>" + MAX_GRAPH_NODES + "), skipping PageRank in consolidate\n");
|
|
725
|
+
for (const id of Object.keys(nodes)) pageRanks[id] = 1 / nodeCount;
|
|
726
|
+
} else {
|
|
727
|
+
pageRanks = computePageRank(nodes, edges, 0.85, 30);
|
|
728
|
+
}
|
|
600
729
|
|
|
601
730
|
// 6. Write updated graph
|
|
602
731
|
writeJSON(GRAPH_PATH, {
|
|
@@ -636,8 +765,8 @@ function consolidate() {
|
|
|
636
765
|
entries: rankedEntries,
|
|
637
766
|
});
|
|
638
767
|
|
|
639
|
-
// 8. Persist updated store (with new insight entries)
|
|
640
|
-
if (newEntries > 0) writeJSON(STORE_PATH, store);
|
|
768
|
+
// 8. Persist updated store (deduped or with new insight entries)
|
|
769
|
+
if (newEntries > 0 || store.length < preDedupCount) writeJSON(STORE_PATH, store);
|
|
641
770
|
|
|
642
771
|
// 9. Save snapshot for delta tracking
|
|
643
772
|
const updatedGraph = readJSON(GRAPH_PATH);
|
|
@@ -8,7 +8,7 @@ COMMIT_MSG=$(git log -1 --pretty=%B)
|
|
|
8
8
|
echo "📊 Recording commit metrics..."
|
|
9
9
|
|
|
10
10
|
# Notify claude-flow of commit
|
|
11
|
-
npx
|
|
11
|
+
npx @claude-flow/cli hooks notify \
|
|
12
12
|
--message "Commit: $COMMIT_MSG" \
|
|
13
13
|
--level info \
|
|
14
14
|
--metadata '{"hash": "'$COMMIT_HASH'"}' 2>/dev/null || true
|
|
@@ -13,7 +13,7 @@ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
|
|
|
13
13
|
for FILE in $STAGED_FILES; do
|
|
14
14
|
if [[ "$FILE" =~ \.(ts|js|tsx|jsx)$ ]]; then
|
|
15
15
|
echo " Validating: $FILE"
|
|
16
|
-
npx
|
|
16
|
+
npx @claude-flow/cli hooks pre-edit --file "$FILE" --validate-syntax 2>/dev/null || true
|
|
17
17
|
fi
|
|
18
18
|
done
|
|
19
19
|
|
|
@@ -5,15 +5,15 @@ echo "🚀 Claude Flow Quick Start"
|
|
|
5
5
|
echo "=========================="
|
|
6
6
|
echo ""
|
|
7
7
|
echo "1. Initialize a swarm:"
|
|
8
|
-
echo " npx
|
|
8
|
+
echo " npx claude-flow swarm init --topology hierarchical"
|
|
9
9
|
echo ""
|
|
10
10
|
echo "2. Spawn agents:"
|
|
11
|
-
echo " npx
|
|
11
|
+
echo " npx claude-flow agent spawn --type coder --name "API Developer""
|
|
12
12
|
echo ""
|
|
13
13
|
echo "3. Orchestrate tasks:"
|
|
14
|
-
echo " npx
|
|
14
|
+
echo " npx claude-flow task orchestrate --task "Build REST API""
|
|
15
15
|
echo ""
|
|
16
16
|
echo "4. Monitor progress:"
|
|
17
|
-
echo " npx
|
|
17
|
+
echo " npx claude-flow swarm monitor"
|
|
18
18
|
echo ""
|
|
19
19
|
echo "📚 For more examples, see .claude/commands/"
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Claude Flow Agent Router
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
|
+
* Static keyword router that suggests an agent for a task description.
|
|
6
|
+
* NOTE: This is *not* a learned model. It is a heuristic table; "confidence"
|
|
7
|
+
* is reported as a heuristic prior, not a calibrated probability.
|
|
8
|
+
*
|
|
9
|
+
* #2257 fix: patterns are now word-boundary-anchored so short tokens like
|
|
10
|
+
* `cd`, `ci`, `ui`, `add`, `structure` no longer match inside unrelated
|
|
11
|
+
* words (`decision`, `infrastructure`, `address`, `addendum`). Default
|
|
12
|
+
* confidence dropped from 0.8 to 0.6 to better reflect that this is a
|
|
13
|
+
* static heuristic, not a learned classifier.
|
|
5
14
|
*/
|
|
6
15
|
|
|
7
16
|
const AGENT_CAPABILITIES = {
|
|
@@ -15,52 +24,82 @@ const AGENT_CAPABILITIES = {
|
|
|
15
24
|
devops: ['ci-cd', 'docker', 'deployment', 'infrastructure'],
|
|
16
25
|
};
|
|
17
26
|
|
|
18
|
-
|
|
27
|
+
// Each entry is an array of tokens. Tokens are alternation-friendly:
|
|
28
|
+
// - multi-word phrases ("unit test") match as phrases
|
|
29
|
+
// - single tokens are wrapped with \b … \b word boundaries at match time
|
|
30
|
+
const TASK_PATTERNS = [
|
|
19
31
|
// Code patterns
|
|
20
|
-
'implement
|
|
21
|
-
'test
|
|
22
|
-
'review
|
|
23
|
-
'research
|
|
24
|
-
'design
|
|
32
|
+
{ tokens: ['implement', 'create', 'build', 'add', 'write code', 'refactor', 'debug'], agent: 'coder' },
|
|
33
|
+
{ tokens: ['test', 'tests', 'spec', 'coverage', 'unit test', 'integration test'], agent: 'tester' },
|
|
34
|
+
{ tokens: ['review', 'audit', 'check', 'validate', 'security'], agent: 'reviewer' },
|
|
35
|
+
{ tokens: ['research', 'find', 'search', 'documentation', 'explore'], agent: 'researcher' },
|
|
36
|
+
{ tokens: ['design', 'architect', 'architecture', 'structure', 'plan'], agent: 'architect' },
|
|
25
37
|
|
|
26
38
|
// Domain patterns
|
|
27
|
-
'api
|
|
28
|
-
'ui
|
|
29
|
-
'
|
|
30
|
-
|
|
39
|
+
{ tokens: ['api', 'endpoint', 'server', 'backend', 'database'], agent: 'backend-dev' },
|
|
40
|
+
{ tokens: ['ui', 'frontend', 'component', 'react', 'css', 'style'], agent: 'frontend-dev' },
|
|
41
|
+
// 'cd' / 'ci' are kept but require word boundaries via \b — they will not
|
|
42
|
+
// match inside "decision" or "specific". 'cd' as a literal command in a
|
|
43
|
+
// task description ("set up cd pipeline") still matches.
|
|
44
|
+
{ tokens: ['deploy', 'docker', 'ci', 'cd', 'ci/cd', 'pipeline', 'infrastructure', 'devops'], agent: 'devops' },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
function escapeRegex(s) {
|
|
48
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Build an anchored alternation regex from a token list.
|
|
52
|
+
// - multi-word phrases (containing whitespace or '/') match literally
|
|
53
|
+
// - single tokens are wrapped with \b boundaries so 'cd' won't match "decide"
|
|
54
|
+
function buildPattern(tokens) {
|
|
55
|
+
const alternatives = tokens.map((tok) => {
|
|
56
|
+
const escaped = escapeRegex(tok.toLowerCase());
|
|
57
|
+
if (/\s|\//.test(tok)) {
|
|
58
|
+
// Phrase: whitespace/'/' on each side acts as a natural boundary
|
|
59
|
+
return escaped;
|
|
60
|
+
}
|
|
61
|
+
return `\\b${escaped}\\b`;
|
|
62
|
+
});
|
|
63
|
+
return new RegExp(`(?:${alternatives.join('|')})`, 'i');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const COMPILED_PATTERNS = TASK_PATTERNS.map((entry) => ({
|
|
67
|
+
agent: entry.agent,
|
|
68
|
+
tokens: entry.tokens,
|
|
69
|
+
regex: buildPattern(entry.tokens),
|
|
70
|
+
}));
|
|
31
71
|
|
|
32
72
|
function routeTask(task) {
|
|
33
|
-
const taskLower = task.toLowerCase();
|
|
73
|
+
const taskLower = String(task ?? '').toLowerCase();
|
|
34
74
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const regex = new RegExp(pattern, 'i');
|
|
38
|
-
if (regex.test(taskLower)) {
|
|
75
|
+
for (const entry of COMPILED_PATTERNS) {
|
|
76
|
+
if (entry.regex.test(taskLower)) {
|
|
39
77
|
return {
|
|
40
|
-
agent,
|
|
41
|
-
|
|
42
|
-
|
|
78
|
+
agent: entry.agent,
|
|
79
|
+
// Heuristic prior, not a learned probability — see file header.
|
|
80
|
+
confidence: 0.6,
|
|
81
|
+
reason: `Matched keyword(s) from: ${entry.tokens.join('|')}`,
|
|
43
82
|
};
|
|
44
83
|
}
|
|
45
84
|
}
|
|
46
85
|
|
|
47
|
-
// Default to coder for unknown tasks
|
|
48
86
|
return {
|
|
49
87
|
agent: 'coder',
|
|
50
|
-
confidence: 0.
|
|
51
|
-
reason: 'Default routing - no specific
|
|
88
|
+
confidence: 0.3,
|
|
89
|
+
reason: 'Default routing - no specific keyword matched',
|
|
52
90
|
};
|
|
53
91
|
}
|
|
54
92
|
|
|
55
93
|
// CLI
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (task) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
} else {
|
|
62
|
-
|
|
63
|
-
|
|
94
|
+
if (require.main === module) {
|
|
95
|
+
const task = process.argv.slice(2).join(' ');
|
|
96
|
+
if (task) {
|
|
97
|
+
const result = routeTask(task);
|
|
98
|
+
console.log(JSON.stringify(result, null, 2));
|
|
99
|
+
} else {
|
|
100
|
+
console.log('Usage: router.js <task description>');
|
|
101
|
+
console.log('\nAvailable agents:', Object.keys(AGENT_CAPABILITIES).join(', '));
|
|
102
|
+
}
|
|
64
103
|
}
|
|
65
104
|
|
|
66
|
-
module.exports = { routeTask, AGENT_CAPABILITIES, TASK_PATTERNS };
|
|
105
|
+
module.exports = { routeTask, AGENT_CAPABILITIES, TASK_PATTERNS, buildPattern };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ruflo-hook.cjs — cross-platform Node.js port of ruflo-hook.sh (#2132)
|
|
4
|
+
*
|
|
5
|
+
* Deployed to .claude/helpers/ during ruflo init. On Windows, the
|
|
6
|
+
* generated .claude/settings.json hooks point here instead of the
|
|
7
|
+
* plugin's bash-only ruflo-hook.sh.
|
|
8
|
+
*
|
|
9
|
+
* Always exits 0 — hook subcommands are best-effort telemetry and must
|
|
10
|
+
* never block a Claude Code turn.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const { spawnSync, execSync } = require('child_process');
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
|
|
18
|
+
function done() { process.exit(0); }
|
|
19
|
+
|
|
20
|
+
function commandExists(cmd) {
|
|
21
|
+
try {
|
|
22
|
+
const r = execSync(
|
|
23
|
+
process.platform === 'win32' ? 'where ' + cmd : 'command -v ' + cmd,
|
|
24
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }
|
|
25
|
+
);
|
|
26
|
+
return r.trim().length > 0;
|
|
27
|
+
} catch { return false; }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function invokeHook(bin, binArgs, hookArgs, stdinData) {
|
|
31
|
+
const args = [...binArgs, ...hookArgs];
|
|
32
|
+
const result = spawnSync(bin, args, {
|
|
33
|
+
shell: process.platform === 'win32',
|
|
34
|
+
input: stdinData || '',
|
|
35
|
+
encoding: 'utf8',
|
|
36
|
+
stdio: ['pipe', 'ignore', 'ignore'],
|
|
37
|
+
timeout: 30_000,
|
|
38
|
+
});
|
|
39
|
+
return result.status === 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function main() {
|
|
43
|
+
const args = process.argv.slice(2);
|
|
44
|
+
if (args.length === 0) done();
|
|
45
|
+
|
|
46
|
+
const [subcommand, ...rest] = args;
|
|
47
|
+
|
|
48
|
+
let stdinData = '';
|
|
49
|
+
try { stdinData = fs.readFileSync(0, 'utf8'); } catch { stdinData = ''; }
|
|
50
|
+
|
|
51
|
+
const hookArgs = ['hooks', subcommand, ...rest];
|
|
52
|
+
|
|
53
|
+
if (commandExists('ruflo')) { invokeHook('ruflo', [], hookArgs, stdinData); done(); }
|
|
54
|
+
if (commandExists('claude-flow')) { invokeHook('claude-flow', [], hookArgs, stdinData); done(); }
|
|
55
|
+
invokeHook('npx', ['--prefer-offline', '--yes', 'ruflo@latest'], hookArgs, stdinData);
|
|
56
|
+
done();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
main();
|
|
@@ -10,6 +10,20 @@ const path = require('path');
|
|
|
10
10
|
const SESSION_DIR = path.join(process.cwd(), '.claude-flow', 'sessions');
|
|
11
11
|
const SESSION_FILE = path.join(SESSION_DIR, 'current.json');
|
|
12
12
|
|
|
13
|
+
// #2307: Atomic write — serialize to a per-process temp file, then rename()
|
|
14
|
+
// into place. rename() is atomic on the same filesystem, so concurrent writers
|
|
15
|
+
// (session-restore, metric, daemon workers, teammates) can't interleave partial
|
|
16
|
+
// content. Without this, two non-atomic writeFileSync calls can race so that a
|
|
17
|
+
// shorter payload overwrites a longer one in place, leaving the longer payload's
|
|
18
|
+
// tail dangling past the end (valid JSON + trailing garbage = parse error).
|
|
19
|
+
// Temp name includes process.pid so concurrent writers don't collide on it.
|
|
20
|
+
// Same class as #1707 (metrics) / #1637 (daemon-state) — session.js was missed.
|
|
21
|
+
function atomicWrite(file, data) {
|
|
22
|
+
const tmp = `${file}.tmp.${process.pid}`;
|
|
23
|
+
fs.writeFileSync(tmp, data);
|
|
24
|
+
fs.renameSync(tmp, file);
|
|
25
|
+
}
|
|
26
|
+
|
|
13
27
|
const commands = {
|
|
14
28
|
start: () => {
|
|
15
29
|
const sessionId = `session-${Date.now()}`;
|
|
@@ -27,7 +41,7 @@ const commands = {
|
|
|
27
41
|
};
|
|
28
42
|
|
|
29
43
|
fs.mkdirSync(SESSION_DIR, { recursive: true });
|
|
30
|
-
|
|
44
|
+
atomicWrite(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
31
45
|
|
|
32
46
|
console.log(`Session started: ${sessionId}`);
|
|
33
47
|
return session;
|
|
@@ -39,9 +53,17 @@ const commands = {
|
|
|
39
53
|
return null;
|
|
40
54
|
}
|
|
41
55
|
|
|
42
|
-
|
|
56
|
+
let session;
|
|
57
|
+
try {
|
|
58
|
+
session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
59
|
+
} catch (e) {
|
|
60
|
+
// #2307: corrupted session file (e.g. from a pre-atomic-write race).
|
|
61
|
+
// Don't throw — start a fresh session so the hook recovers cleanly.
|
|
62
|
+
console.log(`Session file corrupted (${e.message}); starting fresh`);
|
|
63
|
+
return commands.start();
|
|
64
|
+
}
|
|
43
65
|
session.restoredAt = new Date().toISOString();
|
|
44
|
-
|
|
66
|
+
atomicWrite(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
45
67
|
|
|
46
68
|
console.log(`Session restored: ${session.id}`);
|
|
47
69
|
return session;
|
|
@@ -59,7 +81,7 @@ const commands = {
|
|
|
59
81
|
|
|
60
82
|
// Archive session
|
|
61
83
|
const archivePath = path.join(SESSION_DIR, `${session.id}.json`);
|
|
62
|
-
|
|
84
|
+
atomicWrite(archivePath, JSON.stringify(session, null, 2));
|
|
63
85
|
fs.unlinkSync(SESSION_FILE);
|
|
64
86
|
|
|
65
87
|
console.log(`Session ended: ${session.id}`);
|
|
@@ -95,7 +117,7 @@ const commands = {
|
|
|
95
117
|
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
96
118
|
session.context[key] = value;
|
|
97
119
|
session.updatedAt = new Date().toISOString();
|
|
98
|
-
|
|
120
|
+
atomicWrite(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
99
121
|
|
|
100
122
|
return session;
|
|
101
123
|
},
|
|
@@ -116,7 +138,7 @@ const commands = {
|
|
|
116
138
|
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
117
139
|
if (session.metrics[name] !== undefined) {
|
|
118
140
|
session.metrics[name]++;
|
|
119
|
-
|
|
141
|
+
atomicWrite(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
120
142
|
}
|
|
121
143
|
|
|
122
144
|
return session;
|
|
@@ -11,8 +11,8 @@ if ! command -v claude &> /dev/null; then
|
|
|
11
11
|
fi
|
|
12
12
|
|
|
13
13
|
# Add MCP server
|
|
14
|
-
echo "📦 Adding
|
|
15
|
-
claude mcp add
|
|
14
|
+
echo "📦 Adding Claude Flow MCP server..."
|
|
15
|
+
claude mcp add claude-flow npx claude-flow mcp start
|
|
16
16
|
|
|
17
17
|
echo "✅ MCP server setup complete!"
|
|
18
|
-
echo "🎯 You can now use
|
|
18
|
+
echo "🎯 You can now use mcp__claude-flow__ tools in Claude Code"
|