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

index.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.

index.tsBlame117 lines · 2 contributors
fc1817aClaude1import { mkdir } from "fs/promises";
2import app from "./app";
3import { config } from "./lib/config";
eafe8c6Claude4import { startWorker } from "./lib/workflow-runner";
8405c43Claude5import { startWebhookDeliveryWorker } from "./lib/webhook-delivery";
2b821b7Claude6import { startAutopilot } from "./lib/autopilot";
988380aClaude7import { ensureDemoContent } from "./lib/demo-seed";
52ad8b1Claude8import { ensureDemoActivity } from "./lib/demo-activity-seed";
2d985e5Claude9import { ensureEnvSiteAdmin } from "./lib/admin-bootstrap";
5ca514aClaude10import { ensureMarketplaceSeed } from "./lib/agent-marketplace-seed";
96942a6Test User11import { maybeSelfBootstrap } from "./lib/self-bootstrap";
f764c07Claude12import { notifySystemdReady } from "./lib/systemd-notify";
509c376Claude13import { loadConfigIntoEnv } from "./lib/system-config";
fc1817aClaude14
15// Ensure repos directory exists
16await mkdir(config.gitReposPath, { recursive: true });
17
509c376Claude18// /admin/integrations boot hook — pull saved integration secrets out of the
19// system_config table and into process.env BEFORE anything else reads them.
20// This is the magic that lets the existing synchronous config getters
21// (config.anthropicApiKey, config.resendApiKey, …) transparently pick up
22// values an admin saved through the UI, with no restart needed. If the DB
23// is unreachable at boot, env vars stay as the fallback — never blocks
24// startup.
25try {
26 const n = await loadConfigIntoEnv();
27 if (n > 0) console.log(`[system-config] loaded ${n} key(s) from DB into env`);
28} catch (err) {
29 console.warn(
30 "[system-config] boot load failed (env vars remain authoritative):",
31 err instanceof Error ? err.message : err
32 );
33}
34
96942a6Test User35// Self-bootstrap: if Gluecron's own canonical repo (`ccantynz/Gluecron.com.git`
36// by default) doesn't exist on disk yet, initialize it from the GitHub mirror
37// and install the post-receive hook. This is the platform's self-healing path
38// — once it runs successfully on a host, future deploys flow through Gluecron
39// itself with no external CI tooling. Fire-and-forget; never blocks startup.
40void maybeSelfBootstrap().catch((err) => {
41 console.warn(`[self-bootstrap] swallowed: ${(err as Error).message}`);
42});
43
eafe8c6Claude44// Start the Actions-equivalent workflow worker (Block C1). Polls
45// workflow_runs for queued rows and executes them sequentially.
46startWorker();
47
8405c43Claude48// Reliable webhook delivery worker (migration 0056). Polls
49// webhook_deliveries for pending rows whose next_attempt_at <= now() and
50// retries with exponential backoff before dead-lettering.
51startWebhookDeliveryWorker();
52
2b821b7Claude53// Autopilot: periodic mirror sync, merge-queue progress, weekly digests,
54// advisory rescans. No-op when AUTOPILOT_DISABLED=1.
55startAutopilot();
56
2d985e5Claude57// Site-admin bootstrap from env (SITE_ADMIN_USERNAME). Idempotent — if the
58// user exists, they get a row in site_admins; if not, logged and retried
59// on next boot. Background-fired so a slow DB doesn't block startup.
a28cedeClaude60void ensureEnvSiteAdmin().catch((err) => {
61 console.warn(
62 "[admin-bootstrap] ensureEnvSiteAdmin failed:",
63 err instanceof Error ? err.message : err
64 );
65});
2d985e5Claude66
5ca514aClaude67// Agent marketplace seed. Idempotent — inserts the 4 canonical example
68// listings only if they don't already exist. Background-fired with a small
69// delay so the admin-bootstrap path lands first (the seed lists the
70// publisher as the bootstrap admin).
71void (async () => {
72 try {
73 await new Promise((r) => setTimeout(r, 1500));
74 await ensureMarketplaceSeed();
75 } catch (err) {
76 console.warn(
77 "[agent-marketplace-seed] failed:",
78 err instanceof Error ? err.message : err
79 );
80 }
81})();
82
988380aClaude83// Opt-in demo content seed on boot (DEMO_SEED_ON_BOOT=1). Idempotent, never
52ad8b1Claude84// throws — safe to run on every start. Block L3 layers extra activity (more
85// issues, an open + merged PR on todo-api, AI-review comment, auto-merge
86// audit row) so the live /demo page has content out of the box.
988380aClaude87if (process.env.DEMO_SEED_ON_BOOT === "1") {
52ad8b1Claude88 void (async () => {
89 try {
90 await ensureDemoContent();
91 await ensureDemoActivity();
92 } catch {
93 /* never throw out of boot */
94 }
95 })();
988380aClaude96}
97
fc1817aClaude98console.log(`
99 gluecron v0.1.0
100 ──────────────────────
101 http://localhost:${config.port}
102 repos: ${config.gitReposPath}
103`);
104
f764c07Claude105// BLOCK N2 — tell systemd we're ready. No-op when NOTIFY_SOCKET is unset
106// (dev / non-systemd hosts). Fire-and-forget; never throws.
a28cedeClaude107void notifySystemdReady().catch((err) => {
108 console.warn(
109 "[systemd] notifySystemdReady failed:",
110 err instanceof Error ? err.message : err
111 );
112});
f764c07Claude113
fc1817aClaude114export default {
115 port: config.port,
116 fetch: app.fetch,
117};