@double-coding/dsh-connectors 0.1.0-test.0 → 0.2.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.
Files changed (57) hide show
  1. package/CONTRIBUTING.en.md +181 -0
  2. package/CONTRIBUTING.md +9 -1
  3. package/README.en.md +32 -27
  4. package/README.md +29 -24
  5. package/assets/readme/badges/dsh.svg +1 -0
  6. package/assets/readme/badges/github.svg +1 -0
  7. package/assets/readme/badges/mit.svg +1 -0
  8. package/assets/readme/badges/npm.svg +1 -0
  9. package/assets/readme/panel-en.webp +0 -0
  10. package/cordis.patch.yml +1 -1
  11. package/dist/client.js +1324 -578
  12. package/dist/client.js.map +4 -4
  13. package/dist/host/connections.d.ts +3 -0
  14. package/dist/host/connections.js +49 -0
  15. package/dist/host/connections.js.map +1 -1
  16. package/dist/host/mcpServers.d.ts +2 -0
  17. package/dist/host/mcpServers.js +45 -0
  18. package/dist/host/mcpServers.js.map +1 -1
  19. package/dist/host/providers.d.ts +7 -0
  20. package/dist/host/providers.js +8 -0
  21. package/dist/host/providers.js.map +1 -1
  22. package/dist/host/routes.js +33 -0
  23. package/dist/host/routes.js.map +1 -1
  24. package/dist/host/store.d.ts +10 -0
  25. package/dist/host/store.js +5 -0
  26. package/dist/host/store.js.map +1 -1
  27. package/dist/shared/types.d.ts +16 -0
  28. package/dist/shared/types.js.map +1 -1
  29. package/package.json +2 -1
  30. package/providers/amap/provider.json +19 -1
  31. package/providers/baidu-netdisk/provider.json +14 -0
  32. package/providers/circleci/provider.json +17 -1
  33. package/providers/cloudflare-docs/provider.json +17 -1
  34. package/providers/context7/provider.json +15 -1
  35. package/providers/deepwiki/provider.json +16 -1
  36. package/providers/firecrawl/provider.json +12 -0
  37. package/providers/gitee/provider.json +18 -1
  38. package/providers/github/provider.json +17 -1
  39. package/providers/gitlab/provider.json +19 -2
  40. package/providers/gitlab-self-hosted/provider.json +20 -2
  41. package/providers/grafana/provider.json +17 -1
  42. package/providers/linear/provider.json +12 -0
  43. package/providers/microsoft-learn/provider.json +17 -1
  44. package/providers/neon/provider.json +12 -0
  45. package/providers/notion/provider.json +17 -1
  46. package/providers/posthog/provider.json +12 -0
  47. package/providers/postman/provider.json +17 -1
  48. package/providers/qcc/provider.json +62 -12
  49. package/providers/sentry/provider.json +24 -2
  50. package/providers/sourcegraph/provider.json +17 -1
  51. package/providers/supabase/provider.json +12 -0
  52. package/providers/tavily/provider.json +12 -0
  53. package/providers/tencent-docs/provider.json +23 -2
  54. package/providers/tencent-yuanbao-search/provider.json +19 -1
  55. package/providers/tianyancha/provider.json +21 -2
  56. package/providers/yunxiao/provider.json +22 -2
  57. package/schema/provider.schema.json +34 -0
