artifactuse 0.2.0 → 0.2.3

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.
@@ -131,6 +131,40 @@ function getLanguageDisplayName(language) {
131
131
  form: 'Form',
132
132
  social: 'Social Preview',
133
133
  txt: 'Plain Text',
134
+ plaintext: 'Plain Text',
135
+ text: 'Plain Text',
136
+ less: 'Less',
137
+ sass: 'Sass',
138
+ scss: 'SCSS',
139
+ lua: 'Lua',
140
+ perl: 'Perl',
141
+ pl: 'Perl',
142
+ r: 'R',
143
+ dart: 'Dart',
144
+ elixir: 'Elixir',
145
+ ex: 'Elixir',
146
+ haskell: 'Haskell',
147
+ hs: 'Haskell',
148
+ clojure: 'Clojure',
149
+ clj: 'Clojure',
150
+ erlang: 'Erlang',
151
+ erl: 'Erlang',
152
+ objectivec: 'Objective-C',
153
+ objc: 'Objective-C',
154
+ m: 'Objective-C',
155
+ toml: 'TOML',
156
+ ini: 'INI',
157
+ env: 'Environment',
158
+ makefile: 'Makefile',
159
+ cmake: 'CMake',
160
+ terraform: 'Terraform',
161
+ tf: 'Terraform',
162
+ hcl: 'HCL',
163
+ protobuf: 'Protocol Buffers',
164
+ proto: 'Protocol Buffers',
165
+ zig: 'Zig',
166
+ nim: 'Nim',
167
+ v: 'V',
134
168
  };
135
169
  return names[language?.toLowerCase()] || language?.toUpperCase() || 'Code';
136
170
  }
@@ -180,6 +214,41 @@ function getFileExtension$1(language) {
180
214
  svg: 'svg',
181
215
  form: 'json',
182
216
  social: 'json',
217
+ txt: 'txt',
218
+ plaintext: 'txt',
219
+ text: 'txt',
220
+ less: 'less',
221
+ sass: 'sass',
222
+ scss: 'scss',
223
+ lua: 'lua',
224
+ perl: 'pl',
225
+ pl: 'pl',
226
+ r: 'r',
227
+ dart: 'dart',
228
+ elixir: 'ex',
229
+ ex: 'ex',
230
+ haskell: 'hs',
231
+ hs: 'hs',
232
+ clojure: 'clj',
233
+ clj: 'clj',
234
+ erlang: 'erl',
235
+ erl: 'erl',
236
+ objectivec: 'm',
237
+ objc: 'm',
238
+ m: 'm',
239
+ toml: 'toml',
240
+ ini: 'ini',
241
+ env: 'env',
242
+ makefile: 'mk',
243
+ cmake: 'cmake',
244
+ terraform: 'tf',
245
+ tf: 'tf',
246
+ hcl: 'hcl',
247
+ protobuf: 'proto',
248
+ proto: 'proto',
249
+ zig: 'zig',
250
+ nim: 'nim',
251
+ v: 'v',
183
252
  };
184
253
  return extensions[language?.toLowerCase()] || 'txt';
185
254
  }
@@ -217,6 +286,30 @@ function getLanguageFromExtension(ext) {
217
286
  svg: 'svg',
218
287
  diff: 'diff',
219
288
  patch: 'patch',
289
+ txt: 'txt',
290
+ less: 'less',
291
+ sass: 'sass',
292
+ scss: 'scss',
293
+ lua: 'lua',
294
+ pl: 'perl',
295
+ r: 'r',
296
+ dart: 'dart',
297
+ ex: 'elixir',
298
+ exs: 'elixir',
299
+ hs: 'haskell',
300
+ clj: 'clojure',
301
+ erl: 'erlang',
302
+ m: 'objectivec',
303
+ toml: 'toml',
304
+ ini: 'ini',
305
+ env: 'env',
306
+ cmake: 'cmake',
307
+ tf: 'terraform',
308
+ hcl: 'hcl',
309
+ proto: 'proto',
310
+ zig: 'zig',
311
+ nim: 'nim',
312
+ v: 'v',
220
313
  };
221
314
  return map[ext?.toLowerCase()] || null;
222
315
  }
