Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

config.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

config.tsBlame173 lines · 1 contributor
fc1817aClaude1import { join } from "path";
2
3export const config = {
4 get port() {
5 return Number(process.env.PORT || 3000);
6 },
7 get databaseUrl() {
8 return process.env.DATABASE_URL || "";
9 },
10 get gitReposPath() {
11 return process.env.GIT_REPOS_PATH || join(process.cwd(), "repos");
12 },
13 get gatetestUrl() {
a4e1564Claude14 return process.env.GATETEST_URL || "https://gatetest.ai/api/events/push";
fc1817aClaude15 },
e883329Claude16 get gatetestApiKey() {
17 return process.env.GATETEST_API_KEY || "";
18 },
9ecf5a4Claude19 get vapronDeployUrl() {
fc1817aClaude20 return (
9ecf5a4Claude21 process.env.VAPRON_DEPLOY_URL ||
22 process.env.CRONTECH_DEPLOY_URL || // legacy name (pre-rename)
23 "https://vapron.ai/api/webhooks/gluecron-push"
fc1817aClaude24 );
25 },
43cf9b0Claude26 /**
9ecf5a4Claude27 * BLK-016 — only fire the Vapron deploy webhook for pushes to this
ba93444Claude28 * `<owner>/<name>`. Every other repo's push is ignored. Override per
9ecf5a4Claude29 * environment via `VAPRON_REPO` (legacy `CRONTECH_REPO` still honored).
ba93444Claude30 */
9ecf5a4Claude31 get vapronRepo() {
32 return (
33 process.env.VAPRON_REPO ||
34 process.env.CRONTECH_REPO || // legacy name (pre-rename)
35 "ccantynz-alt/vapron"
36 );
37 },
38 /**
39 * HMAC secret for signing the outbound Vapron deploy webhook
40 * (`X-Gluecron-Signature: sha256=<hex>`). Resolution order: the
41 * VAPRON_HMAC_SECRET set on /admin/integrations (or env), the legacy
42 * CRONTECH_HMAC_SECRET, then GLUECRON_WEBHOOK_SECRET (the original
43 * env-only name the signer used before the admin field existed).
44 */
45 get vapronHmacSecret() {
46 return (
47 process.env.VAPRON_HMAC_SECRET ||
48 process.env.CRONTECH_HMAC_SECRET ||
49 process.env.GLUECRON_WEBHOOK_SECRET ||
50 ""
51 );
ba93444Claude52 },
53 /**
9ecf5a4Claude54 * Shared HMAC secret for the outbound deploy webhook to Vapron's
ba93444Claude55 * `POST /api/webhooks/gluecron-push` endpoint. Used to compute the
56 * `X-Gluecron-Signature: sha256=<hex>` header on every fire. Default
9ecf5a4Claude57 * empty → header is omitted and Vapron will reject with 401 (treated
ba93444Claude58 * as a failed deploy).
43cf9b0Claude59 */
60 get gluecronWebhookSecret() {
61 return process.env.GLUECRON_WEBHOOK_SECRET || "";
62 },
e883329Claude63 get anthropicApiKey() {
64 return process.env.ANTHROPIC_API_KEY || "";
65 },
24cf2caClaude66 /** Email provider: "log" (dev, writes to stderr) or "resend" (HTTPS). */
67 get emailProvider() {
68 const v = (process.env.EMAIL_PROVIDER || "log").toLowerCase();
69 return v === "resend" ? "resend" : "log";
70 },
71 /** "From" address for outbound email. */
72 get emailFrom() {
73 return process.env.EMAIL_FROM || "gluecron <no-reply@gluecron.local>";
74 },
75 /** Resend API key (only used when EMAIL_PROVIDER=resend). */
76 get resendApiKey() {
77 return process.env.RESEND_API_KEY || "";
78 },
79 /** Canonical base URL for outbound links in emails + webhooks. */
60323c5Claude80 /** SSH server port. 0 disables SSH (default 2222 in dev, 22 in prod via SSH_PORT). */
81 get sshPort() {
82 const v = process.env.SSH_PORT;
83 if (v === "0") return 0;
84 return Number(v || 2222);
85 },
86 /**
87 * PEM-encoded Ed25519 (or RSA) private key for the SSH host.
88 * If unset, an ephemeral key is generated on startup (fine for dev,
89 * but clients will see "host key changed" warnings on restart —
90 * set SSH_HOST_KEY in production).
91 *
92 * Multi-line keys in env vars: use literal newlines or \\n escapes,
93 * both are normalised in ssh-server.ts.
94 */
95 get sshHostKey() {
96 return process.env.SSH_HOST_KEY || "";
97 },
24cf2caClaude98 get appBaseUrl() {
99 return (process.env.APP_BASE_URL || "http://localhost:3000").replace(
100 /\/+$/,
101 ""
102 );
103 },
845fd8aClaude104 /**
105 * Root directory for OCI container registry blob + manifest storage.
106 * Layout:
107 * ${ociStorePath}/blobs/sha256/<hex64> — finished layer/config blobs
108 * ${ociStorePath}/manifests/<name>/<ref> — image manifests by tag or digest
109 * ${ociStorePath}/uploads/<uuid> — in-progress chunked uploads
110 */
111 get ociStorePath() {
112 return process.env.OCI_STORE_PATH || join(process.cwd(), "oci-store");
113 },
1df50d5Claude114 /**
115 * Base URL used to construct preview URLs for PR builds.
116 * When set, the preview-builder will run and serve static files; when unset,
117 * previews are URL-only (no build runs).
118 *
119 * Production: set to e.g. "https://previews.gluecron.com"
120 */
121 get previewDomain() {
122 return process.env.PREVIEW_DOMAIN || "";
123 },
2df1f8cClaude124 /**
125 * WebAuthn relying-party ID (domain only, no scheme/port). Derived from
126 * appBaseUrl unless overridden. Passkeys issued for one RP ID can't be
127 * replayed against another, so this must be stable.
128 */
129 get webauthnRpId() {
130 if (process.env.WEBAUTHN_RP_ID) return process.env.WEBAUTHN_RP_ID;
131 try {
132 return new URL(this.appBaseUrl).hostname;
133 } catch {
134 return "localhost";
135 }
136 },
137 /** WebAuthn expected origin (must include scheme + port). */
138 get webauthnOrigin() {
139 return process.env.WEBAUTHN_ORIGIN || this.appBaseUrl;
140 },
141 /** Human-facing RP name shown by the browser. */
142 get webauthnRpName() {
143 return process.env.WEBAUTHN_RP_NAME || "gluecron";
144 },
13cbd17Claude145 /**
146 * Redis / Valkey connection URL for cross-instance SSE fan-out.
147 * When set, `src/lib/sse.ts` uses Redis pub/sub so SSE events reach all
148 * server instances behind the load balancer. Falls back to in-process
149 * delivery when unset.
150 */
151 get redisUrl() {
152 return process.env.REDIS_URL || process.env.VALKEY_URL || "";
153 },
6efae38Claude154 /**
155 * AI Auto-Issue Opener (src/lib/ai-auto-issues.ts). When set to "1",
156 * every git push is scanned for TODOs, hardcoded secrets, SQL injection
157 * patterns, and debug console.log calls; matching findings automatically
158 * open issues in the repository. Off by default.
159 */
160 get aiAutoIssues() {
161 return process.env.AI_AUTO_ISSUES === "1";
162 },
da3fc18Claude163 /**
164 * Dependency CVE scanner — when set to "1", the post-receive hook fires
165 * `scanDependencies()` on every push that touches a recognized manifest
166 * file (package.json, requirements.txt, Cargo.toml, go.mod, Gemfile).
167 * Results open security issues automatically. Fire-and-forget; never
168 * blocks a push.
169 */
170 get dependencyScanEnabled() {
171 return process.env.DEPENDENCY_SCAN_ENABLED === "1";
172 },
fc1817aClaude173};