hd-garden 0.8.0 → 0.8.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 (187) hide show
  1. package/.agents/skills/garden-ui/SKILL.md +2 -2
  2. package/.env.en.example +67 -0
  3. package/README.en.md +2 -2
  4. package/README.md +2 -2
  5. package/app/a2/[slug]/page.tsx +4 -3
  6. package/app/a2/page.tsx +4 -3
  7. package/app/about/page.tsx +8 -9
  8. package/app/admin/page.tsx +7 -6
  9. package/app/admin/preview/[...path]/page.tsx +2 -1
  10. package/app/admin/ui/blocks/page.tsx +2 -1
  11. package/app/admin/ui/catalog/page.tsx +2 -1
  12. package/app/admin/ui/evals/page.tsx +2 -1
  13. package/app/admin/ui/page.tsx +2 -1
  14. package/app/blog/[...path]/page.tsx +7 -6
  15. package/app/blog/page.tsx +4 -2
  16. package/app/columns/[column]/[...path]/page.tsx +8 -7
  17. package/app/columns/page.tsx +12 -8
  18. package/app/components/AdminUiShell.tsx +4 -3
  19. package/app/components/ArticleMeasure.tsx +6 -3
  20. package/app/components/ArticleReferences.tsx +4 -1
  21. package/app/components/ArticleTags.tsx +3 -2
  22. package/app/components/BlogArchive.tsx +20 -16
  23. package/app/components/Comments.tsx +16 -10
  24. package/app/components/ContentEmptyState.tsx +29 -28
  25. package/app/components/ExternalEmbed.tsx +15 -14
  26. package/app/components/GardenContentGuide.tsx +10 -2
  27. package/app/components/GardenDocsNav.tsx +4 -2
  28. package/app/components/GiscusComments.tsx +2 -1
  29. package/app/components/GithubLiveOverview.tsx +10 -8
  30. package/app/components/GithubProfile.tsx +31 -21
  31. package/app/components/HandbookLangSwitch.tsx +8 -4
  32. package/app/components/HandbookView.tsx +92 -9
  33. package/app/components/MarkdownArticle.tsx +31 -7
  34. package/app/components/MermaidDiagram.tsx +4 -3
  35. package/app/components/SiteChrome.tsx +3 -3
  36. package/app/components/SiteFooter.tsx +1 -1
  37. package/app/components/SiteHeader.tsx +13 -4
  38. package/app/components/ThoughtCard.tsx +16 -14
  39. package/app/components/UiBlock.tsx +3 -2
  40. package/app/components/Webmentions.tsx +11 -11
  41. package/app/components/WidgetChart.tsx +8 -6
  42. package/app/components/garden/FilePreview.tsx +2 -2
  43. package/app/components/garden/GardenBlock.tsx +7 -0
  44. package/app/components/garden/GardenFile.tsx +2 -2
  45. package/app/components/garden/RefDemo.tsx +62 -0
  46. package/app/components/garden/blocks.tsx +56 -8
  47. package/app/components/garden/patterns.tsx +497 -0
  48. package/app/garden/[...slug]/page.tsx +3 -2
  49. package/app/garden/en/page.tsx +7 -7
  50. package/app/garden/page.tsx +3 -2
  51. package/app/globals.css +49 -1
  52. package/app/lib/a2-meta.ts +26 -3
  53. package/app/lib/content.ts +2 -2
  54. package/app/lib/garden-docs-meta.ts +24 -0
  55. package/app/lib/github-id.mjs +8 -0
  56. package/app/lib/handbook-switch.mjs +12 -0
  57. package/app/lib/i18n.ts +401 -2
  58. package/app/lib/rehype-field-tables.mjs +47 -0
  59. package/app/lib/remark-a2.mjs +18 -8
  60. package/app/lib/remark-link-card.mjs +22 -0
  61. package/app/lib/remark-ref-demos.mjs +42 -0
  62. package/app/lib/tag-filter.ts +9 -2
  63. package/app/not-found.tsx +32 -4
  64. package/app/page.tsx +17 -14
  65. package/app/rss.xml/route.ts +2 -1
  66. package/app/styles/a2.css +338 -0
  67. package/app/styles/shell.css +15 -2
  68. package/app/tags/page.tsx +7 -5
  69. package/app/thoughts/[slug]/page.tsx +2 -1
  70. package/app/thoughts/page/[n]/page.tsx +1 -1
  71. package/app/thoughts/page.tsx +2 -1
  72. package/app/ui-parity/page.tsx +38 -22
  73. package/bin/garden.mjs +129 -19
  74. package/docs/handbook/ai-writing.md +2 -2
  75. package/docs/handbook/assets/reading-layout-en.svg +26 -0
  76. package/docs/handbook/components/card.md +43 -22
  77. package/docs/handbook/components/chart.md +10 -26
  78. package/docs/handbook/components/choice.md +42 -0
  79. package/docs/handbook/components/compare.md +32 -17
  80. package/docs/handbook/components/figure.md +33 -46
  81. package/docs/handbook/components/file.md +10 -15
  82. package/docs/handbook/components/html.md +10 -30
  83. package/docs/handbook/components/interactive.md +9 -35
  84. package/docs/handbook/components/list.md +65 -0
  85. package/docs/handbook/components/relations.md +95 -0
  86. package/docs/handbook/components/stat.md +10 -28
  87. package/docs/handbook/components/timeline.md +13 -28
  88. package/docs/handbook/components.md +210 -19
  89. package/docs/handbook/config.md +5 -3
  90. package/docs/handbook/deploy.md +1 -1
  91. package/docs/handbook/design.md +20 -12
  92. package/docs/handbook/en/ai-writing.md +2 -2
  93. package/docs/handbook/en/components/card.md +42 -21
  94. package/docs/handbook/en/components/chart.md +10 -26
  95. package/docs/handbook/en/components/choice.md +42 -0
  96. package/docs/handbook/en/components/compare.md +30 -15
  97. package/docs/handbook/en/components/figure.md +29 -42
  98. package/docs/handbook/en/components/file.md +9 -14
  99. package/docs/handbook/en/components/html.md +9 -29
  100. package/docs/handbook/en/components/interactive.md +8 -34
  101. package/docs/handbook/en/components/list.md +65 -0
  102. package/docs/handbook/en/components/relations.md +95 -0
  103. package/docs/handbook/en/components/stat.md +9 -27
  104. package/docs/handbook/en/components/timeline.md +9 -24
  105. package/docs/handbook/en/components.md +211 -19
  106. package/docs/handbook/en/config.md +32 -30
  107. package/docs/handbook/en/deploy.md +12 -12
  108. package/docs/handbook/en/design.md +19 -12
  109. package/docs/handbook/en/index.md +2 -2
  110. package/docs/handbook/en/reference/card.md +85 -0
  111. package/docs/handbook/en/reference/chart.md +68 -0
  112. package/docs/handbook/en/reference/choice.md +69 -0
  113. package/docs/handbook/en/reference/compare.md +59 -0
  114. package/docs/handbook/en/reference/figure.md +84 -0
  115. package/docs/handbook/en/reference/file/checklist.md +17 -0
  116. package/docs/handbook/en/reference/file.md +50 -0
  117. package/docs/handbook/en/reference/html.md +62 -0
  118. package/docs/handbook/en/reference/interactive.md +71 -0
  119. package/docs/handbook/en/reference/list.md +72 -0
  120. package/docs/handbook/en/reference/relations.md +113 -0
  121. package/docs/handbook/en/reference/stat.md +60 -0
  122. package/docs/handbook/en/reference/timeline.md +56 -0
  123. package/docs/handbook/en/reference.md +26 -0
  124. package/docs/handbook/en/start.md +2 -2
  125. package/docs/handbook/en/workflow.md +6 -5
  126. package/docs/handbook/en/writing.md +3 -2
  127. package/docs/handbook/index.md +1 -1
  128. package/docs/handbook/reference/card.md +85 -0
  129. package/docs/handbook/reference/chart.md +68 -0
  130. package/docs/handbook/reference/choice.md +69 -0
  131. package/docs/handbook/reference/compare.md +59 -0
  132. package/docs/handbook/reference/figure.md +84 -0
  133. package/docs/handbook/reference/file/checklist.md +17 -0
  134. package/docs/handbook/reference/file.md +50 -0
  135. package/docs/handbook/reference/html.md +62 -0
  136. package/docs/handbook/reference/interactive.md +71 -0
  137. package/docs/handbook/reference/list.md +72 -0
  138. package/docs/handbook/reference/relations.md +113 -0
  139. package/docs/handbook/reference/stat.md +60 -0
  140. package/docs/handbook/reference/timeline.md +56 -0
  141. package/docs/handbook/reference.md +26 -0
  142. package/docs/handbook/start.md +1 -1
  143. package/docs/handbook/workflow.md +6 -5
  144. package/docs/handbook/writing.md +3 -2
  145. package/next.config.ts +6 -0
  146. package/package.json +2 -1
  147. package/public/images/garden/ref-card-book.svg +1 -0
  148. package/public/images/garden/ref-card-lamp.svg +1 -0
  149. package/scripts/build-content.mjs +37 -16
  150. package/scripts/favicon-ico.mjs +9 -6
  151. package/scripts/file-preview.mjs +10 -7
  152. package/scripts/handbook-allowlist.mjs +18 -0
  153. package/scripts/handbook-facts.mjs +305 -11
  154. package/scripts/link-assets.mjs +7 -0
  155. package/scripts/new-post.mjs +18 -9
  156. package/scripts/prepare-pages-output.mjs +30 -18
  157. package/scripts/redirects.mjs +17 -6
  158. package/templates/garden-blocks.md +67 -0
  159. package/templates/garden-snippets.plist +61 -0
  160. package/templates/site/Makefile.en +45 -0
  161. package/templates/site/README.en.md +15 -0
  162. package/templates/site/site.config.en.yaml +55 -0
  163. package/templates/skills-en/garden-interactive-chart/SKILL.md +84 -0
  164. package/templates/skills-en/garden-interactive-chart/references/shell.html +49 -0
  165. package/templates/skills-en/garden-interactive-chart/references/style.md +61 -0
  166. package/templates/skills-en/garden-post-review/SKILL.md +63 -0
  167. package/templates/skills-en/garden-ui/SKILL.md +118 -0
  168. package/templates/workflows/pages.en.yml +195 -0
  169. package/templates/workflows/pages.yml +195 -0
  170. package/ui/garden/catalog.mjs +205 -4
  171. package/ui/garden/check.mjs +6 -0
  172. package/ui/garden/file-block.mjs +8 -7
  173. package/ui/garden/html-lang.mjs +73 -1
  174. package/ui/garden/markdown-links.mjs +7 -4
  175. package/ui/garden/parse.mjs +45 -0
  176. package/ui/garden/relations.mjs +252 -0
  177. package/ui/garden/search-index.mjs +6 -4
  178. package/ui/garden/source-icon.mjs +54 -0
  179. package/ui/parity-fixtures.mjs +77 -0
  180. package/ui/preview/dist/garden-ui.esm.js +41 -4
  181. package/ui/preview/dist/garden-ui.iife.js +41 -4
  182. package/ui/prompt/rules.md +28 -1
  183. package/ui/react/components/chart.tsx +1 -1
  184. package/ui/react/components/display.tsx +1 -1
  185. package/ui/react/lang.tsx +4 -0
  186. package/ui/react/parity.tsx +8 -6
  187. package/worker/index.ts +8 -2
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: 组件参考 · file
3
+ navTitle: file
4
+ description: 给读者提供一份或一组可下载的文件,支持在当前页展开预览。
5
+ section: reference
6
+ order: 9
7
+ badge: file
8
+ ---
9
+
10
+ [← 组件参考](/garden/reference) · [用法:文件下载与预览](/garden/components/file)
11
+
12
+ ## 示例
13
+
14
+ ```garden file
15
+ src: ./file/checklist.md
16
+ title: 发布前检查清单
17
+ note: Markdown 附件示例,可点击「预览」在当前页展开阅读,或直接下载原文件
18
+ ```
19
+
20
+ ## 字段写法
21
+
22
+ ````markdown
23
+ ```garden file
24
+ src: # 单文件必填,路径
25
+ title: # 可选,标题
26
+ note: # 可选,一句说明
27
+ files: # 多文件必填,不与 src 同写
28
+ - src: # 必填,路径
29
+ title: # 可选,默认文件名
30
+ note: # 可选,说明
31
+ ```
32
+ ````
33
+
34
+ ## 字段
35
+
36
+ 围栏写 ` ```garden file `(编辑器代码片段触发词 `;gfile`)。单个附件在顶层写 `src`,多个附件用 `files` 数组;YAML 语法错误或顶层含未知键名时整块报 `garden-yaml` 错误。
37
+
38
+ | 字段 | 是否必填 | 默认值 | 取值与限制 | 说明 |
39
+ | :--- | :--- | :--- | :--- | :--- |
40
+ | `src` | 单文件必填 | 无 | 相对路径、`/public` 路径或 `https://` 网址;缺失或与 `files` 同时写报 `garden-file` 错误,本地路径越出 `content/` 目录报 `file-outside` 错误,本地文件不存在报 `missing-asset` 错误,单文件超过 `5 MB` 报 `file-large` 警告 | 附件路径 |
41
+ | `title` | 可选 | 单文件默认取文件名;多文件默认 `""` | 字符串 | 单文件模式下为附件显示标题;多文件模式下作为整组标题 |
42
+ | `note` | 可选 | `""` | 字符串(与 `files` 同时写在顶层时报 `garden-file` 错误) | 单文件模式下显示在文件名下方的简短说明 |
43
+ | `files` | 多文件必填 | 无 | `{ src, title?, note? }[]`(至少 `1` 项;为空、非数组、与顶层 `src`/`note` 同时写、条目缺少 `src`、含未知键名或手写 `resolved` 字段时均报 `garden-file` 错误) | 多文件列表,每项必填 `src`,可选 `title`(默认取文件名)与 `note`(默认 `""`) |
44
+
45
+ ## 限制与报错
46
+
47
+ - `garden-file`:没写 `src` 也没写 `files`;`files` 为空或不是列表;`files` 和顶层 `src` / `note` 同时写;条目缺 `src` 或含未知键名;手写了 `resolved`。
48
+ - `file-outside`:本地路径越出 `content/` 目录。
49
+ - `missing-asset`:本地文件不存在。
50
+ - `file-large`(警告):单个文件超过 5 MB。
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: 组件参考 · html
3
+ navTitle: html
4
+ description: 在沙盒中运行一段独立的网页小工具、画布动画或演示。
5
+ section: reference
6
+ order: 7
7
+ badge: html
8
+ ---
9
+
10
+ [← 组件参考](/garden/reference) · [用法:嵌入网页片段](/garden/components/html)
11
+
12
+ ## 示例
13
+
14
+ ```garden html
15
+ title: 字符长度与预计阅读耗时小工具
16
+ code: |
17
+ <!doctype html>
18
+ <html lang="zh-CN">
19
+ <head>
20
+ <meta charset="utf-8" />
21
+ <style>
22
+ body { margin: 0; padding: 16px 18px; font: 14px/1.6 system-ui, sans-serif; color: #1b1a18; background: #faf9f5; }
23
+ input { width: 100%; box-sizing: border-box; padding: 8px 10px; border: 1px solid #d5d1c8; border-radius: 6px; font: inherit; background: #fff; color: #1b1a18; }
24
+ .meta { margin-top: 10px; color: #6e6b64; font-variant-numeric: tabular-nums; }
25
+ strong { color: #1b1a18; }
26
+ </style>
27
+ </head>
28
+ <body>
29
+ <input id="txt" value="把文章放在自己的 Git 仓库里,推送后自动构建。" aria-label="输入示例文本" />
30
+ <div class="meta">当前字符数:<strong id="count">23</strong> 字</div>
31
+ <script>
32
+ const input = document.getElementById("txt");
33
+ const count = document.getElementById("count");
34
+ input.addEventListener("input", () => { count.textContent = String(input.value.length); });
35
+ </script>
36
+ </body>
37
+ </html>
38
+ ```
39
+
40
+ ## 字段写法
41
+
42
+ ````markdown
43
+ ```garden html
44
+ src: # 与 code 二选一,文件路径
45
+ code: | # 与 src 二选一,HTML 源码
46
+ title: # 建议填,框顶标题
47
+ ```
48
+ ````
49
+
50
+ ## 字段
51
+
52
+ 围栏写 ` ```garden html `(编辑器代码片段触发词 `;ghtml`)。YAML 语法错误或顶层含未知键名时整块报 `garden-yaml` 错误。
53
+
54
+ | 字段 | 是否必填 | 默认值 | 取值与限制 | 说明 |
55
+ | :--- | :--- | :--- | :--- | :--- |
56
+ | `src` | 与 `code` 二选一 | 无 | 相对路径(如 `./demo.html`) | 引用当前文章同名子目录下的独立 `.html` 文件 |
57
+ | `code` | 与 `src` 二选一 | `---` 分隔线下的 HTML 正文或 `""` | 多行 HTML 字符串 | 直接内联的 HTML 源码(含 `<script>` 时运行在沙盒 `iframe` 中,并自动按内容高度调整;也可以把 HTML 放在 `---` 分隔线下方) |
58
+ | `title` | 建议填写 | `"HTML"` | 字符串 | 框顶标题栏与无障碍 `iframe` 标题 |
59
+
60
+ ## 限制与报错
61
+
62
+ - 除通用的 `garden-yaml` 外,本组件没有专属报错代码;表里写「不做校验」的建议值不会报错。
@@ -0,0 +1,71 @@
1
+ ---
2
+ title: 组件参考 · interactive
3
+ navTitle: interactive
4
+ description: 让读者拖动滑杆或切换选项,实时看到公式和图表的计算结果。
5
+ section: reference
6
+ order: 8
7
+ badge: interactive
8
+ ---
9
+
10
+ [← 组件参考](/garden/reference) · [用法:可调公式与参数](/garden/components/interactive)
11
+
12
+ ## 示例
13
+
14
+ ```garden interactive #reading-time
15
+ caption: 示例:按字数、阅读速度和配图数估算一篇文章的阅读时间。数字只用来演示组件,不是统计结果。
16
+ ---
17
+ <State words={6000} speed={400} images={8} />
18
+ <Let textMinutes={round(words / speed)} />
19
+ <Let imageMinutes={round(images * 12 / 60)} />
20
+ <Let parts={[{ part: "正文", minutes: textMinutes }, { part: "配图", minutes: imageMinutes }]} />
21
+
22
+ <Slider bind="words" label="正文字数" min={1000} max={20000} step={500} unit="字" />
23
+ <Slider bind="speed" label="阅读速度" min={200} max={800} step={50} unit="字/分钟" />
24
+ <Slider bind="images" label="配图数" min={0} max={30} step={1} unit="张" />
25
+
26
+ <Stat label="示例:预计阅读时间" value={textMinutes + imageMinutes} unit="分钟" hint="配图按每张 12 秒估算" />
27
+ <Chart data={parts} x={part} yLabel="分钟">
28
+ <Bar y={minutes} label="示例" />
29
+ </Chart>
30
+ ```
31
+
32
+ ## 字段写法
33
+
34
+ ````markdown
35
+ ```garden interactive #<id>
36
+ caption: # 必填,默认状态的结论
37
+ intent: | # 可选,作者原话
38
+ expect: # 可选,数值断言
39
+ --- # 下方写交互标签
40
+ <State ... /> # 必填,可调状态
41
+ <Let ... /> # 可选,派生值
42
+ <Slider bind="..." /> # 输入控件
43
+ <Stat ... /> # 输出展示
44
+ ```
45
+ ````
46
+
47
+ ## 字段
48
+
49
+ 围栏写 ` ```garden interactive #<id> `(编辑器代码片段触发词 `;ginteractive`)。`---` 分隔线上方是 YAML 头部字段,下方是声明式交互标签(运行 `npx garden ui catalog` 可在 `.garden/ui-catalog.html` 查看全部内部标签参考);YAML 头部语法错误或顶层含未知键名时整块报 `garden-yaml` 错误。
50
+
51
+ | 字段或标签 | 是否必填 | 默认值 | 取值与限制 | 说明 |
52
+ | :--- | :--- | :--- | :--- | :--- |
53
+ | `#<id>` / `id` | 必填 | 无 | 小写字母、数字与连字符 `^[a-z0-9]+(?:-[a-z0-9]+)*$`,篇内唯一;缺失或格式不合法报 `ui-id` 错误 | 写在围栏行末尾(如 `#reading-time`)或 YAML 头部 |
54
+ | `caption` | 必填 | 无 | 非空字符串;缺失或为空报 `ui-caption` 错误 | 图框说明,写出默认状态能看出的结论 |
55
+ | `intent` | 可选 | 无 | 字符串(非字符串报 `ui-header` 错误;改过原话但未重编译时报 `ui-stale` 警告) | 生成该块时的作者原始自然语言想法 |
56
+ | `expect` | 可选 | 无 | `{ given: {...}, <变量名>: <期望值> }[]`(非数组报 `ui-header` 错误,格式不对或断言不通过报 `ui-expect` 错误) | 数值断言列表,`npx garden ui check` 会自动验算(近似值可写 `{ value, tol }`) |
57
+ | `<State />` | 必填 | 无 | 小写字母开头的属性名配数字、字符串或布尔字面量(名字非法、重复或非字面量报 `ui-prop` 错误) | 声明可调状态变量及默认值,如 `<State words={6000} />` |
58
+ | `<Let />` | 可选 | 无 | 表达式属性(引用未知变量或禁用语法报 `ui-expr` 错误,互相依赖成环报 `ui-cycle` 错误,求值出错报 `ui-eval` 错误,全块只有一次简单乘法报 `interactive-trivial` 错误) | 由状态变量派生计算出的中间值、数组或对象 |
59
+ | `<Data />` | 可选 | 无 | `name`(合法标识符)与 `src`(同名子目录下的 `.csv` / `.json`;越界、缺失或解析失败报 `ui-data` 错误) | 引用随文数据文件 |
60
+ | `<Slider />` / `<Stepper />` / `<Toggle />` | 至少一项输入控件 | `Slider`: `scale="linear"`, `snap="none"`(对数且端点为 2 的幂时默认 `"pow2"`);`Stepper`: `step={1}` | `bind` 必须绑定已声明且类型匹配的状态(否则报 `ui-bind` 错误);`max <= min`、对数刻度 `min <= 0` 或默认值越界报 `ui-prop` 错误 | 绑定数字或布尔状态的输入控件 |
61
+ | `<Choice />` / `<Checklist />` / `<Button />` | 可选输入控件 | `Button`: `tone="plain"` | `<Choice>` 的 `options` 限 `2`~`8` 项(超出报 `ui-limit` 错误,默认值不在选项内报 `ui-prop` 错误);`<Checklist>` 的 `items` 限 `1`~`30` 项(超出报 `ui-limit` 错误);`<Button>` 必填且只能填 `set` 或 `reset` 之一(否则报 `ui-prop` 错误) | 选项切换、可勾选清单与状态重置按钮 |
62
+ | `<Stack />` / `<Columns />` / `<Tabs />` / `<Steps />` | 可选布局容器 | `Stack`: `gap={3}`, `direction="col"`;`Columns`: `gap={3}`, `min={220}`;`Steps`: `autoplay={false}` | `gap` 限 `0`~`4` 整数、`Columns.min` 限 `160`~`400`、`Steps.autoplay` 限 `false` 或 `>= 800`(违规报 `ui-prop` 错误);`<Columns>` 最多 `4` 列、`<Tabs>` 限 `2`~`6` 个 `<Tab>`、`<Steps>` 限 `2`~`24` 个 `<Step>`(超出报 `ui-limit` 错误,子元素类型不对报 `ui-children` 错误,步骤只放散文且无状态变化报 `steps-prose` 错误) | 分栏、标签页与分步容器(`<Each>` 超过 `200` 项时只显示前 `200` 项,不报 `ui-limit`;整块展开元素上限 `200` 个,超出报 `ui-limit` 错误) |
63
+ | `<Stat />` / `<Meter />` / `<Chart />` / `<Pie />` | 至少一项输出展示 | `Stat`: `tone="plain"`, `size="md"`;`Meter`: `tone="accent"`;`Chart`: `samples={64}`, `yScale="linear"`, `height={200}` | `<Meter>` 的 `parts` 最多 `5` 段、`<Pie>` 限 `1`~`8` 个 `<Slice>`、`<Chart>` 限 `1`~`4` 个系列子元素且 `data` 模式最多 `2000` 个数据点(超出均报 `ui-limit` 错误);`<Chart>` 的 `samples` 限 `2`~`200`、`height` 限 `120`~`480`(超出报 `ui-prop` 错误) | 实时展示随状态变化的数字、占比条、圆环图与曲线/柱状图 |
64
+ | `<Table />` / `<Grid />` / `<Image />` / `<Code />` / `<Diagram />` / `<Sandbox />` | 可选展示组件 | 无 | `<Table>` 最多 `50` 行、`<Grid>` 的 `cols` 最多 `16` 列且限 `1`~`16` 行、`<Image>` 最多 `12` 个 `<Hotspot>`、`<Code>` 最多 `60` 行、`<Sandbox>` 的 `html` 最多 `12000` 字且 `css` 与 `js` 各最多 `8000` 字(超出均报 `ui-limit` 错误;未知标签报 `ui-component` 错误;块内写 Markdown 标题、代码围栏、HTML 或图片语法报 `ui-markdown` 错误,JSX 语法错误报 `ui-syntax` 错误) | 数据表、检视格、热点图、代码走查、Mermaid 状态图与自包含沙盒 |
65
+
66
+ ## 限制与报错
67
+
68
+ - 头部:`ui-id`(缺 id 或格式不对)、`ui-caption`(缺 caption)、`ui-header`(`intent` 不是字符串或 `expect` 不是列表)、`ui-expect`(断言格式不对或不通过)、`ui-stale`(警告:改过原话但没重新编译)。
69
+ - 标签:`ui-prop`、`ui-expr`、`ui-cycle`、`ui-eval`、`ui-data`、`ui-bind`、`ui-limit`、`ui-children`、`ui-component`、`ui-markdown`、`ui-syntax`,各自的触发条件见上表。
70
+ - 整块:`interactive-trivial`(只有一次简单乘法)、`steps-prose`(步骤只是散文,没有状态变化)。
71
+ - 运行 `npx garden ui check` 可以拿到修复提示词。
@@ -0,0 +1,72 @@
1
+ ---
2
+ title: 组件参考 · list
3
+ navTitle: list
4
+ description: 用线条图标配短句列出几条并列动作,或带小标题列出分步做法。
5
+ section: reference
6
+ order: 11
7
+ badge: list
8
+ ---
9
+
10
+ [← 组件参考](/garden/reference) · [用法:图标列表](/garden/components/list)
11
+
12
+ ## 示例
13
+
14
+ ```garden list
15
+ items:
16
+ - icon: search
17
+ text: 搜索这个月的书名
18
+ - icon: eye
19
+ text: 看了 3 篇书评
20
+ - icon: heart
21
+ text: 收藏了活动页面
22
+ - icon: chat
23
+ text: 在群里问能不能只听不说
24
+ ```
25
+
26
+ ```garden list
27
+ items:
28
+ - icon: flask
29
+ title: 实验一:一个月读一本是不是太多?
30
+ text:
31
+ - 前两次活动分别选一本中篇和一本长篇,记录每个人读完的比例。
32
+ - 读完比例明显下降时,下次改成只读前半本。
33
+ - icon: chat
34
+ title: 实验二:怎样让第一次来的人开口?
35
+ text:
36
+ - 一半活动先轮流说一句话,另一半直接自由讨论。
37
+ - 比较第一次来的人发言的次数。
38
+ - icon: bell
39
+ title: 实验三:提醒要提前几天发?
40
+ text:
41
+ - 分别在活动前三天和前一天发提醒,看到场人数有没有差别。
42
+ ```
43
+
44
+ ## 字段写法
45
+
46
+ ````markdown
47
+ ```garden list
48
+ title: # 可选,总标题
49
+ items: # 必填,列表项
50
+ - icon: # 可选,23 个图标名之一
51
+ title: # 可选,写了就变步骤列表
52
+ text: # 建议填,说明
53
+ caption: # 可选,图注
54
+ ```
55
+ ````
56
+
57
+ ## 字段
58
+
59
+ 围栏写 ` ```garden list `(编辑器代码片段触发词 `;glist`)。YAML 语法错误或顶层含未知键名时整块报 `garden-yaml` 错误。
60
+
61
+ | 字段 | 是否必填 | 默认值 | 取值与限制 | 说明 |
62
+ | :--- | :--- | :--- | :--- | :--- |
63
+ | `title` | 可选 | 无 | 字符串 | 列表上方的总标题 |
64
+ | `items` | 必填 | `[]` | 对象或字符串数组 | 列表项;所有条目都不带 `title` 时渲染为紧凑图标卡片,任一条目带 `title` 时渲染为带分隔线的步骤列表 |
65
+ | `items[].icon` | 可选 | 无(不绘制图标) | 23 个内置图标名之一:`search`、`eye`、`heart`、`chat`、`shield`、`wallet`、`bell`、`check`、`x`、`star`、`flag`、`clock`、`idea`、`book`、`link`、`user`、`chart`、`gear`、`file`、`pin`、`flask`、`target`、`question` | 线条图标名(未识别的名称不显示图标) |
66
+ | `items[].title` | 可选 | 无(默认紧凑行模式) | 字符串 | 条目小标题;填写后整组切换为带分隔线的步骤布局 |
67
+ | `items[].text` | 建议填写 | `[]` | 字符串或字符串数组 | 条目说明文字;写成数组时每个元素渲染为独立段落 |
68
+ | `caption` | 可选 | 无 | 字符串 | 列表底部的图注 |
69
+
70
+ ## 限制与报错
71
+
72
+ - 除通用的 `garden-yaml` 外,本组件没有专属报错代码;表里写「不做校验」的建议值不会报错。
@@ -0,0 +1,113 @@
1
+ ---
2
+ title: 组件参考 · relations
3
+ navTitle: relations
4
+ description: 把三到六个要素排成环或中心辐射结构,画出谁影响谁、哪些是双向的。
5
+ section: reference
6
+ order: 10
7
+ badge: relations
8
+ ---
9
+
10
+ [← 组件参考](/garden/reference) · [用法:关系图](/garden/components/relations)
11
+
12
+ ## 示例
13
+
14
+ ```garden relations
15
+ items:
16
+ - title: 选书
17
+ text: 定下这个月读什么
18
+ - title: 共读
19
+ text: 每周读完约定的章节
20
+ - title: 讨论
21
+ text: 见面聊各自的看法
22
+ - title: 复盘
23
+ text: 记下下次要改的地方
24
+ links:
25
+ - from: 1
26
+ to: 2
27
+ - from: 2
28
+ to: 3
29
+ - from: 3
30
+ to: 4
31
+ - from: 4
32
+ to: 1
33
+ - from: 3
34
+ to: 1
35
+ style: dashed
36
+ label: 影响选书
37
+ - from: 2
38
+ to: 4
39
+ style: dashed
40
+ caption: 四个环节互相提供信息,而不是按固定顺序走一遍。
41
+ ```
42
+
43
+ ```garden relations
44
+ items:
45
+ - title: 组织者
46
+ text: 每月发一次通知
47
+ - title: 成员
48
+ text: 八到十个邻居
49
+ - title: 场地
50
+ text: 咖啡馆或图书馆
51
+ - title: 书单
52
+ text: 大家轮流提名
53
+ center: 组织者
54
+ links:
55
+ - from: 1
56
+ to: 2
57
+ label: 邀请
58
+ - from: 1
59
+ to: 3
60
+ label: 预约
61
+ - from: 1
62
+ to: 4
63
+ label: 汇总
64
+ - from: 2
65
+ to: 4
66
+ style: dashed
67
+ direction: both
68
+ label: 提名
69
+ caption: 组织者放在正中,连着外圈的其余三个;成员和书单互相影响。
70
+ ```
71
+
72
+ ## 字段写法
73
+
74
+ ````markdown
75
+ ```garden relations
76
+ title: # 可选,无障碍标签
77
+ items: # 必填,3–6 项
78
+ - title: # 必填,要素名
79
+ text: # 可选,一句说明
80
+ center: # 可选,序号或标题
81
+ links: # 可选,连线列表
82
+ - from: # 必填,序号或标题
83
+ to: # 必填,不能同 from
84
+ style: # solid | dashed
85
+ direction: # one | both
86
+ label: # 可选,短标签
87
+ caption: # 可选,图注
88
+ ```
89
+ ````
90
+
91
+ ## 字段
92
+
93
+ 围栏写 ` ```garden relations `(编辑器代码片段触发词 `;grel`)。节点没有强调色选项,所有要素视觉权重相同;其他图形直接写 ` ```mermaid ` 围栏,只走一遍的步骤用 `garden list`。YAML 语法错误或顶层含未知键名时整块报 `garden-yaml` 错误。
94
+
95
+ | 字段 | 是否必填 | 默认值 | 取值与限制 | 说明 |
96
+ | :--- | :--- | :--- | :--- | :--- |
97
+ | `title` | 可选 | 无障碍标签默认 `"关系图"`(不渲染可视标题) | 字符串 | 关系图上方的标题 |
98
+ | `items` | 必填 | 无 | 对象数组,严格 `3`~`6` 项(少于 `3` 项或多于 `6` 项报 `garden-relations` 错误) | 要素列表;未设 `center` 时从正上方(12 点钟方向)起顺时针均布在椭圆上 |
99
+ | `items[].title` | 必填 | `""` | 字符串 | 节点标题(`links` 与 `center` 按序号或完整标题引用节点) |
100
+ | `items[].text` | 可选 | `""` | 字符串 | 节点标题下方的一句短说明 |
101
+ | `center` | 可选 | 无(全部要素排在外圈椭圆上) | `1..N` 序号(从 `1` 开始)或节点完整 `title`(找不到对应要素时报 `garden-relations` 错误) | 写在 `items` 与 `links` 之间:把该要素放在正中间,其余要素从正上方起顺时针均布在外圈;不做自动识别 |
102
+ | `links` | 可选 | `[]` | 对象数组(非数组或条目含未知键名时报 `garden-relations` 错误) | 节点之间的连线;外圈相邻要素连线向外轻弧弯曲,其余连线从中间直穿;首尾相接的循环把每一步写成一条 `link`(如 `1->2`、`2->3`、`3->4`、`4->1`) |
103
+ | `links[].from` | 必填 | 无 | `1..N` 序号或节点完整 `title`,且不能与 `to` 相同(缺失、找不到要素或与 `to` 相同时报 `garden-relations` 错误) | 起点要素 |
104
+ | `links[].to` | 必填 | 无 | `1..N` 序号或节点完整 `title`,且不能与 `from` 相同(缺失、找不到要素或与 `from` 相同时报 `garden-relations` 错误) | 终点要素 |
105
+ | `links[].style` | 可选 | `"solid"` | `"solid"` \| `"dashed"`(其他取值报 `garden-relations` 错误) | 实线(`→` / `↔`)或虚线(`⇢` / `⇠⇢`) |
106
+ | `links[].direction` | 可选 | `"one"` | `"one"` \| `"both"`(其他取值报 `garden-relations` 错误) | 单向箭头(指向 `to`)或两端双箭头 |
107
+ | `links[].label` | 可选 | `""` | 短字符串(非字符串类型报 `garden-relations` 错误) | 连线上的短标签(带底色衬垫并自动避开线条交叉点;在连线上放不下时改为圆圈序号,并在图下列出,如「`① 限制:预算 → 场地`」) |
108
+ | `caption` | 可选 | 无 | 字符串 | 关系图底部的图注 |
109
+
110
+ ## 限制与报错
111
+
112
+ - `garden-relations`:`items` 少于 3 项或多于 6 项;`center` 找不到要素;`links` 不是列表或条目含未知键名;`from` / `to` 缺失、找不到或相同;`style`、`direction` 取值不对;`label` 不是字符串。
113
+ - 要素更多、有分支时改用 ```` ```mermaid ```` 流程图;只走一遍的步骤用 `garden list`。
@@ -0,0 +1,60 @@
1
+ ---
2
+ title: 组件参考 · stat
3
+ navTitle: stat
4
+ description: 把 2~4 个关键数字、单位与一句说明并排摆出来。
5
+ section: reference
6
+ order: 2
7
+ badge: stat
8
+ ---
9
+
10
+ [← 组件参考](/garden/reference) · [用法:数字指标](/garden/components/stat)
11
+
12
+ ## 示例
13
+
14
+ ```garden stat
15
+ items:
16
+ - label: 正文列宽
17
+ value: "740"
18
+ unit: px
19
+ caption: 默认阅读列宽度
20
+ - label: 宽图上限
21
+ value: "1040"
22
+ unit: px
23
+ caption: 左右各最多向外延伸 150px
24
+ - label: 宽表上限
25
+ value: "1340"
26
+ unit: px
27
+ caption: 左右各最多向外延伸 300px
28
+ ```
29
+
30
+ ## 字段写法
31
+
32
+ ````markdown
33
+ ```garden stat
34
+ items: # 多项时写,建议 2–4 项
35
+ - label: # 必填,指标名
36
+ value: # 必填,数字
37
+ unit: # 可选,单位
38
+ caption: # 可选,一句说明
39
+ text: # 可选,补充说明
40
+ source: # 可选,来源网址
41
+ ```
42
+ ````
43
+
44
+ ## 字段
45
+
46
+ 围栏写 ` ```garden stat `(编辑器代码片段触发词 `;gstat`)。多个指标放在 `items` 数组里,单个指标也可以直接把字段写在顶层;YAML 语法错误或顶层含未知键名时整块报 `garden-yaml` 错误。
47
+
48
+ | 字段 | 是否必填 | 默认值 | 取值与限制 | 说明 |
49
+ | :--- | :--- | :--- | :--- | :--- |
50
+ | `items` | 多项时必填 | `[顶层对象]` | 对象数组(建议 `2`~`4` 项,不做校验) | 并排展示的指标项列表;省略 `items` 时直接将顶层字段作为单项指标渲染 |
51
+ | `label` | 必填 | `""` | 字符串 | 数字上方的指标名称 |
52
+ | `value` | 必填 | `""` | 字符串或数字 | 大号等宽字体显示的核心数值 |
53
+ | `unit` | 可选 | 无 | 字符串 | 紧跟在 `value` 右侧的单位 |
54
+ | `caption` | 可选 | 无 | 字符串 | 数字下方的简短说明 |
55
+ | `text` | 可选 | 无 | 字符串 | 补充说明文字 |
56
+ | `source` | 可选 | 无 | 网址、`{ url, site?, icon? }` 或数组 | 来源胶囊标签(未填 `site` 时默认取网址去掉 `www.` 后的域名) |
57
+
58
+ ## 限制与报错
59
+
60
+ - 除通用的 `garden-yaml` 外,本组件没有专属报错代码;表里写「不做校验」的建议值不会报错。
@@ -0,0 +1,56 @@
1
+ ---
2
+ title: 组件参考 · timeline
3
+ navTitle: timeline
4
+ description: 按时间或阶段顺序排开版本演进、排查经过或关键节点。
5
+ section: reference
6
+ order: 4
7
+ badge: timeline
8
+ ---
9
+
10
+ [← 组件参考](/garden/reference) · [用法:时间线](/garden/components/timeline)
11
+
12
+ ## 示例
13
+
14
+ ```garden timeline
15
+ title: 静态发布流水线执行步骤
16
+ items:
17
+ - date: 步骤 1
18
+ title: 同步内容与静态资源
19
+ text: 校验文章信息、复制图片附件并生成搜索索引与 RSS。
20
+ - date: 步骤 2
21
+ title: 构建静态站点产物
22
+ text: 把全部页面预渲染到静态目录。
23
+ - date: 步骤 3
24
+ title: 校验静态页面并部署
25
+ text: 检查导出文件完整无误后发布到 GitHub Pages。
26
+ ```
27
+
28
+ ## 字段写法
29
+
30
+ ````markdown
31
+ ```garden timeline
32
+ title: # 可选,总标题
33
+ items: # 必填,按时间先后
34
+ - date: # 可选,时间点
35
+ title: # 必填,节点标题
36
+ text: # 可选,说明
37
+ source: # 可选,来源网址
38
+ ```
39
+ ````
40
+
41
+ ## 字段
42
+
43
+ 围栏写 ` ```garden timeline `(编辑器代码片段触发词 `;gtimeline`)。YAML 语法错误或顶层含未知键名时整块报 `garden-yaml` 错误。
44
+
45
+ | 字段 | 是否必填 | 默认值 | 取值与限制 | 说明 |
46
+ | :--- | :--- | :--- | :--- | :--- |
47
+ | `title` | 可选 | 无 | 字符串 | 时间线上方的总标题 |
48
+ | `items` | 必填 | `[]` | 对象数组(建议至少 `2` 项,不做校验) | 按先后顺序排列的节点列表 |
49
+ | `items[].date` | 可选 | 无 | 字符串 | 节点上方的时间点、年份或阶段编号 |
50
+ | `items[].title` | 必填 | `""` | 字符串 | 节点标题 |
51
+ | `items[].text` | 可选 | 无 | 字符串 | 节点的具体说明 |
52
+ | `items[].source` | 可选 | 无 | 网址、`{ url, site?, icon? }` 或数组 | 跟在节点说明后的来源胶囊(未填 `site` 时默认取网址去掉 `www.` 后的域名) |
53
+
54
+ ## 限制与报错
55
+
56
+ - 除通用的 `garden-yaml` 外,本组件没有专属报错代码;表里写「不做校验」的建议值不会报错。
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: 组件参考
3
+ navTitle: 总览
4
+ description: 12 个内置组件的全部字段、默认值、取值限制和报错代码,每个组件一页。
5
+ section: reference
6
+ order: 0
7
+ ---
8
+
9
+ 每页左边是代码,右边是同一段代码渲染出的真实效果;窄屏下用「效果 / 代码」切换。用法和什么时候用,见各组件的用法页。
10
+
11
+ 所有组件通用:YAML 语法错误,或顶层出现不支持的键名,整块报 `garden-yaml`;围栏名写错报 `garden-name`。
12
+
13
+ | 组件 | 用途 |
14
+ | :--- | :--- |
15
+ | [`card`](/garden/reference/card) | 介绍一篇论文、一个项目或一组值得参考的公开工具。 |
16
+ | [`stat`](/garden/reference/stat) | 把 2~4 个关键数字、单位与一句说明并排摆出来。 |
17
+ | [`compare`](/garden/reference/compare) | 把两三种方案左右并列,或把不好的做法与更好的做法上下对照。 |
18
+ | [`timeline`](/garden/reference/timeline) | 按时间或阶段顺序排开版本演进、排查经过或关键节点。 |
19
+ | [`chart`](/garden/reference/chart) | 把一组算好的数字画成比例条形图,下方自带可展开的数据表。 |
20
+ | [`figure`](/garden/reference/figure) | 一张带切换按钮的结构图,点到哪个部分就高亮并显示对应说明。 |
21
+ | [`html`](/garden/reference/html) | 在沙盒中运行一段独立的网页小工具、画布动画或演示。 |
22
+ | [`interactive`](/garden/reference/interactive) | 让读者拖动滑杆或切换选项,实时看到公式和图表的计算结果。 |
23
+ | [`file`](/garden/reference/file) | 给读者提供一份或一组可下载的文件,支持在当前页展开预览。 |
24
+ | [`relations`](/garden/reference/relations) | 把三到六个要素排成环或中心辐射结构,画出谁影响谁、哪些是双向的。 |
25
+ | [`list`](/garden/reference/list) | 用线条图标配短句列出几条并列动作,或带小标题列出分步做法。 |
26
+ | [`choice`](/garden/reference/choice) | 给出两三个具体选项卡片,读者点选后看到对应的回应。 |
@@ -19,7 +19,7 @@ npm install
19
19
  make dev
