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,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMP-10: QE Quality Daemon — Orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Central tick-loop that coordinates all daemon subsystems:
|
|
5
|
+
* - Priority queue processing
|
|
6
|
+
* - Git commit watching
|
|
7
|
+
* - Coverage delta analysis
|
|
8
|
+
* - CI/CD health monitoring
|
|
9
|
+
* - Test suggestion generation
|
|
10
|
+
* - Nightly consolidation (dream cycle)
|
|
11
|
+
* - Notification delivery
|
|
12
|
+
*
|
|
13
|
+
* Resource-aware: throttles when CPU > 70% or memory > 80%.
|
|
14
|
+
*/
|
|
15
|
+
import { cpus, freemem, totalmem, loadavg } from 'os';
|
|
16
|
+
import { PriorityQueue } from './priority-queue';
|
|
17
|
+
import { GitWatcher } from './git-watcher';
|
|
18
|
+
import { CoverageDeltaAnalyzer } from './coverage-delta';
|
|
19
|
+
import { CIMonitor } from './ci-monitor';
|
|
20
|
+
import { TestSuggester } from './test-suggester';
|
|
21
|
+
import { NightlyConsolidation } from './nightly-consolidation';
|
|
22
|
+
import { NotificationService } from './notification-service';
|
|
23
|
+
const DEFAULT_CONFIG = {
|
|
24
|
+
tickIntervalMs: 30_000,
|
|
25
|
+
ciPollIntervalMs: 5 * 60_000,
|
|
26
|
+
coverageCheckIntervalMs: 2 * 60_000,
|
|
27
|
+
cpuThreshold: 0.7,
|
|
28
|
+
memoryThreshold: 0.8,
|
|
29
|
+
};
|
|
30
|
+
export class QualityDaemon {
|
|
31
|
+
// Subsystems
|
|
32
|
+
queue;
|
|
33
|
+
gitWatcher;
|
|
34
|
+
coverageDelta;
|
|
35
|
+
ciMonitor;
|
|
36
|
+
testSuggester;
|
|
37
|
+
nightlyConsolidation;
|
|
38
|
+
notificationService;
|
|
39
|
+
// State
|
|
40
|
+
tickTimer;
|
|
41
|
+
_running = false;
|
|
42
|
+
_startedAt = 0;
|
|
43
|
+
_tickCount = 0;
|
|
44
|
+
_lastTickAt;
|
|
45
|
+
_throttled = false;
|
|
46
|
+
_commitsAnalyzed = 0;
|
|
47
|
+
_suggestionsGenerated = 0;
|
|
48
|
+
_ciHealth = 100;
|
|
49
|
+
_coverageHealth = 100;
|
|
50
|
+
_lastCICheck;
|
|
51
|
+
_lastCoverageCheck;
|
|
52
|
+
_memory;
|
|
53
|
+
// Config
|
|
54
|
+
config;
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.config = {
|
|
57
|
+
tickIntervalMs: config?.tickIntervalMs ?? DEFAULT_CONFIG.tickIntervalMs,
|
|
58
|
+
ciPollIntervalMs: config?.ciPollIntervalMs ?? DEFAULT_CONFIG.ciPollIntervalMs,
|
|
59
|
+
coverageCheckIntervalMs: config?.coverageCheckIntervalMs ?? DEFAULT_CONFIG.coverageCheckIntervalMs,
|
|
60
|
+
cpuThreshold: config?.cpuThreshold ?? DEFAULT_CONFIG.cpuThreshold,
|
|
61
|
+
memoryThreshold: config?.memoryThreshold ?? DEFAULT_CONFIG.memoryThreshold,
|
|
62
|
+
};
|
|
63
|
+
this.queue = new PriorityQueue();
|
|
64
|
+
this.gitWatcher = new GitWatcher(this.queue, config?.git);
|
|
65
|
+
this.coverageDelta = new CoverageDeltaAnalyzer(this.queue, config?.coverage);
|
|
66
|
+
this.ciMonitor = new CIMonitor(this.queue, config?.ci);
|
|
67
|
+
this.testSuggester = new TestSuggester(config?.suggestions);
|
|
68
|
+
this.nightlyConsolidation = new NightlyConsolidation(this.queue, config?.nightly);
|
|
69
|
+
this.notificationService = new NotificationService(config?.notifications);
|
|
70
|
+
}
|
|
71
|
+
get running() {
|
|
72
|
+
return this._running;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Start the quality daemon tick loop.
|
|
76
|
+
*/
|
|
77
|
+
async start(memory) {
|
|
78
|
+
if (this._running)
|
|
79
|
+
return;
|
|
80
|
+
this._memory = memory;
|
|
81
|
+
this._running = true;
|
|
82
|
+
this._startedAt = Date.now();
|
|
83
|
+
// Initialize subsystems
|
|
84
|
+
this.notificationService.initialize();
|
|
85
|
+
await this.gitWatcher.start().catch((err) => {
|
|
86
|
+
console.debug('[QualityDaemon] Git watcher failed to start:', err);
|
|
87
|
+
});
|
|
88
|
+
// Start tick loop
|
|
89
|
+
this.scheduleTick();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Stop the quality daemon.
|
|
93
|
+
*/
|
|
94
|
+
async stop() {
|
|
95
|
+
if (!this._running)
|
|
96
|
+
return;
|
|
97
|
+
this._running = false;
|
|
98
|
+
if (this.tickTimer) {
|
|
99
|
+
clearTimeout(this.tickTimer);
|
|
100
|
+
this.tickTimer = undefined;
|
|
101
|
+
}
|
|
102
|
+
this.gitWatcher.stop();
|
|
103
|
+
// Persist state
|
|
104
|
+
if (this._memory) {
|
|
105
|
+
await this._memory.set('quality-daemon:state', {
|
|
106
|
+
stoppedAt: Date.now(),
|
|
107
|
+
tickCount: this._tickCount,
|
|
108
|
+
commitsAnalyzed: this._commitsAnalyzed,
|
|
109
|
+
suggestionsGenerated: this._suggestionsGenerated,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get daemon status.
|
|
115
|
+
*/
|
|
116
|
+
getStatus() {
|
|
117
|
+
return {
|
|
118
|
+
running: this._running,
|
|
119
|
+
uptimeSeconds: this._running
|
|
120
|
+
? Math.floor((Date.now() - this._startedAt) / 1000)
|
|
121
|
+
: 0,
|
|
122
|
+
tickCount: this._tickCount,
|
|
123
|
+
queueDepth: this.queue.depths,
|
|
124
|
+
lastTickAt: this._lastTickAt,
|
|
125
|
+
throttled: this._throttled,
|
|
126
|
+
commitsAnalyzed: this._commitsAnalyzed,
|
|
127
|
+
suggestionsGenerated: this._suggestionsGenerated,
|
|
128
|
+
notificationsSent: this.notificationService.sentCount,
|
|
129
|
+
ciHealth: this._ciHealth,
|
|
130
|
+
coverageHealth: this._coverageHealth,
|
|
131
|
+
lastCICheck: this._lastCICheck,
|
|
132
|
+
lastCoverageCheck: this._lastCoverageCheck,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// ============================================================================
|
|
136
|
+
// Tick Loop
|
|
137
|
+
// ============================================================================
|
|
138
|
+
scheduleTick() {
|
|
139
|
+
if (!this._running)
|
|
140
|
+
return;
|
|
141
|
+
this.tickTimer = setTimeout(() => this.tick(), this.config.tickIntervalMs);
|
|
142
|
+
}
|
|
143
|
+
async tick() {
|
|
144
|
+
if (!this._running || !this._memory)
|
|
145
|
+
return;
|
|
146
|
+
this._tickCount++;
|
|
147
|
+
this._lastTickAt = Date.now();
|
|
148
|
+
// Resource check
|
|
149
|
+
this._throttled = this.isResourceConstrained();
|
|
150
|
+
if (this._throttled) {
|
|
151
|
+
// Only process 'now' items when throttled
|
|
152
|
+
await this.processNowItems(this._memory);
|
|
153
|
+
this.scheduleTick();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// Process queue items
|
|
157
|
+
await this.processQueue(this._memory);
|
|
158
|
+
// Periodic checks
|
|
159
|
+
await this.runPeriodicChecks(this._memory);
|
|
160
|
+
// Nightly consolidation
|
|
161
|
+
this.nightlyConsolidation.scheduleIfDue();
|
|
162
|
+
// Prune expired queue items
|
|
163
|
+
this.queue.pruneExpired();
|
|
164
|
+
this.scheduleTick();
|
|
165
|
+
}
|
|
166
|
+
async processQueue(memory) {
|
|
167
|
+
// Process up to 10 items per tick to avoid starving the loop
|
|
168
|
+
let processed = 0;
|
|
169
|
+
const maxPerTick = 10;
|
|
170
|
+
while (processed < maxPerTick && !this.queue.isEmpty) {
|
|
171
|
+
const item = this.queue.dequeue();
|
|
172
|
+
if (!item)
|
|
173
|
+
break;
|
|
174
|
+
await this.handleQueueItem(item, memory);
|
|
175
|
+
processed++;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async processNowItems(memory) {
|
|
179
|
+
const nowItems = this.queue.drainPriority('now');
|
|
180
|
+
for (const item of nowItems) {
|
|
181
|
+
await this.handleQueueItem(item, memory);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async handleQueueItem(item, memory) {
|
|
185
|
+
const payload = item.payload;
|
|
186
|
+
switch (payload.type) {
|
|
187
|
+
case 'git_commit':
|
|
188
|
+
this._commitsAnalyzed++;
|
|
189
|
+
// Trigger coverage analysis for changed files
|
|
190
|
+
const snapshot = await this.coverageDelta.buildSnapshot(memory);
|
|
191
|
+
if (snapshot) {
|
|
192
|
+
const delta = await this.coverageDelta.analyze(snapshot, memory, payload.changedFiles);
|
|
193
|
+
if (delta.regressionDetected) {
|
|
194
|
+
await this.notificationService.send({
|
|
195
|
+
type: 'coverage_drop',
|
|
196
|
+
title: 'Coverage Regression Detected',
|
|
197
|
+
message: `Line coverage delta: ${delta.overallDelta.line.toFixed(1)}% (${delta.affectedFiles.length} files affected)`,
|
|
198
|
+
severity: 'high',
|
|
199
|
+
metadata: { delta: delta.overallDelta, commit: payload.commitHash },
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (delta.newGaps.length > 0) {
|
|
203
|
+
const suggestions = await this.testSuggester.suggest(delta.newGaps, payload.changedFiles, memory);
|
|
204
|
+
this._suggestionsGenerated += suggestions.length;
|
|
205
|
+
if (suggestions.length > 0) {
|
|
206
|
+
await this.notificationService.send({
|
|
207
|
+
type: 'suggestion_available',
|
|
208
|
+
title: 'New Test Suggestions Available',
|
|
209
|
+
message: `${suggestions.length} test suggestions generated for uncovered code`,
|
|
210
|
+
severity: 'info',
|
|
211
|
+
metadata: { count: suggestions.length },
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
case 'coverage_delta': {
|
|
218
|
+
// coverage_delta items are enqueued by analyze() when regression/gaps
|
|
219
|
+
// are found. The analysis itself was already completed by the
|
|
220
|
+
// git_commit handler or periodic check that triggered it.
|
|
221
|
+
// Here we just ensure pending test suggestions are surfaced.
|
|
222
|
+
const pending = await this.testSuggester.getPending(memory);
|
|
223
|
+
if (pending.length > 0) {
|
|
224
|
+
await this.notificationService.send({
|
|
225
|
+
type: 'suggestion_available',
|
|
226
|
+
title: 'Test Suggestions Pending',
|
|
227
|
+
message: `${pending.length} test suggestions awaiting review`,
|
|
228
|
+
severity: 'info',
|
|
229
|
+
metadata: { count: pending.length },
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
case 'gate_failure':
|
|
235
|
+
await this.notificationService.send({
|
|
236
|
+
type: 'gate_failure',
|
|
237
|
+
title: `Quality Gate Failed: ${payload.gateName}`,
|
|
238
|
+
message: `Score ${payload.score} below threshold ${payload.threshold}`,
|
|
239
|
+
severity: 'critical',
|
|
240
|
+
metadata: { gate: payload.gateName, score: payload.score, threshold: payload.threshold },
|
|
241
|
+
});
|
|
242
|
+
break;
|
|
243
|
+
case 'ci_failure':
|
|
244
|
+
await this.notificationService.send({
|
|
245
|
+
type: 'ci_failure',
|
|
246
|
+
title: `CI Failure: ${payload.workflowName}`,
|
|
247
|
+
message: `Workflow ${payload.workflowName} run #${payload.runId} concluded: ${payload.conclusion}`,
|
|
248
|
+
severity: 'high',
|
|
249
|
+
metadata: { workflow: payload.workflowName, runId: payload.runId },
|
|
250
|
+
});
|
|
251
|
+
break;
|
|
252
|
+
case 'nightly': {
|
|
253
|
+
const stats = {
|
|
254
|
+
coverageHealth: this._coverageHealth,
|
|
255
|
+
ciHealth: this._ciHealth,
|
|
256
|
+
commitsAnalyzed: this._commitsAnalyzed,
|
|
257
|
+
suggestionsGenerated: this._suggestionsGenerated,
|
|
258
|
+
notificationsSent: this.notificationService.sentCount,
|
|
259
|
+
queueDepthAvg: this.queue.size,
|
|
260
|
+
uptimeSeconds: Math.floor((Date.now() - this._startedAt) / 1000),
|
|
261
|
+
};
|
|
262
|
+
await this.nightlyConsolidation.execute(memory, stats);
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
default: {
|
|
266
|
+
// Exhaustiveness check — TypeScript will error if a new payload type
|
|
267
|
+
// is added to DaemonTaskPayload without handling it here.
|
|
268
|
+
const _exhaustive = payload;
|
|
269
|
+
console.warn('[QualityDaemon] Unhandled payload type:', _exhaustive.type);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
async runPeriodicChecks(memory) {
|
|
274
|
+
const now = Date.now();
|
|
275
|
+
// CI check
|
|
276
|
+
if (!this._lastCICheck ||
|
|
277
|
+
now - this._lastCICheck >= this.config.ciPollIntervalMs) {
|
|
278
|
+
try {
|
|
279
|
+
const report = await this.ciMonitor.check();
|
|
280
|
+
this._ciHealth = report.healthScore;
|
|
281
|
+
this._lastCICheck = now;
|
|
282
|
+
if (report.flakyWorkflows.length > 0) {
|
|
283
|
+
await this.notificationService.send({
|
|
284
|
+
type: 'flaky_detected',
|
|
285
|
+
title: 'Flaky Workflows Detected',
|
|
286
|
+
message: `${report.flakyWorkflows.length} workflows showing repeated failures: ${report.flakyWorkflows.join(', ')}`,
|
|
287
|
+
severity: 'medium',
|
|
288
|
+
metadata: { workflows: report.flakyWorkflows },
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
// CI check failed, keep going
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Coverage health check — read-only metrics update.
|
|
297
|
+
// Full analysis is triggered by git commits; periodic check only updates
|
|
298
|
+
// the health score from the latest snapshot without re-running analyze()
|
|
299
|
+
// to avoid duplicate notifications.
|
|
300
|
+
if (!this._lastCoverageCheck ||
|
|
301
|
+
now - this._lastCoverageCheck >= this.config.coverageCheckIntervalMs) {
|
|
302
|
+
try {
|
|
303
|
+
const snapshot = await this.coverageDelta.buildSnapshot(memory);
|
|
304
|
+
if (snapshot) {
|
|
305
|
+
this._coverageHealth = Math.round((snapshot.overall.line +
|
|
306
|
+
snapshot.overall.branch +
|
|
307
|
+
snapshot.overall.function +
|
|
308
|
+
snapshot.overall.statement) /
|
|
309
|
+
4);
|
|
310
|
+
this._lastCoverageCheck = now;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// Coverage check failed, keep going
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
// ============================================================================
|
|
319
|
+
// Resource Awareness
|
|
320
|
+
// ============================================================================
|
|
321
|
+
isResourceConstrained() {
|
|
322
|
+
// Memory check
|
|
323
|
+
const memUsage = 1 - freemem() / totalmem();
|
|
324
|
+
if (memUsage > this.config.memoryThreshold)
|
|
325
|
+
return true;
|
|
326
|
+
// CPU check (rough heuristic via load average)
|
|
327
|
+
const cpuCount = cpus().length;
|
|
328
|
+
const load = cpuCount > 0 ? loadavg()[0] / cpuCount : 0;
|
|
329
|
+
if (load > this.config.cpuThreshold)
|
|
330
|
+
return true;
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// Re-export subsystems
|
|
335
|
+
export { PriorityQueue } from './priority-queue';
|
|
336
|
+
export { GitWatcher } from './git-watcher';
|
|
337
|
+
export { CoverageDeltaAnalyzer } from './coverage-delta';
|
|
338
|
+
export { CIMonitor } from './ci-monitor';
|
|
339
|
+
export { TestSuggester } from './test-suggester';
|
|
340
|
+
export { NightlyConsolidation } from './nightly-consolidation';
|
|
341
|
+
export { NotificationService } from './notification-service';
|
|
342
|
+
export { PersistentWorkerMemory } from './persistent-memory';
|
|
343
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMP-10: QE Quality Daemon — Nightly Consolidation
|
|
3
|
+
*
|
|
4
|
+
* Runs the learning dream cycle:
|
|
5
|
+
* - Consolidates patterns from the day's experiences
|
|
6
|
+
* - Prunes expired memory entries
|
|
7
|
+
* - Generates a daily quality report
|
|
8
|
+
* - Enqueues as 'later' priority (runs during idle)
|
|
9
|
+
*/
|
|
10
|
+
import type { WorkerMemory } from '../interfaces';
|
|
11
|
+
import type { PriorityQueue } from './priority-queue';
|
|
12
|
+
export interface ConsolidationResult {
|
|
13
|
+
readonly timestamp: number;
|
|
14
|
+
readonly patternsConsolidated: number;
|
|
15
|
+
readonly entriesPruned: number;
|
|
16
|
+
readonly reportGenerated: boolean;
|
|
17
|
+
readonly durationMs: number;
|
|
18
|
+
}
|
|
19
|
+
export interface DailyQualityReport {
|
|
20
|
+
readonly date: string;
|
|
21
|
+
readonly coverageHealth: number;
|
|
22
|
+
readonly ciHealth: number;
|
|
23
|
+
readonly commitsAnalyzed: number;
|
|
24
|
+
readonly suggestionsGenerated: number;
|
|
25
|
+
readonly notificationsSent: number;
|
|
26
|
+
readonly queueDepthAvg: number;
|
|
27
|
+
readonly daemonUptime: number;
|
|
28
|
+
}
|
|
29
|
+
export interface NightlyConsolidationOptions {
|
|
30
|
+
/** Memory key prefix */
|
|
31
|
+
memoryPrefix?: string;
|
|
32
|
+
/** Max age for memory entries before pruning (ms) */
|
|
33
|
+
maxEntryAge?: number;
|
|
34
|
+
/** Hour to run nightly tasks (0-23, default 2 = 2 AM) */
|
|
35
|
+
nightlyHour?: number;
|
|
36
|
+
}
|
|
37
|
+
export declare class NightlyConsolidation {
|
|
38
|
+
private readonly queue;
|
|
39
|
+
private options;
|
|
40
|
+
private lastRunDate;
|
|
41
|
+
constructor(queue: PriorityQueue, options?: NightlyConsolidationOptions);
|
|
42
|
+
/**
|
|
43
|
+
* Check if nightly consolidation should run.
|
|
44
|
+
*/
|
|
45
|
+
shouldRun(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Schedule nightly consolidation into the queue.
|
|
48
|
+
*/
|
|
49
|
+
scheduleIfDue(): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Execute the nightly consolidation cycle.
|
|
52
|
+
*/
|
|
53
|
+
execute(memory: WorkerMemory, stats: DaemonStats): Promise<ConsolidationResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Get the last consolidation result.
|
|
56
|
+
*/
|
|
57
|
+
getLastResult(memory: WorkerMemory): Promise<ConsolidationResult | undefined>;
|
|
58
|
+
private consolidatePatterns;
|
|
59
|
+
private pruneExpired;
|
|
60
|
+
private generateReport;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Runtime stats passed from the daemon orchestrator.
|
|
64
|
+
*/
|
|
65
|
+
export interface DaemonStats {
|
|
66
|
+
coverageHealth?: number;
|
|
67
|
+
ciHealth?: number;
|
|
68
|
+
commitsAnalyzed?: number;
|
|
69
|
+
suggestionsGenerated?: number;
|
|
70
|
+
notificationsSent?: number;
|
|
71
|
+
queueDepthAvg?: number;
|
|
72
|
+
uptimeSeconds?: number;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=nightly-consolidation.d.ts.map
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMP-10: QE Quality Daemon — Nightly Consolidation
|
|
3
|
+
*
|
|
4
|
+
* Runs the learning dream cycle:
|
|
5
|
+
* - Consolidates patterns from the day's experiences
|
|
6
|
+
* - Prunes expired memory entries
|
|
7
|
+
* - Generates a daily quality report
|
|
8
|
+
* - Enqueues as 'later' priority (runs during idle)
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULTS = {
|
|
11
|
+
memoryPrefix: 'quality-daemon:nightly',
|
|
12
|
+
maxEntryAge: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
13
|
+
nightlyHour: 2,
|
|
14
|
+
};
|
|
15
|
+
export class NightlyConsolidation {
|
|
16
|
+
queue;
|
|
17
|
+
options;
|
|
18
|
+
lastRunDate;
|
|
19
|
+
constructor(queue, options) {
|
|
20
|
+
this.queue = queue;
|
|
21
|
+
this.options = { ...DEFAULTS, ...options };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if nightly consolidation should run.
|
|
25
|
+
*/
|
|
26
|
+
shouldRun() {
|
|
27
|
+
const now = new Date();
|
|
28
|
+
const todayDate = now.toISOString().split('T')[0];
|
|
29
|
+
// Already ran today
|
|
30
|
+
if (this.lastRunDate === todayDate)
|
|
31
|
+
return false;
|
|
32
|
+
// Only run at or after the configured hour
|
|
33
|
+
return now.getHours() >= this.options.nightlyHour;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Schedule nightly consolidation into the queue.
|
|
37
|
+
*/
|
|
38
|
+
scheduleIfDue() {
|
|
39
|
+
if (!this.shouldRun())
|
|
40
|
+
return false;
|
|
41
|
+
const payload = {
|
|
42
|
+
type: 'nightly',
|
|
43
|
+
tasks: ['consolidate_patterns', 'prune_expired', 'generate_report'],
|
|
44
|
+
};
|
|
45
|
+
const item = {
|
|
46
|
+
id: `nightly-${Date.now()}`,
|
|
47
|
+
priority: 'later',
|
|
48
|
+
payload,
|
|
49
|
+
createdAt: Date.now(),
|
|
50
|
+
source: 'nightly-consolidation',
|
|
51
|
+
ttlMs: 12 * 60 * 60 * 1000, // 12 hour TTL
|
|
52
|
+
};
|
|
53
|
+
return this.queue.enqueue(item);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Execute the nightly consolidation cycle.
|
|
57
|
+
*/
|
|
58
|
+
async execute(memory, stats) {
|
|
59
|
+
const startTime = Date.now();
|
|
60
|
+
const todayDate = new Date().toISOString().split('T')[0];
|
|
61
|
+
// 1. Consolidate patterns
|
|
62
|
+
const patternsConsolidated = await this.consolidatePatterns(memory);
|
|
63
|
+
// 2. Prune expired entries
|
|
64
|
+
const entriesPruned = await this.pruneExpired(memory);
|
|
65
|
+
// 3. Generate daily report
|
|
66
|
+
const report = this.generateReport(todayDate, stats);
|
|
67
|
+
await memory.set(`${this.options.memoryPrefix}:report:${todayDate}`, report);
|
|
68
|
+
this.lastRunDate = todayDate;
|
|
69
|
+
const result = {
|
|
70
|
+
timestamp: Date.now(),
|
|
71
|
+
patternsConsolidated,
|
|
72
|
+
entriesPruned,
|
|
73
|
+
reportGenerated: true,
|
|
74
|
+
durationMs: Date.now() - startTime,
|
|
75
|
+
};
|
|
76
|
+
await memory.set(`${this.options.memoryPrefix}:last-result`, result);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the last consolidation result.
|
|
81
|
+
*/
|
|
82
|
+
async getLastResult(memory) {
|
|
83
|
+
return memory.get(`${this.options.memoryPrefix}:last-result`);
|
|
84
|
+
}
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// Private
|
|
87
|
+
// ============================================================================
|
|
88
|
+
async consolidatePatterns(memory) {
|
|
89
|
+
// Find all daemon-generated patterns from today
|
|
90
|
+
const keys = await memory.search('quality-daemon:*');
|
|
91
|
+
let consolidated = 0;
|
|
92
|
+
// Consolidate suggestion stats
|
|
93
|
+
const suggestionCount = await memory.get('quality-daemon:suggestions:count');
|
|
94
|
+
if (suggestionCount) {
|
|
95
|
+
consolidated++;
|
|
96
|
+
}
|
|
97
|
+
// Consolidate coverage deltas
|
|
98
|
+
const delta = await memory.get('quality-daemon:coverage:delta');
|
|
99
|
+
if (delta) {
|
|
100
|
+
consolidated++;
|
|
101
|
+
}
|
|
102
|
+
return consolidated;
|
|
103
|
+
}
|
|
104
|
+
async pruneExpired(memory) {
|
|
105
|
+
const keys = await memory.search('quality-daemon:*');
|
|
106
|
+
let pruned = 0;
|
|
107
|
+
const now = Date.now();
|
|
108
|
+
for (const key of keys) {
|
|
109
|
+
// Skip critical keys
|
|
110
|
+
if (key.endsWith(':snapshot') || key.endsWith(':list'))
|
|
111
|
+
continue;
|
|
112
|
+
const value = await memory.get(key);
|
|
113
|
+
if (value &&
|
|
114
|
+
typeof value.timestamp === 'number' &&
|
|
115
|
+
now - value.timestamp > this.options.maxEntryAge) {
|
|
116
|
+
// Mark as pruned (set to null equivalent)
|
|
117
|
+
await memory.set(key, { pruned: true, prunedAt: now });
|
|
118
|
+
pruned++;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return pruned;
|
|
122
|
+
}
|
|
123
|
+
generateReport(date, stats) {
|
|
124
|
+
return {
|
|
125
|
+
date,
|
|
126
|
+
coverageHealth: stats.coverageHealth ?? 0,
|
|
127
|
+
ciHealth: stats.ciHealth ?? 0,
|
|
128
|
+
commitsAnalyzed: stats.commitsAnalyzed ?? 0,
|
|
129
|
+
suggestionsGenerated: stats.suggestionsGenerated ?? 0,
|
|
130
|
+
notificationsSent: stats.notificationsSent ?? 0,
|
|
131
|
+
queueDepthAvg: stats.queueDepthAvg ?? 0,
|
|
132
|
+
daemonUptime: stats.uptimeSeconds ?? 0,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=nightly-consolidation.js.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMP-10: QE Quality Daemon — Notification Service
|
|
3
|
+
*
|
|
4
|
+
* Delivers notifications via:
|
|
5
|
+
* - File-based: JSON files in `.agentic-qe/notifications/`
|
|
6
|
+
* - Webhook: POST to configured URL (with IMP-07 SSRF protection)
|
|
7
|
+
*
|
|
8
|
+
* Notification types: gate_failure, coverage_drop, flaky_detected, suggestion_available
|
|
9
|
+
*/
|
|
10
|
+
export type NotificationType = 'gate_failure' | 'coverage_drop' | 'flaky_detected' | 'suggestion_available' | 'ci_failure' | 'daemon_health';
|
|
11
|
+
export interface Notification {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly type: NotificationType;
|
|
14
|
+
readonly title: string;
|
|
15
|
+
readonly message: string;
|
|
16
|
+
readonly severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
17
|
+
readonly timestamp: number;
|
|
18
|
+
readonly metadata?: Record<string, unknown>;
|
|
19
|
+
readonly read: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface NotificationServiceOptions {
|
|
22
|
+
/** Directory for file-based notifications */
|
|
23
|
+
notificationsDir?: string;
|
|
24
|
+
/** Maximum stored notifications (oldest pruned) */
|
|
25
|
+
maxNotifications?: number;
|
|
26
|
+
/** Webhook URL for push notifications (optional) */
|
|
27
|
+
webhookUrl?: string;
|
|
28
|
+
/** URL validator function (IMP-07 SSRF guard) */
|
|
29
|
+
urlValidator?: (url: string) => boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare class NotificationService {
|
|
32
|
+
private notificationsDir;
|
|
33
|
+
private maxNotifications;
|
|
34
|
+
private webhookUrl;
|
|
35
|
+
private urlValidator;
|
|
36
|
+
private _sentCount;
|
|
37
|
+
constructor(options?: NotificationServiceOptions);
|
|
38
|
+
get sentCount(): number;
|
|
39
|
+
/**
|
|
40
|
+
* Initialize the notifications directory.
|
|
41
|
+
*/
|
|
42
|
+
initialize(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Send a notification.
|
|
45
|
+
*/
|
|
46
|
+
send(notification: Omit<Notification, 'id' | 'timestamp' | 'read'>): Promise<Notification>;
|
|
47
|
+
/**
|
|
48
|
+
* List recent notifications.
|
|
49
|
+
*/
|
|
50
|
+
list(options?: {
|
|
51
|
+
unreadOnly?: boolean;
|
|
52
|
+
limit?: number;
|
|
53
|
+
type?: NotificationType;
|
|
54
|
+
}): Notification[];
|
|
55
|
+
/**
|
|
56
|
+
* Mark a notification as read.
|
|
57
|
+
*/
|
|
58
|
+
markRead(id: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Clear all notifications.
|
|
61
|
+
*/
|
|
62
|
+
clear(): number;
|
|
63
|
+
private writeToFile;
|
|
64
|
+
private sendWebhook;
|
|
65
|
+
private pruneOldNotifications;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=notification-service.d.ts.map
|