Repository navigation
Expand file tree
/
Copy path.env.example
More file actions
274 lines (223 loc) · 11.3 KB
/
Copy path.env.example
File metadata and controls
274 lines (223 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# Index monorepo — canonical environment variable reference
#
# This is the ONLY committed env file. Copy it to create your local files:
#
# cp .env.example .env.development # local development (API, drizzle, CLIs, Vite dev)
# cp .env.example .env.test # then change NODE_ENV below to test
#
# Exactly two runtime env files exist, both at the REPO ROOT and gitignored:
#
# .env.development local development (also the default when NODE_ENV is unset)
# .env.test loaded when NODE_ENV=test (API tests, protocol tests)
#
# There is deliberately no bare `.env` file and no `.env.production`:
# production configuration is platform-injected (Railway), never file-based.
#
# Who reads what:
# services/api all non-VITE_ vars below (validated at boot by src/startup.env.ts)
# apps/web only VITE_-prefixed vars (build/dev time, via Vite envDir=root)
# packages/protocol subset (DATABASE_URL, OPENROUTER_API_KEY) for tests
#
# Deployment (Railway): variables are injected by the platform — these files are
# not used. `startup.env.ts` hard-fails on invalid vars and prints warnings for
# vars commonly forgotten in deployments. Run `bun scripts/audit-railway-env.ts`
# to diff a Railway service against this reference.
#
# EVERYTHING HERE IS A CREDENTIAL, AN ENDPOINT, OR A TEST OPT-IN.
# There are no feature flags. Behaviour ships on, for everyone, in every
# environment. Two exceptions earn their place because they are values rather
# than gates: CHAT_MODEL / CHAT_REASONING_EFFORT (which model answers) and
# LOG_LEVEL (an incident lever).
#
# Convention: required-for-dev vars are uncommented with placeholder values;
# optional vars are commented out with their defaults shown.
#
# Scope legend — every section below carries a "Scope:" tag naming its consumers:
# [global] read by more than one workspace
# [api] services/api only
# [api+protocol] services/api AND packages/protocol
# [web] apps/web (Vite build/dev time)
########################################
# 1. Core
# Scope: [global] — NODE_ENV/PORT everywhere; DATABASE_URL [api];
# API_URL [api]; WEB_APP_URL [api+web]
########################################
# Postgres connection
# Neon naming caution: every Neon branch (production, dev, local-dev alike)
# hosts a `protocol` database holding a copy of real user data. The name
# marks the DATA, not the environment — it drives the fail-closed guard in
# services/api/src/lib/drizzle/test-database-readiness.ts. Never infer "this is
# production" from the database name (check the
# Neon branch/endpoint instead; the topology is in CLAUDE.md), and never
# report fork query results as production
# numbers. Tests use the empty disposable `neondb` on the same branch.
DATABASE_URL=postgresql://username:password@localhost:5432/protocol_db
# Postgres client pool size. Defaults to 40 on a deployment (Railway,
# detected via NODE_ENV=production or RAILWAY_ENVIRONMENT*) or 15 locally —
# a deployment runs one replica against Neon's pooled endpoint, which
# tolerates far more app-side connections than a raw local Postgres shared
# by several worktree processes at once. Uncomment to override either.
# DATABASE_POOL_MAX=15
# Server (PORT is also read by the apps/web preview server)
PORT=3001
NODE_ENV=development
# Deployed API origin (services/api): auth, OAuth callbacks, email links,
# webhooks. Use HTTPS in production.
# API_URL=https://protocol.dev.index.network
# Deployed web app origin (apps/web): notification links and login redirects.
# Also read by the web build for meta tags.
# WEB_APP_URL=https://index.network
########################################
# 2. Authentication
# Scope: [api]
########################################
# Better Auth (self-hosted authentication)
# Generate with: openssl rand -base64 32
BETTER_AUTH_SECRET=generate-with-openssl-rand-base64-32
# Google OAuth (leave empty to disable Google OAuth Login option)
# GOOGLE_CLIENT_ID=
# GOOGLE_CLIENT_SECRET=
# Production only: the one email allowed to sign up / sign in with a password (plugin-directory reviewers)
# REVIEWER_EMAIL=
# Login with Edge City (POST /api/auth/sign-in/edge-city { token: <EdgeOS bearer> }).
# Leave EDGEOS_TENANT_ID empty to disable. Users are auto-joined to EDGE_CITY_NETWORK_ID when set.
# EDGEOS_API_BASE=https://api.edgeos.world/api/v1
# EDGEOS_TENANT_ID=
# EDGE_CITY_NETWORK_ID=
# Index Early Birds. Index sign-in (web, Mac, Hermes) joins this network, but
# only for people who arrived on their own: anyone signing in on an invite
# landing (/l/:code) or already tied to another network stays out. Leave empty
# to skip. Edge City sign-in joins EDGE_CITY_NETWORK_ID instead.
# INDEX_EARLY_NETWORK_ID=
# Comma-separated list of browser origins allowed to make credentialed requests
# (CORS) and trusted by Better Auth. This list is the only source of that trust:
# the API never trusts a caller's own Origin header. Entries are compared exactly
# (scheme + host + port); anything that is not a valid http(s) origin is skipped
# with a warning and never widens the set.
# TRUSTED_ORIGINS=http://localhost:3000
# Comma-separated emails treated as staff (services/api/src/lib/staff.ts).
# STAFF_EMAILS=
########################################
# 3. LLM / AI (OpenRouter)
# Scope: [api+protocol]
########################################
# Get your API key from https://openrouter.ai/keys
OPENROUTER_API_KEY=your-openrouter-api-key
# Chat agent model and reasoning effort. Values, not gates: they choose which
# model answers, and every environment currently runs the two below.
# CHAT_MODEL=google/gemini-3.7-flash
# CHAT_REASONING_EFFORT=low # low | medium | high
# Local-only. Per-agent model overrides for ad-hoc experiments,
# e.g. {"opportunityPresenter":"anthropic/claude-sonnet-4"}.
# Ignored by the protocol when NODE_ENV=production; the API refuses to boot when
# it is set in a deployed environment (NODE_ENV=production or a Railway env).
# EVAL_MODEL_OVERRIDES=
########################################
# 4. Redis
# Scope: [api]
########################################
# Used for BullMQ job queues and cache. Default: localhost:6379, db 0.
# REDIS_URL= # Full URL (overrides individual settings below)
# REDIS_HOST=localhost
# REDIS_PORT=6379
# REDIS_USERNAME=
# REDIS_PASSWORD=
# REDIS_DB=0
########################################
# 5. Storage (S3-compatible)
# Scope: [api]
########################################
# Avatars, feedback images. Served via presigned URLs through /api/storage/*
# Railway buckets use https://t3.storageapi.dev as endpoint and region=auto
S3_ENDPOINT=https://t3.storageapi.dev
S3_REGION=auto
S3_BUCKET=your-bucket-name
S3_ACCESS_KEY_ID=your-access-key-id
S3_SECRET_ACCESS_KEY=your-secret-access-key
########################################
# 6. Email (Resend)
# Scope: [api]
########################################
# If not set, emails are skipped.
# RESEND_API_KEY=
# Signing secret (whsec_...) of the Resend webhook pointed at <API_URL>/api/webhooks/resend.
# Without it the endpoint answers 503 and no sends, opens or clicks are recorded.
# RESEND_WEBHOOK_SECRET=
# EMAIL_PRODUCTION_MODE=true sends to real recipients.
# When false/absent, emails redirect to TESTING_EMAIL_ADDRESS (or skip if unset).
# EMAIL_PRODUCTION_MODE=
# TESTING_EMAIL_ADDRESS=
########################################
# 7. Integrations
# Scope: [api]
########################################
# Unstructured API (document parsing). If not set, some file types are disabled.
# UNSTRUCTURED_API_URL=
# Parallels API (web crawling and profile extraction for links)
# PARALLELS_API_KEY=
# unavatar.io — resolves a user's avatar during enrichment from their
# github/twitter/telegram handle or email. Optional. Without a token the public
# endpoint is rate-limited (~25 requests/day per IP); set a publishable `pk_*`
# token to use the PRO quota. UNAVATAR_BASE overrides the endpoint for a
# self-hosted instance (default https://unavatar.io).
# UNAVATAR_TOKEN=
# UNAVATAR_BASE=https://unavatar.io
########################################
# 8. Observability
# Scope: [api]
########################################
# Sentry (error tracking, performance tracing, and release tracking)
# Backend must use the Sentry project dedicated to backend events only.
# Do not reuse this DSN for frontend, CLI, or future apps;
# create a separate Sentry project + DSN for each runtime.
# SENTRY_DSN=
# SENTRY_ENVIRONMENT=development
# SENTRY_RELEASE=index-backend@<git-sha> # Optional; inferred from Railway/GitHub commit SHA when unset.
# LangSmith tracing for LangChain/LangGraph graphs (opt-in). With a LangSmith
# API key, uncomment these settings to trace graph and worker invocations.
# This change attaches no additional user prompts, tool inputs, or outputs.
# LANGSMITH_API_KEY=
# LANGSMITH_TRACING=true
# LANGSMITH_PROJECT=index-api-development
# LANGCHAIN_CALLBACKS_BACKGROUND=true # Keep callbacks non-blocking in the long-lived API process.
# LANGSMITH_ENDPOINT= # Optional for non-US LangSmith deployments.
# LANGSMITH_WORKSPACE_ID= # Optional for multi-workspace accounts.
# Logging. An incident lever: turn it up to see more, turn it down when done.
# LOG_LEVEL=debug # verbose | debug (dev default) | info (prod default) | warn | error
########################################
# 9. Test harness (repo-root .env.test only)
# Scope: [api]
########################################
# Test commands lock NODE_ENV before loading this file. A copied .env.test must
# change the Core section's NODE_ENV=development to NODE_ENV=test (or remove it);
# conflicting values abort before database access or migration safety checks.
# Database-backed tests fail closed unless this marker is explicitly enabled.
# DATABASE_URL must point to a dedicated disposable database, never shared/prod.
# TEST_DATABASE_SAFE=1
#
# Provision that database locally with `bun run db:setup:local` (Homebrew
# postgresql@17 + pgvector, database `index_test`, migrations applied), then set
# the repo-root .env.test to:
# DATABASE_URL=postgresql://<your-unix-user>@localhost:5432/index_test
# Local Postgres is strongly preferred over a remote branch: the same four
# questioner adapter suites take ~0.6 s locally versus ~340 s against remote
# Neon, and the remote runs were intermittently stalling for minutes at a time.
# Opt into live/paid provider tests (also requires each provider credential).
# RUN_PAID_INTEGRATION_TESTS=1
# Opt into Redis integration tests. REDIS_URL is required and must identify a
# dedicated disposable Redis instance; tests never fall back to localhost.
# RUN_REDIS_INTEGRATION_TESTS=1
# Opt into E2E tests that call an already-running localhost API server.
# RUN_LOCAL_API_E2E=1
########################################
# 10. Web app
# Scope: [web] — Vite build/dev time; only VITE_-prefixed vars reach the browser
########################################
# Only VITE_-prefixed vars are exposed to the browser bundle. In local dev the
# Vite server proxies /api to the API service, so none of these are required.
# Protocol API URL (required in production builds; the build fails without it)
# VITE_PROTOCOL_URL=https://protocol.example.com
# Evaluator service URL (used by FeedbackWidget)
# VITE_EVALUATOR_URL=http://localhost:3002
# Show debug UI (DebugCopyButton) outside dev builds when set to "true"
# VITE_ENABLE_DEBUG=false