diff --git a/lefthook.yml b/.config/lefthook.yml similarity index 96% rename from lefthook.yml rename to .config/lefthook.yml index dbc5a0a..81ee313 100644 --- a/lefthook.yml +++ b/.config/lefthook.yml @@ -10,9 +10,11 @@ pre-commit: parallel: false commands: oxfmt: + root: src glob: '*.{ts,tsx,css,md,mdx,json,yml,yaml,toml}' run: bunx oxfmt {staged_files} oxlint: + root: src glob: '*.{ts,tsx,js,jsx,astro}' run: bunx oxlint --fix {staged_files} restage: diff --git a/.editorconfig b/.editorconfig index 6324abd..75af23e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,6 +1,3 @@ -# Editor configuration for the Purview-Dev website repository. -# https://editorconfig.org - root = true [*] @@ -19,4 +16,4 @@ trim_trailing_whitespace = false indent_size = 2 [*.astro] -indent_size = 2 \ No newline at end of file +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8d48b3e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,108 @@ +# Default: auto-detect text and normalise to LF in the index. +# Everything below only overrides the *working tree* checkout behaviour. +* text=auto + +# --------------------------------------------------------------------------- +# .NET source and project files +# No eol= means each dev's core.autocrlf / core.eol decides. Set eol=lf here +# instead if you want to hard-enforce LF everywhere -- but keep it in sync +# with end_of_line in .editorconfig or `dotnet format --verify-no-changes` +# will fail in CI. +# --------------------------------------------------------------------------- +*.cs text diff=csharp +*.csx text diff=csharp +*.vb text +*.fs text +*.fsx text +*.csproj text +*.fsproj text +*.vbproj text +*.props text +*.targets text +*.resx text +*.config text +*.ruleset text +*.xaml text +*.cshtml text diff=html +*.razor text diff=html +*.sln text eol=lf +*.slnx text eol=lf + +# --------------------------------------------------------------------------- +# Data, config and docs +# --------------------------------------------------------------------------- +*.json text +*.xml text +*.yml text +*.yaml text +*.toml text +*.md text diff=markdown +*.svg text +*.editorconfig text +.gitattributes text +.gitignore text + +# --------------------------------------------------------------------------- +# Web assets (only relevant if the repo ships any) +# --------------------------------------------------------------------------- +*.js text +*.jsx text +*.ts text +*.tsx text +*.html text diff=html +*.css text +*.scss text + +# --------------------------------------------------------------------------- +# Scripts -- these MUST be pinned regardless of platform. +# cmd.exe misparses LF in multi-line blocks and labels; sh needs LF. +# --------------------------------------------------------------------------- +*.sh text eol=lf +*.bash text eol=lf +*.zsh text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=lf +*.psm1 text eol=lf +*.psd1 text eol=lf +Dockerfile text eol=lf +*.dockerfile text eol=lf +justfile text eol=lf +Makefile text eol=lf + +# Patches carry their own endings -- never touch them. +*.patch -text + +# --------------------------------------------------------------------------- +# Binary +# --------------------------------------------------------------------------- +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.webp binary +*.mp4 binary +*.zip binary +*.gz binary +*.7z binary +*.tar binary +*.exe binary +*.dll binary +*.pdb binary +*.obj binary +*.vsix binary +*.nupkg binary +*.snupkg binary +*.snk binary +*.pfx binary +*.lockb binary +*.woff binary +*.woff2 binary + +# --------------------------------------------------------------------------- +# Keep repo scaffolding out of `git archive` / source packages +# --------------------------------------------------------------------------- +.gitattributes export-ignore +.gitignore export-ignore +.github/ export-ignore diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2c5bc42..28f19eb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,6 +4,9 @@ version: 2 updates: + # The repository is a Bun workspace: the lockfile (`bun.lock`) and the + # workspace root `package.json` live at `/`; the site's dependencies are + # declared in `src/package.json` and are resolved through the root lockfile. - package-ecosystem: npm directory: / schedule: @@ -43,7 +46,7 @@ updates: # major upgrades separate for review. - dependency-name: 'oxfmt' update-types: - - major + - version-update:semver-major - package-ecosystem: github-actions directory: / diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 726e76f..5245a4e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -11,10 +11,10 @@ on: Leave empty for a custom domain or organisation Pages site. required: false type: string - default: '' + default: "" schedule: # Weekly refresh of release information from GitHub and NuGet. - - cron: '17 4 * * 1' + - cron: "17 4 * * 1" repository_dispatch: # Fired by a release workflow in another purview-dev repository. The # expected payload contract is documented in the README. @@ -49,10 +49,17 @@ jobs: with: tool: just@1.58.0 + # The repository is a Bun workspace: the lockfile and root `package.json` + # live here, the Astro site package lives in `src/`, and every `bun run` + # / `just` recipe delegates to `src/` (see `package.json` scripts). - name: Install dependencies run: bun install --frozen-lockfile - name: Run validation + # `just validate` runs a live data sync on fresh checkouts (no cache / + # docs mirror yet), so pass a token to avoid unauthenticated rate limits. + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: just validate - name: Refresh live release and documentation data @@ -98,7 +105,8 @@ jobs: # actions/upload-pages-artifact v5.0.0 uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 with: - path: ./dist + # Build output is written into the `src/` package (see package.json). + path: ./src/dist deploy: needs: build diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index a40a97f..896ec45 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -30,8 +30,15 @@ jobs: with: tool: just@1.58.0 + # The repository is a Bun workspace: the lockfile and root `package.json` + # live here, the Astro site package lives in `src/`, and every `bun run` + # / `just` recipe delegates to `src/` (see `package.json` scripts). - name: Install dependencies run: bun install --frozen-lockfile - name: Run validation + # `just validate` runs a live data sync on fresh checkouts (no cache / + # docs mirror yet), so pass a token to avoid unauthenticated rate limits. + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: just validate diff --git a/.gitignore b/.gitignore index 50dc406..9c8b646 100644 --- a/.gitignore +++ b/.gitignore @@ -1,35 +1,692 @@ -# Dependencies -node_modules/ +# Created by https://www.toptal.com/developers/gitignore/api/openframeworks+visualstudio,visualstudiocode,jetbrains,react,node,astro,aspnetcore,ncrunch,go +# Edit at https://www.toptal.com/developers/gitignore?templates=openframeworks+visualstudio,visualstudiocode,jetbrains,react,node,astro,aspnetcore,ncrunch,go + +### ASPNETCore ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ -# Build output -/dist/ -.astro/ +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json artifacts/ -# Generated data caches and mirrors -.cache/ -src/content/docs/ -src/assets/branding/ -public/branding/ -public/favicon.svg -public/favicon-*.png -public/apple-touch-icon.png -public/icon-*.png -public/og/ - -# Local environment +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/ + +### Astro ### +# Gitignore template for Astro projects +# Ignore content collection generated files +.astro + +### Purview site (workspace lives in src/) ### +# Generated documentation mirror (regenerated by `just data-sync`) +src/src/content/docs/ + +# Build-time caches and output +src/.cache/ +src/dist/ + +# Generated branding/public assets (regenerated by `just data-sync`) +src/public/branding/ +src/public/favicon.svg +src/public/favicon-16.png +src/public/favicon-32.png +src/public/apple-touch-icon.png +src/public/icon-192.png +src/public/icon-512.png +src/public/og/ + +### Go ### +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work + +### JetBrains ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### JetBrains Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +# Azure Toolkit for IntelliJ plugin +# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij +.idea/**/azureSettings.xml + +### NCrunch ### +# NCrunch +*.ncrunch*.user +*.crunch.xml + +### Node ### +# Logs +logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files .env +.env.development.local +.env.test.local +.env.production.local .env.local -# Tooling -*.log -bun-debug.* -bun-error.* +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp -# OS / editor +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +### OpenFrameworks+VisualStudio ### +# ignore generated binaries +# but not the data folder + +/bin/* +!/bin/data/ + +# general + +[Bb]uild/ +*.o +[Dd]ebug*/ +[Rr]elease*/ +*.mode* +*.app/ +.svn/ + +# IDE files which should +# be ignored + +# XCode +*.pbxuser +*.perspective +*.perspectivev3 +*.mode1v3 +*.mode2v3 +# XCode 4 +xcuserdata +*.xcworkspace + +# Code::Blocks +*.depend +*.layout + +# Visual Studio + +# Eclipse +.metadata +local.properties +.externalToolBuilders + +# operating system + +# Linux +# KDE +.directory +.AppleDouble + +# OSX .DS_Store -Thumbs.db *.swp -.idea/ +*~.nib +# Thumbnails +._* + +# Windows +# Image file caches +Thumbs.db +# Folder config file +Desktop.ini + +# Android +.csettings + +### OpenFrameworks+VisualStudio Patch ### + +### react ### +.DS_* +**/*.backup.* +**/*.back.* + +node_modules + +*.sublime* + +psd +thumb +sketch + +### VisualStudioCode ### .vscode/* -!.vscode/extensions.json \ No newline at end of file +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# The generic template ignores `[Rr]elease*/` and `dist` as build output, but +# the site uses those names for source: the releases catalogue page, release +# transforms, committed release fixtures, and the built-output test suite. +!src/fixtures/github/releases/ +!src/fixtures/github/releases/** +!src/fixtures/releases/ +!src/fixtures/releases/** +!src/src/lib/releases/ +!src/src/lib/releases/** +!src/src/pages/releases/ +!src/src/pages/releases/** +!src/tests/dist/ +!src/tests/dist/** + +# End of https://www.toptal.com/developers/gitignore/api/openframeworks+visualstudio,visualstudiocode,jetbrains,react,node,astro,aspnetcore,ncrunch,go + +BenchmarkDotNet.Artifacts/ + +.tools/purview-build/** diff --git a/README.md b/README.md index 7a95c29..cce56ba 100644 --- a/README.md +++ b/README.md @@ -19,21 +19,31 @@ The site is built with [Astro](https://astro.build) and [Preact](https://preactjs.com) islands. Every page is pre-rendered to static HTML; nothing depends on a server at runtime. +The repository is a [Bun workspace](https://bun.sh/docs/install/workspaces) whose +single package — the Astro site — lives in `src/`. All commands are run from the +repo root and delegated to the package: + ``` -src/ -├── content.config.ts # Starlight docs collection schema -├── content/docs/ # GENERATED documentation mirror (gitignored) -├── data/projects.yml # Typed, validated project catalogue manifest -├── lib/ -│ ├── manifest/ # Project manifest schema + validation -│ ├── releases/ # GitHub/NuGet clients, normalisation, transform -│ ├── docs/ # Documentation aggregation + link/alerts transforms -│ ├── urls.ts # Canonical URL + base path handling -│ └── site.ts # Site + brand constants -├── components/ # Shared chrome, Starlight overrides, islands -├── layouts/SiteLayout.astro # Marketing page layout -├── pages/ # Home, catalogue, releases, about, 404 -└── styles/global.css # Design tokens + Tailwind/Starlight theme +purview-dev/ # workspace root +├── package.json # workspace root; delegates scripts to src/ +├── justfile # task runner (runs in the src/ package) +├── docs/decisions/ # architectural decision records +└── src/ # the Astro site package (@purview-dev/website) + ├── assets/branding/ # approved branding sources (never modified) + ├── astro.config.ts # Astro + Starlight configuration + ├── public/ # committed static assets (robots.txt, site.webmanifest) + ├── scripts/ # data sync, branding, checks, fetchers + ├── src/ + │ ├── content.config.ts # Starlight docs collection schema + │ ├── content/docs/ # GENERATED documentation mirror (gitignored) + │ ├── data/projects.yml # Typed, validated project catalogue manifest + │ ├── lib/ # manifest, releases, docs, urls, site constants + │ ├── components/ # shared chrome, Starlight overrides, islands + │ ├── layouts/ # SiteLayout.astro (marketing pages) + │ ├── pages/ # Home, catalogue, releases, about, 404 + │ └── styles/global.css # design tokens + Tailwind/Starlight theme + ├── tests/ # unit tests + built-output assertions + └── fixtures/ # committed offline data fixtures ``` See `docs/decisions/0001-architecture.md` for the architectural decision record. @@ -53,6 +63,7 @@ See `docs/decisions/0001-architecture.md` for the architectural decision record. | Search | Pagefind (bundled with Starlight) | — | | LLM outputs | starlight-llms-txt | 0.12.0 | | Link validation | starlight-links-validator + dist crawl | — | +| Sidebar topics | starlight-sidebar-topics | 0.9.0 | All application and configuration code is TypeScript. oxfmt does not yet support `.astro` files (oxc-project/oxc#15665), so `.astro` components are @@ -148,39 +159,40 @@ bundle. just dev ``` -The dev server starts after a data sync. Edit `src/pages/` for marketing pages -and `src/data/projects.yml` for catalogue content. Documentation pages are -generated under `src/content/docs/` and should not be edited by hand — change -the source repository instead and re-run `just data-sync`. +The dev server starts after a data sync. Edit `src/src/pages/` for marketing +pages and `src/src/data/projects.yml` for catalogue content. Documentation pages +are generated under `src/src/content/docs/` and should not be edited by hand — +change the source repository instead and re-run `just data-sync`. ## Testing and validation -Unit tests live in `tests/unit/` (Bun's test runner) and run without network or -live APIs — they use committed fixtures under `fixtures/`. Built-output -assertions live in `tests/dist/`. `just validate` runs everything needed to +Unit tests live in `src/tests/unit/` (Bun's test runner) and run without network +or live APIs — they use committed fixtures under `src/fixtures/`. Built-output +assertions live in `src/tests/dist/`. `just validate` runs everything needed to prove the site is safe to merge. ## Branding asset handling -The approved branding sources live in `assets/branding/` and are never modified. -`just data-sync` runs `scripts/process-branding.ts`, which copies the assets the -built site needs into `public/` (SVG masters, light/dark logo variants, raster -favicons, touch/application icons, and the generated Open Graph image). The -design tokens in `src/styles/global.css` are derived from the brand values in -`assets/branding/README.md` (purple `#8B3DFF`, deep purple `#6820D2`, ink +The approved branding sources live in `src/assets/branding/` and are never +modified. `just data-sync` runs `src/scripts/process-branding.ts`, which copies +the assets the built site needs into `src/public/` (adaptive SVG masters for the +favicon, header logo, and banner, light/dark PNG variants, raster favicons, +touch/application icons, and the generated Open Graph image). The design tokens +in `src/src/styles/global.css` are derived from the brand values in +`src/assets/branding/README.md` (purple `#8B3DFF`, deep purple `#6820D2`, ink `#17141F`/`#FFFFFF`). `just check-assets` validates the sources and the generated copies. ## Project catalogue -`src/data/projects.yml` is the single source of truth for the catalogue. It is -validated at build time by a typed Zod schema (`src/lib/manifest/schema.ts`). -Validation failures report the source file, the offending property, the -expected shape, and a remediation hint. +`src/src/data/projects.yml` is the single source of truth for the catalogue. It +is validated at build time by a typed Zod schema +(`src/src/lib/manifest/schema.ts`). Validation failures report the source file, +the offending property, the expected shape, and a remediation hint. ### Adding a new Purview-Dev project -1. Add a record to `src/data/projects.yml` with a unique `id`, `name`, +1. Add a record to `src/src/data/projects.yml` with a unique `id`, `name`, `shortDescription`, `description`, `repository` (a purview-dev repo), `category`, `status`, and optional `order`. 2. Declare its NuGet packages under `packages` — every package id must belong to @@ -196,6 +208,13 @@ expected shape, and a remediation hint. docs aggregation, and release transforms are all regenerated from this one file. +### Adding an external (collaboration) project + +Projects the organisation contributes to but does not own are listed under +`externalProjects` in the same file. They are rendered in a "Collaborations" +section on the catalogue page and link to their own site/repository (e.g. +`https://likec4.dev` for LikeC4) rather than the Purview catalogue. + ## Documentation aggregation Documentation is owned by each product repository and presented through this @@ -221,10 +240,10 @@ cache. Version selection is based on semver tags because the organisation's changesets automation publishes `vX.Y.Z-prerelease.N` tags with the GitHub `prerelease` flag set to `false`. -- `just fetch-releases` fetches live data into `.cache/releases/releases.json` +- `just fetch-releases` fetches live data into `src/.cache/releases/releases.json` (typed, versioned, timestamped, gitignored). - Without a cache, the site falls back to committed fixtures under - `fixtures/releases/` and labels the data source (`live` / `cache` / + `src/fixtures/releases/` and labels the data source (`live` / `cache` / `fixture`) in the UI. - `just refresh-fixtures` regenerates the committed test fixtures from live sources (review the diff before committing). @@ -263,7 +282,7 @@ Configuration notes: `purview-dev.github.io`. The workflow validates (`just validate`), refreshes live release/documentation -data, builds, and uploads `./dist`. +data, builds, and uploads `./src/dist`. ### Repository-dispatch integration @@ -299,5 +318,5 @@ kept separate for review. - **`.astro` files are not reformatted**: oxfmt does not support Astro yet (oxc-project/oxc#15665); format them by hand — they are still linted and type-checked. -- **Formatting diffs in generated content**: never edit `src/content/docs/` or - `.cache/` by hand; regenerate them with `just data-sync`. +- **Formatting diffs in generated content**: never edit `src/src/content/docs/` + or `src/.cache/` by hand; regenerate them with `just data-sync`. diff --git a/bun.lock b/bun.lock index 83f30e2..47bbd78 100644 --- a/bun.lock +++ b/bun.lock @@ -3,7 +3,11 @@ "configVersion": 1, "workspaces": { "": { + "name": "purview-dev", + }, + "src": { "name": "@purview-dev/website", + "version": "0.1.0", "dependencies": { "preact": "10.29.8", }, @@ -25,6 +29,7 @@ "sharp": "0.35.4", "starlight-links-validator": "0.26.0", "starlight-llms-txt": "0.12.0", + "starlight-sidebar-topics": "0.9.0", "tailwindcss": "4.3.3", "typescript": "5.9.3", "yaml": "2.9.1", @@ -305,7 +310,7 @@ "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], - "@oxc-project/types": ["@oxc-project/types@0.149.0", "", {}, "sha512-Efcc+iF0j3Bf67YjEqIqWXbX5XddXoK/Mw4K1/JuXwRCZ8N16VR7iT23nlCc9XrveFVh/E5Rqs2StT0V8v9LdA=="], + "@oxc-project/types": ["@oxc-project/types@0.150.0", "", {}, "sha512-rDS5/31E9HfPl/CIzGrn0DOlvBbXFseQ5URJ9sYMfstbKLD/c6Gm9vmRzRGDdAXyOIL4zmO37lc9RIwYqVruZw=="], "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.68.0", "", { "os": "android", "cpu": "arm" }, "sha512-dhfYPbzv/h9JgHjNkl2R6sOjUfxDyLGOZVb3g8/ScaTNwwJcYgmHh8kcYFDUhinuy1QAoANCWUvw1jlk+z6gAg=="], @@ -413,35 +418,37 @@ "@prefresh/vite": ["@prefresh/vite@2.4.12", "", { "dependencies": { "@babel/core": "^7.22.1", "@prefresh/babel-plugin": "^0.5.2", "@prefresh/core": "^1.5.0", "@prefresh/utils": "^1.2.0", "@rollup/pluginutils": "^4.2.1" }, "peerDependencies": { "preact": "^10.4.0 || ^11.0.0-0", "vite": ">=2.0.0" } }, "sha512-FY1fzXpUjiuosznMV0YM7XAOPZjB5FIdWS0W24+XnlxYkt9hNAwwsiKYn+cuTEoMtD/ZVazS5QVssBr9YhpCQA=="], - "@rolldown/binding-android-arm-eabi": ["@rolldown/binding-android-arm-eabi@1.2.8", "", { "os": "android", "cpu": "arm" }, "sha512-tN5aztYkKCte4i5SIrrz5yK/HMjEuCqCSCJa418jOV8tZ1cBY3YF2otxB1ktPxzsLA1BeTqwapK0bfjxNvHJVw=="], + "@purview-dev/website": ["@purview-dev/website@workspace:src"], + + "@rolldown/binding-android-arm-eabi": ["@rolldown/binding-android-arm-eabi@1.2.9", "", { "os": "android", "cpu": "arm" }, "sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.2.8", "", { "os": "android", "cpu": "arm64" }, "sha512-dIYTWl9XprMUiQFoc55KUyk/oS8SKYH3zFl0LTR7RT0Xj4hgSVyuJcroH8JUu8RcpF8fTB6E0aOwCkZoYPcDSQ=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.2.9", "", { "os": "android", "cpu": "arm64" }, "sha512-YC8YsI30o606GTZi0VyzYlsDKFP8W61i/QzayHDkLbNEz/IShqAmTa+hsJRj13xTHA0H+6fk4b2UmGn+Q/cMlg=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.2.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PCSDQGXD2IyTEFrcgPyBM8jJuGmrbCMuoIOXdbEGVemruKACXoLQJrb+A45Z0L5t1RQkdfJprAYPkikbh7dzdA=="], + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.2.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-IwhlH3qK5urrY8hZiEgGkHKEFN901p/p2bjxCxJlr4GyNnF7wYpUvK+Y43uaRYuC4hpfjzbR3SJC3arX1jGvmw=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.2.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-Uk7lRsGhPFHVX/sAUC6D5H9Ol30dFHd6iquokll2th3LpdJ3F5CzQB+7DHn0Ri2mG+U7k2zXiPHDrwZenXhwSA=="], + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.2.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-XxpJfVzFh+jilRxIXUqcfYAYcunIc/XEzIizsOL1fcJee5Sf7H3mH8WlLmfHfluz5amqR88QQo9izKtmMlavAw=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.2.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-DjszaTEVogPqA5bYzsEeqDCQxbcp2fexQwKcRspYji2yzR68fCf+e4fx6kBSRDwX5/brZaHw/hWS9+A/+/w9sQ=="], + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.2.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kSfvhmgeWyfkbT3p/1s5vSgboogoah2zkm9fX2zjg2hHxSV7T4KhMWRUUaRk4OXNqoD3QAUeRqLcs1aZOK4U1g=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.2.8", "", { "os": "linux", "cpu": "arm" }, "sha512-zmwa7FTmdzB6aaEEuuls18H6Ap5JmJPSoPTuXixeJZV6tG40SyLkApQtz1g8ptZtiEKqj9OM0oNLPh1AgvE31Q=="], + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.2.9", "", { "os": "linux", "cpu": "arm" }, "sha512-1RVzG17pxqbTfYLC352JlLt6kKLG+6Hr30n8DlIJqsnV5luUDd2Qdx9Ayw1Cabfyb1K9k0jXEZ7evxkRoT+uiw=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.2.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-KdYQDPHwJVnbFwdTGMgxsI9SqblBlz6STGM+w1We/d5B8OWWidYH0MwkU/uA1wM5fIpO2MkOVxXrNzzuZhw9ew=="], + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.2.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-BXqPvZ2drqVD+/Z8UpKwcs4Mp7grM+eGFku4CAEKrEtcbAsUpzREphK1sogCRZGreVPiMkiiBtw0n3TPteuqvw=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.2.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-jFJTifHnNPY+yzOoNZQfSIysrVyXzEQPhPnOUjmD1bcQGHH6s7c8cViKWar8YplQImE5N9JRqMCLrM2CdxOrZA=="], + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.2.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-11vWvo8YDwLzukt27J3aYDWU+gg2P7J+ZOmiJ0hkF5BXZDW7pVya7r40MXDy6ya0i9KamoENSVKIugvJNgFXIA=="], - "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.2.8", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FhiOziBDWPBjbcmRzfLyIJnaP7AVMFXT7YCXPjXxj7wKU3vx24RjrCNN/zjvVa+N2vVoHJwCoUBvsrN/DG3zIA=="], + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.2.9", "", { "os": "linux", "cpu": "ppc64" }, "sha512-a1tijMkdwsIARtc0F39ApURROkf3NwqinI6TOiSSWCTR7dT96dffNvMUtDHnq64wKNTIZOIlzKrFvvFUznJiyw=="], - "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.2.8", "", { "os": "linux", "cpu": "s390x" }, "sha512-WnHfADMzOV2Y55wlx1hzzQnar/wDt/VdvWSD99r18Mz9ylNieIGOkRx3UV21h7m/eJvjySYJkO26VvGNFkwsIQ=="], + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.2.9", "", { "os": "linux", "cpu": "s390x" }, "sha512-x6SQNdAvv4c3hWqTMaWuawzMX9myaCs/yEmlGsxJzkdClnHW7FbrjQuSiRDhuSYzEYoEMhsaJy9qHG/XNemJPQ=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.2.8", "", { "os": "linux", "cpu": "x64" }, "sha512-H9tRr5ibfXFVLxbPOseVewewFpl28zcEdjRDt2FTUZU7odxP0gEv1ki4/kGmcGOh78oRwZuuQllGLZ9zTJp84g=="], + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.2.9", "", { "os": "linux", "cpu": "x64" }, "sha512-9s0AZ8BFK5/n7B/TBoa2yJE3gI3KURrbXcPBlsAsvjU4VeJKgE90y1YtNxyEUIcHPQkg6/yfF3qihUrcM/Kf0Q=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.2.8", "", { "os": "linux", "cpu": "x64" }, "sha512-UefiqfM3D6IVNlZ8tSGs9+Ejjud2T+oxO0IHADU45Y+lyEjD2dVFyZHbkfX0LUb5Zugo/oIv1eCO/KVYhgYJYA=="], + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.2.9", "", { "os": "linux", "cpu": "x64" }, "sha512-P7VWAmV+WdJluH7ovnRGoiv2i8To7GAZ+kGzfGup635cyL7SyYl3lSUaA3Gp5THf0n/Co5EyEqb2zbqq+nMOHQ=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.2.8", "", { "os": "none", "cpu": "arm64" }, "sha512-637Ke4kWSy6rp9cxQ9gMOXlxPgIw/c1beASV4M//3+9I4uwBVOOl74G+e3zyU3u19U7RkRl/HuewixZ/Z6+Rjg=="], + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.2.9", "", { "os": "none", "cpu": "arm64" }, "sha512-1qixtsE4BK8h+yS3BfmZ09UhA7O/N4IACva6YBr7EBvCJraByTuRcgOTaiA62Tm0vey3UcKXLOaoGHtYmNGEVg=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.2.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-xWBkPOF1Q9k/Gv1nQXnVdLxKu74jXppuOM4Z3mnypVUJJJwLsMl7hNJGRAUJoG8A5MgOI1ACKM+wBFxSJzKy4A=="], + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.2.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-ok8IQjcEPs1AKZfuEUznVBrJw+gK4soq+bx8b1X2XoMqVClarc1q5JDmVtWXY1xfr6ZuHTAsPXHTgTrqKTZeww=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.2.8", "", { "os": "win32", "cpu": "x64" }, "sha512-uz2ZvfgXbxqNwijjjbxrnvALwpyODDcgc1T1N8N3rf/DXKQmaFwmB4LX4yyjggpwN2obdQLb2rgirX5ffCWYng=="], + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.2.9", "", { "os": "win32", "cpu": "x64" }, "sha512-Ip2mXoU0hM0boq3Rf+ekuT653OROSo6aSYcPT1VHE4q52KvyxgFkQgrgb/IEsxOuvQ2fZZbs8khJAyCEPM24/g=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], @@ -667,7 +674,7 @@ "dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="], - "electron-to-chromium": ["electron-to-chromium@1.5.429", "", {}, "sha512-/1ENIE3cx4HTIx4IfPZFaOunJmsrSVTnj6coXoRVbiJUbkeTyFkJvBeWGkdgh08OhFbxYLMT1kbkwFVSarq6Ow=="], + "electron-to-chromium": ["electron-to-chromium@1.5.430", "", {}, "sha512-e1QEj72Y4zd8RlNZVmoTg+iCOSVwpk05IOiiQwdrkwCSVlZfPthevErhE+nckGd2YbsXfp1SkisznhGVIXP2NQ=="], "emmet": ["emmet@2.4.11", "", { "dependencies": { "@emmetio/abbreviation": "^2.3.3", "@emmetio/css-abbreviation": "^2.1.8" } }, "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ=="], @@ -1047,7 +1054,7 @@ "preact-render-to-string": ["preact-render-to-string@6.7.0", "", { "peerDependencies": { "preact": ">=10 || >= 11.0.0-0" } }, "sha512-Z4WR8fmLMRpdYqJ9i7vrlXSsSrxVJydwrkEXHapexfARbWfGb7vGcnvNQnIzN0cXciMVOlz/XLoiMCi9gUsy9Q=="], - "prettier": ["prettier@3.9.6", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g=="], + "prettier": ["prettier@3.9.7", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-T3mF5P7HFzZVLDQuCUNtJj6WK1pcpLMweMNUVwGb01bLNkH9AkKxtZvmInw8K6bnn2O3d6/5RHl6zSHiBAD0Og=="], "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], @@ -1093,7 +1100,7 @@ "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "rolldown": ["rolldown@1.2.8", "", { "dependencies": { "@oxc-project/types": "=0.149.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm-eabi": "1.2.8", "@rolldown/binding-android-arm64": "1.2.8", "@rolldown/binding-darwin-arm64": "1.2.8", "@rolldown/binding-darwin-x64": "1.2.8", "@rolldown/binding-freebsd-x64": "1.2.8", "@rolldown/binding-linux-arm-gnueabihf": "1.2.8", "@rolldown/binding-linux-arm64-gnu": "1.2.8", "@rolldown/binding-linux-arm64-musl": "1.2.8", "@rolldown/binding-linux-ppc64-gnu": "1.2.8", "@rolldown/binding-linux-s390x-gnu": "1.2.8", "@rolldown/binding-linux-x64-gnu": "1.2.8", "@rolldown/binding-linux-x64-musl": "1.2.8", "@rolldown/binding-openharmony-arm64": "1.2.8", "@rolldown/binding-win32-arm64-msvc": "1.2.8", "@rolldown/binding-win32-x64-msvc": "1.2.8" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-Z67nTmhZe7anqnM/EjI392w5i/ANUinjip7QYsOyN37oayduxt3ksdX0hf5OOamkAd53BiIHfbfSzfUmzKFQqQ=="], + "rolldown": ["rolldown@1.2.9", "", { "dependencies": { "@oxc-project/types": "=0.150.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm-eabi": "1.2.9", "@rolldown/binding-android-arm64": "1.2.9", "@rolldown/binding-darwin-arm64": "1.2.9", "@rolldown/binding-darwin-x64": "1.2.9", "@rolldown/binding-freebsd-x64": "1.2.9", "@rolldown/binding-linux-arm-gnueabihf": "1.2.9", "@rolldown/binding-linux-arm64-gnu": "1.2.9", "@rolldown/binding-linux-arm64-musl": "1.2.9", "@rolldown/binding-linux-ppc64-gnu": "1.2.9", "@rolldown/binding-linux-s390x-gnu": "1.2.9", "@rolldown/binding-linux-x64-gnu": "1.2.9", "@rolldown/binding-linux-x64-musl": "1.2.9", "@rolldown/binding-openharmony-arm64": "1.2.9", "@rolldown/binding-win32-arm64-msvc": "1.2.9", "@rolldown/binding-win32-x64-msvc": "1.2.9" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg=="], "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], @@ -1127,6 +1134,8 @@ "starlight-llms-txt": ["starlight-llms-txt@0.12.0", "", { "dependencies": { "@astrojs/mdx": "^8.0.1", "@types/hast": "^3.0.5", "@types/micromatch": "^4.0.10", "github-slugger": "^2.0.0", "hast-util-select": "^6.0.4", "micromatch": "^4.0.8", "rehype-parse": "^9.0.1", "rehype-remark": "^10.0.1", "remark-gfm": "^4.0.1", "remark-stringify": "^11.0.0", "unified": "^11.0.5", "unist-util-remove": "^4.0.0" }, "peerDependencies": { "@astrojs/starlight": ">=0.41.0", "astro": "^7.0.0" } }, "sha512-ya4c0ZoiPUXuHDzd3AYCKh78Y3II3EToSE9Yp6uVN0c2UUKoNpqTjijhW86W/4toZzSUhWSnxeYs7QBcXNIPGg=="], + "starlight-sidebar-topics": ["starlight-sidebar-topics@0.9.0", "", { "dependencies": { "picomatch": "^4.0.3" }, "peerDependencies": { "@astrojs/starlight": ">=0.42.0", "astro": "^7.2.10" } }, "sha512-xFwMAAtTVyqsO5DZ8Ldk0vN+2QoPdtjtDi8fbrzvQATIJvIvfaBLL9JzfXAjNHI9vMkj35VMWMd8tTICeO6RIA=="], + "string-width": ["string-width@8.2.2", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg=="], "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], diff --git a/docs/decisions/0001-architecture.md b/docs/decisions/0001-architecture.md index 48b401a..af93c4b 100644 --- a/docs/decisions/0001-architecture.md +++ b/docs/decisions/0001-architecture.md @@ -43,10 +43,11 @@ repository, edit URL), converts GitHub alert blockquotes to Starlight asides, rewrites relative links and images so they work inside the portal, and resolves `_Sidebar.md` ordering where the source provides it. Each page exposes its owning project, lifecycle status, staleness, and an edit link back to the source -repository. Documentation is served at project-root paths (e.g. -`/telemetry-sourcegenerator/`) rather than `/docs//`: keeping content -in the default locale is required for `llms.txt` generation and avoids a -misleading language selector. +repository. Documentation is served under `/docs//` (e.g. +`/docs/telemetry-sourcegenerator/`), keeping all documentation pages under a +single `/docs/*` namespace while each project keeps its own sidebar section. +Content stays in the default locale, which is required for `llms.txt` +generation and avoids a misleading language selector. ### 4. Preact islands instead of a client-heavy application diff --git a/package.json b/package.json index cb8d17c..042c55d 100644 --- a/package.json +++ b/package.json @@ -1,54 +1,30 @@ { - "name": "@purview-dev/website", - "version": "0.1.0", + "name": "purview-dev", "private": true, - "description": "Purview-Dev public website and unified documentation portal.", + "description": "Purview-Dev public website and unified documentation portal (workspace root).", "license": "MIT", + "workspaces": [ + "src" + ], "type": "module", "scripts": { - "build": "astro build", - "check:assets": "bun run scripts/check-assets.ts", - "check:generated": "bun run scripts/check-generated.ts", - "check:links": "bun run scripts/check-links.ts", - "clean": "bun run scripts/clean.ts", - "data:sync": "bun run scripts/data-sync.ts", - "dev": "astro dev", - "fetch:releases": "bun run scripts/fetch-releases.ts", - "format": "oxfmt", - "format:check": "oxfmt --check", - "lint": "oxlint", - "lint:fix": "oxlint --fix", - "preview": "astro preview", - "refresh:fixtures": "bun run scripts/refresh-fixtures.ts", - "test": "bun test tests/unit", - "test:dist": "bun test tests/dist", - "typecheck": "astro check" - }, - "dependencies": { - "preact": "10.29.8" - }, - "devDependencies": { - "@astrojs/check": "0.9.10", - "@astrojs/preact": "6.0.5", - "@astrojs/sitemap": "3.7.4", - "@astrojs/starlight": "0.42.1", - "@astrojs/starlight-tailwind": "5.0.0", - "@tailwindcss/vite": "4.3.3", - "@types/bun": "1.4.2", - "@types/semver": "^7.8.0", - "astro": "7.3.2", - "fast-glob": "3.3.3", - "lefthook": "2.1.14", - "oxfmt": "0.68.0", - "oxlint": "1.83.0", - "semver": "7.8.5", - "sharp": "0.35.4", - "starlight-links-validator": "0.26.0", - "starlight-llms-txt": "0.12.0", - "tailwindcss": "4.3.3", - "typescript": "5.9.3", - "yaml": "2.9.1", - "zod": "4.6.5" + "build": "bun run --cwd src build", + "check:assets": "bun run --cwd src check:assets", + "check:generated": "bun run --cwd src check:generated", + "check:links": "bun run --cwd src check:links", + "clean": "bun run --cwd src clean", + "data:sync": "bun run --cwd src data:sync", + "dev": "bun run --cwd src dev", + "fetch:releases": "bun run --cwd src fetch:releases", + "format": "bun run --cwd src format", + "format:check": "bun run --cwd src format:check", + "lint": "bun run --cwd src lint", + "lint:fix": "bun run --cwd src lint:fix", + "preview": "bun run --cwd src preview", + "refresh:fixtures": "bun run --cwd src refresh:fixtures", + "test": "bun run --cwd src test", + "test:dist": "bun run --cwd src test:dist", + "typecheck": "bun run --cwd src typecheck" }, "engines": { "bun": ">=1.4.2", diff --git a/.env.example b/src/.env.example similarity index 100% rename from .env.example rename to src/.env.example diff --git a/assets/branding/README.md b/src/assets/branding/README.md similarity index 100% rename from assets/branding/README.md rename to src/assets/branding/README.md diff --git a/assets/branding/purview-banner-dark-1280x320.png b/src/assets/branding/purview-banner-dark-1280x320.png similarity index 100% rename from assets/branding/purview-banner-dark-1280x320.png rename to src/assets/branding/purview-banner-dark-1280x320.png diff --git a/assets/branding/purview-banner-dark-2560x640.png b/src/assets/branding/purview-banner-dark-2560x640.png similarity index 100% rename from assets/branding/purview-banner-dark-2560x640.png rename to src/assets/branding/purview-banner-dark-2560x640.png diff --git a/assets/branding/purview-banner-light-1280x320.png b/src/assets/branding/purview-banner-light-1280x320.png similarity index 100% rename from assets/branding/purview-banner-light-1280x320.png rename to src/assets/branding/purview-banner-light-1280x320.png diff --git a/assets/branding/purview-banner-light-2560x640.png b/src/assets/branding/purview-banner-light-2560x640.png similarity index 100% rename from assets/branding/purview-banner-light-2560x640.png rename to src/assets/branding/purview-banner-light-2560x640.png diff --git a/assets/branding/purview-banner.svg b/src/assets/branding/purview-banner.svg similarity index 100% rename from assets/branding/purview-banner.svg rename to src/assets/branding/purview-banner.svg diff --git a/assets/branding/purview-icon-dark-1024x1024.png b/src/assets/branding/purview-icon-dark-1024x1024.png similarity index 100% rename from assets/branding/purview-icon-dark-1024x1024.png rename to src/assets/branding/purview-icon-dark-1024x1024.png diff --git a/assets/branding/purview-icon-dark-128x128.png b/src/assets/branding/purview-icon-dark-128x128.png similarity index 100% rename from assets/branding/purview-icon-dark-128x128.png rename to src/assets/branding/purview-icon-dark-128x128.png diff --git a/assets/branding/purview-icon-dark-256x256.png b/src/assets/branding/purview-icon-dark-256x256.png similarity index 100% rename from assets/branding/purview-icon-dark-256x256.png rename to src/assets/branding/purview-icon-dark-256x256.png diff --git a/assets/branding/purview-icon-dark-512x512.png b/src/assets/branding/purview-icon-dark-512x512.png similarity index 100% rename from assets/branding/purview-icon-dark-512x512.png rename to src/assets/branding/purview-icon-dark-512x512.png diff --git a/assets/branding/purview-icon-dark-64x64.png b/src/assets/branding/purview-icon-dark-64x64.png similarity index 100% rename from assets/branding/purview-icon-dark-64x64.png rename to src/assets/branding/purview-icon-dark-64x64.png diff --git a/assets/branding/purview-icon-dark-background-rounded-1024x1024.png b/src/assets/branding/purview-icon-dark-background-rounded-1024x1024.png similarity index 100% rename from assets/branding/purview-icon-dark-background-rounded-1024x1024.png rename to src/assets/branding/purview-icon-dark-background-rounded-1024x1024.png diff --git a/assets/branding/purview-icon-dark-background-rounded-128x128.png b/src/assets/branding/purview-icon-dark-background-rounded-128x128.png similarity index 100% rename from assets/branding/purview-icon-dark-background-rounded-128x128.png rename to src/assets/branding/purview-icon-dark-background-rounded-128x128.png diff --git a/assets/branding/purview-icon-dark-background-rounded-256x256.png b/src/assets/branding/purview-icon-dark-background-rounded-256x256.png similarity index 100% rename from assets/branding/purview-icon-dark-background-rounded-256x256.png rename to src/assets/branding/purview-icon-dark-background-rounded-256x256.png diff --git a/assets/branding/purview-icon-dark-background-rounded-512x512.png b/src/assets/branding/purview-icon-dark-background-rounded-512x512.png similarity index 100% rename from assets/branding/purview-icon-dark-background-rounded-512x512.png rename to src/assets/branding/purview-icon-dark-background-rounded-512x512.png diff --git a/assets/branding/purview-icon-dark-background-rounded-64x64.png b/src/assets/branding/purview-icon-dark-background-rounded-64x64.png similarity index 100% rename from assets/branding/purview-icon-dark-background-rounded-64x64.png rename to src/assets/branding/purview-icon-dark-background-rounded-64x64.png diff --git a/assets/branding/purview-icon-dark-background-square-1024x1024.png b/src/assets/branding/purview-icon-dark-background-square-1024x1024.png similarity index 100% rename from assets/branding/purview-icon-dark-background-square-1024x1024.png rename to src/assets/branding/purview-icon-dark-background-square-1024x1024.png diff --git a/assets/branding/purview-icon-dark-background-square-128x128.png b/src/assets/branding/purview-icon-dark-background-square-128x128.png similarity index 100% rename from assets/branding/purview-icon-dark-background-square-128x128.png rename to src/assets/branding/purview-icon-dark-background-square-128x128.png diff --git a/assets/branding/purview-icon-dark-background-square-256x256.png b/src/assets/branding/purview-icon-dark-background-square-256x256.png similarity index 100% rename from assets/branding/purview-icon-dark-background-square-256x256.png rename to src/assets/branding/purview-icon-dark-background-square-256x256.png diff --git a/assets/branding/purview-icon-dark-background-square-512x512.png b/src/assets/branding/purview-icon-dark-background-square-512x512.png similarity index 100% rename from assets/branding/purview-icon-dark-background-square-512x512.png rename to src/assets/branding/purview-icon-dark-background-square-512x512.png diff --git a/assets/branding/purview-icon-dark-background-square-64x64.png b/src/assets/branding/purview-icon-dark-background-square-64x64.png similarity index 100% rename from assets/branding/purview-icon-dark-background-square-64x64.png rename to src/assets/branding/purview-icon-dark-background-square-64x64.png diff --git a/assets/branding/purview-icon-light-1024x1024.png b/src/assets/branding/purview-icon-light-1024x1024.png similarity index 100% rename from assets/branding/purview-icon-light-1024x1024.png rename to src/assets/branding/purview-icon-light-1024x1024.png diff --git a/assets/branding/purview-icon-light-128x128.png b/src/assets/branding/purview-icon-light-128x128.png similarity index 100% rename from assets/branding/purview-icon-light-128x128.png rename to src/assets/branding/purview-icon-light-128x128.png diff --git a/assets/branding/purview-icon-light-256x256.png b/src/assets/branding/purview-icon-light-256x256.png similarity index 100% rename from assets/branding/purview-icon-light-256x256.png rename to src/assets/branding/purview-icon-light-256x256.png diff --git a/assets/branding/purview-icon-light-512x512.png b/src/assets/branding/purview-icon-light-512x512.png similarity index 100% rename from assets/branding/purview-icon-light-512x512.png rename to src/assets/branding/purview-icon-light-512x512.png diff --git a/assets/branding/purview-icon-light-64x64.png b/src/assets/branding/purview-icon-light-64x64.png similarity index 100% rename from assets/branding/purview-icon-light-64x64.png rename to src/assets/branding/purview-icon-light-64x64.png diff --git a/assets/branding/purview-icon-light-background-rounded-1024x1024.png b/src/assets/branding/purview-icon-light-background-rounded-1024x1024.png similarity index 100% rename from assets/branding/purview-icon-light-background-rounded-1024x1024.png rename to src/assets/branding/purview-icon-light-background-rounded-1024x1024.png diff --git a/assets/branding/purview-icon-light-background-rounded-128x128.png b/src/assets/branding/purview-icon-light-background-rounded-128x128.png similarity index 100% rename from assets/branding/purview-icon-light-background-rounded-128x128.png rename to src/assets/branding/purview-icon-light-background-rounded-128x128.png diff --git a/assets/branding/purview-icon-light-background-rounded-256x256.png b/src/assets/branding/purview-icon-light-background-rounded-256x256.png similarity index 100% rename from assets/branding/purview-icon-light-background-rounded-256x256.png rename to src/assets/branding/purview-icon-light-background-rounded-256x256.png diff --git a/assets/branding/purview-icon-light-background-rounded-512x512.png b/src/assets/branding/purview-icon-light-background-rounded-512x512.png similarity index 100% rename from assets/branding/purview-icon-light-background-rounded-512x512.png rename to src/assets/branding/purview-icon-light-background-rounded-512x512.png diff --git a/assets/branding/purview-icon-light-background-rounded-64x64.png b/src/assets/branding/purview-icon-light-background-rounded-64x64.png similarity index 100% rename from assets/branding/purview-icon-light-background-rounded-64x64.png rename to src/assets/branding/purview-icon-light-background-rounded-64x64.png diff --git a/assets/branding/purview-icon-light-background-square-1024x1024.png b/src/assets/branding/purview-icon-light-background-square-1024x1024.png similarity index 100% rename from assets/branding/purview-icon-light-background-square-1024x1024.png rename to src/assets/branding/purview-icon-light-background-square-1024x1024.png diff --git a/assets/branding/purview-icon-light-background-square-128x128.png b/src/assets/branding/purview-icon-light-background-square-128x128.png similarity index 100% rename from assets/branding/purview-icon-light-background-square-128x128.png rename to src/assets/branding/purview-icon-light-background-square-128x128.png diff --git a/assets/branding/purview-icon-light-background-square-256x256.png b/src/assets/branding/purview-icon-light-background-square-256x256.png similarity index 100% rename from assets/branding/purview-icon-light-background-square-256x256.png rename to src/assets/branding/purview-icon-light-background-square-256x256.png diff --git a/assets/branding/purview-icon-light-background-square-512x512.png b/src/assets/branding/purview-icon-light-background-square-512x512.png similarity index 100% rename from assets/branding/purview-icon-light-background-square-512x512.png rename to src/assets/branding/purview-icon-light-background-square-512x512.png diff --git a/assets/branding/purview-icon-light-background-square-64x64.png b/src/assets/branding/purview-icon-light-background-square-64x64.png similarity index 100% rename from assets/branding/purview-icon-light-background-square-64x64.png rename to src/assets/branding/purview-icon-light-background-square-64x64.png diff --git a/assets/branding/purview-icon.svg b/src/assets/branding/purview-icon.svg similarity index 100% rename from assets/branding/purview-icon.svg rename to src/assets/branding/purview-icon.svg diff --git a/assets/branding/purview-logo-horizontal-dark-1200x411.png b/src/assets/branding/purview-logo-horizontal-dark-1200x411.png similarity index 100% rename from assets/branding/purview-logo-horizontal-dark-1200x411.png rename to src/assets/branding/purview-logo-horizontal-dark-1200x411.png diff --git a/assets/branding/purview-logo-horizontal-dark-2400x823.png b/src/assets/branding/purview-logo-horizontal-dark-2400x823.png similarity index 100% rename from assets/branding/purview-logo-horizontal-dark-2400x823.png rename to src/assets/branding/purview-logo-horizontal-dark-2400x823.png diff --git a/assets/branding/purview-logo-horizontal-dark-600x206.png b/src/assets/branding/purview-logo-horizontal-dark-600x206.png similarity index 100% rename from assets/branding/purview-logo-horizontal-dark-600x206.png rename to src/assets/branding/purview-logo-horizontal-dark-600x206.png diff --git a/assets/branding/purview-logo-horizontal-light-1200x411.png b/src/assets/branding/purview-logo-horizontal-light-1200x411.png similarity index 100% rename from assets/branding/purview-logo-horizontal-light-1200x411.png rename to src/assets/branding/purview-logo-horizontal-light-1200x411.png diff --git a/assets/branding/purview-logo-horizontal-light-2400x823.png b/src/assets/branding/purview-logo-horizontal-light-2400x823.png similarity index 100% rename from assets/branding/purview-logo-horizontal-light-2400x823.png rename to src/assets/branding/purview-logo-horizontal-light-2400x823.png diff --git a/assets/branding/purview-logo-horizontal-light-600x206.png b/src/assets/branding/purview-logo-horizontal-light-600x206.png similarity index 100% rename from assets/branding/purview-logo-horizontal-light-600x206.png rename to src/assets/branding/purview-logo-horizontal-light-600x206.png diff --git a/assets/branding/purview-logo-horizontal.svg b/src/assets/branding/purview-logo-horizontal.svg similarity index 100% rename from assets/branding/purview-logo-horizontal.svg rename to src/assets/branding/purview-logo-horizontal.svg diff --git a/astro.config.ts b/src/astro.config.ts similarity index 85% rename from astro.config.ts rename to src/astro.config.ts index f9e30c6..7175c2c 100644 --- a/astro.config.ts +++ b/src/astro.config.ts @@ -5,9 +5,10 @@ import tailwindcss from '@tailwindcss/vite'; import { defineConfig } from 'astro/config'; import starlightLinksValidator from 'starlight-links-validator'; import starlightLlmsTxt from 'starlight-llms-txt'; +import starlightSidebarTopics from 'starlight-sidebar-topics'; import { readDocsManifest } from './src/lib/docs/aggregate'; -import { buildSidebar } from './src/lib/docs/sidebar'; +import { buildProjectItems } from './src/lib/docs/sidebar'; import { loadProjects } from './src/lib/manifest/load'; import { SITE, BRAND } from './src/lib/site'; import { absoluteUrl } from './src/lib/urls'; @@ -15,6 +16,18 @@ import { absoluteUrl } from './src/lib/urls'; const projects = loadProjects(); const docsManifest = readDocsManifest(); +const docsProjects = projects.filter((project) => project.docs && project.status !== 'archived'); +const previewBadge = { text: 'Preview', variant: 'caution' } as const; +const sidebarTopics = [ + { label: 'Documentation home', link: '/docs/' }, + ...docsProjects.map((project) => ({ + label: project.name, + link: `/docs/${project.id}/`, + badge: project.status === 'preview' ? previewBadge : undefined, + items: buildProjectItems(project, docsManifest), + })), +]; + const HEAD = [ { tag: 'link' as const, @@ -77,7 +90,8 @@ export default defineConfig({ starlight({ title: SITE.fullName, description: SITE.description, - favicon: '/favicon.svg', + // The favicon links (including the adaptive SVG) are provided by `head` + // below; declaring `favicon` here as well would emit them twice. // Note: the site header is rendered by a Header override (SiteBrand) so // no `logo` config is needed here. // Documentation is served at project-root paths (e.g. /telemetry-sourcegenerator/). @@ -90,7 +104,9 @@ export default defineConfig({ baseUrl: 'https://github.com/purview-dev/purview-dev.github.io/edit/main/', }, disable404Route: true, - sidebar: buildSidebar(projects, docsManifest), + // Per-project documentation lives under project-root paths; the + // sidebar-topics plugin presents each project as its own dropdown topic, + // so no `sidebar` config is set here. customCss: ['./src/styles/global.css'], expressiveCode: { themes: ['starlight-light', 'starlight-dark'], @@ -102,6 +118,7 @@ export default defineConfig({ PageTitle: './src/components/starlight/PageTitle.astro', }, plugins: [ + starlightSidebarTopics(sidebarTopics), starlightLinksValidator({ // Relative links between aggregated doc pages (e.g. `../foo/`) are // resolved by the browser against the final URL and validated by the diff --git a/src/components/ProjectCard.astro b/src/components/ProjectCard.astro deleted file mode 100644 index 903f5f5..0000000 --- a/src/components/ProjectCard.astro +++ /dev/null @@ -1,32 +0,0 @@ ---- -import StatusBadge from '~/components/StatusBadge.astro'; -import type { ResolvedProject } from '~/lib/manifest/load'; -import { withBase } from '~/lib/urls'; - -interface Props { - project: ResolvedProject; -} - -const { project } = Astro.props; ---- - - -
-