package/dist/client.js CHANGED
@@ -1,4 +1,4 @@
1
- window.__ModuleLoader__.load({ id: "dsh-connectors", factory: (require) => {
1
+ window.__ModuleLoader__.load({ id: "@double-coding/dsh-connectors", factory: (require) => {
2
2
  var module = { exports: {} }; var exports = module.exports;
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -26,9 +26,527 @@ __export(index_exports, {
26
26
  inject: () => inject
27
27
  });
28
28
  module.exports = __toCommonJS(index_exports);
29
- var import_react = require("react");
29
+ var import_react2 = require("react");
30
30
  var import_react_dom = require("react-dom");
31
31
 
32
+ // src/client/cli-en.ts
33
+ var CLI_EN = {
34
+ dingtalk: {
35
+ name: "DingTalk",
36
+ vendor: "DingTalk",
37
+ description: "Manage DingTalk through the official dws CLI: AI sheets, attendance, calendar, group chats and bots, contacts, DING, docs, drive, AI minutes, mail, OA approvals, reports, and tasks.",
38
+ examples: [
39
+ "Send a bot notice to the DingTalk group Product Weekly: the weekly meeting is at 15:00 today in the 3rd-floor meeting room; bring last week's progress materials",
40
+ "Check my DingTalk calendar for next week, list meetings related to Customer Sync, and find a slot when all three of us are free",
41
+ "Add a row to the DingTalk AI sheet Task Tracking: title=Q2 launch review, owner=Zhang San, due=2026-05-20, status=In progress",
42
+ "Use dws to search my DingTalk mail for messages from Finance in the last week with reimbursement in the subject"
43
+ ],
44
+ installLabels: ["Install dws CLI"]
45
+ },
46
+ feishu: {
47
+ name: "Feishu",
48
+ vendor: "Feishu",
49
+ description: "Manage Feishu through the official lark-cli: messages, docs, Bitable, Sheets, Slides, calendar, mail, tasks, and meetings.",
50
+ examples: [
51
+ "Send a message in a Feishu group summarizing this week's project progress and @ the owners",
52
+ "Check my Feishu calendar for next week, list meetings related to Customer Sync, and find free slots",
53
+ "Add a record to the Feishu Bitable Task Tracking: title=Q2 launch review, owner=Zhang San, due=2026-05-20",
54
+ "Search my Feishu mail for messages from Finance in the last week with reimbursement in the subject"
55
+ ],
56
+ installLabels: ["Install lark-cli", "Install Feishu Skills"]
57
+ },
58
+ tmeet: {
59
+ name: "Tencent Meeting",
60
+ vendor: "Tencent",
61
+ description: "Manage Tencent Meeting through the official tmeet CLI: schedule and query meetings, invite attendees, recordings and transcripts, smart minutes, meeting reports, and in-meeting controls.",
62
+ examples: [
63
+ "Schedule a Tencent Meeting for next Wednesday at 15:00, topic Q3 proposal review, and invite Zhang San and Li Si",
64
+ "List my Tencent Meetings for next week in time order",
65
+ "Turn yesterday's smart meeting minutes into action items",
66
+ "Find the recording link and attendance report for last week's meeting"
67
+ ],
68
+ installLabels: ["Install tmeet CLI", "Install Tencent Meeting Skills"]
69
+ },
70
+ wecom: {
71
+ name: "WeCom",
72
+ vendor: "WeCom",
73
+ description: "Manage WeCom through the official wecom-cli: messages, mail, docs, sheets, smart sheets, smart docs, tasks, calendar, meetings, drive, and contacts.",
74
+ examples: [
75
+ "Send a message to Zhang San on WeCom: today's release is moved to 18:00",
76
+ "Search this week's mail and list messages that need a reply today",
77
+ "Add a row to the smart sheet Task Tracking: title=Q3 retrospective, owner=Zhang San, due=2026-11-05",
78
+ "Check tomorrow's calendar and turn customer-related meetings into a one-page to-do list"
79
+ ],
80
+ installLabels: ["Install wecom-cli", "Install WeCom Skills"]
81
+ },
82
+ hf: {
83
+ description: "Manage Hugging Face through the official hf CLI: search and download models and datasets, upload files, manage repos, Spaces, Buckets, Jobs, and Webhooks.",
84
+ examples: [
85
+ "Search Hugging Face for Qwen quantized models, sorted by downloads",
86
+ "Download meta-llama/Llama-3.2-1B-Instruct to the local cache",
87
+ "Upload the local ./model directory to a new model repo under my account",
88
+ "Check whether yesterday's Jobs finished; summarize the logs for failures"
89
+ ],
90
+ installLabels: ["Install hf CLI", "Install Hugging Face Skills"]
91
+ },
92
+ "agent-mail": {
93
+ name: "Agent Mail",
94
+ vendor: "QQ Mail",
95
+ description: "Operate Agent Mail (QQ Mail's dedicated mailbox for agents) through the official agently-cli: send, reply, forward, search, attachments, and trash.",
96
+ examples: [
97
+ "Send an email to alice@example.com with subject Weekly notes and the key points I provide",
98
+ "Show my latest 10 emails and pick the ones that need a reply today",
99
+ "Search the last month for emails with invoice in the subject and download the attachments",
100
+ "Reply to msg_001 and say the meeting moved to Thursday afternoon"
101
+ ],
102
+ installLabels: ["Install agently-cli", "Install Agent Mail Skills"]
103
+ }
104
+ };
105
+ var CLI_ITEM_EN = {
106
+ "tmeet:app": { description: "App activation and authorization" },
107
+ "tmeet:auth": { description: "Sign-in and authorization status" },
108
+ "tmeet:contact": { description: "Enterprise contacts" },
109
+ "tmeet:control": { description: "In-meeting controls (members, mute, share)" },
110
+ "tmeet:event": { description: "Real-time event subscriptions" },
111
+ "tmeet:meeting": { description: "Schedule, query, and invite attendees" },
112
+ "tmeet:minutes": { description: "Smart meeting minutes" },
113
+ "tmeet:record": { description: "Recordings and transcripts" },
114
+ "tmeet:report": { description: "Meeting reports" },
115
+ "tmeet:tshoot": { description: "Troubleshooting" },
116
+ "agent-mail:me": { name: "account", description: "Current account and aliases" },
117
+ "agent-mail:attachment": { description: "Upload and download attachments" },
118
+ "agent-mail:message": { description: "List, read, search, watch, send, reply, forward, trash, and delete mail" },
119
+ "dingtalk:agoal": { description: "Agoal reports, submissions, templates, and goals" },
120
+ "dingtalk:aicard": { description: "Inspect contracts, validate structure, and preview A2UI cards" },
121
+ "dingtalk:aisearch": { description: "Enterprise search across people, knowledge, and activity" },
122
+ "dingtalk:aitable": { description: "AI tables: base, app mode, fields, records, views, forms, dashboards, permissions, and workflows" },
123
+ "dingtalk:attendance": { description: "Attendance records, schedules, shifts, groups, approvals, reports, rules, and leave" },
124
+ "dingtalk:audit": { description: "View, export, and validate local audit logs" },
125
+ "dingtalk:calendar": { description: "Calendars, events, attendees, attachments, rooms, and free/busy lookup" },
126
+ "dingtalk:chat": { description: "Conversations, group chats, members, categories, bots, and messages" },
127
+ "dingtalk:contact": { description: "Contacts, employee directory, departments, and enterprise accounts" },
128
+ "dingtalk:contract": { description: "Smart contracts: ledgers, imports, drafting, archiving, projects, parties, and payments" },
129
+ "dingtalk:dev": { description: "Open-platform apps, permissions, bots, releases, local connectors, and MCP development" },
130
+ "dingtalk:devapp": { description: "Enterprise apps, members, permissions, bots, events, and releases" },
131
+ "dingtalk:devdoc": { description: "Search DingTalk open-platform docs and troubleshooting guides" },
132
+ "dingtalk:ding": { description: "Query DING messages or send and recall in-app, SMS, and phone DING" },
133
+ "dingtalk:dingtalk-tag": { description: "Create and manage digital employees, DWS profiles, and execution status" },
134
+ "dingtalk:doc": { description: "Docs: body content, blocks, comments, import/export, templates, and versions" },
135
+ "dingtalk:drive": { description: "Drive and document-space files, folders, uploads, recycle bin, and publishing" },
136
+ "dingtalk:event": { description: "Real-time personal IM, approval, VoIP, to-do, and card callback events" },
137
+ "dingtalk:hrbrain": { description: "Org talent pool, employee profiles, and talent search" },
138
+ "dingtalk:html": { description: "Create, read, overwrite, and patch native HTML files in Drive and document spaces" },
139
+ "dingtalk:live": { description: "List live streams started by the current user" },
140
+ "dingtalk:mail": { description: "Mailboxes, messages, drafts, attachments, folders, contacts, and templates" },
141
+ "dingtalk:markdown": { description: "Create, read, diff, overwrite, patch, and comment on native Markdown files" },
142
+ "dingtalk:mcp": { description: "Discover and call available MCP services and published tools" },
143
+ "dingtalk:mind": { description: "Create mind maps and manage topic nodes" },
144
+ "dingtalk:minutes": { description: "AI minutes: transcripts, summaries, action items, permissions, recordings, and uploads" },
145
+ "dingtalk:oa": { description: "OA approvals: instances, tasks, records, CC, comments, attachments, templates, and flows" },
146
+ "dingtalk:pat": { description: "Agent PAT authorization and local browser policy" },
147
+ "dingtalk:report": { description: "Log templates, submissions, content, and statistics" },
148
+ "dingtalk:sheet": { description: "Online sheets: import, create, read, edit, export, audit, worksheets, filters, charts, and formats" },
149
+ "dingtalk:todo": { description: "Tasks, tags, subtasks, assignees, participants, comments, attachments, and reminders" },
150
+ "dingtalk:whiteboard": { description: "Create and update standalone or embedded whiteboards, preview diffs, and manage templates" },
151
+ "dingtalk:wiki": { description: "Knowledge-base spaces, nodes, and member permissions" },
152
+ "feishu:lark-approval": { description: "Approval tasks, instances, definitions, and native submissions" },
153
+ "feishu:lark-apps": { description: "Miaoda app development, hosting, logs, analytics, roles, and automation" },
154
+ "feishu:lark-attendance": { description: "View your attendance records" },
155
+ "feishu:lark-base": { description: "Bitable: tables, fields, records, views, forms, dashboards, roles, and templates" },
156
+ "feishu:lark-calendar": { description: "Calendar events, attendees, free/busy, and meeting rooms" },
157
+ "feishu:lark-contact": { description: "Resolve names and emails, look up users, and search visible bots" },
158
+ "feishu:lark-doc": { description: "Docs and wiki content: read, create, edit, images, and mind notes" },
159
+ "feishu:lark-drive": { description: "Drive files and folders: upload, download, move, permissions, comments, and versions" },
160
+ "feishu:lark-event": { description: "Stream Lark events as NDJSON for bots and real-time handlers" },
161
+ "feishu:lark-im": { description: "Messages, group chats, members, files, reactions, and interactive cards" },
162
+ "feishu:lark-mail": { description: "Mail: drafts, send, reply, forward, search, folders, labels, and rules" },
163
+ "feishu:lark-markdown": { description: "View, create, upload, edit, and compare native Markdown files" },
164
+ "feishu:lark-meeting": { description: "Meeting records, minutes, transcripts, live meeting Q&A, and chat" },
165
+ "feishu:lark-minutes": { description: "Meeting minutes (delegated to lark-meeting)" },
166
+ "feishu:lark-note": { description: "Meeting notes (delegated to lark-meeting)" },
167
+ "feishu:lark-okr": { description: "OKR cycles, objectives, key results, alignment, and progress" },
168
+ "feishu:lark-openapi-explorer": { description: "Discover native Lark OpenAPI endpoints beyond the CLI" },
169
+ "feishu:lark-shared": { description: "CLI auth, identity, permissions, and setup" },
170
+ "feishu:lark-sheets": { description: "Spreadsheets: structure, cells, formulas, charts, filters, and import/export" },
171
+ "feishu:lark-skill-maker": { description: "Build reusable lark-cli Skills" },
172
+ "feishu:lark-slides": { description: "Create and edit presentations and slide pages" },
173
+ "feishu:lark-task": { description: "Tasks, lists, subtasks, assignees, attachments, and task agents" },
174
+ "feishu:lark-vc": { description: "Video conferencing (delegated to lark-meeting)" },
175
+ "feishu:lark-vc-agent": { description: "VC agent (delegated to lark-meeting)" },
176
+ "feishu:lark-whiteboard": { description: "Inspect and edit whiteboards" },
177
+ "feishu:lark-wiki": { description: "Knowledge spaces, members, and document nodes" },
178
+ "feishu:lark-workflow-meeting-summary": { description: "Summarize meeting minutes into a structured report" },
179
+ "feishu:lark-workflow-standup-report": { description: "Daily agenda and unfinished-task summary" },
180
+ "wecom:calendar": { description: "Calendar: create, query, cancel, search, and free/busy" },
181
+ "wecom:chat": { description: "Chat messages and conversation lists" },
182
+ "wecom:contact": { description: "Contact lookup" },
183
+ "wecom:disk": { description: "WeCom Drive files" },
184
+ "wecom:doc": { description: "Docs: create, rename, import, search, permissions, and Word content" },
185
+ "wecom:mail": { description: "Mail: send, reply, forward, list, read, and search" },
186
+ "wecom:media": { description: "Upload and download media files" },
187
+ "wecom:message": { description: "Send messages and retrieve media content" },
188
+ "wecom:meeting": { description: "Meetings: create, query, search, cancel, and update" },
189
+ "wecom:sheet": { description: "Sheets: metadata, data, and worksheet management" },
190
+ "wecom:smartpage": { description: "Smart pages: read, manage pages, edit blocks, append or replace content" },
191
+ "wecom:smartsheet": { description: "Smart sheets: metadata, sub-sheets, columns, records, views, and dashboards" },
192
+ "wecom:todo": { description: "To-dos: create, query, and complete" },
193
+ "wecom:slide": { description: "Tencent Docs slides: edit presentations" }
194
+ };
195
+
196
+ // src/client/i18n.ts
197
+ var import_react = require("react");
198
+
199
+ // src/client/en.ts
200
+ var EN = {
201
+ "\u8FDE\u63A5\u5668": "Connectors",
202
+ "\u8FDE\u63A5\u5668\u5F39\u7A97": "Connector dialog",
203
+ "\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668": "Custom connector",
204
+ "\u641C\u7D22\u8FDE\u63A5\u5668": "Search connectors",
205
+ "\u6E05\u7A7A\u641C\u7D22": "Clear search",
206
+ "\u6B63\u5728\u52A0\u8F7D\u8FDE\u63A5\u5668\u2026": "Loading connectors\u2026",
207
+ "\u6CA1\u6709\u5339\u914D\u7684\u8FDE\u63A5\u5668": "No matching connectors",
208
+ "\u5168\u90E8": "All",
209
+ "\u5F00\u53D1\u5DE5\u5177": "Developer tools",
210
+ "\u9879\u76EE\u7BA1\u7406": "Project management",
211
+ "\u6570\u636E\u5E93": "Databases",
212
+ "\u77E5\u8BC6\u68C0\u7D22": "Search & knowledge",
213
+ "\u529E\u516C\u534F\u4F5C": "Productivity",
214
+ "\u5B89\u5168\u8FD0\u7EF4": "Security & ops",
215
+ "\u6570\u636E\u5206\u6790": "Analytics",
216
+ "\u5176\u4ED6": "Other",
217
+ "\u81EA\u5B9A\u4E49": "Custom",
218
+ "CLI \u5904\u7406\u5931\u8D25\uFF0C\u672A\u8FD4\u56DE\u9519\u8BEF\u6458\u8981\u3002": "CLI operation failed without an error summary.",
219
+ "CLI \u5DF2\u5B89\u88C5": "CLI installed",
220
+ "Skills \u672A\u5C31\u7EEA": "Skills not ready",
221
+ "x-dsh \u8BF4\u660E": "About x-dsh",
222
+ "\u4EC5\u5BFC\u5165": "Import only",
223
+ "\u4ECD\u7136\u4EC5\u5BFC\u5165": "Continue importing only",
224
+ "\u4ECD\u7136\u5BFC\u5165\u5E76\u8FDE\u63A5": "Continue import and connect",
225
+ "\u4F8B\u5982\uFF1A\u901A\u8FC7 DeepWiki \u67E5\u8BE2\u4ED3\u5E93\u7ED3\u6784\u4E0E\u6587\u6863": "Example: use DeepWiki to inspect a repository structure and docs",
226
+ "\u4FDD\u5B58": "Save",
227
+ "\u4FDD\u5B58\u4E2D\u2026": "Saving\u2026",
228
+ "\u4FDD\u5B58\u5730\u5740\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5": "Failed to save the address: the host returned no connection.",
229
+ "\u4FDD\u5B58\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5": "Save failed: the host returned no connection.",
230
+ "\u4FDD\u5B58\u5E76\u6388\u6743": "Save and authorize",
231
+ "\u4FDD\u5B58\u5E76\u7EE7\u7EED": "Save and continue",
232
+ "\u4FDD\u5B58\u5E76\u8FDE\u63A5": "Save and connect",
233
+ "\u4FDD\u5B58\u5E76\u91CD\u65B0\u6388\u6743": "Save and reauthorize",
234
+ "\u4FDD\u5B58\u5E76\u91CD\u65B0\u8FDE\u63A5": "Save and reconnect",
235
+ "\u4FDD\u5B58\u5E94\u7528\u51ED\u636E\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5": "Failed to save app credentials: the host returned no connection.",
236
+ "\u505C\u7528": "Disable",
237
+ "\u5173\u95ED": "Close",
238
+ "\u5176\u4ED6 Agent \u5C06\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528\u8BE5 CLI\uFF0C\u5F53\u524D\u767B\u5F55\u6001\u4E5F\u4F1A\u6E05\u9664\uFF1B\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u624D\u80FD\u6062\u590D\u3002": "Other agents will no longer be able to use this CLI. The current login will be cleared; reinstall to restore it.",
239
+ "\u5176\u4ED6 Agent \u5C06\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528\u8FD9\u4E9B Skills\uFF0C\u5F53\u524D\u767B\u5F55\u6001\u4E5F\u4F1A\u6E05\u9664\uFF1B\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u624D\u80FD\u6062\u590D\u3002": "Other agents will no longer be able to use these Skills. The current login will be cleared; reinstall to restore it.",
240
+ "\u51C6\u5907\u66F4\u65B0\u2026": "Preparing update\u2026",
241
+ "\u5220\u9664": "Delete",
242
+ "\u5220\u9664\u4E2D\u2026": "Deleting\u2026",
243
+ "\u5378\u8F7D CLI": "Uninstall CLI",
244
+ "\u5378\u8F7D\u4E2D\u2026": "Uninstalling\u2026",
245
+ "\u5378\u8F7D\u8FDB\u5EA6": "Uninstall progress",
246
+ "\u53BB\u8BD5\u8BD5": "Try it",
247
+ "\u53D6\u6D88": "Cancel",
248
+ "\u53D6\u6D88\u5378\u8F7D": "Cancel uninstall",
249
+ "\u53D6\u6D88\u5B89\u88C5": "Cancel install",
250
+ "\u53D6\u6D88\u6388\u6743": "Cancel authorization",
251
+ "\u53D6\u6D88\u66F4\u65B0": "Cancel update",
252
+ "\u53D6\u6D88\u767B\u5F55": "Cancel login",
253
+ "\u540E\u53F0\u7EE7\u7EED": "Continue in background",
254
+ "\u542F\u52A8\u4E2D\u2026": "Starting\u2026",
255
+ "\u542F\u7528": "Enable",
256
+ "\u542F\u7528\u4E2D\u2026": "Enabling\u2026",
257
+ "\u5730\u5740": "Address",
258
+ "\u5730\u5740\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002": "The address is stored only on this machine.",
259
+ "\u586B\u5199": "Enter",
260
+ "\u586B\u5199\u4EE4\u724C": "Enter token",
261
+ "\u586B\u5199\u5730\u5740": "Enter address",
262
+ "\u5904\u7406\u4E2D": "Working",
263
+ "\u590D\u5236": "Copy",
264
+ "\u590D\u5236\u5931\u8D25": "Copy failed",
265
+ "\u590D\u5236\u65E5\u5FD7": "Copy log",
266
+ "\u590D\u5236\u8BBE\u5907\u7801": "Copy device code",
267
+ "\u590D\u5236\u94FE\u63A5": "Copy link",
268
+ "\u5B89\u88C5": "Install",
269
+ "\u5B89\u88C5\u4E2D\u2026": "Installing\u2026",
270
+ "\u5B89\u88C5\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5": "Install failed: the host returned no connection.",
271
+ "\u5B89\u88C5\u5B8C\u6210": "Installation complete",
272
+ "\u5B89\u88C5\u8FDB\u5EA6": "Install progress",
273
+ "\u5B8C\u6210": "Done",
274
+ "\u5BFC\u5165\u4E2D\u2026": "Importing\u2026",
275
+ "\u5BFC\u5165\u5E76\u8FDE\u63A5": "Import and connect",
276
+ "\u5C55\u5F00\u63CF\u8FF0": "Expand description",
277
+ "\u5DF2\u505C\u7528": "Disabled",
278
+ "\u5DF2\u53D6\u6D88\u6388\u6743": "Authorization canceled",
279
+ "\u5DF2\u542F\u7528": "Enabled",
280
+ "\u5DF2\u590D\u5236": "Copied",
281
+ "\u5DF2\u5B89\u88C5\u672A\u767B\u5F55": "Installed, signed out",
282
+ "\u5DF2\u5B89\u88C5\uFF0C\u5F85\u6388\u6743": "Installed, awaiting authorization",
283
+ "\u5DF2\u5B89\u88C5\uFF0C\u5F85\u914D\u7F6E": "Installed, awaiting configuration",
284
+ "\u5DF2\u6253\u5F00\u6388\u6743\u9875\uFF0C\u5B8C\u6210\u6388\u6743\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\uFF1B\u5982\u5DF2\u5173\u95ED\u6388\u6743\u9875\uFF0C\u8BF7\u70B9\u300C\u53D6\u6D88\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002": "The authorization page is open; access updates automatically when you finish. If you closed it, cancel authorization and try again.",
285
+ "\u5DF2\u767B\u5F55": "Signed in",
286
+ "\u5DF2\u8FDE\u63A5": "Connected",
287
+ "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D": "Connected \xB7 registering",
288
+ "\u5E94\u7528 AppKey / Client ID": "AppKey / Client ID",
289
+ "\u5E94\u7528 SecretKey / Client Secret": "SecretKey / Client Secret",
290
+ "\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u4ECE\u8FDE\u63A5\u5668\u6253\u5F00\u4F1A\u8BDD": "This DSH version cannot open a session from a connector.",
291
+ "\u5F53\u524D\u4EE4\u724C\u4E0D\u4F1A\u663E\u793A\uFF1B\u4FDD\u5B58\u65B0\u4EE4\u724C\u540E\u7ACB\u5373\u66FF\u6362\u3002": "The current token is hidden; saving a new token replaces it immediately.",
292
+ "\u5F85\u914D\u7F6E": "Needs configuration",
293
+ "\u6388\u6743": "Authorize",
294
+ "\u6388\u6743\u4E2D": "Authorizing",
295
+ "\u6388\u6743\u4E2D\u2026": "Authorizing\u2026",
296
+ "\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5": "Authorization failed. Try again.",
297
+ "\u6388\u6743\u5B8C\u6210\uFF0C\u4F46\u6CA1\u6709\u627E\u5230\u8FDE\u63A5\u8BB0\u5F55\uFF0C\u8BF7\u5237\u65B0\u9762\u677F\u91CD\u8BD5": "Authorization completed, but no connection record was found. Refresh the panel and try again.",
298
+ "\u6388\u6743\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u8BD5": "Authorization expired. Try again.",
299
+ "\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5": "Authorization timed out. Try again.",
300
+ "\u641C\u7D22\u5DE5\u5177": "Search tools",
301
+ "\u6536\u8D77": "Collapse",
302
+ "\u6536\u8D77\u63CF\u8FF0": "Collapse description",
303
+ "\u65AD\u5F00": "Disconnect",
304
+ "\u65AD\u5F00\u4E2D\u2026": "Disconnecting\u2026",
305
+ "\u663E\u793A SecretKey": "Show SecretKey",
306
+ "\u663E\u793A\u4EE4\u724C": "Show token",
307
+ "\u66F4\u6362": "Change",
308
+ "\u66F4\u6362\u540E\u4F1A\u65AD\u5F00\u5F53\u524D\u8FDE\u63A5\u3001\u6E05\u9664\u5DF2\u6709\u51ED\u636E\uFF0C\u9700\u8981\u91CD\u65B0\u914D\u7F6E\u6216\u6388\u6743\u3002": "Changing this disconnects the current connection and clears existing credentials. Reconfigure or authorize afterward.",
309
+ "\u66F4\u6362\u5730\u5740": "Change address",
310
+ "\u66F4\u65B0\u4E2D\u2026": "Updating\u2026",
311
+ "\u66F4\u65B0\u4EE4\u724C": "Update token",
312
+ "\u66F4\u65B0\u8FDB\u5EA6": "Update progress",
313
+ "\u6700\u65B0\u7248\u672C": "latest",
314
+ "\u670D\u52A1\u5730\u5740": "Service URL",
315
+ "\u672A\u5B89\u88C5": "Not installed",
316
+ "\u672A\u6388\u6743": "Not authorized",
317
+ "\u672A\u767B\u5F55": "Signed out",
318
+ "\u672A\u77E5": "Unknown",
319
+ "\u672A\u8FDE\u63A5": "Not connected",
320
+ "\u67E5\u770B\u8BE6\u60C5": "View details",
321
+ "\u67E5\u770B\u9519\u8BEF\u65E5\u5FD7": "View error log",
322
+ "\u6B63\u5728\u51C6\u5907\u5E94\u7528\u914D\u7F6E\uFF0C\u6388\u6743\u9875\u9762\u4F1A\u81EA\u52A8\u6253\u5F00\uFF1B\u82E5\u672A\u6253\u5F00\uFF0C\u8BF7\u70B9\u51FB\u300C\u6253\u5F00\u6388\u6743\u9875\u9762\u300D\u3002": 'Preparing the app configuration. The authorization page opens automatically; if it does not, click "Open authorization page".',
323
+ "\u6B63\u5728\u5378\u8F7D CLI \u4E0E\u5B98\u65B9 Skills\u2026": "Uninstalling the CLI and official Skills\u2026",
324
+ "\u6B63\u5728\u66F4\u65B0 CLI\u2026": "Updating the CLI\u2026",
325
+ "\u6B63\u5728\u6CE8\u518C\u5DE5\u5177\u2026": "Registering tools\u2026",
326
+ "\u6B63\u5728\u8FDE\u63A5\u2026": "Connecting\u2026",
327
+ "\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5\u5668": "No connectors available",
328
+ "\u7528 DeepWiki \u67E5\u4E00\u4E0B facebook/react \u7684\u4ED3\u5E93\u7ED3\u6784": "Use DeepWiki to inspect the facebook/react repository structure",
329
+ "\u7559\u7A7A\u4F1A\u5F52\u5165\u300C\u5176\u4ED6\u300D\uFF1B\u53EF\u76F4\u63A5\u8F93\u5165\u65B0\u7C7B\u522B\u3002": 'Leave blank to use "Other"; you can type a new category.',
330
+ "\u7559\u7A7A\u4F7F\u7528 JSON \u4E2D\u7684\u7C7B\u522B\uFF1B\u586B\u5199\u4F1A\u8986\u76D6\u3002": "Leave blank to use the category from JSON; entering one overrides it.",
331
+ "\u767B\u5F55": "Sign in",
332
+ "\u767B\u5F55\u4E2D\u2026": "Signing in\u2026",
333
+ "\u767B\u5F55\u540E\u53EF\u7528": "Available after sign-in",
334
+ "\u767B\u5F55\u5931\u8D25": "Sign-in failed",
335
+ "\u767B\u5F55\u672A\u5B8C\u6210\uFF0C\u8BF7\u5173\u95ED\u540E\u91CD\u65B0\u70B9\u51FB\u300C\u767B\u5F55\u300D\uFF1B\u5B8C\u6574\u9519\u8BEF\u53EF\u4ECE\u5361\u7247\u611F\u53F9\u53F7\u67E5\u770B\u3002": 'Sign-in did not complete. Close this dialog and click "Sign in" again; see the card error for details.',
336
+ "\u767B\u5F55\u6D41\u7A0B\u5DF2\u7ED3\u675F\u6216\u5C1A\u672A\u5F00\u59CB\u3002": "The sign-in flow has ended or has not started.",
337
+ "\u767B\u5F55\u8FDB\u5EA6": "Sign-in progress",
338
+ "\u7B49\u5F85\u6388\u6743": "Waiting for authorization",
339
+ "\u7C98\u8D34\u4EE4\u724C": "Paste token",
340
+ "\u7C98\u8D34\u65B0\u4EE4\u724C": "Paste new token",
341
+ "\u7F16\u8F91\u8FDE\u63A5\u5668\u914D\u7F6E": "Edit connector configuration",
342
+ "\u7F16\u8F91\u914D\u7F6E": "Edit configuration",
343
+ "\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668\u8BF4\u660E": "About custom connectors",
344
+ "\u8BBF\u95EE\u4EE4\u724C": "Access token",
345
+ "\u8BF7\u5148\u5B89\u88C5\u8FDE\u63A5\u5668\uFF0C\u518D\u53D1\u8D77\u6388\u6743": "Install the connector before authorizing.",
346
+ "\u8BF7\u5728\u6D4F\u89C8\u5668\u5B8C\u6210\u767B\u5F55\u6388\u6743\uFF0C\u5B8C\u6210\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\u3002": "Complete sign-in in your browser; it syncs automatically when done.",
347
+ "\u8FDE\u63A5": "Connect",
348
+ "\u8FDE\u63A5\u4E2D": "Connecting",
349
+ "\u8FDE\u63A5\u4E2D\u2026": "Connecting\u2026",
350
+ "\u8FDE\u63A5\u5931\u8D25": "Connection failed",
351
+ "\u9009\u62E9\u7C7B\u522B": "Select category",
352
+ "\u9009\u62E9\u7ED3\u679C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002": "Your selection is stored only on this machine.",
353
+ "\u914D\u7F6E": "Configure",
354
+ "\u914D\u7F6E\u4E2D\u2026": "Configuring\u2026",
355
+ "\u914D\u7F6E\u5E94\u7528\u4E2D": "Configuring app",
356
+ "\u91CD\u65B0\u6388\u6743": "Reauthorize",
357
+ "\u91CD\u65B0\u767B\u5F55": "Sign in again",
358
+ "\u91CD\u8BD5": "Retry",
359
+ "\u91CD\u8BD5\u4E2D\u2026": "Retrying\u2026",
360
+ "\u9690\u85CF SecretKey": "Hide SecretKey",
361
+ "\u9690\u85CF\u4EE4\u724C": "Hide token",
362
+ "\u9ED8\u8BA4\uFF1A\u5176\u4ED6": "Default: Other",
363
+ "\uFF08\u8FDE\u63A5\u5931\u8D25\uFF09": " (failed)",
364
+ "\uFF0C\u5904\u7406\u4E2D": ", working",
365
+ "\uFF0C\u5DF2\u505C\u7528": ", disabled",
366
+ "\uFF0C\u5DF2\u5B89\u88C5\u672A\u767B\u5F55": ", installed, signed out",
367
+ "\uFF0C\u5DF2\u767B\u5F55": ", signed in",
368
+ "\uFF0C\u5DF2\u8FDE\u63A5\uFF0C\u6B63\u5728\u6CE8\u518C\u5DE5\u5177": ", connected, registering tools",
369
+ "\uFF0C\u5F85\u914D\u7F6E": ", needs configuration",
370
+ "\uFF0C\u672A\u5B89\u88C5": ", not installed",
371
+ "\uFF0C\u672A\u6388\u6743": ", not authorized",
372
+ "\uFF0C\u8FDE\u63A5\u4E2D": ", connecting",
373
+ "\u901A\u8FC7 mcpServers \u5BFC\u5165\u7684\u672C\u5730 stdio MCP Server\u3002": "A local stdio MCP server imported from mcpServers.",
374
+ "\u901A\u8FC7 mcpServers \u5BFC\u5165\u7684 SSE MCP Server\u3002": "An SSE MCP server imported from mcpServers.",
375
+ "\u901A\u8FC7 mcpServers \u5BFC\u5165\u7684 Streamable HTTP MCP Server\u3002": "A Streamable HTTP MCP server imported from mcpServers.",
376
+ "CLI \u7248\u672C": "CLI version",
377
+ "\u5361\u7247\u6587\u6848": "Card text",
378
+ "\u4E2D\u6587": "Chinese",
379
+ "\u82F1\u6587\u63CF\u8FF0\uFF08\u53EF\u9009\uFF09": "English description (optional)",
380
+ "\u7559\u7A7A\u4F7F\u7528\u4E2D\u6587\u63CF\u8FF0": "Leave blank to use the Chinese description",
381
+ "\u82F1\u6587\u5206\u7C7B\u663E\u793A\u540D\uFF08\u53EF\u9009\uFF09": "English category label (optional)",
382
+ "\u7559\u7A7A\u4F7F\u7528\u4E2D\u6587\u5206\u7C7B": "Leave blank to use the Chinese category",
383
+ "\u4EC5\u7528\u4E8E\u663E\u793A\uFF0C\u4E0D\u6539\u53D8\u5206\u7C7B\u5206\u7EC4\u3002": "Display only; does not change category grouping.",
384
+ "\u5185\u7F6E\u5206\u7C7B\u4F1A\u81EA\u52A8\u4F7F\u7528\u6807\u51C6\u82F1\u6587\u540D\u79F0\u3002": "Built-in categories use the standard English label.",
385
+ "\u82F1\u6587\u793A\u4F8B\u63D0\u793A\u8BCD\uFF08\u53EF\u9009\uFF0C\u6BCF\u884C\u4E00\u6761\uFF09": "English example prompts (optional, one per line)",
386
+ "\u7559\u7A7A\u4F7F\u7528\u4E2D\u6587\u793A\u4F8B": "Leave blank to use the Chinese examples",
387
+ "\u3002\u767B\u5F55\u8BF7\u56DE\u5230\u5361\u7247\u70B9\u51FB\u300C\u767B\u5F55\u300D\u3002": '. Return to the card and click "Sign in".',
388
+ "\u4E2A Server\uFF1B\u591A Server \u8BF7\u7528\u300C\u4EC5\u5BFC\u5165\u300D\uFF0C\u5BFC\u5165\u540E\u5206\u522B\u8FDE\u63A5\u3002": ' servers. For multiple servers, use "Import only" and connect each afterward.',
389
+ "\u4E2A Skills\u3002": " Skills.",
390
+ "\u4E2A\u3002": ".",
391
+ "\u4F1A\u6CBF\u7528\u539F\u503C\u3002": " keeps the current value.",
392
+ "\u4F4E\u4E8E\u5B98\u65B9\u8981\u6C42": "is below the official requirement",
393
+ "\u4FDD\u5B58\u540E\u4F1A\u6253\u5F00\u6D4F\u89C8\u5668\u5B8C\u6210\u6388\u6743\u3002": "Saving opens the browser to finish authorization.",
394
+ "\u4FEE\u6539\u4F1A\u4FDD\u5B58\u5230\u672C\u673A\uFF1B\u5BC6\u94A5\u4E0E URL \u67E5\u8BE2\u53C2\u6570\u4E0D\u4F1A\u56DE\u663E\uFF0C\u4FDD\u6301": "Changes are saved locally. Secrets and URL query values are not shown; keep",
395
+ "\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u65AD\u8FDE\u63A5\uFF0C\u7ED3\u679C\u4F1A\u663E\u793A\u5728\u5361\u7247\u4E0A\u3002": "Closing this dialog does not interrupt the connection; the result appears on the card.",
396
+ "\u5378\u8F7D": "Uninstall",
397
+ "\u5378\u8F7D\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u6267\u884C\uFF1B\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u6B62\uFF0C\u53EF\u4EE5\u4ECE\u5361\u7247\u91CD\u65B0\u6253\u5F00\u8FDB\u5EA6\u3002": "Uninstall continues on the host. Closing this dialog does not stop it; reopen the progress from the card.",
398
+ "\u53EF\u5728\u6BCF\u4E2A server \u914D\u7F6E\u91CC\u6307\u5B9A\u63CF\u8FF0\u3001\u7C7B\u522B\u4E0E\u793A\u4F8B\uFF0C\u5E76\u7528 translations.en \u63D0\u4F9B\u82F1\u6587\u526F\u672C\uFF1B\u4F18\u5148\u4E8E\u4E0B\u65B9\u8868\u5355\uFF1A": "Each server config can set a description, category, and examples, with an English copy under translations.en; these override the form below:",
399
+ "\u53EF\u7528\u5DE5\u5177": "Available tools",
400
+ "\u53EF\u7528\u80FD\u529B": "Available capabilities",
401
+ "\u53EF\u9009\u6269\u5C55\uFF1Ax-dsh": "Optional extension: x-dsh",
402
+ "\u56DE\u8C03\u5730\u5740": "Callback URL",
403
+ "\u5728": "In",
404
+ "\u5904\u7406\u5931\u8D25": "Operation failed",
405
+ "\u5B89\u88C5\u8F93\u51FA": "Install output",
406
+ "\u5C06\u5378\u8F7D\u672C\u673A npm \u5168\u5C40 CLI": "This uninstalls the global npm CLI",
407
+ "\u5C06\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u5B89\u88C5\u5B98\u65B9 CLI \u4E0E Skills\u3002\u4F1A\u5199\u5165\u672C\u673A npm \u5168\u5C40\u76EE\u5F55\u548C": "This runs the command below to install the official CLI and Skills. It writes to the global npm directory and",
408
+ "\u5DF2\u505C\u7528\uFF0C\u542F\u7528\u540E\u4F1A\u91CD\u65B0\u6CE8\u518C\u5DE5\u5177\u3002": "Disabled. Enabling it registers its tools again.",
409
+ "\u5DF2\u53D1\u73B0": "Found",
410
+ "\u5DF2\u8BFB\u53D6 JSON \u4E2D\u7684 x-dsh\uFF1B\u4E0B\u65B9\u7559\u7A7A\u5C31\u4F7F\u7528\u5B83\uFF0C\u586B\u5199\u4F1A\u8986\u76D6\u3002": "x-dsh was read from the JSON. Leave the fields below blank to use it; entering values overrides it.",
411
+ "\u5F00\u653E\u5E73\u53F0\u521B\u5EFA\u5E94\u7528\uFF0C\u628A\u56DE\u8C03\u5730\u5740\u586B\u5230\u5E94\u7528\u7684\u5B89\u5168\u8BBE\u7F6E\u91CC\uFF0C\u518D\u586B\u5165\u5E94\u7528\u51ED\u636E\uFF1B\u51ED\u636E\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002": "Create an app on the open platform, add the callback URL to its security settings, then enter the app credentials here. Credentials stay on this machine.",
412
+ "\u5F53\u524D\u5DF2\u5B89\u88C5\uFF1B\u5982\u4FEE\u6539\u5730\u5740\u3001\u547D\u4EE4\u3001\u8BF7\u6C42\u5934\u6216\u73AF\u5883\u53D8\u91CF\uFF0C\u4FDD\u5B58\u540E\u4F1A\u65AD\u5F00\u8FDE\u63A5\uFF0C\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u3002": "Currently installed. Changing the address, command, headers, or environment variables disconnects it and requires reinstalling.",
413
+ "\u6211\u786E\u8BA4\u5141\u8BB8\u8BBF\u95EE\u672C\u673A\u6216\u5185\u7F51\u5730\u5740": "I allow access to localhost or a private-network address",
414
+ "\u6253\u5F00\u6388\u6743\u9875\u9762": "Open authorization page",
415
+ "\u6388\u6743\u3002": " authorization.",
416
+ "\u63CF\u8FF0\uFF08\u53EF\u9009\uFF09": "Description (optional)",
417
+ "\u66F4\u65B0": "Update",
418
+ "\u66F4\u65B0 CLI": "Update CLI",
419
+ "\u66F4\u65B0\u4F1A\u539F\u5730\u5347\u7EA7 npm \u5168\u5C40 CLI \u5E76\u91CD\u65B0\u62C9\u53D6 Skills\uFF0C\u4E0D\u4F1A\u6E05\u9664\u767B\u5F55\u6001\uFF1B\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u6B62\uFF0C\u53EF\u518D\u6B21\u6253\u5F00\u67E5\u770B\u8FDB\u5EA6\u3002": "Update upgrades the global npm CLI in place and fetches Skills again without clearing the login. Closing this dialog does not stop it; reopen it to view progress.",
420
+ "\u672C\u6B21\u9519\u8BEF\u6CA1\u6709\u7559\u4E0B\u66F4\u591A\u8FD0\u884C\u65E5\u5FD7\u3002": "This error left no further runtime logs.",
421
+ "\u67E5\u770B\u5B98\u65B9\u5B89\u88C5\u6587\u6863": "View official install docs",
422
+ "\u68C0\u6D4B\u5230": "Detected",
423
+ "\u6B63\u5728\u52A0\u8F7D\u7F16\u8F91\u5668\u2026": "Loading editor\u2026",
424
+ "\u6B63\u5728\u8BFB\u53D6\u65E5\u5FD7\u2026": "Reading logs\u2026",
425
+ "\u6CA1\u6709\u5339\u914D\u7684\u5DE5\u5177": "No matching tools",
426
+ "\u6CA1\u6709\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF1F": "Browser did not open?",
427
+ "\u70B9\u51FB\u300C\u5B89\u88C5\u300D\u540E\u4F1A\u6253\u5F00\u9ED8\u8BA4\u6D4F\u89C8\u5668\u5B8C\u6210": "Click Install to open your default browser and complete",
428
+ "\u70B9\u51FB\u300C\u6388\u6743\u300D\u540E\u586B\u5199": "Click Authorize and enter",
429
+ "\u70B9\u51FB\u300C\u66F4\u65B0\u4EE4\u724C\u300D\u91CD\u65B0\u586B\u5199": "Click Update token to re-enter",
430
+ "\u70B9\u6B64\u6388\u6743": "Authorize here",
431
+ "\u793A\u4F8B\u63D0\u793A\u8BCD\uFF08\u53EF\u9009\uFF0C\u6BCF\u884C\u4E00\u6761\uFF09": "Example prompts (optional, one per line)",
432
+ "\u7BA1\u7406\u8FDE\u63A5\u5668": "Manage connectors",
433
+ "\u7C7B\u522B\uFF08\u53EF\u9009\uFF09": "Category (optional)",
434
+ "\u7C98\u8D34 mcpServers JSON\uFF0C\u652F\u6301 Streamable HTTP\u3001SSE \u4E0E stdio \u4E09\u7C7B MCP Server\u3002": "Paste mcpServers JSON. Streamable HTTP, SSE, and stdio MCP servers are supported.",
435
+ "\u7F16\u8F91\u65F6\u53EA\u80FD\u4FDD\u7559\u4E00\u4E2A Server\uFF0C\u5F53\u524D\u68C0\u6D4B\u5230": "Editing keeps one server only; detected",
436
+ "\u884C": " lines",
437
+ "\u89E3\u7ED1": "Unlink",
438
+ "\u8BD5\u8BD5\u8FD9\u6837\u7528": "Try these",
439
+ "\u8D26\u53F7\u5DF2\u8FDE\u63A5\uFF0C\u53EF\u4EE5\u5173\u95ED\u6B64\u7A97\u53E3\u5E76\u8BA9 Agent \u4F7F\u7528\u5B98\u65B9 Skills\u3002": "Account connected. Close this window and let the agent use the official Skills.",
440
+ "\u8FD0\u884C\u65E5\u5FD7": "Runtime log",
441
+ "\u8FD9\u4E2A\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668\u4F1A\u4ECE\u672C\u673A\u79FB\u9664\uFF0C\u5DF2\u4FDD\u5B58\u7684\u914D\u7F6E\u4E0E\u51ED\u636E\u4F1A\u4E00\u8D77\u5220\u9664\uFF0C\u5DF2\u8FDE\u63A5\u7684\u5DE5\u5177\u4F1A\u6CE8\u9500\u3002": "This custom connector will be removed from this machine. Saved configuration and credentials are deleted, and connected tools are unregistered.",
442
+ "\u914D\u7F6E OAuth \u5E94\u7528": "Configure OAuth app",
443
+ "\u9519\u8BEF\u65E5\u5FD7": "Error log",
444
+ "\u975E https \u5730\u5740\u4F1A\u660E\u6587\u4F20\u8F93\uFF0C\u8BF7\u786E\u8BA4\u7F51\u7EDC\u53EF\u4FE1\u3002": "A non-https address sends data in plain text; make sure the network is trusted.",
445
+ "\uFF0C\u5F71\u54CD\u672C\u673A\u5176\u4ED6 Agent\u3002": ", affecting other agents on this machine.",
446
+ "\uFF0C\u8BF7\u7528\u300C\u66F4\u591A \u2192 \u66F4\u65B0 CLI\u300D\u5347\u7EA7\u3002": "; update it from More \u2192 Update CLI.",
447
+ "\uFF0C\u8FDE\u63A5\u5931\u8D25": ", connection failed",
448
+ "\uFF1B\u4EE4\u724C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002": "; the token stays on this machine.",
449
+ "\u586B\u5199\u4E0B\u65B9\u63CF\u8FF0\u3001\u7C7B\u522B\u3001\u793A\u4F8B\u4F1A\u8986\u76D6\u6240\u6709 Server\uFF1B\u7559\u7A7A\u5219\u5404 Server \u4F7F\u7528\u81EA\u5DF1\u7684 x-dsh\u3002": "Values below override every server; leave them blank to use the x-dsh from each server.",
450
+ "{v0} \u4E2A Skills": "{v0} Skills",
451
+ "{v0} \u4E2A\u4EA7\u54C1": "{v0} products",
452
+ "{v0} \u4E2A\u547D\u4EE4": "{v0} commands",
453
+ "{v0} \u4E2A\u547D\u4EE4\u7EC4": "{v0} command groups",
454
+ "{v0} \u66F4\u591A\u64CD\u4F5C": "More actions for {v0}",
455
+ "{v0} \u9519\u8BEF\u65E5\u5FD7": "{v0} error log",
456
+ "\u4F7F\u7528 {v0} CLI \u5B8C\u6210\u4E00\u4E2A\u7B80\u5355\u4EFB\u52A1\uFF0C\u5148\u8BF4\u660E\u53EF\u4EE5\u505A\u4EC0\u4E48\u3002": "Use the {v0} CLI for a simple task. Start by listing what it can do.",
457
+ "\u4F7F\u7528 {v0} \u7684\u5DE5\u5177\u5B8C\u6210\u4E00\u4E2A\u7B80\u5355\u4EFB\u52A1\uFF0C\u5148\u5217\u51FA\u53EF\u7528\u5DE5\u5177\u3002": "Use {v0} tools for a simple task. Start by listing the available tools.",
458
+ "\u4F7F\u7528 {v0}\uFF1A{v1}": "Use {v0}: {v1}",
459
+ "\u4F7F\u7528{v0} CLI\uFF1A{v1}": "Use the {v0} CLI: {v1}",
460
+ "\u4FDD\u5B58\u540E\u4F1A\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\u5B8C\u6210\u6388\u6743\uFF1B{v0}": "Saving opens the browser to finish authorization; {v0}",
461
+ "\u4FDD\u5B58\u540E\u76F4\u63A5\u8FDE\u63A5\uFF1B{v0}": "Saving connects directly; {v0}",
462
+ "\u4FDD\u5B58\u540E\u7EE7\u7EED\u586B\u5199\u4EE4\u724C\uFF1B{v0}": "Saving continues to the token prompt; {v0}",
463
+ "\u505C\u7528 {v0}": "Disable {v0}",
464
+ "\u5220\u9664 {v0}": "Delete {v0}",
465
+ "\u5378\u8F7D {v0} CLI": "Uninstall the {v0} CLI",
466
+ "\u53BB\u8BD5\u8BD5\uFF1A{v0}": "Try it: {v0}",
467
+ "\u53D6\u6D88\u6388\u6743 {v0}": "Cancel authorization for {v0}",
468
+ "\u542F\u7528 {v0}": "Enable {v0}",
469
+ "\u586B\u5199 {v0} \u4EE4\u724C": "Enter the {v0} token",
470
+ "\u586B\u5199 {v0} \u540E\u8FDE\u63A5\uFF1B\u4EE4\u724C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002": "Enter {v0} to connect; the token stays on this machine.",
471
+ "\u590D\u5236\u793A\u4F8B\uFF1A{v0}": "Copy example: {v0}",
472
+ "\u5B89\u88C5 {v0} CLI": "Install the {v0} CLI",
473
+ "\u5C55\u5F00\u5168\u90E8 {v0} \u4E2A": "Show all {v0}",
474
+ "\u5DF2\u542F\u7528 {v0} \u4E2A\u8FDE\u63A5\u5668": "{v0} connectors enabled",
475
+ "\u5DF2\u5B89\u88C5\uFF0C\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u9009\u62E9{v0}\u540E\u5F00\u59CB\u6388\u6743\u3002": 'Installed. Click "Configure", choose {v0}, then authorize.',
476
+ "\u5DF2\u5B89\u88C5\uFF0C\u70B9\u51FB\u6388\u6743\u540E\u5728\u6D4F\u89C8\u5668\u5B8C\u6210 {v0} \u6388\u6743\u3002": "Installed. Click Authorize and finish {v0} authorization in your browser.",
477
+ "\u5DF2\u66F4\u65B0\u5230 v{v0}\u3002": "Updated to v{v0}.",
478
+ "\u5DF2\u767B\u5F55 \xB7 {v0}": "Signed in \xB7 {v0}",
479
+ "\u5DF2\u8FDE\u63A5 \xB7 {v0} \u4E2A\u5DE5\u5177": "Connected \xB7 {v0} tools",
480
+ "\u5DF2\u8FDE\u63A5 \xB7 {v0} \u4E2A\u5DE5\u5177\n{v1}": "Connected \xB7 {v0} tools\n{v1}",
481
+ "\u6388\u6743 {v0}": "Authorize {v0}",
482
+ "\u66F4\u6362{v0}": "Change {v0}",
483
+ "\u66F4\u65B0 {v0} CLI": "Update the {v0} CLI",
484
+ "\u66F4\u65B0 {v0} \u4EE4\u724C": "Update the {v0} token",
485
+ "\u67E5\u770B {v0} {v1}": "View {v0} {v1}",
486
+ "\u67E5\u770B {v0} \u9519\u8BEF\u65E5\u5FD7": "View the {v0} error log",
487
+ "\u67E5\u770B {v0}{v1}": "View {v0}{v1}",
488
+ "\u6B63\u5728\u5B89\u88C5 {v0}": "Installing {v0}",
489
+ "\u6B63\u5728\u8FDE\u63A5 {v0}": "Connecting to {v0}",
490
+ "\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u586B\u5199\u5B8C\u6574\u7684 MCP \u5730\u5740\uFF1B\u5730\u5740\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002": 'Click "Configure" and enter the full MCP address; it is stored only on this machine.',
491
+ "\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u9009\u62E9{v0}\uFF1B\u9009\u62E9\u7ED3\u679C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002": 'Click "Configure" and choose {v0}; the selection is stored only on this machine.',
492
+ "\u767B\u5F55 {v0}": "Sign in to {v0}",
493
+ "\u9009\u62E9{v0}": "Choose {v0}",
494
+ "\u914D\u7F6E {v0} \u5E94\u7528": "Configure the {v0} app",
495
+ "\uFF0C\u5DF2\u8FDE\u63A5\uFF0C{v0} \u4E2A\u5DE5\u5177": ", connected, {v0} tools",
496
+ "\uFF0C\u5E76\u5220\u9664 ~/.agents/skills \u4E0B {v0} \u4E2A\u5B98\u65B9 Skills": ", and delete {v0} official Skills under ~/.agents/skills",
497
+ "JSON \u4E2D\uFF1A{v0}": "In JSON: {v0}",
498
+ "JSON \u4E2D\uFF1A\n{v0}": "In JSON:\n{v0}"
499
+ };
500
+
501
+ // src/client/i18n.ts
502
+ var localeFace;
503
+ function bindLocale(face) {
504
+ localeFace = face;
505
+ }
506
+ function currentLocale() {
507
+ return localeFace?.getSnapshot().active ?? "zh";
508
+ }
509
+ function useLocaleRevision() {
510
+ const [revision, setRevision] = (0, import_react.useState)(0);
511
+ (0, import_react.useEffect)(() => {
512
+ if (localeFace === void 0) return;
513
+ return localeFace.subscribe(() => setRevision((value) => value + 1));
514
+ }, []);
515
+ return revision;
516
+ }
517
+ function tr(key, params) {
518
+ const template = currentLocale().toLowerCase().startsWith("en") ? EN[key] ?? key : key;
519
+ if (params === void 0) return template;
520
+ return template.replace(/\{(\w+)\}/g, (whole, name) => {
521
+ const value = params[name];
522
+ return value === void 0 ? whole : String(value);
523
+ });
524
+ }
525
+ var PROGRESS_EN = {
526
+ "Install": "Installing",
527
+ "\u5B89\u88C5": "Installing",
528
+ "Configure": "Configuring",
529
+ "\u914D\u7F6E": "Configuring",
530
+ "\u914D\u7F6E\u5E94\u7528": "Configuring app",
531
+ "Authorize": "Authorizing",
532
+ "\u6388\u6743": "Authorizing",
533
+ "Sign in": "Signing in",
534
+ "\u767B\u5F55": "Signing in",
535
+ "Update": "Updating",
536
+ "\u66F4\u65B0": "Updating",
537
+ "Uninstall": "Uninstalling",
538
+ "\u5378\u8F7D": "Uninstalling",
539
+ "Connect": "Connecting",
540
+ "\u8FDE\u63A5": "Connecting"
541
+ };
542
+ function progressText(label) {
543
+ const english = currentLocale().toLowerCase().startsWith("en");
544
+ const translated = english ? tr(label) : label;
545
+ if (translated.endsWith("\u2026")) return translated;
546
+ if (!english) return translated.endsWith("\u4E2D") ? translated : `${translated}\u4E2D\u2026`;
547
+ return `${PROGRESS_EN[translated] ?? translated}\u2026`;
548
+ }
549
+
32
550
  // src/shared/types.ts
33
551
  var ROUTE_PREFIX = "/dsh-connectors";
34
552
 
@@ -250,6 +768,10 @@ function cleanCategory(value) {
250
768
  function categoryKey(value) {
251
769
  return cleanCategory(value).toLocaleLowerCase();
252
770
  }
771
+ function canonicalBuiltinCategory(value) {
772
+ const key = categoryKey(value);
773
+ return BUILTIN_CATEGORIES.find((category) => categoryKey(category) === key);
774
+ }
253
775
  function parseExampleLines(value) {
254
776
  return value.split(/\r?\n/).map((line) => line.trim()).filter((line) => line !== "").slice(0, MAX_EXAMPLES);
255
777
  }
@@ -275,11 +797,60 @@ var CUSTOM_SECRET_PLACEHOLDER = "<\u5DF2\u4FDD\u5B58>";
275
797
 
276
798
  // src/client/index.tsx
277
799
  var import_jsx_runtime2 = require("react/jsx-runtime");
278
- var inject = [];
800
+ var inject = ["locale"];
279
801
  var PANEL_ID = "dsh-connectors";
280
802
  var STYLE_ID = "dsh-connectors-style";
281
803
  var PROBE_ROUNDS = 6;
282
804
  var PROBE_INTERVAL_MS = 350;
805
+ function customSummary(card) {
806
+ return tr(card.server.transport === "stdio" ? "\u901A\u8FC7 mcpServers \u5BFC\u5165\u7684\u672C\u5730 stdio MCP Server\u3002" : card.server.transport === "sse" ? "\u901A\u8FC7 mcpServers \u5BFC\u5165\u7684 SSE MCP Server\u3002" : "\u901A\u8FC7 mcpServers \u5BFC\u5165\u7684 Streamable HTTP MCP Server\u3002");
807
+ }
808
+ function localizedCard(card) {
809
+ const english = currentLocale().toLowerCase().startsWith("en");
810
+ if (card.source === "custom") {
811
+ const copy2 = english ? card.translations?.en : void 0;
812
+ const description = copy2?.description ?? card.description;
813
+ return {
814
+ ...card,
815
+ vendor: tr("\u81EA\u5B9A\u4E49"),
816
+ summary: description ?? customSummary(card),
817
+ ...description === void 0 ? {} : { description },
818
+ examples: copy2?.examples ?? card.examples,
819
+ categoryLabel: english ? copy2?.category ?? tr(card.category) : card.category
820
+ };
821
+ }
822
+ if (!english) return { ...card, categoryLabel: card.category };
823
+ const copy = card.translations?.en;
824
+ return {
825
+ ...card,
826
+ name: copy?.name ?? card.name,
827
+ vendor: copy?.vendor ?? card.vendor,
828
+ summary: copy?.summary ?? card.summary,
829
+ description: copy?.description ?? card.description,
830
+ examples: copy?.examples ?? card.examples,
831
+ categoryLabel: tr(card.category)
832
+ };
833
+ }
834
+ function localizedCli(connector) {
835
+ if (currentLocale().toLowerCase().startsWith("zh")) return connector;
836
+ const copy = CLI_EN[connector.id];
837
+ const capabilities = connector.capabilities === void 0 ? void 0 : {
838
+ ...connector.capabilities,
839
+ items: connector.capabilities.items.map((item) => {
840
+ const translated = CLI_ITEM_EN[`${connector.id}:${item.id}`];
841
+ return translated === void 0 ? item : { ...item, ...translated };
842
+ })
843
+ };
844
+ return {
845
+ ...connector,
846
+ name: copy?.name ?? connector.name,
847
+ vendor: copy?.vendor ?? connector.vendor,
848
+ description: copy?.description ?? connector.description,
849
+ examples: copy?.examples ?? connector.examples,
850
+ installHint: copy?.installLabels ?? connector.installHint,
851
+ ...capabilities === void 0 ? {} : { capabilities }
852
+ };
853
+ }
283
854
  var MCP_SERVERS_PLACEHOLDER = `{
284
855
  "mcpServers": {
285
856
  "my-server": {
@@ -293,15 +864,48 @@ var MCP_SERVERS_PLACEHOLDER = `{
293
864
  }
294
865
  }
295
866
  }`;
867
+ var MCP_SERVERS_PLACEHOLDER_EN = `{
868
+ "mcpServers": {
869
+ "my-server": {
870
+ "url": "https://example.com/mcp",
871
+ "headers": { "Authorization": "Bearer ..." },
872
+ "x-dsh": {
873
+ "description": "Inspect repository structure and docs",
874
+ "category": "\u77E5\u8BC6\u68C0\u7D22",
875
+ "examples": ["Use my-server to look up the latest docs"]
876
+ }
877
+ }
878
+ }
879
+ }`;
880
+ var X_DSH_SAMPLE_EN = `"x-dsh": {
881
+ "description": "Inspect repository structure and docs",
882
+ "category": "\u77E5\u8BC6\u68C0\u7D22",
883
+ "examples": ["Use DeepWiki to inspect the facebook/react repository structure"],
884
+ "translations": {
885
+ "zh": {
886
+ "description": "\u67E5\u8BE2\u4ED3\u5E93\u7ED3\u6784\u4E0E\u6587\u6863",
887
+ "examples": ["\u7528 DeepWiki \u67E5 facebook/react \u7684\u4ED3\u5E93\u7ED3\u6784"]
888
+ }
889
+ }
890
+ }`;
296
891
  function apply(ctx) {
892
+ try {
893
+ return applyInner(ctx);
894
+ } catch (error) {
895
+ console.error("[dsh-connectors] apply failed", error);
896
+ throw error;
897
+ }
898
+ }
899
+ function applyInner(ctx) {
297
900
  installStyles();
298
901
  const get = ctx.get?.bind(ctx);
902
+ bindLocale(ctx.locale);
299
903
  let disposed = false;
300
904
  let timer;
301
905
  const startTrial = (prompt) => {
302
906
  const workspace = get?.("uiWorkspace");
303
907
  if (workspace === void 0 || typeof workspace.startSession !== "function") {
304
- throw new Error("\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u4ECE\u8FDE\u63A5\u5668\u6253\u5F00\u4F1A\u8BDD");
908
+ throw new Error(tr("\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u4ECE\u8FDE\u63A5\u5668\u6253\u5F00\u4F1A\u8BDD"));
305
909
  }
306
910
  workspace.startSession(void 0, { prompt, clearPreviousDraft: true });
307
911
  };
@@ -318,23 +922,23 @@ function apply(ctx) {
318
922
  }
319
923
  try {
320
924
  slots.inject("main", () => slots.register({ name: "main", key: PANEL_ID }, () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Panel, { startTrial })));
321
- slots.inject("sidebar.panellist", () => slots.register({ name: "sidebar.panellist", id: PANEL_ID, order: 20, label: () => "\u8FDE\u63A5\u5668" }, PanelIcon));
925
+ slots.inject("sidebar.panellist", () => slots.register({ name: "sidebar.panellist", id: PANEL_ID, order: 20, label: () => tr("\u8FDE\u63A5\u5668") }, PanelIcon));
322
926
  console.info("[dsh-connectors] panel registered");
323
927
  } catch (error) {
324
928
  console.error("[dsh-connectors] panel registration failed", error);
325
929
  }
326
930
  try {
327
- slots.inject("conversation.input.left", () => slots.register({ name: "conversation.input.left", id: `${PANEL_ID}-dock`, order: 20, label: "\u8FDE\u63A5\u5668" }, ConnectorDock));
931
+ slots.inject("conversation.input.left", () => slots.register({ name: "conversation.input.left", id: `${PANEL_ID}-dock`, order: 20, label: () => tr("\u8FDE\u63A5\u5668") }, ConnectorDock));
328
932
  } catch (error) {
329
933
  console.warn("[dsh-connectors] composer dock slot unavailable", error);
330
934
  }
331
935
  try {
332
- slots.inject("conversation.input.overlay", () => slots.register({ name: "conversation.input.overlay", id: `${PANEL_ID}-popover`, order: 20, label: "\u8FDE\u63A5\u5668" }, ConnectorPopover));
936
+ slots.inject("conversation.input.overlay", () => slots.register({ name: "conversation.input.overlay", id: `${PANEL_ID}-popover`, order: 20, label: () => tr("\u8FDE\u63A5\u5668") }, ConnectorPopover));
333
937
  } catch (error) {
334
938
  console.warn("[dsh-connectors] composer overlay slot unavailable", error);
335
939
  }
336
940
  try {
337
- slots.inject("shell.overlay", () => slots.register({ name: "shell.overlay", id: `${PANEL_ID}-flow`, order: 20, label: "\u8FDE\u63A5\u5668\u5F39\u7A97" }, () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Panel, { startTrial, variant: "overlay" })));
941
+ slots.inject("shell.overlay", () => slots.register({ name: "shell.overlay", id: `${PANEL_ID}-flow`, order: 20, label: () => tr("\u8FDE\u63A5\u5668\u5F39\u7A97") }, () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Panel, { startTrial, variant: "overlay" })));
338
942
  } catch (error) {
339
943
  console.warn("[dsh-connectors] shell overlay slot unavailable", error);
340
944
  }
@@ -395,11 +999,11 @@ async function writeClipboard(text) {
395
999
  if (!copied) throw new Error("copy failed");
396
1000
  }
397
1001
  function promptForExample(card, example) {
398
- return example.toLowerCase().includes(card.name.toLowerCase()) ? example : `\u4F7F\u7528 ${card.name}\uFF1A${example}`;
1002
+ return example.toLowerCase().includes(card.name.toLowerCase()) ? example : tr("\u4F7F\u7528 {v0}\uFF1A{v1}", { v0: card.name, v1: example });
399
1003
  }
400
1004
  function promptForNextExample(card) {
401
1005
  const examples = card.examples ?? [];
402
- if (examples.length === 0) return `\u4F7F\u7528 ${card.name} \u7684\u5DE5\u5177\u5B8C\u6210\u4E00\u4E2A\u7B80\u5355\u4EFB\u52A1\uFF0C\u5148\u5217\u51FA\u53EF\u7528\u5DE5\u5177\u3002`;
1006
+ if (examples.length === 0) return tr("\u4F7F\u7528 {v0} \u7684\u5DE5\u5177\u5B8C\u6210\u4E00\u4E2A\u7B80\u5355\u4EFB\u52A1\uFF0C\u5148\u5217\u51FA\u53EF\u7528\u5DE5\u5177\u3002", { v0: card.name });
403
1007
  const key = `dsh-connectors:trial-index:${card.id}`;
404
1008
  let index = 0;
405
1009
  try {
@@ -430,10 +1034,10 @@ function isTokenCard(card) {
430
1034
  }
431
1035
  function tokenLabel(card) {
432
1036
  const auth = card.auth;
433
- return auth.type === "bearer" || auth.type === "header" ? auth.label : "\u8BBF\u95EE\u4EE4\u724C";
1037
+ return auth.type === "bearer" || auth.type === "header" ? auth.label : tr("\u8BBF\u95EE\u4EE4\u724C");
434
1038
  }
435
1039
  function instanceNoun(card) {
436
- return card.instance?.noun ?? "\u5730\u5740";
1040
+ return card.instance?.noun ?? tr("\u5730\u5740");
437
1041
  }
438
1042
  function tokenHelp(card) {
439
1043
  const auth = card.auth;
@@ -454,10 +1058,10 @@ function Spinner({ inline = false }) {
454
1058
  );
455
1059
  }
456
1060
  function ToolRow({ name, description }) {
457
- const [expanded, setExpanded] = (0, import_react.useState)(false);
458
- const [overflow, setOverflow] = (0, import_react.useState)(false);
459
- const descRef = (0, import_react.useRef)(null);
460
- (0, import_react.useLayoutEffect)(() => {
1061
+ const [expanded, setExpanded] = (0, import_react2.useState)(false);
1062
+ const [overflow, setOverflow] = (0, import_react2.useState)(false);
1063
+ const descRef = (0, import_react2.useRef)(null);
1064
+ (0, import_react2.useLayoutEffect)(() => {
461
1065
  const element = descRef.current;
462
1066
  if (element === null || description === void 0) {
463
1067
  setOverflow(false);
@@ -479,9 +1083,9 @@ function ToolRow({ name, description }) {
479
1083
  {
480
1084
  type: "button",
481
1085
  className: "dshc-tool-expand",
482
- "aria-label": expanded ? "\u6536\u8D77\u63CF\u8FF0" : "\u5C55\u5F00\u63CF\u8FF0",
1086
+ "aria-label": expanded ? tr("\u6536\u8D77\u63CF\u8FF0") : tr("\u5C55\u5F00\u63CF\u8FF0"),
483
1087
  "aria-expanded": expanded,
484
- title: expanded ? "\u6536\u8D77\u63CF\u8FF0" : "\u5C55\u5F00\u63CF\u8FF0",
1088
+ title: expanded ? tr("\u6536\u8D77\u63CF\u8FF0") : tr("\u5C55\u5F00\u63CF\u8FF0"),
485
1089
  onClick: () => setExpanded((current) => !current),
486
1090
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
487
1091
  IconChevronDown,
@@ -540,16 +1144,16 @@ function loadMonaco() {
540
1144
  return monacoPromise;
541
1145
  }
542
1146
  function JsonEditor({ value, onChange }) {
543
- const mountRef = (0, import_react.useRef)(null);
544
- const editorRef = (0, import_react.useRef)(null);
545
- const subscriptionRef = (0, import_react.useRef)(null);
546
- const onChangeRef = (0, import_react.useRef)(onChange);
547
- const valueRef = (0, import_react.useRef)(value);
548
- const [ready, setReady] = (0, import_react.useState)(false);
549
- const [failed, setFailed] = (0, import_react.useState)(false);
1147
+ const mountRef = (0, import_react2.useRef)(null);
1148
+ const editorRef = (0, import_react2.useRef)(null);
1149
+ const subscriptionRef = (0, import_react2.useRef)(null);
1150
+ const onChangeRef = (0, import_react2.useRef)(onChange);
1151
+ const valueRef = (0, import_react2.useRef)(value);
1152
+ const [ready, setReady] = (0, import_react2.useState)(false);
1153
+ const [failed, setFailed] = (0, import_react2.useState)(false);
550
1154
  onChangeRef.current = onChange;
551
1155
  valueRef.current = value;
552
- (0, import_react.useEffect)(() => {
1156
+ (0, import_react2.useEffect)(() => {
553
1157
  let active = true;
554
1158
  void loadMonaco().then((monaco) => {
555
1159
  if (!active || mountRef.current === null) return;
@@ -603,7 +1207,7 @@ function JsonEditor({ value, onChange }) {
603
1207
  editorRef.current = null;
604
1208
  };
605
1209
  }, []);
606
- (0, import_react.useEffect)(() => {
1210
+ (0, import_react2.useEffect)(() => {
607
1211
  const editor = editorRef.current;
608
1212
  if (editor !== null && editor.getValue() !== value) editor.setValue(value);
609
1213
  }, [value]);
@@ -622,19 +1226,19 @@ function JsonEditor({ value, onChange }) {
622
1226
  ),
623
1227
  !ready && !failed && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-json-editor-loading", children: [
624
1228
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
625
- "\u6B63\u5728\u52A0\u8F7D\u7F16\u8F91\u5668\u2026"
1229
+ tr("\u6B63\u5728\u52A0\u8F7D\u7F16\u8F91\u5668\u2026")
626
1230
  ] })
627
1231
  ] });
628
1232
  }
629
1233
  function sleep(ms, signal) {
630
1234
  return new Promise((resolve, reject) => {
631
1235
  if (signal?.aborted) {
632
- reject(new ApiError("oauth_cancelled", "\u5DF2\u53D6\u6D88\u6388\u6743"));
1236
+ reject(new ApiError("oauth_cancelled", tr("\u5DF2\u53D6\u6D88\u6388\u6743")));
633
1237
  return;
634
1238
  }
635
1239
  const onAbort = () => {
636
1240
  clearTimeout(timer);
637
- reject(new ApiError("oauth_cancelled", "\u5DF2\u53D6\u6D88\u6388\u6743"));
1241
+ reject(new ApiError("oauth_cancelled", tr("\u5DF2\u53D6\u6D88\u6388\u6743")));
638
1242
  };
639
1243
  const timer = setTimeout(() => {
640
1244
  signal?.removeEventListener("abort", onAbort);
@@ -661,12 +1265,12 @@ async function authorizeConnector(card, options = {}) {
661
1265
  signal: options.signal
662
1266
  });
663
1267
  } catch (cause) {
664
- if (options.signal?.aborted) throw new ApiError("oauth_cancelled", "\u5DF2\u53D6\u6D88\u6388\u6743");
1268
+ if (options.signal?.aborted) throw new ApiError("oauth_cancelled", tr("\u5DF2\u53D6\u6D88\u6388\u6743"));
665
1269
  throw cause;
666
1270
  }
667
1271
  const { flowId, authorizeUrl, opened } = response.value;
668
1272
  options.onFlow?.({ flowId, authorizeUrl, opened });
669
- if (options.signal?.aborted) throw new ApiError("oauth_cancelled", "\u5DF2\u53D6\u6D88\u6388\u6743");
1273
+ if (options.signal?.aborted) throw new ApiError("oauth_cancelled", tr("\u5DF2\u53D6\u6D88\u6388\u6743"));
670
1274
  const deadline = Date.now() + OAUTH_TIMEOUT_MS;
671
1275
  for (; ; ) {
672
1276
  await sleep(OAUTH_POLL_MS, options.signal);
@@ -678,7 +1282,7 @@ async function authorizeConnector(card, options = {}) {
678
1282
  );
679
1283
  status = payload.value;
680
1284
  } catch {
681
- if (options.signal?.aborted) throw new ApiError("oauth_cancelled", "\u5DF2\u53D6\u6D88\u6388\u6743");
1285
+ if (options.signal?.aborted) throw new ApiError("oauth_cancelled", tr("\u5DF2\u53D6\u6D88\u6388\u6743"));
682
1286
  }
683
1287
  if (status?.status === "done") {
684
1288
  let connection;
@@ -690,27 +1294,27 @@ async function authorizeConnector(card, options = {}) {
690
1294
  connection = list.value.connections.find((item) => item.connectorId === card.id);
691
1295
  fetched = true;
692
1296
  } catch {
693
- if (options.signal?.aborted) throw new ApiError("oauth_cancelled", "\u5DF2\u53D6\u6D88\u6388\u6743");
1297
+ if (options.signal?.aborted) throw new ApiError("oauth_cancelled", tr("\u5DF2\u53D6\u6D88\u6388\u6743"));
694
1298
  }
695
1299
  if (fetched) {
696
1300
  if (connection === void 0) {
697
- throw new ApiError("oauth_failed", "\u6388\u6743\u5B8C\u6210\uFF0C\u4F46\u6CA1\u6709\u627E\u5230\u8FDE\u63A5\u8BB0\u5F55\uFF0C\u8BF7\u5237\u65B0\u9762\u677F\u91CD\u8BD5");
1301
+ throw new ApiError("oauth_failed", tr("\u6388\u6743\u5B8C\u6210\uFF0C\u4F46\u6CA1\u6709\u627E\u5230\u8FDE\u63A5\u8BB0\u5F55\uFF0C\u8BF7\u5237\u65B0\u9762\u677F\u91CD\u8BD5"));
698
1302
  }
699
1303
  return connection;
700
1304
  }
701
1305
  }
702
1306
  if (status?.status === "error") {
703
- throw new ApiError("oauth_failed", status.message ?? "\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5");
1307
+ throw new ApiError("oauth_failed", status.message ?? tr("\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5"));
704
1308
  }
705
1309
  if (status?.status === "expired") {
706
- throw new ApiError("oauth_expired", "\u6388\u6743\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u8BD5");
1310
+ throw new ApiError("oauth_expired", tr("\u6388\u6743\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u8BD5"));
707
1311
  }
708
1312
  if (Date.now() >= deadline) {
709
1313
  await request(`${ROUTE_PREFIX}/api/oauth/cancel`, {
710
1314
  method: "POST",
711
1315
  body: JSON.stringify({ flowId })
712
1316
  }).catch(() => void 0);
713
- throw new ApiError("oauth_timeout", "\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5");
1317
+ throw new ApiError("oauth_timeout", tr("\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5"));
714
1318
  }
715
1319
  }
716
1320
  }
@@ -720,7 +1324,7 @@ async function saveOAuthClient(card, clientId, clientSecret) {
720
1324
  body: JSON.stringify({ clientId, clientSecret })
721
1325
  });
722
1326
  const connection = response.value?.connection;
723
- if (connection === void 0) throw new ApiError("invalid_response", "\u4FDD\u5B58\u5E94\u7528\u51ED\u636E\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5");
1327
+ if (connection === void 0) throw new ApiError("invalid_response", tr("\u4FDD\u5B58\u5E94\u7528\u51ED\u636E\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5"));
724
1328
  return connection;
725
1329
  }
726
1330
  var initialDockSnapshot = {
@@ -750,7 +1354,7 @@ function subscribeDock(listener) {
750
1354
  };
751
1355
  }
752
1356
  function useDock() {
753
- return (0, import_react.useSyncExternalStore)(subscribeDock, () => dockSnapshot);
1357
+ return (0, import_react2.useSyncExternalStore)(subscribeDock, () => dockSnapshot);
754
1358
  }
755
1359
  function refreshDock() {
756
1360
  if (dockRequest !== null) {
@@ -849,14 +1453,17 @@ function enabledDockCli(state) {
849
1453
  return state.cli.filter((connector) => connector.installed && connector.authenticated && connector.enabled !== false).sort((left, right) => left.name.localeCompare(right.name, "zh-CN"));
850
1454
  }
851
1455
  function dockActionLabel(card, connection) {
852
- if (connection === void 0) return "\u5B89\u88C5";
853
- if (card.instance !== void 0 && connection.instanceReady !== true) return "\u914D\u7F6E";
854
- return "\u6388\u6743";
1456
+ if (connection === void 0) return tr("\u5B89\u88C5");
1457
+ if (card.instance !== void 0 && connection.instanceReady !== true) return tr("\u914D\u7F6E");
1458
+ return tr("\u6388\u6743");
855
1459
  }
856
1460
  function openConnectorPanel() {
857
1461
  closeDock();
858
1462
  if (document.querySelector(".dshc-root:not(.dshc-flow-root)") !== null) return;
859
- const button = Array.from(document.querySelectorAll("button")).find((item) => item.getAttribute("aria-label") === "\u8FDE\u63A5\u5668");
1463
+ const button = Array.from(document.querySelectorAll("button")).find((item) => {
1464
+ const label = item.getAttribute("aria-label");
1465
+ return label === "\u8FDE\u63A5\u5668" || label === tr("\u8FDE\u63A5\u5668");
1466
+ });
860
1467
  if (button === void 0) return;
861
1468
  const rect = button.getBoundingClientRect();
862
1469
  const options = {
@@ -908,8 +1515,9 @@ async function cancelDockCli(connector) {
908
1515
  }
909
1516
  }
910
1517
  function ConnectorDock() {
1518
+ useLocaleRevision();
911
1519
  const state = useDock();
912
- (0, import_react.useEffect)(() => {
1520
+ (0, import_react2.useEffect)(() => {
913
1521
  void refreshDock();
914
1522
  const onChange = () => {
915
1523
  void refreshDock();
@@ -930,7 +1538,7 @@ function ConnectorDock() {
930
1538
  ].sort((left, right) => left.name.localeCompare(right.name, "zh-CN"));
931
1539
  const shown = entries.slice(0, 3);
932
1540
  const extra = entries.length - shown.length;
933
- const label = entries.map((entry) => `${entry.name}${entry.failed ? "\uFF08\u8FDE\u63A5\u5931\u8D25\uFF09" : ""}`).join("\u3001");
1541
+ const label = entries.map((entry) => `${entry.name}${entry.failed ? tr("\uFF08\u8FDE\u63A5\u5931\u8D25\uFF09") : ""}`).join("\u3001");
934
1542
  const single = entries.length === 1;
935
1543
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
936
1544
  "button",
@@ -939,7 +1547,7 @@ function ConnectorDock() {
939
1547
  className: single ? "dshc-dock dshc-dock-single" : "dshc-dock",
940
1548
  "data-dshc-dock": "true",
941
1549
  title: label,
942
- "aria-label": `\u5DF2\u542F\u7528 ${entries.length} \u4E2A\u8FDE\u63A5\u5668`,
1550
+ "aria-label": tr("\u5DF2\u542F\u7528 {v0} \u4E2A\u8FDE\u63A5\u5668", { v0: entries.length }),
943
1551
  onClick: toggleDock,
944
1552
  children: [
945
1553
  shown.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dock-icon", style: { zIndex: shown.length - index }, children: [
@@ -955,15 +1563,16 @@ function ConnectorDock() {
955
1563
  );
956
1564
  }
957
1565
  function ConnectorPopover() {
1566
+ useLocaleRevision();
958
1567
  const state = useDock();
959
- const [tip, setTip] = (0, import_react.useState)(null);
960
- const [pendingLabel, setPendingLabel] = (0, import_react.useState)(null);
961
- const flowAckRef = (0, import_react.useRef)(null);
962
- const cliWasActiveRef = (0, import_react.useRef)(false);
963
- (0, import_react.useEffect)(() => {
1568
+ const [tip, setTip] = (0, import_react2.useState)(null);
1569
+ const [pendingLabel, setPendingLabel] = (0, import_react2.useState)(null);
1570
+ const flowAckRef = (0, import_react2.useRef)(null);
1571
+ const cliWasActiveRef = (0, import_react2.useRef)(false);
1572
+ (0, import_react2.useEffect)(() => {
964
1573
  setTip(null);
965
1574
  }, [state.open, state.query]);
966
- (0, import_react.useEffect)(() => {
1575
+ (0, import_react2.useEffect)(() => {
967
1576
  const onStarted = (event) => {
968
1577
  const cardId = event.detail?.cardId;
969
1578
  if (cardId !== void 0) flowAckRef.current = cardId;
@@ -1012,11 +1621,11 @@ function ConnectorPopover() {
1012
1621
  window.removeEventListener("dshc:cli-flow-opened", onCliOpened);
1013
1622
  };
1014
1623
  }, []);
1015
- (0, import_react.useEffect)(() => {
1624
+ (0, import_react2.useEffect)(() => {
1016
1625
  if (state.open) void refreshDock();
1017
1626
  }, [state.open]);
1018
1627
  const cliActive = state.cli.some((connector) => connector.phase !== "idle" && connector.phase !== "error");
1019
- (0, import_react.useEffect)(() => {
1628
+ (0, import_react2.useEffect)(() => {
1020
1629
  if (!state.open) return;
1021
1630
  if (cliActive) {
1022
1631
  cliWasActiveRef.current = true;
@@ -1032,7 +1641,7 @@ function ConnectorPopover() {
1032
1641
  }, 900);
1033
1642
  return () => window.clearTimeout(timer);
1034
1643
  }, [state.open, cliActive]);
1035
- (0, import_react.useEffect)(() => {
1644
+ (0, import_react2.useEffect)(() => {
1036
1645
  if (!state.open) return;
1037
1646
  const onKey = (event) => {
1038
1647
  if (event.key !== "Escape") return;
@@ -1117,25 +1726,24 @@ function ConnectorPopover() {
1117
1726
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ConnectorLogo, { card, size: 18 }) }),
1118
1727
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dock-row-main", children: [
1119
1728
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-name", children: card.name }),
1120
- connection?.error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-error", title: connection.error, children: "\u8FDE\u63A5\u5931\u8D25" })
1729
+ connection?.error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-error", title: connection.error, children: tr("\u8FDE\u63A5\u5931\u8D25") })
1121
1730
  ] }),
1122
- connection !== void 0 && connection.authorized ? pending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-toggle", role: "status", "aria-label": "\u5904\u7406\u4E2D", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1731
+ connection !== void 0 && connection.authorized ? pending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-toggle", role: "status", "aria-label": tr("\u5904\u7406\u4E2D"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1123
1732
  "button",
1124
1733
  {
1125
1734
  type: "button",
1126
1735
  role: "switch",
1127
1736
  className: "dshc-switch",
1128
1737
  "aria-checked": connection.enabled,
1129
- "aria-label": connection.enabled ? `\u505C\u7528 ${card.name}` : `\u542F\u7528 ${card.name}`,
1130
- title: connection.enabled ? "\u505C\u7528" : "\u542F\u7528",
1738
+ "aria-label": connection.enabled ? tr("\u505C\u7528 {v0}", { v0: card.name }) : tr("\u542F\u7528 {v0}", { v0: card.name }),
1739
+ title: connection.enabled ? tr("\u505C\u7528") : tr("\u542F\u7528"),
1131
1740
  onClick: () => {
1132
1741
  void toggleDockConnection(card, !connection.enabled);
1133
1742
  }
1134
1743
  }
1135
- ) : pending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dock-pending", role: "status", "aria-label": `${pendingLabelText}\u4E2D`, children: [
1744
+ ) : pending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dock-pending", role: "status", "aria-label": progressText(pendingLabelText), children: [
1136
1745
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
1137
- pendingLabelText,
1138
- "\u4E2D\u2026",
1746
+ progressText(pendingLabelText),
1139
1747
  canCancel && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1140
1748
  "button",
1141
1749
  {
@@ -1145,7 +1753,7 @@ function ConnectorPopover() {
1145
1753
  event.stopPropagation();
1146
1754
  requestConnectorFlowCancel(card.id);
1147
1755
  },
1148
- children: "\u53D6\u6D88"
1756
+ children: tr("\u53D6\u6D88")
1149
1757
  }
1150
1758
  )
1151
1759
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-dock-connect", onClick: () => startFlow(card), children: [
@@ -1162,7 +1770,7 @@ function ConnectorPopover() {
1162
1770
  const enabled = connector.enabled !== false;
1163
1771
  const ready = connector.installed && connector.authenticated;
1164
1772
  const action = connector.installed ? "login" : "install";
1165
- const actionLabel = connector.installed ? "\u767B\u5F55" : "\u5B89\u88C5";
1773
+ const actionLabel = connector.installed ? tr("\u767B\u5F55") : tr("\u5B89\u88C5");
1166
1774
  const pendingLabel2 = connector.stage ?? actionLabel;
1167
1775
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dock-item", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1168
1776
  "div",
@@ -1174,26 +1782,25 @@ function ConnectorPopover() {
1174
1782
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CliLogo, { connector, size: 18 }) }),
1175
1783
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dock-row-main", children: [
1176
1784
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-name", children: connector.name }),
1177
- connector.phase === "error" && connector.lastError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-error", title: connector.lastError, children: "\u5904\u7406\u5931\u8D25" })
1785
+ connector.phase === "error" && connector.lastError !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-error", title: connector.lastError, children: tr("\u5904\u7406\u5931\u8D25") })
1178
1786
  ] }),
1179
1787
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-row-hint", children: "CLI" }),
1180
- ready && !busy ? pending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-toggle", role: "status", "aria-label": "\u5904\u7406\u4E2D", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1788
+ ready && !busy ? pending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dock-toggle", role: "status", "aria-label": tr("\u5904\u7406\u4E2D"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1181
1789
  "button",
1182
1790
  {
1183
1791
  type: "button",
1184
1792
  role: "switch",
1185
1793
  className: "dshc-switch",
1186
1794
  "aria-checked": enabled,
1187
- "aria-label": enabled ? `\u505C\u7528 ${connector.name}` : `\u542F\u7528 ${connector.name}`,
1188
- title: enabled ? "\u505C\u7528" : "\u542F\u7528",
1795
+ "aria-label": enabled ? tr("\u505C\u7528 {v0}", { v0: connector.name }) : tr("\u542F\u7528 {v0}", { v0: connector.name }),
1796
+ title: enabled ? tr("\u505C\u7528") : tr("\u542F\u7528"),
1189
1797
  onClick: () => {
1190
1798
  void toggleDockCli(connector, !enabled);
1191
1799
  }
1192
1800
  }
1193
- ) : pending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dock-pending", role: "status", "aria-label": `${pendingLabel2}\u4E2D`, children: [
1801
+ ) : pending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dock-pending", role: "status", "aria-label": progressText(pendingLabel2), children: [
1194
1802
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
1195
- pendingLabel2,
1196
- "\u4E2D\u2026",
1803
+ progressText(pendingLabel2),
1197
1804
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1198
1805
  "button",
1199
1806
  {
@@ -1203,7 +1810,7 @@ function ConnectorPopover() {
1203
1810
  event.stopPropagation();
1204
1811
  void cancelDockCli(connector);
1205
1812
  },
1206
- children: "\u53D6\u6D88"
1813
+ children: tr("\u53D6\u6D88")
1207
1814
  }
1208
1815
  )
1209
1816
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-dock-connect", onClick: () => startCliFlow(connector, action), children: [
@@ -1215,7 +1822,7 @@ function ConnectorPopover() {
1215
1822
  ) }, `cli:${connector.id}`);
1216
1823
  };
1217
1824
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1218
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dock-popover", role: "dialog", "aria-label": "\u8FDE\u63A5\u5668", children: [
1825
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dock-popover", role: "dialog", "aria-label": tr("\u8FDE\u63A5\u5668"), children: [
1219
1826
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-dock-search", children: [
1220
1827
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconSearch, { size: 13 }),
1221
1828
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -1227,17 +1834,17 @@ function ConnectorPopover() {
1227
1834
  "data-lpignore": "true",
1228
1835
  "data-1p-ignore": "true",
1229
1836
  "data-bwignore": "true",
1230
- placeholder: "\u641C\u7D22\u8FDE\u63A5\u5668",
1837
+ placeholder: tr("\u641C\u7D22\u8FDE\u63A5\u5668"),
1231
1838
  value: state.query,
1232
1839
  onChange: (event) => updateDock({ query: event.target.value })
1233
1840
  }
1234
1841
  )
1235
1842
  ] }),
1236
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dock-list", onScroll: () => setTip(null), children: !state.loaded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dock-empty", children: state.loading ? "\u6B63\u5728\u52A0\u8F7D\u8FDE\u63A5\u5668\u2026" : "\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5\u5668" }) : rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dock-empty", children: "\u6CA1\u6709\u5339\u914D\u7684\u8FDE\u63A5\u5668" }) : rows.map((entry) => entry.kind === "mcp" ? renderMcpRow(entry.card) : renderCliRow(entry.connector)) }),
1843
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dock-list", onScroll: () => setTip(null), children: !state.loaded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dock-empty", children: state.loading ? tr("\u6B63\u5728\u52A0\u8F7D\u8FDE\u63A5\u5668\u2026") : tr("\u6CA1\u6709\u53EF\u7528\u7684\u8FDE\u63A5\u5668") }) : rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dock-empty", children: tr("\u6CA1\u6709\u5339\u914D\u7684\u8FDE\u63A5\u5668") }) : rows.map((entry) => entry.kind === "mcp" ? renderMcpRow(entry.card) : renderCliRow(entry.connector)) }),
1237
1844
  state.error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dock-error", children: state.error }),
1238
1845
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-dock-manage", onClick: openConnectorPanel, children: [
1239
1846
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconLink, { size: 13 }),
1240
- "\u7BA1\u7406\u8FDE\u63A5\u5668"
1847
+ tr("\u7BA1\u7406\u8FDE\u63A5\u5668")
1241
1848
  ] })
1242
1849
  ] }),
1243
1850
  tip !== null && (0, import_react_dom.createPortal)(
@@ -1247,60 +1854,61 @@ function ConnectorPopover() {
1247
1854
  ] });
1248
1855
  }
1249
1856
  function Panel({ startTrial, variant = "panel" }) {
1250
- const [cards, setCards] = (0, import_react.useState)([]);
1251
- const [connections, setConnections] = (0, import_react.useState)({});
1252
- const [error, setError] = (0, import_react.useState)(null);
1253
- const [query, setQuery] = (0, import_react.useState)("");
1254
- const searchRef = (0, import_react.useRef)(null);
1255
- const [category, setCategory] = (0, import_react.useState)("\u5168\u90E8");
1256
- const [loading, setLoading] = (0, import_react.useState)(false);
1257
- const [dialogCard, setDialogCard] = (0, import_react.useState)(null);
1258
- const [dialogInstall, setDialogInstall] = (0, import_react.useState)(false);
1259
- const [credentialCard, setCredentialCard] = (0, import_react.useState)(null);
1260
- const [credentialMode, setCredentialMode] = (0, import_react.useState)("update");
1261
- const [credentialSaving, setCredentialSaving] = (0, import_react.useState)(null);
1262
- const [credentialError, setCredentialError] = (0, import_react.useState)(null);
1263
- const [oauthAppCard, setOauthAppCard] = (0, import_react.useState)(null);
1264
- const [oauthAppSaving, setOauthAppSaving] = (0, import_react.useState)(false);
1265
- const [oauthAppError, setOauthAppError] = (0, import_react.useState)(null);
1266
- const [dialogError, setDialogError] = (0, import_react.useState)(null);
1267
- const [pending, setPending] = (0, import_react.useState)(null);
1268
- const [connectingId, setConnectingId] = (0, import_react.useState)(null);
1269
- const [togglePending, setTogglePending] = (0, import_react.useState)(null);
1270
- const [cardErrors, setCardErrors] = (0, import_react.useState)({});
1271
- const [oauthFlow, setOAuthFlow] = (0, import_react.useState)(null);
1272
- const [oauthStarting, setOauthStarting] = (0, import_react.useState)(null);
1273
- const oauthAbortRef = (0, import_react.useRef)(null);
1274
- const [customOpen, setCustomOpen] = (0, import_react.useState)(false);
1275
- const [deleteCard, setDeleteCard] = (0, import_react.useState)(null);
1276
- const [deleteError, setDeleteError] = (0, import_react.useState)(null);
1277
- const [instanceCard, setInstanceCard] = (0, import_react.useState)(null);
1278
- const [instanceMode, setInstanceMode] = (0, import_react.useState)("config");
1279
- const [instancePending, setInstancePending] = (0, import_react.useState)(false);
1280
- const [instanceError, setInstanceError] = (0, import_react.useState)(null);
1281
- const [instanceReturnToDetail, setInstanceReturnToDetail] = (0, import_react.useState)(false);
1282
- const [editCard, setEditCard] = (0, import_react.useState)(null);
1283
- const [editConfig, setEditConfig] = (0, import_react.useState)(null);
1284
- const [editReturnToDetail, setEditReturnToDetail] = (0, import_react.useState)(false);
1285
- const dialogCardRef = (0, import_react.useRef)(null);
1286
- const installOpRef = (0, import_react.useRef)(null);
1287
- const [flowTick, setFlowTick] = (0, import_react.useState)(0);
1288
- const [cliConnectors, setCliConnectors] = (0, import_react.useState)([]);
1289
- const [cliError, setCliError] = (0, import_react.useState)(null);
1290
- const [cliDetailId, setCliDetailId] = (0, import_react.useState)(null);
1291
- const [cliInstallId, setCliInstallId] = (0, import_react.useState)(null);
1292
- const [cliLoginId, setCliLoginId] = (0, import_react.useState)(null);
1293
- const [cliUninstallId, setCliUninstallId] = (0, import_react.useState)(null);
1294
- const [cliUpdateId, setCliUpdateId] = (0, import_react.useState)(null);
1295
- const [cliUpdateStarted, setCliUpdateStarted] = (0, import_react.useState)(false);
1296
- const [cliUpdateError, setCliUpdateError] = (0, import_react.useState)(null);
1297
- const [cliUninstallPending, setCliUninstallPending] = (0, import_react.useState)(false);
1298
- const [cliUninstallError, setCliUninstallError] = (0, import_react.useState)(null);
1299
- const [cliBusyId, setCliBusyId] = (0, import_react.useState)(null);
1300
- const [cliTogglePending, setCliTogglePending] = (0, import_react.useState)(null);
1301
- const [cliFlow, setCliFlow] = (0, import_react.useState)(null);
1302
- const [cliErrorId, setCliErrorId] = (0, import_react.useState)(null);
1303
- (0, import_react.useEffect)(() => {
1857
+ const localeRevision = useLocaleRevision();
1858
+ const [cards, setCards] = (0, import_react2.useState)([]);
1859
+ const [connections, setConnections] = (0, import_react2.useState)({});
1860
+ const [error, setError] = (0, import_react2.useState)(null);
1861
+ const [query, setQuery] = (0, import_react2.useState)("");
1862
+ const searchRef = (0, import_react2.useRef)(null);
1863
+ const [category, setCategory] = (0, import_react2.useState)("\u5168\u90E8");
1864
+ const [loading, setLoading] = (0, import_react2.useState)(false);
1865
+ const [dialogCard, setDialogCard] = (0, import_react2.useState)(null);
1866
+ const [dialogInstall, setDialogInstall] = (0, import_react2.useState)(false);
1867
+ const [credentialCard, setCredentialCard] = (0, import_react2.useState)(null);
1868
+ const [credentialMode, setCredentialMode] = (0, import_react2.useState)("update");
1869
+ const [credentialSaving, setCredentialSaving] = (0, import_react2.useState)(null);
1870
+ const [credentialError, setCredentialError] = (0, import_react2.useState)(null);
1871
+ const [oauthAppCard, setOauthAppCard] = (0, import_react2.useState)(null);
1872
+ const [oauthAppSaving, setOauthAppSaving] = (0, import_react2.useState)(false);
1873
+ const [oauthAppError, setOauthAppError] = (0, import_react2.useState)(null);
1874
+ const [dialogError, setDialogError] = (0, import_react2.useState)(null);
1875
+ const [pending, setPending] = (0, import_react2.useState)(null);
1876
+ const [connectingId, setConnectingId] = (0, import_react2.useState)(null);
1877
+ const [togglePending, setTogglePending] = (0, import_react2.useState)(null);
1878
+ const [cardErrors, setCardErrors] = (0, import_react2.useState)({});
1879
+ const [oauthFlow, setOAuthFlow] = (0, import_react2.useState)(null);
1880
+ const [oauthStarting, setOauthStarting] = (0, import_react2.useState)(null);
1881
+ const oauthAbortRef = (0, import_react2.useRef)(null);
1882
+ const [customOpen, setCustomOpen] = (0, import_react2.useState)(false);
1883
+ const [deleteCard, setDeleteCard] = (0, import_react2.useState)(null);
1884
+ const [deleteError, setDeleteError] = (0, import_react2.useState)(null);
1885
+ const [instanceCard, setInstanceCard] = (0, import_react2.useState)(null);
1886
+ const [instanceMode, setInstanceMode] = (0, import_react2.useState)("config");
1887
+ const [instancePending, setInstancePending] = (0, import_react2.useState)(false);
1888
+ const [instanceError, setInstanceError] = (0, import_react2.useState)(null);
1889
+ const [instanceReturnToDetail, setInstanceReturnToDetail] = (0, import_react2.useState)(false);
1890
+ const [editCard, setEditCard] = (0, import_react2.useState)(null);
1891
+ const [editConfig, setEditConfig] = (0, import_react2.useState)(null);
1892
+ const [editReturnToDetail, setEditReturnToDetail] = (0, import_react2.useState)(false);
1893
+ const dialogCardRef = (0, import_react2.useRef)(null);
1894
+ const installOpRef = (0, import_react2.useRef)(null);
1895
+ const [flowTick, setFlowTick] = (0, import_react2.useState)(0);
1896
+ const [cliConnectors, setCliConnectors] = (0, import_react2.useState)([]);
1897
+ const [cliError, setCliError] = (0, import_react2.useState)(null);
1898
+ const [cliDetailId, setCliDetailId] = (0, import_react2.useState)(null);
1899
+ const [cliInstallId, setCliInstallId] = (0, import_react2.useState)(null);
1900
+ const [cliLoginId, setCliLoginId] = (0, import_react2.useState)(null);
1901
+ const [cliUninstallId, setCliUninstallId] = (0, import_react2.useState)(null);
1902
+ const [cliUpdateId, setCliUpdateId] = (0, import_react2.useState)(null);
1903
+ const [cliUpdateStarted, setCliUpdateStarted] = (0, import_react2.useState)(false);
1904
+ const [cliUpdateError, setCliUpdateError] = (0, import_react2.useState)(null);
1905
+ const [cliUninstallPending, setCliUninstallPending] = (0, import_react2.useState)(false);
1906
+ const [cliUninstallError, setCliUninstallError] = (0, import_react2.useState)(null);
1907
+ const [cliBusyId, setCliBusyId] = (0, import_react2.useState)(null);
1908
+ const [cliTogglePending, setCliTogglePending] = (0, import_react2.useState)(null);
1909
+ const [cliFlow, setCliFlow] = (0, import_react2.useState)(null);
1910
+ const [cliErrorId, setCliErrorId] = (0, import_react2.useState)(null);
1911
+ (0, import_react2.useEffect)(() => {
1304
1912
  dialogCardRef.current = dialogCard;
1305
1913
  }, [dialogCard]);
1306
1914
  const refreshConnections = () => {
@@ -1339,8 +1947,8 @@ function Panel({ startTrial, variant = "panel" }) {
1339
1947
  }
1340
1948
  })();
1341
1949
  };
1342
- (0, import_react.useEffect)(load, []);
1343
- (0, import_react.useEffect)(() => {
1950
+ (0, import_react2.useEffect)(load, []);
1951
+ (0, import_react2.useEffect)(() => {
1344
1952
  const onChange = () => refreshConnections();
1345
1953
  window.addEventListener("dshc:connections-changed", onChange);
1346
1954
  return () => window.removeEventListener("dshc:connections-changed", onChange);
@@ -1356,10 +1964,11 @@ function Panel({ startTrial, variant = "panel" }) {
1356
1964
  }
1357
1965
  })();
1358
1966
  };
1359
- (0, import_react.useEffect)(loadCli, []);
1967
+ (0, import_react2.useEffect)(loadCli, []);
1360
1968
  const cliActive = cliConnectors.some((connector) => connector.phase !== "idle" && connector.phase !== "error");
1361
- const cliWasActiveRef = (0, import_react.useRef)(false);
1362
- (0, import_react.useEffect)(() => {
1969
+ const localizedCliConnectors = (0, import_react2.useMemo)(() => cliConnectors.map(localizedCli), [cliConnectors, localeRevision]);
1970
+ const cliWasActiveRef = (0, import_react2.useRef)(false);
1971
+ (0, import_react2.useEffect)(() => {
1363
1972
  if (cliActive) {
1364
1973
  cliWasActiveRef.current = true;
1365
1974
  const timer2 = window.setInterval(() => {
@@ -1378,7 +1987,7 @@ function Panel({ startTrial, variant = "panel" }) {
1378
1987
  const timer = window.setTimeout(loadCli, 900);
1379
1988
  return () => window.clearTimeout(timer);
1380
1989
  }, [cliActive]);
1381
- (0, import_react.useEffect)(() => {
1990
+ (0, import_react2.useEffect)(() => {
1382
1991
  if (variant !== "overlay") return;
1383
1992
  const onRequest = () => {
1384
1993
  if (cliFlowRequest !== null) {
@@ -1390,9 +1999,9 @@ function Panel({ startTrial, variant = "panel" }) {
1390
1999
  if (cliFlowRequest !== null) onRequest();
1391
2000
  return () => window.removeEventListener("dshc:cli-flow-request", onRequest);
1392
2001
  }, [variant]);
1393
- (0, import_react.useEffect)(() => {
2002
+ (0, import_react2.useEffect)(() => {
1394
2003
  if (variant !== "overlay" || cliFlow === null) return;
1395
- const connector = cliConnectors.find((item) => item.id === cliFlow.id);
2004
+ const connector = localizedCliConnectors.find((item) => item.id === cliFlow.id);
1396
2005
  if (connector === void 0) return;
1397
2006
  const request2 = cliFlow;
1398
2007
  setCliFlow(null);
@@ -1403,7 +2012,7 @@ function Panel({ startTrial, variant = "panel" }) {
1403
2012
  setCliLoginId(connector.id);
1404
2013
  }
1405
2014
  announceCliFlowOpened(connector.id);
1406
- }, [variant, cliFlow, cliConnectors]);
2015
+ }, [variant, cliFlow, localizedCliConnectors]);
1407
2016
  const applyCli = (connector) => {
1408
2017
  setCliConnectors((previous) => {
1409
2018
  const existing = previous.find((item) => item.id === connector.id);
@@ -1451,7 +2060,7 @@ function Panel({ startTrial, variant = "panel" }) {
1451
2060
  })();
1452
2061
  };
1453
2062
  const trialCli = (connector, example) => {
1454
- const prompt = example !== void 0 ? `\u4F7F\u7528${connector.name} CLI\uFF1A${example}` : connector.examples[0] !== void 0 ? `\u4F7F\u7528${connector.name} CLI\uFF1A${connector.examples[0]}` : `\u4F7F\u7528 ${connector.name} CLI \u5B8C\u6210\u4E00\u4E2A\u7B80\u5355\u4EFB\u52A1\uFF0C\u5148\u8BF4\u660E\u53EF\u4EE5\u505A\u4EC0\u4E48\u3002`;
2063
+ const prompt = example !== void 0 ? tr("\u4F7F\u7528{v0} CLI\uFF1A{v1}", { v0: connector.name, v1: example }) : connector.examples[0] !== void 0 ? tr("\u4F7F\u7528{v0} CLI\uFF1A{v1}", { v0: connector.name, v1: connector.examples[0] }) : tr("\u4F7F\u7528 {v0} CLI \u5B8C\u6210\u4E00\u4E2A\u7B80\u5355\u4EFB\u52A1\uFF0C\u5148\u8BF4\u660E\u53EF\u4EE5\u505A\u4EC0\u4E48\u3002", { v0: connector.name });
1455
2064
  try {
1456
2065
  startTrial(prompt);
1457
2066
  } catch (cause) {
@@ -1521,9 +2130,9 @@ function Panel({ startTrial, variant = "panel" }) {
1521
2130
  }
1522
2131
  })();
1523
2132
  };
1524
- (0, import_react.useEffect)(() => {
2133
+ (0, import_react2.useEffect)(() => {
1525
2134
  if (cliUninstallId === null) return;
1526
- const connector = cliConnectors.find((item) => item.id === cliUninstallId);
2135
+ const connector = localizedCliConnectors.find((item) => item.id === cliUninstallId);
1527
2136
  if (connector === void 0) return;
1528
2137
  if (connector.phase === "error" && connector.lastError !== void 0) {
1529
2138
  setCliUninstallError(connector.lastError);
@@ -1533,50 +2142,61 @@ function Panel({ startTrial, variant = "panel" }) {
1533
2142
  setCliUninstallError(null);
1534
2143
  notifyConnectionsChanged();
1535
2144
  }
1536
- }, [cliConnectors, cliUninstallId]);
1537
- const cliDetail = cliConnectors.find((connector) => connector.id === cliDetailId) ?? null;
1538
- const cliInstall = cliConnectors.find((connector) => connector.id === cliInstallId) ?? null;
1539
- const cliLogin = cliConnectors.find((connector) => connector.id === cliLoginId) ?? null;
1540
- const cliUninstall = cliConnectors.find((connector) => connector.id === cliUninstallId) ?? null;
1541
- const cliUpdate = cliConnectors.find((connector) => connector.id === cliUpdateId) ?? null;
1542
- const cliErrorConnector = cliConnectors.find((connector) => connector.id === cliErrorId) ?? null;
1543
- const categories = (0, import_react.useMemo)(() => {
2145
+ }, [localizedCliConnectors, cliUninstallId]);
2146
+ const cliDetail = localizedCliConnectors.find((connector) => connector.id === cliDetailId) ?? null;
2147
+ const cliInstall = localizedCliConnectors.find((connector) => connector.id === cliInstallId) ?? null;
2148
+ const cliLogin = localizedCliConnectors.find((connector) => connector.id === cliLoginId) ?? null;
2149
+ const cliUninstall = localizedCliConnectors.find((connector) => connector.id === cliUninstallId) ?? null;
2150
+ const cliUpdate = localizedCliConnectors.find((connector) => connector.id === cliUpdateId) ?? null;
2151
+ const cliErrorConnector = localizedCliConnectors.find((connector) => connector.id === cliErrorId) ?? null;
2152
+ const localizedCards = (0, import_react2.useMemo)(() => cards.map(localizedCard), [cards, localeRevision]);
2153
+ const categoryLabels = (0, import_react2.useMemo)(() => {
2154
+ const labels = /* @__PURE__ */ new Map();
2155
+ for (const card of localizedCards) {
2156
+ if (!labels.has(card.category)) labels.set(card.category, card.categoryLabel ?? tr(card.category));
2157
+ }
2158
+ for (const connector of localizedCliConnectors) {
2159
+ if (!labels.has(connector.category)) labels.set(connector.category, tr(connector.category));
2160
+ }
2161
+ return labels;
2162
+ }, [localizedCards, localizedCliConnectors]);
2163
+ const categories = (0, import_react2.useMemo)(() => {
1544
2164
  const present = /* @__PURE__ */ new Set([
1545
- ...cards.map((card) => card.category),
2165
+ ...localizedCards.map((card) => card.category),
1546
2166
  ...cliConnectors.map((connector) => connector.category)
1547
2167
  ]);
1548
2168
  const builtinSet = new Set(BUILTIN_CATEGORIES);
1549
2169
  const builtin = BUILTIN_CATEGORIES.filter((category2) => present.has(category2));
1550
2170
  const custom = [...present].filter((category2) => !builtinSet.has(category2)).sort((left, right) => left.localeCompare(right, "zh-CN"));
1551
2171
  return ["\u5168\u90E8", ...builtin, ...custom];
1552
- }, [cards, cliConnectors]);
1553
- const categoryOptions = (0, import_react.useMemo)(() => {
2172
+ }, [localizedCards, cliConnectors]);
2173
+ const categoryOptions = (0, import_react2.useMemo)(() => {
1554
2174
  const builtinSet = new Set(BUILTIN_CATEGORIES);
1555
2175
  const custom = [...new Set(
1556
- cards.map((card) => card.category).filter((category2) => !builtinSet.has(category2))
2176
+ localizedCards.map((card) => card.category).filter((category2) => !builtinSet.has(category2))
1557
2177
  )].sort((left, right) => left.localeCompare(right, "zh-CN"));
1558
2178
  return [...BUILTIN_CATEGORIES, ...custom];
1559
- }, [cards]);
1560
- (0, import_react.useEffect)(() => {
2179
+ }, [localizedCards]);
2180
+ (0, import_react2.useEffect)(() => {
1561
2181
  if (!categories.includes(category)) setCategory("\u5168\u90E8");
1562
2182
  }, [categories, category]);
1563
- const visible = (0, import_react.useMemo)(() => {
2183
+ const visible = (0, import_react2.useMemo)(() => {
1564
2184
  const keyword = query.trim().toLowerCase();
1565
- return cards.filter((card) => {
2185
+ return localizedCards.filter((card) => {
1566
2186
  if (category !== "\u5168\u90E8" && card.category !== category) return false;
1567
2187
  if (keyword.length === 0) return true;
1568
2188
  return `${card.name} ${card.vendor ?? ""} ${card.summary} ${(card.tags ?? []).join(" ")}`.toLowerCase().includes(keyword);
1569
2189
  });
1570
- }, [cards, category, query]);
1571
- const visibleCli = (0, import_react.useMemo)(() => {
2190
+ }, [localizedCards, category, query]);
2191
+ const visibleCli = (0, import_react2.useMemo)(() => {
1572
2192
  const keyword = query.trim().toLowerCase();
1573
- return cliConnectors.filter((connector) => {
2193
+ return localizedCliConnectors.filter((connector) => {
1574
2194
  if (category !== "\u5168\u90E8" && connector.category !== category) return false;
1575
2195
  if (keyword.length === 0) return true;
1576
2196
  return `${connector.name} ${connector.vendor} ${connector.description} ${connector.examples.join(" ")}`.toLowerCase().includes(keyword);
1577
2197
  });
1578
- }, [category, cliConnectors, query]);
1579
- const gridEntries = (0, import_react.useMemo)(() => {
2198
+ }, [category, localizedCliConnectors, query]);
2199
+ const gridEntries = (0, import_react2.useMemo)(() => {
1580
2200
  const rank = new Map(BUILTIN_CATEGORIES.map((category2, index) => [category2, index]));
1581
2201
  const categoryRank = (category2) => rank.get(category2) ?? BUILTIN_CATEGORIES.length;
1582
2202
  const items = [
@@ -1606,7 +2226,7 @@ function Panel({ startTrial, variant = "panel" }) {
1606
2226
  body: JSON.stringify({ connectorId: card.id, token })
1607
2227
  }));
1608
2228
  const connection = response.value?.connection;
1609
- if (connection === void 0) throw new ApiError("invalid_response", "\u4FDD\u5B58\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5");
2229
+ if (connection === void 0) throw new ApiError("invalid_response", tr("\u4FDD\u5B58\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5"));
1610
2230
  applyConnection(connection);
1611
2231
  if (connection.authorized && connection.error === void 0 && connection.tools.length === 0) refreshSoon();
1612
2232
  setCredentialCard((current) => current !== null && current.id === card.id ? null : current);
@@ -1715,7 +2335,7 @@ function Panel({ startTrial, variant = "panel" }) {
1715
2335
  body: JSON.stringify({ connectorId: card.id })
1716
2336
  }));
1717
2337
  const connection = response.value?.connection;
1718
- if (connection === void 0) throw new ApiError("invalid_response", "\u5B89\u88C5\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5");
2338
+ if (connection === void 0) throw new ApiError("invalid_response", tr("\u5B89\u88C5\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5"));
1719
2339
  return connection;
1720
2340
  };
1721
2341
  const installRecord = (card, surface) => {
@@ -1767,7 +2387,7 @@ function Panel({ startTrial, variant = "panel" }) {
1767
2387
  setDialogInstall(false);
1768
2388
  }
1769
2389
  if (connection === void 0) {
1770
- throw new ApiError("not_installed", "\u8BF7\u5148\u5B89\u88C5\u8FDE\u63A5\u5668\uFF0C\u518D\u53D1\u8D77\u6388\u6743");
2390
+ throw new ApiError("not_installed", tr("\u8BF7\u5148\u5B89\u88C5\u8FDE\u63A5\u5668\uFF0C\u518D\u53D1\u8D77\u6388\u6743"));
1771
2391
  }
1772
2392
  if (force || !connection.authorized) {
1773
2393
  window.dispatchEvent(new CustomEvent("dshc:flow-authorizing", { detail: { cardId: card.id } }));
@@ -1823,7 +2443,7 @@ function Panel({ startTrial, variant = "panel" }) {
1823
2443
  { method: "POST", body: JSON.stringify({ instanceUrl }) }
1824
2444
  ));
1825
2445
  const connection = response.value?.connection;
1826
- if (connection === void 0) throw new ApiError("invalid_response", "\u4FDD\u5B58\u5730\u5740\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5");
2446
+ if (connection === void 0) throw new ApiError("invalid_response", tr("\u4FDD\u5B58\u5730\u5740\u5931\u8D25\uFF1A\u5BBF\u4E3B\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5"));
1827
2447
  applyConnection(connection);
1828
2448
  setInstanceCard(null);
1829
2449
  setDialogError(null);
@@ -1939,21 +2559,21 @@ function Panel({ startTrial, variant = "panel" }) {
1939
2559
  openDialog(card, false);
1940
2560
  announceConnectorFlow(card.id);
1941
2561
  };
1942
- (0, import_react.useEffect)(() => {
2562
+ (0, import_react2.useEffect)(() => {
1943
2563
  if (variant !== "overlay") return;
1944
2564
  const onRequest = () => setFlowTick((current) => current + 1);
1945
2565
  window.addEventListener("dshc:flow-request", onRequest);
1946
2566
  if (flowRequest !== null) onRequest();
1947
2567
  return () => window.removeEventListener("dshc:flow-request", onRequest);
1948
2568
  }, [variant]);
1949
- (0, import_react.useEffect)(() => {
2569
+ (0, import_react2.useEffect)(() => {
1950
2570
  if (variant !== "overlay" || flowRequest === null || loading) return;
1951
2571
  const cardId = flowRequest;
1952
- const card = cards.find((item) => item.id === cardId);
2572
+ const card = localizedCards.find((item) => item.id === cardId);
1953
2573
  flowRequest = null;
1954
2574
  if (card !== void 0) openFlow(card);
1955
- }, [variant, flowTick, loading, cards, connections]);
1956
- (0, import_react.useEffect)(() => {
2575
+ }, [variant, flowTick, loading, localizedCards, connections]);
2576
+ (0, import_react2.useEffect)(() => {
1957
2577
  if (variant !== "overlay") return;
1958
2578
  const onCancel = (event) => {
1959
2579
  const cardId = event.detail?.cardId;
@@ -1968,7 +2588,7 @@ function Panel({ startTrial, variant = "panel" }) {
1968
2588
  window.addEventListener("dshc:flow-cancel", onCancel);
1969
2589
  return () => window.removeEventListener("dshc:flow-cancel", onCancel);
1970
2590
  }, [variant, oauthStarting, oauthFlow]);
1971
- (0, import_react.useEffect)(() => {
2591
+ (0, import_react2.useEffect)(() => {
1972
2592
  if (variant !== "panel") return;
1973
2593
  const onRequest = () => {
1974
2594
  setDialogCard(null);
@@ -2250,10 +2870,10 @@ function Panel({ startTrial, variant = "panel" }) {
2250
2870
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: variant === "overlay" ? "dshc-root dshc-flow-root" : "dshc-root", children: [
2251
2871
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-inner", children: [
2252
2872
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("header", { className: "dshc-header", children: [
2253
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { children: "\u8FDE\u63A5\u5668" }),
2873
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { children: tr("\u8FDE\u63A5\u5668") }),
2254
2874
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-btn dshc-btn-primary dshc-create", onClick: () => setCustomOpen(true), children: [
2255
2875
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconPlus, { size: 13 }),
2256
- "\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668"
2876
+ tr("\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668")
2257
2877
  ] })
2258
2878
  ] }),
2259
2879
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -2273,7 +2893,7 @@ function Panel({ startTrial, variant = "panel" }) {
2273
2893
  type: "button",
2274
2894
  className: item === category ? "dshc-tab dshc-tab-active" : "dshc-tab",
2275
2895
  onClick: () => setCategory(item),
2276
- children: item
2896
+ children: categoryLabels.get(item) ?? tr(item)
2277
2897
  },
2278
2898
  item
2279
2899
  ))
@@ -2290,7 +2910,7 @@ function Panel({ startTrial, variant = "panel" }) {
2290
2910
  "data-lpignore": "true",
2291
2911
  "data-1p-ignore": "true",
2292
2912
  "data-bwignore": "true",
2293
- placeholder: "\u641C\u7D22\u8FDE\u63A5\u5668",
2913
+ placeholder: tr("\u641C\u7D22\u8FDE\u63A5\u5668"),
2294
2914
  value: query,
2295
2915
  onChange: (event) => setQuery(event.target.value)
2296
2916
  }
@@ -2300,8 +2920,8 @@ function Panel({ startTrial, variant = "panel" }) {
2300
2920
  {
2301
2921
  type: "button",
2302
2922
  className: "dshc-search-clear",
2303
- "aria-label": "\u6E05\u7A7A\u641C\u7D22",
2304
- title: "\u6E05\u7A7A\u641C\u7D22",
2923
+ "aria-label": tr("\u6E05\u7A7A\u641C\u7D22"),
2924
+ title: tr("\u6E05\u7A7A\u641C\u7D22"),
2305
2925
  onMouseDown: (event) => event.preventDefault(),
2306
2926
  onClick: () => {
2307
2927
  setQuery("");
@@ -2312,7 +2932,7 @@ function Panel({ startTrial, variant = "panel" }) {
2312
2932
  )
2313
2933
  ] }),
2314
2934
  error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-error", children: error }),
2315
- visible.length === 0 && visibleCli.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-empty", children: loading ? "\u6B63\u5728\u52A0\u8F7D\u8FDE\u63A5\u5668\u2026" : "\u6CA1\u6709\u5339\u914D\u7684\u8FDE\u63A5\u5668" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-grid", children: gridEntries.map((entry) => entry.kind === "mcp" ? renderCard(entry.card) : renderCli(entry.connector)) })
2935
+ visible.length === 0 && visibleCli.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-empty", children: loading ? tr("\u6B63\u5728\u52A0\u8F7D\u8FDE\u63A5\u5668\u2026") : tr("\u6CA1\u6709\u5339\u914D\u7684\u8FDE\u63A5\u5668") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-grid", children: gridEntries.map((entry) => entry.kind === "mcp" ? renderCard(entry.card) : renderCli(entry.connector)) })
2316
2936
  ] }),
2317
2937
  dialogCard !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2318
2938
  ConnectorDialog,
@@ -2524,24 +3144,24 @@ function Panel({ startTrial, variant = "panel" }) {
2524
3144
  ] });
2525
3145
  }
2526
3146
  function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onLogin, onLogout, onOpenInstall, onOpenLogin, onToggle, onTrial, onOpenError, onCancel, onUninstall, onOpenUninstall, onUpdate, onOpenUpdate }) {
2527
- const [menuOpen, setMenuOpen] = (0, import_react.useState)(false);
2528
- const [menuAbove, setMenuAbove] = (0, import_react.useState)(false);
2529
- const [tip, setTip] = (0, import_react.useState)(null);
2530
- const menuRef = (0, import_react.useRef)(null);
3147
+ const [menuOpen, setMenuOpen] = (0, import_react2.useState)(false);
3148
+ const [menuAbove, setMenuAbove] = (0, import_react2.useState)(false);
3149
+ const [tip, setTip] = (0, import_react2.useState)(null);
3150
+ const menuRef = (0, import_react2.useRef)(null);
2531
3151
  const busy = pending || connector.phase === "installing" || connector.phase === "updating" || connector.phase === "configuring" || connector.phase === "logging_in" || connector.phase === "uninstalling";
2532
3152
  const enabled = connector.enabled !== false;
2533
3153
  const connected = connector.installed && connector.authenticated;
2534
3154
  const canTry = connected && enabled && connector.skills.installed && !busy;
2535
3155
  const error = !busy && connector.phase === "error" && connector.lastError !== void 0 ? connector.lastError : void 0;
2536
- const busyLabel = connector.phase === "installing" ? "\u5B89\u88C5\u4E2D\u2026" : connector.phase === "updating" ? "\u66F4\u65B0\u4E2D\u2026" : connector.phase === "uninstalling" ? "\u5378\u8F7D\u4E2D\u2026" : connector.phase === "configuring" ? "\u914D\u7F6E\u4E2D\u2026" : "\u767B\u5F55\u4E2D\u2026";
2537
- const busyProgress = connector.phase === "installing" ? "\u5B89\u88C5\u8FDB\u5EA6" : connector.phase === "updating" ? "\u66F4\u65B0\u8FDB\u5EA6" : connector.phase === "uninstalling" ? "\u5378\u8F7D\u8FDB\u5EA6" : "\u767B\u5F55\u8FDB\u5EA6";
2538
- const stateLabel = busy ? "\uFF0C\u5904\u7406\u4E2D" : !connector.installed ? "\uFF0C\u672A\u5B89\u88C5" : !connector.authenticated ? "\uFF0C\u5DF2\u5B89\u88C5\u672A\u767B\u5F55" : enabled ? "\uFF0C\u5DF2\u767B\u5F55" : "\uFF0C\u5DF2\u505C\u7528";
3156
+ const busyLabel = connector.phase === "installing" ? tr("\u5B89\u88C5\u4E2D\u2026") : connector.phase === "updating" ? tr("\u66F4\u65B0\u4E2D\u2026") : connector.phase === "uninstalling" ? tr("\u5378\u8F7D\u4E2D\u2026") : connector.phase === "configuring" ? tr("\u914D\u7F6E\u4E2D\u2026") : tr("\u767B\u5F55\u4E2D\u2026");
3157
+ const busyProgress = connector.phase === "installing" ? tr("\u5B89\u88C5\u8FDB\u5EA6") : connector.phase === "updating" ? tr("\u66F4\u65B0\u8FDB\u5EA6") : connector.phase === "uninstalling" ? tr("\u5378\u8F7D\u8FDB\u5EA6") : tr("\u767B\u5F55\u8FDB\u5EA6");
3158
+ const stateLabel = busy ? tr("\uFF0C\u5904\u7406\u4E2D") : !connector.installed ? tr("\uFF0C\u672A\u5B89\u88C5") : !connector.authenticated ? tr("\uFF0C\u5DF2\u5B89\u88C5\u672A\u767B\u5F55") : enabled ? tr("\uFF0C\u5DF2\u767B\u5F55") : tr("\uFF0C\u5DF2\u505C\u7528");
2539
3159
  const toggleMenu = (button) => {
2540
3160
  const rect = button.getBoundingClientRect();
2541
3161
  setMenuAbove(rect.bottom + 170 > window.innerHeight);
2542
3162
  setMenuOpen((current) => !current);
2543
3163
  };
2544
- (0, import_react.useEffect)(() => {
3164
+ (0, import_react2.useEffect)(() => {
2545
3165
  if (!menuOpen) return;
2546
3166
  const onPointerDown = (event) => {
2547
3167
  if (menuRef.current !== null && !menuRef.current.contains(event.target)) setMenuOpen(false);
@@ -2556,7 +3176,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2556
3176
  window.removeEventListener("keydown", onKeyDown);
2557
3177
  };
2558
3178
  }, [menuOpen]);
2559
- (0, import_react.useEffect)(() => {
3179
+ (0, import_react2.useEffect)(() => {
2560
3180
  if (tip === null) return;
2561
3181
  const close = () => setTip(null);
2562
3182
  window.addEventListener("pointerdown", close, true);
@@ -2577,7 +3197,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2577
3197
  className: menuOpen ? "dshc-card dshc-card-menu-open" : "dshc-card",
2578
3198
  role: "button",
2579
3199
  tabIndex: 0,
2580
- "aria-label": `\u67E5\u770B ${connector.name}${stateLabel}`,
3200
+ "aria-label": tr("\u67E5\u770B {v0}{v1}", { v0: connector.name, v1: stateLabel }),
2581
3201
  onClick: () => {
2582
3202
  if (menuOpen) {
2583
3203
  setMenuOpen(false);
@@ -2614,15 +3234,15 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2614
3234
  }
2615
3235
  ),
2616
3236
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-card-foot", children: [
2617
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-badge", children: connector.category }),
3237
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-badge", children: tr(connector.category) }),
2618
3238
  !connector.installed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-install-actions", children: [
2619
3239
  error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2620
3240
  "button",
2621
3241
  {
2622
3242
  type: "button",
2623
3243
  className: "dshc-card-action dshc-card-action-error dshc-card-status",
2624
- title: "\u67E5\u770B\u9519\u8BEF\u65E5\u5FD7",
2625
- "aria-label": `\u67E5\u770B ${connector.name} \u9519\u8BEF\u65E5\u5FD7`,
3244
+ title: tr("\u67E5\u770B\u9519\u8BEF\u65E5\u5FD7"),
3245
+ "aria-label": tr("\u67E5\u770B {v0} \u9519\u8BEF\u65E5\u5FD7", { v0: connector.name }),
2626
3246
  onClick: (event) => {
2627
3247
  event.stopPropagation();
2628
3248
  onOpenError();
@@ -2635,8 +3255,8 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2635
3255
  {
2636
3256
  type: "button",
2637
3257
  className: busy ? "dshc-card-action dshc-card-action-connect dshc-card-action-loading" : "dshc-card-action dshc-card-action-connect",
2638
- title: "\u5B89\u88C5",
2639
- "aria-label": `\u5B89\u88C5 ${connector.name} CLI`,
3258
+ title: tr("\u5B89\u88C5"),
3259
+ "aria-label": tr("\u5B89\u88C5 {v0} CLI", { v0: connector.name }),
2640
3260
  onClick: (event) => {
2641
3261
  event.stopPropagation();
2642
3262
  if (busy) onOpenInstall();
@@ -2651,7 +3271,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2651
3271
  {
2652
3272
  type: "button",
2653
3273
  className: "dshc-card-auth",
2654
- "aria-label": busy ? `\u67E5\u770B ${connector.name} ${busyProgress}` : `\u767B\u5F55 ${connector.name}`,
3274
+ "aria-label": busy ? tr("\u67E5\u770B {v0} {v1}", { v0: connector.name, v1: busyProgress }) : tr("\u767B\u5F55 {v0}", { v0: connector.name }),
2655
3275
  title: busy ? connector.stage ?? busyLabel : void 0,
2656
3276
  onClick: (event) => {
2657
3277
  event.stopPropagation();
@@ -2662,7 +3282,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2662
3282
  },
2663
3283
  children: [
2664
3284
  busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
2665
- busy ? busyLabel : "\u767B\u5F55"
3285
+ busy ? busyLabel : tr("\u767B\u5F55")
2666
3286
  ]
2667
3287
  }
2668
3288
  ),
@@ -2671,22 +3291,22 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2671
3291
  {
2672
3292
  type: "button",
2673
3293
  className: "dshc-card-action dshc-card-action-error dshc-card-status",
2674
- title: "\u67E5\u770B\u9519\u8BEF\u65E5\u5FD7",
2675
- "aria-label": `\u67E5\u770B ${connector.name} \u9519\u8BEF\u65E5\u5FD7`,
3294
+ title: tr("\u67E5\u770B\u9519\u8BEF\u65E5\u5FD7"),
3295
+ "aria-label": tr("\u67E5\u770B {v0} \u9519\u8BEF\u65E5\u5FD7", { v0: connector.name }),
2676
3296
  onClick: (event) => {
2677
3297
  event.stopPropagation();
2678
3298
  onOpenError();
2679
3299
  },
2680
3300
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconAlert, { size: 16 })
2681
3301
  }
2682
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-card-installed", title: "CLI \u5DF2\u5B89\u88C5", "aria-label": "CLI \u5DF2\u5B89\u88C5", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 14 }) })),
3302
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-card-installed", title: tr("CLI \u5DF2\u5B89\u88C5"), "aria-label": tr("CLI \u5DF2\u5B89\u88C5"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 14 }) })),
2683
3303
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-more-wrap", ref: menuRef, children: [
2684
3304
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2685
3305
  "button",
2686
3306
  {
2687
3307
  type: "button",
2688
3308
  className: "dshc-card-more",
2689
- "aria-label": `${connector.name} \u66F4\u591A\u64CD\u4F5C`,
3309
+ "aria-label": tr("{v0} \u66F4\u591A\u64CD\u4F5C", { v0: connector.name }),
2690
3310
  "aria-haspopup": "menu",
2691
3311
  "aria-expanded": menuOpen,
2692
3312
  onClick: (event) => {
@@ -2708,7 +3328,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2708
3328
  },
2709
3329
  children: [
2710
3330
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 14 }),
2711
- connector.phase === "uninstalling" ? "\u53D6\u6D88\u5378\u8F7D" : connector.phase === "updating" ? "\u53D6\u6D88\u66F4\u65B0" : "\u53D6\u6D88\u767B\u5F55"
3331
+ connector.phase === "uninstalling" ? tr("\u53D6\u6D88\u5378\u8F7D") : connector.phase === "updating" ? tr("\u53D6\u6D88\u66F4\u65B0") : tr("\u53D6\u6D88\u767B\u5F55")
2712
3332
  ]
2713
3333
  }
2714
3334
  ) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
@@ -2724,7 +3344,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2724
3344
  },
2725
3345
  children: [
2726
3346
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconRefresh, { size: 14 }),
2727
- "\u66F4\u65B0 CLI"
3347
+ tr("\u66F4\u65B0 CLI")
2728
3348
  ]
2729
3349
  }
2730
3350
  ),
@@ -2740,7 +3360,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2740
3360
  },
2741
3361
  children: [
2742
3362
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconTrash, { size: 14 }),
2743
- "\u5378\u8F7D CLI"
3363
+ tr("\u5378\u8F7D CLI")
2744
3364
  ]
2745
3365
  }
2746
3366
  )
@@ -2753,7 +3373,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2753
3373
  type: "button",
2754
3374
  className: "dshc-card-auth",
2755
3375
  title: connector.stage ?? busyLabel,
2756
- "aria-label": `\u67E5\u770B ${connector.name} ${busyProgress}`,
3376
+ "aria-label": tr("\u67E5\u770B {v0} {v1}", { v0: connector.name, v1: busyProgress }),
2757
3377
  onClick: (event) => {
2758
3378
  event.stopPropagation();
2759
3379
  if (connector.phase === "installing") onOpenInstall();
@@ -2771,15 +3391,15 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2771
3391
  {
2772
3392
  type: "button",
2773
3393
  className: `${actionClass} dshc-card-status`,
2774
- title: "\u67E5\u770B\u9519\u8BEF\u65E5\u5FD7",
2775
- "aria-label": `\u67E5\u770B ${connector.name} \u9519\u8BEF\u65E5\u5FD7`,
3394
+ title: tr("\u67E5\u770B\u9519\u8BEF\u65E5\u5FD7"),
3395
+ "aria-label": tr("\u67E5\u770B {v0} \u9519\u8BEF\u65E5\u5FD7", { v0: connector.name }),
2776
3396
  onClick: (event) => {
2777
3397
  event.stopPropagation();
2778
3398
  onOpenError();
2779
3399
  },
2780
3400
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconAlert, { size: 16 })
2781
3401
  }
2782
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${actionClass} dshc-card-status`, title: enabled ? "\u5DF2\u542F\u7528" : "\u5DF2\u505C\u7528", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 16 }) }),
3402
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${actionClass} dshc-card-status`, title: enabled ? tr("\u5DF2\u542F\u7528") : tr("\u5DF2\u505C\u7528"), "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 16 }) }),
2783
3403
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-controls", children: [
2784
3404
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-more-wrap", ref: menuRef, children: [
2785
3405
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -2787,7 +3407,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2787
3407
  {
2788
3408
  type: "button",
2789
3409
  className: "dshc-card-more",
2790
- "aria-label": `${connector.name} \u66F4\u591A\u64CD\u4F5C`,
3410
+ "aria-label": tr("{v0} \u66F4\u591A\u64CD\u4F5C", { v0: connector.name }),
2791
3411
  "aria-haspopup": "menu",
2792
3412
  "aria-expanded": menuOpen,
2793
3413
  onClick: (event) => {
@@ -2809,7 +3429,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2809
3429
  },
2810
3430
  children: [
2811
3431
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 14 }),
2812
- connector.phase === "installing" ? "\u53D6\u6D88\u5B89\u88C5" : connector.phase === "updating" ? "\u53D6\u6D88\u66F4\u65B0" : connector.phase === "uninstalling" ? "\u53D6\u6D88\u5378\u8F7D" : "\u53D6\u6D88\u767B\u5F55"
3432
+ connector.phase === "installing" ? tr("\u53D6\u6D88\u5B89\u88C5") : connector.phase === "updating" ? tr("\u53D6\u6D88\u66F4\u65B0") : connector.phase === "uninstalling" ? tr("\u53D6\u6D88\u5378\u8F7D") : tr("\u53D6\u6D88\u767B\u5F55")
2813
3433
  ]
2814
3434
  }
2815
3435
  ) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
@@ -2826,7 +3446,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2826
3446
  },
2827
3447
  children: [
2828
3448
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconPlay, { size: 14 }),
2829
- "\u53BB\u8BD5\u8BD5"
3449
+ tr("\u53BB\u8BD5\u8BD5")
2830
3450
  ]
2831
3451
  }
2832
3452
  ),
@@ -2842,7 +3462,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2842
3462
  },
2843
3463
  children: [
2844
3464
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconRefresh, { size: 14 }),
2845
- "\u91CD\u65B0\u767B\u5F55"
3465
+ tr("\u91CD\u65B0\u767B\u5F55")
2846
3466
  ]
2847
3467
  }
2848
3468
  ),
@@ -2858,7 +3478,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2858
3478
  },
2859
3479
  children: [
2860
3480
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconPlug, { size: 14 }),
2861
- "\u89E3\u7ED1"
3481
+ tr("\u89E3\u7ED1")
2862
3482
  ]
2863
3483
  }
2864
3484
  ),
@@ -2874,7 +3494,7 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2874
3494
  },
2875
3495
  children: [
2876
3496
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconRefresh, { size: 14 }),
2877
- "\u66F4\u65B0 CLI"
3497
+ tr("\u66F4\u65B0 CLI")
2878
3498
  ]
2879
3499
  }
2880
3500
  ),
@@ -2890,20 +3510,20 @@ function CliCardView({ connector, togglePending, pending, onOpen, onInstall, onL
2890
3510
  },
2891
3511
  children: [
2892
3512
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconTrash, { size: 14 }),
2893
- "\u5378\u8F7D CLI"
3513
+ tr("\u5378\u8F7D CLI")
2894
3514
  ]
2895
3515
  }
2896
3516
  )
2897
3517
  ] }) })
2898
3518
  ] }),
2899
- togglePending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-card-toggle", role: "status", "aria-label": "\u5904\u7406\u4E2D", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) }) : busy ? null : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3519
+ togglePending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-card-toggle", role: "status", "aria-label": tr("\u5904\u7406\u4E2D"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) }) : busy ? null : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2900
3520
  "button",
2901
3521
  {
2902
3522
  type: "button",
2903
3523
  role: "switch",
2904
3524
  "aria-checked": enabled,
2905
- "aria-label": enabled ? `\u505C\u7528 ${connector.name}` : `\u542F\u7528 ${connector.name}`,
2906
- title: enabled ? "\u505C\u7528" : "\u542F\u7528",
3525
+ "aria-label": enabled ? tr("\u505C\u7528 {v0}", { v0: connector.name }) : tr("\u542F\u7528 {v0}", { v0: connector.name }),
3526
+ title: enabled ? tr("\u505C\u7528") : tr("\u542F\u7528"),
2907
3527
  className: "dshc-switch",
2908
3528
  onClick: (event) => {
2909
3529
  event.stopPropagation();
@@ -2934,67 +3554,70 @@ function CliInstallDialog({ connector, pending, onClose, onConfirm, onCancel })
2934
3554
  onMouseDown: (event) => {
2935
3555
  if (event.target === event.currentTarget) onClose();
2936
3556
  },
2937
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog dshc-dialog-detail", role: "dialog", "aria-modal": "true", "aria-label": `\u5B89\u88C5 ${connector.name} CLI`, children: [
3557
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog dshc-dialog-detail", role: "dialog", "aria-modal": "true", "aria-label": tr("\u5B89\u88C5 {v0} CLI", { v0: connector.name }), children: [
2938
3558
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head", children: [
2939
3559
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-avatar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CliLogo, { connector, size: 28 }) }),
2940
3560
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-title", children: [
2941
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: done ? "\u5B89\u88C5\u5B8C\u6210" : `\u5B89\u88C5 ${connector.name} CLI` }),
3561
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: done ? tr("\u5B89\u88C5\u5B8C\u6210") : tr("\u5B89\u88C5 {v0} CLI", { v0: connector.name }) }),
2942
3562
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.vendor })
2943
3563
  ] }),
2944
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3564
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
2945
3565
  ] }),
2946
3566
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-content", children: busy ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2947
3567
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-cli-wait", children: [
2948
3568
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
2949
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.stage ?? "\u5B89\u88C5\u4E2D\u2026" })
3569
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.stage ?? tr("\u5B89\u88C5\u4E2D\u2026") })
2950
3570
  ] }),
2951
3571
  connector.output !== void 0 && connector.output.trim() !== "" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("details", { className: "dshc-cli-output", open: true, children: [
2952
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("summary", { children: "\u5B89\u88C5\u8F93\u51FA" }),
3572
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("summary", { children: tr("\u5B89\u88C5\u8F93\u51FA") }),
2953
3573
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { children: connector.output.slice(-4e3) })
2954
3574
  ] })
2955
3575
  ] }) : done ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2956
3576
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
2957
- "CLI \u5DF2\u5B89\u88C5",
3577
+ tr("CLI \u5DF2\u5B89\u88C5"),
2958
3578
  connector.version === void 0 ? "" : ` \xB7 v${connector.version}`,
2959
- "\u3002\u767B\u5F55\u8BF7\u56DE\u5230\u5361\u7247\u70B9\u51FB\u300C\u767B\u5F55\u300D\u3002"
3579
+ tr("\u3002\u767B\u5F55\u8BF7\u56DE\u5230\u5361\u7247\u70B9\u51FB\u300C\u767B\u5F55\u300D\u3002")
2960
3580
  ] }),
2961
3581
  connector.skills.installed && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
2962
- "\u5DF2\u53D1\u73B0 ",
3582
+ tr("\u5DF2\u53D1\u73B0"),
3583
+ " ",
2963
3584
  connector.skills.count,
2964
- " \u4E2A Skills\u3002"
3585
+ " ",
3586
+ tr("\u4E2A Skills\u3002")
2965
3587
  ] })
2966
3588
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2967
3589
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
2968
- "\u5C06\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u5B89\u88C5\u5B98\u65B9 CLI \u4E0E Skills\u3002\u4F1A\u5199\u5165\u672C\u673A npm \u5168\u5C40\u76EE\u5F55\u548C ",
3590
+ tr("\u5C06\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u5B89\u88C5\u5B98\u65B9 CLI \u4E0E Skills\u3002\u4F1A\u5199\u5165\u672C\u673A npm \u5168\u5C40\u76EE\u5F55\u548C"),
3591
+ " ",
2969
3592
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: "~/.agents/skills" }),
2970
- "\uFF0C\u5F71\u54CD\u672C\u673A\u5176\u4ED6 Agent\u3002"
3593
+ tr("\uFF0C\u5F71\u54CD\u672C\u673A\u5176\u4ED6 Agent\u3002")
2971
3594
  ] }),
2972
3595
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { className: "dshc-cli-commands", children: connector.installHint.join("\n") }),
2973
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "dshc-link", href: connector.docsUrl, target: "_blank", rel: "noreferrer", children: "\u67E5\u770B\u5B98\u65B9\u5B89\u88C5\u6587\u6863" }) }),
3596
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "dshc-link", href: connector.docsUrl, target: "_blank", rel: "noreferrer", children: tr("\u67E5\u770B\u5B98\u65B9\u5B89\u88C5\u6587\u6863") }) }),
2974
3597
  failed && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: connector.lastError })
2975
3598
  ] }) }),
2976
3599
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: busy ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2977
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onCancel, children: "\u53D6\u6D88\u5B89\u88C5" }),
2978
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: "\u5173\u95ED" })
2979
- ] }) : done ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onClose, children: "\u5173\u95ED" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2980
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: "\u53D6\u6D88" }),
2981
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onConfirm, children: failed ? "\u91CD\u8BD5" : "\u5B89\u88C5" })
3600
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onCancel, children: tr("\u53D6\u6D88\u5B89\u88C5") }),
3601
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: tr("\u5173\u95ED") })
3602
+ ] }) : done ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onClose, children: tr("\u5173\u95ED") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3603
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: tr("\u53D6\u6D88") }),
3604
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onConfirm, children: failed ? tr("\u91CD\u8BD5") : tr("\u5B89\u88C5") })
2982
3605
  ] }) }) })
2983
3606
  ] })
2984
3607
  }
2985
3608
  );
2986
3609
  }
2987
3610
  function CliLoginDialog({ connector, onCancel, onClose }) {
2988
- const [copied, setCopied] = (0, import_react.useState)(null);
2989
- const [copyFailed, setCopyFailed] = (0, import_react.useState)(null);
3611
+ const [copied, setCopied] = (0, import_react2.useState)(null);
3612
+ const [copyFailed, setCopyFailed] = (0, import_react2.useState)(null);
2990
3613
  const busy = connector.phase === "configuring" || connector.phase === "logging_in";
2991
3614
  const failed = connector.phase === "error";
2992
3615
  const success = connector.authenticated && !busy;
2993
3616
  const link = connector.link;
2994
- const statusText = busy ? connector.stage === "\u914D\u7F6E\u5E94\u7528" ? "\u914D\u7F6E\u5E94\u7528\u4E2D" : "\u7B49\u5F85\u6388\u6743" : success ? "\u5DF2\u767B\u5F55" : failed ? "\u767B\u5F55\u5931\u8D25" : "\u672A\u767B\u5F55";
3617
+ const statusText = busy ? connector.stage === "\u914D\u7F6E\u5E94\u7528" ? tr("\u914D\u7F6E\u5E94\u7528\u4E2D") : tr("\u7B49\u5F85\u6388\u6743") : success ? tr("\u5DF2\u767B\u5F55") : failed ? tr("\u767B\u5F55\u5931\u8D25") : tr("\u672A\u767B\u5F55");
2995
3618
  const statusClass = success ? "dshc-status-pill dshc-status-pill-connected" : failed ? "dshc-status-pill dshc-status-pill-error" : "dshc-status-pill";
2996
3619
  const accountLabel = connector.account?.name ?? connector.account?.email;
2997
- const statusLabel = success && accountLabel !== void 0 ? `\u5DF2\u767B\u5F55 \xB7 ${accountLabel}` : statusText;
3620
+ const statusLabel = success && accountLabel !== void 0 ? tr("\u5DF2\u767B\u5F55 \xB7 {v0}", { v0: accountLabel }) : statusText;
2998
3621
  const copy = (value, key) => {
2999
3622
  void (async () => {
3000
3623
  try {
@@ -3016,24 +3639,24 @@ function CliLoginDialog({ connector, onCancel, onClose }) {
3016
3639
  onMouseDown: (event) => {
3017
3640
  if (event.target === event.currentTarget) onClose();
3018
3641
  },
3019
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog dshc-dialog-detail", role: "dialog", "aria-modal": "true", "aria-label": `\u767B\u5F55 ${connector.name}`, children: [
3642
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog dshc-dialog-detail", role: "dialog", "aria-modal": "true", "aria-label": tr("\u767B\u5F55 {v0}", { v0: connector.name }), children: [
3020
3643
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head", children: [
3021
3644
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-avatar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CliLogo, { connector, size: 28 }) }),
3022
3645
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-title", children: [
3023
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: success ? "\u5DF2\u767B\u5F55" : connector.authenticated ? "\u91CD\u65B0\u767B\u5F55" : `\u767B\u5F55 ${connector.name}` }),
3646
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: success ? tr("\u5DF2\u767B\u5F55") : connector.authenticated ? tr("\u91CD\u65B0\u767B\u5F55") : tr("\u767B\u5F55 {v0}", { v0: connector.name }) }),
3024
3647
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.vendor })
3025
3648
  ] }),
3026
3649
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: `${statusClass} dshc-dialog-status-pill`, title: accountLabel, children: [
3027
3650
  busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
3028
3651
  statusLabel
3029
3652
  ] }),
3030
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3653
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3031
3654
  ] }),
3032
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-content", children: success ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u8D26\u53F7\u5DF2\u8FDE\u63A5\uFF0C\u53EF\u4EE5\u5173\u95ED\u6B64\u7A97\u53E3\u5E76\u8BA9 Agent \u4F7F\u7528\u5B98\u65B9 Skills\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3033
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: busy ? connector.stage === "\u914D\u7F6E\u5E94\u7528" ? "\u6B63\u5728\u51C6\u5907\u5E94\u7528\u914D\u7F6E\uFF0C\u6388\u6743\u9875\u9762\u4F1A\u81EA\u52A8\u6253\u5F00\uFF1B\u82E5\u672A\u6253\u5F00\uFF0C\u8BF7\u70B9\u51FB\u300C\u6253\u5F00\u6388\u6743\u9875\u9762\u300D\u3002" : "\u8BF7\u5728\u6D4F\u89C8\u5668\u5B8C\u6210\u767B\u5F55\u6388\u6743\uFF0C\u5B8C\u6210\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\u3002" : failed ? "\u767B\u5F55\u672A\u5B8C\u6210\uFF0C\u8BF7\u5173\u95ED\u540E\u91CD\u65B0\u70B9\u51FB\u300C\u767B\u5F55\u300D\uFF1B\u5B8C\u6574\u9519\u8BEF\u53EF\u4ECE\u5361\u7247\u611F\u53F9\u53F7\u67E5\u770B\u3002" : "\u767B\u5F55\u6D41\u7A0B\u5DF2\u7ED3\u675F\u6216\u5C1A\u672A\u5F00\u59CB\u3002" }),
3655
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-content", children: success ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u8D26\u53F7\u5DF2\u8FDE\u63A5\uFF0C\u53EF\u4EE5\u5173\u95ED\u6B64\u7A97\u53E3\u5E76\u8BA9 Agent \u4F7F\u7528\u5B98\u65B9 Skills\u3002") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3656
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: busy ? connector.stage === "\u914D\u7F6E\u5E94\u7528" ? tr("\u6B63\u5728\u51C6\u5907\u5E94\u7528\u914D\u7F6E\uFF0C\u6388\u6743\u9875\u9762\u4F1A\u81EA\u52A8\u6253\u5F00\uFF1B\u82E5\u672A\u6253\u5F00\uFF0C\u8BF7\u70B9\u51FB\u300C\u6253\u5F00\u6388\u6743\u9875\u9762\u300D\u3002") : tr("\u8BF7\u5728\u6D4F\u89C8\u5668\u5B8C\u6210\u767B\u5F55\u6388\u6743\uFF0C\u5B8C\u6210\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\u3002") : failed ? tr("\u767B\u5F55\u672A\u5B8C\u6210\uFF0C\u8BF7\u5173\u95ED\u540E\u91CD\u65B0\u70B9\u51FB\u300C\u767B\u5F55\u300D\uFF1B\u5B8C\u6574\u9519\u8BEF\u53EF\u4ECE\u5361\u7247\u611F\u53F9\u53F7\u67E5\u770B\u3002") : tr("\u767B\u5F55\u6D41\u7A0B\u5DF2\u7ED3\u675F\u6216\u5C1A\u672A\u5F00\u59CB\u3002") }),
3034
3657
  connector.code !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-cli-code", children: [
3035
3658
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: connector.code }),
3036
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: () => copy(connector.code ?? "", "code"), children: copied === "code" ? "\u5DF2\u590D\u5236" : copyFailed === "code" ? "\u590D\u5236\u5931\u8D25" : "\u590D\u5236\u8BBE\u5907\u7801" })
3659
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: () => copy(connector.code ?? "", "code"), children: copied === "code" ? tr("\u5DF2\u590D\u5236") : copyFailed === "code" ? tr("\u590D\u5236\u5931\u8D25") : tr("\u590D\u5236\u8BBE\u5907\u7801") })
3037
3660
  ] })
3038
3661
  ] }) }),
3039
3662
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-actions", children: [
@@ -3046,20 +3669,20 @@ function CliLoginDialog({ connector, onCancel, onClose }) {
3046
3669
  onCancel();
3047
3670
  onClose();
3048
3671
  },
3049
- children: "\u53D6\u6D88\u767B\u5F55"
3672
+ children: tr("\u53D6\u6D88\u767B\u5F55")
3050
3673
  }
3051
3674
  ),
3052
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: success ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onClose, children: "\u5B8C\u6210" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3675
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: success ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onClose, children: tr("\u5B8C\u6210") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3053
3676
  link !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3054
3677
  "button",
3055
3678
  {
3056
3679
  type: "button",
3057
3680
  className: "dshc-btn dshc-btn-md dshc-btn-outline",
3058
3681
  onClick: () => copy(link, "link"),
3059
- children: copied === "link" ? "\u5DF2\u590D\u5236" : copyFailed === "link" ? "\u590D\u5236\u5931\u8D25" : "\u590D\u5236\u94FE\u63A5"
3682
+ children: copied === "link" ? tr("\u5DF2\u590D\u5236") : copyFailed === "link" ? tr("\u590D\u5236\u5931\u8D25") : tr("\u590D\u5236\u94FE\u63A5")
3060
3683
  }
3061
3684
  ),
3062
- link !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "dshc-btn dshc-btn-md dshc-btn-primary", href: link, target: "_blank", rel: "noreferrer", children: "\u6253\u5F00\u6388\u6743\u9875\u9762" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: "\u5173\u95ED" })
3685
+ link !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "dshc-btn dshc-btn-md dshc-btn-primary", href: link, target: "_blank", rel: "noreferrer", children: tr("\u6253\u5F00\u6388\u6743\u9875\u9762") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: tr("\u5173\u95ED") })
3063
3686
  ] }) })
3064
3687
  ] })
3065
3688
  ] })
@@ -3067,7 +3690,7 @@ function CliLoginDialog({ connector, onCancel, onClose }) {
3067
3690
  );
3068
3691
  }
3069
3692
  function CliUninstallDialog({ connector, running, pending, error, onClose, onConfirm, onCancel }) {
3070
- (0, import_react.useEffect)(() => {
3693
+ (0, import_react2.useEffect)(() => {
3071
3694
  const onKey = (event) => {
3072
3695
  if (event.key === "Escape") onClose();
3073
3696
  };
@@ -3081,33 +3704,34 @@ function CliUninstallDialog({ connector, running, pending, error, onClose, onCon
3081
3704
  onMouseDown: (event) => {
3082
3705
  if (event.target === event.currentTarget) onClose();
3083
3706
  },
3084
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog", role: "dialog", "aria-modal": "true", "aria-busy": running, "aria-label": `\u5378\u8F7D ${connector.name} CLI`, children: [
3707
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog", role: "dialog", "aria-modal": "true", "aria-busy": running, "aria-label": tr("\u5378\u8F7D {v0} CLI", { v0: connector.name }), children: [
3085
3708
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head", children: [
3086
3709
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-avatar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CliLogo, { connector, size: 28 }) }),
3087
3710
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-title", children: [
3088
3711
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h2", { children: [
3089
- "\u5378\u8F7D ",
3712
+ tr("\u5378\u8F7D"),
3713
+ " ",
3090
3714
  connector.name,
3091
3715
  " CLI"
3092
3716
  ] }),
3093
3717
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.vendor })
3094
3718
  ] }),
3095
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3719
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3096
3720
  ] }),
3097
3721
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
3098
3722
  running ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3099
3723
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-cli-wait", children: [
3100
3724
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
3101
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.stage ?? "\u6B63\u5728\u5378\u8F7D CLI \u4E0E\u5B98\u65B9 Skills\u2026" })
3725
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.stage ?? tr("\u6B63\u5728\u5378\u8F7D CLI \u4E0E\u5B98\u65B9 Skills\u2026") })
3102
3726
  ] }),
3103
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u5378\u8F7D\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u6267\u884C\uFF1B\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u6B62\uFF0C\u53EF\u4EE5\u4ECE\u5361\u7247\u91CD\u65B0\u6253\u5F00\u8FDB\u5EA6\u3002" })
3727
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u5378\u8F7D\u5728\u5BBF\u4E3B\u4FA7\u7EE7\u7EED\u6267\u884C\uFF1B\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u6B62\uFF0C\u53EF\u4EE5\u4ECE\u5361\u7247\u91CD\u65B0\u6253\u5F00\u8FDB\u5EA6\u3002") })
3104
3728
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3105
3729
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-body", children: [
3106
- "\u5C06\u5378\u8F7D\u672C\u673A npm \u5168\u5C40 CLI",
3107
- connector.skills.count > 0 ? `\uFF0C\u5E76\u5220\u9664 ~/.agents/skills \u4E0B ${connector.skills.count} \u4E2A\u5B98\u65B9 Skills` : "",
3730
+ tr("\u5C06\u5378\u8F7D\u672C\u673A npm \u5168\u5C40 CLI"),
3731
+ connector.skills.count > 0 ? tr("\uFF0C\u5E76\u5220\u9664 ~/.agents/skills \u4E0B {v0} \u4E2A\u5B98\u65B9 Skills", { v0: connector.skills.count }) : "",
3108
3732
  "\u3002"
3109
3733
  ] }),
3110
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: connector.skills.count > 0 ? "\u5176\u4ED6 Agent \u5C06\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528\u8FD9\u4E9B Skills\uFF0C\u5F53\u524D\u767B\u5F55\u6001\u4E5F\u4F1A\u6E05\u9664\uFF1B\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u624D\u80FD\u6062\u590D\u3002" : "\u5176\u4ED6 Agent \u5C06\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528\u8BE5 CLI\uFF0C\u5F53\u524D\u767B\u5F55\u6001\u4E5F\u4F1A\u6E05\u9664\uFF1B\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u624D\u80FD\u6062\u590D\u3002" })
3734
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: connector.skills.count > 0 ? tr("\u5176\u4ED6 Agent \u5C06\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528\u8FD9\u4E9B Skills\uFF0C\u5F53\u524D\u767B\u5F55\u6001\u4E5F\u4F1A\u6E05\u9664\uFF1B\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u624D\u80FD\u6062\u590D\u3002") : tr("\u5176\u4ED6 Agent \u5C06\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528\u8BE5 CLI\uFF0C\u5F53\u524D\u767B\u5F55\u6001\u4E5F\u4F1A\u6E05\u9664\uFF1B\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u624D\u80FD\u6062\u590D\u3002") })
3111
3735
  ] }),
3112
3736
  error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: error })
3113
3737
  ] }),
@@ -3121,13 +3745,13 @@ function CliUninstallDialog({ connector, running, pending, error, onClose, onCon
3121
3745
  onClick: onCancel,
3122
3746
  children: [
3123
3747
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
3124
- "\u53D6\u6D88\u5378\u8F7D"
3748
+ tr("\u53D6\u6D88\u5378\u8F7D")
3125
3749
  ]
3126
3750
  }
3127
3751
  ),
3128
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: "\u5173\u95ED" }) })
3752
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: tr("\u5173\u95ED") }) })
3129
3753
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3130
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: "\u53D6\u6D88" }),
3754
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: tr("\u53D6\u6D88") }),
3131
3755
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3132
3756
  "button",
3133
3757
  {
@@ -3137,7 +3761,7 @@ function CliUninstallDialog({ connector, running, pending, error, onClose, onCon
3137
3761
  onClick: onConfirm,
3138
3762
  children: [
3139
3763
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
3140
- pending ? "\u542F\u52A8\u4E2D\u2026" : "\u5378\u8F7D CLI"
3764
+ pending ? tr("\u542F\u52A8\u4E2D\u2026") : tr("\u5378\u8F7D CLI")
3141
3765
  ]
3142
3766
  }
3143
3767
  )
@@ -3147,7 +3771,7 @@ function CliUninstallDialog({ connector, running, pending, error, onClose, onCon
3147
3771
  );
3148
3772
  }
3149
3773
  function CliUpdateDialog({ connector, running, started, error, onClose }) {
3150
- (0, import_react.useEffect)(() => {
3774
+ (0, import_react2.useEffect)(() => {
3151
3775
  const onKey = (event) => {
3152
3776
  if (event.key === "Escape") onClose();
3153
3777
  };
@@ -3161,53 +3785,54 @@ function CliUpdateDialog({ connector, running, started, error, onClose }) {
3161
3785
  onMouseDown: (event) => {
3162
3786
  if (event.target === event.currentTarget) onClose();
3163
3787
  },
3164
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog", role: "dialog", "aria-modal": "true", "aria-busy": running, "aria-label": `\u66F4\u65B0 ${connector.name} CLI`, children: [
3788
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog", role: "dialog", "aria-modal": "true", "aria-busy": running, "aria-label": tr("\u66F4\u65B0 {v0} CLI", { v0: connector.name }), children: [
3165
3789
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head", children: [
3166
3790
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-avatar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CliLogo, { connector, size: 28 }) }),
3167
3791
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-title", children: [
3168
3792
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h2", { children: [
3169
- "\u66F4\u65B0 ",
3793
+ tr("\u66F4\u65B0"),
3794
+ " ",
3170
3795
  connector.name,
3171
3796
  " CLI"
3172
3797
  ] }),
3173
3798
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.vendor })
3174
3799
  ] }),
3175
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3800
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3176
3801
  ] }),
3177
3802
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
3178
3803
  running ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3179
3804
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-cli-wait", children: [
3180
3805
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
3181
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.stage ?? "\u6B63\u5728\u66F4\u65B0 CLI\u2026" })
3806
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: connector.stage ?? tr("\u6B63\u5728\u66F4\u65B0 CLI\u2026") })
3182
3807
  ] }),
3183
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u66F4\u65B0\u4F1A\u539F\u5730\u5347\u7EA7 npm \u5168\u5C40 CLI \u5E76\u91CD\u65B0\u62C9\u53D6 Skills\uFF0C\u4E0D\u4F1A\u6E05\u9664\u767B\u5F55\u6001\uFF1B\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u6B62\uFF0C\u53EF\u518D\u6B21\u6253\u5F00\u67E5\u770B\u8FDB\u5EA6\u3002" })
3184
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-body", children: started ? `\u5DF2\u66F4\u65B0\u5230 v${connector.version ?? "\u6700\u65B0\u7248\u672C"}\u3002` : "\u51C6\u5907\u66F4\u65B0\u2026" }),
3808
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u66F4\u65B0\u4F1A\u539F\u5730\u5347\u7EA7 npm \u5168\u5C40 CLI \u5E76\u91CD\u65B0\u62C9\u53D6 Skills\uFF0C\u4E0D\u4F1A\u6E05\u9664\u767B\u5F55\u6001\uFF1B\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u6B62\uFF0C\u53EF\u518D\u6B21\u6253\u5F00\u67E5\u770B\u8FDB\u5EA6\u3002") })
3809
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-body", children: started ? tr("\u5DF2\u66F4\u65B0\u5230 v{v0}\u3002", { v0: connector.version ?? tr("\u6700\u65B0\u7248\u672C") }) : tr("\u51C6\u5907\u66F4\u65B0\u2026") }),
3185
3810
  error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: error })
3186
3811
  ] }),
3187
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: running ? "\u540E\u53F0\u7EE7\u7EED" : "\u5B8C\u6210" }) }) })
3812
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: running ? tr("\u540E\u53F0\u7EE7\u7EED") : tr("\u5B8C\u6210") }) }) })
3188
3813
  ] })
3189
3814
  }
3190
3815
  );
3191
3816
  }
3192
3817
  function CliDetailDialog({ connector, onClose, onTrial, onInstall, onLogin, onUninstall }) {
3193
- const [copied, setCopied] = (0, import_react.useState)(null);
3194
- const [copyFailed, setCopyFailed] = (0, import_react.useState)(null);
3195
- const [showAllCapabilities, setShowAllCapabilities] = (0, import_react.useState)(false);
3196
- const [exampleTip, setExampleTip] = (0, import_react.useState)(null);
3818
+ const [copied, setCopied] = (0, import_react2.useState)(null);
3819
+ const [copyFailed, setCopyFailed] = (0, import_react2.useState)(null);
3820
+ const [showAllCapabilities, setShowAllCapabilities] = (0, import_react2.useState)(false);
3821
+ const [exampleTip, setExampleTip] = (0, import_react2.useState)(null);
3197
3822
  const busy = connector.phase === "installing" || connector.phase === "updating" || connector.phase === "configuring" || connector.phase === "logging_in" || connector.phase === "uninstalling";
3198
3823
  const enabled = connector.enabled !== false;
3199
3824
  const canTry = connector.authenticated && connector.installed && enabled && connector.skills.installed && !busy;
3200
- const status = busy ? connector.stage ?? "\u5904\u7406\u4E2D" : !connector.installed ? "\u672A\u5B89\u88C5" : !connector.authenticated ? "\u5DF2\u5B89\u88C5\u672A\u767B\u5F55" : enabled ? "\u5DF2\u767B\u5F55" : "\u5DF2\u505C\u7528";
3825
+ const status = busy ? connector.stage ?? tr("\u5904\u7406\u4E2D") : !connector.installed ? tr("\u672A\u5B89\u88C5") : !connector.authenticated ? tr("\u5DF2\u5B89\u88C5\u672A\u767B\u5F55") : enabled ? tr("\u5DF2\u767B\u5F55") : tr("\u5DF2\u505C\u7528");
3201
3826
  const statusClass = connector.authenticated && enabled && !busy ? "dshc-status-pill dshc-status-pill-connected" : "dshc-status-pill";
3202
3827
  const accountLabel = connector.account?.name ?? connector.account?.email;
3203
3828
  const statusWithAccount = !busy && accountLabel !== void 0 ? `${status} \xB7 ${accountLabel}` : status;
3204
3829
  const accountTitle = accountLabel === void 0 ? void 0 : [accountLabel, connector.account?.org].filter(Boolean).join(" \xB7 ");
3205
3830
  const capabilities = connector.capabilities;
3206
3831
  const visibleCapabilities = capabilities === void 0 ? [] : showAllCapabilities ? capabilities.items : capabilities.items.slice(0, 4);
3207
- (0, import_react.useEffect)(() => {
3832
+ (0, import_react2.useEffect)(() => {
3208
3833
  setShowAllCapabilities(false);
3209
3834
  }, [connector.id]);
3210
- (0, import_react.useEffect)(() => {
3835
+ (0, import_react2.useEffect)(() => {
3211
3836
  const onKey = (event) => {
3212
3837
  if (event.key === "Escape") onClose();
3213
3838
  };
@@ -3239,7 +3864,7 @@ function CliDetailDialog({ connector, onClose, onTrial, onInstall, onLogin, onUn
3239
3864
  above
3240
3865
  });
3241
3866
  };
3242
- const exampleTipText = exampleTip === null ? null : exampleTip.action === "try" ? canTry ? "\u53BB\u8BD5\u8BD5" : !connector.authenticated ? "\u767B\u5F55\u540E\u53EF\u7528" : !enabled ? "\u5DF2\u505C\u7528" : "Skills \u672A\u5C31\u7EEA" : copied === exampleTip.index ? "\u5DF2\u590D\u5236" : copyFailed === exampleTip.index ? "\u590D\u5236\u5931\u8D25" : "\u590D\u5236";
3867
+ const exampleTipText = exampleTip === null ? null : exampleTip.action === "try" ? canTry ? tr("\u53BB\u8BD5\u8BD5") : !connector.authenticated ? tr("\u767B\u5F55\u540E\u53EF\u7528") : !enabled ? tr("\u5DF2\u505C\u7528") : tr("Skills \u672A\u5C31\u7EEA") : copied === exampleTip.index ? tr("\u5DF2\u590D\u5236") : copyFailed === exampleTip.index ? tr("\u590D\u5236\u5931\u8D25") : tr("\u590D\u5236");
3243
3868
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3244
3869
  "div",
3245
3870
  {
@@ -3253,29 +3878,32 @@ function CliDetailDialog({ connector, onClose, onTrial, onInstall, onLogin, onUn
3253
3878
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-avatar dshc-dialog-avatar dshc-dialog-avatar-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CliLogo, { connector, size: 32 }) }),
3254
3879
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-title", children: [
3255
3880
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: connector.name }),
3256
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: [connector.vendor, connector.category].join(" \xB7 ") })
3881
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: [connector.vendor, tr(connector.category)].join(" \xB7 ") })
3257
3882
  ] }),
3258
3883
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${statusClass} dshc-dialog-status-pill`, title: accountTitle, children: statusWithAccount }),
3259
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3884
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3260
3885
  ] }),
