codex-multi-auth 1.2.0 → 1.2.2
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 +49 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +929 -1712
- package/dist/index.js.map +1 -1
- package/dist/lib/accounts.d.ts +10 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +312 -69
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/auth/index.d.ts +2 -0
- package/dist/lib/auth/index.d.ts.map +1 -0
- package/dist/lib/auth/index.js +2 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/circuit-breaker.d.ts +4 -0
- package/dist/lib/circuit-breaker.d.ts.map +1 -1
- package/dist/lib/circuit-breaker.js +33 -1
- package/dist/lib/circuit-breaker.js.map +1 -1
- package/dist/lib/codex-cli/index.d.ts +5 -0
- package/dist/lib/codex-cli/index.d.ts.map +1 -0
- package/dist/lib/codex-cli/index.js +5 -0
- package/dist/lib/codex-cli/index.js.map +1 -0
- package/dist/lib/codex-manager/auth-commands.d.ts +72 -0
- package/dist/lib/codex-manager/auth-commands.d.ts.map +1 -0
- package/dist/lib/codex-manager/auth-commands.js +643 -0
- package/dist/lib/codex-manager/auth-commands.js.map +1 -0
- package/dist/lib/codex-manager/backend-category-entry.d.ts +103 -0
- package/dist/lib/codex-manager/backend-category-entry.d.ts.map +1 -0
- package/dist/lib/codex-manager/backend-category-entry.js +23 -0
- package/dist/lib/codex-manager/backend-category-entry.js.map +1 -0
- package/dist/lib/codex-manager/backend-category-helpers.d.ts +10 -0
- package/dist/lib/codex-manager/backend-category-helpers.d.ts.map +1 -0
- package/dist/lib/codex-manager/backend-category-helpers.js +29 -0
- package/dist/lib/codex-manager/backend-category-helpers.js.map +1 -0
- package/dist/lib/codex-manager/backend-category-prompt.d.ts +55 -0
- package/dist/lib/codex-manager/backend-category-prompt.d.ts.map +1 -0
- package/dist/lib/codex-manager/backend-category-prompt.js +178 -0
- package/dist/lib/codex-manager/backend-category-prompt.js.map +1 -0
- package/dist/lib/codex-manager/backend-settings-controller.d.ts +11 -0
- package/dist/lib/codex-manager/backend-settings-controller.d.ts.map +1 -0
- package/dist/lib/codex-manager/backend-settings-controller.js +14 -0
- package/dist/lib/codex-manager/backend-settings-controller.js.map +1 -0
- package/dist/lib/codex-manager/backend-settings-entry.d.ts +20 -0
- package/dist/lib/codex-manager/backend-settings-entry.d.ts.map +1 -0
- package/dist/lib/codex-manager/backend-settings-entry.js +12 -0
- package/dist/lib/codex-manager/backend-settings-entry.js.map +1 -0
- package/dist/lib/codex-manager/backend-settings-helpers.d.ts +16 -0
- package/dist/lib/codex-manager/backend-settings-helpers.d.ts.map +1 -0
- package/dist/lib/codex-manager/backend-settings-helpers.js +102 -0
- package/dist/lib/codex-manager/backend-settings-helpers.js.map +1 -0
- package/dist/lib/codex-manager/backend-settings-prompt.d.ts +49 -0
- package/dist/lib/codex-manager/backend-settings-prompt.d.ts.map +1 -0
- package/dist/lib/codex-manager/backend-settings-prompt.js +121 -0
- package/dist/lib/codex-manager/backend-settings-prompt.js.map +1 -0
- package/dist/lib/codex-manager/backend-settings-schema.d.ts +55 -0
- package/dist/lib/codex-manager/backend-settings-schema.d.ts.map +1 -0
- package/dist/lib/codex-manager/backend-settings-schema.js +264 -0
- package/dist/lib/codex-manager/backend-settings-schema.js.map +1 -0
- package/dist/lib/codex-manager/behavior-settings-panel.d.ts +33 -0
- package/dist/lib/codex-manager/behavior-settings-panel.d.ts.map +1 -0
- package/dist/lib/codex-manager/behavior-settings-panel.js +180 -0
- package/dist/lib/codex-manager/behavior-settings-panel.js.map +1 -0
- package/dist/lib/codex-manager/commands/best.d.ts +81 -0
- package/dist/lib/codex-manager/commands/best.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/best.js +223 -0
- package/dist/lib/codex-manager/commands/best.js.map +1 -0
- package/dist/lib/codex-manager/commands/check.d.ts +7 -0
- package/dist/lib/codex-manager/commands/check.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/check.js +5 -0
- package/dist/lib/codex-manager/commands/check.js.map +1 -0
- package/dist/lib/codex-manager/commands/config-explain.d.ts +7 -0
- package/dist/lib/codex-manager/commands/config-explain.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/config-explain.js +31 -0
- package/dist/lib/codex-manager/commands/config-explain.js.map +1 -0
- package/dist/lib/codex-manager/commands/debug-bundle.d.ts +28 -0
- package/dist/lib/codex-manager/commands/debug-bundle.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/debug-bundle.js +62 -0
- package/dist/lib/codex-manager/commands/debug-bundle.js.map +1 -0
- package/dist/lib/codex-manager/commands/doctor.d.ts +85 -0
- package/dist/lib/codex-manager/commands/doctor.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/doctor.js +424 -0
- package/dist/lib/codex-manager/commands/doctor.js.map +1 -0
- package/dist/lib/codex-manager/commands/fix.d.ts +92 -0
- package/dist/lib/codex-manager/commands/fix.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/fix.js +347 -0
- package/dist/lib/codex-manager/commands/fix.js.map +1 -0
- package/dist/lib/codex-manager/commands/forecast.d.ts +71 -0
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/forecast.js +371 -0
- package/dist/lib/codex-manager/commands/forecast.js.map +1 -0
- package/dist/lib/codex-manager/commands/init-config.d.ts +15 -0
- package/dist/lib/codex-manager/commands/init-config.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/init-config.js +95 -0
- package/dist/lib/codex-manager/commands/init-config.js.map +1 -0
- package/dist/lib/codex-manager/commands/report.d.ts +25 -0
- package/dist/lib/codex-manager/commands/report.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/report.js +399 -0
- package/dist/lib/codex-manager/commands/report.js.map +1 -0
- package/dist/lib/codex-manager/commands/status.d.ts +23 -0
- package/dist/lib/codex-manager/commands/status.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/status.js +50 -0
- package/dist/lib/codex-manager/commands/status.js.map +1 -0
- package/dist/lib/codex-manager/commands/switch.d.ts +22 -0
- package/dist/lib/codex-manager/commands/switch.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/switch.js +41 -0
- package/dist/lib/codex-manager/commands/switch.js.map +1 -0
- package/dist/lib/codex-manager/commands/verify-flagged.d.ts +69 -0
- package/dist/lib/codex-manager/commands/verify-flagged.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/verify-flagged.js +251 -0
- package/dist/lib/codex-manager/commands/verify-flagged.js.map +1 -0
- package/dist/lib/codex-manager/dashboard-display-panel.d.ts +40 -0
- package/dist/lib/codex-manager/dashboard-display-panel.d.ts.map +1 -0
- package/dist/lib/codex-manager/dashboard-display-panel.js +187 -0
- package/dist/lib/codex-manager/dashboard-display-panel.js.map +1 -0
- package/dist/lib/codex-manager/dashboard-formatters.d.ts +6 -0
- package/dist/lib/codex-manager/dashboard-formatters.d.ts.map +1 -0
- package/dist/lib/codex-manager/dashboard-formatters.js +19 -0
- package/dist/lib/codex-manager/dashboard-formatters.js.map +1 -0
- package/dist/lib/codex-manager/dashboard-settings-controller.d.ts +12 -0
- package/dist/lib/codex-manager/dashboard-settings-controller.d.ts.map +1 -0
- package/dist/lib/codex-manager/dashboard-settings-controller.js +17 -0
- package/dist/lib/codex-manager/dashboard-settings-controller.js.map +1 -0
- package/dist/lib/codex-manager/dashboard-settings-data.d.ts +10 -0
- package/dist/lib/codex-manager/dashboard-settings-data.d.ts.map +1 -0
- package/dist/lib/codex-manager/dashboard-settings-data.js +95 -0
- package/dist/lib/codex-manager/dashboard-settings-data.js.map +1 -0
- package/dist/lib/codex-manager/dashboard-settings-entry.d.ts +22 -0
- package/dist/lib/codex-manager/dashboard-settings-entry.d.ts.map +1 -0
- package/dist/lib/codex-manager/dashboard-settings-entry.js +13 -0
- package/dist/lib/codex-manager/dashboard-settings-entry.js.map +1 -0
- package/dist/lib/codex-manager/experimental-settings-entry.d.ts +7 -0
- package/dist/lib/codex-manager/experimental-settings-entry.d.ts.map +1 -0
- package/dist/lib/codex-manager/experimental-settings-entry.js +30 -0
- package/dist/lib/codex-manager/experimental-settings-entry.js.map +1 -0
- package/dist/lib/codex-manager/experimental-settings-prompt.d.ts +66 -0
- package/dist/lib/codex-manager/experimental-settings-prompt.d.ts.map +1 -0
- package/dist/lib/codex-manager/experimental-settings-prompt.js +221 -0
- package/dist/lib/codex-manager/experimental-settings-prompt.js.map +1 -0
- package/dist/lib/codex-manager/experimental-settings-schema.d.ts +23 -0
- package/dist/lib/codex-manager/experimental-settings-schema.d.ts.map +1 -0
- package/dist/lib/codex-manager/experimental-settings-schema.js +34 -0
- package/dist/lib/codex-manager/experimental-settings-schema.js.map +1 -0
- package/dist/lib/codex-manager/experimental-sync-target-entry.d.ts +30 -0
- package/dist/lib/codex-manager/experimental-sync-target-entry.d.ts.map +1 -0
- package/dist/lib/codex-manager/experimental-sync-target-entry.js +16 -0
- package/dist/lib/codex-manager/experimental-sync-target-entry.js.map +1 -0
- package/dist/lib/codex-manager/experimental-sync-target.d.ts +23 -0
- package/dist/lib/codex-manager/experimental-sync-target.d.ts.map +1 -0
- package/dist/lib/codex-manager/experimental-sync-target.js +39 -0
- package/dist/lib/codex-manager/experimental-sync-target.js.map +1 -0
- package/dist/lib/codex-manager/forecast-report-commands.d.ts +54 -0
- package/dist/lib/codex-manager/forecast-report-commands.d.ts.map +1 -0
- package/dist/lib/codex-manager/forecast-report-commands.js +443 -0
- package/dist/lib/codex-manager/forecast-report-commands.js.map +1 -0
- package/dist/lib/codex-manager/help.d.ts +36 -0
- package/dist/lib/codex-manager/help.d.ts.map +1 -0
- package/dist/lib/codex-manager/help.js +125 -0
- package/dist/lib/codex-manager/help.js.map +1 -0
- package/dist/lib/codex-manager/repair-commands.d.ts +70 -0
- package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -0
- package/dist/lib/codex-manager/repair-commands.js +1671 -0
- package/dist/lib/codex-manager/repair-commands.js.map +1 -0
- package/dist/lib/codex-manager/settings-hub-entry.d.ts +30 -0
- package/dist/lib/codex-manager/settings-hub-entry.d.ts.map +1 -0
- package/dist/lib/codex-manager/settings-hub-entry.js +11 -0
- package/dist/lib/codex-manager/settings-hub-entry.js.map +1 -0
- package/dist/lib/codex-manager/settings-hub-menu.d.ts +30 -0
- package/dist/lib/codex-manager/settings-hub-menu.d.ts.map +1 -0
- package/dist/lib/codex-manager/settings-hub-menu.js +37 -0
- package/dist/lib/codex-manager/settings-hub-menu.js.map +1 -0
- package/dist/lib/codex-manager/settings-hub-prompt.d.ts +25 -0
- package/dist/lib/codex-manager/settings-hub-prompt.d.ts.map +1 -0
- package/dist/lib/codex-manager/settings-hub-prompt.js +23 -0
- package/dist/lib/codex-manager/settings-hub-prompt.js.map +1 -0
- package/dist/lib/codex-manager/settings-hub.d.ts +10 -29
- package/dist/lib/codex-manager/settings-hub.d.ts.map +1 -1
- package/dist/lib/codex-manager/settings-hub.js +260 -2168
- package/dist/lib/codex-manager/settings-hub.js.map +1 -1
- package/dist/lib/codex-manager/settings-panels.d.ts +56 -0
- package/dist/lib/codex-manager/settings-panels.d.ts.map +1 -0
- package/dist/lib/codex-manager/settings-panels.js +73 -0
- package/dist/lib/codex-manager/settings-panels.js.map +1 -0
- package/dist/lib/codex-manager/settings-persist-utils.d.ts +9 -0
- package/dist/lib/codex-manager/settings-persist-utils.d.ts.map +1 -0
- package/dist/lib/codex-manager/settings-persist-utils.js +33 -0
- package/dist/lib/codex-manager/settings-persist-utils.js.map +1 -0
- package/dist/lib/codex-manager/settings-preview.d.ts +12 -0
- package/dist/lib/codex-manager/settings-preview.d.ts.map +1 -0
- package/dist/lib/codex-manager/settings-preview.js +118 -0
- package/dist/lib/codex-manager/settings-preview.js.map +1 -0
- package/dist/lib/codex-manager/settings-write-queue.d.ts +14 -0
- package/dist/lib/codex-manager/settings-write-queue.d.ts.map +1 -0
- package/dist/lib/codex-manager/settings-write-queue.js +88 -0
- package/dist/lib/codex-manager/settings-write-queue.js.map +1 -0
- package/dist/lib/codex-manager/statusline-order.d.ts +3 -0
- package/dist/lib/codex-manager/statusline-order.d.ts.map +1 -0
- package/dist/lib/codex-manager/statusline-order.js +17 -0
- package/dist/lib/codex-manager/statusline-order.js.map +1 -0
- package/dist/lib/codex-manager/statusline-settings-panel.d.ts +40 -0
- package/dist/lib/codex-manager/statusline-settings-panel.d.ts.map +1 -0
- package/dist/lib/codex-manager/statusline-settings-panel.js +167 -0
- package/dist/lib/codex-manager/statusline-settings-panel.js.map +1 -0
- package/dist/lib/codex-manager/theme-settings-panel.d.ts +26 -0
- package/dist/lib/codex-manager/theme-settings-panel.d.ts.map +1 -0
- package/dist/lib/codex-manager/theme-settings-panel.js +131 -0
- package/dist/lib/codex-manager/theme-settings-panel.js.map +1 -0
- package/dist/lib/codex-manager/unified-settings-controller.d.ts +27 -0
- package/dist/lib/codex-manager/unified-settings-controller.d.ts.map +1 -0
- package/dist/lib/codex-manager/unified-settings-controller.js +50 -0
- package/dist/lib/codex-manager/unified-settings-controller.js.map +1 -0
- package/dist/lib/codex-manager/unified-settings-entry.d.ts +6 -0
- package/dist/lib/codex-manager/unified-settings-entry.d.ts.map +1 -0
- package/dist/lib/codex-manager/unified-settings-entry.js +23 -0
- package/dist/lib/codex-manager/unified-settings-entry.js.map +1 -0
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +441 -2199
- package/dist/lib/codex-manager.js.map +1 -1
- package/dist/lib/config.d.ts +38 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +371 -9
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/errors.d.ts +9 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +13 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/forecast.d.ts +17 -0
- package/dist/lib/forecast.d.ts.map +1 -1
- package/dist/lib/forecast.js +33 -6
- package/dist/lib/forecast.js.map +1 -1
- package/dist/lib/health.d.ts +1 -0
- package/dist/lib/health.d.ts.map +1 -1
- package/dist/lib/health.js +6 -2
- package/dist/lib/health.js.map +1 -1
- package/dist/lib/named-backup-export.js +2 -2
- package/dist/lib/named-backup-export.js.map +1 -1
- package/dist/lib/parallel-probe.d.ts +1 -1
- package/dist/lib/parallel-probe.d.ts.map +1 -1
- package/dist/lib/parallel-probe.js +5 -2
- package/dist/lib/parallel-probe.js.map +1 -1
- package/dist/lib/proactive-refresh.d.ts +1 -1
- package/dist/lib/proactive-refresh.d.ts.map +1 -1
- package/dist/lib/proactive-refresh.js +14 -5
- package/dist/lib/proactive-refresh.js.map +1 -1
- package/dist/lib/prompts/codex.d.ts +8 -3
- package/dist/lib/prompts/codex.d.ts.map +1 -1
- package/dist/lib/prompts/codex.js +16 -26
- package/dist/lib/prompts/codex.js.map +1 -1
- package/dist/lib/refresh-guardian.d.ts +3 -0
- package/dist/lib/refresh-guardian.d.ts.map +1 -1
- package/dist/lib/refresh-guardian.js +142 -52
- package/dist/lib/refresh-guardian.js.map +1 -1
- package/dist/lib/request/failover-config.d.ts +4 -0
- package/dist/lib/request/failover-config.d.ts.map +1 -0
- package/dist/lib/request/failover-config.js +15 -0
- package/dist/lib/request/failover-config.js.map +1 -0
- package/dist/lib/request/fetch-helpers.d.ts +10 -4
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
- package/dist/lib/request/fetch-helpers.js +77 -21
- package/dist/lib/request/fetch-helpers.js.map +1 -1
- package/dist/lib/request/helpers/model-map.d.ts +49 -12
- package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
- package/dist/lib/request/helpers/model-map.js +303 -108
- package/dist/lib/request/helpers/model-map.js.map +1 -1
- package/dist/lib/request/helpers/tool-utils.d.ts +2 -15
- package/dist/lib/request/helpers/tool-utils.d.ts.map +1 -1
- package/dist/lib/request/helpers/tool-utils.js +40 -27
- package/dist/lib/request/helpers/tool-utils.js.map +1 -1
- package/dist/lib/request/index.d.ts +5 -0
- package/dist/lib/request/index.d.ts.map +1 -0
- package/dist/lib/request/index.js +5 -0
- package/dist/lib/request/index.js.map +1 -0
- package/dist/lib/request/request-init.d.ts +3 -0
- package/dist/lib/request/request-init.d.ts.map +1 -0
- package/dist/lib/request/request-init.js +50 -0
- package/dist/lib/request/request-init.js.map +1 -0
- package/dist/lib/request/request-transformer.d.ts +19 -6
- package/dist/lib/request/request-transformer.d.ts.map +1 -1
- package/dist/lib/request/request-transformer.js +210 -193
- package/dist/lib/request/request-transformer.js.map +1 -1
- package/dist/lib/request/response-compaction.d.ts +20 -0
- package/dist/lib/request/response-compaction.d.ts.map +1 -0
- package/dist/lib/request/response-compaction.js +124 -0
- package/dist/lib/request/response-compaction.js.map +1 -0
- package/dist/lib/request/response-handler.d.ts +2 -0
- package/dist/lib/request/response-handler.d.ts.map +1 -1
- package/dist/lib/request/response-handler.js +567 -11
- package/dist/lib/request/response-handler.js.map +1 -1
- package/dist/lib/request/response-metadata.d.ts +3 -0
- package/dist/lib/request/response-metadata.d.ts.map +1 -0
- package/dist/lib/request/response-metadata.js +61 -0
- package/dist/lib/request/response-metadata.js.map +1 -0
- package/dist/lib/request/wait-utils.d.ts +14 -0
- package/dist/lib/request/wait-utils.d.ts.map +1 -0
- package/dist/lib/request/wait-utils.js +44 -0
- package/dist/lib/request/wait-utils.js.map +1 -0
- package/dist/lib/rotation.d.ts +14 -11
- package/dist/lib/rotation.d.ts.map +1 -1
- package/dist/lib/rotation.js +36 -30
- package/dist/lib/rotation.js.map +1 -1
- package/dist/lib/runtime/account-check-helpers.d.ts +8 -0
- package/dist/lib/runtime/account-check-helpers.d.ts.map +1 -0
- package/dist/lib/runtime/account-check-helpers.js +30 -0
- package/dist/lib/runtime/account-check-helpers.js.map +1 -0
- package/dist/lib/runtime/account-check-types.d.ts +18 -0
- package/dist/lib/runtime/account-check-types.d.ts.map +1 -0
- package/dist/lib/runtime/account-check-types.js +12 -0
- package/dist/lib/runtime/account-check-types.js.map +1 -0
- package/dist/lib/runtime/account-check.d.ts +48 -0
- package/dist/lib/runtime/account-check.d.ts.map +1 -0
- package/dist/lib/runtime/account-check.js +202 -0
- package/dist/lib/runtime/account-check.js.map +1 -0
- package/dist/lib/runtime/account-health-check.d.ts +8 -0
- package/dist/lib/runtime/account-health-check.d.ts.map +1 -0
- package/dist/lib/runtime/account-health-check.js +30 -0
- package/dist/lib/runtime/account-health-check.js.map +1 -0
- package/dist/lib/runtime/account-manager-cache-entry.d.ts +25 -0
- package/dist/lib/runtime/account-manager-cache-entry.d.ts.map +1 -0
- package/dist/lib/runtime/account-manager-cache-entry.js +17 -0
- package/dist/lib/runtime/account-manager-cache-entry.js.map +1 -0
- package/dist/lib/runtime/account-manager-cache.d.ts +25 -0
- package/dist/lib/runtime/account-manager-cache.d.ts.map +1 -0
- package/dist/lib/runtime/account-manager-cache.js +44 -0
- package/dist/lib/runtime/account-manager-cache.js.map +1 -0
- package/dist/lib/runtime/account-pool.d.ts +23 -0
- package/dist/lib/runtime/account-pool.d.ts.map +1 -0
- package/dist/lib/runtime/account-pool.js +138 -0
- package/dist/lib/runtime/account-pool.js.map +1 -0
- package/dist/lib/runtime/account-scope.d.ts +10 -0
- package/dist/lib/runtime/account-scope.d.ts.map +1 -0
- package/dist/lib/runtime/account-scope.js +13 -0
- package/dist/lib/runtime/account-scope.js.map +1 -0
- package/dist/lib/runtime/account-select-event.d.ts +19 -0
- package/dist/lib/runtime/account-select-event.d.ts.map +1 -0
- package/dist/lib/runtime/account-select-event.js +53 -0
- package/dist/lib/runtime/account-select-event.js.map +1 -0
- package/dist/lib/runtime/account-selection.d.ts +28 -0
- package/dist/lib/runtime/account-selection.d.ts.map +1 -0
- package/dist/lib/runtime/account-selection.js +46 -0
- package/dist/lib/runtime/account-selection.js.map +1 -0
- package/dist/lib/runtime/account-state.d.ts +13 -0
- package/dist/lib/runtime/account-state.d.ts.map +1 -0
- package/dist/lib/runtime/account-state.js +38 -0
- package/dist/lib/runtime/account-state.js.map +1 -0
- package/dist/lib/runtime/account-status.d.ts +13 -0
- package/dist/lib/runtime/account-status.d.ts.map +1 -0
- package/dist/lib/runtime/account-status.js +37 -0
- package/dist/lib/runtime/account-status.js.map +1 -0
- package/dist/lib/runtime/account-storage-scope-entry.d.ts +26 -0
- package/dist/lib/runtime/account-storage-scope-entry.d.ts.map +1 -0
- package/dist/lib/runtime/account-storage-scope-entry.js +15 -0
- package/dist/lib/runtime/account-storage-scope-entry.js.map +1 -0
- package/dist/lib/runtime/auth-facade.d.ts +51 -0
- package/dist/lib/runtime/auth-facade.d.ts.map +1 -0
- package/dist/lib/runtime/auth-facade.js +48 -0
- package/dist/lib/runtime/auth-facade.js.map +1 -0
- package/dist/lib/runtime/browser-oauth-flow.d.ts +32 -0
- package/dist/lib/runtime/browser-oauth-flow.d.ts.map +1 -0
- package/dist/lib/runtime/browser-oauth-flow.js +31 -0
- package/dist/lib/runtime/browser-oauth-flow.js.map +1 -0
- package/dist/lib/runtime/capability-boost.d.ts +25 -0
- package/dist/lib/runtime/capability-boost.d.ts.map +1 -0
- package/dist/lib/runtime/capability-boost.js +26 -0
- package/dist/lib/runtime/capability-boost.js.map +1 -0
- package/dist/lib/runtime/event-handler.d.ts +53 -0
- package/dist/lib/runtime/event-handler.d.ts.map +1 -0
- package/dist/lib/runtime/event-handler.js +46 -0
- package/dist/lib/runtime/event-handler.js.map +1 -0
- package/dist/lib/runtime/flagged-verify-types.d.ts +9 -0
- package/dist/lib/runtime/flagged-verify-types.d.ts.map +1 -0
- package/dist/lib/runtime/flagged-verify-types.js +7 -0
- package/dist/lib/runtime/flagged-verify-types.js.map +1 -0
- package/dist/lib/runtime/hydrate-emails.d.ts +13 -0
- package/dist/lib/runtime/hydrate-emails.d.ts.map +1 -0
- package/dist/lib/runtime/hydrate-emails.js +56 -0
- package/dist/lib/runtime/hydrate-emails.js.map +1 -0
- package/dist/lib/runtime/live-sync-entry.d.ts +36 -0
- package/dist/lib/runtime/live-sync-entry.d.ts.map +1 -0
- package/dist/lib/runtime/live-sync-entry.js +14 -0
- package/dist/lib/runtime/live-sync-entry.js.map +1 -0
- package/dist/lib/runtime/live-sync.d.ts +35 -0
- package/dist/lib/runtime/live-sync.d.ts.map +1 -0
- package/dist/lib/runtime/live-sync.js +65 -0
- package/dist/lib/runtime/live-sync.js.map +1 -0
- package/dist/lib/runtime/loader-setup.d.ts +9 -0
- package/dist/lib/runtime/loader-setup.d.ts.map +1 -0
- package/dist/lib/runtime/loader-setup.js +8 -0
- package/dist/lib/runtime/loader-setup.js.map +1 -0
- package/dist/lib/runtime/login-menu-accounts.d.ts +29 -0
- package/dist/lib/runtime/login-menu-accounts.d.ts.map +1 -0
- package/dist/lib/runtime/login-menu-accounts.js +33 -0
- package/dist/lib/runtime/login-menu-accounts.js.map +1 -0
- package/dist/lib/runtime/manual-oauth-flow.d.ts +40 -0
- package/dist/lib/runtime/manual-oauth-flow.d.ts.map +1 -0
- package/dist/lib/runtime/manual-oauth-flow.js +71 -0
- package/dist/lib/runtime/manual-oauth-flow.js.map +1 -0
- package/dist/lib/runtime/metrics.d.ts +29 -0
- package/dist/lib/runtime/metrics.d.ts.map +1 -0
- package/dist/lib/runtime/metrics.js +97 -0
- package/dist/lib/runtime/metrics.js.map +1 -0
- package/dist/lib/runtime/oauth-browser-flow.d.ts +9 -0
- package/dist/lib/runtime/oauth-browser-flow.d.ts.map +1 -0
- package/dist/lib/runtime/oauth-browser-flow.js +34 -0
- package/dist/lib/runtime/oauth-browser-flow.js.map +1 -0
- package/dist/lib/runtime/preemptive-quota.d.ts +13 -0
- package/dist/lib/runtime/preemptive-quota.d.ts.map +1 -0
- package/dist/lib/runtime/preemptive-quota.js +9 -0
- package/dist/lib/runtime/preemptive-quota.js.map +1 -0
- package/dist/lib/runtime/quota-headers.d.ts +12 -0
- package/dist/lib/runtime/quota-headers.d.ts.map +1 -0
- package/dist/lib/runtime/quota-headers.js +131 -0
- package/dist/lib/runtime/quota-headers.js.map +1 -0
- package/dist/lib/runtime/quota-probe.d.ts +18 -0
- package/dist/lib/runtime/quota-probe.d.ts.map +1 -0
- package/dist/lib/runtime/quota-probe.js +82 -0
- package/dist/lib/runtime/quota-probe.js.map +1 -0
- package/dist/lib/runtime/quota-settings.d.ts +14 -0
- package/dist/lib/runtime/quota-settings.d.ts.map +1 -0
- package/dist/lib/runtime/quota-settings.js +12 -0
- package/dist/lib/runtime/quota-settings.js.map +1 -0
- package/dist/lib/runtime/refresh-guardian-entry.d.ts +32 -0
- package/dist/lib/runtime/refresh-guardian-entry.d.ts.map +1 -0
- package/dist/lib/runtime/refresh-guardian-entry.js +12 -0
- package/dist/lib/runtime/refresh-guardian-entry.js.map +1 -0
- package/dist/lib/runtime/refresh-guardian.d.ts +24 -0
- package/dist/lib/runtime/refresh-guardian.d.ts.map +1 -0
- package/dist/lib/runtime/refresh-guardian.js +32 -0
- package/dist/lib/runtime/refresh-guardian.js.map +1 -0
- package/dist/lib/runtime/request-init.d.ts +5 -0
- package/dist/lib/runtime/request-init.d.ts.map +1 -0
- package/dist/lib/runtime/request-init.js +50 -0
- package/dist/lib/runtime/request-init.js.map +1 -0
- package/dist/lib/runtime/runtime-services.d.ts +58 -0
- package/dist/lib/runtime/runtime-services.d.ts.map +1 -0
- package/dist/lib/runtime/runtime-services.js +87 -0
- package/dist/lib/runtime/runtime-services.js.map +1 -0
- package/dist/lib/runtime/session-affinity-entry.d.ts +30 -0
- package/dist/lib/runtime/session-affinity-entry.d.ts.map +1 -0
- package/dist/lib/runtime/session-affinity-entry.js +11 -0
- package/dist/lib/runtime/session-affinity-entry.js.map +1 -0
- package/dist/lib/runtime/session-affinity.d.ts +13 -0
- package/dist/lib/runtime/session-affinity.d.ts.map +1 -0
- package/dist/lib/runtime/session-affinity.js +17 -0
- package/dist/lib/runtime/session-affinity.js.map +1 -0
- package/dist/lib/runtime/session-recovery.d.ts +8 -0
- package/dist/lib/runtime/session-recovery.d.ts.map +1 -0
- package/dist/lib/runtime/session-recovery.js +7 -0
- package/dist/lib/runtime/session-recovery.js.map +1 -0
- package/dist/lib/runtime/status-marker.d.ts +3 -0
- package/dist/lib/runtime/status-marker.d.ts.map +1 -0
- package/dist/lib/runtime/status-marker.js +15 -0
- package/dist/lib/runtime/status-marker.js.map +1 -0
- package/dist/lib/runtime/storage-scope.d.ts +13 -0
- package/dist/lib/runtime/storage-scope.d.ts.map +1 -0
- package/dist/lib/runtime/storage-scope.js +14 -0
- package/dist/lib/runtime/storage-scope.js.map +1 -0
- package/dist/lib/runtime/toast.d.ts +16 -0
- package/dist/lib/runtime/toast.d.ts.map +1 -0
- package/dist/lib/runtime/toast.js +16 -0
- package/dist/lib/runtime/toast.js.map +1 -0
- package/dist/lib/runtime/ui-runtime-entry.d.ts +7 -0
- package/dist/lib/runtime/ui-runtime-entry.d.ts.map +1 -0
- package/dist/lib/runtime/ui-runtime-entry.js +4 -0
- package/dist/lib/runtime/ui-runtime-entry.js.map +1 -0
- package/dist/lib/runtime/ui-runtime.d.ts +9 -0
- package/dist/lib/runtime/ui-runtime.d.ts.map +1 -0
- package/dist/lib/runtime/ui-runtime.js +23 -0
- package/dist/lib/runtime/ui-runtime.js.map +1 -0
- package/dist/lib/runtime/verify-flagged.d.ts +44 -0
- package/dist/lib/runtime/verify-flagged.d.ts.map +1 -0
- package/dist/lib/runtime/verify-flagged.js +84 -0
- package/dist/lib/runtime/verify-flagged.js.map +1 -0
- package/dist/lib/schemas.d.ts +2 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +2 -0
- package/dist/lib/schemas.js.map +1 -1
- package/dist/lib/session-affinity.d.ts +10 -0
- package/dist/lib/session-affinity.d.ts.map +1 -1
- package/dist/lib/session-affinity.js +53 -6
- package/dist/lib/session-affinity.js.map +1 -1
- package/dist/lib/storage/account-clear-entry.d.ts +16 -0
- package/dist/lib/storage/account-clear-entry.d.ts.map +1 -0
- package/dist/lib/storage/account-clear-entry.js +12 -0
- package/dist/lib/storage/account-clear-entry.js.map +1 -0
- package/dist/lib/storage/account-clear.d.ts +8 -0
- package/dist/lib/storage/account-clear.d.ts.map +1 -0
- package/dist/lib/storage/account-clear.js +29 -0
- package/dist/lib/storage/account-clear.js.map +1 -0
- package/dist/lib/storage/account-match-utils.d.ts +9 -0
- package/dist/lib/storage/account-match-utils.d.ts.map +1 -0
- package/dist/lib/storage/account-match-utils.js +45 -0
- package/dist/lib/storage/account-match-utils.js.map +1 -0
- package/dist/lib/storage/account-persistence.d.ts +3 -0
- package/dist/lib/storage/account-persistence.d.ts.map +1 -0
- package/dist/lib/storage/account-persistence.js +12 -0
- package/dist/lib/storage/account-persistence.js.map +1 -0
- package/dist/lib/storage/account-port.d.ts +50 -0
- package/dist/lib/storage/account-port.d.ts.map +1 -0
- package/dist/lib/storage/account-port.js +43 -0
- package/dist/lib/storage/account-port.js.map +1 -0
- package/dist/lib/storage/account-save-entry.d.ts +7 -0
- package/dist/lib/storage/account-save-entry.d.ts.map +1 -0
- package/dist/lib/storage/account-save-entry.js +6 -0
- package/dist/lib/storage/account-save-entry.js.map +1 -0
- package/dist/lib/storage/account-save.d.ts +30 -0
- package/dist/lib/storage/account-save.d.ts.map +1 -0
- package/dist/lib/storage/account-save.js +49 -0
- package/dist/lib/storage/account-save.js.map +1 -0
- package/dist/lib/storage/account-snapshot.d.ts +25 -0
- package/dist/lib/storage/account-snapshot.d.ts.map +1 -0
- package/dist/lib/storage/account-snapshot.js +78 -0
- package/dist/lib/storage/account-snapshot.js.map +1 -0
- package/dist/lib/storage/backup-metadata-builder.d.ts +32 -0
- package/dist/lib/storage/backup-metadata-builder.d.ts.map +1 -0
- package/dist/lib/storage/backup-metadata-builder.js +77 -0
- package/dist/lib/storage/backup-metadata-builder.js.map +1 -0
- package/dist/lib/storage/backup-metadata.d.ts +29 -0
- package/dist/lib/storage/backup-metadata.d.ts.map +1 -0
- package/dist/lib/storage/backup-metadata.js +16 -0
- package/dist/lib/storage/backup-metadata.js.map +1 -0
- package/dist/lib/storage/backup-paths.d.ts +10 -0
- package/dist/lib/storage/backup-paths.d.ts.map +1 -0
- package/dist/lib/storage/backup-paths.js +27 -0
- package/dist/lib/storage/backup-paths.js.map +1 -0
- package/dist/lib/storage/backup-restore.d.ts +11 -0
- package/dist/lib/storage/backup-restore.d.ts.map +1 -0
- package/dist/lib/storage/backup-restore.js +52 -0
- package/dist/lib/storage/backup-restore.js.map +1 -0
- package/dist/lib/storage/cache-artifacts.d.ts +2 -0
- package/dist/lib/storage/cache-artifacts.d.ts.map +1 -0
- package/dist/lib/storage/cache-artifacts.js +4 -0
- package/dist/lib/storage/cache-artifacts.js.map +1 -0
- package/dist/lib/storage/error-hints.d.ts +10 -0
- package/dist/lib/storage/error-hints.d.ts.map +1 -0
- package/dist/lib/storage/error-hints.js +36 -0
- package/dist/lib/storage/error-hints.js.map +1 -0
- package/dist/lib/storage/file-paths.d.ts +6 -0
- package/dist/lib/storage/file-paths.d.ts.map +1 -0
- package/dist/lib/storage/file-paths.js +17 -0
- package/dist/lib/storage/file-paths.js.map +1 -0
- package/dist/lib/storage/fixture-guards.d.ts +4 -0
- package/dist/lib/storage/fixture-guards.d.ts.map +1 -0
- package/dist/lib/storage/fixture-guards.js +27 -0
- package/dist/lib/storage/fixture-guards.js.map +1 -0
- package/dist/lib/storage/flagged-entry.d.ts +15 -0
- package/dist/lib/storage/flagged-entry.d.ts.map +1 -0
- package/dist/lib/storage/flagged-entry.js +12 -0
- package/dist/lib/storage/flagged-entry.js.map +1 -0
- package/dist/lib/storage/flagged-load-entry.d.ts +20 -0
- package/dist/lib/storage/flagged-load-entry.d.ts.map +1 -0
- package/dist/lib/storage/flagged-load-entry.js +13 -0
- package/dist/lib/storage/flagged-load-entry.js.map +1 -0
- package/dist/lib/storage/flagged-save-entry.d.ts +7 -0
- package/dist/lib/storage/flagged-save-entry.d.ts.map +1 -0
- package/dist/lib/storage/flagged-save-entry.js +6 -0
- package/dist/lib/storage/flagged-save-entry.js.map +1 -0
- package/dist/lib/storage/flagged-storage-file.d.ts +7 -0
- package/dist/lib/storage/flagged-storage-file.d.ts.map +1 -0
- package/dist/lib/storage/flagged-storage-file.js +25 -0
- package/dist/lib/storage/flagged-storage-file.js.map +1 -0
- package/dist/lib/storage/flagged-storage-io.d.ts +28 -0
- package/dist/lib/storage/flagged-storage-io.d.ts.map +1 -0
- package/dist/lib/storage/flagged-storage-io.js +135 -0
- package/dist/lib/storage/flagged-storage-io.js.map +1 -0
- package/dist/lib/storage/flagged-storage.d.ts +6 -0
- package/dist/lib/storage/flagged-storage.d.ts.map +1 -0
- package/dist/lib/storage/flagged-storage.js +90 -0
- package/dist/lib/storage/flagged-storage.js.map +1 -0
- package/dist/lib/storage/gitignore.d.ts +7 -0
- package/dist/lib/storage/gitignore.d.ts.map +1 -0
- package/dist/lib/storage/gitignore.js +34 -0
- package/dist/lib/storage/gitignore.js.map +1 -0
- package/dist/lib/storage/hash.d.ts +2 -0
- package/dist/lib/storage/hash.d.ts.map +1 -0
- package/dist/lib/storage/hash.js +5 -0
- package/dist/lib/storage/hash.js.map +1 -0
- package/dist/lib/storage/identity.d.ts +21 -0
- package/dist/lib/storage/identity.d.ts.map +1 -0
- package/dist/lib/storage/identity.js +59 -0
- package/dist/lib/storage/identity.js.map +1 -0
- package/dist/lib/storage/import-export.d.ts +24 -0
- package/dist/lib/storage/import-export.d.ts.map +1 -0
- package/dist/lib/storage/import-export.js +108 -0
- package/dist/lib/storage/import-export.js.map +1 -0
- package/dist/lib/storage/metadata-section.d.ts +16 -0
- package/dist/lib/storage/metadata-section.d.ts.map +1 -0
- package/dist/lib/storage/metadata-section.js +16 -0
- package/dist/lib/storage/metadata-section.js.map +1 -0
- package/dist/lib/storage/named-backup-entry.d.ts +15 -0
- package/dist/lib/storage/named-backup-entry.d.ts.map +1 -0
- package/dist/lib/storage/named-backup-entry.js +7 -0
- package/dist/lib/storage/named-backup-entry.js.map +1 -0
- package/dist/lib/storage/named-backups-entry.d.ts +19 -0
- package/dist/lib/storage/named-backups-entry.d.ts.map +1 -0
- package/dist/lib/storage/named-backups-entry.js +7 -0
- package/dist/lib/storage/named-backups-entry.js.map +1 -0
- package/dist/lib/storage/named-backups.d.ts +15 -0
- package/dist/lib/storage/named-backups.d.ts.map +1 -0
- package/dist/lib/storage/named-backups.js +68 -0
- package/dist/lib/storage/named-backups.js.map +1 -0
- package/dist/lib/storage/path-state.d.ts +9 -0
- package/dist/lib/storage/path-state.d.ts.map +1 -0
- package/dist/lib/storage/path-state.js +20 -0
- package/dist/lib/storage/path-state.js.map +1 -0
- package/dist/lib/storage/project-migration.d.ts +10 -0
- package/dist/lib/storage/project-migration.d.ts.map +1 -0
- package/dist/lib/storage/project-migration.js +38 -0
- package/dist/lib/storage/project-migration.js.map +1 -0
- package/dist/lib/storage/record-utils.d.ts +3 -0
- package/dist/lib/storage/record-utils.d.ts.map +1 -0
- package/dist/lib/storage/record-utils.js +9 -0
- package/dist/lib/storage/record-utils.js.map +1 -0
- package/dist/lib/storage/restore-assessment.d.ts +7 -0
- package/dist/lib/storage/restore-assessment.d.ts.map +1 -0
- package/dist/lib/storage/restore-assessment.js +42 -0
- package/dist/lib/storage/restore-assessment.js.map +1 -0
- package/dist/lib/storage/restore-backup-entry.d.ts +24 -0
- package/dist/lib/storage/restore-backup-entry.d.ts.map +1 -0
- package/dist/lib/storage/restore-backup-entry.js +10 -0
- package/dist/lib/storage/restore-backup-entry.js.map +1 -0
- package/dist/lib/storage/restore-metadata.d.ts +10 -0
- package/dist/lib/storage/restore-metadata.d.ts.map +1 -0
- package/dist/lib/storage/restore-metadata.js +18 -0
- package/dist/lib/storage/restore-metadata.js.map +1 -0
- package/dist/lib/storage/restore.d.ts +14 -0
- package/dist/lib/storage/restore.d.ts.map +1 -0
- package/dist/lib/storage/restore.js +53 -0
- package/dist/lib/storage/restore.js.map +1 -0
- package/dist/lib/storage/snapshot-inspectors.d.ts +22 -0
- package/dist/lib/storage/snapshot-inspectors.d.ts.map +1 -0
- package/dist/lib/storage/snapshot-inspectors.js +95 -0
- package/dist/lib/storage/snapshot-inspectors.js.map +1 -0
- package/dist/lib/storage/storage-parser.d.ts +15 -0
- package/dist/lib/storage/storage-parser.d.ts.map +1 -0
- package/dist/lib/storage/storage-parser.js +16 -0
- package/dist/lib/storage/storage-parser.js.map +1 -0
- package/dist/lib/storage/transactions.d.ts +23 -0
- package/dist/lib/storage/transactions.d.ts.map +1 -0
- package/dist/lib/storage/transactions.js +64 -0
- package/dist/lib/storage/transactions.js.map +1 -0
- package/dist/lib/storage.d.ts +8 -47
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +482 -1044
- package/dist/lib/storage.js.map +1 -1
- package/dist/lib/types.d.ts +80 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/package.json +41 -4
- package/scripts/check-pack-budget-lib.js +114 -0
- package/scripts/check-pack-budget.mjs +10 -0
- package/scripts/codex-multi-auth.js +34 -10
- package/scripts/install-codex-auth-utils.js +54 -14
- package/scripts/install-codex-auth.js +62 -33
- package/scripts/update-vendor-provenance.mjs +96 -0
- package/scripts/verify-vendor-provenance.mjs +53 -0
|
@@ -1,17 +1,43 @@
|
|
|
1
|
-
import { promises as fs } from "node:fs";
|
|
2
1
|
import { stdin as input, stdout as output } from "node:process";
|
|
3
|
-
import {
|
|
4
|
-
import { getDefaultPluginConfig, loadPluginConfig, savePluginConfig, } from "../config.js";
|
|
2
|
+
import { loadPluginConfig, savePluginConfig } from "../config.js";
|
|
5
3
|
import { DEFAULT_DASHBOARD_DISPLAY_SETTINGS, getDashboardSettingsPath, loadDashboardDisplaySettings, saveDashboardDisplaySettings, } from "../dashboard-settings.js";
|
|
6
4
|
import { applyOcChatgptSync, planOcChatgptSync, runNamedBackupExport, } from "../oc-chatgpt-orchestrator.js";
|
|
7
5
|
import { detectOcChatgptMultiAuthTarget } from "../oc-chatgpt-target-detection.js";
|
|
8
6
|
import { loadAccounts, normalizeAccountStorage } from "../storage.js";
|
|
9
|
-
import { ANSI } from "../ui/ansi.js";
|
|
10
7
|
import { UI_COPY } from "../ui/copy.js";
|
|
11
8
|
import { getUiRuntimeOptions, setUiRuntimeOptions } from "../ui/runtime.js";
|
|
12
9
|
import { select } from "../ui/select.js";
|
|
13
|
-
import { getUnifiedSettingsPath } from "../unified-settings.js";
|
|
14
10
|
import { sleep } from "../utils.js";
|
|
11
|
+
import { promptBackendCategorySettingsEntry } from "./backend-category-entry.js";
|
|
12
|
+
import { applyBackendCategoryDefaults, getBackendCategory, getBackendCategoryInitialFocus, resolveFocusedBackendNumberKey, } from "./backend-category-helpers.js";
|
|
13
|
+
import { promptBackendCategorySettingsMenu } from "./backend-category-prompt.js";
|
|
14
|
+
import { configureBackendSettingsController } from "./backend-settings-controller.js";
|
|
15
|
+
import { configureBackendSettingsEntry } from "./backend-settings-entry.js";
|
|
16
|
+
import { backendSettingsEqual, buildBackendConfigPatch, buildBackendSettingsPreview, clampBackendNumberForTests, cloneBackendPluginConfig, formatBackendNumberValue, } from "./backend-settings-helpers.js";
|
|
17
|
+
import { promptBackendSettingsMenu } from "./backend-settings-prompt.js";
|
|
18
|
+
import { BACKEND_CATEGORY_OPTIONS, BACKEND_DEFAULTS, BACKEND_NUMBER_OPTION_BY_KEY, BACKEND_TOGGLE_OPTION_BY_KEY, } from "./backend-settings-schema.js";
|
|
19
|
+
import { promptBehaviorSettingsPanel } from "./behavior-settings-panel.js";
|
|
20
|
+
import { promptDashboardDisplayPanel, } from "./dashboard-display-panel.js";
|
|
21
|
+
import { formatDashboardSettingState, formatMenuLayoutMode, formatMenuQuotaTtl, formatMenuSortMode, } from "./dashboard-formatters.js";
|
|
22
|
+
import { configureDashboardSettingsController } from "./dashboard-settings-controller.js";
|
|
23
|
+
import { cloneDashboardSettingsData, dashboardSettingsDataEqual, } from "./dashboard-settings-data.js";
|
|
24
|
+
import { configureDashboardSettingsEntry } from "./dashboard-settings-entry.js";
|
|
25
|
+
import { promptExperimentalSettingsEntry } from "./experimental-settings-entry.js";
|
|
26
|
+
import { promptExperimentalSettingsMenu } from "./experimental-settings-prompt.js";
|
|
27
|
+
import { getExperimentalSelectOptions, mapExperimentalMenuHotkey, mapExperimentalStatusHotkey, } from "./experimental-settings-schema.js";
|
|
28
|
+
import { loadExperimentalSyncTargetState } from "./experimental-sync-target.js";
|
|
29
|
+
import { loadExperimentalSyncTargetEntry } from "./experimental-sync-target-entry.js";
|
|
30
|
+
import { promptSettingsHubEntry } from "./settings-hub-entry.js";
|
|
31
|
+
import { buildSettingsHubItems, findSettingsHubInitialCursor, } from "./settings-hub-menu.js";
|
|
32
|
+
import { promptSettingsHubMenu } from "./settings-hub-prompt.js";
|
|
33
|
+
import { promptBehaviorSettingsPanelEntry, promptDashboardDisplaySettingsPanelEntry, promptStatuslineSettingsPanelEntry, promptThemeSettingsPanelEntry, reorderStatuslineField, } from "./settings-panels.js";
|
|
34
|
+
import { readFileWithRetry, resolvePluginConfigSavePathKey, warnPersistFailure, } from "./settings-persist-utils.js";
|
|
35
|
+
import { buildAccountListPreview as buildAccountListPreviewBase, buildSummaryPreviewText as buildSummaryPreviewTextBase, highlightPreviewToken, normalizeStatuslineFields, } from "./settings-preview.js";
|
|
36
|
+
import { withQueuedRetry } from "./settings-write-queue.js";
|
|
37
|
+
import { promptStatuslineSettingsPanel } from "./statusline-settings-panel.js";
|
|
38
|
+
import { promptThemeSettingsPanel } from "./theme-settings-panel.js";
|
|
39
|
+
import { configureUnifiedSettingsController, } from "./unified-settings-controller.js";
|
|
40
|
+
import { configureUnifiedSettingsEntry } from "./unified-settings-entry.js";
|
|
15
41
|
const DASHBOARD_DISPLAY_OPTIONS = [
|
|
16
42
|
{
|
|
17
43
|
key: "menuShowStatusBadge",
|
|
@@ -64,11 +90,6 @@ const DASHBOARD_DISPLAY_OPTIONS = [
|
|
|
64
90
|
description: "Number keys (1-9) follow what you see in the list.",
|
|
65
91
|
},
|
|
66
92
|
];
|
|
67
|
-
const DEFAULT_STATUSLINE_FIELDS = [
|
|
68
|
-
"last-used",
|
|
69
|
-
"limits",
|
|
70
|
-
"status",
|
|
71
|
-
];
|
|
72
93
|
const STATUSLINE_FIELD_OPTIONS = [
|
|
73
94
|
{
|
|
74
95
|
key: "last-used",
|
|
@@ -95,312 +116,6 @@ const ACCENT_COLOR_OPTIONS = [
|
|
|
95
116
|
"blue",
|
|
96
117
|
"yellow",
|
|
97
118
|
];
|
|
98
|
-
const PREVIEW_ACCOUNT_EMAIL = "demo@example.com";
|
|
99
|
-
const PREVIEW_LAST_USED = "today";
|
|
100
|
-
const PREVIEW_STATUS = "active";
|
|
101
|
-
const PREVIEW_LIMITS = "5h ██████▒▒▒▒ 62% | 7d █████▒▒▒▒▒ 49%";
|
|
102
|
-
const PREVIEW_LIMIT_COOLDOWNS = "5h reset 1h 20m | 7d reset 2d 04h";
|
|
103
|
-
function getExperimentalSelectOptions(ui, help, onInput) {
|
|
104
|
-
return {
|
|
105
|
-
message: UI_COPY.settings.experimentalTitle,
|
|
106
|
-
subtitle: UI_COPY.settings.experimentalSubtitle,
|
|
107
|
-
help,
|
|
108
|
-
clearScreen: true,
|
|
109
|
-
theme: ui.theme,
|
|
110
|
-
selectedEmphasis: "minimal",
|
|
111
|
-
onInput,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
function mapExperimentalMenuHotkey(raw) {
|
|
115
|
-
if (raw === "1")
|
|
116
|
-
return { type: "sync" };
|
|
117
|
-
if (raw === "2")
|
|
118
|
-
return { type: "backup" };
|
|
119
|
-
if (raw === "3")
|
|
120
|
-
return { type: "toggle-refresh-guardian" };
|
|
121
|
-
if (raw === "[" || raw === "-")
|
|
122
|
-
return { type: "decrease-refresh-interval" };
|
|
123
|
-
if (raw === "]" || raw === "+")
|
|
124
|
-
return { type: "increase-refresh-interval" };
|
|
125
|
-
const lower = raw.toLowerCase();
|
|
126
|
-
if (lower === "q")
|
|
127
|
-
return { type: "back" };
|
|
128
|
-
if (lower === "s")
|
|
129
|
-
return { type: "save" };
|
|
130
|
-
return undefined;
|
|
131
|
-
}
|
|
132
|
-
function mapExperimentalStatusHotkey(raw) {
|
|
133
|
-
return raw.toLowerCase() === "q" ? { type: "back" } : undefined;
|
|
134
|
-
}
|
|
135
|
-
const BACKEND_TOGGLE_OPTIONS = [
|
|
136
|
-
{
|
|
137
|
-
key: "liveAccountSync",
|
|
138
|
-
label: "Enable Live Sync",
|
|
139
|
-
description: "Keep accounts synced when files change in another window.",
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
key: "sessionAffinity",
|
|
143
|
-
label: "Enable Session Affinity",
|
|
144
|
-
description: "Try to keep each conversation on the same account.",
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
key: "proactiveRefreshGuardian",
|
|
148
|
-
label: "Enable Token Refresh Guard",
|
|
149
|
-
description: "Refresh tokens early in the background.",
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
key: "retryAllAccountsRateLimited",
|
|
153
|
-
label: "Retry When All Rate-Limited",
|
|
154
|
-
description: "If all accounts are limited, wait and try again.",
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
key: "parallelProbing",
|
|
158
|
-
label: "Enable Parallel Probing",
|
|
159
|
-
description: "Check multiple accounts at the same time.",
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
key: "storageBackupEnabled",
|
|
163
|
-
label: "Enable Storage Backups",
|
|
164
|
-
description: "Create a backup before account data changes.",
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
key: "preemptiveQuotaEnabled",
|
|
168
|
-
label: "Enable Quota Deferral",
|
|
169
|
-
description: "Delay requests before limits are fully exhausted.",
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
key: "fastSession",
|
|
173
|
-
label: "Enable Fast Session Mode",
|
|
174
|
-
description: "Use lighter request handling for faster responses.",
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
key: "sessionRecovery",
|
|
178
|
-
label: "Enable Session Recovery",
|
|
179
|
-
description: "Restore recoverable sessions after restart.",
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
key: "autoResume",
|
|
183
|
-
label: "Enable Auto Resume",
|
|
184
|
-
description: "Automatically continue sessions when possible.",
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
key: "perProjectAccounts",
|
|
188
|
-
label: "Enable Per-Project Accounts",
|
|
189
|
-
description: "Keep separate account lists for each project.",
|
|
190
|
-
},
|
|
191
|
-
];
|
|
192
|
-
const BACKEND_NUMBER_OPTIONS = [
|
|
193
|
-
{
|
|
194
|
-
key: "liveAccountSyncDebounceMs",
|
|
195
|
-
label: "Live Sync Debounce",
|
|
196
|
-
description: "Wait this long before applying sync file changes.",
|
|
197
|
-
min: 50,
|
|
198
|
-
max: 10_000,
|
|
199
|
-
step: 50,
|
|
200
|
-
unit: "ms",
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
key: "liveAccountSyncPollMs",
|
|
204
|
-
label: "Live Sync Poll",
|
|
205
|
-
description: "How often to check files for account updates.",
|
|
206
|
-
min: 500,
|
|
207
|
-
max: 60_000,
|
|
208
|
-
step: 500,
|
|
209
|
-
unit: "ms",
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
key: "sessionAffinityTtlMs",
|
|
213
|
-
label: "Session Affinity TTL",
|
|
214
|
-
description: "How long conversation-to-account mapping is kept.",
|
|
215
|
-
min: 1_000,
|
|
216
|
-
max: 24 * 60 * 60_000,
|
|
217
|
-
step: 60_000,
|
|
218
|
-
unit: "ms",
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
key: "sessionAffinityMaxEntries",
|
|
222
|
-
label: "Session Affinity Max Entries",
|
|
223
|
-
description: "Maximum stored conversation mappings.",
|
|
224
|
-
min: 8,
|
|
225
|
-
max: 4_096,
|
|
226
|
-
step: 32,
|
|
227
|
-
unit: "count",
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
key: "proactiveRefreshIntervalMs",
|
|
231
|
-
label: "Refresh Guard Interval",
|
|
232
|
-
description: "How often to scan for tokens near expiry.",
|
|
233
|
-
min: 5_000,
|
|
234
|
-
max: 10 * 60_000,
|
|
235
|
-
step: 5_000,
|
|
236
|
-
unit: "ms",
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
key: "proactiveRefreshBufferMs",
|
|
240
|
-
label: "Refresh Guard Buffer",
|
|
241
|
-
description: "How early to refresh before expiry.",
|
|
242
|
-
min: 30_000,
|
|
243
|
-
max: 10 * 60_000,
|
|
244
|
-
step: 30_000,
|
|
245
|
-
unit: "ms",
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
key: "parallelProbingMaxConcurrency",
|
|
249
|
-
label: "Parallel Probe Concurrency",
|
|
250
|
-
description: "Maximum checks running at once.",
|
|
251
|
-
min: 1,
|
|
252
|
-
max: 5,
|
|
253
|
-
step: 1,
|
|
254
|
-
unit: "count",
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
key: "fastSessionMaxInputItems",
|
|
258
|
-
label: "Fast Session Max Inputs",
|
|
259
|
-
description: "Max number of input items kept in fast mode.",
|
|
260
|
-
min: 8,
|
|
261
|
-
max: 200,
|
|
262
|
-
step: 2,
|
|
263
|
-
unit: "count",
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
key: "networkErrorCooldownMs",
|
|
267
|
-
label: "Network Error Cooldown",
|
|
268
|
-
description: "Wait time after network errors before retry.",
|
|
269
|
-
min: 0,
|
|
270
|
-
max: 120_000,
|
|
271
|
-
step: 500,
|
|
272
|
-
unit: "ms",
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
key: "serverErrorCooldownMs",
|
|
276
|
-
label: "Server Error Cooldown",
|
|
277
|
-
description: "Wait time after server errors before retry.",
|
|
278
|
-
min: 0,
|
|
279
|
-
max: 120_000,
|
|
280
|
-
step: 500,
|
|
281
|
-
unit: "ms",
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
key: "fetchTimeoutMs",
|
|
285
|
-
label: "Request Timeout",
|
|
286
|
-
description: "Max time to wait for a request.",
|
|
287
|
-
min: 1_000,
|
|
288
|
-
max: 10 * 60_000,
|
|
289
|
-
step: 5_000,
|
|
290
|
-
unit: "ms",
|
|
291
|
-
},
|
|
292
|
-
{
|
|
293
|
-
key: "streamStallTimeoutMs",
|
|
294
|
-
label: "Stream Stall Timeout",
|
|
295
|
-
description: "Max wait before a stuck stream is retried.",
|
|
296
|
-
min: 1_000,
|
|
297
|
-
max: 10 * 60_000,
|
|
298
|
-
step: 5_000,
|
|
299
|
-
unit: "ms",
|
|
300
|
-
},
|
|
301
|
-
{
|
|
302
|
-
key: "tokenRefreshSkewMs",
|
|
303
|
-
label: "Token Refresh Buffer",
|
|
304
|
-
description: "Refresh this long before token expiry.",
|
|
305
|
-
min: 0,
|
|
306
|
-
max: 10 * 60_000,
|
|
307
|
-
step: 10_000,
|
|
308
|
-
unit: "ms",
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
key: "preemptiveQuotaRemainingPercent5h",
|
|
312
|
-
label: "5h Remaining Threshold",
|
|
313
|
-
description: "Start delaying when 5h remaining reaches this percent.",
|
|
314
|
-
min: 0,
|
|
315
|
-
max: 100,
|
|
316
|
-
step: 1,
|
|
317
|
-
unit: "percent",
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
key: "preemptiveQuotaRemainingPercent7d",
|
|
321
|
-
label: "7d Remaining Threshold",
|
|
322
|
-
description: "Start delaying when weekly remaining reaches this percent.",
|
|
323
|
-
min: 0,
|
|
324
|
-
max: 100,
|
|
325
|
-
step: 1,
|
|
326
|
-
unit: "percent",
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
key: "preemptiveQuotaMaxDeferralMs",
|
|
330
|
-
label: "Max Preemptive Deferral",
|
|
331
|
-
description: "Maximum time allowed for quota-based delay.",
|
|
332
|
-
min: 1_000,
|
|
333
|
-
max: 24 * 60 * 60_000,
|
|
334
|
-
step: 60_000,
|
|
335
|
-
unit: "ms",
|
|
336
|
-
},
|
|
337
|
-
];
|
|
338
|
-
const BACKEND_DEFAULTS = getDefaultPluginConfig();
|
|
339
|
-
const BACKEND_TOGGLE_OPTION_BY_KEY = new Map(BACKEND_TOGGLE_OPTIONS.map((option) => [option.key, option]));
|
|
340
|
-
const BACKEND_NUMBER_OPTION_BY_KEY = new Map(BACKEND_NUMBER_OPTIONS.map((option) => [option.key, option]));
|
|
341
|
-
const BACKEND_CATEGORY_OPTIONS = [
|
|
342
|
-
{
|
|
343
|
-
key: "session-sync",
|
|
344
|
-
label: "Session & Sync",
|
|
345
|
-
description: "Sync and session behavior.",
|
|
346
|
-
toggleKeys: [
|
|
347
|
-
"liveAccountSync",
|
|
348
|
-
"sessionAffinity",
|
|
349
|
-
"perProjectAccounts",
|
|
350
|
-
"sessionRecovery",
|
|
351
|
-
"autoResume",
|
|
352
|
-
],
|
|
353
|
-
numberKeys: [
|
|
354
|
-
"liveAccountSyncDebounceMs",
|
|
355
|
-
"liveAccountSyncPollMs",
|
|
356
|
-
"sessionAffinityTtlMs",
|
|
357
|
-
"sessionAffinityMaxEntries",
|
|
358
|
-
],
|
|
359
|
-
},
|
|
360
|
-
{
|
|
361
|
-
key: "rotation-quota",
|
|
362
|
-
label: "Rotation & Quota",
|
|
363
|
-
description: "Quota and retry behavior.",
|
|
364
|
-
toggleKeys: ["preemptiveQuotaEnabled", "retryAllAccountsRateLimited"],
|
|
365
|
-
numberKeys: [
|
|
366
|
-
"preemptiveQuotaRemainingPercent5h",
|
|
367
|
-
"preemptiveQuotaRemainingPercent7d",
|
|
368
|
-
"preemptiveQuotaMaxDeferralMs",
|
|
369
|
-
],
|
|
370
|
-
},
|
|
371
|
-
{
|
|
372
|
-
key: "refresh-recovery",
|
|
373
|
-
label: "Refresh & Recovery",
|
|
374
|
-
description: "Token refresh and recovery safety.",
|
|
375
|
-
toggleKeys: ["storageBackupEnabled"],
|
|
376
|
-
numberKeys: ["proactiveRefreshBufferMs", "tokenRefreshSkewMs"],
|
|
377
|
-
},
|
|
378
|
-
{
|
|
379
|
-
key: "performance-timeouts",
|
|
380
|
-
label: "Performance & Timeouts",
|
|
381
|
-
description: "Speed, probing, and timeout controls.",
|
|
382
|
-
toggleKeys: ["fastSession", "parallelProbing"],
|
|
383
|
-
numberKeys: [
|
|
384
|
-
"fastSessionMaxInputItems",
|
|
385
|
-
"parallelProbingMaxConcurrency",
|
|
386
|
-
"fetchTimeoutMs",
|
|
387
|
-
"streamStallTimeoutMs",
|
|
388
|
-
"networkErrorCooldownMs",
|
|
389
|
-
"serverErrorCooldownMs",
|
|
390
|
-
],
|
|
391
|
-
},
|
|
392
|
-
];
|
|
393
|
-
const RETRYABLE_SETTINGS_WRITE_CODES = new Set([
|
|
394
|
-
"EBUSY",
|
|
395
|
-
"EPERM",
|
|
396
|
-
"EAGAIN",
|
|
397
|
-
"ENOTEMPTY",
|
|
398
|
-
"EACCES",
|
|
399
|
-
]);
|
|
400
|
-
const SETTINGS_WRITE_MAX_ATTEMPTS = 4;
|
|
401
|
-
const SETTINGS_WRITE_BASE_DELAY_MS = 20;
|
|
402
|
-
const SETTINGS_WRITE_MAX_DELAY_MS = 30_000;
|
|
403
|
-
const settingsWriteQueues = new Map();
|
|
404
119
|
const ACCOUNT_LIST_PANEL_KEYS = [
|
|
405
120
|
"menuShowStatusBadge",
|
|
406
121
|
"menuShowCurrentBadge",
|
|
@@ -430,82 +145,6 @@ const THEME_PANEL_KEYS = [
|
|
|
430
145
|
"uiThemePreset",
|
|
431
146
|
"uiAccentColor",
|
|
432
147
|
];
|
|
433
|
-
function readErrorNumber(value) {
|
|
434
|
-
if (typeof value === "number" && Number.isFinite(value))
|
|
435
|
-
return value;
|
|
436
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
437
|
-
const parsed = Number.parseInt(value, 10);
|
|
438
|
-
if (Number.isFinite(parsed))
|
|
439
|
-
return parsed;
|
|
440
|
-
}
|
|
441
|
-
return undefined;
|
|
442
|
-
}
|
|
443
|
-
function getErrorStatusCode(error) {
|
|
444
|
-
if (!error || typeof error !== "object")
|
|
445
|
-
return undefined;
|
|
446
|
-
const record = error;
|
|
447
|
-
return readErrorNumber(record.status) ?? readErrorNumber(record.statusCode);
|
|
448
|
-
}
|
|
449
|
-
function getRetryAfterMs(error) {
|
|
450
|
-
if (!error || typeof error !== "object")
|
|
451
|
-
return undefined;
|
|
452
|
-
const record = error;
|
|
453
|
-
return (readErrorNumber(record.retryAfterMs) ??
|
|
454
|
-
readErrorNumber(record.retry_after_ms) ??
|
|
455
|
-
readErrorNumber(record.retryAfter) ??
|
|
456
|
-
readErrorNumber(record.retry_after));
|
|
457
|
-
}
|
|
458
|
-
function isRetryableSettingsWriteError(error) {
|
|
459
|
-
const statusCode = getErrorStatusCode(error);
|
|
460
|
-
if (statusCode === 429)
|
|
461
|
-
return true;
|
|
462
|
-
const code = error?.code;
|
|
463
|
-
return typeof code === "string" && RETRYABLE_SETTINGS_WRITE_CODES.has(code);
|
|
464
|
-
}
|
|
465
|
-
function resolveRetryDelayMs(error, attempt) {
|
|
466
|
-
const retryAfterMs = getRetryAfterMs(error);
|
|
467
|
-
if (typeof retryAfterMs === "number" &&
|
|
468
|
-
Number.isFinite(retryAfterMs) &&
|
|
469
|
-
retryAfterMs > 0) {
|
|
470
|
-
return Math.max(10, Math.min(SETTINGS_WRITE_MAX_DELAY_MS, Math.round(retryAfterMs)));
|
|
471
|
-
}
|
|
472
|
-
return Math.min(SETTINGS_WRITE_MAX_DELAY_MS, SETTINGS_WRITE_BASE_DELAY_MS * 2 ** attempt);
|
|
473
|
-
}
|
|
474
|
-
async function enqueueSettingsWrite(pathKey, task) {
|
|
475
|
-
const previous = settingsWriteQueues.get(pathKey) ?? Promise.resolve();
|
|
476
|
-
const queued = previous.catch(() => { }).then(task);
|
|
477
|
-
const queueTail = queued.then(() => undefined, () => undefined);
|
|
478
|
-
settingsWriteQueues.set(pathKey, queueTail);
|
|
479
|
-
try {
|
|
480
|
-
return await queued;
|
|
481
|
-
}
|
|
482
|
-
finally {
|
|
483
|
-
if (settingsWriteQueues.get(pathKey) === queueTail) {
|
|
484
|
-
settingsWriteQueues.delete(pathKey);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
async function withQueuedRetry(pathKey, task) {
|
|
489
|
-
return enqueueSettingsWrite(pathKey, async () => {
|
|
490
|
-
let lastError;
|
|
491
|
-
for (let attempt = 0; attempt < SETTINGS_WRITE_MAX_ATTEMPTS; attempt += 1) {
|
|
492
|
-
try {
|
|
493
|
-
return await task();
|
|
494
|
-
}
|
|
495
|
-
catch (error) {
|
|
496
|
-
lastError = error;
|
|
497
|
-
if (!isRetryableSettingsWriteError(error) ||
|
|
498
|
-
attempt + 1 >= SETTINGS_WRITE_MAX_ATTEMPTS) {
|
|
499
|
-
throw error;
|
|
500
|
-
}
|
|
501
|
-
await sleep(resolveRetryDelayMs(error, attempt));
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
throw lastError instanceof Error
|
|
505
|
-
? lastError
|
|
506
|
-
: new Error("settings save retry exhausted");
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
148
|
function copyDashboardSettingValue(target, source, key) {
|
|
510
149
|
const value = source[key];
|
|
511
150
|
target[key] = Array.isArray(value)
|
|
@@ -527,18 +166,6 @@ function mergeDashboardSettingsForKeys(base, selected, keys) {
|
|
|
527
166
|
}
|
|
528
167
|
return cloneDashboardSettings(next);
|
|
529
168
|
}
|
|
530
|
-
function resolvePluginConfigSavePathKey() {
|
|
531
|
-
const envPath = (process.env.CODEX_MULTI_AUTH_CONFIG_PATH ?? "").trim();
|
|
532
|
-
return envPath.length > 0 ? envPath : getUnifiedSettingsPath();
|
|
533
|
-
}
|
|
534
|
-
function formatPersistError(error) {
|
|
535
|
-
if (error instanceof Error)
|
|
536
|
-
return error.message;
|
|
537
|
-
return String(error);
|
|
538
|
-
}
|
|
539
|
-
function warnPersistFailure(scope, error) {
|
|
540
|
-
console.warn(`Settings save failed (${scope}) after retries: ${formatPersistError(error)}`);
|
|
541
|
-
}
|
|
542
169
|
async function persistDashboardSettingsSelection(selected, keys, scope) {
|
|
543
170
|
const fallback = cloneDashboardSettings(selected);
|
|
544
171
|
try {
|
|
@@ -547,38 +174,19 @@ async function persistDashboardSettingsSelection(selected, keys, scope) {
|
|
|
547
174
|
const merged = mergeDashboardSettingsForKeys(latest, selected, keys);
|
|
548
175
|
await saveDashboardDisplaySettings(merged);
|
|
549
176
|
return merged;
|
|
550
|
-
});
|
|
177
|
+
}, { sleep });
|
|
551
178
|
}
|
|
552
179
|
catch (error) {
|
|
553
180
|
warnPersistFailure(scope, error);
|
|
554
181
|
return fallback;
|
|
555
182
|
}
|
|
556
183
|
}
|
|
557
|
-
async function readFileWithRetry(path) {
|
|
558
|
-
for (let attempt = 0;; attempt += 1) {
|
|
559
|
-
try {
|
|
560
|
-
return await fs.readFile(path, "utf-8");
|
|
561
|
-
}
|
|
562
|
-
catch (error) {
|
|
563
|
-
const code = error.code;
|
|
564
|
-
if (code === "ENOENT") {
|
|
565
|
-
throw error;
|
|
566
|
-
}
|
|
567
|
-
if (!code ||
|
|
568
|
-
!RETRYABLE_SETTINGS_WRITE_CODES.has(code) ||
|
|
569
|
-
attempt >= SETTINGS_WRITE_MAX_ATTEMPTS - 1) {
|
|
570
|
-
throw error;
|
|
571
|
-
}
|
|
572
|
-
await sleep(25 * 2 ** attempt);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
184
|
async function persistBackendConfigSelection(selected, scope) {
|
|
577
185
|
const fallback = cloneBackendPluginConfig(selected);
|
|
578
186
|
try {
|
|
579
187
|
await withQueuedRetry(resolvePluginConfigSavePathKey(), async () => {
|
|
580
188
|
await savePluginConfig(buildBackendConfigPatch(selected));
|
|
581
|
-
});
|
|
189
|
+
}, { sleep });
|
|
582
190
|
return fallback;
|
|
583
191
|
}
|
|
584
192
|
catch (error) {
|
|
@@ -586,297 +194,27 @@ async function persistBackendConfigSelection(selected, scope) {
|
|
|
586
194
|
return fallback;
|
|
587
195
|
}
|
|
588
196
|
}
|
|
589
|
-
function normalizeStatuslineFields(fields) {
|
|
590
|
-
const source = fields ?? DEFAULT_STATUSLINE_FIELDS;
|
|
591
|
-
const seen = new Set();
|
|
592
|
-
const normalized = [];
|
|
593
|
-
for (const field of source) {
|
|
594
|
-
if (seen.has(field))
|
|
595
|
-
continue;
|
|
596
|
-
seen.add(field);
|
|
597
|
-
normalized.push(field);
|
|
598
|
-
}
|
|
599
|
-
if (normalized.length === 0) {
|
|
600
|
-
return [...DEFAULT_STATUSLINE_FIELDS];
|
|
601
|
-
}
|
|
602
|
-
return normalized;
|
|
603
|
-
}
|
|
604
|
-
function highlightPreviewToken(text, ui) {
|
|
605
|
-
if (!output.isTTY)
|
|
606
|
-
return text;
|
|
607
|
-
if (ui.v2Enabled) {
|
|
608
|
-
return `${ui.theme.colors.accent}${ANSI.bold}${text}${ui.theme.colors.reset}`;
|
|
609
|
-
}
|
|
610
|
-
return `${ANSI.cyan}${ANSI.bold}${text}${ANSI.reset}`;
|
|
611
|
-
}
|
|
612
|
-
function isLastUsedPreviewFocus(focus) {
|
|
613
|
-
return focus === "menuShowLastUsed" || focus === "last-used";
|
|
614
|
-
}
|
|
615
|
-
function isLimitsPreviewFocus(focus) {
|
|
616
|
-
return focus === "menuShowQuotaSummary" || focus === "limits";
|
|
617
|
-
}
|
|
618
|
-
function isLimitsCooldownPreviewFocus(focus) {
|
|
619
|
-
return focus === "menuShowQuotaCooldown";
|
|
620
|
-
}
|
|
621
|
-
function isStatusPreviewFocus(focus) {
|
|
622
|
-
return focus === "menuShowStatusBadge" || focus === "status";
|
|
623
|
-
}
|
|
624
|
-
function isCurrentBadgePreviewFocus(focus) {
|
|
625
|
-
return focus === "menuShowCurrentBadge";
|
|
626
|
-
}
|
|
627
|
-
function isCurrentRowPreviewFocus(focus) {
|
|
628
|
-
return focus === "menuHighlightCurrentRow";
|
|
629
|
-
}
|
|
630
|
-
function isExpandedRowsPreviewFocus(focus) {
|
|
631
|
-
return (focus === "menuShowDetailsForUnselectedRows" || focus === "menuLayoutMode");
|
|
632
|
-
}
|
|
633
|
-
function buildSummaryPreviewText(settings, ui, focus = null) {
|
|
634
|
-
const partsByField = new Map();
|
|
635
|
-
if (settings.menuShowLastUsed !== false) {
|
|
636
|
-
const part = `last used: ${PREVIEW_LAST_USED}`;
|
|
637
|
-
partsByField.set("last-used", isLastUsedPreviewFocus(focus) ? highlightPreviewToken(part, ui) : part);
|
|
638
|
-
}
|
|
639
|
-
if (settings.menuShowQuotaSummary !== false) {
|
|
640
|
-
const limitsText = settings.menuShowQuotaCooldown === false
|
|
641
|
-
? PREVIEW_LIMITS
|
|
642
|
-
: `${PREVIEW_LIMITS} | ${PREVIEW_LIMIT_COOLDOWNS}`;
|
|
643
|
-
const part = `limits: ${limitsText}`;
|
|
644
|
-
partsByField.set("limits", isLimitsPreviewFocus(focus) || isLimitsCooldownPreviewFocus(focus)
|
|
645
|
-
? highlightPreviewToken(part, ui)
|
|
646
|
-
: part);
|
|
647
|
-
}
|
|
648
|
-
if (settings.menuShowStatusBadge === false) {
|
|
649
|
-
const part = `status: ${PREVIEW_STATUS}`;
|
|
650
|
-
partsByField.set("status", isStatusPreviewFocus(focus) ? highlightPreviewToken(part, ui) : part);
|
|
651
|
-
}
|
|
652
|
-
const orderedParts = normalizeStatuslineFields(settings.menuStatuslineFields)
|
|
653
|
-
.map((field) => partsByField.get(field))
|
|
654
|
-
.filter((part) => typeof part === "string" && part.length > 0);
|
|
655
|
-
if (orderedParts.length > 0) {
|
|
656
|
-
return orderedParts.join(" | ");
|
|
657
|
-
}
|
|
658
|
-
const showsStatusField = normalizeStatuslineFields(settings.menuStatuslineFields).includes("status");
|
|
659
|
-
if (showsStatusField && settings.menuShowStatusBadge !== false) {
|
|
660
|
-
const note = "status text appears only when status badges are hidden";
|
|
661
|
-
return isStatusPreviewFocus(focus) ? highlightPreviewToken(note, ui) : note;
|
|
662
|
-
}
|
|
663
|
-
return "no summary text is visible with current account-list settings";
|
|
664
|
-
}
|
|
665
|
-
function buildAccountListPreview(settings, ui, focus = null) {
|
|
666
|
-
const badges = [];
|
|
667
|
-
if (settings.menuShowCurrentBadge !== false) {
|
|
668
|
-
const currentBadge = "[current]";
|
|
669
|
-
badges.push(isCurrentBadgePreviewFocus(focus)
|
|
670
|
-
? highlightPreviewToken(currentBadge, ui)
|
|
671
|
-
: currentBadge);
|
|
672
|
-
}
|
|
673
|
-
if (settings.menuShowStatusBadge !== false) {
|
|
674
|
-
const statusBadge = "[active]";
|
|
675
|
-
badges.push(isStatusPreviewFocus(focus)
|
|
676
|
-
? highlightPreviewToken(statusBadge, ui)
|
|
677
|
-
: statusBadge);
|
|
678
|
-
}
|
|
679
|
-
const badgeSuffix = badges.length > 0 ? ` ${badges.join(" ")}` : "";
|
|
680
|
-
const accountEmail = isCurrentRowPreviewFocus(focus)
|
|
681
|
-
? highlightPreviewToken(PREVIEW_ACCOUNT_EMAIL, ui)
|
|
682
|
-
: PREVIEW_ACCOUNT_EMAIL;
|
|
683
|
-
const rowDetailMode = resolveMenuLayoutMode(settings) === "expanded-rows"
|
|
684
|
-
? "details shown on all rows"
|
|
685
|
-
: "details shown on selected row only";
|
|
686
|
-
const detailModeText = isExpandedRowsPreviewFocus(focus)
|
|
687
|
-
? highlightPreviewToken(rowDetailMode, ui)
|
|
688
|
-
: rowDetailMode;
|
|
689
|
-
return {
|
|
690
|
-
label: `1. ${accountEmail}${badgeSuffix}`,
|
|
691
|
-
hint: `${buildSummaryPreviewText(settings, ui, focus)}\n${detailModeText}`,
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
197
|
function cloneDashboardSettings(settings) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
showForecastReasons: settings.showForecastReasons,
|
|
700
|
-
showRecommendations: settings.showRecommendations,
|
|
701
|
-
showLiveProbeNotes: settings.showLiveProbeNotes,
|
|
702
|
-
actionAutoReturnMs: settings.actionAutoReturnMs ?? 2_000,
|
|
703
|
-
actionPauseOnKey: settings.actionPauseOnKey ?? true,
|
|
704
|
-
menuAutoFetchLimits: settings.menuAutoFetchLimits ?? true,
|
|
705
|
-
menuSortEnabled: settings.menuSortEnabled ??
|
|
706
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortEnabled ??
|
|
707
|
-
true,
|
|
708
|
-
menuSortMode: settings.menuSortMode ??
|
|
709
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
710
|
-
"ready-first",
|
|
711
|
-
menuSortPinCurrent: settings.menuSortPinCurrent ??
|
|
712
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortPinCurrent ??
|
|
713
|
-
false,
|
|
714
|
-
menuSortQuickSwitchVisibleRow: settings.menuSortQuickSwitchVisibleRow ?? true,
|
|
715
|
-
uiThemePreset: settings.uiThemePreset ?? "green",
|
|
716
|
-
uiAccentColor: settings.uiAccentColor ?? "green",
|
|
717
|
-
menuShowStatusBadge: settings.menuShowStatusBadge ?? true,
|
|
718
|
-
menuShowCurrentBadge: settings.menuShowCurrentBadge ?? true,
|
|
719
|
-
menuShowLastUsed: settings.menuShowLastUsed ?? true,
|
|
720
|
-
menuShowQuotaSummary: settings.menuShowQuotaSummary ?? true,
|
|
721
|
-
menuShowQuotaCooldown: settings.menuShowQuotaCooldown ?? true,
|
|
722
|
-
menuShowFetchStatus: settings.menuShowFetchStatus ?? true,
|
|
723
|
-
menuShowDetailsForUnselectedRows: layoutMode === "expanded-rows",
|
|
724
|
-
menuLayoutMode: layoutMode,
|
|
725
|
-
menuQuotaTtlMs: settings.menuQuotaTtlMs ?? 5 * 60_000,
|
|
726
|
-
menuFocusStyle: settings.menuFocusStyle ?? "row-invert",
|
|
727
|
-
menuHighlightCurrentRow: settings.menuHighlightCurrentRow ?? true,
|
|
728
|
-
menuStatuslineFields: [
|
|
729
|
-
...normalizeStatuslineFields(settings.menuStatuslineFields),
|
|
730
|
-
],
|
|
731
|
-
};
|
|
198
|
+
return cloneDashboardSettingsData(settings, {
|
|
199
|
+
resolveMenuLayoutMode,
|
|
200
|
+
normalizeStatuslineFields,
|
|
201
|
+
});
|
|
732
202
|
}
|
|
733
203
|
function dashboardSettingsEqual(left, right) {
|
|
734
|
-
return (left
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
left.showLiveProbeNotes === right.showLiveProbeNotes &&
|
|
739
|
-
(left.actionAutoReturnMs ?? 2_000) ===
|
|
740
|
-
(right.actionAutoReturnMs ?? 2_000) &&
|
|
741
|
-
(left.actionPauseOnKey ?? true) === (right.actionPauseOnKey ?? true) &&
|
|
742
|
-
(left.menuAutoFetchLimits ?? true) ===
|
|
743
|
-
(right.menuAutoFetchLimits ?? true) &&
|
|
744
|
-
(left.menuSortEnabled ??
|
|
745
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortEnabled ??
|
|
746
|
-
true) ===
|
|
747
|
-
(right.menuSortEnabled ??
|
|
748
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortEnabled ??
|
|
749
|
-
true) &&
|
|
750
|
-
(left.menuSortMode ??
|
|
751
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
752
|
-
"ready-first") ===
|
|
753
|
-
(right.menuSortMode ??
|
|
754
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
755
|
-
"ready-first") &&
|
|
756
|
-
(left.menuSortPinCurrent ??
|
|
757
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortPinCurrent ??
|
|
758
|
-
false) ===
|
|
759
|
-
(right.menuSortPinCurrent ??
|
|
760
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortPinCurrent ??
|
|
761
|
-
false) &&
|
|
762
|
-
(left.menuSortQuickSwitchVisibleRow ?? true) ===
|
|
763
|
-
(right.menuSortQuickSwitchVisibleRow ?? true) &&
|
|
764
|
-
(left.uiThemePreset ?? "green") === (right.uiThemePreset ?? "green") &&
|
|
765
|
-
(left.uiAccentColor ?? "green") === (right.uiAccentColor ?? "green") &&
|
|
766
|
-
(left.menuShowStatusBadge ?? true) ===
|
|
767
|
-
(right.menuShowStatusBadge ?? true) &&
|
|
768
|
-
(left.menuShowCurrentBadge ?? true) ===
|
|
769
|
-
(right.menuShowCurrentBadge ?? true) &&
|
|
770
|
-
(left.menuShowLastUsed ?? true) === (right.menuShowLastUsed ?? true) &&
|
|
771
|
-
(left.menuShowQuotaSummary ?? true) ===
|
|
772
|
-
(right.menuShowQuotaSummary ?? true) &&
|
|
773
|
-
(left.menuShowQuotaCooldown ?? true) ===
|
|
774
|
-
(right.menuShowQuotaCooldown ?? true) &&
|
|
775
|
-
(left.menuShowFetchStatus ?? true) ===
|
|
776
|
-
(right.menuShowFetchStatus ?? true) &&
|
|
777
|
-
resolveMenuLayoutMode(left) === resolveMenuLayoutMode(right) &&
|
|
778
|
-
(left.menuQuotaTtlMs ?? 5 * 60_000) ===
|
|
779
|
-
(right.menuQuotaTtlMs ?? 5 * 60_000) &&
|
|
780
|
-
(left.menuFocusStyle ?? "row-invert") ===
|
|
781
|
-
(right.menuFocusStyle ?? "row-invert") &&
|
|
782
|
-
(left.menuHighlightCurrentRow ?? true) ===
|
|
783
|
-
(right.menuHighlightCurrentRow ?? true) &&
|
|
784
|
-
JSON.stringify(normalizeStatuslineFields(left.menuStatuslineFields)) ===
|
|
785
|
-
JSON.stringify(normalizeStatuslineFields(right.menuStatuslineFields)));
|
|
786
|
-
}
|
|
787
|
-
function cloneBackendPluginConfig(config) {
|
|
788
|
-
const fallbackChain = config.unsupportedCodexFallbackChain;
|
|
789
|
-
return {
|
|
790
|
-
...BACKEND_DEFAULTS,
|
|
791
|
-
...config,
|
|
792
|
-
unsupportedCodexFallbackChain: fallbackChain && typeof fallbackChain === "object"
|
|
793
|
-
? { ...fallbackChain }
|
|
794
|
-
: {},
|
|
795
|
-
};
|
|
796
|
-
}
|
|
797
|
-
function backendSettingsSnapshot(config) {
|
|
798
|
-
const snapshot = {};
|
|
799
|
-
for (const option of BACKEND_TOGGLE_OPTIONS) {
|
|
800
|
-
snapshot[option.key] =
|
|
801
|
-
config[option.key] ?? BACKEND_DEFAULTS[option.key] ?? false;
|
|
802
|
-
}
|
|
803
|
-
for (const option of BACKEND_NUMBER_OPTIONS) {
|
|
804
|
-
snapshot[option.key] =
|
|
805
|
-
config[option.key] ?? BACKEND_DEFAULTS[option.key] ?? option.min;
|
|
806
|
-
}
|
|
807
|
-
return snapshot;
|
|
204
|
+
return dashboardSettingsDataEqual(left, right, {
|
|
205
|
+
resolveMenuLayoutMode,
|
|
206
|
+
normalizeStatuslineFields,
|
|
207
|
+
});
|
|
808
208
|
}
|
|
809
|
-
function
|
|
810
|
-
return (
|
|
811
|
-
JSON.stringify(backendSettingsSnapshot(right)));
|
|
209
|
+
function buildSummaryPreviewText(settings, ui, focus = null) {
|
|
210
|
+
return buildSummaryPreviewTextBase(settings, ui, resolveMenuLayoutMode, focus);
|
|
812
211
|
}
|
|
813
|
-
function
|
|
814
|
-
|
|
815
|
-
return `${Math.round(value)}%`;
|
|
816
|
-
if (option.unit === "count")
|
|
817
|
-
return `${Math.round(value)}`;
|
|
818
|
-
if (value >= 60_000 && value % 60_000 === 0) {
|
|
819
|
-
return `${Math.round(value / 60_000)}m`;
|
|
820
|
-
}
|
|
821
|
-
if (value >= 1_000 && value % 1_000 === 0) {
|
|
822
|
-
return `${Math.round(value / 1_000)}s`;
|
|
823
|
-
}
|
|
824
|
-
return `${Math.round(value)}ms`;
|
|
212
|
+
function buildAccountListPreview(settings, ui, focus = null) {
|
|
213
|
+
return buildAccountListPreviewBase(settings, ui, resolveMenuLayoutMode, focus);
|
|
825
214
|
}
|
|
826
215
|
function clampBackendNumber(option, value) {
|
|
827
216
|
return Math.max(option.min, Math.min(option.max, Math.round(value)));
|
|
828
217
|
}
|
|
829
|
-
function buildBackendSettingsPreview(config, ui, focus = null) {
|
|
830
|
-
const liveSync = config.liveAccountSync ?? BACKEND_DEFAULTS.liveAccountSync ?? true;
|
|
831
|
-
const affinity = config.sessionAffinity ?? BACKEND_DEFAULTS.sessionAffinity ?? true;
|
|
832
|
-
const preemptive = config.preemptiveQuotaEnabled ??
|
|
833
|
-
BACKEND_DEFAULTS.preemptiveQuotaEnabled ??
|
|
834
|
-
true;
|
|
835
|
-
const threshold5h = config.preemptiveQuotaRemainingPercent5h ??
|
|
836
|
-
BACKEND_DEFAULTS.preemptiveQuotaRemainingPercent5h ??
|
|
837
|
-
5;
|
|
838
|
-
const threshold7d = config.preemptiveQuotaRemainingPercent7d ??
|
|
839
|
-
BACKEND_DEFAULTS.preemptiveQuotaRemainingPercent7d ??
|
|
840
|
-
5;
|
|
841
|
-
const fetchTimeout = config.fetchTimeoutMs ?? BACKEND_DEFAULTS.fetchTimeoutMs ?? 60_000;
|
|
842
|
-
const stallTimeout = config.streamStallTimeoutMs ??
|
|
843
|
-
BACKEND_DEFAULTS.streamStallTimeoutMs ??
|
|
844
|
-
45_000;
|
|
845
|
-
const fetchTimeoutOption = BACKEND_NUMBER_OPTION_BY_KEY.get("fetchTimeoutMs");
|
|
846
|
-
const stallTimeoutOption = BACKEND_NUMBER_OPTION_BY_KEY.get("streamStallTimeoutMs");
|
|
847
|
-
const highlightIfFocused = (key, text) => {
|
|
848
|
-
if (focus !== key)
|
|
849
|
-
return text;
|
|
850
|
-
return highlightPreviewToken(text, ui);
|
|
851
|
-
};
|
|
852
|
-
const label = [
|
|
853
|
-
`live sync ${highlightIfFocused("liveAccountSync", liveSync ? "on" : "off")}`,
|
|
854
|
-
`affinity ${highlightIfFocused("sessionAffinity", affinity ? "on" : "off")}`,
|
|
855
|
-
`preemptive ${highlightIfFocused("preemptiveQuotaEnabled", preemptive ? "on" : "off")}`,
|
|
856
|
-
].join(" | ");
|
|
857
|
-
const hint = [
|
|
858
|
-
`thresholds 5h<=${highlightIfFocused("preemptiveQuotaRemainingPercent5h", `${threshold5h}%`)}`,
|
|
859
|
-
`7d<=${highlightIfFocused("preemptiveQuotaRemainingPercent7d", `${threshold7d}%`)}`,
|
|
860
|
-
`timeouts ${highlightIfFocused("fetchTimeoutMs", fetchTimeoutOption ? formatBackendNumberValue(fetchTimeoutOption, fetchTimeout) : `${fetchTimeout}ms`)}/${highlightIfFocused("streamStallTimeoutMs", stallTimeoutOption ? formatBackendNumberValue(stallTimeoutOption, stallTimeout) : `${stallTimeout}ms`)}`,
|
|
861
|
-
].join(" | ");
|
|
862
|
-
return { label, hint };
|
|
863
|
-
}
|
|
864
|
-
function buildBackendConfigPatch(config) {
|
|
865
|
-
const patch = {};
|
|
866
|
-
for (const option of BACKEND_TOGGLE_OPTIONS) {
|
|
867
|
-
const value = config[option.key];
|
|
868
|
-
if (typeof value === "boolean") {
|
|
869
|
-
patch[option.key] = value;
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
for (const option of BACKEND_NUMBER_OPTIONS) {
|
|
873
|
-
const value = config[option.key];
|
|
874
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
875
|
-
patch[option.key] = clampBackendNumber(option, value);
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
return patch;
|
|
879
|
-
}
|
|
880
218
|
function applyUiThemeFromDashboardSettings(settings) {
|
|
881
219
|
const current = getUiRuntimeOptions();
|
|
882
220
|
setUiRuntimeOptions({
|
|
@@ -887,12 +225,6 @@ function applyUiThemeFromDashboardSettings(settings) {
|
|
|
887
225
|
accent: settings.uiAccentColor ?? "green",
|
|
888
226
|
});
|
|
889
227
|
}
|
|
890
|
-
function formatDashboardSettingState(value) {
|
|
891
|
-
return value ? "[x]" : "[ ]";
|
|
892
|
-
}
|
|
893
|
-
function formatMenuSortMode(mode) {
|
|
894
|
-
return mode === "ready-first" ? "Ready-First" : "Manual";
|
|
895
|
-
}
|
|
896
228
|
function resolveMenuLayoutMode(settings) {
|
|
897
229
|
if (settings.menuLayoutMode === "expanded-rows") {
|
|
898
230
|
return "expanded-rows";
|
|
@@ -904,27 +236,8 @@ function resolveMenuLayoutMode(settings) {
|
|
|
904
236
|
? "expanded-rows"
|
|
905
237
|
: "compact-details";
|
|
906
238
|
}
|
|
907
|
-
function formatMenuLayoutMode(mode) {
|
|
908
|
-
return mode === "expanded-rows" ? "Expanded Rows" : "Compact + Details Pane";
|
|
909
|
-
}
|
|
910
|
-
function formatMenuQuotaTtl(ttlMs) {
|
|
911
|
-
if (ttlMs >= 60_000 && ttlMs % 60_000 === 0) {
|
|
912
|
-
return `${Math.round(ttlMs / 60_000)}m`;
|
|
913
|
-
}
|
|
914
|
-
if (ttlMs >= 1_000 && ttlMs % 1_000 === 0) {
|
|
915
|
-
return `${Math.round(ttlMs / 1_000)}s`;
|
|
916
|
-
}
|
|
917
|
-
return `${ttlMs}ms`;
|
|
918
|
-
}
|
|
919
|
-
function clampBackendNumberForTests(settingKey, value) {
|
|
920
|
-
const option = BACKEND_NUMBER_OPTION_BY_KEY.get(settingKey);
|
|
921
|
-
if (!option) {
|
|
922
|
-
throw new Error(`Unknown backend numeric setting key: ${settingKey}`);
|
|
923
|
-
}
|
|
924
|
-
return clampBackendNumber(option, value);
|
|
925
|
-
}
|
|
926
239
|
async function withQueuedRetryForTests(pathKey, task) {
|
|
927
|
-
return withQueuedRetry(pathKey, task);
|
|
240
|
+
return withQueuedRetry(pathKey, task, { sleep });
|
|
928
241
|
}
|
|
929
242
|
async function persistDashboardSettingsSelectionForTests(selected, keys, scope) {
|
|
930
243
|
return persistDashboardSettingsSelection(selected, keys, scope);
|
|
@@ -946,7 +259,7 @@ const __testOnly = {
|
|
|
946
259
|
buildAccountListPreview,
|
|
947
260
|
buildSummaryPreviewText,
|
|
948
261
|
normalizeStatuslineFields,
|
|
949
|
-
reorderField,
|
|
262
|
+
reorderField: reorderStatuslineField,
|
|
950
263
|
promptDashboardDisplaySettings,
|
|
951
264
|
promptStatuslineSettings,
|
|
952
265
|
promptBehaviorSettings,
|
|
@@ -955,1470 +268,249 @@ const __testOnly = {
|
|
|
955
268
|
};
|
|
956
269
|
/* c8 ignore start - interactive prompt flows are covered by integration tests */
|
|
957
270
|
async function promptDashboardDisplaySettings(initial) {
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
return {
|
|
973
|
-
label,
|
|
974
|
-
hint: option.description,
|
|
975
|
-
value: { type: "toggle", key: option.key },
|
|
976
|
-
color,
|
|
977
|
-
};
|
|
978
|
-
});
|
|
979
|
-
const sortMode = draft.menuSortMode ??
|
|
980
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
981
|
-
"ready-first";
|
|
982
|
-
const sortModeItem = {
|
|
983
|
-
label: `Sort mode: ${formatMenuSortMode(sortMode)}`,
|
|
984
|
-
hint: "Applies when smart sort is enabled.",
|
|
985
|
-
value: { type: "cycle-sort-mode" },
|
|
986
|
-
color: sortMode === "ready-first" ? "green" : "yellow",
|
|
987
|
-
};
|
|
988
|
-
const layoutMode = resolveMenuLayoutMode(draft);
|
|
989
|
-
const layoutModeItem = {
|
|
990
|
-
label: `Layout: ${formatMenuLayoutMode(layoutMode)}`,
|
|
991
|
-
hint: "Compact shows one-line rows with a selected details pane.",
|
|
992
|
-
value: { type: "cycle-layout-mode" },
|
|
993
|
-
color: layoutMode === "compact-details" ? "green" : "yellow",
|
|
994
|
-
};
|
|
995
|
-
const items = [
|
|
996
|
-
{
|
|
997
|
-
label: UI_COPY.settings.previewHeading,
|
|
998
|
-
value: { type: "cancel" },
|
|
999
|
-
kind: "heading",
|
|
1000
|
-
},
|
|
1001
|
-
{
|
|
1002
|
-
label: preview.label,
|
|
1003
|
-
hint: preview.hint,
|
|
1004
|
-
value: { type: "cancel" },
|
|
1005
|
-
color: "green",
|
|
1006
|
-
disabled: true,
|
|
1007
|
-
hideUnavailableSuffix: true,
|
|
1008
|
-
},
|
|
1009
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1010
|
-
{
|
|
1011
|
-
label: UI_COPY.settings.displayHeading,
|
|
1012
|
-
value: { type: "cancel" },
|
|
1013
|
-
kind: "heading",
|
|
1014
|
-
},
|
|
1015
|
-
...optionItems,
|
|
1016
|
-
sortModeItem,
|
|
1017
|
-
layoutModeItem,
|
|
1018
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1019
|
-
{
|
|
1020
|
-
label: UI_COPY.settings.resetDefault,
|
|
1021
|
-
value: { type: "reset" },
|
|
1022
|
-
color: "yellow",
|
|
1023
|
-
},
|
|
1024
|
-
{
|
|
1025
|
-
label: UI_COPY.settings.saveAndBack,
|
|
1026
|
-
value: { type: "save" },
|
|
1027
|
-
color: "green",
|
|
1028
|
-
},
|
|
1029
|
-
{
|
|
1030
|
-
label: UI_COPY.settings.backNoSave,
|
|
1031
|
-
value: { type: "cancel" },
|
|
1032
|
-
color: "red",
|
|
1033
|
-
},
|
|
1034
|
-
];
|
|
1035
|
-
const initialCursor = items.findIndex((item) => (item.value.type === "toggle" && item.value.key === focusKey) ||
|
|
1036
|
-
(item.value.type === "cycle-sort-mode" &&
|
|
1037
|
-
focusKey === "menuSortMode") ||
|
|
1038
|
-
(item.value.type === "cycle-layout-mode" &&
|
|
1039
|
-
focusKey === "menuLayoutMode"));
|
|
1040
|
-
const updateFocusedPreview = (cursor) => {
|
|
1041
|
-
const focusedItem = items[cursor];
|
|
1042
|
-
const focusedKey = focusedItem?.value.type === "toggle"
|
|
1043
|
-
? focusedItem.value.key
|
|
1044
|
-
: focusedItem?.value.type === "cycle-sort-mode"
|
|
1045
|
-
? "menuSortMode"
|
|
1046
|
-
: focusedItem?.value.type === "cycle-layout-mode"
|
|
1047
|
-
? "menuLayoutMode"
|
|
1048
|
-
: focusKey;
|
|
1049
|
-
const nextPreview = buildAccountListPreview(draft, ui, focusedKey);
|
|
1050
|
-
const previewItem = items[1];
|
|
1051
|
-
if (!previewItem)
|
|
1052
|
-
return;
|
|
1053
|
-
previewItem.label = nextPreview.label;
|
|
1054
|
-
previewItem.hint = nextPreview.hint;
|
|
1055
|
-
};
|
|
1056
|
-
const result = await select(items, {
|
|
1057
|
-
message: UI_COPY.settings.accountListTitle,
|
|
1058
|
-
subtitle: UI_COPY.settings.accountListSubtitle,
|
|
1059
|
-
help: UI_COPY.settings.accountListHelp,
|
|
1060
|
-
clearScreen: true,
|
|
1061
|
-
theme: ui.theme,
|
|
1062
|
-
selectedEmphasis: "minimal",
|
|
1063
|
-
initialCursor: initialCursor >= 0 ? initialCursor : undefined,
|
|
1064
|
-
onCursorChange: ({ cursor }) => {
|
|
1065
|
-
const focusedItem = items[cursor];
|
|
1066
|
-
if (focusedItem?.value.type === "toggle") {
|
|
1067
|
-
focusKey = focusedItem.value.key;
|
|
1068
|
-
}
|
|
1069
|
-
else if (focusedItem?.value.type === "cycle-sort-mode") {
|
|
1070
|
-
focusKey = "menuSortMode";
|
|
1071
|
-
}
|
|
1072
|
-
else if (focusedItem?.value.type === "cycle-layout-mode") {
|
|
1073
|
-
focusKey = "menuLayoutMode";
|
|
1074
|
-
}
|
|
1075
|
-
updateFocusedPreview(cursor);
|
|
1076
|
-
},
|
|
1077
|
-
onInput: (raw) => {
|
|
1078
|
-
const lower = raw.toLowerCase();
|
|
1079
|
-
if (lower === "q")
|
|
1080
|
-
return { type: "cancel" };
|
|
1081
|
-
if (lower === "s")
|
|
1082
|
-
return { type: "save" };
|
|
1083
|
-
if (lower === "r")
|
|
1084
|
-
return { type: "reset" };
|
|
1085
|
-
if (lower === "m")
|
|
1086
|
-
return { type: "cycle-sort-mode" };
|
|
1087
|
-
if (lower === "l")
|
|
1088
|
-
return { type: "cycle-layout-mode" };
|
|
1089
|
-
const parsed = Number.parseInt(raw, 10);
|
|
1090
|
-
if (Number.isFinite(parsed) &&
|
|
1091
|
-
parsed >= 1 &&
|
|
1092
|
-
parsed <= DASHBOARD_DISPLAY_OPTIONS.length) {
|
|
1093
|
-
const target = DASHBOARD_DISPLAY_OPTIONS[parsed - 1];
|
|
1094
|
-
if (target) {
|
|
1095
|
-
return { type: "toggle", key: target.key };
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
if (parsed === DASHBOARD_DISPLAY_OPTIONS.length + 1) {
|
|
1099
|
-
return { type: "cycle-sort-mode" };
|
|
1100
|
-
}
|
|
1101
|
-
if (parsed === DASHBOARD_DISPLAY_OPTIONS.length + 2) {
|
|
1102
|
-
return { type: "cycle-layout-mode" };
|
|
1103
|
-
}
|
|
1104
|
-
return undefined;
|
|
1105
|
-
},
|
|
1106
|
-
});
|
|
1107
|
-
if (!result || result.type === "cancel") {
|
|
1108
|
-
return null;
|
|
1109
|
-
}
|
|
1110
|
-
if (result.type === "save") {
|
|
1111
|
-
return draft;
|
|
1112
|
-
}
|
|
1113
|
-
if (result.type === "reset") {
|
|
1114
|
-
draft = applyDashboardDefaultsForKeys(draft, ACCOUNT_LIST_PANEL_KEYS);
|
|
1115
|
-
focusKey = DASHBOARD_DISPLAY_OPTIONS[0]?.key ?? focusKey;
|
|
1116
|
-
continue;
|
|
1117
|
-
}
|
|
1118
|
-
if (result.type === "cycle-sort-mode") {
|
|
1119
|
-
const currentMode = draft.menuSortMode ??
|
|
1120
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortMode ??
|
|
1121
|
-
"ready-first";
|
|
1122
|
-
const nextMode = currentMode === "ready-first" ? "manual" : "ready-first";
|
|
1123
|
-
draft = {
|
|
1124
|
-
...draft,
|
|
1125
|
-
menuSortMode: nextMode,
|
|
1126
|
-
menuSortEnabled: nextMode === "ready-first"
|
|
1127
|
-
? true
|
|
1128
|
-
: (draft.menuSortEnabled ??
|
|
1129
|
-
DEFAULT_DASHBOARD_DISPLAY_SETTINGS.menuSortEnabled ??
|
|
1130
|
-
true),
|
|
1131
|
-
};
|
|
1132
|
-
focusKey = "menuSortMode";
|
|
1133
|
-
continue;
|
|
1134
|
-
}
|
|
1135
|
-
if (result.type === "cycle-layout-mode") {
|
|
1136
|
-
const currentLayout = resolveMenuLayoutMode(draft);
|
|
1137
|
-
const nextLayout = currentLayout === "compact-details"
|
|
1138
|
-
? "expanded-rows"
|
|
1139
|
-
: "compact-details";
|
|
1140
|
-
draft = {
|
|
1141
|
-
...draft,
|
|
1142
|
-
menuLayoutMode: nextLayout,
|
|
1143
|
-
menuShowDetailsForUnselectedRows: nextLayout === "expanded-rows",
|
|
1144
|
-
};
|
|
1145
|
-
focusKey = "menuLayoutMode";
|
|
1146
|
-
continue;
|
|
1147
|
-
}
|
|
1148
|
-
focusKey = result.key;
|
|
1149
|
-
draft = {
|
|
1150
|
-
...draft,
|
|
1151
|
-
[result.key]: !draft[result.key],
|
|
1152
|
-
};
|
|
1153
|
-
}
|
|
271
|
+
return promptDashboardDisplaySettingsPanelEntry({
|
|
272
|
+
initial,
|
|
273
|
+
promptDashboardDisplayPanel,
|
|
274
|
+
cloneDashboardSettings,
|
|
275
|
+
buildAccountListPreview,
|
|
276
|
+
formatDashboardSettingState,
|
|
277
|
+
formatMenuSortMode,
|
|
278
|
+
resolveMenuLayoutMode: (settings = DEFAULT_DASHBOARD_DISPLAY_SETTINGS) => resolveMenuLayoutMode(settings),
|
|
279
|
+
formatMenuLayoutMode,
|
|
280
|
+
applyDashboardDefaultsForKeys,
|
|
281
|
+
DASHBOARD_DISPLAY_OPTIONS,
|
|
282
|
+
ACCOUNT_LIST_PANEL_KEYS,
|
|
283
|
+
UI_COPY,
|
|
284
|
+
});
|
|
1154
285
|
}
|
|
1155
286
|
async function configureDashboardDisplaySettings(currentSettings) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
return merged;
|
|
1170
|
-
}
|
|
1171
|
-
function reorderField(fields, key, direction) {
|
|
1172
|
-
const index = fields.indexOf(key);
|
|
1173
|
-
if (index < 0)
|
|
1174
|
-
return fields;
|
|
1175
|
-
const target = index + direction;
|
|
1176
|
-
if (target < 0 || target >= fields.length)
|
|
1177
|
-
return fields;
|
|
1178
|
-
const next = [...fields];
|
|
1179
|
-
const current = next[index];
|
|
1180
|
-
const swap = next[target];
|
|
1181
|
-
if (!current || !swap)
|
|
1182
|
-
return fields;
|
|
1183
|
-
next[index] = swap;
|
|
1184
|
-
next[target] = current;
|
|
1185
|
-
return next;
|
|
287
|
+
return configureDashboardSettingsEntry(currentSettings, {
|
|
288
|
+
configureDashboardSettingsController,
|
|
289
|
+
loadDashboardDisplaySettings,
|
|
290
|
+
promptSettings: promptDashboardDisplaySettings,
|
|
291
|
+
settingsEqual: dashboardSettingsEqual,
|
|
292
|
+
persistSelection: (selected) => persistDashboardSettingsSelection(selected, ACCOUNT_LIST_PANEL_KEYS, "account-list"),
|
|
293
|
+
applyUiThemeFromDashboardSettings,
|
|
294
|
+
isInteractive: () => input.isTTY && output.isTTY,
|
|
295
|
+
getDashboardSettingsPath,
|
|
296
|
+
writeLine: (message) => {
|
|
297
|
+
console.log(message);
|
|
298
|
+
},
|
|
299
|
+
});
|
|
1186
300
|
}
|
|
1187
301
|
async function promptStatuslineSettings(initial) {
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
const key = ordered[index];
|
|
1201
|
-
if (key)
|
|
1202
|
-
orderMap.set(key, index + 1);
|
|
1203
|
-
}
|
|
1204
|
-
const optionItems = STATUSLINE_FIELD_OPTIONS.map((option, index) => {
|
|
1205
|
-
const enabled = selectedSet.has(option.key);
|
|
1206
|
-
const rank = orderMap.get(option.key);
|
|
1207
|
-
const label = `${formatDashboardSettingState(enabled)} ${index + 1}. ${option.label}${rank ? ` (order ${rank})` : ""}`;
|
|
1208
|
-
return {
|
|
1209
|
-
label,
|
|
1210
|
-
hint: option.description,
|
|
1211
|
-
value: { type: "toggle", key: option.key },
|
|
1212
|
-
color: enabled ? "green" : "yellow",
|
|
1213
|
-
};
|
|
1214
|
-
});
|
|
1215
|
-
const items = [
|
|
1216
|
-
{
|
|
1217
|
-
label: UI_COPY.settings.previewHeading,
|
|
1218
|
-
value: { type: "cancel" },
|
|
1219
|
-
kind: "heading",
|
|
1220
|
-
},
|
|
1221
|
-
{
|
|
1222
|
-
label: preview.label,
|
|
1223
|
-
hint: preview.hint,
|
|
1224
|
-
value: { type: "cancel" },
|
|
1225
|
-
color: "green",
|
|
1226
|
-
disabled: true,
|
|
1227
|
-
hideUnavailableSuffix: true,
|
|
1228
|
-
},
|
|
1229
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1230
|
-
{
|
|
1231
|
-
label: UI_COPY.settings.displayHeading,
|
|
1232
|
-
value: { type: "cancel" },
|
|
1233
|
-
kind: "heading",
|
|
1234
|
-
},
|
|
1235
|
-
...optionItems,
|
|
1236
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1237
|
-
{
|
|
1238
|
-
label: UI_COPY.settings.moveUp,
|
|
1239
|
-
value: { type: "move-up", key: focusKey },
|
|
1240
|
-
color: "green",
|
|
1241
|
-
},
|
|
1242
|
-
{
|
|
1243
|
-
label: UI_COPY.settings.moveDown,
|
|
1244
|
-
value: { type: "move-down", key: focusKey },
|
|
1245
|
-
color: "green",
|
|
1246
|
-
},
|
|
1247
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1248
|
-
{
|
|
1249
|
-
label: UI_COPY.settings.resetDefault,
|
|
1250
|
-
value: { type: "reset" },
|
|
1251
|
-
color: "yellow",
|
|
1252
|
-
},
|
|
1253
|
-
{
|
|
1254
|
-
label: UI_COPY.settings.saveAndBack,
|
|
1255
|
-
value: { type: "save" },
|
|
1256
|
-
color: "green",
|
|
1257
|
-
},
|
|
1258
|
-
{
|
|
1259
|
-
label: UI_COPY.settings.backNoSave,
|
|
1260
|
-
value: { type: "cancel" },
|
|
1261
|
-
color: "red",
|
|
1262
|
-
},
|
|
1263
|
-
];
|
|
1264
|
-
const initialCursor = items.findIndex((item) => item.value.type === "toggle" && item.value.key === focusKey);
|
|
1265
|
-
const updateFocusedPreview = (cursor) => {
|
|
1266
|
-
const focusedItem = items[cursor];
|
|
1267
|
-
const focusedKey = focusedItem?.value.type === "toggle" ? focusedItem.value.key : focusKey;
|
|
1268
|
-
const nextPreview = buildAccountListPreview(draft, ui, focusedKey);
|
|
1269
|
-
const previewItem = items[1];
|
|
1270
|
-
if (!previewItem)
|
|
1271
|
-
return;
|
|
1272
|
-
previewItem.label = nextPreview.label;
|
|
1273
|
-
previewItem.hint = nextPreview.hint;
|
|
1274
|
-
};
|
|
1275
|
-
const result = await select(items, {
|
|
1276
|
-
message: UI_COPY.settings.summaryTitle,
|
|
1277
|
-
subtitle: UI_COPY.settings.summarySubtitle,
|
|
1278
|
-
help: UI_COPY.settings.summaryHelp,
|
|
1279
|
-
clearScreen: true,
|
|
1280
|
-
theme: ui.theme,
|
|
1281
|
-
selectedEmphasis: "minimal",
|
|
1282
|
-
initialCursor: initialCursor >= 0 ? initialCursor : undefined,
|
|
1283
|
-
onCursorChange: ({ cursor }) => {
|
|
1284
|
-
const focusedItem = items[cursor];
|
|
1285
|
-
if (focusedItem?.value.type === "toggle") {
|
|
1286
|
-
focusKey = focusedItem.value.key;
|
|
1287
|
-
}
|
|
1288
|
-
updateFocusedPreview(cursor);
|
|
1289
|
-
},
|
|
1290
|
-
onInput: (raw) => {
|
|
1291
|
-
const lower = raw.toLowerCase();
|
|
1292
|
-
if (lower === "q")
|
|
1293
|
-
return { type: "cancel" };
|
|
1294
|
-
if (lower === "s")
|
|
1295
|
-
return { type: "save" };
|
|
1296
|
-
if (lower === "r")
|
|
1297
|
-
return { type: "reset" };
|
|
1298
|
-
if (lower === "[")
|
|
1299
|
-
return { type: "move-up", key: focusKey };
|
|
1300
|
-
if (lower === "]")
|
|
1301
|
-
return { type: "move-down", key: focusKey };
|
|
1302
|
-
const parsed = Number.parseInt(raw, 10);
|
|
1303
|
-
if (Number.isFinite(parsed) &&
|
|
1304
|
-
parsed >= 1 &&
|
|
1305
|
-
parsed <= STATUSLINE_FIELD_OPTIONS.length) {
|
|
1306
|
-
const target = STATUSLINE_FIELD_OPTIONS[parsed - 1];
|
|
1307
|
-
if (target) {
|
|
1308
|
-
return { type: "toggle", key: target.key };
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
return undefined;
|
|
1312
|
-
},
|
|
1313
|
-
});
|
|
1314
|
-
if (!result || result.type === "cancel") {
|
|
1315
|
-
return null;
|
|
1316
|
-
}
|
|
1317
|
-
if (result.type === "save") {
|
|
1318
|
-
return draft;
|
|
1319
|
-
}
|
|
1320
|
-
if (result.type === "reset") {
|
|
1321
|
-
draft = applyDashboardDefaultsForKeys(draft, STATUSLINE_PANEL_KEYS);
|
|
1322
|
-
focusKey = draft.menuStatuslineFields?.[0] ?? "last-used";
|
|
1323
|
-
continue;
|
|
1324
|
-
}
|
|
1325
|
-
if (result.type === "move-up") {
|
|
1326
|
-
draft = {
|
|
1327
|
-
...draft,
|
|
1328
|
-
menuStatuslineFields: reorderField(normalizeStatuslineFields(draft.menuStatuslineFields), result.key, -1),
|
|
1329
|
-
};
|
|
1330
|
-
focusKey = result.key;
|
|
1331
|
-
continue;
|
|
1332
|
-
}
|
|
1333
|
-
if (result.type === "move-down") {
|
|
1334
|
-
draft = {
|
|
1335
|
-
...draft,
|
|
1336
|
-
menuStatuslineFields: reorderField(normalizeStatuslineFields(draft.menuStatuslineFields), result.key, 1),
|
|
1337
|
-
};
|
|
1338
|
-
focusKey = result.key;
|
|
1339
|
-
continue;
|
|
1340
|
-
}
|
|
1341
|
-
focusKey = result.key;
|
|
1342
|
-
const fields = normalizeStatuslineFields(draft.menuStatuslineFields);
|
|
1343
|
-
const isEnabled = fields.includes(result.key);
|
|
1344
|
-
if (isEnabled) {
|
|
1345
|
-
const next = fields.filter((field) => field !== result.key);
|
|
1346
|
-
draft = {
|
|
1347
|
-
...draft,
|
|
1348
|
-
menuStatuslineFields: next.length > 0 ? next : [result.key],
|
|
1349
|
-
};
|
|
1350
|
-
}
|
|
1351
|
-
else {
|
|
1352
|
-
draft = {
|
|
1353
|
-
...draft,
|
|
1354
|
-
menuStatuslineFields: [...fields, result.key],
|
|
1355
|
-
};
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
302
|
+
return promptStatuslineSettingsPanelEntry({
|
|
303
|
+
initial,
|
|
304
|
+
promptStatuslineSettingsPanel,
|
|
305
|
+
cloneDashboardSettings,
|
|
306
|
+
buildAccountListPreview,
|
|
307
|
+
normalizeStatuslineFields,
|
|
308
|
+
formatDashboardSettingState,
|
|
309
|
+
applyDashboardDefaultsForKeys,
|
|
310
|
+
STATUSLINE_FIELD_OPTIONS,
|
|
311
|
+
STATUSLINE_PANEL_KEYS,
|
|
312
|
+
UI_COPY,
|
|
313
|
+
});
|
|
1358
314
|
}
|
|
1359
315
|
async function configureStatuslineSettings(currentSettings) {
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
return merged;
|
|
1374
|
-
}
|
|
1375
|
-
function formatDelayLabel(delayMs) {
|
|
1376
|
-
return delayMs <= 0
|
|
1377
|
-
? "Instant return"
|
|
1378
|
-
: `${Math.round(delayMs / 1000)}s auto-return`;
|
|
316
|
+
return configureDashboardSettingsEntry(currentSettings, {
|
|
317
|
+
configureDashboardSettingsController,
|
|
318
|
+
loadDashboardDisplaySettings,
|
|
319
|
+
promptSettings: promptStatuslineSettings,
|
|
320
|
+
settingsEqual: dashboardSettingsEqual,
|
|
321
|
+
persistSelection: (selected) => persistDashboardSettingsSelection(selected, STATUSLINE_PANEL_KEYS, "summary-fields"),
|
|
322
|
+
applyUiThemeFromDashboardSettings,
|
|
323
|
+
isInteractive: () => input.isTTY && output.isTTY,
|
|
324
|
+
getDashboardSettingsPath,
|
|
325
|
+
writeLine: (message) => {
|
|
326
|
+
console.log(message);
|
|
327
|
+
},
|
|
328
|
+
});
|
|
1379
329
|
}
|
|
1380
330
|
async function promptBehaviorSettings(initial) {
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
const autoFetchLimits = draft.menuAutoFetchLimits ?? true;
|
|
1393
|
-
const fetchStatusVisible = draft.menuShowFetchStatus ?? true;
|
|
1394
|
-
const menuQuotaTtlMs = draft.menuQuotaTtlMs ?? 5 * 60_000;
|
|
1395
|
-
const delayItems = AUTO_RETURN_OPTIONS_MS.map((delayMs) => {
|
|
1396
|
-
const color = currentDelay === delayMs ? "green" : "yellow";
|
|
1397
|
-
return {
|
|
1398
|
-
label: `${currentDelay === delayMs ? "[x]" : "[ ]"} ${formatDelayLabel(delayMs)}`,
|
|
1399
|
-
hint: delayMs === 1_000
|
|
1400
|
-
? "Fastest loop for frequent actions."
|
|
1401
|
-
: delayMs === 2_000
|
|
1402
|
-
? "Balanced default for most users."
|
|
1403
|
-
: "More time to read action output.",
|
|
1404
|
-
value: { type: "set-delay", delayMs },
|
|
1405
|
-
color,
|
|
1406
|
-
};
|
|
1407
|
-
});
|
|
1408
|
-
const pauseColor = pauseOnKey
|
|
1409
|
-
? "green"
|
|
1410
|
-
: "yellow";
|
|
1411
|
-
const items = [
|
|
1412
|
-
{
|
|
1413
|
-
label: UI_COPY.settings.actionTiming,
|
|
1414
|
-
value: { type: "cancel" },
|
|
1415
|
-
kind: "heading",
|
|
1416
|
-
},
|
|
1417
|
-
...delayItems,
|
|
1418
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1419
|
-
{
|
|
1420
|
-
label: `${pauseOnKey ? "[x]" : "[ ]"} Pause on key press`,
|
|
1421
|
-
hint: "Press any key to stop auto-return.",
|
|
1422
|
-
value: { type: "toggle-pause" },
|
|
1423
|
-
color: pauseColor,
|
|
1424
|
-
},
|
|
1425
|
-
{
|
|
1426
|
-
label: `${autoFetchLimits ? "[x]" : "[ ]"} Auto-fetch limits on menu open (5m cache)`,
|
|
1427
|
-
hint: "Refreshes account limits automatically when opening the menu.",
|
|
1428
|
-
value: { type: "toggle-menu-limit-fetch" },
|
|
1429
|
-
color: autoFetchLimits ? "green" : "yellow",
|
|
1430
|
-
},
|
|
1431
|
-
{
|
|
1432
|
-
label: `${fetchStatusVisible ? "[x]" : "[ ]"} Show limit refresh status`,
|
|
1433
|
-
hint: "Shows background fetch progress like [2/7] in menu subtitle.",
|
|
1434
|
-
value: { type: "toggle-menu-fetch-status" },
|
|
1435
|
-
color: fetchStatusVisible ? "green" : "yellow",
|
|
1436
|
-
},
|
|
1437
|
-
{
|
|
1438
|
-
label: `Limit cache TTL: ${formatMenuQuotaTtl(menuQuotaTtlMs)}`,
|
|
1439
|
-
hint: "How fresh cached quota data must be before refresh runs.",
|
|
1440
|
-
value: { type: "set-menu-quota-ttl", ttlMs: menuQuotaTtlMs },
|
|
1441
|
-
color: "yellow",
|
|
1442
|
-
},
|
|
1443
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1444
|
-
{
|
|
1445
|
-
label: UI_COPY.settings.resetDefault,
|
|
1446
|
-
value: { type: "reset" },
|
|
1447
|
-
color: "yellow",
|
|
1448
|
-
},
|
|
1449
|
-
{
|
|
1450
|
-
label: UI_COPY.settings.saveAndBack,
|
|
1451
|
-
value: { type: "save" },
|
|
1452
|
-
color: "green",
|
|
1453
|
-
},
|
|
1454
|
-
{
|
|
1455
|
-
label: UI_COPY.settings.backNoSave,
|
|
1456
|
-
value: { type: "cancel" },
|
|
1457
|
-
color: "red",
|
|
1458
|
-
},
|
|
1459
|
-
];
|
|
1460
|
-
const initialCursor = items.findIndex((item) => {
|
|
1461
|
-
const value = item.value;
|
|
1462
|
-
if (value.type !== focus.type)
|
|
1463
|
-
return false;
|
|
1464
|
-
if (value.type === "set-delay" && focus.type === "set-delay") {
|
|
1465
|
-
return value.delayMs === focus.delayMs;
|
|
1466
|
-
}
|
|
1467
|
-
return true;
|
|
1468
|
-
});
|
|
1469
|
-
const result = await select(items, {
|
|
1470
|
-
message: UI_COPY.settings.behaviorTitle,
|
|
1471
|
-
subtitle: UI_COPY.settings.behaviorSubtitle,
|
|
1472
|
-
help: UI_COPY.settings.behaviorHelp,
|
|
1473
|
-
clearScreen: true,
|
|
1474
|
-
theme: ui.theme,
|
|
1475
|
-
selectedEmphasis: "minimal",
|
|
1476
|
-
initialCursor: initialCursor >= 0 ? initialCursor : undefined,
|
|
1477
|
-
onCursorChange: ({ cursor }) => {
|
|
1478
|
-
const item = items[cursor];
|
|
1479
|
-
if (item && !item.separator && item.kind !== "heading") {
|
|
1480
|
-
focus = item.value;
|
|
1481
|
-
}
|
|
1482
|
-
},
|
|
1483
|
-
onInput: (raw) => {
|
|
1484
|
-
const lower = raw.toLowerCase();
|
|
1485
|
-
if (lower === "q")
|
|
1486
|
-
return { type: "cancel" };
|
|
1487
|
-
if (lower === "s")
|
|
1488
|
-
return { type: "save" };
|
|
1489
|
-
if (lower === "r")
|
|
1490
|
-
return { type: "reset" };
|
|
1491
|
-
if (lower === "p")
|
|
1492
|
-
return { type: "toggle-pause" };
|
|
1493
|
-
if (lower === "l")
|
|
1494
|
-
return { type: "toggle-menu-limit-fetch" };
|
|
1495
|
-
if (lower === "f")
|
|
1496
|
-
return { type: "toggle-menu-fetch-status" };
|
|
1497
|
-
if (lower === "t")
|
|
1498
|
-
return { type: "set-menu-quota-ttl", ttlMs: menuQuotaTtlMs };
|
|
1499
|
-
const parsed = Number.parseInt(raw, 10);
|
|
1500
|
-
if (Number.isFinite(parsed) &&
|
|
1501
|
-
parsed >= 1 &&
|
|
1502
|
-
parsed <= AUTO_RETURN_OPTIONS_MS.length) {
|
|
1503
|
-
const delayMs = AUTO_RETURN_OPTIONS_MS[parsed - 1];
|
|
1504
|
-
if (typeof delayMs === "number")
|
|
1505
|
-
return { type: "set-delay", delayMs };
|
|
1506
|
-
}
|
|
1507
|
-
return undefined;
|
|
1508
|
-
},
|
|
1509
|
-
});
|
|
1510
|
-
if (!result || result.type === "cancel")
|
|
1511
|
-
return null;
|
|
1512
|
-
if (result.type === "save")
|
|
1513
|
-
return draft;
|
|
1514
|
-
if (result.type === "reset") {
|
|
1515
|
-
draft = applyDashboardDefaultsForKeys(draft, BEHAVIOR_PANEL_KEYS);
|
|
1516
|
-
focus = { type: "set-delay", delayMs: draft.actionAutoReturnMs ?? 2_000 };
|
|
1517
|
-
continue;
|
|
1518
|
-
}
|
|
1519
|
-
if (result.type === "toggle-pause") {
|
|
1520
|
-
draft = {
|
|
1521
|
-
...draft,
|
|
1522
|
-
actionPauseOnKey: !(draft.actionPauseOnKey ?? true),
|
|
1523
|
-
};
|
|
1524
|
-
focus = result;
|
|
1525
|
-
continue;
|
|
1526
|
-
}
|
|
1527
|
-
if (result.type === "toggle-menu-limit-fetch") {
|
|
1528
|
-
draft = {
|
|
1529
|
-
...draft,
|
|
1530
|
-
menuAutoFetchLimits: !(draft.menuAutoFetchLimits ?? true),
|
|
1531
|
-
};
|
|
1532
|
-
focus = result;
|
|
1533
|
-
continue;
|
|
1534
|
-
}
|
|
1535
|
-
if (result.type === "toggle-menu-fetch-status") {
|
|
1536
|
-
draft = {
|
|
1537
|
-
...draft,
|
|
1538
|
-
menuShowFetchStatus: !(draft.menuShowFetchStatus ?? true),
|
|
1539
|
-
};
|
|
1540
|
-
focus = result;
|
|
1541
|
-
continue;
|
|
1542
|
-
}
|
|
1543
|
-
if (result.type === "set-menu-quota-ttl") {
|
|
1544
|
-
const currentIndex = MENU_QUOTA_TTL_OPTIONS_MS.findIndex((value) => value === menuQuotaTtlMs);
|
|
1545
|
-
const nextIndex = currentIndex < 0
|
|
1546
|
-
? 0
|
|
1547
|
-
: (currentIndex + 1) % MENU_QUOTA_TTL_OPTIONS_MS.length;
|
|
1548
|
-
const nextTtl = MENU_QUOTA_TTL_OPTIONS_MS[nextIndex] ??
|
|
1549
|
-
MENU_QUOTA_TTL_OPTIONS_MS[0] ??
|
|
1550
|
-
menuQuotaTtlMs;
|
|
1551
|
-
draft = {
|
|
1552
|
-
...draft,
|
|
1553
|
-
menuQuotaTtlMs: nextTtl,
|
|
1554
|
-
};
|
|
1555
|
-
focus = { type: "set-menu-quota-ttl", ttlMs: nextTtl };
|
|
1556
|
-
continue;
|
|
1557
|
-
}
|
|
1558
|
-
draft = {
|
|
1559
|
-
...draft,
|
|
1560
|
-
actionAutoReturnMs: result.delayMs,
|
|
1561
|
-
};
|
|
1562
|
-
focus = result;
|
|
1563
|
-
}
|
|
331
|
+
return promptBehaviorSettingsPanelEntry({
|
|
332
|
+
initial,
|
|
333
|
+
promptBehaviorSettingsPanel,
|
|
334
|
+
cloneDashboardSettings,
|
|
335
|
+
applyDashboardDefaultsForKeys,
|
|
336
|
+
formatMenuQuotaTtl,
|
|
337
|
+
AUTO_RETURN_OPTIONS_MS,
|
|
338
|
+
MENU_QUOTA_TTL_OPTIONS_MS,
|
|
339
|
+
BEHAVIOR_PANEL_KEYS,
|
|
340
|
+
UI_COPY,
|
|
341
|
+
});
|
|
1564
342
|
}
|
|
1565
343
|
async function promptThemeSettings(initial) {
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
const accent = draft.uiAccentColor ?? "green";
|
|
1578
|
-
const paletteItems = THEME_PRESET_OPTIONS.map((candidate, index) => {
|
|
1579
|
-
const color = palette === candidate ? "green" : "yellow";
|
|
1580
|
-
return {
|
|
1581
|
-
label: `${palette === candidate ? "[x]" : "[ ]"} ${index + 1}. ${candidate === "green" ? "Green base" : "Blue base"}`,
|
|
1582
|
-
hint: candidate === "green"
|
|
1583
|
-
? "High-contrast default."
|
|
1584
|
-
: "Codex-style blue look.",
|
|
1585
|
-
value: { type: "set-palette", palette: candidate },
|
|
1586
|
-
color,
|
|
1587
|
-
};
|
|
1588
|
-
});
|
|
1589
|
-
const accentItems = ACCENT_COLOR_OPTIONS.map((candidate) => {
|
|
1590
|
-
const color = accent === candidate ? "green" : "yellow";
|
|
1591
|
-
return {
|
|
1592
|
-
label: `${accent === candidate ? "[x]" : "[ ]"} ${candidate}`,
|
|
1593
|
-
value: { type: "set-accent", accent: candidate },
|
|
1594
|
-
color,
|
|
1595
|
-
};
|
|
1596
|
-
});
|
|
1597
|
-
const items = [
|
|
1598
|
-
{
|
|
1599
|
-
label: UI_COPY.settings.baseTheme,
|
|
1600
|
-
value: { type: "cancel" },
|
|
1601
|
-
kind: "heading",
|
|
1602
|
-
},
|
|
1603
|
-
...paletteItems,
|
|
1604
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1605
|
-
{
|
|
1606
|
-
label: UI_COPY.settings.accentColor,
|
|
1607
|
-
value: { type: "cancel" },
|
|
1608
|
-
kind: "heading",
|
|
1609
|
-
},
|
|
1610
|
-
...accentItems,
|
|
1611
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1612
|
-
{
|
|
1613
|
-
label: UI_COPY.settings.resetDefault,
|
|
1614
|
-
value: { type: "reset" },
|
|
1615
|
-
color: "yellow",
|
|
1616
|
-
},
|
|
1617
|
-
{
|
|
1618
|
-
label: UI_COPY.settings.saveAndBack,
|
|
1619
|
-
value: { type: "save" },
|
|
1620
|
-
color: "green",
|
|
1621
|
-
},
|
|
1622
|
-
{
|
|
1623
|
-
label: UI_COPY.settings.backNoSave,
|
|
1624
|
-
value: { type: "cancel" },
|
|
1625
|
-
color: "red",
|
|
1626
|
-
},
|
|
1627
|
-
];
|
|
1628
|
-
const initialCursor = items.findIndex((item) => {
|
|
1629
|
-
const value = item.value;
|
|
1630
|
-
if (value.type !== focus.type)
|
|
1631
|
-
return false;
|
|
1632
|
-
if (value.type === "set-palette" && focus.type === "set-palette") {
|
|
1633
|
-
return value.palette === focus.palette;
|
|
1634
|
-
}
|
|
1635
|
-
if (value.type === "set-accent" && focus.type === "set-accent") {
|
|
1636
|
-
return value.accent === focus.accent;
|
|
1637
|
-
}
|
|
1638
|
-
return true;
|
|
1639
|
-
});
|
|
1640
|
-
const result = await select(items, {
|
|
1641
|
-
message: UI_COPY.settings.themeTitle,
|
|
1642
|
-
subtitle: UI_COPY.settings.themeSubtitle,
|
|
1643
|
-
help: UI_COPY.settings.themeHelp,
|
|
1644
|
-
clearScreen: true,
|
|
1645
|
-
theme: ui.theme,
|
|
1646
|
-
selectedEmphasis: "minimal",
|
|
1647
|
-
initialCursor: initialCursor >= 0 ? initialCursor : undefined,
|
|
1648
|
-
onCursorChange: ({ cursor }) => {
|
|
1649
|
-
const item = items[cursor];
|
|
1650
|
-
if (item && !item.separator && item.kind !== "heading") {
|
|
1651
|
-
focus = item.value;
|
|
1652
|
-
}
|
|
1653
|
-
},
|
|
1654
|
-
onInput: (raw) => {
|
|
1655
|
-
const lower = raw.toLowerCase();
|
|
1656
|
-
if (lower === "q")
|
|
1657
|
-
return { type: "cancel" };
|
|
1658
|
-
if (lower === "s")
|
|
1659
|
-
return { type: "save" };
|
|
1660
|
-
if (lower === "r")
|
|
1661
|
-
return { type: "reset" };
|
|
1662
|
-
if (raw === "1")
|
|
1663
|
-
return { type: "set-palette", palette: "green" };
|
|
1664
|
-
if (raw === "2")
|
|
1665
|
-
return { type: "set-palette", palette: "blue" };
|
|
1666
|
-
return undefined;
|
|
1667
|
-
},
|
|
1668
|
-
});
|
|
1669
|
-
if (!result || result.type === "cancel") {
|
|
1670
|
-
applyUiThemeFromDashboardSettings(baseline);
|
|
1671
|
-
return null;
|
|
1672
|
-
}
|
|
1673
|
-
if (result.type === "save")
|
|
1674
|
-
return draft;
|
|
1675
|
-
if (result.type === "reset") {
|
|
1676
|
-
draft = applyDashboardDefaultsForKeys(draft, THEME_PANEL_KEYS);
|
|
1677
|
-
focus = { type: "set-palette", palette: draft.uiThemePreset ?? "green" };
|
|
1678
|
-
applyUiThemeFromDashboardSettings(draft);
|
|
1679
|
-
continue;
|
|
1680
|
-
}
|
|
1681
|
-
if (result.type === "set-palette") {
|
|
1682
|
-
draft = { ...draft, uiThemePreset: result.palette };
|
|
1683
|
-
focus = result;
|
|
1684
|
-
applyUiThemeFromDashboardSettings(draft);
|
|
1685
|
-
continue;
|
|
1686
|
-
}
|
|
1687
|
-
draft = { ...draft, uiAccentColor: result.accent };
|
|
1688
|
-
focus = result;
|
|
1689
|
-
applyUiThemeFromDashboardSettings(draft);
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
function resolveFocusedBackendNumberKey(focus, numberOptions = BACKEND_NUMBER_OPTIONS) {
|
|
1693
|
-
const numberKeys = new Set(numberOptions.map((option) => option.key));
|
|
1694
|
-
if (focus && numberKeys.has(focus)) {
|
|
1695
|
-
return focus;
|
|
1696
|
-
}
|
|
1697
|
-
return numberOptions[0]?.key ?? "fetchTimeoutMs";
|
|
1698
|
-
}
|
|
1699
|
-
function getBackendCategory(key) {
|
|
1700
|
-
return (BACKEND_CATEGORY_OPTIONS.find((category) => category.key === key) ?? null);
|
|
1701
|
-
}
|
|
1702
|
-
function getBackendCategoryInitialFocus(category) {
|
|
1703
|
-
const firstToggle = category.toggleKeys[0];
|
|
1704
|
-
if (firstToggle)
|
|
1705
|
-
return firstToggle;
|
|
1706
|
-
return category.numberKeys[0] ?? null;
|
|
1707
|
-
}
|
|
1708
|
-
function applyBackendCategoryDefaults(draft, category) {
|
|
1709
|
-
const next = { ...draft };
|
|
1710
|
-
for (const key of category.toggleKeys) {
|
|
1711
|
-
next[key] = BACKEND_DEFAULTS[key] ?? false;
|
|
1712
|
-
}
|
|
1713
|
-
for (const key of category.numberKeys) {
|
|
1714
|
-
const option = BACKEND_NUMBER_OPTION_BY_KEY.get(key);
|
|
1715
|
-
const fallback = option?.min ?? 0;
|
|
1716
|
-
next[key] = BACKEND_DEFAULTS[key] ?? fallback;
|
|
1717
|
-
}
|
|
1718
|
-
return next;
|
|
344
|
+
return promptThemeSettingsPanelEntry({
|
|
345
|
+
initial,
|
|
346
|
+
promptThemeSettingsPanel,
|
|
347
|
+
cloneDashboardSettings,
|
|
348
|
+
applyDashboardDefaultsForKeys,
|
|
349
|
+
applyUiThemeFromDashboardSettings,
|
|
350
|
+
THEME_PRESET_OPTIONS,
|
|
351
|
+
ACCENT_COLOR_OPTIONS,
|
|
352
|
+
THEME_PANEL_KEYS,
|
|
353
|
+
UI_COPY,
|
|
354
|
+
});
|
|
1719
355
|
}
|
|
1720
356
|
async function promptBackendCategorySettings(initial, category, initialFocus) {
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
});
|
|
1746
|
-
const numberItems = numberOptions.map((option) => {
|
|
1747
|
-
const rawValue = draft[option.key] ?? BACKEND_DEFAULTS[option.key] ?? option.min;
|
|
1748
|
-
const numericValue = typeof rawValue === "number" && Number.isFinite(rawValue)
|
|
1749
|
-
? rawValue
|
|
1750
|
-
: option.min;
|
|
1751
|
-
const clampedValue = clampBackendNumber(option, numericValue);
|
|
1752
|
-
const valueLabel = formatBackendNumberValue(option, clampedValue);
|
|
1753
|
-
return {
|
|
1754
|
-
label: `${option.label}: ${valueLabel}`,
|
|
1755
|
-
hint: `${option.description} Step ${formatBackendNumberValue(option, option.step)}.`,
|
|
1756
|
-
value: { type: "bump", key: option.key, direction: 1 },
|
|
1757
|
-
color: "yellow",
|
|
1758
|
-
};
|
|
1759
|
-
});
|
|
1760
|
-
const focusedNumberKey = resolveFocusedBackendNumberKey(focusKey, numberOptions);
|
|
1761
|
-
const items = [
|
|
1762
|
-
{
|
|
1763
|
-
label: UI_COPY.settings.previewHeading,
|
|
1764
|
-
value: { type: "back" },
|
|
1765
|
-
kind: "heading",
|
|
1766
|
-
},
|
|
1767
|
-
{
|
|
1768
|
-
label: preview.label,
|
|
1769
|
-
hint: preview.hint,
|
|
1770
|
-
value: { type: "back" },
|
|
1771
|
-
disabled: true,
|
|
1772
|
-
color: "green",
|
|
1773
|
-
hideUnavailableSuffix: true,
|
|
1774
|
-
},
|
|
1775
|
-
{ label: "", value: { type: "back" }, separator: true },
|
|
1776
|
-
{
|
|
1777
|
-
label: UI_COPY.settings.backendToggleHeading,
|
|
1778
|
-
value: { type: "back" },
|
|
1779
|
-
kind: "heading",
|
|
1780
|
-
},
|
|
1781
|
-
...toggleItems,
|
|
1782
|
-
{ label: "", value: { type: "back" }, separator: true },
|
|
1783
|
-
{
|
|
1784
|
-
label: UI_COPY.settings.backendNumberHeading,
|
|
1785
|
-
value: { type: "back" },
|
|
1786
|
-
kind: "heading",
|
|
1787
|
-
},
|
|
1788
|
-
...numberItems,
|
|
1789
|
-
];
|
|
1790
|
-
if (numberOptions.length > 0) {
|
|
1791
|
-
items.push({ label: "", value: { type: "back" }, separator: true });
|
|
1792
|
-
items.push({
|
|
1793
|
-
label: UI_COPY.settings.backendDecrease,
|
|
1794
|
-
value: { type: "bump", key: focusedNumberKey, direction: -1 },
|
|
1795
|
-
color: "yellow",
|
|
1796
|
-
});
|
|
1797
|
-
items.push({
|
|
1798
|
-
label: UI_COPY.settings.backendIncrease,
|
|
1799
|
-
value: { type: "bump", key: focusedNumberKey, direction: 1 },
|
|
1800
|
-
color: "green",
|
|
1801
|
-
});
|
|
1802
|
-
}
|
|
1803
|
-
items.push({ label: "", value: { type: "back" }, separator: true });
|
|
1804
|
-
items.push({
|
|
1805
|
-
label: UI_COPY.settings.backendResetCategory,
|
|
1806
|
-
value: { type: "reset-category" },
|
|
1807
|
-
color: "yellow",
|
|
1808
|
-
});
|
|
1809
|
-
items.push({
|
|
1810
|
-
label: UI_COPY.settings.backendBackToCategories,
|
|
1811
|
-
value: { type: "back" },
|
|
1812
|
-
color: "red",
|
|
1813
|
-
});
|
|
1814
|
-
const initialCursor = items.findIndex((item) => {
|
|
1815
|
-
if (item.separator || item.disabled || item.kind === "heading")
|
|
1816
|
-
return false;
|
|
1817
|
-
if (item.value.type === "toggle" && focusKey === item.value.key)
|
|
1818
|
-
return true;
|
|
1819
|
-
if (item.value.type === "bump" && focusKey === item.value.key)
|
|
1820
|
-
return true;
|
|
1821
|
-
return false;
|
|
1822
|
-
});
|
|
1823
|
-
const result = await select(items, {
|
|
1824
|
-
message: `${UI_COPY.settings.backendCategoryTitle}: ${category.label}`,
|
|
1825
|
-
subtitle: category.description,
|
|
1826
|
-
help: UI_COPY.settings.backendCategoryHelp,
|
|
1827
|
-
clearScreen: true,
|
|
1828
|
-
theme: ui.theme,
|
|
1829
|
-
selectedEmphasis: "minimal",
|
|
1830
|
-
initialCursor: initialCursor >= 0 ? initialCursor : undefined,
|
|
1831
|
-
onCursorChange: ({ cursor }) => {
|
|
1832
|
-
const focusedItem = items[cursor];
|
|
1833
|
-
if (focusedItem?.value.type === "toggle" ||
|
|
1834
|
-
focusedItem?.value.type === "bump") {
|
|
1835
|
-
focusKey = focusedItem.value.key;
|
|
1836
|
-
}
|
|
1837
|
-
},
|
|
1838
|
-
onInput: (raw) => {
|
|
1839
|
-
const lower = raw.toLowerCase();
|
|
1840
|
-
if (lower === "q")
|
|
1841
|
-
return { type: "back" };
|
|
1842
|
-
if (lower === "r")
|
|
1843
|
-
return { type: "reset-category" };
|
|
1844
|
-
if (numberOptions.length > 0 &&
|
|
1845
|
-
(lower === "+" || lower === "=" || lower === "]" || lower === "d")) {
|
|
1846
|
-
return {
|
|
1847
|
-
type: "bump",
|
|
1848
|
-
key: resolveFocusedBackendNumberKey(focusKey, numberOptions),
|
|
1849
|
-
direction: 1,
|
|
1850
|
-
};
|
|
1851
|
-
}
|
|
1852
|
-
if (numberOptions.length > 0 &&
|
|
1853
|
-
(lower === "-" || lower === "[" || lower === "a")) {
|
|
1854
|
-
return {
|
|
1855
|
-
type: "bump",
|
|
1856
|
-
key: resolveFocusedBackendNumberKey(focusKey, numberOptions),
|
|
1857
|
-
direction: -1,
|
|
1858
|
-
};
|
|
1859
|
-
}
|
|
1860
|
-
const parsed = Number.parseInt(raw, 10);
|
|
1861
|
-
if (Number.isFinite(parsed) &&
|
|
1862
|
-
parsed >= 1 &&
|
|
1863
|
-
parsed <= toggleOptions.length) {
|
|
1864
|
-
const target = toggleOptions[parsed - 1];
|
|
1865
|
-
if (target)
|
|
1866
|
-
return { type: "toggle", key: target.key };
|
|
1867
|
-
}
|
|
1868
|
-
return undefined;
|
|
1869
|
-
},
|
|
1870
|
-
});
|
|
1871
|
-
if (!result || result.type === "back") {
|
|
1872
|
-
return { draft, focusKey };
|
|
1873
|
-
}
|
|
1874
|
-
if (result.type === "reset-category") {
|
|
1875
|
-
draft = applyBackendCategoryDefaults(draft, category);
|
|
1876
|
-
focusKey = getBackendCategoryInitialFocus(category);
|
|
1877
|
-
continue;
|
|
1878
|
-
}
|
|
1879
|
-
if (result.type === "toggle") {
|
|
1880
|
-
const currentValue = draft[result.key] ?? BACKEND_DEFAULTS[result.key] ?? false;
|
|
1881
|
-
draft = { ...draft, [result.key]: !currentValue };
|
|
1882
|
-
focusKey = result.key;
|
|
1883
|
-
continue;
|
|
1884
|
-
}
|
|
1885
|
-
const option = BACKEND_NUMBER_OPTION_BY_KEY.get(result.key);
|
|
1886
|
-
if (!option)
|
|
1887
|
-
continue;
|
|
1888
|
-
const currentValue = draft[result.key] ?? BACKEND_DEFAULTS[result.key] ?? option.min;
|
|
1889
|
-
const numericCurrent = typeof currentValue === "number" && Number.isFinite(currentValue)
|
|
1890
|
-
? currentValue
|
|
1891
|
-
: option.min;
|
|
1892
|
-
draft = {
|
|
1893
|
-
...draft,
|
|
1894
|
-
[result.key]: clampBackendNumber(option, numericCurrent + option.step * result.direction),
|
|
1895
|
-
};
|
|
1896
|
-
focusKey = result.key;
|
|
1897
|
-
}
|
|
357
|
+
return promptBackendCategorySettingsEntry({
|
|
358
|
+
initial,
|
|
359
|
+
category,
|
|
360
|
+
initialFocus,
|
|
361
|
+
promptBackendCategorySettingsMenu,
|
|
362
|
+
ui: getUiRuntimeOptions(),
|
|
363
|
+
cloneBackendPluginConfig,
|
|
364
|
+
buildBackendSettingsPreview,
|
|
365
|
+
highlightPreviewToken,
|
|
366
|
+
resolveFocusedBackendNumberKey,
|
|
367
|
+
clampBackendNumber,
|
|
368
|
+
formatBackendNumberValue,
|
|
369
|
+
formatDashboardSettingState,
|
|
370
|
+
applyBackendCategoryDefaults: (config, selectedCategory) => applyBackendCategoryDefaults(config, selectedCategory, {
|
|
371
|
+
backendDefaults: BACKEND_DEFAULTS,
|
|
372
|
+
numberOptionByKey: BACKEND_NUMBER_OPTION_BY_KEY,
|
|
373
|
+
}),
|
|
374
|
+
getBackendCategoryInitialFocus,
|
|
375
|
+
backendDefaults: BACKEND_DEFAULTS,
|
|
376
|
+
toggleOptionByKey: BACKEND_TOGGLE_OPTION_BY_KEY,
|
|
377
|
+
numberOptionByKey: BACKEND_NUMBER_OPTION_BY_KEY,
|
|
378
|
+
select,
|
|
379
|
+
copy: UI_COPY.settings,
|
|
380
|
+
});
|
|
1898
381
|
}
|
|
1899
382
|
async function promptBackendSettings(initial) {
|
|
1900
|
-
|
|
383
|
+
const interactive = input.isTTY && output.isTTY;
|
|
384
|
+
if (!interactive) {
|
|
1901
385
|
return null;
|
|
1902
|
-
const ui = getUiRuntimeOptions();
|
|
1903
|
-
let draft = cloneBackendPluginConfig(initial);
|
|
1904
|
-
let activeCategory = BACKEND_CATEGORY_OPTIONS[0]?.key ?? "session-sync";
|
|
1905
|
-
const focusByCategory = {};
|
|
1906
|
-
for (const category of BACKEND_CATEGORY_OPTIONS) {
|
|
1907
|
-
focusByCategory[category.key] = getBackendCategoryInitialFocus(category);
|
|
1908
|
-
}
|
|
1909
|
-
while (true) {
|
|
1910
|
-
const previewFocus = focusByCategory[activeCategory] ?? null;
|
|
1911
|
-
const preview = buildBackendSettingsPreview(draft, ui, previewFocus);
|
|
1912
|
-
const categoryItems = BACKEND_CATEGORY_OPTIONS.map((category, index) => {
|
|
1913
|
-
return {
|
|
1914
|
-
label: `${index + 1}. ${category.label}`,
|
|
1915
|
-
hint: category.description,
|
|
1916
|
-
value: { type: "open-category", key: category.key },
|
|
1917
|
-
color: "green",
|
|
1918
|
-
};
|
|
1919
|
-
});
|
|
1920
|
-
const items = [
|
|
1921
|
-
{
|
|
1922
|
-
label: UI_COPY.settings.previewHeading,
|
|
1923
|
-
value: { type: "cancel" },
|
|
1924
|
-
kind: "heading",
|
|
1925
|
-
},
|
|
1926
|
-
{
|
|
1927
|
-
label: preview.label,
|
|
1928
|
-
hint: preview.hint,
|
|
1929
|
-
value: { type: "cancel" },
|
|
1930
|
-
disabled: true,
|
|
1931
|
-
color: "green",
|
|
1932
|
-
hideUnavailableSuffix: true,
|
|
1933
|
-
},
|
|
1934
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1935
|
-
{
|
|
1936
|
-
label: UI_COPY.settings.backendCategoriesHeading,
|
|
1937
|
-
value: { type: "cancel" },
|
|
1938
|
-
kind: "heading",
|
|
1939
|
-
},
|
|
1940
|
-
...categoryItems,
|
|
1941
|
-
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1942
|
-
{
|
|
1943
|
-
label: UI_COPY.settings.resetDefault,
|
|
1944
|
-
value: { type: "reset" },
|
|
1945
|
-
color: "yellow",
|
|
1946
|
-
},
|
|
1947
|
-
{
|
|
1948
|
-
label: UI_COPY.settings.saveAndBack,
|
|
1949
|
-
value: { type: "save" },
|
|
1950
|
-
color: "green",
|
|
1951
|
-
},
|
|
1952
|
-
{
|
|
1953
|
-
label: UI_COPY.settings.backNoSave,
|
|
1954
|
-
value: { type: "cancel" },
|
|
1955
|
-
color: "red",
|
|
1956
|
-
},
|
|
1957
|
-
];
|
|
1958
|
-
const initialCursor = items.findIndex((item) => {
|
|
1959
|
-
if (item.separator || item.disabled || item.kind === "heading")
|
|
1960
|
-
return false;
|
|
1961
|
-
return (item.value.type === "open-category" && item.value.key === activeCategory);
|
|
1962
|
-
});
|
|
1963
|
-
const result = await select(items, {
|
|
1964
|
-
message: UI_COPY.settings.backendTitle,
|
|
1965
|
-
subtitle: UI_COPY.settings.backendSubtitle,
|
|
1966
|
-
help: UI_COPY.settings.backendHelp,
|
|
1967
|
-
clearScreen: true,
|
|
1968
|
-
theme: ui.theme,
|
|
1969
|
-
selectedEmphasis: "minimal",
|
|
1970
|
-
initialCursor: initialCursor >= 0 ? initialCursor : undefined,
|
|
1971
|
-
onCursorChange: ({ cursor }) => {
|
|
1972
|
-
const focusedItem = items[cursor];
|
|
1973
|
-
if (focusedItem?.value.type === "open-category") {
|
|
1974
|
-
activeCategory = focusedItem.value.key;
|
|
1975
|
-
}
|
|
1976
|
-
},
|
|
1977
|
-
onInput: (raw) => {
|
|
1978
|
-
const lower = raw.toLowerCase();
|
|
1979
|
-
if (lower === "q")
|
|
1980
|
-
return { type: "cancel" };
|
|
1981
|
-
if (lower === "s")
|
|
1982
|
-
return { type: "save" };
|
|
1983
|
-
if (lower === "r")
|
|
1984
|
-
return { type: "reset" };
|
|
1985
|
-
const parsed = Number.parseInt(raw, 10);
|
|
1986
|
-
if (Number.isFinite(parsed) &&
|
|
1987
|
-
parsed >= 1 &&
|
|
1988
|
-
parsed <= BACKEND_CATEGORY_OPTIONS.length) {
|
|
1989
|
-
const target = BACKEND_CATEGORY_OPTIONS[parsed - 1];
|
|
1990
|
-
if (target)
|
|
1991
|
-
return { type: "open-category", key: target.key };
|
|
1992
|
-
}
|
|
1993
|
-
return undefined;
|
|
1994
|
-
},
|
|
1995
|
-
});
|
|
1996
|
-
if (!result || result.type === "cancel")
|
|
1997
|
-
return null;
|
|
1998
|
-
if (result.type === "save")
|
|
1999
|
-
return draft;
|
|
2000
|
-
if (result.type === "reset") {
|
|
2001
|
-
draft = cloneBackendPluginConfig(BACKEND_DEFAULTS);
|
|
2002
|
-
for (const category of BACKEND_CATEGORY_OPTIONS) {
|
|
2003
|
-
focusByCategory[category.key] =
|
|
2004
|
-
getBackendCategoryInitialFocus(category);
|
|
2005
|
-
}
|
|
2006
|
-
activeCategory = BACKEND_CATEGORY_OPTIONS[0]?.key ?? activeCategory;
|
|
2007
|
-
continue;
|
|
2008
|
-
}
|
|
2009
|
-
const category = getBackendCategory(result.key);
|
|
2010
|
-
if (!category)
|
|
2011
|
-
continue;
|
|
2012
|
-
activeCategory = category.key;
|
|
2013
|
-
const categoryResult = await promptBackendCategorySettings(draft, category, focusByCategory[category.key] ?? getBackendCategoryInitialFocus(category));
|
|
2014
|
-
draft = categoryResult.draft;
|
|
2015
|
-
focusByCategory[category.key] = categoryResult.focusKey;
|
|
2016
386
|
}
|
|
387
|
+
return promptBackendSettingsMenu({
|
|
388
|
+
initial,
|
|
389
|
+
isInteractive: () => interactive,
|
|
390
|
+
ui: getUiRuntimeOptions(),
|
|
391
|
+
cloneBackendPluginConfig,
|
|
392
|
+
backendCategoryOptions: BACKEND_CATEGORY_OPTIONS,
|
|
393
|
+
getBackendCategoryInitialFocus,
|
|
394
|
+
buildBackendSettingsPreview,
|
|
395
|
+
highlightPreviewToken,
|
|
396
|
+
select,
|
|
397
|
+
getBackendCategory,
|
|
398
|
+
promptBackendCategorySettings,
|
|
399
|
+
backendDefaults: BACKEND_DEFAULTS,
|
|
400
|
+
copy: UI_COPY.settings,
|
|
401
|
+
});
|
|
2017
402
|
}
|
|
2018
403
|
async function loadExperimentalSyncTarget() {
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
}
|
|
2026
|
-
try {
|
|
2027
|
-
const raw = JSON.parse(await readFileWithRetry(detection.descriptor.accountPath));
|
|
2028
|
-
const normalized = normalizeAccountStorage(raw);
|
|
2029
|
-
if (!normalized) {
|
|
2030
|
-
return {
|
|
2031
|
-
kind: "error",
|
|
2032
|
-
message: "Invalid target account storage format",
|
|
2033
|
-
};
|
|
2034
|
-
}
|
|
2035
|
-
return { kind: "target", detection, destination: normalized };
|
|
2036
|
-
}
|
|
2037
|
-
catch (error) {
|
|
2038
|
-
const code = error.code;
|
|
2039
|
-
if (code === "ENOENT") {
|
|
2040
|
-
return { kind: "target", detection, destination: null };
|
|
2041
|
-
}
|
|
2042
|
-
return {
|
|
2043
|
-
kind: "error",
|
|
2044
|
-
message: error instanceof Error ? error.message : String(error),
|
|
2045
|
-
};
|
|
2046
|
-
}
|
|
404
|
+
return loadExperimentalSyncTargetEntry({
|
|
405
|
+
loadExperimentalSyncTargetState,
|
|
406
|
+
detectTarget: detectOcChatgptMultiAuthTarget,
|
|
407
|
+
readFileWithRetry,
|
|
408
|
+
normalizeAccountStorage,
|
|
409
|
+
sleep,
|
|
410
|
+
});
|
|
2047
411
|
}
|
|
2048
412
|
async function promptExperimentalSettings(initialConfig) {
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
},
|
|
2092
|
-
{
|
|
2093
|
-
label: UI_COPY.settings.backNoSave,
|
|
2094
|
-
value: { type: "back" },
|
|
2095
|
-
color: "red",
|
|
2096
|
-
},
|
|
2097
|
-
], getExperimentalSelectOptions(ui, UI_COPY.settings.experimentalHelpMenu, mapExperimentalMenuHotkey));
|
|
2098
|
-
if (!action || action.type === "back")
|
|
2099
|
-
return null;
|
|
2100
|
-
if (action.type === "save")
|
|
2101
|
-
return draft;
|
|
2102
|
-
if (action.type === "toggle-refresh-guardian") {
|
|
2103
|
-
draft = {
|
|
2104
|
-
...draft,
|
|
2105
|
-
proactiveRefreshGuardian: !(draft.proactiveRefreshGuardian ?? false),
|
|
2106
|
-
};
|
|
2107
|
-
continue;
|
|
2108
|
-
}
|
|
2109
|
-
if (action.type === "decrease-refresh-interval") {
|
|
2110
|
-
draft = {
|
|
2111
|
-
...draft,
|
|
2112
|
-
proactiveRefreshIntervalMs: Math.max(60_000, (draft.proactiveRefreshIntervalMs ?? 60000) - 60000),
|
|
2113
|
-
};
|
|
2114
|
-
continue;
|
|
2115
|
-
}
|
|
2116
|
-
if (action.type === "increase-refresh-interval") {
|
|
2117
|
-
draft = {
|
|
2118
|
-
...draft,
|
|
2119
|
-
proactiveRefreshIntervalMs: Math.min(600000, (draft.proactiveRefreshIntervalMs ?? 60000) + 60000),
|
|
2120
|
-
};
|
|
2121
|
-
continue;
|
|
2122
|
-
}
|
|
2123
|
-
if (action.type === "backup") {
|
|
2124
|
-
const prompt = createInterface({ input, output });
|
|
2125
|
-
try {
|
|
2126
|
-
const backupName = (await prompt.question(UI_COPY.settings.experimentalBackupPrompt)).trim();
|
|
2127
|
-
if (!backupName || backupName.toLowerCase() === "q") {
|
|
2128
|
-
continue;
|
|
2129
|
-
}
|
|
2130
|
-
try {
|
|
2131
|
-
const backupResult = await runNamedBackupExport({ name: backupName });
|
|
2132
|
-
const backupLabel = backupResult.kind === "exported"
|
|
2133
|
-
? `Saved backup to ${backupResult.path}`
|
|
2134
|
-
: backupResult.kind === "collision"
|
|
2135
|
-
? `Backup already exists: ${backupResult.path}`
|
|
2136
|
-
: backupResult.error instanceof Error
|
|
2137
|
-
? backupResult.error.message
|
|
2138
|
-
: String(backupResult.error);
|
|
2139
|
-
await select([
|
|
2140
|
-
{
|
|
2141
|
-
label: backupLabel,
|
|
2142
|
-
value: { type: "back" },
|
|
2143
|
-
disabled: true,
|
|
2144
|
-
hideUnavailableSuffix: true,
|
|
2145
|
-
color: backupResult.kind === "exported" ? "green" : "yellow",
|
|
2146
|
-
},
|
|
2147
|
-
{
|
|
2148
|
-
label: UI_COPY.settings.back,
|
|
2149
|
-
value: { type: "back" },
|
|
2150
|
-
color: "red",
|
|
2151
|
-
},
|
|
2152
|
-
], getExperimentalSelectOptions(ui, UI_COPY.settings.experimentalHelpStatus, mapExperimentalStatusHotkey));
|
|
2153
|
-
}
|
|
2154
|
-
catch (error) {
|
|
2155
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2156
|
-
await select([
|
|
2157
|
-
{
|
|
2158
|
-
label: message,
|
|
2159
|
-
value: { type: "back" },
|
|
2160
|
-
disabled: true,
|
|
2161
|
-
hideUnavailableSuffix: true,
|
|
2162
|
-
color: "yellow",
|
|
2163
|
-
},
|
|
2164
|
-
{
|
|
2165
|
-
label: UI_COPY.settings.back,
|
|
2166
|
-
value: { type: "back" },
|
|
2167
|
-
color: "red",
|
|
2168
|
-
},
|
|
2169
|
-
], getExperimentalSelectOptions(ui, UI_COPY.settings.experimentalHelpStatus, mapExperimentalStatusHotkey));
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
finally {
|
|
2173
|
-
prompt.close();
|
|
2174
|
-
}
|
|
2175
|
-
continue;
|
|
2176
|
-
}
|
|
2177
|
-
const source = await loadAccounts();
|
|
2178
|
-
const targetState = await loadExperimentalSyncTarget();
|
|
2179
|
-
if (targetState.kind === "error") {
|
|
2180
|
-
await select([
|
|
2181
|
-
{
|
|
2182
|
-
label: targetState.message,
|
|
2183
|
-
value: { type: "back" },
|
|
2184
|
-
disabled: true,
|
|
2185
|
-
hideUnavailableSuffix: true,
|
|
2186
|
-
color: "yellow",
|
|
2187
|
-
},
|
|
2188
|
-
{
|
|
2189
|
-
label: UI_COPY.settings.back,
|
|
2190
|
-
value: { type: "back" },
|
|
2191
|
-
color: "red",
|
|
2192
|
-
},
|
|
2193
|
-
], getExperimentalSelectOptions(ui, UI_COPY.settings.experimentalHelpStatus, mapExperimentalStatusHotkey));
|
|
2194
|
-
continue;
|
|
2195
|
-
}
|
|
2196
|
-
const plan = await planOcChatgptSync({
|
|
2197
|
-
source,
|
|
2198
|
-
destination: targetState.kind === "target" ? targetState.destination : null,
|
|
2199
|
-
dependencies: targetState.kind === "target"
|
|
2200
|
-
? { detectTarget: () => targetState.detection }
|
|
2201
|
-
: undefined,
|
|
2202
|
-
});
|
|
2203
|
-
if (plan.kind !== "ready") {
|
|
2204
|
-
await select([
|
|
2205
|
-
{
|
|
2206
|
-
label: plan.kind === "blocked-ambiguous"
|
|
2207
|
-
? `Sync blocked: ${plan.detection.reason}`
|
|
2208
|
-
: `Sync unavailable: ${plan.detection.reason}`,
|
|
2209
|
-
value: { type: "back" },
|
|
2210
|
-
disabled: true,
|
|
2211
|
-
hideUnavailableSuffix: true,
|
|
2212
|
-
color: "yellow",
|
|
2213
|
-
},
|
|
2214
|
-
{
|
|
2215
|
-
label: UI_COPY.settings.back,
|
|
2216
|
-
value: { type: "back" },
|
|
2217
|
-
color: "red",
|
|
2218
|
-
},
|
|
2219
|
-
], getExperimentalSelectOptions(ui, UI_COPY.settings.experimentalHelpStatus, mapExperimentalStatusHotkey));
|
|
2220
|
-
continue;
|
|
2221
|
-
}
|
|
2222
|
-
const review = await select([
|
|
2223
|
-
{
|
|
2224
|
-
label: `Preview: add ${plan.preview.toAdd.length} | update ${plan.preview.toUpdate.length} | skip ${plan.preview.toSkip.length}`,
|
|
2225
|
-
value: { type: "back" },
|
|
2226
|
-
disabled: true,
|
|
2227
|
-
hideUnavailableSuffix: true,
|
|
2228
|
-
color: "green",
|
|
2229
|
-
},
|
|
2230
|
-
{
|
|
2231
|
-
label: `Preserve destination-only: ${plan.preview.unchangedDestinationOnly.length}`,
|
|
2232
|
-
value: { type: "back" },
|
|
2233
|
-
disabled: true,
|
|
2234
|
-
hideUnavailableSuffix: true,
|
|
2235
|
-
color: "green",
|
|
2236
|
-
},
|
|
2237
|
-
{
|
|
2238
|
-
label: `Active selection: ${plan.preview.activeSelectionBehavior}`,
|
|
2239
|
-
value: { type: "back" },
|
|
2240
|
-
disabled: true,
|
|
2241
|
-
hideUnavailableSuffix: true,
|
|
2242
|
-
color: "green",
|
|
2243
|
-
},
|
|
2244
|
-
{
|
|
2245
|
-
label: UI_COPY.settings.experimentalApplySync,
|
|
2246
|
-
value: { type: "apply" },
|
|
2247
|
-
color: "green",
|
|
2248
|
-
},
|
|
2249
|
-
{
|
|
2250
|
-
label: UI_COPY.settings.backNoSave,
|
|
2251
|
-
value: { type: "back" },
|
|
2252
|
-
color: "red",
|
|
2253
|
-
},
|
|
2254
|
-
], getExperimentalSelectOptions(ui, UI_COPY.settings.experimentalHelpPreview, (raw) => {
|
|
2255
|
-
const lower = raw.toLowerCase();
|
|
2256
|
-
if (lower === "q")
|
|
2257
|
-
return { type: "back" };
|
|
2258
|
-
if (lower === "a")
|
|
2259
|
-
return { type: "apply" };
|
|
2260
|
-
return undefined;
|
|
2261
|
-
}));
|
|
2262
|
-
if (!review || review.type === "back")
|
|
2263
|
-
continue;
|
|
2264
|
-
const applied = await applyOcChatgptSync({
|
|
2265
|
-
source,
|
|
2266
|
-
destination: targetState.kind === "target" ? targetState.destination : undefined,
|
|
2267
|
-
dependencies: targetState.kind === "target"
|
|
2268
|
-
? { detectTarget: () => targetState.detection }
|
|
2269
|
-
: undefined,
|
|
2270
|
-
});
|
|
2271
|
-
await select([
|
|
2272
|
-
{
|
|
2273
|
-
label: applied.kind === "applied"
|
|
2274
|
-
? `Applied sync to ${applied.target.accountPath}`
|
|
2275
|
-
: applied.kind === "error"
|
|
2276
|
-
? applied.error instanceof Error
|
|
2277
|
-
? applied.error.message
|
|
2278
|
-
: String(applied.error)
|
|
413
|
+
return promptExperimentalSettingsEntry({
|
|
414
|
+
initialConfig,
|
|
415
|
+
promptExperimentalSettingsMenu,
|
|
416
|
+
isInteractive: () => input.isTTY && output.isTTY,
|
|
417
|
+
ui: getUiRuntimeOptions(),
|
|
418
|
+
cloneBackendPluginConfig,
|
|
419
|
+
select,
|
|
420
|
+
getExperimentalSelectOptions,
|
|
421
|
+
mapExperimentalMenuHotkey,
|
|
422
|
+
mapExperimentalStatusHotkey,
|
|
423
|
+
formatDashboardSettingState,
|
|
424
|
+
copy: UI_COPY.settings,
|
|
425
|
+
input,
|
|
426
|
+
output,
|
|
427
|
+
runNamedBackupExport,
|
|
428
|
+
loadAccounts,
|
|
429
|
+
loadExperimentalSyncTarget,
|
|
430
|
+
planOcChatgptSync,
|
|
431
|
+
applyOcChatgptSync,
|
|
432
|
+
getTargetKind: (targetState) => targetState.kind,
|
|
433
|
+
getTargetDestination: (targetState) => targetState.destination ?? null,
|
|
434
|
+
getTargetDetection: (targetState) => targetState.detection,
|
|
435
|
+
getTargetErrorMessage: (targetState) => targetState.kind === "error"
|
|
436
|
+
? (targetState.message ?? "Unknown error")
|
|
437
|
+
: null,
|
|
438
|
+
getPlanKind: (plan) => plan.kind,
|
|
439
|
+
getPlanBlockedReason: (plan) => {
|
|
440
|
+
const candidate = plan;
|
|
441
|
+
return candidate.kind === "blocked-ambiguous"
|
|
442
|
+
? `Sync blocked: ${candidate.detection?.reason ?? "unknown"}`
|
|
443
|
+
: `Sync unavailable: ${candidate.detection?.reason ?? "unknown"}`;
|
|
444
|
+
},
|
|
445
|
+
getPlanPreview: (plan) => plan.preview,
|
|
446
|
+
getAppliedLabel: (applied) => {
|
|
447
|
+
const candidate = applied;
|
|
448
|
+
return {
|
|
449
|
+
label: candidate.kind === "applied"
|
|
450
|
+
? `Applied sync to ${candidate.target?.accountPath ?? "target"}`
|
|
451
|
+
: candidate.kind === "error"
|
|
452
|
+
? candidate.error instanceof Error
|
|
453
|
+
? candidate.error.message
|
|
454
|
+
: String(candidate.error)
|
|
2279
455
|
: "Sync did not apply",
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
},
|
|
2285
|
-
{ label: UI_COPY.settings.back, value: { type: "back" }, color: "red" },
|
|
2286
|
-
], getExperimentalSelectOptions(ui, UI_COPY.settings.experimentalHelpStatus, mapExperimentalStatusHotkey));
|
|
2287
|
-
}
|
|
456
|
+
color: candidate.kind === "applied" ? "green" : "yellow",
|
|
457
|
+
};
|
|
458
|
+
},
|
|
459
|
+
});
|
|
2288
460
|
}
|
|
2289
461
|
async function configureBackendSettings(currentConfig) {
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
return persistBackendConfigSelection(selected, "backend");
|
|
2301
|
-
}
|
|
2302
|
-
async function promptSettingsHub(initialFocus = "account-list") {
|
|
2303
|
-
if (!input.isTTY || !output.isTTY)
|
|
2304
|
-
return null;
|
|
2305
|
-
const ui = getUiRuntimeOptions();
|
|
2306
|
-
const items = [
|
|
2307
|
-
{
|
|
2308
|
-
label: UI_COPY.settings.sectionTitle,
|
|
2309
|
-
value: { type: "back" },
|
|
2310
|
-
kind: "heading",
|
|
2311
|
-
},
|
|
2312
|
-
{
|
|
2313
|
-
label: UI_COPY.settings.accountList,
|
|
2314
|
-
value: { type: "account-list" },
|
|
2315
|
-
color: "green",
|
|
2316
|
-
},
|
|
2317
|
-
{
|
|
2318
|
-
label: UI_COPY.settings.summaryFields,
|
|
2319
|
-
value: { type: "summary-fields" },
|
|
2320
|
-
color: "green",
|
|
2321
|
-
},
|
|
2322
|
-
{
|
|
2323
|
-
label: UI_COPY.settings.behavior,
|
|
2324
|
-
value: { type: "behavior" },
|
|
2325
|
-
color: "green",
|
|
2326
|
-
},
|
|
2327
|
-
{ label: UI_COPY.settings.theme, value: { type: "theme" }, color: "green" },
|
|
2328
|
-
{ label: "", value: { type: "back" }, separator: true },
|
|
2329
|
-
{
|
|
2330
|
-
label: UI_COPY.settings.advancedTitle,
|
|
2331
|
-
value: { type: "back" },
|
|
2332
|
-
kind: "heading",
|
|
462
|
+
return configureBackendSettingsEntry(currentConfig, {
|
|
463
|
+
configureBackendSettingsController,
|
|
464
|
+
cloneBackendPluginConfig,
|
|
465
|
+
loadPluginConfig,
|
|
466
|
+
promptBackendSettings,
|
|
467
|
+
backendSettingsEqual,
|
|
468
|
+
persistBackendConfigSelection,
|
|
469
|
+
isInteractive: () => input.isTTY && output.isTTY,
|
|
470
|
+
writeLine: (message) => {
|
|
471
|
+
console.log(message);
|
|
2333
472
|
},
|
|
2334
|
-
{
|
|
2335
|
-
label: UI_COPY.settings.experimental,
|
|
2336
|
-
value: { type: "experimental" },
|
|
2337
|
-
color: "yellow",
|
|
2338
|
-
},
|
|
2339
|
-
{
|
|
2340
|
-
label: UI_COPY.settings.backend,
|
|
2341
|
-
value: { type: "backend" },
|
|
2342
|
-
color: "green",
|
|
2343
|
-
},
|
|
2344
|
-
{ label: "", value: { type: "back" }, separator: true },
|
|
2345
|
-
{
|
|
2346
|
-
label: UI_COPY.settings.exitTitle,
|
|
2347
|
-
value: { type: "back" },
|
|
2348
|
-
kind: "heading",
|
|
2349
|
-
},
|
|
2350
|
-
{ label: UI_COPY.settings.back, value: { type: "back" }, color: "red" },
|
|
2351
|
-
];
|
|
2352
|
-
const initialCursor = items.findIndex((item) => {
|
|
2353
|
-
if (item.separator || item.disabled || item.kind === "heading")
|
|
2354
|
-
return false;
|
|
2355
|
-
return item.value.type === initialFocus;
|
|
2356
473
|
});
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
474
|
+
}
|
|
475
|
+
async function promptSettingsHub(initialFocus = "account-list") {
|
|
476
|
+
return promptSettingsHubEntry({
|
|
477
|
+
initialFocus,
|
|
478
|
+
promptSettingsHubMenu,
|
|
479
|
+
isInteractive: () => input.isTTY && output.isTTY,
|
|
480
|
+
getUiRuntimeOptions,
|
|
481
|
+
buildItems: () => buildSettingsHubItems(UI_COPY.settings),
|
|
482
|
+
findInitialCursor: findSettingsHubInitialCursor,
|
|
483
|
+
select,
|
|
484
|
+
copy: {
|
|
485
|
+
title: UI_COPY.settings.title,
|
|
486
|
+
subtitle: UI_COPY.settings.subtitle,
|
|
487
|
+
help: UI_COPY.settings.help,
|
|
2370
488
|
},
|
|
2371
489
|
});
|
|
2372
490
|
}
|
|
2373
491
|
/* c8 ignore stop */
|
|
2374
492
|
async function configureUnifiedSettings(initialSettings) {
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
current = await persistDashboardSettingsSelection(selected, BEHAVIOR_PANEL_KEYS, "behavior");
|
|
2397
|
-
}
|
|
2398
|
-
continue;
|
|
2399
|
-
}
|
|
2400
|
-
if (action.type === "theme") {
|
|
2401
|
-
const selected = await promptThemeSettings(current);
|
|
2402
|
-
if (selected && !dashboardSettingsEqual(current, selected)) {
|
|
2403
|
-
current = await persistDashboardSettingsSelection(selected, THEME_PANEL_KEYS, "theme");
|
|
2404
|
-
applyUiThemeFromDashboardSettings(current);
|
|
2405
|
-
}
|
|
2406
|
-
continue;
|
|
2407
|
-
}
|
|
2408
|
-
if (action.type === "experimental") {
|
|
2409
|
-
const selected = await promptExperimentalSettings(backendConfig);
|
|
2410
|
-
if (selected && !backendSettingsEqual(backendConfig, selected)) {
|
|
2411
|
-
backendConfig = await persistBackendConfigSelection(selected, "experimental");
|
|
2412
|
-
}
|
|
2413
|
-
else if (selected) {
|
|
2414
|
-
backendConfig = selected;
|
|
2415
|
-
}
|
|
2416
|
-
continue;
|
|
2417
|
-
}
|
|
2418
|
-
if (action.type === "backend") {
|
|
2419
|
-
backendConfig = await configureBackendSettings(backendConfig);
|
|
2420
|
-
}
|
|
2421
|
-
}
|
|
493
|
+
return configureUnifiedSettingsEntry(initialSettings, {
|
|
494
|
+
configureUnifiedSettingsController,
|
|
495
|
+
cloneDashboardSettings,
|
|
496
|
+
cloneBackendPluginConfig,
|
|
497
|
+
loadDashboardDisplaySettings,
|
|
498
|
+
loadPluginConfig,
|
|
499
|
+
applyUiThemeFromDashboardSettings,
|
|
500
|
+
promptSettingsHub: async (focus) => promptSettingsHub(focus),
|
|
501
|
+
configureDashboardDisplaySettings,
|
|
502
|
+
configureStatuslineSettings,
|
|
503
|
+
promptBehaviorSettings,
|
|
504
|
+
promptThemeSettings,
|
|
505
|
+
dashboardSettingsEqual,
|
|
506
|
+
persistDashboardSettingsSelection,
|
|
507
|
+
promptExperimentalSettings,
|
|
508
|
+
backendSettingsEqual,
|
|
509
|
+
persistBackendConfigSelection,
|
|
510
|
+
configureBackendSettings,
|
|
511
|
+
BEHAVIOR_PANEL_KEYS,
|
|
512
|
+
THEME_PANEL_KEYS,
|
|
513
|
+
});
|
|
2422
514
|
}
|
|
2423
515
|
export { configureUnifiedSettings, applyUiThemeFromDashboardSettings, resolveMenuLayoutMode, __testOnly, };
|
|
2424
516
|
//# sourceMappingURL=settings-hub.js.map
|