treesap 0.1.9 → 0.1.11

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 (37) hide show
  1. package/dist/components/ChatInput.d.ts +7 -0
  2. package/dist/components/ChatInput.d.ts.map +1 -0
  3. package/dist/components/ChatInput.js +11 -0
  4. package/dist/components/ChatInput.js.map +1 -0
  5. package/dist/components/Sidebar.d.ts +8 -0
  6. package/dist/components/Sidebar.d.ts.map +1 -0
  7. package/dist/components/Sidebar.js +7 -0
  8. package/dist/components/Sidebar.js.map +1 -0
  9. package/dist/components/SimpleLivePreview.js +1 -1
  10. package/dist/components/SimpleLivePreview.js.map +1 -1
  11. package/dist/pages/Code.d.ts.map +1 -1
  12. package/dist/pages/Code.js +2 -2
  13. package/dist/pages/Code.js.map +1 -1
  14. package/dist/services/websocket.d.ts.map +1 -1
  15. package/dist/services/websocket.js +1 -2
  16. package/dist/services/websocket.js.map +1 -1
  17. package/dist/static/components/ChatInput.js +237 -0
  18. package/dist/static/components/Sidebar.js +225 -0
  19. package/dist/static/components/SimpleLivePreview.js +73 -53
  20. package/dist/static/components/Terminal.js +143 -61
  21. package/dist/static/signals/SidebarSignal.js +123 -0
  22. package/dist/static/signals/TerminalSignal.js +137 -2
  23. package/dist/static/styles/main.css +180 -0
  24. package/package.json +1 -1
  25. package/src/components/ChatInput.tsx +56 -0
  26. package/src/components/Sidebar.tsx +99 -0
  27. package/src/components/SimpleLivePreview.tsx +4 -4
  28. package/src/pages/Code.tsx +18 -55
  29. package/src/services/websocket.ts +1 -5
  30. package/src/static/components/ChatInput.js +237 -0
  31. package/src/static/components/Sidebar.js +225 -0
  32. package/src/static/components/SimpleLivePreview.js +73 -53
  33. package/src/static/components/Terminal.js +143 -61
  34. package/src/static/signals/SidebarSignal.js +123 -0
  35. package/src/static/signals/TerminalSignal.js +137 -2
  36. package/src/static/styles/main.css +180 -0
  37. package/tailwind.config.ts +10 -0
@@ -1093,6 +1093,10 @@ video {
1093
1093
  margin-bottom: 0;
1094
1094
  }
1095
1095
 
1096
+ .pointer-events-none {
1097
+ pointer-events: none;
1098
+ }
1099
+
1096
1100
  .visible {
1097
1101
  visibility: visible;
1098
1102
  }
@@ -1101,6 +1105,10 @@ video {
1101
1105
  position: static;
1102
1106
  }
1103
1107
 
1108
+ .fixed {
1109
+ position: fixed;
1110
+ }
1111
+
1104
1112
  .absolute {
1105
1113
  position: absolute;
1106
1114
  }
@@ -1109,10 +1117,38 @@ video {
1109
1117
  position: relative;
1110
1118
  }
1111
1119
 
1120
+ .inset-0 {
1121
+ inset: 0px;
1122
+ }
1123
+
1124
+ .left-0 {
1125
+ left: 0px;
1126
+ }
1127
+
1128
+ .left-4 {
1129
+ left: 1rem;
1130
+ }
1131
+
1132
+ .top-0 {
1133
+ top: 0px;
1134
+ }
1135
+
1136
+ .top-4 {
1137
+ top: 1rem;
1138
+ }
1139
+
1140
+ .z-40 {
1141
+ z-index: 40;
1142
+ }
1143
+
1112
1144
  .z-50 {
1113
1145
  z-index: 50;
1114
1146
  }
1115
1147
 
