bun dw spins up a fully isolated per-worktree dev stack: Neon DB branch, Dragonfly + ElasticMQ via docker compose, portless aliases, tmux session, and emulate.dev Google OAuth. Workers, dev server, vite, checkout, and stripe-listen run as concurrently siblings. bun setup-test auto-runs on first dw and seeds unit-test-org via clearOrg+setupOrg+ensureDefaultStripeAccount with 13 features + team invites for all 5 useautumn.com members. Hardcoded localhost URLs in test scenarios now read AUTUMN_TEST_BASE_URL/AUTUMN_TEST_VITE_URL. preload-env.ts loads .env.local so bun t/cm/setup-test route to the worktree server. 1265-line scripts/dw.ts split into scripts/dw/ module (index + commands + helpers). server/src/db/initDrizzle.ts reverted to upstream (search_path concerns solved by per-branch Neon isolation). Workers enabled in agent worktrees now that SQS is per-worktree via ElasticMQ.
92 lines
2.8 KiB
TypeScript
92 lines
2.8 KiB
TypeScript
// NOTE: For worktree-based agent flows, bun dw writes .env.local directly via
|
|
// writeEnvLocalFiles in scripts/dw.ts. This file is retained for the legacy
|
|
// agent-bootstrap.sh path only.
|
|
import { randomBytes } from "node:crypto";
|
|
import { copyFileSync, existsSync, writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
const root = join(import.meta.dir, "..", "..");
|
|
const serverEnvPath = join(root, "server", ".env");
|
|
const viteEnvPath = join(root, "vite", ".env");
|
|
const viteExamplePath = join(root, "vite", ".env.example");
|
|
|
|
const genUrlSafeBase64 = ({ bytes }: { bytes: number }): string =>
|
|
randomBytes(bytes)
|
|
.toString("base64")
|
|
.replace(/\+/g, "-")
|
|
.replace(/\//g, "_")
|
|
.replace(/=+$/g, "");
|
|
|
|
const serverPort = process.env.AGENT_SERVER_PORT ?? "8080";
|
|
const vitePort = process.env.AGENT_VITE_PORT ?? "3000";
|
|
|
|
if (existsSync(serverEnvPath)) {
|
|
console.log(
|
|
"[writeAgentEnv] server/.env already exists — skipping generation",
|
|
);
|
|
} else {
|
|
const passThrough = [
|
|
"STRIPE_SANDBOX_CLIENT_ID",
|
|
"STRIPE_SANDBOX_SECRET_KEY",
|
|
"STRIPE_SANDBOX_WEBHOOK_SECRET",
|
|
"STRIPE_LIVE_CLIENT_ID",
|
|
"STRIPE_LIVE_SECRET_KEY",
|
|
"STRIPE_LIVE_WEBHOOK_SECRET",
|
|
"ANTHROPIC_API_KEY",
|
|
"RESEND_API_KEY",
|
|
"RESEND_DOMAIN",
|
|
"SVIX_API_KEY",
|
|
"POSTHOG_API_KEY",
|
|
"POSTHOG_HOST",
|
|
] as const;
|
|
|
|
const passLines = passThrough
|
|
.map((k) => `${k}=${process.env[k] ?? ""}`)
|
|
.join("\n");
|
|
|
|
const content = `# -----------------------------------------------------------------------
|
|
# Generated by scripts/setup/writeAgentEnv.ts
|
|
# Delete this file and re-run bun dev:agent to regenerate.
|
|
# -----------------------------------------------------------------------
|
|
|
|
# Per-agent random secrets
|
|
BETTER_AUTH_SECRET=${genUrlSafeBase64({ bytes: 64 })}
|
|
ENCRYPTION_IV=${genUrlSafeBase64({ bytes: 16 })}
|
|
ENCRYPTION_PASSWORD=${genUrlSafeBase64({ bytes: 64 })}
|
|
|
|
# Local services
|
|
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/autumn
|
|
CACHE_URL=redis://localhost:6379
|
|
CACHE_URL_US_EAST=redis://localhost:6379
|
|
REDIS_URL=redis://localhost:6379
|
|
|
|
# ElasticMQ (local SQS, per-agent isolated queue)
|
|
SQS_QUEUE_URL_V2=http://localhost:9324/000000000000/autumn.fifo
|
|
AWS_REGION=us-east-1
|
|
AWS_ACCESS_KEY_ID=x
|
|
AWS_SECRET_ACCESS_KEY=x
|
|
|
|
# ClickHouse (local)
|
|
TINYBIRD_CLICKHOUSE_URL=http://localhost:8123
|
|
|
|
# App URLs
|
|
BETTER_AUTH_URL=http://localhost:${serverPort}
|
|
CLIENT_URL=http://localhost:${vitePort}
|
|
STRIPE_WEBHOOK_URL=http://localhost:${serverPort}
|
|
|
|
# Static team-wide (pass-through from process.env)
|
|
${passLines}
|
|
|
|
# Environment
|
|
NODE_ENV=development
|
|
`;
|
|
|
|
writeFileSync(serverEnvPath, content);
|
|
console.log("[writeAgentEnv] Wrote server/.env");
|
|
}
|
|
|
|
if (!existsSync(viteEnvPath) && existsSync(viteExamplePath)) {
|
|
copyFileSync(viteExamplePath, viteEnvPath);
|
|
console.log("[writeAgentEnv] Wrote vite/.env from .env.example");
|
|
}
|