@publish.os/nextjs 0.0.1-alpha.90 → 0.0.1-alpha.91

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 (223) hide show
  1. package/compiler-assets/nextjs/defaults/group/layout.tsx +1 -5
  2. package/compiler-assets/nextjs/defaults/group/page.tsx +31 -22
  3. package/compiler-assets/nextjs/defaults/project/next.config.mjs +19 -10
  4. package/compiler-assets/nextjs/defaults/project/tsconfig.json.template +10 -0
  5. package/compiler-assets/nextjs/defaults/root/css/components/code-block.css +18 -0
  6. package/compiler-assets/nextjs/shims/document.tsx +38 -0
  7. package/compiler-assets/nextjs/shims/generated-leaf-page.tsx +2 -0
  8. package/compiler-assets/nextjs/shims/global-layout.tsx +8 -42
  9. package/compiler-assets/nextjs/shims/global-not-found.tsx +69 -0
  10. package/compiler-assets/nextjs/shims/markdown-route.ts +2 -0
  11. package/compiler-assets/nextjs/shims/metadata-icons.tsx +39 -0
  12. package/compiler-assets/nextjs/shims/not-found-content.tsx +53 -0
  13. package/compiler-assets/nextjs/shims/not-found-navigation.tsx +60 -0
  14. package/compiler-assets/nextjs/shims/proxy.ts +126 -60
  15. package/compiler-assets/nextjs/shims/site-fenced-code-block.tsx +2 -6
  16. package/compiler-assets/nextjs/shims/site-mdx-components.tsx +28 -16
  17. package/compiler-assets/nextjs/shims/site-mdx.tsx +6 -1
  18. package/dist/{build-operation-2JAYBSKF.js → build-operation-5QMLXF7N.js} +29 -23
  19. package/dist/{button-c3WGnxIj.d.ts → button-BdCScEKi.d.ts} +3 -3
  20. package/dist/capture-local-source-WGGDIUU2.js +258 -0
  21. package/dist/chunk-22RSSUNV.js +13 -0
  22. package/dist/{chunk-WKTEO6RS.js → chunk-4BC2L2KA.js} +46 -12
  23. package/dist/{chunk-WDY4IK6Z.js → chunk-5J3YUNRY.js} +3 -10
  24. package/dist/chunk-5KAD7W53.js +248 -0
  25. package/dist/{chunk-DWA3ZRGW.js → chunk-6C65KV7O.js} +2 -2
  26. package/dist/{chunk-GGKFQ3MA.js → chunk-6D2E6UMD.js} +144 -70
  27. package/dist/{chunk-7OGTPSKI.js → chunk-7NY22B5U.js} +8 -3
  28. package/dist/chunk-EFO6AWXN.js +19 -0
  29. package/dist/{chunk-726GV2NF.js → chunk-F3AGNDF4.js} +100 -67
  30. package/dist/chunk-GBPLER5H.js +426 -0
  31. package/dist/chunk-IL4RJOKI.js +186 -0
  32. package/dist/{chunk-DLDFHU7Y.js → chunk-NNBJZPFM.js} +4 -2
  33. package/dist/{chunk-VO2I7MTM.js → chunk-ORIUWJBQ.js} +8 -6
  34. package/dist/{chunk-H6XILMZX.js → chunk-OXOFRXEI.js} +1806 -831
  35. package/dist/chunk-UYGCOWRF.js +1709 -0
  36. package/dist/{chunk-YLTOLYWM.js → chunk-WL75GQ5M.js} +6 -18
  37. package/dist/compiler.d.ts +15 -2
  38. package/dist/compiler.js +90 -21
  39. package/dist/components/blocks/agent-actions.d.ts +81 -0
  40. package/dist/components/blocks/agent-actions.js +594 -0
  41. package/dist/components/blocks/toc.d.ts +43 -0
  42. package/dist/components/blocks/toc.js +136 -0
  43. package/dist/components/ui/button.d.ts +5 -0
  44. package/dist/components/ui/button.js +94 -0
  45. package/dist/compose-CVBJRAF6.js +16 -0
  46. package/dist/config/createNextConfig.js +17 -3
  47. package/dist/{dev-operation-TZDVJCN7.js → dev-operation-OSHHWRWK.js} +121 -81
  48. package/dist/{framework-selection-X4U6Y6QC.js → framework-selection-ZVO323PK.js} +3 -2
  49. package/dist/ide-support-CU6Z5PVR.js +16 -0
  50. package/dist/index.d.ts +40 -1
  51. package/dist/jsx-dev-runtime.d.ts +6 -0
  52. package/dist/jsx-dev-runtime.js +100 -0
  53. package/dist/jsx-runtime.d.ts +7 -0
  54. package/dist/jsx-runtime.js +97 -0
  55. package/dist/kernel/components/blocks/AgentActions.d.ts +35 -6
  56. package/dist/kernel/components/blocks/AgentActions.js +383 -142
  57. package/dist/kernel/components/blocks/agent-actions.d.ts +5 -0
  58. package/dist/kernel/components/blocks/agent-actions.js +594 -0
  59. package/dist/kernel/components/blocks/animated-icon-swap.js +1 -1
  60. package/dist/kernel/components/blocks/color-palette.js +4 -4
  61. package/dist/kernel/components/blocks/logo-block.js +1 -1
  62. package/dist/kernel/components/blocks/nav-breadcrumb.js +2 -2
  63. package/dist/kernel/components/blocks/navbar.js +17 -17
  64. package/dist/kernel/components/blocks/navigation-progress.js +2 -2
  65. package/dist/kernel/components/blocks/next-prev.js +1 -1
  66. package/dist/kernel/components/blocks/page-list.js +2 -2
  67. package/dist/kernel/components/blocks/search.d.ts +1 -1
  68. package/dist/kernel/components/blocks/search.js +16 -17
  69. package/dist/kernel/components/blocks/sidebar-node.js +1 -1
  70. package/dist/kernel/components/blocks/sidebar.js +7 -4
  71. package/dist/kernel/components/blocks/theme-toggle.d.ts +1 -1
  72. package/dist/kernel/components/blocks/theme-toggle.js +5 -5
  73. package/dist/kernel/components/blocks/toc-client.d.ts +40 -0
  74. package/dist/kernel/components/blocks/toc-client.js +495 -0
  75. package/dist/kernel/components/blocks/toc.d.ts +19 -1
  76. package/dist/kernel/components/blocks/toc.js +121 -179
  77. package/dist/kernel/components/mdx/components/blockquote.js +1 -1
  78. package/dist/kernel/components/mdx/components/callout.js +1 -1
  79. package/dist/kernel/components/mdx/components/code-block.js +2 -2
  80. package/dist/kernel/components/mdx/components/copy-code-button.js +5 -4
  81. package/dist/kernel/components/mdx/components/figure-caption.d.ts +1 -1
  82. package/dist/kernel/components/mdx/components/figure-caption.js +3 -2
  83. package/dist/kernel/components/mdx/components/figure.d.ts +6 -2
  84. package/dist/kernel/components/mdx/components/figure.js +23 -13
  85. package/dist/kernel/components/mdx/components/footnotes.js +1 -1
  86. package/dist/kernel/components/mdx/components/heading-copy-link.js +1 -1
  87. package/dist/kernel/components/mdx/components/heading.js +6 -3
  88. package/dist/kernel/components/mdx/components/hr.js +2 -2
  89. package/dist/kernel/components/mdx/components/image-zoom.js +1 -1
  90. package/dist/kernel/components/mdx/components/image.d.ts +1 -1
  91. package/dist/kernel/components/mdx/components/image.js +21 -16
  92. package/dist/kernel/components/mdx/components/inline-code.js +1 -1
  93. package/dist/kernel/components/mdx/components/kbd.js +2 -2
  94. package/dist/kernel/components/mdx/components/link.d.ts +3 -3
  95. package/dist/kernel/components/mdx/components/link.js +2 -2
  96. package/dist/kernel/components/mdx/components/paragraph.js +1 -1
  97. package/dist/kernel/components/mdx/components/strikethrough.js +1 -1
  98. package/dist/kernel/components/mdx/components/table.js +2 -2
  99. package/dist/kernel/components/mdx/components/task-list.js +1 -1
  100. package/dist/kernel/components/mdx/components/video-player.d.ts +6 -2
  101. package/dist/kernel/components/mdx/components/video-player.js +6 -2
  102. package/dist/kernel/components/mdx/components/video.d.ts +5 -3
  103. package/dist/kernel/components/mdx/components/video.js +7 -5
  104. package/dist/kernel/components/mdx/error-boundary.d.ts +1 -1
  105. package/dist/kernel/components/mdx/error-boundary.js +2 -2
  106. package/dist/kernel/components/mdx/error-fallback.js +1 -1
  107. package/dist/kernel/components/mdx/mdx.d.ts +20 -10
  108. package/dist/kernel/components/mdx/mdx.js +231 -34
  109. package/dist/kernel/components/mdx/rehype-heading-ids.d.ts +1 -0
  110. package/dist/kernel/components/mdx/rehype-heading-ids.js +5 -3
  111. package/dist/kernel/components/mdx/types.d.ts +1 -1
  112. package/dist/kernel/components/next-image.d.ts +12 -0
  113. package/dist/kernel/components/next-image.js +61 -0
  114. package/dist/kernel/components/ui/accordion.js +1 -1
  115. package/dist/kernel/components/ui/breadcrumb-trail.d.ts +2 -2
  116. package/dist/kernel/components/ui/breadcrumb-trail.js +2 -2
  117. package/dist/kernel/components/ui/breadcrumb.d.ts +1 -1
  118. package/dist/kernel/components/ui/breadcrumb.js +4 -4
  119. package/dist/kernel/components/ui/button-group.d.ts +1 -1
  120. package/dist/kernel/components/ui/button-group.js +3 -3
  121. package/dist/kernel/components/ui/button.d.ts +56 -4
  122. package/dist/kernel/components/ui/button.js +43 -39
  123. package/dist/kernel/components/ui/card.js +1 -1
  124. package/dist/kernel/components/ui/dialog.js +1 -1
  125. package/dist/kernel/components/ui/drawer.js +1 -1
  126. package/dist/kernel/components/ui/input.d.ts +2 -2
  127. package/dist/kernel/components/ui/input.js +1 -1
  128. package/dist/kernel/components/ui/kbd.d.ts +1 -1
  129. package/dist/kernel/components/ui/kbd.js +1 -1
  130. package/dist/kernel/components/ui/link.d.ts +8 -2
  131. package/dist/kernel/components/ui/link.js +2 -2
  132. package/dist/kernel/components/ui/menu.js +1 -1
  133. package/dist/kernel/components/ui/mod-key.js +2 -2
  134. package/dist/kernel/components/ui/navigation-menu.js +1 -1
  135. package/dist/kernel/components/ui/popover.js +1 -1
  136. package/dist/kernel/components/ui/progress.js +1 -1
  137. package/dist/kernel/components/ui/scroll-area.d.ts +8 -8
  138. package/dist/kernel/components/ui/scroll-area.js +1 -1
  139. package/dist/kernel/components/ui/select.js +1 -1
  140. package/dist/kernel/components/ui/separator.js +1 -1
  141. package/dist/kernel/components/ui/table.js +1 -1
  142. package/dist/kernel/components/ui/tabs.js +1 -1
  143. package/dist/kernel/components/ui/tag.js +1 -1
  144. package/dist/kernel/components/ui/text.d.ts +1 -1
  145. package/dist/kernel/components/ui/text.js +1 -1
  146. package/dist/kernel/components/ui/toast.js +1 -1
  147. package/dist/kernel/components/ui/tooltip.js +1 -1
  148. package/dist/kernel/defaults.registry.d.ts +2 -15
  149. package/dist/kernel/defaults.registry.js +2 -17
  150. package/dist/kernel/routes/agent/markdown.d.ts +3 -0
  151. package/dist/kernel/routes/agent/markdown.js +219 -48
  152. package/dist/kernel/routes/layouts/group.d.ts +1 -1
  153. package/dist/kernel/routes/layouts/group.js +5 -7
  154. package/dist/kernel/routes/metadata/feed.d.ts +1 -1
  155. package/dist/kernel/routes/metadata/feed.js +109 -83
  156. package/dist/kernel/routes/metadata/llms.d.ts +11 -3
  157. package/dist/kernel/routes/metadata/llms.js +154 -57
  158. package/dist/kernel/routes/metadata/og-image.js +1 -1
  159. package/dist/kernel/routes/metadata/robots.d.ts +1 -1
  160. package/dist/kernel/routes/metadata/sitemap.d.ts +22 -3
  161. package/dist/kernel/routes/metadata/sitemap.js +183 -43
  162. package/dist/kernel/routes/not-found.d.ts +34 -0
  163. package/dist/kernel/routes/not-found.js +213 -0
  164. package/dist/kernel/routes/pages/group.d.ts +2 -2
  165. package/dist/kernel/routes/pages/group.js +1 -1
  166. package/dist/kernel/routes/pages/leaf.d.ts +30 -3
  167. package/dist/kernel/routes/pages/leaf.js +5 -4
  168. package/dist/kernel/routes/pages/root.d.ts +2 -2
  169. package/dist/kernel/routes/pages/root.js +1 -1
  170. package/dist/keyboard-shortcuts.js +1 -1
  171. package/dist/route-metadata-og-image-BeKKFHg7.d.ts +58 -0
  172. package/dist/search.js +7 -9
  173. package/dist/theme-scope.js +1 -1
  174. package/dist/{types-BzkZty3r.d.ts → types-J2w_puPF.d.ts} +1 -20
  175. package/dist/types-sM2g9nW0.d.ts +12 -0
  176. package/dist/types.d.ts +1 -0
  177. package/dist/utils/heading-ids.js +30 -11
  178. package/dist/utils/toc-selection.d.ts +7 -0
  179. package/dist/utils/toc-selection.js +14 -0
  180. package/dist/validate-local-source-SV44DBQT.js +16 -0
  181. package/dist/validate-publish-os-source-NZJF3TB2.js +14 -0
  182. package/init/seed/minimal/publish.os/assets/blog/hello-world.svg +13 -0
  183. package/init/seed/minimal/publish.os/assets/favicon.dark.svg +13 -0
  184. package/init/seed/minimal/publish.os/assets/favicon.svg +13 -0
  185. package/init/seed/minimal/publish.os/blog/content/hello-world.mdx +48 -0
  186. package/init/seed/minimal/publish.os/blog/content/series-a.mdx +11 -0
  187. package/init/seed/minimal/publish.os/blog/index.tsx +82 -0
  188. package/init/seed/minimal/publish.os/blog/layout.tsx +13 -0
  189. package/init/seed/minimal/publish.os/blog/page.tsx +76 -0
  190. package/init/seed/minimal/publish.os/components/blog/copy-link.tsx +64 -0
  191. package/init/seed/minimal/publish.os/docs/content/get-started.mdx +2 -3
  192. package/init/seed/minimal/publish.os/docs/content/groups.mdx +5 -6
  193. package/init/seed/minimal/publish.os/publish.os.config.json +6 -2
  194. package/init/seed/minimal/publish.os/theme.css +3 -3
  195. package/init/seed/minimal/seed.json +11 -4
  196. package/init/seed/scratch/publish.os/docs/content/get-started.mdx +1 -1
  197. package/init/seed/scratch/publish.os/publish.os.config.json +1 -1
  198. package/package.json +45 -20
  199. package/release/app/phosphor/package.json +3 -3
  200. package/release/app/phosphor/pnpm-lock.yaml.template +88 -75
  201. package/release/compiler/package.json +5 -3
  202. package/release/compiler/pnpm-lock.yaml.template +118 -74
  203. package/release/release.json +6 -6
  204. package/dist/button-CtzUJB8u.d.ts +0 -11
  205. package/dist/chunk-535TM4A5.js +0 -1455
  206. package/dist/chunk-B2V22WRT.js +0 -297
  207. package/dist/chunk-NECL5IBJ.js +0 -318
  208. package/dist/chunk-SVYGXXYR.js +0 -36
  209. package/dist/chunk-UF6ATARM.js +0 -1100
  210. package/dist/compose-NN23UJGC.js +0 -13
  211. package/dist/ide-support-ZNW7ODFY.js +0 -15
  212. package/dist/kernel/components/blocks/design-system-preview.d.ts +0 -61
  213. package/dist/kernel/components/blocks/design-system-preview.js +0 -667
  214. package/dist/kernel/components/blocks/link-playground.d.ts +0 -5
  215. package/dist/kernel/components/blocks/link-playground.js +0 -744
  216. package/dist/kernel/components/blocks/navigation-progress-playground.d.ts +0 -5
  217. package/dist/kernel/components/blocks/navigation-progress-playground.js +0 -629
  218. package/dist/kernel/components/ui/theme-toggle.d.ts +0 -24
  219. package/dist/kernel/components/ui/theme-toggle.js +0 -53
  220. package/dist/validate-local-source-XRL2Y7XE.js +0 -14
  221. package/dist/validate-publish-os-source-DAPZ4QGE.js +0 -12
  222. package/init/seed/minimal/publish.os/assets/favicon/favicon.dark.png +0 -0
  223. package/init/seed/minimal/publish.os/assets/favicon/favicon.png +0 -0
