@pagenary/publisher 2026.6.8 → 2026.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +18 -0
  2. package/examples/content-base/config.json +7 -0
  3. package/examples/content-base/content/buttons.md +18 -0
  4. package/examples/content-base/content/changelog.md +14 -0
  5. package/examples/content-base/content/configure.md +25 -0
  6. package/examples/content-base/content/forms.md +16 -0
  7. package/examples/content-base/content/home.md +20 -0
  8. package/examples/content-base/content/install.md +22 -0
  9. package/examples/content-base/content/reference.md +20 -0
  10. package/examples/content-base/manifest.json +61 -0
  11. package/examples/docs-map-corpus/config.json +9 -0
  12. package/examples/docs-map-corpus/content/api-keys.md +10 -0
  13. package/examples/docs-map-corpus/content/authentication.md +11 -0
  14. package/examples/docs-map-corpus/content/configuration.md +16 -0
  15. package/examples/docs-map-corpus/content/errors.md +12 -0
  16. package/examples/docs-map-corpus/content/events.md +10 -0
  17. package/examples/docs-map-corpus/content/first-request.md +15 -0
  18. package/examples/docs-map-corpus/content/installation.md +14 -0
  19. package/examples/docs-map-corpus/content/oauth.md +12 -0
  20. package/examples/docs-map-corpus/content/overview.md +16 -0
  21. package/examples/docs-map-corpus/content/pagination.md +11 -0
  22. package/examples/docs-map-corpus/content/quickstart.md +14 -0
  23. package/examples/docs-map-corpus/content/rate-limits.md +12 -0
  24. package/examples/docs-map-corpus/content/resources.md +11 -0
  25. package/examples/docs-map-corpus/content/webhooks.md +13 -0
  26. package/examples/docs-map-corpus/manifest.json +52 -0
  27. package/examples/interocitor/.public/interocitor.css +334 -0
  28. package/examples/interocitor/config.json +31 -0
  29. package/examples/interocitor/content/assembly.md +28 -0
  30. package/examples/interocitor/content/calibration.md +30 -0
  31. package/examples/interocitor/content/contact.md +18 -0
  32. package/examples/interocitor/content/how-it-works.md +35 -0
  33. package/examples/interocitor/content/overview.html +53 -0
  34. package/examples/interocitor/content/safety.md +26 -0
  35. package/examples/interocitor/content/specifications.md +33 -0
  36. package/examples/interocitor/manifest.json +61 -0
  37. package/examples/interocitor/overrides/index.html +71 -0
  38. package/examples/recipes.tenants.json +117 -0
  39. package/package.json +5 -2
  40. package/scripts/build-tenants.js +401 -126
  41. package/scripts/lib/search-index-generator.js +17 -0
  42. package/scripts/smoke-browser.mjs +191 -0
  43. package/site/app.js +1 -1
  44. package/site/index.html +1 -1
  45. package/site/lib/docs-map.js +1 -0
  46. package/site/lib/fortemi-corpus.js +1 -1
  47. package/site/llms.txt +1 -0
  48. package/site/manifest.js +6 -0
  49. package/site/pages/api.html +20 -56
  50. package/site/pages/architecture.html +10 -39
  51. package/site/pages/deployment.html +14 -11
  52. package/site/pages/developer-guide.html +6 -19
  53. package/site/pages/extending.html +2 -4
  54. package/site/pages/quickstart.html +8 -16
  55. package/site/pages/seo-strategy.html +5 -18
  56. package/site/pages/tenant-config.html +40 -29
  57. package/site/pages/theming-recipes.html +240 -0
  58. package/site/pages/welcome.html +4 -16
  59. package/site/robots.txt +1 -1
  60. package/site/search-index/manifest.json +9 -8
  61. package/site/search-index/part-0000.json +51 -12
  62. package/site/sections/api.js +1 -1
  63. package/site/sections/architecture.js +1 -1
  64. package/site/sections/deployment.js +1 -1
  65. package/site/sections/developer-guide.js +1 -1
  66. package/site/sections/extending.js +1 -1
  67. package/site/sections/quickstart.js +1 -1
  68. package/site/sections/seo-strategy.js +1 -1
  69. package/site/sections/tenant-config.js +1 -1
  70. package/site/sections/theming-recipes.js +3 -0
  71. package/site/sections/welcome.js +1 -1
  72. package/site/sitemap.xml +16 -10
  73. package/site/styles.css +259 -2
  74. package/site/vendor/fortemi-aiwg-index.d.ts +9 -2
  75. package/site/vendor/fortemi-aiwg-index.js +1 -1
  76. package/src/app.js +56 -0
  77. package/src/lib/docs-map.js +239 -0
  78. package/src/lib/fortemi-corpus.js +0 -0
  79. package/src/styles.css +259 -2
  80. package/src/vendor/fortemi-aiwg-index.d.ts +9 -2
  81. package/src/vendor/fortemi-aiwg-index.js +77 -10
