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.tsxBlame181 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";
6563f0aClaude36import orgRoutes from "./routes/orgs";
79136bbClaude37import webRoutes from "./routes/web";
38
39const app = new Hono();
40
3ef4c9dClaude41// Request context (request ID, start time) runs before everything else
42app.use("*", requestContext);
05b973eClaude43// Middleware — compression first (wraps all responses)
44app.use("*", compress());
45// Logger only on non-git routes to avoid overhead on clone/push
46app.use("*", async (c, next) => {
47 if (c.req.path.includes(".git/")) return next();
48 return logger()(c, next);
49});
79136bbClaude50app.use("/api/*", cors());
3ef4c9dClaude51// Rate-limit API + auth endpoints (generous default)
52app.use("/api/*", rateLimit({ windowMs: 60_000, max: 120 }));
53app.use("/login", rateLimit({ windowMs: 60_000, max: 20 }));
54app.use("/register", rateLimit({ windowMs: 60_000, max: 10 }));
79136bbClaude55
56// Git Smart HTTP protocol routes (must be before web routes)
57app.route("/", gitRoutes);
58
3ef4c9dClaude59// Health + metrics
60app.route("/", healthRoutes);
61
ad6d4adClaude62// Inbound API hooks (GateTest callback + backup PAT-authed /api/v1/gate-runs)
63app.route("/", hookRoutes);
64
79136bbClaude65// REST API
66app.route("/", apiRoutes);
67
68// Auth routes (register, login, logout)
69app.route("/", authRoutes);
70
71// Settings routes (profile, SSH keys)
72app.route("/", settingsRoutes);
73
6fc53bdClaude74// Theme toggle (dark/light cookie)
75app.route("/", themeRoutes);
76
77// Audit log UI
78app.route("/", auditRoutes);
79
80// Reactions API (issues, PRs, comments)
81app.route("/", reactionRoutes);
82
24cf2caClaude83// Saved replies (per-user canned comment templates)
84app.route("/", savedReplyRoutes);
85
86// Environments + deployment history UI
87app.route("/", deploymentRoutes);
88
6563f0aClaude89// Organizations + teams (Block B1)
90app.route("/", orgRoutes);
91
c81ab7aClaude92// API tokens
93app.route("/", tokenRoutes);
94
3ef4c9dClaude95// Notifications inbox
96app.route("/", notificationRoutes);
97
98// Dashboard (/dashboard)
99app.route("/", dashboardRoutes);
100
101// AI assistant — /ask + /:owner/:repo/ask
102app.route("/", askRoutes);
103
104// Global search
105app.route("/", searchRoutes);
106
79136bbClaude107// Repo settings (description, visibility, delete)
108app.route("/", repoSettings);
109
c81ab7aClaude110// Webhooks management
111app.route("/", webhookRoutes);
112
79136bbClaude113// Compare view (branch diffs)
114app.route("/", compareRoutes);
115
116// Issue tracker
117app.route("/", issueRoutes);
118
0074234Claude119// Pull requests
120app.route("/", pullRoutes);
121
c81ab7aClaude122// Fork
123app.route("/", forkRoutes);
124
0074234Claude125// Web file editor
126app.route("/", editorRoutes);
127
43de941Claude128// Contributors
129app.route("/", contributorRoutes);
130
3ef4c9dClaude131// Releases
132app.route("/", releaseRoutes);
133
134// Gates (history + settings + branch protection)
135app.route("/", gateRoutes);
136
137// Insights + milestones
138app.route("/", insightsRoutes);
139
c81ab7aClaude140// Explore page
141app.route("/", exploreRoutes);
142
79136bbClaude143// Web UI (catch-all, must be last)
144app.route("/", webRoutes);
145
146// Global 404
147app.notFound((c) => {
148 return c.html(
149 <Layout title="Not Found">
150 <div class="empty-state">
151 <h2>404</h2>
152 <p>Page not found.</p>
153 <a href="/" style="margin-top: 12px; display: inline-block">
154 Go home
155 </a>
156 </div>
157 </Layout>,
158 404
159 );
160});
161
162// Global error handler
163app.onError((err, c) => {
164 console.error("[error]", err);
165 return c.html(
166 <Layout title="Error">
167 <div class="empty-state">
168 <h2>Something went wrong</h2>
169 <p>An unexpected error occurred.</p>
170 {process.env.NODE_ENV !== "production" && (
171 <pre style="margin-top: 16px; text-align: left; font-size: 12px; color: var(--red)">
172 {err.message}
173 </pre>
174 )}
175 </div>
176 </Layout>,
177 500
178 );
179});
180
181export default app;