@@ -259,9 +352,71 @@ function getLanguageIcon(language) {
259
352
  timeline: '<line x1="2" y1="12" x2="22" y2="12"/><circle cx="6" cy="12" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="18" cy="12" r="2"/>',
260
353
  form: '<path d="M4 4h16v2H4V4zm0 4h10v2H4V8zm0 4h16v2H4v-2zm0 4h10v2H4v-2z"/><rect x="16" y="8" width="4" height="4" rx="1"/><rect x="16" y="16" width="4" height="4" rx="1"/>',
261
354
  social: '<path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/>',
355
+ // Languages with display names that were missing icons
356
+ java: '<path d="M8.851 18.56s-.917.534.653.714c1.902.218 2.874.187 4.969-.211 0 0 .552.346 1.321.646-4.699 2.013-10.633-.118-6.943-1.149m-.575-2.627s-1.028.761.542.924c2.032.209 3.636.227 6.413-.308 0 0 .384.389.987.602-5.679 1.661-12.007.13-7.942-1.218m4.84-4.458c1.158 1.333-.304 2.533-.304 2.533s2.939-1.518 1.589-3.418c-1.261-1.772-2.228-2.652 3.007-5.688 0 0-8.216 2.051-4.292 6.573"/><path d="M16.205 20.196s.678.559-.747.991c-2.712.822-11.288 1.069-13.669.033-.856-.373.75-.89 1.254-.998.527-.114.828-.093.828-.093-.953-.671-6.156 1.317-2.643 1.887 9.58 1.553 17.462-.7 14.977-1.82M9.6 13.116s-4.362 1.036-1.544 1.412c1.189.159 3.561.123 5.77-.062 1.806-.152 3.618-.477 3.618-.477s-.637.272-1.098.587c-4.429 1.165-12.986.623-10.522-.568 2.082-1.006 3.776-.892 3.776-.892m7.816 4.368c4.502-2.34 2.421-4.589.968-4.285-.356.075-.515.14-.515.14s.132-.207.385-.296c2.874-1.01 5.086 2.981-.928 4.562 0 0 .07-.062.09-.121"/>',
357
+ c: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/><path d="M10.5 7.5C8.01 7.5 6 9.51 6 12s2.01 4.5 4.5 4.5c1.74 0 3.26-1 4-2.5h-2.18c-.5.63-1.27 1-2.12 1A2.75 2.75 0 0 1 7.5 12a2.75 2.75 0 0 1 2.7-2.5c.85 0 1.62.37 2.12 1h2.18c-.74-1.5-2.26-2.5-4-2.5z"/>',
358
+ cpp: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/><path d="M9.5 7.5C7.01 7.5 5 9.51 5 12s2.01 4.5 4.5 4.5c1.74 0 3.26-1 4-2.5h-2.18c-.5.63-1.27 1-2.12 1A2.75 2.75 0 0 1 6.5 12 2.75 2.75 0 0 1 9.2 9.5c.85 0 1.62.37 2.12 1h2.18c-.74-1.5-2.26-2.5-4-2.5z"/><path d="M16 11h1v-1h1v1h1v1h-1v1h-1v-1h-1zm-3 0h1v-1h1v1h1v1h-1v1h-1v-1h-1z"/>',
359
+ csharp: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/><path d="M9.5 7.5C7.01 7.5 5 9.51 5 12s2.01 4.5 4.5 4.5c1.74 0 3.26-1 4-2.5h-2.18c-.5.63-1.27 1-2.12 1A2.75 2.75 0 0 1 6.5 12 2.75 2.75 0 0 1 9.2 9.5c.85 0 1.62.37 2.12 1h2.18c-.74-1.5-2.26-2.5-4-2.5z"/><path d="M16.5 10.5h-1v-1h-1v1h-1v1h1v1h1v-1h1zM16.5 13.5h-1v-1h-1v1h-1v1h1v1h1v-1h1z"/>',
360
+ cs: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/><path d="M9.5 7.5C7.01 7.5 5 9.51 5 12s2.01 4.5 4.5 4.5c1.74 0 3.26-1 4-2.5h-2.18c-.5.63-1.27 1-2.12 1A2.75 2.75 0 0 1 6.5 12 2.75 2.75 0 0 1 9.2 9.5c.85 0 1.62.37 2.12 1h2.18c-.74-1.5-2.26-2.5-4-2.5z"/><path d="M16.5 10.5h-1v-1h-1v1h-1v1h1v1h1v-1h1zM16.5 13.5h-1v-1h-1v1h-1v1h1v1h1v-1h1z"/>',
361
+ go: '<path d="M3.5 10.83s-.1-.16.06-.21c0 0 2.61-1.05 5.25-1.05h.2c2.64 0 5.25 1.05 5.25 1.05.16.05.06.21.06.21"/><path d="M4.3 11.2c-.15 0-.15-.23 0-.23h4.96c.15 0 .15.23 0 .23H4.3z"/><ellipse cx="6.27" cy="10" rx=".35" ry=".4"/><path d="M14.26 10.83s-.1-.16.06-.21c0 0 1.61-.65 3.25-.65h.2c1.64 0 3.25.65 3.25.65.16.05.06.21.06.21"/><path d="M14.85 11.2c-.15 0-.15-.23 0-.23h4.26c.15 0 .15.23 0 .23h-4.26z"/><ellipse cx="16.57" cy="10" rx=".35" ry=".4"/><path d="M8.98 15.53c-2.6 0-4.72-1.68-4.72-3.75 0-2.07 2.12-3.75 4.72-3.75s4.72 1.68 4.72 3.75-2.12 3.75-4.72 3.75z" fill="none" stroke="currentColor" stroke-width="1"/>',
362
+ rust: '<path d="M12 2l1.09 3.41L15 3.5l-.47 3.53 2.97-1.87-.94 3.42 3.54.16-2.7 2.27 3.15 1.63-3.38.86 2.13 2.87-3.47-.57.78 3.45-3.05-1.73L12 21l-1.56-3.07-3.05 1.73.78-3.45-3.47.57 2.13-2.87-3.38-.86 3.15-1.63L3.9 9.15l3.54-.16-.94-3.42 2.97 1.87L9 3.5l1.91 1.91L12 2z" fill="none" stroke="currentColor" stroke-width="1.2"/><circle cx="12" cy="12" r="3" fill="none" stroke="currentColor" stroke-width="1.2"/>',
363
+ ruby: '<path d="M5.5 18.5L3 14l3-9 4-2h4l4 2 3 9-2.5 4.5L12 21l-6.5-2.5z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M12 3v18M3 14h18M6 5l12 14M18 5L6 19" fill="none" stroke="currentColor" stroke-width=".8"/>',
364
+ rb: '<path d="M5.5 18.5L3 14l3-9 4-2h4l4 2 3 9-2.5 4.5L12 21l-6.5-2.5z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M12 3v18M3 14h18M6 5l12 14M18 5L6 19" fill="none" stroke="currentColor" stroke-width=".8"/>',
365
+ php: '<ellipse cx="12" cy="12" rx="10" ry="6" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M7 9.5h2a1.5 1.5 0 0 1 0 3H8v2M12.5 9.5h2a1.5 1.5 0 0 1 0 3H13.5v2M17 9.5v5"/>',
366
+ swift: '<path d="M20.5 8c.3-1.7-.4-3.6-1.8-5-.5 2.1-1.8 3.7-3.5 4.8C12.6 5.5 9.4 3.3 6 2c.9 1.5 1.7 3 2.3 4.5C5.3 4.4 3 3 3 3s1.3 3.5 4 6.3C5.2 9 3.5 8.6 2 8c1.1 1.8 2.7 3.2 4.5 4.2-.7.2-1.5.3-2.5.3 1.5 1.5 3.5 2.5 5.5 2.5-2 2-5 3-8 3 3.5 2 7.5 3 11 1.5 5-2.2 7.5-7.5 7.5-11.5z"/>',
367
+ kotlin: '<path d="M3 3h18v18H3V3z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M3 3l9 9L3 21M12 3l9 9-9 9"/>',
368
+ scala: '<path d="M4 4c0 0 8 1 16 1v5c-8 0-16-1-16-1V4z"/><path d="M4 10c0 0 8 1 16 1v5c-8 0-16-1-16-1V10z"/><path d="M4 16c0 0 8 1 16 1v4c-8 0-16-1-16-1V16z"/>',
369
+ powershell: '<path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2m0 2v12h16V6H4m2 2l5 3.5L6 15m6 0h5"/>',
370
+ ps1: '<path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2m0 2v12h16V6H4m2 2l5 3.5L6 15m6 0h5"/>',
371
+ xml: '<path d="M7 4l-4 8 4 8M17 4l4 8-4 8M14 4l-4 16"/>',
372
+ yaml: '<path d="M3 4l4.5 5.5L12 4M12 4l4.5 5.5L21 4M12 9.5V20M3 12h18" fill="none" stroke="currentColor" stroke-width="1.5"/>',
373
+ yml: '<path d="M3 4l4.5 5.5L12 4M12 4l4.5 5.5L21 4M12 9.5V20M3 12h18" fill="none" stroke="currentColor" stroke-width="1.5"/>',
374
+ graphql: '<circle cx="12" cy="4" r="1.5"/><circle cx="5" cy="8" r="1.5"/><circle cx="19" cy="8" r="1.5"/><circle cx="5" cy="16" r="1.5"/><circle cx="19" cy="16" r="1.5"/><circle cx="12" cy="20" r="1.5"/><path d="M5.5 8.5l6.5 11M12.5 4.5l6 3.5M5.5 8l13 0M5.5 16l13 0M18 16.5l-6 3.5M5.5 16l6.5-12" fill="none" stroke="currentColor" stroke-width="1"/>',
375
+ dockerfile: '<path d="M2 12.5h3v-3h3v-3h3V3.5h3v3h3v3h1.5a2.5 2.5 0 0 1 0 5H2v-2z"/><path d="M5 9.5h2v2H5zM8 9.5h2v2H8zM8 6.5h2v2H8zM11 6.5h2v2h-2zM11 9.5h2v2h-2zM14 9.5h2v2h-2zM11 3.5h2v2h-2z"/>',
376
+ docker: '<path d="M2 12.5h3v-3h3v-3h3V3.5h3v3h3v3h1.5a2.5 2.5 0 0 1 0 5H2v-2z"/><path d="M5 9.5h2v2H5zM8 9.5h2v2H8zM8 6.5h2v2H8zM11 6.5h2v2h-2zM11 9.5h2v2h-2zM14 9.5h2v2h-2zM11 3.5h2v2h-2z"/>',
377
+ // CSS preprocessors
378
+ less: '<path d="M5 3l.65 3.34h12.59l-.44 2.16H6.11l.65 3.34h11.04l-.78 3.86-5.02 1.67-4.96-1.67-.33-1.69H4.38l.65 3.35L12 19.31l7.02-2.31L20.93 3H5z"/>',
379
+ sass: '<path d="M5 3l.65 3.34h12.59l-.44 2.16H6.11l.65 3.34h11.04l-.78 3.86-5.02 1.67-4.96-1.67-.33-1.69H4.38l.65 3.35L12 19.31l7.02-2.31L20.93 3H5z"/>',
380
+ scss: '<path d="M5 3l.65 3.34h12.59l-.44 2.16H6.11l.65 3.34h11.04l-.78 3.86-5.02 1.67-4.96-1.67-.33-1.69H4.38l.65 3.35L12 19.31l7.02-2.31L20.93 3H5z"/>',
381
+ // New languages
382
+ lua: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z" fill="none" stroke="currentColor" stroke-width="1.5"/><circle cx="12" cy="12" r="4" fill="none" stroke="currentColor" stroke-width="1.5"/><circle cx="18" cy="5" r="2"/>',
383
+ perl: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M9 8v8M9 12h3a2 2 0 1 0 0-4H9"/>',
384
+ pl: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M9 8v8M9 12h3a2 2 0 1 0 0-4H9"/>',
385
+ r: '<path d="M3 5h14a4 4 0 0 1 4 4v0a4 4 0 0 1-4 4H3V5z" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M3 5v14M13 13l5 6" fill="none" stroke="currentColor" stroke-width="1.5"/>',
386
+ dart: '<path d="M4 12L2 6l4-4h6l10 10-6 10H8l-4-4v-6z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M6 2l16 10M2 6l10 16"/>',
387
+ elixir: '<path d="M12 2c-3 4-6 8-6 13a6 6 0 0 0 12 0c0-5-3-9-6-13z" fill="none" stroke="currentColor" stroke-width="1.5"/><ellipse cx="12" cy="16" rx="3" ry="2" fill="none" stroke="currentColor" stroke-width="1"/>',
388
+ ex: '<path d="M12 2c-3 4-6 8-6 13a6 6 0 0 0 12 0c0-5-3-9-6-13z" fill="none" stroke="currentColor" stroke-width="1.5"/><ellipse cx="12" cy="16" rx="3" ry="2" fill="none" stroke="currentColor" stroke-width="1"/>',
389
+ haskell: '<path d="M2 4l5 8-5 8M7 4l5 8-5 8" fill="none" stroke="currentColor" stroke-width="2"/><path d="M12 8l2 4-2 4M14 10h8M14 14h8" fill="none" stroke="currentColor" stroke-width="1.5"/>',
390
+ hs: '<path d="M2 4l5 8-5 8M7 4l5 8-5 8" fill="none" stroke="currentColor" stroke-width="2"/><path d="M12 8l2 4-2 4M14 10h8M14 14h8" fill="none" stroke="currentColor" stroke-width="1.5"/>',
391
+ clojure: '<circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M8 6a7.5 7.5 0 0 0 0 12M16 6a7.5 7.5 0 0 1 0 12"/>',
392
+ clj: '<circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M8 6a7.5 7.5 0 0 0 0 12M16 6a7.5 7.5 0 0 1 0 12"/>',
393
+ erlang: '<path d="M4 18c2-1.5 3-4 3-6s-1-4.5-3-6M20 18c-3-1-5.5-3.5-5.5-6S17 5.5 20 6" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M4 12h16" fill="none" stroke="currentColor" stroke-width="1.5"/>',
394
+ erl: '<path d="M4 18c2-1.5 3-4 3-6s-1-4.5-3-6M20 18c-3-1-5.5-3.5-5.5-6S17 5.5 20 6" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M4 12h16" fill="none" stroke="currentColor" stroke-width="1.5"/>',
395
+ objectivec: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/><path d="M10.5 7.5C8.01 7.5 6 9.51 6 12s2.01 4.5 4.5 4.5c1.74 0 3.26-1 4-2.5h-2.18c-.5.63-1.27 1-2.12 1A2.75 2.75 0 0 1 7.5 12a2.75 2.75 0 0 1 2.7-2.5c.85 0 1.62.37 2.12 1h2.18c-.74-1.5-2.26-2.5-4-2.5z"/>',
396
+ objc: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/><path d="M10.5 7.5C8.01 7.5 6 9.51 6 12s2.01 4.5 4.5 4.5c1.74 0 3.26-1 4-2.5h-2.18c-.5.63-1.27 1-2.12 1A2.75 2.75 0 0 1 7.5 12a2.75 2.75 0 0 1 2.7-2.5c.85 0 1.62.37 2.12 1h2.18c-.74-1.5-2.26-2.5-4-2.5z"/>',
397
+ m: '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/><path d="M10.5 7.5C8.01 7.5 6 9.51 6 12s2.01 4.5 4.5 4.5c1.74 0 3.26-1 4-2.5h-2.18c-.5.63-1.27 1-2.12 1A2.75 2.75 0 0 1 7.5 12a2.75 2.75 0 0 1 2.7-2.5c.85 0 1.62.37 2.12 1h2.18c-.74-1.5-2.26-2.5-4-2.5z"/>',
398
+ // Config/build files
399
+ toml: '<path d="M3 3h18v18H3V3z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M7 7h10M7 11h7M7 15h10"/>',
400
+ ini: '<path d="M3 3h18v18H3V3z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M7 7h10M7 11h7M7 15h10"/>',
401
+ env: '<path d="M3 3h18v18H3V3z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M7 7h10M7 11h7M7 15h10"/>',
402
+ makefile: '<path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2m0 2v12h16V6H4m2 2l4 3-4 3V8m5 5h5v2h-5v-2z"/>',
403
+ cmake: '<path d="M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2m0 2v12h16V6H4m2 2l4 3-4 3V8m5 5h5v2h-5v-2z"/>',
404
+ terraform: '<path d="M1 5l7 4v8l-7-4V5zM9 1l7 4v8l-7-4V1zM9 13l7 4v8l-7-4v-8zM17 5l7 4v8l-7-4V5z"/>',
405
+ tf: '<path d="M1 5l7 4v8l-7-4V5zM9 1l7 4v8l-7-4V1zM9 13l7 4v8l-7-4v-8zM17 5l7 4v8l-7-4V5z"/>',
406
+ hcl: '<path d="M1 5l7 4v8l-7-4V5zM9 1l7 4v8l-7-4V1zM9 13l7 4v8l-7-4v-8zM17 5l7 4v8l-7-4V5z"/>',
407
+ protobuf: '<path d="M4 4h16v16H4V4z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M8 8h8M8 12h5M8 16h8"/>',
408
+ proto: '<path d="M4 4h16v16H4V4z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M8 8h8M8 12h5M8 16h8"/>',
409
+ zig: '<path d="M2 6h7l-5 12h7l5-12h7l-5 12h7" fill="none" stroke="currentColor" stroke-width="1.5"/>',
410
+ nim: '<path d="M12 2l3 5h5l-3 5 3 5h-5l-3 5-3-5H4l3-5-3-5h5l3-5z" fill="none" stroke="currentColor" stroke-width="1.2"/>',
411
+ v: '<path d="M4 4l8 16 8-16" fill="none" stroke="currentColor" stroke-width="2"/>',
412
+ // Text/document icon
413
+ txt: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/>',
414
+ plaintext: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/>',
415
+ text: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/>',
262
416
  };
