Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4b94c20
feat: implement CVE synchronization module, database schema, and enha…
chojuninengu Apr 4, 2026
13a8c80
feat: implement scan history page, enable settings navigation, and ad…
chojuninengu Apr 4, 2026
f549a1b
feat: add manual refresh and error handling to scan history UI, incre…
chojuninengu Apr 4, 2026
ccdb699
feat: implement dynamic AI model fetching and configuration in the se…
chojuninengu Apr 4, 2026
b0a5718
feat: implement document scanning integration, add configurable API U…
chojuninengu Apr 4, 2026
df0f513
feat: add Zenvra sidebar webview for scanner interface and command ma…
chojuninengu Apr 4, 2026
090bd2d
feat: add settings navigation command and update extension activation…
chojuninengu Apr 4, 2026
a754524
chore: bump version to v0.1.1-rc.2 with SSE real-time streaming
chojuninengu Apr 4, 2026
9ea9fee
feat: add success notification and active configuration badge to AI s…
chojuninengu Apr 5, 2026
fe140bf
refactor: implement shared AI configuration store and add SSE replay …
chojuninengu Apr 6, 2026
9f9ce16
feat: implement OSV sync service, add dynamic API base URL configurat…
chojuninengu Apr 6, 2026
7253d4d
style: apply consistent code formatting and cleanup across multiple c…
chojuninengu Apr 6, 2026
0c20bdc
refactor: improve error handling type safety and add keyed each block…
chojuninengu Apr 6, 2026
37b85bb
refactor: update eslint config for svelte files and improve type safe…
chojuninengu Apr 6, 2026
5acb8c7
fix: resolve lint errors, improve OSV sync, and finalize CI/CD
chojuninengu Apr 6, 2026
31932d2
fix(vscode): resolve lint errors and packaging issues
chojuninengu Apr 6, 2026
0b7c343
fix: resolve final lint errors in web and vscode
chojuninengu Apr 6, 2026
c9ecbb2
refactor: improve error handling, add JSON validation for NVD sync, u…
chojuninengu Apr 6, 2026
2f34dee
feat: implement workspace scanning with real-time SSE updates and add…
chojuninengu Apr 11, 2026
4fad9e9
chore: add env config guide and verify SAST engine end-to-end
chojuninengu Apr 16, 2026
fc003d0
fix: resolve security audit failures and update dependencies
chojuninengu Apr 16, 2026
1f73707
fix: update dependencies to resolve npm audit vulnerabilities
chojuninengu Apr 16, 2026
33d87a3
Changes before error encountered
Copilot Apr 28, 2026
dd8e5e8
feat: Phase 3 polish - live dashboard, explanation persistence, works…
Copilot Apr 28, 2026
5ca0757
refactor: extract none_if_empty helper and RESULTS_CACHE_TTL_SECS con…
Copilot Apr 28, 2026
08d77ca
Merge pull request #6 from Cameroon-Developer-Network/copilot/verify-…
chojuninengu Apr 28, 2026
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
48 changes: 44 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
pull_request:
branches: [main, develop]
push:
branches: [develop]
branches: [main, develop]

concurrency:
group: ci-${{ github.ref }}
Expand Down Expand Up @@ -114,10 +114,11 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Install cargo-audit
run: cargo install cargo-audit

- name: Rust audit
uses: rustsec/audit-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
run: cargo audit --ignore RUSTSEC-2023-0071 --ignore RUSTSEC-2026-0097

- name: Setup Node.js
uses: actions/setup-node@v4
Expand All @@ -132,3 +133,42 @@ jobs:
- name: npm audit (web)
working-directory: apps/web
run: pnpm install --frozen-lockfile && pnpm audit --audit-level=high

