@agent-link/server 0.1.187 → 0.1.189

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.
Files changed (76) hide show
  1. package/dist/auth-manager.d.ts +36 -0
  2. package/dist/auth-manager.js +96 -0
  3. package/dist/auth-manager.js.map +1 -0
  4. package/dist/http.d.ts +4 -0
  5. package/dist/http.js +85 -0
  6. package/dist/http.js.map +1 -0
  7. package/dist/index.js +5 -84
  8. package/dist/index.js.map +1 -1
  9. package/dist/message-relay.d.ts +17 -0
  10. package/dist/message-relay.js +23 -0
  11. package/dist/message-relay.js.map +1 -0
  12. package/dist/session-manager.d.ts +44 -0
  13. package/dist/session-manager.js +83 -0
  14. package/dist/session-manager.js.map +1 -0
  15. package/dist/ws-agent.js +19 -27
  16. package/dist/ws-agent.js.map +1 -1
  17. package/dist/ws-client.js +31 -37
  18. package/dist/ws-client.js.map +1 -1
  19. package/package.json +3 -3
  20. package/web/dist/assets/index-DIO7Hox0.js +320 -0
  21. package/web/dist/assets/index-DIO7Hox0.js.map +1 -0
  22. package/web/dist/assets/index-Y1FN_mFe.css +1 -0
  23. package/web/{index.html → dist/index.html} +2 -19
  24. package/dist/auth.d.ts +0 -13
  25. package/dist/auth.js +0 -65
  26. package/dist/auth.js.map +0 -1
  27. package/dist/context.d.ts +0 -52
  28. package/dist/context.js +0 -60
  29. package/dist/context.js.map +0 -1
  30. package/web/app.js +0 -2881
  31. package/web/css/ask-question.css +0 -333
  32. package/web/css/base.css +0 -270
  33. package/web/css/btw.css +0 -148
  34. package/web/css/chat.css +0 -176
  35. package/web/css/file-browser.css +0 -499
  36. package/web/css/input.css +0 -671
  37. package/web/css/loop.css +0 -674
  38. package/web/css/markdown.css +0 -169
  39. package/web/css/responsive.css +0 -314
  40. package/web/css/sidebar.css +0 -593
  41. package/web/css/team.css +0 -1277
  42. package/web/css/tools.css +0 -327
  43. package/web/encryption.js +0 -56
  44. package/web/modules/appHelpers.js +0 -100
  45. package/web/modules/askQuestion.js +0 -63
  46. package/web/modules/backgroundRouting.js +0 -269
  47. package/web/modules/connection.js +0 -731
  48. package/web/modules/fileAttachments.js +0 -125
  49. package/web/modules/fileBrowser.js +0 -398
  50. package/web/modules/filePreview.js +0 -213
  51. package/web/modules/i18n.js +0 -101
  52. package/web/modules/loop.js +0 -338
  53. package/web/modules/loopTemplates.js +0 -110
  54. package/web/modules/markdown.js +0 -83
  55. package/web/modules/messageHelpers.js +0 -206
  56. package/web/modules/sidebar.js +0 -402
  57. package/web/modules/streaming.js +0 -116
  58. package/web/modules/team.js +0 -396
  59. package/web/modules/teamTemplates.js +0 -360
  60. package/web/vendor/highlight.min.js +0 -1213
  61. package/web/vendor/marked.min.js +0 -6
  62. package/web/vendor/nacl-fast.min.js +0 -1
  63. package/web/vendor/nacl-util.min.js +0 -1
  64. package/web/vendor/pako.min.js +0 -2
  65. package/web/vendor/vue.global.prod.js +0 -13
  66. /package/web/{favicon.svg → dist/favicon.svg} +0 -0
  67. /package/web/{images → dist/images}/chat-iPad.webp +0 -0
  68. /package/web/{images → dist/images}/chat-iPhone.webp +0 -0
  69. /package/web/{images → dist/images}/loop-iPad.webp +0 -0
  70. /package/web/{images → dist/images}/team-iPad.webp +0 -0
  71. /package/web/{landing.html → dist/landing.html} +0 -0
  72. /package/web/{landing.zh.html → dist/landing.zh.html} +0 -0
  73. /package/web/{locales → dist/locales}/en.json +0 -0
  74. /package/web/{locales → dist/locales}/zh.json +0 -0
  75. /package/web/{vendor → dist/vendor}/github-dark.min.css +0 -0
  76. /package/web/{vendor → dist/vendor}/github.min.css +0 -0