3261
3886
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
3262
3887
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-body", children: connector.description }),
3263
3888
  connector.versionOutdated && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-error", children: [
3264
- "CLI \u7248\u672C ",
3265
- connector.version ?? "\u672A\u77E5",
3266
- " \u4F4E\u4E8E\u5B98\u65B9\u8981\u6C42 ",
3889
+ tr("CLI \u7248\u672C"),
3890
+ " ",
3891
+ connector.version ?? tr("\u672A\u77E5"),
3892
+ " ",
3893
+ tr("\u4F4E\u4E8E\u5B98\u65B9\u8981\u6C42"),
3894
+ " ",
3267
3895
  connector.minVersion,
3268
- "\uFF0C\u8BF7\u7528\u300C\u66F4\u591A \u2192 \u66F4\u65B0 CLI\u300D\u5347\u7EA7\u3002"
3896
+ tr("\uFF0C\u8BF7\u7528\u300C\u66F4\u591A \u2192 \u66F4\u65B0 CLI\u300D\u5347\u7EA7\u3002")
3269
3897
  ] }),
3270
3898
  capabilities !== void 0 && capabilities.items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "dshc-tools dshc-capabilities", children: [
3271
3899
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-tools-head dshc-capability-head", children: [
3272
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u53EF\u7528\u80FD\u529B" }),
3900
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: tr("\u53EF\u7528\u80FD\u529B") }),
3273
3901
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3274
3902
  "span",
