Sentinel is an advanced knowledge curation platform that bypasses traditional API limitations using a browser-resident agent. It enables users to capture high-signal content (Tweets, Web Articles, Selections) directly from their browsing session, processes it using state-of-the-art LLMs, and stores it in a searchable, vector-indexed vault.
graph TD
User((User))
subgraph Browser
Content["Web Pages (X, Articles)"]
Ext["Browser Extension (Harvester)"]
end
subgraph "Web Application"
Dash["Angular Dashboard (Sentinel Vault)"]
end
subgraph "Backend (ASP.NET Core)"
API["Search & Ingestion API"]
Job["Hangfire Background Workers"]
end
subgraph "AI & Storage"
LLM["OpenAI (GPT-4o / Embeddings)"]
DB[(PostgreSQL + pgvector)]
end
User --> Ext
User --> Dash
Ext -- "Extract Content" --> Content
Ext -- "Submit Content" --> API
Dash -- "Semantic Search" --> API
API -- "Queue Jobs" --> Job
Job -- "Process & Embed" --> LLM
Job -- "Store/Retrieve" --> DB
API -- "Query" --> DB
The project consists of three main components working in concert:
- Chrome Extension: Acts as the data harvester, injecting capture tools directly into web platforms.
- .NET 10 Backend: Manages ingestion, AI-driven processing, and semantic storage.
- Angular Dashboard: A premium web portal for managing your "Personal Knowledge Vault" with semantic search and tag clouds.
- Seamless Capture: Inject "Save to Sentinel" buttons directly into web platforms (X.com, etc.).
- AI-Powered Insights: Automated de-noising, summary extraction, and actionable insight generation using OpenAI Models.
- Semantic Search: Meaning-based retrieval using vector embeddings stored in PostgreSQL.
- Premium Vault: A modern web dashboard with glassmorphism UI and real-time reactive filtering.
- Reliable Processing: Persistent background job management with Hangfire.
- Framework: .NET 10.0 (ASP.NET Core)
- Database: PostgreSQL with
pgvectorextension - Background Jobs: Hangfire (PostgreSQL storage)
- Observability: Serilog (Seq Sink), OpenTelemetry (Metrics), Health Checks
- Processing: OpenAI
gpt-4o/gpt-4o-mini - Embeddings: OpenAI
text-embedding-3-small(1536-dimensional vectors)
- Angular Dashboard: v21 (Modern Zoneless mode), Signals, SCSS, Playwright E2E.
- Browser Extension: Manifest V3, TypeScript, Chrome Storage & Scripting APIs.
- System entity model: canonical overview of the implemented entities, lifecycle states, and main data flows.
- .NET 10 SDK
- Node.js & npm
- Docker Desktop
- OpenAI API Key
From the repository root:
.\build.ps1 -Target Setup
.\build.ps1 -Target Check
.\build.ps1 -Target DevThis starts:
- Backend infrastructure only (
docker compose up -dfrombackend/, startspostgres) - Applies backend EF Core migrations against the local development database
- Backend API (
dotnet watch run --project src/SentinelKnowledgebase.Api) - Backend Worker (
dotnet watch run --project src/SentinelKnowledgebase.Worker) - Angular frontend (
npm run startinfrontend/) - Browser extension watch build (
npm run watchinbrowser-extension/)
Optional: launch Chromium with the extension loaded:
.\build.ps1 -Target Dev -LaunchExtensionBrowserUseful selective startup examples:
.\build.ps1 -Target Dev -SkipExtensionWatch
.\build.ps1 -Target Dev -SkipWorker
.\build.ps1 -Target Dev -SkipInfra
.\build.ps1 -Target DevWithProxySetup installs .NET dependencies, frontend and extension npm dependencies,
creates backend/.env from backend/.env.example when needed, prompts for
missing required secrets such as OPENAI_API_KEY, and installs Playwright
Chromium for both frontend and extension projects.
Check verifies dotnet, node, npm, and Docker availability, reports
likely port conflicts, and prints the expected local URLs for the dev stack.
Dev ensures backend/.env exists for backend startup, waits for PostgreSQL,
and runs dotnet ef database update before launching the API and worker.
DevWithProxy additionally ensures deploy/.env.proxy exists and starts the
shared proxy stack for parity with production or for other local containerized
services.
From the repository root:
.\build.ps1 -Target Setup
.\build.ps1 -Target Check
.\build.ps1 -Target Build
.\build.ps1 -Target Backend
.\build.ps1 -Target WebFrontend
.\build.ps1 -Target Extension
.\build.ps1 -Target InfraUp
.\build.ps1 -Target InfraDown
.\build.ps1 -Target DevWithProxy
.\build.ps1 -Target Clean
.\build.ps1 -Target ExtensionBrowserIf you prefer to run services manually:
-
Start infrastructure
cd backend docker compose up -dIf
backend/.envdoes not exist yet, copybackend/.env.exampletobackend/.envand fill inOPENAI_API_KEYbefore starting the stack.Optional shared proxy:
cp deploy/.env.proxy.example deploy/.env.proxy docker compose -f deploy/docker-compose.proxy.yml --env-file deploy/.env.proxy up -d
-
Run backend API
cd backend dotnet watch run --project src/SentinelKnowledgebase.Api -
Run backend worker
cd backend dotnet watch run --project src/SentinelKnowledgebase.Worker -
Run Angular dashboard
cd frontend npm install npm run start -
Build extension in watch mode
cd browser-extension npm install npm run watch
Extension default API URL is http://localhost:5000 (configurable in extension options).
cd backend
docker compose --profile app up -dThis repository now includes production deployment assets for CI/CD and multi-app hosts:
deploy/docker-compose.prod.yml(Postgres + API + Worker + Web app only)deploy/docker-compose.proxy.yml(shared autodiscovery Caddy edge, run once per host)deploy/docker-compose.litellm.yml(optional LiteLLM Vertex AI OpenAI-compatible proxy)deploy/scripts/deploy.sh(server-side rollout script)backend/Dockerfile.migrator(builds an EF Core migration bundle image from the existing migrations project)frontend/Dockerfile+frontend/Caddyfile(Angular static hosting).github/workflows/deploy.ymlandbitbucket-pipelines.yml(image build/push + SSH deploy).github/workflows/release-please.yml+ release-please config files (versioning + changelog)
For multiple apps on the same server, use one shared autodiscovery Caddy instance:
deploy/docker-compose.proxy.ymldeploy/.env.proxy.example
Bootstrap shared Caddy once:
cd <repo>
cp deploy/.env.proxy.example deploy/.env.proxy
docker compose -f deploy/docker-compose.proxy.yml --env-file deploy/.env.proxy up -dOptional: bootstrap LiteLLM:
cd <repo>
docker network create sentinel-ai || true
cp deploy/.env.litellm.example deploy/.env.litellm
docker compose -f deploy/docker-compose.litellm.yml --env-file deploy/.env.litellm up -dThis starts LiteLLM as a local OpenAI-compatible proxy backed by Vertex AI.
By default it only binds to 127.0.0.1:4000.
Releases are formalized with Release Please and Conventional Commits:
- Merge feature/fix PRs into
mainormasterusing Conventional Commit subjects. - Release Please updates or opens a release PR with:
- version bump
CHANGELOG.mdupdates generated from commit history
- Merge the release PR when ready.
- Release Please creates a Git tag like
v1.2.3. deploy.ymltriggers onv*tags, builds images tagged with the release tag, uploads deployment artifacts to the server, and deploys.
Manual deployment remains available through workflow_dispatch in deploy.yml.
The GitHub deployment workflow now builds and publishes five images:
sentinel-apisentinel-workersentinel-migratorsentinel-serverclisentinel-web
The sentinel-migrator image is not a separate source project. It is an EF Core migration bundle built from the existing backend migrations project.
Server bootstrap (one-time):
-
Clone repo on your server (example:
/opt/sentinel). -
Copy
deploy/.env.proxy.exampletodeploy/.env.proxyand start the shared Caddy stack:cd /opt/sentinel cp deploy/.env.proxy.example deploy/.env.proxy docker compose -f deploy/docker-compose.proxy.yml --env-file deploy/.env.proxy up -d -
Copy
deploy/.env.production.exampletodeploy/.env.production. -
Fill in secrets (
OPENAI_API_KEY, DB password, registry credentials) and setSENTINEL_DOMAIN. Also setAUTHENTICATION_JWT_SIGNING_KEYto a long random secret. -
Run:
cd /opt/sentinel IMAGE_TAG=latest ./deploy/scripts/deploy.sh
The production deploy script runs the stack in this order:
- Start PostgreSQL.
- Run the one-shot
migratorservice, which executes the EF Core migration bundle against PostgreSQL. - Start
api,worker, andweb.
Each CI deployment then updates IMAGE_TAG to commit SHA and re-runs the same script.
The production stack now includes a one-off admin CLI image for direct user management:
sentinel-servercli- service name:
servercli
Run it on the server with the same production env file used for deployment:
docker compose --env-file deploy/.env.production -f deploy/docker-compose.prod.yml run --rm servercli users list
docker compose --env-file deploy/.env.production -f deploy/docker-compose.prod.yml run --rm servercli users add admin@example.com --role admin
docker compose --env-file deploy/.env.production -f deploy/docker-compose.prod.yml run --rm servercli users change-password admin@example.com
docker compose --env-file deploy/.env.production -f deploy/docker-compose.prod.yml run --rm servercli users delete old-user@example.comIf --password is omitted for users add or users change-password, the CLI prompts securely.
If you want to run the same deployment flow manually from your own machine:
-
Copy
deploy/.env.remote.exampletodeploy/.env.remoteand fill SSH values. -
Verify SSH + remote prerequisites:
./deploy/scripts/remote-deploy.sh --config deploy/.env.remote --verify-only
-
Run deployment with a tag (for example a commit SHA):
./deploy/scripts/remote-deploy.sh --config deploy/.env.remote --image-tag <commit-sha>
Optional: preview remote commands without executing deploy:
./deploy/scripts/remote-deploy.sh --config deploy/.env.remote --image-tag <commit-sha> --dry-runThis uses the same server-side deploy script as the GitHub deploy flow, but the transport is different:
- SSH to server
git fetch,git checkout,git pull- execute
deploy/scripts/deploy.shremotely withIMAGE_TAG
GitHub Actions deploys differently:
- build and push images
- upload
deploy/scripts/deploy.shanddeploy/docker-compose.prod.ymlto the server - execute
deploy/scripts/deploy.shover SSH withIMAGE_TAG
- Web Dashboard:
http://localhost:4200 - OpenAPI Document:
https://localhost:5001/openapi/v1.json - Scalar API Reference:
https://localhost:5001/scalar/v1 - Hangfire Dashboard:
https://localhost:5001/hangfire(Job monitoring) - Health Checks:
https://localhost:5001/health - Seq (Logs):
http://localhost:5341(Local logging UI)