@zzclub/pipeline 0.13.2 → 0.16.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 (60) hide show
  1. package/ARTICLE-THEMES.md +86 -0
  2. package/LICENSE +21 -0
  3. package/README.md +182 -788
  4. package/THIRD-PARTY-NOTICES.md +25 -0
  5. package/package.json +6 -2
  6. package/src/adapter-types.ts +3 -0
  7. package/src/adapters/builtin-markdown-renderer.ts +1 -0
  8. package/src/article-theme.test.ts +87 -0
  9. package/src/article-theme.ts +115 -0
  10. package/src/commands/abandon.test.ts +1 -1
  11. package/src/commands/article-theme.ts +16 -0
  12. package/src/commands/checkpoint.test.ts +2 -2
  13. package/src/commands/ingest-handoff.ts +6 -0
  14. package/src/commands/init.ts +10 -0
  15. package/src/commands/prepare.ts +5 -1
  16. package/src/commands/publish.ts +4 -0
  17. package/src/commands/reset.ts +2 -0
  18. package/src/commands/wechat-export.ts +4 -0
  19. package/src/commands/wechat-preview.ts +35 -0
  20. package/src/plugins.ts +2 -0
  21. package/src/providers/index.ts +17 -2
  22. package/src/providers/publish-core.ts +32 -1
  23. package/src/providers/wechat.test.ts +12 -0
  24. package/src/providers/wechat.ts +60 -39
  25. package/src/render-branding.ts +1 -1
  26. package/src/schema/config.ts +12 -0
  27. package/src/schema/state.ts +5 -0
  28. package/src/wechat-preview/assets/browser-dist/.vite/manifest.json +21 -1
  29. package/src/wechat-preview/assets/browser-dist/assets/style-C9-YtTIm.css +1 -0
  30. package/src/wechat-preview/assets/browser-dist/assets/wechat-renderer-D1jHoaM2.js +624 -0
  31. package/src/wechat-preview/assets/browser-dist/editor-export.js +1 -512
  32. package/src/wechat-preview/assets/browser-dist/src/wechat-preview/browser/studio/studio.html +293 -0
  33. package/src/wechat-preview/assets/browser-dist/studio.js +332 -0
  34. package/src/wechat-preview/browser/editor-export.ts +17 -2
  35. package/src/wechat-preview/browser/highlight.ts +2 -0
  36. package/src/wechat-preview/browser/studio/color-palettes.test.ts +31 -0
  37. package/src/wechat-preview/browser/studio/color-palettes.ts +115 -0
  38. package/src/wechat-preview/browser/studio/studio.css +638 -0
  39. package/src/wechat-preview/browser/studio/studio.html +292 -0
  40. package/src/wechat-preview/browser/studio/studio.ts +721 -0
  41. package/src/wechat-preview/browser/studio/syntax-presets.test.ts +74 -0
  42. package/src/wechat-preview/browser/studio/syntax-presets.ts +590 -0
  43. package/src/wechat-preview/fixtures/all-nodes.md +38 -0
  44. package/src/wechat-preview/index.ts +36 -5
  45. package/src/wechat-preview/plugins/builtin-badge.ts +152 -0
  46. package/src/wechat-preview/plugins/builtin-callout.ts +261 -0
  47. package/src/wechat-preview/plugins/builtin-highlight.ts +46 -0
  48. package/src/wechat-preview/plugins/builtin-kbd.ts +133 -0
  49. package/src/wechat-preview/plugins/index.test.ts +313 -0
  50. package/src/wechat-preview/plugins/index.ts +6 -0
  51. package/src/wechat-preview/plugins/registry.ts +62 -0
  52. package/src/wechat-preview/plugins/types.ts +31 -0
  53. package/src/wechat-preview/server/http.ts +160 -3
  54. package/src/wechat-preview/server/paths.ts +2 -2
  55. package/src/wechat-preview/server/singleton.ts +14 -12
  56. package/src/wechat-preview/server/studio.test.ts +92 -0
  57. package/src/wechat-preview/server/ui.ts +1 -0
  58. package/src/wechat-preview/wechat-export.integration.test.ts +9 -1
  59. package/src/wechat-preview/wechat-renderer.ts +72 -7
  60. package/src/workflow.test.ts +1 -0
