@tenphi/cookbook 0.16.0 → 0.17.1

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.
package/README.md CHANGED
@@ -25,6 +25,23 @@ import { defineDocsConfig } from "@tenphi/cookbook/config";
25
25
  export default defineDocsConfig({ site: { title: "My project" } });
26
26
  ```
27
27
 
28
+ Set fonts, typography, and built-in element styles in the same file:
29
+
30
+ ```ts
31
+ export default defineDocsConfig({
32
+ theme: {
33
+ fonts: { body: "Inter", heading: "Newsreader" },
34
+ presets: { h1: { fontSize: "3rem" } },
35
+ styles: { Sidebar: { LinkLabel: { whiteSpace: "normal" } } },
36
+ },
37
+ });
38
+ ```
39
+
40
+ For local fonts, place files in `public/fonts/` and use
41
+ `fonts: { body: { family: "My Font", files: [{ src: "/fonts/my-font.woff2" }] } }`.
42
+ See [Theme and components](./docs/theme-and-components.md) for all named
43
+ sub-elements and the custom component flow.
44
+
28
45
  Without configuration, a root `README.md` becomes `/` and
29
46
  `docs/**/*.{md,mdx}` supplies the remaining pages. Cookbook includes Starlight,
30
47
  generates only static output, and derives its URL base from Astro. Adding other
package/dist/config.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
 
2
- import { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, ComponentStylesConfig, DocsConfig, DocsSource, ThemeConfig, defineDocsConfig, mergeDocsConfig } from "@tenphi/docs/config";
3
- export { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, type ComponentStylesConfig, type DocsConfig, type DocsSource, type ThemeConfig, defineDocsConfig, mergeDocsConfig };
2
+ import { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, ComponentStylesConfig, DocsConfig, DocsSource, ThemeConfig, ThemeFont, ThemeFontFile, ThemeFonts, defineDocsConfig, mergeDocsConfig } from "@tenphi/docs/config";
3
+ export { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, type ComponentStylesConfig, type DocsConfig, type DocsSource, type ThemeConfig, type ThemeFont, type ThemeFontFile, type ThemeFonts, defineDocsConfig, mergeDocsConfig };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
 
2
2
  import starlight_default, { CookbookOptions, DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS } from "@tenphi/starlight";
3
- import { BrandConfig, BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, ComponentStyleConfig, ComponentStyles, ComponentStylesConfig, ComponentsConfig, ContentConfig, CookbookComponentName, CookbookComponentStyles, CookbookComponentSubElementName, DocsAsset, DocsConfig, DocsDiagnostic, DocsEntry, DocsFrontmatter, DocsGraph, DocsRoute, DocsSource, EditLinkConfig, HeadConfig, LocaleConfig, MarkdownConfig, NavigationConfig, NavigationItem, NavigationPlacement, NavigationTab, SearchConfig, SiteConfig, SiteIconConfig, ThemeConfig, ThemePaletteConfig, ThemeTokenValue, ThemeTokens, TypographyPreset, TypographyPresets, defineDocsConfig, mergeDocsConfig } from "@tenphi/docs";
4
- export { type BrandConfig, type BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, type ComponentStyleConfig, type ComponentStyles, type ComponentStylesConfig, type ComponentsConfig, type ContentConfig, type CookbookComponentName, type CookbookComponentStyles, type CookbookComponentSubElementName, type CookbookOptions, DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS, type DocsAsset, type DocsConfig, type DocsDiagnostic, type DocsEntry, type DocsFrontmatter, type DocsGraph, type DocsRoute, type DocsSource, type EditLinkConfig, type HeadConfig, type LocaleConfig, type MarkdownConfig, type NavigationConfig, type NavigationItem, type NavigationPlacement, type NavigationTab, type SearchConfig, type SiteConfig, type SiteIconConfig, type ThemeConfig, type ThemePaletteConfig, type ThemeTokenValue, type ThemeTokens, type TypographyPreset, type TypographyPresets, starlight_default as default, defineDocsConfig, mergeDocsConfig };
3
+ import { BrandConfig, BrandDeclaration, BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, ComponentStyleConfig, ComponentStyles, ComponentStylesConfig, ComponentsConfig, ContentConfig, CookbookComponentName, CookbookComponentStyles, CookbookComponentSubElementName, DocsAsset, DocsConfig, DocsDiagnostic, DocsEntry, DocsFrontmatter, DocsGraph, DocsRoute, DocsSource, EditLinkConfig, HeadConfig, LocaleConfig, MarkdownConfig, NavigationConfig, NavigationItem, NavigationPlacement, NavigationTab, SearchConfig, SiteConfig, SiteIconConfig, SiteVersion, ThemeConfig, ThemeFont, ThemeFontFile, ThemeFonts, ThemePaletteColor, ThemePaletteConfig, ThemeTokenValue, ThemeTokens, TypographyPreset, TypographyPresets, defineDocsConfig, mergeDocsConfig } from "@tenphi/docs";
4
+ export { type BrandConfig, type BrandDeclaration, type BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, type ComponentStyleConfig, type ComponentStyles, type ComponentStylesConfig, type ComponentsConfig, type ContentConfig, type CookbookComponentName, type CookbookComponentStyles, type CookbookComponentSubElementName, type CookbookOptions, DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS, type DocsAsset, type DocsConfig, type DocsDiagnostic, type DocsEntry, type DocsFrontmatter, type DocsGraph, type DocsRoute, type DocsSource, type EditLinkConfig, type HeadConfig, type LocaleConfig, type MarkdownConfig, type NavigationConfig, type NavigationItem, type NavigationPlacement, type NavigationTab, type SearchConfig, type SiteConfig, type SiteIconConfig, type SiteVersion, type ThemeConfig, type ThemeFont, type ThemeFontFile, type ThemeFonts, type ThemePaletteColor, type ThemePaletteConfig, type ThemeTokenValue, type ThemeTokens, type TypographyPreset, type TypographyPresets, starlight_default as default, defineDocsConfig, mergeDocsConfig };
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: AI agents
3
+ description: Create a Cookbook site with a coding agent and make the published docs easy for agents to find and read.
4
+ sidebar:
5
+ order: 3
6
+ ---
7
+
8
+ Cookbook's project creator writes an `AGENTS.md` beside `docs.config.ts` and an
9
+ `.agents/skills/upgrade-cookbook/SKILL.md` for dependency upgrades. They tell
10
+ coding agents where content lives, where to find Cookbook's installed reference
11
+ docs, how to upgrade Cookbook, and how to validate changes. Give an agent a
12
+ concrete task, for example:
13
+
14
+ > Create a Cookbook site for this repository in `docs-site/`. Use the existing
15
+ > README and `docs/` pages as sources. Set the public site URL to
16
+ > `https://docs.example.com`, add a getting started page if one is missing,
17
+ > and run the doctor and production build.
18
+
19
+ From the repository root, the agent can run:
20
+
21
+ ```sh
22
+ npm create @tenphi/cookbook@latest docs-site -- --source . --site https://docs.example.com --yes
23
+ cd docs-site
24
+ npm run doctor
25
+ npm run build
26
+ ```
27
+
28
+ For a new project without existing documentation, omit `--source .`. To document
29
+ an npm artifact, use `--package name@version` instead. The [getting started
30
+ guide](./getting-started.md) covers all three paths. Agents should edit
31
+ `docs.config.ts` for site metadata, navigation, and theme, and follow the
32
+ [customization rules](./customization-rules.md) for styling.
33
+ Replace the example URL with the site's actual public origin.
34
+
35
+ ## Make the published site readable
36
+
37
+ Set `site.url` in `docs.config.ts` to the public HTTPS origin. If the site is
38
+ hosted under a path, set Astro's `base` in `astro.config.ts`. A production build
39
+ then gives every page a canonical URL and creates a sitemap. Cookbook also writes:
40
+
41
+ - `llms.txt`, a short index of published pages with titles, descriptions, and
42
+ links to their readable HTML pages. Drafts are omitted. This is an optional
43
+ discovery aid for agents that choose to read it.
44
+ - `robots.txt` at origin-root deployments with a pointer to the sitemap. A
45
+ `robots.txt` below a path such as `/project/` would not control the origin's
46
+ crawlers, so Cookbook does not generate one there.
47
+
48
+ You can supply your own `public/llms.txt` or `public/robots.txt`; Cookbook keeps
49
+ those files. For sites under a path, configure an origin-root `robots.txt` at
50
+ the hosting layer if you need one.
51
+
52
+ The HTML pages remain the primary source of information. Their text, headings,
53
+ links, and page metadata are present in the static response, so an agent can
54
+ read them without running client JavaScript. Write descriptive headings and
55
+ link text, keep instructions current, and verify the production output with
56
+ `npm run build` and `npm run preview`.
57
+
58
+ Google's [AI Search guidance](https://developers.google.com/search/docs/fundamentals/ai-optimization-guide)
59
+ prioritizes ordinary crawlability and useful content. It says `llms.txt` is
60
+ not used by Google Search; Cookbook provides it for other agents that use the
61
+ [llms.txt proposal](https://llmstxt.org/).
package/docs/cli.md CHANGED
@@ -67,20 +67,20 @@ npm create @tenphi/cookbook@latest docs-site -- --source . --yes
67
67
  npm create @tenphi/cookbook@latest docs-site -- --package @scope/package --yes
68
68
  ```
69
69
 
70
- | Flag | Purpose |
71
- | ----------------------------------- | ------------------------------------------------- |
72
- | `--source <directory>` | Document an existing local repository |
73
- | `--package <specifier>` | Document a locked npm artifact |
74
- | `--yes`, `-y` | Use non-interactive defaults |
75
- | `--brand <color>` | Set the Glaze brand seed |
76
- | `--site <url>` | Set the canonical site URL |
77
- | `--base <path>` | Set Astro's hosting subpath |
78
- | `--deploy github-pages\|none` | Add a deployment workflow |
79
- | `--package-manager npm\|pnpm\|yarn` | Select the project manager |
80
- | `--no-install` | Generate files without installing dependencies |
81
- | `--vendor` | Vendor the npm artifact for offline builds |
82
- | `--trust-package` | Permit MDX execution from the locked npm artifact |
83
- | `--open` | Start and open the development server |
70
+ | Flag | Purpose |
71
+ | ---------------------------------------------------------------- | ------------------------------------------------- |
72
+ | `--source <directory>` | Document an existing local repository |
73
+ | `--package <specifier>` | Document a locked npm artifact |
74
+ | `--yes`, `-y` | Use non-interactive defaults |
75
+ | `--brand <color>` | Set the Glaze brand seed |
76
+ | `--site <url>` | Set the canonical site URL |
77
+ | `--base <path>` | Set Astro's hosting subpath |
78
+ | `--deploy github-pages\|netlify\|cloudflare-pages\|vercel\|none` | Add deployment setup or a host guide |
79
+ | `--package-manager npm\|pnpm\|yarn` | Select the project manager |
80
+ | `--no-install` | Generate files without installing dependencies |
81
+ | `--vendor` | Vendor the npm artifact for offline builds |
82
+ | `--trust-package` | Permit MDX execution from the locked npm artifact |
83
+ | `--open` | Start and open the development server |
84
84
 
85
85
  `--source` and `--package` are mutually exclusive. With neither, the creator
86
86
  writes a local starter. `--vendor` and `--trust-package` require `--package`.
@@ -29,8 +29,10 @@ and the lock live. `--root` chooses the CLI's configuration search directory;
29
29
  discovery and resolves its `root` relative to the integration root.
30
30
 
31
31
  Use `mergeDocsConfig(preset, overrides)` to compose shared configuration. Objects
32
- merge recursively and arrays replace; Tasty styles preserve default values when
33
- adding conditional overrides. Neither input is mutated. See
32
+ merge recursively and arrays replace. Each `theme.fonts` role replaces its
33
+ previous definition, so switching a role from Google to local files takes one
34
+ override. Tasty styles preserve default values when adding conditional
35
+ overrides. Neither input is mutated. See
34
36
  [working examples](./examples.md#share-configuration-and-themes).
35
37
 
36
38
  ## Redirects
@@ -64,7 +66,34 @@ with one locked npm package source infers its version automatically; set this
64
66
  field for local or multi-package documentation. Read it from the package
65
67
  manifest when possible so it remains current. `url` configures Astro's canonical
66
68
  site origin and sitemap metadata. If Astro also declares `site`, the values must
67
- match. `repository` adds a source link to the header.
69
+ match. It also lets Cookbook put absolute page URLs in `llms.txt` and a sitemap
70
+ pointer in the origin-root `robots.txt`. `repository` adds a source link to the
71
+ header.
72
+
73
+ For multiple documentation versions, set `site.versions` and mount content at
74
+ each version root. The header then shows a version selector. It links to the
75
+ same route in another version when that page exists and falls back to the
76
+ other version's root when it does not:
77
+
78
+ ```ts
79
+ site: {
80
+ versions: [
81
+ { label: "Latest", routeBase: "/" },
82
+ { label: "v1", routeBase: "/v1" },
83
+ ],
84
+ },
85
+ content: {
86
+ sources: [
87
+ { file: "README.md", route: "/" },
88
+ { glob: "docs/**/*.md", base: "docs" },
89
+ { file: "versions/v1/README.md", routeBase: "/v1", route: "/" },
90
+ { glob: "versions/v1/docs/**/*.md", base: "versions/v1/docs", routeBase: "/v1" },
91
+ ],
92
+ },
93
+ ```
94
+
95
+ Each `routeBase` must have a page, and version roots must be distinct. A
96
+ single-version site can continue using `site.version` for a simple label.
68
97
 
69
98
  ### Site icons
70
99
 
@@ -315,12 +344,36 @@ fallback. Every internal route named anywhere in navigation must exist.
315
344
  theme: {
316
345
  brand: {
317
346
  from: "#2f5bff",
318
- contrast: { apca: 45 }
347
+ contrast: { apca: [45, 60] }
319
348
  },
320
349
  palette: {
321
- surface: "#fcfcff",
322
- text: "#20232a",
323
- textSoft: "#626875"
350
+ surface: { tone: 98, saturation: 0.05 },
351
+ text: {
352
+ base: "surface",
353
+ tone: 0,
354
+ saturation: 0,
355
+ contrast: { wcag: [7, 10] }
356
+ },
357
+ heading: {
358
+ base: "surface",
359
+ tone: [4, 0],
360
+ saturation: 0,
361
+ contrast: { wcag: [7, 10] }
362
+ },
363
+ textSoft: {
364
+ base: "surface",
365
+ tone: [25, 10],
366
+ saturation: 0.05,
367
+ contrast: { wcag: [4.5, 7] }
368
+ }
369
+ },
370
+ fonts: {
371
+ body: "Inter",
372
+ heading: { google: "Newsreader", weights: [400, 700] },
373
+ code: {
374
+ family: "Project Mono",
375
+ files: [{ src: "/fonts/project-mono.woff2", weight: "100 900" }]
376
+ }
324
377
  },
325
378
  tokens: {
326
379
  "$radius": "8px",
@@ -332,9 +385,8 @@ theme: {
332
385
  },
333
386
  states: {},
334
387
  presets: {
335
- body: { fontFamily: "Inter, sans-serif", boldFontWeight: 680 },
388
+ body: { boldFontWeight: 680 },
336
389
  heading: {
337
- fontFamily: "Newsreader, serif",
338
390
  fontWeight: 650,
339
391
  boldFontWeight: 740
340
392
  }
@@ -351,10 +403,20 @@ theme: {
351
403
 
352
404
  The default brand is `okhsl(266 68% 48%)`, a blue with 68% saturation; controls
353
405
  use an `8px` radius and cards use `16px`. Onest is the default body and heading family, while JetBrains Mono is
354
- used for code. The default layout is capped at `87.5rem` (1400px), matching the
355
- Tasty site, with a `58rem` reading column and a `17.5rem` sidebar. `palette`
356
- supplies semantic Glaze inputs rather than component colors,
357
- so the whole interface continues to adapt in dark and high-contrast modes. A requested APCA floor below 45 requires the explicit
406
+ used for code. `theme.fonts` loads Google families by name or local files from
407
+ `public/`, and applies them to the body, heading, and code presets. See
408
+ [Change font families](./theme-and-components.md#change-font-families) for both
409
+ flows. The default layout is capped at `87.5rem` (1400px), matching the
410
+ Tasty site, with a `58rem` reading column and a `17.5rem` sidebar. `brand.from`
411
+ supplies the color seed. `palette` supplies semantic Glaze declarations that
412
+ inherit its hue and saturation unless a role supplies its own `from`. `tone` and
413
+ a saturation factor set the surface. Reading text uses absolute tones: body
414
+ text starts at 0, and headings at 4. Glaze applies normal-mode tone boundaries
415
+ and adapts the values for dark mode; `base` and `contrast` provide minimum
416
+ contrast safeguards. `palette.heading` follows an explicit `palette.text`
417
+ declaration unless customized separately. Glaze resolves light, dark, and both
418
+ high-contrast modes independently. Literal color shorthand and structured
419
+ brand hue/saturation/tone remain supported. A requested APCA floor below 45 requires the explicit
358
420
  `unsafeContrast: true` escape hatch. Learn more in
359
421
  [Theme and components](./theme-and-components.md).
360
422
 
@@ -393,6 +455,22 @@ Configure renderer-level Markdown options such as custom remark or rehype
393
455
  plugins and Shiki languages through Astro's top-level `markdown` configuration.
394
456
  Cookbook preserves those settings while adding its own build-time transforms.
395
457
 
458
+ Starlight content and behavior plugins can be supplied to the Astro integration:
459
+
460
+ ```ts
461
+ import myStarlightPlugin from "./plugins/my-starlight-plugin.js";
462
+
463
+ export default defineConfig({
464
+ integrations: [cookbook({ plugins: [myStarlightPlugin()] })],
465
+ });
466
+ ```
467
+
468
+ Cookbook forwards these plugins to Starlight. Plugins that add stylesheets or
469
+ style tags fail the production build because Cookbook ships only Tasty styles.
470
+ Plugins that replace
471
+ Cookbook-owned components or change routes can conflict with the content graph.
472
+ Use `theme.styles` for visual changes.
473
+
396
474
  Cookbook renders fenced `mermaid` blocks as responsive, theme-aware SVG during
397
475
  the static build. Flowcharts, state, sequence, class, and entity-relationship
398
476
  diagrams are supported. Invalid or unsupported diagrams remain visible as
@@ -510,7 +588,7 @@ the Astro base. `variant` is `default` or `primary` and applies on desktop;
510
588
  and adds safe new-window attributes when enabled. Customize the complete
511
589
  button and popover style tree through `theme.styles.HeaderLinks`.
512
590
 
513
- `theme.palette.header` sets the translucent header's color seed. It defaults
591
+ `theme.palette.header` sets the translucent header's color declaration. It defaults
514
592
  to `theme.palette.surface`; Glaze resolves it for light, dark, and both high
515
593
  contrast modes. Adjust blur and other header styling via `theme.styles.HeaderFrame`.
516
594
  `theme.palette.overlay` controls the fixed underlay color, defaulting to black at
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Content sources
3
- description: Collect local files, globs, and locked npm package documentation into one route graph.
3
+ description: Collect local files, OpenAPI specs, and locked npm package documentation into one route graph.
4
4
  sidebar:
5
5
  order: 3
6
6
  ---
@@ -92,6 +92,34 @@ A frontmatter `slug` is relative to `routeBase`, including when it begins with
92
92
  accept `routeBase`, which prefixes their explicit `route`. Empty `sources: []`
93
93
  means no sources; omit the property to enable conventions.
94
94
 
95
+ ## OpenAPI references
96
+
97
+ Add a local OpenAPI 3.x JSON or YAML document to generate a searchable overview
98
+ and one page per operation:
99
+
100
+ ```ts
101
+ content: {
102
+ sources: [
103
+ { file: "README.md", route: "/" },
104
+ { openapi: "api/openapi.yaml", routeBase: "/api" },
105
+ ],
106
+ }
107
+ ```
108
+
109
+ The overview appears at `/api`. An operation with `operationId: getWidget`
110
+ appears at `/api/get-widget`. Without an operation ID, Cookbook derives a route
111
+ from its method and path. Operation IDs must create distinct routes. The pages
112
+ include parameters, request bodies, responses, examples, and the document's
113
+ schemas. Source links point back to the spec file. Use a navigation item such
114
+ as `{ label: "API", link: "/api", items: [{ label: "Operations", autogenerate: { directory: "/api" } }] }`
115
+ to show the operations in the sidebar.
116
+
117
+ The source must stay within its declared `root` unless
118
+ `content.allowOutsideRoot` is enabled. External `$ref` values require bundling
119
+ into one local document before the build. Cookbook checks the spec size against
120
+ `build.maxAssetBytes` and reports invalid or duplicate operation routes.
121
+ Generated pages are static references; they do not make requests to the API.
122
+
95
123
  ## npm package sources
96
124
 
97
125
  Package sources read documentation from the actual npm artifact:
@@ -23,6 +23,7 @@ before overriding a built-in component.
23
23
  | ----------------------------- | ------------------------------------------------------ |
24
24
  | Brand and semantic colors | `theme.brand` and the supported `theme.palette` inputs |
25
25
  | Shared dimensions and spacing | `theme.tokens` |
26
+ | Font loading and family roles | `theme.fonts` |
26
27
  | Typography | `theme.presets` |
27
28
  | Responsive conditions | `theme.states` |
28
29
  | Existing component appearance | Partial Tasty objects in `theme.styles.<Name>` |
@@ -63,8 +64,8 @@ belong in `docs.config.ts`.
63
64
  owning style object. Keep their selectors and base styles together instead
64
65
  of spreading component anatomy across unrelated global rules.
65
66
  * Use semantic color tokens such as `#text`, `#surface`, and `#accent-text`
66
- in component styles. Configure color seeds through `theme.brand` and the
67
- supported `theme.palette` roles so Glaze can resolve every scheme and
67
+ in component styles. Configure Glaze color declarations through `theme.brand`
68
+ and the supported `theme.palette` roles so Glaze can resolve every scheme and
68
69
  contrast mode. Do not hard-code component colors or invent palette keys.
69
70
  * Apply semantic typography with `preset`, for example `"small"` or
70
71
  `"h2 / strong"`. Do not reconstruct presets from individual font tokens or
@@ -65,14 +65,31 @@ not required.
65
65
 
66
66
  This site is deployed by the repository's Pages workflow to
67
67
  `cookbook.tenphi.me` with HTTPS enforcement enabled.
68
+ The Cookbook repository deploys its own documentation only after a package
69
+ release. The release workflow creates a version tag and then starts the Pages
70
+ workflow from that tag, so the public reference matches the published code.
68
71
 
69
72
  ## Other static hosts
70
73
 
71
- Use the host's ordinary static-site settings:
74
+ The creator supports `--deploy netlify`, `--deploy cloudflare-pages`, and
75
+ `--deploy vercel`. It writes a `DEPLOYMENT.md` with host settings; Netlify also
76
+ gets `netlify.toml`. You can also use the host's ordinary static-site settings:
72
77
 
73
78
  - build command: `npm run build`
74
79
  - publish directory: `dist`
75
- - Node.js: 22.14 or newer
80
+ - Node.js: 22.19 or newer
76
81
 
77
82
  If the host serves the site below a path rather than at an origin root, set
78
83
  Astro's `base`; Cookbook derives it automatically.
84
+
85
+ ## Discovery and agent access
86
+
87
+ Set `site.url` to the public HTTPS origin before building. This enables canonical
88
+ page URLs and the sitemap. The build also emits `llms.txt` with links to
89
+ published documentation pages. At an origin root, it emits `robots.txt` pointing
90
+ to the sitemap. Host these files with the rest of `dist/`; custom files in
91
+ `public/` take precedence. For path-hosted sites, manage the origin's
92
+ `robots.txt` in the hosting configuration.
93
+
94
+ Check the deployed HTML, `sitemap-index.xml`, and `llms.txt` through their public
95
+ URLs. See [AI agents](./ai-agents.md) for the setup and reading workflow.
package/docs/examples.md CHANGED
@@ -79,7 +79,10 @@ A preset is an ordinary exported `DocsConfig` object:
79
79
  import { defineDocsConfig, mergeDocsConfig } from "@tenphi/cookbook/config";
80
80
 
81
81
  const company = defineDocsConfig({
82
- theme: { brand: "#315efb", tokens: { $radius: "8px" } },
82
+ theme: {
83
+ brand: { from: "#315efb" },
84
+ tokens: { $radius: "8px" },
85
+ },
83
86
  markdown: { rawHtml: "sanitize" },
84
87
  });
85
88
 
@@ -89,6 +92,9 @@ export default mergeDocsConfig(company, {
89
92
  });
90
93
  ```
91
94
 
95
+ Each `theme.brand` or `theme.palette` color replaces the corresponding color in
96
+ the preset. Supply the complete Glaze declaration for a color you override.
97
+
92
98
  Objects merge recursively, arrays replace, and inputs are not mutated. Tasty
93
99
  styles preserve their default values when adding conditional overrides. A preset
94
100
  can live in a shared workspace package. Component overrides remain partial Tasty
@@ -5,7 +5,7 @@ sidebar:
5
5
  order: 2
6
6
  ---
7
7
 
8
- Cookbook requires Node.js 22.14 or newer.
8
+ Cookbook requires Node.js 22.19 or newer.
9
9
 
10
10
  ## Create your first site
11
11
 
@@ -16,7 +16,8 @@ npm run dev
16
16
  ```
17
17
 
18
18
  The creator writes a README, Astro configuration, and `docs.config.ts`, then
19
- installs dependencies. Edit `README.md` to change the home page. Add
19
+ installs dependencies. It also writes `AGENTS.md` with instructions for coding
20
+ agents. Edit `README.md` to change the home page. Add
20
21
  `docs/guide.md` to create `/guide`. New and edited pages appear in the development
21
22
  server without a restart.
22
23
 
@@ -86,10 +87,19 @@ export default defineDocsConfig({
86
87
  description: "Documentation for Example Project",
87
88
  repository: "https://github.com/example/project",
88
89
  },
89
- theme: { brand: "#2f5bff" },
90
+ theme: {
91
+ brand: { from: "#2f5bff" },
92
+ fonts: { body: "Inter", heading: "Newsreader" },
93
+ },
90
94
  });
