Phase H: distribution — GoReleaser, install script, landing + docs site#11
Conversation
- Add .goreleaser.yaml (v2): cross-platform build matrix (linux/darwin/windows × amd64/arm64), tar.gz/zip archives with LICENSE+README, SHA-256 checksums, and the version ldflags matching the symbol the Makefile already injects so a released binary reports its tag. - Sign the checksums file with cosign in keyless mode (no key to manage; verifiable via GitHub OIDC certificate identity). - Add Homebrew (brews) and Scoop (scoops) blocks publishing to the separate nixrajput/homebrew-siphon and nixrajput/scoop-siphon repos; skip_upload: auto so the core release succeeds even before those repos / push tokens exist. - Add .github/workflows/release.yml: tag-triggered (v*), pins GoReleaser ~> v2, installs cosign, grants contents:write + id-token:write. The tap-token env vars resolve to "" when their secrets are unset, so a first release without taps does not error. - Config is reviewed but not run locally (goreleaser/cosign not installed here); the release workflow is the executing check.
- Add scripts/install.sh: curl|sh installer that detects OS/arch (mapped to GoReleaser's archive naming), resolves the latest release tag (or a pinned SIPHON_VERSION), downloads the matching archive AND checksums.txt, verifies the archive's SHA-256 before extracting, and installs to /usr/local/bin (or SIPHON_INSTALL_DIR), escalating with sudo only if the target dir isn't writable. - Refuses to install on a checksum mismatch — integrity is verified before any binary lands on disk. - POSIX sh (curl-or-wget, sha256sum-or-shasum); shellcheck-clean. Verify/tamper logic exercised against a fixture.
- Scaffold a Next.js 15 App-Router app in web/ (TypeScript, Tailwind), hand-authored (no create-next-app template cruft), deployed by Vercel from the web/ root. - Add the docs pipeline (lib/docs.ts): reads the repo's own ../docs/*.md at build time and renders them as /docs/<slug> pages — single source of truth, so the site can't drift from the code repo's docs. A nav map orders the seven concept docs; each page is statically generated via generateStaticParams. The repo docs' own "Table of contents" section is stripped (the site supplies its own nav). - Render via react-markdown + remark-gfm (tables) + rehype-slug (anchor links) + rehype-highlight (code). Placeholder landing + docs index pages; bespoke design lands next. - Verified: npm install + npm run build green; all 7 docs pages prerendered from the Markdown. Note params is awaited (Next 15 made it a Promise). web/ carries its own .gitignore; the Go module ignores it.
- Build the bespoke UI on a "pipe / liquid flow" design thesis: a deep slate base (not generic near-black), a two-tone teal→cyan accent used only on connective/flow elements, amber reserved for the single install action, and monospace as the structural voice (eyebrows, labels, the command transcript) — true to a terminal tool's world. - Hero is the product's own artifact: a syntax-true siphon session (backup → sync → cdc), laid out left→right to mirror `siphon src dst`. - Signature element: a thin animated teal→cyan "flow line" down the feature stream, evoking data moving through a siphon (stilled under prefers-reduced-motion). - Feature cards state siphon's real capabilities in the engineer's terms; install section leads with the amber copy-to-clipboard curl|sh widget (brew + scoop alongside). Docs get a sidebar shell + styled .prose reader for the repo Markdown (tables, code, blockquotes). - Quality floor met + verified: AA text contrast (muted 5.27:1), visible focus outlines, responsive to mobile. Built, linted, and screenshot-reviewed; docs pages render the real repo Markdown.
- README: replace the build-from-source-only Install section with the install script, Homebrew, Scoop, and signed-binary methods (source kept as an option); update the Phase H roadmap row and requirements. - Add web/README.md: develop/build instructions and the owner provisioning checklist (tag v1.0.0, create the tap repos + tokens, Vercel setup) — the account-level steps that publishing depends on. - CHANGELOG: Phase H entry (GoReleaser, release workflow, taps, install script, web site). - golangci-lint: exclude web/ so the JS subtree's vendored stray .go files (node_modules/flatted/golang) don't trip the Go linters; keeps the Go and JS toolchains' checks cleanly separated.
|
Warning Review limit reached
More reviews will be available in 42 minutes and 41 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThis PR adds GitHub issue and pull request templates, a release workflow with GoReleaser and cosign, a checksum-verifying install script, updated release/install documentation, and a Next.js web app that serves the landing page and build-time-rendered docs. ChangesRelease and intake flow
Web docs site
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- release.yml: add a validate gate (go test + golangci-lint + goreleaser check) that the release job depends on, so a broken tag never publishes. Add workflow_dispatch that runs a snapshot dry-run (build everything, publish nothing) to rehearse a release. Scope write/id-token permissions to the release job only; the gate runs read-only. - Add .github/ISSUE_TEMPLATE: a structured bug report (version, engine, OS, exit code) and feature request (problem/proposal/area), plus a config.yml routing questions to Discussions and security reports to the security policy. - Add a PR template with a verification checklist matching the project's discipline (test, lint, integration, docs/CHANGELOG, web build).
- Add two entry-point docs the site was missing: GETTING_STARTED.md (install → profile → backup → verify → restore → sync, with the exit- code taxonomy) and CONFIGURATION.md (the full config-file schema: defaults, profiles, secret refs, storage, retention, audit, telemetry, secrets, groups). Both are grounded in the README + config structs and flow into the site via the existing docs pipeline (nav updated; they lead the sidebar). - Add deliberate, on-thesis motion: a staggered hero load-in (rise) and scroll-revealed feature cards (Reveal), reinforcing the top-to-bottom "flow" metaphor — not scattered effects. The existing flow-line stays the signature. - Reveal is a progressive enhancement: SSR renders content visible, and JS only then arms the hidden→reveal behavior, so no-JS and reduced-motion users never get invisible content (verified: feature text present in SSR HTML; reduced-motion screenshot shows full resting state). npm build + lint green; 9 docs pages prerender.
There was a problem hiding this comment.
Actionable comments posted: 13
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Around line 27-39: The release workflow uses mutable action tags and default
checkout credentials, so harden it by pinning every action in the release job to
an immutable commit SHA instead of `@v`* references. Update both checkout uses to
disable persisted credentials by setting persist-credentials to false in each
checkout step, and apply the same pinning/credential hardening to the other
actions in this workflow such as setup-go, golangci-lint-action, and
goreleaser-action.
- Around line 30-33: The release workflow is using a მოძრable Go toolchain via
actions/setup-go@v6 with go-version: stable, which can make builds and go mod
tidy behavior non-reproducible. Update both setup-go steps in the validate and
release jobs to use a fixed version source by switching to go-version-file:
go.mod, or pinning to the exact Go version declared in go.mod, so the workflow
always builds with the same toolchain.
In @.goreleaser.yaml:
- Around line 12-15: The release configuration currently runs go mod tidy in the
before hooks, which mutates module files during builds. Remove that hook from
the goreleaser setup and keep the release path read-only, then enforce tidy in
CI by checking for go.mod/go.sum diffs instead. Use the before.hooks section in
the goreleaser config as the place to update.
In `@README.md`:
- Around line 59-63: The README install section is inconsistent with the current
release state and exposes multiple installer entrypoints; update the install
copy to explicitly note that the install script, Homebrew, and Scoop are only
available after the first v1.0.0 release/provisioning, and standardize all
references to a single canonical installer URL. Use the Distribution/Install
wording in README.md and the install script references in scripts/install.sh to
keep the documented URL and availability status aligned.
- Line 101: The README’s cosign verification guidance is too weak for keyless
signing because it does not pin the signer identity or OIDC issuer. Update the
existing `cosign verify-blob` instructions to include `--certificate-oidc-issuer
"https://token.actions.githubusercontent.com"` and `--certificate-identity` for
the exact GitHub Actions workflow path used by releases, alongside the current
`checksums.txt`, `checksums.txt.sig`, and `checksums.txt.pem` references. Use
the release workflow name and branch from this repo so the `cosign verify-blob`
step verifies the trusted repository workflow specifically.
In `@scripts/install.sh`:
- Around line 78-86: The installer currently trusts checksums.txt without
authenticating it, so update scripts/install.sh to fetch checksums.txt.sig and
checksums.txt.pem alongside checksums.txt, then verify the downloaded checksum
file with cosign verify-blob before using it. Use the existing download flow
around $DL_O and the checksum validation block to ensure the signature check
succeeds first, then continue with the current expected/actual archive checksum
comparison only after authenticated verification passes.
In `@web/.gitignore`:
- Line 5: Remove the ignore entry for next-env.d.ts from web/.gitignore and
ensure the generated next-env.d.ts is committed so it matches the include
contract in web/tsconfig.json; verify the change around the next-env.d.ts rule
and keep the tsconfig include list pointing at the committed file.
In `@web/app/globals.css`:
- Around line 110-120: The `.reveal` base state currently hides content until
`.is-in` is added by JavaScript, which can leave sections invisible if JS never
runs. Update the `globals.css` reveal styles so the default `.reveal` rule stays
visible, and move the hidden pre-animation state into a JS-ready/initialization
class that is only applied after `IntersectionObserver` is active. Keep the
existing `.reveal.is-in` transition behavior, but ensure `reveal` content
renders safely without relying on client JS.
In `@web/app/page.tsx`:
- Around line 108-110: The install section anchor is being hidden behind the
sticky header when navigating to `#install` from SiteHeader or the hero link.
Update the install section element in page.tsx to include a scroll
offset/scroll-margin-top so the section title lands below the header chrome. Use
the existing install section container in the page component to apply the fix
consistently for both anchor links.
In `@web/components/InstallCommand.tsx`:
- Around line 3-19: The InstallCommand copy flow is scheduling a new timeout on
every click without clearing the previous one, so an older timer can reset the
copied state too early. Update the InstallCommand component’s copy handler to
track the timeout handle, clear any existing timer before setting a new one, and
clean it up on unmount so repeated clicks always keep the label in sync.
In `@web/components/Markdown.tsx`:
- Around line 10-14: The Markdown renderer in ReactMarkdown is leaving
repository .md links untouched, so relative filenames like CONFIGURATION.md
resolve to broken /docs/*.md URLs instead of clean doc slugs. Update the anchor
rendering via the components prop in Markdown.tsx and add/use a helper like
resolveDocHref in web/lib/docs.ts to map markdown filenames through the existing
NAV configuration to /docs/[slug], while preserving any hash fragment. Make sure
the custom link renderer falls back gracefully for non-doc links.
In `@web/components/Reveal.tsx`:
- Around line 22-42: The Reveal component’s useEffect in Reveal.tsx should not
add the hidden `.reveal` state unless `IntersectionObserver` is available;
currently `setArmed(true)` runs before the observer is created, which can leave
content invisible in browsers/webviews that lack the API. Add a guard in the
same effect around the `IntersectionObserver` setup (and before arming) so
unsupported environments keep the server-rendered visible state, while the
existing reduced-motion early return remains unchanged.
In `@web/components/Terminal.tsx`:
- Around line 30-46: The Terminal component is rendering block-level <div>
elements inside the <pre>, which can break SSR hydration. Update the SESSION
mapping in Terminal.tsx to avoid block children under <pre> by using inline
elements such as <code> with <span> wrappers, or render the content as plain
text with newline separators. Keep the existing line-kind branching for cmd,
out, and flow while changing the markup structure.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8d68d179-10c9-4ae6-9a98-a4f8023b1e28
⛔ Files ignored due to path filters (1)
web/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (32)
.github/ISSUE_TEMPLATE/bug_report.yml.github/ISSUE_TEMPLATE/config.yml.github/ISSUE_TEMPLATE/feature_request.yml.github/pull_request_template.md.github/workflows/release.yml.golangci.yml.goreleaser.yamlCHANGELOG.mdREADME.mddocs/CONFIGURATION.mddocs/GETTING_STARTED.mdscripts/install.shweb/.eslintrc.jsonweb/.gitignoreweb/README.mdweb/app/docs/[slug]/page.tsxweb/app/docs/layout.tsxweb/app/docs/page.tsxweb/app/globals.cssweb/app/layout.tsxweb/app/page.tsxweb/components/InstallCommand.tsxweb/components/Markdown.tsxweb/components/Reveal.tsxweb/components/SiteHeader.tsxweb/components/Terminal.tsxweb/lib/docs.tsweb/next.config.mjsweb/package.jsonweb/postcss.config.mjsweb/tailwind.config.tsweb/tsconfig.json
- web/Markdown: rewrite in-repo .md cross-links to /docs/<slug> routes (resolveDocHref in lib/docs). The new docs cross-link each other by filename, which would otherwise 404 as /docs/FILE.md — now verified to resolve to clean slugs with no .md links left. - web/Terminal: render block <span>s inside <pre>, not <div>s — a <pre> auto-closes before a block child, desyncing SSR/hydration on the hero. - web/Reveal: guard for missing IntersectionObserver before arming the hidden state, so unsupported browsers keep the visible server render. - web/InstallCommand: track + clear the copy-reset timer (a rapid second click no longer resets the label early; cleared on unmount). - web/page: scroll-mt on #install so the sticky header doesn't cover it. - release.yml: pin Go via go-version-file: go.mod (reproducible) and set persist-credentials: false on checkouts. - goreleaser: drop the `go mod tidy` before-hook so the release path is read-only (builds from the committed dependency graph). - README: note install methods go live with v1.0.0, standardize the install URL, and pin the cosign verify command to the OIDC issuer + signer identity (a bare verify-blob accepts any Fulcio cert). - install.sh: when cosign is present, verify checksums.txt's keyless signature before trusting it (checksum-only fallback otherwise). - Commit next-env.d.ts (tsconfig includes it); stop gitignoring it.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/install.sh`:
- Around line 87-98: Fail closed in the install script’s provenance verification
and tighten the signer identity check. In scripts/install.sh, update the
checksums verification flow so missing .sig/.pem assets cause an error via err
instead of falling back to checksum-only verification, since the release should
always provide them. Also narrow the cosign --certificate-identity-regexp in the
verification block to the specific release workflow and tag pattern rather than
accepting any workflow and any tag, keeping the trust boundary pinned to the
intended signer.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 27385d1f-08ca-4abc-8b6a-e457502e37fc
📒 Files selected for processing (13)
.github/workflows/release.yml.goreleaser.yamlREADME.mdscripts/install.shweb/.gitignoreweb/app/globals.cssweb/app/page.tsxweb/components/InstallCommand.tsxweb/components/Markdown.tsxweb/components/Reveal.tsxweb/components/Terminal.tsxweb/lib/docs.tsweb/next-env.d.ts
✅ Files skipped from review due to trivial changes (2)
- web/next-env.d.ts
- README.md
🚧 Files skipped from review as they are similar to previous changes (7)
- web/components/Markdown.tsx
- web/components/InstallCommand.tsx
- web/components/Terminal.tsx
- web/components/Reveal.tsx
- web/app/page.tsx
- .goreleaser.yaml
- web/app/globals.css
- When cosign is present, a missing checksums.txt.sig/.pem is now a hard error, not a downgrade to checksum-only — the release pipeline always produces those assets, so their absence means a tampered/malformed release. Checksum-only remains the fallback ONLY when cosign is absent. - Pin the exact signer identity (this repo's release.yml at the tag being installed) instead of a broad workflow/tag regex.
- Add Prettier with the tailwind plugin, a .prettierrc, and format/format:check scripts to the web app. - Add lint:fix and align web scripts with the standard layout (app/components/lib), mirroring the reference project. - Add a committed .githooks/pre-push that runs lint + format check and blocks the push on failure; change-aware so it skips when no web/ files changed. - Add Makefile targets: hooks (enable core.hooksPath), web-lint, and web-format.
- Revamp the hero with a live latest-version pill, star count, in-section install, and an ambient flow-grid backdrop. - Rebuild the top nav as active-route-aware with a sliding underline, version badge, and a responsive mobile menu. - Add home sections: a source-to-target pipeline, an engines strip, and a "built by" section with live GitHub stats. - Rebuild the docs Overview into a grouped, info-rich index with descriptions, a quick start, and active sidebar links. - Add a full developer/copyright footer and reduce repeated portfolio links across the site. - Open external links in a new tab; keep internal links in the same tab. - Add SEO: canonical, OpenGraph/Twitter cards, JSON-LD, sitemap, robots, OG image, and favicon for siphon.nixrajput.com. - Fetch GitHub data through a cached, deduped layer with loading skeletons and graceful degradation on rate limits. - Declare CSS side-effect imports so editor type-checks pass.
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (1)
web/components/ExtLink.tsx (1)
4-11: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winPreserve the component’s external-link safety contract.
Line 11 spreads
restaftertarget="_blank"/rel="noopener noreferrer", so a caller can override those values and silently drop the protection this helper is supposed to guarantee.hrefis also optional inReact.AnchorHTMLAttributes, which weakens the API contract for a component that only makes sense with a real URL.Suggested fix
+type ExtLinkProps = Omit< + React.AnchorHTMLAttributes<HTMLAnchorElement>, + "href" | "target" | "rel" +> & { + href: string; +}; + export function ExtLink({ href, className, children, ...rest -}: React.AnchorHTMLAttributes<HTMLAnchorElement>) { +}: ExtLinkProps) { return ( - <a href={href} target="_blank" rel="noopener noreferrer" className={className} {...rest}> + <a {...rest} href={href} target="_blank" rel="noopener noreferrer" className={className}> {children} </a> ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/components/ExtLink.tsx` around lines 4 - 11, The ExtLink component currently lets callers override target and rel by spreading rest after the নিরাপ safe external-link defaults, and its props still allow an optional href. Update ExtLink so the enforced external-link attributes stay fixed even if extra anchor props are passed, and tighten the component props to require a real href. Use the ExtLink function signature and the anchor render in the component to keep the safety contract intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.githooks/pre-push:
- Around line 25-35: The pre-push hook’s range calculation in the remote-base
check is failing open when origin/main is unavailable locally, because falling
back to a single commit makes git diff inspect the working tree instead of the
pushed commits. Update the logic around the range assignment and the subsequent
git diff/grep gate so that the hook fails closed when the remote base ref cannot
be resolved, rather than using "$local_sha" as a fallback.
In `@web/app/docs/page.tsx`:
- Around line 21-24: Soften the docs copy in the page component that renders the
docs intro, since the current claim that the pages “always match the version you
installed” is too strong. Update the paragraph in the docs page render to
reflect that it shows repository Markdown and may track the latest source rather
than the exact installed binary, especially given the install flow that pulls
from main and defaults to the latest release. Use the existing docs page
component and its intro paragraph as the location to adjust the wording.
In `@web/app/globals.css`:
- Around line 24-26: The font stack declarations in the global stylesheet are
triggering Stylelint’s value-keyword-case rule because several font names in the
root variables use capitalized keywords. Update the font family lists in the
global font variables to use lowercase font names consistently, or adjust the
Stylelint rule only for font lists if that’s the intended convention. Focus on
the declarations for the sans and mono font variables.
In `@web/app/page.tsx`:
- Line 200: The install CTA is using INSTALL_CMD, which points at a mutable
main-branch installer instead of an immutable release reference. Update the
source of truth for INSTALL_CMD so it points to a release asset or is pinned to
the specific tag/commit being documented, and ensure both InstallCommand and
HeroInstall continue to consume the same fixed value.
- Around line 217-219: The release copy in page.tsx overstates what is signed:
it implies each archive has its own cosign signature. Update the wording in the
release/download text near the signed binary mention to clarify that the
archives include SHA-256 checksums and the checksum file is cosign-signed, using
the relevant JSX content around the ExtLink/Releases section.
In `@web/components/githubCache.ts`:
- Around line 61-76: Add a timeout/deadline to the fetch in githubCache’s
request path so a hung GitHub call can’t block the Promise.all consumers
forever. Update the async fetch flow in the cache helper to use an
AbortController (or equivalent timeout wrapper), abort after a short duration,
and let the existing catch/writeCache(url, false, null)/return null fallback
handle the timeout the same way as other failures. Keep the change localized to
the fetch logic used by the caching function so the header/hero/developer hooks
recover automatically.
In `@web/components/SiteFooter.tsx`:
- Line 9: The footer copyright year is hard-coded in SiteFooter, which will
become stale. Update the YEAR value to be computed dynamically at render time
using the current date instead of a fixed constant, and make sure any footer
text that uses YEAR (including the related copyright display in SiteFooter)
reads from that dynamic value.
In `@web/components/SiteHeader.tsx`:
- Around line 119-126: The VersionBadge fallback currently shows v1.0.0 even
when useRepoStats() returns a null version, which incorrectly implies a first
release exists; update VersionBadge to use neutral copy or hide the badge until
a real version is available, and make the same change in HeroInstall so both
components handle the unreleased state consistently.
---
Nitpick comments:
In `@web/components/ExtLink.tsx`:
- Around line 4-11: The ExtLink component currently lets callers override target
and rel by spreading rest after the নিরাপ safe external-link defaults, and its
props still allow an optional href. Update ExtLink so the enforced external-link
attributes stay fixed even if extra anchor props are passed, and tighten the
component props to require a real href. Use the ExtLink function signature and
the anchor render in the component to keep the safety contract intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3072041b-a605-4765-a056-6c1e3166271d
⛔ Files ignored due to path filters (3)
web/app/icon.svgis excluded by!**/*.svgweb/package-lock.jsonis excluded by!**/package-lock.jsonweb/public/og.svgis excluded by!**/*.svg
📒 Files selected for processing (31)
.githooks/pre-pushMakefileREADME.mdscripts/install.shweb/.prettierignoreweb/.prettierrc.jsonweb/README.mdweb/app/docs/[slug]/page.tsxweb/app/docs/layout.tsxweb/app/docs/page.tsxweb/app/globals.cssweb/app/layout.tsxweb/app/page.tsxweb/app/robots.tsweb/app/sitemap.tsweb/components/DeveloperSection.tsxweb/components/DocsNavLink.tsxweb/components/ExtLink.tsxweb/components/HeroInstall.tsxweb/components/InstallCommand.tsxweb/components/Markdown.tsxweb/components/SiteFooter.tsxweb/components/SiteHeader.tsxweb/components/Skeleton.tsxweb/components/Terminal.tsxweb/components/githubCache.tsweb/components/useGitHub.tsweb/lib/docs.tsweb/lib/site.tsweb/package.jsonweb/types/css.d.ts
✅ Files skipped from review due to trivial changes (6)
- web/.prettierignore
- web/app/robots.ts
- web/.prettierrc.json
- web/app/sitemap.ts
- web/types/css.d.ts
- web/README.md
🚧 Files skipped from review as they are similar to previous changes (8)
- web/components/Markdown.tsx
- web/package.json
- web/app/docs/layout.tsx
- web/app/docs/[slug]/page.tsx
- web/components/InstallCommand.tsx
- README.md
- scripts/install.sh
- web/components/Terminal.tsx
- Apply post-review fixes to the landing page and tooling. - Fail closed in the pre-push hook when the remote base ref is unknown, so committed web changes are never skipped. - Add an 8s abort deadline to the GitHub fetch so a hung request can't leave the loading skeletons stuck forever. - Compute the footer copyright year at render time. - Show neutral "unreleased" copy in the version badge and hero until a real release tag exists. - Reword install copy: archives carry checksums and the checksum file is cosign-signed (not per-archive). - Soften the docs "always match installed version" claim.
Summary
Phase H — distribution: the release tooling that produces installable 1.0 binaries, plus a Next.js landing + docs site. Five self-contained commits (release tooling, then the web app) so the two unrelated bodies of work stay reviewable separately.
The tooling is wired and committed; publishing awaits the
v1.0.0tag + owner provisioning (tap repos/tokens, Vercel) — checklist inweb/README.md.Commits
build(release)—.goreleaser.yaml(v2): cross-platform matrix, archives, SHA-256 checksums, cosign-keyless signing of the checksums; Homebrew + Scoop blocks (skip_upload: autoso a first release succeeds before the tap repos/tokens exist); version ldflags match the Makefile's symbol..github/workflows/release.yml— tag-triggered, pins GoReleaser ~> v2, OIDC for cosign, tap tokens resolve to""when unset.build(install)—scripts/install.sh: POSIXcurl | sh, OS/arch detection, latest-release resolution, verifies the archive SHA-256 before extracting (refuses on mismatch). shellcheck-clean; verify/tamper logic exercised against a fixture.feat(web)scaffold — Next.js 15 App Router + Tailwind inweb/; docs pipeline (lib/docs.ts) renders the repo's owndocs/*.mdat build time (single source of truth, no fork).feat(web)UI — bespoke landing on a "pipe / liquid flow" thesis: hero is a syntax-truesiphontranscript, a teal→cyan flow-line signature down the feature stream, amber copy-curl|shwidget, and a sidebar docs reader. AA contrast (verified), focus outlines, reduced-motion, responsive.docs— README install section (script/brew/scoop/signed binaries), CHANGELOG,web/README.mdprovisioning checklist; golangci excludesweb/so the JS subtree doesn't trip the Go linters.Testing / verification
make test(20 packages) +make lint(0) green;web/is not a Go package.sh -nvalid, checksum match/tamper verified against a fixture.npm run build+next lintgreen; all 7 docs pages prerender from the repo Markdown; landing + docs screenshot-reviewed (renders correctly, on-thesis, AA contrast).goreleaser/cosignaren't installed here, so.goreleaser.yamlis config-reviewed (YAML-validated) but not executed — the release workflow is its first real run; and no actual release/tap-push/Vercel deploy happens until provisioned + tagged.Diff size note
~9k insertions is almost entirely
web/package-lock.json(committed intentionally for reproducible Vercel builds). Hand-written code is small; nonode_modules/.nextcommitted.Owner provisioning (in
web/README.md)Tag
v1.0.0(works alone — produces signed binaries + checksums); createnixrajput/homebrew-siphon+nixrajput/scoop-siphonrepos and their PAT secrets to light up brew/scoop; connect the repo to Vercel (root dirweb/).🤖 Generated with Claude Code
Summary by CodeRabbit
curl | shinstallation flow.