20
20
  ```
21
21
 
22
- `npx hd-garden init` 会把站点模板复制到 `my-blog` 目录,并写入 `.agents/skills/` 辅助技能文件。它不会自动执行 `npm install`,也不会自动创建 `.github/workflows/pages.yml`(GitHub Pages 工作流配置见 [发布到 GitHub Pages](/garden/deploy))。
22
+ `npx hd-garden init` 会把站点模板复制到 `my-blog` 目录,并写入 `.agents/skills/` 辅助技能文件(传入 `--locale en` 或 `--locale en_US` 时会生成英文版 `site.config.yaml`、`Makefile`、`README.md`,并安装 `.github/workflows/pages.yml`)。默认中文初始化不会自动执行 `npm install`,也不会自动创建 `.github/workflows/pages.yml`(GitHub Pages 工作流配置见 [发布到 GitHub Pages](/garden/deploy))。
23
23
 
24
24
  首次运行 `make dev` 时,如果还没有 `node_modules`,`Makefile` 中的 `make prepare` 会先自动执行 `npm install`,随后运行 `npx garden dev`(其内部会先执行内容同步)并启动本地开发服务器,默认地址为 `http://localhost:3000`。
25
25
 
@@ -49,11 +49,12 @@ order: 40
49
49
  | `diff-orphan` | 错误 | `diff` 代码块前面没有紧挨着的完整代码块 |
