Surface the repo from the nav, docs and org profile (Tier 0)#790
Merged
Conversation
The repo measured FOUR unique visitors in fourteen days. Nothing on any
surface we own referred anyone to it: the www navigation carried no GitHub
link at all, and the one link in the docs pointed at the ORG page — a repo
list with no star button on it. This is the Tier 0 half of
internal/marketing/github-stars-strategy.md: it does not create demand, it
stops us discarding the demand we already have.
- www nav: a GitHub mark in the desktop bar and a labelled row at the end of
the phone menu, from a single `REPO_LINK` that is a member of
ALL_NAV_DESTINATIONS — so the existing mobile-parity guard covers it and the
two surfaces cannot drift. New nav.test.tsx pins presence, target and a11y.
No star count: a bar announcing a small number converts a neutral visit into
a negative one on every page view. That is a decision, and the test says so.
- docs.json: a first-class `{"type":"github"}` navbar link, and
footer.socials.github moved from the org to the repo.
- docs-nav-guard gains collectRepoLinkIssues(), which WALKS the config rather
than checking the two fields we know about today — a curated list would only
ever report on the list. It exempts seo.organization.sameAs, keyed on what
the guard means (clickable links) rather than on the field that tripped it:
for an Organization node the org profile IS the correct identity. A test
pins that the exemption stays narrow.
- release-cli: `--latest` on release creation. Releases are drafts published
by hand and the publish dialog has its own checkbox, so the flag was a human
decision every time. It went wrong once, silently: the sidebar advertised
wbhk 0.4.0 as Latest for six days while npm served 0.6.0. Already corrected
on the published release; this stops it recurring.
- README: a star ask, a pointer at the good-first-issue label, and a link to a
new CODE_OF_CONDUCT.md (Contributor Covenant 2.1).
Deliberately NOT shipped: .github/FUNDING.yml. This is a commercial
open-core product, not a donation-funded project, and a Sponsor button would
misrepresent the model.
Gate: lint, typecheck, test (29 tasks), build all green. Repo link verified
present in the built static HTML.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016XkxpR5GKp98W5qq2cgsSt
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
The signature registry is the most differentiated open-source thing this repo has and the only part of it that is useful to someone who will never buy the product. It was `private: true` and unpublished, while the CLI and the SDK were both on npm. This is Option B of internal/marketing/github-stars-strategy.md: a starrable artifact that needs no self-host path. It is NOT a repo split — that verdict stands (a bare data repo in this category tops out around a dozen stars). Distribution changes; stars still land on webhook-co/webhook. THE DEFECT THIS UNCOVERED: the build output did not load. `tsc` emits the source's extensionless relative specifiers verbatim (`from "./scheme"`), which TypeScript resolves and Node's ESM loader does not — `npm i` then ERR_MODULE_NOT_FOUND on the first import. Invisible for as long as the package was private, because all five workspace consumers import `src/` and bundle it. Build is now tsup (dual ESM + CJS + bundled declarations), same as the SDK, for the same reason. Entry points stay on `src/` in the committed manifest so those five consumers keep resolving TypeScript; the rewrite to `dist/` lives in `publishConfig`. That replacement is a PNPM feature — `npm publish` ignores it and would upload TypeScript to the registry — so the release workflow uses `pnpm publish`, and the packaged smoke test asserts the rewrite actually happened. - scripts/webhooks-spec-packaged-smoke.mjs: packs, installs the tarball, imports it via BOTH `import` and `require`, and makes it verify a real GitHub signature — plus the negative cases (wrong secret, tampered body). Written after an earlier draft asserted the wrong result shape and made those negatives vacuous: the result is a union on `ok`, not a status string. - .github/workflows/release-webhooks-spec.yml: tag-triggered, gated on a real tag push + NPM_TOKEN, publishes with OIDC provenance. - A package README pitched at someone who has never heard of us, and a standalone-library section in the root README. Verified: 141 providers and 141 adapters at runtime from the built ESM; both README examples executed and round-tripped (sign → verify → wrong-secret rejected); 17/17 packaged-artifact checks pass. Full gate green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016XkxpR5GKp98W5qq2cgsSt
The release workflow is tag-triggered, so its packaged smoke would only ever run at publish time — the point at which finding a broken tarball is most expensive. This package has already shipped an unloadable dist/ once (tsc emits extensionless relative specifiers; nothing ever loaded the build because every workspace consumer imports src/), so the check belongs on every PR, mirroring the SDK's. It also pins that the PACKED manifest points at dist/ and not at TypeScript source. That rewrite comes from publishConfig and is applied by pnpm only; npm publish ignores it. If the release path is ever switched to plain npm, this fails instead of TypeScript reaching the registry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016XkxpR5GKp98W5qq2cgsSt
… regex CodeQL flagged the new end-to-end assertion in docs-nav-guard.test.mjs as js/regex/missing-regexp-anchor (high): an unanchored /github\.com\/…/ used against a URL matches anywhere, so arbitrary hosts can straddle it. The assertion was never validating a URL — it checks that the serialized navbar CONTAINS the repo link, so the deepEqual above it is not passing vacuously. Written as a regex it claimed to be doing host matching. A substring check says what it means and the rule no longer applies. The guard's own URL matcher is unchanged and was already anchored (/^https?:\/\/(?:www\.)?github\.com\/…/) — that is where anchoring is load-bearing, and it is the reason a third-party GitHub URL is correctly ignored rather than policed. 25/25 guard tests still pass; lint green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016XkxpR5GKp98W5qq2cgsSt
choraria
marked this pull request as ready for review
July 24, 2026 10:00
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The repo measured four unique visitors in fourteen days. Nothing on any surface we own referred anyone to it — the
wwwnavigation carried no GitHub link at all, and the one link in the docs pointed at the org page, which is a repo list with no star button on it.This is the Tier 0 half of
internal/marketing/github-stars-strategy.md. It does not create demand; it stops us discarding the demand we already have.What's here
wwwnav — a GitHub mark in the desktop bar and a labelled row at the end of the phone menu, both from a singleREPO_LINKthat is a member ofALL_NAV_DESTINATIONS, so the existing mobile-parity guard covers it and the two surfaces cannot drift. Newnav.test.tsxpins presence, target and a11y.No star count, deliberately. A bar announcing a small number converts a neutral visit into a negative one on every page view. There is a test that says so, so the decision survives the next person who reaches for a widget.
docs.json— a first-class{"type": "github"}navbar link, andfooter.socials.githubmoved from the org to the repo. Docs is our only surface with measured search impressions.docs-nav-guardgainscollectRepoLinkIssues(), which walks the config rather than checking the two fields we know about today — a curated list would only ever report on the list. It exemptsseo.organization.sameAs, keyed on what the guard means (clickable links) rather than on the field that tripped it: for anOrganizationnode the org profile genuinely is the correct identity, andapps/www's JSON-LD asserts the same URL. A test pins that the exemption stays narrow.release-cli—--lateston release creation. Releases are drafts published by hand and the publish dialog carries its own checkbox, so the flag was a human decision every time. It went wrong once, silently: the sidebar advertisedwbhk 0.4.0as Latest for six days while npm served0.6.0, which reads to a first-time visitor as an abandoned project. Already corrected on the published release; this stops it recurring.README — a star ask, a pointer at the
good first issuelabel, and a link to a newCODE_OF_CONDUCT.md(Contributor Covenant 2.1, enforcement at the existinghello@webhook.co).Shipped outside this PR
webhook-co/.githubcreated with a profile README —github.com/webhook-cowas a bare repo list, and it is where the docs footer used to send people. The empty org description is filled too.good first issue: add a provider signature adapter) and Ingest edge returns 403 to stdlib Python (Python-urllib UA), masking a valid token #789 (the stdlib-Python 403, re-verified reproducing today).Deliberately not shipped
.github/FUNDING.yml. This is a commercial open-core product, not a donation-funded project; a Sponsor button would misrepresent the model, and enabling Sponsors is a financial setup on the founder's account. Cal.com, Dub and Documenso carry no donation button either.Verification
pnpm lint,pnpm typecheck,pnpm test(29 tasks),pnpm buildall exit 0. The repo link is verified present in the built static HTML (apps/www/out/index.html), anddocs-nav-guardpasses on the realdocs.json— with its new check proven to fail on the old value first.🤖 Generated with Claude Code
https://claude.ai/code/session_016XkxpR5GKp98W5qq2cgsSt
Also here:
@webhook-co/webhooks-specis now publishable (Option B)The 141-provider signature registry is the most differentiated open-source thing in this repo and the only part of it useful to someone who will never buy the product. It was
private: trueand unpublished, while the CLI and the SDK were both on npm.This is not a repo split — that verdict stands (a bare data repo in this category tops out around a dozen stars). Only distribution changes; stars still land here.
The defect this uncovered
The build output did not load.
tscemits the source's extensionless relative specifiers verbatim (from "./scheme"), which TypeScript resolves and Node's ESM loader does not.npm i @webhook-co/webhooks-specwould have thrownERR_MODULE_NOT_FOUNDon the first import, with a green test suite behind it — invisible for as long as the package was private, because all five workspace consumers importsrc/and bundle it.Build is now
tsup(dual ESM + CJS + bundled declarations), same as the SDK, for the same reason.The pnpm/npm trap, and the guard in front of it
Entry points stay on
src/in the committed manifest so those five consumers keep resolving TypeScript; the rewrite todist/lives inpublishConfig. That replacement is a pnpm feature —npm publishignores it and would upload TypeScript to the registry. So the release workflow usespnpm publish, and the packaged smoke test asserts the rewrite actually happened. Switch the publish path to plain npm and the smoke fails instead of shipping.Verification
scripts/webhooks-spec-packaged-smoke.mjspacks, installs the tarball, imports it via bothimportandrequire, and makes it verify a real GitHub signature — plus the negative cases. 17/17 checks pass.An earlier draft of that test asserted the wrong result shape (
status === "verified"); the result is a discriminated union onok, soundefined !== "verified"made both negative cases vacuous. Fixed, and the comment records why.Also verified: 141 providers and 141 adapters at runtime from the built ESM (the README's claim, checked rather than asserted), and both README examples executed end to end — sign → verify → wrong-secret rejected.
Publishing
.github/workflows/release-webhooks-spec.ymlis tag-triggered (webhooks-spec-vX.Y.Z), gated on a real tag push andNPM_TOKEN, and publishes with OIDC provenance. Nothing is published by merging this PR — the first publish is a deliberate tag push, and the README is the npm landing page, so it's worth an eyeball first.