Managing Zeeq

Local Development

Setting up a local development environment for Zeeq

Summary

This document describes how to get set up for local development or test driving on a local instance of Zeeq.

The primary development target is an Apple Silicon MacBook Pro. Adjust as necessary for your platform.

Key technologies

ComponentTechnology
FrontendVue 3, Nuxt UI (Tailwind CSS), Pinia, Vite
BackendC#/.NET 10, ASP.NET Core Minimal APIs, OpenIddict, EF Core + Npgsql, Testcontainers, TUnit
DatabasePostgreSQL 18, pg_vector, pg_cron, pg_partman (container is defined in build/postgres/Dockerfile)
MessagingPostgres, Google Cloud Pub/Sub

Baseline setup

ToolingDescriptionInstall from...
MiseManages local environment variables and toolingbrew install mise See Installing mise
DockerContainerization and orchestrationDocker
Install and configure mise first; that should install the other dependencies.

Once dotnet CLI is available, restore the tools:

Terminal
# Restore all tools
dotnet tool restore
If needed, install from here: https://dotnet.microsoft.com/en-us/download

Setting local secrets

The runtime requires several local secrets to execute.

These are managed using .NET local user secrets.

Terminal
cd src/backend/Zeeq.Runtime.Server

# Non-secret settings are in  appsettings.Development.json

# Initialize the secrets store
dotnet user-secrets init

# Add secrets to the store (see: src/backend/Zeeq.Runtime.Server/appsettings.Development.json)

# (✅  REQUIRED: Needed to generate embeddings for the search)
# The API key to use for generating embeddings (always needed since there is no UI for this)
dotnet user-secrets set AppSettings:Llm:Embeddings:ApiKey secret-value

# (☑️  OPTIONAL: Required or use in-app managed keys; code reviews will not work without this)
# The API key to use with the default "fast" LLM tier model.
# Not needed if using in-app configured self-managed services.
dotnet user-secrets set AppSettings:Llm:Models:Fast:ApiKey secret-value

# (☑️  OPTIONAL: Only needed for testing signed imports)
# The signing key used for importable Zeeq library export packages
dotnet user-secrets set AppSettings:Documents:LibraryExportSigningKey "$(openssl rand -base64 48 | tr -d '\n')"

# (☑️  OPTIONAL: Only needed for GH integration testing locally)
# The DEV GitHub app webhook secret (other configuration directly in file)
# This is needed to test GitHub webhook flows locally since the GH app only has one webhook URL
# Alternate: configure custom webhooks: https://github.com/zeeq-ai/zeeq-app/settings/hooks
dotnet user-secrets set AppSettings:GitHub:WebhookSecret secret-value

# (☑️  OPTIONAL: Only needed for GH integration testing locally)
# The DEV GitHub app private key PEM for local testing
dotnet user-secrets set AppSettings:GitHub:PrivateKeyPem secret-value

# (☑️  OPTIONAL: Use the mock OAuth provider without need to hook up Google or GH OAuth)
# The client secrets for OAuth providers (e.g. GitHub, Google, etc.) used for user login
# Order matches appsettings.Development.json
dotnet user-secrets set AppSettings:Auth:Providers:0:ClientSecret secret-value # Google
dotnet user-secrets set AppSettings:Auth:Providers:1:ClientSecret secret-value # GitHub

# (☑️  OPTIONAL: Use only for access to the system platform management panel)
# The account identifiers prefixed with the provider that designate system level admins
# The user will need to have an account first locally (or you already know the subject ID)
dotnet user-secrets set AppSettings:Platform:SystemAdminSubjects:0 secret-value

Starting the runtime

Zeeq runs using Aspire as the orchestration layer which launches all processes and containers.

Assuming you have mise set up properly, switching into the source directory:

Terminal
# Smoke test
dotnet --version

# Start aspire which will start the stack
aspire run --detach --non-interactive

# To stop the stack since it is detached in the background
aspire stop

The Aspire stack is now at http://localhost:15010:

The Aspire stack keeps Postgres and Pub/Sub containers as persistent lifetime so they remain running in the background. This is by design to allow faster restarts without restarting these two containers.

The application uses YARP to run on the following endpoints:

EndpointDescription
http://zeeq-web.localhost:8095The main application entrypoint
http://zeeq-docs.localhost:8095/docsThe local docs app backed by the docs-root Aspire parameter
http://zeeq-api.localhost:8095/scalarThe local Scalar UI for the API
http://zeeq-inspector.localhost:8095The local MCP inspector UI for the API
You may need to edit your hosts file.
/etc/hosts
127.0.0.1       zeeq-web.localhost
127.0.0.1       zeeq-api.localhost
127.0.0.1       zeeq-docs.localhost
127.0.0.1       zeeq-inspector.localhost

Connecting

Follow the guide in Connecting Agents but use the endpoint: http://zeeq-web.localhost:8095/mcp as the target.

Common problems

Normal development workflow

During normal development, you should not need to manually stop and start the Aspire stack.

On rebuilds:

Terminal
# Rebuild and restart the resource.
aspire resource zeeq-server --rebuild

When changes are made in the backend, the API stubs are automatically re-generated via a .NET background build process that will output the OpenAPI schema to src/web/src/api/zeeq-api.json. Kubb is used to generate the client stub from here.

Build and test

Typical operations for building and testing:

Terminal
dotnet build && dotnet test --no-restore --no-build