diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md new file mode 100644 index 0000000..5fe2952 --- /dev/null +++ b/BREAKING_CHANGES.md @@ -0,0 +1,20 @@ +# Breaking Changes + +## PR #181 - Enhanced Session Validation and API Documentation + +### Event Pattern Change +- **Changed**: Session handler event pattern changed from `session` to `session*` +- **Impact**: Any integrations listening for specific session events may need to update their event filtering logic +- **Migration**: Update event listeners to use wildcard pattern matching or specific event names (e.g., `session.create`, `session.start`) + +### Volume Naming Pattern +- **Changed**: Volume naming pattern in SessionManager changed to use a more consistent format +- **Previous**: Various inconsistent naming patterns +- **New**: Standardized naming with session ID prefixes +- **Impact**: Existing volumes created with old naming patterns may not be recognized +- **Migration**: Existing sessions may need to be recreated or volumes renamed to match new pattern + +### API Validation +- **Added**: Strict UUID validation for session dependencies +- **Impact**: Sessions with invalid dependency IDs will now be rejected +- **Migration**: Ensure all dependency IDs are valid UUIDs before creating sessions \ No newline at end of file diff --git a/claude-api-swagger.yaml b/claude-api-swagger.yaml index 128a980..ed632bb 100644 --- a/claude-api-swagger.yaml +++ b/claude-api-swagger.yaml @@ -107,6 +107,53 @@ paths: oneOf: - $ref: '#/components/schemas/ClaudeWebhookRequest' - $ref: '#/components/schemas/GitHubWebhookPayload' + examples: + createSession: + summary: Create a new Claude session + value: + type: session.create + session: + type: implementation + project: + repository: acme/webapp + branch: feature/user-auth + requirements: Implement JWT authentication middleware for Express.js with refresh token support + context: Use existing User model, bcrypt for passwords, and jsonwebtoken library + dependencies: [] + createSessionWithDependencies: + summary: Create a session that depends on others + value: + type: session.create + session: + type: testing + project: + repository: acme/webapp + branch: feature/user-auth + requirements: Write comprehensive integration tests for the JWT authentication middleware + context: Test all edge cases including token expiration, invalid tokens, and refresh flow + dependencies: + - 550e8400-e29b-41d4-a716-446655440000 + - 660e8400-e29b-41d4-a716-446655440001 + startSession: + summary: Start an existing session + value: + type: session.start + sessionId: 550e8400-e29b-41d4-a716-446655440000 + orchestrate: + summary: Create an orchestration with multiple sessions + value: + type: orchestrate + autoStart: true + project: + repository: acme/webapp + branch: feature/complete-auth + requirements: | + Implement a complete authentication system: + 1. JWT middleware with refresh tokens + 2. User registration and login endpoints + 3. Password reset functionality + 4. Integration tests for all auth endpoints + context: Use existing User model, PostgreSQL database, and follow REST API conventions responses: '200': description: Webhook processed successfully @@ -114,6 +161,35 @@ paths: application/json: schema: $ref: '#/components/schemas/WebhookResponse' + examples: + sessionCreated: + summary: Session created successfully + value: + success: true + message: Session created successfully + data: + session: + id: 550e8400-e29b-41d4-a716-446655440000 + type: implementation + status: initializing + containerId: claude-session-550e8400 + project: + repository: acme/webapp + branch: feature/user-auth + requirements: Implement JWT authentication middleware for Express.js with refresh token support + context: Use existing User model, bcrypt for passwords, and jsonwebtoken library + dependencies: [] + sessionStarted: + summary: Session started with dependencies + value: + success: true + message: Session queued, waiting for dependencies + data: + session: + id: 660e8400-e29b-41d4-a716-446655440001 + status: pending + waitingFor: + - 550e8400-e29b-41d4-a716-446655440000 '400': description: Bad request content: diff --git a/docker-compose.hackathon.yml b/docker-compose.hackathon.yml deleted file mode 100644 index e040661..0000000 --- a/docker-compose.hackathon.yml +++ /dev/null @@ -1,103 +0,0 @@ -version: '3.8' - -x-webhook-template: &webhook-template - build: . - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ${HOME}/.aws:/root/.aws:ro - - ${HOME}/.claude-hub:/home/node/.claude - environment: - - NODE_ENV=production - - TRUST_PROXY=true - - BOT_EMAIL=${BOT_EMAIL:-claude@example.com} - - DEFAULT_BRANCH=${DEFAULT_BRANCH:-main} - - CLAUDE_USE_CONTAINERS=1 - - CLAUDE_CONTAINER_IMAGE=claudecode:latest - - CLAUDE_AUTH_HOST_DIR=${CLAUDE_AUTH_HOST_DIR:-${HOME}/.claude-hub} - - DISABLE_LOG_REDACTION=true - - BASH_DEFAULT_TIMEOUT_MS=600000 - - BASH_MAX_TIMEOUT_MS=1200000 - - PR_REVIEW_WAIT_FOR_ALL_CHECKS=true - - GITHUB_TOKEN=${GITHUB_TOKEN} - - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - - GITHUB_WEBHOOK_SECRET=${GITHUB_WEBHOOK_SECRET} - - CLAUDE_WEBHOOK_SECRET=${CLAUDE_WEBHOOK_SECRET} - restart: unless-stopped - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3002/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 10s - -services: - # Team 1 instance - webhook-team1: - <<: *webhook-template - ports: - - "3001:3002" - environment: - - PORT=3002 - - AUTHORIZED_USERS=team1-user1,team1-user2 - - BOT_USERNAME=@MCPClaude-Team1 - - DEFAULT_GITHUB_OWNER=team1 - - # Team 2 instance - webhook-team2: - <<: *webhook-template - ports: - - "3002:3002" - environment: - - PORT=3002 - - AUTHORIZED_USERS=team2-user1,team2-user2 - - BOT_USERNAME=@MCPClaude-Team2 - - DEFAULT_GITHUB_OWNER=team2 - - # Team 3 instance - webhook-team3: - <<: *webhook-template - ports: - - "3003:3002" - environment: - - PORT=3002 - - AUTHORIZED_USERS=team3-user1,team3-user2 - - BOT_USERNAME=@MCPClaude-Team3 - - DEFAULT_GITHUB_OWNER=team3 - - # Team 4 instance - webhook-team4: - <<: *webhook-template - ports: - - "3004:3002" - environment: - - PORT=3002 - - AUTHORIZED_USERS=team4-user1,team4-user2 - - BOT_USERNAME=@MCPClaude-Team4 - - DEFAULT_GITHUB_OWNER=team4 - - # Team 5 instance - webhook-team5: - <<: *webhook-template - ports: - - "3005:3002" - environment: - - PORT=3002 - - AUTHORIZED_USERS=team5-user1,team5-user2 - - BOT_USERNAME=@MCPClaude-Team5 - - DEFAULT_GITHUB_OWNER=team5 - - # Add more teams as needed... - - # Optional: Nginx reverse proxy for nice URLs - nginx: - image: nginx:alpine - ports: - - "80:80" - volumes: - - ./nginx-hackathon.conf:/etc/nginx/conf.d/default.conf - depends_on: - - webhook-team1 - - webhook-team2 - - webhook-team3 - - webhook-team4 - - webhook-team5 \ No newline at end of file diff --git a/src/providers/claude/handlers/SessionHandler.ts b/src/providers/claude/handlers/SessionHandler.ts index 5cfbb5b..876d955 100644 --- a/src/providers/claude/handlers/SessionHandler.ts +++ b/src/providers/claude/handlers/SessionHandler.ts @@ -11,6 +11,9 @@ import { randomUUID } from 'crypto'; const logger = createLogger('SessionHandler'); +// UUID validation regex pattern +const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + interface SessionCreatePayload { type: 'session.create'; session: Partial; @@ -133,11 +136,8 @@ export class SessionHandler implements WebhookEventHandler return dep && dep.trim() !== '' && dep.toLowerCase() !== 'none'; }); - // UUID validation regex - const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; - // Check that all remaining dependencies are valid UUIDs - const invalidDependencies = validDependencies.filter(dep => !uuidRegex.test(dep)); + const invalidDependencies = validDependencies.filter(dep => !UUID_REGEX.test(dep)); if (invalidDependencies.length > 0) { return {