Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions cc-registry-v2/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,21 +139,24 @@ docker-compose restart backend

### Theme & Design Tokens

Registry theme is aligned with RunWhen docs (`/workspaces/docs` Starlight custom.css). Use theme tokens; do not hardcode colors.

| Token | Light | Dark | Usage |
|-------|-------|------|-------|
| `primary.main` | `#5282f1` | `#5282f1` | Interactive elements, links |
| `text.primary` | `#3f3f3f` | `#e0e0e0` | Headings, body text |
| `text.secondary` | `#858484` | `#a0a0a0` | Descriptions, metadata |
| `background.paper` | `#ffffff` | `#1e1e1e` | Cards, surfaces |
| `background.default` | `#ffffff` | `#121212` | Page background |
| `divider` | `rgba(0,0,0,0.12)` | `rgba(255,255,255,0.12)` | Borders, separators |
| `primary.main` | `#2F80ED` | `#2F80ED` | Interactive elements, links, header/footer |
| `text.primary` | `#1a202c` | `#e2e8f0` | Headings, body text |
| `text.secondary` | `#4a5568` | `#94a3b8` | Descriptions, metadata |
| `background.paper` | `#ffffff` | `#1e293b` | Cards, surfaces |
| `background.default` | `#ffffff` | `#0f172a` | Page background |
| `divider` | `#e2e8f0` | `rgba(255,255,255,0.12)` | Borders, separators |
| `action.hover` | — | — | Hover/zebra backgrounds |

**Rules:**
- Always use theme tokens — never hardcode `#fff`, `#000`, `#666`, `#ddd`
- Font family: **Raleway** (brand font, do not change)
- Font family: **Inter** (aligned with RunWhen docs; load via Google Fonts in `index.html`)
- Font weight: `400` body, `500` emphasis, `600` headings/buttons — never `700` or `'bold'`
- Font size grid: `0.75rem` (12px), `0.8125rem` (13px), `0.875rem` (14px), `0.9375rem` (15px), `1rem` (16px) — no sizes below 12px
- Border radius: buttons/chips `6px`, cards `8px` (docs `--rw-radius-sm` / `--rw-radius-md`)
- Chip min height: `24px`, row min height: `40px`
- Dark mode is supported via `ThemeContext` — test both modes

Expand Down Expand Up @@ -221,5 +224,4 @@ All containers: `runAsNonRoot: true`, `runAsUser: 1000`, drop all capabilities.
4. Run database operations in HTTP request handlers (use Celery)
5. Show raw database IDs in the UI (use slugs)
6. Use emoji in code or docs unless explicitly requested
7. Change the font to Inter or the primary color to `#0570de` (registry has its own brand)
8. "Fix" `Home.tsx` to match the app design system — it's intentionally different
7. "Fix" `Home.tsx` to match the app design system — it's intentionally different
22 changes: 22 additions & 0 deletions cc-registry-v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,28 @@ The application requires Azure OpenAI credentials for two purposes:

**See [AZURE_OPENAI_SETUP.md](AZURE_OPENAI_SETUP.md) for configuration details.**

### GitHub App (Issue Creation)

The registry can create GitHub issues (intake requests, codebundle requests) using either a GitHub App (preferred) or a personal access token.

**GitHub App (preferred)** -- provides short-lived installation tokens, no long-lived secrets:

| Variable | Required | Description |
|----------|----------|-------------|
| `GITHUB_APP_ID` | Yes | Numeric App ID (Settings > General > App ID) |
| `GITHUB_APP_PRIVATE_KEY` | Yes | PEM private key -- raw PEM text or base64-encoded PEM. Generate under the App's Settings > Private keys |
| `GITHUB_APP_INSTALLATION_ID` | No | Installation ID. If omitted, the first installation returned by the API is used. Useful when the App is installed on multiple orgs |

**Personal Access Token fallback:**

| Variable | Required | Description |
|----------|----------|-------------|
| `GITHUB_TOKEN` | Yes | Classic or fine-grained PAT with `repo` (or Issues read/write) scope on the target repository |

At least one of the above groups must be set, otherwise issue creation is disabled at runtime.

Both the backend (`app/services/github_auth.py`) and the MCP server (`mcp-server/tools/github_issue.py`) use these variables.

### Secrets Configuration

All secrets are managed via Kubernetes secrets. See [k8s/secrets-example.yaml](k8s/secrets-example.yaml) for examples.
Expand Down
10 changes: 5 additions & 5 deletions cc-registry-v2/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ tasks:
desc: Start all services
cmds:
- echo "🚀 Starting all services..."
- docker-compose up -d --build
- . ./az.secret && docker-compose up -d --build

stop:
desc: Stop all services
Expand All @@ -27,7 +27,7 @@ tasks:
desc: Restart all services
cmds:
- echo "🔄 Restarting all services..."
- docker-compose restart
- . ./az.secret && docker-compose restart

# Monitoring commands
logs:
Expand Down Expand Up @@ -83,7 +83,7 @@ tasks:
desc: Start only backend services (db, redis, backend)
cmds:
- echo "🔧 Starting backend services..."
- docker-compose up -d database redis backend
- . ./az.secret && docker-compose up -d database redis backend

frontend:
desc: Start only frontend (requires backend)
Expand All @@ -95,14 +95,14 @@ tasks:
desc: Start worker services
cmds:
- echo "🔄 Starting worker services..."
- docker-compose up -d worker scheduler flower
- . ./az.secret && docker-compose up -d worker scheduler flower

