hd-garden 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/.agents/skills/garden-ui/SKILL.md +26 -19
  2. package/README.en.md +57 -0
  3. package/README.md +31 -46
  4. package/app/blog/[...path]/page.tsx +9 -1
  5. package/app/columns/[column]/[...path]/page.tsx +10 -12
  6. package/app/components/ArticlePager.tsx +32 -0
  7. package/app/components/Comments.tsx +2 -1
  8. package/app/components/FeedMore.tsx +70 -0
  9. package/app/components/GardenDocsNav.tsx +25 -20
  10. package/app/components/HandbookLangRedirect.tsx +30 -0
  11. package/app/components/HandbookLangSwitch.tsx +49 -0
  12. package/app/components/HandbookView.tsx +187 -0
  13. package/app/components/MarkdownArticle.tsx +11 -5
  14. package/app/components/MarkdownImage.tsx +6 -4
  15. package/app/components/SiteChrome.tsx +11 -2
  16. package/app/components/SiteFooter.tsx +5 -3
  17. package/app/components/SiteHeader.tsx +27 -23
  18. package/app/components/TableOfContents.tsx +15 -9
  19. package/app/components/ThoughtFeed.tsx +41 -0
  20. package/app/components/UiLang.tsx +18 -0
  21. package/app/components/Webmentions.tsx +3 -2
  22. package/app/components/garden/FilePreview.tsx +13 -11
  23. package/app/components/garden/GardenBlock.tsx +3 -1
  24. package/app/components/garden/GardenFile.tsx +9 -7
  25. package/app/components/garden/blocks.tsx +34 -24
  26. package/app/components/garden/chrome.tsx +20 -13
  27. package/app/garden/[...slug]/page.tsx +10 -130
  28. package/app/garden/en/[...slug]/page.tsx +28 -0
  29. package/app/garden/en/page.tsx +16 -0
  30. package/app/garden/page.tsx +7 -74
  31. package/app/garden-modules.d.ts +3 -0
  32. package/app/layout.tsx +2 -4
  33. package/app/lib/content.ts +12 -2
  34. package/app/lib/garden-docs-meta.ts +60 -5
  35. package/app/lib/handbook-path.ts +11 -0
  36. package/app/lib/i18n.ts +222 -0
  37. package/app/lib/page-alternates.ts +2 -2
  38. package/app/not-found.tsx +5 -3
  39. package/app/site.config.ts +1 -1
  40. package/app/styles/a2.css +101 -32
  41. package/app/styles/shell.css +6 -0
  42. package/app/thoughts/page/[n]/page.tsx +44 -0
  43. package/app/thoughts/page.tsx +2 -6
  44. package/bin/garden.mjs +4 -0
  45. package/docs/handbook/ai-writing.md +99 -0
  46. package/docs/handbook/components/card.md +2 -0
  47. package/docs/handbook/components/chart.md +2 -0
  48. package/docs/handbook/components/compare.md +10 -12
  49. package/docs/handbook/components/figure.md +2 -0
  50. package/docs/handbook/components/file.md +2 -0
  51. package/docs/handbook/components/html.md +2 -0
  52. package/docs/handbook/components/interactive.md +2 -0
  53. package/docs/handbook/components/stat.md +2 -0
  54. package/docs/handbook/components/timeline.md +2 -0
  55. package/docs/handbook/components.md +1 -1
  56. package/docs/handbook/config.md +2 -2
  57. package/docs/handbook/deploy.md +1 -1
  58. package/docs/handbook/design.md +3 -3
  59. package/docs/handbook/en/ai-writing.md +99 -0
  60. package/docs/handbook/en/components/card.md +46 -0
  61. package/docs/handbook/en/components/chart.md +54 -0
  62. package/docs/handbook/en/components/compare.md +38 -0
  63. package/docs/handbook/en/components/figure.md +72 -0
  64. package/docs/handbook/en/components/file/checklist.md +17 -0
  65. package/docs/handbook/en/components/file.md +34 -0
  66. package/docs/handbook/en/components/html.md +69 -0
  67. package/docs/handbook/en/components/interactive.md +67 -0
  68. package/docs/handbook/en/components/stat.md +57 -0
  69. package/docs/handbook/en/components/timeline.md +52 -0
  70. package/docs/handbook/en/components.md +30 -0
  71. package/docs/handbook/en/config.md +125 -0
  72. package/docs/handbook/en/deploy.md +273 -0
  73. package/docs/handbook/en/design.md +81 -0
  74. package/docs/handbook/en/index.md +192 -0
  75. package/docs/handbook/en/start.md +92 -0
  76. package/docs/handbook/en/workflow.md +81 -0
  77. package/docs/handbook/en/writing.md +156 -0
  78. package/docs/handbook/index.md +98 -3
  79. package/docs/handbook/writing.md +18 -10
  80. package/package.json +1 -1
  81. package/scripts/build-content.mjs +23 -3
  82. package/scripts/handbook-facts.mjs +34 -0
  83. package/scripts/html-lang.mjs +36 -0
  84. package/scripts/static-404.mjs +25 -0
  85. package/scripts/ui-cli.mjs +14 -8
  86. package/templates/site/site.config.yaml +2 -0
  87. package/ui/core/apply.mjs +22 -4
  88. package/ui/core/cli-locale.mjs +67 -0
  89. package/ui/core/fence.mjs +18 -3
  90. package/ui/core/fix-prompt.mjs +18 -15
  91. package/ui/core/garden-fence.mjs +64 -0
  92. package/ui/core/scan.mjs +19 -3
  93. package/ui/garden/adjacent.mjs +21 -0
  94. package/ui/garden/check.mjs +6 -0
  95. package/ui/garden/html-lang.mjs +16 -0
  96. package/ui/garden/paging.mjs +30 -0
  97. package/ui/preview/dist/garden-ui.css +9 -9
  98. package/ui/preview/dist/garden-ui.esm.js +169 -169
  99. package/ui/preview/dist/garden-ui.iife.js +169 -169
  100. package/ui/react/components/chart.tsx +7 -4
  101. package/ui/react/components/display.tsx +6 -3
  102. package/ui/react/components/inputs.tsx +6 -3
  103. package/ui/react/components/layout.tsx +6 -4
  104. package/ui/react/components/media.tsx +7 -4
  105. package/ui/react/components/sandbox.tsx +3 -1
  106. package/ui/react/index.tsx +11 -7
  107. package/ui/react/lang.tsx +85 -0
  108. package/ui/react/runtime.tsx +3 -1
  109. package/ui/react/ui.css +9 -9
  110. package/worker/index.ts +8 -1
