diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md deleted file mode 100644 index 3de6d44..0000000 --- a/.claude/CLAUDE.md +++ /dev/null @@ -1,38 +0,0 @@ -# Probitas Documentation Site - -Documentation for Probitas - a scenario-based testing framework shipped as a -single `probitas` binary (Bun runtime embedded). - -## Quick Reference - -- **Runtime**: Node.js + HonoX + Vite SSG -- **API Generation**: TypeDoc JSON from the npm packages -- **Deploy**: GitHub Pages - -## Commands - -```bash -npm run dev # Dev server with HMR -npm run build # Build static site (client + SSG + Pagefind) -npm run preview # Preview production build -npm test # Check internal links in the built site -npm run generate-api # Regenerate data/api/ from the npm packages -``` - -## Pre-Completion Verification - -BEFORE reporting task completion, run and ensure zero errors: - -```bash -npm run build -``` - -## Reference Probitas Packages - -When referencing Probitas API: - -- Scenarios import from `@probitas-test/probitas` (npm); the JSR mirror is - `@probitas/probitas` -- `data/api/{package}.json` holds the generated TypeDoc JSON of each package -- Check `../probitas/` for the user-facing package and CLI source -- Check `../probitas-packages/` for framework and client package source diff --git a/.claude/rules/architecture.md b/.claude/rules/architecture.md index 547a0e6..df96af9 100644 --- a/.claude/rules/architecture.md +++ b/.claude/rules/architecture.md @@ -7,7 +7,7 @@ paths: "app/**/*.{ts,tsx}, scripts/**/*.ts, vite.config.ts" ## Directory Structure ``` -documents/ +probitas-test.github.io/ ├── app/ # Application source │ ├── server.ts # HonoX entry point │ ├── client.ts # Client-side JavaScript (bundled by Vite) @@ -53,6 +53,8 @@ documents/ ├── scripts/ # Build and generation scripts │ ├── post-build.js # Pagefind indexing & llms.txt.html→llms.txt rename │ └── generate-api-docs.ts # Generate API docs from the npm packages +├── flake.nix # Nix development shell +├── justfile # Task recipes (`just ci` is the quality gate) ├── package.json # npm dependencies ├── vite.config.ts # Vite + HonoX SSG configuration └── tsconfig.json # TypeScript configuration diff --git a/.envrc.sample b/.envrc.sample index 3550a30..11af9c3 100644 --- a/.envrc.sample +++ b/.envrc.sample @@ -1 +1,2 @@ +# Copy to .envrc and run `direnv allow` to enter the Nix dev shell automatically. use flake diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ca5e98b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Check text out with LF on every OS, so a Windows checkout builds and tests +# the same bytes as the others. +* text=auto eol=lf diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 26af321..bff692a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -7,49 +7,63 @@ on: pull_request: workflow_dispatch: -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment -concurrency: - group: "pages" - cancel-in-progress: false jobs: - build: + ci: runs-on: ubuntu-latest + # A pull request only needs its latest commit checked. A run on main waits + # for the one before it instead of cancelling it, so each one finishes. + concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 + - uses: actions/checkout@v7 with: - node-version: lts/* - cache: npm - - - run: npm ci - - - run: npm run build - - - run: npm test - - # Upload artifact for GitHub Pages + persist-credentials: false + - uses: cachix/install-nix-action@v31 + with: + extra_nix_config: | + experimental-features = nix-command flakes + # The store the development shell comes from. Only an exact match is + # restored, and only main saves, so pull requests cannot evict the + # caches each other start from. + - uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('flake.nix', 'flake.lock') }} + save: ${{ github.ref == 'refs/heads/main' }} + # Load the development shell (flake.nix) into the job. + - uses: nicknovitski/nix-develop@v1 + # The same gate as local development (justfile). + - run: just ci + env: + CI: "1" - name: Upload artifact if: github.ref == 'refs/heads/main' && github.event_name == 'push' - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v5 with: path: ./dist + # Keep dist/.vite in the artifact as earlier versions of this action + # did; v4 started dropping dotfiles by default. + include-hidden-files: true deploy: if: github.ref == 'refs/heads/main' && github.event_name == 'push' - needs: build + needs: ci runs-on: ubuntu-latest + # Deployments queue up and never cancel each other. + concurrency: + group: pages + cancel-in-progress: false + permissions: + contents: read + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 diff --git a/.gitignore b/.gitignore index ac6c48f..cdbbc2d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ .playwright-mcp dist/ node_modules/ +/.envrc +.direnv/ +result +/.claude/worktrees/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8ca3e73 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,90 @@ +# probitas-test.github.io + +Documentation site for [Probitas](https://github.com/probitas-test/probitas) - a +scenario-based testing framework shipped as a single binary. + +- **Runtime**: Node.js + HonoX + Vite SSG +- **API reference**: TypeDoc JSON generated from the npm packages +- **Deploy**: GitHub Pages, from `main` + +## How it is built + +- **Test first.** Red → green → refactor. Write the failing test before the + code that makes it pass. +- **Each layer holds one thing.** Put a fact in the one layer that owns it, + and nowhere else. + + | Layer | Holds | + | --- | --- | + | Tests | the details that pin the behaviour down: rules, boundaries, tables | + | Code | how it is done | + | Commits | why a change was made | + | Comments | why it is not done another way | + +- **Dependencies are current.** Before adding or bumping one, look up its + latest release in the registry. Do not copy a version from memory or from + another repository. + +Site structure, routes and the build pipeline are described in +[`.claude/rules/architecture.md`](.claude/rules/architecture.md); writing +guidelines for the pages under `docs/` in +[`.claude/rules/content.md`](.claude/rules/content.md). + +## Commands + +Run `nix develop` (or use direnv with `.envrc.sample`) first so every tool is +on PATH, then: + +```bash +just install # npm ci +just dev # Dev server with HMR +just build # Build static site (client + SSG + Pagefind) +just preview # Preview production build +just test # Check internal links in the built site +just generate-api # Regenerate data/api/ from the npm packages +``` + +## Quality gate + +Run `just ci` before reporting a change as done. CI runs the same recipe. + +## Reference Probitas packages + +When referencing the Probitas API: + +- Scenarios import from `@probitas-test/probitas` (npm); the JSR mirror is + `@probitas/probitas` +- `data/api/{package}.json` holds the generated TypeDoc JSON of each package +- Check `../probitas/` for the user-facing package and CLI source +- Check `../probitas-packages/` for framework and client package source + +## Layout + +| Path | What lives there | +| --- | --- | +| `app/` | HonoX routes, templates, components and libraries | +| `data/` | page configuration, home page examples, generated API JSON | +| `docs/` | Markdown source of the documentation pages (site content) | +| `public/` | static assets copied into the site | +| `scripts/` | post-build step and the API reference generator | +| `tests/` | link check of the built site | +| `probitas/` | Probitas scenarios checking a served site (`DOCS_BASE_URL`) | +| `.github/` | CI and the GitHub Pages deployment | + +## Language + +- README, docs and commit messages: English +- Code comments, log and error messages: English + +## Commits + +[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), as +described in [`.gitmessage`](.gitmessage) (install it with +`git config commit.template .gitmessage`): + +``` +[optional scope]: +``` + +- Types: `feat`, `fix`, `deps`, `refactor`, `test`, `docs`, `style`, `chore`. +- Scopes name the area touched, such as `api`, `ci`, `scripts`, `search`. diff --git a/README.md b/README.md index e207fa4..be3641c 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,14 @@ scenario-based testing framework shipped as a single binary. git clone https://github.com/probitas-test/probitas-test.github.io.git cd probitas-test.github.io +# Enter the development shell (Node.js, Pagefind, just) +nix develop + # Install dependencies -npm ci +just install # Start development server -npm run dev +just dev ``` ## Commands @@ -36,6 +39,7 @@ npm run dev | `npm run preview` | Preview built site | | `npm test` | Check internal links in the built site | | `npm run generate-api` | Regenerate API documentation JSON | +| `just ci` | Everything CI checks (Nix format, build, link check) | ## Project Structure @@ -71,7 +75,8 @@ npm run dev ### Prerequisites -- [Node.js](https://nodejs.org/) (LTS) +- [Nix](https://nixos.org/) with flakes enabled; `nix develop` provides Node.js, + Pagefind and [just](https://just.systems/). Without Nix, install Node.js 24. ### Regenerating API Documentation @@ -105,7 +110,7 @@ The `npm run build` command performs the following steps: This site is deployed to **GitHub Pages** via GitHub Actions. 1. Push to `main` branch -2. GitHub Actions runs `npm run build` +2. GitHub Actions runs `just ci`, which builds the site and checks its links 3. Static files in `dist/` are deployed to GitHub Pages Live site: https://probitas-test.github.io/ diff --git a/flake.lock b/flake.lock index 5bad000..2af9c5a 100644 --- a/flake.lock +++ b/flake.lock @@ -18,24 +18,6 @@ "type": "github" } }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "nixpkgs": { "locked": { "lastModified": 1766747458, @@ -70,7 +52,7 @@ }, "probitas-flake": { "inputs": { - "flake-utils": "flake-utils_2", + "flake-utils": "flake-utils", "nixpkgs": "nixpkgs_2" }, "locked": { @@ -89,7 +71,6 @@ }, "root": { "inputs": { - "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", "probitas-flake": "probitas-flake" } @@ -108,21 +89,6 @@ "repo": "default", "type": "github" } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 8a2b994..ca379df 100644 --- a/flake.nix +++ b/flake.nix @@ -1,26 +1,51 @@ { - description = "Development environment for probitas-test/documents"; + description = "Development environment for the Probitas documentation site"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; probitas-flake.url = "github:probitas-test/probitas"; - flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { nixpkgs, probitas-flake, flake-utils, ... }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { + outputs = + { nixpkgs, probitas-flake, ... }: + let + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system); + pkgsFor = + system: + import nixpkgs { inherit system; overlays = [ probitas-flake.overlays.default ]; }; - in { - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - nodejs - pagefind - probitas - ]; - }; - }); + in + { + devShells = forAllSystems ( + system: + let + pkgs = pkgsFor system; + in + { + default = pkgs.mkShell { + packages = [ + # The scripts and tests run as TypeScript through Node's type + # stripping, so the major version is named instead of following + # whatever nixpkgs' default `nodejs` is. + pkgs.nodejs_24 + pkgs.pagefind + # Runs the scenarios under probitas/ against the site. + pkgs.probitas + pkgs.just + pkgs.nixfmt + ]; + }; + } + ); + + formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixfmt); + }; } diff --git a/justfile b/justfile new file mode 100644 index 0000000..a122654 --- /dev/null +++ b/justfile @@ -0,0 +1,42 @@ +# Run `nix develop` (or use direnv) first so every tool is on PATH. + +set shell := ["bash", "-euo", "pipefail", "-c"] + +# List the recipes. +default: + @just --list + +# Install the npm dependencies exactly as package-lock.json pins them. +install: + npm ci + +# Start the dev server with HMR. +dev: + npm run dev + +# Build the static site into dist/ (client, SSG, Pagefind index). +build: + npm run build + +# Preview the built site. +preview: + npm run preview + +# Check the internal links of the built site. +test: + npm test + +# Regenerate data/api/ from the published npm packages. +generate-api: + npm run generate-api + +# Format the Nix files. +fmt: + git ls-files -z '*.nix' | xargs -0 nixfmt + +# Check the Nix files' formatting without changing them. +fmt-check: + git ls-files -z '*.nix' | xargs -0 nixfmt --check + +# Everything CI runs. +ci: fmt-check install build test diff --git a/package-lock.json b/package-lock.json index 8c2c5a7..de0dbcd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@probitas/docs", + "name": "probitas-test.github.io", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@probitas/docs", + "name": "probitas-test.github.io", "version": "0.1.0", "dependencies": { "hono": "^4.7.0", diff --git a/package.json b/package.json index 544209b..63ab472 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { - "name": "@probitas/docs", + "name": "probitas-test.github.io", + "private": true, "version": "0.1.0", "type": "module", "scripts": {