| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- /**
- * 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 <owner> <repo> <pusher> <issue_number> <issue_title> <issue_body> <issue_action> [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);
- }
- }
|