@@ -1,3 +1,7 @@
1
+ import {
2
+ createNotFoundTextResponse,
3
+ resolveNotFoundScope,
4
+ } from "@publish.os/nextjs/kernel/routes/not-found";
1
5
  import { agentRouteConfig } from "@source/.publishos/agent-route-config.generated";
2
6
  import type { NextRequest } from "next/server";
3
7
  import { NextResponse } from "next/server";
@@ -6,9 +10,11 @@ const AGENT_USER_AGENT_PATTERN =
6
10
  /\b(?:axios|got|node-fetch|undici|curl|wget|python-requests|httpx|aiohttp|claude-code|claudebot|claude|cursor|chatgpt|openai|perplexity|anthropic-ai)\b/i;
7
11
  const INTERNAL_MARKDOWN_PREFIX = "/__publishos/md";
8
12
  const FRAMEWORK_PREFIX = "__PUBLISHOS_FRAMEWORK_PREFIX__";
9
- const PUBLIC_FILE_PATTERN = /\.[a-z0-9]{1,12}$/i;
10
13
  const TEXT_METHODS = new Set(["GET", "HEAD"]);
11
14
  const PUBLIC_PATHS = new Set<string>(agentRouteConfig.publicPaths);
15
+ const MARKDOWN_PATHS = new Set<string>(agentRouteConfig.markdownPaths);
16
+ const OUTPUT_PATHS = new Set<string>(agentRouteConfig.outputPaths);
17
+ const NOT_FOUND_SCOPE_HEADER = "x-publishos-not-found-scope";
12
18
 
