openclacky 1.1.5 → 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 +45 -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 +113 -63
- 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 +521 -17
- data/lib/clacky/server/server_master.rb +8 -14
- data/lib/clacky/server/session_registry.rb +30 -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 +41 -6
- 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 +51 -40
- data/lib/clacky/web/i18n.js +248 -24
- data/lib/clacky/web/index.html +362 -134
- data/lib/clacky/web/mcp.js +328 -0
- data/lib/clacky/web/sessions.js +299 -18
- 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 +15 -2
- 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",
|
|
@@ -88,6 +94,9 @@ const I18n = (() => {
|
|
|
88
94
|
"sib.reasoning.high": "High",
|
|
89
95
|
"sessions.thinking": "Thinking…",
|
|
90
96
|
"sessions.default_name": "Session {{n}}",
|
|
97
|
+
"sessions.cronGroup": "Scheduled Tasks",
|
|
98
|
+
"sessions.cronGroupMeta": "{{n}} sessions",
|
|
99
|
+
"sessions.cronLoading": "Loading scheduled tasks...",
|
|
91
100
|
"sessions.badge.cron": "Auto",
|
|
92
101
|
"sessions.badge.channel": "Channel",
|
|
93
102
|
"sessions.badge.coding": "Coding",
|
|
@@ -243,13 +252,37 @@ const I18n = (() => {
|
|
|
243
252
|
"trash.restoreOk": "Restored: {{path}}",
|
|
244
253
|
"trash.restoreFail": "Restore failed: {{msg}}",
|
|
245
254
|
"trash.confirmDeleteOne": "Permanently delete \"{{name}}\"?\nThis cannot be undone.",
|
|
246
|
-
"trash.confirmEmptyOld": "Permanently delete
|
|
247
|
-
"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.",
|
|
248
257
|
"trash.confirmEmptyOrphans": "Permanently delete {{count}} orphan trash entries whose original project directory is gone?\nThis cannot be undone.",
|
|
249
258
|
"trash.emptied": "Permanently deleted {{count}} file(s), freed {{size}}.",
|
|
250
259
|
"trash.orphansCleaned": "Cleaned {{count}} orphan entries, freed {{size}}. ({{failed}} failed)",
|
|
251
260
|
"trash.nothingOld": "No files older than 7 days.",
|
|
252
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
|
+
|
|
253
286
|
// ── Profile (unified read-only view of USER.md / SOUL.md / memories) ──
|
|
254
287
|
"profile.title": "Assistant Memory",
|
|
255
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.",
|
|
@@ -400,8 +433,48 @@ const I18n = (() => {
|
|
|
400
433
|
"channels.telegram.desc": "Connect via Telegram Bot API (HTTPS long-poll, token from @BotFather)",
|
|
401
434
|
"channels.dingtalk.desc": "Connect via DingTalk Stream Mode WebSocket",
|
|
402
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
|
+
|
|
403
466
|
// ── Settings panel ──
|
|
404
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",
|
|
405
478
|
"settings.models.title": "AI Models",
|
|
406
479
|
"settings.models.add": "+ Add Model",
|
|
407
480
|
"settings.models.loading": "Loading models…",
|
|
@@ -416,6 +489,7 @@ const I18n = (() => {
|
|
|
416
489
|
"settings.models.field.getApiKey": "How to get →",
|
|
417
490
|
"settings.models.field.docsGuide.question": "New to AI keys?",
|
|
418
491
|
"settings.models.field.docsGuide.cta": "See the guide →",
|
|
492
|
+
"settings.models.field.setDefault": "Set as default model",
|
|
419
493
|
"settings.models.placeholder.provider": "— Choose provider —",
|
|
420
494
|
"settings.models.placeholder.model": "e.g. claude-sonnet-4-5",
|
|
421
495
|
"settings.models.placeholder.baseurl": "https://api.anthropic.com",
|
|
@@ -432,10 +506,20 @@ const I18n = (() => {
|
|
|
432
506
|
"settings.models.btn.saving": "Saving…",
|
|
433
507
|
"settings.models.btn.saved": "Saved ✓",
|
|
434
508
|
"settings.models.btn.testing": "Testing…",
|
|
435
|
-
"settings.models.btn.
|
|
436
|
-
"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",
|
|
437
515
|
"settings.models.btn.setting": "Setting…",
|
|
438
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",
|
|
439
523
|
"settings.models.test.ok": "✓ Connected",
|
|
440
524
|
"settings.models.test.fail": "✗ Test fail: {{msg}}",
|
|
441
525
|
"settings.models.badge.model": "Model {{n}}",
|
|
@@ -498,6 +582,11 @@ const I18n = (() => {
|
|
|
498
582
|
"settings.fontSize.medium": "Medium",
|
|
499
583
|
"settings.fontSize.large": "Large",
|
|
500
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
|
+
|
|
501
590
|
// ── Onboard ──
|
|
502
591
|
"onboard.title": "Welcome to {{brand}}",
|
|
503
592
|
"onboard.subtitle": "Let's get you set up in a minute.",
|
|
@@ -515,10 +604,10 @@ const I18n = (() => {
|
|
|
515
604
|
"onboard.key.btn.back": "← Back",
|
|
516
605
|
"onboard.provider.custom": "Custom",
|
|
517
606
|
"provider.recommended": "Recommended",
|
|
518
|
-
"provider.promo.openclacky.title": "
|
|
519
|
-
"provider.promo.openclacky.1": "
|
|
520
|
-
"provider.promo.openclacky.2": "
|
|
521
|
-
"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.",
|
|
522
611
|
"onboard.key.testing": "Testing…",
|
|
523
612
|
"onboard.key.saving": "Saving…",
|
|
524
613
|
"onboard.soul.title": "Personalize your assistant",
|
|
@@ -559,15 +648,38 @@ const I18n = (() => {
|
|
|
559
648
|
"sib.bench.latencyTooltip": "TTFT {{ttft}} · tested {{time}}",
|
|
560
649
|
|
|
561
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",
|
|
562
673
|
},
|
|
563
674
|
|
|
564
675
|
zh: {
|
|
565
676
|
// ── Sidebar ──
|
|
566
|
-
"sidebar.chat": "
|
|
677
|
+
"sidebar.chat": "会话",
|
|
567
678
|
"sidebar.config": "配置",
|
|
568
679
|
"sidebar.tasks": "任务管理",
|
|
569
680
|
"sidebar.skills": "技能管理",
|
|
570
681
|
"sidebar.channels": "频道管理",
|
|
682
|
+
"sidebar.mcp": "MCP 工具",
|
|
571
683
|
"sidebar.trash": "文件召回",
|
|
572
684
|
"sidebar.profile": "助理记忆",
|
|
573
685
|
"sidebar.memories": "记忆",
|
|
@@ -575,11 +687,12 @@ const I18n = (() => {
|
|
|
575
687
|
"sidebar.creator": "创作者中心",
|
|
576
688
|
"sidebar.creatorSection": "创作者",
|
|
577
689
|
"sidebar.settings": "设置",
|
|
690
|
+
"sidebar.billing": "用量信息",
|
|
578
691
|
|
|
579
692
|
// ── Welcome screen ──
|
|
580
693
|
"welcome.title": "欢迎使用 {{brand}}",
|
|
581
|
-
"welcome.body": "
|
|
582
|
-
"welcome.btn": "
|
|
694
|
+
"welcome.body": "新建会话,或从左侧选择一个已有会话。",
|
|
695
|
+
"welcome.btn": "新建会话",
|
|
583
696
|
|
|
584
697
|
// ── Chat panel ──
|
|
585
698
|
"chat.status.idle": "空闲",
|
|
@@ -587,6 +700,8 @@ const I18n = (() => {
|
|
|
587
700
|
"chat.status.error": "出错",
|
|
588
701
|
"chat.input.placeholder": "输入消息…(Enter 发送,Shift+Enter 换行)",
|
|
589
702
|
"chat.input.placeholderRunning": "AI 正在工作,你仍然可以随时补充新信息给它...",
|
|
703
|
+
"chat.input.placeholderMobile": "输入消息…",
|
|
704
|
+
"chat.input.placeholderRunningMobile": "可输入补充消息…",
|
|
590
705
|
"chat.btn.send": "发送",
|
|
591
706
|
"chat.thinking": "思考中…",
|
|
592
707
|
"chat.retrying": "正在重试",
|
|
@@ -602,18 +717,19 @@ const I18n = (() => {
|
|
|
602
717
|
"chat.retry": "重试",
|
|
603
718
|
"chat.copy": "复制",
|
|
604
719
|
"chat.copied": "已复制",
|
|
605
|
-
"chat.empty.title": "
|
|
720
|
+
"chat.empty.title": "开始新会话",
|
|
606
721
|
"chat.empty.subtitle": "直接提问,或用一个 Skill 启动。",
|
|
607
722
|
"chat.empty.tip1": "输入 / 浏览 Skill",
|
|
608
723
|
"chat.empty.tip2": "可粘贴或拖入图片、PDF、文档",
|
|
609
724
|
"chat.empty.tip3": "Shift+Enter 换行",
|
|
725
|
+
"chat.empty.tip4": "每个会话上下文独立,但长期记忆全局共享",
|
|
610
726
|
|
|
611
727
|
// ── Session list ──
|
|
612
|
-
"sessions.empty": "
|
|
613
|
-
"sessions.confirmDelete": "
|
|
728
|
+
"sessions.empty": "暂无会话",
|
|
729
|
+
"sessions.confirmDelete": "删除会话 {{name}}?此操作不可撤销。",
|
|
614
730
|
"sessions.meta": "{{tasks}} 个任务 · ${{cost}}",
|
|
615
731
|
"sessions.metaTasks": "{{n}} 个任务",
|
|
616
|
-
"sessions.deleteTitle": "
|
|
732
|
+
"sessions.deleteTitle": "删除会话",
|
|
617
733
|
"sessions.createError": "错误:",
|
|
618
734
|
"sessions.dirNotEmpty": "该目录已存在且不为空,请换一个目录名。",
|
|
619
735
|
"sessions.export.tooltip": "下载会话文件(session.json + 归档片段 + 当天日志),用于调试",
|
|
@@ -624,6 +740,7 @@ const I18n = (() => {
|
|
|
624
740
|
"sib.dir.tooltip": "点击切换工作目录",
|
|
625
741
|
"sib.dir.changePrompt": "切换工作目录:",
|
|
626
742
|
"sib.model.tooltip": "点击切换模型",
|
|
743
|
+
"sib.model.tooltip.busy": "Agent 回复中,暂时无法切换模型",
|
|
627
744
|
"sib.signal.tooltip": "最近一次 LLM 响应延迟",
|
|
628
745
|
"sib.reasoning.tooltip": "点击调整思考等级",
|
|
629
746
|
"sib.reasoning.label": "思考",
|
|
@@ -634,7 +751,10 @@ const I18n = (() => {
|
|
|
634
751
|
"sib.reasoning.medium": "中",
|
|
635
752
|
"sib.reasoning.high": "高",
|
|
636
753
|
"sessions.thinking": "思考中…",
|
|
637
|
-
"sessions.default_name": "
|
|
754
|
+
"sessions.default_name": "会话 {{n}}",
|
|
755
|
+
"sessions.cronGroup": "定时任务",
|
|
756
|
+
"sessions.cronGroupMeta": "{{n}} 个会话",
|
|
757
|
+
"sessions.cronLoading": "正在加载定时任务...",
|
|
638
758
|
"sessions.badge.cron": "定时",
|
|
639
759
|
"sessions.badge.channel": "频道",
|
|
640
760
|
"sessions.badge.coding": "Coding",
|
|
@@ -722,7 +842,7 @@ const I18n = (() => {
|
|
|
722
842
|
"tasks.paused": "已暂停",
|
|
723
843
|
"tasks.toggleError": "更新任务失败。",
|
|
724
844
|
"tasks.runError": "错误:",
|
|
725
|
-
"tasks.sessionError": "
|
|
845
|
+
"tasks.sessionError": "创建会话失败:",
|
|
726
846
|
"tasks.confirmDelete": "删除任务「{{name}}」?",
|
|
727
847
|
"tasks.deleteError": "删除任务失败。",
|
|
728
848
|
"tasks.label.active": "任务",
|
|
@@ -788,13 +908,39 @@ const I18n = (() => {
|
|
|
788
908
|
"trash.restoreOk": "已恢复:{{path}}",
|
|
789
909
|
"trash.restoreFail": "恢复失败:{{msg}}",
|
|
790
910
|
"trash.confirmDeleteOne": "永久删除 \"{{name}}\"?\n此操作不可撤销。",
|
|
791
|
-
"trash.confirmEmptyOld": "
|
|
792
|
-
"trash.confirmEmptyAll": "
|
|
911
|
+
"trash.confirmEmptyOld": "永久删除 {{count}} 个超过 7 天的回收站文件?\n此操作不可撤销。",
|
|
912
|
+
"trash.confirmEmptyAll": "永久删除回收站中全部 {{count}} 个文件?\n此操作不可撤销。",
|
|
793
913
|
"trash.confirmEmptyOrphans": "永久删除 {{count}} 条原项目已消失的孤儿条目?\n此操作不可撤销。",
|
|
794
914
|
"trash.emptied": "已永久删除 {{count}} 个文件,释放 {{size}}。",
|
|
795
915
|
"trash.orphansCleaned": "已清理 {{count}} 条孤儿,释放 {{size}}。(失败 {{failed}})",
|
|
796
916
|
"trash.nothingOld": "没有超过 7 天的文件。",
|
|
797
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
|
+
|
|
798
944
|
// ── Profile (助理记忆 — USER.md / SOUL.md / 记忆 统一只读视图) ──
|
|
799
945
|
"profile.title": "助理记忆",
|
|
800
946
|
"profile.subtitle": "这是一扇通往 AI 内心的窗口:它是谁、你是谁、以及它在和你共事中记住了什么。",
|
|
@@ -936,7 +1082,7 @@ const I18n = (() => {
|
|
|
936
1082
|
"channels.btn.reconfig": "重新配置",
|
|
937
1083
|
"channels.btn.reconfigure": "重新配置",
|
|
938
1084
|
"channels.sessionError": "未知",
|
|
939
|
-
"channels.noSession": "
|
|
1085
|
+
"channels.noSession": "未返回会话",
|
|
940
1086
|
"channels.feishu.desc": "通过飞书开放平台 WebSocket 长连接接入",
|
|
941
1087
|
"channels.wecom.desc": "通过企业微信智能机器人 WebSocket 接入",
|
|
942
1088
|
"channels.weixin.desc": "通过微信 iLink 机器人接入(扫码登录,HTTP 长轮询)",
|
|
@@ -944,8 +1090,48 @@ const I18n = (() => {
|
|
|
944
1090
|
"channels.telegram.desc": "通过 Telegram Bot API 接入(HTTPS 长轮询,token 来自 @BotFather)",
|
|
945
1091
|
"channels.dingtalk.desc": "通过钉钉 Stream 模式 WebSocket 接入",
|
|
946
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
|
+
|
|
947
1123
|
// ── Settings panel ──
|
|
948
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": "文档",
|
|
949
1135
|
"settings.models.title": "AI 模型",
|
|
950
1136
|
"settings.models.add": "+ 添加模型",
|
|
951
1137
|
"settings.models.loading": "加载模型中…",
|
|
@@ -960,6 +1146,7 @@ const I18n = (() => {
|
|
|
960
1146
|
"settings.models.field.getApiKey": "如何获取 →",
|
|
961
1147
|
"settings.models.field.docsGuide.question": "不会配置 AI 模型?",
|
|
962
1148
|
"settings.models.field.docsGuide.cta": "查看指南 →",
|
|
1149
|
+
"settings.models.field.setDefault": "设为默认模型",
|
|
963
1150
|
"settings.models.placeholder.provider": "— 选择服务商 —",
|
|
964
1151
|
"settings.models.placeholder.model": "如 claude-sonnet-4-5",
|
|
965
1152
|
"settings.models.placeholder.baseurl": "https://api.anthropic.com",
|
|
@@ -976,10 +1163,20 @@ const I18n = (() => {
|
|
|
976
1163
|
"settings.models.btn.saving": "保存中…",
|
|
977
1164
|
"settings.models.btn.saved": "已保存 ✓",
|
|
978
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": "取消",
|
|
979
1170
|
"settings.models.btn.set_default": "设为默认",
|
|
980
1171
|
"settings.models.btn.setDefault": "设为默认",
|
|
981
1172
|
"settings.models.btn.setting": "设置中…",
|
|
982
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": "暂无预设模型",
|
|
983
1180
|
"settings.models.test.ok": "✓ 连接成功",
|
|
984
1181
|
"settings.models.test.fail": "✗ 测试失败:{{msg}}",
|
|
985
1182
|
"settings.models.badge.model": "模型 {{n}}",
|
|
@@ -1042,6 +1239,11 @@ const I18n = (() => {
|
|
|
1042
1239
|
"settings.fontSize.medium": "中",
|
|
1043
1240
|
"settings.fontSize.large": "大",
|
|
1044
1241
|
|
|
1242
|
+
"settings.currency.title": "货币",
|
|
1243
|
+
"settings.currency.usd": "$ 美元",
|
|
1244
|
+
"settings.currency.cny": "¥ 人民币",
|
|
1245
|
+
"settings.currency.exchangeRate": "汇率 (1 美元 =)",
|
|
1246
|
+
|
|
1045
1247
|
// ── Onboard ──
|
|
1046
1248
|
"onboard.title": "欢迎使用 {{brand}}",
|
|
1047
1249
|
"onboard.subtitle": "一分钟完成配置,马上开始。",
|
|
@@ -1059,10 +1261,10 @@ const I18n = (() => {
|
|
|
1059
1261
|
"onboard.key.btn.back": "← 返回",
|
|
1060
1262
|
"onboard.provider.custom": "自定义",
|
|
1061
1263
|
"provider.recommended": "推荐",
|
|
1062
|
-
"provider.promo.openclacky.title": "
|
|
1063
|
-
"provider.promo.openclacky.1": "一个 Key
|
|
1064
|
-
"provider.promo.openclacky.2": "
|
|
1065
|
-
"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%。",
|
|
1066
1268
|
"onboard.key.testing": "测试中…",
|
|
1067
1269
|
"onboard.key.saving": "保存中…",
|
|
1068
1270
|
"onboard.soul.title": "个性化助手",
|
|
@@ -1103,6 +1305,28 @@ const I18n = (() => {
|
|
|
1103
1305
|
"sib.bench.latencyTooltip": "TTFT {{ttft}} · 测试于 {{time}}",
|
|
1104
1306
|
|
|
1105
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": "全部",
|
|
1106
1330
|
}
|
|
1107
1331
|
};
|
|
1108
1332
|
|