sideby 0.16.0 → 0.17.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 (77) hide show
  1. package/README.md +5 -3
  2. package/dist/build.json +1 -1
  3. package/dist/src/cli/commands.d.ts +16 -0
  4. package/dist/src/cli/commands.js +460 -5
  5. package/dist/src/cli/json-schemas.js +115 -0
  6. package/dist/src/cli/main.js +93 -3
  7. package/dist/src/core/ask.d.ts +150 -0
  8. package/dist/src/core/ask.js +365 -0
  9. package/dist/src/core/attachments.d.ts +50 -0
  10. package/dist/src/core/attachments.js +442 -0
  11. package/dist/src/core/autostart.d.ts +88 -0
  12. package/dist/src/core/autostart.js +256 -0
  13. package/dist/src/core/config.d.ts +97 -0
  14. package/dist/src/core/config.js +278 -10
  15. package/dist/src/core/launch.d.ts +15 -4
  16. package/dist/src/core/launch.js +27 -23
  17. package/dist/src/core/local-build.d.ts +17 -0
  18. package/dist/src/core/local-build.js +39 -3
  19. package/dist/src/core/probe.d.ts +78 -0
  20. package/dist/src/core/probe.js +127 -0
  21. package/dist/src/core/same-login.d.ts +9 -4
  22. package/dist/src/core/same-login.js +9 -4
  23. package/dist/src/core/secret-file.d.ts +26 -0
  24. package/dist/src/core/secret-file.js +126 -7
  25. package/dist/src/core/terminal.d.ts +93 -0
  26. package/dist/src/core/terminal.js +371 -0
  27. package/dist/src/core/update.d.ts +17 -0
  28. package/dist/src/core/update.js +63 -1
  29. package/dist/src/families/claude/index.js +3 -0
  30. package/dist/src/families/claude/quota-cache.d.ts +24 -7
  31. package/dist/src/families/claude/quota-cache.js +72 -21
  32. package/dist/src/families/codex/index.js +7 -0
  33. package/dist/src/families/codex/login-key.d.ts +8 -0
  34. package/dist/src/families/codex/login-key.js +33 -0
  35. package/dist/src/families/grok/index.js +3 -0
  36. package/dist/src/families/login-keys.d.ts +6 -0
  37. package/dist/src/families/login-keys.js +6 -0
  38. package/dist/src/families/pi/index.js +4 -0
  39. package/dist/src/panel/background.js +3 -2
  40. package/dist/src/panel/handler.d.ts +29 -2
  41. package/dist/src/panel/handler.js +396 -9
  42. package/dist/src/panel/i18n.d.ts +175 -2
  43. package/dist/src/panel/i18n.js +381 -35
  44. package/dist/src/panel/page-logic.d.ts +214 -0
  45. package/dist/src/panel/page-logic.js +394 -0
  46. package/dist/src/panel/page-script.js +984 -134
  47. package/dist/src/panel/page-styles.js +69 -19
  48. package/dist/src/panel/page.d.ts +5 -0
  49. package/dist/src/panel/page.js +2 -0
  50. package/dist/src/panel/server.d.ts +16 -2
  51. package/dist/src/panel/server.js +41 -13
  52. package/dist/src/plugins/check.d.ts +47 -0
  53. package/dist/src/plugins/check.js +544 -0
  54. package/dist/src/plugins/scaffold.d.ts +21 -0
  55. package/dist/src/plugins/scaffold.js +123 -0
  56. package/dist/src/quota/statusline-tap.js +1 -1
  57. package/dist/src/runtime.d.ts +10 -0
  58. package/dist/src/runtime.js +47 -16
  59. package/dist/src/types.d.ts +19 -0
  60. package/package.json +2 -2
  61. package/schemas/ask.json +180 -0
  62. package/schemas/autostart.json +165 -0
  63. package/schemas/config-get.json +132 -0
  64. package/schemas/config-set.json +107 -0
  65. package/schemas/config.json +73 -6
  66. package/schemas/key.json +93 -0
  67. package/schemas/local.json +4 -0
  68. package/schemas/plugins-check.json +113 -0
  69. package/schemas/plugins-new.json +87 -0
  70. package/schemas/terminal.json +152 -0
  71. package/schemas/try.json +109 -0
  72. package/schemas/update.json +4 -0
  73. package/skills/sideby/SKILL.md +12 -6
  74. package/skills/sideby/references/accounts.md +1 -1
  75. package/skills/sideby/references/ai-tasks.md +116 -0
  76. package/skills/sideby/references/panel.md +14 -0
  77. package/skills/sideby/references/update.md +1 -1
