Skip to content

PotLock/issue-bridge

Repository files navigation

Issue Bridge

A lightweight service that collects feedback from anywhere via API and automatically creates well-formatted GitHub issues on your target repository.

How It Works

Any Source (website, app, Slack bot, form, etc.)
    │
    ▼
POST /api/feedback  ──→  Validate  ──→  AI Rewrite (OpenRouter)  ──→  GitHub Issue
    │                                        │                            │
    │                                        ▼                            ▼
    │                                 Structured issue              Created on your
    │                                 (title, body, labels)         target GitHub repo
    ▼
201 { issueNumber, issueUrl, title }
  1. Any client sends feedback via POST /api/feedback
  2. Input is validated with Zod
  3. AI (via OpenRouter) rewrites the raw feedback into a professional GitHub issue — using project context from PROJECT_CONTEXT.md to match your project's domain, tech stack, and terminology
  4. The issue is created on the configured GitHub repository via GitHub App authentication
  5. Returns the issue number and URL

Project Context

Issue Bridge reads PROJECT_CONTEXT.md at startup to understand your project. The AI uses this context to write issues that reference your actual components, architecture, and conventions — instead of generic descriptions.

Place a PROJECT_CONTEXT.md file in the project root with your project's README or documentation. The content is truncated to ~2000 chars for token efficiency.

Tech Stack

  • Runtime: Node.js 18+ (native fetch)
  • Framework: Express 5 + TypeScript
  • AI: OpenRouter API (any model — Claude, GPT, etc.)
  • GitHub: Octokit + GitHub App authentication
  • Validation: Zod 4
  • Testing: Vitest + Supertest

Project Structure

src/
├── index.ts                    # Server entry point
├── app.ts                      # Express app factory
├── config/
│   ├── env.ts                  # Environment validation (fail-fast)
│   └── project-context.ts      # Loads PROJECT_CONTEXT.md at startup
├── types/
│   ├── feedback.ts             # Request/response types
│   └── issue.ts                # StructuredIssue + ProjectContext interfaces
├── prompts/
│   └── feedback-to-issue.ts    # AI system prompt + context builder
├── services/
│   ├── feedback.service.ts     # Orchestrator: context → AI → GitHub
│   ├── openrouter.service.ts   # AI rewrite via OpenRouter
│   └── github.service.ts       # GitHub App auth + issue creation
├── middleware/
│   ├── validate-feedback.ts    # Zod request validation
│   └── error-handler.ts        # Global error handler
├── routes/
│   └── feedback.route.ts       # POST /api/feedback
└── __tests__/
    ├── openrouter.service.test.ts
    ├── github.service.test.ts
    └── feedback.integration.test.ts

Getting Started

Prerequisites

Installation

pnpm install
cp .env.example .env
# Fill in your credentials in .env

Environment Variables

Variable Description
PORT Server port (default: 3000)
OPENROUTER_API_KEY OpenRouter API key
OPENROUTER_MODEL AI model to use (default: anthropic/claude-sonnet-4)
GITHUB_APP_ID GitHub App ID
GITHUB_APP_PRIVATE_KEY GitHub App private key (PEM content, use \n for newlines)
GITHUB_APP_INSTALLATION_ID GitHub App installation ID
GITHUB_DEFAULT_REPO_OWNER Default repo owner (used when repo not in request)
GITHUB_DEFAULT_REPO_NAME Default repo name

Running

# Development (hot reload)
pnpm dev

# Production
pnpm build
pnpm start

# Type check
pnpm typecheck

# Tests
pnpm test

API

POST /api/feedback

Create a GitHub issue from feedback. The feedback can come from any source — a website widget, mobile app, Slack bot, internal tool, or manual curl.

Request:

{
  "feedback": "Login page is very slow on mobile Safari, sometimes shows blank screen",
  "repo": "owner/repo"
}
Field Type Required Description
feedback string Yes Raw feedback text (1-5000 chars)
repo string No Target repo in owner/repo format. Falls back to env defaults.

Response (201):

{
  "success": true,
  "data": {
    "issueNumber": 42,
    "issueUrl": "https://github.com/owner/repo/issues/42",
    "title": "Fix login page performance on mobile Safari"
  }
}

Error Response (400/502/500):

{
  "success": false,
  "error": "Validation failed",
  "details": "..."
}

GET /health

{ "status": "ok" }

GitHub App Setup

  1. Go to GitHub → Settings → Developer settings → GitHub Apps → New GitHub App
  2. Fill in:
    • App name: issue-bridge (or any name)
    • Homepage URL: http://localhost:3000
    • Webhook: uncheck Active
    • Permissions → Repository → Issues: Read & Write
  3. Click Create GitHub App
  4. Copy the App ID from the app settings page
  5. Scroll down and click Generate a private key (downloads a .pem file)
  6. Go to Install App tab → install on your account/org → select target repo(s)
  7. After installation, get the Installation ID from the URL:
    github.com/settings/installations/12345678
                                       ^^^^^^^^ Installation ID
    
  8. Convert the .pem file to a single line for .env:
    awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' private-key.pem

License

ISC

About

A lightweight service that collects feedback from anywhere via API and automatically creates well-formatted GitHub issues on your target repository.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors