@cogenta/cli 0.4.0 → 0.7.0

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 (174) hide show
  1. package/CHANGELOG.md +3951 -0
  2. package/dist/admin-assets/assets/index-Bc_X94A_.js +1090 -0
  3. package/dist/admin-assets/assets/index-CxZHGwVA.css +1 -0
  4. package/dist/admin-assets/assets/vips-_dmTUXFO.wasm +0 -0
  5. package/dist/admin-assets/assets/vips-es6-DrQTTS8Q.js +7 -0
  6. package/dist/admin-assets/branding/logo-cogenta-dark.png +0 -0
  7. package/dist/admin-assets/branding/logo-cogenta-icon.png +0 -0
  8. package/dist/admin-assets/branding/logo-cogenta-light.png +0 -0
  9. package/dist/admin-assets/branding/logo-cogenta-small.png +0 -0
  10. package/dist/admin-assets/branding/logo-cogenta-transparent.png +0 -0
  11. package/dist/admin-assets/branding/logo-cogenta.png +0 -0
  12. package/dist/admin-assets/favicon.png +0 -0
  13. package/dist/admin-assets/fonts/jetbrains-mono-var.woff2 +0 -0
  14. package/dist/admin-assets/fonts/space-grotesk-var.woff2 +0 -0
  15. package/dist/admin-assets/index.html +3 -2
  16. package/dist/bin.js +6 -0
  17. package/dist/bin.js.map +1 -1
  18. package/dist/commands/admin-assets.d.ts +1 -0
  19. package/dist/commands/admin-assets.d.ts.map +1 -1
  20. package/dist/commands/admin-assets.js +19 -1
  21. package/dist/commands/admin-assets.js.map +1 -1
  22. package/dist/commands/agent-runtime.d.ts +160 -0
  23. package/dist/commands/agent-runtime.d.ts.map +1 -0
  24. package/dist/commands/agent-runtime.js +524 -0
  25. package/dist/commands/agent-runtime.js.map +1 -0
  26. package/dist/commands/assistant.d.ts +89 -3
  27. package/dist/commands/assistant.d.ts.map +1 -1
  28. package/dist/commands/assistant.js +209 -41
  29. package/dist/commands/assistant.js.map +1 -1
  30. package/dist/commands/audit-integrity-alert.d.ts +23 -0
  31. package/dist/commands/audit-integrity-alert.d.ts.map +1 -0
  32. package/dist/commands/audit-integrity-alert.js +33 -0
  33. package/dist/commands/audit-integrity-alert.js.map +1 -0
  34. package/dist/commands/backup.d.ts +78 -0
  35. package/dist/commands/backup.d.ts.map +1 -0
  36. package/dist/commands/backup.js +238 -0
  37. package/dist/commands/backup.js.map +1 -0
  38. package/dist/commands/channels.d.ts +47 -0
  39. package/dist/commands/channels.d.ts.map +1 -0
  40. package/dist/commands/channels.js +284 -0
  41. package/dist/commands/channels.js.map +1 -0
  42. package/dist/commands/default-logo.d.ts +27 -0
  43. package/dist/commands/default-logo.d.ts.map +1 -0
  44. package/dist/commands/default-logo.js +30 -0
  45. package/dist/commands/default-logo.js.map +1 -0
  46. package/dist/commands/doctor.d.ts +5 -1
  47. package/dist/commands/doctor.d.ts.map +1 -1
  48. package/dist/commands/doctor.js +74 -2
  49. package/dist/commands/doctor.js.map +1 -1
  50. package/dist/commands/export.d.ts +22 -0
  51. package/dist/commands/export.d.ts.map +1 -0
  52. package/dist/commands/export.js +182 -0
  53. package/dist/commands/export.js.map +1 -0
  54. package/dist/commands/forms-page.d.ts +75 -0
  55. package/dist/commands/forms-page.d.ts.map +1 -0
  56. package/dist/commands/forms-page.js +191 -0
  57. package/dist/commands/forms-page.js.map +1 -0
  58. package/dist/commands/import.d.ts.map +1 -1
  59. package/dist/commands/import.js +13 -1
  60. package/dist/commands/import.js.map +1 -1
  61. package/dist/commands/mcp.d.ts +35 -0
  62. package/dist/commands/mcp.d.ts.map +1 -0
  63. package/dist/commands/mcp.js +277 -0
  64. package/dist/commands/mcp.js.map +1 -0
  65. package/dist/commands/roles.d.ts +22 -0
  66. package/dist/commands/roles.d.ts.map +1 -0
  67. package/dist/commands/roles.js +79 -0
  68. package/dist/commands/roles.js.map +1 -0
  69. package/dist/commands/search-page.d.ts +15 -0
  70. package/dist/commands/search-page.d.ts.map +1 -1
  71. package/dist/commands/search-page.js +22 -16
  72. package/dist/commands/search-page.js.map +1 -1
  73. package/dist/commands/seo.d.ts +92 -4
  74. package/dist/commands/seo.d.ts.map +1 -1
  75. package/dist/commands/seo.js +168 -4
  76. package/dist/commands/seo.js.map +1 -1
  77. package/dist/commands/serve.d.ts +439 -7
  78. package/dist/commands/serve.d.ts.map +1 -1
  79. package/dist/commands/serve.js +3515 -181
  80. package/dist/commands/serve.js.map +1 -1
  81. package/dist/commands/site-plan.d.ts +27 -1
  82. package/dist/commands/site-plan.d.ts.map +1 -1
  83. package/dist/commands/site-plan.js +79 -8
  84. package/dist/commands/site-plan.js.map +1 -1
  85. package/dist/commands/skin.d.ts.map +1 -1
  86. package/dist/commands/skin.js +7 -2
  87. package/dist/commands/skin.js.map +1 -1
  88. package/dist/commands/term-archive-page.d.ts +94 -0
  89. package/dist/commands/term-archive-page.d.ts.map +1 -0
  90. package/dist/commands/term-archive-page.js +195 -0
  91. package/dist/commands/term-archive-page.js.map +1 -0
  92. package/dist/commands/theme-css.d.ts +22 -7
  93. package/dist/commands/theme-css.d.ts.map +1 -1
  94. package/dist/commands/theme-css.js +33 -8
  95. package/dist/commands/theme-css.js.map +1 -1
  96. package/dist/commands/theme-registry.d.ts +94 -0
  97. package/dist/commands/theme-registry.d.ts.map +1 -0
  98. package/dist/commands/theme-registry.js +130 -0
  99. package/dist/commands/theme-registry.js.map +1 -0
  100. package/dist/commands/theme-render.d.ts +330 -9
  101. package/dist/commands/theme-render.d.ts.map +1 -1
  102. package/dist/commands/theme-render.js +932 -66
  103. package/dist/commands/theme-render.js.map +1 -1
  104. package/dist/commands/theme-wiring.d.ts +107 -0
  105. package/dist/commands/theme-wiring.d.ts.map +1 -0
  106. package/dist/commands/theme-wiring.js +308 -0
  107. package/dist/commands/theme-wiring.js.map +1 -0
  108. package/dist/commands/tools.d.ts +71 -0
  109. package/dist/commands/tools.d.ts.map +1 -0
  110. package/dist/commands/tools.js +330 -0
  111. package/dist/commands/tools.js.map +1 -0
  112. package/dist/commands/update.d.ts +25 -0
  113. package/dist/commands/update.d.ts.map +1 -0
  114. package/dist/commands/update.js +193 -0
  115. package/dist/commands/update.js.map +1 -0
  116. package/dist/index.d.ts +15 -0
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +146 -4
  119. package/dist/index.js.map +1 -1
  120. package/dist/invite-mail.d.ts +39 -0
  121. package/dist/invite-mail.d.ts.map +1 -0
  122. package/dist/invite-mail.js +39 -0
  123. package/dist/invite-mail.js.map +1 -0
  124. package/dist/update/apply.d.ts +54 -0
  125. package/dist/update/apply.d.ts.map +1 -0
  126. package/dist/update/apply.js +77 -0
  127. package/dist/update/apply.js.map +1 -0
  128. package/dist/update/changelog-risk.d.ts +20 -0
  129. package/dist/update/changelog-risk.d.ts.map +1 -0
  130. package/dist/update/changelog-risk.js +55 -0
  131. package/dist/update/changelog-risk.js.map +1 -0
  132. package/dist/update/check.d.ts +60 -0
  133. package/dist/update/check.d.ts.map +1 -0
  134. package/dist/update/check.js +56 -0
  135. package/dist/update/check.js.map +1 -0
  136. package/dist/update/contract-risk.d.ts +55 -0
  137. package/dist/update/contract-risk.d.ts.map +1 -0
  138. package/dist/update/contract-risk.js +75 -0
  139. package/dist/update/contract-risk.js.map +1 -0
  140. package/dist/update/history.d.ts +30 -0
  141. package/dist/update/history.d.ts.map +1 -0
  142. package/dist/update/history.js +38 -0
  143. package/dist/update/history.js.map +1 -0
  144. package/dist/update/index.d.ts +28 -0
  145. package/dist/update/index.d.ts.map +1 -0
  146. package/dist/update/index.js +11 -0
  147. package/dist/update/index.js.map +1 -0
  148. package/dist/update/list-restore-points.d.ts +20 -0
  149. package/dist/update/list-restore-points.d.ts.map +1 -0
  150. package/dist/update/list-restore-points.js +35 -0
  151. package/dist/update/list-restore-points.js.map +1 -0
  152. package/dist/update/npm-registry.d.ts +11 -0
  153. package/dist/update/npm-registry.d.ts.map +1 -0
  154. package/dist/update/npm-registry.js +74 -0
  155. package/dist/update/npm-registry.js.map +1 -0
  156. package/dist/update/restore-point.d.ts +26 -0
  157. package/dist/update/restore-point.d.ts.map +1 -0
  158. package/dist/update/restore-point.js +23 -0
  159. package/dist/update/restore-point.js.map +1 -0
  160. package/dist/update/tar.d.ts +27 -0
  161. package/dist/update/tar.d.ts.map +1 -0
  162. package/dist/update/tar.js +56 -0
  163. package/dist/update/tar.js.map +1 -0
  164. package/dist/update/version-compare.d.ts +17 -0
  165. package/dist/update/version-compare.d.ts.map +1 -0
  166. package/dist/update/version-compare.js +42 -0
  167. package/dist/update/version-compare.js.map +1 -0
  168. package/dist/version.d.ts +13 -0
  169. package/dist/version.d.ts.map +1 -0
  170. package/dist/version.js +18 -0
  171. package/dist/version.js.map +1 -0
  172. package/package.json +33 -16
  173. package/dist/admin-assets/assets/index-C9a7O_Xs.css +0 -1
  174. package/dist/admin-assets/assets/index-DXvMgWvn.js +0 -74
@@ -0,0 +1,79 @@
1
+ import { writeFile } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ import process from 'node:process';
4
+ import { createDatabaseRegistry, createLogger, isCogentaError, loadConfig, } from '@cogenta/core';
5
+ import { createRolePermissionStore, serialiseRolePermissionExport } from '@cogenta/schema';
6
+ import { loadSchemaModule } from './serve.js';
7
+ const DEFAULT_EXPORT_FILE = 'cogenta.role-permissions.json';
8
+ const USAGE = `Usage
9
+ cogenta roles export [--out <path>] Freeze the role permission override table into a file
10
+
11
+ Reads every row an admin has written from the appearance-of-permissions
12
+ screen (or a previous "roles export") and writes it as JSON — a
13
+ point-in-time copy for a site that wants its permission overrides versioned
14
+ in git too, alongside cogenta.schema.*. Re-running this command overwrites
15
+ the file with the table's current state; it never writes back to the table.
16
+ `;
17
+ function reportCogentaError(error, stderr) {
18
+ if (isCogentaError(error)) {
19
+ stderr(`${error.code}: ${error.message}\n`);
20
+ if (error.hint !== undefined)
21
+ stderr(`${error.hint}\n`);
22
+ }
23
+ else {
24
+ stderr(`${error instanceof Error ? error.stack : String(error)}\n`);
25
+ }
26
+ }
27
+ async function runExport(options) {
28
+ const { out, stderr } = options;
29
+ const env = options.env ?? process.env;
30
+ const logger = options.logger ?? createLogger();
31
+ let projectRoot;
32
+ let loaded;
33
+ try {
34
+ loaded = await loadConfig({
35
+ ...(options.cwd === undefined ? {} : { cwd: options.cwd }),
36
+ env,
37
+ });
38
+ projectRoot = loaded.path === null ? (options.cwd ?? process.cwd()) : dirname(loaded.path);
39
+ }
40
+ catch (error) {
41
+ reportCogentaError(error, stderr);
42
+ return 1;
43
+ }
44
+ const selection = await createDatabaseRegistry({ logger }).select(loaded.config.database);
45
+ try {
46
+ const { collections, taxonomies } = await loadSchemaModule(projectRoot);
47
+ const store = createRolePermissionStore({ db: selection.instance, collections, taxonomies });
48
+ const records = await store.list();
49
+ const document = serialiseRolePermissionExport(records);
50
+ const path = options.file ?? join(projectRoot, DEFAULT_EXPORT_FILE);
51
+ await writeFile(path, `${JSON.stringify(document, null, 2)}\n`, 'utf8');
52
+ out.heading('Role permission overrides exported');
53
+ out.ok(`${records.length} override${records.length === 1 ? '' : 's'} written to ${path}`);
54
+ if (records.length === 0) {
55
+ out.detail('The database table holds no override yet — every role permission is still read from cogenta.schema.*.');
56
+ }
57
+ return 0;
58
+ }
59
+ catch (error) {
60
+ reportCogentaError(error, stderr);
61
+ return 1;
62
+ }
63
+ finally {
64
+ await selection.dispose();
65
+ }
66
+ }
67
+ export async function runRoles(options) {
68
+ const { subcommand, out, stderr } = options;
69
+ if (subcommand === undefined) {
70
+ out.line(USAGE);
71
+ return 0;
72
+ }
73
+ if (subcommand === 'export')
74
+ return runExport(options);
75
+ stderr(`Unknown "cogenta roles" subcommand: "${subcommand}".\n`);
76
+ out.line(USAGE);
77
+ return 2;
78
+ }
79
+ //# sourceMappingURL=roles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.js","sourceRoot":"","sources":["../../src/commands/roles.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,8 @@
1
1
  import type { AccessContext, ContentGateway, SearchRouter } from '@cogenta/api';
2
+ import type { MediaAsset } from '@cogenta/render';
2
3
  import { type CollectionDefinition } from '@cogenta/schema';
4
+ import type { SeoRenderDefaults } from './seo.js';
5
+ import { type BrandingSettings, type PageChromeMenus, type SiteIdentityMedia } from './theme-render.js';
3
6
  /**
4
7
  * `GET /search?q=…` — the public half of L10 task 3.
5
8
  *
@@ -31,6 +34,18 @@ export interface SearchPageOptions {
31
34
  };
32
35
  /** The joined skin+theme stylesheet `cogenta serve` serves at `STYLESHEET_PATH` (`theme-render.ts`'s `joinStyles`). `null` when neither could be loaded — served unstyled rather than refused. */
33
36
  readonly styles: string | null;
37
+ /** Same menu wiring the rest of the public site uses (`theme-render.ts`). Absent renders an empty header/footer nav. */
38
+ readonly menus?: PageChromeMenus;
39
+ /** Same live branding read the rest of the public site uses (`theme-render.ts`). Absent means full Cogenta credit. */
40
+ readonly branding?: () => Promise<BrandingSettings>;
41
+ /** Same live active-theme read the rest of the public site uses (`theme-render.ts`). Absent renders with the default theme. */
42
+ readonly activeTheme?: () => Promise<string | null>;
43
+ /** Same live SEO settings read the rest of the public site uses (`theme-render.ts`) — only the search-verification meta tags apply here (fiche 50 task 2). */
44
+ readonly seo?: () => Promise<SeoRenderDefaults>;
45
+ /** Same live site-identity read every other public page uses (audit T01) — the logo and favicon belong on this page too, or the search results look like a different site. */
46
+ readonly identity?: () => Promise<SiteIdentityMedia>;
47
+ /** Same batch media loader (`theme-render.ts`). Needed only to resolve the identity above; absent means the site name in text. */
48
+ readonly loadMedia?: (ids: readonly string[]) => Promise<ReadonlyMap<string, MediaAsset>>;
34
49
  }
35
50
  /**
36
51
  * The whole page. Returns HTML; the caller decides the status code (always
@@ -1 +1 @@
1
- {"version":3,"file":"search-page.d.ts","sourceRoot":"","sources":["../../src/commands/search-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC/E,OAAO,EAAa,KAAK,oBAAoB,EAAkB,MAAM,iBAAiB,CAAA;AAItF;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,oBAAoB,EAAE,CAAA;IACrD,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;QACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;QACpB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;QACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;KAC/B,CAAA;IACD,kMAAkM;IAClM,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AA+ED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAmDjB"}
1
+ {"version":3,"file":"search-page.d.ts","sourceRoot":"","sources":["../../src/commands/search-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAa,KAAK,oBAAoB,EAAkB,MAAM,iBAAiB,CAAA;AAEtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAEpB,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAA;AAE1B;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,oBAAoB,EAAE,CAAA;IACrD,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;QACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;QACpB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;QACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;KAC/B,CAAA;IACD,kMAAkM;IAClM,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,wHAAwH;IACxH,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,sHAAsH;IACtH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACnD,+HAA+H;IAC/H,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACnD,8JAA8J;IAC9J,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAC/C,8KAA8K;IAC9K,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACpD,kIAAkI;IAClI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAA;CAC1F;AA+ED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CA4DjB"}
@@ -1,6 +1,6 @@
1
1
  import { buildPath } from '@cogenta/schema';
2
2
  import { escapeHtmlAttribute, escapeHtmlText } from '@cogenta/seo';
3
- import { STYLESHEET_PATH } from './theme-render.js';
3
+ import { renderPageChrome, } from './theme-render.js';
4
4
  /**
5
5
  * Turns hits into links.
6
6
  *
@@ -82,23 +82,29 @@ export async function renderSearchPage(query, options, context) {
82
82
  : trimmed.length === 0
83
83
  ? ''
84
84
  : resultList(results);
85
- return `<!doctype html>
86
- <html lang="${escapeHtmlAttribute(options.site.defaultLocale)}">
87
- <head>
88
- <meta charset="utf-8">
89
- <meta name="viewport" content="width=device-width, initial-scale=1">
90
- <title>${heading} ${escapeHtmlText(options.site.name)}</title>
91
- <meta name="robots" content="noindex, follow" />
92
- ${options.styles === null ? '' : `<link rel="stylesheet" href="${STYLESHEET_PATH}">`}
93
- </head>
94
- <body>
95
- <main class="cg-main" id="cg-main">
85
+ // The real site chrome (`renderPageChrome`, `theme-render.ts`) — the same
86
+ // skip link, header and footer every collection page renders, not a
87
+ // second, thinner `<html>` shell of this file's own (L20 audit, points
88
+ // 8-9): the stylesheet was always linked here, but the markup its
89
+ // selectors (`.cg-site-header`, the skip link, …) target was never on the
90
+ // page, which is what made it look unstyled.
91
+ return renderPageChrome({
92
+ site: options.site,
93
+ locale: options.site.defaultLocale,
94
+ styles: options.styles,
95
+ headHtml: `<title>${heading} — ${escapeHtmlText(options.site.name)}</title>
96
+ <meta name="robots" content="noindex, follow" />`,
97
+ bodyHtml: `<main class="cg-main" id="cg-main">
96
98
  <h1 class="cg-page__title">${heading}</h1>
97
99
  ${searchForm(trimmed)}
98
100
  ${main}
99
- </main>
100
- </body>
101
- </html>
102
- `;
101
+ </main>`,
102
+ ...(options.menus === undefined ? {} : { menus: options.menus }),
103
+ ...(options.branding === undefined ? {} : { branding: options.branding }),
104
+ ...(options.activeTheme === undefined ? {} : { activeTheme: options.activeTheme }),
105
+ ...(options.seo === undefined ? {} : { seo: options.seo }),
106
+ ...(options.identity === undefined ? {} : { identity: options.identity }),
107
+ ...(options.loadMedia === undefined ? {} : { loadMedia: options.loadMedia }),
108
+ }, context);
103
109
  }
104
110
  //# sourceMappingURL=search-page.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-page.js","sourceRoot":"","sources":["../../src/commands/search-page.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-page.js","sourceRoot":"","sources":["../../src/commands/search-page.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { type AccessContext, type ContentGateway } from '@cogenta/api';
2
- import type { CollectionDefinition, ContentEntry } from '@cogenta/schema';
3
- import { type HreflangAlternate, type SeoImage, type SeoResource, type SeoSite, type SitemapFile } from '@cogenta/seo';
2
+ import { type CollectionDefinition, type ContentEntry, type SiteSettingsStore } from '@cogenta/schema';
3
+ import { type HreflangAlternate, type SeoImage, type SeoResource, type SeoSite, type SitemapCollectionOverride, type SitemapFile, type SitemapUrl } from '@cogenta/seo';
4
4
  /**
5
5
  * `@cogenta/seo`, actually wired to the server (L10, tasks 1-2).
6
6
  *
@@ -18,6 +18,41 @@ export interface SiteIdentity {
18
18
  readonly locales: readonly string[];
19
19
  readonly defaultLocale: string;
20
20
  }
21
+ /**
22
+ * The live-editable half of `@cogenta/seo`'s output (fiche 21 task 3): what
23
+ * an admin set on the merged SEO screen's Général/Sitemap/Réseaux sociaux
24
+ * tabs, read straight from `@cogenta/schema`'s `seo.*` site settings — never
25
+ * cached at server startup, the same "read fresh on every request" contract
26
+ * `ThemeRenderOptions.homePath` already uses. Every field is the empty/absent
27
+ * state when nobody has set anything, so a site that never opens this screen
28
+ * renders exactly as it did before this fiche.
29
+ */
30
+ export interface SeoRenderDefaults {
31
+ readonly titleTemplate: string;
32
+ readonly collectionTitleTemplates: Readonly<Record<string, string>>;
33
+ readonly defaultMetaDescription: string;
34
+ readonly twitterHandle: string;
35
+ readonly defaultSocialImageUrl: string;
36
+ readonly sitemapCollectionSettings: Readonly<Record<string, SitemapCollectionOverride>>;
37
+ /**
38
+ * Fiche 50 task 2 — rendered into `<meta name="google-site-verification">`
39
+ * by `siteVerificationMetaTags` below. Empty means the tag is omitted
40
+ * entirely. Already forced to `''` by `readSeoRenderDefaults` when the
41
+ * fiche 70 task 3 gate (`seo.searchVerificationEnabled`) is off — every
42
+ * consumer of this field sees the gated value, never the raw setting, so
43
+ * there is exactly one place this decision is made.
44
+ */
45
+ readonly googleSiteVerification: string;
46
+ /** Same shape, rendered into `<meta name="msvalidate.01">` — Bing Webmaster Tools' own meta-tag verification. Same gating as `googleSiteVerification`. */
47
+ readonly bingSiteVerification: string;
48
+ /**
49
+ * Fiche 50 task 4 — an admin's own robots.txt lines, merged in by
50
+ * `renderRobots` below. Already forced to `''` by `readSeoRenderDefaults`
51
+ * when `seo.robotsCustomRulesEnabled` (fiche 70 task 3) is off — the saved
52
+ * text is never lost, only its effect on the served document.
53
+ */
54
+ readonly robotsCustomRules: string;
55
+ }
21
56
  /**
22
57
  * The site as the SEO layer sees it.
23
58
  *
@@ -26,8 +61,45 @@ export interface SiteIdentity {
26
61
  * and `matchPath` then resolves `/blog/hello` as well as `/en/blog/hello`.
27
62
  * Saying otherwise would emit canonicals that redirect to themselves — the
28
63
  * exact failure `SeoSite`'s own doc comment warns about.
64
+ *
65
+ * `seo` is optional and, when present, only ever *adds* to what the bare
66
+ * `SiteIdentity` already says: an empty `defaultMetaDescription`/
67
+ * `twitterHandle` is left out entirely rather than passed as `''`, so a page
68
+ * that supplies its own description or the Twitter Card's absence is never
69
+ * overridden by a setting nobody actually set.
70
+ */
71
+ export declare function seoSiteFor(site: SiteIdentity, seo?: SeoRenderDefaults | null): SeoSite;
72
+ /**
73
+ * `<meta>` tags proving domain ownership to Google Search Console and Bing
74
+ * Webmaster Tools (fiche 50 task 2) — the meta-tag verification method both
75
+ * offer as an alternative to DNS/file verification, deliberately the only
76
+ * one this codebase implements: no OAuth flow, no Search Console/Webmaster
77
+ * API call, no second secret to hold (R1/R7). An admin pastes the token the
78
+ * provider's own verification page already shows them; this only renders
79
+ * it, HTML-escaped like every other attribute value `@cogenta/seo` emits.
80
+ */
81
+ export declare function siteVerificationMetaTags(seo: SeoRenderDefaults | null | undefined): string;
82
+ /**
83
+ * The live `seo.*` site settings (fiche 21 task 3), read fresh — never
84
+ * cached at server startup, the same contract `ThemeRenderOptions.homePath`
85
+ * already keeps for `reading.homePath`. A key nobody has ever written comes
86
+ * back as its registry default (an empty string, or `{}`), the same as the
87
+ * settings store itself does for any other group.
88
+ */
89
+ export declare function readSeoRenderDefaults(store: SiteSettingsStore): Promise<SeoRenderDefaults>;
90
+ /**
91
+ * The three off-by-default indexing extras (fiche 50 tasks 3 and 5) —
92
+ * separate from `SeoRenderDefaults` above because none of the three feeds a
93
+ * page's `<head>`: IndexNow is pinged from the content-write path, and
94
+ * `llms.txt` is a route toggle, not a per-page render decision.
29
95
  */
30
- export declare function seoSiteFor(site: SiteIdentity): SeoSite;
96
+ export interface SeoOperationalSettings {
97
+ readonly indexNowEnabled: boolean;
98
+ readonly indexNowKey: string;
99
+ readonly llmsTxtEnabled: boolean;
100
+ }
101
+ /** Read fresh, same "no restart" contract as `readSeoRenderDefaults`. */
102
+ export declare function readSeoOperationalSettings(store: SiteSettingsStore): Promise<SeoOperationalSettings>;
31
103
  /**
32
104
  * Every published entry of every routed collection, as SEO resources.
33
105
  *
@@ -59,6 +131,8 @@ export interface HeadOptions {
59
131
  readonly noindex?: boolean;
60
132
  /** Overrides the derived title. Used for pages that are not one entry. */
61
133
  readonly title?: string;
134
+ /** The admin-editable title templates and default social image (fiche 21 task 3). Absent behaves exactly as before that fiche. */
135
+ readonly seo?: SeoRenderDefaults | null;
62
136
  }
63
137
  /**
64
138
  * The whole `<head>` an entry earns: title, description, canonical,
@@ -79,10 +153,24 @@ export declare function renderSeoHead(site: SeoSite, resource: SeoResource, opti
79
153
  * `/sitemap-N.xml` from the same array, so a site that grows past 50 000 URLs
80
154
  * starts serving an index without anybody changing a route.
81
155
  */
82
- export declare function buildSitemapFiles(site: SeoSite, resources: readonly SeoResource[]): readonly SitemapFile[];
156
+ export declare function buildSitemapFiles(site: SeoSite, resources: readonly SeoResource[], collectionOverrides?: Readonly<Record<string, SitemapCollectionOverride>>,
157
+ /**
158
+ * URLs a crawler should know about that are not entries — today, the
159
+ * taxonomy term archives (audit 2026-09-01, 04-taxonomies-menus.md T01).
160
+ *
161
+ * A separate parameter rather than a synthetic `SeoResource`, because a
162
+ * term genuinely is not one: it has no `status`, no `publishedAt` and no
163
+ * translation family, and faking those three to get it through
164
+ * `indexableResources` would put a lie in the middle of the SEO pipeline
165
+ * so that a URL could come out the other end. These arrive already
166
+ * decided-upon and are appended verbatim.
167
+ */
168
+ extraUrls?: readonly SitemapUrl[]): readonly SitemapFile[];
83
169
  export interface RobotsRenderOptions {
84
170
  /** False on a staging or preview host: blocks every crawler outright. */
85
171
  readonly allowIndexing?: boolean;
172
+ /** An admin's own robots.txt lines (fiche 50 task 4), merged in by `renderRobotsTxt`. */
173
+ readonly customRules?: string;
86
174
  }
87
175
  export declare function renderRobots(site: SeoSite, options?: RobotsRenderOptions): string;
88
176
  //# sourceMappingURL=seo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/commands/seo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAa,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAEjF,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EAML,KAAK,iBAAiB,EAItB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,WAAW,EAEjB,MAAM,cAAc,CAAA;AAErB;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAQtD;AAQD;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,SAAS,oBAAoB,EAAE,EAC5C,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAuCjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,oBAAoB,EAChC,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CA0BvC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAA;IAClD,wFAAwF;IACxF,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,QAAQ,GAAG,IAAI,CAAA;IAChD,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,WAAgB,GACxB,MAAM,CAkBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,SAAS,WAAW,EAAE,GAChC,SAAS,WAAW,EAAE,CAExB;AAED,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CACjC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAUrF"}
