Consolidate env at repo root

- Move all application env vars to repository-root .env (with .env.example
  as the committed template) and drop the per-app .env.example files.
- Add @code/env subpaths (agent, convex) and consume validated exports
  everywhere instead of reading process.env directly.
- Wire every dev/build/start script to load ../../.env via bun --env-file
  and point vite.config.ts envDir at the repo root.
This commit is contained in:
-Puter
2026-07-19 17:29:11 +05:30
parent 87ddc2b73a
commit 6de7c3065e
15 changed files with 100 additions and 40 deletions

View File

@@ -4,13 +4,14 @@
"private": true,
"type": "module",
"exports": {
"./web": "./src/web.ts",
"./agent": "./src/agent.ts",
"./convex": "./src/convex.ts",
"./native": "./src/native.ts",
"./server": "./src/server.ts"
"./server": "./src/server.ts",
"./web": "./src/web.ts"
},
"dependencies": {
"@t3-oss/env-core": "^0.13.11",
"dotenv": "catalog:",
"zod": "catalog:"
},
"devDependencies": {

17
packages/env/src/agent.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
import { z } from "zod";
const agentEnvSchema = z.object({
AGENT_MODEL_API: z.literal("openai-completions"),
AGENT_MODEL_API_KEY: z.string().min(1),
AGENT_MODEL_BASE_URL: z.url(),
AGENT_MODEL_CONTEXT_WINDOW: z.coerce.number().int().positive(),
AGENT_MODEL_MAX_TOKENS: z.coerce.number().int().positive(),
AGENT_MODEL_NAME: z.string().min(1),
AGENT_MODEL_PROVIDER: z.string().min(1),
});
export type AgentEnv = z.infer<typeof agentEnvSchema>;
export const parseAgentEnv = (
runtimeEnv: Record<string, string | undefined>
): AgentEnv => agentEnvSchema.parse(runtimeEnv);

13
packages/env/src/convex.ts vendored Normal file
View File

@@ -0,0 +1,13 @@
import { createEnv } from "@t3-oss/env-core";
import { z } from "zod";
export const env = createEnv({
emptyStringAsUndefined: true,
runtimeEnv: process.env,
server: {
CONVEX_SITE_URL: z.url(),
FLUE_DB_TOKEN: z.string().min(1),
NATIVE_APP_URL: z.string().min(1).default("code://"),
SITE_URL: z.url(),
},
});

View File

@@ -14,6 +14,7 @@ export const env = createEnv({
DAEMON_VERSION: z.string().default("0.0.0"),
DAEMON_HEARTBEAT_MS: z.coerce.number().int().positive().default(15_000),
DAEMON_COMMAND_LEASE_MS: z.coerce.number().int().positive().default(60_000),
FLUE_DB_TOKEN: z.string().min(1),
RIVET_ENDPOINT: z.url().optional(),
},
runtimeEnv: process.env,

9
packages/env/src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1,9 @@
interface ImportMetaEnv {
readonly [key: string]: string | number | boolean | undefined;
readonly VITE_CONVEX_SITE_URL: string;
readonly VITE_CONVEX_URL: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

View File

@@ -7,12 +7,11 @@ const convexUrlSchema = (exampleHost: string) =>
});
export const env = createEnv({
clientPrefix: "VITE_",
client: {
VITE_CONVEX_URL: convexUrlSchema("example.convex.cloud"),
VITE_CONVEX_SITE_URL: convexUrlSchema("example.convex.site"),
VITE_CONVEX_URL: convexUrlSchema("example.convex.cloud"),
},
runtimeEnv: (import.meta as any).env,
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
clientPrefix: "VITE_",
emptyStringAsUndefined: true,
runtimeEnv: import.meta.env,
});