@bytechain.cn/colamd-themes 0.5.0 → 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 (71) hide show
  1. package/README.md +27 -13
  2. package/cordis.patch.yml +9 -0
  3. package/dist/cli.js +3 -3
  4. package/dist/cli.js.map +1 -1
  5. package/dist/dsh-plugin.d.ts +44 -0
  6. package/dist/dsh-plugin.js +72 -0
  7. package/dist/dsh-plugin.js.map +1 -0
  8. package/dist/generator.d.ts +1 -1
  9. package/dist/generator.js +2 -2
  10. package/dist/generator.js.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +2 -0
  13. package/dist/index.js.map +1 -1
  14. package/dist/models.d.ts +1 -1
  15. package/dist/models.js +1 -1
  16. package/dist/models.js.map +1 -1
  17. package/dist/renderer.d.ts +6 -5
  18. package/dist/renderer.js +19 -38
  19. package/dist/renderer.js.map +1 -1
  20. package/dist/theme-store.js +4 -4
  21. package/dist/theme-store.js.map +1 -1
  22. package/dist/validators.d.ts +2 -2
  23. package/dist/validators.js +4 -4
  24. package/dist/validators.js.map +1 -1
  25. package/package.json +22 -2
  26. package/skills/build-skills.sh +5 -5
  27. package/skills/colamd-themes/SKILL.md +5 -5
  28. package/.claude/skills/colamd-themes-preview.skill.md +0 -333
  29. package/.claude/skills/colamd-themes.skill.md +0 -10
  30. package/.dsh/skills/colamd-themes/SKILL.md +0 -14
  31. package/.github/supported-topics.yml +0 -17
  32. package/.hermes/skills/tools/colamd-themes/SKILL.md +0 -14
  33. package/.openclaw/skills/colamd-themes/SKILL.md +0 -21
  34. package/.opencode/skills/colamd-themes/SKILL.md +0 -17
  35. package/.trae/rules/colamd-themes.md +0 -5
  36. package/CHANGELOG.md +0 -318
  37. package/DSH_SUPPORT_SUMMARY.md +0 -87
  38. package/README_CN.md +0 -412
  39. package/RELEASENOTE.md +0 -541
  40. package/bytechain.cn-colamd-themes-0.5.0.tgz +0 -0
  41. package/mcp-server/dist/index.d.ts +0 -13
  42. package/mcp-server/dist/index.d.ts.map +0 -1
  43. package/mcp-server/dist/index.js.map +0 -1
  44. package/mcp-server/package-lock.json +0 -1759
  45. package/mcp-server/package.json +0 -24
  46. package/mcp-server/src/index.ts +0 -0
  47. package/mcp-server/tsconfig.json +0 -19
  48. package/src/cli.ts +0 -474
  49. package/src/color-systems.ts +0 -289
  50. package/src/color-utils.ts +0 -137
  51. package/src/contrast.ts +0 -66
  52. package/src/docx-style-paradigm.ts +0 -811
  53. package/src/export-cli.ts +0 -356
  54. package/src/extractors/base.ts +0 -8
  55. package/src/extractors/docx-extractor.ts +0 -417
  56. package/src/extractors/pdf-extractor.ts +0 -533
  57. package/src/extractors/url-extractor.ts +0 -846
  58. package/src/generator.ts +0 -197
  59. package/src/index.ts +0 -29
  60. package/src/models.ts +0 -212
  61. package/src/renderer.ts +0 -332
  62. package/src/templates/template.css +0 -220
  63. package/src/templates/theme-paradigm.md +0 -530
  64. package/src/templates/theme-template.hbs +0 -256
  65. package/src/theme-store.ts +0 -185
  66. package/src/types/pdf-parse.d.ts +0 -12
  67. package/src/utils/cli-utils.ts +0 -84
  68. package/src/utils/document-paradigm.ts +0 -118
  69. package/src/validators.ts +0 -298
  70. package/themes-preview/demo-content.md +0 -187
  71. package/tsconfig.json +0 -18