1148
+ .z-60 {
1149
+ z-index: 60;
1150
+ }
1151
+
1116
1152
  .mb-12 {
1117
1153
  margin-bottom: 3rem;
1118
1154
  }
@@ -1185,6 +1221,14 @@ video {
1185
1221
  height: 100vh;
1186
1222
  }
1187
1223
 
1224
+ .max-h-\[120px\] {
1225
+ max-height: 120px;
1226
+ }
1227
+
1228
+ .min-h-\[40px\] {
1229
+ min-height: 40px;
1230
+ }
1231
+
1188
1232
  .min-h-screen {
1189
1233
  min-height: 100vh;
1190
1234
  }
@@ -1217,6 +1261,20 @@ video {
1217
1261
  flex-shrink: 0;
1218
1262
  }
1219
1263
 
1264
+ .-translate-x-full {
1265
+ --tw-translate-x: -100%;
1266
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1267
+ }
1268
+
1269
+ .translate-x-0 {
1270
+ --tw-translate-x: 0px;
1271
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1272
+ }
1273
+
1274
+ .transform {
1275
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1276
+ }
1277
+
1220
1278
  @keyframes spin {
1221
1279
  to {
1222
1280
  transform: rotate(360deg);
@@ -1231,6 +1289,10 @@ video {
1231
1289
  cursor: not-allowed;
1232
1290
  }
1233
1291
 
1292
+ .resize-none {
1293
+ resize: none;
1294
+ }
1295
+
1234
1296
  .resize {
1235
1297
  resize: both;
1236
1298
  }
@@ -1239,6 +1301,10 @@ video {
1239
1301
  flex-direction: column;
1240
1302
  }
1241
1303
 
1304
+ .items-end {
1305
+ align-items: flex-end;
1306
+ }
1307
+
1242
1308
  .items-center {
1243
1309
  align-items: center;
1244
1310
  }
@@ -1296,6 +1362,10 @@ video {
1296
1362
  border-right-width: 1px;
1297
1363
  }
1298
1364
 
1365
+ .border-t {
1366
+ border-top-width: 1px;
1367
+ }
1368
+
1299
1369
  .border-t-2 {
1300
1370
  border-top-width: 2px;
1301
1371
  }
@@ -1320,6 +1390,11 @@ video {
1320
1390
  border-color: rgb(156 163 175 / var(--tw-border-opacity, 1));
1321
1391
  }
1322
1392
 
1393
+ .bg-\[\#0e639c\] {
1394
+ --tw-bg-opacity: 1;
1395
+ background-color: rgb(14 99 156 / var(--tw-bg-opacity, 1));
1396
+ }
1397
+
1323
1398
  .bg-\[\#1e1e1e\] {
1324
1399
  --tw-bg-opacity: 1;
1325
1400
  background-color: rgb(30 30 30 / var(--tw-bg-opacity, 1));
@@ -1330,6 +1405,11 @@ video {
1330
1405
  background-color: rgb(37 37 38 / var(--tw-bg-opacity, 1));
1331
1406
  }
1332
1407
 
1408
+ .bg-\[\#28a745\] {
1409
+ --tw-bg-opacity: 1;
1410
+ background-color: rgb(40 167 69 / var(--tw-bg-opacity, 1));
1411
+ }
1412
+
1333
1413
  .bg-\[\#2a2a2a\] {
1334
1414
  --tw-bg-opacity: 1;
1335
1415
  background-color: rgb(42 42 42 / var(--tw-bg-opacity, 1));
@@ -1359,6 +1439,10 @@ video {
1359
1439
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
1360
1440
  }
1361
1441
 
1442
+ .bg-opacity-50 {
1443
+ --tw-bg-opacity: 0.5;
1444
+ }
1445
+
1362
1446
  .bg-gradient-to-br {
1363
1447
  background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
1364
1448
  }
@@ -1416,6 +1500,10 @@ video {
1416
1500
  text-align: center;
1417
1501
  }
1418
1502
 
1503
+ .font-mono {
1504
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
1505
+ }
1506
+
1419
1507
  .font-sans {
1420
1508
  font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
1421
1509
  }
@@ -1491,6 +1579,24 @@ video {
1491
1579
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
1492
1580
  }
1493
1581
 
1582
+ .placeholder-\[\#888\]::-moz-placeholder {
1583
+ --tw-placeholder-opacity: 1;
1584
+ color: rgb(136 136 136 / var(--tw-placeholder-opacity, 1));
1585
+ }
1586
+
1587
+ .placeholder-\[\#888\]::placeholder {
1588
+ --tw-placeholder-opacity: 1;
1589
+ color: rgb(136 136 136 / var(--tw-placeholder-opacity, 1));
1590
+ }
1591
+
1592
+ .opacity-0 {
1593
+ opacity: 0;
1594
+ }
1595
+
1596
+ .opacity-100 {
1597
+ opacity: 1;
1598
+ }
1599
+
1494
1600
  .opacity-50 {
1495
1601
  opacity: 0.5;
1496
1602
  }
@@ -1505,6 +1611,12 @@ video {
1505
1611
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
1506
1612
  }
1507
1613
 
1614
+ .backdrop-blur-sm {
1615
+ --tw-backdrop-blur: blur(4px);
1616
+ -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
1617
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
1618
+ }
1619
+
1508
1620
  .transition-all {
1509
1621
  transition-property: all;
1510
1622
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
@@ -1517,10 +1629,26 @@ video {
1517
1629
  transition-duration: 150ms;
1518
1630
  }
1519
1631
 
1632
+ .transition-opacity {
1633
+ transition-property: opacity;
1634
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1635
+ transition-duration: 150ms;
1636
+ }
1637
+
1638
+ .transition-transform {
1639
+ transition-property: transform;
1640
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1641
+ transition-duration: 150ms;
1642
+ }
1643
+
1520
1644
  .duration-300 {
1521
1645
  transition-duration: 300ms;
1522
1646
  }
1523
1647
 
1648
+ .ease-in-out {
1649
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1650
+ }
1651
+
1524
1652
  .focus-within\:border-\[\#0e639c\]:focus-within {
1525
1653
  --tw-border-opacity: 1;
1526
1654
  border-color: rgb(14 99 156 / var(--tw-border-opacity, 1));
@@ -1531,6 +1659,16 @@ video {
1531
1659
  border-color: rgb(14 99 156 / var(--tw-border-opacity, 1));
1532
1660
  }
1533
1661
 
1662
+ .hover\:bg-\[\#1177bb\]:hover {
1663
+ --tw-bg-opacity: 1;
1664
+ background-color: rgb(17 119 187 / var(--tw-bg-opacity, 1));
1665
+ }
1666
+
1667
+ .hover\:bg-\[\#218838\]:hover {
1668
+ --tw-bg-opacity: 1;
1669
+ background-color: rgb(33 136 56 / var(--tw-bg-opacity, 1));
1670
+ }
1671
+
1534
1672
  .hover\:bg-\[\#2d2d30\]:hover {
1535
1673
  --tw-bg-opacity: 1;
1536
1674
  background-color: rgb(45 45 48 / var(--tw-bg-opacity, 1));
@@ -1567,12 +1705,54 @@ video {
1567
1705
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1568
1706
  }
1569
1707
 
1708
+ .focus\:border-\[\#0e639c\]:focus {
1709
+ --tw-border-opacity: 1;
1710
+ border-color: rgb(14 99 156 / var(--tw-border-opacity, 1));
1711
+ }
1712
+
1570
1713
  .focus\:outline-none:focus {
1571
1714
  outline: 2px solid transparent;
1572
1715
  outline-offset: 2px;
1573
1716
  }
1574
1717
 
1718
+ .disabled\:bg-\[\#3c3c3c\]:disabled {
1719
+ --tw-bg-opacity: 1;
1720
+ background-color: rgb(60 60 60 / var(--tw-bg-opacity, 1));
1721
+ }
1722
+
1723
+ .disabled\:text-\[\#888\]:disabled {
1724
+ --tw-text-opacity: 1;
1725
+ color: rgb(136 136 136 / var(--tw-text-opacity, 1));
1726
+ }
1727
+
1575
1728
  .group:hover .group-hover\:text-white {
1576
1729
  --tw-text-opacity: 1;
1577
1730
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
1578
1731
  }
1732
+
1733
+ @media (min-width: 768px) {
1734
+ .md\:relative {
1735
+ position: relative;
1736
+ }
1737
+
1738
+ .md\:z-auto {
1739
+ z-index: auto;
1740
+ }
1741
+
1742
+ .md\:hidden {
1743
+ display: none;
1744
+ }
1745
+
1746
+ .md\:w-2\/5 {
1747
+ width: 40%;
1748
+ }
1749
+
1750
+ .md\:flex-1 {
1751
+ flex: 1 1 0%;
1752
+ }
1753
+
1754
+ .md\:translate-x-0 {
1755
+ --tw-translate-x: 0px;
1756
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1757
+ }
1758
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "treesap",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "AI Agent Framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,56 @@
1
+ interface ChatInputProps {
2
+ id?: string;
3
+ terminalId?: string;
4
+ }
5
+
6
+ export function ChatInput({ id = "chat-input", terminalId = "terminal-1" }: ChatInputProps) {
7
+ return (
8
+ <sapling-island loading="visible">
9
+ <template>
10
+ <script type="module" src="/components/ChatInput.js"></script>
11
+ </template>
12
+
13
+ <div id={id} class="border-t border-[#3c3c3c] bg-[#2d2d30] p-3">
14
+ <div class="flex items-end gap-2">
15
+ {/* Textarea for multi-line input */}
16
+ <div class="flex-1 relative">
17
+ <textarea
18
+ id={`${id}-textarea`}
19
+ placeholder="Type your command or message..."
20
+ class="w-full min-h-[40px] max-h-[120px] px-3 py-2 bg-[#1e1e1e] border border-[#3c3c3c] rounded-lg text-[#cccccc] placeholder-[#888] resize-none focus:outline-none focus:border-[#0e639c] transition-colors text-sm font-mono"
21
+ rows={1}
22
+ ></textarea>
23
+ </div>
24
+
25
+ {/* Send to Input button */}
26
+ <button
27
+ type="button"
28
+ id={`${id}-send-btn`}
29
+ class="px-3 py-2 bg-[#0e639c] hover:bg-[#1177bb] disabled:bg-[#3c3c3c] disabled:text-[#888] text-white rounded-lg transition-colors flex-shrink-0 flex items-center justify-center min-h-[40px]"
30
+ title="Send to Input Field"
31
+ >
32
+ <iconify-icon icon="tabler:arrow-up" width="16" height="16"></iconify-icon>
33
+ </button>
34
+
35
+ {/* Execute button */}
36
+ <button
37
+ type="button"
38
+ id={`${id}-execute-btn`}
39
+ class="px-3 py-2 bg-[#28a745] hover:bg-[#218838] disabled:bg-[#3c3c3c] disabled:text-[#888] text-white rounded-lg transition-colors flex-shrink-0 flex items-center justify-center min-h-[40px]"
40
+ title="Execute Command"
41
+ >
42
+ <iconify-icon icon="tabler:player-play" width="16" height="16"></iconify-icon>
43
+ </button>
44
+ </div>
45
+ </div>
46
+
47
+ <script dangerouslySetInnerHTML={{__html: `
48
+ // Pass chat input data to JavaScript
49
+ window.chatInputData_${id.replace(/-/g, '_')} = {
50
+ chatInputId: '${id}',
51
+ terminalId: '${terminalId}'
52
+ };
53
+ `}}></script>
54
+ </sapling-island>
55
+ );
56
+ }
@@ -0,0 +1,99 @@
1
+ import { Terminal as TerminalComponent } from "./Terminal.js";
2
+ import { ChatInput } from "./ChatInput.js";
3
+
4
+ interface SidebarProps {
5
+ id?: string;
6
+ previewPort?: number;
7
+ workingDirectory?: string;
8
+ }
9
+
10
+ export function Sidebar({ id = "sidebar", previewPort = 1234, workingDirectory }: SidebarProps) {
11
+ return (
12
+ <sapling-island loading="visible">
13
+ <template>
14
+ <script type="module" src="https://code.iconify.design/iconify-icon/2.0.0/iconify-icon.min.js"></script>
15
+ <script type="module" src="/components/Sidebar.js"></script>
16
+ </template>
17
+
18
+ {/* Mobile backdrop */}
19
+ <div
20
+ id={`${id}-backdrop`}
21
+ class="fixed inset-0 bg-black bg-opacity-50 backdrop-blur-sm z-40 transition-opacity duration-300 opacity-0 pointer-events-none md:hidden"
22
+ ></div>
23
+
24
+ {/* Sidebar container */}
25
+ <div
26
+ id={`${id}-pane`}
27
+ class="fixed left-0 top-0 h-full w-full z-50 transform -translate-x-full transition-transform duration-300 ease-in-out md:relative md:translate-x-0 md:w-2/5 md:z-auto border-r border-[#3c3c3c] flex flex-col bg-[#252526]"
28
+ >
29
+ {/* Preview Controls */}
30
+ <div class="p-3 border-b border-[#3c3c3c] bg-[#2d2d30] flex-shrink-0">
31
+ <div class="flex items-center gap-2">
32
+ {/* Mobile close button */}
33
+ <button
34
+ type="button"
35
+ id={`${id}-close-btn`}
36
+ class="p-2 hover:bg-[#3c3c3c] rounded-md transition-colors flex-shrink-0 text-[#cccccc] hover:text-white md:hidden"
37
+ title="Close Sidebar"
38
+ >
39
+ <iconify-icon icon="tabler:x" width="16" height="16"></iconify-icon>
40
+ </button>
41
+
42
+ {/* Back to Home */}
43
+ <a
44
+ href="/"
45
+ class="p-2 hover:bg-[#3c3c3c] rounded-md transition-colors flex-shrink-0 text-[#cccccc] hover:text-white"
46
+ title="Back to Home"
47
+ >
48
+ <iconify-icon icon="tabler:arrow-left" width="16" height="16"></iconify-icon>
49
+ </a>
50
+
51
+ {/* Refresh button */}
52
+ <button
53
+ type="button"
54
+ id="live-preview-refresh-btn"
55
+ class="p-2 hover:bg-[#3c3c3c] rounded-md transition-colors flex-shrink-0 text-[#cccccc] hover:text-white"
56
+ title="Reload"
57
+ >
58
+ <iconify-icon icon="tabler:refresh" width="16" height="16"></iconify-icon>
59
+ </button>
60
+
61
+ {/* URL input */}
62
+ <div class="flex-1 flex items-center bg-[#1e1e1e] border border-[#3c3c3c] rounded px-3 py-2 hover:border-[#0e639c] focus-within:border-[#0e639c] transition-all">
63
+ <iconify-icon icon="tabler:world" width="16" height="16" class="text-[#cccccc] mr-2"></iconify-icon>
64
+ <span class="text-[#cccccc] text-sm">localhost:{previewPort}/</span>
65
+ <input
66
+ id="live-preview-url-input"
67
+ type="text"
68
+ placeholder="path"
69
+ defaultValue=""
70
+ class="flex-1 bg-transparent text-sm focus:outline-none text-[#cccccc] ml-1"
71
+ />
72
+ <button
73
+ type="button"
74
+ id="live-preview-load-btn"
75
+ class="ml-2 p-1 hover:bg-[#3c3c3c] rounded transition-colors flex-shrink-0 text-[#cccccc] hover:text-white"
76
+ title="Go"
77
+ >
78
+ <iconify-icon icon="tabler:chevron-right" width="16" height="16"></iconify-icon>
79
+ </button>
80
+ </div>
81
+ </div>
82
+ </div>
83
+
84
+ {/* Terminal Content */}
85
+ <div class="flex-1 overflow-hidden bg-[#1e1e1e] flex flex-col">
86
+ {/* Terminal Display */}
87
+ <div class="flex-1 overflow-hidden">
88
+ <TerminalComponent index={1} />
89
+ </div>
90
+
91
+ {/* Chat Input */}
92
+ <div class="flex-shrink-0">
93
+ <ChatInput id="chat-input" terminalId="terminal-1" />
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </sapling-island>
98
+ );
99
+ }
@@ -25,14 +25,14 @@ export function SimpleLivePreview({ id = "simple-preview", previewPort = 5173 }:
25
25
  data-preview-port={previewPort}
26
26
  ></iframe>
27
27
 
28
- {/* Floating Sidebar Toggle */}
28
+ {/* Floating Sidebar Toggle - Only show when sidebar is closed */}
29
29
  <button
30
30
  id={`${id}-floating-hide-sidebar-btn`}
31
- class="absolute p-3 bg-white border-2 border-gray-400 rounded-lg shadow-xl hover:bg-gray-50 hover:shadow-2xl transition-all flex items-center justify-center z-50"
32
- title="Toggle Sidebar"
31
+ class="absolute p-3 bg-white border-2 border-gray-400 rounded-lg shadow-xl hover:bg-gray-50 hover:shadow-2xl transition-all items-center justify-center z-50 hidden"
32
+ title="Show Sidebar"
33
33
  style="position: absolute !important; z-index: 9999 !important; bottom: 16px; left: 16px;"
34
34
  >
35
- <iconify-icon id={`${id}-floating-hide-sidebar-icon`} icon="ph:sidebar-simple" width="20" height="20" class="text-gray-800"></iconify-icon>
35
+ <iconify-icon id={`${id}-floating-hide-sidebar-icon`} icon="ph:sidebar-simple-fill" width="20" height="20" class="text-gray-800"></iconify-icon>
36
36
  </button>
37
37
  </div>
38
38
  </sapling-island>
@@ -1,5 +1,5 @@
1
1
  import Layout from "../layouts/Layout.js";
2
- import { Terminal as TerminalComponent } from "../components/Terminal.js";
2
+ import { Sidebar } from "../components/Sidebar.js";
3
3
  import { SimpleLivePreview } from "../components/SimpleLivePreview.js";
4
4
 
5
5
  interface TerminalProps {
@@ -10,61 +10,24 @@ interface TerminalProps {
10
10
  export function Code({ previewPort = 1234, workingDirectory }: TerminalProps) {
11
11
  return (
12
12
  <Layout title="Code Editor">
13
- <div id="code-container" class="h-screen flex bg-[#1e1e1e]">
14
- {/* Left Pane - Tabbed Sidebar */}
15
- <div id="sidebar-pane" class="w-2/5-plus border-r border-[#3c3c3c] transition-all duration-300 flex flex-col bg-[#252526]">
16
- {/* Preview Controls */}
17
- <div class="p-3 border-b border-[#3c3c3c] bg-[#2d2d30]">
18
- <div class="flex items-center gap-2">
19
- <a
20
- href="/"
21
- class="p-2 hover:bg-[#3c3c3c] rounded-md transition-colors flex-shrink-0 text-[#cccccc] hover:text-white"
22
- title="Back to Home"
23
- >
24
- <iconify-icon icon="tabler:arrow-left" width="16" height="16"></iconify-icon>
25
- </a>
26
- <button
27
- type="button"
28
- id="live-preview-refresh-btn"
29
- class="p-2 hover:bg-[#3c3c3c] rounded-md transition-colors flex-shrink-0 text-[#cccccc] hover:text-white"
30
- title="Reload"
31
- >
32
- <iconify-icon icon="tabler:refresh" width="16" height="16"></iconify-icon>
33
- </button>
34
- <div class="flex-1 flex items-center bg-[#1e1e1e] border border-[#3c3c3c] rounded px-3 py-2 hover:border-[#0e639c] focus-within:border-[#0e639c] transition-all">
35
- <iconify-icon icon="tabler:world" width="16" height="16" class="text-[#cccccc] mr-2"></iconify-icon>
36
- <span class="text-[#cccccc] text-sm">localhost:{previewPort}/</span>
37
- <input
38
- id="live-preview-url-input"
39
- type="text"
40
- placeholder="path"
41
- defaultValue=""
42
- class="flex-1 bg-transparent text-sm focus:outline-none text-[#cccccc] ml-1"
43
- />
44
- <button
45
- type="button"
46
- id="live-preview-load-btn"
47
- class="ml-2 p-1 hover:bg-[#3c3c3c] rounded transition-colors flex-shrink-0 text-[#cccccc] hover:text-white"
48
- title="Go"
49
- >
50
- <iconify-icon icon="tabler:chevron-right" width="16" height="16"></iconify-icon>
51
- </button>
52
- </div>
53
- </div>
54
- </div>
55
-
56
-
57
- {/* Tab Content */}
58
- <div class="flex-1 overflow-hidden bg-[#1e1e1e]">
59
- {/* Single Terminal Content */}
60
- <div class="h-full">
61
- <TerminalComponent index={1} />
62
- </div>
63
- </div>
64
- </div>
13
+ <div id="code-container" class="h-screen flex bg-[#1e1e1e] relative">
14
+ {/* Mobile toggle button */}
15
+ <button
16
+ type="button"
17
+ id="mobile-sidebar-toggle"
18
+ class="fixed top-4 left-4 z-60 p-3 bg-[#2d2d30] border border-[#3c3c3c] rounded-lg shadow-xl hover:bg-[#3c3c3c] transition-all md:hidden"
19
+ title="Toggle Sidebar"
20
+ >
21
+ <iconify-icon icon="tabler:menu-2" width="20" height="20" class="text-[#cccccc]"></iconify-icon>
22
+ </button>
23
+
24
+ {/* Sidebar */}
25
+ <Sidebar id="sidebar" previewPort={previewPort} workingDirectory={workingDirectory} />
65
26
 
66
- {/* Right Pane - Live Preview */}
67
- <SimpleLivePreview id="live-preview" previewPort={previewPort} />
27
+ {/* Main Content - Live Preview */}
28
+ <div class="flex-1 md:flex-1">
29
+ <SimpleLivePreview id="live-preview" previewPort={previewPort} />
30
+ </div>
68
31
  </div>
69
32
  </Layout>
70
33
  );
@@ -104,8 +104,6 @@ export class WebSocketTerminalService {
104
104
  return;
105
105
  }
106
106
 
107
- console.log(`Received message from ${clientId}:`, message.type, message.sessionId);
108
-
109
107
  switch (message.type) {
110
108
  case 'join':
111
109
  this.handleJoin(clientId, message);
@@ -186,9 +184,7 @@ export class WebSocketTerminalService {
186
184
 
187
185
  private static handleInput(clientId: string, message: WebSocketMessage) {
188
186
  const client = this.clients.get(clientId);
189
- if (!client || !message.sessionId || message.data === undefined) return;
190
-
191
- console.log(`Input from client ${clientId} to session ${message.sessionId}`);
187
+ if (!client || !message.sessionId || message.data === undefined) return;;
192
188
 
193
189
  // Get the terminal session
194
190
  const session = TerminalService.getSession(message.sessionId);