Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesPull RequestsActionsSecurityInsightsSettings
✨ AI
More
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.tsBlame182 lines · 2 contributors
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 },
e61e6cdccanty labs53 /**
54 * Tenant API key issued by Vapron. When set, every outbound call to
55 * Vapron carries `Authorization: Bearer <key>` — Vapron's tenant model
56 * authenticates callers by API key (the HMAC signature above remains a
57 * payload-integrity check and is sent alongside when configured).
58 */
59 get vapronApiKey() {
60 return process.env.VAPRON_API_KEY || "";
61 },
ba93444Claude62 /**
9ecf5a4Claude63 * Shared HMAC secret for the outbound deploy webhook to Vapron's
ba93444Claude64 * `POST /api/webhooks/gluecron-push` endpoint. Used to compute the
65 * `X-Gluecron-Signature: sha256=<hex>` header on every fire. Default
9ecf5a4Claude66 * empty → header is omitted and Vapron will reject with 401 (treated
ba93444Claude67 * as a failed deploy).
43cf9b0Claude68 */
69 get gluecronWebhookSecret() {
70 return process.env.GLUECRON_WEBHOOK_SECRET || "";
71 },
e883329Claude72 get anthropicApiKey() {
73 return process.env.ANTHROPIC_API_KEY || "";
74 },
24cf2caClaude75 /** Email provider: "log" (dev, writes to stderr) or "resend" (HTTPS). */
76 get emailProvider() {
77 const v = (process.env.EMAIL_PROVIDER || "log").toLowerCase();
78 return v === "resend" ? "resend" : "log";
79 },
80 /** "From" address for outbound email. */
81 get emailFrom() {
82 return process.env.EMAIL_FROM || "gluecron <no-reply@gluecron.local>";
83 },
84 /** Resend API key (only used when EMAIL_PROVIDER=resend). */
85 get resendApiKey() {
86 return process.env.RESEND_API_KEY || "";
87 },
88 /** Canonical base URL for outbound links in emails + webhooks. */
60323c5Claude89 /** SSH server port. 0 disables SSH (default 2222 in dev, 22 in prod via SSH_PORT). */
90 get sshPort() {
91 const v = process.env.SSH_PORT;
92 if (v === "0") return 0;
93 return Number(v || 2222);
94 },
95 /**
96 * PEM-encoded Ed25519 (or RSA) private key for the SSH host.
97 * If unset, an ephemeral key is generated on startup (fine for dev,
98 * but clients will see "host key changed" warnings on restart —
99 * set SSH_HOST_KEY in production).
100 *
101 * Multi-line keys in env vars: use literal newlines or \\n escapes,
102 * both are normalised in ssh-server.ts.
103 */
104 get sshHostKey() {
105 return process.env.SSH_HOST_KEY || "";
106 },
24cf2caClaude107 get appBaseUrl() {
108 return (process.env.APP_BASE_URL || "http://localhost:3000").replace(
109 /\/+$/,
110 ""
111 );
112 },
845fd8aClaude113 /**
114 * Root directory for OCI container registry blob + manifest storage.
115 * Layout:
116 * ${ociStorePath}/blobs/sha256/<hex64> — finished layer/config blobs
117 * ${ociStorePath}/manifests/<name>/<ref> — image manifests by tag or digest
118 * ${ociStorePath}/uploads/<uuid> — in-progress chunked uploads
119 */
120 get ociStorePath() {
121 return process.env.OCI_STORE_PATH || join(process.cwd(), "oci-store");
122 },
1df50d5Claude123 /**
124 * Base URL used to construct preview URLs for PR builds.
125 * When set, the preview-builder will run and serve static files; when unset,
126 * previews are URL-only (no build runs).
127 *
128 * Production: set to e.g. "https://previews.gluecron.com"
129 */
130 get previewDomain() {
131 return process.env.PREVIEW_DOMAIN || "";
132 },
2df1f8cClaude133 /**
134 * WebAuthn relying-party ID (domain only, no scheme/port). Derived from
135 * appBaseUrl unless overridden. Passkeys issued for one RP ID can't be
136 * replayed against another, so this must be stable.
137 */
138 get webauthnRpId() {
139 if (process.env.WEBAUTHN_RP_ID) return process.env.WEBAUTHN_RP_ID;
140 try {
141 return new URL(this.appBaseUrl).hostname;
142 } catch {
143 return "localhost";
144 }
145 },
146 /** WebAuthn expected origin (must include scheme + port). */
147 get webauthnOrigin() {
148 return process.env.WEBAUTHN_ORIGIN || this.appBaseUrl;
149 },
150 /** Human-facing RP name shown by the browser. */
151 get webauthnRpName() {
152 return process.env.WEBAUTHN_RP_NAME || "gluecron";
153 },
13cbd17Claude154 /**
155 * Redis / Valkey connection URL for cross-instance SSE fan-out.
156 * When set, `src/lib/sse.ts` uses Redis pub/sub so SSE events reach all
157 * server instances behind the load balancer. Falls back to in-process
158 * delivery when unset.
159 */
160 get redisUrl() {
161 return process.env.REDIS_URL || process.env.VALKEY_URL || "";
162 },
6efae38Claude163 /**
164 * AI Auto-Issue Opener (src/lib/ai-auto-issues.ts). When set to "1",
165 * every git push is scanned for TODOs, hardcoded secrets, SQL injection
166 * patterns, and debug console.log calls; matching findings automatically
167 * open issues in the repository. Off by default.
168 */
169 get aiAutoIssues() {
170 return process.env.AI_AUTO_ISSUES === "1";
171 },
da3fc18Claude172 /**
173 * Dependency CVE scanner — when set to "1", the post-receive hook fires
174 * `scanDependencies()` on every push that touches a recognized manifest
175 * file (package.json, requirements.txt, Cargo.toml, go.mod, Gemfile).
176 * Results open security issues automatically. Fire-and-forget; never
177 * blocks a push.
178 */
179 get dependencyScanEnabled() {
180 return process.env.DEPENDENCY_SCAN_ENABLED === "1";
181 },
fc1817aClaude182};