@mooncompany/uplink-chat 0.5.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.
Potentially problematic release.
This version of @mooncompany/uplink-chat might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +185 -0
- package/bin/uplink.js +279 -0
- package/middleware/error-handler.js +69 -0
- package/package.json +93 -0
- package/public/css/agents.36b98c0f.css +1469 -0
- package/public/css/agents.css +1469 -0
- package/public/css/app.a6a7f8f5.css +2731 -0
- package/public/css/app.css +2731 -0
- package/public/css/artifacts.css +444 -0
- package/public/css/commands.css +55 -0
- package/public/css/connection.css +131 -0
- package/public/css/dashboard.css +233 -0
- package/public/css/developer.css +328 -0
- package/public/css/files.css +123 -0
- package/public/css/markdown.css +156 -0
- package/public/css/message-actions.css +278 -0
- package/public/css/mobile.css +614 -0
- package/public/css/panels-unified.css +483 -0
- package/public/css/premium.css +415 -0
- package/public/css/realtime.css +189 -0
- package/public/css/satellites.css +401 -0
- package/public/css/shortcuts.css +185 -0
- package/public/css/split-view.4def0262.css +673 -0
- package/public/css/split-view.css +673 -0
- package/public/css/theme-generator.css +391 -0
- package/public/css/themes.css +387 -0
- package/public/css/timestamps.css +54 -0
- package/public/css/variables.css +78 -0
- package/public/dist/bundle.b55050c4.js +15757 -0
- package/public/favicon.svg +24 -0
- package/public/img/agents/ada.png +0 -0
- package/public/img/agents/clarice.png +0 -0
- package/public/img/agents/dennis-nedry.png +0 -0
- package/public/img/agents/elliot-alderson.png +0 -0
- package/public/img/agents/main.png +0 -0
- package/public/img/agents/scotty.png +0 -0
- package/public/img/agents/top-flight-security.png +0 -0
- package/public/index.html +1083 -0
- package/public/js/agents-data.js +234 -0
- package/public/js/agents-ui.js +72 -0
- package/public/js/agents.js +1525 -0
- package/public/js/app.js +79 -0
- package/public/js/appearance-settings.js +111 -0
- package/public/js/artifacts.js +432 -0
- package/public/js/audio-queue.js +168 -0
- package/public/js/bootstrap.js +54 -0
- package/public/js/chat.js +1211 -0
- package/public/js/commands.js +581 -0
- package/public/js/connection-api.js +121 -0
- package/public/js/connection.js +1231 -0
- package/public/js/context-tracker.js +271 -0
- package/public/js/core.js +172 -0
- package/public/js/dashboard.js +452 -0
- package/public/js/developer.js +432 -0
- package/public/js/encryption.js +124 -0
- package/public/js/errors.js +122 -0
- package/public/js/event-bus.js +77 -0
- package/public/js/fetch-utils.js +171 -0
- package/public/js/file-handler.js +229 -0
- package/public/js/files.js +352 -0
- package/public/js/gateway-chat.js +538 -0
- package/public/js/logger.js +112 -0
- package/public/js/markdown.js +190 -0
- package/public/js/message-actions.js +431 -0
- package/public/js/message-renderer.js +288 -0
- package/public/js/missed-messages.js +235 -0
- package/public/js/mobile-debug.js +95 -0
- package/public/js/notifications.js +367 -0
- package/public/js/offline-queue.js +178 -0
- package/public/js/onboarding.js +543 -0
- package/public/js/panels.js +156 -0
- package/public/js/premium.js +412 -0
- package/public/js/realtime-voice.js +844 -0
- package/public/js/satellite-sync.js +256 -0
- package/public/js/satellite-ui.js +175 -0
- package/public/js/satellites.js +1516 -0
- package/public/js/settings.js +1087 -0
- package/public/js/shortcuts.js +381 -0
- package/public/js/split-chat.js +1234 -0
- package/public/js/split-resize.js +211 -0
- package/public/js/splitview.js +340 -0
- package/public/js/storage.js +408 -0
- package/public/js/streaming-handler.js +324 -0
- package/public/js/stt-settings.js +316 -0
- package/public/js/theme-generator.js +661 -0
- package/public/js/themes.js +164 -0
- package/public/js/timestamps.js +198 -0
- package/public/js/tts-settings.js +575 -0
- package/public/js/ui.js +267 -0
- package/public/js/update-notifier.js +143 -0
- package/public/js/utils/constants.js +165 -0
- package/public/js/utils/sanitize.js +93 -0
- package/public/js/utils/sse-parser.js +195 -0
- package/public/js/voice.js +883 -0
- package/public/manifest.json +58 -0
- package/public/moon_texture.jpg +0 -0
- package/public/sw.js +221 -0
- package/public/three.min.js +6 -0
- package/server/channel.js +529 -0
- package/server/chat.js +270 -0
- package/server/config-store.js +362 -0
- package/server/config.js +159 -0
- package/server/context.js +131 -0
- package/server/gateway-commands.js +211 -0
- package/server/gateway-proxy.js +318 -0
- package/server/index.js +22 -0
- package/server/logger.js +89 -0
- package/server/middleware/auth.js +188 -0
- package/server/middleware.js +218 -0
- package/server/openclaw-discover.js +308 -0
- package/server/premium/index.js +156 -0
- package/server/premium/license.js +140 -0
- package/server/realtime/bridge.js +837 -0
- package/server/realtime/index.js +349 -0
- package/server/realtime/tts-stream.js +446 -0
- package/server/routes/agents.js +564 -0
- package/server/routes/artifacts.js +174 -0
- package/server/routes/chat.js +311 -0
- package/server/routes/config-settings.js +345 -0
- package/server/routes/config.js +603 -0
- package/server/routes/files.js +307 -0
- package/server/routes/index.js +18 -0
- package/server/routes/media.js +451 -0
- package/server/routes/missed-messages.js +107 -0
- package/server/routes/premium.js +75 -0
- package/server/routes/push.js +156 -0
- package/server/routes/satellite.js +406 -0
- package/server/routes/status.js +251 -0
- package/server/routes/stt.js +35 -0
- package/server/routes/voice.js +260 -0
- package/server/routes/webhooks.js +203 -0
- package/server/routes.js +206 -0
- package/server/runtime-config.js +336 -0
- package/server/share.js +305 -0
- package/server/stt/faster-whisper.js +72 -0
- package/server/stt/groq.js +51 -0
- package/server/stt/index.js +196 -0
- package/server/stt/openai.js +49 -0
- package/server/sync.js +244 -0
- package/server/tailscale-https.js +175 -0
- package/server/tts.js +646 -0
- package/server/update-checker.js +172 -0
- package/server/utils/filename.js +129 -0
- package/server/utils.js +147 -0
- package/server/watchdog.js +318 -0
- package/server/websocket/broadcast.js +359 -0
- package/server/websocket/connections.js +339 -0
- package/server/websocket/index.js +215 -0
- package/server/websocket/routing.js +277 -0
- package/server/websocket/sync.js +102 -0
- package/server.js +404 -0
- package/utils/detect-tool-usage.js +93 -0
- package/utils/errors.js +158 -0
- package/utils/html-escape.js +84 -0
- package/utils/id-sanitize.js +94 -0
- package/utils/response.js +130 -0
- package/utils/with-retry.js +105 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// AUDIO QUEUE MODULE
|
|
3
|
+
// TTS audio playback queue and player controls
|
|
4
|
+
// ============================================
|
|
5
|
+
|
|
6
|
+
import { UplinkLogger } from './logger.js';
|
|
7
|
+
import { UplinkUI } from './ui.js';
|
|
8
|
+
|
|
9
|
+
// Audio queue for sequential TTS playback
|
|
10
|
+
const audioQueue = [];
|
|
11
|
+
let isAudioPlaying = false;
|
|
12
|
+
|
|
13
|
+
// ============================================
|
|
14
|
+
// PLAYER UI
|
|
15
|
+
// ============================================
|
|
16
|
+
|
|
17
|
+
function showAudioPlayer() {
|
|
18
|
+
const bar = document.getElementById('audioPlayerBar');
|
|
19
|
+
if (bar) bar.style.display = 'flex';
|
|
20
|
+
UplinkUI.updateMessagesPadding?.();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function hideAudioPlayer() {
|
|
24
|
+
const bar = document.getElementById('audioPlayerBar');
|
|
25
|
+
if (bar) bar.style.display = 'none';
|
|
26
|
+
UplinkUI.updateMessagesPadding?.();
|
|
27
|
+
const fill = document.getElementById('audioPlayerFill');
|
|
28
|
+
if (fill) fill.style.width = '0%';
|
|
29
|
+
const time = document.getElementById('audioPlayerTime');
|
|
30
|
+
if (time) time.textContent = '0:00';
|
|
31
|
+
const icon = document.getElementById('audioPlayerIcon');
|
|
32
|
+
if (icon) icon.setAttribute('d', 'M6 4l15 8-15 8V4z');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function updatePlayerIcon(playing) {
|
|
36
|
+
const icon = document.getElementById('audioPlayerIcon');
|
|
37
|
+
if (!icon) return;
|
|
38
|
+
icon.setAttribute('d', playing
|
|
39
|
+
? 'M6 4h4v16H6V4zm8 0h4v16h-4V4z' // pause
|
|
40
|
+
: 'M6 4l15 8-15 8V4z'); // play
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function formatTime(s) {
|
|
44
|
+
if (!s || !isFinite(s)) return '0:00';
|
|
45
|
+
const m = Math.floor(s / 60);
|
|
46
|
+
const sec = Math.floor(s % 60);
|
|
47
|
+
return `${m}:${sec.toString().padStart(2, '0')}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ============================================
|
|
51
|
+
// QUEUE MANAGEMENT
|
|
52
|
+
// ============================================
|
|
53
|
+
|
|
54
|
+
export function playAudio(url) {
|
|
55
|
+
const audio = document.getElementById('audio');
|
|
56
|
+
if (!audio) return;
|
|
57
|
+
|
|
58
|
+
audioQueue.push(url);
|
|
59
|
+
|
|
60
|
+
if (!isAudioPlaying) {
|
|
61
|
+
playNextInQueue();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function playNextInQueue() {
|
|
66
|
+
const audio = document.getElementById('audio');
|
|
67
|
+
if (!audio || audioQueue.length === 0) {
|
|
68
|
+
isAudioPlaying = false;
|
|
69
|
+
hideAudioPlayer();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
isAudioPlaying = true;
|
|
74
|
+
const url = audioQueue.shift();
|
|
75
|
+
audio.src = url;
|
|
76
|
+
showAudioPlayer();
|
|
77
|
+
updatePlayerIcon(true);
|
|
78
|
+
audio.play().catch(err => {
|
|
79
|
+
UplinkLogger.error('AudioQueue: Playback failed:', err);
|
|
80
|
+
playNextInQueue();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function clearQueue() {
|
|
85
|
+
audioQueue.length = 0;
|
|
86
|
+
isAudioPlaying = false;
|
|
87
|
+
const audio = document.getElementById('audio');
|
|
88
|
+
if (audio) {
|
|
89
|
+
audio.pause();
|
|
90
|
+
audio.src = '';
|
|
91
|
+
}
|
|
92
|
+
hideAudioPlayer();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ============================================
|
|
96
|
+
// INITIALIZATION
|
|
97
|
+
// ============================================
|
|
98
|
+
|
|
99
|
+
export function init() {
|
|
100
|
+
const audio = document.getElementById('audio');
|
|
101
|
+
if (audio && !audio._queueInitialized) {
|
|
102
|
+
audio._queueInitialized = true;
|
|
103
|
+
audio.addEventListener('ended', () => {
|
|
104
|
+
updatePlayerIcon(false);
|
|
105
|
+
playNextInQueue();
|
|
106
|
+
});
|
|
107
|
+
audio.addEventListener('error', () => {
|
|
108
|
+
updatePlayerIcon(false);
|
|
109
|
+
playNextInQueue();
|
|
110
|
+
});
|
|
111
|
+
audio.addEventListener('timeupdate', () => {
|
|
112
|
+
if (!audio.duration) return;
|
|
113
|
+
const pct = (audio.currentTime / audio.duration) * 100;
|
|
114
|
+
const fill = document.getElementById('audioPlayerFill');
|
|
115
|
+
if (fill) fill.style.width = pct + '%';
|
|
116
|
+
const time = document.getElementById('audioPlayerTime');
|
|
117
|
+
if (time) time.textContent = formatTime(audio.duration - audio.currentTime);
|
|
118
|
+
});
|
|
119
|
+
audio.addEventListener('pause', () => updatePlayerIcon(false));
|
|
120
|
+
audio.addEventListener('play', () => updatePlayerIcon(true));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Player controls
|
|
124
|
+
const playBtn = document.getElementById('audioPlayerPlay');
|
|
125
|
+
if (playBtn && !playBtn._init) {
|
|
126
|
+
playBtn._init = true;
|
|
127
|
+
playBtn.addEventListener('click', () => {
|
|
128
|
+
if (audio.paused) audio.play();
|
|
129
|
+
else audio.pause();
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const closeBtn = document.getElementById('audioPlayerClose');
|
|
134
|
+
if (closeBtn && !closeBtn._init) {
|
|
135
|
+
closeBtn._init = true;
|
|
136
|
+
closeBtn.addEventListener('click', () => clearQueue());
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const progress = document.getElementById('audioPlayerProgress');
|
|
140
|
+
if (progress && !progress._init) {
|
|
141
|
+
progress._init = true;
|
|
142
|
+
progress.addEventListener('click', (e) => {
|
|
143
|
+
if (!audio.duration) return;
|
|
144
|
+
const rect = progress.getBoundingClientRect();
|
|
145
|
+
const pct = (e.clientX - rect.left) / rect.width;
|
|
146
|
+
audio.currentTime = pct * audio.duration;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
UplinkLogger.debug('AudioQueue: Initialized');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ============================================
|
|
154
|
+
// PUBLIC API
|
|
155
|
+
// ============================================
|
|
156
|
+
|
|
157
|
+
export const UplinkAudioQueue = {
|
|
158
|
+
init,
|
|
159
|
+
playAudio,
|
|
160
|
+
clearQueue,
|
|
161
|
+
getQueueLength: () => audioQueue.length,
|
|
162
|
+
isPlaying: () => isAudioPlaying
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// Backward compat: assign to window
|
|
166
|
+
window.UplinkAudioQueue = UplinkAudioQueue;
|
|
167
|
+
|
|
168
|
+
UplinkLogger.debug('AudioQueue: Module loaded');
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// BOOTSTRAP
|
|
3
|
+
// Ensures all modules are loaded and initialized
|
|
4
|
+
// ============================================
|
|
5
|
+
|
|
6
|
+
// Module load order (for documentation)
|
|
7
|
+
// 1. core.js - state, config, module registry
|
|
8
|
+
// 2. encryption.js - crypto utilities
|
|
9
|
+
// 3. storage.js - persistence
|
|
10
|
+
// 4. onboarding.js - setup/unlock
|
|
11
|
+
// 5. ui.js - starfield, mode switching
|
|
12
|
+
// 6. chat.js - messages
|
|
13
|
+
// 7. voice.js - voice recording
|
|
14
|
+
// 8. settings.js - settings panel
|
|
15
|
+
// 9. commands.js - slash commands
|
|
16
|
+
// 10. developer.js - dev panel
|
|
17
|
+
// 11. files.js - drag & drop
|
|
18
|
+
|
|
19
|
+
// Wait for all modules to signal ready
|
|
20
|
+
let readyCount = 0;
|
|
21
|
+
const requiredModules = ['core', 'chat', 'ui'];
|
|
22
|
+
|
|
23
|
+
function checkReady() {
|
|
24
|
+
const core = window.UplinkCore;
|
|
25
|
+
if (!core) return;
|
|
26
|
+
|
|
27
|
+
const allReady = requiredModules.every(m => core.hasModule(m));
|
|
28
|
+
if (allReady && window.UplinkLogger?.debug) {
|
|
29
|
+
window.UplinkLogger.debug('Bootstrap: All required modules ready');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Listen for module ready events
|
|
34
|
+
window.addEventListener('uplink:ready', checkReady);
|
|
35
|
+
|
|
36
|
+
// Fallback: check periodically
|
|
37
|
+
const checkInterval = setInterval(() => {
|
|
38
|
+
if (window.UplinkCore?.hasModule('chat')) {
|
|
39
|
+
clearInterval(checkInterval);
|
|
40
|
+
if (window.UplinkLogger?.debug) {
|
|
41
|
+
window.UplinkLogger.debug('Bootstrap: Application ready');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}, 100);
|
|
45
|
+
|
|
46
|
+
// Stop checking after 5 seconds
|
|
47
|
+
setTimeout(() => clearInterval(checkInterval), 5000);
|
|
48
|
+
|
|
49
|
+
if (window.UplinkLogger?.debug) {
|
|
50
|
+
window.UplinkLogger.debug('Bootstrap: Loading modules...');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Export for module system
|
|
54
|
+
export const UplinkBootstrap = { ready: true };
|