@@ -0,0 +1,292 @@
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">
6
+ <title>WeChat Article Visual Studio - 排版可视化工作台</title>
7
+ <link rel="stylesheet" href="./studio.css">
8
+ </head>
9
+ <body>
10
+ <!-- Header -->
11
+ <header class="studio-header">
12
+ <div class="brand-section">
13
+ <span class="brand-logo">🎨</span>
14
+ <h1 class="brand-title">WeChat Visual Studio</h1>
15
+ <span class="brand-badge">实时调优</span>
16
+ </div>
17
+
18
+ <div class="header-controls">
19
+ <div class="account-select-wrap">
20
+ <span>公众号账号:</span>
21
+ <select id="account-select" class="account-select">
22
+ <option value="default">默认账号 (default)</option>
23
+ </select>
24
+ </div>
25
+
26
+ <button id="btn-reset" class="btn" title="恢复当前账号默认样式">
27
+ <span>🔄 重置</span>
28
+ </button>
29
+
30
+ <button id="btn-save" class="btn btn-primary" title="保存当前调整至本地 config.json">
31
+ <span>💾 保存至配置</span>
32
+ </button>
33
+
34
+ <button id="btn-copy" class="btn btn-success" title="复制内联富文本,可直接粘贴到微信公众号后台">
35
+ <span>📋 一键复制到公众号</span>
36
+ </button>
37
+
38
+ <a href="/" class="btn" title="返回导出历史">
39
+ <span>📜 历史记录</span>
40
+ </a>
41
+ </div>
42
+ </header>
43
+
44
+ <!-- Body -->
45
+ <main class="studio-body">
46
+ <!-- Left: Tuning & Plugins -->
47
+ <aside class="panel left-panel">
48
+ <nav class="tab-nav">
49
+ <button id="tab-btn-style" class="tab-btn active">🎨 样式调优</button>
50
+ <button id="tab-btn-syntax" class="tab-btn">🧩 语法与组件</button>
51
+ </nav>
52
+
53
+ <!-- Tab 1: Style Tuning -->
54
+ <div id="tab-content-style" class="tab-content">
55
+ <!-- Typography -->
56
+ <div class="config-section">
57
+ <div class="section-label">
58
+ <span>📐 字号与排版</span>
59
+ </div>
60
+
61
+ <div class="form-group">
62
+ <div class="form-label">
63
+ <span>正文字号</span>
64
+ <span id="val-font-size" class="form-val">16px</span>
65
+ </div>
66
+ <input type="range" id="input-font-size" class="slider-input" min="14" max="18" step="1" value="16">
67
+ </div>
68
+
69
+ <div class="form-group">
70
+ <div class="form-label">
71
+ <span>行高倍数</span>
72
+ <span id="val-line-height" class="form-val">1.84</span>
73
+ </div>
74
+ <input type="range" id="input-line-height" class="slider-input" min="1.5" max="2.2" step="0.02" value="1.84">
75
+ </div>
76
+
77
+ <div class="form-group">
78
+ <div class="form-label">
79
+ <span>字间距 (Letter Spacing)</span>
80
+ <span id="val-letter-spacing" class="form-val">0.012em</span>
81
+ </div>
82
+ <input type="range" id="input-letter-spacing" class="slider-input" min="0" max="0.05" step="0.002" value="0.012">
83
+ </div>
84
+
85
+ <div class="form-group">
86
+ <div class="form-label">
87
+ <span>段落间距 (Margin Bottom)</span>
88
+ <span id="val-para-spacing" class="form-val">1.2em</span>
89
+ </div>
90
+ <input type="range" id="input-para-spacing" class="slider-input" min="0.8" max="2.0" step="0.1" value="1.2">
91
+ </div>
92
+ </div>
93
+
94
+ <!-- Colors -->
95
+ <div class="config-section">
96
+ <div class="section-label">
97
+ <span>🎨 颜色系统</span>
98
+ </div>
99
+
100
+ <div class="form-group" style="margin-bottom: 16px;">
101
+ <div class="form-label">
102
+ <span>🌟 推荐高级配色方案 (杂志 / 服装 / App)</span>
103
+ </div>
104
+ <select id="palette-select" class="preset-select">
105
+ <option value="">-- 选择推荐调色盘 (一键应用) --</option>
106
+ </select>
107
+ <div id="palette-desc" class="preset-desc">可一键应用 Kinfolk 森林绿、Loro Piana 燕麦大地、纽约客石板蓝等</div>
108
+ </div>
109
+
110
+ <div class="form-group">
111
+ <div class="form-label">
112
+ <span>品牌主色 (Brand)</span>
113
+ </div>
114
+ <div class="color-input-row">
115
+ <input type="color" id="picker-brand-color" class="color-picker" value="#ca6093">
116
+ <input type="text" id="hex-brand-color" class="color-hex" value="#ca6093">
117
+ </div>
118
+ </div>
119
+
120
+ <div class="form-group">
121
+ <div class="form-label">
122
+ <span>正文字色 (Body Text)</span>
123
+ </div>
124
+ <div class="color-input-row">
125
+ <input type="color" id="picker-text-color" class="color-picker" value="#292526">
126
+ <input type="text" id="hex-text-color" class="color-hex" value="#292526">
127
+ </div>
128
+ </div>
129
+
130
+ <div class="form-group">
131
+ <div class="form-label">
132
+ <span>二级标题颜色 (H2)</span>
133
+ </div>
134
+ <div class="color-input-row">
135
+ <input type="color" id="picker-h2-color" class="color-picker" value="#1f1b1c">
136
+ <input type="text" id="hex-h2-color" class="color-hex" value="#1f1b1c">
137
+ </div>
138
+ </div>
139
+
140
+ <div class="form-group">
141
+ <div class="form-label">
142
+ <span>三级标题颜色 (H3)</span>
143
+ </div>
144
+ <div class="color-input-row">
145
+ <input type="color" id="picker-h3-color" class="color-picker" value="#5c5658">
146
+ <input type="text" id="hex-h3-color" class="color-hex" value="#5c5658">
147
+ </div>
148
+ </div>
149
+
150
+ <div class="form-group">
151
+ <div class="form-label">
152
+ <span>引用边框与重点色</span>
153
+ </div>
154
+ <div class="color-input-row">
155
+ <input type="color" id="picker-quote-color" class="color-picker" value="#e8c9d7">
156
+ <input type="text" id="hex-quote-color" class="color-hex" value="#e8c9d7">
157
+ </div>
158
+ </div>
159
+
160
+ <div class="form-group">
161
+ <div class="form-label">
162
+ <span>分割线颜色 (Divider)</span>
163
+ </div>
164
+ <div class="color-input-row">
165
+ <input type="color" id="picker-divider-color" class="color-picker" value="#e2dcdf">
166
+ <input type="text" id="hex-divider-color" class="color-hex" value="#e2dcdf">
167
+ </div>
168
+ </div>
169
+ </div>
170
+
171
+ <!-- Syntax Presets -->
172
+ <div class="config-section">
173
+ <div class="section-label">
174
+ <span>🧩 语法节点风格预设 (H2 / H3 / 引用 / 分割线)</span>
175
+ </div>
176
+ <div id="syntax-preset-container">
177
+ <!-- Populated dynamically by studio.ts from SYNTAX_CATEGORIES -->
178
+ </div>
179
+ </div>
180
+
181
+ <!-- Structure -->
182
+ <div class="config-section">
183
+ <div class="section-label">
184
+ <span>🏛️ 装饰与结构</span>
185
+ </div>
186
+
187
+ <div class="form-group">
188
+ <label class="switch-label">
189
+ <span>二级标题自动编号 (01, 02)</span>
190
+ <span class="switch-toggle">
191
+ <input type="checkbox" id="switch-numbered-headings">
192
+ <span class="slider-round"></span>
193
+ </span>
194
+ </label>
195
+ </div>
196
+
197
+ <div class="form-group">
198
+ <div class="form-label">
199
+ <span>标题前缀标签 (例: CHAPTER)</span>
200
+ </div>
201
+ <input type="text" id="input-heading-label" class="color-hex" style="width:100%" placeholder="如:CHAPTER">
202
+ </div>
203
+
204
+ <div class="form-group">
205
+ <div class="form-label">
206
+ <span>引言前缀标签 (例: 摘录)</span>
207
+ </div>
208
+ <input type="text" id="input-quote-label" class="color-hex" style="width:100%" placeholder="如:摘录">
209
+ </div>
210
+ </div>
211
+
212
+ <!-- Custom CSS -->
213
+ <div class="config-section">
214
+ <div class="section-label">
215
+ <span>💻 自定义 CSS 覆盖</span>
216
+ </div>
217
+ <textarea id="input-custom-css" class="css-editor" placeholder="/* 在此处输入自定义 CSS 规则,实时生效 */&#10;h2 { letter-spacing: 0.05em; }&#10;p { text-align: justify; }"></textarea>
218
+ </div>
219
+ </div>
220
+
221
+ <!-- Tab 2: Syntax Cheatsheet -->
222
+ <div id="tab-content-syntax" class="tab-content" style="display: none;">
223
+ <div id="syntax-card-list">
224
+ <!-- Populated dynamically by studio.ts -->
225
+ </div>
226
+ </div>
227
+ </aside>
228
+
229
+ <!-- Center: Markdown Input -->
230
+ <section class="panel editor-panel">
231
+ <div class="panel-header">
232
+ <div class="panel-title">
233
+ <span>📝</span>
234
+ <span>Markdown 草稿编辑</span>
235
+ </div>
236
+ <div class="editor-toolbar">
237
+ <button id="btn-load-sample" class="btn" title="加载全语法验收用例">📄 官方测试稿</button>
238
+ <button id="btn-clear-md" class="btn" title="清空编辑器内容">🗑️ 清空</button>
239
+ </div>
240
+ </div>
241
+
242
+ <textarea id="editor-markdown" class="editor-textarea" spellcheck="false" placeholder="在此粘贴或输入 Markdown 文章内容..."></textarea>
243
+
244
+ <div class="editor-footer">
245
+ <span id="editor-stats">字数: 0 字 | 预计阅读: 1 分钟</span>
246
+ <span>实时渲染: 50ms 防抖</span>
247
+ </div>
248
+ </section>
249
+
250
+ <!-- Right: Live WeChat Viewport -->
251
+ <section class="panel preview-panel">
252
+ <div class="panel-header">
253
+ <div class="panel-title">
254
+ <span>📱</span>
255
+ <span>微信手机仿真视口 (430px)</span>
256
+ </div>
257
+ <div>
258
+ <button id="btn-toggle-view" class="btn" style="font-size: 11px;">🔍 查看 HTML 源码</button>
259
+ </div>
260
+ </div>
261
+
262
+ <div class="preview-container">
263
+ <!-- Phone Simulator Frame -->
264
+ <div class="device-frame">
265
+ <div class="device-notch-bar">
266
+ <span>9:41</span>
267
+ <span>WeChat Article</span>
268
+ <span>100% 🔋</span>
269
+ </div>
270
+ <div id="preview-screen" class="device-screen">
271
+ <!-- Injected by live renderer -->
272
+ </div>
273
+ </div>
274
+
275
+ <!-- HTML Code Viewer (Hidden by default) -->
276
+ <div id="html-source-container" style="display: none; width: 100%; margin-top: 16px;">
277
+ <textarea id="html-source-code" class="css-editor" style="height: 380px; width: 100%;" readonly></textarea>
278
+ </div>
279
+ </div>
280
+ </section>
281
+ </main>
282
+
283
+ <!-- Toast Notification -->
284
+ <div id="toast-container" class="toast-container"></div>
285
+
286
+ <!-- Hidden Milkdown Engine Mount Host -->
287
+ <div id="studio-editor-host"></div>
288
+
289
+ <!-- Studio Script -->
290
+ <script type="module" src="./studio.ts"></script>
291
+ </body>
292
+ </html>