3275
3903
  {
3276
3904
  className: "dshc-tools-count",
3277
- title: capabilities.kind === "products" ? `${capabilities.total} \u4E2A\u547D\u4EE4` : capabilities.kind === "groups" ? `${capabilities.total} \u4E2A\u547D\u4EE4\u7EC4` : `${capabilities.total} \u4E2A Skills`,
3278
- children: capabilities.kind === "products" ? `${capabilities.items.length} \u4E2A\u4EA7\u54C1` : capabilities.kind === "groups" ? `${capabilities.items.length} \u4E2A\u547D\u4EE4\u7EC4` : `${capabilities.total} \u4E2A Skills`
3905
+ title: capabilities.kind === "products" ? tr("{v0} \u4E2A\u547D\u4EE4", { v0: capabilities.total }) : capabilities.kind === "groups" ? tr("{v0} \u4E2A\u547D\u4EE4\u7EC4", { v0: capabilities.total }) : tr("{v0} \u4E2A Skills", { v0: capabilities.total }),
3906
+ children: capabilities.kind === "products" ? tr("{v0} \u4E2A\u4EA7\u54C1", { v0: capabilities.items.length }) : capabilities.kind === "groups" ? tr("{v0} \u4E2A\u547D\u4EE4\u7EC4", { v0: capabilities.items.length }) : tr("{v0} \u4E2A Skills", { v0: capabilities.total })
3279
3907
  }