263
-
264
- const defaultIcon = '<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>';
417
+
418
+ // Text/document fallback for unknown extensions
419
+ const defaultIcon = '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/>';
265
420
  return icons[language?.toLowerCase()] || defaultIcon;
266
421
  }
267
422
 
@@ -739,11 +894,16 @@ function createState() {
739
894
  isPanelOpen: false,
740
895
  viewMode: 'preview', // 'preview' | 'code' | 'split'
741
896
  isFullscreen: false,
897
+ // Multi-tab support
898
+ openTabs: [], // Array of artifact IDs open as tabs (ordered)
899
+ tabViewModes: {}, // { [artifactId]: 'preview' | 'code' | 'split' | 'edit' }
900
+ // Panel empty view
901
+ forceEmptyView: false, // When true, panel shows empty state regardless of artifacts
742
902
  };
743
-
903
+
744
904
  // Subscribers
745
905
  const subscribers = new Set();
746
-
906
+
747
907
  /**
748
908
  * Notify all subscribers of state change
749
909
  */
@@ -756,35 +916,35 @@ function createState() {
756
916
  }
757
917
  });
758
918
  }
759
-
919
+
760
920
  /**
761
921
  * Subscribe to state changes
762
922
  */
763
923
  function subscribe(callback) {
764
924
  subscribers.add(callback);
765
-
925
+
766
926
  // Call immediately with current state
767
927
  callback(state);
768
-
928
+
769
929
  // Return unsubscribe function
770
930
  return () => {
771
931
  subscribers.delete(callback);
772
932
  };
773
933
  }
