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> ·{" "} | |
| 2afb411 | 47 | <a href="#ai-native">AI-native flow</a> ·{" "} |
| 80bed05 | 48 | <a href="#shortcuts">Keyboard shortcuts</a> ·{" "} |
| 49 | <a href="#api">API</a> | |
| 50 | </nav> | |
| 51 | ||
| 52 | <section id="getting-started" style="margin-bottom: 32px"> | |
| 53 | <h2 style="margin-bottom: 12px; font-size: 20px">Getting started</h2> | |
| 54 | <div class="panel"> | |
| 55 | <div class="panel-item"> | |
| 56 | <div> | |
| 57 | <strong>1. Register an account.</strong>{" "} | |
| 58 | Head to <a href="/register">/register</a>, pick a username, and | |
| 59 | set a password. Usernames are your public handle and appear in | |
| 60 | every repo URL. | |
| 61 | </div> | |
| 62 | </div> | |
| 63 | <div class="panel-item"> | |
| 64 | <div> | |
| 65 | <strong>2. Verify your email.</strong>{" "} | |
| 66 | We send a one-time link the first time you sign in. Verified | |
| 67 | addresses can receive issue, PR, and gate-run notifications. | |
| 68 | </div> | |
| 69 | </div> | |
| 70 | <div class="panel-item"> | |
| 71 | <div> | |
| 72 | <strong>3. Create your first repo.</strong>{" "} | |
| 73 | From the dashboard hit <strong>New repository</strong>, or | |
| 74 | visit <a href="/new">/new</a>. Pick public or private, add a | |
| 75 | README, and you're ready to clone. | |
| 76 | </div> | |
| 77 | </div> | |
| 78 | </div> | |
| 79 | </section> | |
| 80 | ||
| 81 | <section id="git-https" style="margin-bottom: 32px"> | |
| 82 | <h2 style="margin-bottom: 12px; font-size: 20px">Git over HTTPS</h2> | |
| 83 | <p style="color: var(--text-muted); margin-bottom: 12px"> | |
| 84 | HTTPS works out of the box. Authenticate with your account | |
| 85 | password or, better, a personal access token. | |
| 86 | </p> | |
| 87 | <div class="panel"> | |
| 88 | <div class="panel-item"> | |
| 89 | <div style="width: 100%"> | |
| 90 | <strong>Clone</strong> | |
| 91 | <pre | |
| 92 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 93 | > | |
| 94 | {`git clone https://<your-host>/<owner>/<repo>.git`} | |
| 95 | </pre> | |
| 96 | </div> | |
| 97 | </div> | |
| 98 | <div class="panel-item"> | |
| 99 | <div style="width: 100%"> | |
| 100 | <strong>Push</strong> | |
| 101 | <pre | |
| 102 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 103 | > | |
| 104 | {`git push origin main`} | |
| 105 | </pre> | |
| 106 | </div> | |
| 107 | </div> | |
| 108 | <div class="panel-item"> | |
| 109 | <div style="width: 100%"> | |
| 110 | <strong>Pull</strong> | |
| 111 | <pre | |
| 112 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 113 | > | |
| 114 | {`git pull origin main`} | |
| 115 | </pre> | |
| 116 | </div> | |
| 117 | </div> | |
| 118 | </div> | |
| 119 | </section> | |
| 120 | ||
| 121 | <section id="git-ssh" style="margin-bottom: 32px"> | |
| 122 | <h2 style="margin-bottom: 12px; font-size: 20px">Git over SSH</h2> | |
| 123 | <p style="color: var(--text-muted); margin-bottom: 12px"> | |
| 124 | SSH avoids typing credentials and is recommended for day-to-day | |
| 125 | work. | |
| 126 | </p> | |
| 127 | <div class="panel"> | |
| 128 | <div class="panel-item"> | |
| 129 | <div> | |
| 130 | <strong>1. Add your key.</strong>{" "} | |
| 131 | Copy your public key (usually{" "} | |
| 132 | <code>~/.ssh/id_ed25519.pub</code>) and paste it into{" "} | |
| 133 | <a href="/settings/keys">/settings/keys</a>. Keys take effect | |
| 134 | immediately. | |
| 135 | </div> | |
| 136 | </div> | |
| 137 | <div class="panel-item"> | |
| 138 | <div style="width: 100%"> | |
| 139 | <strong>2. Clone using the SSH URL.</strong> | |
| 140 | <pre | |
| 141 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 142 | > | |
| 143 | {`git clone git@<your-host>:<owner>/<repo>.git`} | |
| 144 | </pre> | |
| 145 | </div> | |
| 146 | </div> | |
| 147 | <div class="panel-item"> | |
| 148 | <div> | |
| 149 | <strong>3. Rotate or revoke</strong> any key from the same | |
| 150 | settings page — useful when a laptop walks off. | |
| 151 | </div> | |
| 152 | </div> | |
| 153 | </div> | |
| 154 | </section> | |
| 155 | ||
| 156 | <section id="import" style="margin-bottom: 32px"> | |
| 157 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 158 | Importing from GitHub | |
| 159 | </h2> | |
| 160 | <div class="panel"> | |
| 161 | <div class="panel-item"> | |
| 162 | <div> | |
| 163 | Visit <a href="/import">/import</a>, paste the source URL, and | |
| 164 | gluecron will mirror the repository — full history, branches, | |
| 165 | and tags. The mirror is a one-time copy; subsequent pushes | |
| 166 | land on gluecron, not the source. Private sources need a PAT | |
| 167 | on the source side. | |
| 168 | </div> | |
| 169 | </div> | |
| 170 | </div> | |
| 171 | </section> | |
| 172 | ||
| 173 | <section id="webhooks" style="margin-bottom: 32px"> | |
| 174 | <h2 style="margin-bottom: 12px; font-size: 20px">Webhooks</h2> | |
| 175 | <p style="color: var(--text-muted); margin-bottom: 12px"> | |
| 176 | Per-repo webhooks live at{" "} | |
| 177 | <code>/:owner/:repo/settings/webhooks</code>. Register a URL, pick | |
| 178 | events (push, issue, pr, star), and set a secret. | |
| 179 | </p> | |
| 180 | <div class="panel"> | |
| 181 | <div class="panel-item"> | |
| 182 | <div> | |
| 183 | <strong>HMAC signature.</strong>{" "} | |
| 184 | Every delivery includes{" "} | |
| 185 | <code>X-Gluecron-Signature: sha256=<hex></code>.{" "} | |
| 186 | Compute HMAC-SHA256 over the raw request body using your | |
| 187 | secret and compare in constant time. | |
| 188 | </div> | |
| 189 | </div> | |
| 190 | <div class="panel-item"> | |
| 191 | <div style="width: 100%"> | |
| 192 | <strong>Payload shape.</strong> | |
| 193 | <pre | |
| 194 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 195 | > | |
| 196 | {`{ | |
| 197 | "event": "push", | |
| 198 | "repo": { "owner": "acme", "name": "api" }, | |
| 199 | "ref": "refs/heads/main", | |
| 200 | "before": "<sha>", | |
| 201 | "after": "<sha>", | |
| 202 | "commits": [ /* ... */ ], | |
| 203 | "sender": { "username": "kit" } | |
| 204 | }`} | |
| 205 | </pre> | |
| 206 | </div> | |
| 207 | </div> | |
| 208 | <div class="panel-item"> | |
| 209 | <div> | |
| 210 | Deliveries are retried with exponential backoff; inspect the | |
| 211 | last N attempts from the webhook's settings page. | |
| 212 | </div> | |
| 213 | </div> | |
| 214 | </div> | |
| 215 | </section> | |
| 216 | ||
| 217 | <section id="tokens" style="margin-bottom: 32px"> | |
| 218 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 219 | Personal access tokens | |
| 220 | </h2> | |
| 221 | <p style="color: var(--text-muted); margin-bottom: 12px"> | |
| 222 | Tokens authenticate CLI clients, CI jobs, and scripts. Create | |
| 223 | them at <a href="/settings/tokens">/settings/tokens</a>; the value | |
| 224 | is shown once, so copy it immediately. Tokens start with{" "} | |
| 225 | <code>glc_</code>. | |
| 226 | </p> | |
| 227 | <div class="panel"> | |
| 228 | <div class="panel-item"> | |
| 229 | <div style="width: 100%"> | |
| 230 | <strong>Example: list your repos via the API.</strong> | |
| 231 | <pre | |
| 232 | style="margin: 6px 0 0; padding: 10px; background: var(--bg-muted, #0d1117); border-radius: 4px; font-size: 12px; overflow-x: auto" | |
| 233 | > | |
| 234 | {`curl -H "Authorization: Bearer glc_your_token_here" \\ | |
| 235 | https://<your-host>/api/v2/repos`} | |
| 236 | </pre> | |
| 237 | </div> | |
| 238 | </div> | |
| 239 | <div class="panel-item"> | |
| 240 | <div> | |
| 241 | Tokens can also authenticate <code>git</code> over HTTPS — use | |
| 242 | the token as the password in place of your account password. | |
| 243 | </div> | |
| 244 | </div> | |
| 245 | </div> | |
| 246 | </section> | |
| 247 | ||
| 248 | <section id="gates" style="margin-bottom: 32px"> | |
| 249 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 250 | Gates & AI review | |
| 251 | </h2> | |
| 252 | <div class="panel"> | |
| 253 | <div class="panel-item"> | |
| 254 | <div> | |
| 255 | Every push to the default branch (usually <code>main</code>) | |
| 256 | triggers a gate run: GateTest scans the diff for secrets, | |
| 257 | dependency advisories, and policy violations, while the AI | |
| 258 | reviewer reads the patch and comments on any PRs that touch | |
| 259 | the same files. Failing gates block the push by default; | |
| 260 | results appear on the commit page and in the repo's{" "} | |
| 261 | <em>Gate runs</em> tab. Configure gate policy per-repo in | |
| 262 | <strong> Settings → Gates</strong>. | |
| 263 | </div> | |
| 264 | </div> | |
| 265 | </div> | |
| 266 | </section> | |
| 267 | ||
| 2afb411 | 268 | <section id="ai-native" style="margin-bottom: 32px"> |
| 269 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 270 | AI-native flow | |
| 271 | </h2> | |
| 272 | <div class="panel"> | |
| 273 | <div class="panel-item"> | |
| 274 | <div> | |
| 275 | <strong>Issue → PR in one click.</strong> Open any issue you | |
| 276 | own and hit <em>Build with AI</em> in the header. The spec | |
| 277 | form pre-fills with the issue title + body and a{" "} | |
| 278 | <code>Closes #N</code> footer; Claude drafts the diff, opens | |
| 279 | a draft PR, and the merge auto-closes the originating issue. | |
| 280 | </div> | |
| 281 | </div> | |
| 282 | <div class="panel-item"> | |
| 283 | <div> | |
| 284 | <strong>AI-drafted PR descriptions.</strong> The new-PR form | |
| 285 | has a <em>Suggest description with AI</em> button that runs | |
| 286 | <code> generatePrSummary</code> against{" "} | |
| 287 | <code>git diff base...head</code> and fills the description | |
| 288 | with a structured summary (Why · Key changes · Test plan · | |
| 289 | Risks). | |
| 290 | </div> | |
| 291 | </div> | |
| 292 | <div class="panel-item"> | |
| 293 | <div> | |
| 294 | <strong>Auto-review on PR open.</strong> Non-draft PRs get a | |
| 295 | summary comment plus inline file/line annotations from the | |
| 296 | AI reviewer. A second comment posts label + reviewer + | |
| 297 | priority suggestions (the <em>AI Triage</em> block). All | |
| 298 | suggestions; nothing applied automatically. | |
| 299 | </div> | |
| 300 | </div> | |
| 301 | <div class="panel-item"> | |
| 302 | <div> | |
| 303 | <strong>Repo-wide AI surfaces.</strong>{" "} | |
| 304 | <a href="/help#explore">Explain</a> a codebase, run{" "} | |
| 305 | <a href="/help#explore">semantic search</a>, ask the chat | |
| 306 | anything about the repo, generate failing test stubs from a | |
| 307 | source file (the <em>Tests</em> link in the repo nav), and | |
| 308 | draft full PRs from a plain-English spec via{" "} | |
| 309 | <em>Spec to PR</em>. All require{" "} | |
| 310 | <code>ANTHROPIC_API_KEY</code>; without it the surfaces | |
| 311 | degrade gracefully to deterministic fallbacks. | |
| 312 | </div> | |
| 313 | </div> | |
| 314 | <div class="panel-item"> | |
| 315 | <div> | |
| 316 | <strong>Scheduled workflows.</strong> Drop{" "} | |
| 317 | <code>on: schedule: [{`{cron: "0 * * * *"}`}]</code> into any | |
| 318 | <code> .gluecron/workflows/*.yml</code>. The autopilot | |
| 319 | ticker fires the cron from the same node that handles your | |
| 320 | pushes — no external scheduler needed. | |
| 321 | </div> | |
| 322 | </div> | |
| 323 | </div> | |
| 324 | </section> | |
| 325 | ||
| 80bed05 | 326 | <section id="shortcuts" style="margin-bottom: 32px"> |
| 327 | <h2 style="margin-bottom: 12px; font-size: 20px"> | |
| 328 | Keyboard shortcuts | |
| 329 | </h2> | |
| 330 | <div class="panel"> | |
| 331 | <div class="panel-item"> | |
| 332 | <div> | |
| 333 | gluecron ships a full keyboard-first mode — see{" "} | |
| 334 | <a href="/shortcuts">/shortcuts</a> for the complete cheat | |
| 335 | sheet. Press <code>?</code> on any page to pop the overlay. | |
| 336 | </div> | |
| 337 | </div> | |
| 338 | </div> | |
| 339 | </section> | |
| 340 | ||
| 341 | <section id="api" style="margin-bottom: 32px"> | |
| 342 | <h2 style="margin-bottom: 12px; font-size: 20px">API</h2> | |
| 343 | <div class="panel"> | |
| 344 | <div class="panel-item"> | |
| 345 | <div> | |
| 346 | Full REST + GraphQL reference lives at{" "} | |
| 347 | <a href="/api/docs">/api/docs</a>. The GraphQL explorer is at{" "} | |
| 348 | <a href="/api/graphql">/api/graphql</a>. | |
| 349 | </div> | |
| 350 | </div> | |
| 351 | </div> | |
| 352 | </section> | |
| 353 | ||
| 354 | <p | |
| 355 | style="color: var(--text-muted); font-size: 13px; margin-top: 40px; padding-top: 16px; border-top: 1px solid var(--border)" | |
| 356 | > | |
| 357 | Something missing? Open an issue on gluecron's source repo. | |
| 358 | </p> | |
| 359 | </div> | |
| 360 | </Layout> | |
| 361 | ); | |
| 362 | }); | |
| 363 | ||
| 364 | export default help; |