Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Brooooooklyn/simple-git
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.0.0
Choose a base ref
...
head repository: Brooooooklyn/simple-git
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.1.0
Choose a head ref
  • 10 commits
  • 67 files changed
  • 3 contributors

Commits on Jul 6, 2026

  1. feat: simple-git.napi.rs website (landing + docs + Cloudflare deploy) (

    …#146)
    
    * docs: add simple-git website design spec
    
    Design spec for simple-git.napi.rs — a marketing + docs site modeled on
    image.napi.rs (void + Vite + React 19 + Tailwind v4 + Shiki, deployed to
    Cloudflare). Landing + Getting Started, teal-on-slate theme, animated
    benchmark + doc-site 'last updated' showcase (no WASM playground).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs: add website implementation plan (7 tasks)
    
    Executable task breakdown for subagent-driven-development, cloning the
    image.napi.rs void site for @napi-rs/simple-git.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): scaffold void Yarn workspace with blank / and /docs routes
    
    Task 1 of the marketing+docs site: add a minimal void (VoidZero) workspace
    under website/ that installs, builds, and serves two placeholder routes.
    
    - website/package.json (@napi-rs/simple-git-website), void.json, vite.config.ts,
      tsconfig.json, pages/index.tsx (<h1>), pages/docs/index.md.
    - Root package.json: add "workspaces": ["website"] (rewrites yarn.lock).
    - .gitignore: website build artifacts (.void/.wrangler/test-results/etc).
    
    No theme/content, no playground, no WASM — those come in later tasks. The
    native library is untouched (still require()s cleanly).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): move build-artifact ignores into website/.gitignore (keep root .gitignore untouched)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(plan): website ignores go in website/.gitignore, not root
    
    Resolves the plan-internal contradiction Codex flagged in the Task 1 review.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): design system + root layout (theme tokens, fonts, shiki, header/footer)
    
    Task 2 visual foundation for the @napi-rs/simple-git site (dark-only, teal-cyan):
    
    - app.css: Tailwind v4 @theme tokens (cool slate near-black + teal accent),
      fluid clamp() type-scale, film-grain overlay, @layer components helpers
      (.container-page/.site-header/.eyebrow/.reveal), CSS-only mobile-nav rules,
      and self-hosted @font-face for the three variable fonts.
    - lib/highlight.ts: workerd-safe Shiki JS-regex-engine singleton (github-dark).
    - public/favicon.svg: new git-branch mark, teal on #04211f.
    - public/fonts/*.woff2: latin-subset variable fonts sourced from
      @fontsource-variable, preloaded via void.json head.link (stable paths).
    - pages/layout.tsx + pages/_components/Footer.tsx: sticky blurred header with
      JetBrains-Mono wordmark + Docs/GitHub/npm nav, CSS-only mobile drawer,
      and footer (brand + tagline + links + "Built with napi-rs · MIT licensed").
      No analytics.
    - tsconfig.json: include lib/.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): content data, shared UI primitives, Shiki loader (task 3)
    
    Add the content + primitives layer the landing sections (tasks 4-5) consume:
    
    _data modules:
    - samples.ts   — hero + 5 tab code samples, byte-verbatim from README.md
    - benchmarks.ts — 1.9 s vs 65 ms (1000×), ~29× derived
    - features.ts  — the 9 feature cards
    - platforms.ts — 15 napi triples grouped by OS (cross-checked vs package.json), Node >= 10
    - docSites.ts  — Nextra/Docusaurus/Starlight/Fumadocs/Rspress (name + URL + text glyph)
    
    index.server.ts — loader pre-highlights every sample server-side (Shiki JS-regex
    engine, no runtime WASM) and returns HTML as props; head (title + description).
    
    _components — reusable UI: CodeBlock (server-rendered highlighted HTML) plus the
    _-prefixed interactive islands _CopyButton, _InstallSwitcher, _CountUp, _Reveal,
    _TabbedCodeBlock. Landing is a regular Void route (full hydration), so islands need
    no `with { island }` — matches the reference/Task 2 convention.
    
    No-JS safe (code + reveals visible without JS); no analytics; no WASM.
    index.tsx untouched — section wiring is Task 4.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): landing sections A — Hero, Benchmark, Doc-site showcase
    
    Build the first three landing sections and wire them into pages/index.tsx
    (Task 4). Remaining sections land in Task 5.
    
    - Hero: eyebrow, "Git for Node, at native speed." (accent "native"), tagline,
      Get started/GitHub/npm buttons, InstallSwitcher, heroHtml CodeBlock, and three
      CountUp stat tiles (29× / 15 / 0 — all grounded in _data + package.json).
    - Benchmark: "~30× faster than shelling out"; IntersectionObserver bar animation
      (git CLI 1.9 s full bar vs simple-git 65 ms sliver, proportional to ms); big
      29× CountUp; caption from _data/benchmarks.ts (README Performance · performance.mjs).
    - DocSiteShowcase: "Powers 'Last updated on' for your docs"; mock doc footer stamp
      "Last updated on Jul 6, 2026 by LongYinan"; getFilesLatestModified bulk CodeBlock
      (new docSiteSample, byte-verbatim from README, highlighted via the loader); row
      of the 5 generators from _data/docSites.ts (text-glyph monograms, no remote logos).
    
    Shared presentational components: SectionHeader, Button, Chip (un-prefixed, no
    client state). Interactive pieces reuse the Task 3 islands (_CountUp/_Reveal/
    _InstallSwitcher) via the regular-route full-hydration model — no island markers.
    
    No-JS safe: all copy, code, benchmark labels/values and generator names are in the
    SSR HTML; bars render at final proportional widths and CountUp shows final values
    with JS off; reveals are gated behind html.js. No WASM, no analytics, no remote images.
    
    Verify: tsc --noEmit clean; void:prepare + vite build succeed (SSR + client);
    dev SSR renders all three sections with 0 console errors; reveals fire on scroll.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): source benchmark durations from data; align hero stat copy to spec
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): drop uppercase transform so hero stat labels match spec copy
    
    Renders '29× faster / 15 platforms / 0 dependencies' in the approved lower case
    (numbers still sourced from benchSpeedup / platformCount / 0). tsc + build pass.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): landing sections B — Features, CodeSample, PlatformMatrix, CtaBand
    
    Append the remaining four landing sections after Hero/Benchmark/DocSiteShowcase so
    pages/index.tsx is complete end-to-end (Hero → Benchmark → DocSiteShowcase → Features
    → CodeSample → PlatformMatrix → CtaBand; Footer from layout).
    
    - Features: 3×3 responsive card grid from _data/features.ts (9 cards).
    - CodeSample: _TabbedCodeBlock over statusHtml/commitHtml/blameHtml/pushHtml/errorsHtml
      ([Status] [Stage & commit] [Blame] [Push] [Typed errors]); first tab visible with JS off.
    - PlatformMatrix: 15 triples grouped by 6 OS from _data/platforms.ts; count + Node engine derived.
    - CtaBand: centered InstallSwitcher + [Read the docs]->/docs and [GitHub] buttons.
    
    All reuse existing shared/island components + data modules; no island markers, no
    forbidden tech, no-JS safe (all content in SSR HTML). tsc/void:prepare/build clean.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): Getting Started docs page (/docs)
    
    Replace the Task-1 placeholder with the full Getting Started content and add
    a centered prose layout for the /docs route.
    
    - docs/layout.tsx: single-column .void-md prose shell (header/footer come from
      the root layout). @void/md applies the prose theme; code is highlighted at
      build time by voidMarkdown() with Shiki's pure-JS regex engine — no runtime
      WASM, page reads fully with JS disabled.
    - docs/index.md: Install (npm/yarn/pnpm/bun), 15 prebuilt triples + Node >= 10,
      60-second example, flagship getFilesLatestModified doc-site "last updated",
      async & AbortSignal, typed errors (isGitError/GitErrorCode), dispose()/free()/
      using, and Full API links to the GitHub README + npm. In-page [[toc]].
    
    All code/API grounded in README.md and index.d.ts.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(website): add index.d.ts link to the Getting Started Full API section
    
    Full API now links GitHub README + type definitions (index.d.ts) + npm,
    matching the plan/spec requirement.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(plan): Task 7 may add .github/workflows/void-deploy.yml at root
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): Void deploy workflow, Playwright smoke test, inline-code feature cards
    
    Task 7 of the @napi-rs/simple-git website build.
    
    - .github/workflows/void-deploy.yml: mirror ../Image deploy workflow, only
      changing the project to napi-simple-git. Push to main on website/** changes,
      Node 24, corepack, root `yarn install --immutable`, `yarn void deploy
      --project napi-simple-git` in website/, GitHub OIDC (id-token: write).
    - website/playwright.config.ts + website/e2e/smoke.spec.ts: deterministic smoke
      test over the Vite/Void SSR dev server. Asserts `/` 200 + hero H1 "Git for
      Node, at native speed." + "01 — BENCHMARK" eyebrow, and `/docs` 200 + the
      "Getting Started" heading. 2 passed.
    - website/pages/_components/Features.tsx: render backtick-delimited API names in
      feature `desc` strings as styled inline <code> (split on backtick, wrap odd
      segments). No markdown lib, no data change; server-rendered and no-JS safe.
    
    Responsive pass verified empirically (Chromium 320/360/375/414 on / and /docs):
    no horizontal body scroll, wide content scrolls within its own overflow-x:auto
    container, mobile drawer + tap targets work. No CSS changes needed. tsc clean;
    void:prepare + build succeed.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): make tabbed code block no-JS safe (show all panels without JS)
    
    The API section's tabbed code block hid inactive panels with the HTML `hidden`
    attribute and required JS to switch tabs, so with JavaScript disabled only the
    first of five code samples was ever visible.
    
    Emit all five panels with no `hidden` attribute and drive show/hide from app.css,
    gated on the existing `html.js` class (set before first paint by the layout's
    inline script, the same mechanism `.reveal` uses). Without JS the tab bar is
    hidden and every panel shows stacked, each with a visible per-panel label; with
    JS only the active panel (data-active) shows and clicking a tab swaps instantly,
    with no flash of all five before hydration. ARIA tablist/tab/tabpanel wiring is
    preserved.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs: add SEO fixes implementation plan (6 tasks)
    
    Grounded in the multi-agent SEO audit findings (verified). Covers head/social meta,
    canonical, JSON-LD, robots/sitemap, prerender/CWV, and a11y — all inside website/.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): SEO/social static assets (og image, raster icons, robots, sitemap)
    
    Add the static asset layer the SEO/meta tags will reference:
    - public/og.png (1200x630) on-brand social share card
    - public/apple-touch-icon.png (180x180) + public/favicon.png (32x32) from favicon.svg
    - public/robots.txt + public/sitemap.xml (/, /docs @ lastmod 2026-07-06)
    - scripts/gen-og.mjs: reproducible generator using the installed Playwright
      chromium (no new dependency), fonts embedded as data URIs
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): replace ungrounded "Zero-copy" OG chip with "15 platforms"
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): SEO head meta layer — base social tags + home canonical/og
    
    Move route-invariant tags (charset, theme-color, og:type/site_name/image*,
    twitter:card/image, apple-touch-icon + PNG favicon fallback) into the void.json
    base head; add per-route canonical + og:url and benefit-copy og:title on home,
    and rewrite the description const. Delete the tags that moved to base so each
    renders exactly once (void appends links, overrides meta by name/property).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): per-route head for /docs (canonical, og:url, trimmed description)
    
    SEO Task 3: give /docs its own canonical + og:url and a right-length
    description via a co-located server head, since void markdown frontmatter
    silently drops head/link/og keys.
    
    - Add website/pages/docs/index.server.ts head export:
      - re-declares title 'Getting Started' and the docs description (a server
        head REPLACES the frontmatter-derived head)
      - link canonical https://simple-git.napi.rs/docs (non-trailing-slash form)
      - meta description + og:title/og:description + og:url .../docs
    - Trim description to 146 chars (was 175, clipped in SERPs) by dropping the
      trailing "Powered by libgit2 and Rust." clause; keep index.md frontmatter
      in sync. Docs body unchanged.
    
    Void's head merge keeps every route-invariant base social tag (og:type,
    og:site_name, twitter:card, og:image, theme-color, charset) and wraps the
    title with the "%s | @napi-rs/simple-git" template.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): server-render SoftwareApplication + WebSite JSON-LD
    
    SEO Task 4: emit two schema.org JSON-LD blocks from the root layout so
    both / and /docs are eligible for rich results. Fields grounded in
    package.json (name, version 1.0.0, MIT, repo, npm) and the 15 napi
    targets (OS list). Serialized via JSON.stringify; server-only, no client JS.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * perf(website): prerender / and /docs, make static responses edge-cacheable
    
    Both landing (/) and docs (/docs) carry no request- or time-varying data yet
    were re-rendered per request (prerender=false + routing.revalidate {"*":0}),
    re-running Shiki on every hit. Switch both to prerender=true so they render
    once per deploy and serve from the edge cache, and drop the revalidate:0 block
    that (per void's "TTL 0 is skipped" rule) would otherwise suppress prerender.
    Islands (CountUp/InstallSwitcher/tabs) still hydrate client-side; no-JS render
    and the /docs/ 308 redirect are unchanged.
    
    Worker asset precedence (run_worker_first: ["/**"]) is generated by void and
    NOT exposed via void.json (worker/routing are additionalProperties:false, no
    assets knob); left as-is per brief, to raise upstream. See task-5 report.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): a11y + CWV micro-fixes (skip link, focus ring, nav labels, new-tab cues, hero LCP, font/grain)
    
    - Skip link (first fragment child) + <main id="main-content"> (WCAG A)
    - Zero-specificity :where() :focus-visible ring in app.css Base (WCAG 2.4.7)
    - aria-label="Primary" on desktop + drawer navs, "Footer" on footer nav
    - Centralized "opens in a new tab" sr-only cue: Button (target=_blank), layout NAV,
      Footer links, DocSiteShowcase used-by row; rel="noreferrer" kept
    - Hero above-fold code column: <Reveal> -> plain <div> so LCP isn't opacity:0 JS-gated;
      dropped unused Reveal import; below-fold reveals untouched
    - Removed mix-blend-mode: soft-light from body::after film grain
    - font-display: swap -> optional on all three @font-face blocks (no mid-view swap => no CLS)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(plan): add SEO Task 7 — agent-friendliness (llms.txt)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): add llms.txt, llms-full.txt, robots pointer (SEO task 7)
    
    Expose the site to LLM agents via the llmstxt.org convention:
    
    - website/public/llms.txt — curated map (summary, docs links, grounded
      Core API surface, install commands); every API name verified against
      index.d.ts, facts (1.0.0, MIT, 15 targets, Node >= 10) per package.json.
    - website/public/llms-full.txt — full Getting Started docs in one plain
      markdown fetch, derived from pages/docs/index.md (frontmatter + [[toc]]
      stripped, retitled, code blocks intact).
    - website/public/robots.txt — comment pointer to /llms.txt after Sitemap.
    
    All served at web root (dist/client). Build + Playwright e2e green;
    library untouched; only website/public/ changed.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): make llms.txt spec-conformant; correct typed-error claim (docs + llms)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * ci(website): deploy on root lockfile/package-manager changes too
    
    The Void deploy filter only watched website/**, but the site's
    dependencies resolve from the shared root yarn.lock. A lockfile-only
    website dep update (Renovate in-range bump or monthly
    lockFileMaintenance) edits only root yarn.lock, so it matched neither
    website/** nor the workflow file and never deployed — leaving the live
    site on stale deps. Add the root package-manager files to the deploy
    paths. Root/native-only lockfile bumps now redeploy an unchanged site,
    which is a harmless no-op.
    
    Addresses codex review finding on PR #146 (void-deploy.yml path filter).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * ci: fold void-deploy.yml into CI.yml
    
    Consolidate the website (Void) deploy into the main CI workflow and drop
    the standalone void-deploy.yml. Behavior is preserved:
    
    - Deploy runs on push to main only (never on pull_request) and stays
      independent of the native build/test jobs (no `needs` on them), so a
      Rust CI failure can't block a website deploy — same as the old workflow.
    - A small `changes` gate job (dorny/paths-filter) scopes the deploy to
      commits that affect the site (website/** or the shared root
      package-manager files); GitHub can't path-filter one job of a
      multi-job workflow, so the former on.paths filter moves here.
    - OIDC (id-token: write) and the VOID_* env stay scoped to the deploy
      job, so the native jobs keep their default token permissions.
    - Workflow-level concurrency (cancel-in-progress) already gives the
      deploy "latest push wins", replacing the old per-workflow group.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): scope the typed-error feature card to Git-layer errors
    
    The "Typed, catchable errors" card claimed every failure carries a
    GitErrorCode narrowable via isGitError(), but an aborted *Async call
    rejects with napi's AbortError (code === 'Cancelled'), which isGitError
    does not match. Scope the claim to Git-layer errors and note the abort
    exception — consistent with the docs, llms.txt and index.d.ts.
    
    Addresses codex review finding on PR #146 (features.ts typed-error claim).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(plan): merge website build + SEO plans into one
    
    Fold the two same-day website plans into a single
    2026-07-06-simple-git-website-plan.md with a shared, de-duplicated
    Context + Global Constraints preamble and two phases — Phase 1 (build)
    and Phase 2 (SEO, a11y & agent-friendliness) — each keeping its Task 1–7
    and done-criteria verbatim. Delete the standalone SEO plan.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * chore: ignore root .void codegen output
    
    `void prepare`/`void build` can drop a `.void/project.json` at the repo
    root; ignore it like the other build artifacts (target/, *.node). The
    website workspace's own .void is already covered by website/.gitignore.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * ci: deploy to the correct Void project (simple-git)
    
    The deploy job targeted VOID_PROJECT=napi-simple-git, but that project
    does not exist — the real Void project is `simple-git`
    (https://simple-git.void.app). CI deploys would have failed at
    `void deploy --project napi-simple-git`. Point the deploy job (and the
    spec/plan references) at `simple-git`. Verified by a manual
    `void deploy --project simple-git`, which deployed successfully.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * ci: let website markdown-only changes trigger the deploy
    
    After folding the deploy into CI.yml, the workflow-level
    `paths-ignore: **/*.md` skipped the entire run for a website-docs-only
    push (e.g. website/pages/docs/index.md), so `dorny/paths-filter` never
    ran and the site was not redeployed. Replace paths-ignore with a
    positive `paths` filter: `**` triggers, root docs/markdown are excluded,
    and `website/**` is re-included last so website markdown still deploys.
    Native CI still skips pure root-doc/README changes.
    
    Addresses codex review finding on PR #146 (CI.yml deploy path gate).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(spec): API Reference page design (/docs/api)
    
    Hand-authored, comprehensive /docs/api reference (single page + sidebar),
    grounded verbatim against index.d.ts + the README GitErrorCode table.
    Approach approved: hand-authored curated markdown, single page.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): point npm links at npmx.dev
    
    Swap the package host from www.npmjs.com to npmx.dev (same
    /package/@napi-rs/simple-git path; canonical form verified — the bare
    /@scope/name variant 301s to /package/...). Covers the top nav, hero,
    footer, JSON-LD downloadUrl, the docs "Full API" link, and llms.txt /
    llms-full.txt. Labels stay "npm".
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(plan): API Reference implementation plan (7 tasks)
    
    SDD plan for /docs/api: sidebar layout + scaffold, Repository (A/B),
    git objects & handles (object model / operations), interfaces+enums+
    functions, error handling + polish. Each task grounded-verified against
    index.d.ts and codex-gated.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): docs sidebar layout + /docs/api scaffold
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): API reference — Repository (part A)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): tighten grounding of init/findTree/findCommit prose (API ref part A)
    
    Codex grounding gate flagged prose beyond the JSDoc for three thin-doc
    methods. init now states only what README ("init a git repository") +
    the signature support; findTree/findCommit keep the null-if-not-found
    note but tie it explicitly to their `T | null` return type (also
    grounded by the README's `findTree(oid)!` / `findCommit(oid)!` usage).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): API reference — Repository (part B)
    
    Document the second half of the Repository class in website/pages/docs/api.md:
    state & inspection, config/signature, remotes, branches/checkout/references,
    tags, diffs, revwalk and resource cleanup. Signatures copied verbatim from
    index.d.ts; prose grounded in JSDoc/signatures/README.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): API reference — git object handles (object model)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): verbatim TreeIter decl + drop ungrounded rename reflog claim (API ref objects)
    
    Codex gate: (1) the TreeIter fence now shows the complete verbatim class
    declaration from index.d.ts (incl. the body and next()); (2) removed the
    "msg is recorded in the reflog" note on Reference.rename — true in
    libgit2 but not stated in the rename JSDoc or README, so ungrounded.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): byte-match TreeIter fence to index.d.ts (blank line)
    
    Final codex nit ([low]): index.d.ts emits a blank line after the TreeIter
    class opening brace; mirror it so the fenced declaration is byte-identical.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): API reference — remote, index, config, diff & options classes
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): drop RevWalk's redundant 93-line class-body fence (API ref)
    
    The RevWalk entry dumped the entire class body (with all JSDoc) as one
    fence AND repeated every member in its own #### section — a Task-4
    over-correction. The prose one-liner already states the
    `extends Iterator<string, void, void>` inheritance and each member is
    documented individually, so the giant fence was pure redundancy.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): correct Diff intro — no tree-to-tree diff exists (API ref)
    
    Codex gate: the Diff class intro claimed deltas "between two trees, or a
    tree and the working directory", but the only Diff-producing APIs are
    diffTreeToWorkdir and diffTreeToWorkdirWithIndex (both tree-to-workdir);
    there is no tree-to-tree diff method. Dropped the ungrounded "two trees".
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): drop undocumented constructor default-state claims (API ref)
    
    Codex gate [low]: the options-class constructors asserted default states
    (default clone/fetch/push settings, no proxy, no callbacks) that aren't
    in the constructor JSDoc/README. Reduced each to "Create a new X." —
    grounded in the bare constructor signature; the setters below document
    configuration.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): API reference — options/result types, enums & functions
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): DiffFlags belongs to DiffDelta.flags(), not DiffFile (API ref)
    
    Codex gate: the DiffFlags enum note said "flags on a DiffFile", but the
    flags are exposed via DiffDelta.flags() (index.d.ts:349-356) and DiffFile
    has no flags() accessor. Corrected the lead to DiffDelta (the rest of the
    sentence already referenced DiffDelta.flags()).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat(website): API reference — error handling section + whole-page polish
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(website): error example used findRemote (returns null, never throws)
    
    The typed-error try/catch example branched on GitErrorCode.NotFound after
    calling repo.findRemote('does-not-exist'), but findRemote returns
    Remote | null (index.d.ts:1091) — it never throws for a missing remote,
    so the catch would not fire. Replace the call with a neutral placeholder
    (matching the README's error-handling example) in the new /docs/api
    Error handling section AND in the pre-existing Getting Started page +
    llms-full.txt where the same broken example had shipped.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * ci: build + e2e the website on PRs (pre-merge gate)
    
    The website's build/test:e2e were only ever exercised via `yarn void
    deploy`, which is gated to push-to-main — so a PR breaking the Vite/TS/
    markdown build passed native CI and only failed at deploy. Add a
    `website` job (build + Playwright smoke of / , /docs, /docs/api) that
    runs whenever website-affecting paths change, on PRs and pushes alike.
    
    The `changes` gate now fires for all triggers (not just main pushes) so
    it can drive the PR gate; `deploy` gains an explicit push+main guard to
    stay main-only. The website has no dependency on the native .node
    binary (library imports appear only inside doc code fences), so the job
    needs no Rust build.
    
    Addresses codex review finding on PR #146 (website not built in PR CI).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs: merge API-reference spec+plan into the website spec+plan
    
    The API Reference was a follow-on sub-project of the website, tracked in
    its own spec/plan pair. Fold each into its website parent so there is one
    spec and one plan for the whole site:
    
    - spec: API-reference design becomes §11 of the website design spec; the
      superseded "no full API-reference" non-goal and the route list updated.
    - plan: API-reference tasks become Phase 3 (7 tasks + constraints + done
      criteria) of the website plan; intro now says three phases.
    
    Deletes the two standalone -api-reference-{design,plan}.md files. No
    content lost — merged verbatim, re-leveled to fit.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * ci: gate Void deploy on the website smoke job
    
    `deploy` only had `needs: changes`, the same as the `website` job — so on
    a push to main both started in parallel once change-detection finished,
    and `void deploy` could publish before the Playwright smoke (/ , /docs,
    /docs/api) even finished, let alone passed. A later e2e failure then left
    a broken site already live.
    
    Add `website` to deploy's `needs` so the build + smoke must succeed
    first. When website changed the website job always runs (needs
    satisfiable); when it didn't, deploy's existing push+main+website==true
    `if` skips it regardless, so no deadlock.
    
    Addresses codex review finding on PR #146 (deploy not gated on e2e).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Brooooooklyn and claude authored Jul 6, 2026
    Configuration menu
    Copy the full SHA
    6881589 View commit details
    Browse the repository at this point in the history
  2. fix(deps): update dependency @void/md to v0.10.5 (#147)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Jul 6, 2026
    Configuration menu
    Copy the full SHA
    8300a3f View commit details
    Browse the repository at this point in the history
  3. fix(deps): update dependency @void/react to v0.10.5 (#148)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Jul 6, 2026
    Configuration menu
    Copy the full SHA
    638b632 View commit details
    Browse the repository at this point in the history

Commits on Jul 7, 2026

  1. Configuration menu
    Copy the full SHA
    4ca5860 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    723f6b3 View commit details
    Browse the repository at this point in the history
  3. fix(deps): update dependency void to v0.10.5 (#151)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Jul 7, 2026
    Configuration menu
    Copy the full SHA
    9b5a48b View commit details
    Browse the repository at this point in the history
  4. chore(deps): update dorny/paths-filter action to v4 (#150)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Jul 7, 2026
    Configuration menu
    Copy the full SHA
    3ca64c5 View commit details
    Browse the repository at this point in the history
  5. feat: add created (first-add commit) to FileModification (#152)

    * docs: plan for FileModification.created field
    
    * feat: add `created` (first-add commit) to single-file getFileLatestModified
    
    Add a `created: CommitInfo | null` field to `FileModification`, carrying the
    commit that FIRST added the file. Task 1 wires the single-file path end to end
    (sync method + async task); the bulk path is a later task.
    
    - New `#[napi(object)] CommitInfo` (8 commit-metadata fields).
    - `build_commit_info` factors the 8-field extraction; `build_modification`
      routes through it (created: None).
    - `get_file_creation`: separate oldest-first walk
      (Sort::TOPOLOGICAL | Sort::REVERSE, no Sort::TIME) resolving the exact
      repo-root-relative path via tree.get_path, first-hit early-exit, merges
      included, no rename-follow.
    - `get_file_modification_with_created`: merges creation into a Some record only;
      never-committed paths stay null. Shared by the sync method and async run() so
      both are identical.
    - Regenerated index.d.ts (CommitInfo interface + created?). index.js unchanged
      (object types have no JS runtime export).
    - Tests: new `created` test (shape + non-CI CLI parity vs
      `git log --diff-filter=A --reverse`); bulk-vs-single cross-checks scoped with
      a withoutCreated helper until the bulk path is enriched.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * feat: extend `created` (first-add commit) to bulk getFilesLatestModified
    
    Task 2: carry the `created` creation record through the BULK path (sync +
    async), matching the single-file path from Task 1.
    
    - file_modification.rs: add `get_files_creation` (oldest-first
      Sort::TOPOLOGICAL|REVERSE bulk walk, exact tree.get_path, merges included,
      first/oldest containing commit wins) and `get_files_modification_with_created`
      (bulk modification walk + creation walk over present paths only, merged into
      each record's `created`).
    - repo.rs: sync `get_files_latest_modified` and async
      `GitBulkModificationTask::run` both call the shared `_with_created` wrapper so
      results are byte-identical across the async boundary.
    - modification.spec.mjs: remove the temporary `withoutCreated` helper, restore
      full deepEqual in the 3 bulk-vs-single cross-checks, add explicit bulk/async
      `created` assertions and the __proto__-record-carries-created regression.
    
    Bindings regenerated (index.js/index.d.ts unchanged: no public-surface delta).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * test: multi-commit `created` semantics + document created on API surface
    
    Add hermetic multi-commit tests characterizing `created` (the first-adding
    commit) as distinct from the last modification, and document the semantics on
    the public method doc comments (regenerated into index.d.ts).
    
    Tests (__test__/modification.spec.mjs), via a new makeRepoWithHistory helper
    that builds a controlled history and returns each commit's OID:
    - created is the first-adding commit, distinct from the last modification
      (C1 adds f.txt, C2 modifies it; created==C1, commitId==C2)
    - created returns the ORIGINAL add across a delete-then-re-add (C1/C2/C3 -> C1)
    - created equals the modification commit for a root-only file
    - bulk created matches single-file created on a multi-commit repo
    
    Docs: document `created` on getFileLatestModified (adds delete/re-add, merges
    included, no rename-follow to the existing exact-path + glob caveat) and add
    the missing `created` paragraph to getFilesLatestModified.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(file-modification): created is undefined (not null) when absent
    
    `FileModification.created` is an `Option<CommitInfo>` on a `#[napi(object)]`
    struct; `None` serializes by OMITTING the property, so JS sees `created ===
    undefined` (never `null`), matching the sibling Option fields ("Undefined if
    absent"). The docs wrongly said "null" and mislabeled the no-history case.
    
    - file_modification.rs: rewrite the `created` field doc to say "Undefined",
      scope the undefined case to glob/directory input only (exact path always
      present), and clarify a no-history path yields NO record at all (whole
      FileModification is null), not a present record with the field missing.
    - repo.rs get_file_latest_modified: "created may be null" -> "left undefined".
    - add a regression test pinning created === undefined + no own property for a
      glob/pathspec input ("*.rs").
    - regenerate index.d.ts from the Rust docs (no logic change).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(file-modification): created resolves an exact FILE (blob) only
    
    The two creation walks resolved `created` on ANY `tree.get_path()` hit, so a
    DIRECTORY (tree entry) or submodule (gitlink/Commit entry) input produced a
    BOGUS `created` record (the entry's own creation commit) instead of undefined.
    Guard both `get_file_creation` and `get_files_creation` to resolve only when
    `entry.kind() == Some(git2::ObjectType::Blob)`; a non-blob Ok entry keeps
    walking (never resolves for a pure directory -> stays None/undefined).
    
    Symlinks are blobs (correctly files); directories/submodules are excluded. The
    modification walks are untouched (their directory->root behavior is pre-existing
    and out of scope).
    
    Also corrects the `created` doc rationale on both the field and
    getFileLatestModified (a directory DOES match a tree entry -- the old "matches
    no tree entry" reason was wrong; a creation is an exact FILE/blob only) and the
    plan doc (CommitInfo | undefined; FIELD undefined vs bulk map VALUE null).
    
    Adds regression tests (RED on the pre-fix binary): a directory input ("src")
    and a hermetic nested file-vs-directory ("dir/a.txt" resolves, "dir" does not).
    makeRepo now creates parent dirs so nested paths work.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(file-modification): created is undefined for a dir/submodule AT HEAD
    
    The per-commit blob check rejected a pure directory but not a path whose
    TYPE changed across history: a path that was a FILE (blob) long ago but is a
    DIRECTORY (tree) or submodule (gitlink) AT HEAD still found the OLD blob in an
    ancestor tree and returned a bogus `created`, breaking the documented
    directory/submodule -> undefined contract.
    
    Add a HEAD-kind gate at the start of both creation walks (get_file_creation,
    get_files_creation): peel HEAD to its tree and return None / drop the path when
    its entry is a tree or gitlink AT HEAD. A path ABSENT at HEAD (a deleted file)
    is NOT gated -- its original blob creation still resolves. The per-commit blob
    check stays (directory->file transitions still resolve to the commit the path
    became a file).
    
    Docs (created field, get_file_latest_modified, plan semantics) reworded: the
    caveat is decided by the path's entry kind AT HEAD, and a deleted file still
    reports its original creation. Regenerated index.d.ts.
    
    Tests: file->dir (created undefined; RED before fix), deleted-file-stays-resolved
    (created == original add), dir->file (created == the commit it became a file);
    makeRepoWithHistory extended for type-transition steps. 167 tests (was 164).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(repo): correct created-resolution note for dir/submodule at HEAD
    
    get_files_latest_modified doc no longer claims a resolved path always has
    a `created` commit. After the HEAD-kind gate, a present record's `created`
    is undefined when the exact path is a directory (tree) or submodule
    (gitlink) at HEAD; a deleted path still resolves its original creation.
    Regenerated index.d.ts.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs: reconcile bulk-method dir note + add created/CommitInfo to README
    
    Two doc-only fixes for the FileModification.created feature (no logic change):
    
    - get_files_latest_modified doc no longer claims a directory "will not match"
      (it can resolve to a present bulk record); instead states a directory (tree)
      or submodule (gitlink) path is not a file, whose `created` is `undefined` --
      consistent with the `created` paragraph that follows. Regenerated index.d.ts.
    - README: add the `created?: CommitInfo` field to the FileModification snippet
      and a mirrored `CommitInfo` interface (its 8 creating-commit fields).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(file-modification): evil-merge-only files fall back to the creating merge commit
    
    A file introduced only by a merge commit (present at HEAD, in neither parent)
    returned null from getFileLatestModified: the modification walk skips merge
    commits, so no non-merge commit ever touches such a path and the None arm
    returned null without consulting the creation walk.
    
    Both _with_created wrappers now fall back to the file's creating (merge) commit
    for the WHOLE record when the modification walk finds nothing but the file still
    exists, so commitId === created.commitId. The bulk wrapper now runs the creation
    walk over ALL input paths (dropping the present-only optimization) so
    absent-but-existing merge-only paths can fall back; never-committed paths still
    resolve to null. Modification walks, creation walks, and the bare-date methods
    are unchanged; async inherits the fix via the shared wrappers.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(file-modification): gate merge-only fallback on present-at-HEAD
    
    The evil-merge fallback (build the record from the creating commit when the
    modification walk finds nothing) over-fired for a merge-only file that was
    LATER DELETED by a merge: both the add and the delete are merges the
    modification walk skips (-> None), yet get_file_creation still resolves the
    old add (it allows paths absent at HEAD, to support deleted files' `created`).
    So getFileLatestModified reported the stale add-merge instead of null.
    
    Gate the None-branch fallback on the path being a blob AT HEAD: only a file
    still PRESENT at HEAD may fall back to its creating commit; an absent path
    (deleted, even by a merge) stays null. The ATTACH path (modification walk
    returned Some) is unchanged, so a normally-deleted file's `created` still
    resolves to its original add. Bulk peels the HEAD tree lazily (once, only when
    a fallback candidate first appears) so empty / all-present / all-never-committed
    inputs never peel HEAD (which would throw on an unborn HEAD).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * refactor(file-modification): peel HEAD once in single-file merge-only fallback
    
    Extract the reverse blob-walk of `get_file_creation` into a private
    `oldest_blob_commit` helper (no HEAD gate). `get_file_creation` now peels
    HEAD, applies its HEAD-kind gate, then delegates to the helper. The
    single-file `None`-branch fallback in `get_file_modification_with_created`
    peels HEAD ONCE (reusing the tree for its blob gate; the oldest-blob walk
    pushes HEAD itself) instead of peeling twice via `get_file_creation` +
    `path_is_blob_at_head`. Removed the now-dead `path_is_blob_at_head`.
    
    Pure refactor -- no behavior change, tests unchanged (172/172), clippy clean.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(file-modification): narrow committerTime↔date-method parity for merge-only files
    
    The merge-only fallback made getFileLatestModified resolve a file present only
    via merges, but the cheap date twins (getFileLastModifiedDate /
    getFileLatestModifiedDate + async) keep the raw merge-skipping walk and do NOT
    apply that fallback. So committerTime is NOT strictly "identical to
    getFileLastModifiedDate" for such a file — the record has the creating merge's
    time while the date methods return null / throw.
    
    Narrow the three parity claims (the committerTime field, getFileLastModifiedDate,
    getFileLatestModified) to state the merge-only exception, and note on both date
    methods that they keep raw merge-skipping semantics. Docs-only — no behavior
    change. Add a test pinning the intentional divergence so routing the date
    methods through the fallback would fail and force a docs update.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(file-modification): correct getFileLatestModified null-condition for merge-only-absent paths
    
    The summaries said null happens "only when no commit ever added the path", but
    b293ebf's blob-at-HEAD gate makes a file added by a merge and deleted by a merge
    (added in history, yet absent at HEAD) return null — the deleted-by-merge test
    asserts exactly that. The summary contradicted its own merge-only detail
    paragraph.
    
    Correct the null-condition on all four rich accessors (getFileLatestModified +
    async, getFilesLatestModified + async): null ⟺ no non-merge commit recorded a
    change AND the path is absent at HEAD (never added, OR only merge commits touched
    it and it is absent at HEAD, e.g. deleted by a merge). A path present at HEAD
    always resolves. Docs-only — no behavior change.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * docs(file-modification): scope "deleted file resolves created" to ordinary deletes
    
    The created docs said "a DELETED file (absent at HEAD) still reports its ORIGINAL
    creation", but a merge-only-deleted file returns null (no record, no created).
    Only a file deleted by an ordinary (non-merge) commit still yields a record whose
    created resolves. Tighten the three spots (created field, single + bulk methods)
    to say "deleted by an ordinary (non-merge) commit" — matching the tested deletes
    (all non-merge). Docs-only.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * test(file-modification): pin getFilesLatestModified([]) on an unborn HEAD
    
    The existing empty-input test runs on a populated repo, so it never exercised the
    unborn-HEAD case the bulk lazy-peel guards: a no-op call must return {} without
    peeling HEAD (an unconditional peel would throw "unborn HEAD"). Add a no-commits
    repo assertion locking that the lazy peel stays lazy.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(file-modification): merge-only fallback flat fields track the LATEST change, not creation
    
    A path touched only by merge commits, where one evil merge ADDS it and a later
    evil merge CHANGES it (still present at HEAD), built the whole FileModification
    from oldest_blob_commit (the creation), so commitId/committerTime pointed at the
    original add instead of the merge that last changed the file. Same flaw in bulk.
    
    Add latest_blob_change_including_merges: newest-first walk INCLUDING merges that
    returns the first commit whose blob OID at the path differs from that path's blob
    OID in EVERY parent (a root/normal add, or an evil-merge change; an inherited
    blob is skipped). Rewire both fallbacks so flat fields come from it while created
    stays oldest_blob_commit / get_files_creation. Add blob_oid_at helper, reused for
    the blob-at-HEAD gates. commitId === created.commitId now holds only when a single
    merge both added and last-changed the file; docs updated accordingly.
    
    Tests: double-evil-merge fixture (M1 adds v1, M2 changes to v2) asserting
    commitId===M2, created===M1, distinct, single==bulk. Suite 174 -> 176.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    * fix(file-modification): merge-only latest-change walk is mode-aware ((oid,mode), not oid)
    
    latest_blob_change_including_merges compared only the blob OID at the path, so a
    merge that changed ONLY the file mode (100644 -> 100755, same blob OID) looked
    "inherited" and was skipped, wrongly falling back to the older add-merge for the
    flat fields. The non-merge diff walk DOES count a mode-only delta, so merge-only
    files diverged from ordinary diff semantics.
    
    Compare the full tree-entry identity (blob OID, filemode): rename blob_oid_at ->
    blob_entry_at returning (Oid, i32); a commit is a genuine change iff its
    (oid, mode) at the path differs from every parent's. The two fallback HEAD
    blob-gates use blob_entry_at(...).is_some(). Creation stays mode-agnostic
    (oldest_blob_commit / get_file_creation untouched).
    
    Add a mode-only evil-merge fixture + single/bulk tests (M1 adds evil.txt @100644,
    M2 chmods to 100755, same blob): commitId == M2, created == M1. Suite 176 -> 178.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Brooooooklyn and claude authored Jul 7, 2026
    Configuration menu
    Copy the full SHA
    659d5ca View commit details
    Browse the repository at this point in the history
  6. fix(deps): update void to v0.10.6 (#153)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Jul 7, 2026
    Configuration menu
    Copy the full SHA
    e580290 View commit details
    Browse the repository at this point in the history
  7. 1.1.0

    Brooooooklyn committed Jul 7, 2026
    Configuration menu
    Copy the full SHA
    3b8e55c View commit details
    Browse the repository at this point in the history
Loading