mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-11 02:33:51 +08:00
feat(ccw): migrate backend to TypeScript
- Convert 40 JS files to TypeScript (CLI, tools, core, MCP server) - Add Zod for runtime parameter validation - Add type definitions in src/types/ - Keep src/templates/ as JavaScript (dashboard frontend) - Update bin entries to use dist/ - Add tsconfig.json with strict mode - Add backward-compatible exports for tests - All 39 tests passing Breaking changes: None (backward compatible) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -11,17 +11,18 @@ import {
|
||||
ListToolsRequestSchema,
|
||||
} from '@modelcontextprotocol/sdk/types.js';
|
||||
import { getAllToolSchemas, executeTool } from '../tools/index.js';
|
||||
import type { ToolSchema, ToolResult } from '../types/tool.js';
|
||||
|
||||
const SERVER_NAME = 'ccw-tools';
|
||||
const SERVER_VERSION = '6.1.4';
|
||||
|
||||
// Default enabled tools (core set)
|
||||
const DEFAULT_TOOLS = ['write_file', 'edit_file', 'codex_lens', 'smart_search'];
|
||||
const DEFAULT_TOOLS: string[] = ['write_file', 'edit_file', 'codex_lens', 'smart_search'];
|
||||
|
||||
/**
|
||||
* Get list of enabled tools from environment or defaults
|
||||
*/
|
||||
function getEnabledTools() {
|
||||
function getEnabledTools(): string[] | null {
|
||||
const envTools = process.env.CCW_ENABLED_TOOLS;
|
||||
if (envTools) {
|
||||
// Support "all" to enable all tools
|
||||
@@ -36,15 +37,35 @@ function getEnabledTools() {
|
||||
/**
|
||||
* Filter tools based on enabled list
|
||||
*/
|
||||
function filterTools(tools, enabledList) {
|
||||
function filterTools(tools: ToolSchema[], enabledList: string[] | null): ToolSchema[] {
|
||||
if (!enabledList) return tools; // null = all tools
|
||||
return tools.filter(tool => enabledList.includes(tool.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format tool result for display
|
||||
*/
|
||||
function formatToolResult(result: unknown): string {
|
||||
if (result === null || result === undefined) {
|
||||
return 'Tool completed successfully (no output)';
|
||||
}
|
||||
|
||||
if (typeof result === 'string') {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (typeof result === 'object') {
|
||||
// Pretty print JSON with indentation
|
||||
return JSON.stringify(result, null, 2);
|
||||
}
|
||||
|
||||
return String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and configure the MCP server
|
||||
*/
|
||||
function createServer() {
|
||||
function createServer(): Server {
|
||||
const enabledTools = getEnabledTools();
|
||||
|
||||
const server = new Server(
|
||||
@@ -63,7 +84,7 @@ function createServer() {
|
||||
* Handler for tools/list - Returns enabled CCW tools
|
||||
*/
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||
const allTools = getAllToolSchemas();
|
||||
const allTools = getAllToolSchemas().filter((tool): tool is ToolSchema => tool !== null);
|
||||
const tools = filterTools(allTools, enabledTools);
|
||||
return { tools };
|
||||
});
|
||||
@@ -77,27 +98,28 @@ function createServer() {
|
||||
// Check if tool is enabled
|
||||
if (enabledTools && !enabledTools.includes(name)) {
|
||||
return {
|
||||
content: [{ type: 'text', text: `Tool "${name}" is not enabled` }],
|
||||
content: [{ type: 'text' as const, text: `Tool "${name}" is not enabled` }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await executeTool(name, args || {});
|
||||
const result: ToolResult = await executeTool(name, args || {});
|
||||
|
||||
if (!result.success) {
|
||||
return {
|
||||
content: [{ type: 'text', text: `Error: ${result.error}` }],
|
||||
content: [{ type: 'text' as const, text: `Error: ${result.error}` }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
content: [{ type: 'text', text: formatToolResult(result.result) }],
|
||||
content: [{ type: 'text' as const, text: formatToolResult(result.result) }],
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
return {
|
||||
content: [{ type: 'text', text: `Tool execution failed: ${error.message}` }],
|
||||
content: [{ type: 'text' as const, text: `Tool execution failed: ${errorMessage}` }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
@@ -106,32 +128,10 @@ function createServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format tool result for display
|
||||
* @param {*} result - Tool execution result
|
||||
* @returns {string} - Formatted result string
|
||||
*/
|
||||
function formatToolResult(result) {
|
||||
if (result === null || result === undefined) {
|
||||
return 'Tool completed successfully (no output)';
|
||||
}
|
||||
|
||||
if (typeof result === 'string') {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (typeof result === 'object') {
|
||||
// Pretty print JSON with indentation
|
||||
return JSON.stringify(result, null, 2);
|
||||
}
|
||||
|
||||
return String(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main server execution
|
||||
*/
|
||||
async function main() {
|
||||
async function main(): Promise<void> {
|
||||
const server = createServer();
|
||||
const transport = new StdioServerTransport();
|
||||
|
||||
@@ -154,7 +154,8 @@ async function main() {
|
||||
}
|
||||
|
||||
// Run server
|
||||
main().catch((error) => {
|
||||
console.error('Server error:', error);
|
||||
main().catch((error: unknown) => {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
console.error('Server error:', errorMessage);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user