50
50
  | `legacy-fence` | 错误 | 使用了旧版围栏名(如 `garden:stat`、`widget`、`embed`、`html garden`),需改为 `garden <name>` |
51
51
  | `garden-idea` | 错误 | 非草稿文章里还有未编译的空白 `garden` 想法块 |
52
- | `garden-name` | 错误 | 未知的 `garden` 组件名(仅支持 `card`、`stat`、`compare`、`timeline`、`chart`、`figure`、`html`、`interactive`、`file`) |
52
+ | `garden-name` | 错误 | 未知的 `garden` 组件名(仅支持 `card`、`stat`、`compare`、`timeline`、`chart`、`figure`、`html`、`interactive`、`file`、`relations`、`list`、`choice`) |
53
53
  | `garden-yaml` | 错误 | `garden` 围栏内 YAML 语法错误、顶层不是键值/列表,或包含该组件不支持的键名 |
54
+ | `garden-relations` | 错误 | `garden relations` 的要素数量不在 3~6 个之间,或 `links` 配置不合法(要素更多或有分支改用 `mermaid` 流程图,只走一遍的步骤用 `garden list`) |
54
55
  | `garden-file` / `file-outside` | 错误 | `garden file` 手写了 `resolved`、缺少有效的 `src` / `files`,或本地路径越出了 `content/` 目录 |