1
+ {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/commands/seo.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { ANONYMOUS } from '@cogenta/api';
2
2
  import { isCogentaError } from '@cogenta/core';
3
- import { alternatesFor, buildJsonLd, buildMetaTags, buildSitemap, groupTranslationFamilies, renderJsonLdScript, renderMetaTags, renderRobotsTxt, sitemapUrlsFor, } from '@cogenta/seo';
3
+ import { SITE_SETTINGS_SITE_SCOPE, } from '@cogenta/schema';
4
+ import { absoluteUrl, alternatesFor, buildJsonLd, buildMetaTags, buildSitemap, escapeHtmlAttribute, groupTranslationFamilies, renderJsonLdScript, renderMetaTags, renderRobotsTxt, sitemapUrlsFor, } from '@cogenta/seo';
4
5
  /**
5
6
  * The site as the SEO layer sees it.
6
7
  *
@@ -9,14 +10,154 @@ import { alternatesFor, buildJsonLd, buildMetaTags, buildSitemap, groupTranslati
9
10
  * and `matchPath` then resolves `/blog/hello` as well as `/en/blog/hello`.
10
11
  * Saying otherwise would emit canonicals that redirect to themselves — the
11
12
  * exact failure `SeoSite`'s own doc comment warns about.
13
+ *
14
+ * `seo` is optional and, when present, only ever *adds* to what the bare
15
+ * `SiteIdentity` already says: an empty `defaultMetaDescription`/
16
+ * `twitterHandle` is left out entirely rather than passed as `''`, so a page
17
+ * that supplies its own description or the Twitter Card's absence is never
18
+ * overridden by a setting nobody actually set.
12
19
  */
13
- export function seoSiteFor(site) {
20
+ export function seoSiteFor(site, seo) {
14
21
  return {
15
22
  baseUrl: site.url,
16
23
  name: site.name,
17
24
  defaultLocale: site.defaultLocale,
18
25
  locales: site.locales,
19
26
  unprefixedDefaultLocale: true,
27
+ ...(seo?.defaultMetaDescription ? { description: seo.defaultMetaDescription } : {}),
28
+ ...(seo?.twitterHandle ? { twitterSite: seo.twitterHandle } : {}),
29
+ };
30
+ }
31
+ /** `seo.defaultSocialImageUrl`, resolved to an absolute URL a social crawler can fetch without a session. */
32
+ function fallbackImageFor(site, seo) {
33
+ const url = seo?.defaultSocialImageUrl;
34
+ if (url === undefined || url === '')
35
+ return undefined;
36
+ return { url: url.startsWith('http') ? url : absoluteUrl(site, url) };
37
+ }
38
+ const EMPTY_SEO_DEFAULTS = {
39
+ titleTemplate: '',
40
+ collectionTitleTemplates: {},
41
+ defaultMetaDescription: '',
42
+ twitterHandle: '',
43
+ defaultSocialImageUrl: '',
44
+ sitemapCollectionSettings: {},
45
+ googleSiteVerification: '',
46
+ bingSiteVerification: '',
47
+ robotsCustomRules: '',
48
+ };
49
+ /**
50
+ * `<meta>` tags proving domain ownership to Google Search Console and Bing
51
+ * Webmaster Tools (fiche 50 task 2) — the meta-tag verification method both
52
+ * offer as an alternative to DNS/file verification, deliberately the only
53
+ * one this codebase implements: no OAuth flow, no Search Console/Webmaster
54
+ * API call, no second secret to hold (R1/R7). An admin pastes the token the
55
+ * provider's own verification page already shows them; this only renders
56
+ * it, HTML-escaped like every other attribute value `@cogenta/seo` emits.
57
+ */
58
+ export function siteVerificationMetaTags(seo) {
59
+ const tags = [];
60
+ if (seo?.googleSiteVerification) {
61
+ tags.push(`<meta name="google-site-verification" content="${escapeHtmlAttribute(seo.googleSiteVerification)}" />`);
62
+ }
63
+ if (seo?.bingSiteVerification) {
64
+ tags.push(`<meta name="msvalidate.01" content="${escapeHtmlAttribute(seo.bingSiteVerification)}" />`);
65
+ }
66
+ return tags.join('\n');
67
+ }
68
+ function stringSetting(value, fallback) {
69
+ return typeof value === 'string' ? value : fallback;
70
+ }
71
+ function recordSetting(value, fallback) {
72
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
73
+ ? value
74
+ : fallback;
75
+ }
76
+ /**
77
+ * `seo.sitemapCollectionSettings` is stored with `''` sentinels for "no
78
+ * hint" (so an empty text/select input round-trips instead of becoming
79
+ * `NaN`/`undefined`) — `@cogenta/seo`'s own `SitemapCollectionOverride`
80
+ * has no such sentinel, so this is the one place the two shapes meet.
81
+ */
82
+ function toSitemapOverrides(raw) {
83
+ const overrides = {};
84
+ for (const [name, entry] of Object.entries(raw)) {
85
+ overrides[name] = {
86
+ included: entry.included,
87
+ ...(entry.changefreq === '' ? {} : { changefreq: entry.changefreq }),
88
+ ...(entry.priority === '' ? {} : { priority: entry.priority }),
89
+ };
90
+ }
91
+ return overrides;
92
+ }
93
+ /**
94
+ * The live `seo.*` site settings (fiche 21 task 3), read fresh — never
95
+ * cached at server startup, the same contract `ThemeRenderOptions.homePath`
96
+ * already keeps for `reading.homePath`. A key nobody has ever written comes
97
+ * back as its registry default (an empty string, or `{}`), the same as the
98
+ * settings store itself does for any other group.
99
+ */
100
+ export async function readSeoRenderDefaults(store) {
101
+ const [titleTemplate, collectionTitleTemplates, defaultMetaDescription, sitemapCollectionSettings, twitterHandle, defaultSocialImageUrl, googleSiteVerification, bingSiteVerification, robotsCustomRules, searchVerificationEnabled, robotsCustomRulesEnabled,] = await Promise.all([
102
+ store.get('seo.titleTemplate', SITE_SETTINGS_SITE_SCOPE),
103
+ store.get('seo.collectionTitleTemplates', SITE_SETTINGS_SITE_SCOPE),
104
+ store.get('seo.defaultMetaDescription', SITE_SETTINGS_SITE_SCOPE),
105
+ store.get('seo.sitemapCollectionSettings', SITE_SETTINGS_SITE_SCOPE),
106
+ store.get('seo.twitterHandle', SITE_SETTINGS_SITE_SCOPE),
107
+ store.get('seo.defaultSocialImageUrl', SITE_SETTINGS_SITE_SCOPE),
108
+ store.get('seo.googleSiteVerification', SITE_SETTINGS_SITE_SCOPE),
109
+ store.get('seo.bingSiteVerification', SITE_SETTINGS_SITE_SCOPE),
110
+ store.get('seo.robotsCustomRules', SITE_SETTINGS_SITE_SCOPE),
111
+ // Fiche 70 task 3's own two gates. Read here, applied below, so every
112
+ // consumer of `SeoRenderDefaults` — `theme-render.ts`, `serve.ts`'s
113
+ // `/robots.txt` route, `SeoDiagnostics` — sees the gated value without
114
+ // having to know the gate exists (single source of truth, no duplicate
115
+ // check anywhere downstream).
116
+ store.get('seo.searchVerificationEnabled', SITE_SETTINGS_SITE_SCOPE),
117
+ store.get('seo.robotsCustomRulesEnabled', SITE_SETTINGS_SITE_SCOPE),
118
+ ]);
119
+ // Both gates default to `true` (the registry's own default) — an install
120
+ // that has never touched this setting keeps behaving exactly as it did
121
+ // before this fiche.
122
+ const verificationEnabled = searchVerificationEnabled?.value !== false;
123
+ const customRulesEnabled = robotsCustomRulesEnabled?.value !== false;
124
+ return {
125
+ titleTemplate: stringSetting(titleTemplate?.value, EMPTY_SEO_DEFAULTS.titleTemplate),
126
+ collectionTitleTemplates: recordSetting(collectionTitleTemplates?.value, EMPTY_SEO_DEFAULTS.collectionTitleTemplates),
127
+ defaultMetaDescription: stringSetting(defaultMetaDescription?.value, EMPTY_SEO_DEFAULTS.defaultMetaDescription),
128
+ twitterHandle: stringSetting(twitterHandle?.value, EMPTY_SEO_DEFAULTS.twitterHandle),
129
+ defaultSocialImageUrl: stringSetting(defaultSocialImageUrl?.value, EMPTY_SEO_DEFAULTS.defaultSocialImageUrl),
130
+ sitemapCollectionSettings: toSitemapOverrides(recordSetting(sitemapCollectionSettings?.value, {})),
131
+ googleSiteVerification: verificationEnabled
132
+ ? stringSetting(googleSiteVerification?.value, EMPTY_SEO_DEFAULTS.googleSiteVerification)
133
+ : '',
134
+ bingSiteVerification: verificationEnabled
135
+ ? stringSetting(bingSiteVerification?.value, EMPTY_SEO_DEFAULTS.bingSiteVerification)
136
+ : '',
137
+ robotsCustomRules: customRulesEnabled
138
+ ? stringSetting(robotsCustomRules?.value, EMPTY_SEO_DEFAULTS.robotsCustomRules)
139
+ : '',
140
+ };
141
+ }
142
+ const EMPTY_SEO_OPERATIONAL_SETTINGS = {
143
+ indexNowEnabled: false,
144
+ indexNowKey: '',
145
+ llmsTxtEnabled: false,
146
+ };
147
+ function booleanSetting(value, fallback) {
148
+ return typeof value === 'boolean' ? value : fallback;
149
+ }
150
+ /** Read fresh, same "no restart" contract as `readSeoRenderDefaults`. */
151
+ export async function readSeoOperationalSettings(store) {
152
+ const [indexNowEnabled, indexNowKey, llmsTxtEnabled] = await Promise.all([
153
+ store.get('seo.indexNowEnabled', SITE_SETTINGS_SITE_SCOPE),
154
+ store.get('seo.indexNowKey', SITE_SETTINGS_SITE_SCOPE),
155
+ store.get('seo.llmsTxtEnabled', SITE_SETTINGS_SITE_SCOPE),
156
+ ]);
157
+ return {
158
+ indexNowEnabled: booleanSetting(indexNowEnabled?.value, EMPTY_SEO_OPERATIONAL_SETTINGS.indexNowEnabled),
159
+ indexNowKey: stringSetting(indexNowKey?.value, EMPTY_SEO_OPERATIONAL_SETTINGS.indexNowKey),
160
+ llmsTxtEnabled: booleanSetting(llmsTxtEnabled?.value, EMPTY_SEO_OPERATIONAL_SETTINGS.llmsTxtEnabled),
20
161
  };
21
162
  }
22
163
  /** How many entries one collection contributes to a sitemap before it is cut off. */
@@ -114,11 +255,18 @@ export async function alternatesForEntry(site, collection, entry, gateway, conte
114
255
  * this file.
115
256
  */
116
257
  export function renderSeoHead(site, resource, options = {}) {
258
+ const fallbackImage = fallbackImageFor(site, options.seo);
259
+ const collectionTitleTemplates = options.seo?.collectionTitleTemplates;
117
260
  const tags = buildMetaTags(site, resource, {
118
261
  ...(options.alternates === undefined ? {} : { alternates: options.alternates }),
119
262
  ...(options.media === undefined ? {} : { resolvers: { media: options.media } }),
120
263
  ...(options.noindex === undefined ? {} : { noindex: options.noindex }),
121
264
  ...(options.title === undefined ? {} : { title: options.title }),
265
+ ...(options.seo?.titleTemplate ? { titleTemplate: options.seo.titleTemplate } : {}),
266
+ ...(collectionTitleTemplates !== undefined && Object.keys(collectionTitleTemplates).length > 0
267
+ ? { collectionTitleTemplates }
268
+ : {}),
269
+ ...(fallbackImage === undefined ? {} : { fallbackImage }),
122
270
  });
123
271
  const parts = [renderMetaTags(tags)];
124
272
  const graph = buildJsonLd(site, resource, {
@@ -138,8 +286,23 @@ export function renderSeoHead(site, resource, options = {}) {
138
286
  * `/sitemap-N.xml` from the same array, so a site that grows past 50 000 URLs
139
287
  * starts serving an index without anybody changing a route.
140
288
  */
141
- export function buildSitemapFiles(site, resources) {
142
- return buildSitemap(site, sitemapUrlsFor(site, resources));
289
+ export function buildSitemapFiles(site, resources, collectionOverrides,
290
+ /**
291
+ * URLs a crawler should know about that are not entries — today, the
292
+ * taxonomy term archives (audit 2026-09-01, 04-taxonomies-menus.md T01).
293
+ *
294
+ * A separate parameter rather than a synthetic `SeoResource`, because a
295
+ * term genuinely is not one: it has no `status`, no `publishedAt` and no
296
+ * translation family, and faking those three to get it through
297
+ * `indexableResources` would put a lie in the middle of the SEO pipeline
298
+ * so that a URL could come out the other end. These arrive already
299
+ * decided-upon and are appended verbatim.
300
+ */
301
+ extraUrls) {
302
+ return buildSitemap(site, [
303
+ ...sitemapUrlsFor(site, resources, collectionOverrides === undefined ? {} : { collectionOverrides }),
304
+ ...(extraUrls ?? []),
305
+ ]);
143
306
  }
144
307
  export function renderRobots(site, options = {}) {
145
308
  return renderRobotsTxt({
@@ -150,6 +313,7 @@ export function renderRobots(site, options = {}) {
150
313
  // spend requests discovering that.
151
314
  groups: [{ userAgent: '*', allow: ['/'], disallow: ['/admin', '/api/'] }],
152
315
  ...(options.allowIndexing === undefined ? {} : { allowIndexing: options.allowIndexing }),
316
+ ...(options.customRules === undefined ? {} : { customRules: options.customRules }),
153
317
  });
154
318
  }
155
319
  //# sourceMappingURL=seo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"seo.js","sourceRoot":"","sources":["../../src/commands/seo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seo.js","sourceRoot":"","sources":["../../src/commands/seo.ts"],"names":[],"mappings":"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"}