@@ -0,0 +1,99 @@
1
+ ---
2
+ title: 用 AI 写作
3
+ navTitle: 用 AI 写作
4
+ description: 用一句话描述想要的组件,交给 Agent 生成;提交前由同一个脚本检查,失败时打印可粘贴给 AI 的修复提示词。
5
+ section: getting-started
6
+ order: 2
7
+ ---
8
+
9
+ 在 Garden 里写图表、指标或交互组件不用记标签语法。你在正文写一句自然语言想法,Agent 按站点里的 skill 把它编译成组件,提交时再由同一套命令检查。
10
+
11
+ > [!IMPORTANT] 人和 Agent 用同一套工具
12
+ > Agent 找块用 `npx garden ui scan`,写回用 `npx garden ui apply`,自查用 `npx garden ui check`;作者提交时 pre-commit 钩子运行的也是 `npx garden ui check`。检查失败时打印的提示词,就是发给 Agent 的下一步指令。
13
+
14
+ ## 1. 写一句想法
15
+
16
+ 在想放组件的位置写一个不带名字的 `garden` 围栏,只写想让读者做什么、看到什么,不用写组件名:
17
+
18
+ ````markdown
19
+ ```garden
20
+ 让读者拖动每天写的字数和每周写几天,看写完一篇 8000 字的长文要几周。
21
+ ```
22
+ ````
23
+
24
+ 草稿(`draft: true`)里可以保留未编译的想法;非草稿文章里还有未编译的想法时,`npx garden ui check` 和 `npx garden check` 都会报 `garden-idea` 错误。Agent 会根据内容把想法编译成 `garden interactive`、`card`、`stat`、`compare` 等内置组件,或者在一段话就能说清时直接写回普通段落。
25
+
26
+ ## 2. 随包安装的三个 skill
27
+
28
+ 三个 skill 存放在站点根目录的 `.agents/skills/` 下。`npx hd-garden init` 建站时会自动安装,首次运行 `npx garden sync` 或 `npx garden dev` 时会补齐缺失的 skill,运行 `npx garden skill` 可手动重装。
29
+
30
+ | Skill 名称 | 触发话术示例 | 执行操作 |
31
+ | :--- | :--- | :--- |
32
+ | `garden-ui` | 「编译这篇:content/posts/writing-pace.md」「重编译 writing-pace」或直接粘贴修复提示词 | 扫描 `uncompiled`、`stale`、`error` 状态的块,按规则生成组件并用 `npx garden ui apply` 写回;说「这篇哪里适合交互」则进入只读建议模式,最多挑出 5 处可直接粘贴的想法草稿 |
33
+ | `garden-interactive-chart` | 组件目录表达不了的画布动画或模拟 | 在文章同名目录下编写独立 `.html` 文件,正文中只用 `garden html` 围栏嵌入 |
34
+ | `garden-post-review` | 「审稿:content/posts/writing-pace.md」 | 先修 `npx garden check` 报出的结构错误,再按图表规范修交互块,最后通读全文只给修改建议而不改稿 |
35
+
36
+ ## 3. `garden ui` 子命令与整篇检查
37
+
38
+ `garden ui` 下的子命令供作者和 Agent 共用;想法块没有 `id` 时,`npx garden ui apply` 用 `npx garden ui scan` 输出的 `--intent-hash`(或行号 `--at`)定位。
39
+
40
+ | 命令 | 作者何时使用 | Agent 何时使用 |
41
+ | :--- | :--- | :--- |
42
+ | `npx garden ui scan <稿件.md>` | 查看文内有哪些待编译或报错的块 | 第一步:读取每块的 `status`、`startLine`、`hash` 和 `intentHash` |
43
+ | `npx garden ui prompt [--studio]` | 查看组件目录、设计规则与配方示例 | 编写组件前必读,只使用目录里存在的组件与属性 |
44
+ | `npx garden ui schema` | 查看组件目录的 JSON 定义 | 需要结构化读取组件属性约束时调用 |
45
+ | `npx garden ui apply <稿件.md> --id <id>` | 日常手写一般不用 | 按 `--id`、`--intent-hash` 或 `--at` 替换单个围栏,围栏外逐字节不变 |
46
+ | `npx garden ui check <稿件.md>` | 提交前钩子自动运行(也可传 `--staged` 或 `--all`) | 写回后自查,直到退出码为 `0` |
47
+ | `npx garden ui catalog [--out 文件] [--no-open]` | 在 `.garden/ui-catalog.html` 生成离线组件清单并在浏览器查看 | 一般不用 |
48
+ | `npx garden check <稿件.md>` | 单独检查一篇文章的标题、图片与全部围栏 | 全部块写回后的收尾检查,确认输出 JSON 的 `ok` 为 `true` |
49
+
50
+ ## 4. 提交前检查与修复提示词
51
+
52
+ 首次运行 `npx garden sync` 或 `npx garden dev` 时,Garden 会在 `.git/hooks/pre-commit` 写入 `exec npx --no-install garden ui check --staged --quiet`(若已有其他钩子则不覆盖,只提示需添加的命令)。`--staged` 直接通过 `git show :<路径>` 读取暂存区内容,失败时输出文件行号、诊断码和一段修复提示词:
53
+
54
+ ```console
55
+ content/posts/writing-pace.md:9 - garden-idea 还有没编译的想法
56
+
57
+ ──────────────────────── 发给 AI 的修复提示词 ────────────────────────
58
+ 请处理下面 Garden 博文里列出的块:没编译的想法要编译,有错误的交互块要修好。
59
+ ……
60
+ ```
61
+
62
+ - 提示词同时写入 `.garden/ui-fix-prompt.md`,系统有 `pbcopy`、`wl-copy`、`xclip`、`xsel` 或 `clip` 时自动复制到剪贴板;传入 `--no-copy` 或设置 `GARDEN_UI_NO_COPY=1` 可关闭自动复制。
63
+ - 需要把提示词发给无法读取本地仓库的网页端聊天窗口时,运行 `npx garden ui check <稿件.md> --standalone`,提示词末尾会附上完整的 `npx garden ui prompt` 组件规则(单次最多附 10 个问题块的原文)。
64
+ - 交互块里写错标签名(如把 `<Slider>` 写成 `<Slidr>`)也会报 `ui-component` 并指到具体行号;确实要先带病提交时可用 `git commit --no-verify`。
65
+ - 需要重装钩子时运行 `npx garden hooks`(加 `--force` 覆盖已有钩子);不想自动安装钩子时设置 `GARDEN_SKIP_HOOKS=1`。
66
+
67
+ ## 5. 用一句话生成代码对比
68
+
69
+ 在改好的完整代码块正下方放一个 `garden` 想法块,用一句话写出它和上一版相比改了什么:
70
+
71
+ ````markdown
72
+ ```yaml
73
+ pages:
74
+ garden:
75
+ title: "用 Markdown 写丨推送之后网站自己更新"
76
+ ```
77
+
78
+ ```garden
79
+ 和上一版比:标题原来用句号和换行分两行,现在改成用「丨」分行。
80
+ ```
81
+ ````
82
+
83
+ Agent 按 `garden-ui` skill 会把这个想法块替换成一段紧挨着完整代码的 `diff` 围栏。页面渲染时会把完整代码和 `diff` 合成一个带「代码 / 对比上一版」切换按钮的代码框,手写 `diff` 的规则见 [写文章与随想](/garden/writing)。
84
+
85
+ ## 6. 不使用 Agent 时的快捷输入
86
+
87
+ 不借助 AI 手写组件时,可以直接使用包内自带的模板与代码片段:
88
+
89
+ - `make new` 创建的草稿底部自带一段 `<!-- 组件速查 ... -->` 注释,包含想法块和 9 个组件的示例,写完可直接删掉。
90
+ - `templates/garden-blocks.md` 汇总了想法块与 9 个组件的适用场景(`when` / `whenNot`)和可复制示例;macOS 与 Typora / Alfred 用户可导入 `templates/garden-snippets.plist`,输入 `;gidea`(或 `;garden想法`)、`;gcard`、`;gstat`、`;gcompare`、`;gtimeline`、`;gchart`、`;gfigure`、`;ghtml`、`;ginteractive`、`;gfile` 即可展开对应围栏。
91
+ - 引擎仓库的 `editors/vscode`、`editors/typora` 与 `editors/obsidian` 目录提供了对应的编辑器片段与插件支持,运行 `npx garden ui catalog` 则可在本地生成 `.garden/ui-catalog.html` 离线组件画廊。
92
+
93
+ ## 7. 可选的独立管理后台
94
+
95
+ Garden 引擎仓库内置了可选的 `/admin` 管理后台(位于 `app/admin` 与 `worker/`),可通过 `npm run admin:local`、`npm run admin:cloudflare` 或 Docker 单独部署。配置环境变量后,后台提供以下网页端功能:
96
+
97
+ - 通过 GitHub OAuth 登录(仅允许 `ADMIN_GITHUB_LOGINS` 白名单中的用户),在网页端编写随想并用 `CONTENT_GITHUB_TOKEN` 直接提交为 `content/thoughts/*.md`,图片与音视频通过十分钟有效的 Post Policy 直传阿里云 OSS。
98
+ - 在 `/admin/ui/blocks` 查看仓库内全部稿件(含草稿)的交互块状态,一键复制与命令行钩子相同的修复提示词。
99
+ - 在 `/admin/ui` 组件工作台用自然语言试写或手改组件(配置 `UI_MODEL_BASE_URL`、`UI_MODEL_API_KEY`、`UI_MODEL_NAME`),在 `/admin/ui/catalog` 浏览组件清单,在 `/admin/preview/<路径>` 预览未发布草稿,以及在 `/admin/ui/evals` 运行模型自检。
@@ -7,6 +7,8 @@ order: 31
7
7
  badge: card
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「放一张 `card` 介绍 SQLite 的 WAL 文档,带标题、链接和三条要点」,Agent 会按 `garden-ui` skill 生成下面的 `garden card`(手写格式附后)。
11
+
10
12
  ```garden card
11
13
  title: SQLite WAL 写入模式
12
14
  url: https://www.sqlite.org/wal.html
@@ -7,6 +7,8 @@ order: 35
7
7
  badge: chart
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「用 `chart` 画条形图比较正文列、宽图区和宽表区的宽度上限」,Agent 会按 `garden-ui` skill 生成下面的 `garden chart`(手写格式附后)。
11
+
10
12
  ```garden chart