55
56
  | `file-large` | 警告 | `garden file` 引用的单个本地文件体积超过 `5 MB` |
56
- | `compare-long` | 错误 | `garden compare` 单个对比格的正文超过约 60 字 |
57
+ | `compare-long` | 错误 | `garden compare` 并排模式下单个对比格的正文超过约 60 字(带 `verdict` 的上下对照不受此限) |
57
58
  | `interactive-trivial` / `steps-prose` | 错误 | `garden interactive` 只有一次简单乘法,或步骤只是散文而没有状态变化 |
58
59
 
59
60
  ## 3. Git 提交前钩子与组件画廊
@@ -71,10 +72,10 @@ order: 40
71
72
 
72
73
  Garden 通过以下三种方式提供组件模板与智能辅助:
73
74
 
74
- 1. **新建文章自动附带速查表**:运行 `make new SLUG=xxx TITLE="..."` 创建文章时,生成的 `.md` 文件底部会自动带有一段 `<!-- 组件速查 ... -->` HTML 注释,列出想法块和 9 个组件的示例写法,复制需要的那块即可。这段注释不会显示在页面上,写完可以删掉。
75
+ 1. **新建文章自动附带速查表**:运行 `make new SLUG=xxx TITLE="..."` 创建文章时,生成的 `.md` 文件底部会自动带有一段 `<!-- 组件速查 ... -->` HTML 注释,列出想法块和 12 个组件的示例写法,复制需要的那块即可。这段注释不会显示在页面上,写完可以删掉。
75
76
  2. **代码片段模板文件**:`hd-garden` 包内的 `templates/` 目录自带两份模板文件:
