@portel/photon 1.7.0 → 1.8.1

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 (94) hide show
  1. package/README.md +23 -24
  2. package/dist/auto-ui/beam.d.ts.map +1 -1
  3. package/dist/auto-ui/beam.js +117 -42
  4. package/dist/auto-ui/beam.js.map +1 -1
  5. package/dist/auto-ui/design-system/tokens.d.ts +1 -1
  6. package/dist/auto-ui/design-system/tokens.d.ts.map +1 -1
  7. package/dist/auto-ui/design-system/tokens.js +1 -1
  8. package/dist/auto-ui/design-system/tokens.js.map +1 -1
  9. package/dist/auto-ui/frontend/index.html +1 -1
  10. package/dist/auto-ui/rendering/components.d.ts.map +1 -1
  11. package/dist/auto-ui/rendering/components.js +568 -0
  12. package/dist/auto-ui/rendering/components.js.map +1 -1
  13. package/dist/auto-ui/rendering/field-analyzer.d.ts +56 -0
  14. package/dist/auto-ui/rendering/field-analyzer.d.ts.map +1 -1
  15. package/dist/auto-ui/rendering/field-analyzer.js +177 -0
  16. package/dist/auto-ui/rendering/field-analyzer.js.map +1 -1
  17. package/dist/auto-ui/rendering/layout-selector.d.ts +14 -2
  18. package/dist/auto-ui/rendering/layout-selector.d.ts.map +1 -1
  19. package/dist/auto-ui/rendering/layout-selector.js +125 -1
  20. package/dist/auto-ui/rendering/layout-selector.js.map +1 -1
  21. package/dist/auto-ui/streamable-http-transport.d.ts +1 -1
  22. package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
  23. package/dist/auto-ui/streamable-http-transport.js +353 -19
  24. package/dist/auto-ui/streamable-http-transport.js.map +1 -1
  25. package/dist/auto-ui/types.d.ts +7 -1
  26. package/dist/auto-ui/types.d.ts.map +1 -1
  27. package/dist/auto-ui/types.js.map +1 -1
  28. package/dist/beam.bundle.js +22441 -4216
  29. package/dist/beam.bundle.js.map +4 -4
  30. package/dist/cli/commands/info.d.ts.map +1 -1
  31. package/dist/cli/commands/info.js +37 -0
  32. package/dist/cli/commands/info.js.map +1 -1
  33. package/dist/cli/commands/package.d.ts.map +1 -1
  34. package/dist/cli/commands/package.js +16 -0
  35. package/dist/cli/commands/package.js.map +1 -1
  36. package/dist/cli.d.ts.map +1 -1
  37. package/dist/cli.js +628 -14
  38. package/dist/cli.js.map +1 -1
  39. package/dist/context-store.d.ts +79 -0
  40. package/dist/context-store.d.ts.map +1 -0
  41. package/dist/context-store.js +210 -0
  42. package/dist/context-store.js.map +1 -0
  43. package/dist/daemon/client.d.ts +13 -4
  44. package/dist/daemon/client.d.ts.map +1 -1
  45. package/dist/daemon/client.js +138 -77
  46. package/dist/daemon/client.js.map +1 -1
  47. package/dist/daemon/manager.d.ts +0 -25
  48. package/dist/daemon/manager.d.ts.map +1 -1
  49. package/dist/daemon/manager.js +10 -38
  50. package/dist/daemon/manager.js.map +1 -1
  51. package/dist/daemon/protocol.d.ts +7 -2
  52. package/dist/daemon/protocol.d.ts.map +1 -1
  53. package/dist/daemon/protocol.js.map +1 -1
  54. package/dist/daemon/server.js +257 -35
  55. package/dist/daemon/server.js.map +1 -1
  56. package/dist/daemon/session-manager.d.ts +24 -4
  57. package/dist/daemon/session-manager.d.ts.map +1 -1
  58. package/dist/daemon/session-manager.js +62 -12
  59. package/dist/daemon/session-manager.js.map +1 -1
  60. package/dist/index.d.ts +0 -1
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +0 -3
  63. package/dist/index.js.map +1 -1
  64. package/dist/loader.d.ts +3 -20
  65. package/dist/loader.d.ts.map +1 -1
  66. package/dist/loader.js +53 -75
  67. package/dist/loader.js.map +1 -1
  68. package/dist/photon-cli-runner.d.ts.map +1 -1
  69. package/dist/photon-cli-runner.js +258 -218
  70. package/dist/photon-cli-runner.js.map +1 -1
  71. package/dist/photon-doc-extractor.d.ts +2 -0
  72. package/dist/photon-doc-extractor.d.ts.map +1 -1
  73. package/dist/photon-doc-extractor.js +42 -6
  74. package/dist/photon-doc-extractor.js.map +1 -1
  75. package/dist/photons/maker.photon.d.ts.map +1 -1
  76. package/dist/photons/maker.photon.js +3 -1
  77. package/dist/photons/maker.photon.js.map +1 -1
  78. package/dist/photons/maker.photon.ts +3 -1
  79. package/dist/serv/index.d.ts.map +1 -1
  80. package/dist/serv/index.js.map +1 -1
  81. package/dist/server.d.ts +32 -15
  82. package/dist/server.d.ts.map +1 -1
  83. package/dist/server.js +468 -469
  84. package/dist/server.js.map +1 -1
  85. package/dist/shared/security.d.ts.map +1 -1
  86. package/dist/shared/security.js +4 -8
  87. package/dist/shared/security.js.map +1 -1
  88. package/dist/shell-completions.d.ts +21 -0
  89. package/dist/shell-completions.d.ts.map +1 -0
  90. package/dist/shell-completions.js +102 -0
  91. package/dist/shell-completions.js.map +1 -0
  92. package/dist/template-manager.d.ts.map +1 -1
  93. package/dist/template-manager.js.map +1 -1
  94. package/package.json +10 -6
