@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,234 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// AGENTS DATA MODULE
|
|
3
|
+
// API calls, data fetching, agent CRUD
|
|
4
|
+
// ============================================
|
|
5
|
+
|
|
6
|
+
const logger = window.logger || console;
|
|
7
|
+
|
|
8
|
+
// State
|
|
9
|
+
export let agents = [];
|
|
10
|
+
export let defaults = {};
|
|
11
|
+
export let bindings = [];
|
|
12
|
+
export let globalTools = {};
|
|
13
|
+
export let channels = [];
|
|
14
|
+
export let configHash = null;
|
|
15
|
+
export let loaded = false;
|
|
16
|
+
export let loading = false;
|
|
17
|
+
export let saving = false;
|
|
18
|
+
export let restartPending = false;
|
|
19
|
+
|
|
20
|
+
// Update state (for orchestrator to use)
|
|
21
|
+
export function setState(updates) {
|
|
22
|
+
if (updates.agents !== undefined) agents = updates.agents;
|
|
23
|
+
if (updates.defaults !== undefined) defaults = updates.defaults;
|
|
24
|
+
if (updates.bindings !== undefined) bindings = updates.bindings;
|
|
25
|
+
if (updates.globalTools !== undefined) globalTools = updates.globalTools;
|
|
26
|
+
if (updates.channels !== undefined) channels = updates.channels;
|
|
27
|
+
if (updates.configHash !== undefined) configHash = updates.configHash;
|
|
28
|
+
if (updates.loaded !== undefined) loaded = updates.loaded;
|
|
29
|
+
if (updates.loading !== undefined) loading = updates.loading;
|
|
30
|
+
if (updates.saving !== undefined) saving = updates.saving;
|
|
31
|
+
if (updates.restartPending !== undefined) restartPending = updates.restartPending;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ============================================
|
|
35
|
+
// DATA FETCHING
|
|
36
|
+
// ============================================
|
|
37
|
+
|
|
38
|
+
export async function fetchAgents() {
|
|
39
|
+
if (loading) return;
|
|
40
|
+
loading = true;
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const response = await fetch('/api/agents');
|
|
44
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
45
|
+
|
|
46
|
+
const data = await response.json();
|
|
47
|
+
if (!data.ok) throw new Error(data.error || 'Failed to fetch agents');
|
|
48
|
+
|
|
49
|
+
agents = data.agents || [];
|
|
50
|
+
defaults = data.defaults || {};
|
|
51
|
+
bindings = data.bindings || [];
|
|
52
|
+
globalTools = data.globalTools || {};
|
|
53
|
+
channels = data.channels || [];
|
|
54
|
+
configHash = data.hash || null;
|
|
55
|
+
loaded = true;
|
|
56
|
+
|
|
57
|
+
logger.debug('Agents: Loaded', agents.length, 'agents');
|
|
58
|
+
} catch (err) {
|
|
59
|
+
logger.error('Agents: Failed to fetch:', err.message);
|
|
60
|
+
} finally {
|
|
61
|
+
loading = false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function saveAgentChanges(agentId, changes, onConflict) {
|
|
66
|
+
if (saving) return false;
|
|
67
|
+
saving = true;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentId)}`, {
|
|
71
|
+
method: 'PATCH',
|
|
72
|
+
headers: { 'Content-Type': 'application/json' },
|
|
73
|
+
body: JSON.stringify({ changes, baseHash: configHash }),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const data = await response.json();
|
|
77
|
+
|
|
78
|
+
if (response.status === 409) {
|
|
79
|
+
// Hash mismatch — config changed externally
|
|
80
|
+
configHash = data.currentHash;
|
|
81
|
+
loaded = false;
|
|
82
|
+
await fetchAgents();
|
|
83
|
+
if (onConflict) onConflict();
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!response.ok || !data.ok) {
|
|
88
|
+
throw new Error(data.error || `HTTP ${response.status}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Update local state
|
|
92
|
+
configHash = data.hash || configHash;
|
|
93
|
+
const idx = agents.findIndex(a => a.id === agentId);
|
|
94
|
+
if (idx !== -1 && data.agent) {
|
|
95
|
+
agents[idx] = { ...agents[idx], ...data.agent };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return true;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
logger.error('Agents: Save failed:', err.message);
|
|
101
|
+
throw err;
|
|
102
|
+
} finally {
|
|
103
|
+
saving = false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function saveBindings(editedBindings, onConflict) {
|
|
108
|
+
if (saving) return false;
|
|
109
|
+
saving = true;
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const response = await fetch('/api/bindings', {
|
|
113
|
+
method: 'PUT',
|
|
114
|
+
headers: { 'Content-Type': 'application/json' },
|
|
115
|
+
body: JSON.stringify({ bindings: editedBindings, baseHash: configHash }),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const data = await response.json();
|
|
119
|
+
|
|
120
|
+
if (response.status === 409) {
|
|
121
|
+
configHash = data.currentHash;
|
|
122
|
+
loaded = false;
|
|
123
|
+
await fetchAgents();
|
|
124
|
+
if (onConflict) onConflict();
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!response.ok || !data.ok) {
|
|
129
|
+
throw new Error(data.error || `HTTP ${response.status}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Update local state
|
|
133
|
+
configHash = data.hash || configHash;
|
|
134
|
+
bindings = data.bindings || editedBindings;
|
|
135
|
+
|
|
136
|
+
return true;
|
|
137
|
+
} catch (err) {
|
|
138
|
+
logger.error('Agents: Save bindings failed:', err.message);
|
|
139
|
+
throw err;
|
|
140
|
+
} finally {
|
|
141
|
+
saving = false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export async function createAgent(agent) {
|
|
146
|
+
if (saving) return null;
|
|
147
|
+
saving = true;
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const response = await fetch('/api/agents', {
|
|
151
|
+
method: 'POST',
|
|
152
|
+
headers: { 'Content-Type': 'application/json' },
|
|
153
|
+
body: JSON.stringify({ agent, baseHash: configHash }),
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const data = await response.json();
|
|
157
|
+
if (!response.ok || !data.ok) {
|
|
158
|
+
throw new Error(data.error || `HTTP ${response.status}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return data;
|
|
162
|
+
} catch (err) {
|
|
163
|
+
logger.error('Agents: Create failed:', err.message);
|
|
164
|
+
throw err;
|
|
165
|
+
} finally {
|
|
166
|
+
saving = false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export async function deleteAgent(agentId) {
|
|
171
|
+
if (saving) return null;
|
|
172
|
+
saving = true;
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentId)}`, {
|
|
176
|
+
method: 'DELETE',
|
|
177
|
+
headers: { 'Content-Type': 'application/json' },
|
|
178
|
+
body: JSON.stringify({ baseHash: configHash }),
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const data = await response.json();
|
|
182
|
+
if (!response.ok || !data.ok) {
|
|
183
|
+
throw new Error(data.error || `HTTP ${response.status}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return data;
|
|
187
|
+
} catch (err) {
|
|
188
|
+
logger.error('Agents: Delete failed:', err.message);
|
|
189
|
+
throw err;
|
|
190
|
+
} finally {
|
|
191
|
+
saving = false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export async function uploadAgentAvatar(agentId, file) {
|
|
196
|
+
const formData = new FormData();
|
|
197
|
+
formData.append('avatar', file);
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentId)}/avatar`, {
|
|
201
|
+
method: 'POST',
|
|
202
|
+
body: formData,
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const data = await response.json();
|
|
206
|
+
if (!response.ok || !data.ok) {
|
|
207
|
+
throw new Error(data.error || `HTTP ${response.status}`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return data;
|
|
211
|
+
} catch (err) {
|
|
212
|
+
logger.error('Agents: Avatar upload failed:', err.message);
|
|
213
|
+
throw err;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Get current state
|
|
218
|
+
export function getState() {
|
|
219
|
+
return { agents, defaults, bindings, globalTools, channels, configHash, loaded, loading, saving, restartPending };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Expose on window for backward compatibility
|
|
223
|
+
if (typeof window !== 'undefined') {
|
|
224
|
+
window.UplinkAgentsData = {
|
|
225
|
+
fetchAgents,
|
|
226
|
+
saveAgentChanges,
|
|
227
|
+
saveBindings,
|
|
228
|
+
createAgent,
|
|
229
|
+
deleteAgent,
|
|
230
|
+
uploadAgentAvatar,
|
|
231
|
+
getState,
|
|
232
|
+
setState
|
|
233
|
+
};
|
|
234
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// AGENTS UI MODULE
|
|
3
|
+
// Rendering, list view, detail view, forms
|
|
4
|
+
// ============================================
|
|
5
|
+
|
|
6
|
+
// This module will be populated with UI rendering functions
|
|
7
|
+
// For now, it re-exports the original agents.js functionality
|
|
8
|
+
// A full refactor would move all rendering logic here
|
|
9
|
+
|
|
10
|
+
// Tool groups for display
|
|
11
|
+
export const TOOL_GROUPS = {
|
|
12
|
+
'Runtime': { id: 'group:runtime', tools: ['exec', 'bash', 'process'] },
|
|
13
|
+
'File System': { id: 'group:fs', tools: ['read', 'write', 'edit', 'apply_patch'] },
|
|
14
|
+
'Sessions': { id: 'group:sessions', tools: ['sessions_list', 'sessions_history', 'sessions_send', 'sessions_spawn', 'session_status'] },
|
|
15
|
+
'Memory': { id: 'group:memory', tools: ['memory_search', 'memory_get'] },
|
|
16
|
+
'UI': { id: 'group:ui', tools: ['browser', 'canvas'] },
|
|
17
|
+
'Automation': { id: 'group:automation', tools: ['cron', 'gateway'] },
|
|
18
|
+
'Messaging': { id: 'group:messaging', tools: ['message'] },
|
|
19
|
+
'Nodes': { id: 'group:nodes', tools: ['nodes'] },
|
|
20
|
+
'Web': { id: 'group:web', tools: ['web_search', 'web_fetch'] },
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// All individual tools for the tool editor
|
|
24
|
+
export const ALL_TOOLS = [
|
|
25
|
+
'exec', 'bash', 'process', 'read', 'write', 'edit', 'apply_patch',
|
|
26
|
+
'sessions_list', 'sessions_history', 'sessions_send', 'sessions_spawn', 'session_status',
|
|
27
|
+
'memory_search', 'memory_get', 'browser', 'canvas', 'cron', 'gateway',
|
|
28
|
+
'message', 'nodes', 'web_search', 'web_fetch', 'tts', 'image',
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
// Tool presets
|
|
32
|
+
export const TOOL_PRESETS = {
|
|
33
|
+
full: { label: 'Full Access', mode: 'full', list: [] },
|
|
34
|
+
readonly: { label: 'Read Only', mode: 'allow', list: ['read', 'web_search', 'web_fetch', 'image', 'sessions_list', 'sessions_history', 'session_status'] },
|
|
35
|
+
safe: { label: 'Safe Execution', mode: 'allow', list: ['group:runtime', 'group:fs', 'group:sessions', 'group:web', 'image'] },
|
|
36
|
+
comms: { label: 'Communication', mode: 'allow', list: ['group:sessions', 'group:messaging', 'group:nodes', 'tts'] },
|
|
37
|
+
noexec: { label: 'No Exec', mode: 'deny', list: ['group:runtime'] },
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Helper functions
|
|
41
|
+
export function escapeHtml(str) {
|
|
42
|
+
if (!str) return '';
|
|
43
|
+
const div = document.createElement('div');
|
|
44
|
+
div.textContent = String(str);
|
|
45
|
+
return div.innerHTML;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function escapeAttr(str) {
|
|
49
|
+
if (!str) return '';
|
|
50
|
+
return String(str).replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function showToast(message, type = 'info') {
|
|
54
|
+
const notifications = window.UplinkNotifications;
|
|
55
|
+
if (notifications?.show) {
|
|
56
|
+
notifications.show(message, type);
|
|
57
|
+
} else {
|
|
58
|
+
console.log(`[Agents Toast] ${type}: ${message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Expose on window for backward compatibility
|
|
63
|
+
if (typeof window !== 'undefined') {
|
|
64
|
+
window.UplinkAgentsUI = {
|
|
65
|
+
TOOL_GROUPS,
|
|
66
|
+
ALL_TOOLS,
|
|
67
|
+
TOOL_PRESETS,
|
|
68
|
+
escapeHtml,
|
|
69
|
+
escapeAttr,
|
|
70
|
+
showToast
|
|
71
|
+
};
|
|
72
|
+
}
|