@steerable/agent-shell-web 0.6.53 → 0.6.55

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 (90) hide show
  1. package/package.json +4 -4
  2. package/src/brand.ts +1 -1
  3. package/src/components/AgentSidebar.tsx +60 -52
  4. package/src/components/ChatHeader.tsx +41 -25
  5. package/src/components/ConfirmDialog.tsx +4 -3
  6. package/src/components/CreateProjectModal.tsx +29 -19
  7. package/src/components/LocalLlmSettingsModal.tsx +4 -3
  8. package/src/components/SidebarRelease.tsx +2 -1
  9. package/src/components/TerminalPanel.tsx +3 -2
  10. package/src/components/TerminalView.tsx +12 -7
  11. package/src/components/chat/ApprovalModal.tsx +39 -25
  12. package/src/components/chat/ApprovalPromptProvider.tsx +1 -1
  13. package/src/components/chat/AskUserPromptProvider.tsx +1 -1
  14. package/src/components/chat/AskUserQuestionMenu.tsx +19 -14
  15. package/src/components/chat/AssistantMessage.tsx +18 -13
  16. package/src/components/chat/ChatInput.tsx +56 -40
  17. package/src/components/chat/ChatProjectBadge.tsx +24 -19
  18. package/src/components/chat/EmptyChatHero.tsx +2 -1
  19. package/src/components/chat/ExecPolicyPicker.tsx +12 -11
  20. package/src/components/chat/ExecutedActionsCard.tsx +45 -33
  21. package/src/components/chat/FilePathCode.tsx +8 -3
  22. package/src/components/chat/InterruptedTurnCard.tsx +4 -3
  23. package/src/components/chat/LocalChatPanel.tsx +2 -1
  24. package/src/components/chat/Markdown.tsx +2 -1
  25. package/src/components/chat/MessageList.tsx +3 -2
  26. package/src/components/chat/ModelPicker.tsx +25 -16
  27. package/src/components/chat/OrchestrationChildrenCard.tsx +2 -1
  28. package/src/components/chat/OrchestrationFlowCard.tsx +23 -22
  29. package/src/components/chat/PlanTodoList.tsx +2 -1
  30. package/src/components/chat/ProjectTrustBanner.tsx +19 -5
  31. package/src/components/chat/SessionOrchestrationFlow.tsx +27 -26
  32. package/src/components/chat/SessionTodoList.tsx +8 -7
  33. package/src/components/chat/SessionTreeModal.tsx +10 -9
  34. package/src/components/chat/StreamingStatus.tsx +4 -3
  35. package/src/components/chat/SuggestedReplies.tsx +3 -2
  36. package/src/components/chat/TaskOutcomeCards.tsx +8 -5
  37. package/src/components/chat/TaskPanelModal.tsx +31 -21
  38. package/src/components/chat/TaskProcessPanel.tsx +14 -13
  39. package/src/components/chat/TurnFilesCard.tsx +14 -13
  40. package/src/components/chat/UserMessage.tsx +12 -11
  41. package/src/components/chat/executed-actions-model.ts +47 -35
  42. package/src/components/chat/orchestration-flow-model.ts +16 -5
  43. package/src/components/chat/process-status.ts +8 -7
  44. package/src/components/chat/todo-list-model.ts +5 -4
  45. package/src/components/chat/turn-files.ts +8 -8
  46. package/src/components/settings/AgentCapabilityFields.tsx +24 -21
  47. package/src/components/settings/AgentsSettingsPanel.tsx +30 -25
  48. package/src/components/settings/AppUpdateSettingsPanel.tsx +3 -2
  49. package/src/components/settings/AppearanceSettingsPanel.tsx +81 -37
  50. package/src/components/settings/DiagnoseSettingsPanel.tsx +11 -8
  51. package/src/components/settings/InsightsSettingsPanel.tsx +43 -28
  52. package/src/components/settings/LlmSettingsPanel.tsx +104 -83
  53. package/src/components/settings/McpSettingsPanel.tsx +60 -34
  54. package/src/components/settings/ModelIdCombobox.tsx +2 -1
  55. package/src/components/settings/OrchestrationSettingsPanel.tsx +8 -5
  56. package/src/components/settings/PortableSettingsPanel.tsx +83 -55
  57. package/src/components/settings/PythonRunnerSettingsPanel.tsx +22 -19
  58. package/src/components/settings/SecuritySettingsPanel.tsx +55 -31
  59. package/src/components/settings/SettingsNavMenu.tsx +3 -2
  60. package/src/components/settings/SettingsSaveButton.tsx +2 -1
  61. package/src/components/settings/SkillsSettingsPanel.tsx +36 -31
  62. package/src/components/settings/TelemetrySettingsPanel.tsx +15 -12
  63. package/src/components/settings/UsagePanel.tsx +19 -20
  64. package/src/components/settings/WebSearchSettingsPanel.tsx +23 -14
  65. package/src/components/settings/llm-vendors.ts +12 -7
  66. package/src/components/settings/model-capabilities.ts +16 -15
  67. package/src/components/settings/preset-choice-model.ts +6 -3
  68. package/src/fixtures/browser-dev-data.json +24 -24
  69. package/src/hooks/useProjects.ts +1 -1
  70. package/src/i18n/agent-label.ts +15 -0
  71. package/src/i18n/index.tsx +68 -0
  72. package/src/i18n/runtime.ts +117 -0
  73. package/src/i18n/translate.ts +65 -0
  74. package/src/layouts/AgentLayout.tsx +7 -6
  75. package/src/lib/app-release.ts +15 -10
  76. package/src/lib/attachments.ts +16 -7
  77. package/src/lib/browser-dev-electron-mock.ts +34 -34
  78. package/src/lib/chat-title.ts +3 -2
  79. package/src/lib/chat-transport.ts +6 -2
  80. package/src/lib/date-groups.ts +23 -15
  81. package/src/lib/electron-bridge.ts +4 -5
  82. package/src/lib/http-bridge.ts +4 -1
  83. package/src/lib/portable.ts +8 -7
  84. package/src/lib/show-thinking-content.ts +15 -3
  85. package/src/main.tsx +25 -2
  86. package/src/pages/AgentPage.tsx +17 -12
  87. package/src/pages/ChatPanelPreviewPage.tsx +46 -44
  88. package/src/pages/SettingsPage.tsx +48 -42
  89. package/src/vite-env.d.ts +3 -0
  90. package/vite.base.js +6 -2
