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.tsxBlame177 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";
12import issueRoutes from "./routes/issues";
13import repoSettings from "./routes/repo-settings";
14import compareRoutes from "./routes/compare";
0074234Claude15import pullRoutes from "./routes/pulls";
16import editorRoutes from "./routes/editor";
c81ab7aClaude17import forkRoutes from "./routes/fork";
18import webhookRoutes from "./routes/webhooks";
19import exploreRoutes from "./routes/explore";
20import tokenRoutes from "./routes/tokens";
43de941Claude21import contributorRoutes from "./routes/contributors";
3ef4c9dClaude22import notificationRoutes from "./routes/notifications";
23import dashboardRoutes from "./routes/dashboard";
24import askRoutes from "./routes/ask";
25import releaseRoutes from "./routes/releases";
26import gateRoutes from "./routes/gates";
27import insightsRoutes from "./routes/insights";
28import searchRoutes from "./routes/search";
29import healthRoutes from "./routes/health";
ad6d4adClaude30import hookRoutes from "./routes/hooks";
6fc53bdClaude31import themeRoutes from "./routes/theme";
32import auditRoutes from "./routes/audit";
33import reactionRoutes from "./routes/reactions";
24cf2caClaude34import savedReplyRoutes from "./routes/saved-replies";
35import deploymentRoutes from "./routes/deployments";
79136bbClaude36import webRoutes from "./routes/web";
37
38const app = new Hono();
39
3ef4c9dClaude40// Request context (request ID, start time) runs before everything else
41app.use("*", requestContext);
05b973eClaude42// Middleware — compression first (wraps all responses)
43app.use("*", compress());
44// Logger only on non-git routes to avoid overhead on clone/push
45app.use("*", async (c, next) => {
46 if (c.req.path.includes(".git/")) return next();
47 return logger()(c, next);
48});
79136bbClaude49app.use("/api/*", cors());
3ef4c9dClaude50// Rate-limit API + auth endpoints (generous default)
51app.use("/api/*", rateLimit({ windowMs: 60_000, max: 120 }));
52app.use("/login", rateLimit({ windowMs: 60_000, max: 20 }));
53app.use("/register", rateLimit({ windowMs: 60_000, max: 10 }));
79136bbClaude54
55// Git Smart HTTP protocol routes (must be before web routes)
56app.route("/", gitRoutes);
57
3ef4c9dClaude58// Health + metrics
59app.route("/", healthRoutes);
60
ad6d4adClaude61// Inbound API hooks (GateTest callback + backup PAT-authed /api/v1/gate-runs)
62app.route("/", hookRoutes);
63
79136bbClaude64// REST API
65app.route("/", apiRoutes);
66
67// Auth routes (register, login, logout)
68app.route("/", authRoutes);
69
70// Settings routes (profile, SSH keys)
71app.route("/", settingsRoutes);
72
6fc53bdClaude73// Theme toggle (dark/light cookie)
74app.route("/", themeRoutes);
75
76// Audit log UI
77app.route("/", auditRoutes);
78
79// Reactions API (issues, PRs, comments)
80app.route("/", reactionRoutes);
81
24cf2caClaude82// Saved replies (per-user canned comment templates)
83app.route("/", savedReplyRoutes);
84
85// Environments + deployment history UI
86app.route("/", deploymentRoutes);
87
c81ab7aClaude88// API tokens
89app.route("/", tokenRoutes);
90
3ef4c9dClaude91// Notifications inbox
92app.route("/", notificationRoutes);
93
94// Dashboard (/dashboard)
95app.route("/", dashboardRoutes);
96
97// AI assistant — /ask + /:owner/:repo/ask
98app.route("/", askRoutes);
99
100// Global search
101app.route("/", searchRoutes);
102
79136bbClaude103// Repo settings (description, visibility, delete)
104app.route("/", repoSettings);
105
c81ab7aClaude106// Webhooks management
107app.route("/", webhookRoutes);
108
79136bbClaude109// Compare view (branch diffs)
110app.route("/", compareRoutes);
111
112// Issue tracker
113app.route("/", issueRoutes);
114
0074234Claude115// Pull requests
116app.route("/", pullRoutes);
117
c81ab7aClaude118// Fork
119app.route("/", forkRoutes);
120
0074234Claude121// Web file editor
122app.route("/", editorRoutes);
123
43de941Claude124// Contributors
125app.route("/", contributorRoutes);
126
3ef4c9dClaude127// Releases
128app.route("/", releaseRoutes);
129
130// Gates (history + settings + branch protection)
131app.route("/", gateRoutes);
132
133// Insights + milestones
134app.route("/", insightsRoutes);
135
c81ab7aClaude136// Explore page
137app.route("/", exploreRoutes);
138
79136bbClaude139// Web UI (catch-all, must be last)
140app.route("/", webRoutes);
141
142// Global 404
143app.notFound((c) => {
144 return c.html(
145 <Layout title="Not Found">
146 <div class="empty-state">
147 <h2>404</h2>
148 <p>Page not found.</p>
149 <a href="/" style="margin-top: 12px; display: inline-block">
150 Go home
151 </a>
152 </div>
153 </Layout>,
154 404
155 );
156});
157
158// Global error handler
159app.onError((err, c) => {
160 console.error("[error]", err);
161 return c.html(
162 <Layout title="Error">
163 <div class="empty-state">
164 <h2>Something went wrong</h2>
165 <p>An unexpected error occurred.</p>
166 {process.env.NODE_ENV !== "production" && (
167 <pre style="margin-top: 16px; text-align: left; font-size: 12px; color: var(--red)">
168 {err.message}
169 </pre>
170 )}
171 </div>
172 </Layout>,
173 500
174 );
175});
176
177export default app;