11
13
  title: 三种版面区域的宽度上限
12
14
  xLabel: 版面区域
@@ -7,25 +7,23 @@ order: 33
7
7
  badge: compare
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「用 `compare` 并排比较用一句话描述代码改动和手写 diff 两种做法」,Agent 会按 `garden-ui` skill 生成下面的 `garden compare`(手写格式附后)。
11
+
10
12
  ```garden compare
11
13
  items:
12
- - title: 只贴一段 diff
13
- text: 读者只看到增删行;前面没有完整代码块时,garden check 报 diff-orphan 错误。
14
- 能否复制新版: 不能
15
- - title: 完整代码 + 紧跟的 diff
16
- text: 两段合成一个代码框,可在「代码」和「对比上一版」之间切换。
17
- 能否复制新版: 两个标签下都复制新版
14
+ - title: 写一句话说明改了什么
15
+ text: 想法块紧跟在完整代码下面,garden-ui 把它换成 diff,页面合成「代码 / 对比上一版」。
16
+ - title: 手写 diff
17
+ text: 完整代码下面紧跟一段 diff;前面没有完整代码时,garden check 报 diff-orphan。
18
18
  ```
19
19
 
20
20
  ````markdown
21
21
  ```garden compare
22
22
  items:
23
- - title: 只贴一段 diff
24
- text: 读者只看到增删行;前面没有完整代码块时,garden check 报 diff-orphan 错误。
25
- 能否复制新版: 不能
26
- - title: 完整代码 + 紧跟的 diff
27
- text: 两段合成一个代码框,可在「代码」和「对比上一版」之间切换。
28
- 能否复制新版: 两个标签下都复制新版
23
+ - title: 写一句话说明改了什么
24
+ text: 想法块紧跟在完整代码下面,garden-ui 把它换成 diff,页面合成「代码 / 对比上一版」。
25
+ - title: 手写 diff
26
+ text: 完整代码下面紧跟一段 diff;前面没有完整代码时,garden check 报 diff-orphan。
29
27
  ```