3280
3908
  )
3281
3909
  ] }),
@@ -3293,12 +3921,12 @@ function CliDetailDialog({ connector, onClose, onTrial, onInstall, onLogin, onUn
3293
3921
  type: "button",
3294
3922
  className: "dshc-tools-toggle",
3295
3923
  onClick: () => setShowAllCapabilities((current) => !current),
3296
- children: showAllCapabilities ? "\u6536\u8D77" : `\u5C55\u5F00\u5168\u90E8 ${capabilities.items.length} \u4E2A`
3924
+ children: showAllCapabilities ? tr("\u6536\u8D77") : tr("\u5C55\u5F00\u5168\u90E8 {v0} \u4E2A", { v0: capabilities.items.length })
3297
3925
  }
3298
3926
  )
3299
3927
  ] }),
3300
3928
  connector.examples.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "dshc-examples", children: [
3301
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u8BD5\u8BD5\u8FD9\u6837\u7528" }),
3929
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: tr("\u8BD5\u8BD5\u8FD9\u6837\u7528") }),
3302
3930
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-example-list", children: connector.examples.map((example, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-example", children: [
3303
3931
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-example-text", children: example }),
3304
3932
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-example-actions", children: [
@@ -3307,7 +3935,7 @@ function CliDetailDialog({ connector, onClose, onTrial, onInstall, onLogin, onUn
3307
3935
  {
3308
3936
  type: "button",
3309
3937
  className: copied === index ? "dshc-example-action dshc-example-action-success" : copyFailed === index ? "dshc-example-action dshc-example-action-error" : "dshc-example-action",
3310
- "aria-label": `\u590D\u5236\u793A\u4F8B\uFF1A${example}`,
3938
+ "aria-label": tr("\u590D\u5236\u793A\u4F8B\uFF1A{v0}", { v0: example }),
3311
3939
  onMouseEnter: (event) => showExampleTip(event.currentTarget, index, "copy"),
3312
3940
  onMouseLeave: () => setExampleTip(null),
3313
3941
  onFocus: (event) => showExampleTip(event.currentTarget, index, "copy"),
@@ -3321,7 +3949,7 @@ function CliDetailDialog({ connector, onClose, onTrial, onInstall, onLogin, onUn
3321
3949
  {
3322
3950
  type: "button",
3323
3951
  className: "dshc-example-action",
3324
- "aria-label": `\u53BB\u8BD5\u8BD5\uFF1A${example}`,
3952
+ "aria-label": tr("\u53BB\u8BD5\u8BD5\uFF1A{v0}", { v0: example }),
3325
3953
  disabled: !canTry,
3326
3954
  onMouseEnter: (event) => showExampleTip(event.currentTarget, index, "try"),
3327
3955
  onMouseLeave: () => setExampleTip(null),
@@ -3343,13 +3971,13 @@ function CliDetailDialog({ connector, onClose, onTrial, onInstall, onLogin, onUn
3343
3971
  className: "dshc-btn dshc-btn-md dshc-btn-ghost dshc-btn-danger",
3344
3972
  disabled: busy,
3345
3973
  onClick: onUninstall,
3346
- children: "\u5378\u8F7D CLI"
3974
+ children: tr("\u5378\u8F7D CLI")
3347
3975
  }
3348
3976
  ),
3349
3977
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: !connector.installed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
3350
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: "\u5173\u95ED" }),
3351
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: busy, onClick: onInstall, children: "\u5B89\u88C5" })
3352
- ] }) : !connector.authenticated ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: busy, onClick: onLogin, children: "\u767B\u5F55" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onClose, children: "\u5B8C\u6210" }) })
3978
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: tr("\u5173\u95ED") }),
3979
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: busy, onClick: onInstall, children: tr("\u5B89\u88C5") })
3980
+ ] }) : !connector.authenticated ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: busy, onClick: onLogin, children: tr("\u767B\u5F55") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onClose, children: tr("\u5B8C\u6210") }) })
3353
3981
  ] })
3354
3982
  ] }),
3355
3983
  exampleTip !== null && exampleTipText !== null && (0, import_react_dom.createPortal)(
@@ -3368,12 +3996,12 @@ function CliDetailDialog({ connector, onClose, onTrial, onInstall, onLogin, onUn
3368
3996
  );
3369
3997
  }
3370
3998
  function CliErrorDialog({ connector, onClose }) {
3371
- const [log, setLog] = (0, import_react.useState)("");
3372
- const [loading, setLoading] = (0, import_react.useState)(true);
3373
- const [loadError, setLoadError] = (0, import_react.useState)(null);
3374
- const [copied, setCopied] = (0, import_react.useState)(false);
3375
- const [copyFailed, setCopyFailed] = (0, import_react.useState)(false);
3376
- (0, import_react.useEffect)(() => {
3999
+ const [log, setLog] = (0, import_react2.useState)("");
4000
+ const [loading, setLoading] = (0, import_react2.useState)(true);
4001
+ const [loadError, setLoadError] = (0, import_react2.useState)(null);
4002
+ const [copied, setCopied] = (0, import_react2.useState)(false);
4003
+ const [copyFailed, setCopyFailed] = (0, import_react2.useState)(false);
4004
+ (0, import_react2.useEffect)(() => {
3377
4005
  let active = true;
3378
4006
  setLoading(true);
3379
4007
  setLoadError(null);
@@ -3391,7 +4019,7 @@ function CliErrorDialog({ connector, onClose }) {
3391
4019
  active = false;
3392
4020
  };
3393
4021
  }, [connector.id]);
3394
- (0, import_react.useEffect)(() => {
4022
+ (0, import_react2.useEffect)(() => {
3395
4023
  const onKey = (event) => {
3396
4024
  if (event.key === "Escape") onClose();
3397
4025
  };
@@ -3421,33 +4049,35 @@ function CliErrorDialog({ connector, onClose }) {
3421
4049
  onMouseDown: (event) => {
3422
4050
  if (event.target === event.currentTarget) onClose();
3423
4051
  },
3424
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog dshc-dialog-detail", role: "dialog", "aria-modal": "true", "aria-label": `${connector.name} \u9519\u8BEF\u65E5\u5FD7`, children: [
4052
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog dshc-dialog-detail", role: "dialog", "aria-modal": "true", "aria-label": tr("{v0} \u9519\u8BEF\u65E5\u5FD7", { v0: connector.name }), children: [
3425
4053
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head dshc-dialog-head-detail", children: [
3426
4054
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-avatar dshc-dialog-avatar dshc-dialog-avatar-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconAlert, { size: 20 }) }),
3427
4055
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-title", children: [
3428
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: "\u9519\u8BEF\u65E5\u5FD7" }),
4056
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: tr("\u9519\u8BEF\u65E5\u5FD7") }),
3429
4057
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
3430
4058
  connector.name,
3431
4059
  " \xB7 CLI"
3432
4060
  ] })
3433
4061
  ] }),
3434
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-status-pill dshc-status-pill-error dshc-dialog-status-pill", children: "\u5904\u7406\u5931\u8D25" }),
3435
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
4062
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-status-pill dshc-status-pill-error dshc-dialog-status-pill", children: tr("\u5904\u7406\u5931\u8D25") }),
4063
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3436
4064
  ] }),
