artifactuse 0.1.25 → 0.1.28
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/README.md +60 -1
- package/dist/core/detector.d.ts +5 -0
- package/dist/core/index.d.ts +2 -1
- package/dist/{index-Bzk5VnG1.js → index-D56xsAnF.js} +1484 -1411
- package/dist/index.js +1 -1
- package/dist/react/ArtifactuseAgentMessage.d.ts +9 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +863 -803
- package/dist/styles/artifactuse.css +1 -0
- package/dist/styles/components/inline-preview.css +69 -0
- package/dist/styles/components/message.css +7 -1
- package/dist/styles/components/panel.css +18 -0
- package/dist/svelte/index.d.ts +6 -6
- package/dist/svelte/index.js +1909 -1868
- package/dist/vue/index.d.ts +4 -4
- package/dist/vue/index.js +1230 -1169
- package/dist/vue2/composables.d.ts +4 -4
- package/dist/vue2/index.js +265 -27
- package/package.json +1 -1
|
@@ -66,7 +66,7 @@ export function provideArtifactuse(config?: {
|
|
|
66
66
|
isFullscreen: boolean;
|
|
67
67
|
};
|
|
68
68
|
subscribe: (callback: any) => () => void;
|
|
69
|
-
processMessage: (content: any, messageId: any) => {
|
|
69
|
+
processMessage: (content: any, messageId: any, overrides?: {}) => {
|
|
70
70
|
html: string | Promise<string>;
|
|
71
71
|
artifacts: any[];
|
|
72
72
|
};
|
|
@@ -183,7 +183,7 @@ export function provideArtifactuse(config?: {
|
|
|
183
183
|
hasArtifacts: import("vue").ComputedRef<boolean>;
|
|
184
184
|
panelTypes: import("vue").ComputedRef<any>;
|
|
185
185
|
activePanelUrl: import("vue").ComputedRef<any>;
|
|
186
|
-
processMessage: (content: any, messageId: any) => {
|
|
186
|
+
processMessage: (content: any, messageId: any, overrides?: {}) => {
|
|
187
187
|
html: string | Promise<string>;
|
|
188
188
|
artifacts: any[];
|
|
189
189
|
};
|
|
@@ -278,7 +278,7 @@ export function createArtifactuseComposable(config?: {}): {
|
|
|
278
278
|
isFullscreen: boolean;
|
|
279
279
|
};
|
|
280
280
|
subscribe: (callback: any) => () => void;
|
|
281
|
-
processMessage: (content: any, messageId: any) => {
|
|
281
|
+
processMessage: (content: any, messageId: any, overrides?: {}) => {
|
|
282
282
|
html: string | Promise<string>;
|
|
283
283
|
artifacts: any[];
|
|
284
284
|
};
|
|
@@ -395,7 +395,7 @@ export function createArtifactuseComposable(config?: {}): {
|
|
|
395
395
|
hasArtifacts: import("vue").ComputedRef<boolean>;
|
|
396
396
|
panelTypes: import("vue").ComputedRef<any>;
|
|
397
397
|
activePanelUrl: import("vue").ComputedRef<any>;
|
|
398
|
-
processMessage: (content: any, messageId: any) => {
|
|
398
|
+
processMessage: (content: any, messageId: any, overrides?: {}) => {
|
|
399
399
|
html: string | Promise<string>;
|
|
400
400
|
artifacts: any[];
|
|
401
401
|
};
|
package/dist/vue2/index.js
CHANGED
|
@@ -23,7 +23,7 @@ const ARTIFACT_TYPES = {
|
|
|
23
23
|
const PREVIEWABLE_LANGUAGES = [
|
|
24
24
|
// Code languages
|
|
25
25
|
'html', 'htm', 'svg', 'markdown', 'md', 'jsx', 'vue',
|
|
26
|
-
'diff', 'patch', 'json',
|
|
26
|
+
'diff', 'patch', 'smartdiff', 'json',
|
|
27
27
|
'javascript', 'js', 'python', 'py',
|
|
28
28
|
// Visual editors
|
|
29
29
|
'canvas', 'whiteboard', 'drawing',
|
|
@@ -40,7 +40,7 @@ const PANEL_LANGUAGES = [
|
|
|
40
40
|
'video', 'videoeditor', 'timeline',
|
|
41
41
|
'canvas', 'whiteboard', 'drawing',
|
|
42
42
|
// Code (panel for preview)
|
|
43
|
-
'json', 'svg', 'diff', 'patch',
|
|
43
|
+
'json', 'svg', 'diff', 'patch', 'smartdiff',
|
|
44
44
|
'javascript', 'js', 'python', 'py',
|
|
45
45
|
'jsx', 'vue', 'html', 'htm',
|
|
46
46
|
// Structured artifacts (form can be panel based on complexity)
|
|
@@ -117,6 +117,7 @@ function getLanguageDisplayName(language) {
|
|
|
117
117
|
docker: 'Docker',
|
|
118
118
|
diff: 'Diff',
|
|
119
119
|
patch: 'Patch',
|
|
120
|
+
smartdiff: 'Smart Diff',
|
|
120
121
|
// Visual editors
|
|
121
122
|
canvas: 'Canvas',
|
|
122
123
|
video: 'Video Editor',
|
|
@@ -241,6 +242,7 @@ function getLanguageIcon(language) {
|
|
|
241
242
|
sql: '<path d="M12 3C7.58 3 4 4.79 4 7v10c0 2.21 3.58 4 8 4s8-1.79 8-4V7c0-2.21-3.58-4-8-4m0 2c3.87 0 6 1.5 6 2s-2.13 2-6 2-6-1.5-6-2 2.13-2 6-2M6 17v-2.7c1.56.84 3.67 1.36 6 1.36s4.44-.52 6-1.36V17c0 .5-2.13 2-6 2s-6-1.5-6-2m0-5v-2.7c1.56.84 3.67 1.36 6 1.36s4.44-.52 6-1.36V12c0 .5-2.13 2-6 2s-6-1.5-6-2z"/>',
|
|
242
243
|
diff: '<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/>',
|
|
243
244
|
patch: '<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/>',
|
|
245
|
+
smartdiff: '<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/>',
|
|
244
246
|
canvas: '<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/>',
|
|
245
247
|
whiteboard: '<rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/>',
|
|
246
248
|
drawing: '<path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/>',
|
|
@@ -282,6 +284,18 @@ function decodeHtml(encoded) {
|
|
|
282
284
|
.replace(/ /g, ' ');
|
|
283
285
|
}
|
|
284
286
|
|
|
287
|
+
/**
|
|
288
|
+
* Encode HTML for safe embedding
|
|
289
|
+
*/
|
|
290
|
+
function encodeHtml(code) {
|
|
291
|
+
return code
|
|
292
|
+
.replace(/&/g, '&')
|
|
293
|
+
.replace(/"/g, '"')
|
|
294
|
+
.replace(/'/g, ''')
|
|
295
|
+
.replace(/</g, '<')
|
|
296
|
+
.replace(/>/g, '>');
|
|
297
|
+
}
|
|
298
|
+
|
|
285
299
|
/**
|
|
286
300
|
* Encode JSON for safe embedding in HTML attributes using Base64
|
|
287
301
|
*/
|
|
@@ -306,6 +320,16 @@ function encodeJsonForAttribute(obj) {
|
|
|
306
320
|
function extractArtifactTitle(code, language) {
|
|
307
321
|
const langLower = language?.toLowerCase();
|
|
308
322
|
|
|
323
|
+
// For smartdiff, extract language from JSON
|
|
324
|
+
if (langLower === 'smartdiff') {
|
|
325
|
+
try {
|
|
326
|
+
const json = JSON.parse(code);
|
|
327
|
+
return json.language ? `${getLanguageDisplayName(json.language)} Diff` : 'Smart Diff';
|
|
328
|
+
} catch {
|
|
329
|
+
return 'Smart Diff';
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
309
333
|
// For form/social, try to extract title from JSON
|
|
310
334
|
if (langLower === 'form' || langLower === 'social') {
|
|
311
335
|
try {
|
|
@@ -370,6 +394,75 @@ function extractArtifactTitle(code, language) {
|
|
|
370
394
|
return `${getLanguageDisplayName(language)} Code`;
|
|
371
395
|
}
|
|
372
396
|
|
|
397
|
+
/**
|
|
398
|
+
* Compute a simple line-by-line diff for inline preview display
|
|
399
|
+
* Produces +/- prefixed lines that Prism highlights with language-diff
|
|
400
|
+
*/
|
|
401
|
+
function computeSimpleDiff(oldCode, newCode) {
|
|
402
|
+
const oldLines = (oldCode || '').split('\n');
|
|
403
|
+
const newLines = (newCode || '').split('\n');
|
|
404
|
+
const result = [];
|
|
405
|
+
const max = Math.max(oldLines.length, newLines.length);
|
|
406
|
+
for (let i = 0; i < max; i++) {
|
|
407
|
+
const oldLine = i < oldLines.length ? oldLines[i] : undefined;
|
|
408
|
+
const newLine = i < newLines.length ? newLines[i] : undefined;
|
|
409
|
+
if (oldLine === newLine) {
|
|
410
|
+
result.push(' ' + oldLine);
|
|
411
|
+
} else {
|
|
412
|
+
if (oldLine !== undefined) result.push('-' + oldLine);
|
|
413
|
+
if (newLine !== undefined) result.push('+' + newLine);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return result.join('\n');
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Create inline preview HTML for an artifact
|
|
421
|
+
* Shows truncated code with fade overlay for long content
|
|
422
|
+
*/
|
|
423
|
+
function createInlinePreview(artifact, code, langLower, inlinePreview) {
|
|
424
|
+
const maxLines = inlinePreview.maxLines || 15;
|
|
425
|
+
|
|
426
|
+
// Smartdiff: parse JSON, compute diff, use actual language for highlighting
|
|
427
|
+
if (langLower === 'smartdiff') {
|
|
428
|
+
try {
|
|
429
|
+
const diffData = JSON.parse(code);
|
|
430
|
+
const diffText = computeSimpleDiff(diffData.oldCode, diffData.newCode);
|
|
431
|
+
const allDiffLines = diffText.split('\n');
|
|
432
|
+
const truncDiffLines = allDiffLines.slice(0, maxLines);
|
|
433
|
+
|
|
434
|
+
// Separate markers (+/-/space) from code content
|
|
435
|
+
const markers = truncDiffLines.map(l => l[0] || ' ');
|
|
436
|
+
const codeLines = truncDiffLines.map(l => l.slice(1));
|
|
437
|
+
const encoded = encodeHtml(codeLines.join('\n'));
|
|
438
|
+
const isTruncated = allDiffLines.length > maxLines;
|
|
439
|
+
const actualLang = diffData.language || 'plaintext';
|
|
440
|
+
|
|
441
|
+
return `<div class="artifactuse-inline-preview${isTruncated ? ' artifactuse-inline-preview--truncated' : ''}" data-artifact-id="${artifact.id}" data-smartdiff="true" data-smartdiff-markers="${markers.join(',')}">`
|
|
442
|
+
+ `<pre class="artifactuse-inline-preview__pre"><code class="language-${actualLang}">${encoded}</code></pre>`
|
|
443
|
+
+ (isTruncated ? `<div class="artifactuse-inline-preview__fade"><span class="artifactuse-inline-preview__action">View full diff (${allDiffLines.length} lines)</span></div>` : '')
|
|
444
|
+
+ `</div>`;
|
|
445
|
+
} catch {
|
|
446
|
+
// Fallback: show raw content as JSON
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Standard code blocks (and diff/patch)
|
|
451
|
+
let previewCode = code;
|
|
452
|
+
let previewLang = langLower;
|
|
453
|
+
|
|
454
|
+
const lines = previewCode.split('\n');
|
|
455
|
+
const truncated = lines.slice(0, maxLines).join('\n');
|
|
456
|
+
const encoded = encodeHtml(truncated);
|
|
457
|
+
const isTruncated = lines.length > maxLines;
|
|
458
|
+
const label = langLower === 'diff' || langLower === 'patch' ? 'diff' : 'code';
|
|
459
|
+
|
|
460
|
+
return `<div class="artifactuse-inline-preview${isTruncated ? ' artifactuse-inline-preview--truncated' : ''}" data-artifact-id="${artifact.id}">`
|
|
461
|
+
+ `<pre class="artifactuse-inline-preview__pre"><code class="language-${previewLang}">${encoded}</code></pre>`
|
|
462
|
+
+ (isTruncated ? `<div class="artifactuse-inline-preview__fade"><span class="artifactuse-inline-preview__action">View full ${label} (${lines.length} lines)</span></div>` : '')
|
|
463
|
+
+ `</div>`;
|
|
464
|
+
}
|
|
465
|
+
|
|
373
466
|
/**
|
|
374
467
|
* Create artifact placeholder HTML
|
|
375
468
|
*/
|
|
@@ -491,7 +584,25 @@ function extractCodeBlockArtifacts(html, messageId, options = {}) {
|
|
|
491
584
|
minLines = 3,
|
|
492
585
|
minLength = 50,
|
|
493
586
|
extractAll = false,
|
|
587
|
+
inlinePreview = null,
|
|
588
|
+
inlineCode = null,
|
|
589
|
+
tabs = null,
|
|
590
|
+
viewMode = null,
|
|
494
591
|
} = options;
|
|
592
|
+
|
|
593
|
+
function shouldShowPreview(lang) {
|
|
594
|
+
if (!inlinePreview) return false;
|
|
595
|
+
if (inlinePreview.languages === true) return true;
|
|
596
|
+
if (Array.isArray(inlinePreview.languages)) return inlinePreview.languages.includes(lang);
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function shouldShowInlineCode(lang) {
|
|
601
|
+
if (!inlineCode) return false;
|
|
602
|
+
if (inlineCode.languages === true) return true;
|
|
603
|
+
if (Array.isArray(inlineCode.languages)) return inlineCode.languages.includes(lang);
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
495
606
|
|
|
496
607
|
const artifacts = [];
|
|
497
608
|
const codeBlockRegex = /<pre><code class="language-(\w+)">([\s\S]*?)<\/code><\/pre>/gi;
|
|
@@ -510,6 +621,12 @@ function extractCodeBlockArtifacts(html, messageId, options = {}) {
|
|
|
510
621
|
}
|
|
511
622
|
}
|
|
512
623
|
|
|
624
|
+
// inlineCode: highest priority — skip extraction, leave code block as-is
|
|
625
|
+
if (shouldShowInlineCode(langLower)) {
|
|
626
|
+
blockIndex++;
|
|
627
|
+
return match;
|
|
628
|
+
}
|
|
629
|
+
|
|
513
630
|
// Artifact extraction logic
|
|
514
631
|
const isPreviewableLang = isPreviewable(langLower);
|
|
515
632
|
|
|
@@ -517,25 +634,37 @@ function extractCodeBlockArtifacts(html, messageId, options = {}) {
|
|
|
517
634
|
|
|
518
635
|
if (extractAll) {
|
|
519
636
|
shouldExtract = true;
|
|
520
|
-
} else if (langLower === 'diff' || langLower === 'patch') {
|
|
637
|
+
} else if (langLower === 'diff' || langLower === 'patch' || langLower === 'smartdiff') {
|
|
521
638
|
shouldExtract = lineCount > 10;
|
|
522
639
|
} else if (isPreviewableLang) {
|
|
523
640
|
shouldExtract = true;
|
|
524
641
|
} else {
|
|
525
642
|
shouldExtract = code.length >= minLength && lineCount >= minLines;
|
|
526
643
|
}
|
|
527
|
-
|
|
644
|
+
|
|
645
|
+
// Force extraction when inline preview is configured for this language
|
|
646
|
+
if (!shouldExtract && shouldShowPreview(langLower)) {
|
|
647
|
+
shouldExtract = true;
|
|
648
|
+
}
|
|
649
|
+
|
|
528
650
|
if (shouldExtract) {
|
|
529
651
|
const artifact = createArtifact(code, langLower, messageId, blockIndex);
|
|
652
|
+
if (tabs) artifact.tabs = tabs;
|
|
653
|
+
if (viewMode) artifact.viewMode = viewMode;
|
|
530
654
|
blockIndex++;
|
|
531
655
|
artifacts.push(artifact);
|
|
532
|
-
|
|
656
|
+
|
|
657
|
+
// Inline preview mode: show truncated code instead of card
|
|
658
|
+
if (shouldShowPreview(langLower)) {
|
|
659
|
+
return createInlinePreview(artifact, code, langLower, inlinePreview);
|
|
660
|
+
}
|
|
661
|
+
|
|
533
662
|
// Determine placeholder type based on artifact
|
|
534
663
|
let placeholderType = 'panel';
|
|
535
664
|
if (artifact.isInline) {
|
|
536
665
|
placeholderType = artifact.type === 'social' ? 'inline-social' : 'inline-form';
|
|
537
666
|
}
|
|
538
|
-
|
|
667
|
+
|
|
539
668
|
return createArtifactPlaceholder(artifact, placeholderType);
|
|
540
669
|
}
|
|
541
670
|
|
|
@@ -6313,6 +6442,7 @@ const DEFAULT_PANELS = {
|
|
|
6313
6442
|
// Diff/patches
|
|
6314
6443
|
diff: 'diff-panel',
|
|
6315
6444
|
patch: 'diff-panel',
|
|
6445
|
+
smartdiff: 'diff-panel',
|
|
6316
6446
|
|
|
6317
6447
|
// Plain text
|
|
6318
6448
|
txt: 'code-panel',
|
|
@@ -6693,18 +6823,30 @@ function createArtifactuse(userConfig = {}) {
|
|
|
6693
6823
|
* Process AI agent message content
|
|
6694
6824
|
* Returns processed HTML with artifact placeholders
|
|
6695
6825
|
*/
|
|
6696
|
-
function processMessage(content, messageId) {
|
|
6826
|
+
function processMessage(content, messageId, overrides = {}) {
|
|
6697
6827
|
// First, convert markdown to HTML
|
|
6698
6828
|
let html = d.parse(content);
|
|
6699
|
-
|
|
6829
|
+
|
|
6700
6830
|
const artifacts = [];
|
|
6701
|
-
|
|
6831
|
+
|
|
6702
6832
|
// Get current resolved theme for processors that need it
|
|
6703
6833
|
const processorOptions = { theme: theme.resolved };
|
|
6704
|
-
|
|
6834
|
+
|
|
6835
|
+
// Merge overrides with global config (component prop → global config → default)
|
|
6836
|
+
const inlinePreview = overrides.inlinePreview ?? config.inlinePreview ?? null;
|
|
6837
|
+
const inlineCode = overrides.inlineCode ?? config.inlineCode ?? null;
|
|
6838
|
+
const tabs = overrides.tabs ?? config.tabs ?? null;
|
|
6839
|
+
const viewMode = overrides.viewMode ?? config.viewMode ?? null;
|
|
6840
|
+
|
|
6705
6841
|
// Extract all code block artifacts (code, form, social)
|
|
6706
6842
|
if (config.processors.codeBlocks) {
|
|
6707
|
-
const result = extractCodeBlockArtifacts(html, messageId,
|
|
6843
|
+
const result = extractCodeBlockArtifacts(html, messageId, {
|
|
6844
|
+
...config.codeExtraction,
|
|
6845
|
+
inlinePreview,
|
|
6846
|
+
inlineCode,
|
|
6847
|
+
tabs,
|
|
6848
|
+
viewMode,
|
|
6849
|
+
});
|
|
6708
6850
|
html = result.html;
|
|
6709
6851
|
artifacts.push(...result.artifacts);
|
|
6710
6852
|
}
|
|
@@ -6815,6 +6957,25 @@ function createArtifactuse(userConfig = {}) {
|
|
|
6815
6957
|
// Apply syntax highlighting if enabled
|
|
6816
6958
|
if (config.syntaxHighlight) {
|
|
6817
6959
|
highlightAll(container);
|
|
6960
|
+
|
|
6961
|
+
// Post-process smartdiff inline previews:
|
|
6962
|
+
// Prism highlighted the code with the actual language grammar.
|
|
6963
|
+
// Now wrap each line in .token.deleted / .token.inserted based on markers.
|
|
6964
|
+
const el = container === document ? document : container;
|
|
6965
|
+
const smartdiffPreviews = el.querySelectorAll('.artifactuse-inline-preview[data-smartdiff]');
|
|
6966
|
+
smartdiffPreviews.forEach(preview => {
|
|
6967
|
+
const codeEl = preview.querySelector('code');
|
|
6968
|
+
if (!codeEl || codeEl.dataset.smartdiffProcessed) return;
|
|
6969
|
+
const markers = preview.dataset.smartdiffMarkers?.split(',') || [];
|
|
6970
|
+
const lines = codeEl.innerHTML.split('\n');
|
|
6971
|
+
codeEl.innerHTML = lines.map((line, i) => {
|
|
6972
|
+
const marker = markers[i];
|
|
6973
|
+
if (marker === '-') return `<span class="token deleted">${line}</span>`;
|
|
6974
|
+
if (marker === '+') return `<span class="token inserted">${line}</span>`;
|
|
6975
|
+
return line;
|
|
6976
|
+
}).join('\n');
|
|
6977
|
+
codeEl.dataset.smartdiffProcessed = 'true';
|
|
6978
|
+
});
|
|
6818
6979
|
}
|
|
6819
6980
|
|
|
6820
6981
|
await Promise.all(promises);
|
|
@@ -6832,7 +6993,10 @@ function createArtifactuse(userConfig = {}) {
|
|
|
6832
6993
|
|
|
6833
6994
|
state.setActiveArtifact(artifact.id);
|
|
6834
6995
|
state.setPanelOpen(true);
|
|
6835
|
-
|
|
6996
|
+
if (artifact.viewMode) {
|
|
6997
|
+
state.setViewMode(artifact.viewMode);
|
|
6998
|
+
}
|
|
6999
|
+
|
|
6836
7000
|
emit('artifact:opened', artifact);
|
|
6837
7001
|
}
|
|
6838
7002
|
|
|
@@ -10971,6 +11135,26 @@ var script$2 = {
|
|
|
10971
11135
|
type: Boolean,
|
|
10972
11136
|
default: false,
|
|
10973
11137
|
},
|
|
11138
|
+
// Override global inlinePreview config for this message
|
|
11139
|
+
inlinePreview: {
|
|
11140
|
+
type: Object,
|
|
11141
|
+
default: null,
|
|
11142
|
+
},
|
|
11143
|
+
// Show full inline code (no extraction) for listed languages
|
|
11144
|
+
inlineCode: {
|
|
11145
|
+
type: Object,
|
|
11146
|
+
default: null,
|
|
11147
|
+
},
|
|
11148
|
+
// Override visible panel tabs for artifacts from this message
|
|
11149
|
+
tabs: {
|
|
11150
|
+
type: Array,
|
|
11151
|
+
default: null,
|
|
11152
|
+
},
|
|
11153
|
+
// Override initial panel view mode for artifacts from this message
|
|
11154
|
+
viewMode: {
|
|
11155
|
+
type: String,
|
|
11156
|
+
default: null,
|
|
11157
|
+
},
|
|
10974
11158
|
},
|
|
10975
11159
|
|
|
10976
11160
|
setup(props, { emit }) {
|
|
@@ -11001,6 +11185,9 @@ var script$2 = {
|
|
|
11001
11185
|
// Get active artifact ID from state
|
|
11002
11186
|
const activeArtifactId = computed(() => state.activeArtifactId);
|
|
11003
11187
|
|
|
11188
|
+
// Resolve inlineCards: component prop → global config → default (true)
|
|
11189
|
+
const effectiveInlineCards = computed(() => props.inlineCards ?? instance?.config?.inlineCards ?? true);
|
|
11190
|
+
|
|
11004
11191
|
/**
|
|
11005
11192
|
* Track if this message was ever "live" (typed/streamed) in this session
|
|
11006
11193
|
* Used to determine if forms should be active or inactive
|
|
@@ -11349,7 +11536,12 @@ var script$2 = {
|
|
|
11349
11536
|
() => props.content,
|
|
11350
11537
|
(newContent) => {
|
|
11351
11538
|
if (newContent) {
|
|
11352
|
-
const result = processMessage(newContent, props.messageId
|
|
11539
|
+
const result = processMessage(newContent, props.messageId, {
|
|
11540
|
+
inlinePreview: props.inlinePreview,
|
|
11541
|
+
inlineCode: props.inlineCode,
|
|
11542
|
+
tabs: props.tabs,
|
|
11543
|
+
viewMode: props.viewMode,
|
|
11544
|
+
});
|
|
11353
11545
|
processedHtml.value = result.html;
|
|
11354
11546
|
messageArtifacts.value = result.artifacts;
|
|
11355
11547
|
|
|
@@ -11382,6 +11574,19 @@ var script$2 = {
|
|
|
11382
11574
|
removeMediaListeners();
|
|
11383
11575
|
});
|
|
11384
11576
|
|
|
11577
|
+
function handleContentClick(e) {
|
|
11578
|
+
const preview = e.target.closest('.artifactuse-inline-preview');
|
|
11579
|
+
if (preview) {
|
|
11580
|
+
const artifactId = preview.dataset.artifactId;
|
|
11581
|
+
if (artifactId) {
|
|
11582
|
+
const artifact = state.artifacts.find(a => a.id === artifactId);
|
|
11583
|
+
if (artifact) {
|
|
11584
|
+
handleOpenArtifact(artifact);
|
|
11585
|
+
}
|
|
11586
|
+
}
|
|
11587
|
+
}
|
|
11588
|
+
}
|
|
11589
|
+
|
|
11385
11590
|
function handleOpenArtifact(artifact) {
|
|
11386
11591
|
openArtifact(artifact);
|
|
11387
11592
|
emit('artifact-open', artifact);
|
|
@@ -11427,11 +11632,13 @@ var script$2 = {
|
|
|
11427
11632
|
viewerCaption,
|
|
11428
11633
|
theme,
|
|
11429
11634
|
activeArtifactId,
|
|
11635
|
+
effectiveInlineCards,
|
|
11430
11636
|
contentSegments,
|
|
11431
11637
|
formInitialState,
|
|
11432
11638
|
openViewer,
|
|
11433
11639
|
closeViewer,
|
|
11434
11640
|
attachMediaListeners,
|
|
11641
|
+
handleContentClick,
|
|
11435
11642
|
handleOpenArtifact,
|
|
11436
11643
|
handleArtifactCopy,
|
|
11437
11644
|
handleArtifactDownload,
|
|
@@ -11458,7 +11665,11 @@ var __vue_render__$2 = function () {
|
|
|
11458
11665
|
[
|
|
11459
11666
|
_c(
|
|
11460
11667
|
"div",
|
|
11461
|
-
{
|
|
11668
|
+
{
|
|
11669
|
+
ref: "contentRef",
|
|
11670
|
+
staticClass: "artifactuse-message-content",
|
|
11671
|
+
on: { click: _vm.handleContentClick },
|
|
11672
|
+
},
|
|
11462
11673
|
[
|
|
11463
11674
|
_vm._l(_vm.contentSegments, function (segment, index) {
|
|
11464
11675
|
return [
|
|
@@ -11487,7 +11698,7 @@ var __vue_render__$2 = function () {
|
|
|
11487
11698
|
attrs: { artifact: segment.artifact, theme: _vm.theme },
|
|
11488
11699
|
on: { copy: _vm.handleSocialCopy },
|
|
11489
11700
|
})
|
|
11490
|
-
: segment.type === "panel" && _vm.
|
|
11701
|
+
: segment.type === "panel" && _vm.effectiveInlineCards
|
|
11491
11702
|
? _c("ArtifactuseCard", {
|
|
11492
11703
|
key: "panel-" + index,
|
|
11493
11704
|
attrs: {
|
|
@@ -27090,27 +27301,54 @@ var script$1 = defineComponent({
|
|
|
27090
27301
|
};
|
|
27091
27302
|
});
|
|
27092
27303
|
|
|
27304
|
+
// Smartdiff: per-line language-aware highlighting
|
|
27305
|
+
function highlightSmartDiff(artifact) {
|
|
27306
|
+
if (artifact.language !== 'smartdiff') return null;
|
|
27307
|
+
try {
|
|
27308
|
+
const data = JSON.parse(artifact.code);
|
|
27309
|
+
if (data.oldCode === undefined || data.newCode === undefined) return null;
|
|
27310
|
+
const lang = data.language || 'plaintext';
|
|
27311
|
+
const grammar = isPrismAvailable() && window.Prism.languages[lang];
|
|
27312
|
+
const diffLines = computeSimpleDiff(data.oldCode, data.newCode).split('\n');
|
|
27313
|
+
|
|
27314
|
+
const highlighted = diffLines.map(line => {
|
|
27315
|
+
const prefix = line[0];
|
|
27316
|
+
const content = line.slice(1);
|
|
27317
|
+
const hl = grammar ? window.Prism.highlight(content, grammar, lang) : content;
|
|
27318
|
+
if (prefix === '-') return `<span class="token deleted">${hl}</span>`;
|
|
27319
|
+
if (prefix === '+') return `<span class="token inserted">${hl}</span>`;
|
|
27320
|
+
return hl;
|
|
27321
|
+
}).join('\n');
|
|
27322
|
+
|
|
27323
|
+
return { html: highlighted, lineCount: diffLines.length };
|
|
27324
|
+
} catch { return null; }
|
|
27325
|
+
}
|
|
27326
|
+
|
|
27093
27327
|
// Methods
|
|
27094
27328
|
function generateLineNumbers() {
|
|
27095
27329
|
if (!lineNumbersRef.value || !activeArtifact.value?.code) return;
|
|
27096
|
-
|
|
27097
|
-
const lines = activeArtifact.value.code.split('\n').length;
|
|
27330
|
+
const sd = highlightSmartDiff(activeArtifact.value);
|
|
27331
|
+
const lines = sd ? sd.lineCount : activeArtifact.value.code.split('\n').length;
|
|
27098
27332
|
const html = Array.from({ length: lines }, (_, i) => `<div>${i + 1}</div>`).join('');
|
|
27099
27333
|
lineNumbersRef.value.innerHTML = html;
|
|
27100
27334
|
}
|
|
27101
|
-
|
|
27335
|
+
|
|
27102
27336
|
function highlightCode() {
|
|
27103
27337
|
if (codeRef.value && isPrismAvailable() && activeArtifact.value?.code) {
|
|
27104
|
-
const
|
|
27105
|
-
if (
|
|
27106
|
-
codeRef.value.innerHTML =
|
|
27107
|
-
activeArtifact.value.code,
|
|
27108
|
-
grammar,
|
|
27109
|
-
normalizedLanguage.value
|
|
27110
|
-
);
|
|
27338
|
+
const sd = highlightSmartDiff(activeArtifact.value);
|
|
27339
|
+
if (sd) {
|
|
27340
|
+
codeRef.value.innerHTML = sd.html;
|
|
27111
27341
|
} else {
|
|
27112
|
-
|
|
27113
|
-
|
|
27342
|
+
const grammar = window.Prism.languages[normalizedLanguage.value];
|
|
27343
|
+
if (grammar) {
|
|
27344
|
+
codeRef.value.innerHTML = window.Prism.highlight(
|
|
27345
|
+
activeArtifact.value.code,
|
|
27346
|
+
grammar,
|
|
27347
|
+
normalizedLanguage.value
|
|
27348
|
+
);
|
|
27349
|
+
} else {
|
|
27350
|
+
codeRef.value.textContent = activeArtifact.value.code;
|
|
27351
|
+
}
|
|
27114
27352
|
}
|
|
27115
27353
|
codeRef.value.dataset.highlighted = 'true';
|
|
27116
27354
|
|