91
95
  ```
92
96
 
97
+ Change `theme.fonts` to use [Google Fonts by name or your own font files](./theme-and-components.md#change-font-families).
98
+ Use `theme.presets` for typography details, `theme.styles` for built-in elements,
99
+ and `defineComponent()` with `theme.customStyles` to add a new element. The
100
+ [theme guide](./theme-and-components.md) includes examples and the complete
101
+ list of customizable sub-elements.
102
+
93
103
  The integration and CLI load the same configuration. Supported filenames are
94
104
  `docs.config.ts`, `.mts`, `.js`, and `.mjs`, in that order. An explicit integration
95
105
  `config` object takes precedence; `configFile: false` disables discovery.
@@ -120,5 +130,5 @@ npm run preview
120
130
  ```
121
131
 
122
132
  See [working examples](./examples.md), [authoring components](./authoring.mdx),
123
- and [deployment](./deployment.md). Existing users should read the
133
+ the [AI agent workflow](./ai-agents.md), and [deployment](./deployment.md). Existing users should read the
124
134
  [prerelease migration guide](./migration.md).
@@ -28,22 +28,24 @@ cover the configuration language accepted by `theme.styles`:
28
28
 
29
29
  ## Brand color
30
30
 
31
- The default brand is a calm blue with 68% OKHSL saturation. The short form
32
- accepts any color value supported by Glaze:
31
+ The default brand is a calm blue with 68% OKHSL saturation. Set a brand color
32
+ with Glaze's `from` declaration:
33
33
 
