codex-multi-auth 0.1.7 → 0.1.8
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/LICENSE +21 -1
- package/README.md +13 -0
- package/assets/readme-hero.svg +31 -31
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/codex-cli/sync.d.ts +9 -16
- package/dist/lib/codex-cli/sync.d.ts.map +1 -1
- package/dist/lib/codex-cli/sync.js +51 -284
- package/dist/lib/codex-cli/sync.js.map +1 -1
- package/dist/lib/codex-manager/settings-hub.d.ts +44 -2
- package/dist/lib/codex-manager/settings-hub.d.ts.map +1 -1
- package/dist/lib/codex-manager/settings-hub.js +746 -117
- package/dist/lib/codex-manager/settings-hub.js.map +1 -1
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +3 -8
- package/dist/lib/codex-manager.js.map +1 -1
- package/dist/lib/context-overflow.js +10 -10
- package/dist/lib/named-backup-export.d.ts +69 -0
- package/dist/lib/named-backup-export.d.ts.map +1 -0
- package/dist/lib/named-backup-export.js +207 -0
- package/dist/lib/named-backup-export.js.map +1 -0
- package/dist/lib/oc-chatgpt-import-adapter.d.ts +64 -0
- package/dist/lib/oc-chatgpt-import-adapter.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-import-adapter.js +506 -0
- package/dist/lib/oc-chatgpt-import-adapter.js.map +1 -0
- package/dist/lib/oc-chatgpt-orchestrator.d.ts +80 -0
- package/dist/lib/oc-chatgpt-orchestrator.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-orchestrator.js +130 -0
- package/dist/lib/oc-chatgpt-orchestrator.js.map +1 -0
- package/dist/lib/oc-chatgpt-target-detection.d.ts +59 -0
- package/dist/lib/oc-chatgpt-target-detection.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-target-detection.js +327 -0
- package/dist/lib/oc-chatgpt-target-detection.js.map +1 -0
- package/dist/lib/prompts/codex.js +2 -2
- package/dist/lib/runtime-paths.d.ts.map +1 -1
- package/dist/lib/runtime-paths.js +21 -1
- package/dist/lib/runtime-paths.js.map +1 -1
- package/dist/lib/storage.d.ts +42 -3
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +519 -51
- package/dist/lib/storage.js.map +1 -1
- package/dist/lib/ui/copy.d.ts +15 -1
- package/dist/lib/ui/copy.d.ts.map +1 -1
- package/dist/lib/ui/copy.js +15 -1
- package/dist/lib/ui/copy.js.map +1 -1
- package/package.json +132 -133
- package/scripts/bench-format/hashline-v2.mjs +642 -642
- package/scripts/bench-format/render.mjs +496 -496
- package/scripts/bench-format/stats.mjs +54 -54
- package/scripts/bench-format/tasks.mjs +151 -151
- package/scripts/benchmark-render-dashboard.mjs +49 -49
- package/scripts/install-codex-auth.js +9 -9
- package/scripts/test-all-models.sh +7 -7
- package/scripts/test-model-matrix.js +138 -46
- package/scripts/validate-model-map.sh +7 -7
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
1
2
|
import { stdin as input, stdout as output } from "node:process";
|
|
2
|
-
import {
|
|
3
|
-
import { getDefaultPluginConfig, loadPluginConfig, savePluginConfig } from "../config.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { createInterface } from "node:readline/promises";
|
|
4
|
+
import { getDefaultPluginConfig, loadPluginConfig, savePluginConfig, } from "../config.js";
|
|
5
|
+
import { DEFAULT_DASHBOARD_DISPLAY_SETTINGS, getDashboardSettingsPath, loadDashboardDisplaySettings, saveDashboardDisplaySettings, } from "../dashboard-settings.js";
|
|
6
|
+
import { applyOcChatgptSync, planOcChatgptSync, runNamedBackupExport, } from "../oc-chatgpt-orchestrator.js";
|
|
7
|
+
import { detectOcChatgptMultiAuthTarget } from "../oc-chatgpt-target-detection.js";
|
|
8
|
+
import { loadAccounts, normalizeAccountStorage } from "../storage.js";
|
|
6
9
|
import { ANSI } from "../ui/ansi.js";
|
|
7
10
|
import { UI_COPY } from "../ui/copy.js";
|
|
8
11
|
import { getUiRuntimeOptions, setUiRuntimeOptions } from "../ui/runtime.js";
|
|
9
12
|
import { select } from "../ui/select.js";
|
|
13
|
+
import { getUnifiedSettingsPath } from "../unified-settings.js";
|
|
14
|
+
import { sleep } from "../utils.js";
|
|
10
15
|
const DASHBOARD_DISPLAY_OPTIONS = [
|
|
11
16
|
{
|
|
12
17
|
key: "menuShowStatusBadge",
|
|
@@ -59,7 +64,11 @@ const DASHBOARD_DISPLAY_OPTIONS = [
|
|
|
59
64
|
description: "Number keys (1-9) follow what you see in the list.",
|
|
60
65
|
},
|
|
61
66
|
];
|
|
62
|
-
const DEFAULT_STATUSLINE_FIELDS = [
|
|
67
|
+
const DEFAULT_STATUSLINE_FIELDS = [
|
|
68
|
+
"last-used",
|
|
69
|
+
"limits",
|
|
70
|
+
"status",
|
|
71
|
+
];
|
|
63
72
|
const STATUSLINE_FIELD_OPTIONS = [
|
|
64
73
|
{
|
|
65
74
|
key: "last-used",
|
|
@@ -80,7 +89,12 @@ const STATUSLINE_FIELD_OPTIONS = [
|
|
|
80
89
|
const AUTO_RETURN_OPTIONS_MS = [1_000, 2_000, 4_000];
|
|
81
90
|
const MENU_QUOTA_TTL_OPTIONS_MS = [60_000, 5 * 60_000, 10 * 60_000];
|
|
82
91
|
const THEME_PRESET_OPTIONS = ["green", "blue"];
|
|
83
|
-
const ACCENT_COLOR_OPTIONS = [
|
|
92
|
+
const ACCENT_COLOR_OPTIONS = [
|
|
93
|
+
"green",
|
|
94
|
+
"cyan",
|
|
95
|
+
"blue",
|
|
96
|
+
"yellow",
|
|
97
|
+
];
|
|
84
98
|
const PREVIEW_ACCOUNT_EMAIL = "demo@example.com";
|
|
85
99
|
const PREVIEW_LAST_USED = "today";
|
|
86
100
|
const PREVIEW_STATUS = "active";
|
|
@@ -326,12 +340,8 @@ const BACKEND_CATEGORY_OPTIONS = [
|
|
|
326
340
|
key: "refresh-recovery",
|
|
327
341
|
label: "Refresh & Recovery",
|
|
328
342
|
description: "Token refresh and recovery safety.",
|
|
329
|
-
toggleKeys: ["
|
|
330
|
-
numberKeys: [
|
|
331
|
-
"proactiveRefreshIntervalMs",
|
|
332
|
-
"proactiveRefreshBufferMs",
|
|
333
|
-
"tokenRefreshSkewMs",
|
|
334
|
-
],
|
|
343
|
+
toggleKeys: ["storageBackupEnabled"],
|
|
344
|
+
numberKeys: ["proactiveRefreshBufferMs", "tokenRefreshSkewMs"],
|
|
335
345
|
},
|
|
336
346
|
{
|
|
337
347
|
key: "performance-timeouts",
|
|
@@ -348,7 +358,13 @@ const BACKEND_CATEGORY_OPTIONS = [
|
|
|
348
358
|
],
|
|
349
359
|
},
|
|
350
360
|
];
|
|
351
|
-
const RETRYABLE_SETTINGS_WRITE_CODES = new Set([
|
|
361
|
+
const RETRYABLE_SETTINGS_WRITE_CODES = new Set([
|
|
362
|
+
"EBUSY",
|
|
363
|
+
"EPERM",
|
|
364
|
+
"EAGAIN",
|
|
365
|
+
"ENOTEMPTY",
|
|
366
|
+
"EACCES",
|
|
367
|
+
]);
|
|
352
368
|
const SETTINGS_WRITE_MAX_ATTEMPTS = 4;
|
|
353
369
|
const SETTINGS_WRITE_BASE_DELAY_MS = 20;
|
|
354
370
|
const SETTINGS_WRITE_MAX_DELAY_MS = 30_000;
|
|
@@ -368,7 +384,9 @@ const ACCOUNT_LIST_PANEL_KEYS = [
|
|
|
368
384
|
"menuSortQuickSwitchVisibleRow",
|
|
369
385
|
"menuLayoutMode",
|
|
370
386
|
];
|
|
371
|
-
const STATUSLINE_PANEL_KEYS = [
|
|
387
|
+
const STATUSLINE_PANEL_KEYS = [
|
|
388
|
+
"menuStatuslineFields",
|
|
389
|
+
];
|
|
372
390
|
const BEHAVIOR_PANEL_KEYS = [
|
|
373
391
|
"actionAutoReturnMs",
|
|
374
392
|
"actionPauseOnKey",
|
|
@@ -376,7 +394,10 @@ const BEHAVIOR_PANEL_KEYS = [
|
|
|
376
394
|
"menuShowFetchStatus",
|
|
377
395
|
"menuQuotaTtlMs",
|
|
378
396
|
];
|
|
379
|
-
const THEME_PANEL_KEYS = [
|
|
397
|
+
const THEME_PANEL_KEYS = [
|
|
398
|
+
"uiThemePreset",
|
|
399
|
+
"uiAccentColor",
|
|
400
|
+
];
|
|
380
401
|
function readErrorNumber(value) {
|
|
381
402
|
if (typeof value === "number" && Number.isFinite(value))
|
|
382
403
|
return value;
|
|
@@ -411,7 +432,9 @@ function isRetryableSettingsWriteError(error) {
|
|
|
411
432
|
}
|
|
412
433
|
function resolveRetryDelayMs(error, attempt) {
|
|
413
434
|
const retryAfterMs = getRetryAfterMs(error);
|
|
414
|
-
if (typeof retryAfterMs === "number" &&
|
|
435
|
+
if (typeof retryAfterMs === "number" &&
|
|
436
|
+
Number.isFinite(retryAfterMs) &&
|
|
437
|
+
retryAfterMs > 0) {
|
|
415
438
|
return Math.max(10, Math.min(SETTINGS_WRITE_MAX_DELAY_MS, Math.round(retryAfterMs)));
|
|
416
439
|
}
|
|
417
440
|
return Math.min(SETTINGS_WRITE_MAX_DELAY_MS, SETTINGS_WRITE_BASE_DELAY_MS * 2 ** attempt);
|
|
@@ -439,18 +462,23 @@ async function withQueuedRetry(pathKey, task) {
|
|
|
439
462
|
}
|
|
440
463
|
catch (error) {
|
|
441
464
|
lastError = error;
|
|
442
|
-
if (!isRetryableSettingsWriteError(error) ||
|
|
465
|
+
if (!isRetryableSettingsWriteError(error) ||
|
|
466
|
+
attempt + 1 >= SETTINGS_WRITE_MAX_ATTEMPTS) {
|
|
443
467
|
throw error;
|
|
444
468
|
}
|
|
445
469
|
await sleep(resolveRetryDelayMs(error, attempt));
|
|
446
470
|
}
|
|
447
471
|
}
|
|
448
|
-
throw lastError instanceof Error
|
|
472
|
+
throw lastError instanceof Error
|
|
473
|
+
? lastError
|
|
474
|
+
: new Error("settings save retry exhausted");
|
|
449
475
|
});
|
|
450
476
|
}
|
|
451
477
|
function copyDashboardSettingValue(target, source, key) {
|
|
452
478
|
const value = source[key];
|
|
453
|
-
target[key] = Array.isArray(value)
|
|
479
|
+
target[key] = Array.isArray(value)
|
|
480
|
+
? [...value]
|
|
481
|
+
: value;
|
|
454
482
|
}
|
|
455
483
|
function applyDashboardDefaultsForKeys(draft, keys) {
|
|
456
484
|
const next = cloneDashboardSettings(draft);
|
|
@@ -494,6 +522,25 @@ async function persistDashboardSettingsSelection(selected, keys, scope) {
|
|
|
494
522
|
return fallback;
|
|
495
523
|
}
|
|
496
524
|
}
|
|
525
|
+
async function readFileWithRetry(path) {
|
|
526
|
+
for (let attempt = 0;; attempt += 1) {
|
|
527
|
+
try {
|
|
528
|
+
return await fs.readFile(path, "utf-8");
|
|
529
|
+
}
|
|
530
|
+
catch (error) {
|
|
531
|
+
const code = error.code;
|
|
532
|
+
if (code === "ENOENT") {
|
|
533
|
+
throw error;
|
|
534
|
+
}
|
|
535
|
+
if (!code ||
|
|
536
|
+
!RETRYABLE_SETTINGS_WRITE_CODES.has(code) ||
|
|
537
|
+
attempt >= SETTINGS_WRITE_MAX_ATTEMPTS - 1) {
|
|
538
|
+
throw error;
|
|
539
|
+
}
|
|
540
|
+
await sleep(25 * 2 ** attempt);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
497
544
|
async function persistBackendConfigSelection(selected, scope) {
|
|
498
545
|
const fallback = cloneBackendPluginConfig(selected);
|
|
499
546
|
try {
|
|
@@ -549,7 +596,7 @@ function isCurrentRowPreviewFocus(focus) {
|
|
|
549
596
|
return focus === "menuHighlightCurrentRow";
|
|
550
597
|
}
|
|
551
598
|
function isExpandedRowsPreviewFocus(focus) {
|
|
552
|
-
return focus === "menuShowDetailsForUnselectedRows" || focus === "menuLayoutMode";
|
|
599
|
+
return (focus === "menuShowDetailsForUnselectedRows" || focus === "menuLayoutMode");
|
|
553
600
|
}
|
|
554
601
|
function buildSummaryPreviewText(settings, ui, focus = null) {
|
|
555
602
|
const partsByField = new Map();
|
|
@@ -587,11 +634,15 @@ function buildAccountListPreview(settings, ui, focus = null) {
|
|
|
587
634
|
const badges = [];
|
|
588
635
|
if (settings.menuShowCurrentBadge !== false) {
|
|
589
636
|
const currentBadge = "[current]";
|
|
590
|
-
badges.push(isCurrentBadgePreviewFocus(focus)
|
|
637
|
+
badges.push(isCurrentBadgePreviewFocus(focus)
|
|
638
|
+
? highlightPreviewToken(currentBadge, ui)
|
|
639
|
+
: currentBadge);
|
|
591
640
|
}
|
|
592
641
|
if (settings.menuShowStatusBadge !== false) {
|
|
593
642
|
const statusBadge = "[active]";
|
|
594
|
-
badges.push(isStatusPreviewFocus(focus)
|
|
643
|
+
badges.push(isStatusPreviewFocus(focus)
|
|
644
|
+
? highlightPreviewToken(statusBadge, ui)
|
|
645
|
+
: statusBadge);
|
|
595
646
|
}
|
|
596
647
|
const badgeSuffix = badges.length > 0 ? ` ${badges.join(" ")}` : "";
|
|
597
648
|
const accountEmail = isCurrentRowPreviewFocus(focus)
|
|
@@ -619,10 +670,15 @@ function cloneDashboardSettings(settings) {
|
|
|
619
670
|
actionAutoReturnMs: settings.actionAutoReturnMs ?? 2_000,
|
|
620
671
|
actionPauseOnKey: settings.actionPauseOnKey ?? true,
|
|
621
672
|
menuAutoFetchLimits: settings.menuAutoFetchLimits ?? true,
|
|
622
|
-
menuSortEnabled: settings.menuSortEnabled ??
|
|
623
|
-
|
|
673
|
+
menuSortEnabled: settings.menuSortEnabled ??
|
|
674
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortEnabled ??
|
|
675
|
+
true,
|
|
676
|
+
menuSortMode: settings.menuSortMode ??
|
|
677
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
678
|
+
"ready-first",
|
|
624
679
|
menuSortPinCurrent: settings.menuSortPinCurrent ??
|
|
625
|
-
|
|
680
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortPinCurrent ??
|
|
681
|
+
false,
|
|
626
682
|
menuSortQuickSwitchVisibleRow: settings.menuSortQuickSwitchVisibleRow ?? true,
|
|
627
683
|
uiThemePreset: settings.uiThemePreset ?? "green",
|
|
628
684
|
uiAccentColor: settings.uiAccentColor ?? "green",
|
|
@@ -637,7 +693,9 @@ function cloneDashboardSettings(settings) {
|
|
|
637
693
|
menuQuotaTtlMs: settings.menuQuotaTtlMs ?? 5 * 60_000,
|
|
638
694
|
menuFocusStyle: settings.menuFocusStyle ?? "row-invert",
|
|
639
695
|
menuHighlightCurrentRow: settings.menuHighlightCurrentRow ?? true,
|
|
640
|
-
menuStatuslineFields: [
|
|
696
|
+
menuStatuslineFields: [
|
|
697
|
+
...normalizeStatuslineFields(settings.menuStatuslineFields),
|
|
698
|
+
],
|
|
641
699
|
};
|
|
642
700
|
}
|
|
643
701
|
function dashboardSettingsEqual(left, right) {
|
|
@@ -646,29 +704,51 @@ function dashboardSettingsEqual(left, right) {
|
|
|
646
704
|
left.showForecastReasons === right.showForecastReasons &&
|
|
647
705
|
left.showRecommendations === right.showRecommendations &&
|
|
648
706
|
left.showLiveProbeNotes === right.showLiveProbeNotes &&
|
|
649
|
-
(left.actionAutoReturnMs ?? 2_000) ===
|
|
707
|
+
(left.actionAutoReturnMs ?? 2_000) ===
|
|
708
|
+
(right.actionAutoReturnMs ?? 2_000) &&
|
|
650
709
|
(left.actionPauseOnKey ?? true) === (right.actionPauseOnKey ?? true) &&
|
|
651
|
-
(left.menuAutoFetchLimits ?? true) ===
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
710
|
+
(left.menuAutoFetchLimits ?? true) ===
|
|
711
|
+
(right.menuAutoFetchLimits ?? true) &&
|
|
712
|
+
(left.menuSortEnabled ??
|
|
713
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortEnabled ??
|
|
714
|
+
true) ===
|
|
715
|
+
(right.menuSortEnabled ??
|
|
716
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortEnabled ??
|
|
717
|
+
true) &&
|
|
718
|
+
(left.menuSortMode ??
|
|
719
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
720
|
+
"ready-first") ===
|
|
721
|
+
(right.menuSortMode ??
|
|
722
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
723
|
+
"ready-first") &&
|
|
724
|
+
(left.menuSortPinCurrent ??
|
|
725
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortPinCurrent ??
|
|
726
|
+
false) ===
|
|
727
|
+
(right.menuSortPinCurrent ??
|
|
728
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortPinCurrent ??
|
|
729
|
+
false) &&
|
|
658
730
|
(left.menuSortQuickSwitchVisibleRow ?? true) ===
|
|
659
731
|
(right.menuSortQuickSwitchVisibleRow ?? true) &&
|
|
660
732
|
(left.uiThemePreset ?? "green") === (right.uiThemePreset ?? "green") &&
|
|
661
733
|
(left.uiAccentColor ?? "green") === (right.uiAccentColor ?? "green") &&
|
|
662
|
-
(left.menuShowStatusBadge ?? true) ===
|
|
663
|
-
|
|
734
|
+
(left.menuShowStatusBadge ?? true) ===
|
|
735
|
+
(right.menuShowStatusBadge ?? true) &&
|
|
736
|
+
(left.menuShowCurrentBadge ?? true) ===
|
|
737
|
+
(right.menuShowCurrentBadge ?? true) &&
|
|
664
738
|
(left.menuShowLastUsed ?? true) === (right.menuShowLastUsed ?? true) &&
|
|
665
|
-
(left.menuShowQuotaSummary ?? true) ===
|
|
666
|
-
|
|
667
|
-
(left.
|
|
739
|
+
(left.menuShowQuotaSummary ?? true) ===
|
|
740
|
+
(right.menuShowQuotaSummary ?? true) &&
|
|
741
|
+
(left.menuShowQuotaCooldown ?? true) ===
|
|
742
|
+
(right.menuShowQuotaCooldown ?? true) &&
|
|
743
|
+
(left.menuShowFetchStatus ?? true) ===
|
|
744
|
+
(right.menuShowFetchStatus ?? true) &&
|
|
668
745
|
resolveMenuLayoutMode(left) === resolveMenuLayoutMode(right) &&
|
|
669
|
-
(left.menuQuotaTtlMs ?? 5 * 60_000) ===
|
|
670
|
-
|
|
671
|
-
(left.
|
|
746
|
+
(left.menuQuotaTtlMs ?? 5 * 60_000) ===
|
|
747
|
+
(right.menuQuotaTtlMs ?? 5 * 60_000) &&
|
|
748
|
+
(left.menuFocusStyle ?? "row-invert") ===
|
|
749
|
+
(right.menuFocusStyle ?? "row-invert") &&
|
|
750
|
+
(left.menuHighlightCurrentRow ?? true) ===
|
|
751
|
+
(right.menuHighlightCurrentRow ?? true) &&
|
|
672
752
|
JSON.stringify(normalizeStatuslineFields(left.menuStatuslineFields)) ===
|
|
673
753
|
JSON.stringify(normalizeStatuslineFields(right.menuStatuslineFields)));
|
|
674
754
|
}
|
|
@@ -685,15 +765,18 @@ function cloneBackendPluginConfig(config) {
|
|
|
685
765
|
function backendSettingsSnapshot(config) {
|
|
686
766
|
const snapshot = {};
|
|
687
767
|
for (const option of BACKEND_TOGGLE_OPTIONS) {
|
|
688
|
-
snapshot[option.key] =
|
|
768
|
+
snapshot[option.key] =
|
|
769
|
+
config[option.key] ?? BACKEND_DEFAULTS[option.key] ?? false;
|
|
689
770
|
}
|
|
690
771
|
for (const option of BACKEND_NUMBER_OPTIONS) {
|
|
691
|
-
snapshot[option.key] =
|
|
772
|
+
snapshot[option.key] =
|
|
773
|
+
config[option.key] ?? BACKEND_DEFAULTS[option.key] ?? option.min;
|
|
692
774
|
}
|
|
693
775
|
return snapshot;
|
|
694
776
|
}
|
|
695
777
|
function backendSettingsEqual(left, right) {
|
|
696
|
-
return JSON.stringify(backendSettingsSnapshot(left)) ===
|
|
778
|
+
return (JSON.stringify(backendSettingsSnapshot(left)) ===
|
|
779
|
+
JSON.stringify(backendSettingsSnapshot(right)));
|
|
697
780
|
}
|
|
698
781
|
function formatBackendNumberValue(option, value) {
|
|
699
782
|
if (option.unit === "percent")
|
|
@@ -714,7 +797,9 @@ function clampBackendNumber(option, value) {
|
|
|
714
797
|
function buildBackendSettingsPreview(config, ui, focus = null) {
|
|
715
798
|
const liveSync = config.liveAccountSync ?? BACKEND_DEFAULTS.liveAccountSync ?? true;
|
|
716
799
|
const affinity = config.sessionAffinity ?? BACKEND_DEFAULTS.sessionAffinity ?? true;
|
|
717
|
-
const preemptive = config.preemptiveQuotaEnabled ??
|
|
800
|
+
const preemptive = config.preemptiveQuotaEnabled ??
|
|
801
|
+
BACKEND_DEFAULTS.preemptiveQuotaEnabled ??
|
|
802
|
+
true;
|
|
718
803
|
const threshold5h = config.preemptiveQuotaRemainingPercent5h ??
|
|
719
804
|
BACKEND_DEFAULTS.preemptiveQuotaRemainingPercent5h ??
|
|
720
805
|
5;
|
|
@@ -722,7 +807,9 @@ function buildBackendSettingsPreview(config, ui, focus = null) {
|
|
|
722
807
|
BACKEND_DEFAULTS.preemptiveQuotaRemainingPercent7d ??
|
|
723
808
|
5;
|
|
724
809
|
const fetchTimeout = config.fetchTimeoutMs ?? BACKEND_DEFAULTS.fetchTimeoutMs ?? 60_000;
|
|
725
|
-
const stallTimeout = config.streamStallTimeoutMs ??
|
|
810
|
+
const stallTimeout = config.streamStallTimeoutMs ??
|
|
811
|
+
BACKEND_DEFAULTS.streamStallTimeoutMs ??
|
|
812
|
+
45_000;
|
|
726
813
|
const fetchTimeoutOption = BACKEND_NUMBER_OPTION_BY_KEY.get("fetchTimeoutMs");
|
|
727
814
|
const stallTimeoutOption = BACKEND_NUMBER_OPTION_BY_KEY.get("streamStallTimeoutMs");
|
|
728
815
|
const highlightIfFocused = (key, text) => {
|
|
@@ -781,7 +868,9 @@ function resolveMenuLayoutMode(settings) {
|
|
|
781
868
|
if (settings.menuLayoutMode === "compact-details") {
|
|
782
869
|
return "compact-details";
|
|
783
870
|
}
|
|
784
|
-
return settings.menuShowDetailsForUnselectedRows === true
|
|
871
|
+
return settings.menuShowDetailsForUnselectedRows === true
|
|
872
|
+
? "expanded-rows"
|
|
873
|
+
: "compact-details";
|
|
785
874
|
}
|
|
786
875
|
function formatMenuLayoutMode(mode) {
|
|
787
876
|
return mode === "expanded-rows" ? "Expanded Rows" : "Compact + Details Pane";
|
|
@@ -816,8 +905,19 @@ const __testOnly = {
|
|
|
816
905
|
formatMenuLayoutMode,
|
|
817
906
|
cloneDashboardSettings,
|
|
818
907
|
withQueuedRetry: withQueuedRetryForTests,
|
|
908
|
+
loadExperimentalSyncTarget,
|
|
909
|
+
promptExperimentalSettings,
|
|
819
910
|
persistDashboardSettingsSelection: persistDashboardSettingsSelectionForTests,
|
|
820
911
|
persistBackendConfigSelection: persistBackendConfigSelectionForTests,
|
|
912
|
+
buildAccountListPreview,
|
|
913
|
+
buildSummaryPreviewText,
|
|
914
|
+
normalizeStatuslineFields,
|
|
915
|
+
reorderField,
|
|
916
|
+
promptDashboardDisplaySettings,
|
|
917
|
+
promptStatuslineSettings,
|
|
918
|
+
promptBehaviorSettings,
|
|
919
|
+
promptThemeSettings,
|
|
920
|
+
promptBackendSettings,
|
|
821
921
|
};
|
|
822
922
|
/* c8 ignore start - interactive prompt flows are covered by integration tests */
|
|
823
923
|
async function promptDashboardDisplaySettings(initial) {
|
|
@@ -832,7 +932,9 @@ async function promptDashboardDisplaySettings(initial) {
|
|
|
832
932
|
const optionItems = DASHBOARD_DISPLAY_OPTIONS.map((option, index) => {
|
|
833
933
|
const enabled = draft[option.key] ?? true;
|
|
834
934
|
const label = `${formatDashboardSettingState(enabled)} ${index + 1}. ${option.label}`;
|
|
835
|
-
const color = enabled
|
|
935
|
+
const color = enabled
|
|
936
|
+
? "green"
|
|
937
|
+
: "yellow";
|
|
836
938
|
return {
|
|
837
939
|
label,
|
|
838
940
|
hint: option.description,
|
|
@@ -840,7 +942,9 @@ async function promptDashboardDisplaySettings(initial) {
|
|
|
840
942
|
color,
|
|
841
943
|
};
|
|
842
944
|
});
|
|
843
|
-
const sortMode = draft.menuSortMode ??
|
|
945
|
+
const sortMode = draft.menuSortMode ??
|
|
946
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
947
|
+
"ready-first";
|
|
844
948
|
const sortModeItem = {
|
|
845
949
|
label: `Sort mode: ${formatMenuSortMode(sortMode)}`,
|
|
846
950
|
hint: "Applies when smart sort is enabled.",
|
|
@@ -855,7 +959,11 @@ async function promptDashboardDisplaySettings(initial) {
|
|
|
855
959
|
color: layoutMode === "compact-details" ? "green" : "yellow",
|
|
856
960
|
};
|
|
857
961
|
const items = [
|
|
858
|
-
{
|
|
962
|
+
{
|
|
963
|
+
label: UI_COPY.settings.previewHeading,
|
|
964
|
+
value: { type: "cancel" },
|
|
965
|
+
kind: "heading",
|
|
966
|
+
},
|
|
859
967
|
{
|
|
860
968
|
label: preview.label,
|
|
861
969
|
hint: preview.hint,
|
|
@@ -865,18 +973,36 @@ async function promptDashboardDisplaySettings(initial) {
|
|
|
865
973
|
hideUnavailableSuffix: true,
|
|
866
974
|
},
|
|
867
975
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
868
|
-
{
|
|
976
|
+
{
|
|
977
|
+
label: UI_COPY.settings.displayHeading,
|
|
978
|
+
value: { type: "cancel" },
|
|
979
|
+
kind: "heading",
|
|
980
|
+
},
|
|
869
981
|
...optionItems,
|
|
870
982
|
sortModeItem,
|
|
871
983
|
layoutModeItem,
|
|
872
984
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
873
|
-
{
|
|
874
|
-
|
|
875
|
-
|
|
985
|
+
{
|
|
986
|
+
label: UI_COPY.settings.resetDefault,
|
|
987
|
+
value: { type: "reset" },
|
|
988
|
+
color: "yellow",
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
label: UI_COPY.settings.saveAndBack,
|
|
992
|
+
value: { type: "save" },
|
|
993
|
+
color: "green",
|
|
994
|
+
},
|
|
995
|
+
{
|
|
996
|
+
label: UI_COPY.settings.backNoSave,
|
|
997
|
+
value: { type: "cancel" },
|
|
998
|
+
color: "red",
|
|
999
|
+
},
|
|
876
1000
|
];
|
|
877
1001
|
const initialCursor = items.findIndex((item) => (item.value.type === "toggle" && item.value.key === focusKey) ||
|
|
878
|
-
(item.value.type === "cycle-sort-mode" &&
|
|
879
|
-
|
|
1002
|
+
(item.value.type === "cycle-sort-mode" &&
|
|
1003
|
+
focusKey === "menuSortMode") ||
|
|
1004
|
+
(item.value.type === "cycle-layout-mode" &&
|
|
1005
|
+
focusKey === "menuLayoutMode"));
|
|
880
1006
|
const updateFocusedPreview = (cursor) => {
|
|
881
1007
|
const focusedItem = items[cursor];
|
|
882
1008
|
const focusedKey = focusedItem?.value.type === "toggle"
|
|
@@ -927,7 +1053,9 @@ async function promptDashboardDisplaySettings(initial) {
|
|
|
927
1053
|
if (lower === "l")
|
|
928
1054
|
return { type: "cycle-layout-mode" };
|
|
929
1055
|
const parsed = Number.parseInt(raw, 10);
|
|
930
|
-
if (Number.isFinite(parsed) &&
|
|
1056
|
+
if (Number.isFinite(parsed) &&
|
|
1057
|
+
parsed >= 1 &&
|
|
1058
|
+
parsed <= DASHBOARD_DISPLAY_OPTIONS.length) {
|
|
931
1059
|
const target = DASHBOARD_DISPLAY_OPTIONS[parsed - 1];
|
|
932
1060
|
if (target) {
|
|
933
1061
|
return { type: "toggle", key: target.key };
|
|
@@ -954,23 +1082,27 @@ async function promptDashboardDisplaySettings(initial) {
|
|
|
954
1082
|
continue;
|
|
955
1083
|
}
|
|
956
1084
|
if (result.type === "cycle-sort-mode") {
|
|
957
|
-
const currentMode = draft.menuSortMode ??
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1085
|
+
const currentMode = draft.menuSortMode ??
|
|
1086
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
1087
|
+
"ready-first";
|
|
1088
|
+
const nextMode = currentMode === "ready-first" ? "manual" : "ready-first";
|
|
961
1089
|
draft = {
|
|
962
1090
|
...draft,
|
|
963
1091
|
menuSortMode: nextMode,
|
|
964
1092
|
menuSortEnabled: nextMode === "ready-first"
|
|
965
1093
|
? true
|
|
966
|
-
: (draft.menuSortEnabled ??
|
|
1094
|
+
: (draft.menuSortEnabled ??
|
|
1095
|
+
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortEnabled ??
|
|
1096
|
+
true),
|
|
967
1097
|
};
|
|
968
1098
|
focusKey = "menuSortMode";
|
|
969
1099
|
continue;
|
|
970
1100
|
}
|
|
971
1101
|
if (result.type === "cycle-layout-mode") {
|
|
972
1102
|
const currentLayout = resolveMenuLayoutMode(draft);
|
|
973
|
-
const nextLayout = currentLayout === "compact-details"
|
|
1103
|
+
const nextLayout = currentLayout === "compact-details"
|
|
1104
|
+
? "expanded-rows"
|
|
1105
|
+
: "compact-details";
|
|
974
1106
|
draft = {
|
|
975
1107
|
...draft,
|
|
976
1108
|
menuLayoutMode: nextLayout,
|
|
@@ -987,7 +1119,7 @@ async function promptDashboardDisplaySettings(initial) {
|
|
|
987
1119
|
}
|
|
988
1120
|
}
|
|
989
1121
|
async function configureDashboardDisplaySettings(currentSettings) {
|
|
990
|
-
const current = currentSettings ?? await loadDashboardDisplaySettings();
|
|
1122
|
+
const current = currentSettings ?? (await loadDashboardDisplaySettings());
|
|
991
1123
|
if (!input.isTTY || !output.isTTY) {
|
|
992
1124
|
console.log("Settings require interactive mode.");
|
|
993
1125
|
console.log(`Settings file: ${getDashboardSettingsPath()}`);
|
|
@@ -1047,7 +1179,11 @@ async function promptStatuslineSettings(initial) {
|
|
|
1047
1179
|
};
|
|
1048
1180
|
});
|
|
1049
1181
|
const items = [
|
|
1050
|
-
{
|
|
1182
|
+
{
|
|
1183
|
+
label: UI_COPY.settings.previewHeading,
|
|
1184
|
+
value: { type: "cancel" },
|
|
1185
|
+
kind: "heading",
|
|
1186
|
+
},
|
|
1051
1187
|
{
|
|
1052
1188
|
label: preview.label,
|
|
1053
1189
|
hint: preview.hint,
|
|
@@ -1057,15 +1193,39 @@ async function promptStatuslineSettings(initial) {
|
|
|
1057
1193
|
hideUnavailableSuffix: true,
|
|
1058
1194
|
},
|
|
1059
1195
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1060
|
-
{
|
|
1196
|
+
{
|
|
1197
|
+
label: UI_COPY.settings.displayHeading,
|
|
1198
|
+
value: { type: "cancel" },
|
|
1199
|
+
kind: "heading",
|
|
1200
|
+
},
|
|
1061
1201
|
...optionItems,
|
|
1062
1202
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1063
|
-
{
|
|
1064
|
-
|
|
1203
|
+
{
|
|
1204
|
+
label: UI_COPY.settings.moveUp,
|
|
1205
|
+
value: { type: "move-up", key: focusKey },
|
|
1206
|
+
color: "green",
|
|
1207
|
+
},
|
|
1208
|
+
{
|
|
1209
|
+
label: UI_COPY.settings.moveDown,
|
|
1210
|
+
value: { type: "move-down", key: focusKey },
|
|
1211
|
+
color: "green",
|
|
1212
|
+
},
|
|
1065
1213
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1066
|
-
{
|
|
1067
|
-
|
|
1068
|
-
|
|
1214
|
+
{
|
|
1215
|
+
label: UI_COPY.settings.resetDefault,
|
|
1216
|
+
value: { type: "reset" },
|
|
1217
|
+
color: "yellow",
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
label: UI_COPY.settings.saveAndBack,
|
|
1221
|
+
value: { type: "save" },
|
|
1222
|
+
color: "green",
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
label: UI_COPY.settings.backNoSave,
|
|
1226
|
+
value: { type: "cancel" },
|
|
1227
|
+
color: "red",
|
|
1228
|
+
},
|
|
1069
1229
|
];
|
|
1070
1230
|
const initialCursor = items.findIndex((item) => item.value.type === "toggle" && item.value.key === focusKey);
|
|
1071
1231
|
const updateFocusedPreview = (cursor) => {
|
|
@@ -1106,7 +1266,9 @@ async function promptStatuslineSettings(initial) {
|
|
|
1106
1266
|
if (lower === "]")
|
|
1107
1267
|
return { type: "move-down", key: focusKey };
|
|
1108
1268
|
const parsed = Number.parseInt(raw, 10);
|
|
1109
|
-
if (Number.isFinite(parsed) &&
|
|
1269
|
+
if (Number.isFinite(parsed) &&
|
|
1270
|
+
parsed >= 1 &&
|
|
1271
|
+
parsed <= STATUSLINE_FIELD_OPTIONS.length) {
|
|
1110
1272
|
const target = STATUSLINE_FIELD_OPTIONS[parsed - 1];
|
|
1111
1273
|
if (target) {
|
|
1112
1274
|
return { type: "toggle", key: target.key };
|
|
@@ -1161,7 +1323,7 @@ async function promptStatuslineSettings(initial) {
|
|
|
1161
1323
|
}
|
|
1162
1324
|
}
|
|
1163
1325
|
async function configureStatuslineSettings(currentSettings) {
|
|
1164
|
-
const current = currentSettings ?? await loadDashboardDisplaySettings();
|
|
1326
|
+
const current = currentSettings ?? (await loadDashboardDisplaySettings());
|
|
1165
1327
|
if (!input.isTTY || !output.isTTY) {
|
|
1166
1328
|
console.log("Settings require interactive mode.");
|
|
1167
1329
|
console.log(`Settings file: ${getDashboardSettingsPath()}`);
|
|
@@ -1177,7 +1339,9 @@ async function configureStatuslineSettings(currentSettings) {
|
|
|
1177
1339
|
return merged;
|
|
1178
1340
|
}
|
|
1179
1341
|
function formatDelayLabel(delayMs) {
|
|
1180
|
-
return delayMs <= 0
|
|
1342
|
+
return delayMs <= 0
|
|
1343
|
+
? "Instant return"
|
|
1344
|
+
: `${Math.round(delayMs / 1000)}s auto-return`;
|
|
1181
1345
|
}
|
|
1182
1346
|
async function promptBehaviorSettings(initial) {
|
|
1183
1347
|
if (!input.isTTY || !output.isTTY)
|
|
@@ -1207,9 +1371,15 @@ async function promptBehaviorSettings(initial) {
|
|
|
1207
1371
|
color,
|
|
1208
1372
|
};
|
|
1209
1373
|
});
|
|
1210
|
-
const pauseColor = pauseOnKey
|
|
1374
|
+
const pauseColor = pauseOnKey
|
|
1375
|
+
? "green"
|
|
1376
|
+
: "yellow";
|
|
1211
1377
|
const items = [
|
|
1212
|
-
{
|
|
1378
|
+
{
|
|
1379
|
+
label: UI_COPY.settings.actionTiming,
|
|
1380
|
+
value: { type: "cancel" },
|
|
1381
|
+
kind: "heading",
|
|
1382
|
+
},
|
|
1213
1383
|
...delayItems,
|
|
1214
1384
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1215
1385
|
{
|
|
@@ -1237,9 +1407,21 @@ async function promptBehaviorSettings(initial) {
|
|
|
1237
1407
|
color: "yellow",
|
|
1238
1408
|
},
|
|
1239
1409
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1240
|
-
{
|
|
1241
|
-
|
|
1242
|
-
|
|
1410
|
+
{
|
|
1411
|
+
label: UI_COPY.settings.resetDefault,
|
|
1412
|
+
value: { type: "reset" },
|
|
1413
|
+
color: "yellow",
|
|
1414
|
+
},
|
|
1415
|
+
{
|
|
1416
|
+
label: UI_COPY.settings.saveAndBack,
|
|
1417
|
+
value: { type: "save" },
|
|
1418
|
+
color: "green",
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
label: UI_COPY.settings.backNoSave,
|
|
1422
|
+
value: { type: "cancel" },
|
|
1423
|
+
color: "red",
|
|
1424
|
+
},
|
|
1243
1425
|
];
|
|
1244
1426
|
const initialCursor = items.findIndex((item) => {
|
|
1245
1427
|
const value = item.value;
|
|
@@ -1281,7 +1463,9 @@ async function promptBehaviorSettings(initial) {
|
|
|
1281
1463
|
if (lower === "t")
|
|
1282
1464
|
return { type: "set-menu-quota-ttl", ttlMs: menuQuotaTtlMs };
|
|
1283
1465
|
const parsed = Number.parseInt(raw, 10);
|
|
1284
|
-
if (Number.isFinite(parsed) &&
|
|
1466
|
+
if (Number.isFinite(parsed) &&
|
|
1467
|
+
parsed >= 1 &&
|
|
1468
|
+
parsed <= AUTO_RETURN_OPTIONS_MS.length) {
|
|
1285
1469
|
const delayMs = AUTO_RETURN_OPTIONS_MS[parsed - 1];
|
|
1286
1470
|
if (typeof delayMs === "number")
|
|
1287
1471
|
return { type: "set-delay", delayMs };
|
|
@@ -1327,7 +1511,9 @@ async function promptBehaviorSettings(initial) {
|
|
|
1327
1511
|
const nextIndex = currentIndex < 0
|
|
1328
1512
|
? 0
|
|
1329
1513
|
: (currentIndex + 1) % MENU_QUOTA_TTL_OPTIONS_MS.length;
|
|
1330
|
-
const nextTtl = MENU_QUOTA_TTL_OPTIONS_MS[nextIndex] ??
|
|
1514
|
+
const nextTtl = MENU_QUOTA_TTL_OPTIONS_MS[nextIndex] ??
|
|
1515
|
+
MENU_QUOTA_TTL_OPTIONS_MS[0] ??
|
|
1516
|
+
menuQuotaTtlMs;
|
|
1331
1517
|
draft = {
|
|
1332
1518
|
...draft,
|
|
1333
1519
|
menuQuotaTtlMs: nextTtl,
|
|
@@ -1359,7 +1545,9 @@ async function promptThemeSettings(initial) {
|
|
|
1359
1545
|
const color = palette === candidate ? "green" : "yellow";
|
|
1360
1546
|
return {
|
|
1361
1547
|
label: `${palette === candidate ? "[x]" : "[ ]"} ${index + 1}. ${candidate === "green" ? "Green base" : "Blue base"}`,
|
|
1362
|
-
hint: candidate === "green"
|
|
1548
|
+
hint: candidate === "green"
|
|
1549
|
+
? "High-contrast default."
|
|
1550
|
+
: "Codex-style blue look.",
|
|
1363
1551
|
value: { type: "set-palette", palette: candidate },
|
|
1364
1552
|
color,
|
|
1365
1553
|
};
|
|
@@ -1373,15 +1561,35 @@ async function promptThemeSettings(initial) {
|
|
|
1373
1561
|
};
|
|
1374
1562
|
});
|
|
1375
1563
|
const items = [
|
|
1376
|
-
{
|
|
1564
|
+
{
|
|
1565
|
+
label: UI_COPY.settings.baseTheme,
|
|
1566
|
+
value: { type: "cancel" },
|
|
1567
|
+
kind: "heading",
|
|
1568
|
+
},
|
|
1377
1569
|
...paletteItems,
|
|
1378
1570
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1379
|
-
{
|
|
1571
|
+
{
|
|
1572
|
+
label: UI_COPY.settings.accentColor,
|
|
1573
|
+
value: { type: "cancel" },
|
|
1574
|
+
kind: "heading",
|
|
1575
|
+
},
|
|
1380
1576
|
...accentItems,
|
|
1381
1577
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1382
|
-
{
|
|
1383
|
-
|
|
1384
|
-
|
|
1578
|
+
{
|
|
1579
|
+
label: UI_COPY.settings.resetDefault,
|
|
1580
|
+
value: { type: "reset" },
|
|
1581
|
+
color: "yellow",
|
|
1582
|
+
},
|
|
1583
|
+
{
|
|
1584
|
+
label: UI_COPY.settings.saveAndBack,
|
|
1585
|
+
value: { type: "save" },
|
|
1586
|
+
color: "green",
|
|
1587
|
+
},
|
|
1588
|
+
{
|
|
1589
|
+
label: UI_COPY.settings.backNoSave,
|
|
1590
|
+
value: { type: "cancel" },
|
|
1591
|
+
color: "red",
|
|
1592
|
+
},
|
|
1385
1593
|
];
|
|
1386
1594
|
const initialCursor = items.findIndex((item) => {
|
|
1387
1595
|
const value = item.value;
|
|
@@ -1455,7 +1663,7 @@ function resolveFocusedBackendNumberKey(focus, numberOptions = BACKEND_NUMBER_OP
|
|
|
1455
1663
|
return numberOptions[0]?.key ?? "fetchTimeoutMs";
|
|
1456
1664
|
}
|
|
1457
1665
|
function getBackendCategory(key) {
|
|
1458
|
-
return BACKEND_CATEGORY_OPTIONS.find((category) => category.key === key) ?? null;
|
|
1666
|
+
return (BACKEND_CATEGORY_OPTIONS.find((category) => category.key === key) ?? null);
|
|
1459
1667
|
}
|
|
1460
1668
|
function getBackendCategoryInitialFocus(category) {
|
|
1461
1669
|
const firstToggle = category.toggleKeys[0];
|
|
@@ -1517,7 +1725,11 @@ async function promptBackendCategorySettings(initial, category, initialFocus) {
|
|
|
1517
1725
|
});
|
|
1518
1726
|
const focusedNumberKey = resolveFocusedBackendNumberKey(focusKey, numberOptions);
|
|
1519
1727
|
const items = [
|
|
1520
|
-
{
|
|
1728
|
+
{
|
|
1729
|
+
label: UI_COPY.settings.previewHeading,
|
|
1730
|
+
value: { type: "back" },
|
|
1731
|
+
kind: "heading",
|
|
1732
|
+
},
|
|
1521
1733
|
{
|
|
1522
1734
|
label: preview.label,
|
|
1523
1735
|
hint: preview.hint,
|
|
@@ -1527,10 +1739,18 @@ async function promptBackendCategorySettings(initial, category, initialFocus) {
|
|
|
1527
1739
|
hideUnavailableSuffix: true,
|
|
1528
1740
|
},
|
|
1529
1741
|
{ label: "", value: { type: "back" }, separator: true },
|
|
1530
|
-
{
|
|
1742
|
+
{
|
|
1743
|
+
label: UI_COPY.settings.backendToggleHeading,
|
|
1744
|
+
value: { type: "back" },
|
|
1745
|
+
kind: "heading",
|
|
1746
|
+
},
|
|
1531
1747
|
...toggleItems,
|
|
1532
1748
|
{ label: "", value: { type: "back" }, separator: true },
|
|
1533
|
-
{
|
|
1749
|
+
{
|
|
1750
|
+
label: UI_COPY.settings.backendNumberHeading,
|
|
1751
|
+
value: { type: "back" },
|
|
1752
|
+
kind: "heading",
|
|
1753
|
+
},
|
|
1534
1754
|
...numberItems,
|
|
1535
1755
|
];
|
|
1536
1756
|
if (numberOptions.length > 0) {
|
|
@@ -1547,8 +1767,16 @@ async function promptBackendCategorySettings(initial, category, initialFocus) {
|
|
|
1547
1767
|
});
|
|
1548
1768
|
}
|
|
1549
1769
|
items.push({ label: "", value: { type: "back" }, separator: true });
|
|
1550
|
-
items.push({
|
|
1551
|
-
|
|
1770
|
+
items.push({
|
|
1771
|
+
label: UI_COPY.settings.backendResetCategory,
|
|
1772
|
+
value: { type: "reset-category" },
|
|
1773
|
+
color: "yellow",
|
|
1774
|
+
});
|
|
1775
|
+
items.push({
|
|
1776
|
+
label: UI_COPY.settings.backendBackToCategories,
|
|
1777
|
+
value: { type: "back" },
|
|
1778
|
+
color: "red",
|
|
1779
|
+
});
|
|
1552
1780
|
const initialCursor = items.findIndex((item) => {
|
|
1553
1781
|
if (item.separator || item.disabled || item.kind === "heading")
|
|
1554
1782
|
return false;
|
|
@@ -1568,7 +1796,8 @@ async function promptBackendCategorySettings(initial, category, initialFocus) {
|
|
|
1568
1796
|
initialCursor: initialCursor >= 0 ? initialCursor : undefined,
|
|
1569
1797
|
onCursorChange: ({ cursor }) => {
|
|
1570
1798
|
const focusedItem = items[cursor];
|
|
1571
|
-
if (focusedItem?.value.type === "toggle" ||
|
|
1799
|
+
if (focusedItem?.value.type === "toggle" ||
|
|
1800
|
+
focusedItem?.value.type === "bump") {
|
|
1572
1801
|
focusKey = focusedItem.value.key;
|
|
1573
1802
|
}
|
|
1574
1803
|
},
|
|
@@ -1578,14 +1807,26 @@ async function promptBackendCategorySettings(initial, category, initialFocus) {
|
|
|
1578
1807
|
return { type: "back" };
|
|
1579
1808
|
if (lower === "r")
|
|
1580
1809
|
return { type: "reset-category" };
|
|
1581
|
-
if (numberOptions.length > 0 &&
|
|
1582
|
-
|
|
1810
|
+
if (numberOptions.length > 0 &&
|
|
1811
|
+
(lower === "+" || lower === "=" || lower === "]" || lower === "d")) {
|
|
1812
|
+
return {
|
|
1813
|
+
type: "bump",
|
|
1814
|
+
key: resolveFocusedBackendNumberKey(focusKey, numberOptions),
|
|
1815
|
+
direction: 1,
|
|
1816
|
+
};
|
|
1583
1817
|
}
|
|
1584
|
-
if (numberOptions.length > 0 &&
|
|
1585
|
-
|
|
1818
|
+
if (numberOptions.length > 0 &&
|
|
1819
|
+
(lower === "-" || lower === "[" || lower === "a")) {
|
|
1820
|
+
return {
|
|
1821
|
+
type: "bump",
|
|
1822
|
+
key: resolveFocusedBackendNumberKey(focusKey, numberOptions),
|
|
1823
|
+
direction: -1,
|
|
1824
|
+
};
|
|
1586
1825
|
}
|
|
1587
1826
|
const parsed = Number.parseInt(raw, 10);
|
|
1588
|
-
if (Number.isFinite(parsed) &&
|
|
1827
|
+
if (Number.isFinite(parsed) &&
|
|
1828
|
+
parsed >= 1 &&
|
|
1829
|
+
parsed <= toggleOptions.length) {
|
|
1589
1830
|
const target = toggleOptions[parsed - 1];
|
|
1590
1831
|
if (target)
|
|
1591
1832
|
return { type: "toggle", key: target.key };
|
|
@@ -1643,7 +1884,11 @@ async function promptBackendSettings(initial) {
|
|
|
1643
1884
|
};
|
|
1644
1885
|
});
|
|
1645
1886
|
const items = [
|
|
1646
|
-
{
|
|
1887
|
+
{
|
|
1888
|
+
label: UI_COPY.settings.previewHeading,
|
|
1889
|
+
value: { type: "cancel" },
|
|
1890
|
+
kind: "heading",
|
|
1891
|
+
},
|
|
1647
1892
|
{
|
|
1648
1893
|
label: preview.label,
|
|
1649
1894
|
hint: preview.hint,
|
|
@@ -1653,17 +1898,33 @@ async function promptBackendSettings(initial) {
|
|
|
1653
1898
|
hideUnavailableSuffix: true,
|
|
1654
1899
|
},
|
|
1655
1900
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1656
|
-
{
|
|
1901
|
+
{
|
|
1902
|
+
label: UI_COPY.settings.backendCategoriesHeading,
|
|
1903
|
+
value: { type: "cancel" },
|
|
1904
|
+
kind: "heading",
|
|
1905
|
+
},
|
|
1657
1906
|
...categoryItems,
|
|
1658
1907
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1659
|
-
{
|
|
1660
|
-
|
|
1661
|
-
|
|
1908
|
+
{
|
|
1909
|
+
label: UI_COPY.settings.resetDefault,
|
|
1910
|
+
value: { type: "reset" },
|
|
1911
|
+
color: "yellow",
|
|
1912
|
+
},
|
|
1913
|
+
{
|
|
1914
|
+
label: UI_COPY.settings.saveAndBack,
|
|
1915
|
+
value: { type: "save" },
|
|
1916
|
+
color: "green",
|
|
1917
|
+
},
|
|
1918
|
+
{
|
|
1919
|
+
label: UI_COPY.settings.backNoSave,
|
|
1920
|
+
value: { type: "cancel" },
|
|
1921
|
+
color: "red",
|
|
1922
|
+
},
|
|
1662
1923
|
];
|
|
1663
1924
|
const initialCursor = items.findIndex((item) => {
|
|
1664
1925
|
if (item.separator || item.disabled || item.kind === "heading")
|
|
1665
1926
|
return false;
|
|
1666
|
-
return item.value.type === "open-category" && item.value.key === activeCategory;
|
|
1927
|
+
return (item.value.type === "open-category" && item.value.key === activeCategory);
|
|
1667
1928
|
});
|
|
1668
1929
|
const result = await select(items, {
|
|
1669
1930
|
message: UI_COPY.settings.backendTitle,
|
|
@@ -1688,7 +1949,9 @@ async function promptBackendSettings(initial) {
|
|
|
1688
1949
|
if (lower === "r")
|
|
1689
1950
|
return { type: "reset" };
|
|
1690
1951
|
const parsed = Number.parseInt(raw, 10);
|
|
1691
|
-
if (Number.isFinite(parsed) &&
|
|
1952
|
+
if (Number.isFinite(parsed) &&
|
|
1953
|
+
parsed >= 1 &&
|
|
1954
|
+
parsed <= BACKEND_CATEGORY_OPTIONS.length) {
|
|
1692
1955
|
const target = BACKEND_CATEGORY_OPTIONS[parsed - 1];
|
|
1693
1956
|
if (target)
|
|
1694
1957
|
return { type: "open-category", key: target.key };
|
|
@@ -1703,7 +1966,8 @@ async function promptBackendSettings(initial) {
|
|
|
1703
1966
|
if (result.type === "reset") {
|
|
1704
1967
|
draft = cloneBackendPluginConfig(BACKEND_DEFAULTS);
|
|
1705
1968
|
for (const category of BACKEND_CATEGORY_OPTIONS) {
|
|
1706
|
-
focusByCategory[category.key] =
|
|
1969
|
+
focusByCategory[category.key] =
|
|
1970
|
+
getBackendCategoryInitialFocus(category);
|
|
1707
1971
|
}
|
|
1708
1972
|
activeCategory = BACKEND_CATEGORY_OPTIONS[0]?.key ?? activeCategory;
|
|
1709
1973
|
continue;
|
|
@@ -1717,6 +1981,328 @@ async function promptBackendSettings(initial) {
|
|
|
1717
1981
|
focusByCategory[category.key] = categoryResult.focusKey;
|
|
1718
1982
|
}
|
|
1719
1983
|
}
|
|
1984
|
+
async function loadExperimentalSyncTarget() {
|
|
1985
|
+
const detection = detectOcChatgptMultiAuthTarget();
|
|
1986
|
+
if (detection.kind === "ambiguous") {
|
|
1987
|
+
return { kind: "blocked-ambiguous", detection };
|
|
1988
|
+
}
|
|
1989
|
+
if (detection.kind === "none") {
|
|
1990
|
+
return { kind: "blocked-none", detection };
|
|
1991
|
+
}
|
|
1992
|
+
try {
|
|
1993
|
+
const raw = JSON.parse(await readFileWithRetry(detection.descriptor.accountPath));
|
|
1994
|
+
const normalized = normalizeAccountStorage(raw);
|
|
1995
|
+
if (!normalized) {
|
|
1996
|
+
return {
|
|
1997
|
+
kind: "error",
|
|
1998
|
+
message: "Invalid target account storage format",
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
return { kind: "target", detection, destination: normalized };
|
|
2002
|
+
}
|
|
2003
|
+
catch (error) {
|
|
2004
|
+
const code = error.code;
|
|
2005
|
+
if (code === "ENOENT") {
|
|
2006
|
+
return { kind: "target", detection, destination: null };
|
|
2007
|
+
}
|
|
2008
|
+
return {
|
|
2009
|
+
kind: "error",
|
|
2010
|
+
message: error instanceof Error ? error.message : String(error),
|
|
2011
|
+
};
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
async function promptExperimentalSettings(initialConfig) {
|
|
2015
|
+
if (!input.isTTY || !output.isTTY)
|
|
2016
|
+
return null;
|
|
2017
|
+
const ui = getUiRuntimeOptions();
|
|
2018
|
+
let draft = cloneBackendPluginConfig(initialConfig);
|
|
2019
|
+
while (true) {
|
|
2020
|
+
const action = await select([
|
|
2021
|
+
{
|
|
2022
|
+
label: UI_COPY.settings.experimentalSync,
|
|
2023
|
+
value: { type: "sync" },
|
|
2024
|
+
color: "yellow",
|
|
2025
|
+
},
|
|
2026
|
+
{
|
|
2027
|
+
label: UI_COPY.settings.experimentalBackup,
|
|
2028
|
+
value: { type: "backup" },
|
|
2029
|
+
color: "green",
|
|
2030
|
+
},
|
|
2031
|
+
{
|
|
2032
|
+
label: `${formatDashboardSettingState(draft.proactiveRefreshGuardian ?? false)} ${UI_COPY.settings.experimentalRefreshGuard}`,
|
|
2033
|
+
value: { type: "toggle-refresh-guardian" },
|
|
2034
|
+
color: "yellow",
|
|
2035
|
+
},
|
|
2036
|
+
{
|
|
2037
|
+
label: `${UI_COPY.settings.experimentalRefreshInterval}: ${Math.round((draft.proactiveRefreshIntervalMs ?? 60000) / 60000)} min`,
|
|
2038
|
+
value: { type: "back" },
|
|
2039
|
+
disabled: true,
|
|
2040
|
+
hideUnavailableSuffix: true,
|
|
2041
|
+
color: "green",
|
|
2042
|
+
},
|
|
2043
|
+
{
|
|
2044
|
+
label: UI_COPY.settings.experimentalDecreaseInterval,
|
|
2045
|
+
value: { type: "decrease-refresh-interval" },
|
|
2046
|
+
color: "yellow",
|
|
2047
|
+
},
|
|
2048
|
+
{
|
|
2049
|
+
label: UI_COPY.settings.experimentalIncreaseInterval,
|
|
2050
|
+
value: { type: "increase-refresh-interval" },
|
|
2051
|
+
color: "green",
|
|
2052
|
+
},
|
|
2053
|
+
{
|
|
2054
|
+
label: UI_COPY.settings.saveAndBack,
|
|
2055
|
+
value: { type: "save" },
|
|
2056
|
+
color: "green",
|
|
2057
|
+
},
|
|
2058
|
+
{
|
|
2059
|
+
label: UI_COPY.settings.backNoSave,
|
|
2060
|
+
value: { type: "back" },
|
|
2061
|
+
color: "red",
|
|
2062
|
+
},
|
|
2063
|
+
], {
|
|
2064
|
+
message: UI_COPY.settings.experimentalTitle,
|
|
2065
|
+
subtitle: UI_COPY.settings.experimentalSubtitle,
|
|
2066
|
+
help: UI_COPY.settings.experimentalHelpMenu,
|
|
2067
|
+
clearScreen: true,
|
|
2068
|
+
theme: ui.theme,
|
|
2069
|
+
selectedEmphasis: "minimal",
|
|
2070
|
+
onInput: (raw) => raw.toLowerCase() === "q" ? { type: "back" } : undefined,
|
|
2071
|
+
});
|
|
2072
|
+
if (!action || action.type === "back")
|
|
2073
|
+
return null;
|
|
2074
|
+
if (action.type === "save")
|
|
2075
|
+
return draft;
|
|
2076
|
+
if (action.type === "toggle-refresh-guardian") {
|
|
2077
|
+
draft = {
|
|
2078
|
+
...draft,
|
|
2079
|
+
proactiveRefreshGuardian: !(draft.proactiveRefreshGuardian ?? false),
|
|
2080
|
+
};
|
|
2081
|
+
continue;
|
|
2082
|
+
}
|
|
2083
|
+
if (action.type === "decrease-refresh-interval") {
|
|
2084
|
+
draft = {
|
|
2085
|
+
...draft,
|
|
2086
|
+
proactiveRefreshIntervalMs: Math.max(60_000, (draft.proactiveRefreshIntervalMs ?? 60000) - 60000),
|
|
2087
|
+
};
|
|
2088
|
+
continue;
|
|
2089
|
+
}
|
|
2090
|
+
if (action.type === "increase-refresh-interval") {
|
|
2091
|
+
draft = {
|
|
2092
|
+
...draft,
|
|
2093
|
+
proactiveRefreshIntervalMs: Math.min(600000, (draft.proactiveRefreshIntervalMs ?? 60000) + 60000),
|
|
2094
|
+
};
|
|
2095
|
+
continue;
|
|
2096
|
+
}
|
|
2097
|
+
if (action.type === "backup") {
|
|
2098
|
+
const prompt = createInterface({ input, output });
|
|
2099
|
+
try {
|
|
2100
|
+
const backupName = (await prompt.question(UI_COPY.settings.experimentalBackupPrompt)).trim();
|
|
2101
|
+
if (!backupName || backupName.toLowerCase() === "q") {
|
|
2102
|
+
continue;
|
|
2103
|
+
}
|
|
2104
|
+
try {
|
|
2105
|
+
const backupResult = await runNamedBackupExport({ name: backupName });
|
|
2106
|
+
const backupLabel = backupResult.kind === "exported"
|
|
2107
|
+
? `Saved backup to ${backupResult.path}`
|
|
2108
|
+
: backupResult.kind === "collision"
|
|
2109
|
+
? `Backup already exists: ${backupResult.path}`
|
|
2110
|
+
: backupResult.error instanceof Error
|
|
2111
|
+
? backupResult.error.message
|
|
2112
|
+
: String(backupResult.error);
|
|
2113
|
+
await select([
|
|
2114
|
+
{
|
|
2115
|
+
label: backupLabel,
|
|
2116
|
+
value: { type: "back" },
|
|
2117
|
+
disabled: true,
|
|
2118
|
+
hideUnavailableSuffix: true,
|
|
2119
|
+
color: backupResult.kind === "exported" ? "green" : "yellow",
|
|
2120
|
+
},
|
|
2121
|
+
{
|
|
2122
|
+
label: UI_COPY.settings.back,
|
|
2123
|
+
value: { type: "back" },
|
|
2124
|
+
color: "red",
|
|
2125
|
+
},
|
|
2126
|
+
], {
|
|
2127
|
+
message: UI_COPY.settings.experimentalTitle,
|
|
2128
|
+
subtitle: UI_COPY.settings.experimentalSubtitle,
|
|
2129
|
+
help: UI_COPY.settings.experimentalHelpStatus,
|
|
2130
|
+
clearScreen: true,
|
|
2131
|
+
theme: ui.theme,
|
|
2132
|
+
selectedEmphasis: "minimal",
|
|
2133
|
+
});
|
|
2134
|
+
}
|
|
2135
|
+
catch (error) {
|
|
2136
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2137
|
+
await select([
|
|
2138
|
+
{
|
|
2139
|
+
label: message,
|
|
2140
|
+
value: { type: "back" },
|
|
2141
|
+
disabled: true,
|
|
2142
|
+
hideUnavailableSuffix: true,
|
|
2143
|
+
color: "yellow",
|
|
2144
|
+
},
|
|
2145
|
+
{
|
|
2146
|
+
label: UI_COPY.settings.back,
|
|
2147
|
+
value: { type: "back" },
|
|
2148
|
+
color: "red",
|
|
2149
|
+
},
|
|
2150
|
+
], {
|
|
2151
|
+
message: UI_COPY.settings.experimentalTitle,
|
|
2152
|
+
subtitle: UI_COPY.settings.experimentalSubtitle,
|
|
2153
|
+
help: UI_COPY.settings.experimentalHelpStatus,
|
|
2154
|
+
clearScreen: true,
|
|
2155
|
+
theme: ui.theme,
|
|
2156
|
+
selectedEmphasis: "minimal",
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
finally {
|
|
2161
|
+
prompt.close();
|
|
2162
|
+
}
|
|
2163
|
+
continue;
|
|
2164
|
+
}
|
|
2165
|
+
const source = await loadAccounts();
|
|
2166
|
+
const targetState = await loadExperimentalSyncTarget();
|
|
2167
|
+
if (targetState.kind === "error") {
|
|
2168
|
+
await select([
|
|
2169
|
+
{
|
|
2170
|
+
label: targetState.message,
|
|
2171
|
+
value: { type: "back" },
|
|
2172
|
+
disabled: true,
|
|
2173
|
+
hideUnavailableSuffix: true,
|
|
2174
|
+
color: "yellow",
|
|
2175
|
+
},
|
|
2176
|
+
{
|
|
2177
|
+
label: UI_COPY.settings.back,
|
|
2178
|
+
value: { type: "back" },
|
|
2179
|
+
color: "red",
|
|
2180
|
+
},
|
|
2181
|
+
], {
|
|
2182
|
+
message: UI_COPY.settings.experimentalTitle,
|
|
2183
|
+
subtitle: UI_COPY.settings.experimentalSubtitle,
|
|
2184
|
+
help: UI_COPY.settings.experimentalHelpStatus,
|
|
2185
|
+
clearScreen: true,
|
|
2186
|
+
theme: ui.theme,
|
|
2187
|
+
selectedEmphasis: "minimal",
|
|
2188
|
+
});
|
|
2189
|
+
continue;
|
|
2190
|
+
}
|
|
2191
|
+
const plan = await planOcChatgptSync({
|
|
2192
|
+
source,
|
|
2193
|
+
destination: targetState.kind === "target" ? targetState.destination : null,
|
|
2194
|
+
dependencies: targetState.kind === "target"
|
|
2195
|
+
? { detectTarget: () => targetState.detection }
|
|
2196
|
+
: undefined,
|
|
2197
|
+
});
|
|
2198
|
+
if (plan.kind !== "ready") {
|
|
2199
|
+
await select([
|
|
2200
|
+
{
|
|
2201
|
+
label: plan.kind === "blocked-ambiguous"
|
|
2202
|
+
? `Sync blocked: ${plan.detection.reason}`
|
|
2203
|
+
: `Sync unavailable: ${plan.detection.reason}`,
|
|
2204
|
+
value: { type: "back" },
|
|
2205
|
+
disabled: true,
|
|
2206
|
+
hideUnavailableSuffix: true,
|
|
2207
|
+
color: "yellow",
|
|
2208
|
+
},
|
|
2209
|
+
{
|
|
2210
|
+
label: UI_COPY.settings.back,
|
|
2211
|
+
value: { type: "back" },
|
|
2212
|
+
color: "red",
|
|
2213
|
+
},
|
|
2214
|
+
], {
|
|
2215
|
+
message: UI_COPY.settings.experimentalTitle,
|
|
2216
|
+
subtitle: UI_COPY.settings.experimentalSubtitle,
|
|
2217
|
+
help: UI_COPY.settings.experimentalHelpStatus,
|
|
2218
|
+
clearScreen: true,
|
|
2219
|
+
theme: ui.theme,
|
|
2220
|
+
selectedEmphasis: "minimal",
|
|
2221
|
+
});
|
|
2222
|
+
continue;
|
|
2223
|
+
}
|
|
2224
|
+
const review = await select([
|
|
2225
|
+
{
|
|
2226
|
+
label: `Preview: add ${plan.preview.toAdd.length} | update ${plan.preview.toUpdate.length} | skip ${plan.preview.toSkip.length}`,
|
|
2227
|
+
value: { type: "back" },
|
|
2228
|
+
disabled: true,
|
|
2229
|
+
hideUnavailableSuffix: true,
|
|
2230
|
+
color: "green",
|
|
2231
|
+
},
|
|
2232
|
+
{
|
|
2233
|
+
label: `Preserve destination-only: ${plan.preview.unchangedDestinationOnly.length}`,
|
|
2234
|
+
value: { type: "back" },
|
|
2235
|
+
disabled: true,
|
|
2236
|
+
hideUnavailableSuffix: true,
|
|
2237
|
+
color: "green",
|
|
2238
|
+
},
|
|
2239
|
+
{
|
|
2240
|
+
label: `Active selection: ${plan.preview.activeSelectionBehavior}`,
|
|
2241
|
+
value: { type: "back" },
|
|
2242
|
+
disabled: true,
|
|
2243
|
+
hideUnavailableSuffix: true,
|
|
2244
|
+
color: "green",
|
|
2245
|
+
},
|
|
2246
|
+
{
|
|
2247
|
+
label: UI_COPY.settings.experimentalApplySync,
|
|
2248
|
+
value: { type: "apply" },
|
|
2249
|
+
color: "green",
|
|
2250
|
+
},
|
|
2251
|
+
{
|
|
2252
|
+
label: UI_COPY.settings.backNoSave,
|
|
2253
|
+
value: { type: "back" },
|
|
2254
|
+
color: "red",
|
|
2255
|
+
},
|
|
2256
|
+
], {
|
|
2257
|
+
message: UI_COPY.settings.experimentalTitle,
|
|
2258
|
+
subtitle: UI_COPY.settings.experimentalSubtitle,
|
|
2259
|
+
help: UI_COPY.settings.experimentalHelpStatus,
|
|
2260
|
+
clearScreen: true,
|
|
2261
|
+
theme: ui.theme,
|
|
2262
|
+
selectedEmphasis: "minimal",
|
|
2263
|
+
onInput: (raw) => {
|
|
2264
|
+
const lower = raw.toLowerCase();
|
|
2265
|
+
if (lower === "q")
|
|
2266
|
+
return { type: "back" };
|
|
2267
|
+
if (lower === "a")
|
|
2268
|
+
return { type: "apply" };
|
|
2269
|
+
return undefined;
|
|
2270
|
+
},
|
|
2271
|
+
});
|
|
2272
|
+
if (!review || review.type === "back")
|
|
2273
|
+
continue;
|
|
2274
|
+
const applied = await applyOcChatgptSync({
|
|
2275
|
+
source,
|
|
2276
|
+
destination: targetState.kind === "target" ? targetState.destination : undefined,
|
|
2277
|
+
dependencies: targetState.kind === "target"
|
|
2278
|
+
? { detectTarget: () => targetState.detection }
|
|
2279
|
+
: undefined,
|
|
2280
|
+
});
|
|
2281
|
+
await select([
|
|
2282
|
+
{
|
|
2283
|
+
label: applied.kind === "applied"
|
|
2284
|
+
? `Applied sync to ${applied.target.accountPath}`
|
|
2285
|
+
: applied.kind === "error"
|
|
2286
|
+
? applied.error instanceof Error
|
|
2287
|
+
? applied.error.message
|
|
2288
|
+
: String(applied.error)
|
|
2289
|
+
: "Sync did not apply",
|
|
2290
|
+
value: { type: "back" },
|
|
2291
|
+
disabled: true,
|
|
2292
|
+
hideUnavailableSuffix: true,
|
|
2293
|
+
color: applied.kind === "applied" ? "green" : "yellow",
|
|
2294
|
+
},
|
|
2295
|
+
{ label: UI_COPY.settings.back, value: { type: "back" }, color: "red" },
|
|
2296
|
+
], {
|
|
2297
|
+
message: UI_COPY.settings.experimentalTitle,
|
|
2298
|
+
subtitle: UI_COPY.settings.experimentalSubtitle,
|
|
2299
|
+
help: UI_COPY.settings.experimentalHelpStatus,
|
|
2300
|
+
clearScreen: true,
|
|
2301
|
+
theme: ui.theme,
|
|
2302
|
+
selectedEmphasis: "minimal",
|
|
2303
|
+
});
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
1720
2306
|
async function configureBackendSettings(currentConfig) {
|
|
1721
2307
|
const current = cloneBackendPluginConfig(currentConfig ?? loadPluginConfig());
|
|
1722
2308
|
if (!input.isTTY || !output.isTTY) {
|
|
@@ -1735,16 +2321,49 @@ async function promptSettingsHub(initialFocus = "account-list") {
|
|
|
1735
2321
|
return null;
|
|
1736
2322
|
const ui = getUiRuntimeOptions();
|
|
1737
2323
|
const items = [
|
|
1738
|
-
{
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
2324
|
+
{
|
|
2325
|
+
label: UI_COPY.settings.sectionTitle,
|
|
2326
|
+
value: { type: "back" },
|
|
2327
|
+
kind: "heading",
|
|
2328
|
+
},
|
|
2329
|
+
{
|
|
2330
|
+
label: UI_COPY.settings.accountList,
|
|
2331
|
+
value: { type: "account-list" },
|
|
2332
|
+
color: "green",
|
|
2333
|
+
},
|
|
2334
|
+
{
|
|
2335
|
+
label: UI_COPY.settings.summaryFields,
|
|
2336
|
+
value: { type: "summary-fields" },
|
|
2337
|
+
color: "green",
|
|
2338
|
+
},
|
|
2339
|
+
{
|
|
2340
|
+
label: UI_COPY.settings.behavior,
|
|
2341
|
+
value: { type: "behavior" },
|
|
2342
|
+
color: "green",
|
|
2343
|
+
},
|
|
1742
2344
|
{ label: UI_COPY.settings.theme, value: { type: "theme" }, color: "green" },
|
|
1743
2345
|
{ label: "", value: { type: "back" }, separator: true },
|
|
1744
|
-
{
|
|
1745
|
-
|
|
2346
|
+
{
|
|
2347
|
+
label: UI_COPY.settings.advancedTitle,
|
|
2348
|
+
value: { type: "back" },
|
|
2349
|
+
kind: "heading",
|
|
2350
|
+
},
|
|
2351
|
+
{
|
|
2352
|
+
label: UI_COPY.settings.experimental,
|
|
2353
|
+
value: { type: "experimental" },
|
|
2354
|
+
color: "yellow",
|
|
2355
|
+
},
|
|
2356
|
+
{
|
|
2357
|
+
label: UI_COPY.settings.backend,
|
|
2358
|
+
value: { type: "backend" },
|
|
2359
|
+
color: "green",
|
|
2360
|
+
},
|
|
1746
2361
|
{ label: "", value: { type: "back" }, separator: true },
|
|
1747
|
-
{
|
|
2362
|
+
{
|
|
2363
|
+
label: UI_COPY.settings.exitTitle,
|
|
2364
|
+
value: { type: "back" },
|
|
2365
|
+
kind: "heading",
|
|
2366
|
+
},
|
|
1748
2367
|
{ label: UI_COPY.settings.back, value: { type: "back" }, color: "red" },
|
|
1749
2368
|
];
|
|
1750
2369
|
const initialCursor = items.findIndex((item) => {
|
|
@@ -1770,7 +2389,7 @@ async function promptSettingsHub(initialFocus = "account-list") {
|
|
|
1770
2389
|
}
|
|
1771
2390
|
/* c8 ignore stop */
|
|
1772
2391
|
async function configureUnifiedSettings(initialSettings) {
|
|
1773
|
-
let current = cloneDashboardSettings(initialSettings ?? await loadDashboardDisplaySettings());
|
|
2392
|
+
let current = cloneDashboardSettings(initialSettings ?? (await loadDashboardDisplaySettings()));
|
|
1774
2393
|
let backendConfig = cloneBackendPluginConfig(loadPluginConfig());
|
|
1775
2394
|
applyUiThemeFromDashboardSettings(current);
|
|
1776
2395
|
let hubFocus = "account-list";
|
|
@@ -1803,10 +2422,20 @@ async function configureUnifiedSettings(initialSettings) {
|
|
|
1803
2422
|
}
|
|
1804
2423
|
continue;
|
|
1805
2424
|
}
|
|
2425
|
+
if (action.type === "experimental") {
|
|
2426
|
+
const selected = await promptExperimentalSettings(backendConfig);
|
|
2427
|
+
if (selected && !backendSettingsEqual(backendConfig, selected)) {
|
|
2428
|
+
backendConfig = await persistBackendConfigSelection(selected, "experimental");
|
|
2429
|
+
}
|
|
2430
|
+
else if (selected) {
|
|
2431
|
+
backendConfig = selected;
|
|
2432
|
+
}
|
|
2433
|
+
continue;
|
|
2434
|
+
}
|
|
1806
2435
|
if (action.type === "backend") {
|
|
1807
2436
|
backendConfig = await configureBackendSettings(backendConfig);
|
|
1808
2437
|
}
|
|
1809
2438
|
}
|
|
1810
2439
|
}
|
|
1811
|
-
export { configureUnifiedSettings, applyUiThemeFromDashboardSettings, resolveMenuLayoutMode, __testOnly };
|
|
2440
|
+
export { configureUnifiedSettings, applyUiThemeFromDashboardSettings, resolveMenuLayoutMode, __testOnly, };
|
|
1812
2441
|
//# sourceMappingURL=settings-hub.js.map
|