@lark-apaas/coding-templates 0.1.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 (216) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +128 -0
  3. package/meta.json +22 -0
  4. package/package.json +22 -0
  5. package/template-html/README.md +148 -0
  6. package/template-html/_gitignore +2 -0
  7. package/template-html/index.html +22 -0
  8. package/template-html/package.json +12 -0
  9. package/template-html/routes.json +1 -0
  10. package/template-html/scripts/build.sh +31 -0
  11. package/template-nextjs-fullstack/README.md +169 -0
  12. package/template-nextjs-fullstack/_env.local.example +1 -0
  13. package/template-nextjs-fullstack/_gitignore +41 -0
  14. package/template-nextjs-fullstack/components.json +25 -0
  15. package/template-nextjs-fullstack/drizzle.config.ts +10 -0
  16. package/template-nextjs-fullstack/eslint.config.js +15 -0
  17. package/template-nextjs-fullstack/next.config.ts +5 -0
  18. package/template-nextjs-fullstack/package.json +85 -0
  19. package/template-nextjs-fullstack/postcss.config.js +8 -0
  20. package/template-nextjs-fullstack/scripts/build.sh +37 -0
  21. package/template-nextjs-fullstack/src/app/favicon.ico +0 -0
  22. package/template-nextjs-fullstack/src/app/globals.css +130 -0
  23. package/template-nextjs-fullstack/src/app/layout.tsx +24 -0
  24. package/template-nextjs-fullstack/src/app/page.tsx +69 -0
  25. package/template-nextjs-fullstack/src/app/todos/actions.ts +37 -0
  26. package/template-nextjs-fullstack/src/app/todos/page.tsx +26 -0
  27. package/template-nextjs-fullstack/src/app/todos/todo-form.tsx +27 -0
  28. package/template-nextjs-fullstack/src/app/todos/todo-list.tsx +44 -0
  29. package/template-nextjs-fullstack/src/components/header.tsx +32 -0
  30. package/template-nextjs-fullstack/src/components/theme-provider.tsx +8 -0
  31. package/template-nextjs-fullstack/src/components/ui/README.md +134 -0
  32. package/template-nextjs-fullstack/src/components/ui/accordion.tsx +66 -0
  33. package/template-nextjs-fullstack/src/components/ui/alert-dialog.tsx +157 -0
  34. package/template-nextjs-fullstack/src/components/ui/alert.tsx +71 -0
  35. package/template-nextjs-fullstack/src/components/ui/aspect-ratio.tsx +11 -0
  36. package/template-nextjs-fullstack/src/components/ui/avatar.tsx +53 -0
  37. package/template-nextjs-fullstack/src/components/ui/badge.tsx +42 -0
  38. package/template-nextjs-fullstack/src/components/ui/breadcrumb.tsx +109 -0
  39. package/template-nextjs-fullstack/src/components/ui/button-group.tsx +83 -0
  40. package/template-nextjs-fullstack/src/components/ui/button.tsx +69 -0
  41. package/template-nextjs-fullstack/src/components/ui/calendar.tsx +213 -0
  42. package/template-nextjs-fullstack/src/components/ui/card.tsx +82 -0
  43. package/template-nextjs-fullstack/src/components/ui/carousel.tsx +241 -0
  44. package/template-nextjs-fullstack/src/components/ui/chart.tsx +357 -0
  45. package/template-nextjs-fullstack/src/components/ui/checkbox.tsx +32 -0
  46. package/template-nextjs-fullstack/src/components/ui/collapsible.tsx +33 -0
  47. package/template-nextjs-fullstack/src/components/ui/command.tsx +208 -0
  48. package/template-nextjs-fullstack/src/components/ui/context-menu.tsx +324 -0
  49. package/template-nextjs-fullstack/src/components/ui/dialog.tsx +143 -0
  50. package/template-nextjs-fullstack/src/components/ui/drawer.tsx +135 -0
  51. package/template-nextjs-fullstack/src/components/ui/dropdown-menu.tsx +329 -0
  52. package/template-nextjs-fullstack/src/components/ui/empty.tsx +104 -0
  53. package/template-nextjs-fullstack/src/components/ui/field.tsx +248 -0
  54. package/template-nextjs-fullstack/src/components/ui/form.tsx +167 -0
  55. package/template-nextjs-fullstack/src/components/ui/hover-card.tsx +44 -0
  56. package/template-nextjs-fullstack/src/components/ui/icons/file-ae-colorful-icon.tsx +21 -0
  57. package/template-nextjs-fullstack/src/components/ui/icons/file-ai-colorful-icon.tsx +36 -0
  58. package/template-nextjs-fullstack/src/components/ui/icons/file-android-colorful-icon.tsx +33 -0
  59. package/template-nextjs-fullstack/src/components/ui/icons/file-audio-colorful-icon.tsx +21 -0
  60. package/template-nextjs-fullstack/src/components/ui/icons/file-code-colorful-icon.tsx +28 -0
  61. package/template-nextjs-fullstack/src/components/ui/icons/file-csv-colorful-icon.tsx +21 -0
  62. package/template-nextjs-fullstack/src/components/ui/icons/file-eml-colorful-icon.tsx +29 -0
  63. package/template-nextjs-fullstack/src/components/ui/icons/file-ios-colorful-icon.tsx +25 -0
  64. package/template-nextjs-fullstack/src/components/ui/icons/file-keynote-colorful-icon.tsx +29 -0
  65. package/template-nextjs-fullstack/src/components/ui/icons/file-pages-colorful-icon.tsx +29 -0
  66. package/template-nextjs-fullstack/src/components/ui/icons/file-ps-colorful-icon.tsx +21 -0
  67. package/template-nextjs-fullstack/src/components/ui/icons/file-sketch-colorful-icon.tsx +21 -0
  68. package/template-nextjs-fullstack/src/components/ui/icons/file-slide-colorful-icon.tsx +21 -0
  69. package/template-nextjs-fullstack/src/components/ui/icons/file-vcf-colorful-icon.tsx +29 -0
  70. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +23 -0
  71. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +27 -0
  72. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +20 -0
  73. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +21 -0
  74. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +12 -0
  75. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +14 -0
  76. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +23 -0
  77. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +38 -0
  78. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +21 -0
  79. package/template-nextjs-fullstack/src/components/ui/image.tsx +183 -0
  80. package/template-nextjs-fullstack/src/components/ui/input-group.tsx +166 -0
  81. package/template-nextjs-fullstack/src/components/ui/input-otp.tsx +77 -0
  82. package/template-nextjs-fullstack/src/components/ui/input.tsx +21 -0
  83. package/template-nextjs-fullstack/src/components/ui/item.tsx +193 -0
  84. package/template-nextjs-fullstack/src/components/ui/kbd.tsx +28 -0
  85. package/template-nextjs-fullstack/src/components/ui/label.tsx +24 -0
  86. package/template-nextjs-fullstack/src/components/ui/menubar.tsx +348 -0
  87. package/template-nextjs-fullstack/src/components/ui/native-select.tsx +48 -0
  88. package/template-nextjs-fullstack/src/components/ui/navigation-menu.tsx +168 -0
  89. package/template-nextjs-fullstack/src/components/ui/pagination.tsx +127 -0
  90. package/template-nextjs-fullstack/src/components/ui/popover.tsx +48 -0
  91. package/template-nextjs-fullstack/src/components/ui/progress.tsx +31 -0
  92. package/template-nextjs-fullstack/src/components/ui/radio-group.tsx +45 -0
  93. package/template-nextjs-fullstack/src/components/ui/resizable.tsx +56 -0
  94. package/template-nextjs-fullstack/src/components/ui/scroll-area.tsx +58 -0
  95. package/template-nextjs-fullstack/src/components/ui/select.tsx +243 -0
  96. package/template-nextjs-fullstack/src/components/ui/separator.tsx +28 -0
  97. package/template-nextjs-fullstack/src/components/ui/sheet.tsx +139 -0
  98. package/template-nextjs-fullstack/src/components/ui/sidebar.tsx +727 -0
  99. package/template-nextjs-fullstack/src/components/ui/skeleton.tsx +13 -0
  100. package/template-nextjs-fullstack/src/components/ui/slider.tsx +87 -0
  101. package/template-nextjs-fullstack/src/components/ui/sonner.tsx +67 -0
  102. package/template-nextjs-fullstack/src/components/ui/spinner.tsx +16 -0
  103. package/template-nextjs-fullstack/src/components/ui/streamdown.tsx +186 -0
  104. package/template-nextjs-fullstack/src/components/ui/switch.tsx +31 -0
  105. package/template-nextjs-fullstack/src/components/ui/table.tsx +116 -0
  106. package/template-nextjs-fullstack/src/components/ui/tabs.tsx +66 -0
  107. package/template-nextjs-fullstack/src/components/ui/textarea.tsx +18 -0
  108. package/template-nextjs-fullstack/src/components/ui/toggle-group.tsx +83 -0
  109. package/template-nextjs-fullstack/src/components/ui/toggle.tsx +47 -0
  110. package/template-nextjs-fullstack/src/components/ui/tooltip.tsx +61 -0
  111. package/template-nextjs-fullstack/src/db/index.ts +8 -0
  112. package/template-nextjs-fullstack/src/db/schema.ts +11 -0
  113. package/template-nextjs-fullstack/src/hooks/use-mobile.ts +19 -0
  114. package/template-nextjs-fullstack/src/lib/utils.ts +6 -0
  115. package/template-nextjs-fullstack/tailwind.config.ts +10 -0
  116. package/template-nextjs-fullstack/tsconfig.json +34 -0
  117. package/template-nextjs-static/README.md +80 -0
  118. package/template-nextjs-static/_gitignore +41 -0
  119. package/template-nextjs-static/components.json +25 -0
  120. package/template-nextjs-static/eslint.config.js +15 -0
  121. package/template-nextjs-static/next.config.ts +8 -0
  122. package/template-nextjs-static/package.json +77 -0
  123. package/template-nextjs-static/postcss.config.js +8 -0
  124. package/template-nextjs-static/public/favicon.ico +0 -0
  125. package/template-nextjs-static/scripts/build.sh +36 -0
  126. package/template-nextjs-static/src/components/header.tsx +30 -0
  127. package/template-nextjs-static/src/components/theme-provider.tsx +6 -0
  128. package/template-nextjs-static/src/components/ui/README.md +134 -0
  129. package/template-nextjs-static/src/components/ui/accordion.tsx +66 -0
  130. package/template-nextjs-static/src/components/ui/alert-dialog.tsx +157 -0
  131. package/template-nextjs-static/src/components/ui/alert.tsx +71 -0
  132. package/template-nextjs-static/src/components/ui/aspect-ratio.tsx +11 -0
  133. package/template-nextjs-static/src/components/ui/avatar.tsx +53 -0
  134. package/template-nextjs-static/src/components/ui/badge.tsx +42 -0
  135. package/template-nextjs-static/src/components/ui/breadcrumb.tsx +109 -0
  136. package/template-nextjs-static/src/components/ui/button-group.tsx +83 -0
  137. package/template-nextjs-static/src/components/ui/button.tsx +69 -0
  138. package/template-nextjs-static/src/components/ui/calendar.tsx +213 -0
  139. package/template-nextjs-static/src/components/ui/card.tsx +82 -0
  140. package/template-nextjs-static/src/components/ui/carousel.tsx +241 -0
  141. package/template-nextjs-static/src/components/ui/chart.tsx +357 -0
  142. package/template-nextjs-static/src/components/ui/checkbox.tsx +32 -0
  143. package/template-nextjs-static/src/components/ui/collapsible.tsx +33 -0
  144. package/template-nextjs-static/src/components/ui/command.tsx +208 -0
  145. package/template-nextjs-static/src/components/ui/context-menu.tsx +324 -0
  146. package/template-nextjs-static/src/components/ui/dialog.tsx +143 -0
  147. package/template-nextjs-static/src/components/ui/drawer.tsx +135 -0
  148. package/template-nextjs-static/src/components/ui/dropdown-menu.tsx +329 -0
  149. package/template-nextjs-static/src/components/ui/empty.tsx +104 -0
  150. package/template-nextjs-static/src/components/ui/field.tsx +248 -0
  151. package/template-nextjs-static/src/components/ui/form.tsx +167 -0
  152. package/template-nextjs-static/src/components/ui/hover-card.tsx +44 -0
  153. package/template-nextjs-static/src/components/ui/icons/file-ae-colorful-icon.tsx +21 -0
  154. package/template-nextjs-static/src/components/ui/icons/file-ai-colorful-icon.tsx +36 -0
  155. package/template-nextjs-static/src/components/ui/icons/file-android-colorful-icon.tsx +33 -0
  156. package/template-nextjs-static/src/components/ui/icons/file-audio-colorful-icon.tsx +21 -0
  157. package/template-nextjs-static/src/components/ui/icons/file-code-colorful-icon.tsx +28 -0
  158. package/template-nextjs-static/src/components/ui/icons/file-csv-colorful-icon.tsx +21 -0
  159. package/template-nextjs-static/src/components/ui/icons/file-eml-colorful-icon.tsx +29 -0
  160. package/template-nextjs-static/src/components/ui/icons/file-ios-colorful-icon.tsx +25 -0
  161. package/template-nextjs-static/src/components/ui/icons/file-keynote-colorful-icon.tsx +29 -0
  162. package/template-nextjs-static/src/components/ui/icons/file-pages-colorful-icon.tsx +29 -0
  163. package/template-nextjs-static/src/components/ui/icons/file-ps-colorful-icon.tsx +21 -0
  164. package/template-nextjs-static/src/components/ui/icons/file-sketch-colorful-icon.tsx +21 -0
  165. package/template-nextjs-static/src/components/ui/icons/file-slide-colorful-icon.tsx +21 -0
  166. package/template-nextjs-static/src/components/ui/icons/file-vcf-colorful-icon.tsx +29 -0
  167. package/template-nextjs-static/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +23 -0
  168. package/template-nextjs-static/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +27 -0
  169. package/template-nextjs-static/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +20 -0
  170. package/template-nextjs-static/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +21 -0
  171. package/template-nextjs-static/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +12 -0
  172. package/template-nextjs-static/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +14 -0
  173. package/template-nextjs-static/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +23 -0
  174. package/template-nextjs-static/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +38 -0
  175. package/template-nextjs-static/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +21 -0
  176. package/template-nextjs-static/src/components/ui/image.tsx +183 -0
  177. package/template-nextjs-static/src/components/ui/input-group.tsx +166 -0
  178. package/template-nextjs-static/src/components/ui/input-otp.tsx +77 -0
  179. package/template-nextjs-static/src/components/ui/input.tsx +21 -0
  180. package/template-nextjs-static/src/components/ui/item.tsx +193 -0
  181. package/template-nextjs-static/src/components/ui/kbd.tsx +28 -0
  182. package/template-nextjs-static/src/components/ui/label.tsx +24 -0
  183. package/template-nextjs-static/src/components/ui/menubar.tsx +348 -0
  184. package/template-nextjs-static/src/components/ui/native-select.tsx +48 -0
  185. package/template-nextjs-static/src/components/ui/navigation-menu.tsx +168 -0
  186. package/template-nextjs-static/src/components/ui/pagination.tsx +127 -0
  187. package/template-nextjs-static/src/components/ui/popover.tsx +48 -0
  188. package/template-nextjs-static/src/components/ui/progress.tsx +31 -0
  189. package/template-nextjs-static/src/components/ui/radio-group.tsx +45 -0
  190. package/template-nextjs-static/src/components/ui/resizable.tsx +56 -0
  191. package/template-nextjs-static/src/components/ui/scroll-area.tsx +58 -0
  192. package/template-nextjs-static/src/components/ui/select.tsx +243 -0
  193. package/template-nextjs-static/src/components/ui/separator.tsx +28 -0
  194. package/template-nextjs-static/src/components/ui/sheet.tsx +139 -0
  195. package/template-nextjs-static/src/components/ui/sidebar.tsx +727 -0
  196. package/template-nextjs-static/src/components/ui/skeleton.tsx +13 -0
  197. package/template-nextjs-static/src/components/ui/slider.tsx +87 -0
  198. package/template-nextjs-static/src/components/ui/sonner.tsx +67 -0
  199. package/template-nextjs-static/src/components/ui/spinner.tsx +16 -0
  200. package/template-nextjs-static/src/components/ui/streamdown.tsx +186 -0
  201. package/template-nextjs-static/src/components/ui/switch.tsx +31 -0
  202. package/template-nextjs-static/src/components/ui/table.tsx +116 -0
  203. package/template-nextjs-static/src/components/ui/tabs.tsx +66 -0
  204. package/template-nextjs-static/src/components/ui/textarea.tsx +18 -0
  205. package/template-nextjs-static/src/components/ui/toggle-group.tsx +83 -0
  206. package/template-nextjs-static/src/components/ui/toggle.tsx +47 -0
  207. package/template-nextjs-static/src/components/ui/tooltip.tsx +61 -0
  208. package/template-nextjs-static/src/hooks/use-mobile.ts +19 -0
  209. package/template-nextjs-static/src/lib/utils.ts +6 -0
  210. package/template-nextjs-static/src/pages/_app.tsx +11 -0
  211. package/template-nextjs-static/src/pages/_document.tsx +13 -0
  212. package/template-nextjs-static/src/pages/hello.tsx +32 -0
  213. package/template-nextjs-static/src/pages/index.tsx +76 -0
  214. package/template-nextjs-static/src/styles/globals.css +143 -0
  215. package/template-nextjs-static/tailwind.config.ts +10 -0
  216. package/template-nextjs-static/tsconfig.json +34 -0
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Lark Technologies Pte. Ltd. and/or its affiliates
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,provided that the above copyright notice and this permission notice appear in all copies.
6
+
7
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
8
+ IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
9
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
10
+ EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
11
+ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
12
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
13
+ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # @lark-apaas/coding-templates
2
+
3
+ OpenClaw 项目模板包,供 mclaw CLI 使用。
4
+
5
+ ## 模板列表
6
+
7
+ | 模板 | 目录 | 说明 |
8
+ |---|---|---|
9
+ | html | `template-html/` | 纯 HTML,零依赖,原型验证 |
10
+ | nextjs-static | `template-nextjs-static/` | Next.js Pages Router,静态导出,纯前端 |
11
+ | nextjs-fullstack | `template-nextjs-fullstack/` | Next.js App Router + Drizzle + PostgreSQL,全栈 |
12
+
13
+ ## 包结构
14
+
15
+ ```
16
+ template/
17
+ ├── package.json # npm 包定义(@lark-apaas/coding-templates)
18
+ ├── meta.json # 模板元数据(业务侧生成,名称/描述/特性标签)
19
+ ├── template-html/
20
+ │ ├── _gitignore
21
+ │ ├── package.json # mclaw.type: "html"
22
+ │ └── index.html
23
+ ├── template-nextjs-static/
24
+ │ ├── _gitignore # CLI 复制时重命名为 .gitignore
25
+ │ ├── package.json # mclaw.type: "nextjs-static",name 为 {{projectName}}
26
+ │ ├── tailwind.config.ts
27
+ │ ├── eslint.config.js
28
+ │ ├── postcss.config.js
29
+ │ ├── components.json
30
+ │ └── src/
31
+ │ ├── pages/ # Pages Router 路由
32
+ │ ├── components/ui/ # shadcn/ui 58 个组件
33
+ │ ├── hooks/
34
+ │ ├── lib/
35
+ │ └── styles/globals.css
36
+ └── template-nextjs-fullstack/
37
+ ├── _gitignore
38
+ ├── _env.local.example # CLI 复制时重命名为 .env.local.example
39
+ ├── package.json # mclaw.type: "nextjs-fullstack",name 为 {{projectName}}
40
+ ├── drizzle.config.ts
41
+ ├── tailwind.config.ts
42
+ ├── eslint.config.js
43
+ ├── postcss.config.js
44
+ ├── components.json
45
+ └── src/
46
+ ├── app/ # App Router 路由 + Server Actions
47
+ ├── components/ui/ # shadcn/ui 58 个组件
48
+ ├── db/ # Drizzle ORM schema + 连接
49
+ ├── hooks/
50
+ └── lib/
51
+ ```
52
+
53
+ ## 特殊文件命名
54
+
55
+ npm publish 会忽略 `.gitignore` 和 `.env*`,因此模板中使用 `_` 前缀:
56
+
57
+ | 模板中的文件名 | CLI 复制后的文件名 |
58
+ |---|---|
59
+ | `_gitignore` | `.gitignore` |
60
+ | `_env.local.example` | `.env.local.example` |
61
+
62
+ ## 模板类型标识
63
+
64
+ 每个模板的 `package.json` 包含 `mclaw.type` 字段,标识模板类型:
65
+
66
+ ```json
67
+ {
68
+ "mclaw": {
69
+ "type": "nextjs-static"
70
+ }
71
+ }
72
+ ```
73
+
74
+ `meta.json` 由业务侧生成和维护。若 `meta.json` 丢失,CLI 可扫描各模板目录的 `package.json` 中的 `mclaw.type` 恢复。
75
+
76
+ ## mclaw CLI 集成方式
77
+
78
+ ```javascript
79
+ const path = require('path');
80
+ const fs = require('fs-extra');
81
+
82
+ // 1. 读取模板元数据
83
+ const meta = require('@lark-apaas/coding-templates/meta.json');
84
+
85
+ // 2. 定位模板目录
86
+ const templateDir = path.dirname(require.resolve('@lark-apaas/coding-templates/meta.json'));
87
+ const srcDir = path.join(templateDir, selectedTemplate.dir);
88
+
89
+ // 3. 复制到目标目录
90
+ await fs.copy(srcDir, targetDir);
91
+
92
+ // 4. 重命名特殊文件
93
+ const renames = { '_gitignore': '.gitignore', '_env.local.example': '.env.local.example' };
94
+ for (const [from, to] of Object.entries(renames)) {
95
+ const filePath = path.join(targetDir, from);
96
+ if (fs.existsSync(filePath)) {
97
+ await fs.rename(filePath, path.join(targetDir, to));
98
+ }
99
+ }
100
+
101
+ // 5. 替换 package.json 中的占位符
102
+ const pkgPath = path.join(targetDir, 'package.json');
103
+ if (fs.existsSync(pkgPath)) {
104
+ let content = await fs.readFile(pkgPath, 'utf-8');
105
+ content = content.replace('{{projectName}}', projectName);
106
+ await fs.writeFile(pkgPath, content);
107
+ }
108
+ ```
109
+
110
+ ## 技术栈
111
+
112
+ 两个 Next.js 模板共享相同的技术选型:
113
+
114
+ - **Next.js 16** + React 19 + TypeScript 5
115
+ - **Tailwind CSS 4**(`@tailwindcss/postcss`,CSS-first 配置)
116
+ - **shadcn/ui**(base-nova 风格,lucide 图标,58 个组件预装)
117
+ - **ESLint 9** flat config(`@eslint/js` + `typescript-eslint`,无 `eslint-config-next`)
118
+ - **next-themes**(暗色模式)
119
+
120
+ fullstack 模板额外包含:Drizzle ORM + PostgreSQL + Zod
121
+
122
+ ## 发版
123
+
124
+ ```bash
125
+ cd template
126
+ npm version patch
127
+ npm publish
128
+ ```
package/meta.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "templates": [
3
+ {
4
+ "name": "html",
5
+ "dir": "template-html",
6
+ "description": "纯 HTML — 零依赖,原型验证",
7
+ "features": ["tailwind-cdn", "dark-mode"]
8
+ },
9
+ {
10
+ "name": "nextjs-static",
11
+ "dir": "template-nextjs-static",
12
+ "description": "Next.js Pages Router — 静态导出,纯前端应用",
13
+ "features": ["typescript", "tailwind", "shadcn-ui", "dark-mode", "static-export", "ssg"]
14
+ },
15
+ {
16
+ "name": "nextjs-fullstack",
17
+ "dir": "template-nextjs-fullstack",
18
+ "description": "Next.js App Router + Drizzle + PostgreSQL — 全栈应用",
19
+ "features": ["typescript", "tailwind", "shadcn-ui", "dark-mode", "ssr", "server-actions", "drizzle", "postgresql"]
20
+ }
21
+ ]
22
+ }
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@lark-apaas/coding-templates",
3
+ "version": "0.1.0",
4
+ "description": "OpenClaw project templates for mclaw CLI",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "files": [
9
+ "template-html",
10
+ "template-nextjs-static",
11
+ "template-nextjs-fullstack",
12
+ "meta.json"
13
+ ],
14
+ "keywords": [
15
+ "openclaw",
16
+ "template",
17
+ "nextjs",
18
+ "react",
19
+ "vibe-coding"
20
+ ],
21
+ "license": "MIT"
22
+ }
@@ -0,0 +1,148 @@
1
+ # HTML 模板
2
+
3
+ 基础 HTML 单文件模板。
4
+
5
+ ## 技术栈规范
6
+
7
+ ### 文件结构
8
+
9
+ - 单个 `.html` 文件,所有样式和脚本内嵌
10
+ - `<style>` 块仅用于 Tailwind 无法覆盖的自定义样式(如 ECharts 容器尺寸、动画关键帧等)
11
+ - `<script>` 块定义交互逻辑和数据
12
+ - 外部资源通过 `static/` 目录引用
13
+
14
+ ```
15
+ project/
16
+ ├── <name>.html # 主页面
17
+ ├── README.md # 技术栈规范(本文件)
18
+ └── static/
19
+ ├── images/ # 图片资源
20
+ └── data/ # 数据文件(.js / .json)
21
+ ```
22
+
23
+ ### 样式方案
24
+
25
+ **Tailwind CSS**(CDN,已在模板中引入)为主要样式方案:
26
+
27
+ | 规则 | 说明 |
28
+ |------|------|
29
+ | 布局 | 使用 Tailwind 的 Flexbox / Grid 工具类(`flex`、`grid`、`gap-*`) |
30
+ | 响应式 | 使用 Tailwind 响应式前缀(`sm:`、`md:`、`lg:`、`xl:`) |
31
+ | 间距/字号 | 使用 Tailwind 内置的间距和字号类(`p-4`、`text-lg`) |
32
+ | 最大宽度 | 内容区域使用 `max-w-*` + `mx-auto` 居中 |
33
+ | 自定义样式 | 仅在 Tailwind 无法覆盖时使用 `<style>` 块 |
34
+
35
+ ### 颜色系统
36
+
37
+ 通过 `tailwind.config` 定义主题色,使用 HSL 格式:
38
+
39
+ ```javascript
40
+ tailwind.config = {
41
+ theme: {
42
+ extend: {
43
+ colors: {
44
+ bg: 'hsl(220 14% 96%)',
45
+ surface: 'hsl(0 0% 100%)',
46
+ header: 'hsl(0 0% 0%)',
47
+ text: 'hsl(220 13% 13%)',
48
+ 'text-muted': 'hsl(220 9% 46%)',
49
+ primary: 'hsl(0 72% 51%)',
50
+ accent: 'hsl(0 69% 97%)',
51
+ border: 'hsl(220 13% 91%)',
52
+ }
53
+ }
54
+ }
55
+ };
56
+ ```
57
+
58
+ 使用时通过 Tailwind 类引用:`bg-bg`、`text-text`、`border-border`、`bg-primary` 等。
59
+
60
+ ### 外部库
61
+
62
+ | 库 | 用途 | 引入方式 |
63
+ |----|------|---------|
64
+ | Tailwind CSS | 样式方案 | CDN(模板已引入) |
65
+ | ECharts | 图表(需要时) | CDN `<script>` 引入 |
66
+
67
+ ### 资源引用
68
+
69
+ **所有静态资源路径必须使用 `$STATIC$` 前缀模板语法**:
70
+
71
+ | 资源类型 | 正确写法 | 禁止写法 |
72
+ |---------|---------|---------|
73
+ | 图片 | `<img src="$STATIC$/images/xxx.png">` | `<img src="static/images/xxx.png">` |
74
+ | 数据文件 | `<script src="$STATIC$/data/xxx.js">` | `<script src="static/data/xxx.js">` |
75
+ | CSS 背景图 | `background-image: url('$STATIC$/images/xxx.png')` | `url('static/images/xxx.png')` |
76
+
77
+ - `$STATIC$` 是平台注入的模板变量,运行时会被替换为实际静态资源根路径
78
+ - 数据内嵌于 `<script>` 块时无需前缀(纯 JS 变量,不是资源路径)
79
+ - 禁止使用外部 URL 引用本地资源
80
+
81
+ ### 编码规范
82
+
83
+ - 文件编码:UTF-8
84
+ - 缩进:2 空格
85
+ - HTML 语义化标签(`<main>`、`<section>`、`<nav>`、`<header>`、`<footer>`)
86
+
87
+ ---
88
+
89
+ ## HTML 编码规范
90
+
91
+ ### 布局响应式
92
+
93
+ 强制要求:所有页面必须对不同视口宽度做出适配。
94
+
95
+ - 容器使用 `max-width` + 水平 `auto` margin 居中,内容不允许在大屏幕上贴边延伸
96
+ - 多列布局使用 CSS Grid 或 Flexbox,通过媒体查询或 `auto-fill/auto-fit` 自动调整列数
97
+ - 宽屏(≥1024px):多列布局
98
+ - 窄屏(<768px):退化为单列
99
+ - Flexbox 子元素必须设置 `min-width: 0`,防止内容撑破父容器
100
+ - Flexbox 多元素横排时使用 `flex-wrap: wrap`,确保窄屏自动换行
101
+ - 禁止:写死 `width: 720px` 等固定像素宽度作为主容器
102
+
103
+ ### 内容响应式
104
+
105
+ 强制要求:区块高度由内容撑开,不允许固定内容区高度。
106
+
107
+ - 内容区域使用自然高度(`height: auto`),不允许对内容块设置固定 `height` 值
108
+ - 图片/媒体元素使用 `max-width: 100%` + `height: auto` 保持比例自适应
109
+ - 允许对图表等可视化组件设置固定高度(如 ECharts 容器需要明确高度)
110
+ - 文本容器使用 `overflow-wrap: break-word`,防止长单词/URL 溢出
111
+ - 单行截断:同时设置 `white-space: nowrap; overflow: hidden; text-overflow: ellipsis`
112
+ - 表格和代码块添加 `overflow-x: auto`,支持横向滚动,避免内容被截断
113
+
114
+ ### 交互元素规范
115
+
116
+ **交互元素必须有对应功能内容**
117
+
118
+ - 页面中每个按钮、链接、表单输入、标签页、手风琴等交互元素,必须有对应的实际交互内容
119
+ - 禁止:点击后无任何响应的按钮(包括 `href="#"` 的占位链接)
120
+ - 禁止:标签页切换后无内容变化
121
+ - 禁止:下拉菜单展开后列表为空
122
+
123
+ 如需展示一个功能"入口"但暂无内容,**删除该入口,不实现假按钮**。
124
+
125
+ **交互元素必须绑定可执行的事件处理器**
126
+
127
+ 每个交互元素必须绑定**可执行**的事件处理器,产生可见 DOM 变化或明确的用户反馈:
128
+
129
+ - 禁止:空函数(`onclick=""`、`() => {}`)
130
+ - 禁止:仅有 `console.log` 的响应,无 DOM 变化
131
+ - 要求:按钮点击后至少有以下一种反馈:状态切换、内容显示/隐藏、数值更新、页面跳转/滚动
132
+
133
+ **减少功能按钮**
134
+
135
+ - 优先通过内容展示传递信息,而非按钮操作
136
+ - 功能按钮数量控制:整页主操作按钮不超过 3 个
137
+ - 不添加"导出"、"分享"、"下载"等静态页面无法真正执行的操作按钮
138
+
139
+ ### HTML 生成自检清单
140
+
141
+ 生成 HTML 前逐项确认:
142
+
143
+ | 检查项 | 验收标准 |
144
+ |--------|---------|
145
+ | 布局响应式 | `max-width` + `auto` margin 居中;多列 ≤768px 退化单列;flex 子元素有 `min-width: 0` |
146
+ | 内容响应式 | 文本有 `overflow-wrap: break-word`;表格/代码块有 `overflow-x: auto`;无固定 `height`(图表除外) |
147
+ | 交互元素 | 所有交互元素有可执行处理器;无空响应按钮;无 `href="#"` 占位链接 |
148
+ | 静态资源路径 | 所有 `<img src>`、`<script src>`、`url()` 均使用 `$STATIC$/` 前缀;无裸 `static/` 相对路径 |
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ node_modules
@@ -0,0 +1,22 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>应用标题</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script>
9
+ // 可选:Tailwind 运行时配置
10
+ tailwind.config = {};
11
+ </script>
12
+ <style>
13
+ /* 必要的自定义样式(如画布容器尺寸、预览区边框等) */
14
+ </style>
15
+ </head>
16
+ <body class="bg-gray-50">
17
+ <!-- 画布布局容器 -->
18
+ <main id="canvas" class="mx-auto max-w-7xl p-6">
19
+ <!-- 页面内容(由 generate_design 生成的 HTML 片段插入此处) -->
20
+ </main>
21
+ </body>
22
+ </html>
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "mclaw": {
6
+ "stack": "html",
7
+ "stackVersion": "0.1.0"
8
+ },
9
+ "scripts": {
10
+ "build": "bash scripts/build.sh"
11
+ }
12
+ }
@@ -0,0 +1 @@
1
+ { "version": 1, "type": "html", "fallback": "index.html" }
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
5
+ OUTPUT="$ROOT/dist/output"
6
+ OUTPUT_STATIC="$ROOT/dist/output_static"
7
+ STATIC_PREFIX="${MCLAW_STATIC_PREFIX:-}"
8
+
9
+ # 清理
10
+ rm -rf "$ROOT/dist"
11
+ mkdir -p "$OUTPUT"
12
+
13
+ # 1. 所有 .html 文件按目录结构复制到 dist/output/,并替换 __STATIC_PREFIX__
14
+ cd "$ROOT"
15
+ find . -name '*.html' -not -path './dist/*' -not -path './node_modules/*' | while read -r file; do
16
+ dir=$(dirname "$file")
17
+ mkdir -p "$OUTPUT/$dir"
18
+ sed "s|__STATIC_PREFIX__|${STATIC_PREFIX}|g" "$file" > "$OUTPUT/$file"
19
+ done
20
+
21
+ # 2. routes.json → dist/output/
22
+ cp "$ROOT/routes.json" "$OUTPUT/routes.json"
23
+
24
+ # 3. static/ → dist/output_static/(如果存在)
25
+ if [ -d "$ROOT/static" ]; then
26
+ cp -r "$ROOT/static" "$OUTPUT_STATIC"
27
+ fi
28
+
29
+ echo "Build complete"
30
+ echo " HTML → dist/output/"
31
+ [ -d "$OUTPUT_STATIC" ] && echo " Static → dist/output_static/" || true
@@ -0,0 +1,169 @@
1
+ # Next.js 全栈模板
2
+
3
+ Next.js App Router + Drizzle ORM + PostgreSQL 全栈模板,支持 Server Actions、SSR、API Routes。
4
+
5
+ ## 快速开始
6
+
7
+ ```bash
8
+ # 1. 安装依赖
9
+ npm install
10
+
11
+ # 2. 配置数据库(修改 .env.local 中的 DATABASE_URL)
12
+ cp .env.local.example .env.local
13
+
14
+ # 3. 初始化数据库表
15
+ npm run db:push
16
+
17
+ # 4. 启动开发服务器
18
+ npm run dev
19
+ ```
20
+
21
+ 打开 http://localhost:3000 查看效果。
22
+
23
+ ## 命令
24
+
25
+ | 命令 | 说明 |
26
+ |---|---|
27
+ | `npm run dev` | 启动开发服务器 |
28
+ | `npm run build` | 生产构建 |
29
+ | `npm run start` | 启动生产服务 |
30
+ | `npm run lint` | 运行 ESLint |
31
+ | `npm run db:generate` | 生成 Drizzle 迁移文件 |
32
+ | `npm run db:migrate` | 执行数据库迁移 |
33
+ | `npm run db:push` | 推送 schema 到数据库(开发用) |
34
+ | `npm run db:studio` | 打开 Drizzle Studio |
35
+
36
+ ## 独立部署(Docker / FaaS 容器模式)
37
+
38
+ ### 1. 开启 standalone 模式
39
+
40
+ ```ts
41
+ // next.config.ts
42
+ import type { NextConfig } from "next";
43
+
44
+ const nextConfig: NextConfig = {
45
+ output: "standalone",
46
+ assetPrefix: "https://cdn.example.com", // 静态资源 CDN 地址
47
+ };
48
+
49
+ export default nextConfig;
50
+ ```
51
+
52
+ ### 2. 构建
53
+
54
+ ```bash
55
+ npm run build
56
+ ```
57
+
58
+ 产出 `.next/standalone/` 目录,包含:
59
+ - `server.js` — 服务入口,`node server.js` 直接启动
60
+ - `node_modules/` — 仅运行时依赖(tree-shaking 后,远小于完整 node_modules)
61
+ - `.next/server/` — SSR 产物
62
+
63
+ ### 3. Dockerfile
64
+
65
+ ```dockerfile
66
+ FROM node:20-alpine
67
+ WORKDIR /app
68
+
69
+ # 复制 standalone 产出
70
+ COPY .next/standalone ./
71
+ # 静态资源(如果不走 CDN 则需要复制)
72
+ COPY .next/static ./.next/static
73
+ COPY public ./public
74
+
75
+ ENV NODE_ENV=production
76
+ ENV PORT=3000
77
+ EXPOSE 3000
78
+
79
+ CMD ["node", "server.js"]
80
+ ```
81
+
82
+ ```bash
83
+ docker build -t my-app .
84
+ docker run -p 3000:3000 \
85
+ -e DATABASE_URL="postgresql://user:pass@host:5432/db" \
86
+ my-app
87
+ ```
88
+
89
+ 镜像体积约 100-150MB,启动时间 1-2 秒。
90
+
91
+ ### 4. 部署架构
92
+
93
+ ```
94
+ ┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
95
+ │ 浏览器 │────→│ Nginx / 网关 │────→│ FaaS 容器 │
96
+ │ │ │ │ │ server.js │
97
+ │ │ │ 路由分发: │ │ (standalone)│
98
+ │ │ │ /*.html → 容器 │ │ │
99
+ │ │ │ │ │ ↓ │
100
+ │ │ └──────────────────┘ │ PostgreSQL │
101
+ │ │ │ └─────────────┘
102
+ │ │ │
103
+ │ │ ┌────────↓─────────┐
104
+ │ │←────│ CDN │
105
+ │ │ │ _next/static/* │
106
+ │ │ │ (JS/CSS/字体) │
107
+ │ │ └──────────────────┘
108
+ │ │
109
+ │ │ ┌──────────────────┐
110
+ │ │←────│ TOS │
111
+ │ │ │ 图片资源 │
112
+ │ │ │ (独立权限控制) │
113
+ │ │ └──────────────────┘
114
+ ```
115
+
116
+ | 资源类型 | 部署位置 | 说明 |
117
+ |---|---|---|
118
+ | HTML / SSR / API | FaaS 容器 | standalone server.js 处理 |
119
+ | JS / CSS / 字体 | CDN | 通过 `assetPrefix` 配置 |
120
+ | 图片 | TOS | 通过自定义 Image Loader |
121
+ | 数据库 | PostgreSQL | 通过 `DATABASE_URL` 环境变量 |
122
+
123
+ ### 5. 图片走 TOS(可选)
124
+
125
+ 如果图片需要部署到独立的 TOS(对象存储),配置自定义 Image Loader:
126
+
127
+ ```ts
128
+ // next.config.ts
129
+ const nextConfig: NextConfig = {
130
+ output: "standalone",
131
+ assetPrefix: "https://cdn.example.com",
132
+ images: {
133
+ loader: "custom",
134
+ loaderFile: "./src/lib/image-loader.ts",
135
+ },
136
+ };
137
+ ```
138
+
139
+ ```ts
140
+ // src/lib/image-loader.ts
141
+ export default function tosLoader({
142
+ src,
143
+ width,
144
+ quality,
145
+ }: {
146
+ src: string;
147
+ width: number;
148
+ quality?: number;
149
+ }) {
150
+ return `https://tos.example.com${src}?w=${width}&q=${quality || 75}`;
151
+ }
152
+ ```
153
+
154
+ ### 6. 环境变量
155
+
156
+ | 变量 | 说明 | 示例 |
157
+ |---|---|---|
158
+ | `DATABASE_URL` | PostgreSQL 连接地址 | `postgresql://user:pass@host:5432/db` |
159
+ | `PORT` | 服务端口(默认 3000) | `3000` |
160
+ | `HOSTNAME` | 监听地址(容器中建议 0.0.0.0) | `0.0.0.0` |
161
+
162
+ ## 技术栈
163
+
164
+ - Next.js 16(App Router、SSR、Server Actions)
165
+ - React 19、TypeScript 5
166
+ - Tailwind CSS 4 + shadcn/ui(base-nova 风格、lucide 图标)
167
+ - Drizzle ORM + PostgreSQL
168
+ - Zod(数据校验)
169
+ - next-themes(暗色模式)
@@ -0,0 +1 @@
1
+ DATABASE_URL=postgresql://postgres:postgres@localhost:5432/openclaw
@@ -0,0 +1,41 @@
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.*
7
+ .yarn/*
8
+ !.yarn/patches
9
+ !.yarn/plugins
10
+ !.yarn/releases
11
+ !.yarn/versions
12
+
13
+ # testing
14
+ /coverage
15
+
16
+ # next.js
17
+ /.next/
18
+ /out/
19
+
20
+ # production
21
+ /build
22
+
23
+ # misc
24
+ .DS_Store
25
+ *.pem
26
+
27
+ # debug
28
+ npm-debug.log*
29
+ yarn-debug.log*
30
+ yarn-error.log*
31
+ .pnpm-debug.log*
32
+
33
+ # env files (can opt-in for committing if needed)
34
+ .env*
35
+
36
+ # vercel
37
+ .vercel
38
+
39
+ # typescript
40
+ *.tsbuildinfo
41
+ next-env.d.ts
@@ -0,0 +1,25 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "base-nova",
4
+ "rsc": true,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "tailwind.config.ts",
8
+ "css": "src/app/globals.css",
9
+ "baseColor": "neutral",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "iconLibrary": "lucide",
14
+ "rtl": false,
15
+ "aliases": {
16
+ "components": "@/components",
17
+ "utils": "@/lib/utils",
18
+ "ui": "@/components/ui",
19
+ "lib": "@/lib",
20
+ "hooks": "@/hooks"
21
+ },
22
+ "menuColor": "default",
23
+ "menuAccent": "subtle",
24
+ "registries": {}
25
+ }
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from "drizzle-kit";
2
+
3
+ export default defineConfig({
4
+ schema: "./src/db/schema.ts",
5
+ out: "./drizzle",
6
+ dialect: "postgresql",
7
+ dbCredentials: {
8
+ url: process.env.DATABASE_URL!,
9
+ },
10
+ });
@@ -0,0 +1,15 @@
1
+ const js = require('@eslint/js');
2
+ const tseslint = require('typescript-eslint');
3
+
4
+ module.exports = tseslint.config(
5
+ { ignores: ['.next', 'out', 'node_modules'] },
6
+ js.configs.recommended,
7
+ ...tseslint.configs.recommended,
8
+ {
9
+ files: ['src/**/*.{ts,tsx}'],
10
+ rules: {
11
+ '@typescript-eslint/no-unused-vars': 'warn',
12
+ '@typescript-eslint/no-unused-expressions': 'off',
13
+ },
14
+ },
15
+ );
@@ -0,0 +1,5 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {};
4
+
5
+ export default nextConfig;