/** * CppToolRegistrar - Registers cpp.* tools through CapabilityRegistry * DD ยง15. INV-4: registered via capability boundary, not direct runtime import. * * @module packages/toolchain-cpp/src/CppToolRegistrar */ import { CPP_TOOLCHAIN_CAPABILITY } from './capability.js' import { CppProjectDetector } from './detect/CppProjectDetector.js' import { CMakeConfigurator } from './build/CMakeConfigurator.js' import { CppBuilder } from './build/CppBuilder.js' import { CppTestRunner } from './test/CppTestRunner.js' import { CppcheckRunner } from './analysis/CppcheckRunner.js' import { ClangdClient } from './analysis/ClangdClient.js' export class CppToolRegistrar { manifest = CPP_TOOLCHAIN_CAPABILITY /** * Register all cpp.* tools with the provided registry. * INV-4: This is called through CapabilityRegistry boundary, never via direct runtime import. */ register(registry: { register(name: string, definition: any, executor: (call: any) => Promise): void }, project_root: string): void { const detector = new CppProjectDetector(project_root) const configurator = new CMakeConfigurator() const builder = new CppBuilder() const tester = new CppTestRunner() const cppcheck = new CppcheckRunner() const clangd = new ClangdClient() // cpp.detect registry.register('cpp.detect', { name: 'cpp.detect', category: 'toolchain', description: 'Detect C++ project structure and toolchain', input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[0].input_schema, permissions: { read: true, write: false, network: false }, streaming: false }, async (call) => { const result = detector.detect() return { status: 'ok', call_id: call.call_id, tool_name: 'cpp.detect', output: result, metadata: { timestamp: new Date().toISOString() } } }) // cpp.configure registry.register('cpp.configure', { name: 'cpp.configure', category: 'toolchain', description: 'Configure C++ build with CMake', input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[1].input_schema, permissions: { read: true, write: true, network: false }, streaming: false }, async (call) => { const result = configurator.configure({ project_root, generator: call.arguments?.generator as any, build_type: call.arguments?.build_type as any }) if (result.ok) { return { status: 'ok', call_id: call.call_id, tool_name: 'cpp.configure', output: result, metadata: { timestamp: new Date().toISOString() } } } else { return { status: 'error', call_id: call.call_id, tool_name: 'cpp.configure', error: { error_id: call.call_id, kind: 'tool_error', severity: 'error', message: result.error || 'configure failed', retryability: 'not_retryable', semantic_signature: 'cpp.configure' }, metadata: { timestamp: new Date().toISOString() } } } }) // cpp.build registry.register('cpp.build', { name: 'cpp.build', category: 'toolchain', description: 'Build C++ project', input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[2].input_schema, permissions: { read: true, write: true, network: false }, streaming: false }, async (call) => { const result = builder.build(project_root + '/build', call.arguments?.target as string) if (result.ok) { return { status: 'ok', call_id: call.call_id, tool_name: 'cpp.build', output: { built: true, output: result.output, diagnostics: result.diagnostics, elapsed_ms: result.elapsed_ms }, metadata: { timestamp: new Date().toISOString() } } } else { return { status: 'error', call_id: call.call_id, tool_name: 'cpp.build', error: { error_id: call.call_id, kind: 'tool_error', severity: 'error', message: result.output || 'build failed', retryability: 'not_retryable', semantic_signature: 'cpp.build' }, metadata: { timestamp: new Date().toISOString() } } } }) // cpp.test registry.register('cpp.test', { name: 'cpp.test', category: 'toolchain', description: 'Run C++ tests', input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[3].input_schema, permissions: { read: true, write: false, network: false }, streaming: false }, async (call) => { const result = tester.run_tests(project_root + '/build') if (result.ok) { return { status: 'ok', call_id: call.call_id, tool_name: 'cpp.test', output: result, metadata: { timestamp: new Date().toISOString() } } } else { return { status: 'error', call_id: call.call_id, tool_name: 'cpp.test', error: { error_id: call.call_id, kind: 'tool_error', severity: 'error', message: result.output || 'test failed', retryability: 'not_retryable', semantic_signature: 'cpp.test' }, metadata: { timestamp: new Date().toISOString() } } } }) // cpp.cppcheck registry.register('cpp.cppcheck', { name: 'cpp.cppcheck', category: 'toolchain', description: 'Run cppcheck static analysis', input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[4].input_schema, permissions: { read: true, write: false, network: false }, streaming: false }, async (call) => { const result = cppcheck.run(project_root, { enable_all: call.arguments?.enable_all as boolean, check_config: call.arguments?.check_config as boolean }) if (result.ok) { return { status: 'ok', call_id: call.call_id, tool_name: 'cpp.cppcheck', output: result, metadata: { timestamp: new Date().toISOString() } } } else { return { status: 'error', call_id: call.call_id, tool_name: 'cpp.cppcheck', error: { error_id: call.call_id, kind: 'tool_error', severity: 'error', message: result.output || 'cppcheck failed', retryability: 'not_retryable', semantic_signature: 'cpp.cppcheck' }, metadata: { timestamp: new Date().toISOString() } } } }) // cpp.clangd registry.register('cpp.clangd', { name: 'cpp.clangd', category: 'toolchain', description: 'Query clangd for symbol info', input_schema: CPP_TOOLCHAIN_CAPABILITY.tools[5].input_schema, permissions: { read: true, write: false, network: false }, streaming: false }, async (call) => { const result = await clangd.query_symbol(call.arguments?.file as string, call.arguments?.line as number, call.arguments?.column as number) if (result.ok) { return { status: 'ok', call_id: call.call_id, tool_name: 'cpp.clangd', output: result, metadata: { timestamp: new Date().toISOString() } } } else { return { status: 'error', call_id: call.call_id, tool_name: 'cpp.clangd', error: { error_id: call.call_id, kind: 'tool_error', severity: 'error', message: result.error || 'clangd query failed', retryability: 'not_retryable', semantic_signature: 'cpp.clangd' }, metadata: { timestamp: new Date().toISOString() } } } }) } }