3437
4065
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
3438
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: connector.lastError ?? "CLI \u5904\u7406\u5931\u8D25\uFF0C\u672A\u8FD4\u56DE\u9519\u8BEF\u6458\u8981\u3002" }),
4066
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: connector.lastError ?? tr("CLI \u5904\u7406\u5931\u8D25\uFF0C\u672A\u8FD4\u56DE\u9519\u8BEF\u6458\u8981\u3002") }),
3439
4067
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "dshc-cli-log-section", children: [
3440
4068
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-tools-head", children: [
3441
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u8FD0\u884C\u65E5\u5FD7" }),
4069
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: tr("\u8FD0\u884C\u65E5\u5FD7") }),
3442
4070
  !loading && log.trim() !== "" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-tools-count", children: [
3443
4071
  log.split(/\r?\n/).length,
3444
- " \u884C"
4072
+ " ",
4073
+ tr("\u884C")
3445
4074
  ] })
3446
4075
  ] }),
3447
4076
  loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
3448
4077
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
3449
- " \u6B63\u5728\u8BFB\u53D6\u65E5\u5FD7\u2026"
3450
- ] }) : loadError !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: loadError }) : log.trim() === "" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u672C\u6B21\u9519\u8BEF\u6CA1\u6709\u7559\u4E0B\u66F4\u591A\u8FD0\u884C\u65E5\u5FD7\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { className: "dshc-cli-log", children: log })
4078
+ " ",
4079
+ tr("\u6B63\u5728\u8BFB\u53D6\u65E5\u5FD7\u2026")
4080
+ ] }) : loadError !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: loadError }) : log.trim() === "" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u672C\u6B21\u9519\u8BEF\u6CA1\u6709\u7559\u4E0B\u66F4\u591A\u8FD0\u884C\u65E5\u5FD7\u3002") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { className: "dshc-cli-log", children: log })
3451
4081
  ] })
3452
4082
  ] }),
3453
4083
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-actions", children: [
@@ -3460,11 +4090,11 @@ function CliErrorDialog({ connector, onClose }) {
3460
4090
  onClick: copy,
3461
4091
  children: [
3462
4092
  copied ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 14 }) : copyFailed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconAlert, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCopy, { size: 14 }),
3463
- copied ? "\u5DF2\u590D\u5236" : copyFailed ? "\u590D\u5236\u5931\u8D25" : "\u590D\u5236\u65E5\u5FD7"
4093
+ copied ? tr("\u5DF2\u590D\u5236") : copyFailed ? tr("\u590D\u5236\u5931\u8D25") : tr("\u590D\u5236\u65E5\u5FD7")
3464
4094
  ]
3465
4095
  }
3466
4096
  ),
3467
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onClose, children: "\u5173\u95ED" }) })
4097
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-actions-right", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", onClick: onClose, children: tr("\u5173\u95ED") }) })
3468
4098
  ] })
3469
4099
  ] })
3470
4100
  }
@@ -3475,10 +4105,10 @@ function CliLogo({ connector, size }) {
3475
4105
  return src === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-logo-fallback", style: { width: size, height: size }, children: connector.name.slice(0, 1) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { className: "dshc-logo-img", width: size, height: size, src, alt: "" });
3476
4106
  }
3477
4107
  function ConnectorCardView({ card, connection, errorMessage, togglePending, authorizing, installing, connecting, onOpen, onInstall, onAuthorize, onCancelAuthorize, onUpdateCredential, onReauthorize, onReconfigureInstance, onRevoke, onTrial, onToggle, onDisconnect, onDelete, onEditCustom }) {
3478
- const [menuOpen, setMenuOpen] = (0, import_react.useState)(false);
3479
- const [menuAbove, setMenuAbove] = (0, import_react.useState)(false);
3480
- const [tip, setTip] = (0, import_react.useState)(null);
3481
- const menuRef = (0, import_react.useRef)(null);
4108
+ const [menuOpen, setMenuOpen] = (0, import_react2.useState)(false);
4109
+ const [menuAbove, setMenuAbove] = (0, import_react2.useState)(false);
4110
+ const [tip, setTip] = (0, import_react2.useState)(null);
4111
+ const menuRef = (0, import_react2.useRef)(null);
3482
4112
  const connected = connection !== void 0 && connection.authorized && connection.enabled && connection.error === void 0;
3483
4113
  const unauthorized = connection !== void 0 && !connection.authorized;
3484
4114
  const toolCount = connection?.tools.length ?? 0;
@@ -3489,7 +4119,7 @@ function ConnectorCardView({ card, connection, errorMessage, togglePending, auth
3489
4119
  setMenuAbove(rect.bottom + 170 > window.innerHeight);
3490
4120
  setMenuOpen((current) => !current);
3491
4121
  };
3492
- (0, import_react.useEffect)(() => {
4122
+ (0, import_react2.useEffect)(() => {
3493
4123
  if (tip === null) return;
3494
4124
  const close = () => setTip(null);
3495
4125
  window.addEventListener("pointerdown", close, true);
@@ -3502,7 +4132,7 @@ function ConnectorCardView({ card, connection, errorMessage, togglePending, auth
3502
4132
  const left = Math.max(16, Math.min(rect.left, window.innerWidth - width - 16));
3503
4133
  setTip({ text: card.summary, left, top: rect.bottom + 8 });
3504
4134
  };
3505
- (0, import_react.useEffect)(() => {
4135
+ (0, import_react2.useEffect)(() => {
3506
4136
  if (!menuOpen) return;
3507
4137
  const onPointerDown = (event) => {
3508
4138
  if (menuRef.current !== null && !menuRef.current.contains(event.target)) setMenuOpen(false);
@@ -3519,11 +4149,10 @@ function ConnectorCardView({ card, connection, errorMessage, togglePending, auth
3519
4149
  }, [menuOpen]);
3520
4150
  const actionClass = error !== void 0 ? "dshc-card-action dshc-card-action-error" : connection === void 0 ? "dshc-card-action dshc-card-action-connect" : enabled ? "dshc-card-action dshc-card-action-connected" : "dshc-card-action dshc-card-action-disabled";
3521
4151
  const instancePending = card.instance !== void 0 && connection !== void 0 && connection.instanceReady !== true;
3522
- const actionText = connecting ? "\u8FDE\u63A5\u4E2D\u2026" : error ?? (connection === void 0 ? "\u67E5\u770B\u8BE6\u60C5" : unauthorized ? instancePending ? "\u5F85\u914D\u7F6E" : "\u672A\u6388\u6743" : !enabled ? "\u5DF2\u505C\u7528" : toolCount > 0 ? `\u5DF2\u8FDE\u63A5 \xB7 ${toolCount} \u4E2A\u5DE5\u5177
3523
- ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
4152
+ const actionText = connecting ? tr("\u8FDE\u63A5\u4E2D\u2026") : error ?? (connection === void 0 ? tr("\u67E5\u770B\u8BE6\u60C5") : unauthorized ? instancePending ? tr("\u5F85\u914D\u7F6E") : tr("\u672A\u6388\u6743") : !enabled ? tr("\u5DF2\u505C\u7528") : toolCount > 0 ? tr("\u5DF2\u8FDE\u63A5 \xB7 {v0} \u4E2A\u5DE5\u5177\n{v1}", { v0: toolCount, v1: connection.tools.join("\n") }) : tr("\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D"));
3524
4153
  const installActionClass = installing ? "dshc-card-action dshc-card-action-connect dshc-card-action-loading" : "dshc-card-action dshc-card-action-connect";
3525
- const installLabel = installing ? "\u5B89\u88C5\u4E2D\u2026" : error !== void 0 ? "\u91CD\u8BD5" : "\u5B89\u88C5";
3526
- const stateLabel = connecting ? "\uFF0C\u8FDE\u63A5\u4E2D" : error !== void 0 ? "\uFF0C\u8FDE\u63A5\u5931\u8D25" : connection === void 0 ? "" : unauthorized ? instancePending ? "\uFF0C\u5F85\u914D\u7F6E" : "\uFF0C\u672A\u6388\u6743" : !enabled ? "\uFF0C\u5DF2\u505C\u7528" : toolCount > 0 ? `\uFF0C\u5DF2\u8FDE\u63A5\uFF0C${toolCount} \u4E2A\u5DE5\u5177` : "\uFF0C\u5DF2\u8FDE\u63A5\uFF0C\u6B63\u5728\u6CE8\u518C\u5DE5\u5177";
4154
+ const installLabel = installing ? tr("\u5B89\u88C5\u4E2D\u2026") : error !== void 0 ? tr("\u91CD\u8BD5") : tr("\u5B89\u88C5");
4155
+ const stateLabel = connecting ? tr("\uFF0C\u8FDE\u63A5\u4E2D") : error !== void 0 ? tr("\uFF0C\u8FDE\u63A5\u5931\u8D25") : connection === void 0 ? "" : unauthorized ? instancePending ? tr("\uFF0C\u5F85\u914D\u7F6E") : tr("\uFF0C\u672A\u6388\u6743") : !enabled ? tr("\uFF0C\u5DF2\u505C\u7528") : toolCount > 0 ? tr("\uFF0C\u5DF2\u8FDE\u63A5\uFF0C{v0} \u4E2A\u5DE5\u5177", { v0: toolCount }) : tr("\uFF0C\u5DF2\u8FDE\u63A5\uFF0C\u6B63\u5728\u6CE8\u518C\u5DE5\u5177");
3527
4156
  const deleteItem = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3528
4157
  "button",
3529
4158
  {
@@ -3537,7 +4166,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3537
4166
  },
3538
4167
  children: [
3539
4168
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconTrash, { size: 14 }),
3540
- "\u5220\u9664"
4169
+ tr("\u5220\u9664")
3541
4170
  ]
3542
4171
  }
3543
4172
  );
@@ -3553,7 +4182,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3553
4182
  },
3554
4183
  children: [
3555
4184
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconPlug, { size: 14 }),
3556
- "\u65AD\u5F00"
4185
+ tr("\u65AD\u5F00")
3557
4186
  ]
3558
4187
  }
3559
4188
  );
@@ -3570,7 +4199,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3570
4199
  },
3571
4200
  children: [
3572
4201
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconServer, { size: 14 }),
3573
- "\u66F4\u6362",
4202
+ tr("\u66F4\u6362"),
3574
4203
  instanceNoun(card)
3575
4204
  ]
3576
4205
  }
@@ -3588,7 +4217,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3588
4217
  },
3589
4218
  children: [
3590
4219
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconPencil, { size: 14 }),
3591
- "\u7F16\u8F91\u914D\u7F6E"
4220
+ tr("\u7F16\u8F91\u914D\u7F6E")
3592
4221
  ]
3593
4222
  }
3594
4223
  );
@@ -3599,7 +4228,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3599
4228
  className: menuOpen ? "dshc-card dshc-card-menu-open" : "dshc-card",
3600
4229
  role: "button",
3601
4230
  tabIndex: 0,
3602
- "aria-label": `\u67E5\u770B ${card.name}${stateLabel}`,
4231
+ "aria-label": tr("\u67E5\u770B {v0}{v1}", { v0: card.name, v1: stateLabel }),
3603
4232
  onClick: () => {
3604
4233
  if (menuOpen) {
3605
4234
  setMenuOpen(false);
@@ -3634,7 +4263,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3634
4263
  ),
3635
4264
  error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-card-error", title: error, children: error }),
3636
4265
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-card-foot", children: [
3637
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-badge", children: card.category }),
4266
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-badge", children: card.categoryLabel ?? tr(card.category) }),
3638
4267
  connection === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-install-actions", children: [
3639
4268
  onDelete !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-more-wrap dshc-card-more-float", ref: menuRef, children: [
3640
4269
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -3642,7 +4271,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3642
4271
  {
3643
4272
  type: "button",
3644
4273
  className: "dshc-card-more",
3645
- "aria-label": `${card.name} \u66F4\u591A\u64CD\u4F5C`,
4274
+ "aria-label": tr("{v0} \u66F4\u591A\u64CD\u4F5C", { v0: card.name }),
3646
4275
  "aria-haspopup": "menu",
3647
4276
  "aria-expanded": menuOpen,
3648
4277
  onClick: (event) => {
@@ -3663,7 +4292,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3663
4292
  type: "button",
3664
4293
  className: installActionClass,
3665
4294
  title: installLabel,
3666
- "aria-label": installing ? `\u6B63\u5728\u5B89\u88C5 ${card.name}` : `${installLabel} ${card.name}`,
4295
+ "aria-label": installing ? tr("\u6B63\u5728\u5B89\u88C5 {v0}", { v0: card.name }) : `${installLabel} ${card.name}`,
3667
4296
  disabled: installing,
3668
4297
  onClick: (event) => {
3669
4298
  event.stopPropagation();
@@ -3678,7 +4307,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3678
4307
  {
3679
4308
  type: "button",
3680
4309
  className: "dshc-card-auth",
3681
- "aria-label": authorizing ? `\u53D6\u6D88\u6388\u6743 ${card.name}` : connecting ? `\u6B63\u5728\u8FDE\u63A5 ${card.name}` : `${instancePending ? "\u914D\u7F6E" : "\u6388\u6743"} ${card.name}`,
4310
+ "aria-label": authorizing ? tr("\u53D6\u6D88\u6388\u6743 {v0}", { v0: card.name }) : connecting ? tr("\u6B63\u5728\u8FDE\u63A5 {v0}", { v0: card.name }) : `${instancePending ? tr("\u914D\u7F6E") : tr("\u6388\u6743")} ${card.name}`,
3682
4311
  disabled: connecting,
3683
4312
  onClick: (event) => {
3684
4313
  event.stopPropagation();
@@ -3687,7 +4316,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3687
4316
  },
3688
4317
  children: [
3689
4318
  (authorizing || connecting) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, { inline: true }),
3690
- authorizing ? "\u53D6\u6D88\u6388\u6743" : connecting ? "\u8FDE\u63A5\u4E2D\u2026" : instancePending ? "\u914D\u7F6E" : "\u6388\u6743"
4319
+ authorizing ? tr("\u53D6\u6D88\u6388\u6743") : connecting ? tr("\u8FDE\u63A5\u4E2D\u2026") : instancePending ? tr("\u914D\u7F6E") : tr("\u6388\u6743")
3691
4320
  ]
3692
4321
  }
3693
4322
  ),
@@ -3696,8 +4325,8 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3696
4325
  {
3697
4326
  className: "dshc-card-installed",
3698
4327
  role: "img",
3699
- "aria-label": instancePending ? "\u5DF2\u5B89\u88C5\uFF0C\u5F85\u914D\u7F6E" : "\u5DF2\u5B89\u88C5\uFF0C\u5F85\u6388\u6743",
3700
- title: instancePending ? "\u5DF2\u5B89\u88C5\uFF0C\u5F85\u914D\u7F6E" : "\u5DF2\u5B89\u88C5\uFF0C\u5F85\u6388\u6743",
4328
+ "aria-label": instancePending ? tr("\u5DF2\u5B89\u88C5\uFF0C\u5F85\u914D\u7F6E") : tr("\u5DF2\u5B89\u88C5\uFF0C\u5F85\u6388\u6743"),
4329
+ title: instancePending ? tr("\u5DF2\u5B89\u88C5\uFF0C\u5F85\u914D\u7F6E") : tr("\u5DF2\u5B89\u88C5\uFF0C\u5F85\u6388\u6743"),
3701
4330
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 14 })
3702
4331
  }
3703
4332
  ),
@@ -3707,7 +4336,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3707
4336
  {
3708
4337
  type: "button",
3709
4338
  className: "dshc-card-more",
3710
- "aria-label": `${card.name} \u66F4\u591A\u64CD\u4F5C`,
4339
+ "aria-label": tr("{v0} \u66F4\u591A\u64CD\u4F5C", { v0: card.name }),
3711
4340
  "aria-haspopup": "menu",
3712
4341
  "aria-expanded": menuOpen,
3713
4342
  onClick: (event) => {
@@ -3725,7 +4354,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3725
4354
  ] })
3726
4355
  ] })
3727
4356
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-actions", children: [
3728
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${actionClass} dshc-card-status`, title: connecting ? "\u8FDE\u63A5\u4E2D\u2026" : authorizing ? "\u6388\u6743\u4E2D\u2026" : actionText, "aria-hidden": true, children: authorizing || connecting ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) : error !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconAlert, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 16 }) }),
4357
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${actionClass} dshc-card-status`, title: connecting ? tr("\u8FDE\u63A5\u4E2D\u2026") : authorizing ? tr("\u6388\u6743\u4E2D\u2026") : actionText, "aria-hidden": true, children: authorizing || connecting ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) : error !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconAlert, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 16 }) }),
3729
4358
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-controls", children: [
3730
4359
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-card-more-wrap", ref: menuRef, children: [
3731
4360
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -3733,7 +4362,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3733
4362
  {
3734
4363
  type: "button",
3735
4364
  className: "dshc-card-more",
3736
- "aria-label": `${card.name} \u66F4\u591A\u64CD\u4F5C`,
4365
+ "aria-label": tr("{v0} \u66F4\u591A\u64CD\u4F5C", { v0: card.name }),
3737
4366
  "aria-haspopup": "menu",
3738
4367
  "aria-expanded": menuOpen,
3739
4368
  onClick: (event) => {
@@ -3757,7 +4386,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3757
4386
  },
3758
4387
  children: [
3759
4388
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconPlay, { size: 14 }),
3760
- "\u53BB\u8BD5\u8BD5"
4389
+ tr("\u53BB\u8BD5\u8BD5")
3761
4390
  ]
3762
4391
  }
3763
4392
  ),
@@ -3773,7 +4402,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3773
4402
  },
3774
4403
  children: [
3775
4404
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconRefresh, { size: 14 }),
3776
- "\u66F4\u65B0\u4EE4\u724C"
4405
+ tr("\u66F4\u65B0\u4EE4\u724C")
3777
4406
  ]
3778
4407
  }
3779
4408
  ),
@@ -3789,7 +4418,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3789
4418
  },
3790
4419
  children: [
3791
4420
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconRefresh, { size: 14 }),
3792
- "\u91CD\u65B0\u6388\u6743"
4421
+ tr("\u91CD\u65B0\u6388\u6743")
3793
4422
  ]
3794
4423
  }
3795
4424
  ),
@@ -3806,7 +4435,7 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3806
4435
  },
3807
4436
  children: [
3808
4437
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconLink, { size: 14 }),
3809
- "\u53D6\u6D88\u6388\u6743"
4438
+ tr("\u53D6\u6D88\u6388\u6743")
3810
4439
  ]
3811
4440
  }
3812
4441
  ),
@@ -3815,14 +4444,14 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3815
4444
  deleteItem
3816
4445
  ] })
3817
4446
  ] }),
3818
- togglePending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-card-toggle", role: "status", "aria-label": "\u5904\u7406\u4E2D", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4447
+ togglePending ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-card-toggle", role: "status", "aria-label": tr("\u5904\u7406\u4E2D"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3819
4448
  "button",
3820
4449
  {
3821
4450
  type: "button",
3822
4451
  role: "switch",
3823
4452
  "aria-checked": enabled,
3824
- "aria-label": enabled ? `\u505C\u7528 ${card.name}` : `\u542F\u7528 ${card.name}`,
3825
- title: enabled ? "\u505C\u7528" : "\u542F\u7528",
4453
+ "aria-label": enabled ? tr("\u505C\u7528 {v0}", { v0: card.name }) : tr("\u542F\u7528 {v0}", { v0: card.name }),
4454
+ title: enabled ? tr("\u505C\u7528") : tr("\u542F\u7528"),
3826
4455
  className: "dshc-switch",
3827
4456
  onClick: (event) => {
3828
4457
  event.stopPropagation();
@@ -3843,13 +4472,13 @@ ${connection.tools.join("\n")}` : "\u5DF2\u8FDE\u63A5 \xB7 \u6CE8\u518C\u4E2D");
3843
4472
  ] });
3844
4473
  }
3845
4474
  function ConnectorDialog({ card, connection, pending, toggling, authorizing, connecting, authorizeLink, installOpen, error, behind = false, escLocked = false, onClose, onBeginInstall, onCancelInstall, onConnect, onInstallOAuth, onConfigureInstance, onAuthorize, onReauthorize, onReconfigureInstance, onUpdateCredential, onCancelAuthorize, onTryExample, onRevoke, onDisconnect, onToggle, onDelete, onEditCustom }) {
3846
- const [copied, setCopied] = (0, import_react.useState)(null);
3847
- const [copyFailed, setCopyFailed] = (0, import_react.useState)(null);
3848
- const [showAllTools, setShowAllTools] = (0, import_react.useState)(false);
3849
- const [toolQuery, setToolQuery] = (0, import_react.useState)("");
3850
- const toolSearchRef = (0, import_react.useRef)(null);
3851
- const [exampleTip, setExampleTip] = (0, import_react.useState)(null);
3852
- (0, import_react.useEffect)(() => {
4475
+ const [copied, setCopied] = (0, import_react2.useState)(null);
4476
+ const [copyFailed, setCopyFailed] = (0, import_react2.useState)(null);
4477
+ const [showAllTools, setShowAllTools] = (0, import_react2.useState)(false);
4478
+ const [toolQuery, setToolQuery] = (0, import_react2.useState)("");
4479
+ const toolSearchRef = (0, import_react2.useRef)(null);
4480
+ const [exampleTip, setExampleTip] = (0, import_react2.useState)(null);
4481
+ (0, import_react2.useEffect)(() => {
3853
4482
  setToolQuery("");
3854
4483
  }, [card.id]);
3855
4484
  const needsToken = isTokenCard(card);
@@ -3870,15 +4499,15 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
3870
4499
  const showingInstall = installOpen && instance === void 0 && connection === void 0 && !needsToken;
3871
4500
  const needsInstanceConfig = instance !== void 0 && connection !== void 0 && !connection.authorized && connection.instanceReady !== true;
3872
4501
  const busy = pending || toggling;
3873
- const removeLabel = onDelete === void 0 ? "\u5220\u9664" : "\u65AD\u5F00";
3874
- const removingLabel = onDelete === void 0 ? "\u5220\u9664\u4E2D\u2026" : "\u65AD\u5F00\u4E2D\u2026";
4502
+ const removeLabel = onDelete === void 0 ? tr("\u5220\u9664") : tr("\u65AD\u5F00");
4503
+ const removingLabel = onDelete === void 0 ? tr("\u5220\u9664\u4E2D\u2026") : tr("\u65AD\u5F00\u4E2D\u2026");
3875
4504
  const removeClass = onDelete === void 0 ? "dshc-btn dshc-btn-md dshc-btn-outline dshc-btn-danger" : "dshc-btn dshc-btn-md dshc-btn-outline";
3876
- (0, import_react.useEffect)(() => {
4505
+ (0, import_react2.useEffect)(() => {
3877
4506
  setCopied(null);
3878
4507
  setCopyFailed(null);
3879
4508
  setShowAllTools(false);
3880
4509
  }, [card.id]);
3881
- (0, import_react.useEffect)(() => {
4510
+ (0, import_react2.useEffect)(() => {
3882
4511
  const onKey = (event) => {
3883
4512
  if (event.key === "Escape" && !escLocked) onClose();
3884
4513
  };
@@ -3910,8 +4539,8 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
3910
4539
  above
3911
4540
  });
3912
4541
  };
3913
- const exampleTipText = exampleTip === null ? null : exampleTip.action === "try" ? "\u53BB\u8BD5\u8BD5" : copied === exampleTip.index ? "\u5DF2\u590D\u5236" : copyFailed === exampleTip.index ? "\u590D\u5236\u5931\u8D25" : "\u590D\u5236";
3914
- const statusText = connecting && connection !== void 0 && connection.error === void 0 ? "\u8FDE\u63A5\u4E2D" : connection === void 0 ? "\u672A\u8FDE\u63A5" : unauthorized ? authorizing ? "\u6388\u6743\u4E2D" : instancePending ? "\u5F85\u914D\u7F6E" : "\u672A\u6388\u6743" : disabled ? "\u5DF2\u505C\u7528" : connected ? "\u5DF2\u8FDE\u63A5" : "\u8FDE\u63A5\u5931\u8D25";
4542
+ const exampleTipText = exampleTip === null ? null : exampleTip.action === "try" ? tr("\u53BB\u8BD5\u8BD5") : copied === exampleTip.index ? tr("\u5DF2\u590D\u5236") : copyFailed === exampleTip.index ? tr("\u590D\u5236\u5931\u8D25") : tr("\u590D\u5236");
4543
+ const statusText = connecting && connection !== void 0 && connection.error === void 0 ? tr("\u8FDE\u63A5\u4E2D") : connection === void 0 ? tr("\u672A\u8FDE\u63A5") : unauthorized ? authorizing ? tr("\u6388\u6743\u4E2D") : instancePending ? tr("\u5F85\u914D\u7F6E") : tr("\u672A\u6388\u6743") : disabled ? tr("\u5DF2\u505C\u7528") : connected ? tr("\u5DF2\u8FDE\u63A5") : tr("\u8FDE\u63A5\u5931\u8D25");
3915
4544
  const statusClass = connection === void 0 || unauthorized || disabled ? "dshc-status-pill" : connected ? "dshc-status-pill dshc-status-pill-connected" : "dshc-status-pill dshc-status-pill-error";
3916
4545
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3917
4546
  "div",
@@ -3926,39 +4555,43 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
3926
4555
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-avatar dshc-dialog-avatar dshc-dialog-avatar-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ConnectorLogo, { card }) }),
3927
4556
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-title", children: [
3928
4557
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: card.name }),
3929
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: [card.vendor, card.category].filter(Boolean).join(" \xB7 ") })
4558
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: [card.vendor, card.categoryLabel ?? tr(card.category)].filter(Boolean).join(" \xB7 ") })
3930
4559
  ] }),