30
28
  ````
31
29
 
@@ -7,6 +7,8 @@ order: 36
7
7
  badge: figure
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「用 `figure` 画一张静态发布流程的结构图,点到哪一步就高亮并显示那一步的说明」,Agent 会按 `garden-ui` skill 生成下面的 `garden figure`(手写格式附后)。
11
+
10
12
  ```garden figure
11
13
  caption: 点击上方按钮切换高亮各步骤
12
14
  svg: |
@@ -7,6 +7,8 @@ order: 39
7
7
  badge: file
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「用 `file` 给读者一份可以下载和页内预览的发布前检查清单」,Agent 会按 `garden-ui` skill 生成下面的 `garden file`(手写格式附后)。
11
+
10
12
  ```garden file
11
13
  src: ./file/checklist.md
12
14
  title: 发布前检查清单
@@ -7,6 +7,8 @@ order: 37
7
7
  badge: html
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「用 `html` 嵌一个小工具,输入文字就实时算出字符数」,Agent 会按 `garden-ui` skill 生成下面的 `garden html`(手写格式附后)。
11
+
10
12
  ```garden html
11
13
  title: 字符长度与预计阅读耗时小工具
12
14
  height: 156
@@ -7,6 +7,8 @@ order: 38
7
7
  badge: interactive
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「让读者拖动字数、阅读速度和配图数,看预计阅读时间怎么变」,Agent 会按 `garden-ui` skill 生成下面的 `garden interactive`(手写格式附后)。
11
+
10
12
  ```garden interactive #reading-time
11
13
  caption: 示例:按字数、阅读速度和配图数估算一篇文章的阅读时间。数字只用来演示组件,不是统计结果。
12
14
  ---
@@ -7,6 +7,8 @@ order: 32
7
7
  badge: stat
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「用 `stat` 列出正文列、宽图区、宽表区三个宽度上限」,Agent 会按 `garden-ui` skill 生成下面的 `garden stat`(手写格式附后)。
11
+
10
12
  ```garden stat
11
13
  items:
12
14
  - label: 正文列宽
@@ -7,6 +7,8 @@ order: 34
7
7
  badge: timeline
8
8
  ---
9
9
 
10
+ 在 `garden` 想法块里写一句「用 `timeline` 按顺序列出静态发布流水线的三个步骤」,Agent 会按 `garden-ui` skill 生成下面的 `garden timeline`(手写格式附后)。
11
+
10
12
  ```garden timeline
11
13
  title: 静态发布流水线执行步骤
12
14
  items:
@@ -6,7 +6,7 @@ section: components
6
6
  order: 30
7
7
  ---
8
8
 
9
- 当标准 Markdown 段落、列表或表格不够表达时,可以在文章里使用 ```` ```garden <name> ```` 代码块插入内置组件。所有组件名均使用英文,内部使用 YAML(`interactive` 在 `---` 下方使用声明式标签)编写参数。
9
+ 这 9 个组件都可以先在 `garden` 想法块里用一句话描述,交给 Agent 按 `garden-ui` skill 生成(详见 [用 AI 写作](/garden/ai-writing))。手写时使用 ```` ```garden <name> ```` 代码块插入,组件名固定为英文(`card`、`stat`、`compare`、`timeline`、`chart`、`figure`、`html`、`interactive`、`file`),参数采用 YAML 格式,`interactive` 则在 `---` 下方编写声明式标签。
10
10
 
11
11
  ## 9 个组件速查表
12
12
 
@@ -3,7 +3,7 @@ title: 站点与专栏配置
3
3
  navTitle: 站点与专栏配置
4
4
  description: 配置 site.config.yaml 中的站点信息、各页标题、自定义品牌图标与 content/columns.yaml 专栏。
5
5
  section: getting-started
6
- order: 2
6
+ order: 3
7
7
  ---
8
8
 
9
9
  站点的全局文字与外观信息集中在根目录的 `site.config.yaml`,专栏目录集中在 `content/columns.yaml`。修改后运行 `npx garden sync`(或直接 `make dev`)即可生效。
@@ -90,7 +90,7 @@ footer: 持续记录。
90
90
 
91
91
  `pages` 下的每个键对应一个一级路由的页头文字:
92
92
 
93
- - **`pages.home`、`pages.blog`、`pages.thoughts`、`pages.columns`、`pages.garden`**:均使用 `title` 和 `subtitle` 两个字段。其中 `/garden/` 页面会读取 `pages.garden.title`(支持用 `丨` 分成两行)和 `pages.garden.subtitle`。
93
+ - **`pages.home`、`pages.blog`、`pages.thoughts`、`pages.columns`、`pages.garden`**:均使用 `title` 和 `subtitle` 两个字段。其中 `/garden/` 页面会读取 `pages.garden.title`(写一个「丨」就在那里分成两行)和 `pages.garden.subtitle`。
94
94
  - **`pages.about`**:除 `title` 和 `subtitle` 外,还支持 `heading`(正文小标题)、`paragraphs`(段落数组)、`quote`(引言)、`focus`(关注方向标签数组)以及 `cta`(`{ href, label }` 按钮)。
95
95
 
96
96
  ### `brand` 自定义图标与路由重定向
@@ -3,7 +3,7 @@ title: 发布到 GitHub Pages
3
3
  navTitle: 发布到 GitHub Pages
4
4
  description: 配置 GitHub Actions 工作流,支持单个公开仓库或「私有源码仓库 + 公开页面仓库」两种发布方式。
5
5
  section: getting-started
6
- order: 3
6
+ order: 4
7
7
  ---
8
8
 
9
9
  `npx hd-garden init` 不会自动创建 `.github/workflows/pages.yml`。发布到 GitHub Pages 时,在站点仓库新建这个文件。同一份工作流同时支持**单个公开仓库**和**私有源码仓库 + 公开页面仓库**两种模式,按 `PAGES_REPOSITORY` 变量是否为空自动切换。
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: 阅读排版是怎么工作的
3
3
  navTitle: 阅读排版是怎么工作的
