sideby 0.2.2 → 0.4.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.
- package/README.md +27 -10
- package/dist/build.json +1 -1
- package/dist/src/cli/commands.d.ts +8 -1
- package/dist/src/cli/commands.js +330 -9
- package/dist/src/cli/format.d.ts +3 -1
- package/dist/src/cli/format.js +25 -0
- package/dist/src/cli/json-schemas.js +113 -0
- package/dist/src/cli/main.d.ts +5 -0
- package/dist/src/cli/main.js +40 -8
- package/dist/src/core/config.d.ts +41 -0
- package/dist/src/core/config.js +86 -11
- package/dist/src/core/file-memo.d.ts +23 -0
- package/dist/src/core/file-memo.js +37 -0
- package/dist/src/core/handoff-brief.d.ts +17 -0
- package/dist/src/core/handoff-brief.js +75 -0
- package/dist/src/core/handoff-chain.d.ts +74 -0
- package/dist/src/core/handoff-chain.js +74 -0
- package/dist/src/core/handoff-doctor.d.ts +13 -0
- package/dist/src/core/handoff-doctor.js +35 -0
- package/dist/src/core/handoff-run.d.ts +31 -0
- package/dist/src/core/handoff-run.js +346 -0
- package/dist/src/core/handoff-select.d.ts +42 -0
- package/dist/src/core/handoff-select.js +88 -0
- package/dist/src/core/handoff-status.d.ts +66 -0
- package/dist/src/core/handoff-status.js +198 -0
- package/dist/src/core/launch.d.ts +22 -1
- package/dist/src/core/launch.js +54 -4
- package/dist/src/core/memo-store.d.ts +20 -0
- package/dist/src/core/memo-store.js +92 -0
- package/dist/src/core/resume.d.ts +7 -2
- package/dist/src/core/resume.js +22 -9
- package/dist/src/core/tuning-apply.d.ts +51 -0
- package/dist/src/core/tuning-apply.js +237 -0
- package/dist/src/core/tuning.d.ts +98 -0
- package/dist/src/core/tuning.js +176 -0
- package/dist/src/families/claude/brief.d.ts +5 -0
- package/dist/src/families/claude/brief.js +63 -0
- package/dist/src/families/claude/handoff-hook.d.ts +2 -0
- package/dist/src/families/claude/handoff-hook.js +31 -0
- package/dist/src/families/claude/handoff.d.ts +5 -0
- package/dist/src/families/claude/handoff.js +115 -0
- package/dist/src/families/claude/index.js +8 -1
- package/dist/src/families/claude/tuning.d.ts +22 -0
- package/dist/src/families/claude/tuning.js +187 -0
- package/dist/src/families/claude/usage.d.ts +1 -0
- package/dist/src/families/claude/usage.js +2 -2
- package/dist/src/families/codex/brief.d.ts +5 -0
- package/dist/src/families/codex/brief.js +49 -0
- package/dist/src/families/codex/handoff-hook.d.ts +2 -0
- package/dist/src/families/codex/handoff-hook.js +16 -0
- package/dist/src/families/codex/handoff.d.ts +5 -0
- package/dist/src/families/codex/handoff.js +121 -0
- package/dist/src/families/codex/index.js +6 -0
- package/dist/src/families/codex/rate-limits.d.ts +16 -0
- package/dist/src/families/codex/rate-limits.js +92 -0
- package/dist/src/families/codex/rollout.d.ts +1 -2
- package/dist/src/families/codex/rollout.js +4 -48
- package/dist/src/families/codex/tuning.d.ts +16 -0
- package/dist/src/families/codex/tuning.js +145 -0
- package/dist/src/families/grok/brief.d.ts +5 -0
- package/dist/src/families/grok/brief.js +74 -0
- package/dist/src/families/grok/handoff-hook.d.ts +4 -0
- package/dist/src/families/grok/handoff-hook.js +26 -0
- package/dist/src/families/grok/handoff.d.ts +47 -0
- package/dist/src/families/grok/handoff.js +219 -0
- package/dist/src/families/grok/index.js +2 -0
- package/dist/src/families/pi/handoff.d.ts +2 -0
- package/dist/src/families/pi/handoff.js +13 -0
- package/dist/src/families/pi/index.js +2 -0
- package/dist/src/families/shared/brief.d.ts +24 -0
- package/dist/src/families/shared/brief.js +42 -0
- package/dist/src/families/shared/handoff-args.d.ts +18 -0
- package/dist/src/families/shared/handoff-args.js +57 -0
- package/dist/src/families/shared/sessions.d.ts +4 -0
- package/dist/src/families/shared/sessions.js +19 -0
- package/dist/src/families/shared/toml.d.ts +5 -0
- package/dist/src/families/shared/toml.js +30 -0
- package/dist/src/handoff/hook.d.ts +16 -0
- package/dist/src/handoff/hook.js +166 -0
- package/dist/src/handoff/messages.d.ts +7 -0
- package/dist/src/handoff/messages.js +27 -0
- package/dist/src/handoff/reader.d.ts +11 -0
- package/dist/src/handoff/reader.js +9 -0
- package/dist/src/panel/handler.d.ts +6 -0
- package/dist/src/panel/handler.js +110 -0
- package/dist/src/panel/i18n.d.ts +96 -0
- package/dist/src/panel/i18n.js +192 -0
- package/dist/src/panel/page-logic.d.ts +49 -0
- package/dist/src/panel/page-logic.js +67 -0
- package/dist/src/panel/page-script.js +454 -4
- package/dist/src/panel/page-styles.js +28 -2
- package/dist/src/panel/page.js +4 -1
- package/dist/src/quota/claude-statusline.js +4 -7
- package/dist/src/runtime.d.ts +40 -3
- package/dist/src/runtime.js +226 -43
- package/dist/src/types.d.ts +101 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.js +1 -0
- package/package.json +16 -4
- package/schemas/config.json +77 -0
- package/schemas/families.json +5 -1
- package/schemas/handoff-disable.json +106 -0
- package/schemas/handoff-enable.json +106 -0
- package/schemas/handoff-ready.json +23 -0
- package/schemas/handoff-setup.json +60 -0
- package/schemas/handoff-status.json +137 -0
- package/schemas/handoff-teardown.json +30 -0
- package/schemas/list.json +5 -1
- package/schemas/tune-change.json +108 -0
- package/schemas/tune.json +243 -0
- package/skills/sideby/SKILL.md +7 -4
- package/skills/sideby/references/badge.md +31 -0
- package/skills/sideby/references/diagnose.md +4 -0
- package/skills/sideby/references/handoff.md +24 -2
- package/skills/sideby/references/setup.md +3 -2
- package/README.zh-CN.md +0 -112
package/dist/src/panel/i18n.js
CHANGED
|
@@ -89,6 +89,12 @@ const en = {
|
|
|
89
89
|
'need.quota-high.other': '{n} near limit',
|
|
90
90
|
'need.health-warn.one': '{n} with warnings',
|
|
91
91
|
'need.health-warn.other': '{n} with warnings',
|
|
92
|
+
'why.error': 'unreadable',
|
|
93
|
+
'why.health-fail': 'Health check found issues',
|
|
94
|
+
'why.signed-out': 'signed out',
|
|
95
|
+
'why.not-installed': 'tool not installed',
|
|
96
|
+
'why.quota-high': '{label} at {pct}% (warns from {warn}%)',
|
|
97
|
+
'why.health-warn': 'Health check has warnings',
|
|
92
98
|
'tb.search': 'Search accounts',
|
|
93
99
|
'tb.searchPh': 'Search name, alias, email, model…',
|
|
94
100
|
'tb.family': 'Filter by tool',
|
|
@@ -119,6 +125,7 @@ const en = {
|
|
|
119
125
|
'group.toggle': '{title} ({count}): {action}',
|
|
120
126
|
'group.attention.one': '{n} needs attention',
|
|
121
127
|
'group.attention.other': '{n} need attention',
|
|
128
|
+
'group.attentionShow': 'Show {name}',
|
|
122
129
|
'acct.alias': 'Alias',
|
|
123
130
|
'acct.aliasArgs': 'Alias, starts this account with {args}',
|
|
124
131
|
'acct.api': 'API',
|
|
@@ -132,6 +139,7 @@ const en = {
|
|
|
132
139
|
'acct.notInstalled': 'Tool missing',
|
|
133
140
|
'acct.readError': 'Could not read this account.',
|
|
134
141
|
'acct.installHost': '{host} is not installed on this machine. {link}',
|
|
142
|
+
'acct.nearLimit': '{label} quota is {pct}% used; warnings start at {warn}%.',
|
|
135
143
|
'acct.installIt': 'Install it',
|
|
136
144
|
'quota.pctUsed': '{n}% used',
|
|
137
145
|
'quota.pctLeft': '{n}% left',
|
|
@@ -226,6 +234,55 @@ const en = {
|
|
|
226
234
|
'menu.copyEmail': 'Copy email',
|
|
227
235
|
'menu.check': 'Check this account',
|
|
228
236
|
'menu.like': 'New account like this',
|
|
237
|
+
'menu.tune': 'Context tuning',
|
|
238
|
+
'page.accounts': 'Accounts',
|
|
239
|
+
'page.tuning': 'Context tuning',
|
|
240
|
+
'tune.title': 'Context tuning',
|
|
241
|
+
'tune.intro': 'Looks at how you used this over the last {days} days and estimates what auto-compact size would use the fewest tokens. It is only an estimate, and nothing changes until you press Use.',
|
|
242
|
+
'tune.loading': 'Working it out from your recent sessions…',
|
|
243
|
+
'tune.none': 'No sessions to look at yet for this account.',
|
|
244
|
+
'tune.noSource': 'There is nothing to estimate from for this tool.',
|
|
245
|
+
'tune.unreadable': 'The session records could not be read.',
|
|
246
|
+
'tune.calls': '{n} calls',
|
|
247
|
+
'tune.now': 'Now',
|
|
248
|
+
'tune.hostDefault': 'Default',
|
|
249
|
+
'tune.best': 'Suggested',
|
|
250
|
+
'tune.saved': 'Expected to use about {n}% fewer tokens (an estimate).',
|
|
251
|
+
'tune.compactions.one': 'It compacted once, when the conversation reached about {size}.',
|
|
252
|
+
'tune.compactions.other': 'It compacted {n} times, usually when the conversation reached about {size}.',
|
|
253
|
+
'tune.noCompactions': 'It did not compact in this period.',
|
|
254
|
+
'tune.groupShared': 'One setting for these accounts, because they share a settings file: {list}',
|
|
255
|
+
'tune.basis': 'Based on {model} on {ref}, the one used most.',
|
|
256
|
+
'tune.groupNone': 'Not used enough to suggest a size yet. You can still pick one below.',
|
|
257
|
+
'tune.details': 'Details for each account',
|
|
258
|
+
'tune.detailsObserved': 'Only observed (there is no setting to change)',
|
|
259
|
+
'tune.use': 'Use {size}',
|
|
260
|
+
'tune.setting': 'Auto-compact size',
|
|
261
|
+
'tune.hostDefaultLong': 'Default (Claude Code decides)',
|
|
262
|
+
'tune.suggestedTag': 'suggested',
|
|
263
|
+
'tune.useThis': 'Use this',
|
|
264
|
+
'tune.working': 'One moment…',
|
|
265
|
+
'tune.confirmTitle': 'This will change:',
|
|
266
|
+
'tune.change': 'Auto-compact size',
|
|
267
|
+
'tune.file': 'File',
|
|
268
|
+
'tune.willCreate': '(will be created)',
|
|
269
|
+
'tune.shared': 'This file is shared, so this changes all of: {list}',
|
|
270
|
+
'tune.newSessions': 'Only new sessions use it; sessions already running are not affected. You can undo it any time.',
|
|
271
|
+
'tune.confirm': 'Yes, use it',
|
|
272
|
+
'tune.done': 'Done: set to {size}. New sessions use it.',
|
|
273
|
+
'tune.already': 'It is already set to {size}; nothing to change.',
|
|
274
|
+
'tune.applied': 'sideby set this for you (it was {prev} before).',
|
|
275
|
+
'tune.undo': 'Undo',
|
|
276
|
+
'tune.undone': 'Undone. New sessions go back to how it was.',
|
|
277
|
+
'tune.reason.already-best': 'The current setting is already about the cheapest we can estimate for how you work.',
|
|
278
|
+
'tune.reason.insufficient-calls': 'Not enough use in this period to estimate (needs {min} calls).',
|
|
279
|
+
'tune.reason.no-compactions': 'It has not compacted in this period, so there is nothing to estimate from.',
|
|
280
|
+
'tune.reason.no-optimum': 'No clear best value: the cheapest point is outside the range we tried.',
|
|
281
|
+
'tune.reason.unknown-model': 'This is not a Claude model, so sideby cannot estimate it.',
|
|
282
|
+
'tune.reason.observe-only': 'For Codex sideby only shows what happened; it cannot suggest a value yet.',
|
|
283
|
+
'tpage.title': 'Context tuning',
|
|
284
|
+
'tpage.none': 'No account has been used enough to estimate yet.',
|
|
285
|
+
'tpage.idle': 'No use in this period: {list}',
|
|
229
286
|
'nf.title': 'New account',
|
|
230
287
|
'nf.intro': 'It runs next to your existing accounts and shares their skills and settings.',
|
|
231
288
|
'nf.tool': 'Tool',
|
|
@@ -266,6 +323,45 @@ const en = {
|
|
|
266
323
|
'nf.aliasNotAdded': 'Short command not added.',
|
|
267
324
|
'nf.shellFileUpdated': 'Updated {file}.',
|
|
268
325
|
'nf.shellFileSame': '{file} is up to date.',
|
|
326
|
+
'ah.button': 'Auto Handoff',
|
|
327
|
+
'ah.on': 'On',
|
|
328
|
+
'ah.off': 'Off',
|
|
329
|
+
'ah.title': 'Auto Handoff',
|
|
330
|
+
'ah.intro': 'When a session that sideby started runs low on quota, it writes a handoff brief, sideby ends it, and the next account carries on in the same terminal. Off by default.',
|
|
331
|
+
'ah.auto': 'Hand over when quota runs low',
|
|
332
|
+
'ah.sameFamily': 'Also hand over between accounts of the same tool',
|
|
333
|
+
'ah.sameFamilyWarn': 'Moving work between subscriptions of one vendor to get past a limit may break its terms; the risk is yours.',
|
|
334
|
+
'ah.prepareAt': 'Start the brief at (%)',
|
|
335
|
+
'ah.threshold': 'Hand over at (%)',
|
|
336
|
+
'ah.wait': 'Wait if it resets within (min)',
|
|
337
|
+
'ah.countdown': 'Countdown before switching (s)',
|
|
338
|
+
'ah.badLevels': 'Start the brief below the hand-over level.',
|
|
339
|
+
'ah.order': '{host} hands over to',
|
|
340
|
+
'ah.byQuota': 'Most quota left',
|
|
341
|
+
'ah.myOrder': 'My order',
|
|
342
|
+
'ah.byQuotaHint': 'Its own accounts with the most quota left (when same-tool hand-over is on), then API accounts.',
|
|
343
|
+
'ah.add': 'Add account',
|
|
344
|
+
'ah.up': 'Move up',
|
|
345
|
+
'ah.down': 'Move down',
|
|
346
|
+
'ah.remove': 'Remove',
|
|
347
|
+
'ah.emptyOrder': 'Add at least one account, or switch back to most quota left.',
|
|
348
|
+
'ah.readiness': 'On this machine',
|
|
349
|
+
'ah.checking': 'Checking…',
|
|
350
|
+
'ah.ready': 'Ready',
|
|
351
|
+
'ah.notYet': 'Not ready',
|
|
352
|
+
'ah.takesOver': 'Takes over only',
|
|
353
|
+
'ah.steps': 'Still to do, in a terminal:',
|
|
354
|
+
'ah.review': 'Review change',
|
|
355
|
+
'ah.apply': 'Apply',
|
|
356
|
+
'ah.applying': 'Applying…',
|
|
357
|
+
'ah.nothing': 'Nothing to change.',
|
|
358
|
+
'ah.saved': 'Saved to {file}.',
|
|
359
|
+
'ah.changes': 'This changes {file}:',
|
|
360
|
+
'ah.hint': '{ref} is at {p}% of its quota. Sessions can hand their task to another account by themselves when quota runs low.',
|
|
361
|
+
'ah.setUp': 'Set up',
|
|
362
|
+
'ah.dismiss': 'Not now',
|
|
363
|
+
'toast.ahOn': 'Auto Handoff is on for sessions you start with sideby.',
|
|
364
|
+
'toast.ahOff': 'Auto Handoff is off.',
|
|
269
365
|
'qs.title': 'Turn on {host} quota',
|
|
270
366
|
'qs.preparing': 'Preparing the change…',
|
|
271
367
|
'qs.changes': 'This changes {file}:',
|
|
@@ -372,6 +468,12 @@ const zh = {
|
|
|
372
468
|
'need.quota-high.other': '{n} 个接近上限',
|
|
373
469
|
'need.health-warn.one': '{n} 个有警告',
|
|
374
470
|
'need.health-warn.other': '{n} 个有警告',
|
|
471
|
+
'why.error': '读取失败',
|
|
472
|
+
'why.health-fail': '体检发现问题',
|
|
473
|
+
'why.signed-out': '未登录',
|
|
474
|
+
'why.not-installed': '缺少工具',
|
|
475
|
+
'why.quota-high': '{label} 已用 {pct}%({warn}% 起提醒)',
|
|
476
|
+
'why.health-warn': '体检有警告',
|
|
375
477
|
'tb.search': '搜索账号',
|
|
376
478
|
'tb.searchPh': '搜索名称、别名、邮箱、模型…',
|
|
377
479
|
'tb.family': '按工具筛选',
|
|
@@ -402,6 +504,7 @@ const zh = {
|
|
|
402
504
|
'group.toggle': '{title}({count}):{action}',
|
|
403
505
|
'group.attention.one': '{n} 个需要处理',
|
|
404
506
|
'group.attention.other': '{n} 个需要处理',
|
|
507
|
+
'group.attentionShow': '定位到 {name}',
|
|
405
508
|
'acct.alias': '别名',
|
|
406
509
|
'acct.aliasArgs': '别名,启动这个账号并附加 {args}',
|
|
407
510
|
'acct.api': 'API',
|
|
@@ -415,6 +518,7 @@ const zh = {
|
|
|
415
518
|
'acct.notInstalled': '未安装工具',
|
|
416
519
|
'acct.readError': '无法读取这个账号。',
|
|
417
520
|
'acct.installHost': '本机没有安装 {host}。{link}',
|
|
521
|
+
'acct.nearLimit': '{label} 额度已用 {pct}%,达到 {warn}% 就会提醒。',
|
|
418
522
|
'acct.installIt': '去安装',
|
|
419
523
|
'quota.pctUsed': '已用 {n}%',
|
|
420
524
|
'quota.pctLeft': '剩余 {n}%',
|
|
@@ -509,6 +613,55 @@ const zh = {
|
|
|
509
613
|
'menu.copyEmail': '复制邮箱',
|
|
510
614
|
'menu.check': '检查这个账号',
|
|
511
615
|
'menu.like': '照此新建账号',
|
|
616
|
+
'menu.tune': '上下文调优',
|
|
617
|
+
'page.accounts': '账号',
|
|
618
|
+
'page.tuning': '上下文调优',
|
|
619
|
+
'tune.title': '上下文调优',
|
|
620
|
+
'tune.intro': '看看你最近 {days} 天的用法,估算「自动压缩」设成多少最省 token。这只是估算;你点「使用」之前,sideby 不会改任何设置。',
|
|
621
|
+
'tune.loading': '正在根据你最近的会话计算…',
|
|
622
|
+
'tune.none': '这个账号还没有可以参考的会话。',
|
|
623
|
+
'tune.noSource': '这个工具没有可以参考的记录。',
|
|
624
|
+
'tune.unreadable': '会话记录读不出来。',
|
|
625
|
+
'tune.calls': '{n} 次调用',
|
|
626
|
+
'tune.now': '现在',
|
|
627
|
+
'tune.hostDefault': '默认',
|
|
628
|
+
'tune.best': '建议',
|
|
629
|
+
'tune.saved': '预计能少用约 {n}% 的 token(估算)。',
|
|
630
|
+
'tune.compactions.one': '最近自动压缩了 1 次,在对话长到约 {size} 时触发。',
|
|
631
|
+
'tune.compactions.other': '最近自动压缩了 {n} 次,通常在对话长到约 {size} 时触发。',
|
|
632
|
+
'tune.noCompactions': '这段时间没有压缩过。',
|
|
633
|
+
'tune.groupShared': '这些账号共用一个设置文件,所以用同一个设置:{list}',
|
|
634
|
+
'tune.basis': '按用得最多的 {model}({ref})来定。',
|
|
635
|
+
'tune.groupNone': '用得还不够多,暂时给不出建议值。你仍然可以在下面自己选一个。',
|
|
636
|
+
'tune.details': '各账号的详情',
|
|
637
|
+
'tune.detailsObserved': '只做观测(没有可以改的设置)',
|
|
638
|
+
'tune.use': '使用 {size}',
|
|
639
|
+
'tune.setting': '自动压缩大小',
|
|
640
|
+
'tune.hostDefaultLong': '默认(由 Claude Code 自己决定)',
|
|
641
|
+
'tune.suggestedTag': '建议',
|
|
642
|
+
'tune.useThis': '使用这个',
|
|
643
|
+
'tune.working': '稍等…',
|
|
644
|
+
'tune.confirmTitle': '将会修改:',
|
|
645
|
+
'tune.change': '自动压缩大小',
|
|
646
|
+
'tune.file': '文件',
|
|
647
|
+
'tune.willCreate': '(会新建)',
|
|
648
|
+
'tune.shared': '这个文件是几个账号共用的,所以这会同时改变:{list}',
|
|
649
|
+
'tune.newSessions': '只有新开的会话会用上,已经在运行的不受影响。随时可以撤销。',
|
|
650
|
+
'tune.confirm': '确认使用',
|
|
651
|
+
'tune.done': '已设置为 {size},新开的会话生效。',
|
|
652
|
+
'tune.already': '已经是 {size},不用改。',
|
|
653
|
+
'tune.applied': '这是 sideby 帮你设的(原来是{prev})。',
|
|
654
|
+
'tune.undo': '撤销',
|
|
655
|
+
'tune.undone': '已撤销,新开的会话恢复成原来的样子。',
|
|
656
|
+
'tune.reason.already-best': '按你的用法,现在的设置已经差不多是我们能估算出的最省了。',
|
|
657
|
+
'tune.reason.insufficient-calls': '这段时间用得太少,估不准(至少要 {min} 次)。',
|
|
658
|
+
'tune.reason.no-compactions': '这段时间还没压缩过,没有可以参考的数据。',
|
|
659
|
+
'tune.reason.no-optimum': '没有明确的最佳值:最省的点在我们试的范围之外。',
|
|
660
|
+
'tune.reason.unknown-model': '这不是 Claude 的模型,sideby 没法估算。',
|
|
661
|
+
'tune.reason.observe-only': 'Codex 目前只能看到发生了什么,还不能给建议值。',
|
|
662
|
+
'tpage.title': '上下文调优',
|
|
663
|
+
'tpage.none': '还没有账号用得够多,没法估算。',
|
|
664
|
+
'tpage.idle': '这段时间没有使用:{list}',
|
|
512
665
|
'nf.title': '新建账号',
|
|
513
666
|
'nf.intro': '新账号和现有账号并排运行,共享它们的 skills 和设置。',
|
|
514
667
|
'nf.tool': '工具',
|
|
@@ -549,6 +702,45 @@ const zh = {
|
|
|
549
702
|
'nf.aliasNotAdded': '短命令没有添加。',
|
|
550
703
|
'nf.shellFileUpdated': '已更新 {file}。',
|
|
551
704
|
'nf.shellFileSame': '{file} 已是最新。',
|
|
705
|
+
'ah.button': '自动交接',
|
|
706
|
+
'ah.on': '开',
|
|
707
|
+
'ah.off': '关',
|
|
708
|
+
'ah.title': '自动交接',
|
|
709
|
+
'ah.intro': 'sideby 启动的会话额度快用完时,会写好交接说明,sideby 结束它,下一个账号在同一个终端里接着做。默认关闭。',
|
|
710
|
+
'ah.auto': '额度快用完时自动交接',
|
|
711
|
+
'ah.sameFamily': '也允许同一工具的账号之间接力',
|
|
712
|
+
'ah.sameFamilyWarn': '同一家厂商的多个订阅之间接力来绕过限额,可能违反厂商条款,风险由你承担。',
|
|
713
|
+
'ah.prepareAt': '开始写交接说明(%)',
|
|
714
|
+
'ah.threshold': '交接阈值(%)',
|
|
715
|
+
'ah.wait': '这么多分钟内重置就等待',
|
|
716
|
+
'ah.countdown': '交接前倒计时(秒)',
|
|
717
|
+
'ah.badLevels': '开始写说明的比例要低于交接阈值。',
|
|
718
|
+
'ah.order': '{host} 交给',
|
|
719
|
+
'ah.byQuota': '剩余额度最多的',
|
|
720
|
+
'ah.myOrder': '按我的顺序',
|
|
721
|
+
'ah.byQuotaHint': '先选同一工具里剩余额度最多的账号(需打开同工具接力),再选 API 账号。',
|
|
722
|
+
'ah.add': '添加账号',
|
|
723
|
+
'ah.up': '上移',
|
|
724
|
+
'ah.down': '下移',
|
|
725
|
+
'ah.remove': '移除',
|
|
726
|
+
'ah.emptyOrder': '至少添加一个账号,或改回“剩余额度最多的”。',
|
|
727
|
+
'ah.readiness': '本机状态',
|
|
728
|
+
'ah.checking': '正在检查…',
|
|
729
|
+
'ah.ready': '已就绪',
|
|
730
|
+
'ah.notYet': '未就绪',
|
|
731
|
+
'ah.takesOver': '只能接手',
|
|
732
|
+
'ah.steps': '还要在终端里做:',
|
|
733
|
+
'ah.review': '查看改动',
|
|
734
|
+
'ah.apply': '应用',
|
|
735
|
+
'ah.applying': '正在应用…',
|
|
736
|
+
'ah.nothing': '没有要改的。',
|
|
737
|
+
'ah.saved': '已保存到 {file}。',
|
|
738
|
+
'ah.changes': '将修改 {file}:',
|
|
739
|
+
'ah.hint': '{ref} 的额度已用 {p}%。会话可以在额度快用完时,自己把任务交给另一个账号。',
|
|
740
|
+
'ah.setUp': '去设置',
|
|
741
|
+
'ah.dismiss': '暂不',
|
|
742
|
+
'toast.ahOn': '自动交接已开启,对用 sideby 启动的会话生效。',
|
|
743
|
+
'toast.ahOff': '自动交接已关闭。',
|
|
552
744
|
'qs.title': '开启 {host} 额度显示',
|
|
553
745
|
'qs.preparing': '正在准备改动…',
|
|
554
746
|
'qs.changes': '将修改 {file}:',
|
|
@@ -71,6 +71,18 @@ export declare function attentionReasons(a: LogicAccount, health: {
|
|
|
71
71
|
fail: number;
|
|
72
72
|
warn: number;
|
|
73
73
|
} | null, now: number, warn: number): string[];
|
|
74
|
+
/**
|
|
75
|
+
* The most serious reason an Account needs a look, as a message key and its values for the Panel to show where the
|
|
76
|
+
* attention count is: `why.<reason>`; for `quota-high` the fullest live window at or over `warn`, with its label and
|
|
77
|
+
* rounded percentage. Null when all is well.
|
|
78
|
+
*/
|
|
79
|
+
export declare function attentionWhy(a: LogicAccount, health: {
|
|
80
|
+
fail: number;
|
|
81
|
+
warn: number;
|
|
82
|
+
} | null, now: number, warn: number): {
|
|
83
|
+
key: string;
|
|
84
|
+
vars: Record<string, string | number>;
|
|
85
|
+
} | null;
|
|
74
86
|
/** Sorted copy: `pressure` (fullest Quota first), `name`, or `recent` (last activity first). The Main Account leads ties. */
|
|
75
87
|
export declare function sortAccounts<T extends LogicAccount>(list: T[], mode: string, now: number): T[];
|
|
76
88
|
/**
|
|
@@ -152,3 +164,40 @@ export declare function updatedAge(ms: number): {
|
|
|
152
164
|
* language (`zh*` gives Chinese, anything else English).
|
|
153
165
|
*/
|
|
154
166
|
export declare function panelLang(host: string, saved: string, browser: string): string;
|
|
167
|
+
/**
|
|
168
|
+
* The Account that makes the Panel's Auto Handoff hint worth showing (spec §3.17): Auto Handoff is off and a
|
|
169
|
+
* subscription Account of a Family that can start a Handoff is at or above the threshold. The fullest wins.
|
|
170
|
+
*/
|
|
171
|
+
export declare function handoffHintAccount(accounts: readonly LogicAccount[], settings: {
|
|
172
|
+
auto: boolean;
|
|
173
|
+
threshold: number;
|
|
174
|
+
}, starters: readonly string[], now: number): {
|
|
175
|
+
ref: string;
|
|
176
|
+
pressure: number;
|
|
177
|
+
} | null;
|
|
178
|
+
export interface HandoffSettingsView {
|
|
179
|
+
auto: boolean;
|
|
180
|
+
sameFamily: boolean;
|
|
181
|
+
prepareAt: number;
|
|
182
|
+
threshold: number;
|
|
183
|
+
waitIfResetWithinMinutes: number;
|
|
184
|
+
countdownSeconds: number;
|
|
185
|
+
families: Record<string, {
|
|
186
|
+
policy: string;
|
|
187
|
+
order: string[];
|
|
188
|
+
}>;
|
|
189
|
+
}
|
|
190
|
+
export interface HandoffForm {
|
|
191
|
+
auto: boolean;
|
|
192
|
+
sameFamily: boolean;
|
|
193
|
+
prepareAt: number;
|
|
194
|
+
threshold: number;
|
|
195
|
+
wait: number;
|
|
196
|
+
countdown: number;
|
|
197
|
+
orders: Record<string, {
|
|
198
|
+
policy: string;
|
|
199
|
+
order: string[];
|
|
200
|
+
}>;
|
|
201
|
+
}
|
|
202
|
+
/** What the Panel's Auto Handoff form changed, as the `change` /api/handoff/configure takes; {} when nothing. */
|
|
203
|
+
export declare function handoffChangeOf(s: HandoffSettingsView, f: HandoffForm): Record<string, unknown>;
|
|
@@ -82,6 +82,28 @@ export function attentionReasons(a, health, now, warn) {
|
|
|
82
82
|
out.push('health-warn');
|
|
83
83
|
return out;
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* The most serious reason an Account needs a look, as a message key and its values for the Panel to show where the
|
|
87
|
+
* attention count is: `why.<reason>`; for `quota-high` the fullest live window at or over `warn`, with its label and
|
|
88
|
+
* rounded percentage. Null when all is well.
|
|
89
|
+
*/
|
|
90
|
+
export function attentionWhy(a, health, now, warn) {
|
|
91
|
+
const reason = attentionReasons(a, health, now, warn)[0];
|
|
92
|
+
if (!reason)
|
|
93
|
+
return null;
|
|
94
|
+
if (reason !== 'quota-high')
|
|
95
|
+
return { key: `why.${reason}`, vars: {} };
|
|
96
|
+
let top = null;
|
|
97
|
+
for (const w of a.quota?.windows ?? []) {
|
|
98
|
+
const reset = Date.parse(w.resetsAt);
|
|
99
|
+
if (Number.isFinite(reset) && reset <= now)
|
|
100
|
+
continue;
|
|
101
|
+
const pct = Number(w.usedPercent) || 0;
|
|
102
|
+
if (pct >= warn && (!top || pct > top.pct))
|
|
103
|
+
top = { label: w.label, pct };
|
|
104
|
+
}
|
|
105
|
+
return { key: 'why.quota-high', vars: { label: top?.label ?? '', pct: Math.round(top?.pct ?? 0), warn } };
|
|
106
|
+
}
|
|
85
107
|
/** Sorted copy: `pressure` (fullest Quota first), `name`, or `recent` (last activity first). The Main Account leads ties. */
|
|
86
108
|
export function sortAccounts(list, mode, now) {
|
|
87
109
|
const byName = (x, y) => Number(Boolean(y.isMain)) - Number(Boolean(x.isMain)) ||
|
|
@@ -324,3 +346,48 @@ export function panelLang(host, saved, browser) {
|
|
|
324
346
|
return saved;
|
|
325
347
|
return /^zh/i.test(browser || '') ? 'zh' : 'en';
|
|
326
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* The Account that makes the Panel's Auto Handoff hint worth showing (spec §3.17): Auto Handoff is off and a
|
|
351
|
+
* subscription Account of a Family that can start a Handoff is at or above the threshold. The fullest wins.
|
|
352
|
+
*/
|
|
353
|
+
export function handoffHintAccount(accounts, settings, starters, now) {
|
|
354
|
+
if (settings.auto)
|
|
355
|
+
return null;
|
|
356
|
+
let best = null;
|
|
357
|
+
for (const a of accounts) {
|
|
358
|
+
if (a.kind === 'api' || !starters.includes(a.family))
|
|
359
|
+
continue;
|
|
360
|
+
const p = quotaPressure(a, now);
|
|
361
|
+
if (p >= settings.threshold && (!best || p > best.pressure))
|
|
362
|
+
best = { ref: a.ref, pressure: Math.round(p) };
|
|
363
|
+
}
|
|
364
|
+
return best;
|
|
365
|
+
}
|
|
366
|
+
/** What the Panel's Auto Handoff form changed, as the `change` /api/handoff/configure takes; {} when nothing. */
|
|
367
|
+
export function handoffChangeOf(s, f) {
|
|
368
|
+
const c = {};
|
|
369
|
+
if (f.auto !== s.auto)
|
|
370
|
+
c.auto = f.auto;
|
|
371
|
+
if (f.sameFamily !== s.sameFamily)
|
|
372
|
+
c.sameFamily = f.sameFamily;
|
|
373
|
+
if (f.prepareAt !== s.prepareAt)
|
|
374
|
+
c.prepareAt = f.prepareAt;
|
|
375
|
+
if (f.threshold !== s.threshold)
|
|
376
|
+
c.threshold = f.threshold;
|
|
377
|
+
if (f.wait !== s.waitIfResetWithinMinutes)
|
|
378
|
+
c.waitIfResetWithinMinutes = f.wait;
|
|
379
|
+
if (f.countdown !== s.countdownSeconds)
|
|
380
|
+
c.countdownSeconds = f.countdown;
|
|
381
|
+
const orders = [];
|
|
382
|
+
for (const family of Object.keys(f.orders)) {
|
|
383
|
+
const o = f.orders[family];
|
|
384
|
+
const cur = s.families[family];
|
|
385
|
+
const want = o.policy === 'order' ? o.order : [];
|
|
386
|
+
const have = cur && cur.policy === 'order' ? cur.order : [];
|
|
387
|
+
if (want.join('\n') !== have.join('\n'))
|
|
388
|
+
orders.push({ family, order: want.slice() });
|
|
389
|
+
}
|
|
390
|
+
if (orders.length)
|
|
391
|
+
c.orders = orders;
|
|
392
|
+
return c;
|
|
393
|
+
}
|