@leverageaiapps/gogogo 1.0.0

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.
@@ -0,0 +1,509 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
+ <title>gogogo Terminal</title>
7
+ <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='6' fill='%231a1a1a'/%3E%3Cpath d='M7 10l5 6-5 6' stroke='%2322c55e' stroke-width='2.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M14 10l5 6-5 6' stroke='%2322c55e' stroke-width='2.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M21 10l5 6-5 6' stroke='%2322c55e' stroke-width='2.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E">
8
+ <script src="https://cdn.jsdelivr.net/npm/@xterm/xterm@6.0.0/lib/xterm.js" integrity="sha384-f/1U6Z9wM4D71a5eRXEZnyOTMOvjqxr2XLwh+Go1OvIl3L3tOcvUrzudnhbECwl4" crossorigin="anonymous"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0.11.0/lib/addon-fit.js" integrity="sha384-txoiwu4RR2GD3qySbaj+BbzibkLbSJRcfqGYMu6z1EqHil4A2dyBiBW5dlacG6OR" crossorigin="anonymous"></script>
10
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm@6.0.0/css/xterm.css" integrity="sha384-n2n7twoohnW+d3myBKaUgl7DSiwidw6MkQy9oesGzkPpMjejKRR3XlnD+5yCdtBD" crossorigin="anonymous">
11
+ <style>
12
+ :root {
13
+ --bg: #0a0a0a;
14
+ --bg-secondary: #1a1a1a;
15
+ --bg-tertiary: #2a2a2a;
16
+ --fg: #ededed;
17
+ --text: #fff;
18
+ --text-muted: #888;
19
+ --text-dim: #555;
20
+ --border: #333;
21
+ --border-light: #444;
22
+ --input-bg: #0a0a0a;
23
+ --input-area-bg: rgba(26, 26, 26, 0.95);
24
+ --popup-bg: rgba(26, 26, 26, 0.98);
25
+ --accent: #3b82f6;
26
+ --accent-hover: rgba(59, 130, 246, 0.1);
27
+ --success: #22c55e;
28
+ --error: #ef4444;
29
+ --warning: #f59e0b;
30
+ --shadow: rgba(0, 0, 0, 0.3);
31
+ --shadow-heavy: rgba(0, 0, 0, 0.5);
32
+ }
33
+ :root.light {
34
+ --bg: #f5f5f5;
35
+ --bg-secondary: #e8e8e8;
36
+ --bg-tertiary: #ddd;
37
+ --fg: #1a1a1a;
38
+ --text: #1a1a1a;
39
+ --text-muted: #666;
40
+ --text-dim: #999;
41
+ --border: #ccc;
42
+ --border-light: #bbb;
43
+ --input-bg: #fff;
44
+ --input-area-bg: rgba(240, 240, 240, 0.95);
45
+ --popup-bg: rgba(245, 245, 245, 0.98);
46
+ --accent: #2563eb;
47
+ --accent-hover: rgba(37, 99, 235, 0.1);
48
+ --success: #16a34a;
49
+ --error: #dc2626;
50
+ --warning: #d97706;
51
+ --shadow: rgba(0, 0, 0, 0.1);
52
+ --shadow-heavy: rgba(0, 0, 0, 0.2);
53
+ }
54
+ * {
55
+ margin: 0;
56
+ padding: 0;
57
+ box-sizing: border-box;
58
+ }
59
+ html, body {
60
+ height: 100%;
61
+ width: 100%;
62
+ background: var(--bg);
63
+ overflow: hidden;
64
+ overscroll-behavior: none;
65
+ -webkit-overflow-scrolling: auto;
66
+ }
67
+ body {
68
+ position: fixed;
69
+ width: 100%;
70
+ height: 100%;
71
+ }
72
+ #terminal-container {
73
+ position: absolute;
74
+ top: 0;
75
+ left: 0;
76
+ right: 0;
77
+ bottom: 50px;
78
+ padding: 8px;
79
+ /* Custom touch handling - disable native scrolling */
80
+ touch-action: none;
81
+ -webkit-touch-callout: none;
82
+ -webkit-user-select: none;
83
+ user-select: none;
84
+ /* Disable iOS momentum scrolling - we handle it ourselves */
85
+ -webkit-overflow-scrolling: auto;
86
+ overscroll-behavior: contain;
87
+ }
88
+ .xterm-viewport {
89
+ /* Disable native touch handling for custom implementation */
90
+ touch-action: none;
91
+ }
92
+ .xterm-screen {
93
+ user-select: none;
94
+ -webkit-user-select: none;
95
+ }
96
+ .xterm-helper-textarea {
97
+ caret-color: transparent !important;
98
+ }
99
+ #scroll-to-bottom {
100
+ position: fixed;
101
+ bottom: 60px;
102
+ right: 12px;
103
+ width: 40px;
104
+ height: 40px;
105
+ border-radius: 50%;
106
+ background: rgba(59, 130, 246, 0.9);
107
+ border: none;
108
+ color: white;
109
+ cursor: pointer;
110
+ z-index: 1001;
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: center;
114
+ box-shadow: 0 2px 8px var(--shadow);
115
+ opacity: 0;
116
+ transform: scale(0.8);
117
+ transition: all 0.2s ease;
118
+ pointer-events: none;
119
+ }
120
+ #scroll-to-bottom.visible {
121
+ opacity: 1;
122
+ transform: scale(1);
123
+ pointer-events: auto;
124
+ }
125
+ #scroll-to-bottom:hover {
126
+ background: rgba(59, 130, 246, 1);
127
+ transform: scale(1.1);
128
+ }
129
+ #scroll-to-bottom:active {
130
+ transform: scale(0.95);
131
+ }
132
+ #scroll-to-bottom svg {
133
+ width: 20px;
134
+ height: 20px;
135
+ fill: currentColor;
136
+ }
137
+ #status-dot {
138
+ position: fixed;
139
+ top: 12px;
140
+ right: 12px;
141
+ width: 12px;
142
+ height: 12px;
143
+ border-radius: 50%;
144
+ background: var(--success);
145
+ z-index: 1000;
146
+ box-shadow: 0 0 8px rgba(34, 197, 94, 0.5);
147
+ transition: all 0.3s ease;
148
+ }
149
+ #status-dot.disconnected {
150
+ background: var(--error);
151
+ box-shadow: 0 0 8px rgba(239, 68, 68, 0.5);
152
+ }
153
+ #status-dot.connecting {
154
+ background: var(--warning);
155
+ box-shadow: 0 0 8px rgba(245, 158, 11, 0.5);
156
+ animation: blink 1s infinite;
157
+ }
158
+ @keyframes blink {
159
+ 0%, 100% { opacity: 1; }
160
+ 50% { opacity: 0.5; }
161
+ }
162
+ /* Theme toggle button */
163
+ #theme-toggle {
164
+ position: fixed;
165
+ top: 8px;
166
+ right: 32px;
167
+ width: 28px;
168
+ height: 28px;
169
+ border-radius: 50%;
170
+ background: transparent;
171
+ border: 1px solid var(--border);
172
+ color: var(--text-muted);
173
+ cursor: pointer;
174
+ z-index: 1000;
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: center;
178
+ transition: all 0.2s ease;
179
+ padding: 0;
180
+ }
181
+ #theme-toggle:hover {
182
+ background: var(--bg-secondary);
183
+ color: var(--text);
184
+ border-color: var(--border-light);
185
+ }
186
+ #theme-toggle:active {
187
+ transform: scale(0.9);
188
+ }
189
+ #theme-toggle svg {
190
+ width: 16px;
191
+ height: 16px;
192
+ }
193
+ #input-area {
194
+ position: fixed;
195
+ bottom: 0;
196
+ left: 0;
197
+ right: 0;
198
+ padding: 8px 12px;
199
+ background: var(--input-area-bg);
200
+ border-top: 1px solid var(--border);
201
+ z-index: 1000;
202
+ }
203
+ #input-wrapper {
204
+ display: flex;
205
+ align-items: flex-end;
206
+ gap: 8px;
207
+ position: relative;
208
+ }
209
+ #input {
210
+ flex: 1;
211
+ min-height: 34px;
212
+ max-height: 100px;
213
+ background: var(--input-bg);
214
+ border: 1px solid var(--border-light);
215
+ border-radius: 6px;
216
+ padding: 8px 45px 8px 12px;
217
+ color: var(--text);
218
+ font-size: 16px;
219
+ font-family: inherit;
220
+ outline: none;
221
+ resize: none;
222
+ overflow-y: auto;
223
+ scrollbar-width: none;
224
+ -ms-overflow-style: none;
225
+ }
226
+ #input::-webkit-scrollbar { display: none; }
227
+ #input:focus { border-color: var(--accent); }
228
+
229
+ /* File upload button inside input field */
230
+ #file-upload-btn {
231
+ position: absolute;
232
+ right: 52px;
233
+ bottom: 7px;
234
+ width: 32px;
235
+ height: 32px;
236
+ background: transparent;
237
+ border: none;
238
+ border-radius: 50%;
239
+ color: var(--text-muted);
240
+ cursor: pointer;
241
+ transition: all 0.2s ease;
242
+ display: flex;
243
+ align-items: center;
244
+ justify-content: center;
245
+ padding: 0;
246
+ z-index: 10;
247
+ }
248
+ #file-upload-btn:hover {
249
+ background: var(--accent-hover);
250
+ color: var(--accent);
251
+ }
252
+
253
+ /* Special keys button */
254
+ #special-keys-btn {
255
+ width: 40px;
256
+ height: 40px;
257
+ background: var(--bg-secondary);
258
+ border: 1px solid var(--border-light);
259
+ border-radius: 6px;
260
+ color: var(--text-muted);
261
+ cursor: pointer;
262
+ transition: all 0.2s ease;
263
+ display: flex;
264
+ align-items: center;
265
+ justify-content: center;
266
+ font-size: 18px;
267
+ flex-shrink: 0;
268
+ }
269
+ #special-keys-btn:hover {
270
+ background: var(--bg-tertiary);
271
+ color: var(--text);
272
+ border-color: var(--border-light);
273
+ }
274
+ #special-keys-btn:active {
275
+ transform: scale(0.95);
276
+ }
277
+
278
+ /* Special keys popup */
279
+ #special-keys-popup {
280
+ position: fixed;
281
+ bottom: 60px;
282
+ right: 12px;
283
+ background: var(--popup-bg);
284
+ border: 1px solid var(--border-light);
285
+ border-radius: 8px;
286
+ padding: 8px;
287
+ display: none;
288
+ z-index: 1001;
289
+ box-shadow: 0 4px 12px var(--shadow-heavy);
290
+ min-width: 350px;
291
+ max-width: 400px;
292
+ }
293
+ #special-keys-popup.show {
294
+ display: block;
295
+ }
296
+ .key-group {
297
+ margin-bottom: 8px;
298
+ }
299
+ .key-group:last-child {
300
+ margin-bottom: 0;
301
+ }
302
+ .key-group-title {
303
+ color: var(--text-muted);
304
+ font-size: 11px;
305
+ text-transform: uppercase;
306
+ margin-bottom: 4px;
307
+ padding: 0 4px;
308
+ }
309
+ .key-buttons {
310
+ display: flex;
311
+ flex-wrap: wrap;
312
+ gap: 4px;
313
+ }
314
+ .special-key {
315
+ padding: 6px 10px;
316
+ background: var(--input-bg);
317
+ border: 1px solid var(--border);
318
+ border-radius: 4px;
319
+ color: var(--text);
320
+ cursor: pointer;
321
+ font-size: 12px;
322
+ transition: all 0.15s ease;
323
+ white-space: nowrap;
324
+ min-width: 40px;
325
+ text-align: center;
326
+ }
327
+ .special-key:hover {
328
+ background: var(--bg-secondary);
329
+ border-color: var(--accent);
330
+ }
331
+ .special-key:active {
332
+ transform: scale(0.95);
333
+ background: var(--accent);
334
+ }
335
+
336
+ /* Debug console styles */
337
+ .debug-console {
338
+ margin-top: 12px;
339
+ padding-top: 12px;
340
+ border-top: 1px solid var(--border);
341
+ }
342
+ .debug-title {
343
+ color: var(--accent);
344
+ font-size: 12px;
345
+ font-weight: bold;
346
+ margin-bottom: 8px;
347
+ text-transform: uppercase;
348
+ }
349
+ .debug-control {
350
+ margin-bottom: 8px;
351
+ }
352
+ .debug-control label {
353
+ display: block;
354
+ color: var(--text-muted);
355
+ font-size: 11px;
356
+ margin-bottom: 4px;
357
+ }
358
+ .debug-control input[type="number"] {
359
+ width: 100%;
360
+ padding: 4px 8px;
361
+ background: var(--input-bg);
362
+ border: 1px solid var(--border);
363
+ border-radius: 4px;
364
+ color: var(--text);
365
+ font-size: 12px;
366
+ }
367
+ .debug-control input[type="number"]:focus {
368
+ outline: none;
369
+ border-color: var(--accent);
370
+ }
371
+ .context-preview {
372
+ background: var(--input-bg);
373
+ border: 1px solid var(--border);
374
+ border-radius: 4px;
375
+ padding: 8px;
376
+ max-height: 120px;
377
+ overflow-y: auto;
378
+ font-size: 11px;
379
+ color: var(--text-muted);
380
+ white-space: pre-wrap;
381
+ word-wrap: break-word;
382
+ font-family: 'Courier New', monospace;
383
+ }
384
+ .context-preview::-webkit-scrollbar {
385
+ width: 4px;
386
+ }
387
+ .context-preview::-webkit-scrollbar-track {
388
+ background: var(--bg-secondary);
389
+ }
390
+ .context-preview::-webkit-scrollbar-thumb {
391
+ background: var(--border-light);
392
+ border-radius: 2px;
393
+ }
394
+ .api-status {
395
+ margin-top: 8px;
396
+ padding: 4px 8px;
397
+ background: var(--input-bg);
398
+ border: 1px solid var(--border);
399
+ border-radius: 4px;
400
+ font-size: 11px;
401
+ color: var(--text-muted);
402
+ }
403
+ .api-status.connected {
404
+ border-color: var(--success);
405
+ color: var(--success);
406
+ }
407
+ .api-status.error {
408
+ border-color: var(--error);
409
+ color: var(--error);
410
+ }
411
+ #input-area.native-mode {
412
+ opacity: 0.3;
413
+ transition: opacity 0.3s ease;
414
+ }
415
+ #input-area.native-mode:hover,
416
+ #input-area.native-mode:focus-within {
417
+ opacity: 1;
418
+ }
419
+
420
+ </style>
421
+ </head>
422
+ <body>
423
+ <div id="terminal-container"></div>
424
+
425
+ <!-- Status indicator -->
426
+ <div id="status-dot" class="connecting"></div>
427
+ <!-- Theme toggle -->
428
+ <button id="theme-toggle" title="Toggle light/dark theme">
429
+ <svg id="theme-icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none">
430
+ <circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
431
+ </svg>
432
+ <svg id="theme-icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
433
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
434
+ </svg>
435
+ </button>
436
+
437
+ <!-- Scroll to bottom button -->
438
+ <button id="scroll-to-bottom">
439
+ <svg viewBox="0 0 24 24">
440
+ <path d="M7 10l5 5 5-5H7z"/>
441
+ </svg>
442
+ </button>
443
+
444
+ <!-- Input area -->
445
+ <div id="input-area">
446
+ <div id="input-wrapper">
447
+ <textarea id="input" placeholder="Type command..." rows="1"></textarea>
448
+
449
+ <!-- File/image upload button inside input field -->
450
+ <button id="file-upload-btn" title="Upload image (or paste from clipboard)">
451
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
452
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
453
+ <circle cx="8.5" cy="8.5" r="1.5"/>
454
+ <polyline points="21 15 16 10 5 21"/>
455
+ </svg>
456
+ </button>
457
+ <input type="file" id="file-upload-input" accept="image/*" style="display:none">
458
+
459
+ <!-- Special keys button -->
460
+ <button id="special-keys-btn" title="Special keys">⌘</button>
461
+ </div>
462
+ </div>
463
+
464
+ <!-- Special keys popup -->
465
+ <div id="special-keys-popup">
466
+ <div class="key-group">
467
+ <div class="key-group-title">Control</div>
468
+ <div class="key-buttons">
469
+ <button class="special-key" data-key="Escape">Esc</button>
470
+ <button class="special-key" data-key="Tab">Tab</button>
471
+ <button class="special-key" data-key="Up">↑</button>
472
+ <button class="special-key" data-key="Down">↓</button>
473
+ <button class="special-key" data-key="Left">←</button>
474
+ <button class="special-key" data-key="Right">→</button>
475
+ </div>
476
+ </div>
477
+ <div class="key-group">
478
+ <div class="key-group-title">Shortcuts</div>
479
+ <div class="key-buttons">
480
+ <button class="special-key" data-key="Ctrl+C">Ctrl+C</button>
481
+ <button class="special-key" data-key="Ctrl+D">Ctrl+D</button>
482
+ <button class="special-key" data-key="Ctrl+Z">Ctrl+Z</button>
483
+ <button class="special-key" data-key="Ctrl+L">Clear</button>
484
+ </div>
485
+ </div>
486
+ <div class="key-group">
487
+ <div class="key-group-title">Navigation</div>
488
+ <div class="key-buttons">
489
+ <button class="special-key" data-key="Home">Home</button>
490
+ <button class="special-key" data-key="End">End</button>
491
+ <button class="special-key" data-key="PageUp">PgUp</button>
492
+ <button class="special-key" data-key="PageDown">PgDn</button>
493
+ </div>
494
+ </div>
495
+ <div class="key-group">
496
+ <div class="key-group-title">Function</div>
497
+ <div class="key-buttons">
498
+ <button class="special-key" data-key="F1">F1</button>
499
+ <button class="special-key" data-key="F2">F2</button>
500
+ <button class="special-key" data-key="F3">F3</button>
501
+ <button class="special-key" data-key="F4">F4</button>
502
+ </div>
503
+ </div>
504
+
505
+ </div>
506
+
507
+ <script src="/js/terminal.js"></script>
508
+ </body>
509
+ </html>