4
- description: 740/1040/1340px 三级宽度计算、丨标题断行、图片防抖动、深色模式图片衬底与无品牌蓝配色。
4
+ description: 740/1040/1340px 三级宽度计算、「丨」标题断行、图片防抖动、深色模式图片衬底与无品牌蓝配色。
5
5
  section: writing-and-reading
6
6
  order: 11
7
7
  ---
@@ -23,11 +23,11 @@ Garden 的文章页面围绕长文阅读体验做了几项自动化处理。这
23
23
 
24
24
  文章标题通过 `ArticleTitle` 组件处理,规则只有两条:
25
25
 
26
- 1. **写了分隔符(`丨`、`|` 或前后带空格的 ` | `)**:在第一个分隔符处拆成上下两行,并按较长一行的字符宽度(汉字计 `1`、大写字母计 `0.68`、其余字符计 `0.58`、空格计 `0.3`)计算 `--l` 缩放变量,使较长一行刚好放进标题宽度而不再次折行。分隔符本身保留在屏幕阅读器可读文本中。
26
+ 1. **写了分隔符(「丨」、全角「|」,或前后带空格的半角 ` | `)**:在第一个分隔符处拆成上下两行,并按较长一行的字符宽度(汉字计 `1`、大写字母计 `0.68`、其余字符计 `0.58`、空格计 `0.3`)计算 `--l` 缩放变量,使较长一行刚好放进标题宽度而不再次折行。分隔符本身保留在屏幕阅读器可读文本中。
27
27
  2. **没有写分隔符**:保持单段 `<h1>`,仅使用 CSS `text-wrap: balance` 让浏览器均衡换行,**不会**自动在冒号、破折号或中间位置拆行,也不会自动改变字号。
28
28
 
29
29
  > [!NOTE]
30
- > 如果标题里写了 `丨`,但分隔符左边或右边为空(例如 `丨副标题`),`npx garden check` 会报 `title-split` 警告(提示 `分隔符两侧都要有文字`)。
30
+ > 如果标题里写了「丨」,但分隔符左边或右边为空(例如 `丨副标题`),`npx garden check` 会报 `title-split` 警告(提示 `分隔符两侧都要有文字`)。
31
31
 
32
32
  ## 3. 构建期读取图片尺寸与点击放大
33
33
 