package/README.md CHANGED
@@ -272,6 +272,23 @@ npm run lint:content # check trailing whitespace/tabs
272
272
  npm run check:seo # verify SEO metadata
273
273
  npm run check # run all checks
274
274
  npm test # run test suite
275
+ npm run test:browser # optional real-browser smoke (see below)
276
+ ```
277
+
278
+ ### Browser smoke test (optional)
279
+
280
+ `npm run test:browser` runs `scripts/smoke-browser.mjs`, a real-browser check for
281
+ things the jest/node suite can't cover: `<base href>` resolution under a subpath
282
+ mount, asset + section loading, the runtime `<title>` brand, and Fortemi
283
+ command-palette search. It builds + serves the `pagenary` tenant and drives a
284
+ headless Chromium, capturing a screenshot for review.
285
+
286
+ Playwright is **not** a dependency (keeps the install lean); the script skips with
287
+ instructions when it's absent. Enable it once:
288
+
289
+ ```bash
290
+ npm i -D playwright && npx playwright install chromium
291
+ SMOKE_REQUIRE=1 npm run test:browser # fail (not skip) if Playwright is missing — use in CI
275
292
  ```
276
293
 
277
294
  ---
@@ -363,6 +380,7 @@ The full documentation site is published at **[docs.pagenary.com](https://docs.p
363
380
  - [Quick Start Guide](docs/QUICKSTART.md) — step-by-step tenant creation
364
381
  - [Publish with GitHub/Gitea Actions](docs/PUBLISHING.md) — make any docs repo Pagenary-ready: copy-paste CI workflows + auto-discovery
365
382
  - [Tenant Configuration](docs/TENANT-CONFIG.md) — all config options (branding, theme, SEO)
383
+ - [Theming Recipes](docs/THEMING-RECIPES.md) — copy-paste recipes for colors, fonts, and nav positions, with screenshots
366
384
  - [Architecture](docs/ARCHITECTURE.md) — system design
367
385
  - [API Reference](docs/API.md) — module documentation
368
386
  - [Deployment](docs/DEPLOYMENT.md) — hosting patterns
@@ -0,0 +1,7 @@
1
+ {
2
+ "title": "Pagenary Examples",
3
+ "brandMark": "Pagenary",
4
+ "brandSub": "Examples",
5
+ "description": "Shared sample docs used by the Pagenary theming recipe gallery.",
6
+ "tagline": "One small docs set, many looks — driven entirely by config."
7
+ }
@@ -0,0 +1,18 @@
1
+ # Buttons
2
+
3
+ Buttons trigger actions. Keep labels short and specific — prefer "Save changes"
4
+ over "Submit".
5
+
6
+ ## Variants
7
+
8
+ - **Primary** — the main action on a view. One per screen.
9
+ - **Ghost** — secondary actions that shouldn't compete for attention.
10
+ - **Danger** — destructive actions; pair with a confirmation step.
11
+
12
+ ## States
13
+
14
+ Every button has resting, hover, focus, and disabled states. Focus styles are
15
+ not optional — they're how keyboard users navigate.
16
+
17
+ > Tip: a disabled button should explain *why* it's disabled nearby, or users
18
+ > will assume the page is broken.
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ A changelog is documentation too. Keep entries short and write them for the
4
+ reader, not the committer.
5
+
6
+ ## Unreleased
7
+
8
+ - Added the theming recipe gallery.
9
+ - Introduced `top`, `bottom`, and `hybrid` navigation positions.
10
+
11
+ ## Earlier
12
+
13
+ - Color presets: `light`, `dark`, `matrix`.
14
+ - Per-tenant fonts and branding via `config.json`.
@@ -0,0 +1,25 @@
1
+ # Configure
2
+
3
+ All customization lives in a tenant `config.json`. The keys you'll reach for most:
4
+
5
+ | Key | What it controls |
6
+ | --- | --- |
7
+ | `accentColor` | The primary accent used across links and highlights |
8
+ | `theme` | A preset (`light`, `dark`, `matrix`) or a custom color object |
9
+ | `fontBody` / `fontMono` | Typography for prose and code |
10
+ | `navPosition` | Where navigation sits: `left`, `right`, `top`, `bottom`, `hybrid` |
11
+ | `brandMark` / `brandSub` | The two-part wordmark in the header |
12
+
13
+ Change one key, rebuild, and the whole site follows. No template forks, no CSS
14
+ surgery.
15
+
16
+ ## Example
17
+
18
+ ```json
19
+ {
20
+ "brandMark": "Acme",
21
+ "brandSub": "Docs",
22
+ "accentColor": "#2563eb",
23
+ "navPosition": "top"
24
+ }
25
+ ```
@@ -0,0 +1,16 @@
1
+ # Forms
2
+
3
+ Forms collect input. The shorter the form, the more people finish it.
4
+
5
+ ## Validation
6
+
7
+ Validate on submit, not on every keystroke. Show errors next to the field they
8
+ belong to, in plain language:
9
+
10
+ - Good: "Enter an email address like name@example.com"
11
+ - Bad: "Invalid input (code 422)"
12
+
13
+ ## Submission
14
+
15
+ Disable the submit button while a request is in flight and restore it on
16
+ completion. Never leave the user guessing whether their click registered.
@@ -0,0 +1,20 @@
1
+ # Welcome
2
+
3
+ This is a small, deliberately generic documentation set. The **same content**
4
+ is rebuilt into every recipe in the theming gallery (`docs/THEMING-RECIPES.md`)
5
+ — only the tenant `config.json` changes.
6
+
7
+ Use it to see exactly what a given config does before you point Pagenary at your
8
+ own docs.
9
+
10
+ ## What you're looking at
11
+
12
+ - A handful of top-level sections so navigation layouts have something to show.
13
+ - Plain Markdown content, converted at build time.
14
+ - Zero per-recipe content edits — the look is **data, not code**.
15
+
16
+ ## Try it
17
+
18
+ Pick a recipe, copy its config block, and run `npm run build:tenants`. Then serve
19
+ the bundle and compare. Everything here is reproducible from the registry entry
20
+ that built it.
@@ -0,0 +1,22 @@
1
+ # Install
2
+
3
+ Getting set up takes one command.
4
+
5
+ ```bash
6
+ npm install
7
+ npm run build
8
+ ```
9
+
10
+ That produces a static bundle in `dist/`. Serve it locally to preview:
11
+
12
+ ```bash
13
+ npm run serve
14
+ ```
15
+
16
+ There is no server runtime and no database — the output is plain HTML, CSS, and
17
+ JavaScript you can host anywhere.
18
+
19
+ ## Requirements
20
+
21
+ - Node.js 18 or newer
22
+ - A static host (any will do)
@@ -0,0 +1,20 @@
1
+ # Reference
2
+
3
+ A condensed list of the config keys these recipes exercise. See the
4
+ Tenant Configuration guide (`docs/TENANT-CONFIG.md`) for the complete set.
5
+
6
+ ## Branding
7
+
8
+ - `title` — document title and default header text
9
+ - `brandMark`, `brandSub` — the two-part wordmark
10
+ - `tagline`, `description` — used in metadata and intros
11
+
12
+ ## Theming
13
+
14
+ - `theme` — `light` | `dark` | `matrix` | a custom object
15
+ - `accentColor`, `surfaceColor`, `inkColor`, `mutedColor`, `gridLineColor`
16
+ - `fontBody`, `fontMono`
17
+
18
+ ## Layout
19
+
20
+ - `navPosition` — `left` (default) | `right` | `top` | `bottom` | `hybrid`
@@ -0,0 +1,61 @@
1
+ {
2
+ "default": "home",
3
+ "sections": [
4
+ {
5
+ "id": "home",
6
+ "title": "Home",
7
+ "summary": "Start here — what this sample docs set demonstrates.",
8
+ "file": "home.md"
9
+ },
10
+ {
11
+ "id": "guides",
12
+ "title": "Guides",
13
+ "summary": "Practical, task-focused walkthroughs.",
14
+ "sections": [
15
+ {
16
+ "id": "install",
17
+ "title": "Install",
18
+ "summary": "Get the toolkit onto your machine.",
19
+ "file": "install.md"
20
+ },
21
+ {
22
+ "id": "configure",
23
+ "title": "Configure",
24
+ "summary": "Tune behavior with a single config file.",
25
+ "file": "configure.md"
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ "id": "components",
31
+ "title": "Components",
32
+ "summary": "The building blocks and how they behave.",
33
+ "sections": [
34
+ {
35
+ "id": "buttons",
36
+ "title": "Buttons",
37
+ "summary": "Actions, variants, and states.",
38
+ "file": "buttons.md"
39
+ },
40
+ {
41
+ "id": "forms",
42
+ "title": "Forms",
43
+ "summary": "Inputs, validation, and submission.",
44
+ "file": "forms.md"
45
+ }
46
+ ]
47
+ },
48
+ {
49
+ "id": "reference",
50
+ "title": "Reference",
51
+ "summary": "Every option in one place.",
52
+ "file": "reference.md"
53
+ },
54
+ {
55
+ "id": "changelog",
56
+ "title": "Changelog",
57
+ "summary": "What changed, release by release.",
58
+ "file": "changelog.md"
59
+ }
60
+ ]
61
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "title": "Lumen API — Docs Map demo",
3
+ "brandMark": "Lumen",
4
+ "brandSub": "API",
5
+ "description": "A fictional API platform whose richly cross-linked docs power the Pagenary docs-map demo.",
6
+ "tagline": "Interconnected docs, visualized.",
7
+ "accentColor": "#2563eb",
8
+ "docsMap": { "enabled": true, "title": "Docs Map" }
9
+ }
@@ -0,0 +1,10 @@
1
+ # API Keys
2
+
3
+ API keys authorize server-to-server calls. Scope each key narrowly, rotate on a
4
+ schedule, and keep usage under your plan's [Rate Limits](#rate-limits). Keys are
5
+ one of the two mechanisms covered in [Authentication](#authentication).
6
+
7
+ ## Related
8
+
9
+ - [Authentication](#authentication)
10
+ - [Rate Limits](#rate-limits)
@@ -0,0 +1,11 @@
1
+ # Authentication
2
+
3
+ Every request is authorized with either an API key or an OAuth token. Use
4
+ [API Keys](#api-keys) for server-to-server calls and [OAuth](#oauth) when acting
5
+ on behalf of a user. Rejected credentials return the auth [Errors](#errors) shape.
6
+
7
+ ## Related
8
+
9
+ - [API Keys](#api-keys)
10
+ - [OAuth](#oauth)
11
+ - [Errors](#errors)
@@ -0,0 +1,16 @@
1
+ # Configuration
2
+
3
+ Configure environment, base URL, and webhook endpoints once. The CLI reads these
4
+ after [Installation](#installation), and the same values authorize requests per
5
+ [Authentication](#authentication).
6
+
7
+ ```toml
8
+ [lumen]
9
+ env = "production"
10
+ webhook_url = "https://example.com/hooks"
11
+ ```
12
+
13
+ ## Related
14
+
15
+ - [Installation](#installation)
16
+ - [Authentication](#authentication)
@@ -0,0 +1,12 @@
1
+ # Errors
2
+
3
+ Every error shares one JSON shape: a `code`, a human `message`, and a `request_id`.
4
+ Authorization failures point back to [Authentication](#authentication), quota
5
+ failures to [Rate Limits](#rate-limits), and delivery failures appear in your
6
+ [Webhooks](#webhooks) log.
7
+
8
+ ## Related
9
+
10
+ - [Authentication](#authentication)
11
+ - [Rate Limits](#rate-limits)
12
+ - [Webhooks](#webhooks)
@@ -0,0 +1,10 @@
1
+ # Event Types
2
+
3
+ A reference of every event Lumen emits over [Webhooks](#webhooks): `widget.created`,
4
+ `widget.updated`, `order.paid`, and more. Subscriptions are scoped by the same
5
+ grants described in [OAuth](#oauth).
6
+
7
+ ## Related
8
+
9
+ - [Webhooks](#webhooks)
10
+ - [OAuth](#oauth)
@@ -0,0 +1,15 @@
1
+ # Your First Request
2
+
3
+ Call a [Resources](#resources) endpoint and inspect the JSON it returns. Requests
4
+ must be signed per [Authentication](#authentication); failures come back in the
5
+ shape described in [Errors](#errors), and list endpoints use [Pagination](#pagination).
6
+
7
+ ```bash
8
+ lumen get /v1/widgets
9
+ ```
10
+
11
+ ## Related
12
+
13
+ - [Authentication](#authentication)
14
+ - [Errors](#errors)
15
+ - [Pagination](#pagination)
@@ -0,0 +1,14 @@
1
+ # Installation
2
+
3
+ Install the Lumen CLI and language SDKs. Once installed, set your defaults in
4
+ [Configuration](#configuration) and return to the [Quickstart](#quickstart).
5
+
6
+ ```bash
7
+ npm install -g @lumen/cli
8
+ lumen login
9
+ ```
10
+
11
+ ## Related
12
+
13
+ - [Quickstart](#quickstart)
14
+ - [Configuration](#configuration)
@@ -0,0 +1,12 @@
1
+ # OAuth
2
+
3
+ OAuth lets third parties act on behalf of a user without sharing credentials.
4
+ Request only the scopes you need (see [Event Types](#events) for what each grant
5
+ unlocks), and fall back to [API Keys](#api-keys) for first-party automation. OAuth
6
+ is part of [Authentication](#authentication).
7
+
8
+ ## Related
9
+
10
+ - [Authentication](#authentication)
11
+ - [API Keys](#api-keys)
12
+ - [Event Types](#events)
@@ -0,0 +1,16 @@
1
+ # Lumen API
2
+
3
+ Lumen is a fictional API platform used here to demonstrate the Pagenary
4
+ **docs map** — a relationship view built from how these pages link to each other.
5
+ The more the docs cross-reference, the richer the graph.
6
+
7
+ Start with the [Quickstart](#quickstart), learn how requests are authorized in
8
+ [Authentication](#authentication), then explore the [Resources](#resources) you
9
+ can read and write and the [Webhooks](#webhooks) that notify you of changes.
10
+
11
+ ## Related
12
+
13
+ - [Quickstart](#quickstart)
14
+ - [Authentication](#authentication)
15
+ - [Resources](#resources)
16
+ - [Webhooks](#webhooks)
@@ -0,0 +1,11 @@
1
+ # Pagination
2
+
3
+ List endpoints return a page of [Resources](#resources) plus a cursor. Follow the
4
+ cursor until it is empty. Oversized pages are rejected with the [Errors](#errors)
5
+ shape, and rapid paging counts against [Rate Limits](#rate-limits).
6
+
7
+ ## Related
8
+
9
+ - [Resources](#resources)
10
+ - [Errors](#errors)
11
+ - [Rate Limits](#rate-limits)
@@ -0,0 +1,14 @@
1
+ # Quickstart
2
+
3
+ Get a working request in three steps: install the tools, create a key, and call
4
+ an endpoint.
5
+
6
+ 1. Follow [Installation](#installation) to set up the CLI.
7
+ 2. Create a key as described in [Authentication](#authentication).
8
+ 3. Make [Your First Request](#first-request).
9
+
10
+ ## Related
11
+
12
+ - [Installation](#installation)
13
+ - [Authentication](#authentication)
14
+ - [Your First Request](#first-request)
@@ -0,0 +1,12 @@
1
+ # Rate Limits
2
+
3
+ Each plan has a request quota per minute. Exceeding it returns a `429` in the
4
+ [Errors](#errors) shape with a `Retry-After` header. Spread load across
5
+ [API Keys](#api-keys) and respect backoff when receiving [Webhooks](#webhooks)
6
+ retries.
7
+
8
+ ## Related
9
+
10
+ - [Errors](#errors)
11
+ - [API Keys](#api-keys)
12
+ - [Webhooks](#webhooks)
@@ -0,0 +1,11 @@
1
+ # Resources
2
+
3
+ Resources are the objects you read and write — widgets, accounts, and orders.
4
+ Collections are returned with [Pagination](#pagination), changes can notify you
5
+ through [Webhooks](#webhooks), and failed reads surface as [Errors](#errors).
6
+
7
+ ## Related
8
+
9
+ - [Pagination](#pagination)
10
+ - [Webhooks](#webhooks)
11
+ - [Errors](#errors)
@@ -0,0 +1,13 @@
1
+ # Webhooks
2
+
3
+ Webhooks deliver [Event Types](#events) to your endpoint as resources change.
4
+ Delivery failures are retried with backoff (see [Rate Limits](#rate-limits)), and
5
+ non-2xx responses are recorded as [Errors](#errors). Configure endpoints in
6
+ [Configuration](#configuration).
7
+
8
+ ## Related
9
+
10
+ - [Event Types](#events)
11
+ - [Rate Limits](#rate-limits)
12
+ - [Errors](#errors)
13
+ - [Configuration](#configuration)
@@ -0,0 +1,52 @@
1
+ {
2
+ "default": "overview",
3
+ "sections": [
4
+ {
5
+ "id": "overview",
6
+ "title": "Overview",
7
+ "summary": "What Lumen is and how the pieces fit together.",
8
+ "file": "overview.md"
9
+ },
10
+ {
11
+ "id": "getting-started",
12
+ "title": "Getting Started",
13
+ "summary": "From zero to your first API call.",
14
+ "sections": [
15
+ { "id": "quickstart", "title": "Quickstart", "summary": "The fastest path to a working request.", "file": "quickstart.md" },
16
+ { "id": "installation", "title": "Installation", "summary": "Install the CLI and SDKs.", "file": "installation.md" },
17
+ { "id": "first-request", "title": "Your First Request", "summary": "Call an endpoint and read the response.", "file": "first-request.md" }
18
+ ]
19
+ },
20
+ {
21
+ "id": "concepts",
22
+ "title": "Core Concepts",
23
+ "summary": "The model behind the API.",
24
+ "sections": [
25
+ { "id": "resources", "title": "Resources", "summary": "The objects you read and write.", "file": "resources.md" },
26
+ { "id": "authentication", "title": "Authentication", "summary": "How requests are authorized.", "file": "authentication.md" },
27
+ { "id": "webhooks", "title": "Webhooks", "summary": "Receive events as they happen.", "file": "webhooks.md" }
28
+ ]
29
+ },
30
+ {
31
+ "id": "guides",
32
+ "title": "Guides",
33
+ "summary": "Task-focused walkthroughs.",
34
+ "sections": [
35
+ { "id": "api-keys", "title": "API Keys", "summary": "Create, scope, and rotate keys.", "file": "api-keys.md" },
36
+ { "id": "oauth", "title": "OAuth", "summary": "Delegated access for third parties.", "file": "oauth.md" },
37
+ { "id": "pagination", "title": "Pagination", "summary": "Page through large result sets.", "file": "pagination.md" },
38
+ { "id": "rate-limits", "title": "Rate Limits", "summary": "Quotas and how to stay under them.", "file": "rate-limits.md" },
39
+ { "id": "errors", "title": "Errors", "summary": "Error shapes and how to handle them.", "file": "errors.md" }
40
+ ]
41
+ },
42
+ {
43
+ "id": "reference",
44
+ "title": "Reference",
45
+ "summary": "Lookup material.",
46
+ "sections": [
47
+ { "id": "events", "title": "Event Types", "summary": "Every webhook event Lumen emits.", "file": "events.md" },
48
+ { "id": "configuration", "title": "Configuration", "summary": "Environment and client options.", "file": "configuration.md" }
49
+ ]
50
+ }
51
+ ]
52
+ }