76
- - `templates/garden-blocks.md`:想法块和 9 个内置组件的可复制 Markdown 模板。
77
- - `templates/garden-snippets.plist`:macOS 系统文本替换词条(可拖入「系统设置 → 键盘 → 文本替换」),触发词是 `;gidea`(也可以输入 `;garden想法`)、`;gcard`、`;gstat`、`;gcompare`、`;gtimeline`、`;gchart`、`;gfigure`、`;ghtml`、`;ginteractive`、`;gfile`,每个展开成对应的 `garden` 围栏。
77
+ - `templates/garden-blocks.md`:想法块和 12 个内置组件的可复制 Markdown 模板。
78
+ - `templates/garden-snippets.plist`:macOS 系统文本替换词条(可拖入「系统设置 → 键盘 → 文本替换」),触发词是 `;gidea`(也可以输入 `;garden想法`)、`;gcard`、`;gstat`、`;gcompare`、`;gtimeline`、`;gchart`、`;gfigure`、`;ghtml`、`;ginteractive`、`;gfile`、`;grel`、`;glist`、`;gchoice`,每个展开成对应的 `garden` 围栏。
78
79
  3. **安装 AI Agent 技能(`npx garden skill`)**:在站点目录运行 `npx garden skill`(`npx hd-garden init` 时也会自动执行),会把三个技能复制到站点根目录下的 `.agents/skills/`:
