@link-assistant/hive-mind 2.1.3 → 2.1.5
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/CHANGELOG.md +12 -0
- package/README.hi.md +23 -1
- package/README.md +22 -1
- package/README.ru.md +23 -1
- package/README.zh.md +22 -1
- package/package.json +1 -1
- package/src/github-merge-targets.lib.mjs +205 -0
- package/src/limits-i18n.lib.mjs +8 -0
- package/src/limits-subscription.lib.mjs +40 -1
- package/src/limits.lib.mjs +109 -150
- package/src/locales/en.lino +16 -0
- package/src/locales/hi.lino +16 -0
- package/src/locales/ru.lino +16 -0
- package/src/locales/zh.lino +16 -0
- package/src/telegram-merge-command.lib.mjs +93 -15
- package/src/telegram-merge-queue.lib.mjs +108 -24
- package/src/telegram-merge-wait.lib.mjs +75 -0
package/src/limits.lib.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import utc from 'dayjs/plugin/utc.js';
|
|
|
14
14
|
|
|
15
15
|
import { wrapDollarWithGhRetry as _wrapDollarWithGhRetry, execGhWithRetry } from './github-rate-limit.lib.mjs'; // rate-limit marker (#1726): gh API calls flow through $ wrapped by caller. execGhWithRetry adds transient-network retry (#1756).
|
|
16
16
|
import { formatLimitResetsAt, formatLimitResetsIn, formatLocalizedCurrentTime, formatLocalizedRelativeTime, formatLocalizedResetTime, localizeCompactDuration, lt, resolveLimitLocale } from './limits-i18n.lib.mjs';
|
|
17
|
-
import { formatSubscriptionLines, getCachedClaudeSubscription, getCachedCodexSubscription, getClaudeSubscriptionInfo, getCodexSubscriptionInfo } from './limits-subscription.lib.mjs';
|
|
17
|
+
import { formatSubscriptionHeading, formatSubscriptionLines, getCachedClaudeSubscription, getCachedCodexSubscription, getClaudeSubscriptionInfo, getCodexSubscriptionInfo } from './limits-subscription.lib.mjs';
|
|
18
18
|
export { getCachedClaudeSubscription, getCachedCodexSubscription, getClaudeSubscriptionInfo, getCodexSubscriptionInfo };
|
|
19
19
|
// Initialize dayjs plugins
|
|
20
20
|
dayjs.extend(utc);
|
|
@@ -280,6 +280,61 @@ function getLocalizedRelativeReset(window, options = {}, fallbackRelative = null
|
|
|
280
280
|
return formatRelativeTime(window?.resetsAt, options) || localizeCompactDuration(fallbackRelative, options);
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
+
function formatCodeBlock(content) {
|
|
284
|
+
const text = Array.isArray(content) ? content.join('\n') : String(content ?? '');
|
|
285
|
+
return '```\n' + (text.endsWith('\n') ? text : `${text}\n`) + '```';
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function formatPlainTitledCodeSection(section) {
|
|
289
|
+
const text = String(section ?? '').trimEnd();
|
|
290
|
+
if (!text) return '';
|
|
291
|
+
if (text.includes('```')) return text;
|
|
292
|
+
|
|
293
|
+
const lines = text.split('\n');
|
|
294
|
+
const title = lines.shift();
|
|
295
|
+
const body = lines.join('\n');
|
|
296
|
+
if (!body) return formatCodeBlock(title);
|
|
297
|
+
return `${title}\n\n${formatCodeBlock(body)}`;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function formatLimitWindowSection(label, window, periodHours, threshold, options = {}) {
|
|
301
|
+
const locale = resolveLimitLocale(options);
|
|
302
|
+
let section = `${label}\n`;
|
|
303
|
+
if (hasLimitPercentage(window)) {
|
|
304
|
+
const timePassed = calculateTimePassedPercentage(window.resetsAt, periodHours);
|
|
305
|
+
if (timePassed !== null) {
|
|
306
|
+
section += `${getProgressBar(timePassed)} ${timePassed}% ${lt('passed', {}, { locale })}\n`;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const pct = Math.floor(window.percentage);
|
|
310
|
+
const bar = getProgressBar(pct, threshold);
|
|
311
|
+
const suffix = pct >= threshold ? ' ⚠️' : ` ${lt('used', {}, { locale })}`;
|
|
312
|
+
section += `${bar} ${pct}%${suffix}\n`;
|
|
313
|
+
|
|
314
|
+
const resetTime = getLocalizedResetTime(window, { locale });
|
|
315
|
+
if (resetTime) {
|
|
316
|
+
const relativeTime = getLocalizedRelativeReset(window, { locale });
|
|
317
|
+
section += relativeTime ? `${formatLimitResetsIn(relativeTime, resetTime, { locale })}\n` : `${formatLimitResetsAt(resetTime, { locale })}\n`;
|
|
318
|
+
}
|
|
319
|
+
} else {
|
|
320
|
+
section += `${lt('na', {}, { locale })}\n`;
|
|
321
|
+
}
|
|
322
|
+
return section;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function hasPositivePercentage(value) {
|
|
326
|
+
if (value === null || value === undefined) return false;
|
|
327
|
+
const numeric = Number(value);
|
|
328
|
+
return Number.isFinite(numeric) && numeric > 0;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function hasPositiveCreditBalance(credits) {
|
|
332
|
+
if (!credits) return false;
|
|
333
|
+
if (credits.unlimited) return true;
|
|
334
|
+
const numeric = Number.parseFloat(String(credits.balance ?? '0'));
|
|
335
|
+
return Number.isFinite(numeric) && numeric > 0;
|
|
336
|
+
}
|
|
337
|
+
|
|
283
338
|
/**
|
|
284
339
|
* Get GitHub API rate limits by calling gh api rate_limit
|
|
285
340
|
* Returns rate limit info for core, search, graphql, and other resources
|
|
@@ -1061,118 +1116,51 @@ export function formatUsageMessage(usage, diskSpace = null, githubRateLimit = nu
|
|
|
1061
1116
|
sections.push(section);
|
|
1062
1117
|
}
|
|
1063
1118
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1119
|
+
const claudeHeading = formatSubscriptionHeading('claude', subscription, { locale });
|
|
1120
|
+
const useShortClaudeLabels = Boolean(claudeHeading);
|
|
1121
|
+
const claudeSections = [];
|
|
1122
|
+
|
|
1123
|
+
// Claude limits section. When there's an error (e.g., auth expired), show it once and skip empty subsections.
|
|
1066
1124
|
if (claudeError) {
|
|
1067
|
-
|
|
1125
|
+
claudeSections.push(useShortClaudeLabels ? `${claudeError}\n` : `${lt('claude_limits', {}, { locale })}\n${claudeError}\n`);
|
|
1068
1126
|
} else {
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
if (
|
|
1073
|
-
|
|
1074
|
-
if (timePassed !== null) {
|
|
1075
|
-
const timeBar = getProgressBar(timePassed);
|
|
1076
|
-
sessionSection += `${timeBar} ${timePassed}% ${lt('passed', {}, { locale })}\n`;
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
// Use Math.floor so 100% only appears when usage is exactly 100%
|
|
1080
|
-
// See: https://github.com/link-assistant/hive-mind/issues/1133
|
|
1081
|
-
const pct = Math.floor(usage.currentSession.percentage);
|
|
1082
|
-
const bar = getProgressBar(pct, DISPLAY_THRESHOLDS.CLAUDE_5_HOUR_SESSION);
|
|
1083
|
-
const suffix = pct >= DISPLAY_THRESHOLDS.CLAUDE_5_HOUR_SESSION ? ' ⚠️' : ` ${lt('used', {}, { locale })}`;
|
|
1084
|
-
sessionSection += `${bar} ${pct}%${suffix}\n`;
|
|
1085
|
-
|
|
1086
|
-
const sessionResetTime = getLocalizedResetTime(usage.currentSession, { locale });
|
|
1087
|
-
if (sessionResetTime) {
|
|
1088
|
-
const relativeTime = getLocalizedRelativeReset(usage.currentSession, { locale });
|
|
1089
|
-
if (relativeTime) {
|
|
1090
|
-
sessionSection += `${formatLimitResetsIn(relativeTime, sessionResetTime, { locale })}\n`;
|
|
1091
|
-
} else {
|
|
1092
|
-
sessionSection += `${formatLimitResetsAt(sessionResetTime, { locale })}\n`;
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
} else {
|
|
1096
|
-
sessionSection += `${lt('na', {}, { locale })}\n`;
|
|
1127
|
+
const hasSonnetOnly = hasLimitPercentage(usage?.sonnetOnly);
|
|
1128
|
+
claudeSections.push(formatLimitWindowSection(useShortClaudeLabels ? lt('five_hour_limit_session', {}, { locale }) : lt('claude_5_hour_session', {}, { locale }), usage?.currentSession, 5, DISPLAY_THRESHOLDS.CLAUDE_5_HOUR_SESSION, { locale }));
|
|
1129
|
+
claudeSections.push(formatLimitWindowSection(useShortClaudeLabels && !hasSonnetOnly ? lt('current_week', {}, { locale }) : lt('current_week_all_models', {}, { locale }), usage?.allModels, 168, DISPLAY_THRESHOLDS.CLAUDE_WEEKLY, { locale }));
|
|
1130
|
+
if (hasSonnetOnly || !useShortClaudeLabels) {
|
|
1131
|
+
claudeSections.push(formatLimitWindowSection(lt('current_week_sonnet_only', {}, { locale }), usage?.sonnetOnly, 168, DISPLAY_THRESHOLDS.CLAUDE_WEEKLY, { locale }));
|
|
1097
1132
|
}
|
|
1098
|
-
sections.push(sessionSection);
|
|
1099
|
-
|
|
1100
|
-
// Current week (all models / seven_day)
|
|
1101
|
-
// Threshold: One-at-a-time mode when usage >= 97%
|
|
1102
|
-
let allModelsSection = `${lt('current_week_all_models', {}, { locale })}\n`;
|
|
1103
|
-
if (hasLimitPercentage(usage?.allModels)) {
|
|
1104
|
-
const timePassed = calculateTimePassedPercentage(usage.allModels.resetsAt, 168);
|
|
1105
|
-
if (timePassed !== null) {
|
|
1106
|
-
const timeBar = getProgressBar(timePassed);
|
|
1107
|
-
allModelsSection += `${timeBar} ${timePassed}% ${lt('passed', {}, { locale })}\n`;
|
|
1108
|
-
}
|
|
1109
1133
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
const bar = getProgressBar(pct, DISPLAY_THRESHOLDS.CLAUDE_WEEKLY);
|
|
1114
|
-
const suffix = pct >= DISPLAY_THRESHOLDS.CLAUDE_WEEKLY ? ' ⚠️' : ` ${lt('used', {}, { locale })}`;
|
|
1115
|
-
allModelsSection += `${bar} ${pct}%${suffix}\n`;
|
|
1116
|
-
|
|
1117
|
-
const allModelsResetTime = getLocalizedResetTime(usage.allModels, { locale });
|
|
1118
|
-
if (allModelsResetTime) {
|
|
1119
|
-
const relativeTime = getLocalizedRelativeReset(usage.allModels, { locale });
|
|
1120
|
-
if (relativeTime) {
|
|
1121
|
-
allModelsSection += `${formatLimitResetsIn(relativeTime, allModelsResetTime, { locale })}\n`;
|
|
1122
|
-
} else {
|
|
1123
|
-
allModelsSection += `${formatLimitResetsAt(allModelsResetTime, { locale })}\n`;
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
} else {
|
|
1127
|
-
allModelsSection += `${lt('na', {}, { locale })}\n`;
|
|
1134
|
+
if (!useShortClaudeLabels) {
|
|
1135
|
+
const subscriptionLines = formatSubscriptionLines(subscription, { locale });
|
|
1136
|
+
if (subscriptionLines) claudeSections.push(subscriptionLines);
|
|
1128
1137
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
// Current week (Sonnet only / seven_day_sonnet)
|
|
1132
|
-
// Threshold: One-at-a-time mode when usage >= 97% (same as all models)
|
|
1133
|
-
let sonnetSection = `${lt('current_week_sonnet_only', {}, { locale })}\n`;
|
|
1134
|
-
if (hasLimitPercentage(usage?.sonnetOnly)) {
|
|
1135
|
-
// Add time passed progress bar first (no threshold marker for time)
|
|
1136
|
-
const timePassed = calculateTimePassedPercentage(usage.sonnetOnly.resetsAt, 168);
|
|
1137
|
-
if (timePassed !== null) {
|
|
1138
|
-
const timeBar = getProgressBar(timePassed);
|
|
1139
|
-
sonnetSection += `${timeBar} ${timePassed}% ${lt('passed', {}, { locale })}\n`;
|
|
1140
|
-
}
|
|
1138
|
+
}
|
|
1141
1139
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
const sonnetResetTime = getLocalizedResetTime(usage.sonnetOnly, { locale });
|
|
1151
|
-
if (sonnetResetTime) {
|
|
1152
|
-
const relativeTime = getLocalizedRelativeReset(usage.sonnetOnly, { locale });
|
|
1153
|
-
if (relativeTime) {
|
|
1154
|
-
sonnetSection += `${formatLimitResetsIn(relativeTime, sonnetResetTime, { locale })}\n`;
|
|
1155
|
-
} else {
|
|
1156
|
-
sonnetSection += `${formatLimitResetsAt(sonnetResetTime, { locale })}\n`;
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
} else {
|
|
1160
|
-
sonnetSection += `${lt('na', {}, { locale })}\n`;
|
|
1140
|
+
const hasFencedExtraSection = extraSections.some(extra => String(extra ?? '').includes('```'));
|
|
1141
|
+
const useSplitLayout = Boolean(claudeHeading) || hasFencedExtraSection;
|
|
1142
|
+
|
|
1143
|
+
if (!useSplitLayout) {
|
|
1144
|
+
sections.push(...claudeSections);
|
|
1145
|
+
for (const extra of extraSections) {
|
|
1146
|
+
sections.push(extra);
|
|
1161
1147
|
}
|
|
1162
|
-
sections.
|
|
1148
|
+
return formatCodeBlock(sections.join('\n'));
|
|
1149
|
+
}
|
|
1163
1150
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1151
|
+
const markdownSections = [];
|
|
1152
|
+
markdownSections.push(formatCodeBlock(claudeHeading ? sections.join('\n') : [...sections, ...claudeSections].join('\n')));
|
|
1153
|
+
if (claudeHeading) {
|
|
1154
|
+
markdownSections.push(claudeHeading);
|
|
1155
|
+
markdownSections.push(formatCodeBlock(claudeSections.join('\n')));
|
|
1166
1156
|
}
|
|
1167
1157
|
|
|
1168
|
-
// Append any caller-provided extra sections (e.g. queue status) inside the code block
|
|
1169
1158
|
for (const extra of extraSections) {
|
|
1170
|
-
|
|
1159
|
+
const formatted = formatPlainTitledCodeSection(extra);
|
|
1160
|
+
if (formatted) markdownSections.push(formatted);
|
|
1171
1161
|
}
|
|
1172
1162
|
|
|
1173
|
-
|
|
1174
|
-
// Sections are separated by blank lines; the trailing newline on each section provides spacing.
|
|
1175
|
-
return '```\n' + sections.join('\n') + '```';
|
|
1163
|
+
return markdownSections.join('\n\n');
|
|
1176
1164
|
}
|
|
1177
1165
|
|
|
1178
1166
|
/**
|
|
@@ -1185,64 +1173,33 @@ export function formatUsageMessage(usage, diskSpace = null, githubRateLimit = nu
|
|
|
1185
1173
|
*/
|
|
1186
1174
|
export function formatCodexLimitsSection(codexLimits, codexError = null, options = {}) {
|
|
1187
1175
|
const locale = resolveLimitLocale(options);
|
|
1188
|
-
|
|
1189
|
-
return `${lt('codex_limits', {}, { locale })}\n${codexError}\n`;
|
|
1190
|
-
}
|
|
1191
|
-
|
|
1176
|
+
const subscription = options?.subscription || null;
|
|
1192
1177
|
const usage = codexLimits?.usage || null;
|
|
1193
1178
|
const additionalRateLimits = codexLimits?.additionalRateLimits || [];
|
|
1194
1179
|
const credits = codexLimits?.credits || null;
|
|
1195
|
-
const planType = codexLimits?.planType || null;
|
|
1196
|
-
const
|
|
1180
|
+
const planType = subscription?.planType || codexLimits?.planType || null;
|
|
1181
|
+
const heading = formatSubscriptionHeading('codex', subscription, { locale, planType });
|
|
1182
|
+
const useTitledLayout = Boolean(heading);
|
|
1197
1183
|
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1184
|
+
if (codexError) {
|
|
1185
|
+
const errorSection = useTitledLayout ? `${codexError}\n` : `${lt('codex_limits', {}, { locale })}\n${codexError}\n`;
|
|
1186
|
+
return useTitledLayout ? `${heading}\n\n${formatCodeBlock(errorSection)}` : errorSection;
|
|
1201
1187
|
}
|
|
1202
1188
|
|
|
1203
|
-
let
|
|
1204
|
-
if (
|
|
1205
|
-
|
|
1206
|
-
if (timePassed !== null) {
|
|
1207
|
-
sessionSection += `${getProgressBar(timePassed)} ${timePassed}% ${lt('passed', {}, { locale })}\n`;
|
|
1208
|
-
}
|
|
1209
|
-
const pct = Math.floor(usage.currentSession.percentage);
|
|
1210
|
-
const bar = getProgressBar(pct, DISPLAY_THRESHOLDS.CODEX_5_HOUR_SESSION);
|
|
1211
|
-
const suffix = pct >= DISPLAY_THRESHOLDS.CODEX_5_HOUR_SESSION ? ' ⚠️' : ` ${lt('used', {}, { locale })}`;
|
|
1212
|
-
sessionSection += `${bar} ${pct}%${suffix}\n`;
|
|
1213
|
-
const sessionResetTime = getLocalizedResetTime(usage.currentSession, { locale });
|
|
1214
|
-
if (sessionResetTime) {
|
|
1215
|
-
const relativeTime = getLocalizedRelativeReset(usage.currentSession, { locale });
|
|
1216
|
-
sessionSection += relativeTime ? `${formatLimitResetsIn(relativeTime, sessionResetTime, { locale })}\n` : `${formatLimitResetsAt(sessionResetTime, { locale })}\n`;
|
|
1217
|
-
}
|
|
1218
|
-
} else {
|
|
1219
|
-
sessionSection += `${lt('na', {}, { locale })}\n`;
|
|
1189
|
+
let section = useTitledLayout ? '' : `${lt('codex_limits', {}, { locale })}\n`;
|
|
1190
|
+
if (planType && !useTitledLayout) {
|
|
1191
|
+
section += `${lt('plan', {}, { locale })}: ${planType}\n`;
|
|
1220
1192
|
}
|
|
1221
1193
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
const timePassed = calculateTimePassedPercentage(usage.allModels.resetsAt, 168);
|
|
1225
|
-
if (timePassed !== null) {
|
|
1226
|
-
weeklySection += `${getProgressBar(timePassed)} ${timePassed}% ${lt('passed', {}, { locale })}\n`;
|
|
1227
|
-
}
|
|
1228
|
-
const pct = Math.floor(usage.allModels.percentage);
|
|
1229
|
-
const bar = getProgressBar(pct, DISPLAY_THRESHOLDS.CODEX_WEEKLY);
|
|
1230
|
-
const suffix = pct >= DISPLAY_THRESHOLDS.CODEX_WEEKLY ? ' ⚠️' : ` ${lt('used', {}, { locale })}`;
|
|
1231
|
-
weeklySection += `${bar} ${pct}%${suffix}\n`;
|
|
1232
|
-
const weeklyResetTime = getLocalizedResetTime(usage.allModels, { locale });
|
|
1233
|
-
if (weeklyResetTime) {
|
|
1234
|
-
const relativeTime = getLocalizedRelativeReset(usage.allModels, { locale });
|
|
1235
|
-
weeklySection += relativeTime ? `${formatLimitResetsIn(relativeTime, weeklyResetTime, { locale })}\n` : `${formatLimitResetsAt(weeklyResetTime, { locale })}\n`;
|
|
1236
|
-
}
|
|
1237
|
-
} else {
|
|
1238
|
-
weeklySection += `${lt('na', {}, { locale })}\n`;
|
|
1239
|
-
}
|
|
1194
|
+
const sessionSection = formatLimitWindowSection(useTitledLayout ? lt('five_hour_limit_session', {}, { locale }) : lt('codex_5_hour_session', {}, { locale }), usage?.currentSession, 5, DISPLAY_THRESHOLDS.CODEX_5_HOUR_SESSION, { locale });
|
|
1195
|
+
const weeklySection = formatLimitWindowSection(useTitledLayout ? lt('current_week', {}, { locale }) : lt('current_week_all_models', {}, { locale }), usage?.allModels, 168, DISPLAY_THRESHOLDS.CODEX_WEEKLY, { locale });
|
|
1240
1196
|
|
|
1241
1197
|
section += `${sessionSection}\n${weeklySection}`;
|
|
1242
1198
|
|
|
1243
|
-
|
|
1199
|
+
const visibleAdditionalRateLimits = additionalRateLimits.filter(limit => hasPositivePercentage(limit.allModels?.percentage));
|
|
1200
|
+
if (visibleAdditionalRateLimits.length > 0) {
|
|
1244
1201
|
section += `\n${lt('additional_codex_limits', {}, { locale })}\n`;
|
|
1245
|
-
for (const limit of
|
|
1202
|
+
for (const limit of visibleAdditionalRateLimits) {
|
|
1246
1203
|
const sessionPct = limit.currentSession?.percentage;
|
|
1247
1204
|
const weeklyPct = limit.allModels?.percentage;
|
|
1248
1205
|
const sessionText = sessionPct === null || sessionPct === undefined ? `${lt('session', {}, { locale })} ${lt('na', {}, { locale })}` : `${lt('session', {}, { locale })} ${Math.floor(sessionPct)}%`;
|
|
@@ -1251,15 +1208,17 @@ export function formatCodexLimitsSection(codexLimits, codexError = null, options
|
|
|
1251
1208
|
}
|
|
1252
1209
|
}
|
|
1253
1210
|
|
|
1254
|
-
if (credits) {
|
|
1211
|
+
if (hasPositiveCreditBalance(credits)) {
|
|
1255
1212
|
const creditSummary = credits.unlimited ? lt('unlimited', {}, { locale }) : `${credits.balance ?? '0'} ${lt('balance', {}, { locale })}`;
|
|
1256
1213
|
section += `\n${lt('codex_credits', {}, { locale })}\n${creditSummary}\n`;
|
|
1257
1214
|
}
|
|
1258
1215
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1216
|
+
if (!useTitledLayout) {
|
|
1217
|
+
const subscriptionLines = formatSubscriptionLines(subscription, { locale });
|
|
1218
|
+
if (subscriptionLines) section += subscriptionLines;
|
|
1219
|
+
}
|
|
1261
1220
|
|
|
1262
|
-
return section;
|
|
1221
|
+
return useTitledLayout ? `${heading}\n\n${formatCodeBlock(section)}` : section;
|
|
1263
1222
|
}
|
|
1264
1223
|
|
|
1265
1224
|
// ============================================================================
|
package/src/locales/en.lino
CHANGED
|
@@ -192,6 +192,11 @@ en
|
|
|
192
192
|
hour
|
|
193
193
|
session "Claude 5 hour session"
|
|
194
194
|
limits "Claude limits"
|
|
195
|
+
subscription
|
|
196
|
+
title "Claude{{plan}} subscription"
|
|
197
|
+
chatgpt
|
|
198
|
+
subscription
|
|
199
|
+
title "ChatGPT{{plan}} subscription"
|
|
195
200
|
codex
|
|
196
201
|
5
|
|
197
202
|
hour
|
|
@@ -205,6 +210,7 @@ en
|
|
|
205
210
|
current
|
|
206
211
|
time "Current time"
|
|
207
212
|
week
|
|
213
|
+
label "Current week"
|
|
208
214
|
all
|
|
209
215
|
models "Current week (all models)"
|
|
210
216
|
sonnet
|
|
@@ -226,6 +232,8 @@ en
|
|
|
226
232
|
end "End"
|
|
227
233
|
five
|
|
228
234
|
hour
|
|
235
|
+
limit
|
|
236
|
+
session "5 hour session"
|
|
229
237
|
session "5h session"
|
|
230
238
|
min
|
|
231
239
|
load
|
|
@@ -314,6 +322,14 @@ en
|
|
|
314
322
|
session "session"
|
|
315
323
|
start "Start"
|
|
316
324
|
subscription
|
|
325
|
+
detail
|
|
326
|
+
ends
|
|
327
|
+
label "ends {{time}}"
|
|
328
|
+
in "ends in {{duration}}; {{time}}"
|
|
329
|
+
trial
|
|
330
|
+
ends
|
|
331
|
+
label "trial ends {{time}}"
|
|
332
|
+
in "trial ends in {{duration}}; {{time}}"
|
|
317
333
|
ends
|
|
318
334
|
label "Subscription ends {{time}}"
|
|
319
335
|
in "Subscription ends in {{duration}} ({{time}})"
|
package/src/locales/hi.lino
CHANGED
|
@@ -192,6 +192,11 @@ hi
|
|
|
192
192
|
hour
|
|
193
193
|
session "Claude 5 घंटे का सत्र"
|
|
194
194
|
limits "Claude सीमाएँ"
|
|
195
|
+
subscription
|
|
196
|
+
title "Claude{{plan}} सदस्यता"
|
|
197
|
+
chatgpt
|
|
198
|
+
subscription
|
|
199
|
+
title "ChatGPT{{plan}} सदस्यता"
|
|
195
200
|
codex
|
|
196
201
|
5
|
|
197
202
|
hour
|
|
@@ -205,6 +210,7 @@ hi
|
|
|
205
210
|
current
|
|
206
211
|
time "वर्तमान समय"
|
|
207
212
|
week
|
|
213
|
+
label "वर्तमान सप्ताह"
|
|
208
214
|
all
|
|
209
215
|
models "वर्तमान सप्ताह (सभी मॉडल)"
|
|
210
216
|
sonnet
|
|
@@ -226,6 +232,8 @@ hi
|
|
|
226
232
|
end "समाप्ति"
|
|
227
233
|
five
|
|
228
234
|
hour
|
|
235
|
+
limit
|
|
236
|
+
session "5 घंटे का सत्र"
|
|
229
237
|
session "5 घंटे का सत्र"
|
|
230
238
|
min
|
|
231
239
|
load
|
|
@@ -314,6 +322,14 @@ hi
|
|
|
314
322
|
session "सत्र"
|
|
315
323
|
start "शुरुआत"
|
|
316
324
|
subscription
|
|
325
|
+
detail
|
|
326
|
+
ends
|
|
327
|
+
label "{{time}} को समाप्त होगी"
|
|
328
|
+
in "{{duration}} में समाप्त होगी; {{time}}"
|
|
329
|
+
trial
|
|
330
|
+
ends
|
|
331
|
+
label "ट्रायल {{time}} को समाप्त होगा"
|
|
332
|
+
in "ट्रायल {{duration}} में समाप्त होगा; {{time}}"
|
|
317
333
|
ends
|
|
318
334
|
label "सदस्यता समाप्त होगी {{time}}"
|
|
319
335
|
in "सदस्यता {{duration}} में समाप्त होगी ({{time}})"
|
package/src/locales/ru.lino
CHANGED
|
@@ -192,6 +192,11 @@ ru
|
|
|
192
192
|
hour
|
|
193
193
|
session "5-часовой сеанс Claude"
|
|
194
194
|
limits "Лимиты Claude"
|
|
195
|
+
subscription
|
|
196
|
+
title "Подписка Claude{{plan}}"
|
|
197
|
+
chatgpt
|
|
198
|
+
subscription
|
|
199
|
+
title "Подписка ChatGPT{{plan}}"
|
|
195
200
|
codex
|
|
196
201
|
5
|
|
197
202
|
hour
|
|
@@ -205,6 +210,7 @@ ru
|
|
|
205
210
|
current
|
|
206
211
|
time "Текущее время"
|
|
207
212
|
week
|
|
213
|
+
label "Текущая неделя"
|
|
208
214
|
all
|
|
209
215
|
models "Текущая неделя (все модели)"
|
|
210
216
|
sonnet
|
|
@@ -226,6 +232,8 @@ ru
|
|
|
226
232
|
end "Конец"
|
|
227
233
|
five
|
|
228
234
|
hour
|
|
235
|
+
limit
|
|
236
|
+
session "5-часовой сеанс"
|
|
229
237
|
session "5-часовой сеанс"
|
|
230
238
|
min
|
|
231
239
|
load
|
|
@@ -314,6 +322,14 @@ ru
|
|
|
314
322
|
session "сеанс"
|
|
315
323
|
start "Начало"
|
|
316
324
|
subscription
|
|
325
|
+
detail
|
|
326
|
+
ends
|
|
327
|
+
label "заканчивается {{time}}"
|
|
328
|
+
in "заканчивается через {{duration}}; {{time}}"
|
|
329
|
+
trial
|
|
330
|
+
ends
|
|
331
|
+
label "пробный период заканчивается {{time}}"
|
|
332
|
+
in "пробный период заканчивается через {{duration}}; {{time}}"
|
|
317
333
|
ends
|
|
318
334
|
label "Подписка заканчивается {{time}}"
|
|
319
335
|
in "Подписка заканчивается через {{duration}} ({{time}})"
|
package/src/locales/zh.lino
CHANGED
|
@@ -192,6 +192,11 @@ zh
|
|
|
192
192
|
hour
|
|
193
193
|
session "Claude 5 小时会话"
|
|
194
194
|
limits "Claude 限额"
|
|
195
|
+
subscription
|
|
196
|
+
title "Claude{{plan}} 订阅"
|
|
197
|
+
chatgpt
|
|
198
|
+
subscription
|
|
199
|
+
title "ChatGPT{{plan}} 订阅"
|
|
195
200
|
codex
|
|
196
201
|
5
|
|
197
202
|
hour
|
|
@@ -205,6 +210,7 @@ zh
|
|
|
205
210
|
current
|
|
206
211
|
time "当前时间"
|
|
207
212
|
week
|
|
213
|
+
label "本周"
|
|
208
214
|
all
|
|
209
215
|
models "本周(所有模型)"
|
|
210
216
|
sonnet
|
|
@@ -226,6 +232,8 @@ zh
|
|
|
226
232
|
end "结束"
|
|
227
233
|
five
|
|
228
234
|
hour
|
|
235
|
+
limit
|
|
236
|
+
session "5 小时会话"
|
|
229
237
|
session "5 小时会话"
|
|
230
238
|
min
|
|
231
239
|
load
|
|
@@ -314,6 +322,14 @@ zh
|
|
|
314
322
|
session "会话"
|
|
315
323
|
start "开始"
|
|
316
324
|
subscription
|
|
325
|
+
detail
|
|
326
|
+
ends
|
|
327
|
+
label "结束于 {{time}}"
|
|
328
|
+
in "将在 {{duration}} 后结束;{{time}}"
|
|
329
|
+
trial
|
|
330
|
+
ends
|
|
331
|
+
label "试用结束于 {{time}}"
|
|
332
|
+
in "试用将在 {{duration}} 后结束;{{time}}"
|
|
317
333
|
ends
|
|
318
334
|
label "订阅结束于 {{time}}"
|
|
319
335
|
in "订阅将在 {{duration}} 后结束 ({{time}})"
|