774
-
934
+
775
935
  /**
776
936
  * Get current state (immutable copy)
777
937
  */
778
938
  function getState() {
779
939
  return { ...state };
780
940
  }
781
-
941
+
782
942
  /**
783
943
  * Add artifact
784
944
  */
785
945
  function addArtifact(artifact) {
786
946
  const existingIndex = state.artifacts.findIndex(a => a.id === artifact.id);
787
-
947
+
788
948
  if (existingIndex === -1) {
789
949
  state = {
790
950
  ...state,
@@ -799,38 +959,43 @@ function createState() {
799
959
  artifacts: newArtifacts,
800
960
  };
801
961
  }
802
-
962
+
803
963
  notify();
804
964
  }
805
-
965
+
806
966
  /**
807
967
  * Add multiple artifacts
808
968
  */
809
969
  function addArtifacts(artifacts) {
810
970
  artifacts.forEach(addArtifact);
811
971
  }
812
-
972
+
813
973
  /**
814
974
  * Remove artifact
815
975
  */
816
976
  function removeArtifact(artifactId) {
977
+ const newTabs = state.openTabs.filter(id => id !== artifactId);
978
+ const { [artifactId]: _, ...remainingViewModes } = state.tabViewModes;
979
+
817
980
  state = {
818
981
  ...state,
819
982
  artifacts: state.artifacts.filter(a => a.id !== artifactId),
820
983
  activeArtifactId: state.activeArtifactId === artifactId ? null : state.activeArtifactId,
821
984
  isPanelOpen: state.activeArtifactId === artifactId ? false : state.isPanelOpen,
985
+ openTabs: newTabs,
986
+ tabViewModes: remainingViewModes,
822
987
  };
823
-
988
+
824
989
  notify();
825
990
  }
826
-
991
+
827
992
  /**
828
993
  * Get artifact by ID
829
994
  */
830
995
  function getArtifact(artifactId) {
831
996
  return state.artifacts.find(a => a.id === artifactId) || null;
832
997
  }
833
-
998
+
834
999
  /**
835
1000
  * Get active artifact
836
1001
  */
@@ -838,27 +1003,32 @@ function createState() {
838
1003
  if (!state.activeArtifactId) return null;
839
1004
  return getArtifact(state.activeArtifactId);
840
1005
  }
841
-
1006
+
842
1007
  /**
843
1008
  * Set active artifact
844
1009
  */
845
1010
  function setActiveArtifact(artifactId) {
846
1011
  const artifact = getArtifact(artifactId);
847
1012
 
848
- let viewMode = artifact?.isPreviewable === false ? 'code' : 'preview';
849
- if (artifact?.tabs && !artifact.tabs.includes(viewMode)) {
850
- viewMode = artifact.tabs[0];
1013
+ // Try tab-specific viewMode first, then compute from artifact
1014
+ let viewMode = state.tabViewModes[artifactId];
1015
+ if (!viewMode) {
1016
+ viewMode = artifact?.isPreviewable === false ? 'code' : 'preview';
1017
+ if (artifact?.tabs && !artifact.tabs.includes(viewMode)) {
1018
+ viewMode = artifact.tabs[0];
1019
+ }
851
1020
  }
852
1021
 
853
1022
  state = {
854
1023
  ...state,
855
1024
  activeArtifactId: artifactId,
856
1025
  viewMode,
1026
+ forceEmptyView: false,
857
1027
  };
858
1028
 
859
1029
  notify();
860
1030
  }
861
-
1031
+
862
1032
  /**
863
1033
  * Clear active artifact (return to list view)
864
1034
  */
@@ -867,10 +1037,10 @@ function createState() {
867
1037
  ...state,
868
1038
  activeArtifactId: null,
869
1039
  };
870
-
1040
+
871
1041
  notify();
872
1042
  }
873
-
1043
+
874
1044
  /**
875
1045
  * Set panel open state
876
1046
  */
@@ -880,10 +1050,10 @@ function createState() {
880
1050
  isPanelOpen: isOpen,
881
1051
  isFullscreen: isOpen ? state.isFullscreen : false,
882
1052
  };
883
-
1053
+
884
1054
  notify();
885
1055
  }
886
-
1056
+
887
1057
  /**
888
1058
  * Set view mode
889
1059
  */
@@ -892,15 +1062,21 @@ function createState() {
892
1062
  console.warn(`Invalid view mode: ${mode}`);
893
1063
  return;
894
1064
  }
895
-
1065
+
1066
+ // Also store per-tab viewMode for the active artifact
1067
+ const newTabViewModes = state.activeArtifactId
1068
+ ? { ...state.tabViewModes, [state.activeArtifactId]: mode }
1069
+ : state.tabViewModes;
1070
+
896
1071
  state = {
897
1072
  ...state,
898
1073
  viewMode: mode,
1074
+ tabViewModes: newTabViewModes,
899
1075
  };
900
-
1076
+
901
1077
  notify();
902
1078
  }
903
-
1079
+
904
1080
  /**
905
1081
  * Set fullscreen state
906
1082
  */
@@ -909,31 +1085,141 @@ function createState() {
909
1085
  ...state,
910
1086
  isFullscreen,
911
1087
  };
912
-
1088
+
913
1089
  notify();
914
1090
  }
915
-
1091
+
1092
+ /**
1093
+ * Set force empty view state
1094
+ */
1095
+ function setForceEmptyView(value) {
1096
+ state = {
1097
+ ...state,
1098
+ forceEmptyView: !!value,
1099
+ };
1100
+ notify();
1101
+ }
1102
+
916
1103
  /**
917
1104
  * Get artifacts by message ID
918
1105
  */