34
34
  ```ts
35
35
  theme: {
36
- brand: "okhsl(266 68% 48%)",
36
+ brand: {
37
+ from: "#2f5bff";
38
+ }
37
39
  }
38
40
  ```
39
41
 
40
- Use the object form to set an explicit contrast target:
42
+ Add a contrast target when the brand appears as text or focus color:
41
43
 
42
44
  ```ts
43
45
  theme: {
44
46
  brand: {
45
- from: "oklch(58% 0.22 265)",
46
- contrast: { apca: [60, 75] }
47
+ from: "#2f5bff",
48
+ contrast: { apca: [45, 60] }
47
49
  }
48
50
  }
49
51
  ```
@@ -54,33 +56,68 @@ floor requires. Dark and high-contrast schemes resolve independently.
54
56
 
55
57
  Cookbook rejects a normal APCA target below 45 unless
56
58
  `unsafeContrast: true` is present. That escape hatch is intentionally visible
57
- in configuration reviews.
59
+ in configuration reviews. Literal color shorthand and structured
60
+ `hue`/`saturation`/`tone` input also remain supported for the brand.
58
61
 
59
62
  ## Semantic palette
60
63
 
61
- `brand` controls accent text, fills, and focus. The optional palette inputs
62
- control the neutral reading surface. `info`, `success`, `warning`, and `danger`
63
- configure callout status seeds; each exposes a border role, `-text`, and
64
- `-surface` semantic tokens for all schemes and contrast modes. The authored surface is preserved in the
65
- light scheme; its dark counterpart is deliberately desaturated so a nearly
66
- white tint cannot turn into vivid dark chrome when its tone is inverted. Glaze
67
- resolves all values independently for light, dark, normal, and high-contrast
68
- modes:
64
+ `brand` controls accent text, fills, and focus. The optional palette roles
65
+ control the reading surface, text, and callout colors. Declare color
66
+ relationships with Glaze's `tone`, `base`, and `contrast` properties:
69
67
 