3931
4560
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${statusClass} dshc-dialog-status-pill`, children: statusText }),
3932
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
4561
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
3933
4562
  ] }),
3934
4563
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
3935
4564
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-body", children: card.description ?? card.summary }),
3936
4565
  connection?.error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: connection.error }),
3937
- needsInstanceConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: card.instance?.presets === void 0 ? `\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u586B\u5199\u5B8C\u6574\u7684 MCP \u5730\u5740\uFF1B\u5730\u5740\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002` : `\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u9009\u62E9${instanceNoun(card)}\uFF1B\u9009\u62E9\u7ED3\u679C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002` }),
4566
+ needsInstanceConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: card.instance?.presets === void 0 ? tr("\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u586B\u5199\u5B8C\u6574\u7684 MCP \u5730\u5740\uFF1B\u5730\u5740\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002") : tr("\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u9009\u62E9{v0}\uFF1B\u9009\u62E9\u7ED3\u679C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002", { v0: instanceNoun(card) }) }),
3938
4567
  needsToken && connection !== void 0 && !connection.authorized && !needsInstanceConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
3939
- "\u70B9\u51FB\u300C\u6388\u6743\u300D\u540E\u586B\u5199 ",
4568
+ tr("\u70B9\u51FB\u300C\u6388\u6743\u300D\u540E\u586B\u5199"),
4569
+ " ",
3940
4570
  tokenLabel(card),
3941
- "\uFF1B\u4EE4\u724C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002"
4571
+ tr("\uFF1B\u4EE4\u724C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002")
3942
4572
  ] }),
3943
4573
  needsToken && connection?.authorized === true && connection.error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
3944
- "\u70B9\u51FB\u300C\u66F4\u65B0\u4EE4\u724C\u300D\u91CD\u65B0\u586B\u5199 ",
4574
+ tr("\u70B9\u51FB\u300C\u66F4\u65B0\u4EE4\u724C\u300D\u91CD\u65B0\u586B\u5199"),
4575
+ " ",
3945
4576
  tokenLabel(card),
3946
4577
  "\u3002"
3947
4578
  ] }),
3948
4579
  oauth && connection === void 0 && !showingInstall && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
3949
- "\u70B9\u51FB\u300C\u5B89\u88C5\u300D\u540E\u4F1A\u6253\u5F00\u9ED8\u8BA4\u6D4F\u89C8\u5668\u5B8C\u6210 ",
4580
+ tr("\u70B9\u51FB\u300C\u5B89\u88C5\u300D\u540E\u4F1A\u6253\u5F00\u9ED8\u8BA4\u6D4F\u89C8\u5668\u5B8C\u6210"),
4581
+ " ",
3950
4582
  card.name,
3951
- " \u6388\u6743\u3002"
4583
+ " ",
4584
+ tr("\u6388\u6743\u3002")
3952
4585
  ] }),
3953
- oauth && unauthorized && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: authorizing ? "\u5DF2\u6253\u5F00\u6388\u6743\u9875\uFF0C\u5B8C\u6210\u6388\u6743\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\uFF1B\u5982\u5DF2\u5173\u95ED\u6388\u6743\u9875\uFF0C\u8BF7\u70B9\u300C\u53D6\u6D88\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002" : needsInstanceConfig ? `\u5DF2\u5B89\u88C5\uFF0C\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u9009\u62E9${instanceNoun(card)}\u540E\u5F00\u59CB\u6388\u6743\u3002` : `\u5DF2\u5B89\u88C5\uFF0C\u70B9\u51FB\u6388\u6743\u540E\u5728\u6D4F\u89C8\u5668\u5B8C\u6210 ${card.name} \u6388\u6743\u3002` }),
4586
+ oauth && unauthorized && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: authorizing ? tr("\u5DF2\u6253\u5F00\u6388\u6743\u9875\uFF0C\u5B8C\u6210\u6388\u6743\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\uFF1B\u5982\u5DF2\u5173\u95ED\u6388\u6743\u9875\uFF0C\u8BF7\u70B9\u300C\u53D6\u6D88\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002") : needsInstanceConfig ? tr("\u5DF2\u5B89\u88C5\uFF0C\u70B9\u51FB\u300C\u914D\u7F6E\u300D\u9009\u62E9{v0}\u540E\u5F00\u59CB\u6388\u6743\u3002", { v0: instanceNoun(card) }) : tr("\u5DF2\u5B89\u88C5\uFF0C\u70B9\u51FB\u6388\u6743\u540E\u5728\u6D4F\u89C8\u5668\u5B8C\u6210 {v0} \u6388\u6743\u3002", { v0: card.name }) }),
3954
4587
  authorizeLink !== null && authorizing && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
3955
- "\u6CA1\u6709\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF1F",
3956
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "dshc-link", href: authorizeLink, target: "_blank", rel: "noreferrer", children: "\u70B9\u6B64\u6388\u6743" })
4588
+ tr("\u6CA1\u6709\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF1F"),
4589
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "dshc-link", href: authorizeLink, target: "_blank", rel: "noreferrer", children: tr("\u70B9\u6B64\u6388\u6743") })
3957
4590
  ] }),
3958
4591
  error !== null && error !== connection?.error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: error }),
3959
4592
  toolDetails.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "dshc-tools", children: [
3960
4593
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-tools-head", children: [
3961
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u53EF\u7528\u5DE5\u5177" }),
4594
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: tr("\u53EF\u7528\u5DE5\u5177") }),
3962
4595
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-tools-count", children: toolQueryText === "" ? toolDetails.length : `${filteredTools.length}/${toolDetails.length}` }),
3963
4596
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-tools-search-wrap", children: [
3964
4597
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -3973,8 +4606,8 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
3973
4606
  "data-1p-ignore": "true",
3974
4607
  "data-bwignore": "true",
3975
4608
  spellCheck: false,
3976
- "aria-label": "\u641C\u7D22\u5DE5\u5177",
3977
- placeholder: "\u641C\u7D22\u5DE5\u5177",
4609
+ "aria-label": tr("\u641C\u7D22\u5DE5\u5177"),
4610
+ placeholder: tr("\u641C\u7D22\u5DE5\u5177"),
3978
4611
  value: toolQuery,
3979
4612
  onChange: (event) => setToolQuery(event.target.value)
3980
4613
  }
@@ -3984,8 +4617,8 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
3984
4617
  {
3985
4618
  type: "button",
3986
4619
  className: "dshc-tools-search-clear",
3987
- "aria-label": "\u6E05\u7A7A\u641C\u7D22",
3988
- title: "\u6E05\u7A7A\u641C\u7D22",
4620
+ "aria-label": tr("\u6E05\u7A7A\u641C\u7D22"),
4621
+ title: tr("\u6E05\u7A7A\u641C\u7D22"),
3989
4622
  onClick: () => {
3990
4623
  setToolQuery("");
3991
4624
  toolSearchRef.current?.focus();
@@ -4004,7 +4637,7 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4004
4637
  },
4005
4638
  tool.name
4006
4639
  )),
4007
- toolQueryText !== "" && filteredTools.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-tools-empty", children: "\u6CA1\u6709\u5339\u914D\u7684\u5DE5\u5177" })
4640
+ toolQueryText !== "" && filteredTools.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-tools-empty", children: tr("\u6CA1\u6709\u5339\u914D\u7684\u5DE5\u5177") })
4008
4641
  ] }),
4009
4642
  toolQueryText === "" && toolDetails.length > 4 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4010
4643
  "button",
@@ -4012,14 +4645,14 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4012
4645
  type: "button",
4013
4646
  className: "dshc-tools-toggle",
4014
4647
  onClick: () => setShowAllTools((current) => !current),
4015
- children: showAllTools ? "\u6536\u8D77" : `\u5C55\u5F00\u5168\u90E8 ${toolDetails.length} \u4E2A`
4648
+ children: showAllTools ? tr("\u6536\u8D77") : tr("\u5C55\u5F00\u5168\u90E8 {v0} \u4E2A", { v0: toolDetails.length })
4016
4649
  }
4017
4650
  )
4018
4651
  ] }),
4019
- disabled && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u5DF2\u505C\u7528\uFF0C\u542F\u7528\u540E\u4F1A\u91CD\u65B0\u6CE8\u518C\u5DE5\u5177\u3002" }),
4020
- connected && toolDetails.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: connecting ? "\u6B63\u5728\u8FDE\u63A5\u2026" : "\u6B63\u5728\u6CE8\u518C\u5DE5\u5177\u2026" }),
4652
+ disabled && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u5DF2\u505C\u7528\uFF0C\u542F\u7528\u540E\u4F1A\u91CD\u65B0\u6CE8\u518C\u5DE5\u5177\u3002") }),
4653
+ connected && toolDetails.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: connecting ? tr("\u6B63\u5728\u8FDE\u63A5\u2026") : tr("\u6B63\u5728\u6CE8\u518C\u5DE5\u5177\u2026") }),
4021
4654
  examples.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "dshc-examples", children: [
4022
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u8BD5\u8BD5\u8FD9\u6837\u7528" }),
4655
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: tr("\u8BD5\u8BD5\u8FD9\u6837\u7528") }),
4023
4656
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-example-list", children: examples.map((example, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-example", children: [
4024
4657
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-example-text", children: example }),
4025
4658
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-example-actions", children: [
@@ -4028,7 +4661,7 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4028
4661
  {
4029
4662
  type: "button",
4030
4663
  className: copied === index ? "dshc-example-action dshc-example-action-success" : copyFailed === index ? "dshc-example-action dshc-example-action-error" : "dshc-example-action",
4031
- "aria-label": `\u590D\u5236\u793A\u4F8B\uFF1A${example}`,
4664
+ "aria-label": tr("\u590D\u5236\u793A\u4F8B\uFF1A{v0}", { v0: example }),
4032
4665
  onMouseEnter: (event) => showExampleTip(event.currentTarget, index, "copy"),
4033
4666
  onMouseLeave: () => setExampleTip(null),
4034
4667
  onFocus: (event) => showExampleTip(event.currentTarget, index, "copy"),
@@ -4042,7 +4675,7 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4042
4675
  {
4043
4676
  type: "button",
4044
4677
  className: "dshc-example-action",
4045
- "aria-label": `\u53BB\u8BD5\u8BD5\uFF1A${example}`,
4678
+ "aria-label": tr("\u53BB\u8BD5\u8BD5\uFF1A{v0}", { v0: example }),
4046
4679
  disabled: !canTry,
4047
4680
  onMouseEnter: (event) => showExampleTip(event.currentTarget, index, "try"),
4048
4681
  onMouseLeave: () => setExampleTip(null),
@@ -4057,26 +4690,26 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4057
4690
  ] })
4058
4691
  ] }),
4059
4692
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-actions", children: [
4060
- onDelete !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost dshc-btn-danger", disabled: busy, onClick: onDelete, children: "\u5220\u9664" }),
4061
- onEditCustom !== void 0 && !authorizing && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost", disabled: busy, onClick: onEditCustom, children: "\u7F16\u8F91\u914D\u7F6E" }),
4693
+ onDelete !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost dshc-btn-danger", disabled: busy, onClick: onDelete, children: tr("\u5220\u9664") }),
4694
+ onEditCustom !== void 0 && !authorizing && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost", disabled: busy, onClick: onEditCustom, children: tr("\u7F16\u8F91\u914D\u7F6E") }),
4062
4695
  onReconfigureInstance !== void 0 && connection !== void 0 && !authorizing && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost", disabled: busy, onClick: onReconfigureInstance, children: [
4063
- "\u66F4\u6362",
4696
+ tr("\u66F4\u6362"),
4064
4697
  instanceNoun(card)
4065
4698
  ] }),
4066
- oauth && connection?.authorized === true && !authorizing && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost", disabled: busy, onClick: onRevoke, children: "\u53D6\u6D88\u6388\u6743" }),
4699
+ oauth && connection?.authorized === true && !authorizing && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost", disabled: busy, onClick: onRevoke, children: tr("\u53D6\u6D88\u6388\u6743") }),
4067
4700
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dialog-actions-right", children: [
4068
4701
  authorizing && connection?.authorized === true && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4069
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onCancelAuthorize, children: "\u53D6\u6D88\u6388\u6743" }),
4702
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onCancelAuthorize, children: tr("\u53D6\u6D88\u6388\u6743") }),
4070
4703
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: true, children: [
4071
4704
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4072
- "\u6388\u6743\u4E2D\u2026"
4705
+ tr("\u6388\u6743\u4E2D\u2026")
4073
4706
  ] })
4074
4707
  ] }),
4075
4708
  unauthorized && (authorizing ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4076
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onCancelAuthorize, children: "\u53D6\u6D88\u6388\u6743" }),
4709
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onCancelAuthorize, children: tr("\u53D6\u6D88\u6388\u6743") }),
4077
4710
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: true, children: [
4078
4711
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4079
- "\u6388\u6743\u4E2D\u2026"
4712
+ tr("\u6388\u6743\u4E2D\u2026")
4080
4713
  ] })
4081
4714
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4082
4715
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: removeClass, disabled: busy, onClick: onDisconnect, children: removeLabel }),
@@ -4089,11 +4722,12 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4089
4722
  onClick: onConfigureInstance,
4090
4723
  children: [
4091
4724
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4092
- pending ? "\u914D\u7F6E\u4E2D\u2026" : "\u914D\u7F6E"
4725
+ pending ? tr("\u914D\u7F6E\u4E2D\u2026") : tr("\u914D\u7F6E")
4093
4726
  ]
4094
4727
  }
4095
4728
  ) : oauth ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: busy, onClick: onAuthorize, children: [
4096
- "\u6388\u6743 ",
4729
+ tr("\u6388\u6743"),
4730
+ " ",
4097
4731
  card.name
4098
4732
  ] }) : needsToken ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4099
4733
  "button",
@@ -4104,7 +4738,7 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4104
4738
  onClick: onUpdateCredential,
4105
4739
  children: [
4106
4740
  busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4107
- busy ? "\u8FDE\u63A5\u4E2D\u2026" : `\u6388\u6743 ${card.name}`
4741
+ busy ? tr("\u8FDE\u63A5\u4E2D\u2026") : tr("\u6388\u6743 {v0}", { v0: card.name })
4108
4742
  ]
4109
4743
  }
4110
4744
  ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -4114,7 +4748,7 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4114
4748
  className: "dshc-btn dshc-btn-md dshc-btn-primary",
4115
4749
  disabled: busy,
4116
4750
  onClick: () => onConnect(void 0),
4117
- children: pending ? "\u8FDE\u63A5\u4E2D\u2026" : "\u8FDE\u63A5"
4751
+ children: pending ? tr("\u8FDE\u63A5\u4E2D\u2026") : tr("\u8FDE\u63A5")
4118
4752
  }
4119
4753
  )
4120
4754
  ] })),
@@ -4127,26 +4761,26 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4127
4761
  className: "dshc-btn dshc-btn-md dshc-btn-primary",
4128
4762
  disabled: busy,
4129
4763
  onClick: () => onToggle(true),
4130
- children: toggling ? "\u542F\u7528\u4E2D\u2026" : "\u542F\u7528"
4764
+ children: toggling ? tr("\u542F\u7528\u4E2D\u2026") : tr("\u542F\u7528")
4131
4765
  }
4132
4766
  )
4133
4767
  ] }),
4134
4768
  !authorizing && connected && (noneConnecting ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4135
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: "\u53D6\u6D88" }),
4769
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: tr("\u53D6\u6D88") }),
4136
4770
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: true, children: [
4137
4771
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4138
- "\u8FDE\u63A5\u4E2D\u2026"
4772
+ tr("\u8FDE\u63A5\u4E2D\u2026")
4139
4773
  ] })
4140
4774
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4141
4775
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: removeClass, disabled: busy, onClick: onDisconnect, children: pending && !connecting ? removingLabel : removeLabel }),
4142
- oauth && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost", disabled: busy, onClick: onReauthorize, children: "\u91CD\u65B0\u6388\u6743" }),
4776
+ oauth && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost", disabled: busy, onClick: onReauthorize, children: tr("\u91CD\u65B0\u6388\u6743") }),
4143
4777
  needsToken && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-ghost", disabled: busy, onClick: onUpdateCredential, children: [
4144
4778
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4145
- pending ? "\u66F4\u65B0\u4E2D\u2026" : "\u66F4\u65B0\u4EE4\u724C"
4779
+ pending ? tr("\u66F4\u65B0\u4E2D\u2026") : tr("\u66F4\u65B0\u4EE4\u724C")
4146
4780
  ] }),
4147
4781
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-primary", disabled: busy, onClick: onClose, children: [
4148
4782
  connecting && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4149
- connecting ? "\u8FDE\u63A5\u4E2D\u2026" : "\u5B8C\u6210"
4783
+ connecting ? tr("\u8FDE\u63A5\u4E2D\u2026") : tr("\u5B8C\u6210")
4150
4784
  ] })
4151
4785
  ] })),
4152
4786
  !authorizing && connection !== void 0 && connection.authorized && !connected && !disabled && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
@@ -4158,7 +4792,7 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4158
4792
  className: "dshc-btn dshc-btn-md dshc-btn-primary",
4159
4793
  disabled: busy,
4160
4794
  onClick: onReauthorize,
4161
- children: pending ? "\u6388\u6743\u4E2D\u2026" : "\u91CD\u65B0\u6388\u6743"
4795
+ children: pending ? tr("\u6388\u6743\u4E2D\u2026") : tr("\u91CD\u65B0\u6388\u6743")
4162
4796
  }
4163
4797
  ) : needsToken ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4164
4798
  "button",
@@ -4169,7 +4803,7 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4169
4803
  onClick: onUpdateCredential,
4170
4804
  children: [
4171
4805
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4172
- pending ? "\u66F4\u65B0\u4E2D\u2026" : "\u66F4\u65B0\u4EE4\u724C"
4806
+ pending ? tr("\u66F4\u65B0\u4E2D\u2026") : tr("\u66F4\u65B0\u4EE4\u724C")
4173
4807
  ]
4174
4808
  }
4175
4809
  ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -4179,12 +4813,12 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4179
4813
  className: "dshc-btn dshc-btn-md dshc-btn-primary",
4180
4814
  disabled: busy,
4181
4815
  onClick: () => onConnect(void 0),
4182
- children: pending ? "\u91CD\u8BD5\u4E2D\u2026" : "\u91CD\u8BD5"
4816
+ children: pending ? tr("\u91CD\u8BD5\u4E2D\u2026") : tr("\u91CD\u8BD5")
4183
4817
  }
4184
4818
  )
4185
4819
  ] }),
4186
4820
  connection === void 0 && showingInstall && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4187
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", disabled: busy, onClick: onCancelInstall, children: "\u53D6\u6D88" }),
4821
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", disabled: busy, onClick: onCancelInstall, children: tr("\u53D6\u6D88") }),
4188
4822
  oauth && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4189
4823
  "button",
4190
4824
  {
@@ -4194,13 +4828,13 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4194
4828
  onClick: onInstallOAuth,
4195
4829
  children: [
4196
4830
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4197
- pending ? "\u5B89\u88C5\u4E2D\u2026" : "\u5B89\u88C5"
4831
+ pending ? tr("\u5B89\u88C5\u4E2D\u2026") : tr("\u5B89\u88C5")
4198
4832
  ]
4199
4833
  }
4200
4834
  )
4201
4835
  ] }),
4202
4836
  connection === void 0 && !showingInstall && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4203
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: "\u5173\u95ED" }),
4837
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: tr("\u5173\u95ED") }),
4204
4838
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4205
4839
  "button",
4206
4840
  {
@@ -4210,7 +4844,7 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4210
4844
  onClick: onBeginInstall,
4211
4845
  children: [
4212
4846
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4213
- pending ? "\u5B89\u88C5\u4E2D\u2026" : "\u5B89\u88C5"
4847
+ pending ? tr("\u5B89\u88C5\u4E2D\u2026") : tr("\u5B89\u88C5")
4214
4848
  ]
4215
4849
  }
4216
4850
  )
@@ -4236,15 +4870,15 @@ function ConnectorDialog({ card, connection, pending, toggling, authorizing, con
4236
4870
  function InstanceDialog({ card, mode, pending, error, onClose, onSubmit }) {
4237
4871
  const instance = card.instance;
4238
4872
  const presets = instance?.presets;
4239
- const [instanceUrl, setInstanceUrl] = (0, import_react.useState)(presets?.[0]?.url ?? "");
4873
+ const [instanceUrl, setInstanceUrl] = (0, import_react2.useState)(presets?.[0]?.url ?? "");
4240
4874
  const config = mode === "config";
4241
4875
  const noun = instanceNoun(card);
4242
4876
  const selectedPreset = presets?.find((item) => item.url === instanceUrl);
4243
- const title = presets === void 0 ? config ? "\u586B\u5199\u5730\u5740" : "\u66F4\u6362\u5730\u5740" : config ? `\u9009\u62E9${noun}` : `\u66F4\u6362${noun}`;
4244
- const submitLabel = config ? isOAuthCard(card) ? "\u4FDD\u5B58\u5E76\u6388\u6743" : isTokenCard(card) ? "\u4FDD\u5B58\u5E76\u7EE7\u7EED" : "\u4FDD\u5B58\u5E76\u8FDE\u63A5" : isOAuthCard(card) ? "\u4FDD\u5B58\u5E76\u91CD\u65B0\u6388\u6743" : isTokenCard(card) ? "\u4FDD\u5B58" : "\u4FDD\u5B58\u5E76\u91CD\u65B0\u8FDE\u63A5";
4245
- const keepLocal = presets === void 0 ? "\u5730\u5740\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002" : "\u9009\u62E9\u7ED3\u679C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002";
4246
- const configHint = isOAuthCard(card) ? `\u4FDD\u5B58\u540E\u4F1A\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\u5B8C\u6210\u6388\u6743\uFF1B${keepLocal}` : isTokenCard(card) ? `\u4FDD\u5B58\u540E\u7EE7\u7EED\u586B\u5199\u4EE4\u724C\uFF1B${keepLocal}` : `\u4FDD\u5B58\u540E\u76F4\u63A5\u8FDE\u63A5\uFF1B${keepLocal}`;
4247
- (0, import_react.useEffect)(() => {
4877
+ const title = presets === void 0 ? config ? tr("\u586B\u5199\u5730\u5740") : tr("\u66F4\u6362\u5730\u5740") : config ? tr("\u9009\u62E9{v0}", { v0: noun }) : tr("\u66F4\u6362{v0}", { v0: noun });
4878
+ const submitLabel = config ? isOAuthCard(card) ? tr("\u4FDD\u5B58\u5E76\u6388\u6743") : isTokenCard(card) ? tr("\u4FDD\u5B58\u5E76\u7EE7\u7EED") : tr("\u4FDD\u5B58\u5E76\u8FDE\u63A5") : isOAuthCard(card) ? tr("\u4FDD\u5B58\u5E76\u91CD\u65B0\u6388\u6743") : isTokenCard(card) ? tr("\u4FDD\u5B58") : tr("\u4FDD\u5B58\u5E76\u91CD\u65B0\u8FDE\u63A5");
4879
+ const keepLocal = presets === void 0 ? tr("\u5730\u5740\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002") : tr("\u9009\u62E9\u7ED3\u679C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002");
4880
+ const configHint = isOAuthCard(card) ? tr("\u4FDD\u5B58\u540E\u4F1A\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\u5B8C\u6210\u6388\u6743\uFF1B{v0}", { v0: keepLocal }) : isTokenCard(card) ? tr("\u4FDD\u5B58\u540E\u7EE7\u7EED\u586B\u5199\u4EE4\u724C\uFF1B{v0}", { v0: keepLocal }) : tr("\u4FDD\u5B58\u540E\u76F4\u63A5\u8FDE\u63A5\uFF1B{v0}", { v0: keepLocal });
4881
+ (0, import_react2.useEffect)(() => {
4248
4882
  const onKey = (event) => {
4249
4883
  if (event.key === "Escape" && !pending) onClose();
4250
4884
  };
@@ -4268,7 +4902,7 @@ function InstanceDialog({ card, mode, pending, error, onClose, onSubmit }) {
4268
4902
  className: "dshc-dialog dshc-dialog-instance",
4269
4903
  role: "dialog",
4270
4904
  "aria-modal": "true",
4271
- "aria-label": `${config ? "\u586B\u5199" : "\u66F4\u6362"} ${card.name} ${noun}`,
4905
+ "aria-label": `${config ? tr("\u586B\u5199") : tr("\u66F4\u6362")} ${card.name} ${noun}`,
4272
4906
  noValidate: true,
4273
4907
  onSubmit: (event) => {
4274
4908
  event.preventDefault();
@@ -4281,12 +4915,12 @@ function InstanceDialog({ card, mode, pending, error, onClose, onSubmit }) {
4281
4915
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: title }),
4282
4916
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: card.name })
4283
4917
  ] }),
4284
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", disabled: pending, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
4918
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), disabled: pending, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
4285
4919
  ] }),
4286
4920
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
4287
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: config ? configHint : "\u66F4\u6362\u540E\u4F1A\u65AD\u5F00\u5F53\u524D\u8FDE\u63A5\u3001\u6E05\u9664\u5DF2\u6709\u51ED\u636E\uFF0C\u9700\u8981\u91CD\u65B0\u914D\u7F6E\u6216\u6388\u6743\u3002" }),
4921
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: config ? configHint : tr("\u66F4\u6362\u540E\u4F1A\u65AD\u5F00\u5F53\u524D\u8FDE\u63A5\u3001\u6E05\u9664\u5DF2\u6709\u51ED\u636E\uFF0C\u9700\u8981\u91CD\u65B0\u914D\u7F6E\u6216\u6388\u6743\u3002") }),
4288
4922
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-field", children: [
4289
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: instance?.label ?? "\u670D\u52A1\u5730\u5740" }),
4923
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: instance?.label ?? tr("\u670D\u52A1\u5730\u5740") }),
4290
4924
  presets === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4291
4925
  "input",
4292
4926
  {
@@ -4322,11 +4956,11 @@ function InstanceDialog({ card, mode, pending, error, onClose, onSubmit }) {
4322
4956
  instance.help.hint
4323
4957
  ] })
4324
4958
  ] }),
4325
- presets === void 0 && instanceUrl.trim().startsWith("http://") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u975E https \u5730\u5740\u4F1A\u660E\u6587\u4F20\u8F93\uFF0C\u8BF7\u786E\u8BA4\u7F51\u7EDC\u53EF\u4FE1\u3002" }),
4959
+ presets === void 0 && instanceUrl.trim().startsWith("http://") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u975E https \u5730\u5740\u4F1A\u660E\u6587\u4F20\u8F93\uFF0C\u8BF7\u786E\u8BA4\u7F51\u7EDC\u53EF\u4FE1\u3002") }),
4326
4960
  error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: error })
4327
4961
  ] }),
4328
4962
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dialog-actions-right", children: [
4329
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", disabled: pending, onClick: onClose, children: pending ? "\u5173\u95ED" : "\u53D6\u6D88" }),
4963
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", disabled: pending, onClick: onClose, children: pending ? tr("\u5173\u95ED") : tr("\u53D6\u6D88") }),
4330
4964
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4331
4965
  "button",
4332
4966
  {
@@ -4335,7 +4969,7 @@ function InstanceDialog({ card, mode, pending, error, onClose, onSubmit }) {
4335
4969
  disabled: pending || instanceUrl.trim() === "",
4336
4970
  children: [
4337
4971
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4338
- pending ? "\u4FDD\u5B58\u4E2D\u2026" : submitLabel
4972
+ pending ? tr("\u4FDD\u5B58\u4E2D\u2026") : submitLabel
4339
4973
  ]
4340
4974
  }
4341
4975
  )
@@ -4347,12 +4981,12 @@ function InstanceDialog({ card, mode, pending, error, onClose, onSubmit }) {
4347
4981
  );
4348
4982
  }
4349
4983
  function CredentialDialog({ card, mode, saving, error, onClose, onSubmit }) {
4350
- const [token, setToken] = (0, import_react.useState)("");
4351
- const [tokenVisible, setTokenVisible] = (0, import_react.useState)(false);
4984
+ const [token, setToken] = (0, import_react2.useState)("");
4985
+ const [tokenVisible, setTokenVisible] = (0, import_react2.useState)(false);
4352
4986
  const help = tokenHelp(card);
4353
- const title = mode === "install" ? "\u586B\u5199\u4EE4\u724C" : "\u66F4\u65B0\u4EE4\u724C";
4354
- const submitLabel = mode === "install" ? "\u8FDE\u63A5" : "\u4FDD\u5B58";
4355
- (0, import_react.useEffect)(() => {
4987
+ const title = mode === "install" ? tr("\u586B\u5199\u4EE4\u724C") : tr("\u66F4\u65B0\u4EE4\u724C");
4988
+ const submitLabel = mode === "install" ? tr("\u8FDE\u63A5") : tr("\u4FDD\u5B58");
4989
+ (0, import_react2.useEffect)(() => {
4356
4990
  const onKey = (event) => {
4357
4991
  if (event.key === "Escape") onClose();
4358
4992
  };
@@ -4376,7 +5010,7 @@ function CredentialDialog({ card, mode, saving, error, onClose, onSubmit }) {
4376
5010
  className: "dshc-dialog dshc-dialog-credential",
4377
5011
  role: "dialog",
4378
5012
  "aria-modal": "true",
4379
- "aria-label": mode === "install" ? `\u586B\u5199 ${card.name} \u4EE4\u724C` : `\u66F4\u65B0 ${card.name} \u4EE4\u724C`,
5013
+ "aria-label": mode === "install" ? tr("\u586B\u5199 {v0} \u4EE4\u724C", { v0: card.name }) : tr("\u66F4\u65B0 {v0} \u4EE4\u724C", { v0: card.name }),
4380
5014
  children: [
4381
5015
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head", children: [
4382
5016
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-avatar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ConnectorLogo, { card, size: 28 }) }),
@@ -4384,10 +5018,10 @@ function CredentialDialog({ card, mode, saving, error, onClose, onSubmit }) {
4384
5018
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: title }),
4385
5019
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: card.name })
4386
5020
  ] }),
4387
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
5021
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
4388
5022
  ] }),
4389
5023
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
4390
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: mode === "install" ? `\u586B\u5199 ${tokenLabel(card)} \u540E\u8FDE\u63A5\uFF1B\u4EE4\u724C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002` : "\u5F53\u524D\u4EE4\u724C\u4E0D\u4F1A\u663E\u793A\uFF1B\u4FDD\u5B58\u65B0\u4EE4\u724C\u540E\u7ACB\u5373\u66FF\u6362\u3002" }),
5024
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: mode === "install" ? tr("\u586B\u5199 {v0} \u540E\u8FDE\u63A5\uFF1B\u4EE4\u724C\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002", { v0: tokenLabel(card) }) : tr("\u5F53\u524D\u4EE4\u724C\u4E0D\u4F1A\u663E\u793A\uFF1B\u4FDD\u5B58\u65B0\u4EE4\u724C\u540E\u7ACB\u5373\u66FF\u6362\u3002") }),
4391
5025
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-field", children: [
4392
5026
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { htmlFor: "dshc-credential-token", children: tokenLabel(card) }),
4393
5027
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-field-control", children: [
@@ -4403,7 +5037,7 @@ function CredentialDialog({ card, mode, saving, error, onClose, onSubmit }) {
4403
5037
  "data-1p-ignore": "true",
4404
5038
  "data-bwignore": "true",
4405
5039
  disabled: saving,
4406
- placeholder: mode === "install" ? "\u7C98\u8D34\u4EE4\u724C" : "\u7C98\u8D34\u65B0\u4EE4\u724C",
5040
+ placeholder: mode === "install" ? tr("\u7C98\u8D34\u4EE4\u724C") : tr("\u7C98\u8D34\u65B0\u4EE4\u724C"),
4407
5041
  value: token,
4408
5042
  onChange: (event) => setToken(event.target.value),
4409
5043
  onKeyDown: (event) => {
@@ -4419,8 +5053,8 @@ function CredentialDialog({ card, mode, saving, error, onClose, onSubmit }) {
4419
5053
  {
4420
5054
  type: "button",
4421
5055
  className: "dshc-field-reveal",
4422
- "aria-label": tokenVisible ? "\u9690\u85CF\u4EE4\u724C" : "\u663E\u793A\u4EE4\u724C",
4423
- title: tokenVisible ? "\u9690\u85CF\u4EE4\u724C" : "\u663E\u793A\u4EE4\u724C",
5056
+ "aria-label": tokenVisible ? tr("\u9690\u85CF\u4EE4\u724C") : tr("\u663E\u793A\u4EE4\u724C"),
5057
+ title: tokenVisible ? tr("\u9690\u85CF\u4EE4\u724C") : tr("\u663E\u793A\u4EE4\u724C"),
4424
5058
  "aria-pressed": tokenVisible,
4425
5059
  disabled: saving,
4426
5060
  onMouseDown: (event) => event.preventDefault(),
@@ -4438,10 +5072,10 @@ function CredentialDialog({ card, mode, saving, error, onClose, onSubmit }) {
4438
5072
  ] })
4439
5073
  ] }),
4440
5074
  error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: error }),
4441
- saving && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u65AD\u8FDE\u63A5\uFF0C\u7ED3\u679C\u4F1A\u663E\u793A\u5728\u5361\u7247\u4E0A\u3002" })
5075
+ saving && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u5173\u95ED\u5F39\u7A97\u4E0D\u4F1A\u4E2D\u65AD\u8FDE\u63A5\uFF0C\u7ED3\u679C\u4F1A\u663E\u793A\u5728\u5361\u7247\u4E0A\u3002") })
4442
5076
  ] }),
4443
5077
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dialog-actions-right", children: [
4444
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: saving ? "\u5173\u95ED" : "\u53D6\u6D88" }),
5078
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: saving ? tr("\u5173\u95ED") : tr("\u53D6\u6D88") }),
4445
5079
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4446
5080
  "button",
4447
5081
  {
@@ -4451,7 +5085,7 @@ function CredentialDialog({ card, mode, saving, error, onClose, onSubmit }) {
4451
5085
  onClick: submit,
4452
5086
  children: [
4453
5087
  saving && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4454
- saving ? mode === "install" ? "\u8FDE\u63A5\u4E2D\u2026" : "\u4FDD\u5B58\u4E2D\u2026" : submitLabel
5088
+ saving ? mode === "install" ? tr("\u8FDE\u63A5\u4E2D\u2026") : tr("\u4FDD\u5B58\u4E2D\u2026") : submitLabel
4455
5089
  ]
4456
5090
  }
4457
5091
  )
@@ -4463,13 +5097,13 @@ function CredentialDialog({ card, mode, saving, error, onClose, onSubmit }) {
4463
5097
  );
4464
5098
  }
4465
5099
  function OAuthAppDialog({ card, saving, error, onClose, onSubmit }) {
4466
- const [clientId, setClientId] = (0, import_react.useState)("");
4467
- const [clientSecret, setClientSecret] = (0, import_react.useState)("");
4468
- const [secretVisible, setSecretVisible] = (0, import_react.useState)(false);
4469
- const [copied, setCopied] = (0, import_react.useState)(false);
5100
+ const [clientId, setClientId] = (0, import_react2.useState)("");
5101
+ const [clientSecret, setClientSecret] = (0, import_react2.useState)("");
5102
+ const [secretVisible, setSecretVisible] = (0, import_react2.useState)(false);
5103
+ const [copied, setCopied] = (0, import_react2.useState)(false);
4470
5104
  const help = card.auth.type === "oauth2" ? card.auth.help : void 0;
4471
5105
  const callback = oauthRedirectUri(card);
4472
- (0, import_react.useEffect)(() => {
5106
+ (0, import_react2.useEffect)(() => {
4473
5107
  const onKey = (event) => {
4474
5108
  if (event.key === "Escape") onClose();
4475
5109
  };
@@ -4493,26 +5127,26 @@ function OAuthAppDialog({ card, saving, error, onClose, onSubmit }) {
4493
5127
  onMouseDown: (event) => {
4494
5128
  if (event.target === event.currentTarget) onClose();
4495
5129
  },
4496
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog dshc-dialog-credential", role: "dialog", "aria-modal": "true", "aria-label": `\u914D\u7F6E ${card.name} \u5E94\u7528`, children: [
5130
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog dshc-dialog-credential", role: "dialog", "aria-modal": "true", "aria-label": tr("\u914D\u7F6E {v0} \u5E94\u7528", { v0: card.name }), children: [
4497
5131
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head", children: [
4498
5132
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-dialog-avatar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ConnectorLogo, { card, size: 28 }) }),
4499
5133
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-title", children: [
4500
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: "\u914D\u7F6E OAuth \u5E94\u7528" }),
5134
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: tr("\u914D\u7F6E OAuth \u5E94\u7528") }),
4501
5135
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: card.name })
4502
5136
  ] }),
4503
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
5137
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
4504
5138
  ] }),
4505
5139
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
4506
5140
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
4507
- "\u5728",
5141
+ tr("\u5728"),
4508
5142
  card.vendor ?? card.name,
4509
- "\u5F00\u653E\u5E73\u53F0\u521B\u5EFA\u5E94\u7528\uFF0C\u628A\u56DE\u8C03\u5730\u5740\u586B\u5230\u5E94\u7528\u7684\u5B89\u5168\u8BBE\u7F6E\u91CC\uFF0C\u518D\u586B\u5165\u5E94\u7528\u51ED\u636E\uFF1B\u51ED\u636E\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002"
5143
+ tr("\u5F00\u653E\u5E73\u53F0\u521B\u5EFA\u5E94\u7528\uFF0C\u628A\u56DE\u8C03\u5730\u5740\u586B\u5230\u5E94\u7528\u7684\u5B89\u5168\u8BBE\u7F6E\u91CC\uFF0C\u518D\u586B\u5165\u5E94\u7528\u51ED\u636E\uFF1B\u51ED\u636E\u53EA\u4FDD\u5B58\u5728\u672C\u673A\u3002")
4510
5144
  ] }),
4511
5145
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-field", children: [
4512
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { htmlFor: "dshc-oauth-callback", children: "\u56DE\u8C03\u5730\u5740" }),
5146
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { htmlFor: "dshc-oauth-callback", children: tr("\u56DE\u8C03\u5730\u5740") }),
4513
5147
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-field-control", children: [
4514
5148
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { id: "dshc-oauth-callback", readOnly: true, value: callback, onFocus: (event) => event.currentTarget.select() }),
4515
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-field-copy", onClick: copyCallback, children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
5149
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-field-copy", onClick: copyCallback, children: copied ? tr("\u5DF2\u590D\u5236") : tr("\u590D\u5236") })
4516
5150
  ] })
4517
5151
  ] }),
4518
5152
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-field", children: [
@@ -4530,7 +5164,7 @@ function OAuthAppDialog({ card, saving, error, onClose, onSubmit }) {
4530
5164
  "data-bwignore": "true",
4531
5165
  spellCheck: false,
4532
5166
  disabled: saving,
4533
- placeholder: "\u5E94\u7528 AppKey / Client ID",
5167
+ placeholder: tr("\u5E94\u7528 AppKey / Client ID"),
4534
5168
  value: clientId,
4535
5169
  onChange: (event) => setClientId(event.target.value)
4536
5170
  }
@@ -4550,7 +5184,7 @@ function OAuthAppDialog({ card, saving, error, onClose, onSubmit }) {
4550
5184
  "data-1p-ignore": "true",
4551
5185
  "data-bwignore": "true",
4552
5186
  disabled: saving,
4553
- placeholder: "\u5E94\u7528 SecretKey / Client Secret",
5187
+ placeholder: tr("\u5E94\u7528 SecretKey / Client Secret"),
4554
5188
  value: clientSecret,
4555
5189
  onChange: (event) => setClientSecret(event.target.value),
4556
5190
  onKeyDown: (event) => {
@@ -4566,8 +5200,8 @@ function OAuthAppDialog({ card, saving, error, onClose, onSubmit }) {
4566
5200
  {
4567
5201
  type: "button",
4568
5202
  className: "dshc-field-reveal",
4569
- "aria-label": secretVisible ? "\u9690\u85CF SecretKey" : "\u663E\u793A SecretKey",
4570
- title: secretVisible ? "\u9690\u85CF SecretKey" : "\u663E\u793A SecretKey",
5203
+ "aria-label": secretVisible ? tr("\u9690\u85CF SecretKey") : tr("\u663E\u793A SecretKey"),
5204
+ title: secretVisible ? tr("\u9690\u85CF SecretKey") : tr("\u663E\u793A SecretKey"),
4571
5205
  "aria-pressed": secretVisible,
4572
5206
  disabled: saving,
4573
5207
  onMouseDown: (event) => event.preventDefault(),
@@ -4585,10 +5219,10 @@ function OAuthAppDialog({ card, saving, error, onClose, onSubmit }) {
4585
5219
  ] })
4586
5220
  ] }),
4587
5221
  error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: error }),
4588
- saving && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u4FDD\u5B58\u540E\u4F1A\u6253\u5F00\u6D4F\u89C8\u5668\u5B8C\u6210\u6388\u6743\u3002" })
5222
+ saving && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u4FDD\u5B58\u540E\u4F1A\u6253\u5F00\u6D4F\u89C8\u5668\u5B8C\u6210\u6388\u6743\u3002") })
4589
5223
  ] }),
4590
5224
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-dialog-actions-right", children: [
4591
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: saving ? "\u5173\u95ED" : "\u53D6\u6D88" }),
5225
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", onClick: onClose, children: saving ? tr("\u5173\u95ED") : tr("\u53D6\u6D88") }),
4592
5226
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
4593
5227
  "button",
4594
5228
  {
@@ -4598,7 +5232,7 @@ function OAuthAppDialog({ card, saving, error, onClose, onSubmit }) {
4598
5232
  onClick: submit,
4599
5233
  children: [
4600
5234
  saving && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4601
- saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u5E76\u6388\u6743"
5235
+ saving ? tr("\u4FDD\u5B58\u4E2D\u2026") : tr("\u4FDD\u5B58\u5E76\u6388\u6743")
4602
5236
  ]
4603
5237
  }
4604
5238
  )
@@ -4608,63 +5242,77 @@ function OAuthAppDialog({ card, saving, error, onClose, onSubmit }) {
4608
5242
  );
4609
5243
  }
4610
5244
  function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing, onEdited }) {
4611
- const [json, setJson] = (0, import_react.useState)(editing?.initial.json ?? MCP_SERVERS_PLACEHOLDER);
4612
- const [description, setDescription] = (0, import_react.useState)("");
4613
- const [category, setCategory] = (0, import_react.useState)("");
4614
- const [examples, setExamples] = (0, import_react.useState)("");
4615
- const [pending, setPending] = (0, import_react.useState)(false);
4616
- const [error, setError] = (0, import_react.useState)(null);
4617
- const [privateWarning, setPrivateWarning] = (0, import_react.useState)(false);
4618
- const [privateConfirmed, setPrivateConfirmed] = (0, import_react.useState)(false);
4619
- const [categoryOpen, setCategoryOpen] = (0, import_react.useState)(false);
4620
- const [categoryMenu, setCategoryMenu] = (0, import_react.useState)(null);
4621
- const [helpTip, setHelpTip] = (0, import_react.useState)(null);
4622
- const categoryRef = (0, import_react.useRef)(null);
4623
- const categoryMenuRef = (0, import_react.useRef)(null);
4624
- const categoryInputRef = (0, import_react.useRef)(null);
4625
- const helpHideTimerRef = (0, import_react.useRef)(null);
4626
- const helpHoverRef = (0, import_react.useRef)(false);
4627
- const parsedJson = (0, import_react.useMemo)(() => {
5245
+ const [json, setJson] = (0, import_react2.useState)(editing?.initial.json ?? (currentLocale().toLowerCase().startsWith("en") ? MCP_SERVERS_PLACEHOLDER_EN : MCP_SERVERS_PLACEHOLDER));
5246
+ const [description, setDescription] = (0, import_react2.useState)("");
5247
+ const [category, setCategory] = (0, import_react2.useState)("");
5248
+ const [examples, setExamples] = (0, import_react2.useState)("");
5249
+ const [descriptionEn, setDescriptionEn] = (0, import_react2.useState)("");
5250
+ const [categoryEn, setCategoryEn] = (0, import_react2.useState)("");
5251
+ const [examplesEn, setExamplesEn] = (0, import_react2.useState)("");
5252
+ const [metaLang, setMetaLang] = (0, import_react2.useState)(currentLocale().toLowerCase().startsWith("en") ? "en" : "zh");
5253
+ const [pending, setPending] = (0, import_react2.useState)(false);
5254
+ const [error, setError] = (0, import_react2.useState)(null);
5255
+ const [privateWarning, setPrivateWarning] = (0, import_react2.useState)(false);
5256
+ const [privateConfirmed, setPrivateConfirmed] = (0, import_react2.useState)(false);
5257
+ const [categoryOpen, setCategoryOpen] = (0, import_react2.useState)(false);
5258
+ const [categoryMenu, setCategoryMenu] = (0, import_react2.useState)(null);
5259
+ const [helpTip, setHelpTip] = (0, import_react2.useState)(null);
5260
+ const categoryRef = (0, import_react2.useRef)(null);
5261
+ const categoryMenuRef = (0, import_react2.useRef)(null);
5262
+ const categoryInputRef = (0, import_react2.useRef)(null);
5263
+ const helpHideTimerRef = (0, import_react2.useRef)(null);
5264
+ const helpHoverRef = (0, import_react2.useRef)(false);
5265
+ const parsedJson = (0, import_react2.useMemo)(() => {
5266
+ const readMeta = (value) => {
5267
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
5268
+ const record = value;
5269
+ const description2 = typeof record.description === "string" && record.description.trim() !== "" ? record.description.trim() : void 0;
5270
+ const category2 = typeof record.category === "string" && record.category.trim() !== "" ? record.category.trim() : void 0;
5271
+ const examples2 = Array.isArray(record.examples) ? record.examples.filter((item) => typeof item === "string" && item.trim() !== "").map((item) => item.trim()) : void 0;
5272
+ if (description2 === void 0 && category2 === void 0 && (examples2 === void 0 || examples2.length === 0)) {
5273
+ return null;
5274
+ }
5275
+ return {
5276
+ ...description2 === void 0 ? {} : { description: description2 },
5277
+ ...category2 === void 0 ? {} : { category: category2 },
5278
+ ...examples2 === void 0 || examples2.length === 0 ? {} : { examples: examples2 }
5279
+ };
5280
+ };
4628
5281
  try {
4629
5282
  const parsed = JSON.parse(json);
4630
5283
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
4631
- return { count: 0, meta: null };
5284
+ return { count: 0, meta: null, metaEn: null };
4632
5285
  }
4633
5286
  const servers = parsed.mcpServers;
4634
5287
  if (servers === null || typeof servers !== "object" || Array.isArray(servers)) {
4635
- return { count: 0, meta: null };
5288
+ return { count: 0, meta: null, metaEn: null };
4636
5289
  }
4637
5290
  const entries = Object.entries(servers);
4638
- if (entries.length !== 1) return { count: entries.length, meta: null };
5291
+ if (entries.length !== 1) return { count: entries.length, meta: null, metaEn: null };
4639
5292
  const server = entries[0]?.[1];
4640
5293
  if (server === null || typeof server !== "object" || Array.isArray(server)) {
4641
- return { count: 1, meta: null };
5294
+ return { count: 1, meta: null, metaEn: null };
4642
5295
  }
4643
5296
  const xdsh = server["x-dsh"];
4644
5297
  if (xdsh === null || typeof xdsh !== "object" || Array.isArray(xdsh)) {
4645
- return { count: 1, meta: null };
5298
+ return { count: 1, meta: null, metaEn: null };
4646
5299
  }
4647
5300
  const record = xdsh;
4648
- const description2 = typeof record.description === "string" && record.description.trim() !== "" ? record.description.trim() : void 0;
4649
- const category2 = typeof record.category === "string" && record.category.trim() !== "" ? record.category.trim() : void 0;
4650
- const examples2 = Array.isArray(record.examples) ? record.examples.filter((item) => typeof item === "string" && item.trim() !== "").map((item) => item.trim()) : void 0;
4651
- return {
4652
- count: 1,
4653
- meta: {
4654
- ...description2 === void 0 ? {} : { description: description2 },
4655
- ...category2 === void 0 ? {} : { category: category2 },
4656
- ...examples2 === void 0 || examples2.length === 0 ? {} : { examples: examples2 }
4657
- }
4658
- };
5301
+ const translations = record.translations;
5302
+ const en = translations !== null && typeof translations === "object" && !Array.isArray(translations) ? translations.en : void 0;
5303
+ return { count: 1, meta: readMeta(xdsh), metaEn: readMeta(en) };
4659
5304
  } catch {
4660
- return { count: 0, meta: null };
5305
+ return { count: 0, meta: null, metaEn: null };
4661
5306
  }
4662
5307
  }, [json]);
4663
5308
  const serverCount = parsedJson.count;
4664
5309
  const jsonMeta = parsedJson.meta;
4665
- const hasJsonMeta = jsonMeta !== null && (jsonMeta.description !== void 0 || jsonMeta.category !== void 0 || jsonMeta.examples !== void 0);
5310
+ const previewMetaEn = parsedJson.metaEn;
5311
+ const hasJsonMeta = jsonMeta !== null || previewMetaEn !== null;
4666
5312
  const previewMeta = jsonMeta;
4667
- (0, import_react.useEffect)(() => {
5313
+ const effectiveCategory = category.trim() === "" ? previewMeta?.category ?? "\u5176\u4ED6" : category.trim();
5314
+ const englishCategoryAutomatic = canonicalBuiltinCategory(effectiveCategory) !== void 0;
5315
+ (0, import_react2.useEffect)(() => {
4668
5316
  const onKey = (event) => {
4669
5317
  if (event.key !== "Escape" || pending) return;
4670
5318
  if (categoryOpen) {
@@ -4676,7 +5324,7 @@ function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing,
4676
5324
  window.addEventListener("keydown", onKey);
4677
5325
  return () => window.removeEventListener("keydown", onKey);
4678
5326
  }, [onClose, pending, categoryOpen]);
4679
- (0, import_react.useEffect)(() => {
5327
+ (0, import_react2.useEffect)(() => {
4680
5328
  if (!categoryOpen) return;
4681
5329
  const onPointerDown = (event) => {
4682
5330
  const target = event.target;
@@ -4722,11 +5370,19 @@ function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing,
4722
5370
  if (!helpHoverRef.current) setHelpTip(null);
4723
5371
  }, 140);
4724
5372
  };
4725
- (0, import_react.useEffect)(() => () => cancelHelpTipHide(), []);
5373
+ (0, import_react2.useEffect)(() => () => cancelHelpTipHide(), []);
4726
5374
  const submit = (connectNow) => {
4727
5375
  setPending(true);
4728
5376
  setError(null);
4729
5377
  const exampleLines = parseExampleLines(examples);
5378
+ const exampleLinesEn = parseExampleLines(examplesEn);
5379
+ const categoryTranslation = englishCategoryAutomatic ? "" : categoryEn.trim();
5380
+ const enTranslations = {
5381
+ ...descriptionEn.trim() === "" ? {} : { description: descriptionEn.trim() },
5382
+ ...categoryTranslation === "" ? {} : { category: categoryTranslation },
5383
+ ...exampleLinesEn.length === 0 ? {} : { examples: exampleLinesEn }
5384
+ };
5385
+ const translations = Object.keys(enTranslations).length === 0 ? void 0 : { en: enTranslations };
4730
5386
  void (async () => {
4731
5387
  try {
4732
5388
  const body = JSON.stringify({
@@ -4734,7 +5390,8 @@ function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing,
4734
5390
  allowPrivate: privateWarning,
4735
5391
  ...description.trim() === "" ? {} : { description: description.trim() },
4736
5392
  ...category.trim() === "" ? {} : { category: category.trim() },
4737
- ...exampleLines.length === 0 ? {} : { examples: exampleLines }
5393
+ ...exampleLines.length === 0 ? {} : { examples: exampleLines },
5394
+ ...translations === void 0 ? {} : { translations }
4738
5395
  });
4739
5396
  if (editing !== void 0) {
4740
5397
  const response2 = await request(
@@ -4777,7 +5434,7 @@ function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing,
4777
5434
  className: "dshc-dialog dshc-dialog-wide",
4778
5435
  role: "dialog",
4779
5436
  "aria-modal": "true",
4780
- "aria-label": editing === void 0 ? "\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668" : "\u7F16\u8F91\u8FDE\u63A5\u5668\u914D\u7F6E",
5437
+ "aria-label": editing === void 0 ? tr("\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668") : tr("\u7F16\u8F91\u8FDE\u63A5\u5668\u914D\u7F6E"),
4781
5438
  onSubmit: (event) => {
4782
5439
  event.preventDefault();
4783
5440
  if (pending || json.trim() === "" || privateWarning && !privateConfirmed) return;
@@ -4790,13 +5447,13 @@ function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing,
4790
5447
  children: [
4791
5448
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head", children: [
4792
5449
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head-title", children: [
4793
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: editing === void 0 ? "\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668" : "\u7F16\u8F91\u914D\u7F6E" }),
5450
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { children: editing === void 0 ? tr("\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668") : tr("\u7F16\u8F91\u914D\u7F6E") }),
4794
5451
  editing === void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4795
5452
  "button",
4796
5453
  {
4797
5454
  type: "button",
4798
5455
  className: "dshc-help-btn",
4799
- "aria-label": "\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668\u8BF4\u660E",
5456
+ "aria-label": tr("\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668\u8BF4\u660E"),
4800
5457
  onMouseEnter: (event) => showHelpTip(event.currentTarget, "import"),
4801
5458
  onMouseLeave: hideHelpTipSoon,
4802
5459
  onFocus: (event) => showHelpTip(event.currentTarget, "import"),
@@ -4805,10 +5462,10 @@ function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing,
4805
5462
  }
4806
5463
  )
4807
5464
  ] }),
4808
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", disabled: pending, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
5465
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), disabled: pending, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
4809
5466
  ] }),
4810
5467
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
4811
- editing?.initial.installed === true && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u5F53\u524D\u5DF2\u5B89\u88C5\uFF1B\u5982\u4FEE\u6539\u5730\u5740\u3001\u547D\u4EE4\u3001\u8BF7\u6C42\u5934\u6216\u73AF\u5883\u53D8\u91CF\uFF0C\u4FDD\u5B58\u540E\u4F1A\u65AD\u5F00\u8FDE\u63A5\uFF0C\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u3002" }),
5468
+ editing?.initial.installed === true && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u5F53\u524D\u5DF2\u5B89\u88C5\uFF1B\u5982\u4FEE\u6539\u5730\u5740\u3001\u547D\u4EE4\u3001\u8BF7\u6C42\u5934\u6216\u73AF\u5883\u53D8\u91CF\uFF0C\u4FDD\u5B58\u540E\u4F1A\u65AD\u5F00\u8FDE\u63A5\uFF0C\u9700\u8981\u91CD\u65B0\u5B89\u88C5\u3002") }),
4812
5469
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-field", children: [
4813
5470
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dshc-field-label", children: [
4814
5471
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "mcpServers JSON" }),
@@ -4817,7 +5474,7 @@ function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing,
4817
5474
  {
4818
5475
  type: "button",
4819
5476
  className: "dshc-help-btn",
4820
- "aria-label": "x-dsh \u8BF4\u660E",
5477
+ "aria-label": tr("x-dsh \u8BF4\u660E"),
4821
5478
  onMouseEnter: (event) => showHelpTip(event.currentTarget, "x-dsh"),
4822
5479
  onMouseLeave: hideHelpTipSoon,
4823
5480
  onFocus: (event) => showHelpTip(event.currentTarget, "x-dsh"),
@@ -4840,88 +5497,165 @@ function CustomConnectorDialog({ onClose, categoryOptions, onImported, editing,
4840
5497
  )
4841
5498
  ] }),
4842
5499
  editing !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-dialog-hint", children: [
4843
- "\u4FEE\u6539\u4F1A\u4FDD\u5B58\u5230\u672C\u673A\uFF1B\u5BC6\u94A5\u4E0E URL \u67E5\u8BE2\u53C2\u6570\u4E0D\u4F1A\u56DE\u663E\uFF0C\u4FDD\u6301 ",
5500
+ tr("\u4FEE\u6539\u4F1A\u4FDD\u5B58\u5230\u672C\u673A\uFF1B\u5BC6\u94A5\u4E0E URL \u67E5\u8BE2\u53C2\u6570\u4E0D\u4F1A\u56DE\u663E\uFF0C\u4FDD\u6301"),
5501
+ " ",
4844
5502
  CUSTOM_SECRET_PLACEHOLDER,
4845
- " \u4F1A\u6CBF\u7528\u539F\u503C\u3002"
5503
+ " ",
5504
+ tr("\u4F1A\u6CBF\u7528\u539F\u503C\u3002")
4846
5505
  ] }),
4847
- hasJsonMeta && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: "\u5DF2\u8BFB\u53D6 JSON \u4E2D\u7684 x-dsh\uFF1B\u4E0B\u65B9\u7559\u7A7A\u5C31\u4F7F\u7528\u5B83\uFF0C\u586B\u5199\u4F1A\u8986\u76D6\u3002" }),
4848
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-field", children: [
4849
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u63CF\u8FF0\uFF08\u53EF\u9009\uFF09" }),
4850
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4851
- "input",
4852
- {
4853
- autoComplete: "off",
4854
- maxLength: 120,
4855
- placeholder: previewMeta?.description === void 0 ? "\u4F8B\u5982\uFF1A\u901A\u8FC7 DeepWiki \u67E5\u8BE2\u4ED3\u5E93\u7ED3\u6784\u4E0E\u6587\u6863" : `JSON \u4E2D\uFF1A${previewMeta.description}`,
4856
- value: description,
4857
- onChange: (event) => setDescription(event.target.value)
4858
- }
4859
- )
5506
+ hasJsonMeta && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u5DF2\u8BFB\u53D6 JSON \u4E2D\u7684 x-dsh\uFF1B\u4E0B\u65B9\u7559\u7A7A\u5C31\u4F7F\u7528\u5B83\uFF0C\u586B\u5199\u4F1A\u8986\u76D6\u3002") }),
5507
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-meta-lang", children: [
5508
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u5361\u7247\u6587\u6848") }),
5509
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-lang-switch", role: "tablist", children: [
5510
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5511
+ "button",
5512
+ {
5513
+ type: "button",
5514
+ role: "tab",
5515
+ "aria-selected": metaLang === "zh",
5516
+ className: metaLang === "zh" ? "dshc-lang-option dshc-lang-option-active" : "dshc-lang-option",
5517
+ onClick: () => setMetaLang("zh"),
5518
+ children: tr("\u4E2D\u6587")
5519
+ }
5520
+ ),
5521
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5522
+ "button",
5523
+ {
5524
+ type: "button",
5525
+ role: "tab",
5526
+ "aria-selected": metaLang === "en",
5527
+ className: metaLang === "en" ? "dshc-lang-option dshc-lang-option-active" : "dshc-lang-option",
5528
+ onClick: () => setMetaLang("en"),
5529
+ children: "English"
5530
+ }
5531
+ )
5532
+ ] })
4860
5533
  ] }),
4861
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-field", children: [
4862
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-field-label", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u7C7B\u522B\uFF08\u53EF\u9009\uFF09" }) }),
4863
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-select", ref: categoryRef, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-select-control", children: [
5534
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { hidden: metaLang !== "zh", children: [
5535
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-field", children: [
5536
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u63CF\u8FF0\uFF08\u53EF\u9009\uFF09") }),
4864
5537
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4865
5538
  "input",
4866
5539
  {
4867
- ref: categoryInputRef,
4868
5540
  autoComplete: "off",
4869
- placeholder: previewMeta?.category === void 0 ? "\u9ED8\u8BA4\uFF1A\u5176\u4ED6" : `JSON \u4E2D\uFF1A${previewMeta.category}`,
4870
- value: category,
4871
- "aria-expanded": categoryOpen,
4872
- onFocus: openCategoryMenu,
4873
- onChange: (event) => {
4874
- setCategory(event.target.value);
4875
- openCategoryMenu();
4876
- },
4877
- onKeyDown: (event) => {
4878
- if (event.key === "Enter") {
4879
- event.preventDefault();
4880
- setCategoryOpen(false);
5541
+ maxLength: 120,
5542
+ placeholder: previewMeta?.description === void 0 ? tr("\u4F8B\u5982\uFF1A\u901A\u8FC7 DeepWiki \u67E5\u8BE2\u4ED3\u5E93\u7ED3\u6784\u4E0E\u6587\u6863") : tr("JSON \u4E2D\uFF1A{v0}", { v0: previewMeta.description }),
5543
+ value: description,
5544
+ onChange: (event) => setDescription(event.target.value)
5545
+ }
5546
+ )
5547
+ ] }),
5548
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-field", children: [
5549
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dshc-field-label", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u7C7B\u522B\uFF08\u53EF\u9009\uFF09") }) }),
5550
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-select", ref: categoryRef, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-select-control", children: [
5551
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5552
+ "input",
5553
+ {
5554
+ ref: categoryInputRef,
5555
+ autoComplete: "off",
5556
+ placeholder: previewMeta?.category === void 0 ? tr("\u9ED8\u8BA4\uFF1A\u5176\u4ED6") : tr("JSON \u4E2D\uFF1A{v0}", { v0: previewMeta.category }),
5557
+ value: category,
5558
+ "aria-expanded": categoryOpen,
5559
+ onFocus: openCategoryMenu,
5560
+ onChange: (event) => {
5561
+ setCategory(event.target.value);
5562
+ openCategoryMenu();
5563
+ },
5564
+ onKeyDown: (event) => {
5565
+ if (event.key === "Enter") {
5566
+ event.preventDefault();
5567
+ setCategoryOpen(false);
5568
+ }
4881
5569
  }
4882
5570
  }
5571
+ ),
5572
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5573
+ "button",
5574
+ {
5575
+ type: "button",
5576
+ className: "dshc-select-toggle",
5577
+ "aria-label": tr("\u9009\u62E9\u7C7B\u522B"),
5578
+ onMouseDown: (event) => event.preventDefault(),
5579
+ onClick: () => {
5580
+ if (categoryOpen) setCategoryOpen(false);
5581
+ else openCategoryMenu();
5582
+ },
5583
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconChevronDown, { size: 14 })
5584
+ }
5585
+ )
5586
+ ] }) }),
5587
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: previewMeta?.category === void 0 ? tr("\u7559\u7A7A\u4F1A\u5F52\u5165\u300C\u5176\u4ED6\u300D\uFF1B\u53EF\u76F4\u63A5\u8F93\u5165\u65B0\u7C7B\u522B\u3002") : tr("\u7559\u7A7A\u4F7F\u7528 JSON \u4E2D\u7684\u7C7B\u522B\uFF1B\u586B\u5199\u4F1A\u8986\u76D6\u3002") })
5588
+ ] }),
5589
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-field", children: [
5590
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u793A\u4F8B\u63D0\u793A\u8BCD\uFF08\u53EF\u9009\uFF0C\u6BCF\u884C\u4E00\u6761\uFF09") }),
5591
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5592
+ "textarea",
5593
+ {
5594
+ className: "dshc-examples-input",
5595
+ spellCheck: false,
5596
+ placeholder: previewMeta?.examples === void 0 ? tr("\u7528 DeepWiki \u67E5\u4E00\u4E0B facebook/react \u7684\u4ED3\u5E93\u7ED3\u6784") : tr("JSON \u4E2D\uFF1A\n{v0}", { v0: previewMeta.examples.join("\n") }),
5597
+ value: examples,
5598
+ onChange: (event) => setExamples(event.target.value)
5599
+ }
5600
+ )
5601
+ ] })
5602
+ ] }),
5603
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { hidden: metaLang !== "en", children: [
5604
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-field", children: [
5605
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u82F1\u6587\u63CF\u8FF0\uFF08\u53EF\u9009\uFF09") }),
5606
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5607
+ "input",
5608
+ {
5609
+ autoComplete: "off",
5610
+ maxLength: 120,
5611
+ placeholder: previewMetaEn?.description === void 0 ? tr("\u7559\u7A7A\u4F7F\u7528\u4E2D\u6587\u63CF\u8FF0") : tr("JSON \u4E2D\uFF1A{v0}", { v0: previewMetaEn.description }),
5612
+ value: descriptionEn,
5613
+ onChange: (event) => setDescriptionEn(event.target.value)
5614
+ }
5615
+ )
5616
+ ] }),
5617
+ englishCategoryAutomatic ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u5185\u7F6E\u5206\u7C7B\u4F1A\u81EA\u52A8\u4F7F\u7528\u6807\u51C6\u82F1\u6587\u540D\u79F0\u3002") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-field", children: [
5618
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u82F1\u6587\u5206\u7C7B\u663E\u793A\u540D\uFF08\u53EF\u9009\uFF09") }),
5619
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5620
+ "input",
5621
+ {
5622
+ autoComplete: "off",
5623
+ maxLength: 64,
5624
+ placeholder: previewMetaEn?.category === void 0 ? tr("\u7559\u7A7A\u4F7F\u7528\u4E2D\u6587\u5206\u7C7B") : tr("JSON \u4E2D\uFF1A{v0}", { v0: previewMetaEn.category }),
5625
+ value: categoryEn,
5626
+ onChange: (event) => setCategoryEn(event.target.value)
4883
5627
  }
4884
5628
  ),
5629
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: tr("\u4EC5\u7528\u4E8E\u663E\u793A\uFF0C\u4E0D\u6539\u53D8\u5206\u7C7B\u5206\u7EC4\u3002") })
5630
+ ] }),
5631
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-field", children: [
5632
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u82F1\u6587\u793A\u4F8B\u63D0\u793A\u8BCD\uFF08\u53EF\u9009\uFF0C\u6BCF\u884C\u4E00\u6761\uFF09") }),
4885
5633
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4886
- "button",
5634
+ "textarea",
4887
5635
  {
4888
- type: "button",
4889
- className: "dshc-select-toggle",
4890
- "aria-label": "\u9009\u62E9\u7C7B\u522B",
4891
- onMouseDown: (event) => event.preventDefault(),
4892
- onClick: () => {
4893
- if (categoryOpen) setCategoryOpen(false);
4894
- else openCategoryMenu();
4895
- },
4896
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconChevronDown, { size: 14 })
5636
+ className: "dshc-examples-input",
5637
+ spellCheck: false,
5638
+ placeholder: previewMetaEn?.examples === void 0 ? tr("\u7559\u7A7A\u4F7F\u7528\u4E2D\u6587\u793A\u4F8B") : tr("JSON \u4E2D\uFF1A\n{v0}", { v0: previewMetaEn.examples.join("\n") }),
5639
+ value: examplesEn,
5640
+ onChange: (event) => setExamplesEn(event.target.value)
4897
5641
  }
4898
5642
  )
4899
- ] }) }),
4900
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-hint", children: previewMeta?.category === void 0 ? "\u7559\u7A7A\u4F1A\u5F52\u5165\u300C\u5176\u4ED6\u300D\uFF1B\u53EF\u76F4\u63A5\u8F93\u5165\u65B0\u7C7B\u522B\u3002" : "\u7559\u7A7A\u4F7F\u7528 JSON \u4E2D\u7684\u7C7B\u522B\uFF1B\u586B\u5199\u4F1A\u8986\u76D6\u3002" })
4901
- ] }),
4902
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "dshc-field", children: [
4903
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u793A\u4F8B\u63D0\u793A\u8BCD\uFF08\u53EF\u9009\uFF0C\u6BCF\u884C\u4E00\u6761\uFF09" }),
4904
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4905
- "textarea",
4906
- {
4907
- className: "dshc-examples-input",
4908
- spellCheck: false,
4909
- placeholder: previewMeta?.examples === void 0 ? "\u7528 DeepWiki \u67E5\u4E00\u4E0B facebook/react \u7684\u4ED3\u5E93\u7ED3\u6784" : `JSON \u4E2D\uFF1A
4910
- ${previewMeta.examples.join("\n")}`,
4911
- value: examples,
4912
- onChange: (event) => setExamples(event.target.value)
4913
- }
4914
- )
5643
+ ] })
4915
5644
  ] }),
4916
5645
  editing === void 0 && serverCount > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-warning", children: [
4917
- "\u68C0\u6D4B\u5230 ",
5646
+ tr("\u68C0\u6D4B\u5230"),
5647
+ " ",
4918
5648
  serverCount,
4919
- " \u4E2A Server\uFF1B\u591A Server \u8BF7\u7528\u300C\u4EC5\u5BFC\u5165\u300D\uFF0C\u5BFC\u5165\u540E\u5206\u522B\u8FDE\u63A5\u3002 \u586B\u5199\u4E0B\u65B9\u63CF\u8FF0\u3001\u7C7B\u522B\u3001\u793A\u4F8B\u4F1A\u8986\u76D6\u6240\u6709 Server\uFF1B\u7559\u7A7A\u5219\u5404 Server \u4F7F\u7528\u81EA\u5DF1\u7684 x-dsh\u3002"
5649
+ " ",
5650
+ tr("\u4E2A Server\uFF1B\u591A Server \u8BF7\u7528\u300C\u4EC5\u5BFC\u5165\u300D\uFF0C\u5BFC\u5165\u540E\u5206\u522B\u8FDE\u63A5\u3002"),
5651
+ tr("\u586B\u5199\u4E0B\u65B9\u63CF\u8FF0\u3001\u7C7B\u522B\u3001\u793A\u4F8B\u4F1A\u8986\u76D6\u6240\u6709 Server\uFF1B\u7559\u7A7A\u5219\u5404 Server \u4F7F\u7528\u81EA\u5DF1\u7684 x-dsh\u3002")
4920
5652
  ] }),
4921
5653
  editing !== void 0 && json.trim() !== "" && serverCount !== 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "dshc-warning", children: [
4922
- "\u7F16\u8F91\u65F6\u53EA\u80FD\u4FDD\u7559\u4E00\u4E2A Server\uFF0C\u5F53\u524D\u68C0\u6D4B\u5230 ",
5654
+ tr("\u7F16\u8F91\u65F6\u53EA\u80FD\u4FDD\u7559\u4E00\u4E2A Server\uFF0C\u5F53\u524D\u68C0\u6D4B\u5230"),
5655
+ " ",
4923
5656
  serverCount,
4924
- " \u4E2A\u3002"
5657
+ " ",
5658
+ tr("\u4E2A\u3002")
4925
5659
  ] }),
4926
5660
  privateWarning && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4927
5661
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-warning", children: error }),
@@ -4934,13 +5668,13 @@ ${previewMeta.examples.join("\n")}`,
4934
5668
  onChange: (event) => setPrivateConfirmed(event.target.checked)
