Skip to content

Latest commit

 

History

History
105 lines (75 loc) · 5.32 KB

File metadata and controls

105 lines (75 loc) · 5.32 KB

AGENTS.md — Issue Bridge

Guidelines for AI agents working on this codebase.

Project Overview

Issue Bridge is a backend service that collects feedback from any source (websites, apps, bots, forms, internal tools) via a single API endpoint and automatically creates well-formatted GitHub issues on a target repository. It uses AI (OpenRouter) to rewrite raw feedback into professional engineering issues, and GitHub App authentication to create them.

Each instance of Issue Bridge serves one project. Project-specific context is loaded from PROJECT_CONTEXT.md at startup, so the AI writes issues that match the project's domain, tech stack, and terminology.

Architecture

Any client (website, mobile app, Slack bot, form, CLI, etc.)
    │
    ▼
POST /api/feedback
  → validateFeedback (Zod middleware)
  → feedbackService.processFeedback()
    → load projectContext (from PROJECT_CONTEXT.md, cached at startup)
    → openrouterService.rewriteFeedback(feedback, projectContext)
        // AI generates { title, body, labels } using project context
    → githubService.createIssue()  // GitHub App auth via Octokit
  → 201 { issueNumber, issueUrl, title }

Key Design Decisions

  • Express app factory pattern (createApp() in app.ts) — enables testing with Supertest without starting a real server
  • GitHub App auth (not PAT or OAuth) — uses @octokit/auth-app with App ID + private key + installation ID for server-to-server authentication
  • Project context from filePROJECT_CONTEXT.md is read once at startup and injected into every AI prompt, so issues reference real project components
  • Native fetch for OpenRouter — no axios or other HTTP client needed
  • Zod 4 for both env validation (fail-fast at startup) and request validation (middleware)
  • JSON mode in OpenRouter request — ensures AI returns parseable JSON

File Map

File Purpose
src/config/env.ts Zod schema for all env vars. App exits on invalid config.
src/config/project-context.ts Reads PROJECT_CONTEXT.md at startup, exports projectContext singleton
src/types/feedback.ts FeedbackRequest Zod schema + FeedbackResponse interface
src/types/issue.ts StructuredIssue and ProjectContext interfaces
src/prompts/feedback-to-issue.ts System prompt + buildUserMessage() that prepends project context to feedback
src/services/openrouter.service.ts Calls OpenRouter chat completions with project context, validates response with Zod
src/services/github.service.ts Singleton Octokit client with GitHub App auth, createIssue()
src/services/feedback.service.ts Orchestrator: passes project context to AI → calls GitHub
src/middleware/validate-feedback.ts Zod validation middleware for POST body
src/middleware/error-handler.ts Maps errors to HTTP status codes (400, 502, 500)
src/routes/feedback.route.ts Route handler for POST /api/feedback
PROJECT_CONTEXT.md Project-specific context (README/docs of the target project). Read at startup.

Conventions

  • Package manager: pnpm (not npm or yarn)
  • Module system: ESM ("type": "module" in package.json). Use .js extensions in imports.
  • No mutation: Prefer creating new objects over mutating existing ones
  • Error handling: Services throw errors, middleware catches and formats them
  • Testing: Vitest + Supertest. Mock external services (fetch, Octokit). Never call real APIs in tests.

Common Tasks

Adding a new feedback source

No code changes needed. Any client that can send HTTP POST with a JSON body can use Issue Bridge. Just call POST /api/feedback with { "feedback": "..." }.

Changing the target project

Replace PROJECT_CONTEXT.md with the new project's README or documentation. Update GITHUB_DEFAULT_REPO_OWNER and GITHUB_DEFAULT_REPO_NAME in .env. Restart the service.

Adding a new endpoint

  1. Create route in src/routes/
  2. Add validation middleware if needed in src/middleware/
  3. Register route in src/app.ts
  4. Add integration test in src/__tests__/

Modifying the AI prompt

Edit src/prompts/feedback-to-issue.ts. The prompt instructs the AI to return JSON with title, body, and labels. If you change the output schema, also update structuredIssueSchema in openrouter.service.ts and the StructuredIssue type in types/issue.ts.

Modifying project context

Edit src/config/project-context.ts to change the name, description, or techStack fields. The readme field is auto-loaded from PROJECT_CONTEXT.md.

Changing GitHub auth strategy

GitHub auth is isolated in src/services/github.service.ts. The singleton Octokit instance uses createAppAuth. To switch auth methods, modify getOctokit() and update env vars in src/config/env.ts.

Testing

pnpm test          # Run all tests once
pnpm test:watch    # Watch mode
pnpm typecheck     # TypeScript type checking

Tests mock all external dependencies:

  • openrouter.service tests mock globalThis.fetch
  • github.service tests mock octokit module
  • Integration tests mock both services + project-context module

Environment

Required env vars are validated at startup via Zod in src/config/env.ts. If any are missing or invalid, the process exits with a clear error message. See .env.example for the full list.