@michelabboud/visual-forge-mcp 0.11.0 → 0.11.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michelabboud/visual-forge-mcp",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "description": "MCP server for AI image generation from markdown and HTML with multi-provider support, model testing, and automatic web optimization",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -83,6 +83,7 @@
83
83
  },
84
84
  "files": [
85
85
  "dist",
86
+ "templates",
86
87
  "config/pricing.json",
87
88
  "config/pricing-schema.json",
88
89
  "scripts/update-pricing.js",
@@ -0,0 +1,292 @@
1
+ // Visual Forge MCP - Typst Template
2
+ // A professional document template for technical documentation
3
+ //
4
+ // Usage: pandoc input.md -o output.pdf --pdf-engine=typst --template=visual-forge.typ
5
+
6
+ // ============================================================================
7
+ // Pandoc Compatibility Functions
8
+ // ============================================================================
9
+
10
+ // Blockquote function - Pandoc converts markdown > quotes to #blockquote[] calls
11
+ #let blockquote(body) = {
12
+ block(
13
+ fill: rgb("#E3F2FD"),
14
+ inset: 12pt,
15
+ radius: 4pt,
16
+ width: 100%,
17
+ stroke: (left: 3pt + rgb("#2196F3")),
18
+ body,
19
+ )
20
+ }
21
+
22
+ // ============================================================================
23
+ // Document Setup
24
+ // ============================================================================
25
+
26
+ #let visual-forge-doc(
27
+ title: none,
28
+ author: none,
29
+ date: none,
30
+ abstract: none,
31
+ logo: none,
32
+ paper: "a4",
33
+ body,
34
+ ) = {
35
+ // Page setup
36
+ set page(
37
+ paper: paper,
38
+ margin: (
39
+ top: 2.5cm,
40
+ bottom: 2.5cm,
41
+ left: 2.5cm,
42
+ right: 2.5cm,
43
+ ),
44
+ header: context {
45
+ if counter(page).get().first() > 1 [
46
+ #set text(size: 9pt, fill: rgb("#666666"))
47
+ #title
48
+ #h(1fr)
49
+ #date
50
+ #line(length: 100%, stroke: 0.5pt + rgb("#dddddd"))
51
+ ]
52
+ },
53
+ footer: context {
54
+ set text(size: 9pt, fill: rgb("#666666"))
55
+ line(length: 100%, stroke: 0.5pt + rgb("#dddddd"))
56
+ v(0.3em)
57
+ [Visual Forge MCP]
58
+ h(1fr)
59
+ [Page #counter(page).display("1 of 1", both: true)]
60
+ },
61
+ )
62
+
63
+ // Text setup
64
+ set text(
65
+ font: "Linux Libertine",
66
+ size: 11pt,
67
+ lang: "en",
68
+ )
69
+
70
+ // Paragraph setup
71
+ set par(
72
+ justify: true,
73
+ leading: 0.65em,
74
+ first-line-indent: 0em,
75
+ )
76
+
77
+ // Heading setup
78
+ set heading(numbering: "1.1")
79
+
80
+ show heading.where(level: 1): it => {
81
+ pagebreak(weak: true)
82
+ v(1em)
83
+ text(size: 20pt, weight: "bold", fill: rgb("#FF9900"))[#it]
84
+ v(0.5em)
85
+ }
86
+
87
+ show heading.where(level: 2): it => {
88
+ v(0.8em)
89
+ text(size: 16pt, weight: "bold", fill: rgb("#232F3E"))[#it]
90
+ v(0.3em)
91
+ }
92
+
93
+ show heading.where(level: 3): it => {
94
+ v(0.6em)
95
+ text(size: 13pt, weight: "bold", fill: rgb("#232F3E"))[#it]
96
+ v(0.2em)
97
+ }
98
+
99
+ // Link styling
100
+ show link: it => {
101
+ set text(fill: rgb("#146EB4"))
102
+ underline(it)
103
+ }
104
+
105
+ // Code block styling
106
+ show raw.where(block: true): it => {
107
+ set text(font: "DejaVu Sans Mono", size: 9pt)
108
+ block(
109
+ fill: rgb("#f5f5f5"),
110
+ inset: 10pt,
111
+ radius: 4pt,
112
+ width: 100%,
113
+ it,
114
+ )
115
+ }
116
+
117
+ // Inline code styling
118
+ show raw.where(block: false): it => {
119
+ set text(font: "DejaVu Sans Mono", size: 10pt)
120
+ box(
121
+ fill: rgb("#f0f0f0"),
122
+ inset: (x: 3pt, y: 0pt),
123
+ radius: 2pt,
124
+ it,
125
+ )
126
+ }
127
+
128
+ // Table styling
129
+ set table(
130
+ stroke: 0.5pt + rgb("#dddddd"),
131
+ inset: 8pt,
132
+ )
133
+
134
+ show table.cell.where(y: 0): strong
135
+
136
+ // Quote/blockquote styling
137
+ show quote: it => {
138
+ block(
139
+ fill: rgb("#E3F2FD"),
140
+ inset: 12pt,
141
+ radius: 4pt,
142
+ width: 100%,
143
+ stroke: (left: 3pt + rgb("#2196F3")),
144
+ it,
145
+ )
146
+ }
147
+
148
+ // ============================================================================
149
+ // Title Page
150
+ // ============================================================================
151
+
152
+ if title != none {
153
+ align(center)[
154
+ #v(3cm)
155
+
156
+ #if logo != none {
157
+ image(logo, width: 4cm)
158
+ v(1cm)
159
+ }
160
+
161
+ #text(size: 28pt, weight: "bold", fill: rgb("#FF9900"))[#title]
162
+
163
+ #v(1cm)
164
+
165
+ #if author != none {
166
+ text(size: 14pt)[#author]
167
+ v(0.5em)
168
+ }
169
+
170
+ #if date != none {
171
+ text(size: 12pt, fill: rgb("#666666"))[#date]
172
+ }
173
+
174
+ #v(2cm)
175
+
176
+ #if abstract != none {
177
+ align(left)[
178
+ #block(
179
+ width: 80%,
180
+ inset: 20pt,
181
+ fill: rgb("#f9f9f9"),
182
+ radius: 8pt,
183
+ )[
184
+ #text(weight: "bold")[Abstract]
185
+ #v(0.5em)
186
+ #abstract
187
+ ]
188
+ ]
189
+ }
190
+ ]
191
+
192
+ pagebreak()
193
+ }
194
+
195
+ // ============================================================================
196
+ // Table of Contents
197
+ // ============================================================================
198
+
199
+ outline(
200
+ title: [Table of Contents],
201
+ indent: 1.5em,
202
+ depth: 3,
203
+ )
204
+
205
+ pagebreak()
206
+
207
+ // ============================================================================
208
+ // Main Content
209
+ // ============================================================================
210
+
211
+ body
212
+ }
213
+
214
+ // ============================================================================
215
+ // Callout Boxes
216
+ // ============================================================================
217
+
218
+ #let tip-box(body) = {
219
+ block(
220
+ fill: rgb("#E8F5E9"),
221
+ inset: 12pt,
222
+ radius: 4pt,
223
+ width: 100%,
224
+ stroke: (left: 3pt + rgb("#4CAF50")),
225
+ )[
226
+ #text(weight: "bold", fill: rgb("#4CAF50"))[TIP]
227
+ #h(0.5em)
228
+ #body
229
+ ]
230
+ }
231
+
232
+ #let warning-box(body) = {
233
+ block(
234
+ fill: rgb("#FFF8E1"),
235
+ inset: 12pt,
236
+ radius: 4pt,
237
+ width: 100%,
238
+ stroke: (left: 3pt + rgb("#FF9800")),
239
+ )[
240
+ #text(weight: "bold", fill: rgb("#FF9800"))[WARNING]
241
+ #h(0.5em)
242
+ #body
243
+ ]
244
+ }
245
+
246
+ #let note-box(body) = {
247
+ block(
248
+ fill: rgb("#E3F2FD"),
249
+ inset: 12pt,
250
+ radius: 4pt,
251
+ width: 100%,
252
+ stroke: (left: 3pt + rgb("#2196F3")),
253
+ )[
254
+ #text(weight: "bold", fill: rgb("#2196F3"))[NOTE]
255
+ #h(0.5em)
256
+ #body
257
+ ]
258
+ }
259
+
260
+ #let alert-box(body) = {
261
+ block(
262
+ fill: rgb("#FFEBEE"),
263
+ inset: 12pt,
264
+ radius: 4pt,
265
+ width: 100%,
266
+ stroke: (left: 3pt + rgb("#F44336")),
267
+ )[
268
+ #text(weight: "bold", fill: rgb("#F44336"))[ALERT]
269
+ #h(0.5em)
270
+ #body
271
+ ]
272
+ }
273
+
274
+ // ============================================================================
275
+ // Pandoc Template Variables
276
+ // ============================================================================
277
+
278
+ // This section handles Pandoc template variables
279
+ // When used with: pandoc input.md -o output.pdf --pdf-engine=typst --template=this-file.typ
280
+
281
+ $if(title)$
282
+ #show: visual-forge-doc.with(
283
+ title: [$title$],
284
+ $if(author)$author: [$author$],$endif$
285
+ $if(date)$date: [$date$],$endif$
286
+ $if(abstract)$abstract: [$abstract$],$endif$
287
+ )
288
+ $else$
289
+ #show: visual-forge-doc.with()
290
+ $endif$
291
+
292
+ $body$