/** * Main entry point for the Agent Manager Client */ export { ClaudeClient } from './claude-client.js'; export { Config } from './config.js'; export { McpConfigManager } from './mcpConfigManager.js'; export { ToolDiscovery } from './toolDiscovery.js'; export type { IssueData, ClaudeClientConfig, IssueHandlerResult, MCPServerConfig } from './types.js'; // CLI entry point if (import.meta.url === `file://${process.argv[1]}`) { const { ClaudeClient } = await import('./claude-client.js'); const { Config } = await import('./config.js'); const { ToolDiscovery } = await import('./toolDiscovery.js'); const { setupEnvironment, ensureRepository, detectAgentManagerPath } = await import('./repository-manager.js'); const { fetchRepositorySshUrl, getExistingGitRemoteUrl } = await import('./gogs-helper.js'); // Setup environment variables (HOME, PATH, XDG directories) console.log('Setting up environment...'); setupEnvironment(); // Load configuration early: global env vars are needed for Gogs API access and MCP config console.log('Loading configuration...'); Config.loadGlobal(); // Load global .env from ~/.config/agent-manager/.env // Parse command line arguments const args = process.argv.slice(2); if (args.length < 7) { console.error('Usage: node index.js [comment_body] [assignee] [labels]'); process.exit(1); } const [owner, repo, pusher, issueNumber, issueTitle, issueBody, issueAction, commentBody, assignee, labels] = args; // Exit if issue action is 'closed' (but allow 'reopened') if (issueAction === 'closed') { console.log("Issue action is 'closed', skipping automation"); process.exit(0); } // Validate assignee if (assignee && assignee !== 'claude') { console.log(`Issue not assigned to claude (assignee: ${assignee}), skipping`); process.exit(0); } // Skip if pusher is claude for issue_comment events (avoid comment loops) // commentBody is only populated for issue_comment events, not issues events if (pusher === 'claude' && commentBody) { console.log('Pusher is claude for issue_comment event, skipping automation to avoid loops'); process.exit(0); } // Detect Agent Manager path const agentManagerPath = detectAgentManagerPath(); console.log(`Agent Manager Path: ${agentManagerPath}`); // Determine repo path const home = process.env.HOME || '/root'; const repoPath = `${home}/${repo}`; // Fetch SSH URL from Gogs API or use existing git remote let sshUrl: string; try { // First, try to get from existing repository const existingUrl = getExistingGitRemoteUrl(repoPath); if (existingUrl) { console.log(`Using existing git remote URL: ${existingUrl}`); sshUrl = existingUrl; } else { console.log('Fetching repository SSH URL from Gogs API...'); sshUrl = await fetchRepositorySshUrl(owner, repo); console.log(`Fetched SSH URL: ${sshUrl}`); } } catch (error) { console.error('Failed to fetch SSH URL from Gogs API:', error); console.log('Falling back to existing repository or default URL format'); const existingUrl = getExistingGitRemoteUrl(repoPath); if (existingUrl) { sshUrl = existingUrl; } else { // Fallback to default format sshUrl = `ssh://git@git.smartbotics.ai:10022/${owner}/${repo}.git`; console.log(`Using fallback SSH URL: ${sshUrl}`); } } // Ensure repository exists and is up to date console.log('Ensuring repository exists and is up to date...'); ensureRepository(repoPath, sshUrl); // Change to repository directory process.chdir(repoPath); console.log(`Working directory: ${process.cwd()}`); // Load repository-specific .env (overrides global values) Config.load(repoPath); // Generate MCP configuration for this repository const mcpConfig = Config.generateMcpConfig(repoPath, owner, repo); // Discover available tools dynamically console.log('Discovering available tools from MCP servers...'); const allowedTools = await ToolDiscovery.discoverTools(mcpConfig); console.log('\n=== ALLOWED TOOLS ==='); console.log(`Total tools: ${allowedTools.length}`); console.log('Tools list:', JSON.stringify(allowedTools, null, 2)); console.log('=====================\n'); // Configure Claude client const client = new ClaudeClient({ workingDirectory: repoPath, mcpConfigPath: `${repoPath}/.mcp-gogs.json`, allowedTools, dangerouslySkipPermissions: true }); // Handle the issue const result = await client.handleIssue({ owner, repo, number: parseInt(issueNumber, 10), title: issueTitle, body: issueBody, action: issueAction, pusher, assignee, labels, commentBody }); // Output result console.log('---'); console.log('Claude Code execution completed'); if (result.success) { console.log('Session ID:', result.sessionId); console.log('Cost:', result.cost); console.log('Duration:', result.duration); process.exit(0); } else { console.error('Error:', result.error); process.exit(1); } }