@@ -1,6 +1,7 @@
1
1
  import { useCallback, useEffect, useState } from 'react';
2
2
  import { LuChartBar } from 'react-icons/lu';
3
3
  import { BRAND_NAME } from '@/brand';
4
+ import { t } from '@/i18n';
4
5
  import { getElectronBridge, isElectron } from '@/lib/electron-bridge';
5
6
 
6
7
  type InsightsWire = {
@@ -71,13 +72,13 @@ export function InsightsConsentBanner() {
71
72
  className="flex-shrink-0 border-t border-agent-border bg-agent-muted px-2.5 py-2"
72
73
  data-testid="insights-consent-banner"
73
74
  role="region"
74
- aria-label="帮助改进产品同意"
75
+ aria-label={t('Consent to help improve the product')}
75
76
  >
76
77
  <div className="flex items-center justify-between gap-3">
77
78
  <div className="min-w-0">
78
- <p className="text-xs font-medium text-agent-foreground">帮助改进{BRAND_NAME}</p>
79
+ <p className="text-xs font-medium text-agent-foreground">{t('Help improve {brand}', { brand: BRAND_NAME })}</p>
79
80
  <p className="mt-1 text-xs leading-relaxed text-agent-muted-foreground">
80
- 同意上传数据到服务器,帮助改进产品。之后可在设置里更改。
81
+ {t('Agree to upload data to the server to help improve the product. You can change this later in Settings.')}
81
82
  </p>
82
83
  </div>
83
84
  <div className="flex shrink-0 gap-2">
@@ -87,7 +88,7 @@ export function InsightsConsentBanner() {
87
88
  onClick={() => void save(true)}
88
89
  className="h-8 whitespace-nowrap rounded-full bg-agent-foreground px-3.5 text-xs text-agent-canvas disabled:opacity-50"
89
90
  >
90
- 保存
91
+ {t('Save')}
91
92
  </button>
92
93
  <button
93
94
  type="button"
@@ -95,7 +96,7 @@ export function InsightsConsentBanner() {
95
96
  onClick={() => void save(false)}
96
97
  className="h-8 whitespace-nowrap rounded-full border border-agent-border bg-agent-canvas px-3.5 text-xs text-agent-foreground disabled:opacity-50"
97
98
  >
98
- 取消
99
+ {t('Cancel')}
99
100
  </button>
100
101
  </div>
101
102
  </div>
@@ -152,7 +153,7 @@ export function InsightsSettingsPanel() {
152
153
  },
153
154
  });
154
155
  setData({ ...empty, ...res, profile: { ...empty.profile, ...res.profile } });
155
- setStatus('已保存。未勾选的种类只留在本机。');
156
+ setStatus(t('Saved. Unchecked categories stay on this device only.'));
156
157
  } catch (err) {
157
158
  setError(err instanceof Error ? err.message : String(err));
158
159
  } finally {
@@ -170,11 +171,11 @@ export function InsightsSettingsPanel() {
170
171
  });
171
172
  const text = `${JSON.stringify(bundle, null, 2)}\n`;
172
173
  const saved = await getElectronBridge()!.local?.saveTextFile?.({
173
- title: '导出本地洞察记录',
174
+ title: t('Export local insight records'),
174
175
  defaultPath: `deeppath-insights-${new Date().toISOString().slice(0, 10)}.json`,
175
176
  content: text,
176
177
  });
177
- if (saved?.canceled === false) setStatus(`已保存到 ${saved.filePath}`);
178
+ if (saved?.canceled === false) setStatus(t('Saved to {path}', { path: saved.filePath ?? '' }));
178
179
  } catch (err) {
179
180
  setError(err instanceof Error ? err.message : String(err));
180
181
  }