{project.name}

- -
-

{project.shortDescription}

-
- {project.category} - { - project.packages.length > 0 && ( - - {project.packages.length} package{project.packages.length === 1 ? '' : 's'} - - ) - } -
-
\ No newline at end of file diff --git a/src/components/SiteBrand.astro b/src/components/SiteBrand.astro deleted file mode 100644 index cd3ad4d..0000000 --- a/src/components/SiteBrand.astro +++ /dev/null @@ -1,56 +0,0 @@ ---- -import { SITE } from '~/lib/site'; -import { withBase } from '~/lib/urls'; - -interface Props { - /** Compact icon-only mark for dense contexts (default: false). */ - iconOnly?: boolean; -} - -const { iconOnly = false } = Astro.props; ---- - - - { - iconOnly ? ( - - ) : ( - - ) - } - { - iconOnly ? ( - - ) : ( - - ) - } - \ No newline at end of file diff --git a/fixtures/github/releases/aspire-resourcekit.json b/src/fixtures/github/releases/aspire-resourcekit.json similarity index 100% rename from fixtures/github/releases/aspire-resourcekit.json rename to src/fixtures/github/releases/aspire-resourcekit.json diff --git a/fixtures/github/releases/build.json b/src/fixtures/github/releases/build.json similarity index 100% rename from fixtures/github/releases/build.json rename to src/fixtures/github/releases/build.json diff --git a/fixtures/github/releases/dotnet-logging-source-generators.json b/src/fixtures/github/releases/dotnet-logging-source-generators.json similarity index 100% rename from fixtures/github/releases/dotnet-logging-source-generators.json rename to src/fixtures/github/releases/dotnet-logging-source-generators.json diff --git a/fixtures/github/releases/dotnet-project-sdk.json b/src/fixtures/github/releases/dotnet-project-sdk.json similarity index 100% rename from fixtures/github/releases/dotnet-project-sdk.json rename to src/fixtures/github/releases/dotnet-project-sdk.json diff --git a/fixtures/github/releases/event-sourcing.json b/src/fixtures/github/releases/event-sourcing.json similarity index 100% rename from fixtures/github/releases/event-sourcing.json rename to src/fixtures/github/releases/event-sourcing.json diff --git a/fixtures/github/releases/sourcegeneratorframework.json b/src/fixtures/github/releases/sourcegeneratorframework.json similarity index 100% rename from fixtures/github/releases/sourcegeneratorframework.json rename to src/fixtures/github/releases/sourcegeneratorframework.json diff --git a/fixtures/github/releases/telemetry-sourcegenerator.json b/src/fixtures/github/releases/telemetry-sourcegenerator.json similarity index 100% rename from fixtures/github/releases/telemetry-sourcegenerator.json rename to src/fixtures/github/releases/telemetry-sourcegenerator.json diff --git a/fixtures/github/releases/zodsharp.json b/src/fixtures/github/releases/zodsharp.json similarity index 100% rename from fixtures/github/releases/zodsharp.json rename to src/fixtures/github/releases/zodsharp.json diff --git a/fixtures/github/repos/aspire-resourcekit.json b/src/fixtures/github/repos/aspire-resourcekit.json similarity index 100% rename from fixtures/github/repos/aspire-resourcekit.json rename to src/fixtures/github/repos/aspire-resourcekit.json diff --git a/fixtures/github/repos/build.json b/src/fixtures/github/repos/build.json similarity index 100% rename from fixtures/github/repos/build.json rename to src/fixtures/github/repos/build.json diff --git a/fixtures/github/repos/dotnet-logging-source-generators.json b/src/fixtures/github/repos/dotnet-logging-source-generators.json similarity index 100% rename from fixtures/github/repos/dotnet-logging-source-generators.json rename to src/fixtures/github/repos/dotnet-logging-source-generators.json diff --git a/fixtures/github/repos/dotnet-project-sdk.json b/src/fixtures/github/repos/dotnet-project-sdk.json similarity index 100% rename from fixtures/github/repos/dotnet-project-sdk.json rename to src/fixtures/github/repos/dotnet-project-sdk.json diff --git a/fixtures/github/repos/event-sourcing.json b/src/fixtures/github/repos/event-sourcing.json similarity index 100% rename from fixtures/github/repos/event-sourcing.json rename to src/fixtures/github/repos/event-sourcing.json diff --git a/fixtures/github/repos/sourcegeneratorframework.json b/src/fixtures/github/repos/sourcegeneratorframework.json similarity index 100% rename from fixtures/github/repos/sourcegeneratorframework.json rename to src/fixtures/github/repos/sourcegeneratorframework.json diff --git a/fixtures/github/repos/telemetry-sourcegenerator.json b/src/fixtures/github/repos/telemetry-sourcegenerator.json similarity index 100% rename from fixtures/github/repos/telemetry-sourcegenerator.json rename to src/fixtures/github/repos/telemetry-sourcegenerator.json diff --git a/fixtures/github/repos/zodsharp.json b/src/fixtures/github/repos/zodsharp.json similarity index 100% rename from fixtures/github/repos/zodsharp.json rename to src/fixtures/github/repos/zodsharp.json diff --git a/fixtures/nuget/purview.aspire.resourcekit.json b/src/fixtures/nuget/purview.aspire.resourcekit.json similarity index 100% rename from fixtures/nuget/purview.aspire.resourcekit.json rename to src/fixtures/nuget/purview.aspire.resourcekit.json diff --git a/fixtures/nuget/purview.build.json b/src/fixtures/nuget/purview.build.json similarity index 100% rename from fixtures/nuget/purview.build.json rename to src/fixtures/nuget/purview.build.json diff --git a/fixtures/nuget/purview.dotnetprojectsdk.json b/src/fixtures/nuget/purview.dotnetprojectsdk.json similarity index 100% rename from fixtures/nuget/purview.dotnetprojectsdk.json rename to src/fixtures/nuget/purview.dotnetprojectsdk.json diff --git a/fixtures/nuget/purview.eventsourcing.azurestorage.json b/src/fixtures/nuget/purview.eventsourcing.azurestorage.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.azurestorage.json rename to src/fixtures/nuget/purview.eventsourcing.azurestorage.json diff --git a/fixtures/nuget/purview.eventsourcing.cosmosdb.json b/src/fixtures/nuget/purview.eventsourcing.cosmosdb.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.cosmosdb.json rename to src/fixtures/nuget/purview.eventsourcing.cosmosdb.json diff --git a/fixtures/nuget/purview.eventsourcing.inmemory.json b/src/fixtures/nuget/purview.eventsourcing.inmemory.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.inmemory.json rename to src/fixtures/nuget/purview.eventsourcing.inmemory.json diff --git a/fixtures/nuget/purview.eventsourcing.json b/src/fixtures/nuget/purview.eventsourcing.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.json rename to src/fixtures/nuget/purview.eventsourcing.json diff --git a/fixtures/nuget/purview.eventsourcing.mongodb.json b/src/fixtures/nuget/purview.eventsourcing.mongodb.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.mongodb.json rename to src/fixtures/nuget/purview.eventsourcing.mongodb.json diff --git a/fixtures/nuget/purview.eventsourcing.postgres.json b/src/fixtures/nuget/purview.eventsourcing.postgres.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.postgres.json rename to src/fixtures/nuget/purview.eventsourcing.postgres.json diff --git a/fixtures/nuget/purview.eventsourcing.sqlserver.json b/src/fixtures/nuget/purview.eventsourcing.sqlserver.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.sqlserver.json rename to src/fixtures/nuget/purview.eventsourcing.sqlserver.json diff --git a/fixtures/nuget/purview.eventsourcing.validation.fluentvalidation.json b/src/fixtures/nuget/purview.eventsourcing.validation.fluentvalidation.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.validation.fluentvalidation.json rename to src/fixtures/nuget/purview.eventsourcing.validation.fluentvalidation.json diff --git a/fixtures/nuget/purview.eventsourcing.validation.zodsharp.json b/src/fixtures/nuget/purview.eventsourcing.validation.zodsharp.json similarity index 100% rename from fixtures/nuget/purview.eventsourcing.validation.zodsharp.json rename to src/fixtures/nuget/purview.eventsourcing.validation.zodsharp.json diff --git a/fixtures/nuget/purview.sourcegeneratorframework.json b/src/fixtures/nuget/purview.sourcegeneratorframework.json similarity index 100% rename from fixtures/nuget/purview.sourcegeneratorframework.json rename to src/fixtures/nuget/purview.sourcegeneratorframework.json diff --git a/fixtures/nuget/purview.sourcegeneratorframework.testing.json b/src/fixtures/nuget/purview.sourcegeneratorframework.testing.json similarity index 100% rename from fixtures/nuget/purview.sourcegeneratorframework.testing.json rename to src/fixtures/nuget/purview.sourcegeneratorframework.testing.json diff --git a/fixtures/nuget/purview.sourcegeneratorframework.testing.tunit.json b/src/fixtures/nuget/purview.sourcegeneratorframework.testing.tunit.json similarity index 100% rename from fixtures/nuget/purview.sourcegeneratorframework.testing.tunit.json rename to src/fixtures/nuget/purview.sourcegeneratorframework.testing.tunit.json diff --git a/fixtures/nuget/purview.telemetry.sourcegenerator.json b/src/fixtures/nuget/purview.telemetry.sourcegenerator.json similarity index 100% rename from fixtures/nuget/purview.telemetry.sourcegenerator.json rename to src/fixtures/nuget/purview.telemetry.sourcegenerator.json diff --git a/fixtures/nuget/purview.zodsharp.aspnetcore.json b/src/fixtures/nuget/purview.zodsharp.aspnetcore.json similarity index 100% rename from fixtures/nuget/purview.zodsharp.aspnetcore.json rename to src/fixtures/nuget/purview.zodsharp.aspnetcore.json diff --git a/fixtures/nuget/purview.zodsharp.json b/src/fixtures/nuget/purview.zodsharp.json similarity index 100% rename from fixtures/nuget/purview.zodsharp.json rename to src/fixtures/nuget/purview.zodsharp.json diff --git a/fixtures/nuget/purview.zodsharp.newtonsoftjson.json b/src/fixtures/nuget/purview.zodsharp.newtonsoftjson.json similarity index 100% rename from fixtures/nuget/purview.zodsharp.newtonsoftjson.json rename to src/fixtures/nuget/purview.zodsharp.newtonsoftjson.json diff --git a/fixtures/nuget/purview.zodsharp.systemtextjson.json b/src/fixtures/nuget/purview.zodsharp.systemtextjson.json similarity index 100% rename from fixtures/nuget/purview.zodsharp.systemtextjson.json rename to src/fixtures/nuget/purview.zodsharp.systemtextjson.json diff --git a/fixtures/nuget/search/Purview.Aspire.ResourceKit.json b/src/fixtures/nuget/search/Purview.Aspire.ResourceKit.json similarity index 100% rename from fixtures/nuget/search/Purview.Aspire.ResourceKit.json rename to src/fixtures/nuget/search/Purview.Aspire.ResourceKit.json diff --git a/fixtures/nuget/search/Purview.Build.json b/src/fixtures/nuget/search/Purview.Build.json similarity index 100% rename from fixtures/nuget/search/Purview.Build.json rename to src/fixtures/nuget/search/Purview.Build.json diff --git a/fixtures/nuget/search/Purview.DotNetProjectSdk.json b/src/fixtures/nuget/search/Purview.DotNetProjectSdk.json similarity index 100% rename from fixtures/nuget/search/Purview.DotNetProjectSdk.json rename to src/fixtures/nuget/search/Purview.DotNetProjectSdk.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.AzureStorage.json b/src/fixtures/nuget/search/Purview.EventSourcing.AzureStorage.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.AzureStorage.json rename to src/fixtures/nuget/search/Purview.EventSourcing.AzureStorage.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.CosmosDb.json b/src/fixtures/nuget/search/Purview.EventSourcing.CosmosDb.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.CosmosDb.json rename to src/fixtures/nuget/search/Purview.EventSourcing.CosmosDb.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.InMemory.json b/src/fixtures/nuget/search/Purview.EventSourcing.InMemory.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.InMemory.json rename to src/fixtures/nuget/search/Purview.EventSourcing.InMemory.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.MongoDB.json b/src/fixtures/nuget/search/Purview.EventSourcing.MongoDB.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.MongoDB.json rename to src/fixtures/nuget/search/Purview.EventSourcing.MongoDB.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.Postgres.json b/src/fixtures/nuget/search/Purview.EventSourcing.Postgres.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.Postgres.json rename to src/fixtures/nuget/search/Purview.EventSourcing.Postgres.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.SqlServer.json b/src/fixtures/nuget/search/Purview.EventSourcing.SqlServer.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.SqlServer.json rename to src/fixtures/nuget/search/Purview.EventSourcing.SqlServer.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.Validation.FluentValidation.json b/src/fixtures/nuget/search/Purview.EventSourcing.Validation.FluentValidation.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.Validation.FluentValidation.json rename to src/fixtures/nuget/search/Purview.EventSourcing.Validation.FluentValidation.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.Validation.ZodSharp.json b/src/fixtures/nuget/search/Purview.EventSourcing.Validation.ZodSharp.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.Validation.ZodSharp.json rename to src/fixtures/nuget/search/Purview.EventSourcing.Validation.ZodSharp.json diff --git a/fixtures/nuget/search/Purview.EventSourcing.json b/src/fixtures/nuget/search/Purview.EventSourcing.json similarity index 100% rename from fixtures/nuget/search/Purview.EventSourcing.json rename to src/fixtures/nuget/search/Purview.EventSourcing.json diff --git a/fixtures/nuget/search/Purview.SourceGeneratorFramework.Testing.TUnit.json b/src/fixtures/nuget/search/Purview.SourceGeneratorFramework.Testing.TUnit.json similarity index 100% rename from fixtures/nuget/search/Purview.SourceGeneratorFramework.Testing.TUnit.json rename to src/fixtures/nuget/search/Purview.SourceGeneratorFramework.Testing.TUnit.json diff --git a/fixtures/nuget/search/Purview.SourceGeneratorFramework.Testing.json b/src/fixtures/nuget/search/Purview.SourceGeneratorFramework.Testing.json similarity index 100% rename from fixtures/nuget/search/Purview.SourceGeneratorFramework.Testing.json rename to src/fixtures/nuget/search/Purview.SourceGeneratorFramework.Testing.json diff --git a/fixtures/nuget/search/Purview.SourceGeneratorFramework.json b/src/fixtures/nuget/search/Purview.SourceGeneratorFramework.json similarity index 100% rename from fixtures/nuget/search/Purview.SourceGeneratorFramework.json rename to src/fixtures/nuget/search/Purview.SourceGeneratorFramework.json diff --git a/fixtures/nuget/search/Purview.Telemetry.SourceGenerator.json b/src/fixtures/nuget/search/Purview.Telemetry.SourceGenerator.json similarity index 100% rename from fixtures/nuget/search/Purview.Telemetry.SourceGenerator.json rename to src/fixtures/nuget/search/Purview.Telemetry.SourceGenerator.json diff --git a/fixtures/nuget/search/Purview.ZodSharp.AspNetCore.json b/src/fixtures/nuget/search/Purview.ZodSharp.AspNetCore.json similarity index 100% rename from fixtures/nuget/search/Purview.ZodSharp.AspNetCore.json rename to src/fixtures/nuget/search/Purview.ZodSharp.AspNetCore.json diff --git a/fixtures/nuget/search/Purview.ZodSharp.NewtonsoftJson.json b/src/fixtures/nuget/search/Purview.ZodSharp.NewtonsoftJson.json similarity index 100% rename from fixtures/nuget/search/Purview.ZodSharp.NewtonsoftJson.json rename to src/fixtures/nuget/search/Purview.ZodSharp.NewtonsoftJson.json diff --git a/fixtures/nuget/search/Purview.ZodSharp.SystemTextJson.json b/src/fixtures/nuget/search/Purview.ZodSharp.SystemTextJson.json similarity index 100% rename from fixtures/nuget/search/Purview.ZodSharp.SystemTextJson.json rename to src/fixtures/nuget/search/Purview.ZodSharp.SystemTextJson.json diff --git a/fixtures/nuget/search/Purview.ZodSharp.json b/src/fixtures/nuget/search/Purview.ZodSharp.json similarity index 100% rename from fixtures/nuget/search/Purview.ZodSharp.json rename to src/fixtures/nuget/search/Purview.ZodSharp.json diff --git a/fixtures/releases/index.json b/src/fixtures/releases/index.json similarity index 100% rename from fixtures/releases/index.json rename to src/fixtures/releases/index.json diff --git a/src/lib/docs/sidebar.ts b/src/lib/docs/sidebar.ts deleted file mode 100644 index 4b7fab3..0000000 --- a/src/lib/docs/sidebar.ts +++ /dev/null @@ -1,76 +0,0 @@ -import type { ResolvedProject } from '../manifest/load'; -import type { DocsManifest } from './aggregate'; - -export interface SidebarLinkEntry { - label: string; - link: string; -} - -export interface SidebarSlugEntry { - label?: string; - slug: string; -} - -export interface SidebarGroupEntry { - label: string; - collapsed?: boolean; - badge?: { - text: string; - variant?: 'default' | 'note' | 'tip' | 'caution' | 'danger' | 'success'; - }; - items: SidebarEntry[]; -} - -export type SidebarEntry = SidebarLinkEntry | SidebarSlugEntry | SidebarGroupEntry; - -/** - * Build the Starlight sidebar from the project manifest and the aggregated - * documentation manifest. Every project with documentation becomes a group; - * the docs portal landing page is linked at the top. Archived projects are - * excluded (their documentation is not published). - */ -export function buildSidebar( - projects: ResolvedProject[], - manifest: DocsManifest | null, -): SidebarEntry[] { - const sidebar: SidebarEntry[] = [ - { - label: 'Documentation home', - link: '/docs/', - }, - ]; - - for (const project of projects) { - if (!project.docs || project.status === 'archived') { - continue; - } - const docsProject = manifest?.projects.find((entry) => entry.projectId === project.id); - const pages = docsProject?.pages ?? []; - const items: SidebarEntry[] = []; - if (pages.some((page) => page.slug === 'index')) { - items.push({ - label: 'Overview', - // Index pages resolve to the directory slug (no trailing "/index"); - // Starlight prefixes the locale dir itself. - slug: project.id, - }); - } - for (const page of pages) { - if (page.slug === 'index') { - continue; - } - items.push({ - label: page.title, - slug: `${project.id}/${page.slug}`, - }); - } - sidebar.push({ - label: project.name.replace(/^Purview\s+/, ''), - collapsed: false, - badge: project.status === 'preview' ? { text: 'Preview', variant: 'caution' } : undefined, - items, - }); - } - - return sidebar; -} diff --git a/oxfmt.config.ts b/src/oxfmt.config.ts similarity index 100% rename from oxfmt.config.ts rename to src/oxfmt.config.ts diff --git a/oxlint.config.ts b/src/oxlint.config.ts similarity index 100% rename from oxlint.config.ts rename to src/oxlint.config.ts diff --git a/src/package.json b/src/package.json new file mode 100644 index 0000000..b8e73df --- /dev/null +++ b/src/package.json @@ -0,0 +1,59 @@ +{ + "name": "@purview-dev/website", + "version": "0.1.0", + "private": true, + "description": "Purview-Dev public website and unified documentation portal.", + "license": "MIT", + "type": "module", + "scripts": { + "build": "astro build", + "check:assets": "bun run scripts/check-assets.ts", + "check:generated": "bun run scripts/check-generated.ts", + "check:links": "bun run scripts/check-links.ts", + "clean": "bun run scripts/clean.ts", + "data:sync": "bun run scripts/data-sync.ts", + "dev": "astro dev", + "fetch:releases": "bun run scripts/fetch-releases.ts", + "format": "oxfmt", + "format:check": "oxfmt --check", + "lint": "oxlint", + "lint:fix": "oxlint --fix", + "preview": "astro preview", + "refresh:fixtures": "bun run scripts/refresh-fixtures.ts", + "test": "bun test tests/unit", + "test:dist": "bun test tests/dist", + "typecheck": "astro check" + }, + "dependencies": { + "preact": "10.29.8" + }, + "devDependencies": { + "@astrojs/check": "0.9.10", + "@astrojs/preact": "6.0.5", + "@astrojs/sitemap": "3.7.4", + "@astrojs/starlight": "0.42.1", + "@astrojs/starlight-tailwind": "5.0.0", + "@tailwindcss/vite": "4.3.3", + "@types/bun": "1.4.2", + "@types/semver": "^7.8.0", + "astro": "7.3.2", + "fast-glob": "3.3.3", + "lefthook": "2.1.14", + "oxfmt": "0.68.0", + "oxlint": "1.83.0", + "semver": "7.8.5", + "sharp": "0.35.4", + "starlight-links-validator": "0.26.0", + "starlight-llms-txt": "0.12.0", + "starlight-sidebar-topics": "0.9.0", + "tailwindcss": "4.3.3", + "typescript": "5.9.3", + "yaml": "2.9.1", + "zod": "4.6.5" + }, + "engines": { + "bun": ">=1.4.2", + "node": ">=22.12.0" + }, + "packageManager": "bun@1.4.2" +} diff --git a/src/pages/projects/index.astro b/src/pages/projects/index.astro deleted file mode 100644 index 6796558..0000000 --- a/src/pages/projects/index.astro +++ /dev/null @@ -1,46 +0,0 @@ ---- -import SiteLayout from '~/layouts/SiteLayout.astro'; -import ProjectCard from '~/components/ProjectCard.astro'; -import ProjectFilter from '~/components/islands/ProjectFilter.tsx'; -import { loadProjects } from '~/lib/manifest/load'; -import { SITE } from '~/lib/site'; - -const projects = loadProjects(); -const categories = [...new Set(projects.map((project) => project.category))].toSorted(); -const statuses = ['stable', 'preview', 'archived']; ---- - - -
-
-

Catalogue

-

Projects

-

- The complete Purview-Dev product family — open source, MIT licensed, and - published to NuGet. Every project is documented and actively developed. -

-
- -
- -
- -
- { - projects.map((project) => ( -
- -
- )) - } -
-
-
\ No newline at end of file diff --git a/public/robots.txt b/src/public/robots.txt similarity index 100% rename from public/robots.txt rename to src/public/robots.txt diff --git a/public/site.webmanifest b/src/public/site.webmanifest similarity index 100% rename from public/site.webmanifest rename to src/public/site.webmanifest diff --git a/scripts/check-assets.ts b/src/scripts/check-assets.ts similarity index 97% rename from scripts/check-assets.ts rename to src/scripts/check-assets.ts index 7f7dff7..d3505e2 100644 --- a/scripts/check-assets.ts +++ b/src/scripts/check-assets.ts @@ -104,6 +104,9 @@ async function assertGeneratedAssets(): Promise { ['icon-192.png', [192, 192]], ['icon-512.png', [512, 512]], ['og/default.png', [1200, 630]], + ['branding/icon.svg', null], + ['branding/logo-horizontal.svg', null], + ['branding/banner.svg', null], ] as const; for (const [file, dims] of expectedGenerated) { const path = resolve('public', file); diff --git a/scripts/check-generated.ts b/src/scripts/check-generated.ts similarity index 100% rename from scripts/check-generated.ts rename to src/scripts/check-generated.ts diff --git a/scripts/check-links.ts b/src/scripts/check-links.ts similarity index 100% rename from scripts/check-links.ts rename to src/scripts/check-links.ts diff --git a/scripts/clean.ts b/src/scripts/clean.ts similarity index 100% rename from scripts/clean.ts rename to src/scripts/clean.ts diff --git a/scripts/data-sync.ts b/src/scripts/data-sync.ts similarity index 93% rename from scripts/data-sync.ts rename to src/scripts/data-sync.ts index 3110e12..626e969 100644 --- a/scripts/data-sync.ts +++ b/src/scripts/data-sync.ts @@ -84,13 +84,15 @@ async function syncDocsMirror(mode: Mode): Promise { await syncDocs(); } -/** Orchestrate all build-time data preparation (branding, docs, releases). */ +/** Orchestrate all build-time data preparation (branding, releases, docs). */ export async function dataSync(): Promise { const mode = resolveMode(); console.log(`Data sync (mode=${mode})`); await processBranding(); - await syncDocsMirror(mode); + // Releases are fetched first so the docs aggregation can enrich content with + // repository descriptions and topics (tags) from the release cache. await syncReleases(mode); + await syncDocsMirror(mode); if (!existsSync(RELEASES_CACHE_FILE) && !readReleaseFixture('index')) { console.warn( 'Note: release data is unavailable. The releases page will be empty until `just fetch-releases` runs.', diff --git a/scripts/fetch-releases.ts b/src/scripts/fetch-releases.ts similarity index 100% rename from scripts/fetch-releases.ts rename to src/scripts/fetch-releases.ts diff --git a/scripts/process-branding.ts b/src/scripts/process-branding.ts similarity index 93% rename from scripts/process-branding.ts rename to src/scripts/process-branding.ts index ca0feb9..59d13a4 100644 --- a/scripts/process-branding.ts +++ b/src/scripts/process-branding.ts @@ -27,9 +27,14 @@ export async function processBranding(): Promise { ensureDir(PUBLIC_BRANDING_DIR); ensureDir(OG_DIR); - // Adaptive SVG masters (site favicon, icon). Kept as-is. + // Adaptive SVG masters (site favicon, icon, logo, banner). Kept as-is. copyInto(resolve(BRANDING_DIR, 'purview-icon.svg'), resolve(PUBLIC_DIR, 'favicon.svg')); copyInto(resolve(BRANDING_DIR, 'purview-icon.svg'), resolve(PUBLIC_BRANDING_DIR, 'icon.svg')); + copyInto( + resolve(BRANDING_DIR, 'purview-logo-horizontal.svg'), + resolve(PUBLIC_BRANDING_DIR, 'logo-horizontal.svg'), + ); + copyInto(resolve(BRANDING_DIR, 'purview-banner.svg'), resolve(PUBLIC_BRANDING_DIR, 'banner.svg')); // PNG marks: explicit light/dark variants for themed contexts. copyInto( diff --git a/scripts/refresh-fixtures.ts b/src/scripts/refresh-fixtures.ts similarity index 100% rename from scripts/refresh-fixtures.ts rename to src/scripts/refresh-fixtures.ts diff --git a/scripts/sync-docs.ts b/src/scripts/sync-docs.ts similarity index 100% rename from scripts/sync-docs.ts rename to src/scripts/sync-docs.ts diff --git a/src/src/components/ProjectCard.astro b/src/src/components/ProjectCard.astro new file mode 100644 index 0000000..fa382d9 --- /dev/null +++ b/src/src/components/ProjectCard.astro @@ -0,0 +1,83 @@ +--- +import StatusBadge from '~/components/StatusBadge.astro'; +import { buildBadge, nugetDownloadsBadge, nugetVersionBadge, actionsUrl } from '~/lib/badges'; +import { projectRepoEnrichment } from '~/lib/releases/repo'; +import { getReleaseIndex } from '~/lib/releases/runtime'; +import type { ResolvedProject } from '~/lib/manifest/load'; +import { nugetPackageUrl, withBase } from '~/lib/urls'; + +interface Props { + project: ResolvedProject; + /** Show NuGet/build badges below the card (hidden on the home page). */ + showBadges?: boolean; +} + +const { project, showBadges = true } = Astro.props; +const { tags } = projectRepoEnrichment(project, getReleaseIndex().data); +const primaryPackage = project.packages.find((pkg) => pkg.primary) ?? project.packages[0]; +const badges = + project.status === 'archived' + ? [] + : [ + ...(primaryPackage + ? [ + { + href: nugetPackageUrl(primaryPackage.id), + src: nugetVersionBadge(primaryPackage.id), + alt: `NuGet version of ${primaryPackage.id}`, + }, + { + href: nugetPackageUrl(primaryPackage.id), + src: nugetDownloadsBadge(primaryPackage.id), + alt: `NuGet downloads of ${primaryPackage.id}`, + }, + ] + : []), + { + href: actionsUrl(project.repository), + src: buildBadge(project.repository), + alt: `Build status of ${project.name}`, + }, + ]; +--- + + \ No newline at end of file diff --git a/src/src/components/SiteBrand.astro b/src/src/components/SiteBrand.astro new file mode 100644 index 0000000..be45894 --- /dev/null +++ b/src/src/components/SiteBrand.astro @@ -0,0 +1,37 @@ +--- +import { SITE } from '~/lib/site'; +import { withBase } from '~/lib/urls'; + +interface Props { + /** Compact icon-only mark for dense contexts (default: false). */ + iconOnly?: boolean; +} + +const { iconOnly = false } = Astro.props; +--- + + + { + iconOnly ? ( + + ) : ( + + ) + } + \ No newline at end of file diff --git a/src/components/SiteFooter.astro b/src/src/components/SiteFooter.astro similarity index 56% rename from src/components/SiteFooter.astro rename to src/src/components/SiteFooter.astro index ca6cb96..963531e 100644 --- a/src/components/SiteFooter.astro +++ b/src/src/components/SiteFooter.astro @@ -11,28 +11,38 @@ import { withBase } from '~/lib/urls';

- {SITE.tagline} {SITE.orgName} builds developer tooling for .NET — event sourcing, telemetry, validation, source generators, and build automation. + {SITE.tagline} + {SITE.orgName} builds developer tooling for .NET — event sourcing, telemetry, validation, source + generators, and build automation.