pandorga 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +77 -0
  3. data/DESIGN.md +1434 -0
  4. data/LICENSE +21 -0
  5. data/README.md +81 -0
  6. data/_data/themes/dark.yml +97 -0
  7. data/_data/themes/light.yml +120 -0
  8. data/_data/themes/shared.yml +37 -0
  9. data/_data/translations.yml +85 -0
  10. data/_includes/chord-tab.html +38 -0
  11. data/_includes/content-runtime/00-config.html +22 -0
  12. data/_includes/content-runtime/10-utils.html +176 -0
  13. data/_includes/content-runtime/20-markdown.html +264 -0
  14. data/_includes/content-runtime/25-code-blocks.html +315 -0
  15. data/_includes/content-runtime/30-includes-bib.html +190 -0
  16. data/_includes/content-runtime/30-includes-xcite.html +122 -0
  17. data/_includes/content-runtime/30-includes.html +365 -0
  18. data/_includes/content-runtime/40-listing.html +225 -0
  19. data/_includes/content-runtime/41-listing-helpers.html +71 -0
  20. data/_includes/content-runtime/42-listing-filter.html +208 -0
  21. data/_includes/content-runtime/43-blocks.html +379 -0
  22. data/_includes/content-runtime/50-detail.html +861 -0
  23. data/_includes/content-runtime/55-toc.html +176 -0
  24. data/_includes/content-runtime/60-fragments.html +567 -0
  25. data/_includes/content-runtime/90-bootstrap.html +76 -0
  26. data/_includes/cut-in.html +10 -0
  27. data/_includes/cv/cv-box.html +18 -0
  28. data/_includes/dict-card.html +24 -0
  29. data/_includes/figure.html +36 -0
  30. data/_includes/home/band-index.html +43 -0
  31. data/_includes/home/band-listing.html +49 -0
  32. data/_includes/mathjax.html +10 -0
  33. data/_includes/ongoing-product.html +1 -0
  34. data/_includes/page/content-runtime.html +20 -0
  35. data/_includes/page/date_evolution.html +19 -0
  36. data/_includes/page/figure-lightbox.html +102 -0
  37. data/_includes/page/formatted_date.html +15 -0
  38. data/_includes/page/hero-default.html +18 -0
  39. data/_includes/page/listing-runtime-attrs.html +8 -0
  40. data/_includes/page/mermaid.html +101 -0
  41. data/_includes/page/network-graph.html +1253 -0
  42. data/_includes/page/page-header.html +41 -0
  43. data/_includes/page/professional-connections.html +2 -0
  44. data/_includes/page/site-footer.html +101 -0
  45. data/_includes/page/timeline-section.html +868 -0
  46. data/_includes/plotly.html +22 -0
  47. data/_includes/theme/dev-reexport.html +100 -0
  48. data/_includes/theme/favicons.html +4 -0
  49. data/_includes/theme/font-loader.html +55 -0
  50. data/_includes/theme/shell-theme-boot.html +115 -0
  51. data/_includes/theme/site-logo.html +6 -0
  52. data/_includes/theme/tailwind-theme-colors.json.liquid +65 -0
  53. data/_includes/theme/tailwind-theme-fonts.json.liquid +6 -0
  54. data/_includes/theme/theme-context.liquid +20 -0
  55. data/_includes/theme/theme-toggle.html +94 -0
  56. data/_includes/theme/theme-vars-block.liquid +161 -0
  57. data/_includes/theme/theme-vars.html +16 -0
  58. data/_includes/transcription.html +80 -0
  59. data/_includes/tweet.html +22 -0
  60. data/_includes/video.html +11 -0
  61. data/_includes/xcite.html +3 -0
  62. data/_includes/youtube-short.html +26 -0
  63. data/_includes/youtube.html +12 -0
  64. data/_layouts/article.html +27 -0
  65. data/_layouts/articles.html +534 -0
  66. data/_layouts/bibliography.html +417 -0
  67. data/_layouts/blog.html +544 -0
  68. data/_layouts/cv.html +393 -0
  69. data/_layouts/home.html +319 -0
  70. data/_layouts/network.html +9 -0
  71. data/_layouts/pandorga/articles.html +4 -0
  72. data/_layouts/pandorga/bibliography.html +4 -0
  73. data/_layouts/pandorga/blog.html +4 -0
  74. data/_layouts/pandorga/cv.html +4 -0
  75. data/_layouts/pandorga/media.html +4 -0
  76. data/_layouts/pandorga/network.html +4 -0
  77. data/_layouts/pandorga/portfolio.html +4 -0
  78. data/_layouts/post.html +7 -0
  79. data/_layouts/product.html +5 -0
  80. data/_layouts/project.html +27 -0
  81. data/_layouts/projects.html +534 -0
  82. data/_layouts/resources.html +387 -0
  83. data/_layouts/shell.html +203 -0
  84. data/_layouts/text.html +246 -0
  85. data/_plugins/bibliography_artifact.rb +57 -0
  86. data/_plugins/content_backend.rb +37 -0
  87. data/_plugins/content_collections.rb +51 -0
  88. data/_plugins/content_detail_paths.rb +58 -0
  89. data/_plugins/content_headers.rb +73 -0
  90. data/_plugins/content_keys.rb +310 -0
  91. data/_plugins/content_local_serve.rb +168 -0
  92. data/_plugins/content_site_adapter.rb +159 -0
  93. data/_plugins/content_validators_hook.rb +20 -0
  94. data/_plugins/content_writing_index.rb +52 -0
  95. data/_plugins/content_writing_paths.rb +55 -0
  96. data/_plugins/force_utf8_encoding.rb +13 -0
  97. data/_plugins/git_chronology.rb +211 -0
  98. data/_plugins/git_metadata.rb +43 -0
  99. data/_plugins/job_sections.rb +25 -0
  100. data/_plugins/lib/content_validators.rb +27 -0
  101. data/_plugins/lib/resource_validator.rb +56 -0
  102. data/_plugins/lib/tag_validator.rb +153 -0
  103. data/_plugins/lib/text_excerpt.rb +56 -0
  104. data/_plugins/lib/writing_entry.rb +107 -0
  105. data/_plugins/local_detail_rewrites.rb +194 -0
  106. data/_plugins/timeline.rb +507 -0
  107. data/_plugins/writing_slug_limits.rb +70 -0
  108. data/assets/css/article.css +1330 -0
  109. data/assets/css/base.css +1432 -0
  110. data/assets/css/cv.css +13 -0
  111. data/assets/css/global-link.css +94 -0
  112. data/assets/css/ledger/bibliography.css +307 -0
  113. data/assets/css/ledger/chrome.css +118 -0
  114. data/assets/css/ledger/cv.css +836 -0
  115. data/assets/css/ledger/detail.css +1270 -0
  116. data/assets/css/ledger/footer.css +298 -0
  117. data/assets/css/ledger/home.css +1490 -0
  118. data/assets/css/ledger/network.css +106 -0
  119. data/assets/css/ledger/projects.css +716 -0
  120. data/assets/css/ledger/rascunhos.css +379 -0
  121. data/assets/css/ledger/sources.css +327 -0
  122. data/assets/css/ledger/writing.css +754 -0
  123. data/assets/tailwind-play.js +15 -0
  124. data/examples/full/Gemfile +7 -0
  125. data/examples/full/_config.yml +92 -0
  126. data/examples/full/_redirects +3 -0
  127. data/examples/full/content/collections/articles/2026-01-01-welcome.md +9 -0
  128. data/examples/full/content/collections/data/contacts.yml +3 -0
  129. data/examples/full/content/collections/data/education.yml +4 -0
  130. data/examples/full/content/collections/jobs/research-fellow.md +12 -0
  131. data/examples/full/content/collections/posts/2026-01-02-note.md +9 -0
  132. data/examples/full/content/collections/products/ledger-tool.md +6 -0
  133. data/examples/full/content/collections/projects/demo-kit.md +10 -0
  134. data/examples/full/content/collections/resources/style-guide.md +7 -0
  135. data/examples/full/content/pages/cv/summary.md +1 -0
  136. data/examples/full/content/pages/headers.yml +20 -0
  137. data/examples/full/index.html +4 -0
  138. data/examples/minimal/Gemfile +7 -0
  139. data/examples/minimal/_config.yml +47 -0
  140. data/examples/minimal/_redirects +3 -0
  141. data/examples/minimal/content/collections/articles/2026-01-01-hello.md +10 -0
  142. data/examples/minimal/content/collections/articles/2026-01-02-second.md +9 -0
  143. data/examples/minimal/content/pages/headers.yml +6 -0
  144. data/examples/minimal/index.html +4 -0
  145. data/exe/pandorga +7 -0
  146. data/functions/api/studio/[[path]].js +562 -0
  147. data/functions/api/studio/_lib/auth.js +131 -0
  148. data/functions/api/studio/_lib/blocks.js +156 -0
  149. data/functions/api/studio/_lib/gemini.js +62 -0
  150. data/functions/api/studio/_lib/github.js +278 -0
  151. data/functions/api/studio/_lib/guidelines.js +143 -0
  152. data/functions/api/studio/_lib/paths.js +76 -0
  153. data/functions/api/studio/_lib/prompts.js +165 -0
  154. data/functions/api/studio/_lib/rate-limit.js +40 -0
  155. data/functions/api/studio/_lib/rewrite.js +136 -0
  156. data/functions/api/studio/_lib/sanitize.js +143 -0
  157. data/lib/pandorga/cli.rb +66 -0
  158. data/lib/pandorga/commands/doctor.rb +66 -0
  159. data/lib/pandorga/commands/export.rb +30 -0
  160. data/lib/pandorga/commands/install_functions.rb +41 -0
  161. data/lib/pandorga/commands/new.rb +113 -0
  162. data/lib/pandorga/commands/publish.rb +53 -0
  163. data/lib/pandorga/commands/serve.rb +34 -0
  164. data/lib/pandorga/commands/studio_schema.rb +309 -0
  165. data/lib/pandorga/jekyll/generator.rb +74 -0
  166. data/lib/pandorga/jekyll/plugins/bibliography_artifact.rb +57 -0
  167. data/lib/pandorga/jekyll/plugins/content_backend.rb +37 -0
  168. data/lib/pandorga/jekyll/plugins/content_collections.rb +51 -0
  169. data/lib/pandorga/jekyll/plugins/content_detail_paths.rb +58 -0
  170. data/lib/pandorga/jekyll/plugins/content_headers.rb +73 -0
  171. data/lib/pandorga/jekyll/plugins/content_keys.rb +310 -0
  172. data/lib/pandorga/jekyll/plugins/content_local_serve.rb +168 -0
  173. data/lib/pandorga/jekyll/plugins/content_site_adapter.rb +159 -0
  174. data/lib/pandorga/jekyll/plugins/content_validators_hook.rb +20 -0
  175. data/lib/pandorga/jekyll/plugins/content_writing_index.rb +52 -0
  176. data/lib/pandorga/jekyll/plugins/content_writing_paths.rb +55 -0
  177. data/lib/pandorga/jekyll/plugins/force_utf8_encoding.rb +13 -0
  178. data/lib/pandorga/jekyll/plugins/git_chronology.rb +211 -0
  179. data/lib/pandorga/jekyll/plugins/git_metadata.rb +43 -0
  180. data/lib/pandorga/jekyll/plugins/job_sections.rb +25 -0
  181. data/lib/pandorga/jekyll/plugins/lib/content_validators.rb +27 -0
  182. data/lib/pandorga/jekyll/plugins/lib/resource_validator.rb +56 -0
  183. data/lib/pandorga/jekyll/plugins/lib/tag_validator.rb +153 -0
  184. data/lib/pandorga/jekyll/plugins/lib/text_excerpt.rb +56 -0
  185. data/lib/pandorga/jekyll/plugins/lib/writing_entry.rb +107 -0
  186. data/lib/pandorga/jekyll/plugins/local_detail_rewrites.rb +194 -0
  187. data/lib/pandorga/jekyll/plugins/timeline.rb +507 -0
  188. data/lib/pandorga/jekyll/plugins/writing_slug_limits.rb +70 -0
  189. data/lib/pandorga/jekyll.rb +15 -0
  190. data/lib/pandorga/object_store_env.rb +51 -0
  191. data/lib/pandorga/registry/schema.yml +115 -0
  192. data/lib/pandorga/registry.rb +279 -0
  193. data/lib/pandorga/version.rb +5 -0
  194. data/lib/pandorga.rb +19 -0
  195. data/scripts/cdn-allowlist.json +19 -0
  196. data/scripts/content/backfill-content-keys.rb +99 -0
  197. data/scripts/content/band_art.rb +362 -0
  198. data/scripts/content/export-content-json.rb +741 -0
  199. data/scripts/content/flatten-ansi-capture.mjs +153 -0
  200. data/scripts/content/hero_portraits.rb +28 -0
  201. data/scripts/content/publish-content-to-object-store.sh +78 -0
  202. data/scripts/content/publish-content-to-r2.sh +5 -0
  203. data/scripts/content/sync-content-json-to-r2.rb +167 -0
  204. data/scripts/content/sync-content-redirects.rb +12 -0
  205. data/scripts/generate-configuration-doc.rb +127 -0
  206. data/scripts/lib/content_license.rb +50 -0
  207. data/scripts/lib/content_storage_config.rb +70 -0
  208. data/scripts/lib/normalize-display-math.mjs +52 -0
  209. data/scripts/lib/r2_json_sync.rb +76 -0
  210. data/scripts/lib/withdrawn_public_objects.rb +23 -0
  211. data/scripts/lib/writing_index_contract.rb +61 -0
  212. data/scripts/pdf/md-to-pdf.mjs +1400 -0
  213. data/scripts/pdf/md-to-pdf.sh +27 -0
  214. data/scripts/test/fixtures/dual-template/_config.yml +32 -0
  215. data/scripts/test/fixtures/dual-template/index.html +4 -0
  216. data/scripts/test/render-parity/article-note.json +5 -0
  217. data/scripts/test/render-parity/blockquote.json +5 -0
  218. data/scripts/test/render-parity/blocks/ansi-basic.json +7 -0
  219. data/scripts/test/render-parity/blocks/ansi-bold-is-bright.json +7 -0
  220. data/scripts/test/render-parity/blocks/ansi-drops-cursor-moves.json +7 -0
  221. data/scripts/test/render-parity/blocks/ansi-escapes-markup.json +7 -0
  222. data/scripts/test/render-parity/blocks/ansi-extended-colour.json +7 -0
  223. data/scripts/test/render-parity/blocks/ansi-real-control-byte.json +7 -0
  224. data/scripts/test/render-parity/blocks/archive-card-date-once.json +19 -0
  225. data/scripts/test/render-parity/blocks/archive-card-empty-foot.json +7 -0
  226. data/scripts/test/render-parity/blocks/archive-card-footer-dates.json +22 -0
  227. data/scripts/test/render-parity/blocks/archive-card-meta-parts.json +26 -0
  228. data/scripts/test/render-parity/blocks/archive-card.json +32 -0
  229. data/scripts/test/render-parity/blocks/cta-link.json +13 -0
  230. data/scripts/test/render-parity/blocks/lang-pill-pt.json +8 -0
  231. data/scripts/test/render-parity/blocks/lang-pill.json +8 -0
  232. data/scripts/test/render-parity/blocks/ledger-row-meta-parts.json +29 -0
  233. data/scripts/test/render-parity/blocks/ledger-row.json +35 -0
  234. data/scripts/test/render-parity/blocks/meta-strip.json +27 -0
  235. data/scripts/test/render-parity/blocks/poster-media-image.json +8 -0
  236. data/scripts/test/render-parity/blocks/poster-media-video.json +9 -0
  237. data/scripts/test/render-parity/blocks/section-banner.json +13 -0
  238. data/scripts/test/render-parity/blocks/system-card-custom-meta.json +22 -0
  239. data/scripts/test/render-parity/blocks/system-card.json +48 -0
  240. data/scripts/test/render-parity/blocks/tag-chips-links.json +12 -0
  241. data/scripts/test/render-parity/blocks/tag-chips.json +9 -0
  242. data/scripts/test/render-parity/cut-in-blank-line.json +9 -0
  243. data/scripts/test/render-parity/cut-in-right.json +9 -0
  244. data/scripts/test/render-parity/cut-in.json +8 -0
  245. data/scripts/test/render-parity/figure.json +5 -0
  246. data/scripts/test/render-parity/load-runtime.mjs +337 -0
  247. data/scripts/test/render-parity/ongoing-product.json +5 -0
  248. data/scripts/test/render-parity/plotly.json +5 -0
  249. data/scripts/test/render-parity/poem.json +5 -0
  250. data/scripts/test/render-parity/run-absent-field-checks.mjs +232 -0
  251. data/scripts/test/render-parity/run-block-fixture.mjs +86 -0
  252. data/scripts/test/render-parity/run-detail-parity-checks.mjs +123 -0
  253. data/scripts/test/render-parity/run-field-flow-checks.mjs +227 -0
  254. data/scripts/test/render-parity/run-fixture.mjs +159 -0
  255. data/scripts/test/render-parity/selectors.mjs +43 -0
  256. data/scripts/test/render-parity/video.json +5 -0
  257. data/scripts/test/render-parity/youtube-short.json +10 -0
  258. data/scripts/test/render-parity/youtube.json +8 -0
  259. data/scripts/test/test-absent-field-absent-element.rb +43 -0
  260. data/scripts/test/test-cdn-pins.rb +44 -0
  261. data/scripts/test/test-cloudflare-watch-paths-doc.rb +31 -0
  262. data/scripts/test/test-configuration-doc.rb +36 -0
  263. data/scripts/test/test-content-detail-urls.rb +346 -0
  264. data/scripts/test/test-content-keys.rb +110 -0
  265. data/scripts/test/test-content-license.rb +45 -0
  266. data/scripts/test/test-content-render-parity.rb +38 -0
  267. data/scripts/test/test-content-validators.rb +12 -0
  268. data/scripts/test/test-css-structure.rb +72 -0
  269. data/scripts/test/test-cv-export-contract.rb +158 -0
  270. data/scripts/test/test-detail-render-parity.rb +40 -0
  271. data/scripts/test/test-dev-reexport.rb +122 -0
  272. data/scripts/test/test-doctor.rb +39 -0
  273. data/scripts/test/test-dual-template-instances.rb +87 -0
  274. data/scripts/test/test-dual-template-runtime.rb +167 -0
  275. data/scripts/test/test-examples-build.rb +60 -0
  276. data/scripts/test/test-export-content-json-incremental.rb +138 -0
  277. data/scripts/test/test-export.rb +53 -0
  278. data/scripts/test/test-exported-fields-reach-the-view.rb +60 -0
  279. data/scripts/test/test-form-control-theming.rb +143 -0
  280. data/scripts/test/test-git-chronology.rb +414 -0
  281. data/scripts/test/test-hero-portraits.mjs +97 -0
  282. data/scripts/test/test-hero-portraits.rb +162 -0
  283. data/scripts/test/test-home-band-art.rb +135 -0
  284. data/scripts/test/test-install-functions.rb +39 -0
  285. data/scripts/test/test-language-export.rb +79 -0
  286. data/scripts/test/test-listing-filter-contract.rb +119 -0
  287. data/scripts/test/test-math-row-breaks.mjs +79 -0
  288. data/scripts/test/test-math-row-breaks.rb +18 -0
  289. data/scripts/test/test-new.rb +113 -0
  290. data/scripts/test/test-no-personal-data.rb +85 -0
  291. data/scripts/test/test-public-cv-export.rb +164 -0
  292. data/scripts/test/test-r2-config-consistency.rb +57 -0
  293. data/scripts/test/test-r2-json-sync.rb +193 -0
  294. data/scripts/test/test-registry-home.rb +34 -0
  295. data/scripts/test/test-runtime-js-syntax.rb +64 -0
  296. data/scripts/test/test-slim-writing-index.rb +126 -0
  297. data/scripts/test/test-studio-api-contract.rb +99 -0
  298. data/scripts/test/test-studio-content-files.rb +79 -0
  299. data/scripts/test/test-studio-liquid-roundtrip.mjs +179 -0
  300. data/scripts/test/test-studio-rate-limit.mjs +70 -0
  301. data/scripts/test/test-studio-rewrite-api-contract.rb +59 -0
  302. data/scripts/test/test-studio-rewrite-sanitize.mjs +210 -0
  303. data/scripts/test/test-studio-schema-composition.rb +126 -0
  304. data/scripts/test/test-studio-slug-config.rb +167 -0
  305. data/scripts/test/test-template-packages.rb +51 -0
  306. data/scripts/test/test-text-excerpt.rb +51 -0
  307. data/scripts/test/test-unwrap-media-src.mjs +39 -0
  308. data/scripts/test/test-unwrap-media-src.rb +19 -0
  309. data/scripts/test/test-withdrawn-content-export.rb +69 -0
  310. data/scripts/test/test-writing-index-export-slugs.rb +84 -0
  311. data/scripts/test/test-writing-slug-limits.rb +61 -0
  312. data/scripts/test/test-xcite-chronology.rb +106 -0
  313. data/scripts/validate.sh +74 -0
  314. data/scripts/visual/build-cv-pages-json.js +33 -0
  315. data/scripts/visual/build-site-pages-json.js +94 -0
  316. data/scripts/visual/publish-visual-inspection-to-r2.sh +42 -0
  317. data/scripts/visual/take-screenshots.js +88 -0
  318. data/scripts/visual/visual-inspection-pages.json +113 -0
  319. data/studio/assets/index-B_j0pMD5.css +1 -0
  320. data/studio/assets/index-Ch4YEv9g.js +285 -0
  321. data/studio/index.html +27 -0
  322. data/studio/schema.yml +869 -0
  323. data/studio-app/README.md +27 -0
  324. data/studio-app/index.html +26 -0
  325. data/studio-app/package-lock.json +2499 -0
  326. data/studio-app/package.json +26 -0
  327. data/studio-app/skills-lock.json +47 -0
  328. data/studio-app/src/api/client.js +71 -0
  329. data/studio-app/src/editor/body-editor.js +70 -0
  330. data/studio-app/src/editor/liquid-core.js +382 -0
  331. data/studio-app/src/editor/liquid.js +77 -0
  332. data/studio-app/src/lib/document.js +207 -0
  333. data/studio-app/src/lib/list-controls.js +317 -0
  334. data/studio-app/src/lib/schema.js +66 -0
  335. data/studio-app/src/lib/yaml-doc.js +100 -0
  336. data/studio-app/src/main.js +3693 -0
  337. data/studio-app/src/media/browser.js +578 -0
  338. data/studio-app/src/preview/render.js +430 -0
  339. data/studio-app/src/styles/studio.css +2826 -0
  340. data/studio-app/vite.config.js +25 -0
  341. data/templates/articles/README.md +40 -0
  342. data/templates/articles/fixtures/article.md +9 -0
  343. data/templates/articles/screenshots/README.md +6 -0
  344. data/templates/articles/studio.yml +73 -0
  345. data/templates/articles/template.yml +21 -0
  346. data/templates/bibliography/README.md +41 -0
  347. data/templates/bibliography/fixtures/references.json +9 -0
  348. data/templates/bibliography/screenshots/README.md +6 -0
  349. data/templates/bibliography/studio.yml +66 -0
  350. data/templates/bibliography/template.yml +18 -0
  351. data/templates/blog/README.md +38 -0
  352. data/templates/blog/fixtures/post.md +9 -0
  353. data/templates/blog/screenshots/README.md +6 -0
  354. data/templates/blog/studio.yml +69 -0
  355. data/templates/blog/template.yml +20 -0
  356. data/templates/cv/README.md +34 -0
  357. data/templates/cv/fixtures/job.md +12 -0
  358. data/templates/cv/screenshots/README.md +6 -0
  359. data/templates/cv/studio.yml +200 -0
  360. data/templates/cv/template.yml +25 -0
  361. data/templates/media/README.md +38 -0
  362. data/templates/media/fixtures/resource.md +7 -0
  363. data/templates/media/screenshots/README.md +6 -0
  364. data/templates/media/studio.yml +58 -0
  365. data/templates/media/template.yml +17 -0
  366. data/templates/network/README.md +34 -0
  367. data/templates/network/fixtures/sources.json +3 -0
  368. data/templates/network/screenshots/README.md +6 -0
  369. data/templates/network/studio.yml +28 -0
  370. data/templates/network/template.yml +10 -0
  371. data/templates/portfolio/README.md +39 -0
  372. data/templates/portfolio/fixtures/project.md +10 -0
  373. data/templates/portfolio/screenshots/README.md +6 -0
  374. data/templates/portfolio/studio.yml +89 -0
  375. data/templates/portfolio/template.yml +18 -0
  376. metadata +505 -0