@@ -188,7 +189,11 @@ export function InsightsSettingsPanel() {
188
189
  method: 'POST',
189
190
  path: '/api/v2/insights/upload-local',
190
191
  });
191
- setStatus(res.ok ? `已上传到${BRAND_NAME}服务器` : '上传失败,记录仍在本机,可改导出文件发送');
192
+ setStatus(
193
+ res.ok
194
+ ? t('Uploaded to the {brand} server', { brand: BRAND_NAME })
195
+ : t('Upload failed. The records are still on this device. You can export a file and send it instead.'),
196
+ );
192
197
  await load();
193
198
  } catch (err) {
194
199
  setError(err instanceof Error ? err.message : String(err));
@@ -202,15 +207,17 @@ export function InsightsSettingsPanel() {
202
207
  <div className="rounded-agent-md border border-agent-border/60 bg-agent-muted/30 p-2.5 space-y-2">
203
208
  <h4 className="flex items-center gap-1.5 text-xs font-semibold text-agent-foreground">
204
209
  <LuChartBar className="h-3.5 w-3.5 text-agent-muted-foreground" />
205
- 帮助改进产品(行为 / 对话 / 用户信息 分开确认)
210
+ {t('Help improve the product (behavior / conversations / user info are confirmed separately)')}
206
211
  </h4>
207
212
  <p className="text-[11px] text-agent-muted-foreground">
208
- 即使用户不同意上传,记录也会留在本机。可导出 JSON 发给产品团队,或点一次「现在上传」。
213
+ {t(
214
+ 'Even if the user does not agree to upload, records stay on this device. You can export JSON and send it to the product team, or click "Upload now" once.',
215
+ )}
209
216
  </p>
210
217
  {!isElectron() ? (
211
- <p className="text-[11px] text-agent-muted-foreground">需要在桌面客户端中打开</p>
218
+ <p className="text-[11px] text-agent-muted-foreground">{t('Open this in the desktop app')}</p>
212
219
  ) : loading ? (
213
- <p className="text-[11px] text-agent-muted-foreground">读取中…</p>
220
+ <p className="text-[11px] text-agent-muted-foreground">{t('Loading…')}</p>
214
221
  ) : (
215
222
  <>
216
223
  <label className="flex items-start gap-2 text-xs">
@@ -220,8 +227,8 @@ export function InsightsSettingsPanel() {
220
227
  onChange={(e) => setData((d) => ({ ...d, shareBehavior: e.target.checked }))}
221
228
  />
222
229
  <span>
223
- 自动上传<strong>行为</strong>
224
- <span className="block text-[10px] text-agent-muted-foreground">打开、发送、设置卡住等,不含问答正文</span>
230
+ {t('Auto-upload')} <strong>{t('behavior')}</strong>
231
+ <span className="block text-[10px] text-agent-muted-foreground">{t('Opens, sends, stuck settings, and so on. No question or answer text.')}</span>
225
232
  </span>
226
233
  </label>
227
234
  <label className="flex items-start gap-2 text-xs">
@@ -231,8 +238,8 @@ export function InsightsSettingsPanel() {
231
238
  onChange={(e) => setData((d) => ({ ...d, shareConversation: e.target.checked }))}
232
239
  />
233
240
  <span>
234
- 自动上传<strong>对话</strong>
235
- <span className="block text-[10px] text-agent-muted-foreground">提问与回答(已脱敏密钥和用户目录)</span>
241
+ {t('Auto-upload')} <strong>{t('conversations')}</strong>
242
+ <span className="block text-[10px] text-agent-muted-foreground">{t('Questions and answers (keys and user directories are redacted)')}</span>
236
243
  </span>
237
244
  </label>
238
245
  <label className="flex items-start gap-2 text-xs">
@@ -242,21 +249,21 @@ export function InsightsSettingsPanel() {
242
249
  onChange={(e) => setData((d) => ({ ...d, shareProfile: e.target.checked }))}
243
250
  />
244
251
  <span>
245
- 自动上传<strong>用户信息</strong>
246
- <span className="block text-[10px] text-agent-muted-foreground">与上面两项分开,不勾选则称呼/邮箱只留本机</span>
252
+ {t('Auto-upload')} <strong>{t('user info')}</strong>
253
+ <span className="block text-[10px] text-agent-muted-foreground">{t('Separate from the two above. If unchecked, your name and email stay on this device only.')}</span>
247
254
  </span>
248
255
  </label>
249
256
  <div className="grid grid-cols-2 gap-2">
250
257
  {(
251
258
  [
252
- ['displayName', '称呼'],
253
- ['email', '邮箱'],
254
- ['company', '公司/团队'],
255
- ['note', '想告诉我们的'],
259
+ ['displayName', 'Name'],
260
+ ['email', 'Email'],
261
+ ['company', 'Company/team'],
262
+ ['note', 'Anything to tell us'],
256
263
  ] as const
257
264
  ).map(([key, label]) => (
258
265
  <label key={key} className="space-y-1 text-[11px] text-agent-muted-foreground">
259
- {label}
266
+ {t(label)}
260
267
  <input
261
268
  value={data.profile[key]}
262
269
  onChange={(e) =>
@@ -268,7 +275,15 @@ export function InsightsSettingsPanel() {
268
275
  ))}
269
276
  </div>
270
277
  <p className="text-[10px] text-agent-muted-foreground">
271
- 本机已记 行为 {stats.events} / 对话 {stats.turns} / 资料 {stats.profile},待上传 {stats.pending}
278
+ {t(
279
+ 'Recorded on this device: behavior {events} / conversations {turns} / profile {profile}, pending upload {pending}',
280
+ {
281
+ events: stats.events,
282
+ turns: stats.turns,
283
+ profile: stats.profile,
284
+ pending: stats.pending,
285
+ },
286
+ )}
272
287
  {data.installId ? ` · ${data.installId.slice(0, 8)}` : ''}
273
288
  </p>
274
289
  <div className="flex flex-wrap gap-2">
@@ -278,21 +293,21 @@ export function InsightsSettingsPanel() {
278
293
  onClick={() => void save()}
279
294
  className="h-8 rounded-full bg-agent-foreground px-4 text-xs text-agent-canvas"
280
295
  >
281
- 保存
296
+ {t('Save')}
282
297
  </button>
283
298
  <button
284
299
  type="button"
285
300
  onClick={() => void exportFile()}
286
301
  className="h-8 rounded-full border border-agent-border px-4 text-xs"
287
302
  >
288
- 导出文件发给开发者
303
+ {t('Export a file for the developers')}
289
304
  </button>
290
305
  <button
291
306
  type="button"
292
307
  onClick={() => void uploadNow()}
293
308
  className="h-8 rounded-full border border-agent-border px-4 text-xs"
294
309
  >
295
- 现在上传本地记录
310
+ {t('Upload local records now')}
296
311
  </button>
297
312
  </div>
298
313
  </>