919
1106
  function getArtifactsByMessageId(messageId) {
920
1107
  return state.artifacts.filter(a => a.messageId === messageId);
921
1108
  }
922
-
1109
+
923
1110
  /**
924
1111
  * Get artifacts by type
925
1112
  */
926
1113
  function getArtifactsByType(type) {
927
1114
  return state.artifacts.filter(a => a.type === type);
928
1115
  }
929
-
1116
+
930
1117
  /**
931
1118
  * Get artifact count
932
1119
  */
933
1120
  function getArtifactCount() {
934
1121
  return state.artifacts.length;
935
1122
  }
936
-
1123
+
1124
+ // ============================================
1125
+ // Multi-tab methods
1126
+ // ============================================
1127
+
1128
+ /**
1129
+ * Open artifact in a new tab (or focus if already open)
1130
+ */
1131
+ function openTab(artifactId) {
1132
+ const artifact = getArtifact(artifactId);
1133
+ if (!artifact) return;
1134
+
1135
+ const alreadyOpen = state.openTabs.includes(artifactId);
1136
+ const newTabs = alreadyOpen ? state.openTabs : [...state.openTabs, artifactId];
1137
+
1138
+ // Determine view mode for this tab
1139
+ let viewMode = state.tabViewModes[artifactId];
1140
+ if (!viewMode) {
1141
+ viewMode = artifact.isPreviewable === false ? 'code' : 'preview';
1142
+ if (artifact.tabs && !artifact.tabs.includes(viewMode)) {
1143
+ viewMode = artifact.tabs[0];
1144
+ }
1145
+ }
1146
+
1147
+ state = {
1148
+ ...state,
1149
+ openTabs: newTabs,
1150
+ activeArtifactId: artifactId,
1151
+ tabViewModes: { ...state.tabViewModes, [artifactId]: viewMode },
1152
+ viewMode,
1153
+ };
1154
+ notify();
1155
+ }
1156
+
1157
+ /**
1158
+ * Close a tab
1159
+ */
1160
+ function closeTab(artifactId) {
1161
+ const idx = state.openTabs.indexOf(artifactId);
1162
+ if (idx === -1) return;
1163
+
1164
+ const newTabs = state.openTabs.filter(id => id !== artifactId);
1165
+ const { [artifactId]: _, ...remainingViewModes } = state.tabViewModes;
1166
+
1167
+ // If closing the active tab, switch to adjacent
1168
+ let newActiveId = state.activeArtifactId;
1169
+ if (state.activeArtifactId === artifactId) {
1170
+ if (newTabs.length === 0) {
1171
+ newActiveId = null;
1172
+ } else if (idx >= newTabs.length) {
1173
+ newActiveId = newTabs[newTabs.length - 1];
1174
+ } else {
1175
+ newActiveId = newTabs[idx];
1176
+ }
1177
+ }
1178
+
1179
+ const newViewMode = newActiveId ? (remainingViewModes[newActiveId] || 'preview') : 'preview';
1180
+
1181
+ state = {
1182
+ ...state,
1183
+ openTabs: newTabs,
1184
+ activeArtifactId: newActiveId,
1185
+ tabViewModes: remainingViewModes,
1186
+ viewMode: newViewMode,
1187
+ };
1188
+ notify();
1189
+ }
1190
+
1191
+ /**
1192
+ * Close all tabs except one
1193
+ */
1194
+ function closeOtherTabs(keepArtifactId) {
1195
+ const artifact = getArtifact(keepArtifactId);
1196
+ if (!artifact) return;
1197
+
1198
+ const viewMode = state.tabViewModes[keepArtifactId] || state.viewMode;
1199
+
1200
+ state = {
1201
+ ...state,
1202
+ openTabs: [keepArtifactId],
1203
+ activeArtifactId: keepArtifactId,
1204
+ tabViewModes: { [keepArtifactId]: viewMode },
1205
+ viewMode,
1206
+ };
1207
+ notify();
1208
+ }
1209
+
1210
+ /**
1211
+ * Close all tabs
1212
+ */
1213
+ function closeAllTabs() {
1214
+ state = {
1215
+ ...state,
1216
+ openTabs: [],
1217
+ activeArtifactId: null,
1218
+ tabViewModes: {},
1219
+ };
1220
+ notify();
1221
+ }
1222
+
937
1223
  /**
938
1224
  * Clear all state
939
1225
  */
@@ -944,47 +1230,50 @@ function createState() {
944
1230
  isPanelOpen: false,
945
1231
  viewMode: 'preview',
946
1232
  isFullscreen: false,
1233
+ openTabs: [],
1234
+ tabViewModes: {},
1235
+ forceEmptyView: false,
947
1236
  };
948
-
1237
+
949
1238
  notify();
950
1239
  }
951
-
1240
+
952
1241
  /**
953
1242
  * Batch update (for performance)
954
1243
  */
955
1244
  function batch(updateFn) {
956
1245
  const oldNotify = notify;
957
1246
  let notifyPending = false;
958
-
1247
+
959
1248
  // Suppress notifications during batch
960
1249
  const suppressedNotify = () => {
961
1250
  notifyPending = true;
962
1251
  };
963
-
1252
+
964
1253
  try {
965
1254
  // Replace notify temporarily
966
1255
  Object.defineProperty(window, '__artifactuse_notify__', {
967
1256
  value: suppressedNotify,
968
1257
  configurable: true,
969
1258
  });
970
-
1259
+
971
1260
  updateFn();
972
1261
  } finally {
973
1262
  delete window.__artifactuse_notify__;
974
-
1263
+
975
1264
  // Notify once at end if needed
976
1265
  if (notifyPending) {
977
1266
  oldNotify();
978
1267
  }
979
1268
  }
980
1269
  }
981
-
1270
+
982
1271
  // Public API
