@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,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Uplink",
|
|
3
|
+
"short_name": "Uplink",
|
|
4
|
+
"description": "Connect to your AI assistant",
|
|
5
|
+
"start_url": "/",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"background_color": "#000000",
|
|
8
|
+
"theme_color": "#000000",
|
|
9
|
+
"orientation": "portrait-primary",
|
|
10
|
+
"icons": [
|
|
11
|
+
{
|
|
12
|
+
"src": "/favicon.svg",
|
|
13
|
+
"sizes": "any",
|
|
14
|
+
"type": "image/svg+xml",
|
|
15
|
+
"purpose": "any"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"src": "/favicon.svg",
|
|
19
|
+
"sizes": "any",
|
|
20
|
+
"type": "image/svg+xml",
|
|
21
|
+
"purpose": "maskable"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"src": "/icon-192.png",
|
|
25
|
+
"sizes": "192x192",
|
|
26
|
+
"type": "image/png"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"src": "/icon-512.png",
|
|
30
|
+
"sizes": "512x512",
|
|
31
|
+
"type": "image/png"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"categories": ["productivity", "utilities"],
|
|
35
|
+
"shortcuts": [
|
|
36
|
+
{
|
|
37
|
+
"name": "New Chat",
|
|
38
|
+
"url": "/?action=new",
|
|
39
|
+
"description": "Start a new chat session"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"share_target": {
|
|
43
|
+
"action": "/?share=true",
|
|
44
|
+
"method": "POST",
|
|
45
|
+
"enctype": "multipart/form-data",
|
|
46
|
+
"params": {
|
|
47
|
+
"title": "title",
|
|
48
|
+
"text": "text",
|
|
49
|
+
"url": "url",
|
|
50
|
+
"files": [
|
|
51
|
+
{
|
|
52
|
+
"name": "media",
|
|
53
|
+
"accept": ["image/*"]
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
Binary file
|
package/public/sw.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
const CACHE_NAME = 'uplink-v109';
|
|
2
|
+
const STATIC_ASSETS = [
|
|
3
|
+
'/',
|
|
4
|
+
'/index.html',
|
|
5
|
+
// Core CSS
|
|
6
|
+
'/css/variables.css',
|
|
7
|
+
'/css/app.a6a7f8f5.css',
|
|
8
|
+
'/css/mobile.css',
|
|
9
|
+
'/css/themes.css',
|
|
10
|
+
'/css/premium.css',
|
|
11
|
+
'/css/theme-generator.css',
|
|
12
|
+
'/css/commands.css',
|
|
13
|
+
'/css/connection.css',
|
|
14
|
+
'/css/developer.css',
|
|
15
|
+
'/css/agents.36b98c0f.css',
|
|
16
|
+
'/css/dashboard.css',
|
|
17
|
+
'/css/files.css',
|
|
18
|
+
'/css/markdown.css',
|
|
19
|
+
'/css/shortcuts.css',
|
|
20
|
+
'/css/timestamps.css',
|
|
21
|
+
'/css/satellites.css',
|
|
22
|
+
'/css/panels-unified.css',
|
|
23
|
+
'/css/message-actions.css',
|
|
24
|
+
'/css/artifacts.css',
|
|
25
|
+
'/css/realtime.css',
|
|
26
|
+
// Vendor JS
|
|
27
|
+
'/three.min.js',
|
|
28
|
+
// Bundle
|
|
29
|
+
'/dist/bundle.b55050c4.js',
|
|
30
|
+
// Core JS modules
|
|
31
|
+
'/js/logger.js',
|
|
32
|
+
'/js/core.js',
|
|
33
|
+
'/js/bootstrap.js',
|
|
34
|
+
'/js/storage.js',
|
|
35
|
+
'/js/encryption.js',
|
|
36
|
+
'/js/onboarding.js',
|
|
37
|
+
'/js/ui.js',
|
|
38
|
+
'/js/errors.js',
|
|
39
|
+
'/js/chat.js',
|
|
40
|
+
'/js/voice.js',
|
|
41
|
+
'/js/settings.js',
|
|
42
|
+
'/js/commands.js',
|
|
43
|
+
'/js/developer.js',
|
|
44
|
+
'/js/dashboard.js',
|
|
45
|
+
'/js/files.js',
|
|
46
|
+
// Feature modules
|
|
47
|
+
'/js/panels.js',
|
|
48
|
+
'/js/themes.js',
|
|
49
|
+
'/js/premium.js',
|
|
50
|
+
'/js/theme-generator.js',
|
|
51
|
+
'/js/notifications.js',
|
|
52
|
+
'/js/shortcuts.js',
|
|
53
|
+
'/js/missed-messages.js',
|
|
54
|
+
'/js/timestamps.js',
|
|
55
|
+
'/js/markdown.js',
|
|
56
|
+
'/js/connection.js',
|
|
57
|
+
'/js/gateway-chat.js',
|
|
58
|
+
'/js/agents.js',
|
|
59
|
+
'/js/satellites.js',
|
|
60
|
+
'/js/message-actions.js',
|
|
61
|
+
'/js/context-tracker.js',
|
|
62
|
+
'/js/splitview.js',
|
|
63
|
+
'/js/update-notifier.js',
|
|
64
|
+
// Assets
|
|
65
|
+
'/favicon.svg',
|
|
66
|
+
'/manifest.json'
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
// Install - cache static assets
|
|
70
|
+
self.addEventListener('install', (event) => {
|
|
71
|
+
event.waitUntil(
|
|
72
|
+
caches.open(CACHE_NAME).then((cache) => {
|
|
73
|
+
return cache.addAll(STATIC_ASSETS);
|
|
74
|
+
})
|
|
75
|
+
);
|
|
76
|
+
self.skipWaiting();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Activate - clean old caches
|
|
80
|
+
self.addEventListener('activate', (event) => {
|
|
81
|
+
event.waitUntil(
|
|
82
|
+
caches.keys().then((keys) => {
|
|
83
|
+
return Promise.all(
|
|
84
|
+
keys.filter(key => key !== CACHE_NAME).map(key => caches.delete(key))
|
|
85
|
+
);
|
|
86
|
+
})
|
|
87
|
+
);
|
|
88
|
+
self.clients.claim();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Periodic version check — if server has a newer version, nuke cache and re-register
|
|
92
|
+
async function checkForUpdate() {
|
|
93
|
+
try {
|
|
94
|
+
const res = await fetch('/api/sw-version', { cache: 'no-store' });
|
|
95
|
+
if (!res.ok) return;
|
|
96
|
+
const { version } = await res.json();
|
|
97
|
+
if (version && version !== CACHE_NAME) {
|
|
98
|
+
console.log(`[SW] Server version ${version} !== ${CACHE_NAME} — purging cache`);
|
|
99
|
+
const keys = await caches.keys();
|
|
100
|
+
await Promise.all(keys.map(k => caches.delete(k)));
|
|
101
|
+
self.registration.update();
|
|
102
|
+
}
|
|
103
|
+
} catch (_) { /* offline, ignore */ }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check on activate and every 5 minutes
|
|
107
|
+
self.addEventListener('activate', () => { checkForUpdate(); });
|
|
108
|
+
setInterval(checkForUpdate, 5 * 60 * 1000);
|
|
109
|
+
|
|
110
|
+
// Fetch - network first, fallback to cache
|
|
111
|
+
self.addEventListener('fetch', (event) => {
|
|
112
|
+
// Skip non-GET requests
|
|
113
|
+
if (event.request.method !== 'GET') return;
|
|
114
|
+
|
|
115
|
+
// Skip API requests - they should fail when offline
|
|
116
|
+
if (event.request.url.includes('/api/')) return;
|
|
117
|
+
|
|
118
|
+
// Skip cache-clear page
|
|
119
|
+
if (event.request.url.includes('clear-cache')) return;
|
|
120
|
+
|
|
121
|
+
// Skip non-http(s) requests (chrome-extension://, etc.)
|
|
122
|
+
if (!event.request.url.startsWith('http')) return;
|
|
123
|
+
|
|
124
|
+
// Skip external URLs (Google Fonts, etc.) - let browser handle directly
|
|
125
|
+
if (!event.request.url.startsWith(self.location.origin)) return;
|
|
126
|
+
|
|
127
|
+
event.respondWith(
|
|
128
|
+
fetch(event.request)
|
|
129
|
+
.then((response) => {
|
|
130
|
+
// Clone and cache successful responses (only same-origin)
|
|
131
|
+
if (response.ok && event.request.url.startsWith(self.location.origin)) {
|
|
132
|
+
const clone = response.clone();
|
|
133
|
+
caches.open(CACHE_NAME).then((cache) => {
|
|
134
|
+
cache.put(event.request, clone);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return response;
|
|
138
|
+
})
|
|
139
|
+
.catch(() => {
|
|
140
|
+
// Network failed, try cache (return undefined-safe)
|
|
141
|
+
return caches.match(event.request).then(cached => {
|
|
142
|
+
return cached || new Response('Offline', { status: 503, statusText: 'Service Unavailable' });
|
|
143
|
+
});
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// Trigger version check on navigation requests (ensures mobile users get updates)
|
|
148
|
+
if (event.request.mode === 'navigate') {
|
|
149
|
+
event.waitUntil(checkForUpdate());
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Push - handle push notifications when tab is closed
|
|
154
|
+
self.addEventListener('push', (event) => {
|
|
155
|
+
console.log('[SW] Push received!', event);
|
|
156
|
+
|
|
157
|
+
let data = {};
|
|
158
|
+
try {
|
|
159
|
+
data = event.data?.json() || {};
|
|
160
|
+
} catch (e) {
|
|
161
|
+
console.error('[SW] Failed to parse push data:', e);
|
|
162
|
+
data = { body: event.data?.text() || 'New message' };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
console.log('[SW] Push data:', data);
|
|
166
|
+
|
|
167
|
+
const title = data.title || 'Uplink';
|
|
168
|
+
const options = {
|
|
169
|
+
body: data.body || 'New message',
|
|
170
|
+
icon: '/favicon.svg',
|
|
171
|
+
badge: '/favicon.svg',
|
|
172
|
+
tag: data.tag || 'uplink-message',
|
|
173
|
+
data: {
|
|
174
|
+
url: data.url || '/',
|
|
175
|
+
satelliteId: data.satelliteId
|
|
176
|
+
},
|
|
177
|
+
requireInteraction: false,
|
|
178
|
+
renotify: true
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
console.log('[SW] Showing notification:', title, options);
|
|
182
|
+
|
|
183
|
+
event.waitUntil(
|
|
184
|
+
self.registration.showNotification(title, options)
|
|
185
|
+
.then(() => console.log('[SW] Notification shown'))
|
|
186
|
+
.catch(err => console.error('[SW] Notification failed:', err))
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Notification click - open/focus Uplink
|
|
191
|
+
self.addEventListener('notificationclick', (event) => {
|
|
192
|
+
event.notification.close();
|
|
193
|
+
|
|
194
|
+
const url = event.notification.data?.url || '/';
|
|
195
|
+
const satelliteId = event.notification.data?.satelliteId;
|
|
196
|
+
|
|
197
|
+
event.waitUntil(
|
|
198
|
+
clients.matchAll({ type: 'window' }).then((windowClients) => {
|
|
199
|
+
// Look for existing Uplink window
|
|
200
|
+
for (const client of windowClients) {
|
|
201
|
+
if (client.url.includes(self.location.origin) && 'focus' in client) {
|
|
202
|
+
// If we have a satelliteId, try to switch to that satellite
|
|
203
|
+
if (satelliteId) {
|
|
204
|
+
client.postMessage({
|
|
205
|
+
type: 'switchSatellite',
|
|
206
|
+
satelliteId: satelliteId
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return client.focus();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// No existing window, open new one
|
|
214
|
+
let targetUrl = self.location.origin;
|
|
215
|
+
if (url !== '/') {
|
|
216
|
+
targetUrl += url;
|
|
217
|
+
}
|
|
218
|
+
return clients.openWindow(targetUrl);
|
|
219
|
+
})
|
|
220
|
+
);
|
|
221
|
+
});
|