@treeseed/core 0.1.2

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 (384) hide show
  1. package/README.md +145 -0
  2. package/dist/agents/index.js +5 -0
  3. package/dist/agents/registry-helper.js +14 -0
  4. package/dist/agents/registry.js +88 -0
  5. package/dist/components/DevWatchReload.astro +45 -0
  6. package/dist/components/SiteTitle.astro +51 -0
  7. package/dist/components/content/ContentStatusLegend.astro +18 -0
  8. package/dist/components/content/StatusBadge.astro +11 -0
  9. package/dist/components/docs/BookFontControls.astro +180 -0
  10. package/dist/components/docs/DesktopSidebarToggle.astro +88 -0
  11. package/dist/components/docs/DownloadBook.astro +34 -0
  12. package/dist/components/docs/Footer.astro +196 -0
  13. package/dist/components/docs/Header.astro +150 -0
  14. package/dist/components/docs/PageFrame.astro +260 -0
  15. package/dist/components/docs/PageSidebar.astro +63 -0
  16. package/dist/components/docs/PageTitle.astro +39 -0
  17. package/dist/components/docs/Sidebar.astro +41 -0
  18. package/dist/components/docs/ThemeSelect.astro +3 -0
  19. package/dist/components/forms/ContactForm.astro +234 -0
  20. package/dist/components/forms/FooterSubscribeForm.astro +189 -0
  21. package/dist/components/site/BookList.astro +27 -0
  22. package/dist/components/site/CTASection.astro +24 -0
  23. package/dist/components/site/ChronicleList.astro +33 -0
  24. package/dist/components/site/Hero.astro +18 -0
  25. package/dist/components/site/NotesList.astro +18 -0
  26. package/dist/components/site/PathCard.astro +16 -0
  27. package/dist/components/site/ProfileList.astro +30 -0
  28. package/dist/components/site/SectionIntro.astro +9 -0
  29. package/dist/components/site/StageBanner.astro +8 -0
  30. package/dist/components/site/TrustCallout.astro +9 -0
  31. package/dist/components/starlight.js +6 -0
  32. package/dist/config.js +8 -0
  33. package/dist/content-config.js +9 -0
  34. package/dist/content.js +230 -0
  35. package/dist/contracts.d.ts +130 -0
  36. package/dist/contracts.js +0 -0
  37. package/dist/deploy/config.d.ts +4 -0
  38. package/dist/deploy/config.js +154 -0
  39. package/dist/deploy/runtime.js +77 -0
  40. package/dist/env.yaml +322 -0
  41. package/dist/environment.d.ts +130 -0
  42. package/dist/environment.js +324 -0
  43. package/dist/index.js +81 -0
  44. package/dist/layouts/AuthoredEntryLayout.astro +87 -0
  45. package/dist/layouts/BookLayout.astro +35 -0
  46. package/dist/layouts/BridgeLayout.astro +11 -0
  47. package/dist/layouts/ContentLayout.astro +24 -0
  48. package/dist/layouts/MainLayout.astro +203 -0
  49. package/dist/layouts/NoteLayout.astro +26 -0
  50. package/dist/layouts/ProfileLayout.astro +81 -0
  51. package/dist/middleware/starlightRouteData.js +45 -0
  52. package/dist/pages/404.astro +29 -0
  53. package/dist/pages/[slug].astro +30 -0
  54. package/dist/pages/agents/[slug].astro +29 -0
  55. package/dist/pages/agents/index.astro +27 -0
  56. package/dist/pages/api/form/submit.js +14 -0
  57. package/dist/pages/books/[slug].astro +19 -0
  58. package/dist/pages/books/index.astro +28 -0
  59. package/dist/pages/contact.astro +27 -0
  60. package/dist/pages/feed.xml.js +34 -0
  61. package/dist/pages/index.astro +290 -0
  62. package/dist/pages/notes/[slug].astro +19 -0
  63. package/dist/pages/notes/index.astro +21 -0
  64. package/dist/pages/objectives/[slug].astro +31 -0
  65. package/dist/pages/objectives/index.astro +30 -0
  66. package/dist/pages/people/[slug].astro +29 -0
  67. package/dist/pages/people/index.astro +28 -0
  68. package/dist/pages/questions/[slug].astro +31 -0
  69. package/dist/pages/questions/index.astro +30 -0
  70. package/dist/plugin-default.js +4 -0
  71. package/dist/plugins/builtin/default-plugin.d.ts +21 -0
  72. package/dist/plugins/builtin/default-plugin.js +32 -0
  73. package/dist/plugins/constants.d.ts +21 -0
  74. package/dist/plugins/constants.js +28 -0
  75. package/dist/plugins/plugin.d.ts +42 -0
  76. package/dist/plugins/plugin.js +6 -0
  77. package/dist/plugins/runtime.d.ts +31 -0
  78. package/dist/plugins/runtime.js +120 -0
  79. package/dist/scripts/aggregate-book.js +112 -0
  80. package/dist/scripts/assert-release-tag-version.js +21 -0
  81. package/dist/scripts/build-dist.js +384 -0
  82. package/dist/scripts/build-tenant-worker.js +36 -0
  83. package/dist/scripts/package-tools.js +88 -0
  84. package/dist/scripts/patch-starlight-content-path.js +172 -0
  85. package/dist/scripts/paths.js +11 -0
  86. package/dist/scripts/publish-package.js +20 -0
  87. package/dist/scripts/release-verify.js +52 -0
  88. package/dist/scripts/run-fixture-astro-command.js +21 -0
  89. package/dist/scripts/tenant-astro-command.js +3 -0
  90. package/dist/scripts/tenant-build.js +16 -0
  91. package/dist/scripts/tenant-check.js +7 -0
  92. package/dist/scripts/test-smoke.js +105 -0
  93. package/dist/server.js +53 -0
  94. package/dist/site-resources.d.ts +29 -0
  95. package/dist/site-resources.js +127 -0
  96. package/dist/site.js +313 -0
  97. package/dist/styles/global.css +683 -0
  98. package/dist/styles/prose.css +89 -0
  99. package/dist/styles/tokens.css +24 -0
  100. package/dist/tenant/bridge.js +5 -0
  101. package/dist/tenant/config.d.ts +9 -0
  102. package/dist/tenant/config.js +124 -0
  103. package/dist/tenant/runtime-config.js +20 -0
  104. package/dist/tsconfigs/strict.json +3 -0
  105. package/dist/types/agents.d.ts +1 -0
  106. package/dist/types/agents.js +1 -0
  107. package/dist/types/astro-build.d.js +0 -0
  108. package/dist/types/cloudflare-sockets.d.js +0 -0
  109. package/dist/types/cloudflare.d.ts +1 -0
  110. package/dist/types/cloudflare.js +1 -0
  111. package/dist/types/forms.js +4 -0
  112. package/dist/utils/agents/adapters/execution.js +90 -0
  113. package/dist/utils/agents/adapters/mutations.js +30 -0
  114. package/dist/utils/agents/adapters/notification.js +16 -0
  115. package/dist/utils/agents/adapters/repository.js +61 -0
  116. package/dist/utils/agents/adapters/research.js +25 -0
  117. package/dist/utils/agents/adapters/verification.js +62 -0
  118. package/dist/utils/agents/cli-tools.js +5 -0
  119. package/dist/utils/agents/contracts/messages.d.ts +88 -0
  120. package/dist/utils/agents/contracts/messages.js +138 -0
  121. package/dist/utils/agents/contracts/run.d.ts +20 -0
  122. package/dist/utils/agents/contracts/run.js +0 -0
  123. package/dist/utils/agents/runtime-types.d.ts +117 -0
  124. package/dist/utils/agents/runtime-types.js +4 -0
  125. package/dist/utils/books-data.js +82 -0
  126. package/dist/utils/content-status.js +38 -0
  127. package/dist/utils/forms/config.js +87 -0
  128. package/dist/utils/forms/constants.js +27 -0
  129. package/dist/utils/forms/contact-submissions-local.js +19 -0
  130. package/dist/utils/forms/contact-submissions.js +72 -0
  131. package/dist/utils/forms/crypto.js +64 -0
  132. package/dist/utils/forms/guard.js +76 -0
  133. package/dist/utils/forms/http.js +51 -0
  134. package/dist/utils/forms/provider-core.js +88 -0
  135. package/dist/utils/forms/routing-core.js +7 -0
  136. package/dist/utils/forms/routing.js +13 -0
  137. package/dist/utils/forms/runtime-core.js +17 -0
  138. package/dist/utils/forms/runtime.js +27 -0
  139. package/dist/utils/forms/service-core.js +256 -0
  140. package/dist/utils/forms/service.js +55 -0
  141. package/dist/utils/forms/session.js +57 -0
  142. package/dist/utils/forms/smtp-cloudflare.js +107 -0
  143. package/dist/utils/forms/smtp-node.js +27 -0
  144. package/dist/utils/forms/smtp.js +10 -0
  145. package/dist/utils/forms/subscribers-local.js +21 -0
  146. package/dist/utils/forms/subscribers.js +53 -0
  147. package/dist/utils/forms/turnstile.js +31 -0
  148. package/dist/utils/forms/validation.js +58 -0
  149. package/dist/utils/hub-content.js +28 -0
  150. package/dist/utils/plugin-runtime.js +158 -0
  151. package/dist/utils/routes.js +17 -0
  152. package/dist/utils/seo.js +4 -0
  153. package/dist/utils/site-config-schema.js +282 -0
  154. package/dist/utils/site-config.js +122 -0
  155. package/dist/utils/starlight-nav.js +62 -0
  156. package/dist/utils/theme.js +49 -0
  157. package/dist/vendor/starlight/components/AnchorHeading.astro +53 -0
  158. package/dist/vendor/starlight/components/Banner.astro +23 -0
  159. package/dist/vendor/starlight/components/ContentNotice.astro +33 -0
  160. package/dist/vendor/starlight/components/ContentPanel.astro +27 -0
  161. package/dist/vendor/starlight/components/DraftContentNotice.astro +5 -0
  162. package/dist/vendor/starlight/components/EditLink.astro +28 -0
  163. package/dist/vendor/starlight/components/FallbackContentNotice.astro +5 -0
  164. package/dist/vendor/starlight/components/Footer.astro +61 -0
  165. package/dist/vendor/starlight/components/Head.astro +5 -0
  166. package/dist/vendor/starlight/components/Header.astro +94 -0
  167. package/dist/vendor/starlight/components/Hero.astro +143 -0
  168. package/dist/vendor/starlight/components/Icons.js +121 -0
  169. package/dist/vendor/starlight/components/LanguageSelect.astro +57 -0
  170. package/dist/vendor/starlight/components/LastUpdated.astro +14 -0
  171. package/dist/vendor/starlight/components/MarkdownContent.astro +5 -0
  172. package/dist/vendor/starlight/components/MobileMenuFooter.astro +35 -0
  173. package/dist/vendor/starlight/components/MobileMenuToggle.astro +107 -0
  174. package/dist/vendor/starlight/components/MobileTableOfContents.astro +151 -0
  175. package/dist/vendor/starlight/components/Page.astro +126 -0
  176. package/dist/vendor/starlight/components/PageFrame.astro +97 -0
  177. package/dist/vendor/starlight/components/PageSidebar.astro +59 -0
  178. package/dist/vendor/starlight/components/PageTitle.astro +17 -0
  179. package/dist/vendor/starlight/components/Pagination.astro +79 -0
  180. package/dist/vendor/starlight/components/Search.astro +488 -0
  181. package/dist/vendor/starlight/components/Select.astro +99 -0
  182. package/dist/vendor/starlight/components/Sidebar.astro +15 -0
  183. package/dist/vendor/starlight/components/SidebarPersistState.js +43 -0
  184. package/dist/vendor/starlight/components/SidebarPersister.astro +78 -0
  185. package/dist/vendor/starlight/components/SidebarRestorePoint.astro +12 -0
  186. package/dist/vendor/starlight/components/SidebarSublist.astro +154 -0
  187. package/dist/vendor/starlight/components/SiteTitle.astro +59 -0
  188. package/dist/vendor/starlight/components/SkipLink.astro +26 -0
  189. package/dist/vendor/starlight/components/SocialIcons.astro +32 -0
  190. package/dist/vendor/starlight/components/StarlightPage.astro +17 -0
  191. package/dist/vendor/starlight/components/TableOfContents/TableOfContentsList.astro +79 -0
  192. package/dist/vendor/starlight/components/TableOfContents/starlight-toc.js +93 -0
  193. package/dist/vendor/starlight/components/TableOfContents.astro +18 -0
  194. package/dist/vendor/starlight/components/ThemeProvider.astro +38 -0
  195. package/dist/vendor/starlight/components/ThemeSelect.astro +73 -0
  196. package/dist/vendor/starlight/components/TwoColumnContent.astro +54 -0
  197. package/dist/vendor/starlight/components.js +26 -0
  198. package/dist/vendor/starlight/constants.js +4 -0
  199. package/dist/vendor/starlight/expressive-code.d.js +1 -0
  200. package/dist/vendor/starlight/global.d.js +0 -0
  201. package/dist/vendor/starlight/i18n.d.js +1 -0
  202. package/dist/vendor/starlight/index.js +119 -0
  203. package/dist/vendor/starlight/integrations/asides-error.js +12 -0
  204. package/dist/vendor/starlight/integrations/asides.js +179 -0
  205. package/dist/vendor/starlight/integrations/code-rtl-support.js +21 -0
  206. package/dist/vendor/starlight/integrations/expressive-code/hast.d.js +1 -0
  207. package/dist/vendor/starlight/integrations/expressive-code/index.js +63 -0
  208. package/dist/vendor/starlight/integrations/expressive-code/preprocessor.js +92 -0
  209. package/dist/vendor/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc +1796 -0
  210. package/dist/vendor/starlight/integrations/expressive-code/themes/night-owl-dark.jsonc.js +1 -0
  211. package/dist/vendor/starlight/integrations/expressive-code/themes/night-owl-light.jsonc +1695 -0
  212. package/dist/vendor/starlight/integrations/expressive-code/themes/night-owl-light.jsonc.js +1 -0
  213. package/dist/vendor/starlight/integrations/expressive-code/theming.js +62 -0
  214. package/dist/vendor/starlight/integrations/expressive-code/translations.js +29 -0
  215. package/dist/vendor/starlight/integrations/heading-links.js +61 -0
  216. package/dist/vendor/starlight/integrations/pagefind.js +43 -0
  217. package/dist/vendor/starlight/integrations/remark-rehype.js +68 -0
  218. package/dist/vendor/starlight/integrations/shared/absolutePathToLang.js +15 -0
  219. package/dist/vendor/starlight/integrations/shared/localeToLang.js +9 -0
  220. package/dist/vendor/starlight/integrations/shared/slugToLocale.js +10 -0
  221. package/dist/vendor/starlight/integrations/sitemap.js +20 -0
  222. package/dist/vendor/starlight/integrations/virtual-user-config.js +110 -0
  223. package/dist/vendor/starlight/integrations/vite-layer-order.js +42 -0
  224. package/dist/vendor/starlight/internal.js +6 -0
  225. package/dist/vendor/starlight/loaders.js +36 -0
  226. package/dist/vendor/starlight/locals.d.js +0 -0
  227. package/dist/vendor/starlight/locals.js +30 -0
  228. package/dist/vendor/starlight/package.json +231 -0
  229. package/dist/vendor/starlight/package.json.js +248 -0
  230. package/dist/vendor/starlight/props.js +0 -0
  231. package/dist/vendor/starlight/route-data.js +6 -0
  232. package/dist/vendor/starlight/routes/common.astro +23 -0
  233. package/dist/vendor/starlight/routes/ssr/404.astro +7 -0
  234. package/dist/vendor/starlight/routes/ssr/index.astro +14 -0
  235. package/dist/vendor/starlight/routes/static/404.astro +7 -0
  236. package/dist/vendor/starlight/routes/static/index.astro +12 -0
  237. package/dist/vendor/starlight/schema.js +102 -0
  238. package/dist/vendor/starlight/schemas/badge.js +26 -0
  239. package/dist/vendor/starlight/schemas/components.js +235 -0
  240. package/dist/vendor/starlight/schemas/expressiveCode.js +12 -0
  241. package/dist/vendor/starlight/schemas/favicon.js +33 -0
  242. package/dist/vendor/starlight/schemas/head.js +32 -0
  243. package/dist/vendor/starlight/schemas/hero.js +57 -0
  244. package/dist/vendor/starlight/schemas/i18n.js +101 -0
  245. package/dist/vendor/starlight/schemas/icon.js +7 -0
  246. package/dist/vendor/starlight/schemas/logo.js +24 -0
  247. package/dist/vendor/starlight/schemas/pagefind.js +108 -0
  248. package/dist/vendor/starlight/schemas/prevNextLink.js +14 -0
  249. package/dist/vendor/starlight/schemas/sidebar.js +80 -0
  250. package/dist/vendor/starlight/schemas/site-title.js +19 -0
  251. package/dist/vendor/starlight/schemas/social.js +19 -0
  252. package/dist/vendor/starlight/schemas/tableOfContents.js +16 -0
  253. package/dist/vendor/starlight/style/anchor-links.css +131 -0
  254. package/dist/vendor/starlight/style/asides.css +51 -0
  255. package/dist/vendor/starlight/style/layers.css +1 -0
  256. package/dist/vendor/starlight/style/markdown.css +253 -0
  257. package/dist/vendor/starlight/style/print.css +175 -0
  258. package/dist/vendor/starlight/style/props.css +188 -0
  259. package/dist/vendor/starlight/style/reset.css +52 -0
  260. package/dist/vendor/starlight/style/util.css +63 -0
  261. package/dist/vendor/starlight/translations/ar.json +30 -0
  262. package/dist/vendor/starlight/translations/ar.json.js +32 -0
  263. package/dist/vendor/starlight/translations/ca.json +43 -0
  264. package/dist/vendor/starlight/translations/ca.json.js +45 -0
  265. package/dist/vendor/starlight/translations/cs.json +43 -0
  266. package/dist/vendor/starlight/translations/cs.json.js +45 -0
  267. package/dist/vendor/starlight/translations/da.json +30 -0
  268. package/dist/vendor/starlight/translations/da.json.js +32 -0
  269. package/dist/vendor/starlight/translations/de.json +30 -0
  270. package/dist/vendor/starlight/translations/de.json.js +32 -0
  271. package/dist/vendor/starlight/translations/el.json +30 -0
  272. package/dist/vendor/starlight/translations/el.json.js +32 -0
  273. package/dist/vendor/starlight/translations/en.json +30 -0
  274. package/dist/vendor/starlight/translations/en.json.js +32 -0
  275. package/dist/vendor/starlight/translations/es.json +43 -0
  276. package/dist/vendor/starlight/translations/es.json.js +45 -0
  277. package/dist/vendor/starlight/translations/fa.json +30 -0
  278. package/dist/vendor/starlight/translations/fa.json.js +32 -0
  279. package/dist/vendor/starlight/translations/fi.json +30 -0
  280. package/dist/vendor/starlight/translations/fi.json.js +32 -0
  281. package/dist/vendor/starlight/translations/fr.json +33 -0
  282. package/dist/vendor/starlight/translations/fr.json.js +35 -0
  283. package/dist/vendor/starlight/translations/gl.json +43 -0
  284. package/dist/vendor/starlight/translations/gl.json.js +45 -0
  285. package/dist/vendor/starlight/translations/he.json +30 -0
  286. package/dist/vendor/starlight/translations/he.json.js +32 -0
  287. package/dist/vendor/starlight/translations/hi.json +30 -0
  288. package/dist/vendor/starlight/translations/hi.json.js +32 -0
  289. package/dist/vendor/starlight/translations/hu.json +43 -0
  290. package/dist/vendor/starlight/translations/hu.json.js +45 -0
  291. package/dist/vendor/starlight/translations/id.json +30 -0
  292. package/dist/vendor/starlight/translations/id.json.js +32 -0
  293. package/dist/vendor/starlight/translations/index.js +77 -0
  294. package/dist/vendor/starlight/translations/it.json +30 -0
  295. package/dist/vendor/starlight/translations/it.json.js +32 -0
  296. package/dist/vendor/starlight/translations/ja.json +30 -0
  297. package/dist/vendor/starlight/translations/ja.json.js +32 -0
  298. package/dist/vendor/starlight/translations/ko.json +30 -0
  299. package/dist/vendor/starlight/translations/ko.json.js +32 -0
  300. package/dist/vendor/starlight/translations/lv.json +30 -0
  301. package/dist/vendor/starlight/translations/lv.json.js +32 -0
  302. package/dist/vendor/starlight/translations/nb.json +30 -0
  303. package/dist/vendor/starlight/translations/nb.json.js +32 -0
  304. package/dist/vendor/starlight/translations/nl.json +30 -0
  305. package/dist/vendor/starlight/translations/nl.json.js +32 -0
  306. package/dist/vendor/starlight/translations/pl.json +33 -0
  307. package/dist/vendor/starlight/translations/pl.json.js +35 -0
  308. package/dist/vendor/starlight/translations/pt.json +30 -0
  309. package/dist/vendor/starlight/translations/pt.json.js +32 -0
  310. package/dist/vendor/starlight/translations/ro.json +30 -0
  311. package/dist/vendor/starlight/translations/ro.json.js +32 -0
  312. package/dist/vendor/starlight/translations/ru.json +33 -0
  313. package/dist/vendor/starlight/translations/ru.json.js +35 -0
  314. package/dist/vendor/starlight/translations/sk.json +30 -0
  315. package/dist/vendor/starlight/translations/sk.json.js +32 -0
  316. package/dist/vendor/starlight/translations/sv.json +30 -0
  317. package/dist/vendor/starlight/translations/sv.json.js +32 -0
  318. package/dist/vendor/starlight/translations/th.json +30 -0
  319. package/dist/vendor/starlight/translations/th.json.js +32 -0
  320. package/dist/vendor/starlight/translations/tr.json +30 -0
  321. package/dist/vendor/starlight/translations/tr.json.js +32 -0
  322. package/dist/vendor/starlight/translations/uk.json +30 -0
  323. package/dist/vendor/starlight/translations/uk.json.js +32 -0
  324. package/dist/vendor/starlight/translations/vi.json +30 -0
  325. package/dist/vendor/starlight/translations/vi.json.js +32 -0
  326. package/dist/vendor/starlight/translations/zh-CN.json +30 -0
  327. package/dist/vendor/starlight/translations/zh-CN.json.js +32 -0
  328. package/dist/vendor/starlight/translations/zh-TW.json +30 -0
  329. package/dist/vendor/starlight/translations/zh-TW.json.js +32 -0
  330. package/dist/vendor/starlight/types.js +0 -0
  331. package/dist/vendor/starlight/user-components/Aside.astro +40 -0
  332. package/dist/vendor/starlight/user-components/Badge.astro +148 -0
  333. package/dist/vendor/starlight/user-components/Card.astro +68 -0
  334. package/dist/vendor/starlight/user-components/CardGrid.astro +38 -0
  335. package/dist/vendor/starlight/user-components/FileTree.astro +137 -0
  336. package/dist/vendor/starlight/user-components/Icon.astro +42 -0
  337. package/dist/vendor/starlight/user-components/LinkButton.astro +78 -0
  338. package/dist/vendor/starlight/user-components/LinkCard.astro +78 -0
  339. package/dist/vendor/starlight/user-components/Steps.astro +90 -0
  340. package/dist/vendor/starlight/user-components/TabItem.astro +19 -0
  341. package/dist/vendor/starlight/user-components/Tabs.astro +268 -0
  342. package/dist/vendor/starlight/user-components/file-tree-icons.js +608 -0
  343. package/dist/vendor/starlight/user-components/rehype-file-tree.js +160 -0
  344. package/dist/vendor/starlight/user-components/rehype-steps.js +53 -0
  345. package/dist/vendor/starlight/user-components/rehype-tabs.js +73 -0
  346. package/dist/vendor/starlight/utils/base.js +14 -0
  347. package/dist/vendor/starlight/utils/canonical.js +13 -0
  348. package/dist/vendor/starlight/utils/collection-fs.js +13 -0
  349. package/dist/vendor/starlight/utils/collection.js +16 -0
  350. package/dist/vendor/starlight/utils/createPathFormatter.js +39 -0
  351. package/dist/vendor/starlight/utils/createTranslationSystem.js +60 -0
  352. package/dist/vendor/starlight/utils/error-map.js +110 -0
  353. package/dist/vendor/starlight/utils/format-path.js +9 -0
  354. package/dist/vendor/starlight/utils/generateToC.js +18 -0
  355. package/dist/vendor/starlight/utils/git.js +92 -0
  356. package/dist/vendor/starlight/utils/gitInlined.js +13 -0
  357. package/dist/vendor/starlight/utils/head.js +156 -0
  358. package/dist/vendor/starlight/utils/i18n.js +121 -0
  359. package/dist/vendor/starlight/utils/localizedUrl.js +37 -0
  360. package/dist/vendor/starlight/utils/navigation.js +320 -0
  361. package/dist/vendor/starlight/utils/path.js +52 -0
  362. package/dist/vendor/starlight/utils/plugins.js +355 -0
  363. package/dist/vendor/starlight/utils/routing/data.js +116 -0
  364. package/dist/vendor/starlight/utils/routing/index.js +107 -0
  365. package/dist/vendor/starlight/utils/routing/middleware.js +40 -0
  366. package/dist/vendor/starlight/utils/routing/types.js +0 -0
  367. package/dist/vendor/starlight/utils/routing.js +1 -0
  368. package/dist/vendor/starlight/utils/slugs.js +70 -0
  369. package/dist/vendor/starlight/utils/starlight-page.js +123 -0
  370. package/dist/vendor/starlight/utils/translations-fs.js +31 -0
  371. package/dist/vendor/starlight/utils/translations.js +31 -0
  372. package/dist/vendor/starlight/utils/types.js +0 -0
  373. package/dist/vendor/starlight/utils/url.js +5 -0
  374. package/dist/vendor/starlight/utils/user-config.js +255 -0
  375. package/dist/vendor/starlight/utils/validateLogoImports.js +22 -0
  376. package/dist/vendor/starlight/virtual-internal.d.js +0 -0
  377. package/dist/vendor/starlight/virtual.d.js +0 -0
  378. package/dist/worker/forms-worker.js +141 -0
  379. package/package.json +156 -0
  380. package/style/anchor-links.css +131 -0
  381. package/templates/github/deploy.workflow.yml +47 -0
  382. package/tsconfigs/strict.json +3 -0
  383. package/utils/git.ts +121 -0
  384. package/utils/gitInlined.ts +20 -0