# ─── Deploy (Latest) ──────────────────────────────────────────────────────
deploy:
name: Deploy β€” Build & Push (Latest)
needs: [rust, web, vscode, audit]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push API (latest)
uses: docker/build-push-action@v5
with:
context: .
file: crates/server/Dockerfile
push: true
tags: ghcr.io/${{ github.repository }}-api:latest
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Build and push Web (latest)
uses: docker/build-push-action@v5
with:
context: ./apps/web
push: true
tags: ghcr.io/${{ github.repository }}-web:latest
cache-from: type=gha
cache-to: type=gha,mode=max
Comment on lines +157 to +174
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Potential :latest tag conflict with release.yml.

Both this deploy job and the docker-publish job in release.yml push :latest tags to the same image names (ghcr.io/${{ github.repository }}-api:latest and -web:latest). When a release tag is pushed to main, both workflows may run concurrently, causing race conditions on the :latest tag.

Consider one of these approaches:

  1. Use a different tag here (e.g., :main or :edge) to distinguish CI builds from releases
  2. Add a condition to skip this job when a version tag is present
  3. Remove the :latest tag push from one of the workflows
Option 1: Use distinct tag for CI builds
      - name: Build and push API (latest)
        uses: docker/build-push-action@v5
        with:
          context: .
          file: crates/server/Dockerfile
          push: true
-          tags: ghcr.io/${{ github.repository }}-api:latest
+          tags: ghcr.io/${{ github.repository }}-api:edge
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Build and push Web (latest)
        uses: docker/build-push-action@v5
        with:
          context: ./apps/web
          push: true
-          tags: ghcr.io/${{ github.repository }}-web:latest
+          tags: ghcr.io/${{ github.repository }}-web:edge
          cache-from: type=gha
          cache-to: type=gha,mode=max
πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 156 - 173, The CI workflow's Docker
steps "Build and push API (latest)" and "Build and push Web (latest)" push
:latest tags that conflict with the release.yml docker-publish job; update these
steps to avoid the race by either (A) changing the tags from ghcr.io/${{
github.repository }}-api:latest and -web:latest to a CI-specific tag like :main
or :edge, or (B) adding a condition to these jobs to skip when a Git tag event
is present (e.g., check github.ref for refs/tags), or (C) remove the push of the
:latest tag here and keep it only in release.ymlβ€”apply the chosen change to both
the API and Web docker/build-push-action steps so tags do not collide.

57 changes: 57 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v4

Expand All @@ -30,3 +31,59 @@ jobs:
generate_release_notes: true
draft: false
prerelease: ${{ contains(github.ref, '-beta') || contains(github.ref, '-alpha') }}

docker-publish:
name: Build & publish images
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (API)
id: meta-api
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}-api
tags: |
type=semver,pattern={{version}}
type=raw,value=latest,enable=${{ !contains(github.ref, '-') }}

