@bytechain.cn/colamd-themes 0.5.1 → 0.5.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 (61) hide show
  1. package/README.md +25 -11
  2. package/cordis.patch.yml +9 -0
  3. package/dist/cli.js +3 -3
  4. package/dist/dsh-plugin.d.ts +44 -0
  5. package/dist/dsh-plugin.js +72 -0
  6. package/dist/dsh-plugin.js.map +1 -0
  7. package/dist/generator.d.ts +1 -1
  8. package/dist/generator.js +2 -2
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +2 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/models.d.ts +1 -1
  13. package/dist/models.js +1 -1
  14. package/dist/renderer.d.ts +2 -2
  15. package/dist/renderer.js +3 -3
  16. package/package.json +22 -2
  17. package/skills/build-skills.sh +5 -5
  18. package/skills/colamd-themes/SKILL.md +5 -5
  19. package/.claude/skills/colamd-themes-preview.skill.md +0 -333
  20. package/.claude/skills/colamd-themes.skill.md +0 -10
  21. package/.dsh/skills/colamd-themes/SKILL.md +0 -14
  22. package/.github/supported-topics.yml +0 -17
  23. package/.hermes/skills/tools/colamd-themes/SKILL.md +0 -14
  24. package/.openclaw/skills/colamd-themes/SKILL.md +0 -21
  25. package/.opencode/skills/colamd-themes/SKILL.md +0 -17
  26. package/.trae/rules/colamd-themes.md +0 -5
  27. package/CHANGELOG.md +0 -331
  28. package/DSH_SUPPORT_SUMMARY.md +0 -87
  29. package/README_CN.md +0 -412
  30. package/RELEASENOTE.md +0 -541
  31. package/mcp-server/dist/index.d.ts +0 -13
  32. package/mcp-server/dist/index.d.ts.map +0 -1
  33. package/mcp-server/dist/index.js.map +0 -1
  34. package/mcp-server/package-lock.json +0 -1759
  35. package/mcp-server/package.json +0 -24
  36. package/mcp-server/src/index.ts +0 -0
  37. package/mcp-server/tsconfig.json +0 -19
  38. package/src/cli.ts +0 -474
  39. package/src/color-systems.ts +0 -289
  40. package/src/color-utils.ts +0 -137
  41. package/src/contrast.ts +0 -66
  42. package/src/docx-style-paradigm.ts +0 -811
  43. package/src/export-cli.ts +0 -356
  44. package/src/extractors/base.ts +0 -8
  45. package/src/extractors/docx-extractor.ts +0 -417
  46. package/src/extractors/pdf-extractor.ts +0 -533
  47. package/src/extractors/url-extractor.ts +0 -846
  48. package/src/generator.ts +0 -197
  49. package/src/index.ts +0 -29
  50. package/src/models.ts +0 -212
  51. package/src/renderer.ts +0 -310
  52. package/src/templates/template.css +0 -220
  53. package/src/templates/theme-paradigm.md +0 -530
  54. package/src/templates/theme-template.hbs +0 -256
  55. package/src/theme-store.ts +0 -185
  56. package/src/types/pdf-parse.d.ts +0 -12
  57. package/src/utils/cli-utils.ts +0 -84
  58. package/src/utils/document-paradigm.ts +0 -118
  59. package/src/validators.ts +0 -298
  60. package/themes-preview/demo-content.md +0 -187
  61. package/tsconfig.json +0 -18