# Development commands
dev:
desc: Start development environment (backend + frontend)
cmds:
- echo "💻 Starting development environment..."
- docker-compose up -d database redis backend frontend
- . ./az.secret && docker-compose up -d database redis backend frontend

dev:logs:
desc: Show logs for development services
Expand Down
8 changes: 8 additions & 0 deletions cc-registry-v2/backend/app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ class Settings(BaseSettings):
GITHUB_WEBHOOK_SECRET: str = "your_webhook_secret_here"
GITHUB_OWNER: str = "runwhen-contrib"
GITHUB_REPO: str = "codecollection-registry"

# GitHub App Authentication (preferred over GITHUB_TOKEN when configured)
GITHUB_APP_ID: Optional[str] = None
GITHUB_APP_PRIVATE_KEY: Optional[str] = None
GITHUB_APP_INSTALLATION_ID: Optional[int] = None

# Target repo for intake wizard issue creation
GITHUB_INTAKE_REPO: str = "runwhen-contrib/codecollection-registry"

# Security
SECRET_KEY: str = "your-secret-key-change-in-production"
Expand Down
3 changes: 2 additions & 1 deletion cc-registry-v2/backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ async def health_check():
}

# Include routers
from app.routers import admin, tasks, raw_data, admin_crud, task_execution_admin, versions, task_management, admin_inventory, helm_charts, mcp_chat, chat_debug, github_issues, schedule_config, analytics, vector_search
from app.routers import admin, tasks, raw_data, admin_crud, task_execution_admin, versions, task_management, admin_inventory, helm_charts, mcp_chat, chat_debug, github_issues, schedule_config, analytics, vector_search, intake
app.include_router(admin.router)
app.include_router(tasks.router)
app.include_router(raw_data.router)
Expand All @@ -115,6 +115,7 @@ async def health_check():
app.include_router(github_issues.router, prefix="/api/v1")
app.include_router(analytics.router)
app.include_router(vector_search.router)
app.include_router(intake.router)

@app.get("/api/v1/registry/collections")
async def list_collections():
Expand Down
53 changes: 26 additions & 27 deletions cc-registry-v2/backend/app/routers/github_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import requests

from app.core.config import settings
from app.services.github_auth import get_github_auth

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/github", tags=["github"])
Expand All @@ -32,19 +33,18 @@ class IssueResponse(BaseModel):
async def create_task_request_issue(request: TaskRequestIssue):
"""Create a GitHub issue requesting new tasks for the registry"""

if settings.GITHUB_TOKEN == "your_github_token_here":
gh = get_github_auth()
if not gh.is_configured:
raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail="GitHub integration not configured. Please set GITHUB_TOKEN in environment variables."
detail="GitHub integration not configured. Set GITHUB_APP_ID/GITHUB_APP_PRIVATE_KEY or GITHUB_TOKEN.",
)

try:
# Create issue title
title = f"Task Request: {request.user_query}"

# Create issue body

body_parts = [
"## 🚀 New Task Request",
"## New Task Request",
"",
f"**User Query:** {request.user_query}",
"",
Expand All @@ -58,12 +58,10 @@ async def create_task_request_issue(request: TaskRequestIssue):
f"- **Platform:** {request.platform}",
f"- **Priority:** {request.priority}",
]

if request.user_email:
body_parts.extend([
f"- **Requested by:** {request.user_email}",
])

body_parts.append(f"- **Requested by:** {request.user_email}")

body_parts.extend([
"",
"### Acceptance Criteria",
Expand All @@ -75,51 +73,52 @@ async def create_task_request_issue(request: TaskRequestIssue):
"---",
"*This issue was automatically created from the CodeCollection Registry chat interface.*"
])

body = "\n".join(body_parts)

# Create GitHub issue

github_api_url = f"https://api.github.com/repos/{settings.GITHUB_OWNER}/{settings.GITHUB_REPO}/issues"

headers = {
"Authorization": f"token {settings.GITHUB_TOKEN}",
**gh.auth_header(),
"Accept": "application/vnd.github.v3+json",
"Content-Type": "application/json"
"Content-Type": "application/json",
}

issue_data = {
"title": title,
"body": body,
"labels": ["enhancement", "task-request", f"platform:{request.platform.lower()}", f"priority:{request.priority}"]
"labels": ["enhancement", "task-request", f"platform:{request.platform.lower()}", f"priority:{request.priority}"],
}

response = requests.post(github_api_url, json=issue_data, headers=headers)

if response.status_code == 201:
issue_info = response.json()
return IssueResponse(
issue_url=issue_info["html_url"],
issue_number=issue_info["number"],
message=f"Successfully created GitHub issue #{issue_info['number']}"
message=f"Successfully created GitHub issue #{issue_info['number']}",
)
else:
logger.error(f"GitHub API error: {response.status_code} - {response.text}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to create GitHub issue: {response.text}"
detail=f"GitHub API error: {response.text}",
)


except HTTPException:
raise
except requests.RequestException as e:
logger.error(f"Error creating GitHub issue: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Error communicating with GitHub: {str(e)}"
detail=f"Error communicating with GitHub: {str(e)}",
)
except Exception as e:
logger.error(f"Unexpected error creating GitHub issue: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Unexpected error: {str(e)}"
detail=f"Unexpected error: {str(e)}",
)


Expand Down
Loading
Loading