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

app.tsx

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

app.tsxBlame185 lines · 1 contributor
79136bbClaude1import { Hono } from "hono";
2import { logger } from "hono/logger";
3import { cors } from "hono/cors";
05b973eClaude4import { compress } from "hono/compress";
79136bbClaude5import { Layout } from "./views/layout";
3ef4c9dClaude6import { requestContext } from "./middleware/request-context";
7import { rateLimit } from "./middleware/rate-limit";
79136bbClaude8import gitRoutes from "./routes/git";
9import apiRoutes from "./routes/api";
10import authRoutes from "./routes/auth";
11import settingsRoutes from "./routes/settings";
7298a17Claude12import settings2faRoutes from "./routes/settings-2fa";
79136bbClaude13import issueRoutes from "./routes/issues";
14import repoSettings from "./routes/repo-settings";
15import compareRoutes from "./routes/compare";
0074234Claude16import pullRoutes from "./routes/pulls";
17import editorRoutes from "./routes/editor";
c81ab7aClaude18import forkRoutes from "./routes/fork";
19import webhookRoutes from "./routes/webhooks";
20import exploreRoutes from "./routes/explore";
21import tokenRoutes from "./routes/tokens";
43de941Claude22import contributorRoutes from "./routes/contributors";
3ef4c9dClaude23import notificationRoutes from "./routes/notifications";
24import dashboardRoutes from "./routes/dashboard";
25import askRoutes from "./routes/ask";
26import releaseRoutes from "./routes/releases";
27import gateRoutes from "./routes/gates";
28import insightsRoutes from "./routes/insights";
29import searchRoutes from "./routes/search";
30import healthRoutes from "./routes/health";
ad6d4adClaude31import hookRoutes from "./routes/hooks";
6fc53bdClaude32import themeRoutes from "./routes/theme";
33import auditRoutes from "./routes/audit";
34import reactionRoutes from "./routes/reactions";
24cf2caClaude35import savedReplyRoutes from "./routes/saved-replies";
36import deploymentRoutes from "./routes/deployments";
6563f0aClaude37import orgRoutes from "./routes/orgs";
79136bbClaude38import webRoutes from "./routes/web";
39
40const app = new Hono();
41
3ef4c9dClaude42// Request context (request ID, start time) runs before everything else
43app.use("*", requestContext);
05b973eClaude44// Middleware — compression first (wraps all responses)
45app.use("*", compress());
46// Logger only on non-git routes to avoid overhead on clone/push
47app.use("*", async (c, next) => {
48 if (c.req.path.includes(".git/")) return next();
49 return logger()(c, next);
50});
79136bbClaude51app.use("/api/*", cors());
3ef4c9dClaude52// Rate-limit API + auth endpoints (generous default)
53app.use("/api/*", rateLimit({ windowMs: 60_000, max: 120 }));
54app.use("/login", rateLimit({ windowMs: 60_000, max: 20 }));
55app.use("/register", rateLimit({ windowMs: 60_000, max: 10 }));
79136bbClaude56
57// Git Smart HTTP protocol routes (must be before web routes)
58app.route("/", gitRoutes);
59
3ef4c9dClaude60// Health + metrics
61app.route("/", healthRoutes);
62
ad6d4adClaude63// Inbound API hooks (GateTest callback + backup PAT-authed /api/v1/gate-runs)
64app.route("/", hookRoutes);
65
79136bbClaude66// REST API
67app.route("/", apiRoutes);
68
69// Auth routes (register, login, logout)
70app.route("/", authRoutes);
71
72// Settings routes (profile, SSH keys)
73app.route("/", settingsRoutes);
74
7298a17Claude75// 2FA / TOTP settings (Block B4)
76app.route("/", settings2faRoutes);
77
6fc53bdClaude78// Theme toggle (dark/light cookie)
79app.route("/", themeRoutes);
80
81// Audit log UI
82app.route("/", auditRoutes);
83
84// Reactions API (issues, PRs, comments)
85app.route("/", reactionRoutes);
86
24cf2caClaude87// Saved replies (per-user canned comment templates)
88app.route("/", savedReplyRoutes);
89
90// Environments + deployment history UI
91app.route("/", deploymentRoutes);
92
6563f0aClaude93// Organizations + teams (Block B1)
94app.route("/", orgRoutes);
95
c81ab7aClaude96// API tokens
97app.route("/", tokenRoutes);
98
3ef4c9dClaude99// Notifications inbox
100app.route("/", notificationRoutes);
101
102// Dashboard (/dashboard)
103app.route("/", dashboardRoutes);
104
105// AI assistant — /ask + /:owner/:repo/ask
106app.route("/", askRoutes);
107
108// Global search
109app.route("/", searchRoutes);
110
79136bbClaude111// Repo settings (description, visibility, delete)
112app.route("/", repoSettings);
113
c81ab7aClaude114// Webhooks management
115app.route("/", webhookRoutes);
116
79136bbClaude117// Compare view (branch diffs)
118app.route("/", compareRoutes);
119
120// Issue tracker
121app.route("/", issueRoutes);
122
0074234Claude123// Pull requests
124app.route("/", pullRoutes);
125
c81ab7aClaude126// Fork
127app.route("/", forkRoutes);
128
0074234Claude129// Web file editor
130app.route("/", editorRoutes);
131
43de941Claude132// Contributors
133app.route("/", contributorRoutes);
134
3ef4c9dClaude135// Releases
136app.route("/", releaseRoutes);
137
138// Gates (history + settings + branch protection)
139app.route("/", gateRoutes);
140
141// Insights + milestones
142app.route("/", insightsRoutes);
143
c81ab7aClaude144// Explore page
145app.route("/", exploreRoutes);
146
79136bbClaude147// Web UI (catch-all, must be last)
148app.route("/", webRoutes);
149
150// Global 404
151app.notFound((c) => {
152 return c.html(
153 <Layout title="Not Found">
154 <div class="empty-state">
155 <h2>404</h2>
156 <p>Page not found.</p>
157 <a href="/" style="margin-top: 12px; display: inline-block">
158 Go home
159 </a>
160 </div>
161 </Layout>,
162 404
163 );
164});
165
166// Global error handler
167app.onError((err, c) => {
168 console.error("[error]", err);
169 return c.html(
170 <Layout title="Error">
171 <div class="empty-state">
172 <h2>Something went wrong</h2>
173 <p>An unexpected error occurred.</p>
174 {process.env.NODE_ENV !== "production" && (
175 <pre style="margin-top: 16px; text-align: left; font-size: 12px; color: var(--red)">
176 {err.message}
177 </pre>
178 )}
179 </div>
180 </Layout>,
181 500
182 );
183});
184
185export default app;