@@ -0,0 +1,99 @@
1
+ ---
2
+ title: Writing with AI
3
+ navTitle: Writing with AI
4
+ description: Describe components in one sentence for an Agent to compile, and validate staged files with the same CLI in the pre-commit hook.
5
+ section: getting-started
6
+ order: 2
7
+ ---
8
+
9
+ You do not need to memorize component tags to add charts, metrics, or interactive calculators in Garden. Write a one-sentence idea in the post body, let an Agent compile it using the repository's skills, and verify the result on commit with the same CLI commands.
10
+
11
+ > [!IMPORTANT] Humans and Agents Share the Same Tools
12
+ > The Agent uses `npx garden ui scan` to locate blocks, `npx garden ui apply` to write them back, and `npx garden ui check` to validate them; the author's pre-commit hook runs `npx garden ui check` too. When a check fails, the printed prompt is the instruction to hand to the Agent.
13
+
14
+ ## 1. Write a One-sentence Idea
15
+
16
+ Place an unnamed `garden` fence where the component belongs and state what the reader should do and see, without naming a component:
17
+
18
+ ````markdown
19
+ ```garden
20
+ Let the reader drag daily word count and writing days per week to see how many weeks an 8,000-word article takes.
21
+ ```
22
+ ````
23
+
24
+ Draft posts (`draft: true`) may keep uncompiled idea fences; in non-draft posts, both `npx garden ui check` and `npx garden check` report a `garden-idea` error. Depending on the content, the Agent compiles the idea into a built-in component (`garden interactive`, `card`, `stat`, `compare`, and others) or replaces it with plain prose when a paragraph is clearer.
25
+
26
+ ## 2. Three Bundled Skills
27
+
28
+ Three skills live in `.agents/skills/` at the root of the site repository. `npx hd-garden init` installs them when creating a site, the first `npx garden sync` or `npx garden dev` fills in any missing skill files, and `npx garden skill` reinstalls them on demand.
29
+
30
+ | Skill Name | Example Trigger Prompt | What It Does |
31
+ | :--- | :--- | :--- |
32
+ | `garden-ui` | "Compile this post: content/posts/writing-pace.md", "Recompile writing-pace", or pasting a fix prompt | Scans `uncompiled`, `stale`, and `error` blocks, generates components, and writes them back via `npx garden ui apply`; asking where interactive blocks fit runs read-only suggestion mode and returns up to 5 ready-to-paste idea fences |
33
+ | `garden-interactive-chart` | Canvas animations or simulations beyond the built-in component catalog | Writes a standalone `.html` file inside the post's sidecar directory and embeds it in the post with a `garden html` fence |
34
+ | `garden-post-review` | "Review post: content/posts/writing-pace.md" | Fixes structural errors reported by `npx garden check`, repairs interactive blocks against the chart rules, and reads the full post to offer editorial suggestions without rewriting prose |
35
+
36
+ ## 3. `garden ui` Subcommands and Post Checks
37
+
38
+ Authors and Agents run the same `garden ui` subcommands; when an idea fence has no `id`, `npx garden ui apply` targets it by the `--intent-hash` (or `--at` line number) returned by `npx garden ui scan`.
39
+
40
+ | Command | When the Author Runs It | When the Agent Runs It |
41
+ | :--- | :--- | :--- |
42
+ | `npx garden ui scan <post.md>` | Inspect which blocks in a post are uncompiled or failing | Step 1: read each block's `status`, `startLine`, `hash`, and `intentHash` |
43
+ | `npx garden ui prompt [--studio]` | Read the component catalog, design rules, and recipes | Read before writing a block so only cataloged components and props are used |
44
+ | `npx garden ui schema` | Inspect the JSON schema of the component catalog | Read structured prop constraints programmatically |
45
+ | `npx garden ui apply <post.md> --id <id>` | Rarely needed when writing by hand | Replace a single fence by `--id`, `--intent-hash`, or `--at` while keeping everything outside the fence byte-identical |
46
+ | `npx garden ui check <post.md>` | Run automatically by the pre-commit hook (also accepts `--staged` or `--all`) | Validate after applying changes until the exit code is `0` |
47
+ | `npx garden ui catalog [--out file] [--no-open]` | Generate `.garden/ui-catalog.html` for offline browsing | Not used by the Agent |
48
+ | `npx garden check <post.md>` | Check a single post's title, images, and fences | Final check after all blocks are applied, verifying `"ok": true` in the JSON output |
49
+
50
+ ## 4. Pre-commit Hook and Fix Prompts
51
+
52
+ On the first `npx garden sync` or `npx garden dev` run, Garden writes `exec npx --no-install garden ui check --staged --quiet` to `.git/hooks/pre-commit` (if a custom hook already exists, it leaves the file untouched and prints the line to add). `--staged` reads staged content directly via `git show :<path>` and, on failure, prints the line numbers, diagnostic codes, and a fix prompt:
53
+
54
+ ```console
55
+ content/posts/writing-pace.md:9 - garden-idea uncompiled idea remaining
56
+
57
+ ──────────────────────── Fix prompt for AI ────────────────────────
58
+ Handle the Garden post blocks listed below: compile uncompiled ideas, and fix interactive blocks that have errors.
59
+ ……
60
+ ```
61
+
62
+ - The prompt is written to `.garden/ui-fix-prompt.md` and copied to the clipboard when `pbcopy`, `wl-copy`, `xclip`, `xsel`, or `clip` is available; pass `--no-copy` or set `GARDEN_UI_NO_COPY=1` to disable clipboard copying.
63
+ - When pasting into a web chat that cannot read your local repository, run `npx garden ui check <post.md> --standalone` to append the full `npx garden ui prompt` rules to the prompt (including source fences for up to 10 failing blocks).
64
+ - A misspelled tag inside an interactive block (such as `<Slidr>` instead of `<Slider>`) reports `ui-component` with its exact line number; to commit anyway, run `git commit --no-verify`.
65
+ - Run `npx garden hooks` to reinstall the hook (pass `--force` to overwrite an existing hook), or set `GARDEN_SKIP_HOOKS=1` to skip automatic hook installation.
66
+
67
+ ## 5. Generate a Code Diff from One Sentence
68
+
69
+ Place a `garden` idea fence immediately below an updated code block and state in one sentence what changed compared with the previous version:
70
+
71
+ ````markdown
72
+ ```yaml
73
+ pages:
74
+ garden:
75
+ title: "Write in Markdown | Push to Update the Site"
76
+ ```
77
+
78
+ ```garden
79
+ Compared with the previous version: split the title into two lines with " | " instead of a period and newline.
80
+ ```
81
+ ````
82
+
83
+ Following the `garden-ui` skill, the Agent replaces that idea fence with a `diff` fence right below the code block. The page merges the adjacent code and `diff` fences into a single code frame with a toggle between the full code and the diff; see [Writing Posts & Thoughts](/garden/en/writing) for the hand-written `diff` format.
84
+
85
+ ## 6. Templates and Snippets Without an Agent
86
+
87
+ When writing components by hand without AI, you can use the templates and snippets shipped in the package:
88
+
89
+ - Every draft created by `make new` includes an HTML comment at the bottom with copy-ready examples for idea fences and all 9 components; delete the comment whenever you are done.
90
+ - `templates/garden-blocks.md` lists `when` / `whenNot` guidance and copyable templates for every block; macOS, Typora, and Alfred users can import `templates/garden-snippets.plist` to expand `;gidea`, `;gcard`, `;gstat`, `;gcompare`, `;gtimeline`, `;gchart`, `;gfigure`, `;ghtml`, `;ginteractive`, and `;gfile`.
91
+ - The engine repository also ships editor integrations under `editors/vscode`, `editors/typora`, and `editors/obsidian`, and `npx garden ui catalog` generates an offline component catalog at `.garden/ui-catalog.html`.
92
+
93
+ ## 7. Optional Standalone Admin
94
+
95
+ The Garden engine includes an optional `/admin` console (under `app/admin` and `worker/`) that can be deployed separately with `npm run admin:local`, `npm run admin:cloudflare`, or Docker. Once configured via environment variables, it provides:
96
+
97
+ - GitHub OAuth sign-in restricted to the `ADMIN_GITHUB_LOGINS` allowlist, a web editor that commits thoughts directly to `content/thoughts/*.md` using `CONTENT_GITHUB_TOKEN`, and direct browser uploads to Alibaba Cloud OSS via 10-minute Post Policies.
98
+ - An interactive block overview at `/admin/ui/blocks` across all posts (including drafts) with one-click copying of the same fix prompt produced by the CLI hook.
99
+ - The `/admin/ui` studio for drafting or editing components with a model (`UI_MODEL_BASE_URL`, `UI_MODEL_API_KEY`, `UI_MODEL_NAME`), the catalog at `/admin/ui/catalog`, draft previews at `/admin/preview/<path>`, and model evaluations at `/admin/ui/evals`.
@@ -0,0 +1,46 @@
1
+ ---
2
+ title: Reference Card (card)
3
+ navTitle: card
4
+ description: Summarize a paper, repository, or module in a card with metadata and numbered takeaways.
5
+ section: components
6
+ order: 31
7
+ badge: card
8
+ ---
9
+
10
+ Write "add a `card` summarizing the SQLite WAL documentation with a title, link, and three takeaways" inside a `garden` idea block, and the Agent generates the `garden card` block below via the `garden-ui` skill (hand-written syntax follows).
11
+
12
+ ```garden card
13
+ title: SQLite Write-Ahead Logging
14
+ url: https://www.sqlite.org/wal.html
15
+ meta: Documentation · sqlite.org
16
+ description: Appends changes sequentially to a write-ahead log while readers continue reading the original database pages, reducing read-write contention.
17
+ points:
18
+ - Writes append to the end of the `-wal` file instead of overwriting database pages in place on commit.
19
+ - Readers record the current end-of-log mark to see a consistent snapshot without blocking concurrent writers.
20
+ - Background checkpoints copy log pages back into the main database file in batches once a threshold is reached.
21
+ ```
22
+
23
+ ````markdown
24
+ ```garden card
25
+ title: SQLite Write-Ahead Logging
26
+ url: https://www.sqlite.org/wal.html
27
+ meta: Documentation · sqlite.org
28
+ description: Appends changes sequentially to a write-ahead log while readers continue reading the original database pages, reducing read-write contention.
29
+ points:
30
+ - Writes append to the end of the `-wal` file instead of overwriting database pages in place on commit.
31
+ - Readers record the current end-of-log mark to see a consistent snapshot without blocking concurrent writers.
32
+ - Background checkpoints copy log pages back into the main database file in batches once a threshold is reached.
33
+ ```
34
+ ````
35
+
36
+ - **Use when**: Introducing a paper, open-source project, or subsystem where a source link and 2 to 4 numbered points belong together.
37
+ - **Skip when**: A sentence or two of prose or a `[Title](url "{card}")` link card is enough.
38
+
39
+ | Field | Required | Type | Description |
40
+ | :--- | :--- | :--- | :--- |
41
+ | `title` | Recommended | string | Card heading |
42
+ | `url` | No | full URL | External link shown next to the heading |
43
+ | `meta` | No | string | Subtitle or metadata line below the heading |
44
+ | `description` | Either this or `points` | string | Main summary paragraph (supports inline bold and code) |
45
+ | `points` | Either this or `description` | string[] | Numbered list of takeaways below the summary |
46
+ | `source` | No | string or `{ title, url }` | Source attribution in the bottom-right corner |
@@ -0,0 +1,54 @@
1
+ ---
2
+ title: Bar Chart (chart)
3
+ navTitle: chart
4
+ description: Render proportional horizontal bars from YAML data, with a built-in expandable table underneath.
5
+ section: components
6
+ order: 35
7
+ badge: chart
8
+ ---
9
+
10
+ Write "use `chart` to compare the max widths of the prose column, wide figures, and wide tables" inside a `garden` idea block, and the Agent generates the `garden chart` block below via the `garden-ui` skill (hand-written syntax follows).
11
+
12
+ ```garden chart
13
+ title: Max Width by Layout Zone
14
+ xLabel: Layout Zone
15
+ yLabel: Max Width
16
+ unit: px
17
+ data:
18
+ - x: Prose Column
19
+ y: 740
20
+ - x: Wide Figure Zone
21
+ y: 1040
22
+ - x: Wide Table Zone
23
+ y: 1340
24
+ caption: Click "View data table" below to expand the full numeric table.
25
+ ```
26
+
27
+ ````markdown
28
+ ```garden chart
29
+ title: Max Width by Layout Zone
30
+ xLabel: Layout Zone
31
+ yLabel: Max Width
32
+ unit: px
33
+ data:
34
+ - x: Prose Column
35
+ y: 740
36
+ - x: Wide Figure Zone
37
+ y: 1040
38
+ - x: Wide Table Zone
39
+ y: 1340
40
+ caption: Click "View data table" below to expand the full numeric table.
41
+ ```
42
+ ````
43
+
44
+ - **Use when**: Comparing the relative magnitudes of 2 to 8 values that share the same unit.
45
+ - **Skip when**: You already have a Markdown table with the same numbers in that section (`chart` includes its own expandable table).
46
+
47
+ | Field | Required | Type | Description |
48
+ | :--- | :--- | :--- | :--- |
49
+ | `title` | Recommended | string | Chart heading |
50
+ | `data` | Yes | `{ x, y, label? }[]` (at least 2) | Data rows where `x` is the label and `y` is the numeric value |
51
+ | `unit` | No | string | Unit suffix appended when a row does not specify its own `label` |
52
+ | `xLabel` | No | string | Header for the first column of the expandable table |
53
+ | `yLabel` | No | string | Header for the second column of the expandable table |
54
+ | `caption` | No | string | Caption shown below the chart |
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: Side-by-Side Comparison (compare)
3
+ navTitle: compare
4
+ description: Place two or three options side by side to contrast tradeoffs and attributes.
5
+ section: components
6
+ order: 33
7
+ badge: compare
8
+ ---
9
+
10
+ Write "use `compare` to contrast describing a code change in one sentence against writing a diff block by hand" inside a `garden` idea block, and the Agent generates the `garden compare` block below via the `garden-ui` skill (hand-written syntax follows).
11
+
12
+ ```garden compare
13
+ items:
14
+ - title: Describe the change in one sentence
15
+ text: Idea block under full code; garden-ui writes the diff.
16
+ - title: Write the diff by hand
17
+ text: Place a diff below full code; alone it raises diff-orphan.
18
+ ```
19
+
20
+ ````markdown
21
+ ```garden compare
22
+ items:
23
+ - title: Describe the change in one sentence
24
+ text: Idea block under full code; garden-ui writes the diff.
25
+ - title: Write the diff by hand
26
+ text: Place a diff below full code; alone it raises diff-orphan.
27
+ ```
28
+ ````
29
+
30
+ - **Use when**: Comparing 2 or 3 options, configurations, or before/after behaviors side by side (keep each cell under ~60 characters).
31
+ - **Skip when**: Comparing more than 3 items or aligning multiple attributes across rows; use a Markdown table instead.
32
+
33
+ | Field | Required | Type | Description |
34
+ | :--- | :--- | :--- | :--- |
35
+ | `items` | Yes | array (at least 2) | Options to compare; each entry can also be a `"Title: description"` shorthand string |
36
+ | `items[].title` | Recommended | string | Column heading |
37
+ | `items[].text` | Recommended | string or string[] | Body description for the column |
38
+ | `items[].<customKey>` | No | string or number | Extra key-value pairs rendered as attribute tags along the bottom of the card |
@@ -0,0 +1,72 @@
1
+ ---
2
+ title: Annotated Diagram (figure)
3
+ navTitle: figure
4
+ description: Pair an SVG diagram with step buttons that highlight each region and show its explanation.
5
+ section: components
6
+ order: 36
7
+ badge: figure
8
+ ---
9
+
10
+ Write "use `figure` to draw the static publishing flow where clicking each step highlights that box and shows what it does" inside a `garden` idea block, and the Agent generates the `garden figure` block below via the `garden-ui` skill (hand-written syntax follows).
11
+
12
+ ```garden figure
13
+ caption: Click the buttons above to highlight each stage
14
+ svg: |
15
+ <svg viewBox="0 0 680 110" xmlns="http://www.w3.org/2000/svg" font-family="var(--sans)">
16
+ <rect data-p="sync" x="12" y="18" width="196" height="74" rx="10" fill="var(--card)" stroke="var(--rule-strong)" stroke-width="1.5"/>
17
+ <text data-p="sync" x="110" y="50" text-anchor="middle" font-size="14" font-weight="600" fill="var(--ink)">1. garden sync</text>
18
+ <text data-p="sync" x="110" y="72" text-anchor="middle" font-size="12" fill="var(--muted)">Parse Markdown &amp; image sizes</text>
19
+ <path d="M214 55 H236" stroke="var(--muted)" stroke-width="1.5"/>
20
+ <rect data-p="build" x="242" y="18" width="196" height="74" rx="10" fill="var(--card)" stroke="var(--rule-strong)" stroke-width="1.5"/>
21
+ <text data-p="build" x="340" y="50" text-anchor="middle" font-size="14" font-weight="600" fill="var(--ink)">2. garden build</text>
22
+ <text data-p="build" x="340" y="72" text-anchor="middle" font-size="12" fill="var(--muted)">Build static pages &amp; index</text>
23
+ <path d="M444 55 H466" stroke="var(--muted)" stroke-width="1.5"/>
24
+ <rect data-p="validate" x="472" y="18" width="196" height="74" rx="10" fill="var(--card)" stroke="var(--rule-strong)" stroke-width="1.5"/>
25
+ <text data-p="validate" x="570" y="50" text-anchor="middle" font-size="14" font-weight="600" fill="var(--ink)">3. pages:validate</text>
26
+ <text data-p="validate" x="570" y="72" text-anchor="middle" font-size="12" fill="var(--muted)">Check index.html &amp; files</text>
27
+ </svg>
28
+ parts:
29
+ - id: sync
30
+ label: 1. Sync Content
31
+ text: Scans `content/` and `docs/handbook/`, copies sidecar assets, and generates `.garden/generated-content.ts`.
32
+ - id: build
33
+ label: 2. Build Pages
34
+ text: Prerenders all routes with `STATIC_EXPORT=1` and outputs RSS, sitemap, and full-text search indexes.
35
+ - id: validate
36
+ label: 3. Validate Export
37
+ text: Runs pages:validate to confirm `index.html` exists and no `.env`, source directories, `.map` or `.md` files, or symlinks are present.
38
+ ```
39
+
40
+ ````markdown
41
+ ```garden figure
42
+ caption: Click the buttons above to highlight each stage
43
+ svg: |
44
+ <svg viewBox="0 0 680 110" xmlns="http://www.w3.org/2000/svg" font-family="var(--sans)">
45
+ <rect data-p="sync" x="12" y="18" width="196" height="74" rx="10" fill="var(--card)" stroke="var(--rule-strong)" stroke-width="1.5"/>
46
+ <text data-p="sync" x="110" y="50" text-anchor="middle" font-size="14" font-weight="600" fill="var(--ink)">1. garden sync</text>
47
+ <text data-p="sync" x="110" y="72" text-anchor="middle" font-size="12" fill="var(--muted)">Parse Markdown &amp; image sizes</text>
48
+ <rect data-p="build" x="242" y="18" width="196" height="74" rx="10" fill="var(--card)" stroke="var(--rule-strong)" stroke-width="1.5"/>
49
+ <rect data-p="validate" x="472" y="18" width="196" height="74" rx="10" fill="var(--card)" stroke="var(--rule-strong)" stroke-width="1.5"/>
50
+ </svg>
51
+ parts:
52
+ - id: sync
53
+ label: 1. Sync Content
54
+ text: Scans `content/` and `docs/handbook/`, copies sidecar assets, and generates `.garden/generated-content.ts`.
55
+ - id: build
56
+ label: 2. Build Pages
57
+ text: Prerenders all routes with `STATIC_EXPORT=1` and outputs RSS, sitemap, and full-text search indexes.
58
+ - id: validate
59
+ label: 3. Validate Export
60
+ text: Runs pages:validate to confirm `index.html` exists and no `.env`, source directories, `.map` or `.md` files, or symlinks are present.
61
+ ```
62
+ ````
63
+
64
+ - **Use when**: Walking through module boundaries or data flow where clicking each button highlights the matching SVG elements and explains their role (use theme variables like `var(--well)`, `var(--ink)`, and `var(--muted)` inside SVG so dark mode works).
65
+ - **Skip when**: A static image or a `mermaid` diagram does not need interactive region highlighting.
66
+
67
+ | Field | Required | Type | Description |
68
+ | :--- | :--- | :--- | :--- |
69
+ | `svg` | Either this or `image` | multiline string | Inline `<svg>` markup; tag elements to highlight with `data-p="<id>"` |
70
+ | `image` | Either this or `svg` | path string | Image path (or `{ src, alt }`) |
71
+ | `parts` | No | `{ id, label, text }[]` | Buttons shown above the diagram and the matching explanation below |
72
+ | `caption` | No | string | Caption below the frame |
@@ -0,0 +1,17 @@
1
+ # Site Pre-publish Checklist
2
+
3
+ Before running `make update` to push changes, verify the following items:
4
+
5
+ ## 1. Post Front Matter and Paths
6
+
7
+ - [x] `title`, `date`, and `description` are filled in, and the filename uses only lowercase letters, digits, and hyphens
8
+ - [x] Local images and attachments live in the post's sidecar folder and use `./<slug>/file.ext` relative paths
9
+ - [x] `draft: true` has been removed from posts ready to publish
10
+
11
+ ## 2. Local Validation Commands
12
+
13
+ | Command | What It Checks |
14
+ | :--- | :--- |
15
+ | `npx garden check content/posts/<slug>.md` | Checks a single post's component fields, code diffs, and local asset paths |
16
+ | `make check` | Runs `npx garden sync && npx garden build` to validate the full site build |
17
+ | `CONTENT_INCLUDE_DRAFTS=1 make dev` | Previews drafts and scheduled posts locally |