|
|
4 mēneši atpakaļ | |
|---|---|---|
| .. | ||
| src | 4 mēneši atpakaļ | |
| .gitignore | 9 mēneši atpakaļ | |
| README.md | 8 mēneši atpakaļ | |
| package-lock.json | 9 mēneši atpakaļ | |
| package.json | 9 mēneši atpakaļ | |
| tsconfig.json | 9 mēneši atpakaļ | |
TypeScript-based Claude Agent SDK client for automated issue handling in Gogs repositories.
This client uses the @anthropic-ai/claude-agent-sdk to provide AI-powered issue automation. It replaces the previous bash-based Claude Code implementation with a more robust, type-safe TypeScript solution.
The client is organized into focused modules with clear responsibilities:
client/
├── src/
│ ├── claude-client.ts # Main Claude Agent SDK client
│ │ # - Handles issue automation requests
│ │ # - Builds prompts with label-aware instructions
│ │ # - Manages Claude Agent SDK sessions
│ │ # - Reads and includes CLAUDE.md project memory
│ │
│ ├── config.ts # Configuration management
│ │ # - Loads .env files
│ │ # - Generates MCP configurations
│ │ # - Manages GOGS_MCP_PATH setting
│ │
│ ├── mcpConfigManager.ts # MCP configuration loader
│ │ # - Per-repository config support
│ │ # - Global default config
│ │ # - Environment variable substitution
│ │ # - Security checks (file permissions)
│ │
│ ├── toolDiscovery.ts # Dynamic tool discovery
│ │ # - Discovers tools from MCP servers
│ │ # - Includes built-in Claude Code tools
│ │ # - Formats tool names (mcp__{server}__{tool})
│ │
│ ├── repository-manager.ts # Git repository operations
│ │ # - Clones repositories on demand
│ │ # - Pulls latest changes
│ │ # - Environment setup (HOME, PATH, XDG)
│ │ # - Agent Manager path detection
│ │
│ ├── gogs-helper.ts # Gogs API helper functions
│ │ # - Fetches SSH URLs from Gogs API
│ │ # - Reads existing Git remote URLs
│ │ # - Direct API access (pre-MCP)
│ │
│ ├── types.ts # TypeScript type definitions
│ │ # - IssueData, IssueHandlerResult
│ │ # - ClaudeClientConfig, MCPServerConfig
│ │ # - Type-safe interfaces
│ │
│ └── index.ts # CLI entry point
│ # - Parses command-line arguments
│ # - Orchestrates repository management
│ # - Invokes ClaudeClient
│
├── dist/ # Compiled JavaScript (generated by tsc)
├── package.json # Dependencies and scripts
└── tsconfig.json # TypeScript configuration
ClaudeClient (claude-client.ts)
McpConfigManager (mcpConfigManager.ts)
ToolDiscovery (toolDiscovery.ts)
RepositoryManager (repository-manager.ts)
cd client
npm install
npm run build
This compiles TypeScript to JavaScript in the dist/ directory.
import { ClaudeClient, Config, ToolDiscovery } from './client/dist/index.js';
// Load configuration
Config.load('/path/to/repo');
// Generate MCP config (with dynamic per-repo support)
const mcpConfig = Config.generateMcpConfig('/path/to/repo', 'owner', 'repo');
// Discover available tools automatically
const allowedTools = await ToolDiscovery.discoverTools(mcpConfig);
// Create client
const client = new ClaudeClient({
workingDirectory: '/path/to/repo',
mcpConfigPath: '/path/to/repo/.mcp-gogs.json',
allowedTools, // Automatically discovered tools
dangerouslySkipPermissions: true
});
// Handle issue
const result = await client.handleIssue({
owner: 'username',
repo: 'repo-name',
number: 42,
title: 'Issue title',
body: 'Issue description',
action: 'opened',
pusher: 'username',
assignee: 'claude'
});
console.log(result);
node dist/index.js <owner> <repo> <pusher> <issue_number> <issue_title> <issue_body> <issue_action> [comment_body] [assignee]
The client is called directly from commands.json for issue and issue_comment events. The TypeScript client handles all environment setup, repository management, and issue processing.
The client loads environment variables from two locations (in priority order):
~/.config/agent-manager/.env (shared across all repositories).env in repository root (overrides global)This allows you to set common values (like GOGS_ACCESS_TOKEN) once in the global file, eliminating the need to duplicate them in every cloned repository.
~/.config/agent-manager/.env)Create this file to set global defaults for all repositories:
# Required: Gogs API authentication (applies to all repositories)
GOGS_ACCESS_TOKEN=your-token-here
GOGS_BASE_URL=https://git.smartbotics.ai
# Optional: Path to gogs-mcp server
GOGS_MCP_PATH=/data/gogs-mcp/dist/index.js
Setup:
mkdir -p ~/.config/agent-manager
cp /path/to/agent-manager/examples/global-env.example ~/.config/agent-manager/.env
chmod 600 ~/.config/agent-manager/.env
# Edit the file and add your values
.env in repository)Optional. Use this to override global values for specific repositories:
# Example: Use a different Gogs token for this specific repository
GOGS_ACCESS_TOKEN=repo-specific-token
# Example: Custom home directory for this repository
HOME=/custom/home/path
Notes:
.env file, it uses only global values.env files in every cloned repositoryWhen called from commands.json, the client receives these variables from webhooks:
{{repo_owner}} - Repository owner (e.g., "fszontagh"){{repo}} - Repository name (e.g., "agent-manager"){{pusher}} - Username who triggered the webhook{{issue_number}} - Issue number{{issue_title}} - Issue title{{issue_body}} - Issue description{{issue_action}} - Action (opened, assigned, closed, reopened){{comment_body}} - Comment text (for issue_comment events){{issue_assignee}} - Assigned username (e.g., "claude"){{issue_labels}} - Comma-separated label names (e.g., "bug,enhancement")The client automatically discovers available tools from all configured MCP servers at runtime. You don't need to manually configure the tool list.
ToolDiscovery connects to each configured MCP servermcp__{server-name}__{tool-name}Read, Write, EditBash, Grep, GlobTodoWrite, TaskWebFetch, WebSearchNotebookEdit, BashOutput, KillShell, Skill, SlashCommandWhen using the default gogs-mcp server, these tools are automatically discovered:
User Tools:
mcp__gogs__get_current_user, mcp__gogs__get_user, mcp__gogs__search_usersRepository Tools:
mcp__gogs__list_user_repositories, mcp__gogs__search_repositories, mcp__gogs__get_repositorymcp__gogs__create_repository, mcp__gogs__delete_repositoryContent Tools:
mcp__gogs__get_contents, mcp__gogs__get_raw_contentmcp__gogs__list_branches, mcp__gogs__get_commitsIssue Tools:
mcp__gogs__list_issues, mcp__gogs__get_issue, mcp__gogs__create_issue, mcp__gogs__update_issuemcp__gogs__list_issue_comments, mcp__gogs__create_issue_comment, mcp__gogs__update_issue_commentWhen you add a custom MCP server to your repository configuration, its tools are automatically discovered and available to Claude. No additional configuration needed!
For example, if you configure a "github" MCP server with tools like "create_pr" and "list_repos", they will automatically be available as mcp__github__create_pr and mcp__github__list_repos.
The Claude agent automatically adjusts its behavior based on issue labels. Labels are extracted from webhook payloads and influence how Claude approaches the task.
🔴 "question" Label
📚 "documentation" Label
🐛 "bug" Label
✨ "enhancement" Label
claude-client.ts parses labels from the {{issue_labels}} variableIf an issue is labeled with "question":
⚠️ QUESTION LABEL DETECTED:
- This issue is labeled as "question"
- DO NOT implement any code changes or features
- Your role is to provide information, guidance, and answers only
- You may read code to understand context, but do not modify files
- Respond with helpful explanations, suggestions, or clarifications
The client supports flexible MCP server configuration with three priority levels. This allows different repositories to use different MCP servers and tools.
~/.config/agent-manager/mcp/{owner}/{repo}.json~/.config/agent-manager/mcp/default.json{
"mcpServers": {
"gogs": {
"type": "stdio",
"command": "node",
"args": ["/data/gogs-mcp/dist/index.js"],
"env": {}
},
"custom-server": {
"type": "stdio",
"command": "node",
"args": ["/path/to/custom-mcp/dist/index.js"],
"env": {
"API_KEY": "${MY_API_KEY}"
}
}
}
}
Configuration files support ${VAR_NAME} syntax for secure secret management:
{
"mcpServers": {
"api-service": {
"type": "stdio",
"command": "node",
"args": ["/path/to/api-mcp/dist/index.js"],
"env": {
"API_KEY": "${MY_API_KEY}",
"JWT_TOKEN": "${JWT_TOKEN}"
}
}
}
}
Variables are resolved from the process environment at runtime.
~/.config/agent-manager/mcp/ outside repository directoriesFor detailed configuration examples and setup instructions, see:
examples/MCP-CONFIG.mdexamples/mcp-config-default.jsonexamples/mcp-config-multi-server.jsonThe client automatically manages Git repositories for issue handling:
Automatic Cloning
/home/claude/{owner}/{repo}Automatic Updates
Dynamic Git URL Fetching
fetchRepositorySshUrl()Environment Setup
~/.local/binRepository management is handled by repository-manager.ts:
// Clone repository if it doesn't exist
cloneRepository(sshUrl, targetPath);
// Pull latest changes if repository exists
pullRepository(repoPath);
// Setup environment variables
setupEnvironment();
// Detect agent-manager installation path
detectAgentManagerPath();
The client automatically reads and includes the CLAUDE.md file from the repository root if it exists. This provides Claude with:
When processing an issue, the CLAUDE.md content is injected into the prompt, ensuring Claude has full context about the project.
npm run watch
npm run clean
npm run build
The client has minimal production dependencies:
{
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.1.28",
"@modelcontextprotocol/sdk": "^1.0.4"
},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.3.0"
}
}
The client integrates seamlessly with the main Agent Manager webhook server through commands.json:
{
"commands": {
"issues": [
{
"name": "handle-issue-assigned",
"description": "Handle issues assigned to Claude",
"type": "node",
"command": "client/dist/index.js",
"args": [
"{{repo_owner}}",
"{{repo}}",
"{{pusher}}",
"{{issue_number}}",
"{{issue_title}}",
"{{issue_body}}",
"{{issue_action}}",
"",
"{{issue_assignee}}",
"{{issue_labels}}"
],
"filterActions": ["assigned"],
"filterAssignee": "claude"
}
],
"issue_comment": [
{
"name": "handle-issue-comment",
"description": "Handle comments on issues assigned to Claude",
"type": "node",
"command": "client/dist/index.js",
"args": [
"{{repo_owner}}",
"{{repo}}",
"{{pusher}}",
"{{issue_number}}",
"{{issue_title}}",
"{{issue_body}}",
"{{issue_action}}",
"{{comment_body}}",
"{{issue_assignee}}",
"{{issue_labels}}"
],
"filterAssignee": "claude"
}
]
}
}
Solution: Ensure SSH keys are configured and GOGS_ACCESS_TOKEN is set
Solution: Check that MCP configuration exists and servers are accessible. Review logs for connection errors.
Solution: Verify HOME, XDG directories exist and have correct permissions (700 for directories, 600 for config files)
Solution: Ensure {{issue_labels}} variable is passed from commands.json and labels are set on the issue in Gogs
Solution: Verify CLAUDE.md exists in repository root and is readable by the claude user
ISC