diff --git a/.gitignore b/.gitignore
index c5ae93bd..726bf996 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,7 @@
*.iml
*.ipr
.github
-docker-compose.yml
\ No newline at end of file
+docker-compose.yml
+
+**/newrelic.jar
+**/newrelic.yml
\ No newline at end of file
diff --git a/deployment/config/rag-pipeline/.env.sample b/deployment/config/rag-pipeline/.env.sample
index 17db344a..e19d8008 100644
--- a/deployment/config/rag-pipeline/.env.sample
+++ b/deployment/config/rag-pipeline/.env.sample
@@ -20,6 +20,9 @@ RAG_MAX_FILES_PER_INDEX=40000
RAG_USE_AST_SPLITTER=true
+# Concurrency: Number of Uvicorn workers (allows parallel indexing)
+UVICORN_WORKERS=4
+
# Alternative OpenRouter models (use full format with provider prefix):
# OPENROUTER_MODEL=openai/text-embedding-3-large # Higher quality, more expensive
# OPENROUTER_MODEL=openai/text-embedding-ada-002 # Legacy model
diff --git a/deployment/docker-compose-sample-new-relic.yml b/deployment/docker-compose-sample-new-relic.yml
new file mode 100644
index 00000000..d26a3b40
--- /dev/null
+++ b/deployment/docker-compose-sample-new-relic.yml
@@ -0,0 +1,256 @@
+services:
+ postgres:
+ image: postgres:15-alpine
+ container_name: codecrow-postgres
+ environment:
+ POSTGRES_DB: codecrow_ai
+ POSTGRES_USER: codecrow_user
+ POSTGRES_PASSWORD: codecrow_pass
+ POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
+ ports:
+ - "127.0.0.1:5432:5432"
+ volumes:
+ - postgres_data:/var/lib/postgresql/data
+ networks:
+ - codecrow-network
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U codecrow_user -d codecrow_ai"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 30s
+
+ redis:
+ image: redis:7-alpine
+ container_name: codecrow-redis
+ ports:
+ - "127.0.0.1:6379:6379"
+ volumes:
+ - redis_data:/data
+ networks:
+ - codecrow-network
+ healthcheck:
+ test: ["CMD", "redis-cli", "ping"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+
+ qdrant:
+ image: qdrant/qdrant:latest
+ container_name: codecrow-qdrant
+ ports:
+ - "127.0.0.1:6333:6333"
+ - "127.0.0.1:6334:6334"
+ volumes:
+ - qdrant_data:/qdrant/storage
+ networks:
+ - codecrow-network
+ healthcheck:
+ test: ["CMD-SHELL", "bash -c '>/dev/tcp/localhost/6333'"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 30s
+ restart: unless-stopped
+
+ web-server:
+ build:
+ context: ../java-ecosystem/services/web-server
+ dockerfile: Dockerfile.observable
+ container_name: codecrow-web-application
+ environment:
+ SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/codecrow_ai
+ SPRING_DATASOURCE_USERNAME: codecrow_user
+ SPRING_DATASOURCE_PASSWORD: codecrow_pass
+
+ SPRING_JPA_HIBERNATE_DDL_AUTO: update
+ SPRING_JPA_SHOW_SQL: "true"
+ SPRING_JPA_PROPERTIES_HIBERNATE_FORMAT_SQL: "true"
+ SPRING_JPA_DATABASE_PLATFORM: org.hibernate.dialect.PostgreSQLDialect
+ SPRING_CONFIG_LOCATION: file:/app/config/application.properties
+
+ SERVER_PORT: 8081
+
+ SPRING_SESSION_STORE_TYPE: redis
+ SPRING_REDIS_HOST: redis
+ SPRING_REDIS_PORT: 6379
+ MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,info,metrics
+ MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: when-authorized
+ JAVA_OPTS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
+ LOGGING_FILE_NAME: /app/logs/codecrow-web-application.log
+ # Internal API secret for service-to-service communication
+ CODECROW_INTERNAL_API_SECRET: ${INTERNAL_API_SECRET:-codecrow-internal-secret-change-me}
+ ports:
+ - "8081:8081"
+ - "5005:5005"
+ depends_on:
+ postgres:
+ condition: service_healthy
+ redis:
+ condition: service_healthy
+ networks:
+ - codecrow-network
+ volumes:
+ - web_logs:/app/logs
+ - ./config/java-shared/application.properties:/app/config/application.properties
+ - ./config/java-shared/github-private-key/codecrow-local.2025-12-09.private-key.pem:/app/config/github-app-private-key.pem
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:8081/actuator/health"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 60s
+ restart: unless-stopped
+
+ pipeline-agent:
+ build:
+ context: ../java-ecosystem/services/pipeline-agent
+ dockerfile: Dockerfile.observable
+ container_name: codecrow-pipeline-agent
+ environment:
+ SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/codecrow_ai
+ SPRING_DATASOURCE_USERNAME: codecrow_user
+ SPRING_DATASOURCE_PASSWORD: codecrow_pass
+
+ SPRING_JPA_HIBERNATE_DDL_AUTO: update
+ SPRING_JPA_SHOW_SQL: "true"
+ SPRING_JPA_PROPERTIES_HIBERNATE_FORMAT_SQL: "true"
+ SPRING_JPA_DATABASE_PLATFORM: org.hibernate.dialect.PostgreSQLDialect
+ SPRING_CONFIG_LOCATION: file:/app/config/application.properties
+
+ SERVER_PORT: 8082
+
+ SPRING_SESSION_STORE_TYPE: redis
+ SPRING_REDIS_HOST: redis
+ SPRING_REDIS_PORT: 6379
+ RAG_API_URL: http://localhost:8001
+ RAG_ENABLED: "true"
+ JAVA_OPTS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006"
+ LOGGING_FILE_NAME: /app/logs/codecrow-pipeline-agent.log
+ ports:
+ - "8082:8082"
+ - "5006:5006"
+ depends_on:
+ postgres:
+ condition: service_healthy
+ redis:
+ condition: service_healthy
+ fix-permissions:
+ condition: service_completed_successfully
+ networks:
+ - codecrow-network
+ volumes:
+ - source_code_tmp:/tmp
+ - pipeline_agent_logs:/app/logs
+ - ./config/java-shared/application.properties:/app/config/application.properties
+ - ./config/java-shared/github-private-key/codecrow-local.2025-12-09.private-key.pem:/app/config/github-app-private-key.pem
+ healthcheck:
+ test: [ "CMD", "curl", "-f", "http://localhost:8082/actuator/health" ]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 60s
+ restart: unless-stopped
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
+
+ mcp-client:
+ build:
+ context: ../python-ecosystem/mcp-client
+ container_name: codecrow-mcp-client
+ ports:
+ - "127.0.0.1:8000:8000"
+ depends_on:
+ - rag-pipeline
+ networks:
+ - codecrow-network
+ volumes:
+ - ./config/mcp-client/.env:/app/.env
+ restart: unless-stopped
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
+ deploy:
+ resources:
+ limits:
+ cpus: '1.0'
+ memory: 1G
+ reservations:
+ cpus: '0.5'
+ memory: 512M
+
+ rag-pipeline:
+ build:
+ context: ../python-ecosystem/rag-pipeline
+ container_name: codecrow-rag-pipeline
+ ports:
+ - "127.0.0.1:8001:8001"
+ depends_on:
+ fix-permissions:
+ condition: service_completed_successfully
+ qdrant:
+ condition: service_healthy
+ networks:
+ - codecrow-network
+ volumes:
+ - source_code_tmp:/tmp
+ - rag_logs:/app/logs
+ - ./config/rag-pipeline/.env:/app/.env
+ healthcheck:
+ test: [ "CMD", "curl", "-f", "http://localhost:8001/health" ]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 60s
+ restart: unless-stopped
+ extra_hosts:
+ - "host.docker.internal:host-gateway"
+
+ web-frontend:
+ build:
+ context: ../frontend
+ container_name: codecrow-web-frontend
+ ports:
+ - "8080:8080"
+ networks:
+ - codecrow-network
+ volumes:
+ - web_frontend_logs:/app/logs
+ - ./config/web-frontend/.env:/app/.env
+ command: ["sh", "-c", "serve -s dist -l 8080 >> /app/logs/web-frontend.log 2>&1"]
+ restart: unless-stopped
+
+ fix-permissions:
+ image: busybox
+ command: sh -c "chmod -R 777 /tmp"
+ volumes:
+ - source_code_tmp:/tmp
+
+volumes:
+ source_code_tmp:
+ name: source_code_tmp
+ driver: local
+ postgres_data:
+ name: postgres_data
+ driver: local
+ redis_data:
+ name: redis_data
+ driver: local
+ qdrant_data:
+ name: qdrant_data
+ driver: local
+ web_logs:
+ name: web_logs
+ driver: local
+ pipeline_agent_logs:
+ name: agent_logs
+ driver: local
+ web_frontend_logs:
+ name: frontend_logs
+ driver: local
+ rag_logs:
+ name: rag_logs
+ driver: local
+
+networks:
+ codecrow-network:
+ driver: bridge
diff --git a/deployment/docker-compose-sample.yml b/deployment/docker-compose-sample.yml
index 31a54e92..acef7db7 100644
--- a/deployment/docker-compose-sample.yml
+++ b/deployment/docker-compose-sample.yml
@@ -8,7 +8,7 @@ services:
POSTGRES_PASSWORD: codecrow_pass
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
ports:
- - "5432:5432"
+ - "127.0.0.1:5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
@@ -24,7 +24,7 @@ services:
image: redis:7-alpine
container_name: codecrow-redis
ports:
- - "6379:6379"
+ - "127.0.0.1:6379:6379"
volumes:
- redis_data:/data
networks:
@@ -39,8 +39,8 @@ services:
image: qdrant/qdrant:latest
container_name: codecrow-qdrant
ports:
- - "6333:6333"
- - "6334:6334"
+ - "127.0.0.1:6333:6333"
+ - "127.0.0.1:6334:6334"
volumes:
- qdrant_data:/qdrant/storage
networks:
@@ -157,7 +157,7 @@ services:
context: ../python-ecosystem/mcp-client
container_name: codecrow-mcp-client
ports:
- - "8000:8000"
+ - "127.0.0.1:8000:8000"
depends_on:
- rag-pipeline
networks:
@@ -181,7 +181,7 @@ services:
context: ../python-ecosystem/rag-pipeline
container_name: codecrow-rag-pipeline
ports:
- - "8001:8001"
+ - "127.0.0.1:8001:8001"
depends_on:
fix-permissions:
condition: service_completed_successfully
diff --git a/frontend b/frontend
index b2d8460a..d454df4b 160000
--- a/frontend
+++ b/frontend
@@ -1 +1 @@
-Subproject commit b2d8460a6af5fe3b2d0f79e672522e9cc6f436ab
+Subproject commit d454df4badb567583dbf640a2995541120f9be2f
diff --git a/java-ecosystem/libs/analysis-api/.gitignore b/java-ecosystem/libs/analysis-api/.gitignore
new file mode 100644
index 00000000..495a9bdd
--- /dev/null
+++ b/java-ecosystem/libs/analysis-api/.gitignore
@@ -0,0 +1,40 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+/src/main/resources/application.properties
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
+
+index.ts
+.env
+server.log
\ No newline at end of file
diff --git a/java-ecosystem/libs/analysis-api/pom.xml b/java-ecosystem/libs/analysis-api/pom.xml
new file mode 100644
index 00000000..56512c75
--- /dev/null
+++ b/java-ecosystem/libs/analysis-api/pom.xml
@@ -0,0 +1,49 @@
+
+
+ 4.0.0
+
+
+ org.rostilos.codecrow
+ codecrow-parent
+ 1.0
+ ../../pom.xml
+
+
+ codecrow-analysis-api
+ jar
+ 1.0
+ CodeCrow Analysis API
+ API interfaces for analysis services - allows modules to depend on interfaces without implementations
+
+
+ 17
+
+
+
+
+
+ org.rostilos.codecrow
+ codecrow-core
+
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+
+
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+
+
+
+
+
diff --git a/java-ecosystem/libs/analysis-api/src/main/java/module-info.java b/java-ecosystem/libs/analysis-api/src/main/java/module-info.java
new file mode 100644
index 00000000..464e1483
--- /dev/null
+++ b/java-ecosystem/libs/analysis-api/src/main/java/module-info.java
@@ -0,0 +1,6 @@
+module org.rostilos.codecrow.analysisapi {
+ requires org.rostilos.codecrow.core;
+ requires org.slf4j;
+
+ exports org.rostilos.codecrow.analysisapi.rag;
+}
diff --git a/java-ecosystem/libs/analysis-api/src/main/java/org/rostilos/codecrow/analysisapi/rag/RagOperationsService.java b/java-ecosystem/libs/analysis-api/src/main/java/org/rostilos/codecrow/analysisapi/rag/RagOperationsService.java
new file mode 100644
index 00000000..1092006f
--- /dev/null
+++ b/java-ecosystem/libs/analysis-api/src/main/java/org/rostilos/codecrow/analysisapi/rag/RagOperationsService.java
@@ -0,0 +1,304 @@
+package org.rostilos.codecrow.analysisapi.rag;
+
+import org.rostilos.codecrow.core.model.project.Project;
+
+import java.util.function.Consumer;
+import java.util.Map;
+
+/**
+ * Interface for RAG (Retrieval-Augmented Generation) operations.
+ *
+ * This interface defines the contract for RAG operations, allowing modules to depend on
+ * the interface without requiring the full RAG implementation. This enables:
+ * - analysis-engine to use RAG operations without directly depending on rag-engine
+ * - Optional RAG support (implementations can be conditionally loaded)
+ * - Easy testing with mock implementations
+ *
+ * Implementations are provided by the rag-engine module.
+ */
+public interface RagOperationsService {
+
+ /**
+ * Check if RAG is enabled for the given project.
+ *
+ * @param project The project to check
+ * @return true if RAG is enabled, false otherwise
+ */
+ boolean isRagEnabled(Project project);
+
+ /**
+ * Check if RAG index is in a ready state for the given project.
+ *
+ * @param project The project to check
+ * @return true if RAG index is ready, false otherwise
+ */
+ boolean isRagIndexReady(Project project);
+
+ /**
+ * Trigger an incremental RAG update for the given project after a branch merge or commit.
+ *
+ * @param project The project to update
+ * @param branchName The branch name that was updated
+ * @param commitHash The commit hash of the update
+ * @param rawDiff The raw diff from the VCS (used to determine which files changed)
+ * @param eventConsumer Consumer to receive status updates during processing
+ */
+ void triggerIncrementalUpdate(
+ Project project,
+ String branchName,
+ String commitHash,
+ String rawDiff,
+ Consumer