package/web/css/tools.css DELETED
@@ -1,327 +0,0 @@
1
- /* ── Tool use lines (collapsible, compact, subdued) ── */
2
- .tool-line-wrapper {
3
- max-width: 100%;
4
- padding-left: 0.25rem;
5
- overflow: hidden;
6
- }
7
-
8
- .tool-line {
9
- display: flex;
10
- align-items: center;
11
- gap: 6px;
12
- padding: 3px 6px;
13
- border-radius: 4px;
14
- font-size: 0.8rem;
15
- cursor: pointer;
16
- user-select: none;
17
- transition: background 0.15s;
18
- color: var(--text-secondary);
19
- min-width: 0;
20
- overflow: hidden;
21
- }
22
-
23
- .tool-line:hover {
24
- background: var(--bg-tertiary);
25
- }
26
-
27
- .tool-icon {
28
- flex-shrink: 0;
29
- display: flex;
30
- align-items: center;
31
- color: var(--text-secondary);
32
- opacity: 0.6;
33
- }
34
-
35
- .tool-name {
36
- font-weight: 500;
37
- color: var(--text-secondary);
38
- overflow: hidden;
39
- text-overflow: ellipsis;
40
- white-space: nowrap;
41
- min-width: 0;
42
- }
43
-
44
- .tool-summary {
45
- color: var(--text-secondary);
46
- overflow: hidden;
47
- text-overflow: ellipsis;
48
- white-space: nowrap;
49
- flex: 1;
50
- min-width: 0;
51
- }
52
-
53
- .tool-status-icon {
54
- color: var(--text-secondary);
55
- font-weight: normal;
56
- flex-shrink: 0;
57
- font-size: 0.75rem;
58
- opacity: 0.7;
59
- }
60
-
61
- .tool-line.completed .tool-status-icon {
62
- color: var(--success);
63
- opacity: 0.6;
64
- }
65
-
66
- .running-dots {
67
- display: inline-flex;
68
- gap: 2px;
69
- }
70
-
71
- .running-dots span {
72
- width: 3px;
73
- height: 3px;
74
- border-radius: 50%;
75
- background: var(--text-secondary);
76
- animation: typing 1.2s infinite ease-in-out;
77
- }
78
-
79
- .running-dots span:nth-child(2) { animation-delay: 0.2s; }
80
- .running-dots span:nth-child(3) { animation-delay: 0.4s; }
81
-
82
- .tool-toggle {
83
- color: var(--text-secondary);
84
- font-size: 0.6rem;
85
- flex-shrink: 0;
86
- margin-left: auto;
87
- opacity: 0.5;
88
- }
89
-
90
- .tool-expand {
91
- margin-top: 2px;
92
- margin-left: 20px;
93
- border-left: 1px solid var(--border);
94
- padding-left: 8px;
95
- overflow: hidden;
96
- animation: toolExpand 0.15s ease-out;
97
- }
98
-
99
- @keyframes toolExpand {
100
- from { opacity: 0; }
101
- to { opacity: 1; }
102
- }
103
-
104
- .tool-block {
105
- background: var(--bg-secondary);
106
- border-radius: 4px;
107
- padding: 0.4rem 0.6rem;
108
- margin-top: 0.25rem;
109
- overflow-x: auto;
110
- font-size: 0.75rem;
111
- line-height: 1.4;
112
- max-height: 200px;
113
- overflow-y: auto;
114
- white-space: pre-wrap;
115
- word-break: break-all;
116
- color: var(--text-secondary);
117
- }
118
-
119
- .tool-output {
120
- border-left: 2px solid var(--success);
121
- color: var(--text-primary);
122
- }
123
-
124
- /* ── Formatted tool input (Read, Write, Bash, Glob, Grep) ── */
125
- .tool-input-formatted {
126
- padding: 0.3rem 0.5rem;
127
- margin-top: 0.25rem;
128
- font-size: 0.75rem;
129
- line-height: 1.5;
130
- color: var(--text-secondary);
131
- word-break: break-all;
132
- }
133
-
134
- .tool-input-meta {
135
- color: var(--text-secondary);
136
- opacity: 0.6;
137
- }
138
-
139
- .tool-input-cmd {
140
- background: var(--bg-secondary);
141
- padding: 0.1rem 0.4rem;
142
- border-radius: 3px;
143
- font-size: 0.73rem;
144
- word-break: break-all;
145
- white-space: pre-wrap;
146
- }
147
-
148
- /* ── TodoWrite checklist ── */
149
- .todo-list {
150
- display: flex;
151
- flex-direction: column;
152
- gap: 2px;
153
- }
154
-
155
- .todo-item {
156
- display: flex;
157
- align-items: baseline;
158
- gap: 6px;
159
- font-size: 0.75rem;
160
- line-height: 1.4;
161
- color: var(--text-secondary);
162
- }
163
-
164
- .todo-item.todo-done {
165
- opacity: 0.55;
166
- }
167
-
168
- .todo-item.todo-active {
169
- color: var(--text-primary);
170
- }
171
-
172
- .todo-icon {
173
- flex-shrink: 0;
174
- width: 1em;
175
- text-align: center;
176
- font-size: 0.7rem;
177
- opacity: 0.5;
178
- }
179
-
180
- .todo-icon.done {
181
- color: var(--success);
182
- opacity: 0.8;
183
- }
184
-
185
- .todo-icon.active {
186
- color: var(--accent);
187
- opacity: 1;
188
- font-size: 0.55rem;
189
- }
190
-
191
- .todo-text {
192
- word-break: break-word;
193
- }
194
-
195
- /* ── Task / WebFetch formatted fields ── */
196
- .task-field {
197
- font-size: 0.75rem;
198
- line-height: 1.5;
199
- color: var(--text-secondary);
200
- }
201
-
202
- .task-field + .task-field {
203
- margin-top: 2px;
204
- }
205
-
206
- .task-prompt {
207
- background: var(--bg-secondary);
208
- border-radius: 3px;
209
- padding: 0.3rem 0.5rem;
210
- margin-top: 3px;
211
- font-size: 0.73rem;
212
- line-height: 1.4;
213
- color: var(--text-secondary);
214
- white-space: pre-wrap;
215
- word-break: break-word;
216
- max-height: 150px;
217
- overflow-y: auto;
218
- }
219
-
220
- .tool-link {
221
- color: var(--accent);
222
- font-size: 0.75rem;
223
- word-break: break-all;
224
- text-decoration: none;
225
- }
226
-
227
- .tool-link:hover {
228
- text-decoration: underline;
229
- }
230
-
231
- [data-theme="light"] .todo-icon.active {
232
- color: #0969da;
233
- }
234
-
235
- [data-theme="light"] .tool-link {
236
- color: #0969da;
237
- }
238
-
239
- /* ── Edit tool diff view ── */
240
- .tool-diff {
241
- background: var(--bg-secondary);
242
- border-radius: 4px;
243
- padding: 0.4rem 0.6rem;
244
- margin-top: 0.25rem;
245
- overflow-x: auto;
246
- font-size: 0.75rem;
247
- line-height: 1.5;
248
- max-height: 300px;
249
- overflow-y: auto;
250
- font-family: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', 'Consolas', monospace;
251
- }
252
-
253
- .diff-file {
254
- color: var(--text-secondary);
255
- margin-bottom: 0.35rem;
256
- font-weight: 500;
257
- }
258
-
259
- .diff-replace-all {
260
- opacity: 0.6;
261
- font-weight: 400;
262
- }
263
-
264
- .diff-lines {
265
- border-radius: 3px;
266
- overflow: hidden;
267
- }
268
-
269
- .diff-removed, .diff-added {
270
- white-space: pre-wrap;
271
- word-break: break-all;
272
- padding: 0 0.4rem;
273
- }
274
-
275
- .diff-removed {
276
- background: rgba(212, 84, 84, 0.12);
277
- color: #d4716b;
278
- }
279
-
280
- .diff-added {
281
- background: rgba(78, 173, 106, 0.12);
282
- color: #5cb87a;
283
- }
284
-
285
- .diff-sign {
286
- display: inline-block;
287
- width: 1.2em;
288
- user-select: none;
289
- opacity: 0.7;
290
- }
291
-
292
- [data-theme="light"] .diff-removed {
293
- background: rgba(208, 46, 38, 0.12);
294
- color: #b31d28;
295
- }
296
-
297
- [data-theme="light"] .diff-added {
298
- background: rgba(34, 134, 58, 0.12);
299
- color: #22863a;
300
- }
301
-
302
- /* ── Context summary (collapsible continuation notice) ── */
303
- .context-summary-wrapper {
304
- margin: 0.75rem 0;
305
- }
306
-
307
- /* ── Plan mode divider ── */
308
- .plan-mode-divider {
309
- display: flex;
310
- align-items: center;
311
- gap: 12px;
312
- margin: 8px 0;
313
- }
314
-
315
- .plan-mode-divider-line {
316
- flex: 1;
317
- height: 1px;
318
- background: var(--border);
319
- }
320
-
321
- .plan-mode-divider-text {
322
- font-size: 0.75rem;
323
- color: var(--text-secondary);
324
- white-space: nowrap;
325
- font-weight: 500;
326
- }
327
-
package/web/encryption.js DELETED
@@ -1,56 +0,0 @@
1
- /**
2
- * Browser-compatible encryption utilities using TweetNaCl and Pako from CDN.
3
- * Requires: nacl, nacl.util (tweetnacl-util), and pako globals.
4
- */
5
-
6
- const COMPRESS_THRESHOLD = 512;
7
-
8
- export function encrypt(data, key) {
9
- const nonce = nacl.randomBytes(24);
10
- const jsonStr = JSON.stringify(data);
11
-
12
- let message;
13
- let compressed = false;
14
-
15
- if (jsonStr.length > COMPRESS_THRESHOLD) {
16
- message = pako.gzip(jsonStr);
17
- compressed = true;
18
- } else {
19
- message = nacl.util.decodeUTF8(jsonStr);
20
- }
21
-
22
- const encrypted = nacl.secretbox(message, nonce, key);
23
- const result = {
24
- n: nacl.util.encodeBase64(nonce),
25
- c: nacl.util.encodeBase64(encrypted),
26
- };
27
- if (compressed) result.z = true;
28
- return result;
29
- }
30
-
31
- export function decrypt(encrypted, key) {
32
- try {
33
- const nonce = nacl.util.decodeBase64(encrypted.n);
34
- const ciphertext = nacl.util.decodeBase64(encrypted.c);
35
- const decrypted = nacl.secretbox.open(ciphertext, nonce, key);
36
- if (!decrypted) return null;
37
-
38
- if (encrypted.z) {
39
- const decompressed = pako.ungzip(decrypted, { to: 'string' });
40
- return JSON.parse(decompressed);
41
- } else {
42
- return JSON.parse(nacl.util.encodeUTF8(decrypted));
43
- }
44
- } catch (err) {
45
- console.error('[Decrypt] Failed:', err.message);
46
- return null;
47
- }
48
- }
49
-
50
- export function isEncrypted(msg) {
51
- return msg && typeof msg === 'object' && typeof msg.n === 'string' && typeof msg.c === 'string';
52
- }
53
-
54
- export function decodeKey(encodedKey) {
55
- return nacl.util.decodeBase64(encodedKey);
56
- }
@@ -1,100 +0,0 @@
1
- // ── UI utility functions for the main App component ──────────────────────────
2
-
3
- /**
4
- * Create scroll management functions.
5
- * @param {string} selector - CSS selector for the scrollable element
6
- * @returns {{ onScroll, scrollToBottom, cleanup }}
7
- */
8
- export function createScrollManager(selector) {
9
- let _rafId = null;
10
- let _userScrolledUp = false;
11
-
12
- function onScroll(e) {
13
- const el = e.target;
14
- _userScrolledUp = (el.scrollHeight - el.scrollTop - el.clientHeight) > 80;
15
- }
16
-
17
- function scrollToBottom(force) {
18
- if (_userScrolledUp && !force) return;
19
- if (document.hidden) return;
20
- if (_rafId) return;
21
- _rafId = requestAnimationFrame(() => {
22
- _rafId = null;
23
- const el = document.querySelector(selector);
24
- if (el) el.scrollTop = el.scrollHeight;
25
- });
26
- }
27
-
28
- function cleanup() {
29
- if (_rafId) { cancelAnimationFrame(_rafId); _rafId = null; }
30
- }
31
-
32
- return { onScroll, scrollToBottom, cleanup };
33
- }
34
-
35
- /**
36
- * Create a debounced highlight.js scheduler.
37
- * @returns {{ scheduleHighlight, cleanup }}
38
- */
39
- export function createHighlightScheduler() {
40
- let _hlTimer = null;
41
-
42
- function scheduleHighlight() {
43
- if (_hlTimer) return;
44
- _hlTimer = setTimeout(() => {
45
- _hlTimer = null;
46
- if (typeof hljs !== 'undefined') {
47
- const root = document.querySelector('.message-list') || document;
48
- root.querySelectorAll('pre code:not([data-highlighted])').forEach(block => {
49
- hljs.highlightElement(block);
50
- block.dataset.highlighted = 'true';
51
- });
52
- }
53
- }, 300);
54
- }
55
-
56
- function cleanup() {
57
- if (_hlTimer) { clearTimeout(_hlTimer); _hlTimer = null; }
58
- }
59
-
60
- return { scheduleHighlight, cleanup };
61
- }
62
-
63
- /**
64
- * Format a token count for display (e.g. 1500 → "1.5k").
65
- * @param {number} n
66
- * @returns {string}
67
- */
68
- export function formatTokens(n) {
69
- if (n >= 1000) return (n / 1000).toFixed(1) + 'k';
70
- return String(n);
71
- }
72
-
73
- export function formatDurationShort(ms) {
74
- if (!ms && ms !== 0) return '';
75
- const totalSecs = Math.floor(ms / 1000);
76
- if (totalSecs < 60) return (ms / 1000).toFixed(1) + 's';
77
- const m = Math.floor(totalSecs / 60);
78
- const s = totalSecs % 60;
79
- if (m < 60) return m + 'm ' + String(s).padStart(2, '0') + 's';
80
- const h = Math.floor(m / 60);
81
- const rm = m % 60;
82
- return h + 'h ' + String(rm).padStart(2, '0') + 'm';
83
- }
84
-
85
- /**
86
- * Format a usage stats object into a human-readable summary string.
87
- * @param {object|null} u - Usage stats from turn_completed
88
- * @returns {string}
89
- */
90
- export function formatUsage(u, t) {
91
- if (!u) return '';
92
- const pct = u.contextWindow ? Math.round(u.inputTokens / u.contextWindow * 100) : 0;
93
- const ctx = formatTokens(u.inputTokens) + ' / ' + formatTokens(u.contextWindow) + ' (' + pct + '%)';
94
- const cost = '$' + u.totalCost.toFixed(2);
95
- const model = u.model.replace(/^claude-/, '').replace(/-\d{8}$/, '').replace(/-1m$/, '');
96
- const dur = formatDurationShort(u.durationMs);
97
- const contextLabel = t ? t('usage.context') : 'Context';
98
- const costLabel = t ? t('usage.cost') : 'Cost';
99
- return contextLabel + ' ' + ctx + ' \u00b7 ' + costLabel + ' ' + cost + ' \u00b7 ' + model + ' \u00b7 ' + dur;
100
- }
@@ -1,63 +0,0 @@
1
- // ── AskUserQuestion interaction ───────────────────────────────────────────────
2
-
3
- export function selectQuestionOption(msg, qIndex, optLabel) {
4
- if (msg.answered) return;
5
- const q = msg.questions[qIndex];
6
- if (!q) return;
7
- if (q.multiSelect) {
8
- const sel = msg.selectedAnswers[qIndex] || [];
9
- const idx = sel.indexOf(optLabel);
10
- if (idx >= 0) sel.splice(idx, 1);
11
- else sel.push(optLabel);
12
- msg.selectedAnswers[qIndex] = [...sel];
13
- } else {
14
- msg.selectedAnswers[qIndex] = optLabel;
15
- msg.customTexts[qIndex] = '';
16
- }
17
- }
18
-
19
- export function submitQuestionAnswer(msg, wsSend) {
20
- if (msg.answered) return;
21
- const answers = {};
22
- for (let i = 0; i < msg.questions.length; i++) {
23
- const q = msg.questions[i];
24
- const key = q.question || String(i);
25
- const custom = (msg.customTexts[i] || '').trim();
26
- if (custom) {
27
- answers[key] = custom;
28
- } else {
29
- const sel = msg.selectedAnswers[i];
30
- if (Array.isArray(sel) && sel.length > 0) {
31
- answers[key] = sel.join(', ');
32
- } else if (sel != null) {
33
- answers[key] = sel;
34
- }
35
- }
36
- }
37
- msg.answered = true;
38
- wsSend({ type: 'ask_user_answer', requestId: msg.requestId, answers });
39
- }
40
-
41
- export function hasQuestionAnswer(msg) {
42
- for (let i = 0; i < msg.questions.length; i++) {
43
- const sel = msg.selectedAnswers[i];
44
- const custom = (msg.customTexts[i] || '').trim();
45
- if (custom || (Array.isArray(sel) ? sel.length > 0 : sel != null)) return true;
46
- }
47
- return false;
48
- }
49
-
50
- export function getQuestionResponseSummary(msg) {
51
- const parts = [];
52
- for (let i = 0; i < msg.questions.length; i++) {
53
- const custom = (msg.customTexts[i] || '').trim();
54
- if (custom) {
55
- parts.push(custom);
56
- } else {
57
- const sel = msg.selectedAnswers[i];
58
- if (Array.isArray(sel)) parts.push(sel.join(', '));
59
- else if (sel) parts.push(sel);
60
- }
61
- }
62
- return parts.join(' | ');
63
- }