An internal Repository Q&A console that connects your codebase and produces evidence-backed answers within team-scoped permissions.
RepoQ syncs Azure DevOps or GitHub repositories and lets users ask questions against a chosen project/branch scope. The backend is a single Go server, the frontend is React/Vite, and a production deployment can embed the React build (web/dist) into the Go binary so it ships as a single executable.
One-liner: a tool for CS/TS/dev/ops teams to ask "based on which branch, with what code evidence, and why" — and to keep an auditable record of every answer.
- Why RepoQ
- Use Cases
- Core Features
- How It Works
- Project Layout
- Requirements
- Quick Start
- Initial Setup Flow
- Key Concepts
- Local Development
- Configuration
- Build & Deploy
- Docker
- Operations Checklist
- API
- Frontend / i18n Development
- Testing & Verification
- Troubleshooting
- Security Notes
- Related Docs
Asking a generic chatbot "how does this work in our code?" is fast, but in a real operations setting it leads to the following problems:
| Problem | RepoQ's approach |
|---|---|
| Unclear which repo/branch the answer is grounded in | The user explicitly picks a project and reference branch |
| Unauthorized users can see internal repo structure | Operators specify which repos/branches each team can query |
| No evidence makes answers hard to use for CS/TS responses | File path, line range, and snippet origin are stored alongside the answer |
| Tokens and code over-exposed to the LLM runtime | PATs/tokens are stored server-side and stripped from the Codex execution env |
| Hard to improve question quality over time | Question history, failures, feedback, and a satisfaction dashboard are built in |
RepoQ is not a "chatbot that anyone can use to crawl the entire company codebase." It is an internal knowledge/support console that produces answers with code evidence, strictly within the scope an operator approved.
When a customer inquiry comes in, the responder asks RepoQ in the context of the product branch.
Example questions:
- "On the
release/3.1branch, what error message is returned when login fails?" - "Explain what status value a payment-cancellation request transitions to."
- "Summarize the conditions under which this option becomes disabled, in language we can send to a customer."
Why it helps:
- You see not just the answer, but the supporting files and line ranges.
- Per-team answer guidelines keep the tone safe to forward to customers.
- Helpful / needs-improvement feedback per Q&A captures answer quality over time.
The same feature can be implemented differently across main, develop, release/*, or hotfix/*. RepoQ requires you to pick a reference branch, which makes it well suited to "what does it look like on the branch about to be released?".
Example questions:
- "On
release/4.0, what conditions enable the new auth flow?" - "Did the hotfix branch include this specific exception handling?"
- "Which file defines the default value for this setting?"
A new developer or operator can map out the system before they go spelunking through every repository.
Example questions:
- "Walk me through the admin login flow file by file."
- "In what order does the server execute steps to generate an answer?"
- "Which layer enforces the user permission check?"
RepoQ itself ships an admin console for teams, users, repositories, branches, and question history. Operators run the system through this flow:
- Save provider connection
- Sync repositories and branches
- Enable repositories for Q&A
- Assign per-team accessible branches
- Create users and assign them to teams
- Review question history and feedback
RepoQ stores every question and answer in the database, so it has stronger operational traceability than a personal chatbot.
- Who asked what
- What answer was generated
- Which sources were used
- Whether the answer failed, was blocked, or completed
- Whether the user marked it helpful
RepoQ is not appropriate for:
- Bypassing repository permissions
- Extracting secrets, tokens, or personal data
- Acting as an autonomous agent that performs large code changes
- Pipelines that exfiltrate code to external systems without approval
The server includes guard rules to block dangerous request patterns, and Codex is invoked in a read-only style execution.
- Source provider integration: sync repos and branches from Azure DevOps and GitHub
- Repository operations: enable repos for Q&A, set include/exclude paths, write per-repo retrieval guidance
- Teams & permissions: hierarchical org tree, members, and per-team accessible repos/branches
- Roles: regular users ask, admins manage the operations console
- Code Q&A: sync the chosen project/branch workspace and produce answers via the Codex CLI
- Evidence-backed answers: persist source file snippets and origins next to the answer
- History & feedback: question log, helpful / needs-improvement feedback, dashboard statistics
- Multilingual UI: Korean / English / Japanese
- Single-binary distribution:
go build -tags embedbundlesweb/distinto the binary - Local vs production split:
-dev,-insecure-cookie, secure cookies, CSRF, separate session TTL
flowchart LR
User[User / Admin Browser] -->|Cookie session + CSRF| Go[Go HTTP Server]
Go --> SQLite[(SQLite DB)]
Go --> Source[Azure DevOps / GitHub]
Go --> Workspace[.repoq-workspaces]
Workspace --> Retrieval[Snippet Retrieval]
Retrieval --> Codex[Codex CLI]
Codex --> Go
Go -->|SSE answer stream| User
Admin[Admin Console] -->|Provider token save| Go
Go -->|PAT/Token encrypted| SQLite
Question pipeline:
- The user submits a project/branch and a question.
- The server creates a
qa_runsrecord for the question. - Dangerous request patterns are blocked before invoking Codex.
- The target repositories are computed from team/branch permissions.
- Repository/branch workspaces are synced under
.repoq-workspaces/. - Relevant file snippets are selected from the local workspace.
- If evidence is thin, the Azure Code Search fallback is attempted.
- Codex CLI is invoked in a read-only style runtime to produce the answer.
- Answer, sources, status, and feedback are persisted to the database.
repoq/
├─ api/ # Go backend package
│ ├─ server.go # CLI flags/env loading, server bootstrap
│ ├─ handler*.go # HTTP routing/API/auth/security handlers
│ ├─ store*.go # SQLite/GORM store: auth, catalog, groups, runs
│ ├─ source_*_service.go # Azure/GitHub source sync and branch refresh
│ ├─ workspace.go # local workspace sync at question time
│ ├─ retrieval.go # evidence snippet retrieval
│ ├─ codex_runner.go # Codex CLI execution
│ ├─ crypto.go # AES-GCM encryption for PAT/tokens
│ └─ guard.go # dangerous-request guard rules
├─ web/ # React/Vite frontend
│ ├─ src/main.tsx # app shell / routing entrypoint
│ ├─ src/app/AppProviders.tsx # I18n/Dialog/Route/User provider composition
│ ├─ src/api.ts # API/SSE client
│ ├─ src/i18n/ # i18n provider/runtime/locales
│ ├─ src/features/ # Q&A, dashboard, admin screens
│ └─ src/styles/ # CSS tokens, layout, responsive styles
├─ main.go # root binary entrypoint (embed-aware)
├─ web_dev.go # default build: serve web/dist from disk
├─ web_embed.go # embed tag build: web/dist baked into binary
├─ Makefile
├─ Dockerfile
├─ go.mod / go.sum
└─ README.md
| Component | Recommended | Why |
|---|---|---|
| Go | 1.25+ | Backend build/run |
| Node.js | 22+ | React/Vite build |
| npm | 10.x | Lockfile-based install |
| Git | On PATH | Clone/fetch repositories |
| Codex CLI | On PATH | Generate answers |
| Azure DevOps PAT or GitHub Token | Read scopes | Read repos / branches / code |
- Azure DevOps: read access to projects/repositories/code/branches. To use the Azure Code Search fallback you also need access to the Code Search API.
- GitHub: read access to public repos for public scope, plus private repo read scope if you need private repositories.
- Tokens are stored encrypted in SQLite. Back up and protect the database and the encryption key together.
PowerShell-flavored. We pass -dev -insecure-cookie so browser login works over plain HTTP locally.
# 1) Install frontend dependencies and build
cd web
npm ci
npm run build
cd ..
# 2) Run the integrated backend + frontend server
# -dev: local convenience mode, allows admin/admin bootstrap
# -insecure-cookie: disables Secure cookie for local HTTP
# Default port :8080
go run . -addr 127.0.0.1:8080 -dev -insecure-cookieOpen in the browser:
- App: http://127.0.0.1:8080/
- Admin console: http://127.0.0.1:8080/admin
- Health: http://127.0.0.1:8080/health
Local dev bootstrap account:
- Default:
admin / admin - Never use
-dev,-insecure-cookie, oradmin/adminon a shared/production environment.
In production mode, if ADMIN_PASSWORD is empty or admin, the server prints a randomly generated admin password to stdout on first boot. Log in with it and rotate immediately.
To pick a different port, change -addr (e.g. 18080):
go run . -addr 127.0.0.1:18080 -dev -insecure-cookie
# Open: http://127.0.0.1:18080/If you also run a separate Vite dev server, set VITE_API_BASE to the backend URL (see Local Development § option 2).
On a fresh install, follow the steps below. Once you log in as admin, the empty-state screens for Q&A / dashboard / source management each show a CTA button to the next step, so you can simply follow the on-screen flow (e.g. clicking "Connect a source" from the Q&A empty state takes you to System Settings).
flowchart TD
A[Login] --> B[System Settings: Provider connection]
B --> C[Sync repositories]
C --> D[Source management: enable repos for RepoQ]
D --> E[Access control: assign team/branch permissions]
E --> F[Create users and assign teams]
F --> G[Pick project/branch in Q&A and ask]
- Login
- Sign in as the admin at
/login.
- Sign in as the admin at
- System settings
/admin→ System settings- Choose
Azure DevOpsorGitHub - Enter organization/owner and the PAT/token
- Click Save connection
- Click Sync repositories
- Source management
/admin→ Sources- Enable the repositories you want available for Q&A
- Optionally configure include/exclude paths
- Add per-repository retrieval guidance
- Access control
/admin→ Access control- Create teams and assign members
- Assign accessible repositories and branches per team
- User management
/admin→ Users- Create regular or admin users
- Ask questions
- At
/, pick a project and branch, then ask
- At
A provider is the external code host RepoQ reads source listings and files from.
Supported providers:
- Azure DevOps
- GitHub
Connection metadata lives in the azure_connections table. PATs/tokens are encrypted with REPOQ_SECRET_KEY or the .repoq.key file.
Source management decides "is this repository a Q&A candidate at all?".
- A repository with
Use in RepoQoff is excluded from the question search scope. - Enabling a repository alone does not expose it to users.
- It only appears to users once a team's access policy grants a branch on it.
Access control answers "which team can ask questions against which repositories' which branches?".
- Users can only see projects/branches their team has access to.
- Admins can see a wider scope for operational reasons.
- Repositories without a granted branch are not shown in the Q&A scope picker.
Per-team answer guidelines are operational instructions that get folded into the Codex prompt.
Example:
- Lead with a customer-facing summary
- For security/payment topics, prescribe verification steps rather than absolute statements
- Always cite the supporting file and branch
Per-repository retrieval guidance is the domain context for "how should this repository be read?".
Example:
- Code under src/legacy is for backward compatibility.
- Payment status values: check payment/domain/status.go first.
- Customer-facing messages live under i18n/messages.
The repoq_sid localStorage value in the browser is not an authentication credential.
- Purpose: groups question history under a
session_id. - Created where: in the browser client.
- Security meaning: none. Leaking it does not compromise the login session.
- Authentication is handled by the
repoq_sessionHttpOnly cookie.
Build React once, then have the Go server serve web/dist. This is the closest setup to production.
cd web
npm ci
npm run build
cd ..
go run . -addr 127.0.0.1:8080 -dev -insecure-cookieWhen you change frontend files, rebuild:
cd web
npm run build
cd ..Use this when you need frontend HMR.
Terminal A — API server:
go run . -addr 127.0.0.1:8080 -dev -insecure-cookieTerminal B — Vite dev server:
cd web
npm ci
npm run devOpen:
- Vite: http://127.0.0.1:5173/
- API: http://127.0.0.1:8080/
The proxy in web/vite.config.ts defaults to http://localhost:8080. If your API runs on another port, override via env var:
cd web
$env:VITE_API_BASE = "http://127.0.0.1:18080"
npm run devCLI flags take precedence over env vars.
| Flag | Env | Default | Description |
|---|---|---|---|
-addr |
- | :8080 |
HTTP listen address |
-dev |
- | false |
Local-dev convenience mode. Allows admin/admin bootstrap and disables Secure cookie. |
-insecure-cookie |
- | false |
Drop Secure flag from auth/csrf cookies on local HTTP |
-name |
APP_NAME |
RepoQ |
App name shown in UI/logs |
-db |
REPOQ_DB_PATH |
repoq.db |
SQLite database path |
-azdo-org |
AZDO_ORG |
empty | Seed Azure DevOps organization on boot |
-azdo-pat |
AZDO_PAT |
empty | Seed Azure DevOps PAT on boot |
-codex-model |
CODEX_MODEL |
gpt-5.5 |
Model passed to the Codex CLI |
-codex-reasoning-effort |
CODEX_REASONING_EFFORT |
xhigh |
Codex reasoning effort |
-codex-timeout |
CODEX_TIMEOUT |
2m |
Per-question Codex timeout. e.g. 120s, 2m |
-max-snippets |
REPOQ_MAX_SNIPPETS |
10 |
Max evidence snippets used per answer |
-max-context-chars |
REPOQ_MAX_CONTEXT_CHARS |
90000 |
Max evidence character count fed to Codex |
-workspace-cache-dir |
REPOQ_WORKSPACE_CACHE_DIR |
.repoq-workspaces |
Repository workspace cache path |
-workspace-max-files |
REPOQ_WORKSPACE_MAX_FILES |
800 |
Max files materialized per workspace |
-workspace-max-mb |
REPOQ_WORKSPACE_MAX_MB |
80 |
Max total workspace size in MB |
-workspace-max-file-kb |
REPOQ_WORKSPACE_MAX_FILE_KB |
512 |
Max single-file size in KB |
Additional env vars:
| Env | Default | Description |
|---|---|---|
ADMIN_USERNAME |
admin |
Admin username created when no users exist yet |
ADMIN_PASSWORD |
dev: admin, prod: random |
Admin password created when no users exist yet |
ADMIN_RESET |
empty | If 1, re-seed the bootstrap admin and invalidate existing sessions on next boot |
REPOQ_SECRET_KEY |
.repoq.key file |
AES-GCM key for PAT/token encryption. Set explicitly in production. |
REPOQ_SESSION_TTL |
12h |
Regular user session TTL |
REPOQ_MIN_PASSWORD_LENGTH |
12 |
Minimum user password length. Tighten as needed. |
REPOQ_WORKSPACE_MARKER_TTL |
5m |
Workspace freshness marker TTL |
REPOQ_SNIPPET_MAX_CHARS |
9000 |
Max characters per snippet window |
CODEX_ALLOW_OPENAI_API_KEY |
empty | If 1, allow OPENAI_API_KEY to flow into the Codex execution env |
For safety, AZDO_PAT and AZURE_DEVOPS_EXT_PAT are stripped from the Codex execution env. OPENAI_API_KEY is also stripped by default — opt in with CODEX_ALLOW_OPENAI_API_KEY=1 only when truly needed.
RepoQ encrypts provider PATs/tokens with AES-GCM at rest.
Resolution order:
REPOQ_SECRET_KEYenv var.repoq.keyfile
Production recommendation:
$env:REPOQ_SECRET_KEY = "change-this-to-a-long-random-secret-at-least-32-chars"Caveats:
- Already-encrypted PATs require the same key to decrypt.
- If you back up the DB but lose the key, you have to re-save provider connections.
- If you rely on
.repoq.key, include the key file in the same backup/protection policy as the DB.
A plain go build does not embed React. In that case the binary expects web/dist next to it at run time.
cd web
npm ci
npm run build
cd ..
go build -o repoq.exe .
.\repoq.exe -addr 127.0.0.1:8080 -dev -insecure-cookieThe embed build tag bakes web/dist into the Go binary.
cd web
npm ci
npm run build
cd ..
go test ./...
go build -tags embed -trimpath -ldflags="-s -w" -o repoq.exe .With version stamping:
$version = git rev-parse --short HEAD
go build -tags embed -trimpath -ldflags="-s -w -X repoq/api.Version=$version" -o repoq.exe .Run:
$env:REPOQ_SECRET_KEY = "change-this-to-a-long-random-secret-at-least-32-chars"
.\repoq.exe -addr :8080 -db .\data\repoq.db -workspace-cache-dir .\data\.repoq-workspacesNotes:
- Only React static files are embedded into the binary.
- The SQLite DB,
.repoq-workspaces/, and log/runtime files are written separately at runtime. - The deployment host needs
gitandcodexon PATH for question answering to work. - In production, place a TLS reverse proxy in front and avoid
-insecure-cookie.
PowerShell:
cd web
npm ci
npm run build
cd ..
$env:GOOS = "linux"
$env:GOARCH = "amd64"
go build -tags embed -trimpath -ldflags="-s -w" -o repoq-linux-amd64 .
Remove-Item Env:\GOOS
Remove-Item Env:\GOARCH| Target | Description |
|---|---|
make build |
Embed build with version from git SHA (bin/repoq) |
make test |
go test ./... |
make test-race |
go test -race ./... |
make lint |
golangci-lint run ./... |
make vet |
go vet ./... |
make tidy |
go mod tidy |
make fmt |
gofmt -s -w . |
make dev |
go run ./ -dev -insecure-cookie |
make run |
go run ./ |
make mod-why |
go mod why -m all |
The current Dockerfile assumes web/dist already exists before the build.
cd web
npm ci
npm run build
cd ..
$version = git rev-parse --short HEAD
docker build --build-arg VERSION=$version -t repoq:dev .Run:
docker volume create repoq-data
docker run --rm -p 8080:8080 `
-v repoq-data:/data `
-e REPOQ_SECRET_KEY="change-this-to-a-long-random-secret-at-least-32-chars" `
repoq:dev `
-addr :8080 `
-db /data/repoq.db `
-workspace-cache-dir /data/.repoq-workspacesImportant:
- The current runtime image is distroless and does not ship
gitorcodex. - It is fine for UI/API smoke testing, but to actually answer questions inside a container you need to extend the runtime image with
gitandcodex. - For single-host internal deployments, running the embed binary directly is currently the simplest path.
- Did you produce a fresh
web/distbuild? - Did
go test ./...andnpm testpass? - Have you removed
-devand-insecure-cookiefor production? - Is
REPOQ_SECRET_KEYset to a strong, unique value? - Are
gitandcodexreachable on the server's PATH? - Are the DB and
.repoq-workspacespaths under a managed data directory? - Is the service behind a TLS reverse proxy or internal HTTPS path?
- Did you rotate the bootstrap admin password?
| Path / value | Importance | Description |
|---|---|---|
repoq.db |
Required | Users, teams, permissions, provider connections, question history |
repoq.db-wal, repoq.db-shm |
Recommended | Back up alongside the main DB if WAL is in use |
REPOQ_SECRET_KEY or .repoq.key |
Required | Decryption key for stored PATs/tokens |
.repoq-workspaces/ |
Optional | Repository cache, can be re-synced |
| Built binary | Recommended | Reproduce the deployed version |
Stop the server first.
Get-NetTCPConnection -State Listen -LocalPort 8080 -ErrorAction SilentlyContinue |
ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }
Remove-Item -LiteralPath .\repoq.db, .\repoq.db-shm, .\repoq.db-wal -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath .\.repoq-workspaces -Recurse -Force -ErrorAction SilentlyContinueIf you lose the admin password, re-seed the bootstrap admin once with ADMIN_RESET=1:
$env:ADMIN_USERNAME = "admin"
$env:ADMIN_PASSWORD = "new-strong-password-1234"
$env:ADMIN_RESET = "1"
.\repoq.exe -addr :8080 -db .\data\repoq.db
Remove-Item Env:\ADMIN_RESETLeaving ADMIN_RESET=1 set will re-seed the admin password on every restart, so unset it after recovery.
| Path | Auth | Description |
|---|---|---|
/login |
Public | Sign in |
/ |
Logged-in | Q&A main screen |
/dashboard |
Logged-in | Satisfaction / usage dashboard |
/admin |
Admin | Operations console |
/logs |
Admin | Alias for the admin logs view |
/health |
Public | Health JSON |
Authentication is cookie based via the repoq_session HttpOnly cookie. The frontend calls the API with same-origin credentials.
Mutating requests (POST, PUT, PATCH, DELETE) require CSRF.
- CSRF cookie:
qa_csrf - CSRF header:
X-CSRF-Token
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/login |
Public | Sign in, issue session/CSRF cookies |
POST |
/logout |
Logged-in | Sign out |
GET |
/api/me |
Logged-in | Current user |
PUT |
/api/me/password |
Logged-in | Change own password |
GET |
/api/dashboard-summary |
Logged-in | Dashboard statistics |
GET |
/api/repositories/summary |
Logged-in | Summary of repositories you can ask against |
GET |
/api/question-access |
Logged-in | Visible projects/branches for the current user |
POST |
/ask |
Logged-in | SSE-based question streaming |
POST |
/api/questions |
Logged-in | Same as /ask |
PATCH |
/api/runs/{id}/feedback |
Logged-in | Submit feedback for a question |
GET |
/admin/api/connection |
Admin | Read source connection |
PUT |
/admin/api/connection |
Admin | Save source connection |
POST |
/admin/api/sync |
Admin | Sync repositories/branches |
GET |
/admin/api/projects |
Admin | List projects |
GET |
/admin/api/repositories |
Admin | List repositories |
PATCH |
/admin/api/repositories/{id} |
Admin | Toggle repository / update paths and instructions |
GET |
/admin/api/repositories/{id}/branches |
Admin | Refresh / read repository branches |
GET |
/admin/api/groups |
Admin | List teams |
POST |
/admin/api/groups |
Admin | Create a team |
PATCH |
/admin/api/groups/{id} |
Admin | Edit team info / answer instructions |
DELETE |
/admin/api/groups/{id} |
Admin | Delete a team |
PUT |
/admin/api/groups/{id}/repository-branches |
Admin | Save per-team repo/branch permissions |
GET |
/admin/api/users |
Admin | List users |
POST |
/admin/api/users |
Admin | Create a user |
PUT |
/admin/api/users/{id}/groups |
Admin | Assign user to teams |
GET |
/admin/api/runs |
Admin | Paged question history |
GET |
/admin/api/feedback-summary |
Admin | Feedback summary |
PowerShell login:
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
Invoke-RestMethod `
-Uri http://127.0.0.1:8080/login `
-Method POST `
-WebSession $session `
-ContentType "application/json" `
-Body '{"username":"admin","password":"admin"}'
Invoke-RestMethod -Uri http://127.0.0.1:8080/api/me -WebSession $sessionA CSRF-protected request:
$csrf = ($session.Cookies.GetCookies("http://127.0.0.1:8080") | Where-Object { $_.Name -eq "qa_csrf" }).Value
Invoke-RestMethod `
-Uri http://127.0.0.1:8080/logout `
-Method POST `
-WebSession $session `
-Headers @{ "X-CSRF-Token" = $csrf }Question payload shape:
{
"question": "Explain the login flow in this repository",
"session_id": "browser-generated-uuid",
"language": "en",
"project_id": 1,
"branch_name": "main"
}The response is Server-Sent Events with status, sources, text, error, and done events.
- App provider composition lives in
web/src/app/AppProviders.tsx. - The i18n provider lives in
web/src/i18n/provider.tsx. - The i18n public surface is exported from
web/src/i18n/index.ts. - Supported languages:
ko,en,ja. - The selected language is persisted in localStorage as
repoq_language. - The browser-side question session UUID is persisted in localStorage as
repoq_sid. - Translation keys are validated by
web/scripts/check-translations.cjsbeforenpm run build.
Provider composition:
<I18nProvider>
<DialogProvider>
<RouteProvider>
<UserProvider>{children}</UserProvider>
</RouteProvider>
</DialogProvider>
</I18nProvider>go test ./...
go test -race ./...
go vet ./...cd web
npm ci
npm test
npm run lint
npm run build
cd ..The Playwright config and Chromium browser are installed, and a golden-path spec exists at web/tests/e2e/login.spec.ts. It is currently gated by test.describe.skip, so to run it for real, start the backend and remove the .skip.
Terminal A — API server:
go run . -addr 127.0.0.1:8080 -dev -insecure-cookieTerminal B — Playwright:
cd web
npm run test:e2ecd web
npm ci
npm run build
cd ..
go build -tags embed -o repoq-check.exe .
.\repoq-check.exe -addr 127.0.0.1:18080 -dev -insecure-cookieHealth probe:
Invoke-RestMethod http://127.0.0.1:18080/health | ConvertTo-Json -Depth 5A healthy response returns status: ok, codex_available: true/false, source_configured: true/false, etc.
The most likely cause is Secure cookie being on while you serve over plain HTTP.
go run . -addr 127.0.0.1:8080 -dev -insecure-cookieIn production, keep Secure cookies on and run behind HTTPS.
The Go server can't read web/dist/index.html.
cd web
npm ci
npm run build
cd ..
go run . -addr 127.0.0.1:8080 -dev -insecure-cookieFor the single-binary build, use go build -tags embed.
The default proxy targets localhost:8080. If the backend runs elsewhere, set VITE_API_BASE:
$env:VITE_API_BASE = "http://127.0.0.1:18080"
npm run devThe server's PATH doesn't have codex.
Get-Command codex
codex --versionInstall/log in to the Codex CLI, then restart the server.
In the admin console, save the provider/organization/PAT and then run Sync repositories.
One of the following is missing:
- The repository is enabled
- The team has members
- The team has repository/branch permissions
Admins can see a wider scope based on enabled repos/branches.
- Re-run the repository sync.
- Confirm the per-repo branch refresh API can reach the provider with the saved token.
- For private GitHub repos, double-check the token's scope.
- Make the question more specific.
- Check that include/exclude paths aren't too restrictive.
- Delete
.repoq-workspaces/and ask again to rebuild the workspace. - For Azure DevOps, verify Code Search is available with the configured token.
REPOQ_SECRET_KEY or .repoq.key likely changed.
Fix:
- Restore the original key.
- If that's not possible, re-save the provider token from System Settings.
- The default
admin/admincredentials are for local checks only. Never keep them in production. - Do not run with
-devor-insecure-cookiein production. - PATs/tokens are stored encrypted in the DB. Protect both the DB file and the encryption key.
- Codex is invoked in a read-only style, but the analyzed workspace contains your company's code. Restrict who can reach the server.
- The server pre-blocks dangerous patterns (code dumps, secret extraction, exfiltration). You still need to run the logs and DB under your internal security policy.
OPENAI_API_KEYis stripped from the Codex execution env by default. Opt in withCODEX_ALLOW_OPENAI_API_KEY=1only when strictly necessary.- Questions, answers, and evidence snippets are persisted to the DB, so define a policy that keeps personal data and customer secrets out of the question text.
| Package | Version | Rationale |
|---|---|---|
gorm.io/gorm |
v1.31.x | SQL ORM; SQLite-focused but driver-swappable |
github.com/glebarez/sqlite |
v1.11.0 | Pure-Go SQLite driver. Windows-friendly cross-compile, no CGO |
golang.org/x/crypto |
v0.50.x | bcrypt password hashing, crypto utilities |
react / react-dom |
v19.x | UI runtime |
vite |
v7.x | Frontend build / dev server |
i18next / react-i18next |
latest lockfile | Multilingual UI provider |
We use github.com/glebarez/sqlite rather than mattn/go-sqlite3. It cross-builds Windows/Linux without CGO and is fast enough for an internal single-tenant tool. Because SQLite serializes writers, the connection pool is intentionally MaxOpenConns(1).
Local run:
cd web
npm ci
npm run build
cd ..
go run . -addr 127.0.0.1:8080 -dev -insecure-cookieSingle binary:
cd web
npm ci
npm run build
cd ..
go build -tags embed -trimpath -ldflags="-s -w" -o repoq.exe .Production launch:
$env:REPOQ_SECRET_KEY = "change-this-to-a-long-random-secret-at-least-32-chars"
.\repoq.exe -addr :8080 -db .\data\repoq.db -workspace-cache-dir .\data\.repoq-workspacesCHANGELOG.md— change logweb/CSS_ARCHITECTURE.md— CSS architecture decisions (Tailwind trigger conditions, BEM policy)
