@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.

Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/bin/uplink.js +279 -0
  4. package/middleware/error-handler.js +69 -0
  5. package/package.json +93 -0
  6. package/public/css/agents.36b98c0f.css +1469 -0
  7. package/public/css/agents.css +1469 -0
  8. package/public/css/app.a6a7f8f5.css +2731 -0
  9. package/public/css/app.css +2731 -0
  10. package/public/css/artifacts.css +444 -0
  11. package/public/css/commands.css +55 -0
  12. package/public/css/connection.css +131 -0
  13. package/public/css/dashboard.css +233 -0
  14. package/public/css/developer.css +328 -0
  15. package/public/css/files.css +123 -0
  16. package/public/css/markdown.css +156 -0
  17. package/public/css/message-actions.css +278 -0
  18. package/public/css/mobile.css +614 -0
  19. package/public/css/panels-unified.css +483 -0
  20. package/public/css/premium.css +415 -0
  21. package/public/css/realtime.css +189 -0
  22. package/public/css/satellites.css +401 -0
  23. package/public/css/shortcuts.css +185 -0
  24. package/public/css/split-view.4def0262.css +673 -0
  25. package/public/css/split-view.css +673 -0
  26. package/public/css/theme-generator.css +391 -0
  27. package/public/css/themes.css +387 -0
  28. package/public/css/timestamps.css +54 -0
  29. package/public/css/variables.css +78 -0
  30. package/public/dist/bundle.b55050c4.js +15757 -0
  31. package/public/favicon.svg +24 -0
  32. package/public/img/agents/ada.png +0 -0
  33. package/public/img/agents/clarice.png +0 -0
  34. package/public/img/agents/dennis-nedry.png +0 -0
  35. package/public/img/agents/elliot-alderson.png +0 -0
  36. package/public/img/agents/main.png +0 -0
  37. package/public/img/agents/scotty.png +0 -0
  38. package/public/img/agents/top-flight-security.png +0 -0
  39. package/public/index.html +1083 -0
  40. package/public/js/agents-data.js +234 -0
  41. package/public/js/agents-ui.js +72 -0
  42. package/public/js/agents.js +1525 -0
  43. package/public/js/app.js +79 -0
  44. package/public/js/appearance-settings.js +111 -0
  45. package/public/js/artifacts.js +432 -0
  46. package/public/js/audio-queue.js +168 -0
  47. package/public/js/bootstrap.js +54 -0
  48. package/public/js/chat.js +1211 -0
  49. package/public/js/commands.js +581 -0
  50. package/public/js/connection-api.js +121 -0
  51. package/public/js/connection.js +1231 -0
  52. package/public/js/context-tracker.js +271 -0
  53. package/public/js/core.js +172 -0
  54. package/public/js/dashboard.js +452 -0
  55. package/public/js/developer.js +432 -0
  56. package/public/js/encryption.js +124 -0
  57. package/public/js/errors.js +122 -0
  58. package/public/js/event-bus.js +77 -0
  59. package/public/js/fetch-utils.js +171 -0
  60. package/public/js/file-handler.js +229 -0
  61. package/public/js/files.js +352 -0
  62. package/public/js/gateway-chat.js +538 -0
  63. package/public/js/logger.js +112 -0
  64. package/public/js/markdown.js +190 -0
  65. package/public/js/message-actions.js +431 -0
  66. package/public/js/message-renderer.js +288 -0
  67. package/public/js/missed-messages.js +235 -0
  68. package/public/js/mobile-debug.js +95 -0
  69. package/public/js/notifications.js +367 -0
  70. package/public/js/offline-queue.js +178 -0
  71. package/public/js/onboarding.js +543 -0
  72. package/public/js/panels.js +156 -0
  73. package/public/js/premium.js +412 -0
  74. package/public/js/realtime-voice.js +844 -0
  75. package/public/js/satellite-sync.js +256 -0
  76. package/public/js/satellite-ui.js +175 -0
  77. package/public/js/satellites.js +1516 -0
  78. package/public/js/settings.js +1087 -0
  79. package/public/js/shortcuts.js +381 -0
  80. package/public/js/split-chat.js +1234 -0
  81. package/public/js/split-resize.js +211 -0
  82. package/public/js/splitview.js +340 -0
  83. package/public/js/storage.js +408 -0
  84. package/public/js/streaming-handler.js +324 -0
  85. package/public/js/stt-settings.js +316 -0
  86. package/public/js/theme-generator.js +661 -0
  87. package/public/js/themes.js +164 -0
  88. package/public/js/timestamps.js +198 -0
  89. package/public/js/tts-settings.js +575 -0
  90. package/public/js/ui.js +267 -0
  91. package/public/js/update-notifier.js +143 -0
  92. package/public/js/utils/constants.js +165 -0
  93. package/public/js/utils/sanitize.js +93 -0
  94. package/public/js/utils/sse-parser.js +195 -0
  95. package/public/js/voice.js +883 -0
  96. package/public/manifest.json +58 -0
  97. package/public/moon_texture.jpg +0 -0
  98. package/public/sw.js +221 -0
  99. package/public/three.min.js +6 -0
  100. package/server/channel.js +529 -0
  101. package/server/chat.js +270 -0
  102. package/server/config-store.js +362 -0
  103. package/server/config.js +159 -0
  104. package/server/context.js +131 -0
  105. package/server/gateway-commands.js +211 -0
  106. package/server/gateway-proxy.js +318 -0
  107. package/server/index.js +22 -0
  108. package/server/logger.js +89 -0
  109. package/server/middleware/auth.js +188 -0
  110. package/server/middleware.js +218 -0
  111. package/server/openclaw-discover.js +308 -0
  112. package/server/premium/index.js +156 -0
  113. package/server/premium/license.js +140 -0
  114. package/server/realtime/bridge.js +837 -0
  115. package/server/realtime/index.js +349 -0
  116. package/server/realtime/tts-stream.js +446 -0
  117. package/server/routes/agents.js +564 -0
  118. package/server/routes/artifacts.js +174 -0
  119. package/server/routes/chat.js +311 -0
  120. package/server/routes/config-settings.js +345 -0
  121. package/server/routes/config.js +603 -0
  122. package/server/routes/files.js +307 -0
  123. package/server/routes/index.js +18 -0
  124. package/server/routes/media.js +451 -0
  125. package/server/routes/missed-messages.js +107 -0
  126. package/server/routes/premium.js +75 -0
  127. package/server/routes/push.js +156 -0
  128. package/server/routes/satellite.js +406 -0
  129. package/server/routes/status.js +251 -0
  130. package/server/routes/stt.js +35 -0
  131. package/server/routes/voice.js +260 -0
  132. package/server/routes/webhooks.js +203 -0
  133. package/server/routes.js +206 -0
  134. package/server/runtime-config.js +336 -0
  135. package/server/share.js +305 -0
  136. package/server/stt/faster-whisper.js +72 -0
  137. package/server/stt/groq.js +51 -0
  138. package/server/stt/index.js +196 -0
  139. package/server/stt/openai.js +49 -0
  140. package/server/sync.js +244 -0
  141. package/server/tailscale-https.js +175 -0
  142. package/server/tts.js +646 -0
  143. package/server/update-checker.js +172 -0
  144. package/server/utils/filename.js +129 -0
  145. package/server/utils.js +147 -0
  146. package/server/watchdog.js +318 -0
  147. package/server/websocket/broadcast.js +359 -0
  148. package/server/websocket/connections.js +339 -0
  149. package/server/websocket/index.js +215 -0
  150. package/server/websocket/routing.js +277 -0
  151. package/server/websocket/sync.js +102 -0
  152. package/server.js +404 -0
  153. package/utils/detect-tool-usage.js +93 -0
  154. package/utils/errors.js +158 -0
  155. package/utils/html-escape.js +84 -0
  156. package/utils/id-sanitize.js +94 -0
  157. package/utils/response.js +130 -0
  158. 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 };