@@ -0,0 +1,25 @@
1
+ import { defineConfig } from "vite";
2
+ import path from "node:path";
3
+
4
+ export default defineConfig({
5
+ root: ".",
6
+ base: "/studio/",
7
+ publicDir: false,
8
+ build: {
9
+ outDir: path.resolve(__dirname, "../studio"),
10
+ emptyOutDir: false,
11
+ assetsDir: "assets",
12
+ rollupOptions: {
13
+ input: path.resolve(__dirname, "index.html"),
14
+ },
15
+ },
16
+ server: {
17
+ port: 5173,
18
+ proxy: {
19
+ "/api/studio": {
20
+ target: process.env.STUDIO_API_PROXY || "http://127.0.0.1:8788",
21
+ changeOrigin: true,
22
+ },
23
+ },
24
+ },
25
+ });
@@ -0,0 +1,40 @@
1
+ # Template: articles
2
+
3
+ Writing collection rendered as a card grid with an optional featured item.
4
+ Shares the writing contract with `blog`; only presentation differs.
5
+
6
+ ## Required registry keys
7
+
8
+ | Key | Role |
9
+ |---|---|
10
+ | `key` | Page id |
11
+ | `template` | Must be `articles` |
12
+ | `collection` | Writing collection folder under `content/collections/` |
13
+ | `path` | Listing URL |
14
+ | `detail` | Detail route pattern, for example `/articles/:slug/` |
15
+
16
+ Optional: `title`, `language`, `accent`, `nav`, `home`, `taxonomy`.
17
+
18
+ ## Collection contract
19
+
20
+ `title`, `key`, `date`, `tags`, `language`, `thumbnail`, Markdown body.
21
+
22
+ ## Configuration
23
+
24
+ ```yaml
25
+ - key: articles
26
+ template: articles
27
+ collection: articles
28
+ path: /pages/articles/
29
+ detail: /articles/:slug/
30
+ ```
31
+
32
+ The same template may be registered twice with different `key`, `collection`,
33
+ and `path` values. Each instance gets its own listing page.
34
+
35
+ ## Package layout
36
+
37
+ - `template.yml` — slots, detail route, export fields
38
+ - `studio.yml` — Studio field schema for the collection slot
39
+ - `fixtures/` — minimal sample front matter
40
+ - `screenshots/` — capture notes (manual or CI later)
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: Welcome article
3
+ key: welcome
4
+ date: 2026-01-01
5
+ tags: [Writing]
6
+ language: en
7
+ ---
8
+
9
+ Fictional sample for the articles template fixture.
@@ -0,0 +1,6 @@
1
+ # Screenshots
2
+
3
+ Capture the articles listing (grid plus featured lead when present) manually
4
+ or in CI visual inspection. PLT-AC-4 requires a screenshot for this template;
5
+ place PNG or WebP files here when available. This directory fulfills the
6
+ package contract until automated capture lands.
@@ -0,0 +1,73 @@
1
+ # Studio fragment for the articles writing template.
2
+ # Refs: PLT-AC-3, docs/spec.md §5.5
3
+ group: writing
4
+ group_label: Writing
5
+ needs_media: true
6
+ collection:
7
+ label: Articles
8
+ type: collection
9
+ format: yaml-frontmatter
10
+ filename: "{year}-{month}-{day}-{key}.md"
11
+ operations:
12
+ delete: false
13
+ view:
14
+ primary: title
15
+ fields: [thumbnail, title, date, published, language, key]
16
+ list_meta_fields: [date, language]
17
+ fields:
18
+ - name: layout
19
+ label: Layout
20
+ type: string
21
+ hidden: true
22
+ default: article
23
+ - name: key
24
+ label: Key
25
+ type: string
26
+ required: true
27
+ description: "URL slug and citation handle. Filename stem: YYYY-MM-DD-key.md."
28
+ - name: title
29
+ label: Title
30
+ type: string
31
+ required: true
32
+ - name: description
33
+ label: Description
34
+ type: text
35
+ description: "Deck under the title and link-preview text."
36
+ - name: date
37
+ label: Date
38
+ type: date
39
+ required: true
40
+ options:
41
+ format: yyyy-MM-dd
42
+ time: false
43
+ - name: tags
44
+ label: Tags
45
+ type: select
46
+ description: "Up to three. Empty is valid."
47
+ options:
48
+ multiple: true
49
+ max: 3
50
+ values: [Writing, Research, Notes]
51
+ - name: language
52
+ label: Language
53
+ type: select
54
+ options:
55
+ values: [enus, ptbr, frfr, eses]
56
+ - name: thumbnail
57
+ label: Thumbnail
58
+ type: image
59
+ description: "HTTPS URL or /media/… path."
60
+ options:
61
+ media: images
62
+ path: content/media/images/covers/articles
63
+ rename: safe
64
+ - name: published
65
+ label: Published
66
+ type: boolean
67
+ default: true
68
+ - name: redirects
69
+ label: Redirects
70
+ type: string
71
+ list: true
72
+ - name: body
73
+ component: markdown_body
@@ -0,0 +1,21 @@
1
+ name: articles
2
+ collection_slots:
3
+ - name: collection
4
+ required: true
5
+ contract: writing
6
+ detail: /articles/:slug/
7
+ nav:
8
+ group: Writing
9
+ home:
10
+ featured: true
11
+ limit: 3
12
+ export_fields:
13
+ - title
14
+ - key
15
+ - date
16
+ - tags
17
+ - language
18
+ - thumbnail
19
+ - description
20
+ - author
21
+ - body
@@ -0,0 +1,41 @@
1
+ # Template: bibliography
2
+
3
+ Citation index built from a bibliography collection plus writings listed in
4
+ `cited_by`. No per-item detail route; the listing is the page.
5
+
6
+ ## Required registry keys
7
+
8
+ | Key | Role |
9
+ |---|---|
10
+ | `key` | Page id |
11
+ | `template` | Must be `bibliography` |
12
+ | `collection` | Bibliography folder under `content/collections/` |
13
+ | `cited_by` | Array of writing page keys that cite entries |
14
+ | `path` | Listing URL |
15
+
16
+ Optional: `title`, `nav` (often `false`), `home` (default is a references
17
+ index panel).
18
+
19
+ ## Collection contract
20
+
21
+ Bibliography data as BibTeX or JSON under the collection folder; writings
22
+ reference keys via includes such as `xcite`.
23
+
24
+ ## Configuration
25
+
26
+ ```yaml
27
+ - key: bibliography
28
+ template: bibliography
29
+ title: Bibliography
30
+ collection: bibliography
31
+ cited_by: [articles, blog]
32
+ path: /pages/bibliography/
33
+ nav: false
34
+ home: { band: index, group: references }
35
+ ```
36
+
37
+ ## Package layout
38
+
39
+ - `template.yml` — slots and home defaults
40
+ - `fixtures/` — minimal sample bibliography JSON
41
+ - `screenshots/` — capture notes (manual or CI later)
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "key": "example2026",
4
+ "title": "Example Paper",
5
+ "year": "2026",
6
+ "author": "Ada Example",
7
+ "type": "article"
8
+ }
9
+ ]
@@ -0,0 +1,6 @@
1
+ # Screenshots
2
+
3
+ Capture the bibliography listing manually or in CI visual inspection.
4
+ PLT-AC-4 requires a screenshot for this template; place PNG or WebP files
5
+ here when available. This directory fulfills the package contract until
6
+ automated capture lands.
@@ -0,0 +1,66 @@
1
+ # Studio fragment for the bibliography template.
2
+ # Refs: PLT-AC-3, docs/spec.md §5.5
3
+ group: references
4
+ group_label: References
5
+ collection:
6
+ label: Bibliography
7
+ type: collection
8
+ format: yaml
9
+ filename: "{primary}.yml"
10
+ operations:
11
+ delete: false
12
+ view:
13
+ primary: title
14
+ fields: [type, title, author, year]
15
+ list_meta_fields: [key]
16
+ fields:
17
+ - name: type
18
+ label: Type
19
+ type: select
20
+ default: misc
21
+ options:
22
+ values: [article, book, incollection, misc, techreport]
23
+ - name: title
24
+ label: Title
25
+ type: string
26
+ - name: author
27
+ label: Author
28
+ type: string
29
+ description: "Lastname, Firstname and Lastname2, Firstname2"
30
+ - name: year
31
+ label: Year
32
+ type: string
33
+ - name: url
34
+ label: URL
35
+ type: string
36
+ - name: doi
37
+ label: DOI
38
+ type: string
39
+ description: "Without URL prefix."
40
+ - name: journal
41
+ label: Journal
42
+ type: string
43
+ - name: publisher
44
+ label: Publisher
45
+ type: string
46
+ - name: institution
47
+ label: Institution
48
+ type: string
49
+ - name: howpublished
50
+ label: How published
51
+ type: string
52
+ - name: volume
53
+ label: Volume
54
+ type: string
55
+ - name: number
56
+ label: Number
57
+ type: string
58
+ - name: pages
59
+ label: Pages
60
+ type: string
61
+ - name: month
62
+ label: Month
63
+ type: string
64
+ - name: note
65
+ label: Note
66
+ type: text
@@ -0,0 +1,18 @@
1
+ name: bibliography
2
+ collection_slots:
3
+ - name: collection
4
+ required: true
5
+ contract: bibliography
6
+ cited_by:
7
+ required: true
8
+ description: Writing page keys whose citations feed this index
9
+ nav: false
10
+ home:
11
+ band: index
12
+ group: references
13
+ export_fields:
14
+ - key
15
+ - title
16
+ - year
17
+ - author
18
+ - type
@@ -0,0 +1,38 @@
1
+ # Template: blog
2
+
3
+ Writing collection rendered as a dense ledger list with month bands and
4
+ folio numbers. Shares the writing contract with `articles`; only
5
+ presentation differs.
6
+
7
+ ## Required registry keys
8
+
9
+ | Key | Role |
10
+ |---|---|
11
+ | `key` | Page id |
12
+ | `template` | Must be `blog` |
13
+ | `collection` | Writing collection folder under `content/collections/` |
14
+ | `path` | Listing URL |
15
+ | `detail` | Detail route pattern, for example `/posts/:slug/` |
16
+
17
+ Optional: `title`, `language`, `accent`, `nav`, `home`, `taxonomy`.
18
+
19
+ ## Collection contract
20
+
21
+ `title`, `key`, `date`, `tags`, `language`, `thumbnail`, Markdown body.
22
+
23
+ ## Configuration
24
+
25
+ ```yaml
26
+ - key: blog
27
+ template: blog
28
+ title: Drafts
29
+ collection: posts
30
+ path: /pages/blog/
31
+ detail: /posts/:slug/
32
+ ```
33
+
34
+ ## Package layout
35
+
36
+ - `template.yml` — slots, detail route, export fields
37
+ - `fixtures/` — minimal sample front matter
38
+ - `screenshots/` — capture notes (manual or CI later)
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: A short draft note
3
+ key: note
4
+ date: 2026-01-02
5
+ tags: [notes]
6
+ language: en
7
+ ---
8
+
9
+ Fictional draft for the blog template fixture.
@@ -0,0 +1,6 @@
1
+ # Screenshots
2
+
3
+ Capture the blog ledger listing manually or in CI visual inspection.
4
+ PLT-AC-4 requires a screenshot for this template; place PNG or WebP files
5
+ here when available. This directory fulfills the package contract until
6
+ automated capture lands.
@@ -0,0 +1,69 @@
1
+ # Studio fragment for the blog writing template.
2
+ # Refs: PLT-AC-3, docs/spec.md §5.5
3
+ group: writing
4
+ group_label: Writing
5
+ needs_media: true
6
+ collection:
7
+ label: Posts
8
+ type: collection
9
+ format: yaml-frontmatter
10
+ filename: "{year}-{month}-{day}-{key}.md"
11
+ operations:
12
+ delete: false
13
+ view:
14
+ primary: title
15
+ fields: [thumbnail, title, date, published, language, key]
16
+ list_meta_fields: [date, language]
17
+ fields:
18
+ - name: layout
19
+ label: Layout
20
+ type: string
21
+ hidden: true
22
+ default: post
23
+ - name: key
24
+ label: Key
25
+ type: string
26
+ required: true
27
+ description: "URL slug and citation handle. Filename stem: YYYY-MM-DD-key.md."
28
+ - name: title
29
+ label: Title
30
+ type: string
31
+ required: true
32
+ - name: date
33
+ label: Date
34
+ type: date
35
+ required: true
36
+ options:
37
+ format: yyyy-MM-dd
38
+ time: false
39
+ - name: tags
40
+ label: Tags
41
+ type: select
42
+ description: "Up to three. Empty is valid."
43
+ options:
44
+ multiple: true
45
+ max: 3
46
+ values: [Notes, Drafts, Ideas]
47
+ - name: language
48
+ label: Language
49
+ type: select
50
+ options:
51
+ values: [enus, ptbr, frfr, eses]
52
+ - name: thumbnail
53
+ label: Thumbnail
54
+ type: image
55
+ description: "HTTPS URL or /media/… path."
56
+ options:
57
+ media: images
58
+ path: content/media/images/covers/posts
59
+ rename: safe
60
+ - name: published
61
+ label: Published
62
+ type: boolean
63
+ default: true
64
+ - name: redirects
65
+ label: Redirects
66
+ type: string
67
+ list: true
68
+ - name: body
69
+ component: markdown_body
@@ -0,0 +1,20 @@
1
+ name: blog
2
+ collection_slots:
3
+ - name: collection
4
+ required: true
5
+ contract: writing
6
+ detail: /posts/:slug/
7
+ nav:
8
+ group: Writing
9
+ home:
10
+ limit: 4
11
+ export_fields:
12
+ - title
13
+ - key
14
+ - date
15
+ - tags
16
+ - language
17
+ - thumbnail
18
+ - description
19
+ - author
20
+ - body
@@ -0,0 +1,34 @@
1
+ # Template: cv
2
+
3
+ Public curriculum page: jobs, products, skills, education, and contacts from
4
+ data collections. Only fields listed in the contract leave the repository on
5
+ export (`body_public` and the allowlisted job fields).
6
+
7
+ ## Required registry keys
8
+
9
+ | Key | Role |
10
+ |---|---|
11
+ | `key` | Page id (nav, headers, Studio) |
12
+ | `template` | Must be `cv` |
13
+ | `path` | Listing URL, for example `/pages/cv/` |
14
+ | `collections` | Map of slots: at least `jobs` and `products` (folder names under `content/collections/`) |
15
+
16
+ Optional: `title`, `nav`, `home` (default band is `hero`).
17
+
18
+ ## Configuration
19
+
20
+ ```yaml
21
+ - key: cv
22
+ template: cv
23
+ title: Curriculum Vitæ
24
+ path: /pages/cv/
25
+ collections: { jobs: jobs, products: products }
26
+ nav: { group: Profile, icon: article_person }
27
+ home: { band: hero }
28
+ ```
29
+
30
+ ## Package layout
31
+
32
+ - `template.yml` — slots and home defaults
33
+ - `fixtures/` — minimal sample front matter
34
+ - `screenshots/` — capture notes (manual or CI later)
@@ -0,0 +1,12 @@
1
+ ---
2
+ title: Research Fellow
3
+ key: research-fellow
4
+ company: Example Labs
5
+ role: Research Fellow
6
+ start: 2024-01
7
+ end: 2026-06
8
+ location: Example City
9
+ summary: Fictional public CV entry.
10
+ ---
11
+
12
+ Public summary only.
@@ -0,0 +1,6 @@
1
+ # Screenshots
2
+
3
+ Capture the CV listing (and optional print view) manually or in CI visual
4
+ inspection. PLT-AC-4 requires a screenshot for this template; place PNG or
5
+ WebP files here when available. This directory fulfills the package contract
6
+ until automated capture lands.