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,149 @@
|
|
|
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 * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// PluginCache
|
|
12
|
+
// ============================================================================
|
|
13
|
+
export class PluginCache {
|
|
14
|
+
cacheDir;
|
|
15
|
+
keepVersions;
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
this.cacheDir = options.cacheDir
|
|
18
|
+
?? path.join(process.cwd(), '.agentic-qe', 'plugins');
|
|
19
|
+
this.keepVersions = options.keepVersions ?? 2;
|
|
20
|
+
}
|
|
21
|
+
/** Check if a specific version is cached. */
|
|
22
|
+
has(name, version) {
|
|
23
|
+
const dir = this.versionDir(name, version);
|
|
24
|
+
return fs.existsSync(dir) && fs.existsSync(path.join(dir, 'qe-plugin.json'));
|
|
25
|
+
}
|
|
26
|
+
/** Get the cached path for a plugin version, or undefined if not cached. */
|
|
27
|
+
get(name, version) {
|
|
28
|
+
if (!this.has(name, version))
|
|
29
|
+
return undefined;
|
|
30
|
+
const dir = this.versionDir(name, version);
|
|
31
|
+
const raw = fs.readFileSync(path.join(dir, 'qe-plugin.json'), 'utf-8');
|
|
32
|
+
const manifest = JSON.parse(raw);
|
|
33
|
+
const stat = fs.statSync(dir);
|
|
34
|
+
return {
|
|
35
|
+
manifest,
|
|
36
|
+
path: dir,
|
|
37
|
+
cachedAt: stat.birthtime.toISOString(),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Store a plugin in the cache by copying from a source directory.
|
|
42
|
+
* Returns the cache path. If already cached, returns the existing path
|
|
43
|
+
* (immutable — no overwrite).
|
|
44
|
+
*/
|
|
45
|
+
store(manifest, sourceDir) {
|
|
46
|
+
const dir = this.versionDir(manifest.name, manifest.version);
|
|
47
|
+
if (fs.existsSync(dir)) {
|
|
48
|
+
// Already cached — immutable, don't overwrite
|
|
49
|
+
return dir;
|
|
50
|
+
}
|
|
51
|
+
// Copy source to cache
|
|
52
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
53
|
+
this.copyDir(sourceDir, dir);
|
|
54
|
+
// Write the manifest (ensure it's present even if source didn't have it at root)
|
|
55
|
+
fs.writeFileSync(path.join(dir, 'qe-plugin.json'), JSON.stringify(manifest, null, 2));
|
|
56
|
+
// Cleanup old versions
|
|
57
|
+
this.pruneOldVersions(manifest.name);
|
|
58
|
+
return dir;
|
|
59
|
+
}
|
|
60
|
+
/** Remove a specific cached version. */
|
|
61
|
+
remove(name, version) {
|
|
62
|
+
const dir = this.versionDir(name, version);
|
|
63
|
+
if (!fs.existsSync(dir))
|
|
64
|
+
return false;
|
|
65
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
/** List all cached versions for a plugin. */
|
|
69
|
+
listVersions(name) {
|
|
70
|
+
const pluginDir = path.join(this.cacheDir, name);
|
|
71
|
+
if (!fs.existsSync(pluginDir))
|
|
72
|
+
return [];
|
|
73
|
+
const results = [];
|
|
74
|
+
const entries = fs.readdirSync(pluginDir);
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
const fullPath = path.join(pluginDir, entry);
|
|
77
|
+
const manifestPath = path.join(fullPath, 'qe-plugin.json');
|
|
78
|
+
if (fs.existsSync(manifestPath)) {
|
|
79
|
+
try {
|
|
80
|
+
const raw = fs.readFileSync(manifestPath, 'utf-8');
|
|
81
|
+
const manifest = JSON.parse(raw);
|
|
82
|
+
const stat = fs.statSync(fullPath);
|
|
83
|
+
results.push({
|
|
84
|
+
manifest,
|
|
85
|
+
path: fullPath,
|
|
86
|
+
cachedAt: stat.birthtime.toISOString(),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Skip corrupted entries
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return results;
|
|
95
|
+
}
|
|
96
|
+
/** List all cached plugins (latest version of each). */
|
|
97
|
+
listAll() {
|
|
98
|
+
if (!fs.existsSync(this.cacheDir))
|
|
99
|
+
return [];
|
|
100
|
+
const results = [];
|
|
101
|
+
const entries = fs.readdirSync(this.cacheDir);
|
|
102
|
+
for (const name of entries) {
|
|
103
|
+
const versions = this.listVersions(name);
|
|
104
|
+
if (versions.length > 0) {
|
|
105
|
+
// Return the latest version (lexicographic semver sort)
|
|
106
|
+
versions.sort((a, b) => b.manifest.version.localeCompare(a.manifest.version));
|
|
107
|
+
results.push(versions[0]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return results;
|
|
111
|
+
}
|
|
112
|
+
// --------------------------------------------------------------------------
|
|
113
|
+
// Internal
|
|
114
|
+
// --------------------------------------------------------------------------
|
|
115
|
+
versionDir(name, version) {
|
|
116
|
+
return path.join(this.cacheDir, name, version);
|
|
117
|
+
}
|
|
118
|
+
pruneOldVersions(name) {
|
|
119
|
+
const versions = this.listVersions(name);
|
|
120
|
+
if (versions.length <= this.keepVersions)
|
|
121
|
+
return;
|
|
122
|
+
// Sort oldest first
|
|
123
|
+
versions.sort((a, b) => a.cachedAt.localeCompare(b.cachedAt));
|
|
124
|
+
const toRemove = versions.slice(0, versions.length - this.keepVersions);
|
|
125
|
+
for (const cached of toRemove) {
|
|
126
|
+
fs.rmSync(cached.path, { recursive: true, force: true });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
copyDir(src, dest) {
|
|
130
|
+
if (!fs.existsSync(src))
|
|
131
|
+
return;
|
|
132
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
const srcPath = path.join(src, entry.name);
|
|
135
|
+
const destPath = path.join(dest, entry.name);
|
|
136
|
+
if (entry.isDirectory()) {
|
|
137
|
+
// Skip .git directories
|
|
138
|
+
if (entry.name === '.git' || entry.name === 'node_modules')
|
|
139
|
+
continue;
|
|
140
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
141
|
+
this.copyDir(srcPath, destPath);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
fs.copyFileSync(srcPath, destPath);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Plugin Architecture (IMP-09)
|
|
3
|
+
*
|
|
4
|
+
* External plugin system for QE domain extensions.
|
|
5
|
+
* Supports local, GitHub, and npm plugin sources.
|
|
6
|
+
*/
|
|
7
|
+
export { type QEPluginManifest, type ManifestValidationResult, validateManifest, parseManifest } from './manifest';
|
|
8
|
+
export { PluginCache, type CachedPlugin, type PluginCacheOptions } from './cache';
|
|
9
|
+
export { PluginResolver, type ResolvedPlugin, type ResolutionResult } from './resolver';
|
|
10
|
+
export { checkPluginSecurity, isNameSafe, type SecurityCheckResult } from './security';
|
|
11
|
+
export { PluginLifecycleManager, type InstallResult, type PluginInfo, type PluginLifecycleOptions } from './lifecycle';
|
|
12
|
+
export { LocalPluginSource, type PluginSource } from './sources/local';
|
|
13
|
+
export { GitHubPluginSource } from './sources/github';
|
|
14
|
+
export { NpmPluginSource } from './sources/npm';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Plugin Architecture (IMP-09)
|
|
3
|
+
*
|
|
4
|
+
* External plugin system for QE domain extensions.
|
|
5
|
+
* Supports local, GitHub, and npm plugin sources.
|
|
6
|
+
*/
|
|
7
|
+
export { validateManifest, parseManifest } from './manifest';
|
|
8
|
+
export { PluginCache } from './cache';
|
|
9
|
+
export { PluginResolver } from './resolver';
|
|
10
|
+
export { checkPluginSecurity, isNameSafe } from './security';
|
|
11
|
+
export { PluginLifecycleManager } from './lifecycle';
|
|
12
|
+
export { LocalPluginSource } from './sources/local';
|
|
13
|
+
export { GitHubPluginSource } from './sources/github';
|
|
14
|
+
export { NpmPluginSource } from './sources/npm';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Plugin Lifecycle Manager (IMP-09)
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the full plugin lifecycle:
|
|
5
|
+
* discover -> validate -> resolve deps -> cache -> load -> register
|
|
6
|
+
*
|
|
7
|
+
* Integrates with:
|
|
8
|
+
* - Plugin sources (local, GitHub, npm) for discovery
|
|
9
|
+
* - Plugin cache for versioned immutable storage
|
|
10
|
+
* - Plugin resolver for dependency ordering
|
|
11
|
+
* - Plugin security for validation
|
|
12
|
+
* - Kernel PluginLoader for registration
|
|
13
|
+
*/
|
|
14
|
+
import type { QEPluginManifest } from './manifest';
|
|
15
|
+
import { PluginCache } from './cache';
|
|
16
|
+
import { type ResolutionResult } from './resolver';
|
|
17
|
+
import { type PluginSource } from './sources/local';
|
|
18
|
+
export interface PluginLifecycleOptions {
|
|
19
|
+
/** Plugin cache instance */
|
|
20
|
+
cache?: PluginCache;
|
|
21
|
+
/** Additional plugin sources beyond local */
|
|
22
|
+
sources?: PluginSource[];
|
|
23
|
+
}
|
|
24
|
+
export interface InstallResult {
|
|
25
|
+
success: boolean;
|
|
26
|
+
manifest?: QEPluginManifest;
|
|
27
|
+
cachePath?: string;
|
|
28
|
+
errors: string[];
|
|
29
|
+
securityViolations: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface PluginInfo {
|
|
32
|
+
name: string;
|
|
33
|
+
version: string;
|
|
34
|
+
description: string;
|
|
35
|
+
domains: string[];
|
|
36
|
+
source: string;
|
|
37
|
+
cachePath: string;
|
|
38
|
+
}
|
|
39
|
+
export declare class PluginLifecycleManager {
|
|
40
|
+
private readonly cache;
|
|
41
|
+
private readonly resolver;
|
|
42
|
+
private readonly sources;
|
|
43
|
+
constructor(options?: PluginLifecycleOptions);
|
|
44
|
+
/**
|
|
45
|
+
* Install a plugin from a given location.
|
|
46
|
+
* Runs the full lifecycle: resolve -> validate -> security check -> cache.
|
|
47
|
+
* Disabled via AQE_PLUGINS_DISABLED=true.
|
|
48
|
+
*/
|
|
49
|
+
install(location: string, sourceType?: string): Promise<InstallResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Remove a plugin from the cache.
|
|
52
|
+
*/
|
|
53
|
+
remove(name: string, version?: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* List all installed plugins.
|
|
56
|
+
*/
|
|
57
|
+
list(): PluginInfo[];
|
|
58
|
+
/**
|
|
59
|
+
* Resolve load order for all cached plugins.
|
|
60
|
+
*/
|
|
61
|
+
resolveLoadOrder(): ResolutionResult;
|
|
62
|
+
/**
|
|
63
|
+
* Register a plugin source.
|
|
64
|
+
*/
|
|
65
|
+
registerSource(source: PluginSource): void;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Plugin Lifecycle Manager (IMP-09)
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the full plugin lifecycle:
|
|
5
|
+
* discover -> validate -> resolve deps -> cache -> load -> register
|
|
6
|
+
*
|
|
7
|
+
* Integrates with:
|
|
8
|
+
* - Plugin sources (local, GitHub, npm) for discovery
|
|
9
|
+
* - Plugin cache for versioned immutable storage
|
|
10
|
+
* - Plugin resolver for dependency ordering
|
|
11
|
+
* - Plugin security for validation
|
|
12
|
+
* - Kernel PluginLoader for registration
|
|
13
|
+
*/
|
|
14
|
+
import { validateManifest } from './manifest';
|
|
15
|
+
import { PluginCache } from './cache';
|
|
16
|
+
import { PluginResolver } from './resolver';
|
|
17
|
+
import { checkPluginSecurity } from './security';
|
|
18
|
+
import { LocalPluginSource } from './sources/local';
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// PluginLifecycleManager
|
|
21
|
+
// ============================================================================
|
|
22
|
+
export class PluginLifecycleManager {
|
|
23
|
+
cache;
|
|
24
|
+
resolver;
|
|
25
|
+
sources = new Map();
|
|
26
|
+
constructor(options = {}) {
|
|
27
|
+
this.cache = options.cache ?? new PluginCache();
|
|
28
|
+
this.resolver = new PluginResolver();
|
|
29
|
+
// Register default local source
|
|
30
|
+
const localSource = new LocalPluginSource();
|
|
31
|
+
this.sources.set('local', localSource);
|
|
32
|
+
// Register additional sources
|
|
33
|
+
if (options.sources) {
|
|
34
|
+
for (const source of options.sources) {
|
|
35
|
+
this.sources.set(source.type, source);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// --------------------------------------------------------------------------
|
|
40
|
+
// Public API
|
|
41
|
+
// --------------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Install a plugin from a given location.
|
|
44
|
+
* Runs the full lifecycle: resolve -> validate -> security check -> cache.
|
|
45
|
+
* Disabled via AQE_PLUGINS_DISABLED=true.
|
|
46
|
+
*/
|
|
47
|
+
async install(location, sourceType = 'local') {
|
|
48
|
+
if (process.env.AQE_PLUGINS_DISABLED === 'true') {
|
|
49
|
+
return {
|
|
50
|
+
success: false,
|
|
51
|
+
errors: ['Plugin loading is disabled (AQE_PLUGINS_DISABLED=true)'],
|
|
52
|
+
securityViolations: [],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const errors = [];
|
|
56
|
+
// 1. Get the source
|
|
57
|
+
const source = this.sources.get(sourceType);
|
|
58
|
+
if (!source) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
errors: [`Unknown source type: ${sourceType}. Available: ${[...this.sources.keys()].join(', ')}`],
|
|
62
|
+
securityViolations: [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// 2. Resolve manifest from source
|
|
66
|
+
let manifest;
|
|
67
|
+
try {
|
|
68
|
+
manifest = await source.resolve(location);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
errors: [`Failed to resolve plugin: ${err instanceof Error ? err.message : String(err)}`],
|
|
74
|
+
securityViolations: [],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// 3. Validate manifest
|
|
78
|
+
const validation = validateManifest(manifest);
|
|
79
|
+
if (!validation.valid) {
|
|
80
|
+
return {
|
|
81
|
+
success: false,
|
|
82
|
+
manifest,
|
|
83
|
+
errors: validation.errors,
|
|
84
|
+
securityViolations: [],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// 4. Security check
|
|
88
|
+
const security = checkPluginSecurity(manifest);
|
|
89
|
+
if (!security.safe) {
|
|
90
|
+
return {
|
|
91
|
+
success: false,
|
|
92
|
+
manifest,
|
|
93
|
+
errors: ['Plugin failed security checks'],
|
|
94
|
+
securityViolations: security.violations,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// 5. Check if already cached
|
|
98
|
+
if (this.cache.has(manifest.name, manifest.version)) {
|
|
99
|
+
const cached = this.cache.get(manifest.name, manifest.version);
|
|
100
|
+
return {
|
|
101
|
+
success: true,
|
|
102
|
+
manifest,
|
|
103
|
+
cachePath: cached.path,
|
|
104
|
+
errors: [],
|
|
105
|
+
securityViolations: [],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// 6. Get plugin path and store in cache
|
|
109
|
+
let pluginPath;
|
|
110
|
+
try {
|
|
111
|
+
pluginPath = await source.getPluginPath(location);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
return {
|
|
115
|
+
success: false,
|
|
116
|
+
manifest,
|
|
117
|
+
errors: [`Failed to get plugin path: ${err instanceof Error ? err.message : String(err)}`],
|
|
118
|
+
securityViolations: [],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const cachePath = this.cache.store(manifest, pluginPath);
|
|
122
|
+
return {
|
|
123
|
+
success: true,
|
|
124
|
+
manifest,
|
|
125
|
+
cachePath,
|
|
126
|
+
errors,
|
|
127
|
+
securityViolations: [],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Remove a plugin from the cache.
|
|
132
|
+
*/
|
|
133
|
+
remove(name, version) {
|
|
134
|
+
if (version) {
|
|
135
|
+
return this.cache.remove(name, version);
|
|
136
|
+
}
|
|
137
|
+
// Remove all versions
|
|
138
|
+
const versions = this.cache.listVersions(name);
|
|
139
|
+
let removed = false;
|
|
140
|
+
for (const v of versions) {
|
|
141
|
+
if (this.cache.remove(name, v.manifest.version)) {
|
|
142
|
+
removed = true;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return removed;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* List all installed plugins.
|
|
149
|
+
*/
|
|
150
|
+
list() {
|
|
151
|
+
const cached = this.cache.listAll();
|
|
152
|
+
return cached.map(c => ({
|
|
153
|
+
name: c.manifest.name,
|
|
154
|
+
version: c.manifest.version,
|
|
155
|
+
description: c.manifest.description,
|
|
156
|
+
domains: c.manifest.domains,
|
|
157
|
+
source: 'cached',
|
|
158
|
+
cachePath: c.path,
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Resolve load order for all cached plugins.
|
|
163
|
+
*/
|
|
164
|
+
resolveLoadOrder() {
|
|
165
|
+
const all = this.cache.listAll();
|
|
166
|
+
return this.resolver.resolve(all.map(c => c.manifest));
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Register a plugin source.
|
|
170
|
+
*/
|
|
171
|
+
registerSource(source) {
|
|
172
|
+
this.sources.set(source.type, source);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Plugin Manifest Schema & Validation (IMP-09)
|
|
3
|
+
*
|
|
4
|
+
* Defines the `qe-plugin.json` manifest format that external QE domain
|
|
5
|
+
* plugins must provide. Includes validation logic for name, version,
|
|
6
|
+
* entry point, and permissions.
|
|
7
|
+
*/
|
|
8
|
+
import type { DomainName } from '../shared/types';
|
|
9
|
+
export interface QEPluginManifest {
|
|
10
|
+
/** Plugin name (e.g., "aqe-plugin-sap-testing") */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Semantic version */
|
|
13
|
+
version: string;
|
|
14
|
+
/** Human-readable description */
|
|
15
|
+
description: string;
|
|
16
|
+
/** Author name or org */
|
|
17
|
+
author: string;
|
|
18
|
+
/** Domains this plugin adds or extends */
|
|
19
|
+
domains: DomainName[];
|
|
20
|
+
/** Dependencies on other plugins (name -> semver range) */
|
|
21
|
+
dependencies?: Record<string, string>;
|
|
22
|
+
/** Relative path to the main module entry point */
|
|
23
|
+
entryPoint: string;
|
|
24
|
+
/** Hook event -> handler path mappings */
|
|
25
|
+
hooks?: Record<string, string>;
|
|
26
|
+
/** Minimum AQE version required */
|
|
27
|
+
minAqeVersion?: string;
|
|
28
|
+
/** Required permissions */
|
|
29
|
+
permissions?: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface ManifestValidationResult {
|
|
32
|
+
valid: boolean;
|
|
33
|
+
errors: string[];
|
|
34
|
+
warnings: string[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Validate a plugin manifest. Returns structured errors and warnings.
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateManifest(manifest: unknown): ManifestValidationResult;
|
|
40
|
+
/**
|
|
41
|
+
* Parse and validate a manifest from a JSON string or object.
|
|
42
|
+
* Throws on invalid manifests.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseManifest(input: string | object): QEPluginManifest;
|
|
45
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Plugin Manifest Schema & Validation (IMP-09)
|
|
3
|
+
*
|
|
4
|
+
* Defines the `qe-plugin.json` manifest format that external QE domain
|
|
5
|
+
* plugins must provide. Includes validation logic for name, version,
|
|
6
|
+
* entry point, and permissions.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Constants
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/** Regex for valid plugin names: lowercase, alphanumeric, hyphens */
|
|
12
|
+
const VALID_NAME_REGEX = /^[a-z][a-z0-9-]*$/;
|
|
13
|
+
/** Regex for semver: major.minor.patch with optional pre-release */
|
|
14
|
+
const SEMVER_REGEX = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/;
|
|
15
|
+
/** Reserved name prefixes that third-party plugins cannot use */
|
|
16
|
+
const RESERVED_PREFIXES = ['aqe-core-', 'agentic-qe-core-'];
|
|
17
|
+
/** Maximum name length */
|
|
18
|
+
const MAX_NAME_LENGTH = 64;
|
|
19
|
+
/** Maximum description length */
|
|
20
|
+
const MAX_DESCRIPTION_LENGTH = 500;
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Validation
|
|
23
|
+
// ============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Validate a plugin manifest. Returns structured errors and warnings.
|
|
26
|
+
*/
|
|
27
|
+
export function validateManifest(manifest) {
|
|
28
|
+
const errors = [];
|
|
29
|
+
const warnings = [];
|
|
30
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
31
|
+
return { valid: false, errors: ['Manifest must be a non-null object'], warnings: [] };
|
|
32
|
+
}
|
|
33
|
+
const m = manifest;
|
|
34
|
+
// --- Required fields ---
|
|
35
|
+
if (!m.name || typeof m.name !== 'string') {
|
|
36
|
+
errors.push('name is required and must be a string');
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
validateName(m.name, errors, warnings);
|
|
40
|
+
}
|
|
41
|
+
if (!m.version || typeof m.version !== 'string') {
|
|
42
|
+
errors.push('version is required and must be a string');
|
|
43
|
+
}
|
|
44
|
+
else if (!SEMVER_REGEX.test(m.version)) {
|
|
45
|
+
errors.push(`version "${m.version}" is not valid semver (expected: major.minor.patch)`);
|
|
46
|
+
}
|
|
47
|
+
if (!m.description || typeof m.description !== 'string') {
|
|
48
|
+
errors.push('description is required and must be a string');
|
|
49
|
+
}
|
|
50
|
+
else if (m.description.length > MAX_DESCRIPTION_LENGTH) {
|
|
51
|
+
warnings.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters`);
|
|
52
|
+
}
|
|
53
|
+
if (!m.author || typeof m.author !== 'string') {
|
|
54
|
+
errors.push('author is required and must be a string');
|
|
55
|
+
}
|
|
56
|
+
if (!Array.isArray(m.domains) || m.domains.length === 0) {
|
|
57
|
+
errors.push('domains is required and must be a non-empty array');
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
for (const d of m.domains) {
|
|
61
|
+
if (typeof d !== 'string') {
|
|
62
|
+
errors.push('Each domain must be a string');
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (!m.entryPoint || typeof m.entryPoint !== 'string') {
|
|
68
|
+
errors.push('entryPoint is required and must be a string');
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
validateEntryPoint(m.entryPoint, errors);
|
|
72
|
+
}
|
|
73
|
+
// --- Optional fields ---
|
|
74
|
+
if (m.dependencies !== undefined) {
|
|
75
|
+
if (typeof m.dependencies !== 'object' || m.dependencies === null || Array.isArray(m.dependencies)) {
|
|
76
|
+
errors.push('dependencies must be an object mapping plugin names to semver ranges');
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
for (const [depName, depVersion] of Object.entries(m.dependencies)) {
|
|
80
|
+
if (typeof depVersion !== 'string') {
|
|
81
|
+
errors.push(`Dependency "${depName}" must have a string version range`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (m.hooks !== undefined) {
|
|
87
|
+
if (typeof m.hooks !== 'object' || m.hooks === null || Array.isArray(m.hooks)) {
|
|
88
|
+
errors.push('hooks must be an object mapping event names to handler paths');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
for (const [, handlerPath] of Object.entries(m.hooks)) {
|
|
92
|
+
if (typeof handlerPath !== 'string') {
|
|
93
|
+
errors.push('Hook handler paths must be strings');
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
if (handlerPath.includes('..')) {
|
|
97
|
+
errors.push(`Hook handler path "${handlerPath}" must not contain ".." (path traversal)`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (m.minAqeVersion !== undefined) {
|
|
103
|
+
if (typeof m.minAqeVersion !== 'string' || !SEMVER_REGEX.test(m.minAqeVersion)) {
|
|
104
|
+
warnings.push('minAqeVersion should be valid semver');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (m.permissions !== undefined) {
|
|
108
|
+
if (!Array.isArray(m.permissions)) {
|
|
109
|
+
errors.push('permissions must be an array of strings');
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
for (const p of m.permissions) {
|
|
113
|
+
if (typeof p !== 'string') {
|
|
114
|
+
errors.push('Each permission must be a string');
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Parse and validate a manifest from a JSON string or object.
|
|
124
|
+
* Throws on invalid manifests.
|
|
125
|
+
*/
|
|
126
|
+
export function parseManifest(input) {
|
|
127
|
+
const parsed = typeof input === 'string' ? JSON.parse(input) : input;
|
|
128
|
+
const result = validateManifest(parsed);
|
|
129
|
+
if (!result.valid) {
|
|
130
|
+
throw new Error(`Invalid plugin manifest:\n - ${result.errors.join('\n - ')}`);
|
|
131
|
+
}
|
|
132
|
+
return parsed;
|
|
133
|
+
}
|
|
134
|
+
// ============================================================================
|
|
135
|
+
// Internal Validators
|
|
136
|
+
// ============================================================================
|
|
137
|
+
function validateName(name, errors, warnings) {
|
|
138
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
139
|
+
errors.push(`name must be ${MAX_NAME_LENGTH} characters or fewer`);
|
|
140
|
+
}
|
|
141
|
+
if (!VALID_NAME_REGEX.test(name)) {
|
|
142
|
+
errors.push('name must be lowercase alphanumeric with hyphens, starting with a letter');
|
|
143
|
+
}
|
|
144
|
+
// Check for non-ASCII characters
|
|
145
|
+
// eslint-disable-next-line no-control-regex
|
|
146
|
+
if (/[^\x00-\x7F]/.test(name)) {
|
|
147
|
+
errors.push('name must contain only ASCII characters');
|
|
148
|
+
}
|
|
149
|
+
for (const prefix of RESERVED_PREFIXES) {
|
|
150
|
+
if (name.startsWith(prefix)) {
|
|
151
|
+
errors.push(`name cannot start with reserved prefix "${prefix}"`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Warn on overly generic names
|
|
155
|
+
if (['plugin', 'test', 'tool'].includes(name)) {
|
|
156
|
+
warnings.push(`name "${name}" is very generic — consider a more descriptive name`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function validateEntryPoint(entryPoint, errors) {
|
|
160
|
+
// Block path traversal
|
|
161
|
+
if (entryPoint.includes('..')) {
|
|
162
|
+
errors.push('entryPoint must not contain ".." (path traversal)');
|
|
163
|
+
}
|
|
164
|
+
// Block absolute paths
|
|
165
|
+
if (entryPoint.startsWith('/') || entryPoint.startsWith('\\')) {
|
|
166
|
+
errors.push('entryPoint must be a relative path');
|
|
167
|
+
}
|
|
168
|
+
// Must end in .js or .ts
|
|
169
|
+
if (!entryPoint.endsWith('.js') && !entryPoint.endsWith('.ts') && !entryPoint.endsWith('.mjs')) {
|
|
170
|
+
errors.push('entryPoint must end in .js, .ts, or .mjs');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Plugin Dependency Resolver (IMP-09)
|
|
3
|
+
*
|
|
4
|
+
* DFS dependency resolution with cycle detection.
|
|
5
|
+
* Given a set of plugin manifests, produces a topologically-sorted
|
|
6
|
+
* load order where dependencies are loaded before dependents.
|
|
7
|
+
*/
|
|
8
|
+
import type { QEPluginManifest } from './manifest';
|
|
9
|
+
export interface ResolvedPlugin {
|
|
10
|
+
manifest: QEPluginManifest;
|
|
11
|
+
/** Order index (0 = load first) */
|
|
12
|
+
order: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ResolutionResult {
|
|
15
|
+
/** Plugins in dependency-safe load order */
|
|
16
|
+
ordered: ResolvedPlugin[];
|
|
17
|
+
/** Unresolvable dependencies (plugin -> missing deps) */
|
|
18
|
+
missing: Map<string, string[]>;
|
|
19
|
+
}
|
|
20
|
+
export declare class PluginResolver {
|
|
21
|
+
/**
|
|
22
|
+
* Resolve plugin load order via DFS topological sort.
|
|
23
|
+
*
|
|
24
|
+
* @param manifests - All available plugin manifests
|
|
25
|
+
* @returns Ordered list of plugins safe to load sequentially
|
|
26
|
+
* @throws Error if a dependency cycle is detected
|
|
27
|
+
*/
|
|
28
|
+
resolve(manifests: QEPluginManifest[]): ResolutionResult;
|
|
29
|
+
/**
|
|
30
|
+
* Check if a specific plugin can be loaded given the currently loaded set.
|
|
31
|
+
*/
|
|
32
|
+
canLoad(manifest: QEPluginManifest, loaded: Set<string>): {
|
|
33
|
+
canLoad: boolean;
|
|
34
|
+
missingDeps: string[];
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=resolver.d.ts.map
|