983
1272
  return {
984
1273
  // State access
985
1274
  getState,
986
1275
  subscribe,
987
-
1276
+
988
1277
  // Artifacts
989
1278
  addArtifact,
990
1279
  addArtifacts,
@@ -994,14 +1283,21 @@ function createState() {
994
1283
  getArtifactsByMessageId,
995
1284
  getArtifactsByType,
996
1285
  getArtifactCount,
997
-
1286
+
998
1287
  // Panel state
999
1288
  setActiveArtifact,
1000
1289
  clearActiveArtifact,
1001
1290
  setPanelOpen,
1002
1291
  setViewMode,
1003
1292
  setFullscreen,
1004
-
1293
+ setForceEmptyView,
1294
+
1295
+ // Multi-tab
1296
+ openTab,
1297
+ closeTab,
1298
+ closeOtherTabs,
1299
+ closeAllTabs,
1300
+
1005
1301
  // Utilities
1006
1302
  clear,
1007
1303
  batch,
@@ -6543,6 +6839,9 @@ const DEFAULT_CONFIG = {
6543
6839
  // Can be overridden per-component via props
6544
6840
  splitPosition: 50,
6545
6841
 
6842
+ // Enable multi-tab mode (open multiple artifacts as tabs)
6843
+ multiTab: false,
6844
+
6546
6845
  // Panel configuration
6547
6846
  // Users can add/override/disable panels here
6548
6847
  //
@@ -7048,7 +7347,13 @@ function createArtifactuse(userConfig = {}) {
7048
7347
  return;
7049
7348
  }
7050
7349
 
7051
- state.setActiveArtifact(artifact.id);
7350
+ if (config.multiTab) {
7351
+ state.openTab(artifact.id);
7352
+ } else {
7353
+ state.setActiveArtifact(artifact.id);
7354
+ }
7355
+
7356
+ state.setForceEmptyView(false);
7052
7357
  state.setPanelOpen(true);
7053
7358
  if (artifact.viewMode) {
7054
7359
  state.setViewMode(artifact.viewMode);
@@ -7104,6 +7409,17 @@ function createArtifactuse(userConfig = {}) {
7104
7409
  return state.getArtifact(id);
7105
7410
  }
7106
7411
 
7412
+ /**
7413
+ * Open panel in empty state
7414
+ */
7415
+ function openPanel() {
7416
+ state.clearActiveArtifact();
7417
+ state.setForceEmptyView(true);
7418
+ state.setPanelOpen(true);
7419
+
7420
+ emit('panel:opened');
7421
+ }
7422
+
7107
7423
  /**
7108
7424
  * Close panel
7109
7425
  */
@@ -7341,6 +7657,7 @@ function createArtifactuse(userConfig = {}) {
7341
7657
  openFile,
7342
7658
  openCode,
7343
7659
  updateFile,
7660
+ openPanel,
7344
7661
  closePanel,
7345
7662
  togglePanel,
7346
7663
  toggleFullscreen,
@@ -7348,6 +7665,11 @@ function createArtifactuse(userConfig = {}) {
7348
7665
  getPanelUrl,
7349
7666
  sendToPanel,
7350
7667
 
7668
+ // Multi-tab
7669
+ closeTab: (artifactId) => state.closeTab(artifactId),
7670
+ closeOtherTabs: (artifactId) => state.closeOtherTabs(artifactId),
7671
+ closeAllTabs: () => state.closeAllTabs(),
7672
+
7351
7673
  // Panel management (new)
7352
7674
  hasPanel,
7353
7675
  registerPanel,
@@ -7473,8 +7795,11 @@ function provideArtifactuse(config = {}) {
7473
7795
  isPanelOpen: false,
7474
7796
  viewMode: 'preview',
7475
7797
  isFullscreen: false,
7798
+ openTabs: [],
7799
+ tabViewModes: {},
7800
+ forceEmptyView: false,
7476
7801
  });
7477
-
7802
+
7478
7803
  // Subscribe to state changes
7479
7804
  instance.state.subscribe((newState) => {
7480
7805
  state.artifacts = newState.artifacts;
@@ -7482,14 +7807,17 @@ function provideArtifactuse(config = {}) {
7482
7807
  state.isPanelOpen = newState.isPanelOpen;
7483
7808
  state.viewMode = newState.viewMode;
7484
7809
  state.isFullscreen = newState.isFullscreen;
7810
+ state.openTabs = newState.openTabs;
7811
+ state.tabViewModes = newState.tabViewModes;
7812
+ state.forceEmptyView = newState.forceEmptyView;
7485
7813
  });
7486
-
7814
+
7487
7815
  // Computed
7488
7816
  const activeArtifact = computed(() => {
7489
7817
  if (!state.activeArtifactId) return null;
7490
7818
  return state.artifacts.find(a => a.id === state.activeArtifactId) || null;
7491
7819
  });
7492
-
7820
+
7493
7821
  // Only count non-inline artifacts (inline artifacts render in message content)
7494
7822
  const artifactCount = computed(() => state.artifacts.filter(a => !a.isInline).length);
7495
7823
 
@@ -7505,7 +7833,7 @@ function provideArtifactuse(config = {}) {
7505
7833
 
7506
7834
  // Apply theme immediately on initialization
7507
7835
  instance.applyTheme();
7508
-
7836
+
7509
7837
  // Provide value
7510
7838
  const provided = {
7511
7839
  instance,
@@ -7513,11 +7841,11 @@ function provideArtifactuse(config = {}) {
7513
7841
  activeArtifact,
7514
7842
  artifactCount,
7515
7843
  hasArtifacts,
7516
-
7844
+
7517
7845
  // Panel computed
7518
7846
  panelTypes,
7519
7847
  activePanelUrl,
7520
-
7848
+
7521
7849
  // Methods
7522
7850
  processMessage: instance.processMessage,
7523
7851
  initializeContent: instance.initializeContent,
@@ -7525,19 +7853,25 @@ function provideArtifactuse(config = {}) {
7525
7853
  openFile: instance.openFile,
7526
7854
  openCode: instance.openCode,
7527
7855
  updateFile: instance.updateFile,
7856
+ openPanel: instance.openPanel,
7528
7857
  closePanel: instance.closePanel,
7529
7858
  togglePanel: instance.togglePanel,
7530
7859
  toggleFullscreen: instance.toggleFullscreen,
7531
7860
  setViewMode: instance.setViewMode,
7532
7861
  getPanelUrl: instance.getPanelUrl,
7533
7862
  sendToPanel: instance.sendToPanel,
7534
-
7863
+
7535
7864
  // Panel management
7536
7865
  hasPanel: instance.hasPanel,
7537
7866
  registerPanel: instance.registerPanel,
7538
7867
  unregisterPanel: instance.unregisterPanel,
7539
7868
  getPanelTypes: instance.getPanelTypes,
7540
-
7869
+
7870
+ // Multi-tab
7871
+ closeTab: instance.closeTab,
7872
+ closeOtherTabs: instance.closeOtherTabs,
7873
+ closeAllTabs: instance.closeAllTabs,
7874
+
7541
7875
  // Events
7542
7876
  on: instance.on,
7543
7877
  off: instance.off,
@@ -7586,11 +7920,14 @@ function createArtifactuseComposable(config = {}) {
7586
7920
  isPanelOpen: false,
7587
7921
  viewMode: 'preview',
7588
7922
  isFullscreen: false,
7923
+ openTabs: [],
7924
+ tabViewModes: {},
7925
+ forceEmptyView: false,
7589
7926
  });
7590
-
7927
+
7591
7928
  // Subscribe to state changes
7592
7929
  let unsubscribe;
7593
-
7930
+
7594
7931
  onMounted(() => {
7595
7932
  unsubscribe = instance.state.subscribe((newState) => {
7596
7933
  state.artifacts = newState.artifacts;
@@ -7598,6 +7935,9 @@ function createArtifactuseComposable(config = {}) {
7598
7935
  state.isPanelOpen = newState.isPanelOpen;
7599
7936
  state.viewMode = newState.viewMode;
7600
7937
  state.isFullscreen = newState.isFullscreen;
7938
+ state.openTabs = newState.openTabs;
7939
+ state.tabViewModes = newState.tabViewModes;
7940
+ state.forceEmptyView = newState.forceEmptyView;
7601
7941
  });
7602
7942
 
7603
7943
  // Apply theme
@@ -7646,6 +7986,7 @@ function createArtifactuseComposable(config = {}) {
7646
7986
  openFile: instance.openFile,
7647
7987
  openCode: instance.openCode,
7648
7988
  updateFile: instance.updateFile,
7989
+ openPanel: instance.openPanel,
7649
7990
  closePanel: instance.closePanel,
7650
7991
  togglePanel: instance.togglePanel,
7651
7992
  toggleFullscreen: instance.toggleFullscreen,
@@ -7658,7 +7999,12 @@ function createArtifactuseComposable(config = {}) {
7658
7999
  registerPanel: instance.registerPanel,
7659
8000
  unregisterPanel: instance.unregisterPanel,
7660
8001
  getPanelTypes: instance.getPanelTypes,
7661
-
8002
+
8003
+ // Multi-tab
8004
+ closeTab: instance.closeTab,
8005
+ closeOtherTabs: instance.closeOtherTabs,
8006
+ closeAllTabs: instance.closeAllTabs,
8007
+
7662
8008
  // Events
7663
8009
  on: instance.on,
7664
8010
  off: instance.off,
@@ -27229,6 +27575,36 @@ var JSZip = /*@__PURE__*/getDefaultExportFromCjs(libExports);
27229
27575
  //
27230
27576
  //
27231
27577
  //
27578
+ //
27579
+ //
27580
+ //
27581
+ //
27582
+ //
27583
+ //
27584
+ //
27585
+ //
27586
+ //
27587
+ //
27588
+ //
27589
+ //
27590
+ //
27591
+ //
27592
+ //
27593
+ //
27594
+ //
27595
+ //
27596
+ //
27597
+ //
27598
+ //
27599
+ //
27600
+ //
27601
+ //
27602
+ //
27603
+ //
27604
+ //
27605
+ //
27606
+ //
27607
+ //
27232
27608
 
27233
27609
 
27234
27610
  var script$1 = defineComponent({
@@ -27353,6 +27729,16 @@ var script$1 = defineComponent({
27353
27729
  return instance.config?.branding !== false;
27354
27730
  });
27355
27731
 
27732
+ // Multi-tab computed
27733
+ const isMultiTab = computed(() => instance.config?.multiTab === true);
27734
+
27735
+ const openTabArtifacts = computed(() => {
27736
+ if (!isMultiTab.value) return [];
27737
+ return state.openTabs
27738
+ .map(id => state.artifacts.find(a => a.id === id))
27739
+ .filter(Boolean);
27740
+ });
27741
+
27356
27742
  const sharingEnabled = computed(() => {
27357
27743
  return instance.share?.enabled !== false;
27358
27744
  });
@@ -27363,7 +27749,7 @@ var script$1 = defineComponent({
27363
27749
 
27364
27750
  // Effective panel width - smaller for list/empty views
27365
27751
  const effectivePanelWidth = computed(() => {
27366
- if (!activeArtifact.value) {
27752
+ if (!activeArtifact.value && !state.forceEmptyView) {
27367
27753
  return Math.min(panelWidth.value, 30);
27368
27754
  }
27369
27755
  return panelWidth.value;
@@ -27372,11 +27758,13 @@ var script$1 = defineComponent({
27372
27758
  const panelClasses = computed(() => {
27373
27759
  return {
27374
27760
  'artifactuse-panel--fullscreen': state.isFullscreen,
27375
- 'artifactuse-panel--list': !activeArtifact.value && hasArtifacts.value,
27376
- 'artifactuse-panel--empty': !hasArtifacts.value,
27761
+ 'artifactuse-panel--list': !activeArtifact.value && hasArtifacts.value && !state.forceEmptyView,
27762
+ 'artifactuse-panel--empty': !hasArtifacts.value && !state.forceEmptyView,
27377
27763
  };
27378
27764
  });
27379
-
27765
+
27766
+ const forceEmptyView = computed(() => state.forceEmptyView);
27767
+
27380
27768
  // Smartdiff: per-line language-aware highlighting
27381
27769
  function highlightSmartDiff(artifact) {
27382
27770
  if (artifact.language !== 'smartdiff') return null;
@@ -27757,6 +28145,18 @@ var script$1 = defineComponent({
27757
28145
  }
27758
28146
  }
27759
28147
 
28148
+ // Multi-tab methods
28149
+ function selectTab(artifact) {
28150
+ openArtifact(artifact);
28151
+ }
28152
+
28153
+ function handleCloseTab(artifactId) {
28154
+ instance.closeTab(artifactId);
28155
+ if (state.openTabs.length === 0) {
28156
+ cameFromList.value = false;
28157
+ }
28158
+ }
28159
+
27760
28160
  function goBackToList() {
27761
28161
  cameFromList.value = false;
27762
28162
  instance.state.clearActiveArtifact();
@@ -28023,9 +28423,12 @@ var script$1 = defineComponent({
28023
28423
  showBranding,
28024
28424
  effectivePanelWidth,
28025
28425
  panelClasses,
28426
+ forceEmptyView,
28026
28427
  sharingEnabled,
28027
28428
  isAuthenticated,
28028
28429
  isEditorAvailable,
28430
+ isMultiTab,
28431
+ openTabArtifacts,
28029
28432
 
28030
28433
  // Methods
28031
28434
  handleIframeLoad,
@@ -28043,6 +28446,10 @@ var script$1 = defineComponent({
28043
28446
  startSplitResize,
28044
28447
  handleEditorSave,
28045
28448
 
28449
+ // Multi-tab methods
28450
+ selectTab,
28451
+ handleCloseTab,
28452
+
28046
28453
  // Share methods
28047
28454
  toggleSharePopup,
28048
28455
  closeShareModal,
@@ -28107,7 +28514,7 @@ var __vue_render__$1 = function () {
28107
28514
  )
28108
28515
  : _vm._e(),
28109
28516
  _vm._v(" "),
28110
- !_vm.hasArtifacts
28517
+ !_vm.hasArtifacts || _vm.forceEmptyView
28111
28518
  ? [
28112
28519
  _c(
28113
28520
  "header",
@@ -28124,26 +28531,51 @@ var __vue_render__$1 = function () {
28124
28531
  "span",
28125
28532
  { staticClass: "artifactuse-panel__icon" },
28126
28533
  [
28127
- _c(
28128
- "svg",
28129
- {
28130
- attrs: {
28131
- viewBox: "0 0 24 24",
28132
- fill: "none",
28133
- stroke: "currentColor",
28134
- "stroke-width": "2",
28135
- },
28136
- },
28137
- [
28138
- _c("polyline", {
28139
- attrs: { points: "16 18 22 12 16 6" },
28140
- }),
28141
- _vm._v(" "),
28142
- _c("polyline", {
28143
- attrs: { points: "8 6 2 12 8 18" },
28144
- }),
28145
- ]
28146
- ),
28534
+ _vm.forceEmptyView
28535
+ ? _c(
28536
+ "svg",
28537
+ {
28538
+ attrs: {
28539
+ viewBox: "0 0 24 24",
28540
+ fill: "none",
28541
+ stroke: "currentColor",
28542
+ "stroke-width": "2",
28543
+ },
28544
+ },
28545
+ [
28546
+ _c("path", {
28547
+ attrs: {
28548
+ d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z",
28549
+ },
28550
+ }),
28551
+ _vm._v(" "),
28552
+ _c("polyline", {
28553
+ attrs: { points: "14 2 14 8 20 8" },
28554
+ }),
28555
+ ]
28556
+ )
28557
+ : _c(
28558
+ "svg",
28559
+ {
28560
+ attrs: {
28561
+ viewBox: "0 0 24 24",
28562
+ fill: "none",
28563
+ stroke: "currentColor",
28564
+ "stroke-width": "2",
28565
+ },
28566
+ },
28567
+ [
28568
+ _c("polyline", {
28569
+ attrs: {
28570
+ points: "16 18 22 12 16 6",
28571
+ },
28572
+ }),
28573
+ _vm._v(" "),
28574
+ _c("polyline", {
28575
+ attrs: { points: "8 6 2 12 8 18" },
28576
+ }),
28577
+ ]
28578
+ ),
28147
28579
  ]
28148
28580
  ),
28149
28581
  _vm._v(" "),
@@ -28157,7 +28589,15 @@ var __vue_render__$1 = function () {
28157
28589
  _c(
28158
28590
  "span",
28159
28591
  { staticClass: "artifactuse-panel__name" },
28160
- [_vm._v("Artifacts")]
28592
+ [
28593
+ _vm._v(
28594
+ _vm._s(
28595
+ _vm.forceEmptyView
28596
+ ? "Artifact Viewer"
28597
+ : "Artifacts"
28598
+ )
28599
+ ),
28600
+ ]
28161
28601
  ),
28162
28602
  ]
28163
28603
  ),
@@ -28247,7 +28687,15 @@ var __vue_render__$1 = function () {
28247
28687
  _c(
28248
28688
  "h3",
28249
28689
  { staticClass: "artifactuse-panel__empty-title" },
28250
- [_vm._v("No artifacts yet")]
28690
+ [
28691
+ _vm._v(
28692
+ _vm._s(
28693
+ _vm.forceEmptyView
28694
+ ? "No artifact selected"
28695
+ : "No artifacts yet"
28696
+ )
28697
+ ),
28698
+ ]
28251
28699
  ),
28252
28700
  _vm._v(" "),
28253
28701
  _c(
@@ -28255,7 +28703,13 @@ var __vue_render__$1 = function () {
28255
28703
  { staticClass: "artifactuse-panel__empty-text" },
28256
28704
  [
28257
28705
  _vm._v(
28258
- "\n Code blocks, forms, and other interactive content will appear here as the AI generates them.\n "
28706
+ "\n " +
28707
+ _vm._s(
28708
+ _vm.forceEmptyView
28709
+ ? "Open an artifact to have it appear here"
28710
+ : "Code blocks, forms, and other interactive content will appear here as the AI generates them."
28711
+ ) +
28712
+ "\n "
28259
28713
  ),
28260
28714
  ]
28261
28715
  ),
@@ -28315,7 +28769,7 @@ var __vue_render__$1 = function () {
28315
28769
  ]
28316
28770
  ),
28317
28771
  ]
28318
- : !_vm.activeArtifact
28772
+ : !_vm.activeArtifact && !_vm.forceEmptyView
28319
28773
  ? [
28320
28774
  _c(
28321
28775
  "header",
@@ -28683,12 +29137,16 @@ var __vue_render__$1 = function () {
28683
29137
  "header",
28684
29138
  { staticClass: "artifactuse-panel__header" },
28685
29139
  [
28686
- _vm.cameFromList
29140
+ _vm.isMultiTab || _vm.cameFromList
28687
29141
  ? _c(
28688
29142
  "button",
28689
29143
  {
28690
29144
  staticClass: "artifactuse-panel__back",
28691
- attrs: { title: "Back to list" },
29145
+ attrs: {
29146
+ title: _vm.isMultiTab
29147
+ ? "Browse artifacts"
29148
+ : "Back to list",
29149
+ },
28692
29150
  on: { click: _vm.goBackToList },
28693
29151
  },
28694
29152
  [
@@ -29164,6 +29622,114 @@ var __vue_render__$1 = function () {
29164
29622
  ]
29165
29623
  ),
29166
29624
  _vm._v(" "),
29625
+ _vm.isMultiTab && _vm.openTabArtifacts.length > 0
29626
+ ? _c(
29627
+ "div",
29628
+ { staticClass: "artifactuse-panel__file-tabs" },
29629
+ [
29630
+ _c(
29631
+ "div",
29632
+ {
29633
+ staticClass:
29634
+ "artifactuse-panel__file-tabs-scroll",
29635
+ },
29636
+ _vm._l(_vm.openTabArtifacts, function (tab) {
29637
+ return _c(
29638
+ "button",
29639
+ {
29640
+ key: tab.id,
29641
+ staticClass:
29642
+ "artifactuse-panel__file-tab",
29643
+ class: {
29644
+ "artifactuse-panel__file-tab--active":
29645
+ _vm.activeArtifact &&
29646
+ tab.id === _vm.activeArtifact.id,
29647
+ },
29648
+ on: {
29649
+ click: function ($event) {
29650
+ return _vm.selectTab(tab)
29651
+ },
29652
+ },
29653
+ },
29654
+ [
29655
+ _c("span", {
29656
+ staticClass:
29657
+ "artifactuse-panel__file-tab-icon",
29658
+ domProps: {
29659
+ innerHTML: _vm._s(
29660
+ _vm.getArtifactIconHtml(tab)
29661
+ ),
29662
+ },
29663
+ }),
29664
+ _vm._v(" "),
29665
+ _c(
29666
+ "span",
29667
+ {
29668
+ staticClass:
29669
+ "artifactuse-panel__file-tab-title",
29670
+ },
29671
+ [
29672
+ _vm._v(
29673
+ _vm._s(tab.title || "Untitled")
29674
+ ),
29675
+ ]
29676
+ ),
29677
+ _vm._v(" "),
29678
+ _c(
29679
+ "button",
29680
+ {
29681
+ staticClass:
29682
+ "artifactuse-panel__file-tab-close",
29683
+ attrs: { title: "Close tab" },
29684
+ on: {
29685
+ click: function ($event) {
29686
+ $event.stopPropagation();
29687
+ return _vm.handleCloseTab(tab.id)
29688
+ },
29689
+ },
29690
+ },
29691
+ [
29692
+ _c(
29693
+ "svg",
29694
+ {
29695
+ attrs: {
29696
+ viewBox: "0 0 24 24",
29697
+ fill: "none",
29698
+ stroke: "currentColor",
29699
+ "stroke-width": "2",
29700
+ },
29701
+ },
29702
+ [
29703
+ _c("line", {
29704
+ attrs: {
29705
+ x1: "18",
29706
+ y1: "6",
29707
+ x2: "6",
29708
+ y2: "18",
29709
+ },
29710
+ }),
29711
+ _vm._v(" "),
29712
+ _c("line", {
29713
+ attrs: {
29714
+ x1: "6",
29715
+ y1: "6",
29716
+ x2: "18",
29717
+ y2: "18",
29718
+ },
29719
+ }),
29720
+ ]
29721
+ ),
29722
+ ]
29723
+ ),
29724
+ ]
29725
+ )
29726
+ }),
29727
+ 0
29728
+ ),
29729
+ ]
29730
+ )
29731
+ : _vm._e(),
29732
+ _vm._v(" "),
29167
29733
  _c(
29168
29734
  "div",
29169
29735
  {
@@ -30659,6 +31225,7 @@ var __vue_render__$1 = function () {
30659
31225
  )
30660
31226
  : _vm._e(),
30661
31227
  _vm._v(" "),
31228
+ !_vm.isMultiTab &&
30662
31229
  _vm.nonInlineArtifacts.length > 1
30663
31230
  ? _c(
30664
31231
  "div",