CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
dxt.ts
Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.
| cd4f63b | 1 | /** |
| 2 | * BLOCK Q1 — Claude Desktop (.dxt) extension download endpoint. | |
| 3 | * | |
| 4 | * GET /gluecron.dxt → serves public/gluecron.dxt | |
| 5 | * | |
| 6 | * The `.dxt` bundle is built by `scripts/build-dxt.sh`. If the build hasn't | |
| 7 | * been run (file missing), we return a friendly 404 JSON payload pointing | |
| 8 | * at the build step + the curl-pipe install fallback — never crash the | |
| 9 | * page or 500. | |
| 10 | * | |
| 11 | * Coexists with `scripts/install.sh` (Block L2). The .dxt is the GUI sibling | |
| 12 | * for non-CLI users; the install.sh path remains for terminal users. | |
| 13 | */ | |
| 14 | ||
| 15 | import { Hono } from "hono"; | |
| 16 | import { existsSync, statSync } from "node:fs"; | |
| 17 | import { join } from "node:path"; | |
| 18 | ||
| 19 | const dxt = new Hono(); | |
| 20 | ||
| 21 | const DXT_PATH = join(process.cwd(), "public", "gluecron.dxt"); | |
| 22 | ||
| 23 | dxt.get("/gluecron.dxt", (c) => { | |
| 24 | if (!existsSync(DXT_PATH)) { | |
| 25 | return c.json( | |
| 26 | { | |
| 27 | error: "extension_not_built", | |
| 28 | message: | |
| 29 | "Gluecron .dxt bundle has not been built on this server yet. Run `bash scripts/build-dxt.sh` or install via the CLI fallback: `curl -sSL https://gluecron.com/install | bash`.", | |
| 30 | fallback: "https://gluecron.com/install", | |
| 31 | }, | |
| 32 | 404 | |
| 33 | ); | |
| 34 | } | |
| 35 | ||
| 36 | const stat = statSync(DXT_PATH); | |
| 37 | const file = Bun.file(DXT_PATH); | |
| 38 | ||
| 39 | return new Response(file.stream(), { | |
| 40 | headers: { | |
| 41 | // .dxt is a registered extension, but Anthropic has not (yet) published | |
| 42 | // a canonical MIME type. octet-stream is the safe default — the | |
| 43 | // Content-Disposition forces the OS to treat it as a file download | |
| 44 | // which Claude Desktop's "Open With" hook can then claim. | |
| 45 | "Content-Type": "application/octet-stream", | |
| 46 | "Content-Disposition": 'attachment; filename="gluecron.dxt"', | |
| 47 | "Content-Length": String(stat.size), | |
| 48 | // Short cache window so deploys-with-new-bundle propagate within an | |
| 49 | // hour. Public so CDNs / browser caches can hold it. | |
| 50 | "Cache-Control": "public, max-age=3600", | |
| 51 | }, | |
| 52 | }); | |
| 53 | }); | |
| 54 | ||
| 55 | export default dxt; |