CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
help.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.
| 80bed05 | 1 | /** |
| 2 | * /help — public quickstart + API cheatsheet for owners migrating their | |
| 3 | * products onto gluecron. Covers the first five minutes (register, clone, | |
| 4 | * push), integration surfaces (SSH, import, webhooks, tokens), and the | |
| 5 | * AI-native extras (gates + AI review). Linked from the landing page nav. | |
| 6 | * | |
| 7 | * Uses softAuth so the nav bar renders with the signed-in user's session | |
| 8 | * cookie when present; the page itself is reachable without auth. | |
| 9 | */ | |
| 10 | ||
| 11 | import { Hono } from "hono"; | |
| 12 | import { Layout } from "../views/layout"; | |
| 13 | import { softAuth } from "../middleware/auth"; | |
| 14 | import type { AuthEnv } from "../middleware/auth"; | |
| 15 | ||
| 16 | const help = new Hono<AuthEnv>(); | |
| 17 | help.use("*", softAuth); | |
| 18 | ||
| 19 | help.get("/help", (c) => { | |
| 20 | const user = c.get("user"); | |
| 21 | ||
| 22 | return c.html( | |
| 23 | <Layout title="Help — gluecron" user={user}> | |
| 24 | <div style="max-width: 860px; margin: 0 auto; padding: 24px 16px"> | |
| 25 | <h1 style="margin: 0 0 8px; font-size: 28px">Help & quickstart</h1> | |
| 26 | <p style="color: var(--text-muted); margin-bottom: 24px"> | |
| 27 | Everything an owner migrating a product onto gluecron needs in one | |
| 28 | page. If something's unclear, open an issue — link at the bottom. | |
| 29 | </p> | |
| 30 | ||
| 31 | <nav | |
| 32 | class="panel" | |
| 33 | style="margin-bottom: 32px; padding: 12px 16px; font-size: 13px" | |
| 34 | > | |
| 35 | <strong | |
| 36 | style="display: block; margin-bottom: 6px; font-size: 12px; text-transform: uppercase; color: var(--text-muted)" | |
| 37 | > | |
| 38 | On this page | |
| 39 | </strong> | |
| 40 | <a href="#getting-started">Getting started</a> ·{" "} | |
| 41 | <a href="#git-https">Git over HTTPS</a> ·{" "} | |
| 42 | <a href="#git-ssh">Git over SSH</a> ·{" "} | |
| 43 | <a href="#import">Importing from GitHub</a> ·{" "} | |
| 44 | <a href="#webhooks">Webhooks</a> ·{" "} | |
| 45 | <a href="#tokens">Personal access tokens</a> ·{" "} | |
| 46 | <a href="#gates">Gates & AI review</a> ·{" "} | |
| 47 | <a href="#shortcuts">Keyboard shortcuts</a> ·{" "} | |
| 48 | <a href="#api">API</a> | |
| 49 | </nav> | |
| 50 | ||
| 51 | <section id="getting-started" style="margin-bottom: 32px"> | |
| 52 | <h2 style="margin-bottom: 12px; font-size: 20px">Getting started</h2> | |
| 53 | <div class="panel"> | |
| 54 | <div class="panel-item"> | |
| 55 | <div> | |
| 56 | <strong>1. Register an account.</strong>{" "} | |
| 57 | Head to <a href="/register">/register</a>, pick a username, and | |
| 58 | set a password. Usernames are your public handle and appear in | |
| 59 | every repo URL. | |
| 60 | </div> | |
| 61 | </div> | |
| 62 | <div class="panel-item"> | |
| 63 | <div> | |
| 64 | <strong>2. Verify your email.</strong>{" "} | |
| 65 | We send a one-time link the first time you sign in. Verified | |
| 66 | addresses can receive issue, PR, and gate-run notifications. | |
| 67 | </div> | |
| 68 | </div> | |
| 69 | <div class="panel-item"> | |
| 70 | <div> | |
| 71 | <strong>3. Create your first repo.</strong>{" "} | |
| 72 | From the dashboard hit <strong>New repository</strong>, or | |
| 73 | visit <a href="/new">/new</a>. Pick public or private, add a | |
| 74 | README, and you're ready to clone. | |
| 75 | </div> | |
| 76 | </div> | |
| 77 | </div> | |
| 78 | </section> | |
| 79 | ||
| 80 | <section id="git-https" style="margin-bottom: 32px"> | |
| 81 | <h2 style="margin-bottom: 12px; font-size: 20px">Git over HTTPS</h2> | |
| 82 | <p style="color: var(--text-muted); margin-bottom: 12px"> | |
| 83 | HTTPS works out of the box. Authenticate with your account | |
| 84 | password or, better, a personal access token. | |
| 85 | </p> | |
| 86 | <div class="panel"> | |
| 87 | <div class="panel-item"> | |
| 88 | <div style="width: 100%"> | |
| 89 | <strong>Clone</strong> | |
| 90 | <pre | |
| 91 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 92 | > | |
| 93 | {`git clone https://<your-host>/<owner>/<repo>.git`} | |
| 94 | </pre> | |
| 95 | </div> | |
| 96 | </div> | |
| 97 | <div class="panel-item"> | |
| 98 | <div style="width: 100%"> | |
| 99 | <strong>Push</strong> | |
| 100 | <pre | |
| 101 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 102 | > | |
| 103 | {`git push origin main`} | |
| 104 | </pre> | |
| 105 | </div> | |
| 106 | </div> | |
| 107 | <div class="panel-item"> | |
| 108 | <div style="width: 100%"> | |
| 109 | <strong>Pull</strong> | |
| 110 | <pre | |
| 111 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 112 | > | |
| 113 | {`git pull origin main`} | |
| 114 | </pre> | |
| 115 | </div> | |
| 116 | </div> | |
| 117 | </div> | |
| 118 | </section> | |
| 119 | ||
| 120 | <section id="git-ssh" style="margin-bottom: 32px"> | |
| 121 | <h2 style="margin-bottom: 12px; font-size: 20px">Git over SSH</h2> | |
| 122 | <p style="color: var(--text-muted); margin-bottom: 12px"> | |
| 123 | SSH avoids typing credentials and is recommended for day-to-day | |
| 124 | work. | |
| 125 | </p> | |
| 126 | <div class="panel"> | |
| 127 | <div class="panel-item"> | |
| 128 | <div> | |
| 129 | <strong>1. Add your key.</strong>{" "} | |
| 130 | Copy your public key (usually{" "} | |
| 131 | <code>~/.ssh/id_ed25519.pub</code>) and paste it into{" "} | |
| 132 | <a href="/settings/keys">/settings/keys</a>. Keys take effect | |
| 133 | immediately. | |
| 134 | </div> | |
| 135 | </div> | |
| 136 | <div class="panel-item"> | |
| 137 | <div style="width: 100%"> | |
| 138 | <strong>2. Clone using the SSH URL.</strong> | |
| 139 | <pre | |
| 140 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 141 | > | |
| 142 | {`git clone git@<your-host>:<owner>/<repo>.git`} | |
| 143 | </pre> | |
| 144 | </div> | |
| 145 | </div> | |
| 146 | <div class="panel-item"> | |
| 147 | <div> | |
| 148 | <strong>3. Rotate or revoke</strong> any key from the same | |
| 149 | settings page — useful when a laptop walks off. | |
| 150 | </div> | |
| 151 | </div> | |
| 152 | </div> | |
| 153 | </section> | |
| 154 | ||
| 155 | <section id="import" style="margin-bottom: 32px"> | |
| 156 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 157 | Importing from GitHub | |
| 158 | </h2> | |
| 159 | <div class="panel"> | |
| 160 | <div class="panel-item"> | |
| 161 | <div> | |
| 162 | Visit <a href="/import">/import</a>, paste the source URL, and | |
| 163 | gluecron will mirror the repository — full history, branches, | |
| 164 | and tags. The mirror is a one-time copy; subsequent pushes | |
| 165 | land on gluecron, not the source. Private sources need a PAT | |
| 166 | on the source side. | |
| 167 | </div> | |
| 168 | </div> | |
| 169 | </div> | |
| 170 | </section> | |
| 171 | ||
| 172 | <section id="webhooks" style="margin-bottom: 32px"> | |
| 173 | <h2 style="margin-bottom: 12px; font-size: 20px">Webhooks</h2> | |
| 174 | <p style="color: var(--text-muted); margin-bottom: 12px"> | |
| 175 | Per-repo webhooks live at{" "} | |
| 176 | <code>/:owner/:repo/settings/webhooks</code>. Register a URL, pick | |
| 177 | events (push, issue, pr, star), and set a secret. | |
| 178 | </p> | |
| 179 | <div class="panel"> | |
| 180 | <div class="panel-item"> | |
| 181 | <div> | |
| 182 | <strong>HMAC signature.</strong>{" "} | |
| 183 | Every delivery includes{" "} | |
| 184 | <code>X-Gluecron-Signature: sha256=<hex></code>.{" "} | |
| 185 | Compute HMAC-SHA256 over the raw request body using your | |
| 186 | secret and compare in constant time. | |
| 187 | </div> | |
| 188 | </div> | |
| 189 | <div class="panel-item"> | |
| 190 | <div style="width: 100%"> | |
| 191 | <strong>Payload shape.</strong> | |
| 192 | <pre | |
| 193 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 194 | > | |
| 195 | {`{ | |
| 196 | "event": "push", | |
| 197 | "repo": { "owner": "acme", "name": "api" }, | |
| 198 | "ref": "refs/heads/main", | |
| 199 | "before": "<sha>", | |
| 200 | "after": "<sha>", | |
| 201 | "commits": [ /* ... */ ], | |
| 202 | "sender": { "username": "kit" } | |
| 203 | }`} | |
| 204 | </pre> | |
| 205 | </div> | |
| 206 | </div> | |
| 207 | <div class="panel-item"> | |
| 208 | <div> | |
| 209 | Deliveries are retried with exponential backoff; inspect the | |
| 210 | last N attempts from the webhook's settings page. | |
| 211 | </div> | |
| 212 | </div> | |
| 213 | </div> | |
| 214 | </section> | |
| 215 | ||
| 216 | <section id="tokens" style="margin-bottom: 32px"> | |
| 217 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 218 | Personal access tokens | |
| 219 | </h2> | |
| 220 | <p style="color: var(--text-muted); margin-bottom: 12px"> | |
| 221 | Tokens authenticate CLI clients, CI jobs, and scripts. Create | |
| 222 | them at <a href="/settings/tokens">/settings/tokens</a>; the value | |
| 223 | is shown once, so copy it immediately. Tokens start with{" "} | |
| 224 | <code>glc_</code>. | |
| 225 | </p> | |
| 226 | <div class="panel"> | |
| 227 | <div class="panel-item"> | |
| 228 | <div style="width: 100%"> | |
| 229 | <strong>Example: list your repos via the API.</strong> | |
| 230 | <pre | |
| 231 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 232 | > | |
| 233 | {`curl -H "Authorization: Bearer glc_your_token_here" \\ | |
| 234 | https://<your-host>/api/v2/repos`} | |
| 235 | </pre> | |
| 236 | </div> | |
| 237 | </div> | |
| 238 | <div class="panel-item"> | |
| 239 | <div> | |
| 240 | Tokens can also authenticate <code>git</code> over HTTPS — use | |
| 241 | the token as the password in place of your account password. | |
| 242 | </div> | |
| 243 | </div> | |
| 244 | </div> | |
| 245 | </section> | |
| 246 | ||
| 247 | <section id="gates" style="margin-bottom: 32px"> | |
| 248 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 249 | Gates & AI review | |
| 250 | </h2> | |
| 251 | <div class="panel"> | |
| 252 | <div class="panel-item"> | |
| 253 | <div> | |
| 254 | Every push to the default branch (usually <code>main</code>) | |
| 255 | triggers a gate run: GateTest scans the diff for secrets, | |
| 256 | dependency advisories, and policy violations, while the AI | |
| 257 | reviewer reads the patch and comments on any PRs that touch | |
| 258 | the same files. Failing gates block the push by default; | |
| 259 | results appear on the commit page and in the repo's{" "} | |
| 260 | <em>Gate runs</em> tab. Configure gate policy per-repo in | |
| 261 | <strong> Settings → Gates</strong>. | |
| 262 | </div> | |
| 263 | </div> | |
| 264 | </div> | |
| 265 | </section> | |
| 266 | ||
| 267 | <section id="shortcuts" style="margin-bottom: 32px"> | |
| 268 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 269 | Keyboard shortcuts | |
| 270 | </h2> | |
| 271 | <div class="panel"> | |
| 272 | <div class="panel-item"> | |
| 273 | <div> | |
| 274 | gluecron ships a full keyboard-first mode — see{" "} | |
| 275 | <a href="/shortcuts">/shortcuts</a> for the complete cheat | |
| 276 | sheet. Press <code>?</code> on any page to pop the overlay. | |
| 277 | </div> | |
| 278 | </div> | |
| 279 | </div> | |
| 280 | </section> | |
| 281 | ||
| 282 | <section id="api" style="margin-bottom: 32px"> | |
| 283 | <h2 style="margin-bottom: 12px; font-size: 20px">API</h2> | |
| 284 | <div class="panel"> | |
| 285 | <div class="panel-item"> | |
| 286 | <div> | |
| 287 | Full REST + GraphQL reference lives at{" "} | |
| 288 | <a href="/api/docs">/api/docs</a>. The GraphQL explorer is at{" "} | |
| 289 | <a href="/api/graphql">/api/graphql</a>. | |
| 290 | </div> | |
| 291 | </div> | |
| 292 | </div> | |
| 293 | </section> | |
| 294 | ||
| 295 | <p | |
| 296 | style="color: var(--text-muted); font-size: 13px; margin-top: 40px; padding-top: 16px; border-top: 1px solid var(--border)" | |
| 297 | > | |
| 298 | Something missing? Open an issue on gluecron's source repo. | |
| 299 | </p> | |
| 300 | </div> | |
| 301 | </Layout> | |
| 302 | ); | |
| 303 | }); | |
| 304 | ||
| 305 | export default help; |