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.tsxBlame169 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";
79136bbClaude34import webRoutes from "./routes/web";
35
36const app = new Hono();
37
3ef4c9dClaude38// Request context (request ID, start time) runs before everything else
39app.use("*", requestContext);
05b973eClaude40// Middleware — compression first (wraps all responses)
41app.use("*", compress());
42// Logger only on non-git routes to avoid overhead on clone/push
43app.use("*", async (c, next) => {
44 if (c.req.path.includes(".git/")) return next();
45 return logger()(c, next);
46});
79136bbClaude47app.use("/api/*", cors());
3ef4c9dClaude48// Rate-limit API + auth endpoints (generous default)
49app.use("/api/*", rateLimit({ windowMs: 60_000, max: 120 }));
50app.use("/login", rateLimit({ windowMs: 60_000, max: 20 }));
51app.use("/register", rateLimit({ windowMs: 60_000, max: 10 }));
79136bbClaude52
53// Git Smart HTTP protocol routes (must be before web routes)
54app.route("/", gitRoutes);
55
3ef4c9dClaude56// Health + metrics
57app.route("/", healthRoutes);
58
ad6d4adClaude59// Inbound API hooks (GateTest callback + backup PAT-authed /api/v1/gate-runs)
60app.route("/", hookRoutes);
61
79136bbClaude62// REST API
63app.route("/", apiRoutes);
64
65// Auth routes (register, login, logout)
66app.route("/", authRoutes);
67
68// Settings routes (profile, SSH keys)
69app.route("/", settingsRoutes);
70
6fc53bdClaude71// Theme toggle (dark/light cookie)
72app.route("/", themeRoutes);
73
74// Audit log UI
75app.route("/", auditRoutes);
76
77// Reactions API (issues, PRs, comments)
78app.route("/", reactionRoutes);
79
c81ab7aClaude80// API tokens
81app.route("/", tokenRoutes);
82
3ef4c9dClaude83// Notifications inbox
84app.route("/", notificationRoutes);
85
86// Dashboard (/dashboard)
87app.route("/", dashboardRoutes);
88
89// AI assistant — /ask + /:owner/:repo/ask
90app.route("/", askRoutes);
91
92// Global search
93app.route("/", searchRoutes);
94
79136bbClaude95// Repo settings (description, visibility, delete)
96app.route("/", repoSettings);
97
c81ab7aClaude98// Webhooks management
99app.route("/", webhookRoutes);
100
79136bbClaude101// Compare view (branch diffs)
102app.route("/", compareRoutes);
103
104// Issue tracker
105app.route("/", issueRoutes);
106
0074234Claude107// Pull requests
108app.route("/", pullRoutes);
109
c81ab7aClaude110// Fork
111app.route("/", forkRoutes);
112
0074234Claude113// Web file editor
114app.route("/", editorRoutes);
115
43de941Claude116// Contributors
117app.route("/", contributorRoutes);
118
3ef4c9dClaude119// Releases
120app.route("/", releaseRoutes);
121
122// Gates (history + settings + branch protection)
123app.route("/", gateRoutes);
124
125// Insights + milestones
126app.route("/", insightsRoutes);
127
c81ab7aClaude128// Explore page
129app.route("/", exploreRoutes);
130
79136bbClaude131// Web UI (catch-all, must be last)
132app.route("/", webRoutes);
133
134// Global 404
135app.notFound((c) => {
136 return c.html(
137 <Layout title="Not Found">
138 <div class="empty-state">
139 <h2>404</h2>
140 <p>Page not found.</p>
141 <a href="/" style="margin-top: 12px; display: inline-block">
142 Go home
143 </a>
144 </div>
145 </Layout>,
146 404
147 );
148});
149
150// Global error handler
151app.onError((err, c) => {
152 console.error("[error]", err);
153 return c.html(
154 <Layout title="Error">
155 <div class="empty-state">
156 <h2>Something went wrong</h2>
157 <p>An unexpected error occurred.</p>
158 {process.env.NODE_ENV !== "production" && (
159 <pre style="margin-top: 16px; text-align: left; font-size: 12px; color: var(--red)">
160 {err.message}
161 </pre>
162 )}
163 </div>
164 </Layout>,
165 500
166 );
167});
168
169export default app;