openclacky 1.1.6 → 1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/CONTRIBUTING.md +92 -0
- data/README.md +10 -0
- data/README_CN.md +10 -0
- data/ROADMAP.md +29 -0
- data/docs/billing-system.md +340 -0
- data/docs/mcp-architecture.md +114 -0
- data/docs/mcp.example.json +22 -0
- data/lib/clacky/agent/cost_tracker.rb +37 -0
- data/lib/clacky/agent/llm_caller.rb +0 -1
- data/lib/clacky/agent/session_serializer.rb +2 -11
- data/lib/clacky/agent/skill_manager.rb +73 -26
- data/lib/clacky/agent/system_prompt_builder.rb +0 -5
- data/lib/clacky/agent/time_machine.rb +6 -0
- data/lib/clacky/agent.rb +26 -1
- data/lib/clacky/agent_config.rb +9 -19
- data/lib/clacky/billing/billing_record.rb +67 -0
- data/lib/clacky/billing/billing_store.rb +193 -0
- data/lib/clacky/cli.rb +108 -6
- data/lib/clacky/default_skills/browser-setup/SKILL.md +26 -4
- data/lib/clacky/default_skills/mcp-manager/SKILL.md +343 -0
- data/lib/clacky/idle_compression_timer.rb +4 -2
- data/lib/clacky/mcp/client.rb +204 -0
- data/lib/clacky/mcp/http_transport.rb +155 -0
- data/lib/clacky/mcp/registry.rb +229 -0
- data/lib/clacky/mcp/skill_provider.rb +75 -0
- data/lib/clacky/mcp/stdio_transport.rb +112 -0
- data/lib/clacky/mcp/transport.rb +23 -0
- data/lib/clacky/mcp/virtual_skill.rb +131 -0
- data/lib/clacky/message_history.rb +0 -1
- data/lib/clacky/server/channel/adapters/weixin/adapter.rb +2 -35
- data/lib/clacky/server/http_server.rb +519 -15
- data/lib/clacky/server/server_master.rb +8 -14
- data/lib/clacky/server/session_registry.rb +24 -2
- data/lib/clacky/server/web_ui_controller.rb +4 -0
- data/lib/clacky/session_manager.rb +41 -12
- data/lib/clacky/skill.rb +1 -5
- data/lib/clacky/skill_loader.rb +36 -5
- data/lib/clacky/tools/browser.rb +217 -38
- data/lib/clacky/tools/trash_manager.rb +154 -3
- data/lib/clacky/ui2/components/command_suggestions.rb +6 -2
- data/lib/clacky/ui_interface.rb +1 -0
- data/lib/clacky/utils/model_pricing.rb +11 -7
- data/lib/clacky/utils/trash_directory.rb +37 -6
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/web/app.css +2907 -1764
- data/lib/clacky/web/app.js +84 -10
- data/lib/clacky/web/billing.js +275 -0
- data/lib/clacky/web/brand.js +3 -0
- data/lib/clacky/web/i18n.js +242 -24
- data/lib/clacky/web/index.html +351 -134
- data/lib/clacky/web/mcp.js +328 -0
- data/lib/clacky/web/sessions.js +193 -11
- data/lib/clacky/web/settings.js +686 -174
- data/lib/clacky/web/sidebar.js +2 -0
- data/lib/clacky/web/trash.js +323 -60
- data/lib/clacky/web/ws-dispatcher.js +14 -1
- data/lib/clacky.rb +4 -0
- data/scripts/install.ps1 +23 -11
- metadata +30 -10
data/lib/clacky/web/i18n.js
CHANGED
|
@@ -19,6 +19,7 @@ const I18n = (() => {
|
|
|
19
19
|
"sidebar.tasks": "Task Management",
|
|
20
20
|
"sidebar.skills": "Skill Management",
|
|
21
21
|
"sidebar.channels": "Channel Management",
|
|
22
|
+
"sidebar.mcp": "MCP Servers",
|
|
22
23
|
"sidebar.trash": "File Recall",
|
|
23
24
|
"sidebar.profile": "Assistant Memory",
|
|
24
25
|
"sidebar.memories": "Memories",
|
|
@@ -26,6 +27,7 @@ const I18n = (() => {
|
|
|
26
27
|
"sidebar.creator": "Creator Hub",
|
|
27
28
|
"sidebar.creatorSection": "Creator",
|
|
28
29
|
"sidebar.settings": "Settings",
|
|
30
|
+
"sidebar.billing": "Usage",
|
|
29
31
|
|
|
30
32
|
// ── Welcome screen ──
|
|
31
33
|
"welcome.title": "Welcome to {{brand}}",
|
|
@@ -38,6 +40,8 @@ const I18n = (() => {
|
|
|
38
40
|
"chat.status.error": "error",
|
|
39
41
|
"chat.input.placeholder": "Message… (Enter to send, Shift+Enter for newline)",
|
|
40
42
|
"chat.input.placeholderRunning": "AI is working — you can still send extra info anytime...",
|
|
43
|
+
"chat.input.placeholderMobile": "Message…",
|
|
44
|
+
"chat.input.placeholderRunningMobile": "Add more info…",
|
|
41
45
|
"chat.btn.send": "Send",
|
|
42
46
|
"chat.thinking": "Thinking…",
|
|
43
47
|
"chat.retrying": "Retrying",
|
|
@@ -60,6 +64,7 @@ const I18n = (() => {
|
|
|
60
64
|
"chat.empty.tip1": "Type / to browse skills",
|
|
61
65
|
"chat.empty.tip2": "Attach images, PDFs, or docs for context",
|
|
62
66
|
"chat.empty.tip3": "Shift+Enter for a new line",
|
|
67
|
+
"chat.empty.tip4": "Each session is isolated, but long-term memories are shared across sessions",
|
|
63
68
|
|
|
64
69
|
// ── Session list ──
|
|
65
70
|
"sessions.empty": "No sessions yet",
|
|
@@ -77,6 +82,7 @@ const I18n = (() => {
|
|
|
77
82
|
"sib.dir.tooltip": "Click to change directory",
|
|
78
83
|
"sib.dir.changePrompt": "Change working directory:",
|
|
79
84
|
"sib.model.tooltip": "Click to switch model",
|
|
85
|
+
"sib.model.tooltip.busy": "Model switching is disabled while the agent is responding",
|
|
80
86
|
"sib.signal.tooltip": "Recent LLM latency",
|
|
81
87
|
"sib.reasoning.tooltip": "Click to change reasoning effort",
|
|
82
88
|
"sib.reasoning.label": "Reasoning",
|
|
@@ -246,13 +252,37 @@ const I18n = (() => {
|
|
|
246
252
|
"trash.restoreOk": "Restored: {{path}}",
|
|
247
253
|
"trash.restoreFail": "Restore failed: {{msg}}",
|
|
248
254
|
"trash.confirmDeleteOne": "Permanently delete \"{{name}}\"?\nThis cannot be undone.",
|
|
249
|
-
"trash.confirmEmptyOld": "Permanently delete
|
|
250
|
-
"trash.confirmEmptyAll": "Permanently delete
|
|
255
|
+
"trash.confirmEmptyOld": "Permanently delete {{count}} trashed file(s) older than 7 days?\nThis cannot be undone.",
|
|
256
|
+
"trash.confirmEmptyAll": "Permanently delete all {{count}} trashed file(s)?\nThis cannot be undone.",
|
|
251
257
|
"trash.confirmEmptyOrphans": "Permanently delete {{count}} orphan trash entries whose original project directory is gone?\nThis cannot be undone.",
|
|
252
258
|
"trash.emptied": "Permanently deleted {{count}} file(s), freed {{size}}.",
|
|
253
259
|
"trash.orphansCleaned": "Cleaned {{count}} orphan entries, freed {{size}}. ({{failed}} failed)",
|
|
254
260
|
"trash.nothingOld": "No files older than 7 days.",
|
|
255
261
|
|
|
262
|
+
// ── Session trash ──
|
|
263
|
+
"trash.tabFile": "Agent Files",
|
|
264
|
+
"trash.tabSession": "Sessions",
|
|
265
|
+
"trash.summarySessions": "{{count}} session(s), {{size}}",
|
|
266
|
+
"trash.sessionTasks": "{{n}} tasks",
|
|
267
|
+
"trash.restoreSession": "Restore",
|
|
268
|
+
"trash.deleteSession": "Delete",
|
|
269
|
+
"trash.noSessionTrash": "No deleted sessions.",
|
|
270
|
+
"trash.confirmDeleteSession": "Permanently delete \"{{name}}\"?\nThis cannot be undone.",
|
|
271
|
+
"trash.confirmEmptySessionOld": "Permanently delete {{count}} session(s) trashed more than 7 days ago?\nThis cannot be undone.",
|
|
272
|
+
"trash.confirmEmptySessionAll": "Permanently delete all {{count}} trashed session(s)?\nThis cannot be undone.",
|
|
273
|
+
"trash.sessionsCleaned": "Permanently deleted {{count}} session(s).",
|
|
274
|
+
"trash.sessionRestoreOk": "Session restored.",
|
|
275
|
+
"trash.sessionRestoreFail": "Restore failed: {{msg}}",
|
|
276
|
+
"trash.sessionRestoreOkAction": "Open",
|
|
277
|
+
"trash.deleteFail": "Delete failed: {{msg}}",
|
|
278
|
+
"trash.cleanFail": "Operation failed: {{msg}}",
|
|
279
|
+
|
|
280
|
+
// ── Relative time (used by _humanTime helper) ──
|
|
281
|
+
"time.justNow": "just now",
|
|
282
|
+
"time.minsAgo": "{{n}}m ago",
|
|
283
|
+
"time.hoursAgo": "{{n}}h ago",
|
|
284
|
+
"time.daysAgo": "{{n}}d ago",
|
|
285
|
+
|
|
256
286
|
// ── Profile (unified read-only view of USER.md / SOUL.md / memories) ──
|
|
257
287
|
"profile.title": "Assistant Memory",
|
|
258
288
|
"profile.subtitle": "A window into the assistant's inner life: who it is, who you are, and what it remembers about your work together.",
|
|
@@ -403,8 +433,48 @@ const I18n = (() => {
|
|
|
403
433
|
"channels.telegram.desc": "Connect via Telegram Bot API (HTTPS long-poll, token from @BotFather)",
|
|
404
434
|
"channels.dingtalk.desc": "Connect via DingTalk Stream Mode WebSocket",
|
|
405
435
|
|
|
436
|
+
// ── MCP panel ──
|
|
437
|
+
"mcp.title": "MCP Servers",
|
|
438
|
+
"mcp.subtitle": "Standard Model Context Protocol servers (Claude Desktop / Cursor compatible). Edit ~/.clacky/mcp.json to add or remove servers.",
|
|
439
|
+
"mcp.loading": "Loading…",
|
|
440
|
+
"mcp.empty.title": "No MCP servers configured",
|
|
441
|
+
"mcp.empty.body": "Create ~/.clacky/mcp.json to plug in MCP servers. The format matches Claude Desktop and Cursor, so existing configs work as-is.",
|
|
442
|
+
"mcp.config.path": "Config file:",
|
|
443
|
+
"mcp.config.missing": "(not created yet)",
|
|
444
|
+
"mcp.command": "Command",
|
|
445
|
+
"mcp.url": "URL",
|
|
446
|
+
"mcp.toggle.on": "Enabled — click to disable",
|
|
447
|
+
"mcp.toggle.off": "Disabled — click to enable",
|
|
448
|
+
"mcp.toggle.error": "Failed to toggle: {{msg}}",
|
|
449
|
+
"mcp.toolsHeader": "Tools",
|
|
450
|
+
"mcp.toolsLoading": "Loading tools…",
|
|
451
|
+
"mcp.toolsLoadError": "Failed to load tools: {{msg}}",
|
|
452
|
+
"mcp.toolsNone": "Server returned no tools.",
|
|
453
|
+
"mcp.btn.probe": "Show tools",
|
|
454
|
+
"mcp.btn.hide": "Hide tools",
|
|
455
|
+
"mcp.btn.refresh": "Refresh",
|
|
456
|
+
"mcp.btn.remove": "Remove",
|
|
457
|
+
"mcp.btn.askClacky": "Let Clacky help me set this up",
|
|
458
|
+
"mcp.cta.title": "Want to add a new MCP server?",
|
|
459
|
+
"mcp.cta.body": "Tell Clacky in plain words — it'll pick the right package, ask for the parameters that matter, and verify it works.",
|
|
460
|
+
"mcp.cta.button": "Ask Clacky to add one",
|
|
461
|
+
"mcp.remove.confirm": "Remove MCP server '{{name}}'? Its tools will no longer be available.",
|
|
462
|
+
"mcp.remove.error": "Failed to remove: {{msg}}",
|
|
463
|
+
"mcp.loadError": "Failed to load MCP servers: {{msg}}",
|
|
464
|
+
"mcp.docsLink": "How does this work?",
|
|
465
|
+
|
|
406
466
|
// ── Settings panel ──
|
|
407
467
|
"settings.title": "Settings",
|
|
468
|
+
"settings.tabs.models": "Models",
|
|
469
|
+
"settings.tabs.ui": "UI",
|
|
470
|
+
"settings.tabs.general": "General",
|
|
471
|
+
"settings.tabs.about": "About",
|
|
472
|
+
"settings.about.version": "Version",
|
|
473
|
+
"settings.about.appName": "Application",
|
|
474
|
+
"settings.about.versionLabel": "Version",
|
|
475
|
+
"settings.about.links": "Links",
|
|
476
|
+
"settings.about.website": "Website",
|
|
477
|
+
"settings.about.docs": "Documentation",
|
|
408
478
|
"settings.models.title": "AI Models",
|
|
409
479
|
"settings.models.add": "+ Add Model",
|
|
410
480
|
"settings.models.loading": "Loading models…",
|
|
@@ -419,6 +489,7 @@ const I18n = (() => {
|
|
|
419
489
|
"settings.models.field.getApiKey": "How to get →",
|
|
420
490
|
"settings.models.field.docsGuide.question": "New to AI keys?",
|
|
421
491
|
"settings.models.field.docsGuide.cta": "See the guide →",
|
|
492
|
+
"settings.models.field.setDefault": "Set as default model",
|
|
422
493
|
"settings.models.placeholder.provider": "— Choose provider —",
|
|
423
494
|
"settings.models.placeholder.model": "e.g. claude-sonnet-4-5",
|
|
424
495
|
"settings.models.placeholder.baseurl": "https://api.anthropic.com",
|
|
@@ -435,10 +506,20 @@ const I18n = (() => {
|
|
|
435
506
|
"settings.models.btn.saving": "Saving…",
|
|
436
507
|
"settings.models.btn.saved": "Saved ✓",
|
|
437
508
|
"settings.models.btn.testing": "Testing…",
|
|
438
|
-
"settings.models.btn.
|
|
439
|
-
"settings.models.btn.
|
|
509
|
+
"settings.models.btn.test": "Test",
|
|
510
|
+
"settings.models.btn.edit": "Edit",
|
|
511
|
+
"settings.models.btn.delete": "Delete",
|
|
512
|
+
"settings.models.btn.cancel": "Cancel",
|
|
513
|
+
"settings.models.btn.set_default": "Default",
|
|
514
|
+
"settings.models.btn.setDefault": "Default",
|
|
440
515
|
"settings.models.btn.setting": "Setting…",
|
|
441
516
|
"settings.models.btn.done": "Done ✓",
|
|
517
|
+
"settings.models.modal.add": "Add Model",
|
|
518
|
+
"settings.models.modal.edit": "Edit Model",
|
|
519
|
+
"settings.models.field.provider": "Provider",
|
|
520
|
+
"settings.models.provider.custom": "Custom",
|
|
521
|
+
"settings.models.unnamed": "Unnamed Model",
|
|
522
|
+
"settings.models.noModels": "No preset models available",
|
|
442
523
|
"settings.models.test.ok": "✓ Connected",
|
|
443
524
|
"settings.models.test.fail": "✗ Test fail: {{msg}}",
|
|
444
525
|
"settings.models.badge.model": "Model {{n}}",
|
|
@@ -501,6 +582,11 @@ const I18n = (() => {
|
|
|
501
582
|
"settings.fontSize.medium": "Medium",
|
|
502
583
|
"settings.fontSize.large": "Large",
|
|
503
584
|
|
|
585
|
+
"settings.currency.title": "Currency",
|
|
586
|
+
"settings.currency.usd": "$ USD",
|
|
587
|
+
"settings.currency.cny": "¥ CNY",
|
|
588
|
+
"settings.currency.exchangeRate": "Exchange Rate (1 USD =)",
|
|
589
|
+
|
|
504
590
|
// ── Onboard ──
|
|
505
591
|
"onboard.title": "Welcome to {{brand}}",
|
|
506
592
|
"onboard.subtitle": "Let's get you set up in a minute.",
|
|
@@ -518,10 +604,10 @@ const I18n = (() => {
|
|
|
518
604
|
"onboard.key.btn.back": "← Back",
|
|
519
605
|
"onboard.provider.custom": "Custom",
|
|
520
606
|
"provider.recommended": "Recommended",
|
|
521
|
-
"provider.promo.openclacky.title": "
|
|
522
|
-
"provider.promo.openclacky.1": "
|
|
523
|
-
"provider.promo.openclacky.2": "
|
|
524
|
-
"provider.promo.openclacky.3": "Same pricing as official APIs,
|
|
607
|
+
"provider.promo.openclacky.title": "OpenClacky AI Keys",
|
|
608
|
+
"provider.promo.openclacky.1": "All frontier models, one key — Claude, Gemini, DeepSeek & more.",
|
|
609
|
+
"provider.promo.openclacky.2": "Top reasoning, best value, best vision — unified in one API.",
|
|
610
|
+
"provider.promo.openclacky.3": "Same pricing as official APIs, switch models instantly.",
|
|
525
611
|
"onboard.key.testing": "Testing…",
|
|
526
612
|
"onboard.key.saving": "Saving…",
|
|
527
613
|
"onboard.soul.title": "Personalize your assistant",
|
|
@@ -562,15 +648,38 @@ const I18n = (() => {
|
|
|
562
648
|
"sib.bench.latencyTooltip": "TTFT {{ttft}} · tested {{time}}",
|
|
563
649
|
|
|
564
650
|
"onboard.welcome": "Welcome to {{name}}",
|
|
651
|
+
|
|
652
|
+
// ── Billing panel ──
|
|
653
|
+
"billing.title": "Billing",
|
|
654
|
+
"billing.loading": "Loading billing data...",
|
|
655
|
+
"billing.error": "Failed to load billing data",
|
|
656
|
+
"billing.totalCost": "Total Cost",
|
|
657
|
+
"billing.totalTokens": "Total Tokens",
|
|
658
|
+
"billing.requests": "API Requests",
|
|
659
|
+
"billing.tokenBreakdown": "Token Breakdown",
|
|
660
|
+
"billing.promptTokens": "Prompt",
|
|
661
|
+
"billing.completionTokens": "Completion",
|
|
662
|
+
"billing.cacheRead": "Cache Read",
|
|
663
|
+
"billing.cacheWrite": "Cache Write",
|
|
664
|
+
"billing.byModel": "By Model",
|
|
665
|
+
"billing.model": "Model",
|
|
666
|
+
"billing.cost": "Cost",
|
|
667
|
+
"billing.dailyUsage": "Daily Usage",
|
|
668
|
+
"billing.period.day": "Today",
|
|
669
|
+
"billing.period.week": "This Week",
|
|
670
|
+
"billing.period.month": "This Month",
|
|
671
|
+
"billing.period.year": "This Year",
|
|
672
|
+
"billing.period.all": "All Time",
|
|
565
673
|
},
|
|
566
674
|
|
|
567
675
|
zh: {
|
|
568
676
|
// ── Sidebar ──
|
|
569
|
-
"sidebar.chat": "
|
|
677
|
+
"sidebar.chat": "会话",
|
|
570
678
|
"sidebar.config": "配置",
|
|
571
679
|
"sidebar.tasks": "任务管理",
|
|
572
680
|
"sidebar.skills": "技能管理",
|
|
573
681
|
"sidebar.channels": "频道管理",
|
|
682
|
+
"sidebar.mcp": "MCP 工具",
|
|
574
683
|
"sidebar.trash": "文件召回",
|
|
575
684
|
"sidebar.profile": "助理记忆",
|
|
576
685
|
"sidebar.memories": "记忆",
|
|
@@ -578,11 +687,12 @@ const I18n = (() => {
|
|
|
578
687
|
"sidebar.creator": "创作者中心",
|
|
579
688
|
"sidebar.creatorSection": "创作者",
|
|
580
689
|
"sidebar.settings": "设置",
|
|
690
|
+
"sidebar.billing": "用量信息",
|
|
581
691
|
|
|
582
692
|
// ── Welcome screen ──
|
|
583
693
|
"welcome.title": "欢迎使用 {{brand}}",
|
|
584
|
-
"welcome.body": "
|
|
585
|
-
"welcome.btn": "
|
|
694
|
+
"welcome.body": "新建会话,或从左侧选择一个已有会话。",
|
|
695
|
+
"welcome.btn": "新建会话",
|
|
586
696
|
|
|
587
697
|
// ── Chat panel ──
|
|
588
698
|
"chat.status.idle": "空闲",
|
|
@@ -590,6 +700,8 @@ const I18n = (() => {
|
|
|
590
700
|
"chat.status.error": "出错",
|
|
591
701
|
"chat.input.placeholder": "输入消息…(Enter 发送,Shift+Enter 换行)",
|
|
592
702
|
"chat.input.placeholderRunning": "AI 正在工作,你仍然可以随时补充新信息给它...",
|
|
703
|
+
"chat.input.placeholderMobile": "输入消息…",
|
|
704
|
+
"chat.input.placeholderRunningMobile": "可输入补充消息…",
|
|
593
705
|
"chat.btn.send": "发送",
|
|
594
706
|
"chat.thinking": "思考中…",
|
|
595
707
|
"chat.retrying": "正在重试",
|
|
@@ -605,18 +717,19 @@ const I18n = (() => {
|
|
|
605
717
|
"chat.retry": "重试",
|
|
606
718
|
"chat.copy": "复制",
|
|
607
719
|
"chat.copied": "已复制",
|
|
608
|
-
"chat.empty.title": "
|
|
720
|
+
"chat.empty.title": "开始新会话",
|
|
609
721
|
"chat.empty.subtitle": "直接提问,或用一个 Skill 启动。",
|
|
610
722
|
"chat.empty.tip1": "输入 / 浏览 Skill",
|
|
611
723
|
"chat.empty.tip2": "可粘贴或拖入图片、PDF、文档",
|
|
612
724
|
"chat.empty.tip3": "Shift+Enter 换行",
|
|
725
|
+
"chat.empty.tip4": "每个会话上下文独立,但长期记忆全局共享",
|
|
613
726
|
|
|
614
727
|
// ── Session list ──
|
|
615
|
-
"sessions.empty": "
|
|
616
|
-
"sessions.confirmDelete": "
|
|
728
|
+
"sessions.empty": "暂无会话",
|
|
729
|
+
"sessions.confirmDelete": "删除会话 {{name}}?此操作不可撤销。",
|
|
617
730
|
"sessions.meta": "{{tasks}} 个任务 · ${{cost}}",
|
|
618
731
|
"sessions.metaTasks": "{{n}} 个任务",
|
|
619
|
-
"sessions.deleteTitle": "
|
|
732
|
+
"sessions.deleteTitle": "删除会话",
|
|
620
733
|
"sessions.createError": "错误:",
|
|
621
734
|
"sessions.dirNotEmpty": "该目录已存在且不为空,请换一个目录名。",
|
|
622
735
|
"sessions.export.tooltip": "下载会话文件(session.json + 归档片段 + 当天日志),用于调试",
|
|
@@ -627,6 +740,7 @@ const I18n = (() => {
|
|
|
627
740
|
"sib.dir.tooltip": "点击切换工作目录",
|
|
628
741
|
"sib.dir.changePrompt": "切换工作目录:",
|
|
629
742
|
"sib.model.tooltip": "点击切换模型",
|
|
743
|
+
"sib.model.tooltip.busy": "Agent 回复中,暂时无法切换模型",
|
|
630
744
|
"sib.signal.tooltip": "最近一次 LLM 响应延迟",
|
|
631
745
|
"sib.reasoning.tooltip": "点击调整思考等级",
|
|
632
746
|
"sib.reasoning.label": "思考",
|
|
@@ -637,7 +751,7 @@ const I18n = (() => {
|
|
|
637
751
|
"sib.reasoning.medium": "中",
|
|
638
752
|
"sib.reasoning.high": "高",
|
|
639
753
|
"sessions.thinking": "思考中…",
|
|
640
|
-
"sessions.default_name": "
|
|
754
|
+
"sessions.default_name": "会话 {{n}}",
|
|
641
755
|
"sessions.cronGroup": "定时任务",
|
|
642
756
|
"sessions.cronGroupMeta": "{{n}} 个会话",
|
|
643
757
|
"sessions.cronLoading": "正在加载定时任务...",
|
|
@@ -728,7 +842,7 @@ const I18n = (() => {
|
|
|
728
842
|
"tasks.paused": "已暂停",
|
|
729
843
|
"tasks.toggleError": "更新任务失败。",
|
|
730
844
|
"tasks.runError": "错误:",
|
|
731
|
-
"tasks.sessionError": "
|
|
845
|
+
"tasks.sessionError": "创建会话失败:",
|
|
732
846
|
"tasks.confirmDelete": "删除任务「{{name}}」?",
|
|
733
847
|
"tasks.deleteError": "删除任务失败。",
|
|
734
848
|
"tasks.label.active": "任务",
|
|
@@ -794,13 +908,39 @@ const I18n = (() => {
|
|
|
794
908
|
"trash.restoreOk": "已恢复:{{path}}",
|
|
795
909
|
"trash.restoreFail": "恢复失败:{{msg}}",
|
|
796
910
|
"trash.confirmDeleteOne": "永久删除 \"{{name}}\"?\n此操作不可撤销。",
|
|
797
|
-
"trash.confirmEmptyOld": "
|
|
798
|
-
"trash.confirmEmptyAll": "
|
|
911
|
+
"trash.confirmEmptyOld": "永久删除 {{count}} 个超过 7 天的回收站文件?\n此操作不可撤销。",
|
|
912
|
+
"trash.confirmEmptyAll": "永久删除回收站中全部 {{count}} 个文件?\n此操作不可撤销。",
|
|
799
913
|
"trash.confirmEmptyOrphans": "永久删除 {{count}} 条原项目已消失的孤儿条目?\n此操作不可撤销。",
|
|
800
914
|
"trash.emptied": "已永久删除 {{count}} 个文件,释放 {{size}}。",
|
|
801
915
|
"trash.orphansCleaned": "已清理 {{count}} 条孤儿,释放 {{size}}。(失败 {{failed}})",
|
|
802
916
|
"trash.nothingOld": "没有超过 7 天的文件。",
|
|
803
917
|
|
|
918
|
+
// ── Session trash ──
|
|
919
|
+
"trash.tabFile": "文件回收",
|
|
920
|
+
"trash.tabSession": "会话回收",
|
|
921
|
+
"trash.summarySessions": "共 {{count}} 个会话,{{size}}",
|
|
922
|
+
"trash.sessionTasks": "{{n}} 个任务",
|
|
923
|
+
"trash.sessionMessages": "{{n}} 条消息",
|
|
924
|
+
"trash.sessionModel": "模型",
|
|
925
|
+
"trash.restoreSession": "恢复",
|
|
926
|
+
"trash.deleteSession": "删除",
|
|
927
|
+
"trash.noSessionTrash": "回收站中没有被删除的会话。",
|
|
928
|
+
"trash.confirmDeleteSession": "永久删除「{{name}}」?\n此操作不可撤销。",
|
|
929
|
+
"trash.confirmEmptySessionOld": "永久删除 {{count}} 个 7 天前放入回收站的会话?\n此操作不可撤销。",
|
|
930
|
+
"trash.confirmEmptySessionAll": "永久删除回收站中全部 {{count}} 个会话?\n此操作不可撤销。",
|
|
931
|
+
"trash.sessionsCleaned": "已永久删除 {{count}} 个会话。",
|
|
932
|
+
"trash.sessionRestoreOk": "会话已恢复。",
|
|
933
|
+
"trash.sessionRestoreFail": "恢复失败:{{msg}}",
|
|
934
|
+
"trash.sessionRestoreOkAction": "去查看",
|
|
935
|
+
"trash.deleteFail": "删除失败:{{msg}}",
|
|
936
|
+
"trash.cleanFail": "操作失败:{{msg}}",
|
|
937
|
+
|
|
938
|
+
// ── Relative time (used by _humanTime helper) ──
|
|
939
|
+
"time.justNow": "刚刚",
|
|
940
|
+
"time.minsAgo": "{{n}} 分钟前",
|
|
941
|
+
"time.hoursAgo": "{{n}} 小时前",
|
|
942
|
+
"time.daysAgo": "{{n}} 天前",
|
|
943
|
+
|
|
804
944
|
// ── Profile (助理记忆 — USER.md / SOUL.md / 记忆 统一只读视图) ──
|
|
805
945
|
"profile.title": "助理记忆",
|
|
806
946
|
"profile.subtitle": "这是一扇通往 AI 内心的窗口:它是谁、你是谁、以及它在和你共事中记住了什么。",
|
|
@@ -942,7 +1082,7 @@ const I18n = (() => {
|
|
|
942
1082
|
"channels.btn.reconfig": "重新配置",
|
|
943
1083
|
"channels.btn.reconfigure": "重新配置",
|
|
944
1084
|
"channels.sessionError": "未知",
|
|
945
|
-
"channels.noSession": "
|
|
1085
|
+
"channels.noSession": "未返回会话",
|
|
946
1086
|
"channels.feishu.desc": "通过飞书开放平台 WebSocket 长连接接入",
|
|
947
1087
|
"channels.wecom.desc": "通过企业微信智能机器人 WebSocket 接入",
|
|
948
1088
|
"channels.weixin.desc": "通过微信 iLink 机器人接入(扫码登录,HTTP 长轮询)",
|
|
@@ -950,8 +1090,48 @@ const I18n = (() => {
|
|
|
950
1090
|
"channels.telegram.desc": "通过 Telegram Bot API 接入(HTTPS 长轮询,token 来自 @BotFather)",
|
|
951
1091
|
"channels.dingtalk.desc": "通过钉钉 Stream 模式 WebSocket 接入",
|
|
952
1092
|
|
|
1093
|
+
// ── MCP panel ──
|
|
1094
|
+
"mcp.title": "MCP 工具",
|
|
1095
|
+
"mcp.subtitle": "标准 Model Context Protocol 服务(与 Claude Desktop / Cursor 兼容)。编辑 ~/.clacky/mcp.json 添加或移除服务。",
|
|
1096
|
+
"mcp.loading": "加载中…",
|
|
1097
|
+
"mcp.empty.title": "尚未配置 MCP 服务",
|
|
1098
|
+
"mcp.empty.body": "新建 ~/.clacky/mcp.json 即可接入 MCP 服务。格式与 Claude Desktop、Cursor 一致,现有配置可直接复用。",
|
|
1099
|
+
"mcp.config.path": "配置文件:",
|
|
1100
|
+
"mcp.config.missing": "(尚未创建)",
|
|
1101
|
+
"mcp.command": "启动命令",
|
|
1102
|
+
"mcp.url": "URL",
|
|
1103
|
+
"mcp.toggle.on": "已启用 — 点击关闭",
|
|
1104
|
+
"mcp.toggle.off": "已禁用 — 点击启用",
|
|
1105
|
+
"mcp.toggle.error": "切换失败:{{msg}}",
|
|
1106
|
+
"mcp.toolsHeader": "工具列表",
|
|
1107
|
+
"mcp.toolsLoading": "正在拉取工具…",
|
|
1108
|
+
"mcp.toolsLoadError": "拉取工具失败:{{msg}}",
|
|
1109
|
+
"mcp.toolsNone": "服务未返回任何工具。",
|
|
1110
|
+
"mcp.btn.probe": "查看工具",
|
|
1111
|
+
"mcp.btn.hide": "收起",
|
|
1112
|
+
"mcp.btn.refresh": "刷新",
|
|
1113
|
+
"mcp.btn.remove": "移除",
|
|
1114
|
+
"mcp.btn.askClacky": "让 Clacky 帮我配置",
|
|
1115
|
+
"mcp.cta.title": "想接入新的 MCP 服务?",
|
|
1116
|
+
"mcp.cta.body": "用一句大白话告诉 Clacky 想做什么——它会挑合适的包、问关键参数、跑通后回复你。",
|
|
1117
|
+
"mcp.cta.button": "让 Clacky 帮我添加",
|
|
1118
|
+
"mcp.remove.confirm": "移除 MCP 服务 '{{name}}'?相关工具将不再可用。",
|
|
1119
|
+
"mcp.remove.error": "移除失败:{{msg}}",
|
|
1120
|
+
"mcp.loadError": "加载 MCP 服务失败:{{msg}}",
|
|
1121
|
+
"mcp.docsLink": "这个机制怎么工作?",
|
|
1122
|
+
|
|
953
1123
|
// ── Settings panel ──
|
|
954
1124
|
"settings.title": "设置",
|
|
1125
|
+
"settings.tabs.models": "模型",
|
|
1126
|
+
"settings.tabs.ui": "界面",
|
|
1127
|
+
"settings.tabs.general": "通用",
|
|
1128
|
+
"settings.tabs.about": "关于",
|
|
1129
|
+
"settings.about.version": "版本",
|
|
1130
|
+
"settings.about.appName": "应用程序",
|
|
1131
|
+
"settings.about.versionLabel": "版本号",
|
|
1132
|
+
"settings.about.links": "链接",
|
|
1133
|
+
"settings.about.website": "官网",
|
|
1134
|
+
"settings.about.docs": "文档",
|
|
955
1135
|
"settings.models.title": "AI 模型",
|
|
956
1136
|
"settings.models.add": "+ 添加模型",
|
|
957
1137
|
"settings.models.loading": "加载模型中…",
|
|
@@ -966,6 +1146,7 @@ const I18n = (() => {
|
|
|
966
1146
|
"settings.models.field.getApiKey": "如何获取 →",
|
|
967
1147
|
"settings.models.field.docsGuide.question": "不会配置 AI 模型?",
|
|
968
1148
|
"settings.models.field.docsGuide.cta": "查看指南 →",
|
|
1149
|
+
"settings.models.field.setDefault": "设为默认模型",
|
|
969
1150
|
"settings.models.placeholder.provider": "— 选择服务商 —",
|
|
970
1151
|
"settings.models.placeholder.model": "如 claude-sonnet-4-5",
|
|
971
1152
|
"settings.models.placeholder.baseurl": "https://api.anthropic.com",
|
|
@@ -982,10 +1163,20 @@ const I18n = (() => {
|
|
|
982
1163
|
"settings.models.btn.saving": "保存中…",
|
|
983
1164
|
"settings.models.btn.saved": "已保存 ✓",
|
|
984
1165
|
"settings.models.btn.testing": "测试中…",
|
|
1166
|
+
"settings.models.btn.test": "测试",
|
|
1167
|
+
"settings.models.btn.edit": "编辑",
|
|
1168
|
+
"settings.models.btn.delete": "删除",
|
|
1169
|
+
"settings.models.btn.cancel": "取消",
|
|
985
1170
|
"settings.models.btn.set_default": "设为默认",
|
|
986
1171
|
"settings.models.btn.setDefault": "设为默认",
|
|
987
1172
|
"settings.models.btn.setting": "设置中…",
|
|
988
1173
|
"settings.models.btn.done": "完成 ✓",
|
|
1174
|
+
"settings.models.modal.add": "添加模型",
|
|
1175
|
+
"settings.models.modal.edit": "编辑模型",
|
|
1176
|
+
"settings.models.field.provider": "供应商",
|
|
1177
|
+
"settings.models.provider.custom": "自定义",
|
|
1178
|
+
"settings.models.unnamed": "未命名模型",
|
|
1179
|
+
"settings.models.noModels": "暂无预设模型",
|
|
989
1180
|
"settings.models.test.ok": "✓ 连接成功",
|
|
990
1181
|
"settings.models.test.fail": "✗ 测试失败:{{msg}}",
|
|
991
1182
|
"settings.models.badge.model": "模型 {{n}}",
|
|
@@ -1048,6 +1239,11 @@ const I18n = (() => {
|
|
|
1048
1239
|
"settings.fontSize.medium": "中",
|
|
1049
1240
|
"settings.fontSize.large": "大",
|
|
1050
1241
|
|
|
1242
|
+
"settings.currency.title": "货币",
|
|
1243
|
+
"settings.currency.usd": "$ 美元",
|
|
1244
|
+
"settings.currency.cny": "¥ 人民币",
|
|
1245
|
+
"settings.currency.exchangeRate": "汇率 (1 美元 =)",
|
|
1246
|
+
|
|
1051
1247
|
// ── Onboard ──
|
|
1052
1248
|
"onboard.title": "欢迎使用 {{brand}}",
|
|
1053
1249
|
"onboard.subtitle": "一分钟完成配置,马上开始。",
|
|
@@ -1065,10 +1261,10 @@ const I18n = (() => {
|
|
|
1065
1261
|
"onboard.key.btn.back": "← 返回",
|
|
1066
1262
|
"onboard.provider.custom": "自定义",
|
|
1067
1263
|
"provider.recommended": "推荐",
|
|
1068
|
-
"provider.promo.openclacky.title": "
|
|
1069
|
-
"provider.promo.openclacky.1": "一个 Key
|
|
1070
|
-
"provider.promo.openclacky.2": "
|
|
1071
|
-
"provider.promo.openclacky.3": "
|
|
1264
|
+
"provider.promo.openclacky.title": "推荐 OpenClacky AI Keys",
|
|
1265
|
+
"provider.promo.openclacky.1": "一个 Key 直通全球顶级模型 — Claude、Gemini、DeepSeek 等。",
|
|
1266
|
+
"provider.promo.openclacky.2": "最强推理 × 最优性价比 × 最佳视觉 — 一站式统一接入。",
|
|
1267
|
+
"provider.promo.openclacky.3": "国内直连,官方同价,模型随心切换,缓存命中率接近 100%。",
|
|
1072
1268
|
"onboard.key.testing": "测试中…",
|
|
1073
1269
|
"onboard.key.saving": "保存中…",
|
|
1074
1270
|
"onboard.soul.title": "个性化助手",
|
|
@@ -1109,6 +1305,28 @@ const I18n = (() => {
|
|
|
1109
1305
|
"sib.bench.latencyTooltip": "TTFT {{ttft}} · 测试于 {{time}}",
|
|
1110
1306
|
|
|
1111
1307
|
"onboard.welcome": "欢迎使用 {{name}}",
|
|
1308
|
+
|
|
1309
|
+
// ── Billing panel ──
|
|
1310
|
+
"billing.title": "账单",
|
|
1311
|
+
"billing.loading": "加载账单数据中...",
|
|
1312
|
+
"billing.error": "加载账单数据失败",
|
|
1313
|
+
"billing.totalCost": "总费用",
|
|
1314
|
+
"billing.totalTokens": "总 Token",
|
|
1315
|
+
"billing.requests": "API 请求数",
|
|
1316
|
+
"billing.tokenBreakdown": "Token 明细",
|
|
1317
|
+
"billing.promptTokens": "输入",
|
|
1318
|
+
"billing.completionTokens": "输出",
|
|
1319
|
+
"billing.cacheRead": "缓存读取",
|
|
1320
|
+
"billing.cacheWrite": "缓存写入",
|
|
1321
|
+
"billing.byModel": "按模型",
|
|
1322
|
+
"billing.model": "模型",
|
|
1323
|
+
"billing.cost": "费用",
|
|
1324
|
+
"billing.dailyUsage": "每日用量",
|
|
1325
|
+
"billing.period.day": "今日",
|
|
1326
|
+
"billing.period.week": "本周",
|
|
1327
|
+
"billing.period.month": "本月",
|
|
1328
|
+
"billing.period.year": "今年",
|
|
1329
|
+
"billing.period.all": "全部",
|
|
1112
1330
|
}
|
|
1113
1331
|
};
|
|
1114
1332
|
|