Files
wehub-resource-sync 23f7624596
ADR-166 MCP Bridge Security Lock / Static-source security lock (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / Compose default binds loopback + Mongo has auth (push) Failing after 2s
CodeQL Advanced / Analyze (rust) (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / plugin-agent-federation bindHost default (push) Failing after 1s
ADR-166 MCP Bridge Security Lock / Runtime behavior — 401 + terminal gate + fail-closed (push) Failing after 4s
business-pods-smoke / smoke (push) Failing after 1s
all-plugins-smoke / smoke-all (push) Failing after 2s
CI/CD Pipeline / Security & Code Quality (push) Failing after 1s
CI/CD Pipeline / Test Suite (ubuntu-latest) (push) Failing after 1s
CI/CD Pipeline / Build & Package (macos-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (ubuntu-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (windows-latest) (push) Has been skipped
CI/CD Pipeline / Documentation & Examples (push) Failing after 1s
Clone Tracker (14-day rolling) / Snapshot clones for ruflo ecosystem (push) Failing after 1s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
federation-peer-rust / stable-noop (push) Failing after 1s
metaharness-ci / score (push) Failing after 1s
metaharness-ci / router-compat (push) Failing after 0s
metaharness-ci / similarity-tests (push) Failing after 0s
no-agentbbs-smoke / smoke-without-agentbbs (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (windows-latest) (push) Has been skipped
codex-integration-audit / Codex integration audit (push) Failing after 1s
helpers-manifest-guard / guard (push) Failing after 1s
🔗 Cross-Agent Integration Tests / 🤝 Agent Coordination Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🧠 Memory Sharing Integration (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🛡️ Fault Tolerance Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / ⚡ Performance Integration Tests (push) Has been skipped
metaharness-ci / mcp-scan (push) Failing after 1s
metaharness-ci / eject-dryrun (push) Failing after 1s
metaharness-ci / metaharness-real-data (push) Failing after 0s
no-cli-optdep-bloat-2561 / guard (push) Failing after 1s
no-metaharness-smoke / smoke-without-metaharness (push) Failing after 1s
no-phantom-agentic-flow-subpath / guard (push) Failing after 1s
🔄 Automated Rollback Manager / 🚨 Failure Detection (push) Failing after 1s
V3 CI/CD Pipeline / Plugin hooks smoke / ubuntu-latest / Node 22 (push) Failing after 1s
V3 CI/CD Pipeline / ruflo-graph-intelligence build + test smoke (#2044, ADR-123) (push) Failing after 1s
CVE Audit Gate / Audit root (critical-blocking) (push) Failing after 2s
cost-tracker-smoke / smoke (push) Failing after 3s
oia-audit-weekly / audit (push) Failing after 2s
ruflo-agent-smoke / ruflo-agent structural smoke (push) Failing after 1s
📊 Status Badges Update / 📊 Update Status Badges (push) Failing after 1s
V3 CI/CD Pipeline / Static regression guards (#2267 YAML + (push) Failing after 1s
V3 CI/CD Pipeline / Test V3 Packages (push) Failing after 0s
V3 CI/CD Pipeline / agent_execute provider routing smoke (#2042) (push) Failing after 0s
CVE Audit Gate / Audit v3 (critical-blocking) (push) Failing after 1s
federation-peer-rust / stable-native (push) Failing after 2s
🔗 Cross-Agent Integration Tests / 🚀 Integration Test Setup (push) Failing after 2s
neural-trader-smoke / runtime-smoke (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (macos-latest) (push) Has been skipped
V3 CI/CD Pipeline / Build V3 (ubuntu-latest) (push) Has been skipped
V3 CI/CD Pipeline / Type Check V3 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 24 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 22 (push) Failing after 2s
V3 CI/CD Pipeline / browser rvf create flag smoke (#2015) (push) Failing after 0s
V3 CI/CD Pipeline / Dependency review (#2046) (push) Has been skipped
V3 CI/CD Pipeline / Supply-chain audit (#2046) (push) Failing after 0s
V3 CI/CD Pipeline / witness marker drift smoke (#2021) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader portfolio CG smoke (#2068, ADR-126 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader backtest signing smoke (#2068, ADR-126 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / kg-extract type-import classification smoke (#2049) (push) Failing after 0s
V3 CI/CD Pipeline / witness verify precondition smoke (#1880) (push) Failing after 2s
V3 CI/CD Pipeline / neural-trader pipeline risk-gate smoke (#2068, ADR-126 Phase 5) (push) Failing after 0s
V3 CI/CD Pipeline / neural-trader feature attribution smoke (#2068, ADR-126 Phase 6) (push) Failing after 0s
V3 CI/CD Pipeline / plugin-registry signature verification smoke (#1922, CWE-347) (push) Failing after 4s
V3 CI/CD Pipeline / memory stats legacy-DB smoke (#2120) (push) Failing after 4s
V3 CI/CD Pipeline / github deprecated actions smoke (#2089, ADR-127 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / graph query + pathfinder smoke (ADR-130 P2+P5) (push) Has been skipped
V3 CI/CD Pipeline / graph trajectory hooks smoke (ADR-130 P3) (push) Has been skipped
V3 CI/CD Pipeline / graph plugin adapter smoke (ADR-130 P4) (push) Has been skipped
V3 CI/CD Pipeline / graph benchmark (ADR-130 P6) (push) Has been skipped
V3 CI/CD Pipeline / statusline generator delegation smoke (#2195) (push) Failing after 1s
V3 CI/CD Pipeline / wizard init regression guard (#2206 (push) Failing after 1s
V3 CI/CD Pipeline / memory no-stray-db smoke (ADR-125 P7) (push) Failing after 1s
V3 CI/CD Pipeline / github-safe injection smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github actions pin smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github attribution opt-in smoke (#2089, ADR-127 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / pre-bash hook safety smoke (#2017) (push) Failing after 1s
V3 CI/CD Pipeline / Memory import smoke / ubuntu-latest (push) Failing after 0s
V3 CI/CD Pipeline / MCP protocol smoke / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / ruvllm WASM auto-init smoke (#2086) (push) Failing after 4s
V3 CI/CD Pipeline / MCP paired-tool round-trip smoke (#1889) (push) Failing after 1s
V3 CI/CD Pipeline / Plugin package install-safety (#1902/#1903/#1904) (push) Failing after 1s
V3 CI/CD Pipeline / Tool description discoverability (ADR-112) (push) Failing after 3s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (22) (push) Failing after 1s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (24) (push) Failing after 1s
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Vector-index dimension audit (#1947) (push) Failing after 0s
V3 CI/CD Pipeline / Hook-command install safety (#1921) (push) Failing after 1s
V3 CI/CD Pipeline / ToolOutputGuardrail smoke (ADR-131, (push) Failing after 1s
V3 CI/CD Pipeline / init-bundle invariants smoke (#2095, ADR-128 Phase 5) (push) Failing after 1s
V3 CI/CD Pipeline / wasm provider bridge smoke (ADR-129 P1) (push) Failing after 2s
V3 CI/CD Pipeline / wasm gallery CRUD smoke (ADR-129 P3) (push) Failing after 1s
V3 CI/CD Pipeline / wasm plugin bridge smoke (ADR-129 P4) (push) Failing after 0s
V3 CI/CD Pipeline / wasm compose smoke (ADR-129 P2) (push) Failing after 4s
V3 CI/CD Pipeline / graph schema smoke (ADR-130 P1) (push) Failing after 0s
Validate Marketplace / validate (push) Failing after 1s
🔍 Verification Pipeline / 🚀 Setup Verification (push) Failing after 1s
🔍 Verification Pipeline / 🛡️ Security Verification (push) Has been skipped
🔍 Verification Pipeline / 📝 Code Quality (push) Has been skipped
🔍 Verification Pipeline / 🧪 Test Verification (${{ matrix.os }}, Node ${{ matrix.node }}) (push) Has been skipped
🔍 Verification Pipeline / 🏗️ Build Verification (push) Has been skipped
🔍 Verification Pipeline / 📚 Documentation Verification (push) Has been skipped
CVE Audit Gate / High-severity report (warn only) (push) Has been cancelled
🔄 Automated Rollback Manager / 🔄 Execute Rollback (push) Has been cancelled
🔄 Automated Rollback Manager / ✅ Post-Rollback Verification (push) Has been cancelled
🔄 Automated Rollback Manager / 📊 Rollback Monitoring (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / windows-latest (push) Has been cancelled
🔄 Automated Rollback Manager / ⏳ Manual Rollback Approval (push) Has been cancelled
V3 CI/CD Pipeline / MCP protocol smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Memory import smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / ubuntu-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Publish to npm (alpha) (push) Has been cancelled
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / macos-latest / Node 22 (push) Has been cancelled
V3 CI/CD Pipeline / Plugin hooks smoke / macos-latest / Node 22 (push) Has been cancelled
CI/CD Pipeline / Deploy & Release (push) Has been cancelled
CI/CD Pipeline / CI Status (push) Has been cancelled
🔗 Cross-Agent Integration Tests / 📊 Integration Test Report (push) Has been cancelled
🔄 Automated Rollback Manager / 🔍 Pre-Rollback Validation (push) Has been cancelled
🔍 Verification Pipeline / ⚡ Performance Verification (push) Has been cancelled
🔍 Verification Pipeline / 📊 Verification Report (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:02:19 +08:00

1202 lines
49 KiB
TypeScript

/**
* Deep MCP Tools Test Suite
*
* Comprehensive tests for all MCP tool files covering:
* - Schema validation (name, description, inputSchema)
* - Array schemas have `items` field
* - Handler existence and error handling
* - Tool registration across all 24 tool modules
* - System tools version/status correctness
*
* Uses vitest with mocks to isolate from external dependencies.
*/
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
// ============================================================================
// Mock setup - must be before imports
// ============================================================================
// Mock fs to prevent actual file I/O during tests
vi.mock('node:fs', () => {
const memStore = new Map<string, string>();
return {
existsSync: vi.fn((p: string) => memStore.has(p)),
readFileSync: vi.fn((p: string) => memStore.get(p) || '{}'),
writeFileSync: vi.fn((p: string, d: string) => memStore.set(p, d)),
mkdirSync: vi.fn(),
readdirSync: vi.fn(() => []),
unlinkSync: vi.fn(),
statSync: vi.fn(() => ({ size: 100, isFile: () => true, isDirectory: () => false })),
};
});
vi.mock('fs', () => {
const memStore = new Map<string, string>();
return {
existsSync: vi.fn((p: string) => memStore.has(p)),
readFileSync: vi.fn((p: string) => memStore.get(p) || '{}'),
writeFileSync: vi.fn((p: string, d: string) => memStore.set(p, d)),
mkdirSync: vi.fn(),
readdirSync: vi.fn(() => []),
unlinkSync: vi.fn(),
statSync: vi.fn(() => ({ size: 100, isFile: () => true, isDirectory: () => false })),
};
});
// Mock child_process for browser/security tools
vi.mock('child_process', () => ({
execSync: vi.fn(() => '{}'),
spawnSync: vi.fn(() => ({ status: 0, stdout: '' })),
}));
// Mock the memory bridge for agentdb tools
vi.mock('../src/memory/memory-bridge.js', () => ({
bridgeHealthCheck: vi.fn(async () => ({ available: true, status: 'healthy' })),
bridgeListControllers: vi.fn(async () => []),
bridgeStorePattern: vi.fn(async () => ({ success: true })),
bridgeSearchPatterns: vi.fn(async () => ({ results: [] })),
bridgeRecordFeedback: vi.fn(async () => ({ success: true })),
bridgeRecordCausalEdge: vi.fn(async () => ({ success: true })),
bridgeRouteTask: vi.fn(async () => ({ route: 'general', confidence: 0.5, agents: ['coder'] })),
bridgeSessionStart: vi.fn(async () => ({ success: true })),
bridgeSessionEnd: vi.fn(async () => ({ success: true })),
bridgeHierarchicalStore: vi.fn(async () => ({ success: true })),
bridgeHierarchicalRecall: vi.fn(async () => ({ results: [] })),
bridgeConsolidate: vi.fn(async () => ({ success: true })),
bridgeBatchOperation: vi.fn(async () => ({ success: true })),
bridgeContextSynthesize: vi.fn(async () => ({ success: true })),
bridgeSemanticRoute: vi.fn(async () => ({ route: null })),
}));
// Mock memory-initializer
vi.mock('../src/memory/memory-initializer.js', () => ({
generateEmbedding: vi.fn(async () => ({ embedding: new Array(384).fill(0.1), dimensions: 384, model: 'mock' })),
storeEntry: vi.fn(async () => ({ success: true, id: 'mock-id' })),
searchEntries: vi.fn(async () => ({ success: true, results: [], searchTime: 1 })),
listEntries: vi.fn(async () => ({ success: true, entries: [] })),
getEntry: vi.fn(async () => null),
deleteEntry: vi.fn(async () => ({ success: true })),
getStats: vi.fn(async () => ({ totalEntries: 0 })),
initializeDatabase: vi.fn(async () => ({ success: true })),
initializeMemoryDatabase: vi.fn(async () => ({ success: true })),
checkMemoryInitialization: vi.fn(async () => ({ initialized: true, version: '3.0.0' })),
migrateFromLegacy: vi.fn(async () => ({ success: true, migrated: 0 })),
}));
// Mock intelligence module
vi.mock('../src/memory/intelligence.js', () => ({
getIntelligenceStats: vi.fn(() => ({
patternsLearned: 0,
trajectoriesRecorded: 0,
reasoningBankSize: 0,
sonaEnabled: false,
lastAdaptation: null,
})),
initializeIntelligence: vi.fn(async () => {}),
benchmarkAdaptation: vi.fn(() => ({ avgMs: 0.01, minMs: 0.005, maxMs: 0.02, targetMet: true })),
}));
// Mock ruvector modules
vi.mock('../src/ruvector/model-router.js', () => ({
getModelRouter: vi.fn(() => ({ route: async () => ({ model: 'sonnet', routedBy: 'router' }) })),
}));
vi.mock('../src/ruvector/enhanced-model-router.js', () => ({
getEnhancedModelRouter: vi.fn(() => ({
route: async () => ({ tier: 2, model: 'sonnet', canSkipLLM: false }),
})),
}));
vi.mock('../src/ruvector/diff-classifier.js', () => ({
analyzeDiff: vi.fn(async () => ({
ref: 'HEAD', timestamp: new Date().toISOString(), files: [],
risk: { overall: 'low', score: 10 }, classification: { type: 'patch' },
summary: 'No changes', fileRisks: [], recommendedReviewers: [],
})),
assessFileRisk: vi.fn(() => ({ risk: 'low', score: 10, reasons: [] })),
assessOverallRisk: vi.fn(() => ({ overall: 'low', score: 10 })),
classifyDiff: vi.fn(() => ({ type: 'patch' })),
suggestReviewers: vi.fn(() => []),
getGitDiffNumstat: vi.fn(() => []),
}));
vi.mock('../src/ruvector/moe-router.js', () => ({
getMoERouter: vi.fn(async () => null),
}));
vi.mock('../src/memory/sona-optimizer.js', () => ({
getSONAOptimizer: vi.fn(async () => null),
}));
vi.mock('../src/memory/ewc-consolidation.js', () => ({
getEWCConsolidator: vi.fn(async () => null),
}));
// Mock transfer modules
vi.mock('../src/transfer/anonymization/index.js', () => ({
detectPII: vi.fn(() => ({ hasPII: false, entities: [] })),
}));
vi.mock('../src/transfer/ipfs/client.js', () => ({
resolveIPNS: vi.fn(async () => 'QmMock'),
}));
// Mock module for auto-install
vi.mock('../src/mcp-tools/auto-install.js', () => ({
autoInstallPackage: vi.fn(async () => false),
}));
// Mock security package
vi.mock('@claude-flow/aidefence', () => {
throw new Error('Cannot find package');
});
// Mock embeddings package
vi.mock('@claude-flow/embeddings', () => {
throw new Error('Cannot find package');
});
vi.mock('agentic-flow/reasoningbank', () => {
throw new Error('Cannot find package');
});
// ============================================================================
// Import all tool modules (after mocks are set up)
// ============================================================================
import { agentTools } from '../src/mcp-tools/agent-tools.js';
import { agentdbTools } from '../src/mcp-tools/agentdb-tools.js';
import { analyzeTools } from '../src/mcp-tools/analyze-tools.js';
import { browserTools } from '../src/mcp-tools/browser-tools.js';
import { claimsTools } from '../src/mcp-tools/claims-tools.js';
import { configTools } from '../src/mcp-tools/config-tools.js';
import { coordinationTools } from '../src/mcp-tools/coordination-tools.js';
import { daaTools } from '../src/mcp-tools/daa-tools.js';
import { embeddingsTools } from '../src/mcp-tools/embeddings-tools.js';
import { githubTools } from '../src/mcp-tools/github-tools.js';
import { hiveMindTools } from '../src/mcp-tools/hive-mind-tools.js';
import { memoryTools } from '../src/mcp-tools/memory-tools.js';
import { neuralTools } from '../src/mcp-tools/neural-tools.js';
import { performanceTools } from '../src/mcp-tools/performance-tools.js';
import { progressTools } from '../src/mcp-tools/progress-tools.js';
import { securityTools } from '../src/mcp-tools/security-tools.js';
import { sessionTools } from '../src/mcp-tools/session-tools.js';
import { swarmTools } from '../src/mcp-tools/swarm-tools.js';
import { systemTools } from '../src/mcp-tools/system-tools.js';
import { taskTools } from '../src/mcp-tools/task-tools.js';
import { terminalTools } from '../src/mcp-tools/terminal-tools.js';
import { transferTools } from '../src/mcp-tools/transfer-tools.js';
import { workflowTools } from '../src/mcp-tools/workflow-tools.js';
import { hooksTools } from '../src/mcp-tools/hooks-tools.js';
import type { MCPTool } from '../src/mcp-tools/types.js';
// ============================================================================
// Collect all tool modules
// ============================================================================
interface ToolModule {
name: string;
tools: MCPTool[];
}
const ALL_MODULES: ToolModule[] = [
{ name: 'agent-tools', tools: agentTools },
{ name: 'agentdb-tools', tools: agentdbTools },
{ name: 'analyze-tools', tools: analyzeTools },
{ name: 'browser-tools', tools: browserTools },
{ name: 'claims-tools', tools: claimsTools },
{ name: 'config-tools', tools: configTools },
{ name: 'coordination-tools', tools: coordinationTools },
{ name: 'daa-tools', tools: daaTools },
{ name: 'embeddings-tools', tools: embeddingsTools },
{ name: 'github-tools', tools: githubTools },
{ name: 'hive-mind-tools', tools: hiveMindTools },
{ name: 'hooks-tools', tools: hooksTools },
{ name: 'memory-tools', tools: memoryTools },
{ name: 'neural-tools', tools: neuralTools },
{ name: 'performance-tools', tools: performanceTools },
{ name: 'progress-tools', tools: progressTools },
{ name: 'security-tools', tools: securityTools },
{ name: 'session-tools', tools: sessionTools },
{ name: 'swarm-tools', tools: swarmTools },
{ name: 'system-tools', tools: systemTools },
{ name: 'task-tools', tools: taskTools },
{ name: 'terminal-tools', tools: terminalTools },
{ name: 'transfer-tools', tools: transferTools },
{ name: 'workflow-tools', tools: workflowTools },
];
const ALL_TOOLS: MCPTool[] = ALL_MODULES.flatMap(m => m.tools);
// ============================================================================
// Tests
// ============================================================================
describe('MCP Tools Deep Test Suite', () => {
// --------------------------------------------------------------------------
// 1. Module Loading & Registration
// --------------------------------------------------------------------------
describe('Module Loading & Registration', () => {
it('should load all 24 tool modules', () => {
expect(ALL_MODULES).toHaveLength(24);
});
it('should have at least 100 total tools across all modules', () => {
expect(ALL_TOOLS.length).toBeGreaterThanOrEqual(100);
});
it('should export arrays from each module', () => {
for (const mod of ALL_MODULES) {
expect(Array.isArray(mod.tools)).toBe(true);
expect(mod.tools.length).toBeGreaterThan(0);
}
});
it('should have no duplicate tool names across all modules', () => {
const names = ALL_TOOLS.map(t => t.name);
const uniqueNames = new Set(names);
const duplicates = names.filter((n, i) => names.indexOf(n) !== i);
expect(duplicates).toEqual([]);
expect(uniqueNames.size).toBe(names.length);
});
it('should register expected tool counts per module', () => {
const minCounts: Record<string, number> = {
'agent-tools': 7,
'agentdb-tools': 15,
'analyze-tools': 6,
'browser-tools': 20,
'claims-tools': 12,
'config-tools': 6,
'coordination-tools': 7,
'daa-tools': 8,
'embeddings-tools': 7,
'github-tools': 5,
'hive-mind-tools': 9,
'memory-tools': 7,
'neural-tools': 6,
'performance-tools': 6,
'progress-tools': 4,
'security-tools': 6,
'session-tools': 5,
'swarm-tools': 4,
'system-tools': 7,
'task-tools': 7,
'terminal-tools': 5,
'transfer-tools': 11,
'workflow-tools': 10,
};
for (const mod of ALL_MODULES) {
const min = minCounts[mod.name];
if (min !== undefined) {
expect(mod.tools.length).toBeGreaterThanOrEqual(min);
}
}
});
});
// --------------------------------------------------------------------------
// 2. Schema Validation
// --------------------------------------------------------------------------
describe('Schema Validation - All Tools', () => {
it('every tool has a non-empty name', () => {
for (const tool of ALL_TOOLS) {
expect(tool.name).toBeDefined();
expect(typeof tool.name).toBe('string');
expect(tool.name.length).toBeGreaterThan(0);
}
});
it('every tool has a non-empty description', () => {
for (const tool of ALL_TOOLS) {
expect(tool.description).toBeDefined();
expect(typeof tool.description).toBe('string');
expect(tool.description.length).toBeGreaterThan(0);
}
});
it('every tool has an inputSchema with type "object"', () => {
for (const tool of ALL_TOOLS) {
expect(tool.inputSchema).toBeDefined();
expect(tool.inputSchema.type).toBe('object');
}
});
it('every tool inputSchema has a properties field', () => {
for (const tool of ALL_TOOLS) {
expect(tool.inputSchema.properties).toBeDefined();
expect(typeof tool.inputSchema.properties).toBe('object');
}
});
it('every tool has a handler function', () => {
for (const tool of ALL_TOOLS) {
expect(tool.handler).toBeDefined();
expect(typeof tool.handler).toBe('function');
}
});
it('required field is either absent or an array of strings', () => {
for (const tool of ALL_TOOLS) {
if (tool.inputSchema.required !== undefined) {
expect(Array.isArray(tool.inputSchema.required)).toBe(true);
for (const req of tool.inputSchema.required!) {
expect(typeof req).toBe('string');
}
}
}
});
it('required fields reference existing properties', () => {
for (const tool of ALL_TOOLS) {
if (tool.inputSchema.required) {
const propNames = Object.keys(tool.inputSchema.properties);
for (const req of tool.inputSchema.required) {
expect(propNames).toContain(req);
}
}
}
});
it('tool names follow naming conventions (category_action or category_action-detail)', () => {
for (const tool of ALL_TOOLS) {
// Names should contain underscore or hyphen as separators
// and not have spaces or special chars
expect(tool.name).toMatch(/^[a-z][a-z0-9_-]+$/);
}
});
});
// --------------------------------------------------------------------------
// 3. Array Schema Validation - items field
// --------------------------------------------------------------------------
describe('Array Schema Validation', () => {
function findArrayProperties(tool: MCPTool): Array<{ toolName: string; propName: string; prop: any }> {
const results: Array<{ toolName: string; propName: string; prop: any }> = [];
const properties = tool.inputSchema.properties;
for (const [propName, prop] of Object.entries(properties)) {
const p = prop as Record<string, unknown>;
if (p.type === 'array') {
results.push({ toolName: tool.name, propName, prop: p });
}
}
return results;
}
it('all array-typed properties have an items field', () => {
const missingItems: string[] = [];
for (const tool of ALL_TOOLS) {
const arrayProps = findArrayProperties(tool);
for (const { toolName, propName, prop } of arrayProps) {
if (!prop.items) {
missingItems.push(`${toolName}.${propName}`);
}
}
}
expect(missingItems).toEqual([]);
});
it('array items field specifies a type', () => {
for (const tool of ALL_TOOLS) {
const arrayProps = findArrayProperties(tool);
for (const { prop } of arrayProps) {
if (prop.items) {
expect(prop.items.type).toBeDefined();
}
}
}
});
});
// --------------------------------------------------------------------------
// 4. Category Consistency
// --------------------------------------------------------------------------
describe('Category Consistency', () => {
it('tool name prefix matches category when category is set', () => {
const exceptions = new Set([
'mcp_status', // system-tools exports mcp_status
'mcp_start', // system-tools exports mcp_start (#1916 — in-process no-op)
'mcp_stop', // system-tools exports mcp_stop (#1916 — in-process no-op)
'task_summary', // system-tools exports task_summary
]);
for (const tool of ALL_TOOLS) {
if (tool.category && !exceptions.has(tool.name)) {
const prefix = tool.name.split('_')[0].replace(/-/g, '');
const cat = tool.category.replace(/-/g, '');
// Prefix should match category (e.g., agent_spawn -> agent category)
expect(prefix).toBe(cat);
}
}
});
});
// --------------------------------------------------------------------------
// 5. Handler Invocation - Agent Tools
// --------------------------------------------------------------------------
describe('Agent Tools - Handler Invocation', () => {
it('agent_spawn creates an agent with required agentType', async () => {
const tool = agentTools.find(t => t.name === 'agent_spawn')!;
const result: any = await tool.handler({ agentType: 'coder' });
expect(result.success).toBe(true);
expect(result.agentId).toBeDefined();
expect(result.agentType).toBe('coder');
});
it('agent_list returns agents array', async () => {
const tool = agentTools.find(t => t.name === 'agent_list')!;
const result: any = await tool.handler({});
expect(result.agents).toBeDefined();
expect(Array.isArray(result.agents)).toBe(true);
});
it('agent_status returns not_found for unknown agent', async () => {
const tool = agentTools.find(t => t.name === 'agent_status')!;
const result: any = await tool.handler({ agentId: 'nonexistent' });
expect(result.status).toBe('not_found');
});
it('agent_terminate returns error for unknown agent', async () => {
const tool = agentTools.find(t => t.name === 'agent_terminate')!;
const result: any = await tool.handler({ agentId: 'nonexistent' });
expect(result.success).toBe(false);
});
it('agent_pool status action returns pool info', async () => {
const tool = agentTools.find(t => t.name === 'agent_pool')!;
const result: any = await tool.handler({ action: 'status' });
expect(result.action).toBe('status');
expect(result.poolId).toBeDefined();
});
it('agent_health returns overall health info', async () => {
const tool = agentTools.find(t => t.name === 'agent_health')!;
const result: any = await tool.handler({});
expect(result.overall).toBeDefined();
});
it('agent_update returns error for unknown agent', async () => {
const tool = agentTools.find(t => t.name === 'agent_update')!;
const result: any = await tool.handler({ agentId: 'nonexistent' });
expect(result.success).toBe(false);
});
});
// --------------------------------------------------------------------------
// 6. Handler Invocation - System Tools
// --------------------------------------------------------------------------
describe('System Tools - Handler Invocation', () => {
it('system_status returns version and status', async () => {
const tool = systemTools.find(t => t.name === 'system_status')!;
const result: any = await tool.handler({});
expect(result.version).toBeDefined();
expect(result.status).toBeDefined();
});
it('system_info returns system information', async () => {
const tool = systemTools.find(t => t.name === 'system_info')!;
const result: any = await tool.handler({});
expect(result.version).toBeDefined();
expect(result.platform).toBeDefined();
});
it('system_health returns health checks', async () => {
const tool = systemTools.find(t => t.name === 'system_health')!;
const result: any = await tool.handler({});
expect(result.overall).toBeDefined();
expect(result.checks).toBeDefined();
});
it('system_metrics returns metrics data', async () => {
const tool = systemTools.find(t => t.name === 'system_metrics')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('mcp_status returns MCP server info', async () => {
const tool = systemTools.find(t => t.name === 'mcp_status')!;
const result: any = await tool.handler({});
expect(result.running).toBeDefined();
expect(result.transport).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 7. Handler Invocation - Config Tools
// --------------------------------------------------------------------------
describe('Config Tools - Handler Invocation', () => {
it('config_get returns value for known key', async () => {
const tool = configTools.find(t => t.name === 'config_get')!;
const result: any = await tool.handler({ key: 'logging.level' });
expect(result.key).toBe('logging.level');
expect(result.exists).toBeDefined();
});
it('config_set stores a value', async () => {
const tool = configTools.find(t => t.name === 'config_set')!;
const result: any = await tool.handler({ key: 'test.key', value: 'test-value' });
expect(result.success).toBe(true);
});
it('config_list returns configurations', async () => {
const tool = configTools.find(t => t.name === 'config_list')!;
const result: any = await tool.handler({});
expect(result.configs).toBeDefined();
expect(Array.isArray(result.configs)).toBe(true);
});
it('config_reset returns success', async () => {
const tool = configTools.find(t => t.name === 'config_reset')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
});
it('config_export returns config data', async () => {
const tool = configTools.find(t => t.name === 'config_export')!;
const result: any = await tool.handler({});
expect(result.config).toBeDefined();
});
it('config_import returns success', async () => {
const tool = configTools.find(t => t.name === 'config_import')!;
const result: any = await tool.handler({ config: { 'test.k': 'v' } });
expect(result.success).toBe(true);
});
});
// --------------------------------------------------------------------------
// 8. Handler Invocation - Swarm Tools
// --------------------------------------------------------------------------
describe('Swarm Tools - Handler Invocation', () => {
it('swarm_init returns swarmId and topology', async () => {
const tool = swarmTools.find(t => t.name === 'swarm_init')!;
const result: any = await tool.handler({ topology: 'hierarchical' });
expect(result.success).toBe(true);
expect(result.swarmId).toBeDefined();
expect(result.persisted).toBe(true);
});
it('swarm_status returns running status after init', async () => {
// Init a swarm first so status has something to report
const initTool = swarmTools.find(t => t.name === 'swarm_init')!;
const initResult: any = await initTool.handler({ topology: 'mesh' });
const tool = swarmTools.find(t => t.name === 'swarm_status')!;
const result: any = await tool.handler({ swarmId: initResult.swarmId });
expect(result.status).toBe('running');
});
it('swarm_shutdown returns success after init', async () => {
const initTool = swarmTools.find(t => t.name === 'swarm_init')!;
const initResult: any = await initTool.handler({ topology: 'hierarchical' });
const tool = swarmTools.find(t => t.name === 'swarm_shutdown')!;
const result: any = await tool.handler({ swarmId: initResult.swarmId });
expect(result.success).toBe(true);
expect(result.terminated).toBe(true);
});
it('swarm_health returns healthy checks after init', async () => {
const initTool = swarmTools.find(t => t.name === 'swarm_init')!;
const initResult: any = await initTool.handler({ topology: 'hierarchical' });
const tool = swarmTools.find(t => t.name === 'swarm_health')!;
const result: any = await tool.handler({ swarmId: initResult.swarmId });
expect(result.status).toBe('healthy');
expect(result.checks).toBeDefined();
expect(result.healthy).toBe(true);
});
it('swarm_health returns not_found for nonexistent swarm ID', async () => {
const tool = swarmTools.find(t => t.name === 'swarm_health')!;
const result: any = await tool.handler({ swarmId: 'nonexistent-id-999' });
expect(result.status).toBe('not_found');
expect(result.healthy).toBe(false);
expect(result.checks).toBeDefined();
});
it('swarm_init rejects invalid topology', async () => {
const tool = swarmTools.find(t => t.name === 'swarm_init')!;
const result: any = await tool.handler({ topology: 'invalid-topo' });
expect(result.success).toBe(false);
expect(result.error).toContain('Invalid topology');
});
});
// --------------------------------------------------------------------------
// 9. Handler Invocation - Task Tools
// --------------------------------------------------------------------------
describe('Task Tools - Handler Invocation', () => {
it('task_create creates a task', async () => {
const tool = taskTools.find(t => t.name === 'task_create')!;
const result: any = await tool.handler({ type: 'feature', description: 'Test task' });
expect(result.taskId).toBeDefined();
expect(result.type).toBe('feature');
expect(result.status).toBe('pending');
});
it('task_list returns tasks array', async () => {
const tool = taskTools.find(t => t.name === 'task_list')!;
const result: any = await tool.handler({});
expect(result.tasks).toBeDefined();
expect(Array.isArray(result.tasks)).toBe(true);
});
it('task_status returns not_found for unknown task', async () => {
const tool = taskTools.find(t => t.name === 'task_status')!;
const result: any = await tool.handler({ taskId: 'nonexistent' });
expect(result.status).toBe('not_found');
});
});
// --------------------------------------------------------------------------
// 10. Handler Invocation - Session Tools
// --------------------------------------------------------------------------
describe('Session Tools - Handler Invocation', () => {
it('session_list returns sessions', async () => {
const tool = sessionTools.find(t => t.name === 'session_list')!;
const result: any = await tool.handler({});
expect(result.sessions).toBeDefined();
});
it('session_save creates a session', async () => {
const tool = sessionTools.find(t => t.name === 'session_save')!;
const result: any = await tool.handler({ name: 'Test Session' });
expect(result.sessionId).toBeDefined();
expect(result.name).toBe('Test Session');
});
});
// --------------------------------------------------------------------------
// 11. Handler Invocation - Hive Mind Tools
// --------------------------------------------------------------------------
describe('Hive Mind Tools - Handler Invocation', () => {
it('hive-mind_init initializes the hive', async () => {
const tool = hiveMindTools.find(t => t.name === 'hive-mind_init')!;
const result: any = await tool.handler({ topology: 'mesh' });
expect(result.success).toBe(true);
expect(result.topology).toBe('mesh');
});
it('hive-mind_status returns status info', async () => {
const tool = hiveMindTools.find(t => t.name === 'hive-mind_status')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('hive-mind_consensus with list action returns data', async () => {
const tool = hiveMindTools.find(t => t.name === 'hive-mind_consensus')!;
const result: any = await tool.handler({ action: 'list' });
expect(result.action).toBe('list');
});
});
// --------------------------------------------------------------------------
// 12. Handler Invocation - Workflow Tools
// --------------------------------------------------------------------------
describe('Workflow Tools - Handler Invocation', () => {
it('workflow_list returns workflows', async () => {
const tool = workflowTools.find(t => t.name === 'workflow_list')!;
const result: any = await tool.handler({});
expect(result.workflows).toBeDefined();
});
it('workflow_create creates a workflow', async () => {
const tool = workflowTools.find(t => t.name === 'workflow_create')!;
const result: any = await tool.handler({ name: 'test-wf', description: 'Test workflow' });
expect(result.workflowId).toBeDefined();
expect(result.name).toBe('test-wf');
});
});
// --------------------------------------------------------------------------
// 13. Handler Invocation - DAA Tools
// --------------------------------------------------------------------------
describe('DAA Tools - Handler Invocation', () => {
it('daa_agent_create creates an agent', async () => {
const tool = daaTools.find(t => t.name === 'daa_agent_create')!;
const result: any = await tool.handler({ id: 'test-daa-1' });
expect(result.success).toBe(true);
expect(result.agent.id).toBe('test-daa-1');
});
it('daa_learning_status returns summary', async () => {
const tool = daaTools.find(t => t.name === 'daa_learning_status')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
expect(result.summary).toBeDefined();
});
it('daa_cognitive_pattern returns patterns info', async () => {
const tool = daaTools.find(t => t.name === 'daa_cognitive_pattern')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
expect(result.patterns).toBeDefined();
});
it('daa_performance_metrics returns metrics', async () => {
const tool = daaTools.find(t => t.name === 'daa_performance_metrics')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
});
});
// --------------------------------------------------------------------------
// 14. Handler Invocation - Coordination Tools
// --------------------------------------------------------------------------
describe('Coordination Tools - Handler Invocation', () => {
it('coordination_topology get action returns topology', async () => {
const tool = coordinationTools.find(t => t.name === 'coordination_topology')!;
const result: any = await tool.handler({ action: 'get' });
expect(result.success).toBe(true);
expect(result.topology).toBeDefined();
});
it('coordination_sync status returns sync state', async () => {
const tool = coordinationTools.find(t => t.name === 'coordination_sync')!;
const result: any = await tool.handler({ action: 'status' });
expect(result.success).toBe(true);
});
it('coordination_node list returns nodes', async () => {
const tool = coordinationTools.find(t => t.name === 'coordination_node')!;
const result: any = await tool.handler({ action: 'list' });
expect(result.success).toBe(true);
expect(result.nodes).toBeDefined();
});
it('coordination_metrics returns metrics', async () => {
const tool = coordinationTools.find(t => t.name === 'coordination_metrics')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
});
it('coordination_orchestrate accepts task', async () => {
const tool = coordinationTools.find(t => t.name === 'coordination_orchestrate')!;
const result: any = await tool.handler({ task: 'test task' });
expect(result.success).toBe(true);
expect(result.orchestrationId).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 15. Handler Invocation - GitHub Tools
// --------------------------------------------------------------------------
describe('GitHub Tools - Handler Invocation', () => {
it('github_repo_analyze returns analysis', async () => {
const tool = githubTools.find(t => t.name === 'github_repo_analyze')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
expect(result.repository).toBeDefined();
});
it('github_pr_manage list returns PRs', async () => {
const tool = githubTools.find(t => t.name === 'github_pr_manage')!;
const result: any = await tool.handler({ action: 'list' });
expect(result.success).toBe(true);
});
it('github_metrics returns all metrics', async () => {
const tool = githubTools.find(t => t.name === 'github_metrics')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
expect(result.commits).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 16. Handler Invocation - Terminal Tools
// --------------------------------------------------------------------------
describe('Terminal Tools - Handler Invocation', () => {
it('terminal_create creates a session', async () => {
const tool = terminalTools.find(t => t.name === 'terminal_create')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
expect(result.sessionId).toBeDefined();
});
it('terminal_list returns sessions', async () => {
const tool = terminalTools.find(t => t.name === 'terminal_list')!;
const result: any = await tool.handler({});
expect(result.sessions).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 17. Handler Invocation - Claims Tools
// --------------------------------------------------------------------------
describe('Claims Tools - Handler Invocation', () => {
it('claims_list returns claims', async () => {
const tool = claimsTools.find(t => t.name === 'claims_list')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
expect(result.claims).toBeDefined();
});
it('claims_claim with invalid claimant returns error', async () => {
const tool = claimsTools.find(t => t.name === 'claims_claim')!;
const result: any = await tool.handler({ issueId: 'issue-1', claimant: 'invalid' });
expect(result.success).toBe(false);
expect(result.error).toContain('Invalid claimant');
});
it('claims_board returns board view', async () => {
const tool = claimsTools.find(t => t.name === 'claims_board')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
expect(result.board).toBeDefined();
});
it('claims_stealable returns stealable issues', async () => {
const tool = claimsTools.find(t => t.name === 'claims_stealable')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
});
});
// --------------------------------------------------------------------------
// 18. Handler Invocation - Performance Tools
// --------------------------------------------------------------------------
describe('Performance Tools - Handler Invocation', () => {
it('performance_report returns a report', async () => {
const tool = performanceTools.find(t => t.name === 'performance_report')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('performance_metrics returns metrics', async () => {
const tool = performanceTools.find(t => t.name === 'performance_metrics')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('performance_benchmark runs a benchmark', async () => {
const tool = performanceTools.find(t => t.name === 'performance_benchmark')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 19. Handler Invocation - Neural Tools
// --------------------------------------------------------------------------
describe('Neural Tools - Handler Invocation', () => {
it('neural_status returns status', async () => {
const tool = neuralTools.find(t => t.name === 'neural_status')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('neural_patterns returns patterns list', async () => {
const tool = neuralTools.find(t => t.name === 'neural_patterns')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 20. Handler Invocation - AgentDB Tools
// --------------------------------------------------------------------------
describe('AgentDB Tools - Handler Invocation', () => {
it('agentdb_health returns availability', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_health')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('agentdb_controllers returns controllers list', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_controllers')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('agentdb_pattern-store requires pattern param', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_pattern-store')!;
const result: any = await tool.handler({});
expect(result.success).toBe(false);
expect(result.error).toMatch(/pattern.*(required|must be)/i);
});
it('agentdb_pattern-search requires query param', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_pattern-search')!;
const result: any = await tool.handler({});
expect(result.error).toMatch(/query.*(required|must be)/i);
});
it('agentdb_causal-edge validates required fields', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_causal-edge')!;
const result: any = await tool.handler({});
expect(result.success).toBe(false);
});
it('agentdb_route requires task param', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_route')!;
const result: any = await tool.handler({});
expect(result.error).toMatch(/task.*(required|must be)/i);
});
it('agentdb_batch validates entries array', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_batch')!;
const result: any = await tool.handler({ operation: 'insert' });
expect(result.success).toBe(false);
expect(result.error).toContain('entries is required');
});
it('agentdb_batch validates operation type', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_batch')!;
const result: any = await tool.handler({ operation: 'invalid', entries: [{ key: 'k' }] });
expect(result.success).toBe(false);
expect(result.error).toContain('Invalid operation');
});
});
// --------------------------------------------------------------------------
// 21. Error Handling
// --------------------------------------------------------------------------
describe('Error Handling', () => {
it('tools handle empty input gracefully', async () => {
// Test a selection of tools with empty input
const toolsToTest = [
agentTools.find(t => t.name === 'agent_list')!,
configTools.find(t => t.name === 'config_list')!,
swarmTools.find(t => t.name === 'swarm_status')!,
taskTools.find(t => t.name === 'task_list')!,
daaTools.find(t => t.name === 'daa_learning_status')!,
coordinationTools.find(t => t.name === 'coordination_metrics')!,
performanceTools.find(t => t.name === 'performance_report')!,
];
for (const tool of toolsToTest) {
const result = await tool.handler({});
expect(result).toBeDefined();
}
});
it('tools do not throw on invalid input types', async () => {
// These should return errors gracefully instead of throwing
const tool = agentTools.find(t => t.name === 'agent_spawn')!;
// Pass number instead of string for agentType
const result: any = await tool.handler({ agentType: 123 as any });
// Should still succeed - type coercion
expect(result).toBeDefined();
});
it('agentdb tools validate string inputs', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_pattern-store')!;
// Empty string should fail validation
const result: any = await tool.handler({ pattern: '' });
expect(result.success).toBe(false);
});
it('agentdb tools enforce max string length', async () => {
const tool = agentdbTools.find(t => t.name === 'agentdb_feedback')!;
// Very long taskId should be rejected
const longId = 'x'.repeat(1000);
const result: any = await tool.handler({ taskId: longId });
expect(result.success).toBe(false);
});
});
// --------------------------------------------------------------------------
// 22. Security Checks
// --------------------------------------------------------------------------
describe('Security Checks', () => {
it('no tool schemas contain hardcoded paths', () => {
for (const tool of ALL_TOOLS) {
const schema = JSON.stringify(tool.inputSchema);
expect(schema).not.toContain('/home/');
expect(schema).not.toContain('/etc/');
expect(schema).not.toContain('C:\\');
}
});
it('no tool schemas contain hardcoded secrets or tokens', () => {
for (const tool of ALL_TOOLS) {
const schema = JSON.stringify(tool.inputSchema);
expect(schema).not.toMatch(/sk-[a-zA-Z0-9]{20,}/);
expect(schema).not.toMatch(/password.*=.*[a-zA-Z0-9]{8,}/i);
}
});
it('no tool names expose internal implementation details', () => {
for (const tool of ALL_TOOLS) {
expect(tool.name).not.toContain('internal');
expect(tool.name).not.toContain('debug');
expect(tool.name).not.toContain('_raw');
}
});
it('session tools sanitize sessionId against path traversal', () => {
// session_save should handle path traversal attempts
const tool = sessionTools.find(t => t.name === 'session_save')!;
// The session file path should be sanitized
expect(tool).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 23. Return Format Consistency
// --------------------------------------------------------------------------
describe('Return Format Consistency', () => {
it('agent_spawn returns success field', async () => {
const tool = agentTools.find(t => t.name === 'agent_spawn')!;
const result: any = await tool.handler({ agentType: 'coder' });
expect(typeof result.success).toBe('boolean');
});
it('config tools return success field', async () => {
const setTool = configTools.find(t => t.name === 'config_set')!;
const result: any = await setTool.handler({ key: 'test', value: 'v' });
expect(typeof result.success).toBe('boolean');
});
it('task_create returns taskId and status', async () => {
const tool = taskTools.find(t => t.name === 'task_create')!;
const result: any = await tool.handler({ type: 'bugfix', description: 'Fix the bug' });
expect(result.taskId).toBeDefined();
expect(typeof result.taskId).toBe('string');
expect(result.status).toBe('pending');
});
it('swarm_init returns success and swarmId', async () => {
const tool = swarmTools.find(t => t.name === 'swarm_init')!;
const result: any = await tool.handler({});
expect(result.success).toBe(true);
expect(result.swarmId).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 24. Progress & Embeddings Tools
// --------------------------------------------------------------------------
describe('Progress Tools - Handler Invocation', () => {
it('progress_check returns progress metrics', async () => {
const tool = progressTools.find(t => t.name === 'progress_check')!;
expect(tool).toBeDefined();
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('progress_summary returns summary', async () => {
const tool = progressTools.find(t => t.name === 'progress_summary')!;
expect(tool).toBeDefined();
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
});
describe('Embeddings Tools - Handler Invocation', () => {
it('embeddings_status returns initialization state', async () => {
const tool = embeddingsTools.find(t => t.name === 'embeddings_status')!;
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('embeddings_init initializes the subsystem', async () => {
const tool = embeddingsTools.find(t => t.name === 'embeddings_init')!;
const result: any = await tool.handler({ force: true });
expect(result.success).toBe(true);
});
});
// --------------------------------------------------------------------------
// 25. Hooks Tools
// --------------------------------------------------------------------------
describe('Hooks Tools - Handler Invocation', () => {
it('hooks_list returns hooks list', async () => {
const tool = hooksTools.find(t => t.name === 'hooks_list')!;
expect(tool).toBeDefined();
const result: any = await tool.handler({});
expect(result.hooks).toBeDefined();
});
it('hooks_metrics returns metrics', async () => {
const tool = hooksTools.find(t => t.name === 'hooks_metrics')!;
expect(tool).toBeDefined();
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('hooks_worker-list returns workers', async () => {
const tool = hooksTools.find(t => t.name === 'hooks_worker-list')!;
expect(tool).toBeDefined();
const result: any = await tool.handler({});
expect(result.workers).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 26. Memory Tools
// --------------------------------------------------------------------------
describe('Memory Tools - Handler Invocation', () => {
it('memory_store stores an entry', async () => {
const tool = memoryTools.find(t => t.name === 'memory_store')!;
expect(tool).toBeDefined();
const result: any = await tool.handler({ key: 'test-key', value: 'test-value' });
expect(result).toBeDefined();
});
it('memory_list returns entries', async () => {
const tool = memoryTools.find(t => t.name === 'memory_list')!;
expect(tool).toBeDefined();
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
it('memory_stats returns statistics', async () => {
const tool = memoryTools.find(t => t.name === 'memory_stats')!;
expect(tool).toBeDefined();
const result: any = await tool.handler({});
expect(result).toBeDefined();
});
});
// --------------------------------------------------------------------------
// 27. Cross-Module Integrity
// --------------------------------------------------------------------------
describe('Cross-Module Integrity', () => {
it('all tool names are valid MCP tool identifiers', () => {
for (const tool of ALL_TOOLS) {
// MCP tool names should be alphanumeric with underscores/hyphens
expect(tool.name).toMatch(/^[a-z][a-z0-9_-]*$/);
// No double underscores or hyphens
expect(tool.name).not.toMatch(/__/);
expect(tool.name).not.toMatch(/--/);
}
});
it('all descriptions are human-readable sentences', () => {
for (const tool of ALL_TOOLS) {
// Description should start with uppercase or lowercase letter
expect(tool.description).toMatch(/^[A-Za-z]/);
// Should be at least 10 characters
expect(tool.description.length).toBeGreaterThanOrEqual(10);
}
});
it('no tool has an empty properties object with required fields', () => {
for (const tool of ALL_TOOLS) {
if (tool.inputSchema.required && tool.inputSchema.required.length > 0) {
const propCount = Object.keys(tool.inputSchema.properties).length;
expect(propCount).toBeGreaterThan(0);
}
}
});
it('every property in schema has a type or description', () => {
for (const tool of ALL_TOOLS) {
for (const [propName, prop] of Object.entries(tool.inputSchema.properties)) {
const p = prop as Record<string, unknown>;
// Every property should have at least a type or description
const hasType = p.type !== undefined;
const hasDesc = p.description !== undefined;
expect(hasType || hasDesc).toBe(true);
}
}
});
});
});