Releases: cocoar-dev/shelf
Release list
v2.2.0
Added
- Open-source vs proprietary marker — a product can be tagged Open Source or Proprietary (or left unspecified). The marker shows as a colored badge on the landing page, so closed-source product docs can be hosted and found alongside open-source ones and be clearly told apart. The landing page gains a matching filter. Purely a display dimension — orthogonal to visibility and access control.
- Optional repository URL — a product can carry a source-repository link. When set, the landing card shows a discreet "Source ↗" link; leave it empty and closed-source docs carry no repo link. Set both on the product form (General tab).
Full changelog: https://github.com/cocoar-dev/shelf/blob/develop/CHANGELOG.md
v2.1.1
Fixed
- A deleted product no longer reappears after a restart. The product JSON seed is now genuinely one-time: a
SeedStatemarker records that the import has run, and the migration never re-reads the seed files again. Previously the seed re-imported any product missing from the database on every startup, so a product deleted via the UI/API was resurrected from its lingering seed file. Existing databases are marked seeded on first boot of this version without re-importing, so previously-deleted products stay deleted.
Full changelog: https://github.com/cocoar-dev/shelf/blob/develop/CHANGELOG.md
Shelf 2.1.0
Access control for restricted documentation, a much richer analytics dashboard, and a unified app shell. Backwards-compatible: existing products stay public and nothing changes until you mark a product restricted.
Added
- Restricted products & access control — mark a product restricted: hidden from anyone without a read grant,
404on unauthorized access (no existence leak), anonymous visitors sent to login. Orthogonal to visibility. - Permission groups — grant read access (and optionally adminship) via explicit email members or a sandboxed JsEval auto-membership predicate over the login claims snapshot. Managed under Administration → Groups, with a script dry-run.
- Product-side access grants — assign who may read a restricted product on the product's Access tab: both groups and individual users (users keyed by email, stageable before first login).
- Detailed analytics dashboard — interactive world map of visitor cities, country/city breakdowns with flags + full names, browser/OS/language/referrer breakdowns, per-product + IP-exclude filters. All aggregation server-side.
- Groups & principals API —
/_api/groups/*,/_api/groups/recalculate,/_api/groups/test-script,/_api/principals.
Changed
- Unified app shell — landing and admin share one shell: same header everywhere (dark/light toggle), admin sidebar for logged-in admins on every page, dark mode on the landing.
- Analytics summary returns cities, geolocated map points and UA/language/referrer breakdowns; access log stores visitor lat/lng and shows country flags. Groups live under Administration.
Security
- Product writes via the admin cookie now require admin (previously any authenticated user could write). The CI/CD Bearer API-key path is unchanged.
- Admin can additionally be granted via an
IsAdminGrouppermission group.
Full details in CHANGELOG.md.
Shelf 2.0.0
Shelf 2.0 turns the file-only server into a modgud-federated, PostgreSQL-backed platform with a full admin UI and SSO login (OIDC code flow). Docs serving is unchanged; the CI/CD upload API keeps its shape and keys under /_api.
Highlights: admin UI (products/versions/users/analytics/settings), federated SSO login with silent re-login, UI-managed API keys, page-view analytics with GeoIP, product metadata (tags/visibility), PostgreSQL as source of truth with one-time JSON seed import.
See CHANGELOG.md for the full entry including breaking changes and the upgrade guide.
🤖 Generated with Claude Code
v1.0.0
Shelf v1.0.0
Shelf your Docs. Static documentation hosting for Cocoar products.
Shelf is an ASP.NET Core application that serves VitePress-generated documentation with multi-product and multi-version support. Deploy new versions without touching old ones — just upload a ZIP from your CI/CD pipeline.
Highlights
Upload API
Deploy documentation directly from CI/CD pipelines via HTTP POST. No SSH, no file copying — just curl a ZIP to the API endpoint.
curl -X POST \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/zip" \
--data-binary @docs.zip \
https://docs.example.com/api/products/myproduct/versions/v1.0.0SemVer Versioning
Full semantic versioning support: v5, v5.2, v5.2.0, v5.2.0-beta.1. Pre-release versions are accessible but never served as "latest" — visitors are always redirected to the highest stable version.
Product Registration
Explicit product registration via JSON config files with live-reload. Control which products are available for upload and visible on the landing page.
Base Path Rewriting
VitePress sites built with default base: '/' work out of the box. Shelf rewrites HTML, CSS, and JS responses on the fly to match the product/version URL structure.
Landing Page
Optional product overview page at the root URL listing all registered products with their versions.
Features
- Multi-Product — Host documentation for multiple products under one domain
- Multi-Version — Deploy new versions without touching old ones
- Upload API — ZIP upload with atomic deployment, ZIP-Slip protection, and per-version locking
- SemVer — Supports
v5,v5.2,v5.2.0,v5.2.0-beta.1 - API Key Auth — Bearer token authentication for upload endpoint
- Base Path Rewriting — Automatic for VitePress (HTML, CSS, JS)
- Resilient File Monitoring — Powered by Cocoar.FileSystem
- Immutable Asset Caching — Hashed assets served with 1-year cache headers
- Landing Page — Optional product overview at root URL
- PathBase — Configurable global URL prefix for sub-path hosting
- LLM Documentation — Serve
llms.txtandllms-full.txtfor AI-friendly docs
API Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/api/products |
No | List all products with versions |
GET |
/api/products/{product}/versions |
No | Versions of a product |
POST |
/api/products/{product}/versions/{version} |
Bearer | Upload ZIP as new version |
Quick Start
services:
shelf:
image: ghcr.io/cocoar-dev/shelf:latest
ports:
- "80:8080"
volumes:
- docs-data:/data/docs
- config-data:/data/config:ro
environment:
- Shelf__ApiKey=${SHELF_API_KEY:-}
restart: unless-stoppedDocumentation
Full documentation: docs.cocoar.dev/shelf
License
Apache-2.0