agentic-qe 3.7.16 → 3.7.18
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/agents/v3/qe-devils-advocate.md +20 -0
- package/.claude/agents/v3/qe-gap-detector.md +25 -0
- package/.claude/agents/v3/qe-quality-gate.md +8 -0
- package/.claude/agents/v3/qe-requirements-validator.md +25 -0
- package/.claude/agents/v3/subagents/qe-code-reviewer.md +11 -0
- package/.claude/agents/v3/subagents/qe-integration-reviewer.md +11 -0
- package/.claude/agents/v3/subagents/qe-performance-reviewer.md +11 -0
- package/.claude/agents/v3/subagents/qe-security-reviewer.md +11 -0
- package/.claude/helpers/adr-compliance.sh +10 -10
- package/.claude/helpers/auto-memory-hook.mjs +24 -9
- package/.claude/helpers/brain-checkpoint.cjs +55 -145
- package/.claude/helpers/ddd-tracker.sh +2 -2
- package/.claude/helpers/guidance-hooks.sh +2 -2
- package/.claude/helpers/hook-handler.cjs +57 -18
- package/.claude/helpers/statusline.cjs +414 -595
- package/.claude/helpers/v3/quality-criteria/evidence-classification.md +116 -116
- package/.claude/helpers/v3/quality-criteria/htsm-categories.md +139 -139
- package/.claude/skills/README.md +8 -11
- package/.claude/skills/brutal-honesty-review/SKILL.md +3 -0
- package/.claude/skills/code-review-quality/SKILL.md +3 -0
- package/.claude/skills/qcsd-cicd-swarm/SKILL.md +79 -2075
- package/.claude/skills/qcsd-cicd-swarm/steps/01-flag-detection.md +62 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/02-core-agents.md +33 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/03-batch1-results.md +21 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/04-conditional-agents.md +23 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/05-decision-synthesis.md +30 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/06-report-generation.md +17 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/07-learning-persistence.md +27 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/08-deployment-advisor.md +25 -0
- package/.claude/skills/qcsd-cicd-swarm/steps/09-final-output.md +16 -0
- package/.claude/skills/qcsd-development-swarm/SKILL.md +79 -2027
- package/.claude/skills/qcsd-development-swarm/steps/01-flag-detection.md +50 -0
- package/.claude/skills/qcsd-development-swarm/steps/02-core-agents.md +29 -0
- package/.claude/skills/qcsd-development-swarm/steps/03-batch1-results.md +14 -0
- package/.claude/skills/qcsd-development-swarm/steps/04-conditional-agents.md +23 -0
- package/.claude/skills/qcsd-development-swarm/steps/05-decision-synthesis.md +30 -0
- package/.claude/skills/qcsd-development-swarm/steps/06-report-generation.md +16 -0
- package/.claude/skills/qcsd-development-swarm/steps/07-learning-persistence.md +25 -0
- package/.claude/skills/qcsd-development-swarm/steps/08-defect-predictor.md +25 -0
- package/.claude/skills/qcsd-development-swarm/steps/09-final-output.md +16 -0
- package/.claude/skills/qcsd-ideation-swarm/SKILL.md +94 -1894
- package/.claude/skills/qcsd-ideation-swarm/steps/01-flag-detection.md +57 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/02-core-agents.md +29 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/03-batch1-results.md +15 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/04-conditional-agents.md +23 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/05-decision-synthesis.md +29 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/06-report-generation.md +18 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/07-learning-persistence.md +29 -0
- package/.claude/skills/qcsd-ideation-swarm/steps/08-final-output.md +18 -0
- package/.claude/skills/qcsd-production-swarm/SKILL.md +88 -2663
- package/.claude/skills/qcsd-production-swarm/steps/01-flag-detection.md +206 -0
- package/.claude/skills/qcsd-production-swarm/steps/02-core-agents.md +428 -0
- package/.claude/skills/qcsd-production-swarm/steps/03-batch1-results.md +101 -0
- package/.claude/skills/qcsd-production-swarm/steps/04-conditional-agents.md +125 -0
- package/.claude/skills/qcsd-production-swarm/steps/05-decision-synthesis.md +136 -0
- package/.claude/skills/qcsd-production-swarm/steps/06-report-generation.md +181 -0
- package/.claude/skills/qcsd-production-swarm/steps/07-learning-persistence.md +185 -0
- package/.claude/skills/qcsd-production-swarm/steps/08-feedback-loop.md +122 -0
- package/.claude/skills/qcsd-production-swarm/steps/09-final-output.md +140 -0
- package/.claude/skills/qcsd-refinement-swarm/SKILL.md +59 -2312
- package/.claude/skills/qcsd-refinement-swarm/steps/01-flag-detection.md +91 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/02-core-agents.md +40 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/03-batch1-results.md +40 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/04-conditional-agents.md +35 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/05-decision-synthesis.md +43 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/06-report-generation.md +42 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/07-learning-persistence.md +53 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/08-transformation.md +36 -0
- package/.claude/skills/qcsd-refinement-swarm/steps/09-final-output.md +46 -0
- package/.claude/skills/sherlock-review/SKILL.md +3 -0
- package/.claude/skills/skill-builder/SKILL.md +103 -0
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +29 -0
- package/assets/agents/v3/qe-devils-advocate.md +20 -0
- package/assets/agents/v3/qe-gap-detector.md +25 -0
- package/assets/agents/v3/qe-quality-gate.md +8 -0
- package/assets/agents/v3/qe-requirements-validator.md +25 -0
- package/assets/agents/v3/subagents/qe-code-reviewer.md +11 -0
- package/assets/agents/v3/subagents/qe-integration-reviewer.md +11 -0
- package/assets/agents/v3/subagents/qe-performance-reviewer.md +11 -0
- package/assets/agents/v3/subagents/qe-security-reviewer.md +11 -0
- package/assets/helpers/statusline-v3.cjs +693 -0
- package/assets/skills/brutal-honesty-review/SKILL.md +3 -0
- package/assets/skills/code-review-quality/SKILL.md +3 -0
- package/assets/skills/qcsd-cicd-swarm/SKILL.md +79 -2075
- package/assets/skills/qcsd-cicd-swarm/steps/01-flag-detection.md +62 -0
- package/assets/skills/qcsd-cicd-swarm/steps/02-core-agents.md +33 -0
- package/assets/skills/qcsd-cicd-swarm/steps/03-batch1-results.md +21 -0
- package/assets/skills/qcsd-cicd-swarm/steps/04-conditional-agents.md +23 -0
- package/assets/skills/qcsd-cicd-swarm/steps/05-decision-synthesis.md +30 -0
- package/assets/skills/qcsd-cicd-swarm/steps/06-report-generation.md +17 -0
- package/assets/skills/qcsd-cicd-swarm/steps/07-learning-persistence.md +27 -0
- package/assets/skills/qcsd-cicd-swarm/steps/08-deployment-advisor.md +25 -0
- package/assets/skills/qcsd-cicd-swarm/steps/09-final-output.md +16 -0
- package/assets/skills/qcsd-development-swarm/SKILL.md +79 -2027
- package/assets/skills/qcsd-development-swarm/steps/01-flag-detection.md +50 -0
- package/assets/skills/qcsd-development-swarm/steps/02-core-agents.md +29 -0
- package/assets/skills/qcsd-development-swarm/steps/03-batch1-results.md +14 -0
- package/assets/skills/qcsd-development-swarm/steps/04-conditional-agents.md +23 -0
- package/assets/skills/qcsd-development-swarm/steps/05-decision-synthesis.md +30 -0
- package/assets/skills/qcsd-development-swarm/steps/06-report-generation.md +16 -0
- package/assets/skills/qcsd-development-swarm/steps/07-learning-persistence.md +25 -0
- package/assets/skills/qcsd-development-swarm/steps/08-defect-predictor.md +25 -0
- package/assets/skills/qcsd-development-swarm/steps/09-final-output.md +16 -0
- package/assets/skills/qcsd-ideation-swarm/SKILL.md +94 -1894
- package/assets/skills/qcsd-ideation-swarm/steps/01-flag-detection.md +57 -0
- package/assets/skills/qcsd-ideation-swarm/steps/02-core-agents.md +29 -0
- package/assets/skills/qcsd-ideation-swarm/steps/03-batch1-results.md +15 -0
- package/assets/skills/qcsd-ideation-swarm/steps/04-conditional-agents.md +23 -0
- package/assets/skills/qcsd-ideation-swarm/steps/05-decision-synthesis.md +29 -0
- package/assets/skills/qcsd-ideation-swarm/steps/06-report-generation.md +18 -0
- package/assets/skills/qcsd-ideation-swarm/steps/07-learning-persistence.md +29 -0
- package/assets/skills/qcsd-ideation-swarm/steps/08-final-output.md +18 -0
- package/assets/skills/qcsd-production-swarm/SKILL.md +88 -2663
- package/assets/skills/qcsd-production-swarm/steps/01-flag-detection.md +206 -0
- package/assets/skills/qcsd-production-swarm/steps/02-core-agents.md +428 -0
- package/assets/skills/qcsd-production-swarm/steps/03-batch1-results.md +101 -0
- package/assets/skills/qcsd-production-swarm/steps/04-conditional-agents.md +125 -0
- package/assets/skills/qcsd-production-swarm/steps/05-decision-synthesis.md +136 -0
- package/assets/skills/qcsd-production-swarm/steps/06-report-generation.md +181 -0
- package/assets/skills/qcsd-production-swarm/steps/07-learning-persistence.md +185 -0
- package/assets/skills/qcsd-production-swarm/steps/08-feedback-loop.md +122 -0
- package/assets/skills/qcsd-production-swarm/steps/09-final-output.md +140 -0
- package/assets/skills/qcsd-refinement-swarm/SKILL.md +59 -2312
- package/assets/skills/qcsd-refinement-swarm/steps/01-flag-detection.md +91 -0
- package/assets/skills/qcsd-refinement-swarm/steps/02-core-agents.md +40 -0
- package/assets/skills/qcsd-refinement-swarm/steps/03-batch1-results.md +40 -0
- package/assets/skills/qcsd-refinement-swarm/steps/04-conditional-agents.md +35 -0
- package/assets/skills/qcsd-refinement-swarm/steps/05-decision-synthesis.md +43 -0
- package/assets/skills/qcsd-refinement-swarm/steps/06-report-generation.md +42 -0
- package/assets/skills/qcsd-refinement-swarm/steps/07-learning-persistence.md +53 -0
- package/assets/skills/qcsd-refinement-swarm/steps/08-transformation.md +36 -0
- package/assets/skills/qcsd-refinement-swarm/steps/09-final-output.md +46 -0
- package/assets/skills/sherlock-review/SKILL.md +3 -0
- package/assets/templates/agent-override-example.yaml +39 -0
- package/dist/agents/devils-advocate/agent.d.ts +25 -1
- package/dist/agents/devils-advocate/agent.js +108 -4
- package/dist/agents/devils-advocate/types.d.ts +54 -0
- package/dist/agents/devils-advocate/types.js +14 -0
- package/dist/agents/overlay-loader.d.ts +28 -0
- package/dist/agents/overlay-loader.js +232 -0
- package/dist/agents/overlay-schema.d.ts +56 -0
- package/dist/agents/overlay-schema.js +77 -0
- package/dist/analysis/branch-enumerator.d.ts +68 -0
- package/dist/analysis/branch-enumerator.js +393 -0
- package/dist/analysis/index.d.ts +2 -0
- package/dist/analysis/index.js +2 -0
- package/dist/cli/bundle.js +2415 -624
- package/dist/cli/commands/coverage.js +50 -0
- package/dist/context/compiler.d.ts +62 -0
- package/dist/context/compiler.js +143 -0
- package/dist/context/index.d.ts +8 -0
- package/dist/context/index.js +6 -0
- package/dist/context/sources/coverage-source.d.ts +15 -0
- package/dist/context/sources/coverage-source.js +77 -0
- package/dist/context/sources/git-source.d.ts +12 -0
- package/dist/context/sources/git-source.js +33 -0
- package/dist/context/sources/index.d.ts +6 -0
- package/dist/context/sources/index.js +5 -0
- package/dist/context/sources/memory-source.d.ts +17 -0
- package/dist/context/sources/memory-source.js +94 -0
- package/dist/context/sources/test-source.d.ts +13 -0
- package/dist/context/sources/test-source.js +53 -0
- package/dist/context/sources/types.d.ts +42 -0
- package/dist/context/sources/types.js +5 -0
- package/dist/init/agents-installer.d.ts +9 -0
- package/dist/init/agents-installer.js +79 -0
- package/dist/init/phases/07-hooks.d.ts +11 -0
- package/dist/init/phases/07-hooks.js +67 -0
- package/dist/init/phases/09-assets.js +18 -10
- package/dist/init/settings-merge.js +1 -1
- package/dist/mcp/bundle.js +4411 -3979
- package/dist/mcp/services/task-router.d.ts +11 -0
- package/dist/mcp/services/task-router.js +26 -0
- package/dist/routing/qe-agent-registry.d.ts +11 -0
- package/dist/routing/qe-agent-registry.js +34 -0
- package/dist/routing/qe-task-router.d.ts +1 -0
- package/dist/routing/qe-task-router.js +34 -2
- package/dist/routing/types.d.ts +2 -0
- package/dist/validation/index.d.ts +3 -0
- package/dist/validation/index.js +10 -0
- package/dist/validation/pipeline.d.ts +80 -0
- package/dist/validation/pipeline.js +173 -0
- package/dist/validation/steps/requirements.d.ts +32 -0
- package/dist/validation/steps/requirements.js +596 -0
- package/package.json +6 -6
- package/.claude/agents/consensus/README.md +0 -253
- package/.claude/agents/deprecated/qe-api-contract-validator.md.v2 +0 -162
- package/.claude/agents/deprecated/qe-coverage-analyzer.md.v2 +0 -208
- package/.claude/agents/deprecated/qe-test-generator.md.v2 +0 -212
- package/.claude/agents/deprecated/qe-visual-tester.md.v2 +0 -216
- package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +0 -130
- package/.claude/agents/hive-mind/queen-coordinator.md +0 -203
- package/.claude/agents/hive-mind/scout-explorer.md +0 -242
- package/.claude/agents/hive-mind/swarm-memory-manager.md +0 -193
- package/.claude/agents/hive-mind/worker-specialist.md +0 -217
- package/.claude/agents/neural/safla-neural.md +0 -74
- package/.claude/agents/optimization/README.md +0 -250
- package/.claude/agents/reasoning/agent.md +0 -816
- package/.claude/agents/reasoning/goal-planner.md +0 -73
- package/.claude/agents/subagents/qe-code-reviewer.md +0 -76
- package/.claude/agents/subagents/qe-coverage-gap-analyzer.md +0 -76
- package/.claude/agents/subagents/qe-data-generator.md +0 -77
- package/.claude/agents/subagents/qe-flaky-investigator.md +0 -91
- package/.claude/agents/subagents/qe-integration-tester.md +0 -90
- package/.claude/agents/subagents/qe-performance-validator.md +0 -92
- package/.claude/agents/subagents/qe-security-auditor.md +0 -94
- package/.claude/agents/subagents/qe-test-data-architect-sub.md +0 -93
- package/.claude/agents/subagents/qe-test-implementer.md +0 -106
- package/.claude/agents/subagents/qe-test-refactorer.md +0 -117
- package/.claude/agents/subagents/qe-test-writer.md +0 -112
- package/.claude/agents/swarm/README.md +0 -190
- package/.claude/agents/templates/migration-plan.md +0 -746
- package/.claude/agents/testing/unit/tdd-london-swarm.md +0 -244
- package/.claude/agents/testing/validation/production-validator.md +0 -395
- package/.claude/agents/v3/README.md +0 -39
- package/.claude/agents/v3/typescript-specialist.yaml +0 -21
- package/.claude/agents/v3/v3-memory-specialist.md +0 -318
- package/.claude/agents/v3/v3-performance-engineer.md +0 -397
- package/.claude/agents/v3/v3-queen-coordinator.md +0 -98
- package/.claude/agents/v3/v3-security-architect.md +0 -174
- package/.claude/commands/README.md +0 -106
- package/.claude/commands/agents/README.md +0 -10
- package/.claude/commands/agents/agent-capabilities.md +0 -21
- package/.claude/commands/agents/agent-coordination.md +0 -28
- package/.claude/commands/agents/agent-spawning.md +0 -28
- package/.claude/commands/agents/agent-types.md +0 -26
- package/.claude/commands/coordination/README.md +0 -9
- package/.claude/commands/coordination/agent-spawn.md +0 -25
- package/.claude/commands/coordination/init.md +0 -44
- package/.claude/commands/coordination/orchestrate.md +0 -43
- package/.claude/commands/coordination/spawn.md +0 -45
- package/.claude/commands/coordination/swarm-init.md +0 -85
- package/.claude/commands/coordination/task-orchestrate.md +0 -25
- package/.claude/commands/hive-mind/README.md +0 -17
- package/.claude/commands/hive-mind/hive-mind-consensus.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-init.md +0 -18
- package/.claude/commands/hive-mind/hive-mind-memory.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-metrics.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-resume.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-sessions.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-spawn.md +0 -21
- package/.claude/commands/hive-mind/hive-mind-status.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-stop.md +0 -8
- package/.claude/commands/hive-mind/hive-mind-wizard.md +0 -8
- package/.claude/commands/hive-mind/hive-mind.md +0 -27
- package/.claude/commands/memory/README.md +0 -9
- package/.claude/commands/memory/memory-persist.md +0 -25
- package/.claude/commands/memory/memory-search.md +0 -25
- package/.claude/commands/memory/memory-usage.md +0 -25
- package/.claude/commands/memory/neural.md +0 -47
- package/.claude/commands/swarm/README.md +0 -15
- package/.claude/commands/swarm/swarm-analysis.md +0 -8
- package/.claude/commands/swarm/swarm-background.md +0 -8
- package/.claude/commands/swarm/swarm-init.md +0 -19
- package/.claude/commands/swarm/swarm-modes.md +0 -8
- package/.claude/commands/swarm/swarm-monitor.md +0 -8
- package/.claude/commands/swarm/swarm-spawn.md +0 -19
- package/.claude/commands/swarm/swarm-status.md +0 -8
- package/.claude/commands/swarm/swarm-strategies.md +0 -8
- package/.claude/commands/swarm/swarm.md +0 -27
- package/.claude/commands/training/README.md +0 -9
- package/.claude/commands/training/model-update.md +0 -25
- package/.claude/commands/training/neural-patterns.md +0 -74
- package/.claude/commands/training/neural-train.md +0 -25
- package/.claude/commands/training/pattern-learn.md +0 -25
- package/.claude/commands/training/specialization.md +0 -63
- package/.claude/commands/workflows/README.md +0 -9
- package/.claude/commands/workflows/development.md +0 -78
- package/.claude/commands/workflows/research.md +0 -63
- package/.claude/commands/workflows/workflow-create.md +0 -25
- package/.claude/commands/workflows/workflow-execute.md +0 -25
- package/.claude/commands/workflows/workflow-export.md +0 -25
- package/.claude/skills/agentic-jujutsu/SKILL.md +0 -645
- package/.claude/skills/hive-mind-advanced/SKILL.md +0 -712
- package/.claude/skills/iterative-loop/SKILL.md +0 -371
- package/.claude/skills/performance-analysis/SKILL.md +0 -569
- package/.claude/skills/performance-analysis/evals/performance-analysis.yaml +0 -144
- package/.claude/skills/performance-analysis/schemas/output.json +0 -588
- package/.claude/skills/performance-analysis/scripts/validate-config.json +0 -36
|
@@ -222,6 +222,56 @@ export function createCoverageCommand(context, cleanupAndExit, ensureInitialized
|
|
|
222
222
|
await cleanupAndExit(1);
|
|
223
223
|
}
|
|
224
224
|
});
|
|
225
|
+
// Subcommand: coverage gaps — enumerate unhandled branches via static analysis
|
|
226
|
+
coverageCmd
|
|
227
|
+
.command('gaps')
|
|
228
|
+
.description('Enumerate unhandled branches in source files')
|
|
229
|
+
.argument('<file>', 'Source file to analyze')
|
|
230
|
+
.option('--mechanical', 'Exhaustive mode: report all branches without filtering')
|
|
231
|
+
.option('--json', 'Output as JSON')
|
|
232
|
+
.option('--markdown', 'Output as markdown report')
|
|
233
|
+
.action(async (file, options) => {
|
|
234
|
+
try {
|
|
235
|
+
const { readFileSync, existsSync } = await import('fs');
|
|
236
|
+
const pathMod = await import('path');
|
|
237
|
+
const { enumerateBranches, formatBranchReport, formatBranchJSON } = await import('../../analysis/branch-enumerator.js');
|
|
238
|
+
const resolvedFile = pathMod.resolve(file);
|
|
239
|
+
if (!existsSync(resolvedFile)) {
|
|
240
|
+
console.error(chalk.red(`\n File not found: ${resolvedFile}\n`));
|
|
241
|
+
await cleanupAndExit(1);
|
|
242
|
+
}
|
|
243
|
+
const sourceCode = readFileSync(resolvedFile, 'utf-8');
|
|
244
|
+
const result = enumerateBranches(sourceCode, resolvedFile);
|
|
245
|
+
if (options.json) {
|
|
246
|
+
console.log(formatBranchJSON(result));
|
|
247
|
+
}
|
|
248
|
+
else if (options.markdown) {
|
|
249
|
+
console.log(formatBranchReport(result));
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
// Table format
|
|
253
|
+
console.log(`\n${chalk.cyan('Branch Enumeration:')} ${chalk.white(file)}`);
|
|
254
|
+
console.log(chalk.gray(`Found ${result.unhandledCount} unhandled branches (${result.duration}ms)\n`));
|
|
255
|
+
if (result.branches.length > 0) {
|
|
256
|
+
console.log(chalk.dim('Line | Severity | Construct | Trigger'));
|
|
257
|
+
console.log(chalk.dim('-----|----------|---------------------------|--------'));
|
|
258
|
+
for (const b of result.branches) {
|
|
259
|
+
const severityColor = b.severity === 'high' ? chalk.red : b.severity === 'medium' ? chalk.yellow : chalk.gray;
|
|
260
|
+
console.log(`${String(b.line).padStart(4)} | ${severityColor(b.severity.padEnd(8))} | ${b.construct.padEnd(25)} | ${b.triggerCondition}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
console.log(chalk.green('No unhandled branches detected.'));
|
|
265
|
+
}
|
|
266
|
+
console.log('');
|
|
267
|
+
}
|
|
268
|
+
await cleanupAndExit(0);
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
console.error(chalk.red('\nBranch enumeration failed:'), error);
|
|
272
|
+
await cleanupAndExit(1);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
225
275
|
return coverageCmd;
|
|
226
276
|
}
|
|
227
277
|
//# sourceMappingURL=coverage.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Compiler (BMAD-005)
|
|
3
|
+
*
|
|
4
|
+
* Aggregates relevant context from multiple sources before agent execution.
|
|
5
|
+
* Produces a focused context document that reduces redundant queries.
|
|
6
|
+
*/
|
|
7
|
+
import type { ContextSource, ContextRequest, ContextFragment } from './sources/types.js';
|
|
8
|
+
export interface CompiledContext {
|
|
9
|
+
/** One-paragraph overview */
|
|
10
|
+
summary: string;
|
|
11
|
+
/** Aggregated fragments sorted by priority */
|
|
12
|
+
fragments: ContextFragment[];
|
|
13
|
+
/** Total estimated tokens */
|
|
14
|
+
totalTokens: number;
|
|
15
|
+
/** Which sources contributed */
|
|
16
|
+
sources: string[];
|
|
17
|
+
/** Compilation timestamp */
|
|
18
|
+
timestamp: string;
|
|
19
|
+
/** Compilation duration in ms */
|
|
20
|
+
duration: number;
|
|
21
|
+
}
|
|
22
|
+
export interface CompilerConfig {
|
|
23
|
+
/** Maximum total token budget (default: 8000, using chars/3.5 estimation per Gap 7) */
|
|
24
|
+
maxTokenBudget?: number;
|
|
25
|
+
/** Sources to use (default: all) */
|
|
26
|
+
sources?: ContextSource[];
|
|
27
|
+
/** Cache TTL in ms (default: 5 minutes) */
|
|
28
|
+
cacheTtlMs?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create default context sources.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createDefaultSources(): ContextSource[];
|
|
34
|
+
export declare class ContextCompiler {
|
|
35
|
+
private sources;
|
|
36
|
+
private maxTokenBudget;
|
|
37
|
+
private cache;
|
|
38
|
+
private cacheTtl;
|
|
39
|
+
constructor(config?: CompilerConfig);
|
|
40
|
+
/**
|
|
41
|
+
* Compile context for a request.
|
|
42
|
+
*/
|
|
43
|
+
compile(request: ContextRequest): Promise<CompiledContext>;
|
|
44
|
+
/**
|
|
45
|
+
* Clear the cache.
|
|
46
|
+
*/
|
|
47
|
+
clearCache(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Get cache stats.
|
|
50
|
+
*/
|
|
51
|
+
getCacheStats(): {
|
|
52
|
+
size: number;
|
|
53
|
+
ttlMs: number;
|
|
54
|
+
};
|
|
55
|
+
private buildCacheKey;
|
|
56
|
+
private generateSummary;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Format compiled context as a string for agent prompts.
|
|
60
|
+
*/
|
|
61
|
+
export declare function formatContextForPrompt(context: CompiledContext): string;
|
|
62
|
+
//# sourceMappingURL=compiler.d.ts.map
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Compiler (BMAD-005)
|
|
3
|
+
*
|
|
4
|
+
* Aggregates relevant context from multiple sources before agent execution.
|
|
5
|
+
* Produces a focused context document that reduces redundant queries.
|
|
6
|
+
*/
|
|
7
|
+
import { MemoryContextSource } from './sources/memory-source.js';
|
|
8
|
+
import { GitContextSource } from './sources/git-source.js';
|
|
9
|
+
import { TestContextSource } from './sources/test-source.js';
|
|
10
|
+
import { CoverageContextSource } from './sources/coverage-source.js';
|
|
11
|
+
const DEFAULT_TOKEN_BUDGET = 8000;
|
|
12
|
+
const DEFAULT_CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
13
|
+
/**
|
|
14
|
+
* Create default context sources.
|
|
15
|
+
*/
|
|
16
|
+
export function createDefaultSources() {
|
|
17
|
+
return [
|
|
18
|
+
new MemoryContextSource(),
|
|
19
|
+
new TestContextSource(),
|
|
20
|
+
new GitContextSource(),
|
|
21
|
+
new CoverageContextSource(),
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
export class ContextCompiler {
|
|
25
|
+
sources;
|
|
26
|
+
maxTokenBudget;
|
|
27
|
+
cache = new Map();
|
|
28
|
+
cacheTtl;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.sources = config?.sources || createDefaultSources();
|
|
31
|
+
this.maxTokenBudget = config?.maxTokenBudget || DEFAULT_TOKEN_BUDGET;
|
|
32
|
+
this.cacheTtl = config?.cacheTtlMs || DEFAULT_CACHE_TTL;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Compile context for a request.
|
|
36
|
+
*/
|
|
37
|
+
async compile(request) {
|
|
38
|
+
const start = Date.now();
|
|
39
|
+
// Check cache
|
|
40
|
+
const cacheKey = this.buildCacheKey(request);
|
|
41
|
+
const cached = this.cache.get(cacheKey);
|
|
42
|
+
if (cached && Date.now() - cached.timestamp < this.cacheTtl) {
|
|
43
|
+
return cached.result;
|
|
44
|
+
}
|
|
45
|
+
// Override budget if request specifies
|
|
46
|
+
const budget = request.maxTokenBudget || this.maxTokenBudget;
|
|
47
|
+
// Gather from all sources in parallel
|
|
48
|
+
const sourceResults = await Promise.allSettled(this.sources.map(async (source) => {
|
|
49
|
+
try {
|
|
50
|
+
const fragments = await source.gather(request);
|
|
51
|
+
return { sourceId: source.id, sourceName: source.name, priority: source.priority, fragments };
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return { sourceId: source.id, sourceName: source.name, priority: source.priority, fragments: [] };
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
// Collect all fragments with source priority
|
|
58
|
+
const allFragments = [];
|
|
59
|
+
const contributingSources = [];
|
|
60
|
+
for (const result of sourceResults) {
|
|
61
|
+
if (result.status === 'fulfilled') {
|
|
62
|
+
const { sourceId, priority, fragments } = result.value;
|
|
63
|
+
if (fragments.length > 0) {
|
|
64
|
+
contributingSources.push(sourceId);
|
|
65
|
+
for (const fragment of fragments) {
|
|
66
|
+
allFragments.push({ ...fragment, sourcePriority: priority });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Sort by priority (highest first), then by relevance
|
|
72
|
+
allFragments.sort((a, b) => {
|
|
73
|
+
if (a.sourcePriority !== b.sourcePriority)
|
|
74
|
+
return b.sourcePriority - a.sourcePriority;
|
|
75
|
+
return b.relevance - a.relevance;
|
|
76
|
+
});
|
|
77
|
+
// Trim to fit budget
|
|
78
|
+
const selectedFragments = [];
|
|
79
|
+
let usedTokens = 0;
|
|
80
|
+
for (const fragment of allFragments) {
|
|
81
|
+
if (usedTokens + fragment.estimatedTokens <= budget) {
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
83
|
+
const { sourcePriority: _sp, ...frag } = fragment;
|
|
84
|
+
selectedFragments.push(frag);
|
|
85
|
+
usedTokens += fragment.estimatedTokens;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Generate summary
|
|
89
|
+
const summary = this.generateSummary(request, selectedFragments, contributingSources);
|
|
90
|
+
const compiled = {
|
|
91
|
+
summary,
|
|
92
|
+
fragments: selectedFragments,
|
|
93
|
+
totalTokens: usedTokens,
|
|
94
|
+
sources: contributingSources,
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
duration: Date.now() - start,
|
|
97
|
+
};
|
|
98
|
+
// Cache result
|
|
99
|
+
this.cache.set(cacheKey, { result: compiled, timestamp: Date.now() });
|
|
100
|
+
return compiled;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Clear the cache.
|
|
104
|
+
*/
|
|
105
|
+
clearCache() {
|
|
106
|
+
this.cache.clear();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get cache stats.
|
|
110
|
+
*/
|
|
111
|
+
getCacheStats() {
|
|
112
|
+
return { size: this.cache.size, ttlMs: this.cacheTtl };
|
|
113
|
+
}
|
|
114
|
+
buildCacheKey(request) {
|
|
115
|
+
return `${request.agentType}:${request.targetFiles.sort().join(',')}:${request.taskDescription.slice(0, 100)}`;
|
|
116
|
+
}
|
|
117
|
+
generateSummary(request, fragments, sources) {
|
|
118
|
+
return [
|
|
119
|
+
`Context compiled for ${request.agentType} agent.`,
|
|
120
|
+
`Target: ${request.targetFiles.length} file(s).`,
|
|
121
|
+
`Sources: ${sources.join(', ')}.`,
|
|
122
|
+
`Fragments: ${fragments.length} (${fragments.reduce((s, f) => s + f.estimatedTokens, 0)} est. tokens).`,
|
|
123
|
+
].join(' ');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Format compiled context as a string for agent prompts.
|
|
128
|
+
*/
|
|
129
|
+
export function formatContextForPrompt(context) {
|
|
130
|
+
const lines = [];
|
|
131
|
+
lines.push('## Compiled Context');
|
|
132
|
+
lines.push('');
|
|
133
|
+
lines.push(context.summary);
|
|
134
|
+
lines.push('');
|
|
135
|
+
for (const fragment of context.fragments) {
|
|
136
|
+
lines.push(`### ${fragment.title}`);
|
|
137
|
+
lines.push(fragment.content);
|
|
138
|
+
lines.push('');
|
|
139
|
+
}
|
|
140
|
+
lines.push(`_Context compiled: ${context.timestamp} (${context.duration}ms)_`);
|
|
141
|
+
return lines.join('\n');
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=compiler.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { ContextCompiler, formatContextForPrompt, createDefaultSources } from './compiler.js';
|
|
2
|
+
export type { CompiledContext, CompilerConfig } from './compiler.js';
|
|
3
|
+
export type { ContextSource, ContextRequest, ContextFragment } from './sources/types.js';
|
|
4
|
+
export { MemoryContextSource } from './sources/memory-source.js';
|
|
5
|
+
export { GitContextSource } from './sources/git-source.js';
|
|
6
|
+
export { TestContextSource } from './sources/test-source.js';
|
|
7
|
+
export { CoverageContextSource } from './sources/coverage-source.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ContextCompiler, formatContextForPrompt, createDefaultSources } from './compiler.js';
|
|
2
|
+
export { MemoryContextSource } from './sources/memory-source.js';
|
|
3
|
+
export { GitContextSource } from './sources/git-source.js';
|
|
4
|
+
export { TestContextSource } from './sources/test-source.js';
|
|
5
|
+
export { CoverageContextSource } from './sources/coverage-source.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage Source - Coverage data for target files
|
|
3
|
+
*
|
|
4
|
+
* Reads coverage reports from standard locations (Istanbul/NYC output)
|
|
5
|
+
* and extracts per-file and project-level coverage metrics.
|
|
6
|
+
*/
|
|
7
|
+
import type { ContextSource, ContextRequest, ContextFragment } from './types.js';
|
|
8
|
+
export declare class CoverageContextSource implements ContextSource {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
priority: number;
|
|
12
|
+
maxTokens: number;
|
|
13
|
+
gather(request: ContextRequest): Promise<ContextFragment[]>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=coverage-source.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage Source - Coverage data for target files
|
|
3
|
+
*
|
|
4
|
+
* Reads coverage reports from standard locations (Istanbul/NYC output)
|
|
5
|
+
* and extracts per-file and project-level coverage metrics.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync } from 'fs';
|
|
8
|
+
import { join, basename } from 'path';
|
|
9
|
+
export class CoverageContextSource {
|
|
10
|
+
id = 'coverage';
|
|
11
|
+
name = 'Coverage Data';
|
|
12
|
+
priority = 50;
|
|
13
|
+
maxTokens = 1000;
|
|
14
|
+
async gather(request) {
|
|
15
|
+
const fragments = [];
|
|
16
|
+
// Look for coverage reports in standard locations
|
|
17
|
+
const coveragePaths = [
|
|
18
|
+
join(process.cwd(), 'coverage', 'coverage-summary.json'),
|
|
19
|
+
join(process.cwd(), 'coverage', 'coverage-final.json'),
|
|
20
|
+
join(process.cwd(), '.coverage', 'coverage-summary.json'),
|
|
21
|
+
];
|
|
22
|
+
for (const coveragePath of coveragePaths) {
|
|
23
|
+
if (!existsSync(coveragePath))
|
|
24
|
+
continue;
|
|
25
|
+
try {
|
|
26
|
+
const raw = readFileSync(coveragePath, 'utf-8');
|
|
27
|
+
const data = JSON.parse(raw);
|
|
28
|
+
// Extract coverage for target files
|
|
29
|
+
const targetCoverage = [];
|
|
30
|
+
for (const targetFile of request.targetFiles) {
|
|
31
|
+
const fileName = basename(targetFile);
|
|
32
|
+
// Search for matching entries in coverage data
|
|
33
|
+
for (const [filePath, metrics] of Object.entries(data)) {
|
|
34
|
+
if (filePath.includes(fileName) && metrics && typeof metrics === 'object') {
|
|
35
|
+
const m = metrics;
|
|
36
|
+
const lines = m.lines?.pct ?? m.statements?.pct;
|
|
37
|
+
const branches = m.branches?.pct;
|
|
38
|
+
const functions = m.functions?.pct;
|
|
39
|
+
if (lines !== undefined) {
|
|
40
|
+
targetCoverage.push(`${fileName}: lines=${lines}%${branches !== undefined ? `, branches=${branches}%` : ''}${functions !== undefined ? `, functions=${functions}%` : ''}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (targetCoverage.length > 0) {
|
|
46
|
+
const content = `Coverage for target files:\n${targetCoverage.join('\n')}`;
|
|
47
|
+
fragments.push({
|
|
48
|
+
sourceId: this.id,
|
|
49
|
+
title: 'File Coverage Data',
|
|
50
|
+
content,
|
|
51
|
+
estimatedTokens: Math.ceil(content.length / 3.5),
|
|
52
|
+
relevance: 0.6,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Also extract overall project coverage if available
|
|
56
|
+
if (data.total && typeof data.total === 'object') {
|
|
57
|
+
const total = data.total;
|
|
58
|
+
const content = `Project coverage: lines=${total.lines?.pct ?? '?'}%, branches=${total.branches?.pct ?? '?'}%, functions=${total.functions?.pct ?? '?'}%`;
|
|
59
|
+
fragments.push({
|
|
60
|
+
sourceId: this.id,
|
|
61
|
+
title: 'Project Coverage Summary',
|
|
62
|
+
content,
|
|
63
|
+
estimatedTokens: Math.ceil(content.length / 3.5),
|
|
64
|
+
relevance: 0.4,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
break; // Found a coverage file, stop looking
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Failed to parse coverage file
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return fragments;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=coverage-source.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Source - Recent commit context for target files
|
|
3
|
+
*/
|
|
4
|
+
import type { ContextSource, ContextRequest, ContextFragment } from './types.js';
|
|
5
|
+
export declare class GitContextSource implements ContextSource {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
priority: number;
|
|
9
|
+
maxTokens: number;
|
|
10
|
+
gather(request: ContextRequest): Promise<ContextFragment[]>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=git-source.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Source - Recent commit context for target files
|
|
3
|
+
*/
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
export class GitContextSource {
|
|
6
|
+
id = 'git';
|
|
7
|
+
name = 'Git History';
|
|
8
|
+
priority = 60;
|
|
9
|
+
maxTokens = 1500;
|
|
10
|
+
async gather(request) {
|
|
11
|
+
const fragments = [];
|
|
12
|
+
for (const file of request.targetFiles.slice(0, 5)) { // Cap at 5 files
|
|
13
|
+
try {
|
|
14
|
+
const log = execSync(`git log --oneline -5 -- "${file}" 2>/dev/null || true`, { encoding: 'utf-8', timeout: 5000 }).trim();
|
|
15
|
+
if (log) {
|
|
16
|
+
const content = `Recent commits for ${file}:\n${log}`;
|
|
17
|
+
fragments.push({
|
|
18
|
+
sourceId: this.id,
|
|
19
|
+
title: `Git history: ${file}`,
|
|
20
|
+
content,
|
|
21
|
+
estimatedTokens: Math.ceil(content.length / 3.5),
|
|
22
|
+
relevance: 0.5,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Git command failed — skip this file
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return fragments;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=git-source.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { ContextSource, ContextRequest, ContextFragment } from './types.js';
|
|
2
|
+
export { MemoryContextSource } from './memory-source.js';
|
|
3
|
+
export { GitContextSource } from './git-source.js';
|
|
4
|
+
export { TestContextSource } from './test-source.js';
|
|
5
|
+
export { CoverageContextSource } from './coverage-source.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Source - Relevant patterns from learning database
|
|
3
|
+
*
|
|
4
|
+
* Queries the SQLite pattern store for patterns relevant to the current task.
|
|
5
|
+
* Falls back to basic task context when the database is unavailable.
|
|
6
|
+
*/
|
|
7
|
+
import type { ContextSource, ContextRequest, ContextFragment } from './types.js';
|
|
8
|
+
export declare class MemoryContextSource implements ContextSource {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
priority: number;
|
|
12
|
+
maxTokens: number;
|
|
13
|
+
gather(request: ContextRequest): Promise<ContextFragment[]>;
|
|
14
|
+
private fallbackGather;
|
|
15
|
+
private extractDomainKeywords;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=memory-source.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Source - Relevant patterns from learning database
|
|
3
|
+
*
|
|
4
|
+
* Queries the SQLite pattern store for patterns relevant to the current task.
|
|
5
|
+
* Falls back to basic task context when the database is unavailable.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
export class MemoryContextSource {
|
|
10
|
+
id = 'memory';
|
|
11
|
+
name = 'Pattern Memory';
|
|
12
|
+
priority = 80;
|
|
13
|
+
maxTokens = 2000;
|
|
14
|
+
async gather(request) {
|
|
15
|
+
const fragments = [];
|
|
16
|
+
// Try to query the learning database for relevant patterns
|
|
17
|
+
try {
|
|
18
|
+
const dbPath = join(process.cwd(), '.agentic-qe', 'memory.db');
|
|
19
|
+
if (!existsSync(dbPath)) {
|
|
20
|
+
return this.fallbackGather(request);
|
|
21
|
+
}
|
|
22
|
+
// Dynamic import to avoid hard dependency
|
|
23
|
+
const Database = (await import('better-sqlite3')).default;
|
|
24
|
+
const db = new Database(dbPath, { readonly: true });
|
|
25
|
+
try {
|
|
26
|
+
// Query patterns relevant to the task domain
|
|
27
|
+
const domainKeywords = this.extractDomainKeywords(request.taskDescription);
|
|
28
|
+
if (domainKeywords.length > 0) {
|
|
29
|
+
const placeholders = domainKeywords.map(() => 'domain LIKE ?').join(' OR ');
|
|
30
|
+
const likePatterns = domainKeywords.map(k => `%${k}%`);
|
|
31
|
+
const stmt = db.prepare(`SELECT name, domain, description, confidence
|
|
32
|
+
FROM qe_patterns
|
|
33
|
+
WHERE ${placeholders}
|
|
34
|
+
ORDER BY confidence DESC
|
|
35
|
+
LIMIT 10`);
|
|
36
|
+
const patterns = stmt.all(...likePatterns);
|
|
37
|
+
if (patterns.length > 0) {
|
|
38
|
+
const content = patterns.map(p => `- **${p.name}** (${p.domain}, confidence: ${(p.confidence * 100).toFixed(0)}%): ${p.description || 'No description'}`).join('\n');
|
|
39
|
+
fragments.push({
|
|
40
|
+
sourceId: this.id,
|
|
41
|
+
title: 'Relevant Patterns from Learning Database',
|
|
42
|
+
content: `Found ${patterns.length} relevant patterns:\n\n${content}`,
|
|
43
|
+
estimatedTokens: Math.ceil(content.length / 3.5),
|
|
44
|
+
relevance: 0.8,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
db.close();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Database access failed -- use fallback
|
|
55
|
+
return this.fallbackGather(request);
|
|
56
|
+
}
|
|
57
|
+
if (fragments.length === 0) {
|
|
58
|
+
return this.fallbackGather(request);
|
|
59
|
+
}
|
|
60
|
+
return fragments;
|
|
61
|
+
}
|
|
62
|
+
fallbackGather(request) {
|
|
63
|
+
const content = [
|
|
64
|
+
`Task: ${request.taskDescription}`,
|
|
65
|
+
`Agent: ${request.agentType}`,
|
|
66
|
+
`Files: ${request.targetFiles.join(', ')}`,
|
|
67
|
+
].join('\n');
|
|
68
|
+
return [{
|
|
69
|
+
sourceId: this.id,
|
|
70
|
+
title: 'Task Context',
|
|
71
|
+
content,
|
|
72
|
+
estimatedTokens: Math.ceil(content.length / 3.5),
|
|
73
|
+
relevance: 0.5,
|
|
74
|
+
}];
|
|
75
|
+
}
|
|
76
|
+
extractDomainKeywords(description) {
|
|
77
|
+
const keywords = [];
|
|
78
|
+
const desc = description.toLowerCase();
|
|
79
|
+
const domainMap = {
|
|
80
|
+
'test-generation': ['test', 'generate', 'create test', 'unit test', 'spec'],
|
|
81
|
+
'coverage-analysis': ['coverage', 'gap', 'branch', 'uncovered'],
|
|
82
|
+
'security-compliance': ['security', 'vulnerability', 'owasp', 'injection', 'auth'],
|
|
83
|
+
'quality-assessment': ['quality', 'review', 'code review', 'assessment'],
|
|
84
|
+
'defect-intelligence': ['defect', 'bug', 'regression', 'root cause'],
|
|
85
|
+
};
|
|
86
|
+
for (const [domain, terms] of Object.entries(domainMap)) {
|
|
87
|
+
if (terms.some(t => desc.includes(t))) {
|
|
88
|
+
keywords.push(domain);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return keywords.length > 0 ? keywords : ['test-generation']; // default
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=memory-source.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Source - Existing tests for target files
|
|
3
|
+
*/
|
|
4
|
+
import type { ContextSource, ContextRequest, ContextFragment } from './types.js';
|
|
5
|
+
export declare class TestContextSource implements ContextSource {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
priority: number;
|
|
9
|
+
maxTokens: number;
|
|
10
|
+
gather(request: ContextRequest): Promise<ContextFragment[]>;
|
|
11
|
+
private findTestPaths;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=test-source.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Source - Existing tests for target files
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, readFileSync } from 'fs';
|
|
5
|
+
import { basename, dirname, join } from 'path';
|
|
6
|
+
export class TestContextSource {
|
|
7
|
+
id = 'tests';
|
|
8
|
+
name = 'Existing Tests';
|
|
9
|
+
priority = 70;
|
|
10
|
+
maxTokens = 2000;
|
|
11
|
+
async gather(request) {
|
|
12
|
+
const fragments = [];
|
|
13
|
+
for (const file of request.targetFiles.slice(0, 3)) {
|
|
14
|
+
const testPaths = this.findTestPaths(file);
|
|
15
|
+
for (const testPath of testPaths) {
|
|
16
|
+
if (existsSync(testPath)) {
|
|
17
|
+
try {
|
|
18
|
+
const content = readFileSync(testPath, 'utf-8');
|
|
19
|
+
// Extract test names only (not full bodies) to save tokens
|
|
20
|
+
const testNames = content.match(/(?:it|test|describe)\s*\(\s*['"`]([^'"`]+)['"`]/g) || [];
|
|
21
|
+
if (testNames.length > 0) {
|
|
22
|
+
const summary = `Tests for ${basename(file)} (${testPath}):\n${testNames.join('\n')}`;
|
|
23
|
+
fragments.push({
|
|
24
|
+
sourceId: this.id,
|
|
25
|
+
title: `Tests: ${basename(file)}`,
|
|
26
|
+
content: summary,
|
|
27
|
+
estimatedTokens: Math.ceil(summary.length / 3.5),
|
|
28
|
+
relevance: 0.8,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// File read failed — skip
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return fragments;
|
|
39
|
+
}
|
|
40
|
+
findTestPaths(filePath) {
|
|
41
|
+
const base = basename(filePath).replace(/\.(ts|js|tsx|jsx)$/, '');
|
|
42
|
+
const dir = dirname(filePath);
|
|
43
|
+
const extensions = ['.test.ts', '.spec.ts', '.test.js', '.spec.js'];
|
|
44
|
+
const paths = [];
|
|
45
|
+
for (const ext of extensions) {
|
|
46
|
+
paths.push(join(dir, `${base}${ext}`));
|
|
47
|
+
paths.push(join(dir, '__tests__', `${base}${ext}`));
|
|
48
|
+
paths.push(join(dir, '..', 'tests', `${base}${ext}`));
|
|
49
|
+
}
|
|
50
|
+
return paths;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=test-source.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Source Types (BMAD-005)
|
|
3
|
+
*/
|
|
4
|
+
export interface ContextRequest {
|
|
5
|
+
/** Target files to gather context for */
|
|
6
|
+
targetFiles: string[];
|
|
7
|
+
/** Agent type requesting context */
|
|
8
|
+
agentType: string;
|
|
9
|
+
/** Task description */
|
|
10
|
+
taskDescription: string;
|
|
11
|
+
/** Maximum token budget across all sources */
|
|
12
|
+
maxTokenBudget?: number;
|
|
13
|
+
/** Additional metadata */
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface ContextFragment {
|
|
17
|
+
/** Source identifier */
|
|
18
|
+
sourceId: string;
|
|
19
|
+
/** Fragment title */
|
|
20
|
+
title: string;
|
|
21
|
+
/** Fragment content */
|
|
22
|
+
content: string;
|
|
23
|
+
/** Estimated token count (chars / 3.5 with safety margin) */
|
|
24
|
+
estimatedTokens: number;
|
|
25
|
+
/** Relevance score 0-1 */
|
|
26
|
+
relevance: number;
|
|
27
|
+
/** Metadata */
|
|
28
|
+
metadata?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
export interface ContextSource {
|
|
31
|
+
/** Source identifier */
|
|
32
|
+
id: string;
|
|
33
|
+
/** Human-readable name */
|
|
34
|
+
name: string;
|
|
35
|
+
/** Priority (higher = more important, included first) */
|
|
36
|
+
priority: number;
|
|
37
|
+
/** Maximum tokens this source can use */
|
|
38
|
+
maxTokens: number;
|
|
39
|
+
/** Gather context fragments */
|
|
40
|
+
gather(request: ContextRequest): Promise<ContextFragment[]>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=types.d.ts.map
|