70
68
  ```ts
71
69
  theme: {
72
- brand: "okhsl(266 68% 48%)",
70
+ brand: { from: "#2f5bff" },
73
71
  palette: {
74
- surface: "#fffdf8",
75
- text: "#211f1c",
76
- textSoft: "#66615a"
72
+ surface: { tone: 98, saturation: 0.05 },
73
+ text: {
74
+ base: "surface",
75
+ tone: 0,
76
+ saturation: 0,
77
+ contrast: { wcag: [7, 10] }
78
+ },
79
+ heading: {
80
+ base: "surface",
81
+ tone: [4, 0],
82
+ saturation: 0,
83
+ contrast: { wcag: [7, 10] }
84
+ },
85
+ textSoft: {
86
+ base: "surface",
87
+ tone: [25, 10],
88
+ saturation: 0.05,
89
+ contrast: { wcag: [4.5, 7] }
90
+ }
77
91
  },
78
92
  contrastLevel: "auto"
79
93
  }
80
94
  ```
81
95
 
96
+ Glaze resolves each declaration for light, dark, normal, and high-contrast
97
+ modes. In a tone or contrast pair, the first value applies to normal mode;
98
+ the second applies to high contrast. Use absolute tones for reading text:
99
+ `text` starts at tone 0 and `heading` at tone 4, giving headings only a slight
100
+ reduction in contrast. Glaze applies its tone boundaries in normal mode, so
101
+ body text is not pure black, then inverts the tones for dark mode. High-contrast
102
+ mode uses the full range. `textSoft` is reserved for secondary text.
103
+ `heading` follows an explicitly configured `text` declaration unless it has
104
+ its own declaration, preserving existing custom palettes.
105
+ Contrast requirements are minimum safeguards: Glaze preserves the authored
106
+ tone when it already meets the floor. A small relative tone step from the
107
+ surface would instead leave the solver to produce text at that minimum.
108
+
109
+ Palette declarations inherit the brand hue and saturation:
110
+ `saturation` is a 0–1 factor of that seed, and `tone` is 0–100. They can set
111
+ an absolute tone or a tone relative to `base`. Use `from` on a palette role
112
+ when it needs its own color seed; otherwise relative declarations keep its
113
+ relationship to the brand and surrounding surface as the scheme or contrast
114
+ changes. `info`, `success`, `warning`, and `danger` also accept Glaze
115
+ declarations and expose border, `-text`, and `-surface` semantic tokens.
116
+ Cookbook keeps literal surface seeds desaturated in the dark scheme so a nearly
117
+ white tint does not become vivid dark chrome when its tone is inverted.
118
+
82
119
  Components consume semantic colors consistently: `surface`, `header`, `surface-2`,
