@leverageaiapps/theseus-server 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.
- package/LICENSE +21 -0
- package/README.md +165 -0
- package/dist/capture.d.ts +3 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +134 -0
- package/dist/capture.js.map +1 -0
- package/dist/cloudflare-tunnel.d.ts +9 -0
- package/dist/cloudflare-tunnel.d.ts.map +1 -0
- package/dist/cloudflare-tunnel.js +218 -0
- package/dist/cloudflare-tunnel.js.map +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +84 -0
- package/dist/config.js.map +1 -0
- package/dist/context-extractor.d.ts +17 -0
- package/dist/context-extractor.d.ts.map +1 -0
- package/dist/context-extractor.js +118 -0
- package/dist/context-extractor.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/pty.d.ts +20 -0
- package/dist/pty.d.ts.map +1 -0
- package/dist/pty.js +148 -0
- package/dist/pty.js.map +1 -0
- package/dist/relay.d.ts +5 -0
- package/dist/relay.d.ts.map +1 -0
- package/dist/relay.js +131 -0
- package/dist/relay.js.map +1 -0
- package/dist/session.d.ts +5 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +257 -0
- package/dist/session.js.map +1 -0
- package/dist/voice-recognition-modelscope.d.ts +50 -0
- package/dist/voice-recognition-modelscope.d.ts.map +1 -0
- package/dist/voice-recognition-modelscope.js +171 -0
- package/dist/voice-recognition-modelscope.js.map +1 -0
- package/dist/web-server.d.ts +6 -0
- package/dist/web-server.d.ts.map +1 -0
- package/dist/web-server.js +1971 -0
- package/dist/web-server.js.map +1 -0
- package/package.json +66 -0
- package/public/index.html +639 -0
- package/public/js/terminal-asr.js +508 -0
- package/public/js/terminal.js +514 -0
- package/public/js/voice-input.js +422 -0
- package/scripts/postinstall.js +66 -0
- package/scripts/verify-install.js +124 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
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>Theseus Terminal</title>
|
|
7
|
+
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
|
|
8
|
+
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0.10.0/lib/addon-fit.js"></script>
|
|
9
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css">
|
|
10
|
+
<style>
|
|
11
|
+
* {
|
|
12
|
+
margin: 0;
|
|
13
|
+
padding: 0;
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
}
|
|
16
|
+
html, body {
|
|
17
|
+
height: 100%;
|
|
18
|
+
width: 100%;
|
|
19
|
+
background: #0a0a0a;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
overscroll-behavior: none;
|
|
22
|
+
-webkit-overflow-scrolling: auto;
|
|
23
|
+
}
|
|
24
|
+
body {
|
|
25
|
+
position: fixed;
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
}
|
|
29
|
+
#terminal-container {
|
|
30
|
+
position: absolute;
|
|
31
|
+
top: 0;
|
|
32
|
+
left: 0;
|
|
33
|
+
right: 0;
|
|
34
|
+
bottom: 50px;
|
|
35
|
+
padding: 8px;
|
|
36
|
+
/* Custom touch handling - disable native scrolling */
|
|
37
|
+
touch-action: none;
|
|
38
|
+
-webkit-touch-callout: none;
|
|
39
|
+
-webkit-user-select: none;
|
|
40
|
+
user-select: none;
|
|
41
|
+
/* Disable iOS momentum scrolling - we handle it ourselves */
|
|
42
|
+
-webkit-overflow-scrolling: auto;
|
|
43
|
+
overscroll-behavior: contain;
|
|
44
|
+
}
|
|
45
|
+
.xterm-viewport {
|
|
46
|
+
overflow-y: auto !important;
|
|
47
|
+
scrollbar-width: none;
|
|
48
|
+
-ms-overflow-style: none;
|
|
49
|
+
/* Disable native touch handling for custom implementation */
|
|
50
|
+
touch-action: none;
|
|
51
|
+
-webkit-overflow-scrolling: auto;
|
|
52
|
+
}
|
|
53
|
+
.xterm-viewport::-webkit-scrollbar {
|
|
54
|
+
display: none;
|
|
55
|
+
}
|
|
56
|
+
.xterm-screen {
|
|
57
|
+
user-select: none;
|
|
58
|
+
-webkit-user-select: none;
|
|
59
|
+
}
|
|
60
|
+
#scroll-to-bottom {
|
|
61
|
+
position: fixed;
|
|
62
|
+
bottom: 60px;
|
|
63
|
+
right: 12px;
|
|
64
|
+
width: 40px;
|
|
65
|
+
height: 40px;
|
|
66
|
+
border-radius: 50%;
|
|
67
|
+
background: rgba(59, 130, 246, 0.9);
|
|
68
|
+
border: none;
|
|
69
|
+
color: white;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
z-index: 999;
|
|
72
|
+
display: flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
justify-content: center;
|
|
75
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
76
|
+
opacity: 0;
|
|
77
|
+
transform: scale(0.8);
|
|
78
|
+
transition: all 0.2s ease;
|
|
79
|
+
pointer-events: none;
|
|
80
|
+
}
|
|
81
|
+
#scroll-to-bottom.visible {
|
|
82
|
+
opacity: 1;
|
|
83
|
+
transform: scale(1);
|
|
84
|
+
pointer-events: auto;
|
|
85
|
+
}
|
|
86
|
+
#scroll-to-bottom:hover {
|
|
87
|
+
background: rgba(59, 130, 246, 1);
|
|
88
|
+
transform: scale(1.1);
|
|
89
|
+
}
|
|
90
|
+
#scroll-to-bottom:active {
|
|
91
|
+
transform: scale(0.95);
|
|
92
|
+
}
|
|
93
|
+
#scroll-to-bottom svg {
|
|
94
|
+
width: 20px;
|
|
95
|
+
height: 20px;
|
|
96
|
+
fill: currentColor;
|
|
97
|
+
}
|
|
98
|
+
#status-dot {
|
|
99
|
+
position: fixed;
|
|
100
|
+
top: 12px;
|
|
101
|
+
right: 12px;
|
|
102
|
+
width: 12px;
|
|
103
|
+
height: 12px;
|
|
104
|
+
border-radius: 50%;
|
|
105
|
+
background: #22c55e;
|
|
106
|
+
z-index: 1000;
|
|
107
|
+
box-shadow: 0 0 8px rgba(34, 197, 94, 0.5);
|
|
108
|
+
transition: all 0.3s ease;
|
|
109
|
+
}
|
|
110
|
+
#status-dot.disconnected {
|
|
111
|
+
background: #ef4444;
|
|
112
|
+
box-shadow: 0 0 8px rgba(239, 68, 68, 0.5);
|
|
113
|
+
}
|
|
114
|
+
#status-dot.connecting {
|
|
115
|
+
background: #f59e0b;
|
|
116
|
+
box-shadow: 0 0 8px rgba(245, 158, 11, 0.5);
|
|
117
|
+
animation: pulse 1s infinite;
|
|
118
|
+
}
|
|
119
|
+
@keyframes pulse {
|
|
120
|
+
0%, 100% { opacity: 1; }
|
|
121
|
+
50% { opacity: 0.5; }
|
|
122
|
+
}
|
|
123
|
+
#input-area {
|
|
124
|
+
position: fixed;
|
|
125
|
+
bottom: 0;
|
|
126
|
+
left: 0;
|
|
127
|
+
right: 0;
|
|
128
|
+
padding: 8px 12px;
|
|
129
|
+
background: rgba(26, 26, 26, 0.95);
|
|
130
|
+
border-top: 1px solid #333;
|
|
131
|
+
z-index: 1000;
|
|
132
|
+
}
|
|
133
|
+
#input-wrapper {
|
|
134
|
+
display: flex;
|
|
135
|
+
align-items: flex-end;
|
|
136
|
+
gap: 8px;
|
|
137
|
+
position: relative;
|
|
138
|
+
}
|
|
139
|
+
#input {
|
|
140
|
+
flex: 1;
|
|
141
|
+
min-height: 34px;
|
|
142
|
+
max-height: 100px;
|
|
143
|
+
background: #0a0a0a;
|
|
144
|
+
border: 1px solid #444;
|
|
145
|
+
border-radius: 6px;
|
|
146
|
+
padding: 8px 45px 8px 12px;
|
|
147
|
+
color: #fff;
|
|
148
|
+
font-size: 16px;
|
|
149
|
+
font-family: inherit;
|
|
150
|
+
outline: none;
|
|
151
|
+
resize: none;
|
|
152
|
+
overflow-y: auto;
|
|
153
|
+
scrollbar-width: none;
|
|
154
|
+
-ms-overflow-style: none;
|
|
155
|
+
}
|
|
156
|
+
#input::-webkit-scrollbar { display: none; }
|
|
157
|
+
#input:focus { border-color: #3b82f6; }
|
|
158
|
+
|
|
159
|
+
/* Voice input button inside the input field */
|
|
160
|
+
#voice-btn {
|
|
161
|
+
position: absolute;
|
|
162
|
+
right: 52px;
|
|
163
|
+
bottom: 7px;
|
|
164
|
+
width: 32px;
|
|
165
|
+
height: 32px;
|
|
166
|
+
background: transparent;
|
|
167
|
+
border: none;
|
|
168
|
+
border-radius: 50%;
|
|
169
|
+
color: #888;
|
|
170
|
+
cursor: pointer;
|
|
171
|
+
transition: all 0.2s ease;
|
|
172
|
+
display: flex;
|
|
173
|
+
align-items: center;
|
|
174
|
+
justify-content: center;
|
|
175
|
+
padding: 0;
|
|
176
|
+
z-index: 10;
|
|
177
|
+
}
|
|
178
|
+
#voice-btn:hover {
|
|
179
|
+
background: rgba(59, 130, 246, 0.1);
|
|
180
|
+
color: #3b82f6;
|
|
181
|
+
}
|
|
182
|
+
#voice-btn.active {
|
|
183
|
+
background: #ef4444;
|
|
184
|
+
color: white;
|
|
185
|
+
animation: voice-pulse 1.5s infinite;
|
|
186
|
+
z-index: 20;
|
|
187
|
+
}
|
|
188
|
+
#voice-btn.active:hover {
|
|
189
|
+
background: #dc2626;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* Voice animation */
|
|
193
|
+
@keyframes voice-pulse {
|
|
194
|
+
0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
|
|
195
|
+
70% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); }
|
|
196
|
+
100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* Voice waveform animation */
|
|
200
|
+
.voice-wave {
|
|
201
|
+
display: none;
|
|
202
|
+
position: absolute;
|
|
203
|
+
right: 58px;
|
|
204
|
+
bottom: 17px;
|
|
205
|
+
width: 20px;
|
|
206
|
+
height: 16px;
|
|
207
|
+
align-items: center;
|
|
208
|
+
justify-content: space-between;
|
|
209
|
+
}
|
|
210
|
+
#voice-btn.active + .voice-wave {
|
|
211
|
+
display: flex;
|
|
212
|
+
}
|
|
213
|
+
.voice-bar {
|
|
214
|
+
width: 3px;
|
|
215
|
+
height: 100%;
|
|
216
|
+
background: #ef4444;
|
|
217
|
+
border-radius: 2px;
|
|
218
|
+
animation: wave 1s ease-in-out infinite;
|
|
219
|
+
}
|
|
220
|
+
.voice-bar:nth-child(1) { animation-delay: 0s; }
|
|
221
|
+
.voice-bar:nth-child(2) { animation-delay: 0.1s; }
|
|
222
|
+
.voice-bar:nth-child(3) { animation-delay: 0.2s; }
|
|
223
|
+
.voice-bar:nth-child(4) { animation-delay: 0.3s; }
|
|
224
|
+
|
|
225
|
+
@keyframes wave {
|
|
226
|
+
0%, 100% { transform: scaleY(0.3); }
|
|
227
|
+
50% { transform: scaleY(1); }
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* Transcription indicator */
|
|
231
|
+
.transcription-text {
|
|
232
|
+
position: absolute;
|
|
233
|
+
bottom: 45px;
|
|
234
|
+
left: 12px;
|
|
235
|
+
right: 12px;
|
|
236
|
+
padding: 10px 14px;
|
|
237
|
+
background: linear-gradient(135deg, rgba(59, 130, 246, 0.25), rgba(37, 99, 235, 0.2));
|
|
238
|
+
backdrop-filter: blur(10px);
|
|
239
|
+
-webkit-backdrop-filter: blur(10px);
|
|
240
|
+
border: 1px solid rgba(59, 130, 246, 0.5);
|
|
241
|
+
border-radius: 8px;
|
|
242
|
+
color: #93c5fd;
|
|
243
|
+
font-size: 13px;
|
|
244
|
+
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
|
|
245
|
+
display: none;
|
|
246
|
+
white-space: pre-wrap;
|
|
247
|
+
/* Don't block touch events */
|
|
248
|
+
pointer-events: none;
|
|
249
|
+
word-wrap: break-word;
|
|
250
|
+
max-height: 80px;
|
|
251
|
+
overflow-y: auto;
|
|
252
|
+
box-shadow: 0 4px 20px rgba(59, 130, 246, 0.15),
|
|
253
|
+
0 0 40px rgba(59, 130, 246, 0.1) inset,
|
|
254
|
+
0 1px 0 rgba(255, 255, 255, 0.1) inset;
|
|
255
|
+
animation: slideUp 0.3s ease-out;
|
|
256
|
+
transition: all 0.3s ease;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.transcription-text.visible {
|
|
260
|
+
display: block;
|
|
261
|
+
animation: slideUp 0.3s ease-out, pulse 2s ease-in-out infinite;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Subtle pulse animation */
|
|
265
|
+
@keyframes pulse {
|
|
266
|
+
0%, 100% {
|
|
267
|
+
box-shadow: 0 4px 20px rgba(59, 130, 246, 0.15),
|
|
268
|
+
0 0 40px rgba(59, 130, 246, 0.1) inset,
|
|
269
|
+
0 1px 0 rgba(255, 255, 255, 0.1) inset;
|
|
270
|
+
}
|
|
271
|
+
50% {
|
|
272
|
+
box-shadow: 0 4px 25px rgba(59, 130, 246, 0.25),
|
|
273
|
+
0 0 50px rgba(59, 130, 246, 0.15) inset,
|
|
274
|
+
0 1px 0 rgba(255, 255, 255, 0.15) inset;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* Slide up animation */
|
|
279
|
+
@keyframes slideUp {
|
|
280
|
+
from {
|
|
281
|
+
opacity: 0;
|
|
282
|
+
transform: translateY(10px);
|
|
283
|
+
}
|
|
284
|
+
to {
|
|
285
|
+
opacity: 1;
|
|
286
|
+
transform: translateY(0);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* Custom scrollbar for transcription */
|
|
291
|
+
.transcription-text::-webkit-scrollbar {
|
|
292
|
+
width: 4px;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.transcription-text::-webkit-scrollbar-track {
|
|
296
|
+
background: rgba(59, 130, 246, 0.1);
|
|
297
|
+
border-radius: 2px;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.transcription-text::-webkit-scrollbar-thumb {
|
|
301
|
+
background: rgba(59, 130, 246, 0.5);
|
|
302
|
+
border-radius: 2px;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.transcription-text::-webkit-scrollbar-thumb:hover {
|
|
306
|
+
background: rgba(59, 130, 246, 0.7);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* Strong text in transcription (final results) */
|
|
310
|
+
.transcription-text strong {
|
|
311
|
+
color: #dbeafe;
|
|
312
|
+
font-weight: 600;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* Interim text (partial results) */
|
|
316
|
+
.transcription-text span {
|
|
317
|
+
color: #93c5fd;
|
|
318
|
+
opacity: 0.8;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/* Special keys button */
|
|
322
|
+
#special-keys-btn {
|
|
323
|
+
width: 40px;
|
|
324
|
+
height: 40px;
|
|
325
|
+
background: #1a1a1a;
|
|
326
|
+
border: 1px solid #444;
|
|
327
|
+
border-radius: 6px;
|
|
328
|
+
color: #888;
|
|
329
|
+
cursor: pointer;
|
|
330
|
+
transition: all 0.2s ease;
|
|
331
|
+
display: flex;
|
|
332
|
+
align-items: center;
|
|
333
|
+
justify-content: center;
|
|
334
|
+
font-size: 18px;
|
|
335
|
+
flex-shrink: 0;
|
|
336
|
+
}
|
|
337
|
+
#special-keys-btn:hover {
|
|
338
|
+
background: #2a2a2a;
|
|
339
|
+
color: #fff;
|
|
340
|
+
border-color: #555;
|
|
341
|
+
}
|
|
342
|
+
#special-keys-btn:active {
|
|
343
|
+
transform: scale(0.95);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/* Special keys popup */
|
|
347
|
+
#special-keys-popup {
|
|
348
|
+
position: fixed;
|
|
349
|
+
bottom: 60px;
|
|
350
|
+
right: 12px;
|
|
351
|
+
background: rgba(26, 26, 26, 0.98);
|
|
352
|
+
border: 1px solid #444;
|
|
353
|
+
border-radius: 8px;
|
|
354
|
+
padding: 8px;
|
|
355
|
+
display: none;
|
|
356
|
+
z-index: 1001;
|
|
357
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
|
|
358
|
+
min-width: 350px;
|
|
359
|
+
max-width: 400px;
|
|
360
|
+
}
|
|
361
|
+
#special-keys-popup.show {
|
|
362
|
+
display: block;
|
|
363
|
+
}
|
|
364
|
+
.key-group {
|
|
365
|
+
margin-bottom: 8px;
|
|
366
|
+
}
|
|
367
|
+
.key-group:last-child {
|
|
368
|
+
margin-bottom: 0;
|
|
369
|
+
}
|
|
370
|
+
.key-group-title {
|
|
371
|
+
color: #888;
|
|
372
|
+
font-size: 11px;
|
|
373
|
+
text-transform: uppercase;
|
|
374
|
+
margin-bottom: 4px;
|
|
375
|
+
padding: 0 4px;
|
|
376
|
+
}
|
|
377
|
+
.key-buttons {
|
|
378
|
+
display: flex;
|
|
379
|
+
flex-wrap: wrap;
|
|
380
|
+
gap: 4px;
|
|
381
|
+
}
|
|
382
|
+
.special-key {
|
|
383
|
+
padding: 6px 10px;
|
|
384
|
+
background: #0a0a0a;
|
|
385
|
+
border: 1px solid #333;
|
|
386
|
+
border-radius: 4px;
|
|
387
|
+
color: #fff;
|
|
388
|
+
cursor: pointer;
|
|
389
|
+
font-size: 12px;
|
|
390
|
+
transition: all 0.15s ease;
|
|
391
|
+
white-space: nowrap;
|
|
392
|
+
min-width: 40px;
|
|
393
|
+
text-align: center;
|
|
394
|
+
}
|
|
395
|
+
.special-key:hover {
|
|
396
|
+
background: #1a1a1a;
|
|
397
|
+
border-color: #3b82f6;
|
|
398
|
+
}
|
|
399
|
+
.special-key:active {
|
|
400
|
+
transform: scale(0.95);
|
|
401
|
+
background: #3b82f6;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/* Debug console styles */
|
|
405
|
+
.debug-console {
|
|
406
|
+
margin-top: 12px;
|
|
407
|
+
padding-top: 12px;
|
|
408
|
+
border-top: 1px solid #333;
|
|
409
|
+
}
|
|
410
|
+
.debug-title {
|
|
411
|
+
color: #3b82f6;
|
|
412
|
+
font-size: 12px;
|
|
413
|
+
font-weight: bold;
|
|
414
|
+
margin-bottom: 8px;
|
|
415
|
+
text-transform: uppercase;
|
|
416
|
+
}
|
|
417
|
+
.debug-control {
|
|
418
|
+
margin-bottom: 8px;
|
|
419
|
+
}
|
|
420
|
+
.debug-control label {
|
|
421
|
+
display: block;
|
|
422
|
+
color: #888;
|
|
423
|
+
font-size: 11px;
|
|
424
|
+
margin-bottom: 4px;
|
|
425
|
+
}
|
|
426
|
+
.debug-control input[type="number"] {
|
|
427
|
+
width: 100%;
|
|
428
|
+
padding: 4px 8px;
|
|
429
|
+
background: #0a0a0a;
|
|
430
|
+
border: 1px solid #333;
|
|
431
|
+
border-radius: 4px;
|
|
432
|
+
color: #fff;
|
|
433
|
+
font-size: 12px;
|
|
434
|
+
}
|
|
435
|
+
.debug-control input[type="number"]:focus {
|
|
436
|
+
outline: none;
|
|
437
|
+
border-color: #3b82f6;
|
|
438
|
+
}
|
|
439
|
+
.context-preview {
|
|
440
|
+
background: #0a0a0a;
|
|
441
|
+
border: 1px solid #333;
|
|
442
|
+
border-radius: 4px;
|
|
443
|
+
padding: 8px;
|
|
444
|
+
max-height: 120px;
|
|
445
|
+
overflow-y: auto;
|
|
446
|
+
font-size: 11px;
|
|
447
|
+
color: #888;
|
|
448
|
+
white-space: pre-wrap;
|
|
449
|
+
word-wrap: break-word;
|
|
450
|
+
font-family: 'Courier New', monospace;
|
|
451
|
+
}
|
|
452
|
+
.context-preview::-webkit-scrollbar {
|
|
453
|
+
width: 4px;
|
|
454
|
+
}
|
|
455
|
+
.context-preview::-webkit-scrollbar-track {
|
|
456
|
+
background: #1a1a1a;
|
|
457
|
+
}
|
|
458
|
+
.context-preview::-webkit-scrollbar-thumb {
|
|
459
|
+
background: #444;
|
|
460
|
+
border-radius: 2px;
|
|
461
|
+
}
|
|
462
|
+
.api-status {
|
|
463
|
+
margin-top: 8px;
|
|
464
|
+
padding: 4px 8px;
|
|
465
|
+
background: #0a0a0a;
|
|
466
|
+
border: 1px solid #333;
|
|
467
|
+
border-radius: 4px;
|
|
468
|
+
font-size: 11px;
|
|
469
|
+
color: #888;
|
|
470
|
+
}
|
|
471
|
+
.api-status.connected {
|
|
472
|
+
border-color: #22c55e;
|
|
473
|
+
color: #22c55e;
|
|
474
|
+
}
|
|
475
|
+
.api-status.error {
|
|
476
|
+
border-color: #ef4444;
|
|
477
|
+
color: #ef4444;
|
|
478
|
+
}
|
|
479
|
+
/* Context overlay - shows when recording */
|
|
480
|
+
#context-overlay {
|
|
481
|
+
position: fixed;
|
|
482
|
+
top: 50px;
|
|
483
|
+
left: 50%;
|
|
484
|
+
transform: translateX(-50%);
|
|
485
|
+
max-width: 600px;
|
|
486
|
+
width: 90%;
|
|
487
|
+
background: rgba(26, 26, 26, 0.98);
|
|
488
|
+
border: 1px solid #3b82f6;
|
|
489
|
+
border-radius: 8px;
|
|
490
|
+
padding: 12px;
|
|
491
|
+
display: none;
|
|
492
|
+
z-index: 1002;
|
|
493
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
|
|
494
|
+
/* Allow touch events to pass through to terminal when hidden */
|
|
495
|
+
pointer-events: none;
|
|
496
|
+
}
|
|
497
|
+
#context-overlay.visible {
|
|
498
|
+
display: block;
|
|
499
|
+
/* Block touch events only when visible */
|
|
500
|
+
pointer-events: auto;
|
|
501
|
+
}
|
|
502
|
+
#context-overlay-title {
|
|
503
|
+
color: #3b82f6;
|
|
504
|
+
font-size: 12px;
|
|
505
|
+
font-weight: bold;
|
|
506
|
+
margin-bottom: 8px;
|
|
507
|
+
text-transform: uppercase;
|
|
508
|
+
}
|
|
509
|
+
#context-overlay-content {
|
|
510
|
+
background: #0a0a0a;
|
|
511
|
+
border: 1px solid #333;
|
|
512
|
+
border-radius: 4px;
|
|
513
|
+
padding: 8px;
|
|
514
|
+
max-height: 200px;
|
|
515
|
+
overflow-y: auto;
|
|
516
|
+
font-size: 11px;
|
|
517
|
+
color: #888;
|
|
518
|
+
white-space: pre-wrap;
|
|
519
|
+
word-wrap: break-word;
|
|
520
|
+
font-family: 'Courier New', monospace;
|
|
521
|
+
}
|
|
522
|
+
#context-overlay-content::-webkit-scrollbar {
|
|
523
|
+
width: 4px;
|
|
524
|
+
}
|
|
525
|
+
#context-overlay-content::-webkit-scrollbar-track {
|
|
526
|
+
background: #1a1a1a;
|
|
527
|
+
}
|
|
528
|
+
#context-overlay-content::-webkit-scrollbar-thumb {
|
|
529
|
+
background: #444;
|
|
530
|
+
border-radius: 2px;
|
|
531
|
+
}
|
|
532
|
+
</style>
|
|
533
|
+
</head>
|
|
534
|
+
<body>
|
|
535
|
+
<div id="terminal-container"></div>
|
|
536
|
+
|
|
537
|
+
<!-- Context overlay - shows when recording -->
|
|
538
|
+
<div id="context-overlay">
|
|
539
|
+
<div id="context-overlay-title">🎙️ Using Terminal Context for Voice Recognition</div>
|
|
540
|
+
<div id="context-overlay-content">No context available yet...</div>
|
|
541
|
+
</div>
|
|
542
|
+
|
|
543
|
+
<!-- Status indicator -->
|
|
544
|
+
<div id="status-dot" class="connecting"></div>
|
|
545
|
+
|
|
546
|
+
<!-- Scroll to bottom button -->
|
|
547
|
+
<button id="scroll-to-bottom">
|
|
548
|
+
<svg viewBox="0 0 24 24">
|
|
549
|
+
<path d="M7 10l5 5 5-5H7z"/>
|
|
550
|
+
</svg>
|
|
551
|
+
</button>
|
|
552
|
+
|
|
553
|
+
<!-- Input area -->
|
|
554
|
+
<div id="input-area">
|
|
555
|
+
<!-- Transcription text display -->
|
|
556
|
+
<div class="transcription-text" id="transcription"></div>
|
|
557
|
+
|
|
558
|
+
<div id="input-wrapper">
|
|
559
|
+
<textarea id="input" placeholder="Type command or use voice input..." rows="1"></textarea>
|
|
560
|
+
|
|
561
|
+
<!-- Voice input button inside input field -->
|
|
562
|
+
<button id="voice-btn" title="Voice input (Click to start/stop)">
|
|
563
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
564
|
+
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
|
|
565
|
+
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
|
|
566
|
+
<line x1="12" y1="19" x2="12" y2="23"/>
|
|
567
|
+
<line x1="8" y1="23" x2="16" y2="23"/>
|
|
568
|
+
</svg>
|
|
569
|
+
</button>
|
|
570
|
+
|
|
571
|
+
<!-- Voice waveform animation -->
|
|
572
|
+
<div class="voice-wave">
|
|
573
|
+
<div class="voice-bar"></div>
|
|
574
|
+
<div class="voice-bar"></div>
|
|
575
|
+
<div class="voice-bar"></div>
|
|
576
|
+
<div class="voice-bar"></div>
|
|
577
|
+
</div>
|
|
578
|
+
|
|
579
|
+
<!-- Special keys button -->
|
|
580
|
+
<button id="special-keys-btn" title="Special keys">⌘</button>
|
|
581
|
+
</div>
|
|
582
|
+
</div>
|
|
583
|
+
|
|
584
|
+
<!-- Special keys popup -->
|
|
585
|
+
<div id="special-keys-popup">
|
|
586
|
+
<div class="key-group">
|
|
587
|
+
<div class="key-group-title">Control</div>
|
|
588
|
+
<div class="key-buttons">
|
|
589
|
+
<button class="special-key" data-key="Escape">Esc</button>
|
|
590
|
+
<button class="special-key" data-key="Tab">Tab</button>
|
|
591
|
+
<button class="special-key" data-key="Up">↑</button>
|
|
592
|
+
<button class="special-key" data-key="Down">↓</button>
|
|
593
|
+
<button class="special-key" data-key="Left">←</button>
|
|
594
|
+
<button class="special-key" data-key="Right">→</button>
|
|
595
|
+
</div>
|
|
596
|
+
</div>
|
|
597
|
+
<div class="key-group">
|
|
598
|
+
<div class="key-group-title">Shortcuts</div>
|
|
599
|
+
<div class="key-buttons">
|
|
600
|
+
<button class="special-key" data-key="Ctrl+C">Ctrl+C</button>
|
|
601
|
+
<button class="special-key" data-key="Ctrl+D">Ctrl+D</button>
|
|
602
|
+
<button class="special-key" data-key="Ctrl+Z">Ctrl+Z</button>
|
|
603
|
+
<button class="special-key" data-key="Ctrl+L">Clear</button>
|
|
604
|
+
</div>
|
|
605
|
+
</div>
|
|
606
|
+
<div class="key-group">
|
|
607
|
+
<div class="key-group-title">Navigation</div>
|
|
608
|
+
<div class="key-buttons">
|
|
609
|
+
<button class="special-key" data-key="Home">Home</button>
|
|
610
|
+
<button class="special-key" data-key="End">End</button>
|
|
611
|
+
<button class="special-key" data-key="PageUp">PgUp</button>
|
|
612
|
+
<button class="special-key" data-key="PageDown">PgDn</button>
|
|
613
|
+
</div>
|
|
614
|
+
</div>
|
|
615
|
+
<div class="key-group">
|
|
616
|
+
<div class="key-group-title">Function</div>
|
|
617
|
+
<div class="key-buttons">
|
|
618
|
+
<button class="special-key" data-key="F1">F1</button>
|
|
619
|
+
<button class="special-key" data-key="F2">F2</button>
|
|
620
|
+
<button class="special-key" data-key="F3">F3</button>
|
|
621
|
+
<button class="special-key" data-key="F4">F4</button>
|
|
622
|
+
</div>
|
|
623
|
+
</div>
|
|
624
|
+
|
|
625
|
+
<!-- Debug Console for ASR -->
|
|
626
|
+
<div class="debug-console">
|
|
627
|
+
<div class="debug-title">🎙️ ASR Settings</div>
|
|
628
|
+
<div class="debug-control">
|
|
629
|
+
<label for="context-length">Context Length (characters):</label>
|
|
630
|
+
<input type="number" id="context-length" min="100" max="10000" value="2000" step="100">
|
|
631
|
+
</div>
|
|
632
|
+
</div>
|
|
633
|
+
</div>
|
|
634
|
+
|
|
635
|
+
<script src="/js/terminal.js"></script>
|
|
636
|
+
<script src="/js/terminal-asr.js"></script>
|
|
637
|
+
<script src="/js/voice-input.js"></script>
|
|
638
|
+
</body>
|
|
639
|
+
</html>
|