@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,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, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
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
+ }