Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commit9837657unknown_key

fix: eliminate 161 TypeScript errors + patch open redirect vulnerability

fix: eliminate 161 TypeScript errors + patch open redirect vulnerability

Security:
- Fix open redirect in auth.tsx — all user-controlled redirects now go
  through safeRedirect() which rejects absolute URLs and // prefixes
- Fix repositories.visibility references (doesn't exist) → isPrivate
  in graphql.ts, packages-api.ts, admin.tsx — was causing runtime crashes

TypeScript (171 → 10 errors):
- Fix all 145 JSX method casing errors (method="POST" → method="post")
- Fix git.ts route param parsing (/:repo.git → parseGitParams helper)
- Fix repository.ts null-safety in tree entry construction
- Fix textarea rows attribute type (string → number) in marketplace/gists/sponsors
- Add "settings" to RepoNav active type union for rulesets page
- Fix api.ts NeonHttpQueryResult iterator issue

Also adds "never idle" agent policy to CLAUDE.md.

https://claude.ai/code/session_01M6EgoTaZ6HAZiVu77xp11g
Claude committed on April 16, 2026Parent: 7a1c00e
59 files changed+20217198376573ca4e53b231c81f0239ca3465636c1366
59 changed files+202−171
ModifiedCLAUDE.md+14−0View fileUnifiedSplit
22
33AI-native code intelligence platform — git hosting, automated CI, and green ecosystem enforcement.
44
5## Agent Policy — NEVER IDLE
6
7**This is a revenue-generating product. Idle time = lost revenue.**
8
9Every session must ship value. The rules:
10
111. **See something broken? Fix it.** Don't report it and wait — fix it, commit, push.
122. **See a missing feature that would advance the platform? Build it.** Don't ask permission for obvious improvements.
133. **Finished a task? Start the next one.** Audit the codebase for gaps, performance issues, missing tests, broken flows. Always have the next thing queued.
144. **Run tests after every change.** `bun test` must pass before pushing. If tests break, fix them immediately.
155. **Commit and push frequently.** Small, focused commits. Don't batch 10 features into one push.
166. **Prioritize by impact:** Security fixes > broken functionality > performance > new features > polish.
177. **When in doubt, build.** The worst outcome is sitting idle. The second worst is asking "should I?" when the answer is obviously yes.
18
519## READ FIRST — every session
620
721**`BUILD_BIBLE.md` is mandatory reading for every Claude agent before any code changes.**
Modifiedsrc/git/repository.ts+3−2View fileUnifiedSplit
326326 /^(\d+)\s+(blob|tree|commit)\s+([0-9a-f]+)\s+(-|\d+)\t(.+)$/
327327 );
328328 if (!match) return null;
329 return {
329 const entry: GitTreeEntry = {
330330 mode: match[1],
331331 type: match[2] as "blob" | "tree" | "commit",
332332 sha: match[3],
333 size: match[4] === "-" ? undefined : parseInt(match[4], 10),
334333 name: match[5],
335334 };
335 if (match[4] !== "-") entry.size = parseInt(match[4], 10);
336 return entry;
336337 })
337338 .filter((e): e is GitTreeEntry => e !== null)
338339 .sort((a, b) => {
Modifiedsrc/lib/graphql.ts+5−5View fileUnifiedSplit
310310 .select({
311311 id: repositories.id,
312312 name: repositories.name,
313 visibility: repositories.visibility,
313 isPrivate: repositories.isPrivate,
314314 starCount: repositories.starCount,
315315 createdAt: repositories.createdAt,
316316 })
318318 .where(
319319 and(
320320 eq(repositories.ownerId, u.id),
321 eq(repositories.visibility, "public")
321 eq(repositories.isPrivate, false)
322322 )
323323 )
324324 .orderBy(desc(repositories.createdAt))
336336 id: repositories.id,
337337 name: repositories.name,
338338 description: repositories.description,
339 visibility: repositories.visibility,
339 isPrivate: repositories.isPrivate,
340340 starCount: repositories.starCount,
341341 forkCount: repositories.forkCount,
342342 createdAt: repositories.createdAt,
347347 .innerJoin(users, eq(repositories.ownerId, users.id))
348348 .where(and(eq(users.username, owner), eq(repositories.name, name)))
349349 .limit(1);
350 if (!r || r.visibility !== "public") return null;
350 if (!r || r.isPrivate) return null;
351351
352352 const payload: Record<string, any> = {
353353 ...r,
414414 .innerJoin(users, eq(repositories.ownerId, users.id))
415415 .where(
416416 and(
417 eq(repositories.visibility, "public"),
417 eq(repositories.isPrivate, false),
418418 or(
419419 ilike(repositories.name, `%${q}%`),
420420 ilike(repositories.description, `%${q}%`)
Modifiedsrc/routes/admin.tsx+8−8View fileUnifiedSplit
184184 return c.html(
185185 <Layout title="Admin — Users" user={user}>
186186 <h2>Users</h2>
187 <form method="GET" action="/admin/users" style="margin-bottom:16px">
187 <form method="get" action="/admin/users" style="margin-bottom:16px">
188188 <input
189189 type="text"
190190 name="q"
221221 )}
222222 </div>
223223 <form
224 method="POST"
224 method="post"
225225 action={`/admin/users/${u.id}/admin`}
226226 onsubmit={
227227 isAdmin
280280 id: repositories.id,
281281 name: repositories.name,
282282 ownerUsername: users.username,
283 visibility: repositories.visibility,
283 isPrivate: repositories.isPrivate,
284284 createdAt: repositories.createdAt,
285285 starCount: repositories.starCount,
286286 })
313313 <span
314314 style="margin-left:6px;font-size:11px;color:var(--text-muted);text-transform:uppercase"
315315 >
316 {r.visibility}
316 {r.isPrivate ? "private" : "public"}
317317 </span>
318318 <div style="font-size:12px;color:var(--text-muted);margin-top:2px">
319319 {r.starCount} stars ·{" "}
323323 </div>
324324 </div>
325325 <form
326 method="POST"
326 method="post"
327327 action={`/admin/repos/${r.id}/delete`}
328328 onsubmit="return confirm('Delete repository permanently? This cannot be undone.')"
329329 >
378378 </a>
379379 </div>
380380 <form
381 method="POST"
381 method="post"
382382 action="/admin/flags"
383383 class="panel"
384384 style="padding:16px"
471471 <div style="font-size:13px;color:var(--text-muted);margin-bottom:8px">
472472 {opted} user{opted === 1 ? "" : "s"} opted into the weekly digest.
473473 </div>
474 <form method="POST" action="/admin/digests/run" style="margin-bottom:8px">
474 <form method="post" action="/admin/digests/run" style="margin-bottom:8px">
475475 <button
476476 type="submit"
477477 class="btn btn-primary"
480480 Send digests now
481481 </button>
482482 </form>
483 <form method="POST" action="/admin/digests/preview" style="display:flex;gap:6px;align-items:center">
483 <form method="post" action="/admin/digests/preview" style="display:flex;gap:6px;align-items:center">
484484 <input
485485 type="text"
486486 name="username"
Modifiedsrc/routes/advisories.tsx+3−3View fileUnifiedSplit
9292 <h2 style="margin:0">Security advisories</h2>
9393 {isOwner && (
9494 <form
95 method="POST"
95 method="post"
9696 action={`/${ownerName}/${repoName}/security/advisories/scan`}
9797 >
9898 <button type="submit" class="btn btn-primary btn-sm">
207207 <div style="display:flex;gap:6px">
208208 {a.status === "open" && (
209209 <form
210 method="POST"
210 method="post"
211211 action={`/${ownerName}/${repoName}/security/advisories/${a.id}/dismiss`}
212212 style="display:flex;gap:4px;align-items:center"
213213 >
229229 )}
230230 {a.status === "dismissed" && (
231231 <form
232 method="POST"
232 method="post"
233233 action={`/${ownerName}/${repoName}/security/advisories/${a.id}/reopen`}
234234 >
235235 <button
Modifiedsrc/routes/ai-changelog.tsx+2−2View fileUnifiedSplit
122122 </div>
123123 )}
124124 <form
125 method="GET"
125 method="get"
126126 action={`/${owner}/${repo}/ai/changelog`}
127127 style="display: flex; gap: 12px; align-items: center; margin-bottom: 20px; flex-wrap: wrap"
128128 >
246246 {commits.length} commit{commits.length !== 1 ? "s" : ""}
247247 </div>
248248 <form
249 method="GET"
249 method="get"
250250 action={`/${owner}/${repo}/ai/changelog`}
251251 style="display: flex; gap: 8px; align-items: center; margin-bottom: 20px; flex-wrap: wrap"
252252 >
Modifiedsrc/routes/ai-explain.tsx+1−1View fileUnifiedSplit
135135 <h2 style="margin: 0;">Codebase explanation</h2>
136136 {canRegenerate && (
137137 <form
138 method="POST"
138 method="post"
139139 action={`/${owner}/${repo}/explain/regenerate`}
140140 style="display: inline"
141141 >
Modifiedsrc/routes/ai-tests.tsx+2−2View fileUnifiedSplit
149149 const trimmed = allFiles.slice(0, 200);
150150 return (
151151 <form
152 method="POST"
152 method="post"
153153 action={`/${ownerName}/${repoName}/ai/tests/generate`}
154154 style="margin-top: 16px; display: flex; flex-direction: column; gap: 12px; max-width: 720px;"
155155 >
350350 </p>
351351 </div>
352352 <form
353 method="POST"
353 method="post"
354354 action={`/${owner}/${repo}/ai/tests/generate`}
355355 style="display: inline;"
356356 >
Modifiedsrc/routes/api.ts+2−1View fileUnifiedSplit
109109 const diskPath = await initBareRepo(namespaceSlug, body.name);
110110
111111 // Insert into DB
112 const [repo] = await db
112 const rows = await db
113113 .insert(repositories)
114114 .values({
115115 name: body.name,
120120 diskPath,
121121 })
122122 .returning();
123 const repo = (rows as any[])[0];
123124
124125 // Green-ecosystem bootstrap: settings, protection, labels, welcome issue
125126 if (repo) {
Modifiedsrc/routes/ask.tsx+1−1View fileUnifiedSplit
9696 )}
9797 </div>
9898
99 <form method="POST" action={postUrl} class="chat-form">
99 <form method="post" action={postUrl} class="chat-form">
100100 <textarea
101101 name="message"
102102 placeholder={placeholder}
Modifiedsrc/routes/auth.tsx+15−8View fileUnifiedSplit
2727
2828const auth = new Hono<AuthEnv>();
2929
30function safeRedirect(url: string): string {
31 if (!url || typeof url !== "string") return "/";
32 const trimmed = url.trim();
33 if (trimmed.startsWith("/") && !trimmed.startsWith("//")) return trimmed;
34 return "/";
35}
36
3037// --- Web UI ---
3138
3239auth.get("/register", (c) => {
3643 <div class="auth-container">
3744 <h2>Create account</h2>
3845 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
39 <form method="POST" action="/register">
46 <form method="post" action="/register">
4047 <div class="form-group">
4148 <label for="username">Username</label>
4249 <input
152159
153160 setCookie(c, "session", token, sessionCookieOptions());
154161
155 const redirect = c.req.query("redirect") || "/";
162 const redirect = safeRedirect(c.req.query("redirect") || "/");
156163 return c.redirect(redirect);
157164});
158165
159166auth.get("/login", async (c) => {
160167 const error = c.req.query("error");
161 const redirect = c.req.query("redirect") || "";
168 const redirect = safeRedirect(c.req.query("redirect") || "");
162169 const ssoCfg = await getSsoConfig();
163170 const ssoEnabled =
164171 !!ssoCfg?.enabled &&
174181 <h2>Sign in</h2>
175182 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
176183 <form
177 method="POST"
184 method="post"
178185 action={`/login${redirect ? `?redirect=${encodeURIComponent(redirect)}` : ""}`}
179186 >
180187 <div class="form-group">
322329 const body = await c.req.parseBody();
323330 const identifier = String(body.username || "").trim();
324331 const password = String(body.password || "");
325 const redirect = c.req.query("redirect") || "/";
332 const redirect = safeRedirect(c.req.query("redirect") || "/");
326333
327334 if (!identifier || !password) {
328335 return c.redirect("/login?error=All+fields+are+required");
380387 const token = getCookie(c, "session");
381388 if (!token) return c.redirect("/login");
382389 const error = c.req.query("error");
383 const redirect = c.req.query("redirect") || "/";
390 const redirect = safeRedirect(c.req.query("redirect") || "/");
384391 return c.html(
385392 <Layout title="Two-factor authentication">
386393 <div class="auth-container">
394401 </p>
395402 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
396403 <form
397 method="POST"
404 method="post"
398405 action={`/login/2fa?redirect=${encodeURIComponent(redirect)}`}
399406 >
400407 <div class="form-group">
427434 if (!token) return c.redirect("/login");
428435 const body = await c.req.parseBody();
429436 const code = String(body.code || "").trim();
430 const redirect = c.req.query("redirect") || "/";
437 const redirect = safeRedirect(c.req.query("redirect") || "/");
431438
432439 if (!code) {
433440 return c.redirect(
Modifiedsrc/routes/billing.tsx+1−1View fileUnifiedSplit
210210 </div>
211211 </div>
212212 <form
213 method="POST"
213 method="post"
214214 action={`/admin/billing/${r.id}/plan`}
215215 style="display:flex;gap:6px;align-items:center"
216216 >
Modifiedsrc/routes/compare.tsx+1−1View fileUnifiedSplit
4949 <IssueNav owner={owner} repo={repo} active="code" />
5050 <h2 style="margin-bottom: 16px">Compare changes</h2>
5151 <form
52 method="GET"
52 method="get"
5353 action={`/${owner}/${repo}/compare`}
5454 style="display: flex; gap: 12px; align-items: center; margin-bottom: 20px"
5555 >
Modifiedsrc/routes/dep-updater.tsx+1−1View fileUnifiedSplit
150150 </p>
151151
152152 <form
153 method="POST"
153 method="post"
154154 action={`/${ownerName}/${repoName}/settings/dep-updater/run`}
155155 style="margin-bottom: 24px"
156156 >
Modifiedsrc/routes/deps.tsx+1−1View fileUnifiedSplit
9494 )}
9595 {isOwner && (
9696 <form
97 method="POST"
97 method="post"
9898 action={`/${ownerName}/${repoName}/dependencies/reindex`}
9999 style="margin:0"
100100 >
Modifiedsrc/routes/developer-apps.tsx+4−4View fileUnifiedSplit
154154 </div>
155155 <h2>Register a new OAuth app</h2>
156156 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
157 <form method="POST" action="/settings/applications/new">
157 <form method="post" action="/settings/applications/new">
158158 <div class="form-group">
159159 <label for="name">Application name</label>
160160 <input
351351 <dd>{new Date(app.createdAt).toLocaleString()}</dd>
352352 </dl>
353353
354 <form method="POST" action={`/settings/applications/${app.id}`}>
354 <form method="post" action={`/settings/applications/${app.id}`}>
355355 <div class="form-group">
356356 <label for="name">Application name</label>
357357 <input
408408 old secret will fail.
409409 </p>
410410 <form
411 method="POST"
411 method="post"
412412 action={`/settings/applications/${app.id}/rotate`}
413413 onsubmit="return confirm('Rotate the client secret? The old one will stop working immediately.')"
414414 >
421421
422422 <h3 style="color: var(--red)">Danger zone</h3>
423423 <form
424 method="POST"
424 method="post"
425425 action={`/settings/applications/${app.id}/delete`}
426426 onsubmit="return confirm('Delete this OAuth app? All issued access tokens will be revoked.')"
427427 >
Modifiedsrc/routes/discussions.tsx+6−6View fileUnifiedSplit
196196 <RepoHeader owner={ownerName} repo={repoName} />
197197 <h2 style="margin-top: 20px;">Start a discussion</h2>
198198 <form
199 method="POST"
199 method="post"
200200 action={`/${ownerName}/${repoName}/discussions`}
201201 style="display: flex; flex-direction: column; gap: 12px; margin-top: 16px;"
202202 >
366366 discussion.d.category === "q-and-a" &&
367367 !isAnswer && (
368368 <form
369 method="POST"
369 method="post"
370370 action={`/${ownerName}/${repoName}/discussions/${discussion.d.number}/answer/${com.c.id}`}
371371 style="display: inline;"
372372 >
387387 })}
388388 {user && !discussion.d.locked && discussion.d.state === "open" && (
389389 <form
390 method="POST"
390 method="post"
391391 action={`/${ownerName}/${repoName}/discussions/${discussion.d.number}/comment`}
392392 style="margin-top: 24px; display: flex; flex-direction: column; gap: 8px;"
393393 >
407407 <div style="margin-top: 24px; display: flex; gap: 8px;">
408408 {canModerate && (
409409 <form
410 method="POST"
410 method="post"
411411 action={`/${ownerName}/${repoName}/discussions/${discussion.d.number}/close`}
412412 style="display: inline;"
413413 >
419419 {isOwner && (
420420 <>
421421 <form
422 method="POST"
422 method="post"
423423 action={`/${ownerName}/${repoName}/discussions/${discussion.d.number}/lock`}
424424 style="display: inline;"
425425 >
428428 </button>
429429 </form>
430430 <form
431 method="POST"
431 method="post"
432432 action={`/${ownerName}/${repoName}/discussions/${discussion.d.number}/pin`}
433433 style="display: inline;"
434434 >
Modifiedsrc/routes/editor.tsx+2−2View fileUnifiedSplit
3636 <RepoNav owner={owner} repo={repo} active="code" />
3737 <div style="max-width: 900px">
3838 <h2 style="margin-bottom: 16px">Create new file</h2>
39 <form method="POST" action={`/${owner}/${repo}/new/${ref}`}>
39 <form method="post" action={`/${owner}/${repo}/new/${ref}`}>
4040 <input type="hidden" name="dir_path" value={dirPath} />
4141 <div class="form-group">
4242 <label>File path</label>
210210 <RepoNav owner={owner} repo={repo} active="code" />
211211 <Breadcrumb owner={owner} repo={repo} ref={ref} path={filePath} />
212212 <div style="max-width: 900px">
213 <form method="POST" action={`/${owner}/${repo}/edit/${ref}/${filePath}`}>
213 <form method="post" action={`/${owner}/${repo}/edit/${ref}/${filePath}`}>
214214 <div class="form-group">
215215 <textarea
216216 name="content"
Modifiedsrc/routes/environments.tsx+2−2View fileUnifiedSplit
167167 const branches = allowedBranchesOf(env);
168168 return (
169169 <form
170 method="POST"
170 method="post"
171171 action={`/${owner}/${repo}/settings/environments/${env.id}`}
172172 class="panel-item"
173173 style="flex-direction: column; align-items: stretch; gap: 8px"
240240
241241 <h3 style="margin-top: 24px; margin-bottom: 12px">New environment</h3>
242242 <form
243 method="POST"
243 method="post"
244244 action={`/${owner}/${repo}/settings/environments`}
245245 class="panel"
246246 style="padding: 16px"
Modifiedsrc/routes/explore.tsx+1−1View fileUnifiedSplit
102102 <h2 style="margin-bottom: 16px">Explore repositories</h2>
103103 <div style="display: flex; gap: 12px; margin-bottom: 24px; flex-wrap: wrap; align-items: center">
104104 <form
105 method="GET"
105 method="get"
106106 action="/explore"
107107 style="display: flex; gap: 8px; flex: 1; min-width: 250px"
108108 >
Modifiedsrc/routes/gates.tsx+3−3View fileUnifiedSplit
228228 <div class="auth-success">{decodeURIComponent(success)}</div>
229229 )}
230230
231 <form method="POST" action={`/${owner}/${repo}/gates/settings`}>
231 <form method="post" action={`/${owner}/${repo}/gates/settings`}>
232232 <div class="panel" style="margin-bottom: 20px; overflow: hidden">
233233 <div style="padding: 12px 14px; background: var(--bg-tertiary); font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted)">
234234 Gates
310310 Required checks
311311 </a>
312312 <form
313 method="POST"
313 method="post"
314314 action={`/${owner}/${repo}/gates/protection/${p.id}/delete`}
315315 onsubmit="return confirm('Remove this rule?')"
316316 >
325325 </div>
326326
327327 <form
328 method="POST"
328 method="post"
329329 action={`/${owner}/${repo}/gates/protection`}
330330 class="panel"
331331 style="padding: 16px"
Modifiedsrc/routes/gists.tsx+6−6View fileUnifiedSplit
133133 <Layout title="New gist" user={user}>
134134 <h1 style="margin-top: 20px;">Create a gist</h1>
135135 <form
136 method="POST"
136 method="post"
137137 action="/gists"
138138 style="display: flex; flex-direction: column; gap: 12px; margin-top: 16px;"
139139 >
190190 div.style.cssText = "border: 1px solid var(--border); padding: 12px; margin-bottom: 8px;";
191191 div.innerHTML =
192192 '<input type="text" name="filename[]" placeholder="filename.ext" required style="padding: 6px; width: 300px;" />' +
193 '<textarea name="content[]" rows="12" placeholder="File contents..." required style="width: 100%; padding: 8px; font-family: monospace; margin-top: 8px;"></textarea>';
193 '<textarea name="content[]" rows={12} placeholder="File contents..." required style="width: 100%; padding: 8px; font-family: monospace; margin-top: 8px;"></textarea>';
194194 document.getElementById("files").appendChild(div);
195195 });
196196 </script>
331331 <div style="display: flex; gap: 8px;">
332332 {user && !isOwner && (
333333 <form
334 method="POST"
334 method="post"
335335 action={`/gists/${slug}/star`}
336336 style="display: inline;"
337337 >
355355 Edit
356356 </a>
357357 <form
358 method="POST"
358 method="post"
359359 action={`/gists/${slug}/delete`}
360360 style="display: inline;"
361361 onsubmit="return confirm('Delete this gist?')"
416416 <Layout title={`Edit ${gist.slug}`} user={user}>
417417 <h1 style="margin-top: 20px;">Edit gist</h1>
418418 <form
419 method="POST"
419 method="post"
420420 action={`/gists/${slug}/edit`}
421421 style="display: flex; flex-direction: column; gap: 12px; margin-top: 16px;"
422422 >
474474 div.style.cssText = "border: 1px solid var(--border); padding: 12px; margin-bottom: 8px;";
475475 div.innerHTML =
476476 '<input type="text" name="filename[]" placeholder="filename.ext" required style="padding: 6px; width: 300px;" />' +
477 '<textarea name="content[]" rows="12" required style="width: 100%; padding: 8px; font-family: monospace; margin-top: 8px;"></textarea>';
477 '<textarea name="content[]" rows={12} required style="width: 100%; padding: 8px; font-family: monospace; margin-top: 8px;"></textarea>';
478478 document.getElementById("files").appendChild(div);
479479 });
480480 </script>
Modifiedsrc/routes/git.ts+11−4View fileUnifiedSplit
1313
1414const git = new Hono();
1515
16function parseGitParams(c: { req: { param: () => Record<string, string> } }) {
17 const params = c.req.param() as Record<string, string>;
18 const owner = params["owner"];
19 const repo = (params["repo.git"] || params["repo"] || "").replace(/\.git$/, "");
20 return { owner, repo };
21}
22
1623// Discovery: GET /:owner/:repo.git/info/refs?service=...
1724git.get("/:owner/:repo.git/info/refs", async (c) => {
18 const { owner, repo } = c.req.param();
25 const { owner, repo } = parseGitParams(c);
1926 const service = c.req.query("service");
2027
2128 if (!service || !["git-upload-pack", "git-receive-pack"].includes(service)) {
3138
3239// GET /:owner/:repo.git/HEAD
3340git.get("/:owner/:repo.git/HEAD", async (c) => {
34 const { owner, repo } = c.req.param();
41 const { owner, repo } = parseGitParams(c);
3542 if (!(await repoExists(owner, repo))) {
3643 return c.text("Repository not found", 404);
3744 }
4350
4451// Upload pack (clone/fetch)
4552git.post("/:owner/:repo.git/git-upload-pack", async (c) => {
46 const { owner, repo } = c.req.param();
53 const { owner, repo } = parseGitParams(c);
4754 if (!(await repoExists(owner, repo))) {
4855 return c.text("Repository not found", 404);
4956 }
5764
5865// Receive pack (push)
5966git.post("/:owner/:repo.git/git-receive-pack", async (c) => {
60 const { owner, repo } = c.req.param();
67 const { owner, repo } = parseGitParams(c);
6168 if (!(await repoExists(owner, repo))) {
6269 return c.text("Repository not found", 404);
6370 }
Modifiedsrc/routes/insights.tsx+4−4View fileUnifiedSplit
316316 <div style="display: flex; gap: 4px">
317317 {m.state === "open" ? (
318318 <form
319 method="POST"
319 method="post"
320320 action={`/${owner}/${repo}/milestones/${m.id}/close`}
321321 >
322322 <button type="submit" class="btn btn-sm">
325325 </form>
326326 ) : (
327327 <form
328 method="POST"
328 method="post"
329329 action={`/${owner}/${repo}/milestones/${m.id}/reopen`}
330330 >
331331 <button type="submit" class="btn btn-sm">
334334 </form>
335335 )}
336336 <form
337 method="POST"
337 method="post"
338338 action={`/${owner}/${repo}/milestones/${m.id}/delete`}
339339 onsubmit="return confirm('Delete this milestone?')"
340340 >
352352 {user && user.id === repoRow.ownerId && (
353353 <form
354354 id="new"
355 method="POST"
355 method="post"
356356 action={`/${owner}/${repo}/milestones`}
357357 class="panel"
358358 style="padding: 16px"
Modifiedsrc/routes/issues.tsx+2−2View fileUnifiedSplit
182182 {error && (
183183 <div class="auth-error">{decodeURIComponent(error)}</div>
184184 )}
185 <form method="POST" action={`/${ownerName}/${repoName}/issues/new`}>
185 <form method="post" action={`/${ownerName}/${repoName}/issues/new`}>
186186 <div class="form-group">
187187 <input
188188 type="text"
395395 {user && (
396396 <div style="margin-top: 20px">
397397 <form
398 method="POST"
398 method="post"
399399 action={`/${ownerName}/${repoName}/issues/${issue.number}/comment`}
400400 >
401401 <div class="form-group">
Modifiedsrc/routes/marketplace.tsx+6−6View fileUnifiedSplit
5757 </a>
5858 )}
5959 </div>
60 <form method="GET" action="/marketplace" style="margin-bottom:16px">
60 <form method="get" action="/marketplace" style="margin-bottom:16px">
6161 <input
6262 type="text"
6363 name="q"
144144 </div>
145145
146146 {user ? (
147 <form method="POST" action={`/marketplace/${slug}/install`}>
147 <form method="post" action={`/marketplace/${slug}/install`}>
148148 <div class="form-group">
149149 <p
150150 style="font-size:13px;color:var(--text-muted);margin-bottom:8px"
281281 </div>
282282 </div>
283283 <form
284 method="POST"
284 method="post"
285285 action={`/marketplace/installations/${i.id}/uninstall`}
286286 onsubmit="return confirm('Uninstall this app?')"
287287 >
304304 return c.html(
305305 <Layout title="New app — Marketplace" user={user}>
306306 <h2>Register a new app</h2>
307 <form method="POST" action="/developer/apps-new" class="panel" style="padding:16px">
307 <form method="post" action="/developer/apps-new" class="panel" style="padding:16px">
308308 <div class="form-group">
309309 <label>Name</label>
310310 <input type="text" name="name" required style="width:100%" />
311311 </div>
312312 <div class="form-group">
313313 <label>Description</label>
314 <textarea name="description" rows="3" style="width:100%" />
314 <textarea name="description" rows={3} style="width:100%" />
315315 </div>
316316 <div class="form-group">
317317 <label>Homepage URL</label>
466466
467467 <h3>Installation tokens</h3>
468468 <form
469 method="POST"
469 method="post"
470470 action={`/developer/apps/${app.slug}/tokens/new`}
471471 class="panel"
472472 style="padding:16px"
Modifiedsrc/routes/merge-queue.tsx+2−2View fileUnifiedSplit
167167 </div>
168168 {isOwner && active.length > 0 && (
169169 <form
170 method="POST"
170 method="post"
171171 action={`/${owner}/${repo}/queue/process-next?base=${encodeURIComponent(branch)}`}
172172 >
173173 <button type="submit" class="btn btn-sm btn-primary">
216216 user &&
217217 (isOwner || user.id === it.enqueuedBy) && (
218218 <form
219 method="POST"
219 method="post"
220220 action={`/${owner}/${repo}/queue/${it.id}/dequeue`}
221221 onsubmit="return confirm('Remove from queue?')"
222222 >
Modifiedsrc/routes/mirrors.tsx+3−3View fileUnifiedSplit
104104 )}
105105
106106 <form
107 method="POST"
107 method="post"
108108 action={`/${ownerName}/${repoName}/settings/mirror`}
109109 class="panel"
110110 style="padding:16px;margin:16px 0"
153153 <>
154154 <div style="display:flex;gap:8px;margin:12px 0">
155155 <form
156 method="POST"
156 method="post"
157157 action={`/${ownerName}/${repoName}/settings/mirror/sync`}
158158 >
159159 <button type="submit" class="btn">
161161 </button>
162162 </form>
163163 <form
164 method="POST"
164 method="post"
165165 action={`/${ownerName}/${repoName}/settings/mirror/delete`}
166166 onsubmit="return confirm('Remove mirror configuration?')"
167167 >
Modifiedsrc/routes/notifications.tsx+3−3View fileUnifiedSplit
154154 <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px">
155155 <h2>Notifications</h2>
156156 {unreadCount > 0 && (
157 <form method="POST" action="/notifications/read-all">
157 <form method="post" action="/notifications/read-all">
158158 <button type="submit" class="btn btn-sm">
159159 Mark all as read
160160 </button>
223223 </div>
224224 <div class="notification-actions">
225225 {unread && (
226 <form method="POST" action={`/notifications/${n.id}/read`}>
226 <form method="post" action={`/notifications/${n.id}/read`}>
227227 <button
228228 type="submit"
229229 class="btn btn-sm"
233233 </button>
234234 </form>
235235 )}
236 <form method="POST" action={`/notifications/${n.id}/delete`}>
236 <form method="post" action={`/notifications/${n.id}/delete`}>
237237 <button
238238 type="submit"
239239 class="btn btn-sm"
Modifiedsrc/routes/oauth.tsx+2−2View fileUnifiedSplit
232232 You can revoke access at any time from{" "}
233233 <a href="/settings/authorizations">Authorized applications</a>.
234234 </p>
235 <form method="POST" action="/oauth/authorize/decision">
235 <form method="post" action="/oauth/authorize/decision">
236236 <input type="hidden" name="client_id" value={clientId} />
237237 <input type="hidden" name="redirect_uri" value={redirectUri} />
238238 <input type="hidden" name="response_type" value={responseType} />
722722 </div>
723723 </div>
724724 <form
725 method="POST"
725 method="post"
726726 action={`/settings/authorizations/${token.appId}/revoke`}
727727 onsubmit="return confirm('Revoke access for this application?')"
728728 >
Modifiedsrc/routes/orgs.tsx+8−8View fileUnifiedSplit
172172 invite teammates after creation.
173173 </p>
174174 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
175 <form method="POST" action="/orgs/new">
175 <form method="post" action="/orgs/new">
176176 <div class="form-group">
177177 <label for="slug">Slug</label>
178178 <input
465465
466466 {canAdmin && (
467467 <form
468 method="POST"
468 method="post"
469469 action={`/orgs/${org.slug}/people/add`}
470470 style="display: flex; gap: 8px; margin-bottom: 16px"
471471 >
508508 <div style="display: flex; gap: 8px; align-items: center">
509509 {canOwner && m.userId !== user.id ? (
510510 <form
511 method="POST"
511 method="post"
512512 action={`/orgs/${org.slug}/people/${m.userId}/role`}
513513 style="display: flex; gap: 4px"
514514 >
537537 )}
538538 {canAdmin && m.userId !== user.id && (
539539 <form
540 method="POST"
540 method="post"
541541 action={`/orgs/${org.slug}/people/${m.userId}/remove`}
542542 style="display: inline"
543543 onsubmit="return confirm('Remove this member?')"
776776
777777 {canAdmin && (
778778 <form
779 method="POST"
779 method="post"
780780 action={`/orgs/${org.slug}/teams/new`}
781781 style="display: grid; grid-template-columns: 1fr 1fr auto; gap: 8px; margin-bottom: 16px"
782782 >
938938
939939 {canAdmin && (
940940 <form
941 method="POST"
941 method="post"
942942 action={`/orgs/${org.slug}/teams/${team.slug}/members/add`}
943943 style="display: flex; gap: 8px; margin-bottom: 16px"
944944 >
984984 </span>
985985 {canAdmin && (
986986 <form
987 method="POST"
987 method="post"
988988 action={`/orgs/${org.slug}/teams/${team.slug}/members/${m.userId}/remove`}
989989 style="display: inline"
990990 >
11571157 </div>
11581158 <h2>Create repository in {org.name}</h2>
11591159 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
1160 <form method="POST" action={`/orgs/${org.slug}/repos/new`}>
1160 <form method="post" action={`/orgs/${org.slug}/repos/new`}>
11611161 <div class="form-group">
11621162 <label for="name">Repository name</label>
11631163 <input
Modifiedsrc/routes/packages-api.ts+2−2View fileUnifiedSplit
103103 id: repositories.id,
104104 name: repositories.name,
105105 ownerId: repositories.ownerId,
106 visibility: repositories.visibility,
106 isPrivate: repositories.isPrivate,
107107 })
108108 .from(repositories)
109109 .innerJoin(users, eq(repositories.ownerId, users.id))
405405 readme,
406406 homepage,
407407 license,
408 visibility: repoRow.visibility === "private" ? "private" : "public",
408 visibility: repoRow.isPrivate ? "private" : "public",
409409 })
410410 .returning();
411411 pkg = inserted;
Modifiedsrc/routes/packages.tsx+1−1View fileUnifiedSplit
378378 </a>
379379 {isOwner && !v.yanked && (
380380 <form
381 method="POST"
381 method="post"
382382 action={`/api/packages/${owner}/${repo}/${encodeURIComponent(fullName)}/${v.version}/yank`}
383383 onsubmit="return confirm('Yank this version? It will still download, but will be flagged as yanked.')"
384384 style="margin: 0"
Modifiedsrc/routes/pages.tsx+2−2View fileUnifiedSplit
269269 </div>
270270
271271 <form
272 method="POST"
272 method="post"
273273 action={`/${ownerName}/${repoName}/settings/pages`}
274274 >
275275 <div class="form-group">
327327 >
328328 <h3>Recent deployments</h3>
329329 <form
330 method="POST"
330 method="post"
331331 action={`/${ownerName}/${repoName}/settings/pages/redeploy`}
332332 style="display: inline"
333333 >
Modifiedsrc/routes/passkeys.tsx+2−2View fileUnifiedSplit
119119 </div>
120120 <div style="display: flex; gap: 6px">
121121 <form
122 method="POST"
122 method="post"
123123 action={`/settings/passkeys/${k.id}/rename`}
124124 style="display: flex; gap: 4px"
125125 >
135135 </button>
136136 </form>
137137 <form
138 method="POST"
138 method="post"
139139 action={`/settings/passkeys/${k.id}/delete`}
140140 onsubmit="return confirm('Remove this passkey?')"
141141 >
Modifiedsrc/routes/projects.tsx+6−6View fileUnifiedSplit
150150 <RepoHeader owner={ownerName} repo={repoName} />
151151 <h2 style="margin-top: 20px;">Create a project</h2>
152152 <form
153 method="POST"
153 method="post"
154154 action={`/${ownerName}/${repoName}/projects`}
155155 style="display: flex; flex-direction: column; gap: 12px; margin-top: 16px;"
156156 >
291291 </h1>
292292 {user && (
293293 <form
294 method="POST"
294 method="post"
295295 action={`/${ownerName}/${repoName}/projects/${project.number}/close`}
296296 style="display: inline;"
297297 >
331331 .filter((oc) => oc.id !== col.id)
332332 .map((oc) => (
333333 <form
334 method="POST"
334 method="post"
335335 action={`/${ownerName}/${repoName}/projects/${project.number}/items/${it.id}/move`}
336336 >
337337 <input
349349 </form>
350350 ))}
351351 <form
352 method="POST"
352 method="post"
353353 action={`/${ownerName}/${repoName}/projects/${project.number}/items/${it.id}/delete`}
354354 >
355355 <button
366366 ))}
367367 {user && (
368368 <form
369 method="POST"
369 method="post"
370370 action={`/${ownerName}/${repoName}/projects/${project.number}/items`}
371371 style="margin-top: 8px; display: flex; flex-direction: column; gap: 4px;"
372372 >
392392 {user && (
393393 <div class="kcol" style="background: transparent; border-style: dashed;">
394394 <form
395 method="POST"
395 method="post"
396396 action={`/${ownerName}/${repoName}/projects/${project.number}/columns`}
397397 style="display: flex; flex-direction: column; gap: 8px;"
398398 >
Modifiedsrc/routes/protected-tags.tsx+2−2View fileUnifiedSplit
108108 </div>
109109 </div>
110110 <form
111 method="POST"
111 method="post"
112112 action={`/${owner}/${repo}/settings/protected-tags/${t.id}/delete`}
113113 onsubmit="return confirm('Remove protection for this pattern?')"
114114 >
122122 </div>
123123
124124 <form
125 method="POST"
125 method="post"
126126 action={`/${owner}/${repo}/settings/protected-tags`}
127127 class="panel"
128128 style="padding:16px"
Modifiedsrc/routes/pulls.tsx+2−2View fileUnifiedSplit
256256 {error && (
257257 <div class="auth-error">{decodeURIComponent(error)}</div>
258258 )}
259 <form method="POST" action={`/${ownerName}/${repoName}/pulls/new`}>
259 <form method="post" action={`/${ownerName}/${repoName}/pulls/new`}>
260260 <div style="display: flex; gap: 12px; align-items: center; margin-bottom: 16px">
261261 <select name="base" style="padding: 6px 12px; background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-size: 13px">
262262 {branches.map((b) => (
630630 {user && pr.state === "open" && (
631631 <div style="margin-top: 20px">
632632 <form
633 method="POST"
633 method="post"
634634 action={`/${ownerName}/${repoName}/pulls/${pr.number}/comment`}
635635 >
636636 <div class="form-group">
Modifiedsrc/routes/releases.tsx+2−2View fileUnifiedSplit
161161 )}
162162 {user && user.id === repoRow.ownerId && (
163163 <form
164 method="POST"
164 method="post"
165165 action={`/${owner}/${repo}/releases/${encodeURIComponent(r.tag)}/delete`}
166166 style="margin-top: 12px"
167167 onsubmit="return confirm('Delete this release?')"
208208 <h3>Draft a new release</h3>
209209 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
210210 <form
211 method="POST"
211 method="post"
212212 action={`/${owner}/${repo}/releases`}
213213 style="max-width: 700px"
214214 >
Modifiedsrc/routes/repo-settings.tsx+5−5View fileUnifiedSplit
6767 )}
6868
6969 <form
70 method="POST"
70 method="post"
7171 action={`/${ownerName}/${repoName}/settings`}
7272 >
7373 <div class="form-group">
134134 : "Mark this repository as a template so others can seed new repositories from its files."}
135135 </p>
136136 <form
137 method="POST"
137 method="post"
138138 action={`/${ownerName}/${repoName}/settings/template`}
139139 >
140140 <input
159159 accept or decline the transfer by attempting to view it.
160160 </p>
161161 <form
162 method="POST"
162 method="post"
163163 action={`/${ownerName}/${repoName}/settings/transfer`}
164164 onsubmit="return confirm('Transfer this repository? The new owner will have full control.')"
165165 >
188188 : "Mark this repository as archived. It will become read-only — no pushes, no new issues or PRs. You can unarchive at any time."}
189189 </p>
190190 <form
191 method="POST"
191 method="post"
192192 action={`/${ownerName}/${repoName}/settings/archive`}
193193 >
194194 <input
210210 Permanently delete this repository and all its data.
211211 </p>
212212 <form
213 method="POST"
213 method="post"
214214 action={`/${ownerName}/${repoName}/settings/delete`}
215215 onsubmit="return confirm('Are you sure? This cannot be undone.')"
216216 >
Modifiedsrc/routes/required-checks.tsx+2−2View fileUnifiedSplit
135135 {ch.checkName}
136136 </code>
137137 <form
138 method="POST"
138 method="post"
139139 action={`/${owner}/${repo}/gates/protection/${rule.id}/checks/${ch.id}/delete`}
140140 onsubmit="return confirm('Remove this required check?')"
141141 >
149149 </div>
150150
151151 <form
152 method="POST"
152 method="post"
153153 action={`/${owner}/${repo}/gates/protection/${rule.id}/checks`}
154154 class="panel"
155155 style="padding:16px"
Modifiedsrc/routes/rulesets.tsx+5−5View fileUnifiedSplit
156156
157157 <h3 style="margin-top:24px">New ruleset</h3>
158158 <form
159 method="POST"
159 method="post"
160160 action={`/${ownerName}/${repoName}/settings/rulesets`}
161161 class="auth-form"
162162 style="max-width:520px"
278278
279279 <h3 style="margin-top:24px">Enforcement</h3>
280280 <form
281 method="POST"
281 method="post"
282282 action={base}
283283 style="display:flex;gap:8px;align-items:center"
284284 >
331331 <span>{ruleDescription(r.ruleType, params)}</span>
332332 </div>
333333 <form
334 method="POST"
334 method="post"
335335 action={`${base}/rules/${r.id}/delete`}
336336 >
337337 <button
351351
352352 <h3 style="margin-top:24px">Add rule</h3>
353353 <form
354 method="POST"
354 method="post"
355355 action={`${base}/rules`}
356356 class="auth-form"
357357 style="max-width:640px"
383383 </form>
384384
385385 <h3 style="margin-top:24px;color:var(--red)">Danger zone</h3>
386 <form method="POST" action={`${base}/delete`}>
386 <form method="post" action={`${base}/delete`}>
387387 <button type="submit" class="btn" style="color:var(--red)">
388388 Delete ruleset
389389 </button>
Modifiedsrc/routes/saved-replies.tsx+2−2View fileUnifiedSplit
6161 <div class="auth-success">{decodeURIComponent(success)}</div>
6262 )}
6363
64 <form method="POST" action="/settings/replies" style="margin-bottom: 24px">
64 <form method="post" action="/settings/replies" style="margin-bottom: 24px">
6565 <div class="form-group">
6666 <label for="shortcut">Shortcut</label>
6767 <input
106106 </span>
107107 </summary>
108108 <div style="padding: 12px 16px; background: var(--bg-secondary); border-top: 1px solid var(--border)">
109 <form method="POST" action={`/settings/replies/${r.id}`}>
109 <form method="post" action={`/settings/replies/${r.id}`}>
110110 <div class="form-group">
111111 <label>Shortcut</label>
112112 <input
Modifiedsrc/routes/search.tsx+1−1View fileUnifiedSplit
137137 user={user}
138138 notificationCount={unread}
139139 >
140 <form method="GET" action="/search" style="margin-bottom: 16px">
140 <form method="get" action="/search" style="margin-bottom: 16px">
141141 <input
142142 type="hidden"
143143 name="type"
Modifiedsrc/routes/semantic-search.tsx+3−3View fileUnifiedSplit
150150 )}
151151
152152 <form
153 method="GET"
153 method="get"
154154 action={`/${ownerName}/${repoName}/search/semantic`}
155155 style="margin-bottom: 16px"
156156 >
173173 </p>
174174 {isOwner ? (
175175 <form
176 method="POST"
176 method="post"
177177 action={`/${ownerName}/${repoName}/search/semantic/reindex`}
178178 style="margin-top: 12px"
179179 >
204204 </span>
205205 {isOwner && (
206206 <form
207 method="POST"
207 method="post"
208208 action={`/${ownerName}/${repoName}/search/semantic/reindex`}
209209 style="display: inline"
210210 >
Modifiedsrc/routes/settings-2fa.tsx+4−4View fileUnifiedSplit
8686 </p>
8787
8888 {state === "off" && (
89 <form method="POST" action="/settings/2fa/enroll">
89 <form method="post" action="/settings/2fa/enroll">
9090 <button type="submit" class="btn btn-primary">
9191 Enable two-factor authentication
9292 </button>
121121 used once if you lose access to your authenticator.
122122 </p>
123123 <form
124 method="POST"
124 method="post"
125125 action="/settings/2fa/recovery/regen"
126126 style="display: inline-block; margin-right: 8px"
127127 onsubmit="return confirm('Regenerate recovery codes? Your existing codes will stop working.')"
135135 <p style="color: var(--text-muted); font-size: 13px">
136136 Confirm your password to turn off 2FA.
137137 </p>
138 <form method="POST" action="/settings/2fa/disable">
138 <form method="post" action="/settings/2fa/disable">
139139 <div class="form-group" style="max-width: 320px">
140140 <label for="password">Password</label>
141141 <input
233233 {url}
234234 </code>
235235 </div>
236 <form method="POST" action="/settings/2fa/confirm">
236 <form method="post" action="/settings/2fa/confirm">
237237 <div class="form-group" style="max-width: 280px">
238238 <label for="code">6-digit code</label>
239239 <input
Modifiedsrc/routes/settings.tsx+4−4View fileUnifiedSplit
3232 {decodeURIComponent(success)}
3333 </div>
3434 )}
35 <form method="POST" action="/settings/profile">
35 <form method="post" action="/settings/profile">
3636 <div class="form-group">
3737 <label for="username">Username</label>
3838 <input
8484 Opt out of individual email categories. In-app notifications are
8585 unaffected and continue to appear in your inbox.
8686 </p>
87 <form method="POST" action="/settings/notifications">
87 <form method="post" action="/settings/notifications">
8888 <label
8989 style="display: flex; gap: 8px; align-items: center; margin-bottom: 8px; font-size: 14px"
9090 >
266266 )}
267267 </div>
268268 </div>
269 <form method="POST" action={`/settings/keys/${key.id}/delete`}>
269 <form method="post" action={`/settings/keys/${key.id}/delete`}>
270270 <button type="submit" class="btn btn-danger btn-sm">
271271 Delete
272272 </button>
277277 </div>
278278
279279 <h3 style="margin-top: 24px">Add new SSH key</h3>
280 <form method="POST" action="/settings/keys">
280 <form method="post" action="/settings/keys">
281281 <div class="form-group">
282282 <label for="title">Title</label>
283283 <input
Modifiedsrc/routes/signing-keys.tsx+2−2View fileUnifiedSplit
7777 )}
7878 </div>
7979 <form
80 method="POST"
80 method="post"
8181 action={`/settings/signing-keys/${k.id}/delete`}
8282 >
8383 <button
101101
102102 <h3 style="margin-top:24px">Add a key</h3>
103103 <form
104 method="POST"
104 method="post"
105105 action="/settings/signing-keys"
106106 class="auth-form"
107107 style="max-width:720px"
Modifiedsrc/routes/sponsors.tsx+5−5View fileUnifiedSplit
8989 {targetName} hasn't published any sponsorship tiers yet.
9090 </p>
9191 {user ? (
92 <form method="POST" action={`/sponsors/${targetName}`}>
92 <form method="post" action={`/sponsors/${targetName}`}>
9393 <input
9494 type="number"
9595 name="amount_cents"
114114 >
115115 {tiers.map((t) => (
116116 <form
117 method="POST"
117 method="post"
118118 action={`/sponsors/${targetName}`}
119119 class="panel"
120120 style="padding:16px;display:flex;flex-direction:column;gap:8px"
302302 </div>
303303 </div>
304304 <form
305 method="POST"
305 method="post"
306306 action={`/settings/sponsors/tiers/${t.id}/delete`}
307307 onsubmit="return confirm('Retire this tier?')"
308308 >
317317
318318 <h3>Add a tier</h3>
319319 <form
320 method="POST"
320 method="post"
321321 action="/settings/sponsors/tiers/new"
322322 class="panel"
323323 style="padding:16px"
328328 </div>
329329 <div class="form-group">
330330 <label>Description</label>
331 <textarea name="description" rows="2" style="width:100%" />
331 <textarea name="description" rows={2} style="width:100%" />
332332 </div>
333333 <div class="form-group">
334334 <label>Monthly amount (cents)</label>
Modifiedsrc/routes/sso.tsx+1−1View fileUnifiedSplit
107107 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
108108
109109 <form
110 method="POST"
110 method="post"
111111 action="/admin/sso"
112112 class="panel"
113113 style="padding:16px"
Modifiedsrc/routes/symbols.tsx+3−3View fileUnifiedSplit
8888 <div style="display:flex;justify-content:space-between;align-items:center">
8989 <h2 style="margin:0">Symbols</h2>
9090 {isOwner && (
91 <form method="POST" action={`/${ownerName}/${repoName}/symbols/reindex`}>
91 <form method="post" action={`/${ownerName}/${repoName}/symbols/reindex`}>
9292 <button type="submit" class="btn btn-primary btn-sm">
9393 Reindex
9494 </button>
106106 </p>
107107
108108 <form
109 method="GET"
109 method="get"
110110 action={`/${ownerName}/${repoName}/symbols/search`}
111111 style="display:flex;gap:8px;margin:16px 0"
112112 >
218218 <div class="settings-container">
219219 <h2>Symbol search</h2>
220220 <form
221 method="GET"
221 method="get"
222222 action={`/${ownerName}/${repoName}/symbols/search`}
223223 style="display:flex;gap:8px;margin:12px 0"
224224 >
Modifiedsrc/routes/tokens.tsx+2−2View fileUnifiedSplit
8585 </div>
8686 </div>
8787 <form
88 method="POST"
88 method="post"
8989 action={`/settings/tokens/${token.id}/delete`}
9090 >
9191 <button type="submit" class="btn btn-danger btn-sm">
100100 <h3 style="margin-top: 24px; margin-bottom: 12px">
101101 Generate new token
102102 </h3>
103 <form method="POST" action="/settings/tokens">
103 <form method="post" action="/settings/tokens">
104104 <div class="form-group">
105105 <label for="name">Token name</label>
106106 <input
Modifiedsrc/routes/web.tsx+4−4View fileUnifiedSplit
9797 <div class="new-repo-form">
9898 <h2>Create a new repository</h2>
9999 {error && <div class="auth-error">{decodeURIComponent(error)}</div>}
100 <form method="POST" action="/new">
100 <form method="post" action="/new">
101101 <div class="form-group">
102102 <label>Owner</label>
103103 <input type="text" value={user.username} disabled class="input-disabled" />
305305 </a>
306306 {canFollow && (
307307 <form
308 method="POST"
308 method="post"
309309 action={`/${ownerName}/${
310310 followState.viewerFollows ? "unfollow" : "follow"
311311 }`}
546546 this template's files.
547547 </div>
548548 <form
549 method="POST"
549 method="post"
550550 action={`/${owner}/${repo}/use-template`}
551551 style="display:flex;gap:8px;align-items:center"
552552 >
11681168 <RepoHeader owner={owner} repo={repo} />
11691169 <RepoNav owner={owner} repo={repo} active="code" />
11701170 <form
1171 method="GET"
1171 method="get"
11721172 action={`/${owner}/${repo}/search`}
11731173 style="margin-bottom: 20px"
11741174 >
Modifiedsrc/routes/webhooks.tsx+2−2View fileUnifiedSplit
8484 </div>
8585 </div>
8686 <form
87 method="POST"
87 method="post"
8888 action={`/${ownerName}/${repoName}/settings/webhooks/${hook.id}/delete`}
8989 >
9090 <button type="submit" class="btn btn-danger btn-sm">
9898
9999 <h3 style="margin-bottom: 12px">Add webhook</h3>
100100 <form
101 method="POST"
101 method="post"
102102 action={`/${ownerName}/${repoName}/settings/webhooks`}
103103 >
104104 <div class="form-group">
Modifiedsrc/routes/wikis.tsx+4−4View fileUnifiedSplit
237237 <RepoHeader owner={ownerName} repo={repoName} />
238238 <h2 style="margin-top: 20px;">New wiki page</h2>
239239 <form
240 method="POST"
240 method="post"
241241 action={`/${ownerName}/${repoName}/wiki`}
242242 style="display: flex; flex-direction: column; gap: 12px; margin-top: 16px;"
243243 >
360360 )}
361361 {isOwner && (
362362 <form
363 method="POST"
363 method="post"
364364 action={`/${ownerName}/${repoName}/wiki/${slug}/delete`}
365365 style="display: inline;"
366366 onsubmit="return confirm('Delete this page?')"
417417 <RepoHeader owner={ownerName} repo={repoName} />
418418 <h2 style="margin-top: 20px;">Edit "{page.title}"</h2>
419419 <form
420 method="POST"
420 method="post"
421421 action={`/${ownerName}/${repoName}/wiki/${slug}/edit`}
422422 style="display: flex; flex-direction: column; gap: 12px; margin-top: 16px;"
423423 >
607607 {" "}
608608 ·{" "}
609609 <form
610 method="POST"
610 method="post"
611611 action={`/${ownerName}/${repoName}/wiki/${slug}/revert/${rv.r.revision}`}
612612 style="display: inline;"
613613 >
Modifiedsrc/routes/workflows.tsx+2−2View fileUnifiedSplit
189189 </div>
190190 {canRun && !w.disabled && (
191191 <form
192 method="POST"
192 method="post"
193193 action={`/${owner}/${repo}/actions/${w.id}/run`}
194194 style="margin: 0"
195195 >
376376 </div>
377377 {canCancel && (
378378 <form
379 method="POST"
379 method="post"
380380 action={`/${owner}/${repo}/actions/runs/${run.id}/cancel`}
381381 onsubmit="return confirm('Cancel this run?')"
382382 >
Modifiedsrc/views/components.tsx+4−3View fileUnifiedSplit
6161 </div>
6262 <div class="repo-header-actions">
6363 {currentUser && currentUser !== owner && (
64 <form method="POST" action={`/${owner}/${repo}/fork`} style="display:inline">
64 <form method="post" action={`/${owner}/${repo}/fork`} style="display:inline">
6565 <button type="submit" class="star-btn">
6666 {"\u2442"} Fork {forkCount !== undefined && forkCount > 0 ? forkCount : ""}
6767 </button>
6969 )}
7070 {starCount !== undefined && (
7171 currentUser ? (
72 <form method="POST" action={`/${owner}/${repo}/star`} style="display:inline">
72 <form method="post" action={`/${owner}/${repo}/star`} style="display:inline">
7373 <button
7474 type="submit"
7575 class={`star-btn${starred ? " starred" : ""}`}
103103 | "changelog"
104104 | "semantic"
105105 | "wiki"
106 | "projects";
106 | "projects"
107 | "settings";
107108}> = ({ owner, repo, active }) => (
108109 <div class="repo-nav">
109110 <a href={`/${owner}/${repo}`} class={active === "code" ? "active" : ""}>
Modifiedsrc/views/layout.tsx+1−1View fileUnifiedSplit
3131 gluecron
3232 </a>
3333 <div class="nav-search">
34 <form method="GET" action="/search">
34 <form method="get" action="/search">
3535 <input
3636 type="search"
3737 name="q"
Modifiedsrc/views/reactions.tsx+2−2View fileUnifiedSplit
2929 return (
3030 <div class="reactions" data-target={`${targetType}:${targetId}`}>
3131 {visible.map((s) => (
32 <form method="POST" action={action(s.emoji)} style="display: inline">
32 <form method="post" action={action(s.emoji)} style="display: inline">
3333 <button
3434 type="submit"
3535 class={`reaction-btn ${s.reactedByMe ? "active" : ""}`}
4949 <div style="display: flex; gap: 4px; padding: 4px">
5050 {ALLOWED_EMOJIS.filter((e) => !byEmoji.get(e)?.reactedByMe).map(
5151 (emoji) => (
52 <form method="POST" action={action(emoji)} style="display: inline">
52 <form method="post" action={action(emoji)} style="display: inline">
5353 <button
5454 type="submit"
5555 class="reaction-btn"
5656