4935
5669
  }
4936
5670
  ),
4937
- "\u6211\u786E\u8BA4\u5141\u8BB8\u8BBF\u95EE\u672C\u673A\u6216\u5185\u7F51\u5730\u5740"
5671
+ tr("\u6211\u786E\u8BA4\u5141\u8BB8\u8BBF\u95EE\u672C\u673A\u6216\u5185\u7F51\u5730\u5740")
4938
5672
  ] })
4939
5673
  ] })
4940
5674
  ] }),
4941
5675
  error !== null && !privateWarning && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dshc-dialog-alert", role: "alert", children: error }),
4942
5676
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-actions", children: [
4943
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", disabled: pending, onClick: onClose, children: "\u53D6\u6D88" }),
5677
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", disabled: pending, onClick: onClose, children: tr("\u53D6\u6D88") }),
4944
5678
  editing === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
4945
5679
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
4946
5680
  "button",
@@ -4949,7 +5683,7 @@ ${previewMeta.examples.join("\n")}`,
4949
5683
  className: "dshc-btn dshc-btn-md dshc-btn-outline",
4950
5684
  disabled: pending || json.trim() === "" || privateWarning && !privateConfirmed,
4951
5685
  onClick: () => submit(false),
4952
- children: privateWarning ? "\u4ECD\u7136\u4EC5\u5BFC\u5165" : "\u4EC5\u5BFC\u5165"
5686
+ children: privateWarning ? tr("\u4ECD\u7136\u4EC5\u5BFC\u5165") : tr("\u4EC5\u5BFC\u5165")
4953
5687
  }
4954
5688
  ),
4955
5689
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -4958,7 +5692,7 @@ ${previewMeta.examples.join("\n")}`,
4958
5692
  type: "submit",
4959
5693
  className: "dshc-btn dshc-btn-md dshc-btn-primary",
4960
5694
  disabled: pending || json.trim() === "" || serverCount !== 1 || privateWarning && !privateConfirmed,
4961
- children: pending ? "\u5BFC\u5165\u4E2D\u2026" : privateWarning ? "\u4ECD\u7136\u5BFC\u5165\u5E76\u8FDE\u63A5" : "\u5BFC\u5165\u5E76\u8FDE\u63A5"
5695
+ children: pending ? tr("\u5BFC\u5165\u4E2D\u2026") : privateWarning ? tr("\u4ECD\u7136\u5BFC\u5165\u5E76\u8FDE\u63A5") : tr("\u5BFC\u5165\u5E76\u8FDE\u63A5")
4962
5696
  }
4963
5697
  )
4964
5698
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
@@ -4969,7 +5703,7 @@ ${previewMeta.examples.join("\n")}`,
4969
5703
  disabled: pending || json.trim() === "" || serverCount !== 1 || privateWarning && !privateConfirmed,
4970
5704
  children: [
4971
5705
  pending && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
4972
- pending ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58"
5706
+ pending ? tr("\u4FDD\u5B58\u4E2D\u2026") : tr("\u4FDD\u5B58")
4973
5707
  ]
4974
5708
  }
4975
5709
  )
@@ -4996,7 +5730,7 @@ ${previewMeta.examples.join("\n")}`,
4996
5730
  setCategory(item);
4997
5731
  setCategoryOpen(false);
4998
5732
  },
4999
- children: item
5733
+ children: tr(item)
5000
5734
  },
5001
5735
  item
5002
5736
  ))
@@ -5024,15 +5758,22 @@ ${previewMeta.examples.join("\n")}`,
5024
5758
  setHelpTip(null);
5025
5759
  },
5026
5760
  children: helpTip.kind === "import" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
5027
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668" }),
5028
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u7C98\u8D34 mcpServers JSON\uFF0C\u652F\u6301 Streamable HTTP\u3001SSE \u4E0E stdio \u4E09\u7C7B MCP Server\u3002" })
5761
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: tr("\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668") }),
5762
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u7C98\u8D34 mcpServers JSON\uFF0C\u652F\u6301 Streamable HTTP\u3001SSE \u4E0E stdio \u4E09\u7C7B MCP Server\u3002") })
5029
5763
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
5030
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u53EF\u9009\u6269\u5C55\uFF1Ax-dsh" }),
5031
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u53EF\u5728\u6BCF\u4E2A server \u914D\u7F6E\u91CC\u6307\u5B9A\u63CF\u8FF0\u3001\u7C7B\u522B\u4E0E\u793A\u4F8B\uFF0C\u4F18\u5148\u4E8E\u4E0B\u65B9\u8868\u5355\uFF1A" }),
5032
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: `"x-dsh": {
5764
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: tr("\u53EF\u9009\u6269\u5C55\uFF1Ax-dsh") }),
5765
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: tr("\u53EF\u5728\u6BCF\u4E2A server \u914D\u7F6E\u91CC\u6307\u5B9A\u63CF\u8FF0\u3001\u7C7B\u522B\u4E0E\u793A\u4F8B\uFF0C\u5E76\u7528 translations.en \u63D0\u4F9B\u82F1\u6587\u526F\u672C\uFF1B\u4F18\u5148\u4E8E\u4E0B\u65B9\u8868\u5355\uFF1A") }),
5766
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: currentLocale().toLowerCase().startsWith("en") ? X_DSH_SAMPLE_EN : `"x-dsh": {
5033
5767
  "description": "\u67E5\u8BE2\u4ED3\u5E93\u7ED3\u6784\u4E0E\u6587\u6863",
5034
5768
  "category": "\u77E5\u8BC6\u68C0\u7D22",
5035
- "examples": ["\u7528 DeepWiki \u67E5 facebook/react \u7684\u4ED3\u5E93\u7ED3\u6784"]
5769
+ "examples": ["\u7528 DeepWiki \u67E5 facebook/react \u7684\u4ED3\u5E93\u7ED3\u6784"],
5770
+ "translations": {
5771
+ "en": {
5772
+ "description": "Inspect repository structure and docs",
5773
+ "category": "Search & knowledge",
5774
+ "examples": ["Use DeepWiki to inspect facebook/react"]
5775
+ }
5776
+ }
5036
5777
  }` })
5037
5778
  ] })
5038
5779
  }
@@ -5044,7 +5785,7 @@ ${previewMeta.examples.join("\n")}`,
5044
5785
  );
5045
5786
  }
5046
5787
  function DeleteCustomDialog({ card, pending, error, onClose, onConfirm }) {
5047
- (0, import_react.useEffect)(() => {
5788
+ (0, import_react2.useEffect)(() => {
5048
5789
  const onKey = (event) => {
5049
5790
  if (event.key === "Escape" && !pending) onClose();
5050
5791
  };
@@ -5058,20 +5799,21 @@ function DeleteCustomDialog({ card, pending, error, onClose, onConfirm }) {
5058
5799
  onMouseDown: (event) => {
5059
5800
  if (event.target === event.currentTarget && !pending) onClose();
5060
5801
  },
5061
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog", role: "dialog", "aria-modal": "true", "aria-label": `\u5220\u9664 ${card.name}`, children: [
5802
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog", role: "dialog", "aria-modal": "true", "aria-label": tr("\u5220\u9664 {v0}", { v0: card.name }), children: [
5062
5803
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-head", children: [
5063
5804
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h2", { children: [
5064
- "\u5220\u9664 ",
5805
+ tr("\u5220\u9664"),
5806
+ " ",
5065
5807
  card.name
5066
5808
  ] }),
5067
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": "\u5173\u95ED", disabled: pending, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
5809
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-icon-btn", "aria-label": tr("\u5173\u95ED"), disabled: pending, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconClose, { size: 16 }) })
5068
5810
  ] }),
5069
5811
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-content", children: [
5070
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-body", children: "\u8FD9\u4E2A\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668\u4F1A\u4ECE\u672C\u673A\u79FB\u9664\uFF0C\u5DF2\u4FDD\u5B58\u7684\u914D\u7F6E\u4E0E\u51ED\u636E\u4F1A\u4E00\u8D77\u5220\u9664\uFF0C\u5DF2\u8FDE\u63A5\u7684\u5DE5\u5177\u4F1A\u6CE8\u9500\u3002" }),
5812
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-body", children: tr("\u8FD9\u4E2A\u81EA\u5B9A\u4E49\u8FDE\u63A5\u5668\u4F1A\u4ECE\u672C\u673A\u79FB\u9664\uFF0C\u5DF2\u4FDD\u5B58\u7684\u914D\u7F6E\u4E0E\u51ED\u636E\u4F1A\u4E00\u8D77\u5220\u9664\uFF0C\u5DF2\u8FDE\u63A5\u7684\u5DE5\u5177\u4F1A\u6CE8\u9500\u3002") }),
5071
5813
  error !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "dshc-dialog-error", children: error })
5072
5814
  ] }),
5073
5815
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dshc-dialog-actions", children: [
5074
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", disabled: pending, onClick: onClose, children: "\u53D6\u6D88" }),
5816
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dshc-btn dshc-btn-md dshc-btn-outline", disabled: pending, onClick: onClose, children: tr("\u53D6\u6D88") }),
5075
5817
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5076
5818
  "button",
5077
5819
  {
@@ -5079,7 +5821,7 @@ function DeleteCustomDialog({ card, pending, error, onClose, onConfirm }) {
5079
5821
  className: "dshc-btn dshc-btn-md dshc-btn-outline dshc-btn-danger",
5080
5822
  disabled: pending,
5081
5823
  onClick: onConfirm,
5082
- children: pending ? "\u5220\u9664\u4E2D\u2026" : "\u5220\u9664"
5824
+ children: pending ? tr("\u5220\u9664\u4E2D\u2026") : tr("\u5220\u9664")
5083
5825
  }
5084
5826
  )
5085
5827
  ] })
@@ -5283,6 +6025,10 @@ button.dshc-card-action:focus-visible{outline:2px solid var(--dsw-alias-state-bu
5283
6025
  .dshc-status-pill-error{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}
5284
6026
  .dshc-status-pill .dshc-spinner{margin-right:5px}
5285
6027
  .dshc-field{display:flex;flex-direction:column;gap:6px;font-size:13px;line-height:18px;color:var(--dsw-alias-label-secondary)}
6028
+ .dshc-meta-lang{display:flex;align-items:center;gap:10px;font-size:13px;line-height:18px;color:var(--dsw-alias-label-secondary)}
6029
+ .dshc-lang-switch{display:inline-flex;gap:2px;padding:2px;border:.5px solid var(--dsw-alias-border-l);border-radius:var(--dsw-radius-md)}
6030
+ .dshc-lang-option{border:0;background:transparent;color:inherit;font:inherit;font-size:12px;line-height:18px;padding:2px 8px;border-radius:calc(var(--dsw-radius-md) - 2px);cursor:pointer}
6031
+ .dshc-lang-option-active{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}
5286
6032
  .dshc-field input{box-sizing:border-box;height:40px;padding:0 14px;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;outline:none}
5287
6033
  .dshc-field-control{position:relative;display:block}
5288
6034
  .dshc-field-control input{width:100%;padding-right:40px}