package/src/validators.ts DELETED
@@ -1,298 +0,0 @@
1
- /**
2
- * Paradigm validation engine — checks SeedPalette against v4.0 design constraints
3
- * and scans generated CSS for the ColaMD 2.7.8-rc.1 theme contract.
4
- * Based on theme-paradigm.md Section 2.
5
- */
6
-
7
- import { parse, walk, generate } from "css-tree";
8
- import { contrastRatio, hslSaturation, hslLightness, hslHue, sameHueAxis, isLightMode } from "./contrast.js";
9
-
10
- export interface ValidationIssue {
11
- ruleId: string;
12
- level: "MUST" | "MUST_NOT" | "SHOULD" | "SHOULD_NOT";
13
- message: string;
14
- fix?: string;
15
- }
16
-
17
- export interface SeedPalette {
18
- accent: string;
19
- accentLight: string;
20
- accentDark: string;
21
- surface: string;
22
- panel: string;
23
- panelAlt: string;
24
- ink: string;
25
- inkMuted: string;
26
- inkDim: string;
27
- border: string;
28
- borderStrong: string;
29
- }
30
-
31
- export function validateSeedPalette(palette: SeedPalette): ValidationIssue[] {
32
- const issues: ValidationIssue[] = [];
33
- const light = isLightMode(palette.surface);
34
-
35
- // CR-01: ink vs surface ≥ 7:1
36
- const crInk = contrastRatio(palette.ink, palette.surface);
37
- if (crInk < 7.0) {
38
- issues.push({
39
- ruleId: "CR-01",
40
- level: "MUST",
41
- message: `正文-底色对比度 ${crInk.toFixed(1)}:1 < 7:1 (WCAG AAA)`,
42
- fix: `建议加深 ink 或调浅 surface`,
43
- });
44
- }
45
-
46
- // CR-02: inkMuted vs surface ≥ 4.5:1
47
- const crMuted = contrastRatio(palette.inkMuted, palette.surface);
48
- if (crMuted < 4.5) {
49
- issues.push({
50
- ruleId: "CR-02",
51
- level: "MUST",
52
- message: `次要文字-底色对比度 ${crMuted.toFixed(1)}:1 < 4.5:1 (WCAG AA)`,
53
- });
54
- }
55
-
56
- // CR-04: accent vs surface ≥ 4.5:1
57
- const crAccent = contrastRatio(palette.accent, palette.surface);
58
- if (crAccent < 4.5) {
59
- issues.push({
60
- ruleId: "CR-04",
61
- level: "MUST",
62
- message: `点缀色-底色对比度 ${crAccent.toFixed(1)}:1 < 4.5:1`,
63
- });
64
- }
65
-
66
- // SL-01: surface saturation ≤ 0.05
67
- const sSurface = hslSaturation(palette.surface);
68
- if (sSurface > 0.05) {
69
- issues.push({
70
- ruleId: "SL-01",
71
- level: "MUST",
72
- message: `底色饱和度 ${(sSurface * 100).toFixed(1)}% > 5%,页面会偏色`,
73
- });
74
- }
75
-
76
- // SL-02: panel/panelAlt saturation ≤ 0.10
77
- for (const [name, hex] of [["panel", palette.panel], ["panelAlt", palette.panelAlt]] as const) {
78
- const s = hslSaturation(hex);
79
- if (s > 0.10) {
80
- issues.push({
81
- ruleId: "SL-02",
82
- level: "MUST_NOT",
83
- message: `表面色 ${name} 饱和度 ${(s * 100).toFixed(1)}% > 10%`,
84
- });
85
- }
86
- }
87
-
88
- // SL-03: surface/panel/panelAlt same hue axis
89
- if (!sameHueAxis(palette.surface, palette.panel, 5) || !sameHueAxis(palette.surface, palette.panelAlt, 5)) {
90
- issues.push({
91
- ruleId: "SL-03",
92
- level: "SHOULD",
93
- message: "三层表面色应保持相同色相轴(H 偏差 ≤ 5°)",
94
- });
95
- }
96
-
97
- // SL-04: L(surface) > L(panel) > L(panelAlt) for light
98
- const lSurface = hslLightness(palette.surface);
99
- const lPanel = hslLightness(palette.panel);
100
- const lPanelAlt = hslLightness(palette.panelAlt);
101
- if (light) {
102
- if (!(lSurface > lPanel && lPanel > lPanelAlt)) {
103
- issues.push({
104
- ruleId: "SL-04",
105
- level: "MUST",
106
- message: `浅色主题要求 L(surface) > L(panel) > L(panelAlt)`,
107
- });
108
- }
109
- } else {
110
- if (!(lSurface < lPanel && lPanel < lPanelAlt)) {
111
- issues.push({
112
- ruleId: "SL-04",
113
- level: "MUST",
114
- message: `深色主题要求 L(surface) < L(panel) < L(panelAlt)`,
115
- });
116
- }
117
- }
118
-
119
- // NT-01: ink/inkMuted/inkDim same hue axis
120
- if (!sameHueAxis(palette.ink, palette.inkMuted, 3) || !sameHueAxis(palette.ink, palette.inkDim, 3)) {
121
- issues.push({
122
- ruleId: "NT-01",
123
- level: "MUST",
124
- message: "文字色必须位于同一色相轴(H 偏差 ≤ 3°)",
125
- });
126
- }
127
-
128
- // NT-02: border vs panel lightness diff ≥ 0.08
129
- const lBorder = hslLightness(palette.border);
130
- if (Math.abs(lBorder - lPanel) < 0.08) {
131
- issues.push({
132
- ruleId: "NT-02",
133
- level: "MUST",
134
- message: `边框色与 panel 明度差 ${Math.abs(lBorder - lPanel).toFixed(3)} < 0.08,边框不可见`,
135
- });
136
- }
137
-
138
- // NT-03: border should be neutral gray
139
- const sBorder = hslSaturation(palette.border);
140
- if (sBorder > 0.05) {
141
- issues.push({
142
- ruleId: "NT-03",
143
- level: "SHOULD",
144
- message: `边框色饱和度 ${(sBorder * 100).toFixed(1)}% > 5%,应使用中性灰`,
145
- });
146
- }
147
-
148
- // HR-01: accent saturation ≥ 0.30 for light themes
149
- const sAccent = hslSaturation(palette.accent);
150
- if (light && sAccent < 0.30) {
151
- issues.push({
152
- ruleId: "HR-01",
153
- level: "SHOULD",
154
- message: `点缀色饱和度 ${(sAccent * 100).toFixed(1)}% < 30%,建议选暖色或冷色`,
155
- });
156
- }
157
-
158
- return issues;
159
- }
160
-
161
- // ═══════════════════════════════════════════════════════════
162
- // CSS contract validation (ColaMD 2.7.8-rc.1)
163
- // ═══════════════════════════════════════════════════════════
164
-
165
- /** 2.7 编辑器不再消费的变量:留着只会让人照抄。 */
166
- const DEAD_VARIABLES = new Set([
167
- "--surface-color", "--surface-alt", "--text-dim", "--heading-color",
168
- "--accent-color", "--accent-dark", "--accent-light", "--hr-color",
169
- "--code-color", "--code-block-color", "--table-border",
170
- "--content-width", "--font-size-root", "--font-heading", "--font-code",
171
- "--font-mermaid", "--font-size-mermaid",
172
- ]);
173
-
174
- /** 前缀匹配的死变量族(Mermaid 20 变量、圆角、字阶、行高、滚动条)。 */
175
- const DEAD_VARIABLE_PREFIXES = [
176
- "--mermaid-", "--radius-", "--font-scale-", "--line-height-", "--scrollbar-thumb",
177
- ];
178
-
179
- /** 旧编辑器 DOM 的选择器:在 CodeMirror 6 里命中不到任何元素。 */
180
- const DEAD_SELECTOR_PATTERNS: Array<{ re: RegExp; label: string; fix: string }> = [
181
- { re: /(^|[\s>+~,])#write(?![-\w])/, label: "#write", fix: "改用 #editor .cm-content" },
182
- { re: /\.ProseMirror\b/, label: ".ProseMirror", fix: "改用 #editor .cm-content .cm-md-*" },
183
- { re: /\.theme-custom\b/, label: "body.theme-custom", fix: "自定义主题变量写在 :root" },
184
- { re: /\.mermaid-(block|preview)\b/, label: ".mermaid-*", fix: "图表用 .cm-md-mermaid 与 --pele-*" },
185
- ];
186
-
187
- /** 引用块/代码块在 CM6 里一行一个 div,纵向 padding 会按行累加。 */
188
- function hasVerticalPadding(rule: { block: { children: { forEach: (cb: (node: any) => void) => void } } }): boolean {
189
- let found = false;
190
- rule.block.children.forEach((node: any) => {
191
- if (node.type !== "Declaration" || node.property.startsWith("--")) return;
192
- if (node.property === "padding") {
193
- const values = generate(node.value).trim().split(/\s+/);
194
- // 1~2 个值:第一个是纵向;3 个值:第二个;4 个值:第一个与第三个。
195
- const vertical = values.length === 1 ? values[0]
196
- : values.length === 2 ? values[0]
197
- : values.length === 3 ? values[1] : `${values[0]} ${values[2]}`;
198
- if (vertical.split(/\s+/).some((v) => !/^0(px|em|rem|%)?$/.test(v))) found = true;
199
- } else if (node.property === "padding-top" || node.property === "padding-bottom") {
200
- const value = generate(node.value).trim();
201
- if (!/^0(px|em|rem|%)?$/.test(value)) found = true;
202
- }
203
- });
204
- return found;
205
- }
206
-
207
- /** 校验生成的 CSS 是否符合 ColaMD 2.7.8-rc.1 契约。 */
208
- export function validateThemeCss(css: string): ValidationIssue[] {
209
- const issues: ValidationIssue[] = [];
210
- const ast = parse(css, { positions: false });
211
- let hasRootBlock = false;
212
-
213
- walk(ast, (node) => {
214
- if (node.type === "Declaration" && node.property.startsWith("--")) {
215
- const name = node.property;
216
- const dead = DEAD_VARIABLES.has(name)
217
- || DEAD_VARIABLE_PREFIXES.some((prefix) => name.startsWith(prefix));
218
- if (dead) {
219
- issues.push({
220
- ruleId: "CSS-01",
221
- level: "MUST_NOT",
222
- message: `变量 ${name} 在 ColaMD 2.7.8-rc.1 契约中已不再消费`,
223
- fix: "改用活变量清单(--bg-color / --text-secondary / --pele-* 等)",
224
- });
225
- }
226
- }
227
-
228
- if (node.type === "Rule" && node.prelude.type === "SelectorList") {
229
- const selector = generate(node.prelude);
230
- if (/(^|,)\s*:root\b/.test(selector)) hasRootBlock = true;
231
-
232
- for (const dead of DEAD_SELECTOR_PATTERNS) {
233
- if (dead.re.test(selector)) {
234
- issues.push({
235
- ruleId: "CSS-02",
236
- level: "MUST_NOT",
237
- message: `选择器 ${dead.label} 在 CodeMirror 6 中命中不到元素(${selector})`,
238
- fix: dead.fix,
239
- });
240
- }
241
- }
242
-
243
- if (/\.cm-md-(blockquote|codeblock)\b/.test(selector) && hasVerticalPadding(node)) {
244
- issues.push({
245
- ruleId: "CSS-03",
246
- level: "MUST_NOT",
247
- message: `引用/代码块不能设置纵向 padding(每行一个 div,会按行累加):${selector}`,
248
- fix: "只设 padding-left / padding-right",
249
- });
250
- }
251
-
252
- walk(node.block, (child) => {
253
- if (child.type === "Declaration" && child.value.type === "Value") {
254
- walk(child.value, (valueNode) => {
255
- if (valueNode.type === "Dimension" && valueNode.unit === "pt") {
256
- issues.push({
257
- ruleId: "CSS-04",
258
- level: "MUST_NOT",
259
- message: `使用了 pt 单位:${child.property}: ${generate(child.value)}`,
260
- fix: "统一换算为 px(1pt ≈ 1.333px)",
261
- });
262
- }
263
- });
264
- }
265
- });
266
- }
267
- });
268
-
269
- if (!hasRootBlock) {
270
- issues.push({
271
- ruleId: "CSS-05",
272
- level: "MUST",
273
- message: "缺少 :root 根块,主题变量无法被继承",
274
- fix: "把变量块写到 :root 上",
275
- });
276
- }
277
-
278
- return issues;
279
- }
280
-
281
- /** Summarize validation results. */
282
- export function summarizeIssues(issues: ValidationIssue[]): string {
283
- const errors = issues.filter((i) => i.level === "MUST" || i.level === "MUST_NOT");
284
- const warnings = issues.filter((i) => i.level === "SHOULD" || i.level === "SHOULD_NOT");
285
- const lines: string[] = [];
286
- if (errors.length > 0) {
287
- lines.push(`ERRORS (${errors.length}):`);
288
- for (const e of errors) lines.push(` [${e.ruleId}] ${e.message}`);
289
- }
290
- if (warnings.length > 0) {
291
- lines.push(`WARNINGS (${warnings.length}):`);
292
- for (const w of warnings) lines.push(` [${w.ruleId}] ${w.message}`);
293
- }
294
- if (errors.length === 0 && warnings.length === 0) {
295
- lines.push("All validations passed.");
296
- }
297
- return lines.join("\n");
298
- }
@@ -1,187 +0,0 @@
1
- # 会议纪要主题演示
2
-
3
- 这是 **meeting-minutes** 主题的完整预览。该主题从实际的会议纪要文档中提取,适合正式的商务文档排版。
4
-
5
- ## 2. 二级标题样式
6
-
7
- ### 3. 三级标题样式
8
-
9
- 这是一段普通文本,包含 **粗体**、*斜体*、`行内代码`、[链接](https://example.com) 和 ~~删除线~~。还会包含一些中文文本以测试字体效果。
10
-
11
- > 这是一个引用块。引用块通常用于强调或展示外部内容。这里可以包含 *斜体* 和 **粗体** 文本。
12
- >
13
- > —— 会议记录人
14
-
15
- ### 列表样式
16
-
17
- **无序列表:**
18
-
19
- - 第一项讨论内容
20
- - 第二项讨论内容
21
- - 嵌套的子项目 A
22
- - 嵌套的子项目 B
23
- - 第三项行动项
24
-
25
- **有序列表:**
26
-
27
- 1. 开场致辞
28
- 2. 议程第一项:财务报告
29
- 1. 第一季度回顾
30
- 2. 第二季度预测
31
- 3. 议程第二项:项目进展
32
- 1. 核心功能完成度
33
- 2. 下一步里程碑
34
-
35
- **任务列表:**
36
-
37
- - [x] 会议材料准备
38
- - [x] 会议室预订
39
- - [ ] 会后纪要分发
40
- - [ ] 行动项跟进
41
-
42
- ### 代码块样式
43
-
44
- ```python
45
- def generate_meeting_minutes(attendees, topics, decisions):
46
- """
47
- 生成会议纪要
48
- """
49
- minutes = {
50
- "date": datetime.now(),
51
- "attendees": attendees,
52
- "topics": topics,
53
- "decisions": decisions,
54
- "action_items": []
55
- }
56
- return minutes
57
- ```
58
-
59
- ```javascript
60
- // JavaScript 示例
61
- const meeting = {
62
- title: "Sprint Planning",
63
- duration: "2 hours",
64
- participants: ["Alice", "Bob", "Charlie"]
65
- };
66
- ```
67
-
68
- ### 表格样式
69
-
70
- | 项目 | 负责人 | 截止日期 | 状态 |
71
- |------|--------|----------|------|
72
- | 用户调研 | 张三 | 2025-06-15 | ✅ 已完成 |
73
- | 原型设计 | 李四 | 2025-06-20 | 🔄 进行中 |
74
- | 开发实现 | 王五 | 2025-07-15 | ⏳ 未开始 |
75
- | 测试验收 | 赵六 | 2025-07-30 | ⏳ 未开始 |
76
-
77
- | Header 1 | Header 2 | Header 3 |
78
- |----------|----------|----------|
79
- | Cell 1 | Cell 2 | Cell 3 |
80
- | Cell 4 | Cell 5 | Cell 6 |
81
-
82
- ---
83
-
84
- ### Mermaid 图表
85
-
86
- ```mermaid
87
- graph TD
88
- A[会议开始] --> B[议程介绍]
89
- B --> C[财务报告]
90
- B --> D[项目进展]
91
- B --> E[其他事项]
92
- C --> F[决策1]
93
- D --> G[决策2]
94
- E --> H[决策3]
95
- F --> I[行动项分配]
96
- G --> I
97
- H --> I
98
- I --> J[下次会议安排]
99
- ```
100
-
101
- ```mermaid
102
- sequenceDiagram
103
- participant 主持人
104
- participant 张三
105
- participant 李四
106
- 主持人->>张三: 请介绍财务情况
107
- 张三->>所有人: Q1营收增长15%
108
- 李四->>所有人: 建议增加营销预算
109
- 主持人->>所有人: 通过决议
110
- ```
111
-
112
- ---
113
-
114
- ### 数学公式
115
-
116
- $$
117
- \int_{a}^{b} f(x) \, dx = F(b) - F(a)
118
- $$
119
-
120
- $$
121
- E = mc^2
122
- $$
123
-
124
- ---
125
-
126
- ### 分隔线
127
-
128
- ---
129
-
130
- ### 行内元素变体
131
-
132
- | 样式 | 示例 |
133
- |------|------|
134
- | 代码 | `const x = 10;` |
135
- | 强调 | *重要内容* |
136
- | 加粗 | **必须完成** |
137
- | 标记 | ==高亮显示== |
138
- | 下标 | H~2~O |
139
- | 上标 | x^2^ |
140
-
141
- ---
142
-
143
- ### YAML Frontmatter 示例
144
-
145
- ```yaml
146
- ---
147
- title: 项目周会纪要
148
- date: 2025-05-25
149
- location: 会议室 A305
150
- attendees:
151
- - 张三 (产品经理)
152
- - 李四 (技术负责人)
153
- - 王五 (设计师)
154
- decisions:
155
- - 同意增加前端开发人员
156
- - 下周启动用户调研
157
- action_items:
158
- - { owner: 李四, task: 完成技术方案, due: 2025-06-01 }
159
- - { owner: 王五, task: 提供设计稿, due: 2025-06-05 }
160
- ---
161
- ```
162
-
163
- ---
164
-
165
- ### 脚注示例
166
-
167
- 这是一个包含脚注的段落。会议决议需要所有核心成员确认[^1],并在会后24小时内分发纪要[^2]。
168
-
169
- [^1]: 核心成员指产品、技术、设计负责人
170
- [^2]: 分发渠道:企业微信 + 邮件
171
-
172
- ---
173
-
174
- ### 定义列表
175
-
176
- **Term 1**
177
- : Definition 1a
178
- : Definition 1b
179
-
180
- **Term 2**
181
- : Definition 2a
182
-
183
- ---
184
-
185
- <div style="margin-top: 3rem; padding: 1rem; background: var(--seed-panel); border-left: 4px solid var(--seed-accent); border-radius: var(--radius-md);">
186
- <strong>💡 提示:</strong> 这个主题使用了 <code>macaron-blueberry</code> 配色方案,特点是柔和的蓝色强调色搭配干净的白色背景,适合正式文档和会议纪要。
187
- </div>
package/tsconfig.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "Node16",
5
- "moduleResolution": "Node16",
6
- "outDir": "dist",
7
- "rootDir": "src",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "declaration": true,
13
- "resolveJsonModule": true,
14
- "sourceMap": true
15
- },
16
- "include": ["src/**/*"],
17
- "exclude": ["node_modules", "dist", "tests"]
18
- }