From e1ebf1bad2b303295ff993393f4edd8896e6f9af Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Nov 2025 14:48:22 +0000 Subject: [PATCH 1/7] fix: Update Docker build workflow to trigger only on tags Changes: - Remove main branch push trigger from docker-build.yml - Now Docker images are built only when version tags are pushed - This aligns with the bump-version.sh workflow where tags are created - Keep PR and manual workflow_dispatch triggers for testing Also remove unused demo_curl.sh script: - Script was not referenced in any documentation - No longer needed for the project --- .github/workflows/docker-build.yml | 2 - scripts/demo_curl.sh | 265 ----------------------------- 2 files changed, 267 deletions(-) delete mode 100755 scripts/demo_curl.sh diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 8de2b7b..3be2555 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -2,8 +2,6 @@ name: Build and Push Docker Images on: push: - branches: - - main tags: - 'v*' pull_request: diff --git a/scripts/demo_curl.sh b/scripts/demo_curl.sh deleted file mode 100755 index 18433e4..0000000 --- a/scripts/demo_curl.sh +++ /dev/null @@ -1,265 +0,0 @@ -#!/bin/bash - -################################################################################ -# API Demo Script -# Purpose: Demonstrate all core API endpoints of codebase-rag -# Usage: ./scripts/demo_curl.sh -################################################################################ - -set -e # Exit on error - -# Colors -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -# Configuration -BASE_URL="${API_BASE_URL:-http://localhost:8000}" -API_VERSION="v1" -API_BASE="${BASE_URL}/api/${API_VERSION}" - -# Test data -TEST_REPO_PATH="${TEST_REPO_PATH:-/tmp/test-repo}" -TEST_REPO_ID="demo-repo-$(date +%s)" - -echo -e "${GREEN}========================================${NC}" -echo -e "${GREEN}codebase-rag API Demo${NC}" -echo -e "${GREEN}========================================${NC}" -echo -e "Base URL: ${BLUE}${BASE_URL}${NC}" -echo -e "Test Repo: ${BLUE}${TEST_REPO_PATH}${NC}" -echo "" - -# Function to print API call -print_api_call() { - echo -e "\n${YELLOW}=== $1 ===${NC}" - echo -e "${BLUE}$2${NC}" -} - -# Function to make API call and display result -api_call() { - local description=$1 - local method=$2 - local endpoint=$3 - local data=$4 - - print_api_call "$description" "$method $endpoint" - - if [ "$method" = "GET" ]; then - response=$(curl -s -w "\nHTTP_STATUS:%{http_code}" "$endpoint") - else - response=$(curl -s -w "\nHTTP_STATUS:%{http_code}" -X "$method" \ - -H "Content-Type: application/json" \ - -d "$data" \ - "$endpoint") - fi - - # Extract HTTP status - http_status=$(echo "$response" | grep "HTTP_STATUS:" | cut -d: -f2) - body=$(echo "$response" | sed '/HTTP_STATUS:/d') - - # Pretty print JSON if possible - if command -v jq &> /dev/null; then - echo "$body" | jq '.' 2>/dev/null || echo "$body" - else - echo "$body" - fi - - # Check status - if [ "$http_status" -ge 200 ] && [ "$http_status" -lt 300 ]; then - echo -e "${GREEN}✓ Success (HTTP $http_status)${NC}" - else - echo -e "${RED}✗ Failed (HTTP $http_status)${NC}" - fi - - # Save response for later use - echo "$body" > /tmp/last_response.json -} - -################################################################################ -# 1. HEALTH CHECK -################################################################################ - -api_call \ - "1. Health Check" \ - "GET" \ - "${API_BASE}/health" - -################################################################################ -# 2. SYSTEM INFO -################################################################################ - -api_call \ - "2. System Information" \ - "GET" \ - "${BASE_URL}/info" - -################################################################################ -# 3. REPOSITORY INGESTION -################################################################################ - -# Create test repository if it doesn't exist -if [ ! -d "$TEST_REPO_PATH" ]; then - echo -e "\n${YELLOW}Creating test repository at ${TEST_REPO_PATH}${NC}" - mkdir -p "$TEST_REPO_PATH/src/auth" - - cat > "$TEST_REPO_PATH/src/auth/token.py" << 'EOF' -"""Token management module""" - -def generate_token(user_id: str) -> str: - """Generate authentication token for user""" - return f"token_{user_id}" - -def validate_token(token: str) -> bool: - """Validate authentication token""" - return token.startswith("token_") -EOF - - cat > "$TEST_REPO_PATH/src/auth/user.py" << 'EOF' -"""User management module""" - -class User: - def __init__(self, username: str): - self.username = username - - def authenticate(self, password: str) -> bool: - """Authenticate user with password""" - return len(password) > 8 -EOF - - cat > "$TEST_REPO_PATH/src/main.py" << 'EOF' -"""Main application entry point""" - -from auth.token import generate_token -from auth.user import User - -def main(): - user = User("admin") - if user.authenticate("password123"): - token = generate_token("admin") - print(f"Logged in: {token}") - -if __name__ == "__main__": - main() -EOF - - echo -e "${GREEN}✓ Test repository created${NC}" -fi - -# Ingest repository -api_call \ - "3. Ingest Repository" \ - "POST" \ - "${API_BASE}/ingest/repo" \ - "{ - \"local_path\": \"$TEST_REPO_PATH\", - \"include_globs\": [\"**/*.py\", \"**/*.ts\", \"**/*.tsx\"], - \"exclude_globs\": [\"**/node_modules/**\", \"**/.git/**\", \"**/__pycache__/**\"] - }" - -# Wait a moment for ingestion to complete -sleep 2 - -################################################################################ -# 4. RELATED FILES SEARCH -################################################################################ - -api_call \ - "4a. Search Related Files - 'auth'" \ - "GET" \ - "${API_BASE}/graph/related?query=auth&repoId=${TEST_REPO_ID}&limit=10" - -api_call \ - "4b. Search Related Files - 'token'" \ - "GET" \ - "${API_BASE}/graph/related?query=token&repoId=${TEST_REPO_ID}&limit=10" - -api_call \ - "4c. Search Related Files - 'user'" \ - "GET" \ - "${API_BASE}/graph/related?query=user&repoId=${TEST_REPO_ID}&limit=10" - -################################################################################ -# 5. CONTEXT PACK GENERATION -################################################################################ - -api_call \ - "5a. Context Pack - Plan Stage" \ - "GET" \ - "${API_BASE}/context/pack?repoId=${TEST_REPO_ID}&stage=plan&budget=1500&keywords=auth,token" - -api_call \ - "5b. Context Pack - Review Stage with Focus" \ - "GET" \ - "${API_BASE}/context/pack?repoId=${TEST_REPO_ID}&stage=review&budget=2000&keywords=auth&focus=src/auth" - -api_call \ - "5c. Context Pack - Large Budget" \ - "GET" \ - "${API_BASE}/context/pack?repoId=${TEST_REPO_ID}&stage=implement&budget=5000" - -################################################################################ -# 6. IMPACT ANALYSIS -################################################################################ - -api_call \ - "6a. Impact Analysis - token.py (depth=1)" \ - "GET" \ - "${API_BASE}/graph/impact?repoId=${TEST_REPO_ID}&file=src/auth/token.py&depth=1&limit=50" - -api_call \ - "6b. Impact Analysis - user.py (depth=2)" \ - "GET" \ - "${API_BASE}/graph/impact?repoId=${TEST_REPO_ID}&file=src/auth/user.py&depth=2&limit=50" - -################################################################################ -# 7. GRAPH STATISTICS -################################################################################ - -api_call \ - "7. Graph Statistics" \ - "GET" \ - "${API_BASE}/statistics" - -################################################################################ -# 8. GRAPH SCHEMA -################################################################################ - -api_call \ - "8. Graph Schema" \ - "GET" \ - "${API_BASE}/schema" - -################################################################################ -# SUMMARY -################################################################################ - -echo -e "\n${GREEN}========================================${NC}" -echo -e "${GREEN}Demo Complete!${NC}" -echo -e "${GREEN}========================================${NC}" -echo "" -echo -e "API Endpoints Tested:" -echo -e " ${GREEN}✓${NC} GET /api/v1/health" -echo -e " ${GREEN}✓${NC} GET /info" -echo -e " ${GREEN}✓${NC} POST /api/v1/ingest/repo" -echo -e " ${GREEN}✓${NC} GET /api/v1/graph/related" -echo -e " ${GREEN}✓${NC} GET /api/v1/context/pack" -echo -e " ${GREEN}✓${NC} GET /api/v1/graph/impact" -echo -e " ${GREEN}✓${NC} GET /api/v1/statistics" -echo -e " ${GREEN}✓${NC} GET /api/v1/schema" -echo "" -echo -e "For interactive API documentation, visit:" -echo -e " ${BLUE}${BASE_URL}/docs${NC}" -echo "" -echo -e "Test repository created at:" -echo -e " ${BLUE}${TEST_REPO_PATH}${NC}" -echo "" - -# Cleanup option -read -p "Remove test repository? (y/N) " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]]; then - rm -rf "$TEST_REPO_PATH" - echo -e "${GREEN}✓ Test repository removed${NC}" -fi From 1aadb6570bcaf2fc68b9c2e61ae0f96c678ee720 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Nov 2025 14:58:34 +0000 Subject: [PATCH 2/7] feat: Migrate NiceGUI monitoring features to React frontend This commit migrates all task monitoring features from NiceGUI to the React frontend: ## New UI Components - Dialog: Modal component for task details - Input: Text input component - Textarea: Multi-line text input - Select: Dropdown select component - Label: Form label component ## Enhanced Tasks Page Features 1. **File Upload**: Upload single files (max 50KB) for processing - Auto-detect file type based on extension - Real-time upload progress - Size validation with helpful error messages 2. **Directory Batch Processing**: Process multiple files from a directory - Directory path input - File pattern filtering (wildcards supported) - Background task creation 3. **Task Details Modal**: Comprehensive task information display - Basic info: Task ID, status, progress - Timing info: Created, started, completed timestamps - Status messages and error details - Metadata JSON viewer 4. **Task Management**: - Cancel button for pending/running tasks - Status filter dropdown (All, Pending, Running, Success, Failed, Cancelled) - Real-time task status updates (3s interval) 5. **Enhanced Task Cards**: - Progress bars for running tasks - Status icons and badges - Error message display - Action buttons (Details, Cancel) ## API Updates - Added processDocument endpoint for file uploads - Added processDirectory endpoint for batch processing - Enhanced TypeScript interfaces for better type safety This completes Phase 2 of the NiceGUI migration. All monitoring features from the NiceGUI interface have been successfully replicated in React with improved UX and better performance. Next: Phase 3 will remove NiceGUI dependencies from the backend. --- frontend/src/components/ui/dialog.tsx | 113 ++++++++ frontend/src/components/ui/input.tsx | 24 ++ frontend/src/components/ui/label.tsx | 23 ++ frontend/src/components/ui/select.tsx | 25 ++ frontend/src/components/ui/textarea.tsx | 23 ++ frontend/src/lib/api.ts | 31 ++ frontend/src/routes/tasks.tsx | 360 +++++++++++++++++++++++- 7 files changed, 589 insertions(+), 10 deletions(-) create mode 100644 frontend/src/components/ui/dialog.tsx create mode 100644 frontend/src/components/ui/input.tsx create mode 100644 frontend/src/components/ui/label.tsx create mode 100644 frontend/src/components/ui/select.tsx create mode 100644 frontend/src/components/ui/textarea.tsx diff --git a/frontend/src/components/ui/dialog.tsx b/frontend/src/components/ui/dialog.tsx new file mode 100644 index 0000000..ca0aa0b --- /dev/null +++ b/frontend/src/components/ui/dialog.tsx @@ -0,0 +1,113 @@ +import * as React from 'react' +import { X } from 'lucide-react' +import { cn } from '@/lib/utils' + +interface DialogProps { + open?: boolean + onOpenChange?: (open: boolean) => void + children: React.ReactNode +} + +interface DialogContentProps extends React.HTMLAttributes { + children: React.ReactNode +} + +const Dialog = ({ open, onOpenChange, children }: DialogProps) => { + return ( + <> + {open && ( +
+ {/* Backdrop */} +
onOpenChange?.(false)} + /> + {/* Content */} +
{children}
+
+ )} + + ) +} + +const DialogContent = React.forwardRef( + ({ className, children, ...props }, ref) => { + return ( +
+ {children} +
+ ) + } +) +DialogContent.displayName = 'DialogContent' + +interface DialogHeaderProps extends React.HTMLAttributes { + children: React.ReactNode +} + +const DialogHeader = ({ className, children, ...props }: DialogHeaderProps) => { + return ( +
+ {children} +
+ ) +} + +interface DialogTitleProps extends React.HTMLAttributes { + children: React.ReactNode +} + +const DialogTitle = ({ className, children, ...props }: DialogTitleProps) => { + return ( +

+ {children} +

+ ) +} + +interface DialogDescriptionProps extends React.HTMLAttributes { + children: React.ReactNode +} + +const DialogDescription = ({ className, children, ...props }: DialogDescriptionProps) => { + return ( +

+ {children} +

+ ) +} + +interface DialogCloseProps extends React.ButtonHTMLAttributes { + onClose: () => void +} + +const DialogClose = ({ onClose, className, ...props }: DialogCloseProps) => { + return ( + + ) +} + +export { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogClose } diff --git a/frontend/src/components/ui/input.tsx b/frontend/src/components/ui/input.tsx new file mode 100644 index 0000000..0b02367 --- /dev/null +++ b/frontend/src/components/ui/input.tsx @@ -0,0 +1,24 @@ +import * as React from 'react' +import { cn } from '@/lib/utils' + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = 'Input' + +export { Input } diff --git a/frontend/src/components/ui/label.tsx b/frontend/src/components/ui/label.tsx new file mode 100644 index 0000000..2face72 --- /dev/null +++ b/frontend/src/components/ui/label.tsx @@ -0,0 +1,23 @@ +import * as React from 'react' +import { cn } from '@/lib/utils' + +export interface LabelProps + extends React.LabelHTMLAttributes {} + +const Label = React.forwardRef( + ({ className, ...props }, ref) => { + return ( +