@agent-link/server 0.1.160 → 0.1.161

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.
@@ -0,0 +1,250 @@
1
+ {
2
+ "header.toggleSidebar": "Toggle sidebar",
3
+ "header.chat": "Chat",
4
+ "header.team": "Team",
5
+ "header.loop": "Loop",
6
+ "header.lightMode": "Switch to light mode",
7
+ "header.darkMode": "Switch to dark mode",
8
+
9
+ "status.noSession": "No Session",
10
+ "status.connecting": "Connecting...",
11
+ "status.connected": "Connected",
12
+ "status.waiting": "Waiting",
13
+ "status.reconnecting": "Reconnecting...",
14
+ "status.disconnected": "Disconnected",
15
+ "status.authRequired": "Authentication Required",
16
+ "status.locked": "Locked",
17
+
18
+ "statusCard.status": "Status:",
19
+ "statusCard.agent": "Agent:",
20
+ "statusCard.directory": "Directory:",
21
+ "statusCard.session": "Session:",
22
+
23
+ "sidebar.sessions": "Sessions",
24
+ "sidebar.files": "Files",
25
+ "sidebar.refresh": "Refresh",
26
+ "sidebar.close": "Close",
27
+ "sidebar.expand": "Expand",
28
+ "sidebar.collapse": "Collapse",
29
+ "sidebar.workingDirectory": "Working Directory",
30
+ "sidebar.browseFiles": "Browse files",
31
+ "sidebar.changeDirectory": "Change directory",
32
+ "sidebar.copyPath": "Copy path",
33
+ "sidebar.recentDirectories": "Recent Directories",
34
+ "sidebar.removeFromHistory": "Remove from history",
35
+ "sidebar.chatHistory": "Chat History",
36
+ "sidebar.newConversation": "New conversation",
37
+ "sidebar.loadingSessions": "Loading sessions...",
38
+ "sidebar.noSessions": "No previous sessions found.",
39
+ "sidebar.renameSession": "Rename session",
40
+ "sidebar.deleteSession": "Delete session",
41
+ "sidebar.confirm": "Confirm",
42
+ "sidebar.cancel": "Cancel",
43
+ "sidebar.teamsHistory": "Teams History",
44
+ "sidebar.newTeam": "New team",
45
+ "sidebar.untitledTeam": "Untitled team",
46
+ "sidebar.renameTeam": "Rename team",
47
+ "sidebar.deleteTeam": "Delete team",
48
+ "sidebar.loops": "Loops",
49
+ "sidebar.newLoop": "New loop",
50
+ "sidebar.noLoops": "No loops configured.",
51
+ "sidebar.untitledLoop": "Untitled loop",
52
+ "sidebar.renameLoop": "Rename loop",
53
+ "sidebar.deleteLoop": "Delete loop",
54
+ "sidebar.active": "active",
55
+ "sidebar.paused": "paused",
56
+ "sidebar.tasks": "tasks",
57
+ "sidebar.server": "server",
58
+ "sidebar.agent": "agent",
59
+
60
+ "filePanel.files": "Files",
61
+ "filePanel.loading": "Loading...",
62
+ "filePanel.noFiles": "No files found.",
63
+ "filePanel.empty": "(empty)",
64
+
65
+ "preview.preview": "Preview",
66
+ "preview.closePreview": "Close preview",
67
+ "preview.loading": "Loading...",
68
+ "preview.fileTruncated": "File truncated — showing first 100 KB of {size}",
69
+ "preview.binaryFile": "Binary file",
70
+ "preview.showSource": "Show source",
71
+ "preview.renderMarkdown": "Render markdown",
72
+
73
+ "team.launchAgentTeam": "Launch Agent Team",
74
+ "team.selectTemplateDesc": "Select a template, review the lead prompt, and describe your task.",
75
+ "team.template": "Template",
76
+ "team.leadPrompt": "Lead Prompt",
77
+ "team.taskDescription": "Task Description",
78
+ "team.taskPlaceholder": "Describe the task for the team... e.g. 'Review the authentication module for security issues and fix any vulnerabilities found.'",
79
+ "team.launchTeam": "Launch Team",
80
+ "team.backToChat": "Back to Chat",
81
+ "team.examples": "Examples",
82
+ "team.tryIt": "Try it",
83
+ "team.reset": "Reset",
84
+ "team.previousTeams": "Previous Teams",
85
+ "team.dissolveTeam": "Dissolve Team",
86
+ "team.newTeam": "New Team",
87
+ "team.agentTeam": "Agent Team",
88
+ "team.showLess": "Show less",
89
+ "team.showMore": "Show more",
90
+ "team.tasks": "Tasks",
91
+ "team.done": "done",
92
+ "team.pending": "Pending",
93
+ "team.activeCol": "Active",
94
+ "team.doneCol": "Done",
95
+ "team.failed": "Failed",
96
+ "team.noTasks": "No tasks",
97
+ "team.agents": "Agents",
98
+ "team.planningTasks": "Planning tasks...",
99
+ "team.noAgents": "No agents",
100
+ "team.activity": "Activity",
101
+ "team.lead": "Lead",
102
+ "team.tasksStat": "Tasks",
103
+ "team.duration": "Duration",
104
+ "team.cost": "Cost",
105
+ "team.agentsStat": "Agents",
106
+ "team.summary": "Summary",
107
+ "team.dashboard": "Dashboard",
108
+ "team.noMessages": "No messages yet.",
109
+ "team.taskPrompt": "Task Prompt",
110
+ "team.agentResult": "Agent Result",
111
+ "team.launchAnotherPlaceholder": "Launch another team task...",
112
+
113
+ "loop.editLoop": "Edit Loop",
114
+ "loop.createLoop": "Create a Scheduled Loop",
115
+ "loop.createDesc": "Configure recurring tasks that run on a schedule. Select a template or create your own.",
116
+ "loop.templates": "Templates",
117
+ "loop.name": "Name",
118
+ "loop.namePlaceholder": "e.g. Daily Code Review",
119
+ "loop.prompt": "Prompt",
120
+ "loop.promptPlaceholder": "Describe what the Loop should do each time it runs...",
121
+ "loop.schedule": "Schedule",
122
+ "loop.manual": "Manual",
123
+ "loop.manualDetail": "run only when triggered",
124
+ "loop.everyHour": "Every hour",
125
+ "loop.everyDay": "Every day",
126
+ "loop.advancedCron": "Advanced (cron)",
127
+ "loop.saveChanges": "Save Changes",
128
+ "loop.createLoopBtn": "Create Loop",
129
+ "loop.cancel": "Cancel",
130
+ "loop.backToChat": "Back to Chat",
131
+ "loop.backToLoops": "Back to Loops",
132
+ "loop.enabled": "Enabled",
133
+ "loop.disabled": "Disabled",
134
+ "loop.edit": "Edit",
135
+ "loop.runNow": "Run Now",
136
+ "loop.enable": "Enable",
137
+ "loop.disable": "Disable",
138
+ "loop.executionHistory": "Execution History",
139
+ "loop.loadingExecutions": "Loading executions...",
140
+ "loop.noExecutions": "No executions yet.",
141
+ "loop.running": "Running...",
142
+ "loop.loadingExecution": "Loading execution...",
143
+ "loop.noExecMessages": "No messages recorded for this execution.",
144
+ "loop.loopPrompt": "Loop Prompt",
145
+ "loop.view": "View",
146
+ "loop.cancelExec": "Cancel",
147
+ "loop.loadMore": "Load more",
148
+ "loop.activeLoops": "Active Loops",
149
+ "loop.run": "Run",
150
+ "loop.pause": "Pause",
151
+ "loop.resume": "Resume",
152
+ "loop.del": "Del",
153
+ "loop.deleteLoop": "Delete Loop",
154
+ "loop.deleteConfirm": "Are you sure you want to delete <strong>{name}</strong>? This cannot be undone.",
155
+ "loop.delete": "Delete",
156
+ "loop.isRunning": "is running...",
157
+ "loop.manualBadge": "manual",
158
+
159
+ "chat.you": "You",
160
+ "chat.claude": "Claude",
161
+ "chat.copy": "Copy",
162
+ "chat.copied": "Copied!",
163
+ "chat.contextContinued": "Context continued from previous conversation",
164
+ "chat.hide": "Hide",
165
+ "chat.show": "Show",
166
+ "chat.connectedTo": "Connected to",
167
+ "chat.sendToStart": "Send a message to start.",
168
+ "chat.loadingHistory": "Loading conversation history...",
169
+ "chat.loadEarlier": "Load earlier messages",
170
+ "chat.submit": "Submit",
171
+ "chat.customResponse": "Or type a custom response...",
172
+
173
+ "input.placeholder": "Send a message · Enter to send",
174
+ "input.compacting": "Context compacting in progress...",
175
+ "input.removeFromQueue": "Remove from queue",
176
+ "input.attachFiles": "Attach files",
177
+ "input.stopGeneration": "Stop generation",
178
+ "input.send": "Send",
179
+ "input.remove": "Remove",
180
+
181
+ "folderPicker.title": "Select Working Directory",
182
+ "folderPicker.pathPlaceholder": "Enter path...",
183
+ "folderPicker.parentDir": "Go to parent directory",
184
+ "folderPicker.noSubdirs": "No subdirectories found.",
185
+ "folderPicker.cancel": "Cancel",
186
+ "folderPicker.open": "Open",
187
+
188
+ "dialog.deleteSession": "Delete Session",
189
+ "dialog.deleteSessionConfirm": "Are you sure you want to delete this session?",
190
+ "dialog.cannotUndo": "This action cannot be undone.",
191
+ "dialog.cancel": "Cancel",
192
+ "dialog.delete": "Delete",
193
+ "dialog.deleteTeam": "Delete Team",
194
+ "dialog.deleteTeamConfirm": "Are you sure you want to delete this team?",
195
+
196
+ "auth.sessionProtected": "Session Protected",
197
+ "auth.passwordRequired": "This session requires a password to access.",
198
+ "auth.passwordPlaceholder": "Enter password...",
199
+ "auth.unlock": "Unlock",
200
+ "auth.accessLocked": "Access Locked",
201
+ "auth.tryAgainLater": "Close this tab and try again later.",
202
+
203
+ "workdir.switching": "Switching directory...",
204
+
205
+ "contextMenu.askClaudeRead": "Ask Claude to read",
206
+ "contextMenu.copyPath": "Copy path",
207
+ "contextMenu.copied": "Copied!",
208
+ "contextMenu.insertPath": "Insert path to input",
209
+
210
+ "system.newConversation": "New conversation started.",
211
+ "system.contextCompacting": "Context compacting...",
212
+ "system.contextCompacted": "Context compacted",
213
+ "system.generationStopped": "Generation stopped.",
214
+ "system.agentProcessing": "Agent is processing...",
215
+ "system.sessionRestored": "Session restored. You can continue the conversation.",
216
+ "system.workdirChanged": "Working directory changed to: {dir}",
217
+
218
+ "error.noSessionId": "No session ID in URL. Use a session URL provided by agentlink start.",
219
+ "error.incorrectPassword": "Incorrect password.",
220
+ "error.tooManyAttempts": "Too many failed attempts.",
221
+ "error.agentNotConnected": "Agent is not connected yet.",
222
+ "error.agentDisconnected": "Agent disconnected. Waiting for reconnect...",
223
+ "error.unableToReconnect": "Unable to reconnect. Please refresh the page.",
224
+ "error.connectionLost": "Connection lost. Reconnecting... (attempt {n})",
225
+ "error.attemptsRemaining": "{n} attempt(s) remaining",
226
+
227
+ "time.justNow": "just now",
228
+ "time.minutesAgo": "{n}m ago",
229
+ "time.hoursAgo": "{n}h ago",
230
+ "time.daysAgo": "{n}d ago",
231
+
232
+ "session.today": "Today",
233
+ "session.yesterday": "Yesterday",
234
+ "session.thisWeek": "This week",
235
+ "session.earlier": "Earlier",
236
+
237
+ "tool.description": "Description",
238
+ "tool.agent": "Agent",
239
+ "tool.prompt": "Prompt",
240
+ "tool.lines": "lines {start}–{end}",
241
+ "tool.fromLine": "from line {offset}",
242
+ "tool.firstLines": "first {limit} lines",
243
+ "tool.lineCount": "{n} lines",
244
+ "tool.inPath": "in {path}",
245
+ "tool.done": "{done}/{total} done",
246
+ "tool.replaceAll": "(replace all)",
247
+
248
+ "usage.context": "Context",
249
+ "usage.cost": "Cost"
250
+ }
@@ -0,0 +1,250 @@
1
+ {
2
+ "header.toggleSidebar": "切换侧栏",
3
+ "header.chat": "Chat",
4
+ "header.team": "Team",
5
+ "header.loop": "Loop",
6
+ "header.lightMode": "切换到浅色模式",
7
+ "header.darkMode": "切换到深色模式",
8
+
9
+ "status.noSession": "无会话",
10
+ "status.connecting": "连接中...",
11
+ "status.connected": "已连接",
12
+ "status.waiting": "等待中",
13
+ "status.reconnecting": "重新连接中...",
14
+ "status.disconnected": "已断开",
15
+ "status.authRequired": "需要认证",
16
+ "status.locked": "已锁定",
17
+
18
+ "statusCard.status": "状态:",
19
+ "statusCard.agent": "代理:",
20
+ "statusCard.directory": "目录:",
21
+ "statusCard.session": "会话:",
22
+
23
+ "sidebar.sessions": "会话",
24
+ "sidebar.files": "文件",
25
+ "sidebar.refresh": "刷新",
26
+ "sidebar.close": "关闭",
27
+ "sidebar.expand": "展开",
28
+ "sidebar.collapse": "折叠",
29
+ "sidebar.workingDirectory": "工作目录",
30
+ "sidebar.browseFiles": "浏览文件",
31
+ "sidebar.changeDirectory": "更改目录",
32
+ "sidebar.copyPath": "复制路径",
33
+ "sidebar.recentDirectories": "最近目录",
34
+ "sidebar.removeFromHistory": "从历史记录中移除",
35
+ "sidebar.chatHistory": "Chat History",
36
+ "sidebar.newConversation": "新对话",
37
+ "sidebar.loadingSessions": "加载会话中...",
38
+ "sidebar.noSessions": "没有找到历史会话。",
39
+ "sidebar.renameSession": "重命名会话",
40
+ "sidebar.deleteSession": "删除会话",
41
+ "sidebar.confirm": "确认",
42
+ "sidebar.cancel": "取消",
43
+ "sidebar.teamsHistory": "Teams History",
44
+ "sidebar.newTeam": "新建团队",
45
+ "sidebar.untitledTeam": "未命名团队",
46
+ "sidebar.renameTeam": "重命名团队",
47
+ "sidebar.deleteTeam": "删除团队",
48
+ "sidebar.loops": "Loops",
49
+ "sidebar.newLoop": "新建循环",
50
+ "sidebar.noLoops": "暂无循环配置。",
51
+ "sidebar.untitledLoop": "未命名循环",
52
+ "sidebar.renameLoop": "重命名循环",
53
+ "sidebar.deleteLoop": "删除循环",
54
+ "sidebar.active": "活跃",
55
+ "sidebar.paused": "暂停",
56
+ "sidebar.tasks": "个任务",
57
+ "sidebar.server": "server",
58
+ "sidebar.agent": "agent",
59
+
60
+ "filePanel.files": "文件",
61
+ "filePanel.loading": "加载中...",
62
+ "filePanel.noFiles": "未找到文件。",
63
+ "filePanel.empty": "(空)",
64
+
65
+ "preview.preview": "预览",
66
+ "preview.closePreview": "关闭预览",
67
+ "preview.loading": "加载中...",
68
+ "preview.fileTruncated": "文件已截断 — 显示前 100 KB(共 {size})",
69
+ "preview.binaryFile": "二进制文件",
70
+ "preview.showSource": "显示源码",
71
+ "preview.renderMarkdown": "渲染 Markdown",
72
+
73
+ "team.launchAgentTeam": "启动代理团队",
74
+ "team.selectTemplateDesc": "选择模板,查看主导提示词,并描述您的任务。",
75
+ "team.template": "模板",
76
+ "team.leadPrompt": "主导提示词",
77
+ "team.taskDescription": "任务描述",
78
+ "team.taskPlaceholder": "描述团队任务...例如「审查认证模块的安全问题并修复发现的漏洞。」",
79
+ "team.launchTeam": "启动团队",
80
+ "team.backToChat": "返回对话",
81
+ "team.examples": "示例",
82
+ "team.tryIt": "试一试",
83
+ "team.reset": "重置",
84
+ "team.previousTeams": "历史团队",
85
+ "team.dissolveTeam": "解散团队",
86
+ "team.newTeam": "新建团队",
87
+ "team.agentTeam": "代理团队",
88
+ "team.showLess": "收起",
89
+ "team.showMore": "展开",
90
+ "team.tasks": "任务",
91
+ "team.done": "已完成",
92
+ "team.pending": "待处理",
93
+ "team.activeCol": "进行中",
94
+ "team.doneCol": "已完成",
95
+ "team.failed": "失败",
96
+ "team.noTasks": "暂无任务",
97
+ "team.agents": "代理",
98
+ "team.planningTasks": "正在规划任务...",
99
+ "team.noAgents": "暂无代理",
100
+ "team.activity": "活动",
101
+ "team.lead": "主导",
102
+ "team.tasksStat": "任务",
103
+ "team.duration": "耗时",
104
+ "team.cost": "费用",
105
+ "team.agentsStat": "代理",
106
+ "team.summary": "总结",
107
+ "team.dashboard": "控制台",
108
+ "team.noMessages": "暂无消息。",
109
+ "team.taskPrompt": "任务提示",
110
+ "team.agentResult": "代理结果",
111
+ "team.launchAnotherPlaceholder": "启动另一个团队任务...",
112
+
113
+ "loop.editLoop": "编辑循环",
114
+ "loop.createLoop": "创建定时循环",
115
+ "loop.createDesc": "配置按计划运行的重复任务。选择模板或自行创建。",
116
+ "loop.templates": "模板",
117
+ "loop.name": "名称",
118
+ "loop.namePlaceholder": "例如「每日代码审查」",
119
+ "loop.prompt": "提示词",
120
+ "loop.promptPlaceholder": "描述循环每次运行时应执行的操作...",
121
+ "loop.schedule": "计划",
122
+ "loop.manual": "手动",
123
+ "loop.manualDetail": "仅在手动触发时运行",
124
+ "loop.everyHour": "每小时",
125
+ "loop.everyDay": "每天",
126
+ "loop.advancedCron": "高级 (cron)",
127
+ "loop.saveChanges": "保存更改",
128
+ "loop.createLoopBtn": "创建循环",
129
+ "loop.cancel": "取消",
130
+ "loop.backToChat": "返回对话",
131
+ "loop.backToLoops": "返回循环列表",
132
+ "loop.enabled": "已启用",
133
+ "loop.disabled": "已禁用",
134
+ "loop.edit": "编辑",
135
+ "loop.runNow": "立即运行",
136
+ "loop.enable": "启用",
137
+ "loop.disable": "禁用",
138
+ "loop.executionHistory": "执行历史",
139
+ "loop.loadingExecutions": "加载执行记录...",
140
+ "loop.noExecutions": "暂无执行记录。",
141
+ "loop.running": "运行中...",
142
+ "loop.loadingExecution": "加载执行记录...",
143
+ "loop.noExecMessages": "此次执行无消息记录。",
144
+ "loop.loopPrompt": "循环提示词",
145
+ "loop.view": "查看",
146
+ "loop.cancelExec": "取消",
147
+ "loop.loadMore": "加载更多",
148
+ "loop.activeLoops": "活跃循环",
149
+ "loop.run": "运行",
150
+ "loop.pause": "暂停",
151
+ "loop.resume": "恢复",
152
+ "loop.del": "删除",
153
+ "loop.deleteLoop": "删除循环",
154
+ "loop.deleteConfirm": "确定要删除 <strong>{name}</strong> 吗?此操作无法撤销。",
155
+ "loop.delete": "删除",
156
+ "loop.isRunning": "运行中...",
157
+ "loop.manualBadge": "手动",
158
+
159
+ "chat.you": "你",
160
+ "chat.claude": "Claude",
161
+ "chat.copy": "复制",
162
+ "chat.copied": "已复制!",
163
+ "chat.contextContinued": "上下文从上一次对话中延续",
164
+ "chat.hide": "隐藏",
165
+ "chat.show": "显示",
166
+ "chat.connectedTo": "已连接到",
167
+ "chat.sendToStart": "发送消息以开始。",
168
+ "chat.loadingHistory": "加载对话历史中...",
169
+ "chat.loadEarlier": "加载更早的消息",
170
+ "chat.submit": "提交",
171
+ "chat.customResponse": "或输入自定义回复...",
172
+
173
+ "input.placeholder": "发送消息 · 按 Enter 发送",
174
+ "input.compacting": "上下文压缩中...",
175
+ "input.removeFromQueue": "从队列中移除",
176
+ "input.attachFiles": "附加文件",
177
+ "input.stopGeneration": "停止生成",
178
+ "input.send": "发送",
179
+ "input.remove": "移除",
180
+
181
+ "folderPicker.title": "选择工作目录",
182
+ "folderPicker.pathPlaceholder": "输入路径...",
183
+ "folderPicker.parentDir": "返回上级目录",
184
+ "folderPicker.noSubdirs": "未找到子目录。",
185
+ "folderPicker.cancel": "取消",
186
+ "folderPicker.open": "打开",
187
+
188
+ "dialog.deleteSession": "删除会话",
189
+ "dialog.deleteSessionConfirm": "确定要删除此会话吗?",
190
+ "dialog.cannotUndo": "此操作无法撤销。",
191
+ "dialog.cancel": "取消",
192
+ "dialog.delete": "删除",
193
+ "dialog.deleteTeam": "删除团队",
194
+ "dialog.deleteTeamConfirm": "确定要删除此团队吗?",
195
+
196
+ "auth.sessionProtected": "会话已保护",
197
+ "auth.passwordRequired": "访问此会话需要密码。",
198
+ "auth.passwordPlaceholder": "输入密码...",
199
+ "auth.unlock": "解锁",
200
+ "auth.accessLocked": "访问已锁定",
201
+ "auth.tryAgainLater": "关闭此标签页,稍后再试。",
202
+
203
+ "workdir.switching": "正在切换目录...",
204
+
205
+ "contextMenu.askClaudeRead": "让 Claude 读取",
206
+ "contextMenu.copyPath": "复制路径",
207
+ "contextMenu.copied": "已复制!",
208
+ "contextMenu.insertPath": "插入路径到输入框",
209
+
210
+ "system.newConversation": "新对话已开始。",
211
+ "system.contextCompacting": "上下文压缩中...",
212
+ "system.contextCompacted": "上下文已压缩",
213
+ "system.generationStopped": "生成已停止。",
214
+ "system.agentProcessing": "代理处理中...",
215
+ "system.sessionRestored": "会话已恢复。您可以继续对话。",
216
+ "system.workdirChanged": "工作目录已更改为:{dir}",
217
+
218
+ "error.noSessionId": "URL 中没有会话 ID。请使用 agentlink start 提供的会话 URL。",
219
+ "error.incorrectPassword": "密码错误。",
220
+ "error.tooManyAttempts": "失败次数过多。",
221
+ "error.agentNotConnected": "代理尚未连接。",
222
+ "error.agentDisconnected": "代理已断开连接。等待重新连接...",
223
+ "error.unableToReconnect": "无法重新连接。请刷新页面。",
224
+ "error.connectionLost": "连接中断。正在重新连接...(第 {n} 次尝试)",
225
+ "error.attemptsRemaining": "剩余 {n} 次尝试机会",
226
+
227
+ "time.justNow": "刚刚",
228
+ "time.minutesAgo": "{n}分钟前",
229
+ "time.hoursAgo": "{n}小时前",
230
+ "time.daysAgo": "{n}天前",
231
+
232
+ "session.today": "今天",
233
+ "session.yesterday": "昨天",
234
+ "session.thisWeek": "本周",
235
+ "session.earlier": "更早",
236
+
237
+ "tool.description": "描述",
238
+ "tool.agent": "代理",
239
+ "tool.prompt": "提示词",
240
+ "tool.lines": "第 {start}–{end} 行",
241
+ "tool.fromLine": "从第 {offset} 行",
242
+ "tool.firstLines": "前 {limit} 行",
243
+ "tool.lineCount": "{n} 行",
244
+ "tool.inPath": "在 {path}",
245
+ "tool.done": "{done}/{total} 已完成",
246
+ "tool.replaceAll": "(全部替换)",
247
+
248
+ "usage.context": "上下文",
249
+ "usage.cost": "费用"
250
+ }
@@ -73,12 +73,14 @@ export function formatTokens(n) {
73
73
  * @param {object|null} u - Usage stats from turn_completed
74
74
  * @returns {string}
75
75
  */
76
- export function formatUsage(u) {
76
+ export function formatUsage(u, t) {
77
77
  if (!u) return '';
78
78
  const pct = u.contextWindow ? Math.round(u.inputTokens / u.contextWindow * 100) : 0;
79
79
  const ctx = formatTokens(u.inputTokens) + ' / ' + formatTokens(u.contextWindow) + ' (' + pct + '%)';
80
80
  const cost = '$' + u.totalCost.toFixed(2);
81
81
  const model = u.model.replace(/^claude-/, '').replace(/-\d{8}$/, '').replace(/-1m$/, '');
82
82
  const dur = (u.durationMs / 1000).toFixed(1) + 's';
83
- return 'Context ' + ctx + ' \u00b7 Cost ' + cost + ' \u00b7 ' + model + ' \u00b7 ' + dur;
83
+ const contextLabel = t ? t('usage.context') : 'Context';
84
+ const costLabel = t ? t('usage.cost') : 'Cost';
85
+ return contextLabel + ' ' + ctx + ' \u00b7 ' + costLabel + ' ' + cost + ' \u00b7 ' + model + ' \u00b7 ' + dur;
84
86
  }
@@ -25,6 +25,8 @@ export function createConnection(deps) {
25
25
  // Multi-session parallel
26
26
  currentConversationId, processingConversations, conversationCache,
27
27
  switchConversation,
28
+ // i18n
29
+ t,
28
30
  } = deps;
29
31
 
30
32
  // Dequeue callback — set after creation to resolve circular dependency
@@ -163,7 +165,7 @@ export function createConnection(deps) {
163
165
  const sid = getSessionId();
164
166
  if (!sid) {
165
167
  status.value = 'No Session';
166
- error.value = 'No session ID in URL. Use a session URL provided by agentlink start.';
168
+ error.value = t('error.noSessionId');
167
169
  return;
168
170
  }
169
171
  sessionId.value = sid;
@@ -194,9 +196,9 @@ export function createConnection(deps) {
194
196
  return;
195
197
  }
196
198
  if (parsed.type === 'auth_failed') {
197
- authError.value = parsed.message || 'Incorrect password.';
199
+ authError.value = parsed.message || t('error.incorrectPassword');
198
200
  authAttempts.value = parsed.attemptsRemaining != null
199
- ? `${parsed.attemptsRemaining} attempt${parsed.attemptsRemaining !== 1 ? 's' : ''} remaining`
201
+ ? t('error.attemptsRemaining', { n: parsed.attemptsRemaining })
200
202
  : null;
201
203
  authPassword.value = '';
202
204
  return;
@@ -204,7 +206,7 @@ export function createConnection(deps) {
204
206
  if (parsed.type === 'auth_locked') {
205
207
  authLocked.value = true;
206
208
  authRequired.value = false;
207
- authError.value = parsed.message || 'Too many failed attempts.';
209
+ authError.value = parsed.message || t('error.tooManyAttempts');
208
210
  status.value = 'Locked';
209
211
  return;
210
212
  }
@@ -283,7 +285,7 @@ export function createConnection(deps) {
283
285
  wsSend({ type: 'query_active_conversations' });
284
286
  } else {
285
287
  status.value = 'Waiting';
286
- error.value = 'Agent is not connected yet.';
288
+ error.value = t('error.agentNotConnected');
287
289
  }
288
290
  } else if (msg.type === 'pong') {
289
291
  if (typeof msg.ts === 'number') {
@@ -294,7 +296,7 @@ export function createConnection(deps) {
294
296
  status.value = 'Waiting';
295
297
  agentName.value = '';
296
298
  hostname.value = '';
297
- error.value = 'Agent disconnected. Waiting for reconnect...';
299
+ error.value = t('error.agentDisconnected');
298
300
  isProcessing.value = false;
299
301
  isCompacting.value = false;
300
302
  queuedMessages.value = [];
@@ -423,7 +425,7 @@ export function createConnection(deps) {
423
425
  isCompacting.value = true;
424
426
  messages.value.push({
425
427
  id: streaming.nextId(), role: 'system',
426
- content: 'Context compacting...', isCompactStart: true,
428
+ content: t('system.contextCompacting'), isCompactStart: true,
427
429
  timestamp: new Date(),
428
430
  });
429
431
  scrollToBottom();
@@ -432,7 +434,7 @@ export function createConnection(deps) {
432
434
  // Update the start message to show completed
433
435
  const startMsg = [...messages.value].reverse().find(m => m.isCompactStart && !m.compactDone);
434
436
  if (startMsg) {
435
- startMsg.content = 'Context compacted';
437
+ startMsg.content = t('system.contextCompacted');
436
438
  startMsg.compactDone = true;
437
439
  }
438
440
  scrollToBottom();
@@ -451,7 +453,7 @@ export function createConnection(deps) {
451
453
  needsResume.value = true;
452
454
  messages.value.push({
453
455
  id: streaming.nextId(), role: 'system',
454
- content: 'Generation stopped.', timestamp: new Date(),
456
+ content: t('system.generationStopped'), timestamp: new Date(),
455
457
  });
456
458
  scrollToBottom();
457
459
  }
@@ -507,20 +509,20 @@ export function createConnection(deps) {
507
509
  isProcessing.value = true;
508
510
  messages.value.push({
509
511
  id: streaming.nextId(), role: 'system',
510
- content: 'Context compacting...', isCompactStart: true,
512
+ content: t('system.contextCompacting'), isCompactStart: true,
511
513
  timestamp: new Date(),
512
514
  });
513
515
  } else if (msg.isProcessing) {
514
516
  isProcessing.value = true;
515
517
  messages.value.push({
516
518
  id: streaming.nextId(), role: 'system',
517
- content: 'Agent is processing...',
519
+ content: t('system.agentProcessing'),
518
520
  timestamp: new Date(),
519
521
  });
520
522
  } else {
521
523
  messages.value.push({
522
524
  id: streaming.nextId(), role: 'system',
523
- content: 'Session restored. You can continue the conversation.',
525
+ content: t('system.sessionRestored'),
524
526
  timestamp: new Date(),
525
527
  });
526
528
  }
@@ -564,7 +566,7 @@ export function createConnection(deps) {
564
566
  }
565
567
  messages.value.push({
566
568
  id: streaming.nextId(), role: 'system',
567
- content: 'Working directory changed to: ' + msg.workDir,
569
+ content: t('system.workdirChanged', { dir: msg.workDir }),
568
570
  timestamp: new Date(),
569
571
  });
570
572
  // Clear old history immediately so UI doesn't show stale data
@@ -601,13 +603,13 @@ export function createConnection(deps) {
601
603
  function scheduleReconnect(scheduleHighlight) {
602
604
  if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
603
605
  status.value = 'Disconnected';
604
- error.value = 'Unable to reconnect. Please refresh the page.';
606
+ error.value = t('error.unableToReconnect');
605
607
  return;
606
608
  }
607
609
  const delay = Math.min(RECONNECT_BASE_DELAY * Math.pow(1.5, reconnectAttempts), RECONNECT_MAX_DELAY);
608
610
  reconnectAttempts++;
609
611
  status.value = 'Reconnecting...';
610
- error.value = 'Connection lost. Reconnecting... (attempt ' + reconnectAttempts + ')';
612
+ error.value = t('error.connectionLost', { n: reconnectAttempts });
611
613
  if (reconnectTimer) clearTimeout(reconnectTimer);
612
614
  reconnectTimer = setTimeout(() => { reconnectTimer = null; connect(scheduleHighlight); }, delay);
613
615
  }