{"repo": "1ike-m0on/devcontext", "files": {"docker-compose.yml": {"cf4cee8e3f2d701e5325b875bf513a0d3fdf8105": {"t": 1785746355.606039, "n": 2119, "h": "c690848b49b15a1e", "c": "services:\n backend:\n build:\n context: .\n dockerfile: Dockerfile\n ports:\n - \"18080:18080\"\n environment:\n SPRING_DATASOURCE_URL: jdbc:sqlite:/app/data/devcontext.sqlite\n DEVCONTEXT_LLM_PROVIDER: ${DEVCONTEXT_LLM_PROVIDER:-mock}\n GEMINI_API_KEY: ${GEMINI_API_KEY:-}\n GEMINI_MODEL: ${GEMINI_MODEL:-gemini-2.0-flash}\n GEMINI_BASE_URL: ${GEMINI_BASE_URL:-https://generativelanguage.googleapis.com/v1beta}\n GEMINI_TIMEOUT: ${GEMINI_TIMEOUT:-60s}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n DEEPSEEK_MODEL: ${DEEPSEEK_MODEL:-deepseek-chat}\n DEEPSEEK_BASE_URL: ${DEEPSEEK_BASE_URL:-https://api.deepseek.com}\n DEEPSEEK_TIMEOUT: ${DEEPSEEK_TIMEOUT:-120s}\n DEVCONTEXT_VECTOR_PROVIDER: ${DEVCONTEXT_VECTOR_PROVIDER:-qdrant}\n QDRANT_BASE_URL: http://qdrant:6333\n QDRANT_API_KEY: ${QDRANT_API_KEY:-}\n QDRANT_DISTANCE: ${QDRANT_DISTANCE:-Cosine}\n QDRANT_TIMEOUT: ${QDRANT_TIMEOUT:-10s}\n volumes:\n - ./data/devcontext:/app/data\n - ${DEVCONTEXT_PROJECTS_DIR:-./workspace/projects}:/workspace/projects\n depends_on:\n qdrant:\n condition: service_healthy\n healthcheck:\n test: [\"CMD-SHELL\", \"curl -fsS http://localhost:18080/api/health >/dev/null\"]\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 30s\n\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n ports:\n - \"5173:80\"\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [\"CMD-SHELL\", \"curl -fsS http://localhost/ >/dev/null\"]\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 10s\n\n qdrant:\n image: qdrant/qdrant:v1.18.1\n ports:\n - \"6333:6333\"\n - \"6334:6334\"\n volumes:\n - ./data/qdrant:/qdrant/storage\n healthcheck:\n test: >\n timeout 5 bash -ec 'exec 3<>/dev/tcp/127.0.0.1/6333;\n printf \"GET /healthz HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n\" >&3;\n grep -q \"200 OK\" <&3'\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 10s\n"}, "308e32e695394696de3dec02e3ec583df041f0e2": {"t": 1785762436.2749128, "n": 1527, "h": "bdf6fea5b6c69a60", "c": "services:\n backend:\n build:\n context: .\n dockerfile: Dockerfile\n container_name: devcontext-backend\n ports:\n - \"18080:18080\"\n environment:\n SPRING_DATASOURCE_URL: jdbc:sqlite:/app/data/devcontext.sqlite\n DEVCONTEXT_LLM_PROVIDER: ${DEVCONTEXT_LLM_PROVIDER:-mock}\n GEMINI_API_KEY: ${GEMINI_API_KEY:-}\n GEMINI_MODEL: ${GEMINI_MODEL:-gemini-2.0-flash}\n GEMINI_BASE_URL: ${GEMINI_BASE_URL:-https://generativelanguage.googleapis.com/v1beta}\n GEMINI_TIMEOUT: ${GEMINI_TIMEOUT:-60s}\n DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:-}\n DEEPSEEK_MODEL: ${DEEPSEEK_MODEL:-deepseek-chat}\n DEEPSEEK_BASE_URL: ${DEEPSEEK_BASE_URL:-https://api.deepseek.com}\n DEEPSEEK_TIMEOUT: ${DEEPSEEK_TIMEOUT:-120s}\n DEVCONTEXT_VECTOR_PROVIDER: ${DEVCONTEXT_VECTOR_PROVIDER:-qdrant}\n QDRANT_BASE_URL: http://qdrant:6333\n QDRANT_API_KEY: ${QDRANT_API_KEY:-}\n QDRANT_DISTANCE: ${QDRANT_DISTANCE:-Cosine}\n QDRANT_TIMEOUT: ${QDRANT_TIMEOUT:-10s}\n volumes:\n - ./data/devcontext:/app/data\n - ${DEVCONTEXT_PROJECTS_DIR:-./workspace/projects}:/workspace/projects\n depends_on:\n - qdrant\n\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n container_name: devcontext-frontend\n ports:\n - \"5173:80\"\n depends_on:\n - backend\n\n qdrant:\n image: qdrant/qdrant:latest\n container_name: devcontext-qdrant\n ports:\n - \"6333:6333\"\n - \"6334:6334\"\n volumes:\n - ./data/qdrant:/qdrant/storage\n"}}, "src/main/resources/application.yml": {"cf4cee8e3f2d701e5325b875bf513a0d3fdf8105": {"t": 1785746356.8361642, "n": 1181, "h": "59eea19200bb613f", "c": "spring:\n config:\n import:\n - optional:file:.env[.properties]\n - optional:file:./devcontext.local.yml\n - optional:file:./config/devcontext.local.yml\n application:\n name: devcontext\n datasource:\n url: jdbc:sqlite:data/devcontext.sqlite\n driver-class-name: org.sqlite.JDBC\n sql:\n init:\n mode: always\n schema-locations: classpath:db/schema.sql\n\nserver:\n port: 18080\n\ndevcontext:\n llm:\n provider: ${DEVCONTEXT_LLM_PROVIDER:mock}\n mock:\n model: ${DEVCONTEXT_MOCK_MODEL:mock-llm}\n gemini:\n api-key: ${GEMINI_API_KEY:}\n model: ${GEMINI_MODEL:gemini-2.0-flash}\n base-url: ${GEMINI_BASE_URL:https://generativelanguage.googleapis.com/v1beta}\n timeout: ${GEMINI_TIMEOUT:60s}\n deepseek:\n api-key: ${DEEPSEEK_API_KEY:}\n model: ${DEEPSEEK_MODEL:deepseek-chat}\n base-url: ${DEEPSEEK_BASE_URL:https://api.deepseek.com}\n timeout: ${DEEPSEEK_TIMEOUT:120s}\n vector:\n provider: ${DEVCONTEXT_VECTOR_PROVIDER:jdbc}\n qdrant:\n base-url: ${QDRANT_BASE_URL:http://localhost:6333}\n api-key: ${QDRANT_API_KEY:}\n distance: ${QDRANT_DISTANCE:Cosine}\n timeout: ${QDRANT_TIMEOUT:10s}\n"}, "2439bbc7de38fd9ec2383756edf6e698c9872414": {"t": 1785762415.6770327, "n": 1181, "h": "59eea19200bb613f", "c": "spring:\n config:\n import:\n - optional:file:.env[.properties]\n - optional:file:./devcontext.local.yml\n - optional:file:./config/devcontext.local.yml\n application:\n name: devcontext\n datasource:\n url: jdbc:sqlite:data/devcontext.sqlite\n driver-class-name: org.sqlite.JDBC\n sql:\n init:\n mode: always\n schema-locations: classpath:db/schema.sql\n\nserver:\n port: 18080\n\ndevcontext:\n llm:\n provider: ${DEVCONTEXT_LLM_PROVIDER:mock}\n mock:\n model: ${DEVCONTEXT_MOCK_MODEL:mock-llm}\n gemini:\n api-key: ${GEMINI_API_KEY:}\n model: ${GEMINI_MODEL:gemini-2.0-flash}\n base-url: ${GEMINI_BASE_URL:https://generativelanguage.googleapis.com/v1beta}\n timeout: ${GEMINI_TIMEOUT:60s}\n deepseek:\n api-key: ${DEEPSEEK_API_KEY:}\n model: ${DEEPSEEK_MODEL:deepseek-chat}\n base-url: ${DEEPSEEK_BASE_URL:https://api.deepseek.com}\n timeout: ${DEEPSEEK_TIMEOUT:120s}\n vector:\n provider: ${DEVCONTEXT_VECTOR_PROVIDER:jdbc}\n qdrant:\n base-url: ${QDRANT_BASE_URL:http://localhost:6333}\n api-key: ${QDRANT_API_KEY:}\n distance: ${QDRANT_DISTANCE:Cosine}\n timeout: ${QDRANT_TIMEOUT:10s}\n"}, "308e32e695394696de3dec02e3ec583df041f0e2": {"t": 1785762417.0456738, "n": 1019, "h": "d7a3fc6dd5933ba6", "c": "spring:\n config:\n import: optional:file:.env[.properties]\n application:\n name: devcontext\n datasource:\n url: jdbc:sqlite:data/devcontext.sqlite\n driver-class-name: org.sqlite.JDBC\n sql:\n init:\n mode: always\n schema-locations: classpath:db/schema.sql\n\nserver:\n port: 18080\n\ndevcontext:\n llm:\n provider: ${DEVCONTEXT_LLM_PROVIDER:mock}\n gemini:\n api-key: ${GEMINI_API_KEY:}\n model: ${GEMINI_MODEL:gemini-2.0-flash}\n base-url: ${GEMINI_BASE_URL:https://generativelanguage.googleapis.com/v1beta}\n timeout: ${GEMINI_TIMEOUT:60s}\n deepseek:\n api-key: ${DEEPSEEK_API_KEY:}\n model: ${DEEPSEEK_MODEL:deepseek-chat}\n base-url: ${DEEPSEEK_BASE_URL:https://api.deepseek.com}\n timeout: ${DEEPSEEK_TIMEOUT:120s}\n vector:\n provider: ${DEVCONTEXT_VECTOR_PROVIDER:jdbc}\n qdrant:\n base-url: ${QDRANT_BASE_URL:http://localhost:6333}\n api-key: ${QDRANT_API_KEY:}\n distance: ${QDRANT_DISTANCE:Cosine}\n timeout: ${QDRANT_TIMEOUT:10s}\n"}, "439128b6f615c7389a5d97dddd2daadedd37a27c": {"t": 1785762418.2077377, "n": 490, "h": "bca8311ef48a6257", "c": "spring:\n application:\n name: devcontext\n datasource:\n url: jdbc:sqlite:data/devcontext.sqlite\n driver-class-name: org.sqlite.JDBC\n sql:\n init:\n mode: always\n schema-locations: classpath:db/schema.sql\n\nserver:\n port: 18080\n\ndevcontext:\n llm:\n provider: ${DEVCONTEXT_LLM_PROVIDER:mock}\n gemini:\n api-key: ${GEMINI_API_KEY:}\n model: ${GEMINI_MODEL:gemini-2.0-flash}\n base-url: ${GEMINI_BASE_URL:https://generativelanguage.googleapis.com/v1beta}\n"}, "060fcbdb183a3232ca12329aa7f8d1bd07e54cbf": {"t": 1785762420.4639235, "n": 248, "h": "284787cf8b71434a", "c": "spring:\n application:\n name: devcontext\n datasource:\n url: jdbc:sqlite:data/devcontext.sqlite\n driver-class-name: org.sqlite.JDBC\n sql:\n init:\n mode: always\n schema-locations: classpath:db/schema.sql\n\nserver:\n port: 18080\n"}, "a4326c7c31e948fc045dd27946a901428a1d4f7d": {"t": 1785762422.4978607, "n": 67, "h": "e31221a207da5168", "c": "spring:\n application:\n name: devcontext\n\nserver:\n port: 18080\n"}, "aae4ae4fd8d2aac3b6ddc7780b4f9d81084a0a8b": {"t": 1785762424.8613803, "n": 67, "h": "541a88fd2a69235b", "c": "spring:\n application:\n name: devcontext\n\nserver:\n port: 8080\n\n"}}, ".github/workflows/ci.yml": {"cf4cee8e3f2d701e5325b875bf513a0d3fdf8105": {"t": 1785747034.522561, "n": 6504, "h": "ed3668c4be4cad7f", "c": "name: CI\n\non:\n pull_request:\n push:\n branches:\n - main\n\njobs:\n backend:\n name: Java backend tests\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Java\n uses: actions/setup-java@v4\n with:\n distribution: temurin\n java-version: \"21\"\n cache: maven\n\n - name: Run tests\n run: mvn test\n\n frontend:\n name: React frontend build\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Node\n uses: actions/setup-node@v4\n with:\n node-version: \"22\"\n cache: npm\n cache-dependency-path: frontend/package-lock.json\n\n - name: Install frontend dependencies\n run: npm ci --prefix frontend\n\n - name: Build frontend\n run: npm run frontend:build\n\n docs-guard:\n name: Private docs guard\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Verify private docs are not tracked\n shell: bash\n run: |\n set -euo pipefail\n blocked_paths=\"$(git ls-files -- AGENTS.md docs .ai)\"\n if [[ -n \"$blocked_paths\" ]]; then\n printf 'Private/local management docs must stay ignored, but these files are tracked:\\n%s\\n' \"$blocked_paths\"\n exit 1\n fi\n\n docker-build:\n name: Docker image build\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Build backend and frontend images\n run: docker compose build backend frontend\n\n compose-smoke:\n name: Docker Compose smoke\n runs-on: ubuntu-latest\n env:\n COMPOSE_FILE: docker-compose.smoke.yml\n COMPOSE_PROJECT_NAME: devcontext-smoke-${{ github.run_id }}\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Write smoke Compose file\n shell: bash\n run: |\n cat > docker-compose.smoke.yml <<'YAML'\n services:\n backend:\n build:\n context: .\n dockerfile: Dockerfile\n ports:\n - \"18080\"\n environment:\n SPRING_DATASOURCE_URL: jdbc:sqlite:/app/data/devcontext.sqlite\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: qdrant\n QDRANT_BASE_URL: http://qdrant:6333\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n QDRANT_API_KEY: \"\"\n volumes:\n - devcontext-data:/app/data\n - ./workspace/projects:/workspace/projects\n depends_on:\n qdrant:\n condition: service_healthy\n healthcheck:\n test: [\"CMD-SHELL\", \"curl -fsS http://localhost:18080/api/health >/dev/null\"]\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 30s\n\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n ports:\n - \"80\"\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [\"CMD-SHELL\", \"curl -fsS http://localhost/ >/dev/null\"]\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 10s\n\n qdrant:\n image: qdrant/qdrant:v1.18.1\n ports:\n - \"6333\"\n - \"6334\"\n volumes:\n - qdrant-data:/qdrant/storage\n healthcheck:\n test: >\n timeout 5 bash -ec 'exec 3<>/dev/tcp/127.0.0.1/6333;\n printf \"GET /healthz HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n\" >&3;\n grep -q \"200 OK\" <&3'\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 10s\n\n volumes:\n devcontext-data:\n qdrant-data:\n YAML\n\n - name: Clean up previous Compose stack\n run: docker compose down -v --remove-orphans\n\n - name: Start Compose stack\n run: docker compose up -d --build\n\n - name: Verify smoke endpoints\n shell: bash\n run: |\n set -euo pipefail\n backend_addr=\"$(docker compose port backend 18080 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n frontend_addr=\"$(docker compose port frontend 80 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n qdrant_addr=\"$(docker compose port qdrant 6333 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n backend_url=\"http://${backend_addr}/api/health\"\n frontend_url=\"http://${frontend_addr}\"\n qdrant_url=\"http://${qdrant_addr}/healthz\"\n echo \"Backend smoke URL: ${backend_url}\"\n echo \"Frontend smoke URL: ${frontend_url}\"\n echo \"Qdrant smoke URL: ${qdrant_url}\"\n for attempt in {1..90}; do\n if curl -fsS \"${backend_url}\" > backend-health.json \\\n && grep -Eq '\"status\"[[:space:]]*:[[:space:]]*\"UP\"' backend-health.json \\\n && grep -Eq '\"llmProvider\"[[:space:]]*:[[:space:]]*\"mock\"' backend-health.json \\\n && grep -Eq '\"llmClient\"[[:space:]]*:[[:space:]]*\"MockLlmClient\"' backend-health.json \\\n && curl -fsS \"${frontend_url}\" > frontend-home.html \\\n && curl -fsS \"${qdrant_url}\" > qdrant-health.txt; then\n cat backend-health.json\n cat qdrant-health.txt\n exit 0\n fi\n echo \"Waiting for Compose smoke endpoints, attempt ${attempt}/90...\"\n docker compose ps\n sleep 2\n done\n echo \"Compose smoke endpoints did not become ready.\"\n exit 1\n\n - name: Show Compose logs\n if: failure()\n run: docker compose logs --no-color\n\n - name: Clean up Compose stack\n if: always()\n run: docker compose down -v --remove-orphans\n"}, "57ce8c786858642894d8011f44497e048dc9160d": {"t": 1785762418.6545413, "n": 6504, "h": "ed3668c4be4cad7f", "c": "name: CI\n\non:\n pull_request:\n push:\n branches:\n - main\n\njobs:\n backend:\n name: Java backend tests\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Java\n uses: actions/setup-java@v4\n with:\n distribution: temurin\n java-version: \"21\"\n cache: maven\n\n - name: Run tests\n run: mvn test\n\n frontend:\n name: React frontend build\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Node\n uses: actions/setup-node@v4\n with:\n node-version: \"22\"\n cache: npm\n cache-dependency-path: frontend/package-lock.json\n\n - name: Install frontend dependencies\n run: npm ci --prefix frontend\n\n - name: Build frontend\n run: npm run frontend:build\n\n docs-guard:\n name: Private docs guard\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Verify private docs are not tracked\n shell: bash\n run: |\n set -euo pipefail\n blocked_paths=\"$(git ls-files -- AGENTS.md docs .ai)\"\n if [[ -n \"$blocked_paths\" ]]; then\n printf 'Private/local management docs must stay ignored, but these files are tracked:\\n%s\\n' \"$blocked_paths\"\n exit 1\n fi\n\n docker-build:\n name: Docker image build\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Build backend and frontend images\n run: docker compose build backend frontend\n\n compose-smoke:\n name: Docker Compose smoke\n runs-on: ubuntu-latest\n env:\n COMPOSE_FILE: docker-compose.smoke.yml\n COMPOSE_PROJECT_NAME: devcontext-smoke-${{ github.run_id }}\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Write smoke Compose file\n shell: bash\n run: |\n cat > docker-compose.smoke.yml <<'YAML'\n services:\n backend:\n build:\n context: .\n dockerfile: Dockerfile\n ports:\n - \"18080\"\n environment:\n SPRING_DATASOURCE_URL: jdbc:sqlite:/app/data/devcontext.sqlite\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: qdrant\n QDRANT_BASE_URL: http://qdrant:6333\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n QDRANT_API_KEY: \"\"\n volumes:\n - devcontext-data:/app/data\n - ./workspace/projects:/workspace/projects\n depends_on:\n qdrant:\n condition: service_healthy\n healthcheck:\n test: [\"CMD-SHELL\", \"curl -fsS http://localhost:18080/api/health >/dev/null\"]\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 30s\n\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n ports:\n - \"80\"\n depends_on:\n backend:\n condition: service_healthy\n healthcheck:\n test: [\"CMD-SHELL\", \"curl -fsS http://localhost/ >/dev/null\"]\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 10s\n\n qdrant:\n image: qdrant/qdrant:v1.18.1\n ports:\n - \"6333\"\n - \"6334\"\n volumes:\n - qdrant-data:/qdrant/storage\n healthcheck:\n test: >\n timeout 5 bash -ec 'exec 3<>/dev/tcp/127.0.0.1/6333;\n printf \"GET /healthz HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n\" >&3;\n grep -q \"200 OK\" <&3'\n interval: 10s\n timeout: 5s\n retries: 12\n start_period: 10s\n\n volumes:\n devcontext-data:\n qdrant-data:\n YAML\n\n - name: Clean up previous Compose stack\n run: docker compose down -v --remove-orphans\n\n - name: Start Compose stack\n run: docker compose up -d --build\n\n - name: Verify smoke endpoints\n shell: bash\n run: |\n set -euo pipefail\n backend_addr=\"$(docker compose port backend 18080 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n frontend_addr=\"$(docker compose port frontend 80 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n qdrant_addr=\"$(docker compose port qdrant 6333 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n backend_url=\"http://${backend_addr}/api/health\"\n frontend_url=\"http://${frontend_addr}\"\n qdrant_url=\"http://${qdrant_addr}/healthz\"\n echo \"Backend smoke URL: ${backend_url}\"\n echo \"Frontend smoke URL: ${frontend_url}\"\n echo \"Qdrant smoke URL: ${qdrant_url}\"\n for attempt in {1..90}; do\n if curl -fsS \"${backend_url}\" > backend-health.json \\\n && grep -Eq '\"status\"[[:space:]]*:[[:space:]]*\"UP\"' backend-health.json \\\n && grep -Eq '\"llmProvider\"[[:space:]]*:[[:space:]]*\"mock\"' backend-health.json \\\n && grep -Eq '\"llmClient\"[[:space:]]*:[[:space:]]*\"MockLlmClient\"' backend-health.json \\\n && curl -fsS \"${frontend_url}\" > frontend-home.html \\\n && curl -fsS \"${qdrant_url}\" > qdrant-health.txt; then\n cat backend-health.json\n cat qdrant-health.txt\n exit 0\n fi\n echo \"Waiting for Compose smoke endpoints, attempt ${attempt}/90...\"\n docker compose ps\n sleep 2\n done\n echo \"Compose smoke endpoints did not become ready.\"\n exit 1\n\n - name: Show Compose logs\n if: failure()\n run: docker compose logs --no-color\n\n - name: Clean up Compose stack\n if: always()\n run: docker compose down -v --remove-orphans\n"}, "95f6c01b798910e875d6d9e823d3f066ade7db4d": {"t": 1785762430.218998, "n": 5565, "h": "42cfdeea54d0d470", "c": "name: CI\n\non:\n pull_request:\n push:\n branches:\n - main\n\njobs:\n backend:\n name: Java backend tests\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Java\n uses: actions/setup-java@v4\n with:\n distribution: temurin\n java-version: \"21\"\n cache: maven\n\n - name: Run tests\n run: mvn test\n\n frontend:\n name: React frontend build\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Node\n uses: actions/setup-node@v4\n with:\n node-version: \"22\"\n cache: npm\n cache-dependency-path: frontend/package-lock.json\n\n - name: Install frontend dependencies\n run: npm ci --prefix frontend\n\n - name: Build frontend\n run: npm run frontend:build\n\n docs-guard:\n name: Private docs guard\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Verify private docs are not tracked\n shell: bash\n run: |\n set -euo pipefail\n blocked_paths=\"$(git ls-files -- AGENTS.md docs .ai)\"\n if [[ -n \"$blocked_paths\" ]]; then\n printf 'Private/local management docs must stay ignored, but these files are tracked:\\n%s\\n' \"$blocked_paths\"\n exit 1\n fi\n\n docker-build:\n name: Docker image build\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Build backend and frontend images\n run: docker compose build backend frontend\n\n compose-smoke:\n name: Docker Compose smoke\n runs-on: ubuntu-latest\n env:\n COMPOSE_FILE: docker-compose.smoke.yml\n COMPOSE_PROJECT_NAME: devcontext-smoke-${{ github.run_id }}\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Write smoke Compose file\n shell: bash\n run: |\n cat > docker-compose.smoke.yml <<'YAML'\n services:\n backend:\n build:\n context: .\n dockerfile: Dockerfile\n ports:\n - \"18080\"\n environment:\n SPRING_DATASOURCE_URL: jdbc:sqlite:/app/data/devcontext.sqlite\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: qdrant\n QDRANT_BASE_URL: http://qdrant:6333\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n QDRANT_API_KEY: \"\"\n volumes:\n - devcontext-data:/app/data\n - ./workspace/projects:/workspace/projects\n depends_on:\n - qdrant\n\n frontend:\n build:\n context: ./frontend\n dockerfile: Dockerfile\n ports:\n - \"80\"\n depends_on:\n - backend\n\n qdrant:\n image: qdrant/qdrant:latest\n ports:\n - \"6333\"\n - \"6334\"\n volumes:\n - qdrant-data:/qdrant/storage\n\n volumes:\n devcontext-data:\n qdrant-data:\n YAML\n\n - name: Clean up previous Compose stack\n run: docker compose down -v --remove-orphans\n\n - name: Start Compose stack\n run: docker compose up -d --build\n\n - name: Verify smoke endpoints\n shell: bash\n run: |\n set -euo pipefail\n backend_addr=\"$(docker compose port backend 18080 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n frontend_addr=\"$(docker compose port frontend 80 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n qdrant_addr=\"$(docker compose port qdrant 6333 | sed -e 's/^0\\.0\\.0\\.0/127.0.0.1/' -e 's/^\\[::\\]/127.0.0.1/')\"\n backend_url=\"http://${backend_addr}/api/health\"\n frontend_url=\"http://${frontend_addr}\"\n qdrant_url=\"http://${qdrant_addr}/healthz\"\n echo \"Backend smoke URL: ${backend_url}\"\n echo \"Frontend smoke URL: ${frontend_url}\"\n echo \"Qdrant smoke URL: ${qdrant_url}\"\n for attempt in {1..90}; do\n if curl -fsS \"${backend_url}\" > backend-health.json \\\n && grep -Eq '\"status\"[[:space:]]*:[[:space:]]*\"UP\"' backend-health.json \\\n && grep -Eq '\"llmProvider\"[[:space:]]*:[[:space:]]*\"mock\"' backend-health.json \\\n && grep -Eq '\"llmClient\"[[:space:]]*:[[:space:]]*\"MockLlmClient\"' backend-health.json \\\n && curl -fsS \"${frontend_url}\" > frontend-home.html \\\n && curl -fsS \"${qdrant_url}\" > qdrant-health.txt; then\n cat backend-health.json\n cat qdrant-health.txt\n exit 0\n fi\n echo \"Waiting for Compose smoke endpoints, attempt ${attempt}/90...\"\n docker compose ps\n sleep 2\n done\n echo \"Compose smoke endpoints did not become ready.\"\n exit 1\n\n - name: Show Compose logs\n if: failure()\n run: docker compose logs --no-color\n\n - name: Clean up Compose stack\n if: always()\n run: docker compose down -v --remove-orphans\n"}, "075142929905e3b6958cfb406bf646786b78a204": {"t": 1785762433.0311155, "n": 1923, "h": "a64783869a51732a", "c": "name: CI\n\non:\n pull_request:\n push:\n branches:\n - main\n\njobs:\n backend:\n name: Java backend tests\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Java\n uses: actions/setup-java@v4\n with:\n distribution: temurin\n java-version: \"21\"\n cache: maven\n\n - name: Run tests\n run: mvn test\n\n frontend:\n name: React frontend build\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Node\n uses: actions/setup-node@v4\n with:\n node-version: \"22\"\n cache: npm\n cache-dependency-path: frontend/package-lock.json\n\n - name: Install frontend dependencies\n run: npm ci --prefix frontend\n\n - name: Build frontend\n run: npm run frontend:build\n\n docs-guard:\n name: Private docs guard\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Verify private docs are not tracked\n shell: bash\n run: |\n set -euo pipefail\n blocked_paths=\"$(git ls-files -- AGENTS.md docs .ai)\"\n if [[ -n \"$blocked_paths\" ]]; then\n printf 'Private/local management docs must stay ignored, but these files are tracked:\\n%s\\n' \"$blocked_paths\"\n exit 1\n fi\n\n docker-build:\n name: Docker image build\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Build backend and frontend images\n run: docker compose build backend frontend\n"}, "5f0d4e4c79ffe14e9c624849d7185091099f9c51": {"t": 1785762435.5450885, "n": 1545, "h": "3d9d931e5b48d4a2", "c": "name: CI\n\non:\n pull_request:\n push:\n branches:\n - main\n\njobs:\n backend:\n name: Java backend tests\n runs-on: ubuntu-latest\n env:\n DEVCONTEXT_LLM_PROVIDER: mock\n DEVCONTEXT_VECTOR_PROVIDER: jdbc\n GEMINI_API_KEY: \"\"\n DEEPSEEK_API_KEY: \"\"\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Java\n uses: actions/setup-java@v4\n with:\n distribution: temurin\n java-version: \"21\"\n cache: maven\n\n - name: Run tests\n run: mvn test\n\n frontend:\n name: React frontend build\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Node\n uses: actions/setup-node@v4\n with:\n node-version: \"22\"\n cache: npm\n cache-dependency-path: frontend/package-lock.json\n\n - name: Install frontend dependencies\n run: npm ci --prefix frontend\n\n - name: Build frontend\n run: npm run frontend:build\n\n docs-guard:\n name: Private docs guard\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Verify private docs are not tracked\n shell: bash\n run: |\n set -euo pipefail\n blocked_paths=\"$(git ls-files -- AGENTS.md docs .ai)\"\n if [[ -n \"$blocked_paths\" ]]; then\n printf 'Private/local management docs must stay ignored, but these files are tracked:\\n%s\\n' \"$blocked_paths\"\n exit 1\n fi\n"}, "308e32e695394696de3dec02e3ec583df041f0e2": {"t": 1785762437.231808, "n": 384, "h": "60219d9e98638037", "c": "name: CI\n\non:\n pull_request:\n push:\n branches:\n - main\n\njobs:\n test:\n runs-on: ubuntu-latest\n\n steps:\n - name: Checkout\n uses: actions/checkout@v4\n\n - name: Set up Java\n uses: actions/setup-java@v4\n with:\n distribution: temurin\n java-version: \"21\"\n cache: maven\n\n - name: Run tests\n run: mvn test\n"}}}}