83
- `surface-3`, `text`, `text-soft`, `border`, `border-strong`, `accent-text`,
120
+ `surface-3`, `text`, `heading`, `text-soft`, `border`, `border-strong`, `accent-text`,
84
121
  `accent-surface`, `accent-surface-text`, and `focus`. Tasty components can use
85
122
  these as `#surface`, `#text`, `#border`, and so on; the Astro shell consumes the
86
123
  same resolved values. Glaze also generates hover and pressed states, subtle
@@ -153,18 +190,74 @@ without one-off component overrides.
153
190
  The built-in [typography presets](./upstream/tasty/docs/styles.md#preset) are
154
191
  `body`, `heading`, `h1` through `h6`, `navigation`, `small`, and `code`. Onest
155
192
  is self-hosted and used for body and heading text by default; JetBrains Mono is
156
- self-hosted for code. Presets merge property-by-property, so changing a font
157
- does not require copying its size, weight, or line height:
193
+ self-hosted for code.
194
+
195
+ ### Change font families
196
+
197
+ Set `theme.fonts` to load fonts and apply them to the matching presets. A Google
198
+ Fonts family needs only its name:
199
+
200
+ ```ts
201
+ theme: {
202
+ fonts: {
203
+ body: "Inter",
204
+ heading: "Newsreader"
205
+ }
206
+ }
207
+ ```
208
+
209
+ The short form requests the family's default style. To use specific weights,
210
+ list them explicitly. Google Fonts must support the requested weights; see the
211
+ [Google Fonts CSS API](https://developers.google.com/fonts/docs/css2) for its
212
+ available styles and weight syntax.
213
+
214
+ ```ts
215
+ theme: {
216
+ fonts: {
217
+ body: { google: "Inter", weights: [400, 600, 700] }
218
+ }
219
+ }
220
+ ```
221
+
222
+ For a font you own, put its files in `public/fonts/` and give Cookbook their
223
+ public paths. Cookbook checks that each file exists during the build and adjusts
224
+ its URL for the Astro `base` path. A variable font can cover a weight range;
225
+ use separate entries for regular and italic files when needed:
226
+
227
+ ```ts
228
+ theme: {
229
+ fonts: {
230
+ body: {
231
+ family: "Acme Sans",
232
+ files: [
233
+ { src: "/fonts/acme-sans.woff2", weight: "100 900" },
234
+ { src: "/fonts/acme-sans-italic.woff2", weight: "100 900", style: "italic" }
235
+ ]
236
+ }
237
+ }
238
+ }
239
+ ```
240
+
241
+ The `body` role also feeds navigation and small text. `heading` feeds `h1`
242
+ through `h6`, while `code` covers code text. Each role has a system fallback.
243
+ Cookbook emits the font faces through Tasty. Google font names are resolved at
244
+ build time, so those builds need network access; the generated site has no
245
+ Google CSS stylesheet. Font files are requested from Google's font CDN when
246
+ visitors open the site. Use local files if you need a self-hosted site.
247
+
248
+ ### Adjust presets
249
+
250
+ Presets merge property-by-property, so changing size, weight, or line height
251
+ does not require copying the rest of the preset. `theme.presets` takes precedence
252
+ over `theme.fonts` for an explicitly set `fontFamily`:
158
253
 
159
254
  ```ts
160
255
  theme: {
161
256
  presets: {
162
257
  body: {
163
- fontFamily: "Inter, system-ui, sans-serif",
164
258
  boldFontWeight: 680
165
259
  },
166
260
  heading: {
167
- fontFamily: "Newsreader, Georgia, serif",
168
261
  fontWeight: 650,
169
262
  boldFontWeight: 740
170
263
  },
@@ -172,13 +265,15 @@ theme: {
172
265
  fontSize: "3rem",
173
266
  letterSpacing: "-0.02em"
174
267
  },
175
- code: {
176
- fontFamily: "Berkeley Mono, ui-monospace, monospace"
177
- }
268
+ code: { fontSize: "0.9rem" }
178
269
  }
179
270
  }
180
271
  ```
181
272
 
273
+ For a system or already loaded font, set its CSS family directly with
274
+ `theme.presets.<role>.fontFamily`. This does not load a font file. Additional
275
+ named presets are available to custom MDX components.
276
+
182
277
  Heading presets reference the `heading` family and weights; body, navigation,
183
278
  and controls reference `body`. Semantic `strong` and `b` elements use Tasty's
184
279
  `strong` modifier, so their weight comes from the active preset's
@@ -206,8 +301,6 @@ disclosure icons with `Caret` and `ExpandedCaret`.
206
301
  Adjacent sidebar items have a `1bw` gap. Inline code scales to `0.875em` of its
207
302
  surrounding text, including smaller table text; code blocks keep the `code` preset
208
303
  size. Customize inline code through `theme.styles.MarkdownInlineCode`.
209
- Additional named presets are passed through to Tasty SSR for use in custom MDX
210
- components.
211
304
  Cookbook applies each semantic typography role through its complete Tasty
212
305
  `preset`, so configured fields such as `fontStyle` and `textTransform` are not
213
306
  silently omitted.
@@ -285,6 +378,7 @@ sub-elements:
285
378
  | `MobileNavigationTabs` | `Trigger`, `Marker`, `Caret`, `ExpandedCaret`, `Label`, `List`, `Item`, `Link`, `HoverLink`, `CurrentLink` |
286
379
  | `MobileTableOfContents` | `Item`, `Link`, `LinkLabel`, `HoverLink`, `CurrentLink`, `CurrentIndicator` |
287
380
  | `PackageVersion` | None |
381
+ | `VersionSwitcher` | `Trigger`, `Panel`, `OpenPanel`, `Link`, `CurrentLink` |
288
382
  | `Preview` | `Caption`, `Stage`, `Frame`, `Code`, `Summary`, `Pre` |
289
383
  | `Sidebar` | `Backdrop`, `OpenBackdrop`, `MobileHeading`, `HomeLink`, `HomeLogo`, `HomeLabel`, `Close`, `HoverClose`, `CloseIcon`, `CurrentLink`, `OpenPane`, `Content`, `Tree`, `List`, `Item`, `TopLevelSpacing`, `GroupSpacing`, `NestedItem`, `SectionHeading`, `Control`, `Summary`, `GroupLabel`, `GroupLabelText`, `Link`, `LinkLabel`, `InteractiveControl`, `SummaryMarker`, `Caret`, `ExpandedCaret`, `LinkedSummary`, `GroupLink`, `LinkedSectionHeading`, `SectionLink`, `Badge`, `TopLevelLink` |
290
384
  | `SocialIcons` | `Link`, `HoverLink`, `Icon` |
@@ -293,6 +387,7 @@ sub-elements:
293
387
  | `SearchButton` | `Label`, `Shortcut`, `Hover`, `Active`, `NativeIcon`, `Icon` |
294
388
  | `Layout` | `LockedPage` |
295
389
  | `HeaderLinks` | `Desktop`, `Link`, `HoverLink`, `PrimaryLink`, `HoverPrimaryLink`, `Trigger`, `HoverTrigger`, `Panel`, `PanelNavigation`, `PanelLink`, `FirstPanelLink`, `Close`, `HoverClose` |
390
+ | `Heading` | `Level1`, `Level2`, `Level3`, `Level4`, `Level5`, `Level6`, `PageTitle` |
296
391
  | `HeaderFrame` | None |
297
392
  | `PageFrame` | `MainFrame`, `SidebarFrame`, `Columns` |
298
393
  | `Steps` | `Item`, `Marker` |
@@ -653,7 +748,7 @@ selector, and a close button. The drawer slides in and out over 120ms and
653
748
  disables motion when the reader prefers reduced motion. Its mobile shadow uses
654
749
  the Glaze `shadow`-typed `#shadow` token. Customize the movement and shadow through
655
750
  `theme.styles.Sidebar`, and the underlay through `Sidebar.Backdrop` and
656
- `OpenBackdrop`. `theme.palette.overlay` supplies the underlay seed, which defaults
751
+ `OpenBackdrop`. `theme.palette.overlay` supplies the underlay declaration, which defaults
657
752
  to black at 50% opacity. Glaze resolves it in fixed mode with tone remapping
658
753
  disabled, so it stays black in dark and high-contrast schemes.
659
754
  Icon buttons retain their plain desktop appearance on mobile. More uses
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/cookbook",
3
- "version": "0.16.0",
3
+ "version": "0.17.1",
4
4
  "description": "Repository-native static documentation for Astro",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -47,7 +47,7 @@
47
47
  "index": "docs/index.md"
48
48
  },
49
49
  "engines": {
50
- "node": ">=22.14"
50
+ "node": ">=22.19"
51
51
  },
52
52
  "publishConfig": {
53
53
  "access": "public"
@@ -64,8 +64,8 @@
64
64
  "author": "Andrey Yamanov",
65
65
  "license": "MIT",
66
66
  "dependencies": {
67
- "@tenphi/docs": "0.16.0",
68
- "@tenphi/starlight": "0.16.0"
67
+ "@tenphi/docs": "0.17.1",
68
+ "@tenphi/starlight": "0.17.1"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "astro": "^7.3.2"