agentic-qe 3.8.13 → 3.9.0
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/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +48 -0
- package/dist/adapters/a2ui/integration/agui-sync.js +2 -1
- package/dist/audit/witness-chain.js +15 -3
- package/dist/boot/fast-paths.d.ts +24 -0
- package/dist/boot/fast-paths.js +43 -0
- package/dist/boot/parallel-prefetch.d.ts +26 -0
- package/dist/boot/parallel-prefetch.js +36 -0
- package/dist/cli/bundle.js +12 -9431
- package/dist/cli/chunks/adapter-WBR5NXS3.js +2 -0
- package/dist/cli/chunks/agent-booster-wasm-PQYB7VRU.js +2 -0
- package/dist/cli/chunks/agent-handler-QDAB5NQS.js +33 -0
- package/dist/cli/chunks/aqe-learning-engine-TK4JQCGT.js +2 -0
- package/dist/cli/chunks/audit-S7JUYYVP.js +3 -0
- package/dist/cli/chunks/base-2WXOSMBQ.js +2 -0
- package/dist/cli/chunks/better-sqlite3-7KY2RDXO.js +2 -0
- package/dist/cli/chunks/brain-handler-PPEGDCN4.js +68 -0
- package/dist/cli/chunks/branch-enumerator-XK4V5W7L.js +7 -0
- package/dist/cli/chunks/browser-PALA5PL3.js +4 -0
- package/dist/cli/chunks/browser-workflow-42F7GK5T.js +2 -0
- package/dist/cli/chunks/chunk-24FKIJNC.js +15 -0
- package/dist/cli/chunks/chunk-263XS447.js +2 -0
- package/dist/cli/chunks/chunk-2BZFNEN2.js +4 -0
- package/dist/cli/chunks/chunk-2E5NQNSU.js +180 -0
- package/dist/cli/chunks/chunk-2I7J3O6V.js +2 -0
- package/dist/cli/chunks/chunk-3ADGXLTM.js +14 -0
- package/dist/cli/chunks/chunk-3IHG3WOY.js +12 -0
- package/dist/cli/chunks/chunk-3IUNFTIF.js +2 -0
- package/dist/cli/chunks/chunk-3JPRUND5.js +2 -0
- package/dist/cli/chunks/chunk-3NZLZHJI.js +2 -0
- package/dist/cli/chunks/chunk-3THRQEZ2.js +95 -0
- package/dist/cli/chunks/chunk-3ZOONQG6.js +2 -0
- package/dist/cli/chunks/chunk-4B6NCELM.js +2 -0
- package/dist/cli/chunks/chunk-4I2IOUS4.js +2 -0
- package/dist/cli/chunks/chunk-4VBTXZRM.js +2 -0
- package/dist/cli/chunks/chunk-4VUPRTVX.js +3 -0
- package/dist/cli/chunks/chunk-4YOMLWEK.js +70 -0
- package/dist/cli/chunks/chunk-4YS3IJ45.js +2 -0
- package/dist/cli/chunks/chunk-5SKGFSKD.js +2 -0
- package/dist/cli/chunks/chunk-5T2ZQWKF.js +27 -0
- package/dist/cli/chunks/chunk-62ADTHV7.js +2 -0
- package/dist/cli/chunks/chunk-6EOS7KX2.js +2 -0
- package/dist/cli/chunks/chunk-6SVX4DJC.js +6 -0
- package/dist/cli/chunks/chunk-72WOAVK6.js +2 -0
- package/dist/cli/chunks/chunk-7R6YMLVS.js +3 -0
- package/dist/cli/chunks/chunk-7VDBAVTY.js +2 -0
- package/dist/cli/chunks/chunk-AFLLQ5PP.js +15 -0
- package/dist/cli/chunks/chunk-AKE543X2.js +2 -0
- package/dist/cli/chunks/chunk-B36CDR4U.js +2 -0
- package/dist/cli/chunks/chunk-B6LLWYQ6.js +2 -0
- package/dist/cli/chunks/chunk-BDIEMZ22.js +91 -0
- package/dist/cli/chunks/chunk-BGXNSCXX.js +4 -0
- package/dist/cli/chunks/chunk-BLBRY5UD.js +2 -0
- package/dist/cli/chunks/chunk-BPWXXEH2.js +3029 -0
- package/dist/cli/chunks/chunk-BR26T7ZS.js +180 -0
- package/dist/cli/chunks/chunk-BTREG4IW.js +2 -0
- package/dist/cli/chunks/chunk-BULKFVYX.js +2 -0
- package/dist/cli/chunks/chunk-BXAXGEFC.js +24 -0
- package/dist/cli/chunks/chunk-CL6POIX4.js +2 -0
- package/dist/cli/chunks/chunk-CS2KS7LP.js +2 -0
- package/dist/cli/chunks/chunk-CWFB6BSA.js +316 -0
- package/dist/cli/chunks/chunk-DRT3WKQW.js +2 -0
- package/dist/cli/chunks/chunk-EHDQJQ6Y.js +27 -0
- package/dist/cli/chunks/chunk-ESVQ6MEB.js +2 -0
- package/dist/cli/chunks/chunk-FEKY7T6Q.js +2 -0
- package/dist/cli/chunks/chunk-FGA7VIFR.js +7 -0
- package/dist/cli/chunks/chunk-FIA6X7UL.js +2 -0
- package/dist/cli/chunks/chunk-GAOJV3OX.js +2 -0
- package/dist/cli/chunks/chunk-GKNNSCLC.js +5 -0
- package/dist/cli/chunks/chunk-GPQ57KA4.js +2 -0
- package/dist/cli/chunks/chunk-GRUUQAR6.js +2 -0
- package/dist/cli/chunks/chunk-HRO6OZQD.js +2 -0
- package/dist/cli/chunks/chunk-HY6PMO5W.js +66 -0
- package/dist/cli/chunks/chunk-IAV2JMIX.js +167 -0
- package/dist/cli/chunks/chunk-IFNIIK34.js +21 -0
- package/dist/cli/chunks/chunk-IGJPMN4I.js +3 -0
- package/dist/cli/chunks/chunk-J3KWWR6Z.js +1 -0
- package/dist/cli/chunks/chunk-JBANAPWG.js +2 -0
- package/dist/cli/chunks/chunk-JJO7Y4H3.js +604 -0
- package/dist/cli/chunks/chunk-JRYGQO2W.js +2 -0
- package/dist/cli/chunks/chunk-JXM26HEE.js +2 -0
- package/dist/cli/chunks/chunk-JZSDOIXA.js +2 -0
- package/dist/cli/chunks/chunk-KP5NUODU.js +3 -0
- package/dist/cli/chunks/chunk-LHJQD2VU.js +750 -0
- package/dist/cli/chunks/chunk-LNQIY6BP.js +2 -0
- package/dist/cli/chunks/chunk-MDUHYUHF.js +2 -0
- package/dist/cli/chunks/chunk-MV6CMOJQ.js +65 -0
- package/dist/cli/chunks/chunk-MZOFWJTM.js +2 -0
- package/dist/cli/chunks/chunk-N2NS2PHA.js +45 -0
- package/dist/cli/chunks/chunk-N4TL73TH.js +314 -0
- package/dist/cli/chunks/chunk-N5UXCLFI.js +2 -0
- package/dist/cli/chunks/chunk-NZ2VCPN4.js +2 -0
- package/dist/cli/chunks/chunk-OF4D7MYI.js +2 -0
- package/dist/cli/chunks/chunk-OI5NGQO2.js +2 -0
- package/dist/cli/chunks/chunk-OLHKGP35.js +2 -0
- package/dist/cli/chunks/chunk-QOVHWZEP.js +1 -0
- package/dist/cli/chunks/chunk-RFSN6IDA.js +79 -0
- package/dist/cli/chunks/chunk-RTGGL7D7.js +4 -0
- package/dist/cli/chunks/chunk-RU5WAHB7.js +3 -0
- package/dist/cli/chunks/chunk-SUSEVMZT.js +2 -0
- package/dist/cli/chunks/chunk-TLHP5EII.js +2 -0
- package/dist/cli/chunks/chunk-TWUWL5EJ.js +2 -0
- package/dist/cli/chunks/chunk-U5RN7YQW.js +2 -0
- package/dist/cli/chunks/chunk-UFUVUO3J.js +2 -0
- package/dist/cli/chunks/chunk-UQHYFOBX.js +16 -0
- package/dist/cli/chunks/chunk-VOS4NQSF.js +2 -0
- package/dist/cli/chunks/chunk-VSVXUTJN.js +256 -0
- package/dist/cli/chunks/chunk-WBQSXPBI.js +2 -0
- package/dist/cli/chunks/chunk-WGMPEW2T.js +2 -0
- package/dist/cli/chunks/chunk-WIEC7VKK.js +2 -0
- package/dist/cli/chunks/chunk-WJ3DLOXF.js +14 -0
- package/dist/cli/chunks/chunk-X3KI6JOY.js +9 -0
- package/dist/cli/chunks/chunk-X5IJGWYG.js +2 -0
- package/dist/cli/chunks/chunk-XIBDETCS.js +146 -0
- package/dist/cli/chunks/chunk-XLRQYLWW.js +2 -0
- package/dist/cli/chunks/chunk-XO6PVK2P.js +3 -0
- package/dist/cli/chunks/chunk-XRE2HCWG.js +3 -0
- package/dist/cli/chunks/chunk-XT2V2322.js +2 -0
- package/dist/cli/chunks/chunk-Y7BHKZFJ.js +18 -0
- package/dist/cli/chunks/chunk-YAGODYIG.js +59 -0
- package/dist/cli/chunks/chunk-YANUP2RO.js +2 -0
- package/dist/cli/chunks/chunk-YPFOCNOE.js +30 -0
- package/dist/cli/chunks/chunk-YR6ZZGH7.js +81 -0
- package/dist/cli/chunks/chunk-YVA65UZL.js +2 -0
- package/dist/cli/chunks/chunk-YW2THB5Q.js +2 -0
- package/dist/cli/chunks/chunk-ZAPS3UGQ.js +20 -0
- package/dist/cli/chunks/chunk-ZDATDCYN.js +2 -0
- package/dist/cli/chunks/ci-J374KDLI.js +81 -0
- package/dist/cli/chunks/ci-output-7JN7F6CI.js +2 -0
- package/dist/cli/chunks/claude-flow-setup-245JLJCN.js +2 -0
- package/dist/cli/chunks/client-MCSNSH2C.js +2 -0
- package/dist/cli/chunks/cline-installer-LBA2M5N3.js +4 -0
- package/dist/cli/chunks/code-U4N4WONM.js +38 -0
- package/dist/cli/chunks/code-index-extractor-A57Z6BO4.js +3 -0
- package/dist/cli/chunks/codex-installer-UXMK2N4T.js +8 -0
- package/dist/cli/chunks/completions-W66BSCOE.js +1364 -0
- package/dist/cli/chunks/complexity-analyzer-AB4OZARV.js +2 -0
- package/dist/cli/chunks/continuedev-installer-LRFZ2SJM.js +14 -0
- package/dist/cli/chunks/copilot-installer-CQ3JYBIB.js +3 -0
- package/dist/cli/chunks/cost-tracker-4F723RB6.js +2 -0
- package/dist/cli/chunks/coverage-4PUEQXAY.js +27 -0
- package/dist/cli/chunks/cross-domain-router-OWR5IJ5G.js +2 -0
- package/dist/cli/chunks/cursor-installer-JZEDEDHA.js +3 -0
- package/dist/cli/chunks/daemon-B7TWGHXQ.js +19 -0
- package/dist/cli/chunks/dag-attention-scheduler-JWO6XI6A.js +2 -0
- package/dist/cli/chunks/detect-L6ZZHUSX.js +2 -0
- package/dist/cli/chunks/domain-handler-FT5FLZWL.js +25 -0
- package/dist/cli/chunks/domain-transfer-5Y4FGJAJ.js +2 -0
- package/dist/cli/chunks/dream-4TDBIYED.js +2 -0
- package/dist/cli/chunks/esm-node-2PKHKOTS.js +2 -0
- package/dist/cli/chunks/eval-GHMPFGWV.js +15 -0
- package/dist/cli/chunks/fast-paths-B3R647KN.js +2 -0
- package/dist/cli/chunks/feature-flags-DWS7ARSX.js +2 -0
- package/dist/cli/chunks/feature-flags-IVQ3AL4Q.js +2 -0
- package/dist/cli/chunks/file-discovery-QFPA6GMV.js +2 -0
- package/dist/cli/chunks/fleet-EKOKMOMW.js +43 -0
- package/dist/cli/chunks/gnn-wrapper-OYC55N5E.js +2 -0
- package/dist/cli/chunks/heartbeat-handler-MBBS4IBU.js +48 -0
- package/dist/cli/chunks/heartbeat-scheduler-XDGMOT7X.js +2 -0
- package/dist/cli/chunks/hnsw-index-YO7CT23I.js +2 -0
- package/dist/cli/chunks/hnswlib-node-56YWVXFE.js +2 -0
- package/dist/cli/chunks/hooks-L5VLZGEK.js +101 -0
- package/dist/cli/chunks/hypergraph-engine-A4Y2ZRAG.js +2 -0
- package/dist/cli/chunks/hypergraph-handler-3HDGB5SZ.js +35 -0
- package/dist/cli/chunks/impact-analyzer-UEIGXSZ4.js +2 -0
- package/dist/cli/chunks/init-handler-JDET6WUN.js +68 -0
- package/dist/cli/chunks/init-wizard-JWZUGIPJ.js +2 -0
- package/dist/cli/chunks/kernel-YNDTVKIW.js +2 -0
- package/dist/cli/chunks/kilocode-installer-GZZG5AFW.js +4 -0
- package/dist/cli/chunks/kiro-installer-IWNY5TKH.js +74 -0
- package/dist/cli/chunks/knowledge-graph-NGJKFTSN.js +2 -0
- package/dist/cli/chunks/learning-722ZNSZ6.js +107 -0
- package/dist/cli/chunks/llm-router-DNAV746L.js +30 -0
- package/dist/cli/chunks/load-Y3GCUFM4.js +2 -0
- package/dist/cli/chunks/load-test-GZUBXFF3.js +2 -0
- package/dist/cli/chunks/mcp-LKPIBZ3W.js +2 -0
- package/dist/cli/chunks/memory-L57MLFOP.js +32 -0
- package/dist/cli/chunks/memory-backend-3NQIZUXE.js +2 -0
- package/dist/cli/chunks/memory-handlers-MDZQ7HVW.js +2 -0
- package/dist/cli/chunks/opencode-installer-4HUB36H5.js +3 -0
- package/dist/cli/chunks/orchestrator-QHSBB2UC.js +371 -0
- package/dist/cli/chunks/pipeline-D3QER35Z.js +19 -0
- package/dist/cli/chunks/platform-T4E7Q3RD.js +2 -0
- package/dist/cli/chunks/plugin-JHW2YPRC.js +27 -0
- package/dist/cli/chunks/prime-radiant-advanced-wasm-G7CFNNQV.js +2 -0
- package/dist/cli/chunks/protocol-executor-SPUVRDWT.js +2 -0
- package/dist/cli/chunks/protocol-handler-2BQQ4HDM.js +20 -0
- package/dist/cli/chunks/prove-UQ6JFT73.js +3 -0
- package/dist/cli/chunks/qe-reasoning-bank-3HBK2FVD.js +2 -0
- package/dist/cli/chunks/quality-JRZYMC77.js +7 -0
- package/dist/cli/chunks/queen-coordinator-RW3NKO5A.js +2 -0
- package/dist/cli/chunks/real-embeddings-GK63VF35.js +2 -0
- package/dist/cli/chunks/roocode-installer-F4E2LAYR.js +4 -0
- package/dist/cli/chunks/router-RJGHWDQ3.js +2 -0
- package/dist/cli/chunks/routing-feedback-ZXBXFKX6.js +2 -0
- package/dist/cli/chunks/routing-handler-VNKFUUGB.js +20 -0
- package/dist/cli/chunks/ruvector-commands-2TLNHC3A.js +8 -0
- package/dist/cli/chunks/rvf-dual-writer-MQW2SJLT.js +2 -0
- package/dist/cli/chunks/rvf-native-adapter-LKFKTMUN.js +2 -0
- package/dist/cli/chunks/safe-db-G22E5ROA.js +2 -0
- package/dist/cli/chunks/schedule-Y7VVCPYV.js +2 -0
- package/dist/cli/chunks/scheduler-AUQIFQB7.js +2 -0
- package/dist/cli/chunks/security-EBEG2OPU.js +14 -0
- package/dist/cli/chunks/shared-rvf-dual-writer-BVSCQAFS.js +2 -0
- package/dist/cli/chunks/sqlite-persistence-JAVHUGGL.js +2 -0
- package/dist/cli/chunks/status-handler-VZ32M4G4.js +45 -0
- package/dist/cli/chunks/structural-health-K6LRCKV6.js +2 -0
- package/dist/cli/chunks/sync-MHSHNLIM.js +23 -0
- package/dist/cli/chunks/task-handler-JNOIBZ2G.js +49 -0
- package/dist/cli/chunks/task-handlers-P5DSUKND.js +2 -0
- package/dist/cli/chunks/test-DO22BNIL.js +33 -0
- package/dist/cli/chunks/test-scheduling-VLRQZEFL.js +15 -0
- package/dist/cli/chunks/token-bootstrap-4VJKGVMK.js +2 -0
- package/dist/cli/chunks/token-usage-LG3PXRXH.js +25 -0
- package/dist/cli/chunks/transformers-GY7SIKEU.js +2 -0
- package/dist/cli/chunks/tree-sitter-wasm-parser-FT2KB66N.js +2 -0
- package/dist/cli/chunks/types-QJGNBKP2.js +2 -0
- package/dist/cli/chunks/unified-memory-XYGENQUT.js +2 -0
- package/dist/cli/chunks/unified-memory-hnsw-MVEGQBF3.js +2 -0
- package/dist/cli/chunks/unified-persistence-PFRCWEUG.js +2 -0
- package/dist/cli/chunks/validate-VQCRSVNQ.js +21 -0
- package/dist/cli/chunks/validate-swarm-A5DHAWTP.js +14 -0
- package/dist/cli/chunks/vibium-RZBSL4EB.js +2 -0
- package/dist/cli/chunks/visual-security-V47BLGJM.js +2 -0
- package/dist/cli/chunks/web-tree-sitter-7C4NXEOF.js +2 -0
- package/dist/cli/chunks/windsurf-installer-ES3KPQG3.js +7 -0
- package/dist/cli/chunks/witness-chain-BR63P4A7.js +2 -0
- package/dist/cli/chunks/workflow-JETHX4ML.js +51 -0
- package/dist/cli/chunks/workflow-orchestrator-7PZMX3JZ.js +2 -0
- package/dist/cli/chunks/wrappers-WP5RH745.js +2 -0
- package/dist/cli/commands/daemon.d.ts +13 -0
- package/dist/cli/commands/daemon.js +224 -0
- package/dist/cli/commands/hooks-handlers/hooks-shared.js +2 -1
- package/dist/cli/commands/plugin.d.ts +12 -0
- package/dist/cli/commands/plugin.js +135 -0
- package/dist/cli/commands/workflow.d.ts +10 -0
- package/dist/cli/commands/workflow.js +587 -0
- package/dist/cli/handlers/brain-handler.js +13 -8
- package/dist/cli/handlers/heartbeat-handler.d.ts +1 -0
- package/dist/cli/handlers/heartbeat-handler.js +20 -10
- package/dist/cli/handlers/hypergraph-handler.js +3 -3
- package/dist/cli/handlers/init-handler.js +10 -9
- package/dist/cli/handlers/interfaces.d.ts +4 -4
- package/dist/cli/index.js +159 -638
- package/dist/cli/lazy-registry.d.ts +27 -0
- package/dist/cli/lazy-registry.js +70 -0
- package/dist/context/compaction/context-budget.d.ts +71 -0
- package/dist/context/compaction/context-budget.js +120 -0
- package/dist/context/compaction/index.d.ts +96 -0
- package/dist/context/compaction/index.js +259 -0
- package/dist/context/compaction/llm-caller-adapter.d.ts +14 -0
- package/dist/context/compaction/llm-caller-adapter.js +47 -0
- package/dist/context/compaction/tier1-microcompact.d.ts +33 -0
- package/dist/context/compaction/tier1-microcompact.js +47 -0
- package/dist/context/compaction/tier2-session-summary.d.ts +72 -0
- package/dist/context/compaction/tier2-session-summary.js +172 -0
- package/dist/context/compaction/tier3-llm-compact.d.ts +65 -0
- package/dist/context/compaction/tier3-llm-compact.js +166 -0
- package/dist/context/compaction/tier4-reactive.d.ts +54 -0
- package/dist/context/compaction/tier4-reactive.js +129 -0
- package/dist/coordination/consensus/providers/claude-provider.d.ts +1 -0
- package/dist/coordination/consensus/providers/claude-provider.js +23 -3
- package/dist/domains/test-generation/generators/base-test-generator.d.ts +1 -1
- package/dist/domains/test-generation/generators/base-test-generator.js +11 -11
- package/dist/domains/test-generation/generators/go-test-generator.js +12 -12
- package/dist/domains/test-generation/generators/junit5-generator.js +9 -9
- package/dist/domains/test-generation/generators/kotlin-junit-generator.js +10 -10
- package/dist/domains/test-generation/generators/pytest-generator.js +8 -8
- package/dist/domains/test-generation/generators/swift-testing-generator.js +8 -8
- package/dist/domains/test-generation/generators/test-value-helpers.d.ts +20 -0
- package/dist/domains/test-generation/generators/test-value-helpers.js +48 -0
- package/dist/domains/test-generation/generators/xunit-generator.js +11 -11
- package/dist/hooks/cross-phase-hooks.d.ts +11 -0
- package/dist/hooks/cross-phase-hooks.js +73 -9
- package/dist/hooks/security/config-snapshot.d.ts +21 -0
- package/dist/hooks/security/config-snapshot.js +33 -0
- package/dist/hooks/security/exit-codes.d.ts +28 -0
- package/dist/hooks/security/exit-codes.js +33 -0
- package/dist/hooks/security/index.d.ts +15 -0
- package/dist/hooks/security/index.js +15 -0
- package/dist/hooks/security/ssrf-guard.d.ts +25 -0
- package/dist/hooks/security/ssrf-guard.js +69 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -2
- package/dist/init/init-wizard-hooks.js +15 -1
- package/dist/init/phases/07-hooks.js +2 -2
- package/dist/init/settings-merge.js +3 -7
- package/dist/kernel/kernel.js +35 -0
- package/dist/kernel/memory-backend.js +3 -1
- package/dist/mcp/bundle.js +416 -362
- package/dist/mcp/entry.js +132 -77
- package/dist/mcp/http-server.js +4 -1
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +5 -4
- package/dist/mcp/middleware/batch-executor.d.ts +46 -0
- package/dist/mcp/middleware/batch-executor.js +150 -0
- package/dist/mcp/middleware/microcompact.d.ts +97 -0
- package/dist/mcp/middleware/microcompact.js +179 -0
- package/dist/mcp/middleware/middleware-chain.d.ts +37 -0
- package/dist/mcp/middleware/middleware-chain.js +60 -0
- package/dist/mcp/protocol-server.d.ts +16 -0
- package/dist/mcp/protocol-server.js +140 -36
- package/dist/mcp/services/session-durability-middleware.d.ts +22 -0
- package/dist/mcp/services/session-durability-middleware.js +64 -0
- package/dist/mcp/services/session-resume.d.ts +29 -0
- package/dist/mcp/services/session-resume.js +221 -0
- package/dist/mcp/services/session-store.d.ts +84 -0
- package/dist/mcp/services/session-store.js +163 -0
- package/dist/mcp/tool-registry.d.ts +9 -0
- package/dist/mcp/tool-registry.js +30 -1
- package/dist/mcp/types.d.ts +1 -0
- package/dist/plugins/cache.d.ts +44 -0
- package/dist/plugins/cache.js +149 -0
- package/dist/plugins/index.d.ts +15 -0
- package/dist/plugins/index.js +15 -0
- package/dist/plugins/lifecycle.d.ts +67 -0
- package/dist/plugins/lifecycle.js +175 -0
- package/dist/plugins/manifest.d.ts +45 -0
- package/dist/plugins/manifest.js +173 -0
- package/dist/plugins/resolver.d.ts +37 -0
- package/dist/plugins/resolver.js +80 -0
- package/dist/plugins/security.d.ts +23 -0
- package/dist/plugins/security.js +125 -0
- package/dist/plugins/sources/github.d.ts +17 -0
- package/dist/plugins/sources/github.js +77 -0
- package/dist/plugins/sources/local.d.ts +20 -0
- package/dist/plugins/sources/local.js +32 -0
- package/dist/plugins/sources/npm.d.ts +18 -0
- package/dist/plugins/sources/npm.js +82 -0
- package/dist/shared/llm/retry.d.ts +5 -2
- package/dist/shared/llm/retry.js +7 -3
- package/dist/shared/prompt-cache-latch.d.ts +41 -0
- package/dist/shared/prompt-cache-latch.js +63 -0
- package/dist/shared/retry-engine.d.ts +77 -0
- package/dist/shared/retry-engine.js +194 -0
- package/dist/workers/daemon.d.ts +8 -0
- package/dist/workers/daemon.js +13 -0
- package/dist/workers/quality-daemon/ci-monitor.d.ts +55 -0
- package/dist/workers/quality-daemon/ci-monitor.js +147 -0
- package/dist/workers/quality-daemon/coverage-delta.d.ts +72 -0
- package/dist/workers/quality-daemon/coverage-delta.js +135 -0
- package/dist/workers/quality-daemon/git-watcher.d.ts +51 -0
- package/dist/workers/quality-daemon/git-watcher.js +209 -0
- package/dist/workers/quality-daemon/index.d.ts +119 -0
- package/dist/workers/quality-daemon/index.js +343 -0
- package/dist/workers/quality-daemon/nightly-consolidation.d.ts +74 -0
- package/dist/workers/quality-daemon/nightly-consolidation.js +136 -0
- package/dist/workers/quality-daemon/notification-service.d.ts +67 -0
- package/dist/workers/quality-daemon/notification-service.js +178 -0
- package/dist/workers/quality-daemon/persistent-memory.d.ts +31 -0
- package/dist/workers/quality-daemon/persistent-memory.js +30 -0
- package/dist/workers/quality-daemon/priority-queue.d.ts +97 -0
- package/dist/workers/quality-daemon/priority-queue.js +126 -0
- package/dist/workers/quality-daemon/test-suggester.d.ts +50 -0
- package/dist/workers/quality-daemon/test-suggester.js +121 -0
- package/dist/workers/worker-manager.js +2 -1
- package/package.json +1 -1
- package/dist/mcp/server.d.ts +0 -46
- package/dist/mcp/server.js +0 -802
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Session Resume Service
|
|
3
|
+
*
|
|
4
|
+
* IMP-04: Transcript-First Session Durability
|
|
5
|
+
* Reads an existing JSONL session file by sampling the head (first 4KB)
|
|
6
|
+
* and tail (last 64KB) to reconstruct metadata and recent entries
|
|
7
|
+
* without reading the entire file.
|
|
8
|
+
*
|
|
9
|
+
* @module mcp/services/session-resume
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
const HEAD_BYTES = 4 * 1024; // 4KB
|
|
17
|
+
const TAIL_BYTES = 64 * 1024; // 64KB
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Public API
|
|
20
|
+
// ============================================================================
|
|
21
|
+
/**
|
|
22
|
+
* Resume a session from a JSONL file.
|
|
23
|
+
*
|
|
24
|
+
* Reads the first 4KB (head) to extract session start metadata and
|
|
25
|
+
* the last 64KB (tail) to get recent entries. Parses JSONL lines,
|
|
26
|
+
* reconstructs the parentUuid linked list, and returns metadata +
|
|
27
|
+
* recent entries + resume capability.
|
|
28
|
+
*
|
|
29
|
+
* Corrupt or incomplete lines are skipped gracefully.
|
|
30
|
+
*/
|
|
31
|
+
export function resumeSession(filePath) {
|
|
32
|
+
// If file doesn't exist, return non-resumable result
|
|
33
|
+
if (!fs.existsSync(filePath)) {
|
|
34
|
+
return {
|
|
35
|
+
metadata: {
|
|
36
|
+
sessionId: extractSessionId(filePath),
|
|
37
|
+
createdAt: 0,
|
|
38
|
+
lastActivityAt: 0,
|
|
39
|
+
entryCount: 0,
|
|
40
|
+
state: 'idle',
|
|
41
|
+
},
|
|
42
|
+
recentEntries: [],
|
|
43
|
+
lastState: 'idle',
|
|
44
|
+
canResume: false,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const stat = fs.statSync(filePath);
|
|
48
|
+
const fileSize = stat.size;
|
|
49
|
+
if (fileSize === 0) {
|
|
50
|
+
return {
|
|
51
|
+
metadata: {
|
|
52
|
+
sessionId: extractSessionId(filePath),
|
|
53
|
+
createdAt: 0,
|
|
54
|
+
lastActivityAt: 0,
|
|
55
|
+
entryCount: 0,
|
|
56
|
+
state: 'idle',
|
|
57
|
+
},
|
|
58
|
+
recentEntries: [],
|
|
59
|
+
lastState: 'idle',
|
|
60
|
+
canResume: false,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Read head (first 4KB)
|
|
64
|
+
const headEntries = readHead(filePath, fileSize);
|
|
65
|
+
// Read tail (last 64KB)
|
|
66
|
+
const tailEntries = readTail(filePath, fileSize);
|
|
67
|
+
// Merge and deduplicate: use a Map keyed by uuid to ensure uniqueness
|
|
68
|
+
const entryMap = new Map();
|
|
69
|
+
for (const entry of headEntries) {
|
|
70
|
+
entryMap.set(entry.uuid, entry);
|
|
71
|
+
}
|
|
72
|
+
for (const entry of tailEntries) {
|
|
73
|
+
entryMap.set(entry.uuid, entry);
|
|
74
|
+
}
|
|
75
|
+
const allEntries = Array.from(entryMap.values());
|
|
76
|
+
allEntries.sort((a, b) => a.timestamp - b.timestamp);
|
|
77
|
+
// Reconstruct metadata from available entries
|
|
78
|
+
const firstEntry = headEntries[0] ?? allEntries[0];
|
|
79
|
+
const lastEntry = tailEntries[tailEntries.length - 1] ?? allEntries[allEntries.length - 1];
|
|
80
|
+
// For entry count: if file is small enough that head+tail overlap,
|
|
81
|
+
// allEntries.length is accurate. Otherwise, count total lines.
|
|
82
|
+
let entryCount;
|
|
83
|
+
if (fileSize <= HEAD_BYTES + TAIL_BYTES) {
|
|
84
|
+
entryCount = allEntries.length;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
entryCount = countLines(filePath);
|
|
88
|
+
}
|
|
89
|
+
const lastState = lastEntry?.state ?? 'idle';
|
|
90
|
+
const metadata = {
|
|
91
|
+
sessionId: extractSessionId(filePath),
|
|
92
|
+
createdAt: firstEntry?.timestamp ?? 0,
|
|
93
|
+
lastActivityAt: lastEntry?.timestamp ?? 0,
|
|
94
|
+
entryCount,
|
|
95
|
+
state: lastState,
|
|
96
|
+
};
|
|
97
|
+
return {
|
|
98
|
+
metadata,
|
|
99
|
+
recentEntries: tailEntries,
|
|
100
|
+
lastState,
|
|
101
|
+
canResume: allEntries.length > 0,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// ============================================================================
|
|
105
|
+
// Private helpers
|
|
106
|
+
// ============================================================================
|
|
107
|
+
/**
|
|
108
|
+
* Extract session ID from file path (filename without extension).
|
|
109
|
+
*/
|
|
110
|
+
function extractSessionId(filePath) {
|
|
111
|
+
return path.basename(filePath, '.jsonl');
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Read and parse the first HEAD_BYTES of the file.
|
|
115
|
+
*/
|
|
116
|
+
function readHead(filePath, fileSize) {
|
|
117
|
+
const bytesToRead = Math.min(HEAD_BYTES, fileSize);
|
|
118
|
+
const fd = fs.openSync(filePath, 'r');
|
|
119
|
+
try {
|
|
120
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
121
|
+
fs.readSync(fd, buffer, 0, bytesToRead, 0);
|
|
122
|
+
const text = buffer.toString('utf-8');
|
|
123
|
+
return parseJsonlLines(text, /* isHead */ true);
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
fs.closeSync(fd);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Read and parse the last TAIL_BYTES of the file.
|
|
131
|
+
*/
|
|
132
|
+
function readTail(filePath, fileSize) {
|
|
133
|
+
const bytesToRead = Math.min(TAIL_BYTES, fileSize);
|
|
134
|
+
const offset = Math.max(0, fileSize - bytesToRead);
|
|
135
|
+
const fd = fs.openSync(filePath, 'r');
|
|
136
|
+
try {
|
|
137
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
138
|
+
fs.readSync(fd, buffer, 0, bytesToRead, offset);
|
|
139
|
+
const text = buffer.toString('utf-8');
|
|
140
|
+
// When offset is 0, we read from the start of the file so
|
|
141
|
+
// the first line is complete -- don't skip it.
|
|
142
|
+
const isMidFileRead = offset > 0;
|
|
143
|
+
return parseJsonlLines(text, /* isHead */ false, isMidFileRead);
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
fs.closeSync(fd);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Parse JSONL text into SessionEntry[], skipping corrupt/incomplete lines.
|
|
151
|
+
* When reading from a mid-file offset (tail), the first partial line is skipped.
|
|
152
|
+
* When reading head, the last partial line is skipped if the chunk doesn't
|
|
153
|
+
* end with a newline.
|
|
154
|
+
*
|
|
155
|
+
* @param text - Raw text from the file chunk
|
|
156
|
+
* @param isHead - Whether this is a head read (skip trailing partial line)
|
|
157
|
+
* @param skipFirstLine - Whether to skip the first line (true for mid-file
|
|
158
|
+
* tail reads where the first line is likely a partial). Defaults to !isHead.
|
|
159
|
+
*/
|
|
160
|
+
function parseJsonlLines(text, isHead, skipFirstLine) {
|
|
161
|
+
const lines = text.split('\n');
|
|
162
|
+
const entries = [];
|
|
163
|
+
// Default: skip first line for non-head reads (standard tail behavior)
|
|
164
|
+
const shouldSkipFirst = skipFirstLine ?? !isHead;
|
|
165
|
+
for (let i = 0; i < lines.length; i++) {
|
|
166
|
+
const line = lines[i].trim();
|
|
167
|
+
if (!line)
|
|
168
|
+
continue;
|
|
169
|
+
// Skip first line of mid-file tail read (may be partial)
|
|
170
|
+
if (shouldSkipFirst && i === 0 && lines.length > 1)
|
|
171
|
+
continue;
|
|
172
|
+
// Skip last line of head read if it may be truncated
|
|
173
|
+
if (isHead && i === lines.length - 1 && lines.length > 1 && !text.endsWith('\n'))
|
|
174
|
+
continue;
|
|
175
|
+
try {
|
|
176
|
+
const entry = JSON.parse(line);
|
|
177
|
+
if (isValidEntry(entry)) {
|
|
178
|
+
entries.push(entry);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// Skip corrupt lines
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return entries;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Minimal validation that a parsed object looks like a SessionEntry.
|
|
190
|
+
*/
|
|
191
|
+
function isValidEntry(obj) {
|
|
192
|
+
if (typeof obj !== 'object' || obj === null)
|
|
193
|
+
return false;
|
|
194
|
+
const entry = obj;
|
|
195
|
+
return (typeof entry.uuid === 'string' &&
|
|
196
|
+
typeof entry.timestamp === 'number' &&
|
|
197
|
+
typeof entry.type === 'string' &&
|
|
198
|
+
typeof entry.state === 'string');
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Count total lines in a file (for large files where head+tail don't overlap).
|
|
202
|
+
* Only counts non-empty lines that parse as valid JSON.
|
|
203
|
+
*/
|
|
204
|
+
function countLines(filePath) {
|
|
205
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
206
|
+
let count = 0;
|
|
207
|
+
for (const line of content.split('\n')) {
|
|
208
|
+
const trimmed = line.trim();
|
|
209
|
+
if (trimmed) {
|
|
210
|
+
try {
|
|
211
|
+
JSON.parse(trimmed);
|
|
212
|
+
count++;
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Skip corrupt lines in count
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return count;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=session-resume.js.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Append-Only JSONL Session Store
|
|
3
|
+
*
|
|
4
|
+
* IMP-04: Transcript-First Session Durability
|
|
5
|
+
* Provides an append-only JSONL log of all tool calls, results, and state
|
|
6
|
+
* changes within a session. Supports write batching (100ms window) and
|
|
7
|
+
* lazy file creation (no file until first append).
|
|
8
|
+
*
|
|
9
|
+
* @module mcp/services/session-store
|
|
10
|
+
*/
|
|
11
|
+
export interface SessionEntry {
|
|
12
|
+
uuid: string;
|
|
13
|
+
parentUuid: string | null;
|
|
14
|
+
timestamp: number;
|
|
15
|
+
type: 'tool_call' | 'tool_result' | 'state_change' | 'error';
|
|
16
|
+
toolName?: string;
|
|
17
|
+
params?: Record<string, unknown>;
|
|
18
|
+
result?: unknown;
|
|
19
|
+
state: 'idle' | 'running' | 'requires_action';
|
|
20
|
+
tokenEstimate?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface SessionMetadata {
|
|
23
|
+
sessionId: string;
|
|
24
|
+
createdAt: number;
|
|
25
|
+
lastActivityAt: number;
|
|
26
|
+
entryCount: number;
|
|
27
|
+
state: 'idle' | 'running' | 'requires_action';
|
|
28
|
+
}
|
|
29
|
+
export type SessionEntryInput = Omit<SessionEntry, 'uuid' | 'parentUuid'>;
|
|
30
|
+
export declare class SessionStore {
|
|
31
|
+
private readonly sessionDir;
|
|
32
|
+
private sessionId;
|
|
33
|
+
private filePath;
|
|
34
|
+
private fileCreated;
|
|
35
|
+
private lastUuid;
|
|
36
|
+
private entryCount;
|
|
37
|
+
private createdAt;
|
|
38
|
+
private lastActivityAt;
|
|
39
|
+
private currentState;
|
|
40
|
+
private writeBuffer;
|
|
41
|
+
private flushTimer;
|
|
42
|
+
private closed;
|
|
43
|
+
constructor(sessionDir?: string);
|
|
44
|
+
/**
|
|
45
|
+
* Start a new session. Returns the sessionId (UUID).
|
|
46
|
+
* File is NOT created until the first append (lazy creation).
|
|
47
|
+
*/
|
|
48
|
+
startSession(): string;
|
|
49
|
+
/**
|
|
50
|
+
* Append an entry to the session log.
|
|
51
|
+
* Assigns a uuid, links parentUuid to the previous entry,
|
|
52
|
+
* and writes a JSON line to the file.
|
|
53
|
+
*
|
|
54
|
+
* First write uses appendFileSync for write-ahead guarantee.
|
|
55
|
+
* Subsequent writes are batched for up to 100ms before flushing.
|
|
56
|
+
*
|
|
57
|
+
* Returns the assigned uuid.
|
|
58
|
+
*/
|
|
59
|
+
append(entry: SessionEntryInput): string;
|
|
60
|
+
/**
|
|
61
|
+
* Force sync any buffered writes to disk immediately.
|
|
62
|
+
*/
|
|
63
|
+
flush(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Returns metadata about the current session.
|
|
66
|
+
*/
|
|
67
|
+
getMetadata(): SessionMetadata;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the current session ID, or null if no session is active.
|
|
70
|
+
*/
|
|
71
|
+
getSessionId(): string | null;
|
|
72
|
+
/**
|
|
73
|
+
* Flush pending writes and mark the session as complete.
|
|
74
|
+
*/
|
|
75
|
+
close(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Returns the file path for the current session, or null.
|
|
78
|
+
* Exposed for testing and resume integration.
|
|
79
|
+
*/
|
|
80
|
+
getFilePath(): string | null;
|
|
81
|
+
private ensureDirectory;
|
|
82
|
+
private scheduleBatchFlush;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=session-store.d.ts.map
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Append-Only JSONL Session Store
|
|
3
|
+
*
|
|
4
|
+
* IMP-04: Transcript-First Session Durability
|
|
5
|
+
* Provides an append-only JSONL log of all tool calls, results, and state
|
|
6
|
+
* changes within a session. Supports write batching (100ms window) and
|
|
7
|
+
* lazy file creation (no file until first append).
|
|
8
|
+
*
|
|
9
|
+
* @module mcp/services/session-store
|
|
10
|
+
*/
|
|
11
|
+
import { randomUUID } from 'crypto';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Session Store
|
|
16
|
+
// ============================================================================
|
|
17
|
+
const DEFAULT_SESSION_DIR = '.agentic-qe/sessions';
|
|
18
|
+
const BATCH_FLUSH_MS = 100;
|
|
19
|
+
export class SessionStore {
|
|
20
|
+
sessionDir;
|
|
21
|
+
sessionId = null;
|
|
22
|
+
filePath = null;
|
|
23
|
+
fileCreated = false;
|
|
24
|
+
lastUuid = null;
|
|
25
|
+
entryCount = 0;
|
|
26
|
+
createdAt = 0;
|
|
27
|
+
lastActivityAt = 0;
|
|
28
|
+
currentState = 'idle';
|
|
29
|
+
writeBuffer = [];
|
|
30
|
+
flushTimer = null;
|
|
31
|
+
closed = false;
|
|
32
|
+
constructor(sessionDir) {
|
|
33
|
+
this.sessionDir = sessionDir ?? DEFAULT_SESSION_DIR;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Start a new session. Returns the sessionId (UUID).
|
|
37
|
+
* File is NOT created until the first append (lazy creation).
|
|
38
|
+
*/
|
|
39
|
+
startSession() {
|
|
40
|
+
if (this.sessionId !== null) {
|
|
41
|
+
this.close();
|
|
42
|
+
}
|
|
43
|
+
this.sessionId = randomUUID();
|
|
44
|
+
this.filePath = path.join(this.sessionDir, `${this.sessionId}.jsonl`);
|
|
45
|
+
this.fileCreated = false;
|
|
46
|
+
this.lastUuid = null;
|
|
47
|
+
this.entryCount = 0;
|
|
48
|
+
this.createdAt = Date.now();
|
|
49
|
+
this.lastActivityAt = this.createdAt;
|
|
50
|
+
this.currentState = 'idle';
|
|
51
|
+
this.writeBuffer = [];
|
|
52
|
+
this.flushTimer = null;
|
|
53
|
+
this.closed = false;
|
|
54
|
+
return this.sessionId;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Append an entry to the session log.
|
|
58
|
+
* Assigns a uuid, links parentUuid to the previous entry,
|
|
59
|
+
* and writes a JSON line to the file.
|
|
60
|
+
*
|
|
61
|
+
* First write uses appendFileSync for write-ahead guarantee.
|
|
62
|
+
* Subsequent writes are batched for up to 100ms before flushing.
|
|
63
|
+
*
|
|
64
|
+
* Returns the assigned uuid.
|
|
65
|
+
*/
|
|
66
|
+
append(entry) {
|
|
67
|
+
if (!this.sessionId || this.closed) {
|
|
68
|
+
throw new Error('No active session. Call startSession() first.');
|
|
69
|
+
}
|
|
70
|
+
const uuid = randomUUID();
|
|
71
|
+
const fullEntry = {
|
|
72
|
+
...entry,
|
|
73
|
+
uuid,
|
|
74
|
+
parentUuid: this.lastUuid,
|
|
75
|
+
};
|
|
76
|
+
this.lastUuid = uuid;
|
|
77
|
+
this.entryCount++;
|
|
78
|
+
this.lastActivityAt = fullEntry.timestamp;
|
|
79
|
+
this.currentState = fullEntry.state;
|
|
80
|
+
const line = JSON.stringify(fullEntry) + '\n';
|
|
81
|
+
if (!this.fileCreated) {
|
|
82
|
+
// First write: synchronous for write-ahead guarantee
|
|
83
|
+
this.ensureDirectory();
|
|
84
|
+
fs.appendFileSync(this.filePath, line, 'utf-8');
|
|
85
|
+
this.fileCreated = true;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Subsequent writes: buffer and batch
|
|
89
|
+
this.writeBuffer.push(line);
|
|
90
|
+
this.scheduleBatchFlush();
|
|
91
|
+
}
|
|
92
|
+
return uuid;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Force sync any buffered writes to disk immediately.
|
|
96
|
+
*/
|
|
97
|
+
flush() {
|
|
98
|
+
if (this.flushTimer !== null) {
|
|
99
|
+
clearTimeout(this.flushTimer);
|
|
100
|
+
this.flushTimer = null;
|
|
101
|
+
}
|
|
102
|
+
if (this.writeBuffer.length > 0 && this.filePath && this.fileCreated) {
|
|
103
|
+
const batch = this.writeBuffer.join('');
|
|
104
|
+
this.writeBuffer = [];
|
|
105
|
+
fs.appendFileSync(this.filePath, batch, 'utf-8');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Returns metadata about the current session.
|
|
110
|
+
*/
|
|
111
|
+
getMetadata() {
|
|
112
|
+
if (!this.sessionId) {
|
|
113
|
+
throw new Error('No active session. Call startSession() first.');
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
sessionId: this.sessionId,
|
|
117
|
+
createdAt: this.createdAt,
|
|
118
|
+
lastActivityAt: this.lastActivityAt,
|
|
119
|
+
entryCount: this.entryCount,
|
|
120
|
+
state: this.currentState,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Returns the current session ID, or null if no session is active.
|
|
125
|
+
*/
|
|
126
|
+
getSessionId() {
|
|
127
|
+
return this.sessionId;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Flush pending writes and mark the session as complete.
|
|
131
|
+
*/
|
|
132
|
+
close() {
|
|
133
|
+
if (this.closed)
|
|
134
|
+
return;
|
|
135
|
+
this.flush();
|
|
136
|
+
this.closed = true;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Returns the file path for the current session, or null.
|
|
140
|
+
* Exposed for testing and resume integration.
|
|
141
|
+
*/
|
|
142
|
+
getFilePath() {
|
|
143
|
+
return this.filePath;
|
|
144
|
+
}
|
|
145
|
+
// --------------------------------------------------------------------------
|
|
146
|
+
// Private helpers
|
|
147
|
+
// --------------------------------------------------------------------------
|
|
148
|
+
ensureDirectory() {
|
|
149
|
+
const dir = path.dirname(this.filePath);
|
|
150
|
+
if (!fs.existsSync(dir)) {
|
|
151
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
scheduleBatchFlush() {
|
|
155
|
+
if (this.flushTimer === null) {
|
|
156
|
+
this.flushTimer = setTimeout(() => {
|
|
157
|
+
this.flushTimer = null;
|
|
158
|
+
this.flush();
|
|
159
|
+
}, BATCH_FLUSH_MS);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=session-store.js.map
|
|
@@ -90,6 +90,15 @@ export declare class ToolRegistry {
|
|
|
90
90
|
* Clear all tools
|
|
91
91
|
*/
|
|
92
92
|
clear(): void;
|
|
93
|
+
/**
|
|
94
|
+
* IMP-02: Invoke multiple tools with concurrency partitioning.
|
|
95
|
+
* Concurrent-safe tools (isConcurrencySafe: true) run in parallel batches.
|
|
96
|
+
* Non-safe tools run sequentially between batches.
|
|
97
|
+
*/
|
|
98
|
+
invokeBatch(calls: Array<{
|
|
99
|
+
name: string;
|
|
100
|
+
params: Record<string, unknown>;
|
|
101
|
+
}>): Promise<Array<ToolResult<unknown>>>;
|
|
93
102
|
/**
|
|
94
103
|
* Create result metadata
|
|
95
104
|
*/
|
|
@@ -8,6 +8,8 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
8
8
|
import { ALL_DOMAINS } from '../shared/types';
|
|
9
9
|
import { sanitizeInput } from './security/cve-prevention';
|
|
10
10
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
11
|
+
import { BatchToolExecutor } from './middleware/batch-executor';
|
|
12
|
+
import { withRetry, isRetryableError } from '../shared/retry-engine';
|
|
11
13
|
// ============================================================================
|
|
12
14
|
// Security: Input Validation (SEC-001 Fix)
|
|
13
15
|
// ============================================================================
|
|
@@ -363,12 +365,21 @@ export class ToolRegistry {
|
|
|
363
365
|
tool.lastUsed = new Date();
|
|
364
366
|
this.stats.invocations++;
|
|
365
367
|
try {
|
|
366
|
-
|
|
368
|
+
// IMP-03: Wrap tool handler with unified retry engine
|
|
369
|
+
const retryResult = await withRetry(() => tool.handler(sanitizedParams), {
|
|
370
|
+
maxAttempts: 3,
|
|
371
|
+
baseDelayMs: 500,
|
|
372
|
+
maxDelayMs: 4000,
|
|
373
|
+
jitterFraction: 0.25,
|
|
374
|
+
retryableErrors: isRetryableError,
|
|
375
|
+
});
|
|
376
|
+
const result = retryResult.result;
|
|
367
377
|
return {
|
|
368
378
|
...result,
|
|
369
379
|
metadata: {
|
|
370
380
|
...result.metadata,
|
|
371
381
|
...this.createMetadata(startTime, requestId, tool.definition.domain),
|
|
382
|
+
...(retryResult.attempts > 1 ? { retryAttempts: retryResult.attempts } : {}),
|
|
372
383
|
},
|
|
373
384
|
};
|
|
374
385
|
}
|
|
@@ -463,6 +474,24 @@ export class ToolRegistry {
|
|
|
463
474
|
errors: 0,
|
|
464
475
|
};
|
|
465
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* IMP-02: Invoke multiple tools with concurrency partitioning.
|
|
479
|
+
* Concurrent-safe tools (isConcurrencySafe: true) run in parallel batches.
|
|
480
|
+
* Non-safe tools run sequentially between batches.
|
|
481
|
+
*/
|
|
482
|
+
async invokeBatch(calls) {
|
|
483
|
+
const batchCalls = calls.map(call => {
|
|
484
|
+
const tool = this.tools.get(call.name);
|
|
485
|
+
return {
|
|
486
|
+
name: call.name,
|
|
487
|
+
handler: () => this.invoke(call.name, call.params),
|
|
488
|
+
isConcurrencySafe: tool?.definition.isConcurrencySafe ?? false,
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
const executor = new BatchToolExecutor();
|
|
492
|
+
const batchResult = await executor.executeBatch(batchCalls);
|
|
493
|
+
return batchResult.results;
|
|
494
|
+
}
|
|
466
495
|
/**
|
|
467
496
|
* Create result metadata
|
|
468
497
|
*/
|
package/dist/mcp/types.d.ts
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Plugin Cache (IMP-09)
|
|
3
|
+
*
|
|
4
|
+
* Versioned immutable cache for installed plugins.
|
|
5
|
+
* Stores plugins at `.agentic-qe/plugins/{name}@{version}/`.
|
|
6
|
+
* Once cached, a version is never modified — only new versions are added.
|
|
7
|
+
*/
|
|
8
|
+
import type { QEPluginManifest } from './manifest';
|
|
9
|
+
export interface CachedPlugin {
|
|
10
|
+
manifest: QEPluginManifest;
|
|
11
|
+
path: string;
|
|
12
|
+
cachedAt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PluginCacheOptions {
|
|
15
|
+
/** Base directory for the plugin cache (default: .agentic-qe/plugins) */
|
|
16
|
+
cacheDir?: string;
|
|
17
|
+
/** Number of old versions to keep per plugin (default: 2) */
|
|
18
|
+
keepVersions?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class PluginCache {
|
|
21
|
+
private readonly cacheDir;
|
|
22
|
+
private readonly keepVersions;
|
|
23
|
+
constructor(options?: PluginCacheOptions);
|
|
24
|
+
/** Check if a specific version is cached. */
|
|
25
|
+
has(name: string, version: string): boolean;
|
|
26
|
+
/** Get the cached path for a plugin version, or undefined if not cached. */
|
|
27
|
+
get(name: string, version: string): CachedPlugin | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Store a plugin in the cache by copying from a source directory.
|
|
30
|
+
* Returns the cache path. If already cached, returns the existing path
|
|
31
|
+
* (immutable — no overwrite).
|
|
32
|
+
*/
|
|
33
|
+
store(manifest: QEPluginManifest, sourceDir: string): string;
|
|
34
|
+
/** Remove a specific cached version. */
|
|
35
|
+
remove(name: string, version: string): boolean;
|
|
36
|
+
/** List all cached versions for a plugin. */
|
|
37
|
+
listVersions(name: string): CachedPlugin[];
|
|
38
|
+
/** List all cached plugins (latest version of each). */
|
|
39
|
+
listAll(): CachedPlugin[];
|
|
40
|
+
private versionDir;
|
|
41
|
+
private pruneOldVersions;
|
|
42
|
+
private copyDir;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=cache.d.ts.map
|