package/src/generator.ts DELETED
@@ -1,197 +0,0 @@
1
- /** CSS theme file generator — v4.0 seed palette pipeline (ColaMD 2.7.7 contract). */
2
-
3
- import Handlebars from "handlebars";
4
- import { readFileSync, writeFileSync, mkdirSync, existsSync, statSync } from "node:fs";
5
- import { join, dirname, isAbsolute } from "node:path";
6
- import { fileURLToPath } from "node:url";
7
- import type { ThemeStyle } from "./models.js";
8
- import { paletteToSeed } from "./models.js";
9
- import { toRgba, normalizeThemeStyle } from "./color-utils.js";
10
- import { matchColorSystem } from "./color-systems.js";
11
- import { contrastRatio } from "./contrast.js";
12
- import { validateSeedPalette, validateThemeCss, summarizeIssues } from "./validators.js";
13
-
14
- const __dirname = dirname(fileURLToPath(import.meta.url));
15
- const templatePath = join(__dirname, "templates", "theme-template.hbs");
16
-
17
- // ── Handlebars helpers ──
18
-
19
- Handlebars.registerHelper("rgba", (hex: unknown, alpha: unknown) => {
20
- return toRgba(String(hex), Number(alpha));
21
- });
22
-
23
- // ── Template Cache with Size Limits and Auto-Invalidation ──
24
-
25
- /** 模板上下文:ThemeStyle + 生成阶段算出的派生值。 */
26
- type TemplateContext = ThemeStyle & { codeBlockText: string };
27
-
28
- interface CachedTemplate {
29
- compiled: HandlebarsTemplateDelegate<TemplateContext>;
30
- mtimeMs: number;
31
- compiledAt: number;
32
- }
33
-
34
- const TEMPLATE_CACHE_MAX_SIZE = 10;
35
- const TEMPLATE_CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes
36
- const templateCache = new Map<string, CachedTemplate>();
37
-
38
- /**
39
- * Get or compile a Handlebars template with caching.
40
- *
41
- * Features:
42
- * - LRU-style cache (max 10 templates)
43
- * - File modification time detection for auto-invalidation
44
- * - TTL-based expiration (30 minutes)
45
- * - Automatic cleanup of expired entries on access
46
- */
47
- function getTemplate(path?: string): HandlebarsTemplateDelegate<TemplateContext> {
48
- const key = path || templatePath;
49
-
50
- // Check cache hit
51
- const cached = templateCache.get(key);
52
- if (cached) {
53
- // Check TTL expiration
54
- if (Date.now() - cached.compiledAt > TEMPLATE_CACHE_TTL_MS) {
55
- templateCache.delete(key);
56
- }
57
- // Check file modification time
58
- else {
59
- try {
60
- const stats = statSync(key);
61
- if (stats.mtimeMs > cached.mtimeMs) {
62
- templateCache.delete(key);
63
- } else {
64
- return cached.compiled;
65
- }
66
- } catch {
67
- return cached.compiled;
68
- }
69
- }
70
- }
71
-
72
- // Enforce max cache size (evict oldest entry)
73
- if (templateCache.size >= TEMPLATE_CACHE_MAX_SIZE) {
74
- let oldestKey: string | null = null;
75
- let oldestTime = Infinity;
76
-
77
- for (const [k, v] of templateCache.entries()) {
78
- if (v.compiledAt < oldestTime) {
79
- oldestTime = v.compiledAt;
80
- oldestKey = k;
81
- }
82
- }
83
-
84
- if (oldestKey) {
85
- templateCache.delete(oldestKey);
86
- }
87
- }
88
-
89
- // Compile new template
90
- const source = readFileSync(key, "utf-8");
91
- const compiled = Handlebars.compile(source, { noEscape: true });
92
-
93
- // Get modification time for invalidation
94
- let mtimeMs = 0;
95
- try {
96
- mtimeMs = statSync(key).mtimeMs;
97
- } catch {
98
- mtimeMs = Date.now();
99
- }
100
-
101
- templateCache.set(key, {
102
- compiled,
103
- mtimeMs,
104
- compiledAt: Date.now(),
105
- });
106
-
107
- return compiled;
108
- }
109
-
110
- /**
111
- * Clear all cached templates to free memory.
112
- */
113
- export function clearTemplateCache(): void {
114
- templateCache.clear();
115
- }
116
-
117
- /**
118
- * 代码块文字色:从代码块底色出发,在白、浅灰、种子正文色里挑对比度最高的一档。
119
- * 深色代码块(如 elegant)因此拿到浅色文字,浅色代码块拿到正文色。
120
- */
121
- function pickCodeBlockText(bg: string, seed: ThemeStyle["seed"]): string {
122
- const candidates = Array.from(new Set(["#ffffff", "#f5f5f5", seed.surface, seed.ink]));
123
- let best = candidates[0];
124
- let bestRatio = 0;
125
- for (const candidate of candidates) {
126
- const ratio = contrastRatio(candidate, bg);
127
- if (ratio > bestRatio) {
128
- bestRatio = ratio;
129
- best = candidate;
130
- }
131
- }
132
- return best;
133
- }
134
-
135
- // ── Pipeline ──
136
-
137
- export function generateCss(style: ThemeStyle): string {
138
- // 1. Map legacy palette → seed palette if seed is still default
139
- if (style.seed.accent === "#6366f1") {
140
- style.seed = paletteToSeed(style.palette);
141
- }
142
-
143
- // 2. Normalize from legacy extractor path
144
- normalizeThemeStyle(style);
145
-
146
- // 3. Match color system
147
- if (!style.colorSystemId) {
148
- const cs = matchColorSystem(style.seed.accent, style.seed.surface);
149
- style.colorSystemId = cs.id;
150
- }
151
-
152
- // 4. Validate seed palette against paradigm
153
- const issues = validateSeedPalette(style.seed);
154
- if (issues.filter((i) => i.level === "MUST" || i.level === "MUST_NOT").length > 0) {
155
- console.warn("Paradigm validation issues:", summarizeIssues(issues));
156
- }
157
-
158
- // 5. Render
159
- const template = getTemplate();
160
- const css = template({
161
- ...style,
162
- codeBlockText: pickCodeBlockText(style.seed.panelAlt, style.seed),
163
- });
164
-
165
- // 6. Self-check the rendered CSS against the 2.7.7 contract
166
- const cssIssues = validateThemeCss(css).filter(
167
- (i) => i.level === "MUST" || i.level === "MUST_NOT"
168
- );
169
- if (cssIssues.length > 0) {
170
- console.warn("CSS contract issues:", summarizeIssues(cssIssues));
171
- }
172
-
173
- return css;
174
- }
175
-
176
- export function writeThemeFile(
177
- style: ThemeStyle,
178
- target: string = "themes"
179
- ): string {
180
- const css = generateCss(style);
181
- const safeName = style.name.replace(/[^a-zA-Z0-9_-]/g, "-").replace(/-+/g, "-");
182
-
183
- let filePath: string;
184
- if (target.endsWith(".css")) {
185
- filePath = isAbsolute(target) ? target : join(process.cwd(), target);
186
- } else {
187
- const dirPath = isAbsolute(target) ? target : join(process.cwd(), target);
188
- if (!existsSync(dirPath)) mkdirSync(dirPath, { recursive: true });
189
- filePath = join(dirPath, `${safeName}.css`);
190
- }
191
-
192
- const parent = dirname(filePath);
193
- if (!existsSync(parent)) mkdirSync(parent, { recursive: true });
194
-
195
- writeFileSync(filePath, css, "utf-8");
196
- return filePath;
197
- }
package/src/index.ts DELETED
@@ -1,29 +0,0 @@
1
- /** ColaMD Theme Development Tool. */
2
-
3
- export * from "./models.js";
4
- export * from "./color-utils.js";
5
- export * from "./generator.js";
6
- export { UrlExtractor } from "./extractors/url-extractor.js";
7
- export { DocxExtractor } from "./extractors/docx-extractor.js";
8
- export { PdfExtractor } from "./extractors/pdf-extractor.js";
9
- export type { Extractor } from "./extractors/base.js";
10
-
11
- export {
12
- ACADEMIC_PAPER_DEFAULTS,
13
- BUSINESS_REPORT_DEFAULTS,
14
- TECHNICAL_DOC_DEFAULTS,
15
- generatePrintFriendlyGrayscale,
16
- generateMorandiPrintPalette,
17
- validateDocumentStyle,
18
- normalizeForPrinting,
19
- getRecommendedPreset,
20
- DOCUMENT_STYLE_PRESETS,
21
- } from "./docx-style-paradigm.js";
22
-
23
- export type {
24
- DocumentStyleParadigm,
25
- FontStyleDefinition,
26
- TableCellStyle,
27
- PrintOptimization,
28
- StyleValidationIssue,
29
- } from "./docx-style-paradigm.js";
package/src/models.ts DELETED
@@ -1,212 +0,0 @@
1
- /** Theme style data models — v4.0 Seed Palette paradigm (ColaMD 2.7.7 contract). */
2
-
3
- // ═══════════════════════════════════════════════════════════
4
- // Legacy model (kept for extractor compatibility)
5
- // ═══════════════════════════════════════════════════════════
6
-
7
- export interface ColorPalette {
8
- bgColor: string;
9
- textColor: string;
10
- headingColor: string;
11
- borderColor: string;
12
- accentColor: string;
13
- codeBg: string;
14
- codeColor: string;
15
- codeBlockBg: string;
16
- codeBlockText: string;
17
- blockquoteBg: string;
18
- blockquoteBorder: string;
19
- tableHeaderBg: string;
20
- selectionBg: string;
21
- textMuted: string;
22
- }
23
-
24
- export interface Typography {
25
- bodyFontFamily: string;
26
- headingFontFamily: string;
27
- codeFontFamily: string;
28
- baseFontSize: string;
29
- baseLineHeight: number;
30
- headingWeight: number;
31
- }
32
-
33
- export interface Spacing {
34
- contentMaxWidth: string;
35
- contentPadding: string;
36
- paragraphMargin: string;
37
- headingMarginTop: string;
38
- headingMarginBottom: string;
39
- }
40
-
41
- export interface SyntaxHighlighting {
42
- comment: string;
43
- punctuation: string;
44
- keyword: string;
45
- booleanBuiltinTag: string;
46
- string: string;
47
- number: string;
48
- functionClass: string;
49
- operator: string;
50
- variable: string;
51
- regex: string;
52
- }
53
-
54
- // ═══════════════════════════════════════════════════════════
55
- // 2.7 Seed Palette model
56
- // ═══════════════════════════════════════════════════════════
57
-
58
- export interface SeedPalette {
59
- accent: string;
60
- accentLight: string;
61
- accentDark: string;
62
- surface: string;
63
- panel: string;
64
- panelAlt: string;
65
- ink: string;
66
- inkMuted: string;
67
- inkDim: string;
68
- border: string;
69
- borderStrong: string;
70
- }
71
-
72
- export interface SeedTypography {
73
- fontBody: string;
74
- fontHeading: string;
75
- fontCode: string;
76
- /** @deprecated 2.7 起图表改用 Pele,Mermaid 字段仅为提取器兼容保留 */
77
- fontMermaid: string;
78
- fontSizeRoot: string; // e.g. "16px"
79
- fontScaleH1: number;
80
- fontScaleH2: number;
81
- fontScaleH3: number;
82
- fontScaleH4: number;
83
- fontScaleH5: number;
84
- fontScaleH6: number;
85
- /** @deprecated 2.7 起图表改用 Pele */
86
- fontSizeMermaid: string;
87
- lineHeightBody: number;
88
- lineHeightHeading: number;
89
- lineHeightCode: number;
90
- }
91
-
92
- export interface ThemeStyle {
93
- name: string;
94
- description: string;
95
- /** Legacy — populated by extractors, then mapped to seed */
96
- palette: ColorPalette;
97
- typography: Typography;
98
- spacing: Spacing;
99
- syntax: SyntaxHighlighting;
100
- /** 2.7 seed palette */
101
- seed: SeedPalette;
102
- seedTypography: SeedTypography;
103
- /** Selected color system */
104
- colorSystemId: string;
105
- /** Metadata */
106
- sourceUrl: string;
107
- sourceType: string;
108
- /** Computed radius and width */
109
- radiusSm: string;
110
- radiusMd: string;
111
- radiusLg: string;
112
- contentWidth: string;
113
- }
114
-
115
- // ═══════════════════════════════════════════════════════════
116
- // Defaults
117
- // ═══════════════════════════════════════════════════════════
118
-
119
- export function defaultPalette(): ColorPalette {
120
- return {
121
- bgColor: "#ffffff", textColor: "#000000", headingColor: "",
122
- borderColor: "#cccccc", accentColor: "#0000ff", codeBg: "#f5f5f5",
123
- codeColor: "", codeBlockBg: "#1e1e1e", codeBlockText: "#d4d4d4",
124
- blockquoteBg: "#f9f9f9", blockquoteBorder: "",
125
- tableHeaderBg: "#f0f0f0", selectionBg: "", textMuted: "#666666",
126
- };
127
- }
128
-
129
- export function defaultTypography(): Typography {
130
- return {
131
- bodyFontFamily: "Georgia, serif", headingFontFamily: "",
132
- codeFontFamily: "'JetBrains Mono', 'Fira Code', monospace",
133
- baseFontSize: "16px", baseLineHeight: 1.9, headingWeight: 700,
134
- };
135
- }
136
-
137
- export function defaultSpacing(): Spacing {
138
- return {
139
- contentMaxWidth: "820px", contentPadding: "30px 60px 100px",
140
- paragraphMargin: "0.8em 0", headingMarginTop: "1.8em",
141
- headingMarginBottom: "0.6em",
142
- };
143
- }
144
-
145
- export function defaultSyntax(): SyntaxHighlighting {
146
- return { comment: "", punctuation: "", keyword: "", booleanBuiltinTag: "",
147
- string: "", number: "", functionClass: "", operator: "", variable: "", regex: "" };
148
- }
149
-
150
- export function defaultSeedPalette(): SeedPalette {
151
- return {
152
- accent: "#6366f1", accentLight: "#eef2ff", accentDark: "#4f46e5",
153
- surface: "#ffffff", panel: "#f8f9fb", panelAlt: "#f1f3f5",
154
- ink: "#1a1d26", inkMuted: "#6b7280", inkDim: "#9ca3af",
155
- border: "#e5e7eb", borderStrong: "#d1d5db",
156
- };
157
- }
158
-
159
- export function defaultSeedTypography(): SeedTypography {
160
- return {
161
- fontBody: `"Inter", "SF Pro Text", -apple-system, "Noto Serif SC", "Source Han Serif SC", Georgia, serif`,
162
- fontHeading: `"Inter", "SF Pro Display", -apple-system, "Noto Sans SC", "PingFang SC", sans-serif`,
163
- fontCode: `"JetBrains Mono", "SF Mono", "Fira Code", Menlo, Consolas, monospace`,
164
- fontMermaid: `var(--font-body)`,
165
- fontSizeRoot: "16px",
166
- fontScaleH1: 2.0, fontScaleH2: 1.5, fontScaleH3: 1.25,
167
- fontScaleH4: 1.1, fontScaleH5: 1.0, fontScaleH6: 0.95,
168
- fontSizeMermaid: "13px",
169
- lineHeightBody: 1.75, lineHeightHeading: 1.35, lineHeightCode: 1.6,
170
- };
171
- }
172
-
173
- // ═══════════════════════════════════════════════════════════
174
- // Factory
175
- // ═══════════════════════════════════════════════════════════
176
-
177
- export function makeThemeStyle(name: string, sourceType: string, sourceUrl: string): ThemeStyle {
178
- return {
179
- name,
180
- description: `Theme extracted from ${sourceType}`,
181
- palette: defaultPalette(),
182
- typography: defaultTypography(),
183
- spacing: defaultSpacing(),
184
- syntax: defaultSyntax(),
185
- seed: defaultSeedPalette(),
186
- seedTypography: defaultSeedTypography(),
187
- colorSystemId: "",
188
- sourceUrl,
189
- sourceType,
190
- radiusSm: "3px",
191
- radiusMd: "6px",
192
- radiusLg: "10px",
193
- contentWidth: "820px",
194
- };
195
- }
196
-
197
- /** Map legacy ColorPalette to SeedPalette. */
198
- export function paletteToSeed(palette: ColorPalette): SeedPalette {
199
- return {
200
- accent: palette.accentColor,
201
- accentLight: palette.selectionBg || palette.accentColor,
202
- accentDark: palette.accentColor,
203
- surface: palette.bgColor,
204
- panel: palette.codeBg,
205
- panelAlt: palette.codeBlockBg,
206
- ink: palette.textColor,
207
- inkMuted: palette.textMuted,
208
- inkDim: palette.textMuted,
209
- border: palette.borderColor,
210
- borderStrong: palette.borderColor,
211
- };
212
- }