@@ -0,0 +1,324 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { parse as parseYaml } from "yaml";
6
+ import { loadTreeseedDeployConfig } from "./deploy/config.js";
7
+ import { loadTreeseedPlugins } from "./plugins/runtime.js";
8
+ import { loadTreeseedManifest } from "./tenant/config.js";
9
+ const TREESEED_ENVIRONMENT_SCOPES = ["local", "staging", "prod"];
10
+ const TREESEED_ENVIRONMENT_REQUIREMENTS = ["required", "conditional", "optional"];
11
+ const TREESEED_ENVIRONMENT_TARGETS = [
12
+ "local-file",
13
+ "wrangler-dev-vars",
14
+ "github-secret",
15
+ "github-variable",
16
+ "cloudflare-secret",
17
+ "cloudflare-var",
18
+ "config-file"
19
+ ];
20
+ const TREESEED_ENVIRONMENT_PURPOSES = ["dev", "save", "deploy", "destroy", "config"];
21
+ const TREESEED_ENVIRONMENT_SENSITIVITY = ["secret", "plain", "derived"];
22
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
23
+ const CORE_ENVIRONMENT_PATH = resolve(moduleDir, "env.yaml");
24
+ const TENANT_ENVIRONMENT_OVERLAY_PATH = "src/env.yaml";
25
+ function loadOptionalTenantConfig() {
26
+ try {
27
+ return loadTreeseedManifest();
28
+ } catch {
29
+ return void 0;
30
+ }
31
+ }
32
+ function turnstileEnabled(context) {
33
+ return context.deployConfig.turnstile?.enabled !== false;
34
+ }
35
+ function smtpEnabled(context) {
36
+ return context.deployConfig.smtp?.enabled === true;
37
+ }
38
+ function generatedSecret(bytes = 24) {
39
+ return randomBytes(bytes).toString("hex");
40
+ }
41
+ const VALUE_RESOLVERS = {
42
+ generatedSecret: () => generatedSecret(),
43
+ localFormsBypassDefault: () => "true"
44
+ };
45
+ const PREDICATES = {
46
+ turnstileEnabled: (context) => turnstileEnabled(context),
47
+ turnstileNonLocal: (context, scope) => turnstileEnabled(context) && scope !== "local",
48
+ smtpEnabled: (context) => smtpEnabled(context),
49
+ smtpNonLocal: (context, scope) => smtpEnabled(context) && scope !== "local"
50
+ };
51
+ function deepMerge(left, right) {
52
+ if (Array.isArray(left) && Array.isArray(right)) {
53
+ return [...right];
54
+ }
55
+ if (left && typeof left === "object" && !Array.isArray(left) && right && typeof right === "object" && !Array.isArray(right)) {
56
+ const result = { ...left };
57
+ for (const [key, value] of Object.entries(right)) {
58
+ result[key] = key in result ? deepMerge(result[key], value) : value;
59
+ }
60
+ return result;
61
+ }
62
+ return right;
63
+ }
64
+ function normalizeOverlay(raw, label) {
65
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
66
+ throw new Error(`Invalid Treeseed environment registry overlay from ${label}.`);
67
+ }
68
+ const overlay = raw;
69
+ if (overlay.entries === void 0) {
70
+ return { entries: {} };
71
+ }
72
+ if (!overlay.entries || typeof overlay.entries !== "object" || Array.isArray(overlay.entries)) {
73
+ throw new Error(`Invalid Treeseed environment registry overlay entries in ${label}.`);
74
+ }
75
+ return overlay;
76
+ }
77
+ function readYamlOverlayIfPresent(filePath) {
78
+ if (!existsSync(filePath)) {
79
+ return null;
80
+ }
81
+ return normalizeOverlay(parseYaml(readFileSync(filePath, "utf8")), filePath);
82
+ }
83
+ function pluginEnvironmentCandidates(baseDir) {
84
+ const dir = resolve(baseDir);
85
+ return [
86
+ resolve(dir, "env.yaml"),
87
+ resolve(dir, "src/env.yaml"),
88
+ resolve(dir, "../env.yaml"),
89
+ resolve(dir, "../src/env.yaml"),
90
+ resolve(dir, "../../env.yaml"),
91
+ resolve(dir, "../../src/env.yaml")
92
+ ];
93
+ }
94
+ function readPluginEnvironmentOverlay(baseDir) {
95
+ for (const candidate of pluginEnvironmentCandidates(baseDir)) {
96
+ const overlay = readYamlOverlayIfPresent(candidate);
97
+ if (overlay) {
98
+ return { path: candidate, overlay };
99
+ }
100
+ }
101
+ return null;
102
+ }
103
+ function loadTreeseedEnvironmentOverlay(tenantRoot) {
104
+ const overlayPath = resolve(tenantRoot, TENANT_ENVIRONMENT_OVERLAY_PATH);
105
+ return {
106
+ path: overlayPath,
107
+ overlay: readYamlOverlayIfPresent(overlayPath) ?? { entries: {} }
108
+ };
109
+ }
110
+ function resolveNamedValueResolver(ref) {
111
+ if (!ref) return void 0;
112
+ const resolver = VALUE_RESOLVERS[ref];
113
+ if (!resolver) {
114
+ throw new Error(`Unknown Treeseed environment value resolver "${ref}".`);
115
+ }
116
+ return resolver;
117
+ }
118
+ function resolveNamedPredicate(ref) {
119
+ if (!ref) return void 0;
120
+ const predicate = PREDICATES[ref];
121
+ if (!predicate) {
122
+ throw new Error(`Unknown Treeseed environment predicate "${ref}".`);
123
+ }
124
+ return predicate;
125
+ }
126
+ function materializeEntry(id, entry) {
127
+ return {
128
+ ...entry,
129
+ id,
130
+ defaultValue: resolveNamedValueResolver(entry.defaultValueRef),
131
+ localDefaultValue: resolveNamedValueResolver(entry.localDefaultValueRef),
132
+ isRelevant: resolveNamedPredicate(entry.relevanceRef),
133
+ requiredWhen: resolveNamedPredicate(entry.requiredWhenRef)
134
+ };
135
+ }
136
+ function mergeEntryYaml(baseEntry, id, override) {
137
+ const merged = baseEntry ? deepMerge(baseEntry, override) : override;
138
+ if (typeof merged.label !== "string" || typeof merged.group !== "string" || typeof merged.description !== "string" || typeof merged.howToGet !== "string" || !Array.isArray(merged.targets) || !Array.isArray(merged.scopes) || typeof merged.requirement !== "string" || !Array.isArray(merged.purposes) || typeof merged.sensitivity !== "string") {
139
+ throw new Error(`Treeseed environment registry entry "${id}" is missing required metadata after merge.`);
140
+ }
141
+ return merged;
142
+ }
143
+ function collectOverlaySources(context) {
144
+ const sources = [];
145
+ const coreOverlay = readYamlOverlayIfPresent(CORE_ENVIRONMENT_PATH);
146
+ if (!coreOverlay) {
147
+ throw new Error(`Treeseed core environment registry file was not found at ${CORE_ENVIRONMENT_PATH}.`);
148
+ }
149
+ sources.push({ label: CORE_ENVIRONMENT_PATH, overlay: coreOverlay });
150
+ for (const pluginEntry of context.plugins) {
151
+ const fileOverlay = readPluginEnvironmentOverlay(pluginEntry.baseDir);
152
+ if (fileOverlay) {
153
+ sources.push({ label: fileOverlay.path, overlay: fileOverlay.overlay });
154
+ }
155
+ const overlaySource = pluginEntry.plugin.environmentRegistry;
156
+ if (!overlaySource) {
157
+ continue;
158
+ }
159
+ const pluginContext = {
160
+ projectRoot: context.tenantRoot,
161
+ tenantConfig: context.tenantConfig,
162
+ deployConfig: context.deployConfig,
163
+ pluginConfig: pluginEntry.config
164
+ };
165
+ const overlay = typeof overlaySource === "function" ? overlaySource(pluginContext) : overlaySource;
166
+ if (overlay) {
167
+ sources.push({
168
+ label: `plugin ${pluginEntry.package}`,
169
+ overlay: normalizeOverlay(overlay, `plugin ${pluginEntry.package}`)
170
+ });
171
+ }
172
+ }
173
+ const tenantOverlay = loadTreeseedEnvironmentOverlay(context.tenantRoot);
174
+ sources.push({ label: tenantOverlay.path, overlay: tenantOverlay.overlay });
175
+ return sources;
176
+ }
177
+ function resolveTreeseedEnvironmentContext(options = {}) {
178
+ const deployConfig = options.deployConfig ?? loadTreeseedDeployConfig();
179
+ const tenantConfig = options.tenantConfig ?? loadOptionalTenantConfig();
180
+ const plugins = options.plugins ?? loadTreeseedPlugins(deployConfig);
181
+ const tenantRoot = deployConfig.__tenantRoot ?? tenantConfig?.__tenantRoot ?? process.cwd();
182
+ return {
183
+ deployConfig,
184
+ tenantConfig,
185
+ plugins,
186
+ tenantRoot
187
+ };
188
+ }
189
+ function resolveTreeseedEnvironmentRegistry(options = {}) {
190
+ const context = resolveTreeseedEnvironmentContext(options);
191
+ const entriesById = /* @__PURE__ */ new Map();
192
+ const order = [];
193
+ for (const source of collectOverlaySources(context)) {
194
+ for (const [id, override] of Object.entries(source.overlay.entries ?? {})) {
195
+ const current = entriesById.get(id);
196
+ entriesById.set(id, mergeEntryYaml(current, id, override ?? {}));
197
+ if (!current) {
198
+ order.push(id);
199
+ }
200
+ }
201
+ }
202
+ return {
203
+ context,
204
+ entries: order.map((id) => materializeEntry(id, entriesById.get(id)))
205
+ };
206
+ }
207
+ function isTreeseedEnvironmentEntryRelevant(entry, context, scope, purpose) {
208
+ if (!entry.scopes.includes(scope)) {
209
+ return false;
210
+ }
211
+ if (purpose && !entry.purposes.includes(purpose)) {
212
+ return false;
213
+ }
214
+ if (entry.isRelevant) {
215
+ return entry.isRelevant(context, scope, purpose);
216
+ }
217
+ return true;
218
+ }
219
+ function isEntryRequired(entry, context, scope, purpose) {
220
+ if (entry.requirement === "required") {
221
+ return true;
222
+ }
223
+ if (entry.requirement === "conditional") {
224
+ return entry.requiredWhen ? entry.requiredWhen(context, scope, purpose) : true;
225
+ }
226
+ return false;
227
+ }
228
+ function materializeDefaultValue(entry, context, scope) {
229
+ const source = scope === "local" && entry.localDefaultValue !== void 0 ? entry.localDefaultValue : entry.defaultValue;
230
+ if (source === void 0) {
231
+ return void 0;
232
+ }
233
+ return typeof source === "function" ? source(context, scope) : source;
234
+ }
235
+ function getTreeseedEnvironmentSuggestedValues(options) {
236
+ const registry = resolveTreeseedEnvironmentRegistry(options);
237
+ return Object.fromEntries(
238
+ registry.entries.filter((entry) => isTreeseedEnvironmentEntryRelevant(entry, registry.context, options.scope, options.purpose)).map((entry) => [entry.id, materializeDefaultValue(entry, registry.context, options.scope)]).filter(([, value]) => value !== void 0)
239
+ );
240
+ }
241
+ function valuePresent(value) {
242
+ return typeof value === "string" && value.trim().length > 0;
243
+ }
244
+ function validateValue(entry, value) {
245
+ if (!entry.validation) {
246
+ return null;
247
+ }
248
+ switch (entry.validation.kind) {
249
+ case "string":
250
+ case "nonempty":
251
+ return valuePresent(value) ? null : `${entry.id} must be a non-empty string.`;
252
+ case "boolean":
253
+ return /^(true|false|1|0)$/i.test(value) ? null : `${entry.id} must be true or false.`;
254
+ case "number":
255
+ return Number.isFinite(Number(value)) ? null : `${entry.id} must be a number.`;
256
+ case "url":
257
+ try {
258
+ new URL(value);
259
+ return null;
260
+ } catch {
261
+ return `${entry.id} must be a valid URL.`;
262
+ }
263
+ case "email":
264
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) ? null : `${entry.id} must be a valid email address.`;
265
+ case "enum":
266
+ return entry.validation.values.includes(value) ? null : `${entry.id} must be one of: ${entry.validation.values.join(", ")}.`;
267
+ default:
268
+ return null;
269
+ }
270
+ }
271
+ function validateTreeseedEnvironmentValues(options) {
272
+ const registry = resolveTreeseedEnvironmentRegistry(options);
273
+ const relevantEntries = registry.entries.filter(
274
+ (entry) => isTreeseedEnvironmentEntryRelevant(entry, registry.context, options.scope, options.purpose)
275
+ );
276
+ const requiredEntries = relevantEntries.filter(
277
+ (entry) => isEntryRequired(entry, registry.context, options.scope, options.purpose)
278
+ );
279
+ const missing = [];
280
+ const invalid = [];
281
+ for (const entry of requiredEntries) {
282
+ const value = options.values[entry.id];
283
+ if (!valuePresent(value)) {
284
+ missing.push({
285
+ id: entry.id,
286
+ label: entry.label,
287
+ reason: "missing",
288
+ message: `${entry.id} is required for ${options.purpose} (${options.scope}). ${entry.howToGet}`,
289
+ entry
290
+ });
291
+ continue;
292
+ }
293
+ const validationMessage = validateValue(entry, value);
294
+ if (validationMessage) {
295
+ invalid.push({
296
+ id: entry.id,
297
+ label: entry.label,
298
+ reason: "invalid",
299
+ message: validationMessage,
300
+ entry
301
+ });
302
+ }
303
+ }
304
+ return {
305
+ ok: missing.length === 0 && invalid.length === 0,
306
+ entries: relevantEntries,
307
+ required: requiredEntries,
308
+ missing,
309
+ invalid
310
+ };
311
+ }
312
+ export {
313
+ TREESEED_ENVIRONMENT_PURPOSES,
314
+ TREESEED_ENVIRONMENT_REQUIREMENTS,
315
+ TREESEED_ENVIRONMENT_SCOPES,
316
+ TREESEED_ENVIRONMENT_SENSITIVITY,
317
+ TREESEED_ENVIRONMENT_TARGETS,
318
+ getTreeseedEnvironmentSuggestedValues,
319
+ isTreeseedEnvironmentEntryRelevant,
320
+ loadTreeseedEnvironmentOverlay,
321
+ resolveTreeseedEnvironmentContext,
322
+ resolveTreeseedEnvironmentRegistry,
323
+ validateTreeseedEnvironmentValues
324
+ };
package/dist/index.js ADDED
@@ -0,0 +1,81 @@
1
+ import {
2
+ defineTreeseedTenant,
3
+ getTenantContentRoot,
4
+ loadTreeseedManifest,
5
+ loadTreeseedTenantManifest,
6
+ tenantFeatureEnabled
7
+ } from "./tenant/config.js";
8
+ import { deriveCloudflareWorkerName, loadTreeseedDeployConfig, resolveTreeseedDeployConfigPath } from "./deploy/config.js";
9
+ import {
10
+ getTreeseedAgentProviderSelections,
11
+ getTreeseedDeployConfig,
12
+ getTreeseedDeployProvider,
13
+ getTreeseedDocsProvider,
14
+ getTreeseedFormsProvider,
15
+ getTreeseedSiteProvider,
16
+ isTreeseedSmtpEnabled,
17
+ isTreeseedTurnstileEnabled,
18
+ resetTreeseedDeployConfigForTests
19
+ } from "./deploy/runtime.js";
20
+ import { defineTreeseedPlugin } from "./plugins/plugin.js";
21
+ import { loadTreeseedPluginRuntime, loadTreeseedPlugins } from "./plugins/runtime.js";
22
+ import {
23
+ getTreeseedEnvironmentSuggestedValues,
24
+ isTreeseedEnvironmentEntryRelevant,
25
+ loadTreeseedEnvironmentOverlay,
26
+ resolveTreeseedEnvironmentContext,
27
+ resolveTreeseedEnvironmentRegistry,
28
+ TREESEED_ENVIRONMENT_PURPOSES,
29
+ TREESEED_ENVIRONMENT_REQUIREMENTS,
30
+ TREESEED_ENVIRONMENT_SCOPES,
31
+ TREESEED_ENVIRONMENT_SENSITIVITY,
32
+ TREESEED_ENVIRONMENT_TARGETS,
33
+ validateTreeseedEnvironmentValues
34
+ } from "./environment.js";
35
+ import {
36
+ buildTreeseedSiteLayers,
37
+ resolveTreeseedPageEntrypoint,
38
+ resolveTreeseedSiteResource,
39
+ resolveTreeseedStyleEntrypoint,
40
+ TREESEED_SITE_RESOURCE_KINDS
41
+ } from "./site-resources.js";
42
+ import { parseSiteConfig } from "./utils/site-config-schema.js";
43
+ export {
44
+ TREESEED_ENVIRONMENT_PURPOSES,
45
+ TREESEED_ENVIRONMENT_REQUIREMENTS,
46
+ TREESEED_ENVIRONMENT_SCOPES,
47
+ TREESEED_ENVIRONMENT_SENSITIVITY,
48
+ TREESEED_ENVIRONMENT_TARGETS,
49
+ TREESEED_SITE_RESOURCE_KINDS,
50
+ buildTreeseedSiteLayers,
51
+ defineTreeseedPlugin,
52
+ defineTreeseedTenant,
53
+ deriveCloudflareWorkerName,
54
+ getTenantContentRoot,
55
+ getTreeseedAgentProviderSelections,
56
+ getTreeseedDeployConfig,
57
+ getTreeseedDeployProvider,
58
+ getTreeseedDocsProvider,
59
+ getTreeseedEnvironmentSuggestedValues,
60
+ getTreeseedFormsProvider,
61
+ getTreeseedSiteProvider,
62
+ isTreeseedEnvironmentEntryRelevant,
63
+ isTreeseedSmtpEnabled,
64
+ isTreeseedTurnstileEnabled,
65
+ loadTreeseedDeployConfig,
66
+ loadTreeseedEnvironmentOverlay,
67
+ loadTreeseedManifest,
68
+ loadTreeseedPluginRuntime,
69
+ loadTreeseedPlugins,
70
+ loadTreeseedTenantManifest,
71
+ parseSiteConfig,
72
+ resetTreeseedDeployConfigForTests,
73
+ resolveTreeseedDeployConfigPath,
74
+ resolveTreeseedEnvironmentContext,
75
+ resolveTreeseedEnvironmentRegistry,
76
+ resolveTreeseedPageEntrypoint,
77
+ resolveTreeseedSiteResource,
78
+ resolveTreeseedStyleEntrypoint,
79
+ tenantFeatureEnabled,
80
+ validateTreeseedEnvironmentValues
81
+ };
@@ -0,0 +1,87 @@
1
+ ---
2
+ import MainLayout from './MainLayout.astro';
3
+ import StatusBadge from '../components/content/StatusBadge.astro';
4
+ import type { CollectionEntry } from 'astro:content';
5
+
6
+ const {
7
+ entry,
8
+ currentPath,
9
+ contributor,
10
+ metaLabel,
11
+ metaValue,
12
+ relatedQuestions = [],
13
+ relatedObjectives = [],
14
+ relatedBooks = [],
15
+ } = Astro.props as {
16
+ entry: {
17
+ title: string;
18
+ description: string;
19
+ summary: string;
20
+ status: 'live' | 'in progress' | 'exploratory' | 'planned' | 'speculative';
21
+ date: Date;
22
+ motivation: string;
23
+ tags: string[];
24
+ };
25
+ currentPath: string;
26
+ contributor: CollectionEntry<'people'> | CollectionEntry<'agents'> | undefined | null;
27
+ metaLabel?: string;
28
+ metaValue?: string;
29
+ relatedQuestions?: CollectionEntry<'questions'>[];
30
+ relatedObjectives?: CollectionEntry<'objectives'>[];
31
+ relatedBooks?: CollectionEntry<'books'>[];
32
+ };
33
+ ---
34
+
35
+ <MainLayout title={entry.title} description={entry.description} currentPath={currentPath}>
36
+ <article class="max-w-4xl space-y-8">
37
+ <div class="space-y-4 border-b border-[color:var(--site-border)] pb-8">
38
+ <div class="flex flex-wrap items-center gap-3">
39
+ <StatusBadge status={entry.status} />
40
+ <p class="text-sm font-medium text-[color:var(--site-text-soft)]">{entry.date.toISOString().slice(0, 10)}</p>
41
+ {contributor && <p class="text-sm text-[color:var(--site-text-soft)]">{contributor.data.name}</p>}
42
+ {metaLabel && metaValue && <p class="text-sm text-[color:var(--site-text-soft)]">{metaLabel}: {metaValue}</p>}
43
+ </div>
44
+ <h1 class="max-w-4xl font-serif text-5xl font-bold tracking-tight text-[color:var(--site-text)] md:text-6xl">{entry.title}</h1>
45
+ <p class="max-w-3xl text-xl leading-10 text-[color:var(--site-text-muted)]">{entry.summary}</p>
46
+ <p class="max-w-3xl text-base leading-8 text-[color:var(--site-text-muted)]">{entry.motivation}</p>
47
+ {entry.tags.length > 0 && (
48
+ <p class="text-sm uppercase tracking-[0.14em] text-[color:var(--site-accent-strong)]">{entry.tags.join(' / ')}</p>
49
+ )}
50
+ </div>
51
+ <div class="prose-karyon">
52
+ <slot />
53
+ </div>
54
+ <div class="grid gap-6 border-t border-[color:var(--site-border)] pt-8 md:grid-cols-3">
55
+ {relatedQuestions.length > 0 && (
56
+ <div>
57
+ <p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">Related questions</p>
58
+ <ul class="mt-3 space-y-2 text-[color:var(--site-text-muted)]">
59
+ {relatedQuestions.map((question) => (
60
+ <li><a href={`/questions/${question.id}/`} class="hover:text-[color:var(--site-text)]">{question.data.title}</a></li>
61
+ ))}
62
+ </ul>
63
+ </div>
64
+ )}
65
+ {relatedObjectives.length > 0 && (
66
+ <div>
67
+ <p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">Related objectives</p>
68
+ <ul class="mt-3 space-y-2 text-[color:var(--site-text-muted)]">
69
+ {relatedObjectives.map((objective) => (
70
+ <li><a href={`/objectives/${objective.id}/`} class="hover:text-[color:var(--site-text)]">{objective.data.title}</a></li>
71
+ ))}
72
+ </ul>
73
+ </div>
74
+ )}
75
+ {relatedBooks.length > 0 && (
76
+ <div>
77
+ <p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">Related books</p>
78
+ <ul class="mt-3 space-y-2 text-[color:var(--site-text-muted)]">
79
+ {relatedBooks.map((book) => (
80
+ <li><a href={`/books/${book.id}/`} class="hover:text-[color:var(--site-text)]">{book.data.title}</a></li>
81
+ ))}
82
+ </ul>
83
+ </div>
84
+ )}
85
+ </div>
86
+ </article>
87
+ </MainLayout>
@@ -0,0 +1,35 @@
1
+ ---
2
+ import MainLayout from './MainLayout.astro';
3
+
4
+ const { entry, currentPath } = Astro.props;
5
+ ---
6
+
7
+ <MainLayout title={entry.title} description={entry.description} currentPath={currentPath}>
8
+ <article class="max-w-5xl space-y-8">
9
+ <div class="space-y-4 border-b border-[color:var(--site-border)] pb-8">
10
+ <p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">{entry.sectionLabel}</p>
11
+ <h1 class="max-w-4xl font-serif text-5xl font-bold tracking-tight text-[color:var(--site-text)] md:text-6xl">{entry.title}</h1>
12
+ <p class="max-w-4xl text-xl leading-10 text-[color:var(--site-text-muted)]">{entry.summary}</p>
13
+ {entry.tags.length > 0 && (
14
+ <p class="text-sm uppercase tracking-[0.14em] text-[color:var(--site-accent-strong)]">{entry.tags.join(' / ')}</p>
15
+ )}
16
+ <div class="flex flex-wrap gap-3 pt-2">
17
+ <a href={entry.landingPath} class="border border-[color:var(--site-border-strong)] px-4 py-2 text-sm font-semibold text-[color:var(--site-text)] transition hover:border-[color:var(--site-blue)] hover:bg-[color:var(--site-blue-soft)]">Open knowledge</a>
18
+ <a href={entry.downloadHref} class="border border-[color:var(--site-accent)] bg-[color:var(--site-accent)] px-4 py-2 text-sm font-semibold text-[color:var(--site-text)] transition hover:border-[color:var(--site-blue)] hover:bg-[color:var(--site-blue-soft)]">Download book</a>
19
+ </div>
20
+ </div>
21
+ <div class="grid gap-6 md:grid-cols-[1.25fr_0.75fr]">
22
+ <div class="prose-karyon">
23
+ <slot />
24
+ </div>
25
+ <div class="border border-[color:var(--site-border)] bg-[color:var(--site-surface)] p-5">
26
+ <p class="text-sm font-semibold uppercase tracking-[0.14em] text-[color:var(--site-blue-strong)]">Book paths</p>
27
+ <ul class="mt-3 space-y-2 text-[color:var(--site-text-muted)]">
28
+ <li>Landing path: <code>{entry.landingPath}</code></li>
29
+ <li>Base path: <code>{entry.basePath}</code></li>
30
+ <li>Download file: <code>{entry.downloadFileName}</code></li>
31
+ </ul>
32
+ </div>
33
+ </div>
34
+ </article>
35
+ </MainLayout>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import MainLayout from './MainLayout.astro';
3
+
4
+ const { entry, currentPath } = Astro.props;
5
+ ---
6
+
7
+ <MainLayout title={entry.title} description={entry.description} currentPath={currentPath}>
8
+ <div class="space-y-10">
9
+ <slot />
10
+ </div>
11
+ </MainLayout>
@@ -0,0 +1,24 @@
1
+ ---
2
+ import MainLayout from './MainLayout.astro';
3
+ import StatusBadge from '../components/content/StatusBadge.astro';
4
+ import StageBanner from '../components/site/StageBanner.astro';
5
+
6
+ const { entry, currentPath } = Astro.props;
7
+ ---
8
+
9
+ <MainLayout title={entry.title} description={entry.description} currentPath={currentPath}>
10
+ <div class="space-y-8">
11
+ <StageBanner />
12
+ <section class="max-w-5xl space-y-5 border-b border-[color:var(--site-border)] pb-8">
13
+ <div class="flex flex-wrap items-center gap-3">
14
+ <StatusBadge status={entry.status} />
15
+ <p class="text-sm font-medium text-[color:var(--site-text-soft)]">Updated {entry.updated.toISOString().slice(0, 10)}</p>
16
+ </div>
17
+ <h1 class="max-w-4xl font-serif text-5xl font-bold tracking-tight text-[color:var(--site-text)] md:text-7xl">{entry.title}</h1>
18
+ <p class="max-w-4xl text-xl leading-10 text-[color:var(--site-text-muted)]">{entry.summary}</p>
19
+ </section>
20
+ <article class="prose-karyon max-w-4xl">
21
+ <slot />
22
+ </article>
23
+ </div>
24
+ </MainLayout>