5 Commits
Author SHA1 Message Date
Kevin Codex 1f25242207 chore(hosts): move the explorer to explorer.twigpine.com
The explorer, its docs and its agent files now name explorer.twigpine.com
and node / node2 / node3.twigpine.com, and the proxy rules call the nodes
by those names. explorer.gitlawb.com forwards pages to the new address;
the API proxy, llms.txt, skill.md and the raw docs keep answering there.
The Manila node keeps its current address, and the documented node default
for ICAPTCHA_URL is unchanged because it is the value the node ships with.
2026-10-13 15:51:30 +08:00
Kevin Codex 2d873b3914 feat: serve raw markdown to text clients on /docs and repo pages
Clients that don't advertise text/html in Accept (curl, AI agents,
scripts) got an empty SPA shell from /docs, /docs/:slug, and
/repos/:owner/:name — the advertised agent entry points were blank
without JavaScript. Negotiate on the Accept header: text clients now
get the section's raw markdown (or a generated index for the docs hub)
and a markdown repo summary with the clone URL, owner DID, recent
signed push certificates, and raw node-API links.

Social and search crawlers send wildcard Accept headers too, so a UA
allowlist keeps serving them the meta-tagged HTML shell — link preview
cards are unaffected. All negotiated responses carry
Vary: Accept, User-Agent.
2026-08-17 16:11:52 +08:00
Kevin Codex 35ffdfae80 fix: ESM-proof the api function imports; inline the OG layout
Follow-up to the repoSocial move — two more tracer/runtime mismatches
kept api/og crashing:

- The package is type:module, so compiled functions run as Node ESM and
  extensionless relative specifiers never resolve. All cross-file api
  imports now carry explicit .js extensions (TS, Vite, and vitest all
  resolve .js -> .ts natively).
- The tracer maps .js specifiers to .ts sources but not .tsx, so an
  imported .tsx module is silently dropped from the bundle. og-layout is
  inlined into the og.tsx entrypoint (entrypoint .tsx compiles fine);
  its exports remain for the tests.

Verified against a local vercel build: both compiled functions import
cleanly under node --input-type=module, and GET on og.js renders a real
200 image/png including the traced JetBrains Mono TTFs.
2026-07-22 14:01:39 +08:00
Kevin Codex 04e8e8be6d fix: move repoSocial into api/_lib so Vercel functions can import it
Both api/repo-page and api/og crashed in production with
ERR_MODULE_NOT_FOUND on /var/task/src/lib/repoSocial: Vercel compiles
TypeScript under api/ only, so a function importing ../src/lib/* ships
an import specifier the Node runtime can't resolve — and the
/repos/:owner/:name rewrite meant every direct repo-page load 500'd.
The module was already runtime-agnostic by design; it now lives in
api/_lib with the browser hook importing across, and tsconfig.api's
src special-case is gone.
2026-07-22 13:54:57 +08:00
Kevin Codex c682af2e9e feat: per-repo social metadata — SSR share pages + dynamic OG images
Crawler-visible metadata for /repos/:owner/:name without turning the SPA
into an SSR app: a Vercel function fetches the built index.html, swaps
the marker-delimited social-meta block for repo-specific tags, and a
sibling function renders per-repo OG cards with @vercel/og (JetBrains
Mono TTFs; Satori can't consume WOFF2). Private repos and upstream
errors always get the generic site metadata plus noindex — repository
data is never interpolated on those paths. The client hook keeps
document meta in sync during SPA navigation, and the /api proxy narrows
to /api/v1 so local functions are reachable. Cache tiers: immutable
versioned OG URLs, 5m/1h SWR for pages, no-store on errors.
2026-07-22 12:48:19 +08:00