13
19
  function debugAgentRoute(
14
20
  event: string,
@@ -48,29 +54,6 @@ function markdownAlternatePath(pathname: string): string {
48
54
  return normalized.endsWith(".md") ? normalized : `${normalized}.md`;
49
55
  }
50
56
 
51
- function markdownNotFoundBody(): string {
52
- const links = [
53
- agentRouteConfig.discoveryLinks.home
54
- ? `> Home: ${agentRouteConfig.discoveryLinks.home}`
55
- : undefined,
56
- agentRouteConfig.discoveryLinks.sitemap
57
- ? `> Sitemap: ${agentRouteConfig.discoveryLinks.sitemap}`
58
- : undefined,
59
- agentRouteConfig.discoveryLinks.llms
60
- ? `> LLMS index: ${agentRouteConfig.discoveryLinks.llms}`
61
- : undefined,
62
- ].filter((line): line is string => Boolean(line));
63
-
64
- return [
65
- "# Not found",
66
- "",
67
- ...links,
68
- "",
69
- "The requested Markdown page was not found.",
70
- "",
71
- ].join("\n");
72
- }
73
-
74
57
  function explicitAcceptQuality(accept: string, mimeType: string): number {
75
58
  if (!accept) return 0;
76
59
 
@@ -102,8 +85,10 @@ function explicitAcceptQuality(accept: string, mimeType: string): number {
102
85
  return bestQuality;
103
86
  }
104
87
 
105
- function wantsMarkdown(request: NextRequest): boolean {
106
- if (!TEXT_METHODS.has(request.method)) return false;
88
+ function negotiatedTextType(
89
+ request: NextRequest,
90
+ ): "text/markdown; charset=utf-8" | "text/plain; charset=utf-8" | undefined {
91
+ if (!TEXT_METHODS.has(request.method)) return undefined;
107
92
 
108
93
  const accept = request.headers.get("accept") ?? "";
109
94
  const markdownQuality = agentRouteConfig.markdownAccept
@@ -114,12 +99,13 @@ function wantsMarkdown(request: NextRequest): boolean {
114
99
  : 0;
115
100
  const htmlQuality = explicitAcceptQuality(accept, "text/html");
116
101
 
117
- if (markdownQuality > 0 && markdownQuality >= htmlQuality) return true;
102
+ if (markdownQuality > 0 && markdownQuality >= htmlQuality) {
103
+ return "text/markdown; charset=utf-8";
104
+ }
118
105
  if (plainQuality > 0 && htmlQuality === 0 && markdownQuality === 0) {
119
- return true;
106
+ return "text/plain; charset=utf-8";
120
107
  }
121
-
122
- return false;
108
+ return undefined;
123
109
  }
124
110
 
125
111
  function looksLikeAgent(request: NextRequest): boolean {
@@ -141,7 +127,7 @@ function markdownRequestReason(
141
127
  ) {
142
128
  return "extension";
143
129
  }
144
- if (wantsMarkdown(request)) return "accept";
130
+ if (negotiatedTextType(request)) return "accept";
145
131
  if (looksLikeAgent(request)) return "agent";
146
132
  return undefined;
147
133
  }
@@ -154,6 +140,7 @@ function isInternalMarkdownRoute(pathname: string): boolean {
154
140
  }
155
141
 
156
142
  function isStaticOrMetadataRoute(pathname: string): boolean {
143
+ if (OUTPUT_PATHS.has(normalizePagePath(pathname))) return true;
157
144
  if (
158
145
  pathname === FRAMEWORK_PREFIX ||
159
146
  pathname.startsWith(`${FRAMEWORK_PREFIX}/`) ||
@@ -175,21 +162,29 @@ function isStaticOrMetadataRoute(pathname: string): boolean {
175
162
  return true;
176
163
  }
177
164
 
178
- return PUBLIC_FILE_PATTERN.test(pathname) && !pathname.endsWith(".md");
165
+ return false;
179
166
  }
180
167
 
181
- function rewriteToMarkdown(
182
- request: NextRequest,
183
- reason: "accept" | "agent" | "extension",
184
- ): NextResponse {
185
- const url = request.nextUrl.clone();
168
+ function rewriteToMarkdown({
169
+ request,
170
+ reason,
171
+ requestHeaders,
172
+ }: {
173
+ request: NextRequest;
174
+ reason: "accept" | "agent" | "extension";
175
+ requestHeaders: Headers;
176
+ }): NextResponse {
177
+ const url = new URL(request.url);
186
178
  url.pathname =
187
179
  normalizePagePath(url.pathname) === "/"
188
180
  ? "/sitemap.md"
189
181
  : markdownRoutePath(url.pathname);
182
+ const revision = request.nextUrl.searchParams.get("publishos_revision");
183
+ url.search = "";
184
+ url.hash = "";
185
+ if (revision) url.searchParams.set("publishos_revision", revision);
190
186
 
191
- const requestHeaders = new Headers(request.headers);
192
- requestHeaders.set("x-publishos-agent-route", "markdown");
187
+ requestHeaders.set("accept", "text/markdown");
193
188
 
194
189
  debugAgentRoute("md", {
195
190
  accept: request.headers.get("accept") ?? undefined,
@@ -241,20 +236,28 @@ function withDiscoveryHeaders(
241
236
 
242
237
  export function proxy(request: NextRequest) {
243
238
  const { pathname } = request.nextUrl;
239
+ const requestHeaders = new Headers(request.headers);
240
+ requestHeaders.delete(NOT_FOUND_SCOPE_HEADER);
241
+ requestHeaders.delete("x-publishos-agent-route");
244
242
 
245
- if (pathname === "/_not-found") return NextResponse.next();
243
+ if (pathname === "/_not-found") {
244
+ requestHeaders.set(NOT_FOUND_SCOPE_HEADER, "none");
245
+ const response = NextResponse.next({
246
+ request: { headers: requestHeaders },
247
+ });
248
+ response.headers.set("x-robots-tag", "noindex");
249
+ response.headers.set("vary", "Accept, User-Agent");
250
+ return response;
251
+ }
246
252
 
247
253
  if (isInternalMarkdownRoute(pathname)) {
248
- if (request.headers.get("x-publishos-agent-route") === "markdown") {
249
- return NextResponse.next();
250
- }
251
254
  if (!agentRouteConfig.blockInternalMarkdownRoute) {
252
255
  debugAgentRoute("pass", {
253
256
  method: request.method,
254
257
  path: pathname,
255
258
  reason: "allowed-internal",
256
259
  });
257
- return NextResponse.next();
260
+ return NextResponse.next({ request: { headers: requestHeaders } });
258
261
  }
259
262
 
260
263
  debugAgentRoute("md", {
@@ -264,15 +267,7 @@ export function proxy(request: NextRequest) {
264
267
  status: 404,
265
268
  });
266
269
 
267
- return new Response(markdownNotFoundBody(), {
268
- status: 404,
269
- headers: {
270
- "cache-control": "public, max-age=60, s-maxage=300",
271
- "content-type": "text/markdown; charset=utf-8",
272
- "x-content-type-options": "nosniff",
273
- "x-robots-tag": "noindex",
274
- },
275
- });
270
+ return createNotFoundTextResponse({ method: request.method });
276
271
  }
277
272
 
278
273
  if (isStaticOrMetadataRoute(pathname)) {
@@ -281,12 +276,53 @@ export function proxy(request: NextRequest) {
281
276
  path: pathname,
282
277
  reason: "static-or-metadata",
283
278
  });
284
- return NextResponse.next();
279
+ return NextResponse.next({ request: { headers: requestHeaders } });
285
280
  }
286
281
 
287
282
  const markdownReason = markdownRequestReason(request);
288
283
  if (markdownReason) {
289
- return rewriteToMarkdown(request, markdownReason);
284
+ let htmlPath: string | undefined;
285
+ try {
286
+ const decoded = normalizePagePath(decodeURIComponent(pathname));
287
+ htmlPath = decoded.endsWith(".md")
288
+ ? decoded.slice(0, -3) || "/"
289
+ : decoded;
290
+ } catch {
291
+ htmlPath = undefined;
292
+ }
293
+ const scope = resolveNotFoundScope({
294
+ scopes: agentRouteConfig.notFoundScopes,
295
+ pathname,
296
+ });
297
+ const hasArtifact =
298
+ htmlPath === "/"
299
+ ? OUTPUT_PATHS.has("/sitemap.md")
300
+ : htmlPath !== undefined && MARKDOWN_PATHS.has(htmlPath);
301
+ if (!scope || !hasArtifact) {
302
+ const response = createNotFoundTextResponse({
303
+ scope,
304
+ pathname,
305
+ method: request.method,
306
+ contentType:
307
+ markdownReason === "accept" ? negotiatedTextType(request) : undefined,
308
+ vary: markdownReason !== "extension",
309
+ });
310
+ if (!agentRouteConfig.enabled || !agentRouteConfig.discoveryHeaders) {
311
+ for (const name of [
312
+ "link",
313
+ "x-publishos-llms",
314
+ "x-publishos-sitemap",
315
+ ]) {
316
+ response.headers.delete(name);
317
+ }
318
+ }
319
+ return response;
320
+ }
321
+ return rewriteToMarkdown({
322
+ request,
323
+ reason: markdownReason,
324
+ requestHeaders,
325
+ });
290
326
  }
291
327
 
292
328
  let pagePath: string;
@@ -296,10 +332,37 @@ export function proxy(request: NextRequest) {
296
332
  pagePath = pathname;
297
333
  }
298
334
  if (!PUBLIC_PATHS.has(pagePath)) {
299
- // Use Next's static 404 before an unknown catch-all reaches error recovery.
300
- const url = request.nextUrl.clone();
335
+ // Select Next's error route before an unknown catch-all can stream.
336
+ const scope = resolveNotFoundScope({
337
+ scopes: agentRouteConfig.notFoundScopes,
338
+ pathname,
339
+ });
340
+ requestHeaders.set(NOT_FOUND_SCOPE_HEADER, scope?.id ?? "none");
341
+ const url = new URL(request.url);
301
342
  url.pathname = "/_not-found";
302
- return NextResponse.rewrite(url, { status: 404 });
343
+ url.search = "";
344
+ url.hash = "";
345
+ const response = NextResponse.rewrite(url, {
346
+ status: 404,
347
+ request: { headers: requestHeaders },
348
+ });
349
+ const recoveryHeaders = createNotFoundTextResponse({
350
+ scope,
351
+ pathname,
352
+ method: request.method,
353
+ vary: true,
354
+ }).headers;
355
+ for (const name of [
356
+ "x-robots-tag",
357
+ "vary",
358
+ ...(agentRouteConfig.enabled && agentRouteConfig.discoveryHeaders
359
+ ? ["link", "x-publishos-llms", "x-publishos-sitemap"]
360
+ : []),
361
+ ]) {
362
+ const value = recoveryHeaders.get(name);
363
+ if (value) response.headers.set(name, value);
364
+ }
365
+ return response;
303
366
  }
304
367
 
305
368
  if (!agentRouteConfig.enabled || !agentRouteConfig.discoveryHeaders) {
@@ -310,7 +373,7 @@ export function proxy(request: NextRequest) {
310
373
  ? "discovery-disabled"
311
374
  : "agent-routes-disabled",
312
375
  });
313
- return NextResponse.next();
376
+ return NextResponse.next({ request: { headers: requestHeaders } });
314
377
  }
315
378
 
316
379
  debugAgentRoute("html", {
@@ -321,7 +384,10 @@ export function proxy(request: NextRequest) {
321
384
  userAgent: request.headers.get("user-agent") ?? undefined,
322
385
  });
323
386
 
324
- return withDiscoveryHeaders(NextResponse.next(), pathname);
387
+ return withDiscoveryHeaders(
388
+ NextResponse.next({ request: { headers: requestHeaders } }),
389
+ pathname,
390
+ );
325
391
  }
326
392
 
327
393
  export const config = {
@@ -1,9 +1,5 @@
1
1
  import { CodeBlock } from "@components/mdx/code-block";
2
- import {
3
- type ComponentPropsWithoutRef,
4
- isValidElement,
5
- type ReactNode,
6
- } from "react";
2
+ import { type HTMLAttributes, isValidElement, type ReactNode } from "react";
7
3
 
8
4
  type CodeChildProps = {
9
5
  children?: ReactNode;
@@ -15,7 +11,7 @@ export function FencedCodeBlock({
15
11
  children,
16
12
  title,
17
13
  ...props
18
- }: ComponentPropsWithoutRef<"pre">) {
14
+ }: HTMLAttributes<HTMLElement>) {
19
15
  const codeElement = isValidElement<CodeChildProps>(children)
20
16
  ? children
21
17
  : null;
@@ -37,51 +37,63 @@ const VideoComponent = (sourceMedia.video ??
37
37
  const FigureComponent = (sourceMedia.figure ??
38
38
  PublishOsFigure) as typeof PublishOsFigure;
39
39
 
40
- function resolveMediaAsset(src: unknown): ResolvedMediaAsset | undefined {
41
- if (typeof src !== "string" || !src.startsWith("/assets/")) return undefined;
42
- return mediaManifest.assets[src as keyof typeof mediaManifest.assets] as
43
- | ResolvedMediaAsset
44
- | undefined;
40
+ function getMediaMetadata(src: unknown): ResolvedMediaAsset | undefined {
41
+ if (typeof src !== "string") return undefined;
42
+ const pathname = src.split(/[?#]/u, 1)[0];
43
+ if (!pathname?.startsWith("/publishos/assets/")) return undefined;
44
+ return Object.values(
45
+ mediaManifest.assets as Record<string, ResolvedMediaAsset>,
46
+ ).find((asset) => asset.outputPath === pathname);
47
+ }
48
+
49
+ function authoredDimension(value: unknown): number | undefined {
50
+ if (typeof value === "number") return value;
51
+ if (typeof value !== "string" || !/^\d+$/u.test(value)) return undefined;
52
+ const dimension = Number(value);
53
+ return Number.isSafeInteger(dimension) && dimension > 0
54
+ ? dimension
55
+ : undefined;
45
56
  }
46
57
 
47
58
  function Link(props: LinkProps) {
48
- const asset = resolveMediaAsset(props.href);
59
+ const asset = getMediaMetadata(props.href);
49
60
  const shouldDownload =
50
61
  asset?.mediaType === "document" || asset?.mediaType === "file";
51
62
  return (
52
63
  <LinkComponent
53
64
  {...props}
54
65
  download={props.download ?? (shouldDownload ? "" : undefined)}
55
- href={asset?.outputPath ?? props.href}
66
+ href={props.href}
56
67
  />
57
68
  );
58
69
  }
59
70
 
60
71
  function Image(props: ImageProps) {
61
- const asset = resolveMediaAsset(props.src);
72
+ const asset = getMediaMetadata(props.src);
73
+ const width = authoredDimension(props.width);
74
+ const height = authoredDimension(props.height);
62
75
  return (
63
76
  <ImageComponent
64
77
  {...props}
65
78
  aspect={props.aspect ?? asset?.aspect}
66
- height={props.height ?? asset?.height}
79
+ height={height ?? asset?.height}
67
80
  intrinsicHeight={asset?.intrinsicHeight ?? asset?.height}
68
81
  intrinsicWidth={asset?.intrinsicWidth ?? asset?.width}
69
- optimized={asset?.optimized}
70
- src={asset?.outputPath ?? props.src}
71
- width={props.width ?? asset?.width}
82
+ optimized={props.optimized ?? asset?.optimized}
83
+ src={props.src}
84
+ width={width ?? asset?.width}
72
85
  />
73
86
  );
74
87
  }
75
88
 
76
89
  function Video(props: VideoProps) {
77
- const asset = resolveMediaAsset(props.src);
78
- const poster = resolveMediaAsset(props.poster);
90
+ const asset = getMediaMetadata(props.src);
79
91
  return (
80
92
  <VideoComponent
81
93
  {...props}
82
94
  height={props.height ?? asset?.height}
83
- poster={poster?.outputPath ?? props.poster}
84
- src={asset?.outputPath ?? props.src}
95
+ poster={props.poster}
96
+ src={props.src}
85
97
  width={props.width ?? asset?.width}
86
98
  />
87
99
  );
@@ -1,12 +1,17 @@
1
1
  import type { MDXProps } from "@publish.os/nextjs/mdx/mdx";
2
2
  import { renderMdx } from "@publish.os/nextjs/mdx/mdx";
3
3
  import { mdxComponents } from "@source/_internal/mdx-components.generated";
4
+ import { importedMdxComponents } from "@source/_internal/mdx-icon-components.generated";
4
5
 
5
6
  export type { MDXComponents, MDXProps } from "@publish.os/nextjs/mdx/mdx";
6
7
  export { Figure, Image, Link, Video } from "@publish.os/nextjs/mdx/mdx";
7
8
 
8
9
  export async function MDX(props: MDXProps) {
9
- return renderMdx({ ...props, siteComponents: mdxComponents });
10
+ return renderMdx({
11
+ ...props,
12
+ siteComponents: mdxComponents,
13
+ importedComponents: importedMdxComponents[props.page.path],
14
+ });
10
15
  }
11
16
 
12
17
  Object.defineProperty(MDX, "__publishOsMdx", { value: true });
@@ -1,30 +1,30 @@
1
+ import {
2
+ approveLocalComposition,
3
+ installLocalApp
4
+ } from "./chunk-4BC2L2KA.js";
5
+ import {
6
+ withLocalOperation
7
+ } from "./chunk-IL4RJOKI.js";
1
8
  import {
2
9
  prepareIdeSupport
3
- } from "./chunk-UF6ATARM.js";
10
+ } from "./chunk-GBPLER5H.js";
11
+ import "./chunk-6D2E6UMD.js";
4
12
  import {
5
13
  composeFrameworkSource
6
- } from "./chunk-H6XILMZX.js";
14
+ } from "./chunk-OXOFRXEI.js";
7
15
  import {
8
16
  validateLocalSource
9
- } from "./chunk-VO2I7MTM.js";
10
- import "./chunk-726GV2NF.js";
11
- import "./chunk-NECL5IBJ.js";
12
- import "./chunk-535TM4A5.js";
13
- import {
14
- approveLocalComposition
15
- } from "./chunk-SVYGXXYR.js";
16
- import {
17
- withLocalOperation
18
- } from "./chunk-B2V22WRT.js";
19
- import {
20
- installLocalApp
21
- } from "./chunk-WKTEO6RS.js";
22
- import "./chunk-GGKFQ3MA.js";
23
- import "./chunk-DLDFHU7Y.js";
24
- import "./chunk-7OGTPSKI.js";
25
- import "./chunk-YLTOLYWM.js";
17
+ } from "./chunk-ORIUWJBQ.js";
18
+ import "./chunk-NNBJZPFM.js";
19
+ import "./chunk-F3AGNDF4.js";
20
+ import "./chunk-7NY22B5U.js";
21
+ import "./chunk-UYGCOWRF.js";
22
+ import "./chunk-EFO6AWXN.js";
23
+ import "./chunk-5KAD7W53.js";
24
+ import "./chunk-WL75GQ5M.js";
26
25
  import "./chunk-AI2UULNX.js";
27
- import "./chunk-WDY4IK6Z.js";
26
+ import "./chunk-5J3YUNRY.js";
27
+ import "./chunk-22RSSUNV.js";
28
28
 
29
29
  // src/lib/compiler/lifecycle/build-operation.ts
30
30
  async function runLocalBuild(options) {
@@ -40,10 +40,10 @@ async function runLocalBuild(options) {
40
40
  sourceRoot: lifetime.sourceRoot
41
41
  });
42
42
  return await approveLocalComposition({ options }), options.request.context?.ide && await prepareIdeSupport({
43
+ frameworkOptions: { ...options, signal: lifetime.signal },
43
44
  publishOsDir: lifetime.sourceRoot,
44
45
  source,
45
- framework,
46
- frameworkOptions: { ...options, signal: lifetime.signal }
46
+ framework
47
47
  }), await lifetime.replaceOutput(async (outputDir) => {
48
48
  await composeFrameworkSource({
49
49
  request: {
@@ -62,7 +62,13 @@ async function runLocalBuild(options) {
62
62
  },
63
63
  source,
64
64
  signal: lifetime.signal,
65
- onProgress: (message) => options.onEvent?.({ type: "progress", message })
65
+ onProgress: (message) => options.onEvent?.({ type: "progress", message }),
66
+ onWarning: (warning) => options.onEvent?.({
67
+ type: "diagnostics",
68
+ diagnostics: {
69
+ diagnostics: [{ ...warning, severity: "warning" }]
70
+ }
71
+ })
66
72
  });
67
73
  let app = await installLocalApp({
68
74
  outputDir,
@@ -3,9 +3,9 @@ import { VariantProps } from 'class-variance-authority';
3
3
  import { ReactNode, ComponentPropsWithRef } from 'react';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "solid" | "soft" | "outline" | "ghost" | null | undefined;
7
- size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
8
- iconOnly?: boolean | null | undefined;
6
+ readonly variant?: "solid" | "soft" | "outline" | "ghost" | null | undefined;
7
+ readonly size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
8
+ readonly iconOnly?: boolean | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  type ButtonVariantProps = VariantProps<typeof buttonVariants>;
11
11
  type ButtonProps = {