79
80
  - `garden-ui`:把文章里的 `garden` 想法描述编译成具体的组件围栏。
80
81
  - `garden-interactive-chart`:根据文章数据编写 `interactive`、`chart`、`figure` 与 `html` 组件。
@@ -110,10 +110,11 @@ func openStore(path string) (*Store, error) {
110
110
  > [!WARNING] 升级前先备份数据目录
111
111
  > 修改页大小后需要重建索引文件,不能直接原地回退。
112
112
 
113
- ## 4. 本地图片与外部链接卡片
113
+ ## 4. 本地图片、来源胶囊与外部链接卡片
114
114
 
115
115
  - **本地图片与随文目录**:如果文章路径是 `content/posts/my-post.md`,把配图放在同名的 `content/posts/my-post/` 文件夹下,在文中以 `./my-post/diagram.svg` 相对路径引用。构建时会自动复制图片、读取像素宽高,并把 `alt` 文字(以 `image`、`截图`、`img` 开头的默认占位词除外)渲染成图注 `<figcaption>`。
116
- - **行内外部链接**:正文里的外部链接会自动加上目标站点的 Favicon 小图标,并保证图标与链接第一个字同行不折断。
116
+ - **行内外部链接**:正文里的普通外部链接会自动加上目标站点的 Favicon 小图标与右上角 `↗` 箭头,并保证图标与链接第一个字同行不折断。
117
+ - **行内来源胶囊(`{source}`)**:在行内外部链接的 `)` 后面紧跟 `{source}`(中间不加空格),例如 `[wikipedia.org](https://en.wikipedia.org/wiki/Book_discussion_club){source}`,会渲染成圆角来源胶囊:左侧是构建期抓到的站点 Favicon(未抓到时回退为可注册域名主体的首字母,如 `en.wikipedia.org` 显示 `W`),右侧是链接文字,**不带** `↗` 外链箭头。效果如:引自维基百科词条 [wikipedia.org](https://en.wikipedia.org/wiki/Book_discussion_club){source}。
117
118
  - **链接卡片**:有两种写法可以把外部链接渲染成带网站名、标题和简介的链接卡片:
118
119
  1. 把完整网址单独写成一行段落(前后空行):`https://spec.commonmark.org/`
119
120
  2. 在段落内的链接末尾紧跟 `{card}`(中间不加空格):`参见 [CommonMark 规范](https://spec.commonmark.org/){card}。`
package/next.config.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  import type { NextConfig } from "next";
2
2
  import { trailingSlashEnabled } from "./ui/garden/site-href.mjs";
3
3
 
4
+ // A site served under a subpath (GitHub project pages, /repo/…) sets
5
+ // NEXT_PUBLIC_BASE_PATH; the build, the search index and every page link
6
+ // already read it, and the router and assets need the same prefix.
7
+ const basePath = (process.env.NEXT_PUBLIC_BASE_PATH ?? "").replace(/\/+$/u, "");
8
+
4
9
  const nextConfig: NextConfig = {
10
+ ...(basePath ? { basePath } : {}),
5
11
  ...(process.env.STATIC_EXPORT === "1"
6
12
  ? {
7
13
  output: "export",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hd-garden",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "private": false,
5
5
  "description": "用 Markdown 写作、用 GitHub Pages 发布的个人博客引擎。",
6
6
  "license": "MIT",
@@ -37,6 +37,7 @@
37
37
  "worker",
38
38
  ".agents",
39
39
  ".env.example",
40
+ ".env.en.example",
40
41
  ".openai",
41
42
  "Makefile",
42
43
  "eslint.config.mjs",
@@ -0,0 +1 @@
1
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 132 132'><rect width='132' height='132' fill='#F0EEE6'/><rect x='34' y='26' width='64' height='84' rx='6' fill='#C9B79C'/><rect x='34' y='26' width='10' height='84' fill='#8B6A45'/><rect x='52' y='44' width='34' height='5' rx='2' fill='#FAF9F5'/><rect x='52' y='54' width='24' height='5' rx='2' fill='#FAF9F5'/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 132 132'><rect width='132' height='132' fill='#E8EEF0'/><circle cx='66' cy='60' r='30' fill='#9DB7A8'/><rect x='30' y='98' width='72' height='8' rx='4' fill='#3F6B55'/><rect x='44' y='112' width='44' height='6' rx='3' fill='#9DB7A8'/></svg>