@@ -385,6 +385,301 @@ export function generateComponentCSS() {
385
385
  color: var(--color-on-surface-variant);
386
386
  }
387
387
 
388
+ /* Metric Component */
389
+ .smart-metric {
390
+ text-align: center;
391
+ padding: var(--space-5) var(--space-4);
392
+ }
393
+
394
+ .smart-metric-value {
395
+ font-size: 3rem;
396
+ font-weight: 700;
397
+ color: var(--color-on-surface);
398
+ line-height: 1.1;
399
+ font-variant-numeric: tabular-nums;
400
+ }
401
+
402
+ .smart-metric-label {
403
+ font-size: var(--text-body-sm);
404
+ color: var(--color-on-surface-variant);
405
+ text-transform: uppercase;
406
+ letter-spacing: 0.08em;
407
+ margin-top: var(--space-1);
408
+ }
409
+
410
+ .smart-metric-delta {
411
+ display: inline-block;
412
+ padding: var(--space-1) var(--space-3);
413
+ border-radius: var(--radius-full);
414
+ font-weight: 600;
415
+ margin-top: var(--space-2);
416
+ }
417
+
418
+ .smart-metric-delta.up { color: var(--color-success); }
419
+ .smart-metric-delta.down { color: var(--color-error); }
420
+
421
+ /* Gauge Component */
422
+ .smart-gauge {
423
+ text-align: center;
424
+ padding: var(--space-4);
425
+ }
426
+
427
+ /* Timeline Component */
428
+ .smart-timeline {
429
+ position: relative;
430
+ padding-left: var(--space-6);
431
+ }
432
+
433
+ .smart-timeline::before {
434
+ content: '';
435
+ position: absolute;
436
+ left: calc(var(--space-2) + 4px);
437
+ top: 0;
438
+ bottom: 0;
439
+ width: 2px;
440
+ background: var(--color-outline-variant);
441
+ }
442
+
443
+ .timeline-item {
444
+ position: relative;
445
+ padding: var(--space-2) 0 var(--space-2) var(--space-4);
446
+ }
447
+
448
+ .timeline-item::before {
449
+ content: '';
450
+ position: absolute;
451
+ left: calc(-1 * var(--space-4));
452
+ top: calc(var(--space-2) + 6px);
453
+ width: 10px;
454
+ height: 10px;
455
+ border-radius: 50%;
456
+ background: var(--color-primary);
457
+ border: 2px solid var(--color-surface);
458
+ }
459
+
460
+ .timeline-item-title {
461
+ font-weight: var(--weight-semibold);
462
+ color: var(--color-on-surface);
463
+ }
464
+
465
+ .timeline-item-time {
466
+ font-size: var(--text-label-sm);
467
+ color: var(--color-on-surface-variant);
468
+ }
469
+
470
+ .timeline-item-description {
471
+ font-size: var(--text-body-sm);
472
+ color: var(--color-on-surface-variant);
473
+ margin-top: var(--space-1);
474
+ }
475
+
476
+ /* Dashboard Component */
477
+ .smart-dashboard {
478
+ display: grid;
479
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
480
+ gap: var(--space-4);
481
+ }
482
+
483
+ .dashboard-panel {
484
+ background: var(--color-surface-container);
485
+ border: 1px solid var(--color-outline-variant);
486
+ border-radius: var(--radius-md);
487
+ overflow: hidden;
488
+ }
489
+
490
+ .dashboard-panel-header {
491
+ padding: var(--space-2) var(--space-3);
492
+ font-size: var(--text-label-sm);
493
+ font-weight: var(--weight-semibold);
494
+ color: var(--color-on-surface-variant);
495
+ text-transform: uppercase;
496
+ letter-spacing: 0.06em;
497
+ border-bottom: 1px solid var(--color-outline-variant);
498
+ }
499
+
500
+ .dashboard-panel-content {
501
+ padding: var(--space-2);
502
+ }
503
+
504
+ /* Cart Component */
505
+ .smart-cart-item {
506
+ display: flex;
507
+ align-items: center;
508
+ gap: 12px;
509
+ padding: 8px 12px;
510
+ border-bottom: 1px solid var(--color-outline-variant, #334155);
511
+ }
512
+
513
+ .smart-cart-item:last-of-type {
514
+ border-bottom: none;
515
+ }
516
+
517
+ .smart-cart-item-image {
518
+ width: 40px;
519
+ height: 40px;
520
+ border-radius: 4px;
521
+ object-fit: cover;
522
+ flex-shrink: 0;
523
+ }
524
+
525
+ .smart-cart-item-info {
526
+ flex: 1;
527
+ min-width: 0;
528
+ }
529
+
530
+ .smart-cart-item-name {
531
+ font-weight: 500;
532
+ }
533
+
534
+ .smart-cart-qty {
535
+ padding: 2px 8px;
536
+ background: rgba(255,255,255,0.05);
537
+ border-radius: 4px;
538
+ font-size: 0.8rem;
539
+ color: #94a3b8;
540
+ }
541
+
542
+ .smart-cart-line-total {
543
+ font-weight: 600;
544
+ font-variant-numeric: tabular-nums;
545
+ min-width: 60px;
546
+ text-align: right;
547
+ }
548
+
549
+ .smart-cart-divider {
550
+ height: 1px;
551
+ background: var(--color-outline-variant, #334155);
552
+ margin: 8px 0;
553
+ }
554
+
555
+ .smart-cart-summary-row {
556
+ display: flex;
557
+ justify-content: space-between;
558
+ padding: 4px 12px;
559
+ font-size: 0.9rem;
560
+ }
561
+
562
+ .smart-cart-summary-row.total {
563
+ font-weight: 700;
564
+ font-size: 1rem;
565
+ padding-top: 8px;
566
+ border-top: 1px solid var(--color-outline-variant, #334155);
567
+ margin-top: 4px;
568
+ }
569
+
570
+ /* Panels Container */
571
+ .smart-panels {
572
+ display: grid;
573
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
574
+ gap: 16px;
575
+ }
576
+
577
+ .smart-panels.cols-2 { grid-template-columns: repeat(2, 1fr); }
578
+ .smart-panels.cols-3 { grid-template-columns: repeat(3, 1fr); }
579
+ .smart-panels.cols-4 { grid-template-columns: repeat(4, 1fr); }
580
+
581
+ .smart-panel {
582
+ border: 1px solid var(--color-outline-variant, #334155);
583
+ border-radius: 8px;
584
+ overflow: hidden;
585
+ }
586
+
587
+ .smart-panel-header {
588
+ padding: 8px 12px;
589
+ font-size: 0.75rem;
590
+ font-weight: 600;
591
+ color: #64748b;
592
+ text-transform: uppercase;
593
+ letter-spacing: 0.06em;
594
+ border-bottom: 1px solid var(--color-outline-variant, #334155);
595
+ }
596
+
597
+ .smart-panel-content {
598
+ padding: 8px;
599
+ }
600
+
601
+ /* Tabs Container */
602
+ .smart-tabs-bar {
603
+ display: flex;
604
+ border-bottom: 1px solid var(--color-outline-variant, #334155);
605
+ margin-bottom: 12px;
606
+ }
607
+
608
+ .smart-tab {
609
+ padding: 8px 16px;
610
+ border-bottom: 2px solid transparent;
611
+ color: #64748b;
612
+ font-weight: 500;
613
+ cursor: pointer;
614
+ }
615
+
616
+ .smart-tab.active {
617
+ color: #6366f1;
618
+ border-bottom-color: #6366f1;
619
+ }
620
+
621
+ .smart-tab-content { display: none; }
622
+ .smart-tab-content.active { display: block; }
623
+
624
+ /* Accordion Container */
625
+ .smart-accordion {
626
+ border: 1px solid var(--color-outline-variant, #334155);
627
+ border-radius: 8px;
628
+ overflow: hidden;
629
+ }
630
+
631
+ .smart-accordion-header {
632
+ display: flex;
633
+ align-items: center;
634
+ justify-content: space-between;
635
+ padding: 8px 12px;
636
+ cursor: pointer;
637
+ background: rgba(255,255,255,0.02);
638
+ font-weight: 500;
639
+ border-bottom: 1px solid var(--color-outline-variant, #334155);
640
+ }
641
+
642
+ .smart-accordion-header:last-child { border-bottom: none; }
643
+ .smart-accordion-body { display: none; padding: 8px 12px; }
644
+ .smart-accordion-body.expanded { display: block; }
645
+
646
+ /* Stack Container */
647
+ .smart-stack {
648
+ display: flex;
649
+ flex-direction: column;
650
+ gap: 12px;
651
+ }
652
+
653
+ .smart-stack-item {
654
+ border: 1px solid var(--color-outline-variant, #334155);
655
+ border-radius: 8px;
656
+ overflow: hidden;
657
+ }
658
+
659
+ .smart-stack-label {
660
+ padding: 6px 12px;
661
+ font-size: 0.75rem;
662
+ font-weight: 600;
663
+ color: #64748b;
664
+ text-transform: uppercase;
665
+ letter-spacing: 0.06em;
666
+ border-bottom: 1px solid var(--color-outline-variant, #334155);
667
+ }
668
+
669
+ .smart-stack-content {
670
+ padding: 8px;
671
+ }
672
+
673
+ /* Columns Container */
674
+ .smart-columns {
675
+ display: grid;
676
+ gap: 16px;
677
+ }
678
+
679
+ .smart-columns.cols-2 { grid-template-columns: repeat(2, 1fr); }
680
+ .smart-columns.cols-3 { grid-template-columns: repeat(3, 1fr); }
681
+ .smart-columns.cols-4 { grid-template-columns: repeat(4, 1fr); }
682
+
388
683
  /* JSON Syntax Highlighting */
389
684
  .json-highlighted {
390
685
  margin: 0;
@@ -500,6 +795,29 @@ function renderSmartResult(data, format, layoutHints) {
500
795
  return typeof data === 'string' ? data : (data?.html || String(data));
501
796
  case 'code':
502
797
  return '<pre class="code-block">' + escapeHtml(String(data)) + '</pre>';
798
+ case 'metric':
799
+ return renderMetric(data);
800
+ case 'gauge':
801
+ return renderGauge(data);
802
+ case 'timeline':
803
+ return renderTimeline(data);
804
+ case 'dashboard':
805
+ return renderDashboard(data);
806
+ case 'cart':
807
+ return renderCart(data);
808
+ case 'panels':
809
+ return renderPanels(data, layoutHints);
810
+ case 'tabs':
811
+ return renderTabs(data, layoutHints);
812
+ case 'accordion':
813
+ return renderAccordion(data, layoutHints);
814
+ case 'stack':
815
+ return renderStack(data, layoutHints);
816
+ case 'columns':
817
+ return renderColumns(data, layoutHints);
818
+ case 'chart':
819
+ // Charts require Chart.js (only in Beam). Fallback to table/JSON in playground.
820
+ return '<pre class="json-highlighted">' + syntaxHighlightJson(data) + '</pre>';
503
821
  case 'json':
504
822
  default:
505
823
  return '<pre class="json-highlighted">' + syntaxHighlightJson(data) + '</pre>';
@@ -768,6 +1086,256 @@ function getStatusClass(value) {
768
1086
  if (/pending|warning|waiting|processing/.test(lower)) return 'status-pending';
769
1087
  return '';
770
1088
  }
1089
+
1090
+ function renderMetric(data) {
1091
+ if (!data || typeof data !== 'object') {
1092
+ if (typeof data === 'number') {
1093
+ return '<div style="text-align:center;padding:24px;"><div style="font-size:3rem;font-weight:700;">' + data.toLocaleString() + '</div></div>';
1094
+ }
1095
+ return '<div>No metric data</div>';
1096
+ }
1097
+ var keys = Object.keys(data);
1098
+ var numericKey = keys.find(function(k) { return typeof data[k] === 'number'; });
1099
+ if (!numericKey) return '<pre class="json-highlighted">' + syntaxHighlightJson(data) + '</pre>';
1100
+ var value = data[numericKey];
1101
+ var label = data.label || data.name || data.title || (numericKey !== 'value' ? formatFieldLabel(numericKey) : '');
1102
+ var delta = data.delta || data.change || data.diff;
1103
+ var html = '<div style="text-align:center;padding:24px;">';
1104
+ html += '<div style="font-size:3rem;font-weight:700;">' + value.toLocaleString() + '</div>';
1105
+ if (label) html += '<div style="font-size:0.85rem;color:#64748b;text-transform:uppercase;letter-spacing:0.08em;margin-top:4px;">' + escapeHtml(label) + '</div>';
1106
+ if (delta) {
1107
+ var color = String(delta).startsWith('+') ? '#16a34a' : String(delta).startsWith('-') ? '#dc2626' : '#64748b';
1108
+ html += '<div style="display:inline-block;padding:2px 10px;border-radius:12px;margin-top:8px;font-weight:600;color:' + color + ';">' + escapeHtml(String(delta)) + '</div>';
1109
+ }
1110
+ html += '</div>';
1111
+ return html;
1112
+ }
1113
+
1114
+ function renderGauge(data) {
1115
+ if (!data || typeof data !== 'object') return '<div>No gauge data</div>';
1116
+ var value, min = 0, max = 100, label;
1117
+ if ('progress' in data && typeof data.progress === 'number') {
1118
+ value = data.progress * 100;
1119
+ label = data.label || 'Progress';
1120
+ } else {
1121
+ value = data.value || 0;
1122
+ min = data.min || 0;
1123
+ max = data.max || 100;
1124
+ label = data.label;
1125
+ }
1126
+ var pct = Math.max(0, Math.min(100, ((value - min) / (max - min)) * 100));
1127
+ var displayVal = data.progress !== undefined ? Math.round(value) + '%' : Math.round(value);
1128
+ var html = '<div style="text-align:center;padding:16px;">';
1129
+ html += '<div style="width:160px;margin:0 auto;">';
1130
+ html += '<div style="position:relative;width:160px;height:12px;background:#334155;border-radius:6px;overflow:hidden;">';
1131
+ html += '<div style="height:100%;width:' + pct + '%;background:linear-gradient(90deg,#22c55e,#eab308,#ef4444);border-radius:6px;transition:width 0.5s;"></div>';
1132
+ html += '</div>';
1133
+ html += '<div style="font-size:1.5rem;font-weight:700;margin-top:8px;">' + displayVal + '</div>';
1134
+ if (label) html += '<div style="font-size:0.8rem;color:#64748b;text-transform:uppercase;">' + escapeHtml(label) + '</div>';
1135
+ html += '</div></div>';
1136
+ return html;
1137
+ }
1138
+
1139
+ function renderTimeline(data) {
1140
+ if (!Array.isArray(data) || data.length === 0) return '<div>No timeline data</div>';
1141
+ var datePattern = /^(date|time|createdAt|updatedAt|created|updated|timestamp)/i;
1142
+ var titlePattern = /^(title|event|name|label|subject|action)/i;
1143
+ var descPattern = /^(description|details|body|content|message|summary)/i;
1144
+ var sample = data[0];
1145
+ var dateField, titleField, descField;
1146
+ var fields = Object.keys(sample);
1147
+ for (var i = 0; i < fields.length; i++) {
1148
+ if (!dateField && datePattern.test(fields[i])) dateField = fields[i];
1149
+ if (!titleField && titlePattern.test(fields[i])) titleField = fields[i];
1150
+ if (!descField && descPattern.test(fields[i])) descField = fields[i];
1151
+ }
1152
+ var html = '<div style="position:relative;padding-left:24px;">';
1153
+ html += '<div style="position:absolute;left:9px;top:0;bottom:0;width:2px;background:#334155;"></div>';
1154
+ for (var j = 0; j < data.length; j++) {
1155
+ var item = data[j];
1156
+ html += '<div style="position:relative;padding:8px 0 8px 16px;">';
1157
+ html += '<div style="position:absolute;left:-4px;top:14px;width:10px;height:10px;border-radius:50%;background:#6366f1;border:2px solid #0f172a;z-index:1;"></div>';
1158
+ if (titleField) html += '<div style="font-weight:600;">' + escapeHtml(String(item[titleField])) + '</div>';
1159
+ if (dateField) {
1160
+ try { html += '<div style="font-size:0.75rem;color:#64748b;">' + new Date(item[dateField]).toLocaleString() + '</div>'; }
1161
+ catch(e) { html += '<div style="font-size:0.75rem;color:#64748b;">' + escapeHtml(String(item[dateField])) + '</div>'; }
1162
+ }
1163
+ if (descField && item[descField]) html += '<div style="font-size:0.85rem;color:#94a3b8;margin-top:4px;">' + escapeHtml(String(item[descField])) + '</div>';
1164
+ html += '</div>';
1165
+ }
1166
+ html += '</div>';
1167
+ return html;
1168
+ }
1169
+
1170
+ function renderDashboard(data) {
1171
+ if (!data || typeof data !== 'object') return '<div>No dashboard data</div>';
1172
+ var keys = Object.keys(data);
1173
+ var html = '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px;">';
1174
+ for (var i = 0; i < keys.length; i++) {
1175
+ var key = keys[i];
1176
+ var val = data[key];
1177
+ html += '<div style="border:1px solid #334155;border-radius:8px;overflow:hidden;">';
1178
+ html += '<div style="padding:8px 12px;font-size:0.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:0.06em;border-bottom:1px solid #334155;">' + formatFieldLabel(key) + '</div>';
1179
+ html += '<div style="padding:8px;">';
1180
+ if (typeof val === 'number') {
1181
+ html += '<div style="text-align:center;padding:16px;font-size:2rem;font-weight:700;">' + val.toLocaleString() + '</div>';
1182
+ } else if (Array.isArray(val)) {
1183
+ html += renderSmartResult(val, null, null);
1184
+ } else if (typeof val === 'object' && val !== null) {
1185
+ if ('value' in val && typeof val.value === 'number') {
1186
+ html += renderMetric(val);
1187
+ } else if ('progress' in val && typeof val.progress === 'number') {
1188
+ html += renderGauge(val);
1189
+ } else {
1190
+ html += renderSmartResult(val, null, null);
1191
+ }
1192
+ } else {
1193
+ html += '<div style="padding:8px;">' + escapeHtml(String(val)) + '</div>';
1194
+ }
1195
+ html += '</div></div>';
1196
+ }
1197
+ html += '</div>';
1198
+ return html;
1199
+ }
1200
+
1201
+ function renderInnerContent(data, innerLayout) {
1202
+ if (innerLayout) {
1203
+ return renderSmartResult(data, innerLayout, null);
1204
+ }
1205
+ // Auto-detect
1206
+ return renderSmartResult(data, null, null);
1207
+ }
1208
+
1209
+ function renderCart(data) {
1210
+ if (!data) return '<div>No cart data</div>';
1211
+ var items, summary = {};
1212
+ if (Array.isArray(data)) {
1213
+ items = data;
1214
+ } else {
1215
+ items = data.items || [];
1216
+ for (var k in data) {
1217
+ if (k !== 'items' && typeof data[k] === 'number') summary[k] = data[k];
1218
+ }
1219
+ }
1220
+ if (items.length === 0) return '<div>Cart is empty</div>';
1221
+ var computedTotal = 0;
1222
+ for (var i = 0; i < items.length; i++) {
1223
+ var qty = items[i].quantity || items[i].qty || 1;
1224
+ computedTotal += (items[i].price || 0) * qty;
1225
+ }
1226
+ if (Object.keys(summary).length === 0) summary = { total: computedTotal };
1227
+ var html = '<div>';
1228
+ for (var i = 0; i < items.length; i++) {
1229
+ var item = items[i];
1230
+ var qty = item.quantity || item.qty || 1;
1231
+ var lineTotal = (item.price || 0) * qty;
1232
+ var name = item.name || item.title || item.label || item.product || 'Item';
1233
+ html += '<div class="smart-cart-item">';
1234
+ if (item.image) html += '<img class="smart-cart-item-image" src="' + escapeHtml(item.image) + '" alt="">';
1235
+ html += '<div class="smart-cart-item-info"><div class="smart-cart-item-name">' + escapeHtml(name) + '</div></div>';
1236
+ if (qty > 1) html += '<span class="smart-cart-qty">&times;' + qty + '</span>';
1237
+ html += '<span class="smart-cart-line-total">$' + lineTotal.toFixed(2) + '</span>';
1238
+ html += '</div>';
1239
+ }
1240
+ html += '<div class="smart-cart-divider"></div>';
1241
+ var summaryKeys = Object.keys(summary);
1242
+ for (var i = 0; i < summaryKeys.length; i++) {
1243
+ var sk = summaryKeys[i];
1244
+ var isTotal = sk.toLowerCase() === 'total';
1245
+ html += '<div class="smart-cart-summary-row' + (isTotal ? ' total' : '') + '">';
1246
+ html += '<span>' + formatFieldLabel(sk) + '</span>';
1247
+ html += '<span>$' + summary[sk].toFixed(2) + '</span>';
1248
+ html += '</div>';
1249
+ }
1250
+ html += '</div>';
1251
+ return html;
1252
+ }
1253
+
1254
+ function renderPanels(data, layoutHints) {
1255
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return '<div>Panels require an object</div>';
1256
+ var keys = Object.keys(data);
1257
+ var cols = layoutHints && layoutHints.columns ? parseInt(layoutHints.columns) : 0;
1258
+ var colsClass = cols >= 2 && cols <= 4 ? ' cols-' + cols : '';
1259
+ var inner = layoutHints ? layoutHints.inner : null;
1260
+ var html = '<div class="smart-panels' + colsClass + '">';
1261
+ for (var i = 0; i < keys.length; i++) {
1262
+ html += '<div class="smart-panel">';
1263
+ html += '<div class="smart-panel-header">' + formatFieldLabel(keys[i]) + '</div>';
1264
+ html += '<div class="smart-panel-content">' + renderInnerContent(data[keys[i]], inner) + '</div>';
1265
+ html += '</div>';
1266
+ }
1267
+ html += '</div>';
1268
+ return html;
1269
+ }
1270
+
1271
+ function renderTabs(data, layoutHints) {
1272
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return '<div>Tabs require an object</div>';
1273
+ var keys = Object.keys(data);
1274
+ var inner = layoutHints ? layoutHints.inner : null;
1275
+ var tabId = 'tabs-' + Math.random().toString(36).slice(2, 8);
1276
+ var html = '<div>';
1277
+ html += '<div class="smart-tabs-bar">';
1278
+ for (var i = 0; i < keys.length; i++) {
1279
+ html += '<div class="smart-tab' + (i === 0 ? ' active' : '') + '" onclick="(function(el){var bar=el.parentElement;var tabs=bar.parentElement.querySelectorAll(\\'.smart-tab-content\\');bar.querySelectorAll(\\'.smart-tab\\').forEach(function(t){t.classList.remove(\\'active\\')});el.classList.add(\\'active\\');tabs.forEach(function(t){t.classList.remove(\\'active\\')});tabs[' + i + '].classList.add(\\'active\\');})(this)">' + formatFieldLabel(keys[i]) + '</div>';
1280
+ }
1281
+ html += '</div>';
1282
+ for (var i = 0; i < keys.length; i++) {
1283
+ html += '<div class="smart-tab-content' + (i === 0 ? ' active' : '') + '">';
1284
+ html += renderInnerContent(data[keys[i]], inner);
1285
+ html += '</div>';
1286
+ }
1287
+ html += '</div>';
1288
+ return html;
1289
+ }
1290
+
1291
+ function renderAccordion(data, layoutHints) {
1292
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return '<div>Accordion requires an object</div>';
1293
+ var keys = Object.keys(data);
1294
+ var inner = layoutHints ? layoutHints.inner : null;
1295
+ var html = '<div class="smart-accordion">';
1296
+ for (var i = 0; i < keys.length; i++) {
1297
+ var bodyId = 'acc-' + Math.random().toString(36).slice(2, 8);
1298
+ html += '<div class="smart-accordion-header" onclick="var b=document.getElementById(\\'' + bodyId + '\\');b.classList.toggle(\\'expanded\\')">';
1299
+ html += '<span>' + formatFieldLabel(keys[i]) + '</span><span>&#x25B6;</span>';
1300
+ html += '</div>';
1301
+ html += '<div id="' + bodyId + '" class="smart-accordion-body' + (i === 0 ? ' expanded' : '') + '">';
1302
+ html += renderInnerContent(data[keys[i]], inner);
1303
+ html += '</div>';
1304
+ }
1305
+ html += '</div>';
1306
+ return html;
1307
+ }
1308
+
1309
+ function renderStack(data, layoutHints) {
1310
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return '<div>Stack requires an object</div>';
1311
+ var keys = Object.keys(data);
1312
+ var inner = layoutHints ? layoutHints.inner : null;
1313
+ var html = '<div class="smart-stack">';
1314
+ for (var i = 0; i < keys.length; i++) {
1315
+ html += '<div class="smart-stack-item">';
1316
+ html += '<div class="smart-stack-label">' + formatFieldLabel(keys[i]) + '</div>';
1317
+ html += '<div class="smart-stack-content">' + renderInnerContent(data[keys[i]], inner) + '</div>';
1318
+ html += '</div>';
1319
+ }
1320
+ html += '</div>';
1321
+ return html;
1322
+ }
1323
+
1324
+ function renderColumns(data, layoutHints) {
1325
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return '<div>Columns require an object</div>';
1326
+ var keys = Object.keys(data);
1327
+ var cols = layoutHints && layoutHints.columns ? Math.min(Math.max(parseInt(layoutHints.columns), 2), 4) : Math.min(keys.length, 4);
1328
+ var inner = layoutHints ? layoutHints.inner : null;
1329
+ var html = '<div class="smart-columns cols-' + cols + '">';
1330
+ for (var i = 0; i < keys.length; i++) {
1331
+ html += '<div>';
1332
+ html += '<div style="font-size:0.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:0.06em;margin-bottom:4px;">' + formatFieldLabel(keys[i]) + '</div>';
1333
+ html += renderInnerContent(data[keys[i]], inner);
1334
+ html += '</div>';
1335
+ }
1336
+ html += '</div>';
1337
+ return html;
1338
+ }
771
1339
  `;
772
1340
  }
773
1341
  //# sourceMappingURL=components.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","sourceRoot":"","sources":["../../../src/auto-ui/rendering/components.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAaH;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+YR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8VR,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../../../src/auto-ui/rendering/components.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAaH;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsrBR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+mBR,CAAC;AACF,CAAC"}
@@ -41,6 +41,62 @@ export declare function formatFieldLabel(field: string): string;
41
41
  * Get the best display value for a field
42
42
  */
43
43
  export declare function getDisplayValue(value: any, typeHint?: string): string;
44
+ /**
45
+ * Count numeric fields in an object
46
+ */
47
+ export declare function countNumericFields(obj: object): number;
48
+ /**
49
+ * Check if object has date-like fields (by name or value)
50
+ */
51
+ export declare function hasDateFields(obj: object): boolean;
52
+ /**
53
+ * Check if object has numeric fields
54
+ */
55
+ export declare function hasNumericFields(obj: object): boolean;
56
+ /**
57
+ * Get the names of string fields in an object
58
+ */
59
+ export declare function getStringFields(obj: object): string[];
60
+ /**
61
+ * Get the names of numeric fields in an object
62
+ */
63
+ export declare function getNumericFields(obj: object): string[];
64
+ /**
65
+ * Get date field names from an object (by name pattern or ISO value)
66
+ */
67
+ export declare function getDateFields(obj: object): string[];
68
+ /**
69
+ * Check if data looks like a single metric (KPI)
70
+ * Patterns: { value: 1234 }, { value: 1234, label: "Users" }, { value: 1234, delta: "+12%" }
71
+ */
72
+ export declare function isMetricShaped(data: any): boolean;
73
+ /**
74
+ * Check if data looks like a gauge value
75
+ * Patterns: { value: 73, max: 100 }, { progress: 0.73 }
76
+ */
77
+ export declare function isGaugeShaped(data: any): boolean;
78
+ /**
79
+ * Check if array data is chart-shaped
80
+ * Conservative: only returns true for clearly chart-like data
81
+ */
82
+ export declare function isChartShaped(data: any[]): boolean;
83
+ /**
84
+ * Check if array data is timeline-shaped
85
+ * Requires: date field + title/event/description field, 3+ items
86
+ */
87
+ export declare function isTimelineShaped(data: any[]): boolean;
88
+ /**
89
+ * Check if object data is dashboard-shaped
90
+ * Object where values are a mix of metrics, arrays, and objects (3+ keys)
91
+ */
92
+ export declare function isDashboardShaped(data: any): boolean;
93
+ /**
94
+ * Check if data looks like a shopping cart
95
+ * Patterns:
96
+ * - Array where all items have price + (quantity | qty)
97
+ * - Object with items array where items have price + (quantity | qty)
98
+ */
99
+ export declare function isCartShaped(data: any): boolean;
44
100
  /**
45
101
  * Generate JavaScript code for field analyzer (to embed in HTML)
46
102
  */
@@ -1 +1 @@
1
- {"version":3,"file":"field-analyzer.d.ts","sourceRoot":"","sources":["../../../src/auto-ui/rendering/field-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;CACrF;AAyBD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,YAAY,CAgCnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,aAAa,EAAE,CA4CzE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAajD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAqBrE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAuGhD"}
1
+ {"version":3,"file":"field-analyzer.d.ts","sourceRoot":"","sources":["../../../src/auto-ui/rendering/field-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;CACrF;AAyBD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,YAAY,CAgCnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,aAAa,EAAE,CA4CzE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAajD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAqBrE;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAMlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAIrD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAItD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAQnD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAYjD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAQhD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAmBlD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAerD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAqBpD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CA0B/C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAuGhD"}