- name: Build and push Zenvra API
uses: docker/build-push-action@v5
with:
context: .
file: crates/server/Dockerfile
push: true
tags: ${{ steps.meta-api.outputs.tags }}
labels: ${{ steps.meta-api.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Extract metadata (Web)
id: meta-web
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}-web
tags: |
type=semver,pattern={{version}}
type=raw,value=latest,enable=${{ !contains(github.ref, '-') }}

- name: Build and push Zenvra Web
uses: docker/build-push-action@v5
with:
context: ./apps/web
push: true
tags: ${{ steps.meta-web.outputs.tags }}
labels: ${{ steps.meta-web.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ node_modules
.next
out
dist
build

# VS Code extension output
extensions/vscode/out
extensions/vscode/*.vsix

# OS
.DS_Store
Expand All @@ -32,3 +34,6 @@ coverage
.idea
*.swp
*.swo
*~
*.tmp
deploy-ghcr.sh
75 changes: 75 additions & 0 deletions CONFIG_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Zenvra Configuration & Hardcoded Values

## Current State

### βœ… Already Configurable via Environment Variables

1. **Backend API URL** β€” `PUBLIC_API_URL` (default: `http://localhost:8080`)
- Used in: `apps/web/src/lib/api.ts`, `apps/web/src/lib/stores/aiConfig.svelte.ts`
- Allows pointing to different API endpoints (local dev, staging, production)

2. **AI Provider Configuration** β€” Persisted in localStorage
- **Provider**: anthropic, openai, google, custom (user-selected)
- **API Key**: User-provided via Settings UI
- **Model**: User-selected from available models for provider
- **Endpoint**: Optional, user-provided for custom providers
- Allows bring-your-own-key pattern βœ“

3. **Database URL** β€” `DATABASE_URL` in `.env` (for server)
- Allows local dev, Docker, or cloud databases

4. **CVE Data Feeds** β€” `NVD_API_KEY` in `.env`
- Synced on server startup or manual trigger

### ⚠️ Hardcoded Values to Consider

1. **Server Port** β€” `8080` (hardcoded in server)
- Suggestion: Make configurable via `PORT` env var

2. **Web Dev Port** β€” `5173` (Vite default)
- Vite automatically uses next available port if occupied

3. **Database Credentials** β€” `postgres:postgres@localhost:5433/zenvra`
- Should be parameterized in `.env`

4. **Scan Engines** β€” Hardcoded in CLI/server (sast, sca, secrets, ai_code)
- Already configurable per-request via `--disable` flag and API

5. **Severity Thresholds** β€” Default `low` in CLI
- Already configurable via `--severity` flag

### πŸ“‹ Recommended Next Steps

1. **Server** β€” Add `PORT` and `HOST` env vars
2. **Web** β€” Consider `PUBLIC_APP_NAME`, `PUBLIC_VERSION` for UI
3. **Database** β€” Already parametrized in `.env`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Fix spelling inconsistency.

The word "parametrized" is inconsistent with "parameterized" used on line 27. Use consistent spelling throughout the document.

πŸ“ Proposed fix
-3. **Database** β€” Already parametrized in `.env`
+3. **Database** β€” Already parameterized in `.env`
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
3. **Database** β€” Already parametrized in `.env`
3. **Database** β€” Already parameterized in `.env`
🧰 Tools
πŸͺ› LanguageTool

[uncategorized] ~45-~45: Do not mix variants of the same word (β€˜parametrize’ and β€˜parameterize’) within a single text.
Context: ...RSIONfor UI 3. **Database** β€” Already parametrized in.env` 4. AI Config β€” Already pe...

(EN_WORD_COHERENCY)

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CONFIG_GUIDE.md` at line 45, The spelling "parametrized" in CONFIG_GUIDE.md
(line showing "3. **Database** β€” Already parametrized in `.env`") is
inconsistent with "parameterized" used earlier; update that occurrence to
"parameterized" to match the document's preferred spelling so both instances
read "parameterized".

4. **AI Config** β€” Already per-user via localStorage + Settings UI

## How to Use Development Environment

```bash
# Terminal 1: Start PostgreSQL + Redis
docker compose up -d postgres redis

# Terminal 2: Start API Server
set -a && source .env && set +a
cargo run -p zenvra-server

# Terminal 3: Sync CVE data
cargo run -p zenvra-server -- sync

# Terminal 4: Start Web Frontend
cd apps/web
pnpm dev

# Open http://localhost:5174 in browser
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Fix port inconsistency.

Line 65 references http://localhost:5174, but line 29 states the Vite default dev port is 5173. Use the consistent port number.

πŸ“ Proposed fix
-# Open http://localhost:5174 in browser
+# Open http://localhost:5173 in browser
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Open http://localhost:5174 in browser
# Open http://localhost:5173 in browser
πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CONFIG_GUIDE.md` at line 65, Update the port in the documentation to be
consistent: replace the string "http://localhost:5174" with
"http://localhost:5173" (the Vite default port referenced earlier) so the
instruction line that currently reads http://localhost:5174 matches the port
stated on line 29.

```

## API Endpoints

- `/health` β€” Health check
- `/api/v1/scan` β€” Submit code scan (returns scan ID)
- `/api/v1/scan/:id/events` β€” Stream scan results via SSE
- `/api/v1/history` β€” Get scan history
- `/api/v1/sync` β€” Trigger manual CVE sync
- `/api/v1/ai/models` β€” Fetch available AI models for provider
Loading
Loading