@@ -33,6 +33,9 @@ const en = {
33
33
  'upd.local': 'Local build from this checkout, built {at}.',
34
34
  'upd.localDirty': 'Local build from this checkout, with changes not committed yet, built {at}.',
35
35
  'loc.toNpm': 'Switch to the release',
36
+ 'loc.toNpmV': 'Switch to the release {v}',
37
+ 'upd.localSwitch': 'You are running a local build, and sideby {v} is out. Switching to the release puts it in place, and the skill comes along.',
38
+ 'upd.localManual': 'Or run this in the sideby checkout:',
36
39
  'loc.toNpmHint': 'Go back to the version published on npm; switch here again to come back.',
37
40
  'loc.toLocal': 'Switch to the local build',
38
41
  'loc.toLocalHint': 'A local build is kept: {b}, built {at}. It is not rebuilt; pnpm local in the checkout builds a new one.',
@@ -234,6 +237,7 @@ const en = {
234
237
  'row.collapse': 'Hide details of {name}',
235
238
  'row.expand': 'Show details of {name}',
236
239
  'row.runs': 'Runs as',
240
+ 'row.browser': 'Signed in on the web in Chrome',
237
241
  'group.toggle': '{title} ({count}): {action}',
238
242
  'group.attention.one': '{n} needs attention',
239
243
  'group.attention.other': '{n} need attention',
@@ -272,7 +276,6 @@ const en = {
272
276
  'quota.asOf': 'As of {ago}',
273
277
  'quota.sharedFrom': 'Same login as {name}; quota read from {name}, {ago}',
274
278
  'login.label': 'Same login: {names}',
275
- 'login.dirs': '{n} directories · shared quota',
276
279
  'login.explain': 'These directories are signed in to the same account, so their quota counts as one.',
277
280
  'login.copyRun': 'Copy start command',
278
281
  'login.showAs': 'Show this name',
@@ -347,9 +350,8 @@ const en = {
347
350
  'last.unknown': 'No recent activity recorded',
348
351
  'health.title': 'Health check',
349
352
  'health.intro': 'Checks that shared skills, settings and credentials are in place for every account.',
350
- 'health.lead': 'Checks {shared} and reports {drift}.',
351
- 'health.sharedTerm': 'Shared Items',
352
- 'health.driftTerm': 'Drift',
353
+ 'health.lead': 'Checks that every account {shared} the main account the way it should.',
354
+ 'health.sharedTerm': 'shares settings with',
353
355
  'health.more.one': 'Show {n} more',
354
356
  'health.more.other': 'Show {n} more',
355
357
  'health.run': 'Run check',
@@ -415,6 +417,139 @@ const en = {
415
417
  'ai.orderHint': 'or ask your AI',
416
418
  'ai.emptyHint': 'Or let your AI assistant set it up for you.',
417
419
  'ai.how': 'How',
420
+ 'ai.ask.api': 'Add a DeepSeek API account for me.',
421
+ 'ai.ask.tool': 'Help sideby support a new tool.',
422
+ 'ask.button': 'Let AI do it',
423
+ 'ask.title': 'Let AI do it',
424
+ 'ask.title.fix': 'Let AI fix it',
425
+ 'ask.title.quota': 'Ask AI why',
426
+ 'ask.title.account': 'Let AI set up an account',
427
+ 'ask.title.host': 'Let AI support a new tool',
428
+ 'ask.title.plugin': 'Let AI write a plugin',
429
+ 'ask.title.terminal': 'Let AI set up your terminal',
430
+ 'ask.title.handoff': 'Let AI tune it',
431
+ 'ask.intro': 'Your own AI opens in a terminal and does it with the sideby skill. It shows you every change first, and you answer its questions there.',
432
+ 'ask.what': 'What should AI do?',
433
+ 'ask.whatMore': 'Anything to add? (optional)',
434
+ 'ask.ph.free': 'For example: add a DeepSeek API account',
435
+ 'ask.ph.account': 'For example: I have a DeepSeek API key',
436
+ 'ask.ph.fix': 'Anything to add? You can leave this empty',
437
+ 'ask.ph.quota': 'Anything to add? You can leave this empty',
438
+ 'ask.ph.host': 'Which tool do you want to use?',
439
+ 'ask.ph.plugin': 'What should the plugin do?',
440
+ 'ask.ph.terminal': 'Which terminal do you use?',
441
+ 'ask.ph.handoff': 'Anything to add? For example: use work first',
442
+ 'ask.ex.handoff.1': 'Recommend a threshold for my accounts',
443
+ 'ask.ex.handoff.2': 'Use my team account last',
444
+ 'ask.ex.handoff.3': 'Explain how a handoff works first',
445
+ 'ask.ex.account.1': 'Add a Claude subscription account',
446
+ 'ask.ex.account.2': 'I have an API address or a docs link',
447
+ 'ask.ex.fix.1': 'Fix these problems for me',
448
+ 'ask.ex.fix.2': 'Explain them first, then fix them',
449
+ 'ask.ex.quota.1': "Why can't I see my quota?",
450
+ 'ask.ex.quota.2': 'Turn on the quota display for me',
451
+ 'ask.ex.host.1': 'I want to use Gemini CLI',
452
+ 'ask.ex.host.2': 'I want to use OpenCode',
453
+ 'ask.ex.plugin.1': 'Switch my proxy before each launch',
454
+ 'ask.ex.plugin.2': 'Copy my settings into each new account',
455
+ 'ask.ex.terminal.1': 'I use Warp',
456
+ 'ask.ex.terminal.2': "sideby doesn't recognize my terminal",
457
+ 'ask.examples': 'Or start from one of these:',
458
+ 'ask.task.fix': 'AI will fix the problems the health check cannot fix by itself ({n}).',
459
+ 'ask.task.quota': 'AI will find out why {ref} shows no quota, and make it show.',
460
+ 'ask.task.account': 'AI will help you add an account: a subscription, or one from an API address or docs link you have.',
461
+ 'ask.task.host': 'AI will help sideby support a tool it does not list yet, first as a plugin on this computer.',
462
+ 'ask.task.plugin': 'AI will help you write a sideby plugin or hook.',
463
+ 'ask.task.handoff': 'AI looks at your accounts and recommends when to hand over and in what order; it shows the change before saving it.',
464
+ 'ask.task.terminal': 'AI will write the command that opens AI tasks in your terminal, and ask you before saving it.',
465
+ 'ask.keyWarn': 'That looks like a key. Keys never go to AI: enter them with "Enter key" in the account menu.',
466
+ 'ask.keyRemoved': 'Key-shaped text was taken out before the AI sees it. Enter keys with "Enter key" in the account menu.',
467
+ 'ask.account': 'Account',
468
+ 'ask.terminal': 'Terminal',
469
+ 'ask.chooseAccount': 'Choose an account',
470
+ 'ask.confirm': 'Opens {terminal} and starts {ref} there.',
471
+ 'ask.open': 'Open in {terminal}',
472
+ 'ask.opening': 'Opening…',
473
+ 'ask.loading': 'Finding an account…',
474
+ 'ask.noAccount.no-accounts': 'There is no account to run AI with yet.',
475
+ 'ask.noAccount.none-signed-in': 'No account is signed in, so none can run the AI.',
476
+ 'ask.noAccount.all-full': 'Every signed-in account is out of quota right now.',
477
+ 'ask.noAccountHint': 'Copy the prompt and paste it into any AI you like.',
478
+ 'ask.signInMain': 'Sign in {ref}',
479
+ 'ask.copyPrompt': 'Copy prompt',
480
+ 'ask.promptShown': 'the prompt',
481
+ 'ask.showPrompt': 'See the prompt',
482
+ 'ask.readOnly': 'This panel is read-only, so it cannot open a terminal. Copy the prompt and paste it into any AI.',
483
+ 'ask.opened': 'Opened {terminal} with {ref}. Carry on there.',
484
+ 'ask.failed': '{terminal} did not open.',
485
+ 'ask.paste': 'Paste it into your terminal and press Return. It starts the same task; it waits for one hour.',
486
+ 'ask.copiedCmd': 'The command is copied.',
487
+ 'ask.attach': 'Add image or video',
488
+ 'ask.attachHint': 'You can also paste a screenshot, or drop files here.',
489
+ 'ask.attachWarn': 'Pictures go to the AI with your words; check they show no keys or passwords.',
490
+ 'ask.attachRemove': 'Remove {name}',
491
+ 'ask.attachUploading': 'Uploading {pct}%',
492
+ 'ask.attachMax': 'At most 5 files per task. Remove one to add another.',
493
+ 'ask.attachTooBig': '{name} is too big: images up to 20 MB, videos up to 200 MB.',
494
+ 'ask.attachType': '{name} is not a supported file. Attach a PNG, JPEG, GIF or WebP image, or an MP4, MOV or WebM video.',
495
+ 'ask.attachFailed': '{name} did not upload. Remove it and try again.',
496
+ 'ask.attachFull': 'Too many files are waiting to be sent. Send this task or remove some files, then add {name} again.',
497
+ 'ask.attachWaiting': 'Waiting for files…',
498
+ 'ask.attachVideo': 'Video',
499
+ 'ask.automation': 'macOS did not let sideby control {terminal}. To allow it, open System Settings → Privacy & Security → Automation and turn it on for the app running the panel.',
500
+ 'ask.notInstalled': 'Pick a terminal you have in Settings → Preferred terminal.',
501
+ 'ask.yourself': 'Or ask your AI yourself',
502
+ 'ask.fixTitle': 'Hand the problems without a one-click fix to your own AI',
503
+ 'ask.quotaWhy': 'Ask AI why',
504
+ 'ask.setUp': 'Not sure what to fill in? Let AI set it up',
505
+ 'ask.otherTool': 'Other tool…',
506
+ 'ask.otherToolSub': 'Not in this list',
507
+ 'ask.plugin': 'Let AI write a plugin',
508
+ 'login.opened': 'Opened {terminal}: sign in to {ref} there.',
509
+ 'login.failed': 'Could not open a terminal. Copied: paste it into your terminal and press Return.',
510
+ 'login.automation': 'Copied. To let sideby open {terminal}, turn it on in System Settings → Privacy & Security → Automation.',
511
+ 'menu.signIn': 'Sign in',
512
+ 'menu.enterKey': 'Enter key',
513
+ 'key.title': 'Enter key for {ref}',
514
+ 'key.intro': "sideby writes the key into this account's proxy.env on this computer. It is never shown again or sent to AI.",
515
+ 'key.label': 'Key ({var})',
516
+ 'key.varLabel': 'Variable name',
517
+ 'key.otherVar': 'Use another variable',
518
+ 'key.varHint': "Only change this when the tool's docs name a different variable.",
519
+ 'key.noVar': 'This tool names no key variable; enter the one its docs name.',
520
+ 'key.save': 'Save key',
521
+ 'key.saving': 'Saving…',
522
+ 'key.saved': 'Saved {var} to {file}.',
523
+ 'key.badVar': 'Use capitals, digits and _ only, such as API_KEY.',
524
+ 'key.empty': 'Enter the key.',
525
+ 'key.tryLead': 'Check that it works?',
526
+ 'key.try': 'Try it',
527
+ 'key.tryCost': 'This sends one short message, so it spends a few tokens. It runs:',
528
+ 'key.tryRun': 'Send it',
529
+ 'key.trying': 'Waiting for the reply… (up to a minute)',
530
+ 'key.tryOk': 'It works: {ref} answered.',
531
+ 'key.tryFail': 'It did not work.',
532
+ 'key.tryTimeout': 'No reply within a minute.',
533
+ 'key.output': 'What the tool said (keys hidden):',
534
+ 'key.noOutput': 'The tool printed nothing.',
535
+ 'key.explain': 'Let AI explain',
536
+ 'key.explainText': '`sideby try {ref}` failed. This is what it printed:\n{output}',
537
+ 'key.cannotTry': 'This tool cannot be tried here; start it with {cmd} and send one short message.',
538
+ 'term.title': 'Preferred terminal',
539
+ 'term.intro': 'sideby opens this terminal when AI does something for you, and to sign in.',
540
+ 'term.pick': 'Terminal',
541
+ 'term.auto': 'Guess for me',
542
+ 'term.guess.config': 'You chose {name}.',
543
+ 'term.guess.env': 'Guess: {name}, the terminal this panel was started from.',
544
+ 'term.guess.default': 'Guess: {name}, the one every Mac has.',
545
+ 'term.none': 'No supported terminal was found on this computer. sideby will copy a command for you to paste.',
546
+ 'term.custom': 'Custom terminal command',
547
+ 'term.customHint': 'For any other terminal. sideby fills in {cmd} (the command) and {cwd} (the folder); no shell runs it. Example: myterm --cwd {cwd} -e {cmd}',
548
+ 'term.customSave': 'Save command',
549
+ 'term.customClear': 'Remove',
550
+ 'term.askAi': 'Not sure how? Let AI set it up',
551
+ 'term.saved': 'Saved.',
552
+ 'term.loading': 'Looking for terminals…',
418
553
  'att.quota': 'Almost full',
419
554
  'att.fix': 'Needs a fix',
420
555
  'att.check': 'Take a look',
@@ -727,6 +862,44 @@ const en = {
727
862
  'set.theme.system': 'System',
728
863
  'set.theme.light': 'Light',
729
864
  'set.theme.dark': 'Dark',
865
+ 'set.title': 'Settings',
866
+ 'set.g.look': 'Appearance',
867
+ 'set.g.start': 'Startup',
868
+ 'set.g.accounts': 'Accounts and quota',
869
+ 'set.g.ai': 'Let AI help',
870
+ 'set.more': 'More settings…',
871
+ 'set.saveFailed': 'Could not save the setting: {msg}',
872
+ 'as.label': 'Start sideby in the background at login',
873
+ 'as.hint': 'No window opens; the panel is up to date when you open it.',
874
+ 'as.checking': 'Checking…',
875
+ 'as.failed': 'Could not check: {msg}',
876
+ 'as.unsupported': 'Not supported on this system yet; Linux and Windows come later.',
877
+ 'as.foreign': 'A login item with the same name was not made by sideby, so sideby leaves it alone.',
878
+ 'as.stale': 'It points to a sideby that is no longer there.',
879
+ 'as.other': 'It starts another copy of sideby, not this one.',
880
+ 'as.fix': 'Point it at this sideby',
881
+ 'as.copyPath': 'Copy its path',
882
+ 'as.onTitle': 'Start sideby at login',
883
+ 'as.offTitle': 'Stop starting sideby at login',
884
+ 'as.planning': 'Working out what changes…',
885
+ 'as.writes': 'sideby writes this file:',
886
+ 'as.runs': 'At each login it runs:',
887
+ 'as.noWindow': 'No window opens. The panel waits in the background, so it is up to date when you open it.',
888
+ 'as.removes': 'sideby removes this file:',
889
+ 'as.offNote': 'A panel running now keeps running until you stop it or log out.',
890
+ 'as.alreadyOn': 'It already starts this sideby at login; nothing to change.',
891
+ 'as.alreadyOff': 'It is already off; nothing to change.',
892
+ 'as.turnOn': 'Turn on',
893
+ 'as.turnOff': 'Turn off',
894
+ 'as.doneOn': 'sideby now starts in the background at login.',
895
+ 'as.doneOff': 'sideby no longer starts at login.',
896
+ 'as.nextLogin': 'It takes effect at your next login.',
897
+ 'as.changedSince': 'Something changed since the preview; look at it again.',
898
+ 'as.block.npx-cache': 'sideby runs from the npx cache, which npm may clear, so it cannot start at login from there. Install it first:',
899
+ 'as.block.temp-dir': 'sideby runs from a temporary folder that the system empties. Install it first:',
900
+ 'as.block.unsafe-path': 'The path of sideby or Node has characters a login item cannot run safely. Install sideby in an ordinary folder:',
901
+ 'as.block.unsupported': 'Not supported on this system yet; Linux and Windows come later.',
902
+ 'as.block.foreign': "The file at this path was not made by sideby, so sideby leaves it alone. Look at it, and remove or rename it yourself if you don't need it:",
730
903
  'set.rcOn': 'Remote Control starts by itself',
731
904
  'rc.button': 'Remote Control (continue on phone or web)',
732
905
  'rc.state.on': 'On',
@@ -782,6 +955,9 @@ const zh = {
782
955
  'upd.local': '本地构建,来自仓库代码,构建于 {at}。',
783
956
  'upd.localDirty': '本地构建,含还没提交的改动,构建于 {at}。',
784
957
  'loc.toNpm': '切换到正式版',
958
+ 'loc.toNpmV': '切换到正式版 {v}',
959
+ 'upd.localSwitch': '你在用本地构建,sideby {v} 已发布。切换到正式版就会用上它,skill 也会一起同步。',
960
+ 'upd.localManual': '也可以在 sideby 仓库里运行:',
785
961
  'loc.toNpmHint': '回到 npm 上发布的版本,之后可以在这里再切回来。',
786
962
  'loc.toLocal': '切换到本地构建',
787
963
  'loc.toLocalHint': '本机留着一份本地构建:{b},构建于 {at}。切换不会重新构建;要新的就在仓库里运行 pnpm local。',
@@ -983,6 +1159,7 @@ const zh = {
983
1159
  'row.collapse': '收起 {name} 的详情',
984
1160
  'row.expand': '展开 {name} 的详情',
985
1161
  'row.runs': '运行方式',
1162
+ 'row.browser': '在 Chrome 网页上登录',
986
1163
  'group.toggle': '{title}({count}):{action}',
987
1164
  'group.attention.one': '{n} 个需要处理',
988
1165
  'group.attention.other': '{n} 个需要处理',
@@ -1000,7 +1177,7 @@ const zh = {
1000
1177
  'stat.needWho': '{names}',
1001
1178
  'stat.needWhoMore': '{names} 等 {n} 个',
1002
1179
  'acct.sameLogin': '与 {names} 同一登录',
1003
- 'acct.sameLoginHint': '与 {names} 用同一个身份登录。供应商只算一份额度,所以它们显示同一份额度,交接也不会在它们之间进行。',
1180
+ 'acct.sameLoginHint': '与 {names} 用同一个身份登录。供应商只算一份额度,所以它们显示同一份额度,接力也不会在它们之间进行。',
1004
1181
  'acct.notInstalled': '未安装工具',
1005
1182
  'acct.readError': '无法读取这个账号。',
1006
1183
  'acct.installHost': '本机没有安装 {host}。{link}',
@@ -1021,7 +1198,6 @@ const zh = {
1021
1198
  'quota.asOf': '截至 {ago}',
1022
1199
  'quota.sharedFrom': '与 {name} 同一登录;额度读自 {name},{ago}',
1023
1200
  'login.label': '同一登录:{names}',
1024
- 'login.dirs': '{n} 个目录 · 共用额度',
1025
1201
  'login.explain': '这几个目录登录的是同一个账号,额度一起算。',
1026
1202
  'login.copyRun': '复制启动命令',
1027
1203
  'login.showAs': '设为显示名',
@@ -1029,7 +1205,7 @@ const zh = {
1029
1205
  'login.shown': '显示名',
1030
1206
  'login.shownHint': '这一行用这个目录的名字显示',
1031
1207
  'login.section': '{name}',
1032
- 'login.hint': '{names} 用同一个身份登录。供应商只算一份额度,所以这里只显示一次,交接也不会在它们之间进行。',
1208
+ 'login.hint': '{names} 用同一个身份登录。供应商只算一份额度,所以这里只显示一次,接力也不会在它们之间进行。',
1033
1209
  'quota.noWindows': '没有额度窗口数据。',
1034
1210
  'quota.off': '额度未开启',
1035
1211
  'quota.turnOnFamily': '开启额度显示',
@@ -1096,9 +1272,8 @@ const zh = {
1096
1272
  'last.unknown': '没有最近的活动记录',
1097
1273
  'health.title': '健康检查',
1098
1274
  'health.intro': '检查每个账号的共享 skills、设置和凭据文件是否就位。',
1099
- 'health.lead': '检查{shared},报告{drift}。',
1100
- 'health.sharedTerm': '共享项',
1101
- 'health.driftTerm': '偏离',
1275
+ 'health.lead': '检查每个账号是否按规则{shared}。',
1276
+ 'health.sharedTerm': '和主账号共享设置',
1102
1277
  'health.more.one': '再显示 {n} 条',
1103
1278
  'health.more.other': '再显示 {n} 条',
1104
1279
  'health.run': '运行检查',
@@ -1159,11 +1334,144 @@ const zh = {
1159
1334
  'ai.ask.new': '再加一个 Claude 账号,短命令叫 cc009。',
1160
1335
  'ai.ask.pin': '把 claude:work 置顶。',
1161
1336
  'ai.ask.fix': '检查一下我的账号,把该共享的修好。',
1162
- 'ai.ask.handoff': '帮我开启自动交接。',
1337
+ 'ai.ask.handoff': '帮我开启自动接力。',
1163
1338
  'ai.ask.rc': '把所有 Claude 账号的远程控制关掉。',
1164
1339
  'ai.orderHint': '也可以让 AI 帮你排',
1165
1340
  'ai.emptyHint': '也可以让你的 AI 编程助手帮你装好、加账号。',
1166
1341
  'ai.how': '怎么做',
1342
+ 'ai.ask.api': '帮我加一个 DeepSeek API 账号。',
1343
+ 'ai.ask.tool': '帮 sideby 支持一个新工具。',
1344
+ 'ask.button': '让 AI 帮我',
1345
+ 'ask.title': '让 AI 帮我',
1346
+ 'ask.title.fix': '让 AI 修复',
1347
+ 'ask.title.quota': '问 AI 为什么',
1348
+ 'ask.title.account': '让 AI 帮我配账号',
1349
+ 'ask.title.host': '让 AI 支持一个新工具',
1350
+ 'ask.title.plugin': '让 AI 写插件',
1351
+ 'ask.title.terminal': '让 AI 帮我配终端',
1352
+ 'ask.title.handoff': '让 AI 帮我调',
1353
+ 'ask.intro': '你自己的 AI 会在终端里打开,用 sideby skill 来做。每一步改动它都先给你看,你在终端里回答它的问题。',
1354
+ 'ask.what': '你想让 AI 做什么?',
1355
+ 'ask.whatMore': '还有要补充的吗?(可不填)',
1356
+ 'ask.ph.free': '比如:帮我加一个 DeepSeek API 账号',
1357
+ 'ask.ph.account': '比如:我有一个 DeepSeek 的 API key',
1358
+ 'ask.ph.fix': '想补充什么?可以不填',
1359
+ 'ask.ph.quota': '想补充什么?可以不填',
1360
+ 'ask.ph.host': '你想用哪个工具?',
1361
+ 'ask.ph.plugin': '你想让插件做什么?',
1362
+ 'ask.ph.terminal': '你用的是什么终端?',
1363
+ 'ask.ph.handoff': '想补充什么?比如:先用 work',
1364
+ 'ask.ex.handoff.1': '按我的账号推荐阈值',
1365
+ 'ask.ex.handoff.2': '团队账号放到最后',
1366
+ 'ask.ex.handoff.3': '先讲讲接力是怎么工作的',
1367
+ 'ask.ex.account.1': '加一个 Claude 订阅账号',
1368
+ 'ask.ex.account.2': '我有一个 API 地址或文档链接',
1369
+ 'ask.ex.fix.1': '帮我修好这些问题',
1370
+ 'ask.ex.fix.2': '先解释一下再修',
1371
+ 'ask.ex.quota.1': '为什么看不到额度',
1372
+ 'ask.ex.quota.2': '帮我开启额度显示',
1373
+ 'ask.ex.host.1': '我想用 Gemini CLI',
1374
+ 'ask.ex.host.2': '我想用 OpenCode',
1375
+ 'ask.ex.plugin.1': '启动前自动切换代理',
1376
+ 'ask.ex.plugin.2': '新建账号时复制我的配置',
1377
+ 'ask.ex.terminal.1': '我用 Warp',
1378
+ 'ask.ex.terminal.2': '我用的终端没被认出来',
1379
+ 'ask.examples': '也可以从这些开始:',
1380
+ 'ask.task.fix': 'AI 会修好体检不能自动修复的问题({n} 个)。',
1381
+ 'ask.task.quota': 'AI 会找出 {ref} 为什么没有额度数据,并让它显示出来。',
1382
+ 'ask.task.account': 'AI 会帮你加一个账号:订阅账号,或者用你手上的 API 地址、文档链接。',
1383
+ 'ask.task.host': 'AI 会帮 sideby 支持一个列表里没有的工具,先做成这台电脑上的插件。',
1384
+ 'ask.task.plugin': 'AI 会帮你写一个 sideby 插件或 hook。',
1385
+ 'ask.task.handoff': 'AI 看过你的账号后,推荐什么时候接力、按什么顺序;保存前先给你看改动。',
1386
+ 'ask.task.terminal': 'AI 会写一条命令,让 sideby 在你的终端里打开 AI 任务;保存前先问你。',
1387
+ 'ask.keyWarn': '这看起来像密钥。密钥不要发给 AI:请用账号菜单里的「填写密钥」。',
1388
+ 'ask.keyRemoved': '像密钥的内容已在交给 AI 前去掉。密钥请用账号菜单里的「填写密钥」。',
1389
+ 'ask.account': '账号',
1390
+ 'ask.terminal': '终端',
1391
+ 'ask.chooseAccount': '选一个账号',
1392
+ 'ask.confirm': '将打开 {terminal},在里面启动 {ref}。',
1393
+ 'ask.open': '在 {terminal} 中打开',
1394
+ 'ask.opening': '正在打开…',
1395
+ 'ask.loading': '正在挑选账号…',
1396
+ 'ask.noAccount.no-accounts': '还没有能用来跑 AI 的账号。',
1397
+ 'ask.noAccount.none-signed-in': '没有已登录的账号,没法启动 AI。',
1398
+ 'ask.noAccount.all-full': '已登录的账号现在都没有额度了。',
1399
+ 'ask.noAccountHint': '复制提示词,贴给你喜欢的任何 AI。',
1400
+ 'ask.signInMain': '登录 {ref}',
1401
+ 'ask.copyPrompt': '复制提示词',
1402
+ 'ask.promptShown': '提示词',
1403
+ 'ask.showPrompt': '查看提示词',
1404
+ 'ask.readOnly': '这个面板是只读的,不能打开终端。复制提示词,贴给任何 AI 就行。',
1405
+ 'ask.opened': '已用 {ref} 打开 {terminal},请到那边继续。',
1406
+ 'ask.failed': '{terminal} 没有打开。',
1407
+ 'ask.paste': '粘贴到你的终端,按回车。它会开始同一个任务;任务保留一小时。',
1408
+ 'ask.copiedCmd': '命令已复制。',
1409
+ 'ask.attach': '添加图片或视频',
1410
+ 'ask.attachHint': '也可以直接粘贴截图,或把文件拖进来。',
1411
+ 'ask.attachWarn': '图片会和你的话一起发给 AI,先确认里面没有密钥或密码。',
1412
+ 'ask.attachRemove': '移除 {name}',
1413
+ 'ask.attachUploading': '正在上传 {pct}%',
1414
+ 'ask.attachMax': '一次最多 5 个文件。删掉一个才能再加。',
1415
+ 'ask.attachTooBig': '{name} 太大了:图片最大 20MB,视频最大 200MB。',
1416
+ 'ask.attachType': '{name} 不是支持的文件。请用 PNG、JPEG、GIF、WebP 图片,或 MP4、MOV、WebM 视频。',
1417
+ 'ask.attachFailed': '{name} 没传上去。删掉它再试一次。',
1418
+ 'ask.attachFull': '待发送的文件太多了。先发出这个任务或删掉几个文件,再添加 {name}。',
1419
+ 'ask.attachWaiting': '等文件传完…',
1420
+ 'ask.attachVideo': '视频',
1421
+ 'ask.automation': 'macOS 不允许 sideby 控制 {terminal}。要允许,打开「系统设置 → 隐私与安全性 → 自动化」,给运行面板的程序打开它。',
1422
+ 'ask.notInstalled': '在「设置 → 首选终端」里选一个这台电脑上有的终端。',
1423
+ 'ask.yourself': '也可以自己去问 AI',
1424
+ 'ask.fixTitle': '把不能一键修复的问题交给你自己的 AI',
1425
+ 'ask.quotaWhy': '问 AI 为什么',
1426
+ 'ask.setUp': '不知道怎么填?让 AI 帮我配',
1427
+ 'ask.otherTool': '其他工具……',
1428
+ 'ask.otherToolSub': '列表里没有',
1429
+ 'ask.plugin': '让 AI 写插件',
1430
+ 'login.opened': '已打开 {terminal},请在那里登录 {ref}。',
1431
+ 'login.failed': '终端没打开,命令已复制:粘贴到你的终端,按回车。',
1432
+ 'login.automation': '命令已复制。要让 sideby 打开 {terminal},请在「系统设置 → 隐私与安全性 → 自动化」里打开它。',
1433
+ 'menu.signIn': '登录',
1434
+ 'menu.enterKey': '填写密钥',
1435
+ 'key.title': '为 {ref} 填写密钥',
1436
+ 'key.intro': 'sideby 会把密钥写进这台电脑上这个账号的 proxy.env。之后不会再显示,也不会发给 AI。',
1437
+ 'key.label': '密钥({var})',
1438
+ 'key.varLabel': '变量名',
1439
+ 'key.otherVar': '用别的变量',
1440
+ 'key.varHint': '只有工具文档写的是另一个变量时才改。',
1441
+ 'key.noVar': '这个工具没有默认的密钥变量,请填它文档里写的那个。',
1442
+ 'key.save': '保存密钥',
1443
+ 'key.saving': '正在保存…',
1444
+ 'key.saved': '已把 {var} 写进 {file}。',
1445
+ 'key.badVar': '只能用大写字母、数字和 _,比如 API_KEY。',
1446
+ 'key.empty': '请填写密钥。',
1447
+ 'key.tryLead': '要试一下能不能用吗?',
1448
+ 'key.try': '试一下',
1449
+ 'key.tryCost': '这会发一条很短的消息,要花少量 token。会运行:',
1450
+ 'key.tryRun': '发送',
1451
+ 'key.trying': '正在等回复……(最多一分钟)',
1452
+ 'key.tryOk': '能用:{ref} 回复了。',
1453
+ 'key.tryFail': '没能用。',
1454
+ 'key.tryTimeout': '一分钟内没有回复。',
1455
+ 'key.output': '工具的输出(密钥已隐藏):',
1456
+ 'key.noOutput': '工具没有输出任何内容。',
1457
+ 'key.explain': '让 AI 解释',
1458
+ 'key.explainText': '`sideby try {ref}` 失败了,它的输出是:\n{output}',
1459
+ 'key.cannotTry': '这个工具不能在这里试;用 {cmd} 启动它,发一条很短的消息。',
1460
+ 'term.title': '首选终端',
1461
+ 'term.intro': 'AI 帮你做事、以及登录时,sideby 会打开这个终端。',
1462
+ 'term.pick': '终端',
1463
+ 'term.auto': '帮我猜',
1464
+ 'term.guess.config': '你选的是 {name}。',
1465
+ 'term.guess.env': '猜测:{name},也就是启动这个面板的终端。',
1466
+ 'term.guess.default': '猜测:{name},每台 Mac 都有。',
1467
+ 'term.none': '这台电脑上没找到支持的终端。sideby 会复制一条命令,让你自己粘贴。',
1468
+ 'term.custom': '自定义终端命令',
1469
+ 'term.customHint': '用于其他终端。sideby 填入 {cmd}(命令)和 {cwd}(文件夹),不经过 shell。例:myterm --cwd {cwd} -e {cmd}',
1470
+ 'term.customSave': '保存命令',
1471
+ 'term.customClear': '去掉',
1472
+ 'term.askAi': '不会写?让 AI 帮我配',
1473
+ 'term.saved': '已保存。',
1474
+ 'term.loading': '正在查找终端…',
1167
1475
  'att.quota': '快用完',
1168
1476
  'att.fix': '需要修复',
1169
1477
  'att.check': '看一下',
@@ -1261,22 +1569,22 @@ const zh = {
1261
1569
  'md.nothing': '没有要改的。',
1262
1570
  'md.changes': '将修改 sideby 的配置:',
1263
1571
  'md.saved': '已保存,{ref} 的新会话会用它。',
1264
- 'page.handoff': '自动交接',
1265
- 'hp.title': '自动交接',
1572
+ 'page.handoff': '自动接力',
1573
+ 'hp.title': '自动接力',
1266
1574
  'hp.advanced': '高级设置',
1267
1575
  'hp.loading': '检查中…',
1268
1576
  'hp.intro': '账号额度快用完时,你的工作会自动换到下一个账号接着做,不用你操心。',
1269
1577
  'hp.how1': '你照常在用 sideby 启动的会话里工作(短命令如 cc001,或 sideby run)。',
1270
1578
  'hp.how2': '这个账号用到 {p}% 时,sideby 让 AI 写一份任务小结,然后结束这个会话。',
1271
1579
  'hp.how3': '倒计时 {s} 秒后(按回车可取消),下一个账号在同一个终端里按小结接着做。',
1272
- 'hp.noStarters': '你的账号里还没有能发起交接的。先添加一个 Claude、Codex 或 Grok 账号。',
1580
+ 'hp.noStarters': '你的账号里还没有能发起接力的。先添加一个 Claude、Codex 或 Grok 账号。',
1273
1581
  'hp.sameFamily': '同一个工具的账号之间也切换(例如 cc001 到 cc002)',
1274
- 'hp.turnOn': '开启自动交接',
1582
+ 'hp.turnOn': '开启自动接力',
1275
1583
  'hp.turnOff': '关闭',
1276
1584
  'hp.willDo': '开启时 sideby 会:',
1277
- 'hp.step.config': '在 sideby 的设置里打开自动交接',
1278
- 'hp.step.quota': '打开 {host} 的额度显示(交接要靠它知道用了多少)',
1279
- 'hp.step.hook': '给 {host} 装上 sideby 的交接钩子',
1585
+ 'hp.step.config': '在 sideby 的设置里打开自动接力',
1586
+ 'hp.step.quota': '打开 {host} 的额度显示(接力要靠它知道用了多少)',
1587
+ 'hp.step.hook': '给 {host} 装上 sideby 的接力钩子',
1280
1588
  'hp.step.copy': '把钩子文件复制到你的其他 {host} 账号({accounts}),它们的其他文件不动',
1281
1589
  'hp.showChange': '查看改动',
1282
1590
  'hp.sameFamilyOffNote': '同一个工具的账号之间不会互相切换,之后可以在本页打开。',
@@ -1297,18 +1605,18 @@ const zh = {
1297
1605
  'hp.planChanged': '你查看之后设置有了变化,所以还没有改任何东西。下面是现在要做的改动,请再确认一次。',
1298
1606
  'hp.none': '现在没有能接手的账号',
1299
1607
  'hp.noneBack': '现在没有能接手的账号;{ref} 在 {at} 恢复',
1300
- 'hp.noAccounts': '没有能发起交接的订阅账号。',
1301
- 'hp.recent': '最近的交接',
1608
+ 'hp.noAccounts': '没有能发起接力的订阅账号。',
1609
+ 'hp.recent': '最近的接力',
1302
1610
  'hp.noneYet': '还没有。下次有账号额度快用完时,这里会出现记录。',
1303
- 'hp.why.threshold': '额度到了交接线',
1611
+ 'hp.why.threshold': '额度到了接力线',
1304
1612
  'hp.why.limit': '撞到了用量上限',
1305
- 'hp.why.manual': '按你的要求交接',
1613
+ 'hp.why.manual': '按你的要求接力',
1306
1614
  'hp.missing': '还差一步',
1307
1615
  'hp.complete': '补全设置',
1308
- 'hp.onlySideby': '只有用 sideby 启动的会话才会交接(短命令如 cc001,或 sideby run)。直接敲 claude 启动的不会。',
1616
+ 'hp.onlySideby': '只有用 sideby 启动的会话才会接力(短命令如 cc001,或 sideby run)。直接敲 claude 启动的不会。',
1309
1617
  'hp.sameConfirm': '确认打开',
1310
- 'hp.sameOn': '已开启同工具交接。',
1311
- 'hp.sameOff': '已关闭同工具交接。',
1618
+ 'hp.sameOn': '已开启同工具接力。',
1619
+ 'hp.sameOff': '已关闭同工具接力。',
1312
1620
  'page.accounts': '账号',
1313
1621
  'page.tuning': '上下文调优',
1314
1622
  'tune.title': '上下文调优',
@@ -1403,19 +1711,19 @@ const zh = {
1403
1711
  'nf.aliasNotAdded': '短命令没有添加。',
1404
1712
  'nf.shellFileUpdated': '已更新 {file}。',
1405
1713
  'nf.shellFileSame': '{file} 已是最新。',
1406
- 'ah.button': '自动交接',
1714
+ 'ah.button': '自动接力',
1407
1715
  'ah.on': '开',
1408
1716
  'ah.off': '关',
1409
- 'ah.title': '自动交接',
1410
- 'ah.intro': 'sideby 启动的会话额度快用完时,会写好交接说明,sideby 结束它,下一个账号在同一个终端里接着做。默认关闭。',
1411
- 'ah.auto': '额度快用完时自动交接',
1717
+ 'ah.title': '自动接力',
1718
+ 'ah.intro': 'sideby 启动的会话额度快用完时,会写好接力说明,sideby 结束它,下一个账号在同一个终端里接着做。默认关闭。',
1719
+ 'ah.auto': '额度快用完时自动接力',
1412
1720
  'ah.sameFamily': '也允许同一工具的账号之间接力',
1413
1721
  'ah.sameFamilyWarn': '同一家厂商的多个订阅之间接力来绕过限额,可能违反厂商条款,风险由你承担。',
1414
- 'ah.prepareAt': '开始写交接说明(%)',
1415
- 'ah.threshold': '交接阈值(%)',
1722
+ 'ah.prepareAt': '开始写接力说明(%)',
1723
+ 'ah.threshold': '接力阈值(%)',
1416
1724
  'ah.wait': '这么多分钟内重置就等待',
1417
- 'ah.countdown': '交接前倒计时(秒)',
1418
- 'ah.badLevels': '开始写说明的比例要低于交接阈值。',
1725
+ 'ah.countdown': '接力前倒计时(秒)',
1726
+ 'ah.badLevels': '开始写说明的比例要低于接力阈值。',
1419
1727
  'ah.order': '{host} 交给',
1420
1728
  'ah.byQuota': '剩余额度最多的',
1421
1729
  'ah.myOrder': '按我的顺序',
@@ -1440,8 +1748,8 @@ const zh = {
1440
1748
  'ah.hint': '{ref} 的额度已用 {p}%。会话可以在额度快用完时,自己把任务交给另一个账号。',
1441
1749
  'ah.setUp': '去设置',
1442
1750
  'ah.dismiss': '暂不',
1443
- 'toast.ahOn': '自动交接已开启,对用 sideby 启动的会话生效。',
1444
- 'toast.ahOff': '自动交接已关闭。',
1751
+ 'toast.ahOn': '自动接力已开启,对用 sideby 启动的会话生效。',
1752
+ 'toast.ahOff': '自动接力已关闭。',
1445
1753
  'qs.title': '开启 {host} 额度显示',
1446
1754
  'qs.preparing': '正在准备改动…',
1447
1755
  'qs.changes': '将修改 {file}:',
@@ -1476,6 +1784,44 @@ const zh = {
1476
1784
  'set.theme.system': '跟随系统',
1477
1785
  'set.theme.light': '浅色',
1478
1786
  'set.theme.dark': '深色',
1787
+ 'set.title': '设置',
1788
+ 'set.g.look': '外观',
1789
+ 'set.g.start': '启动',
1790
+ 'set.g.accounts': '账号与额度',
1791
+ 'set.g.ai': '让 AI 帮我',
1792
+ 'set.more': '更多设置…',
1793
+ 'set.saveFailed': '设置没有保存:{msg}',
1794
+ 'as.label': '登录后在后台启动 sideby',
1795
+ 'as.hint': '不打开窗口,打开面板时就是最新状态',
1796
+ 'as.checking': '正在检查…',
1797
+ 'as.failed': '没能检查:{msg}',
1798
+ 'as.unsupported': '这个系统暂不支持,Linux 和 Windows 稍后。',
1799
+ 'as.foreign': '同名的登录项不是 sideby 建的,sideby 不动它。',
1800
+ 'as.stale': '它指向的 sideby 已经不在了。',
1801
+ 'as.other': '它启动的是另一份 sideby,不是现在这份。',
1802
+ 'as.fix': '改成现在这份',
1803
+ 'as.copyPath': '复制文件路径',
1804
+ 'as.onTitle': '登录后启动 sideby',
1805
+ 'as.offTitle': '不再登录后启动 sideby',
1806
+ 'as.planning': '正在列出要改的内容…',
1807
+ 'as.writes': 'sideby 会写这个文件:',
1808
+ 'as.runs': '每次登录时运行:',
1809
+ 'as.noWindow': '不打开窗口。面板在后台准备好,打开时就是最新状态。',
1810
+ 'as.removes': 'sideby 会删除这个文件:',
1811
+ 'as.offNote': '现在开着的面板会继续运行,直到你关掉它或退出登录。',
1812
+ 'as.alreadyOn': '已经是登录后启动这份 sideby,不用改。',
1813
+ 'as.alreadyOff': '已经是关闭的,不用改。',
1814
+ 'as.turnOn': '开启',
1815
+ 'as.turnOff': '关闭',
1816
+ 'as.doneOn': '已开启:登录后 sideby 会在后台启动。',
1817
+ 'as.doneOff': '已关闭:登录后不再启动 sideby。',
1818
+ 'as.nextLogin': '下次登录时生效。',
1819
+ 'as.changedSince': '预览之后有变化,请再看一遍。',
1820
+ 'as.block.npx-cache': 'sideby 现在从 npx 缓存运行,npm 可能清掉它,没法从那里登录后启动。先安装:',
1821
+ 'as.block.temp-dir': 'sideby 现在从系统会清空的临时文件夹运行。先安装:',
1822
+ 'as.block.unsafe-path': 'sideby 或 Node 的路径里有登录项没法安全运行的字符。把 sideby 装到普通文件夹:',
1823
+ 'as.block.unsupported': '这个系统暂不支持,Linux 和 Windows 稍后。',
1824
+ 'as.block.foreign': '这个位置的文件不是 sideby 建的,sideby 不动它。先看一下,不需要的话自己删除或改名:',
1479
1825
  'set.rcOn': 'Remote Control 会自动打开',
1480
1826
  'rc.button': '远程控制(Remote Control)',
1481
1827
  'rc.state.on': '开',