11import { createInterface } from "node:readline/promises" ;
2+ import type {
3+ ApplyOcChatgptSyncOptions ,
4+ OcChatgptSyncApplyResult ,
5+ OcChatgptSyncPlanResult ,
6+ PlanOcChatgptSyncOptions ,
7+ } from "../oc-chatgpt-orchestrator.js" ;
8+ import type { AccountStorageV3 } from "../storage.js" ;
29import type { PluginConfig } from "../types.js" ;
10+ import type { MenuItem , select } from "../ui/select.js" ;
311import type { UiRuntimeOptions } from "../ui/runtime.js" ;
12+ import type {
13+ ExperimentalSettingsAction ,
14+ getExperimentalSelectOptions ,
15+ mapExperimentalMenuHotkey ,
16+ mapExperimentalStatusHotkey ,
17+ } from "./experimental-settings-schema.js" ;
418
5- export async function promptExperimentalSettingsMenu <
6- TAction ,
19+ export type ExperimentalSettingsCopy = {
20+ experimentalSync : string ;
21+ experimentalBackup : string ;
22+ experimentalRefreshGuard : string ;
23+ experimentalRefreshInterval : string ;
24+ experimentalDecreaseInterval : string ;
25+ experimentalIncreaseInterval : string ;
26+ saveAndBack : string ;
27+ backNoSave : string ;
28+ experimentalHelpMenu : string ;
29+ experimentalBackupPrompt : string ;
30+ back : string ;
31+ experimentalHelpStatus : string ;
32+ experimentalApplySync : string ;
33+ experimentalHelpPreview : string ;
34+ } ;
35+
36+ export type ExperimentalSettingsPromptDeps <
737 TTargetState ,
8- TPlan ,
9- TApplied ,
10- > ( params : {
38+ > = {
1139 initialConfig : PluginConfig ;
1240 isInteractive : ( ) => boolean ;
1341 ui : UiRuntimeOptions ;
1442 cloneBackendPluginConfig : ( config : PluginConfig ) => PluginConfig ;
15- select : < T > (
16- items : Array < Record < string , unknown > > ,
17- options : Record < string , unknown > ,
18- ) => Promise < T | null > ;
19- getExperimentalSelectOptions : (
20- ui : UiRuntimeOptions ,
21- help : string ,
22- hotkeyMapper : ( raw : string ) => TAction | undefined ,
23- ) => Record < string , unknown > ;
24- mapExperimentalMenuHotkey : ( raw : string ) => TAction | undefined ;
25- mapExperimentalStatusHotkey : ( raw : string ) => TAction | undefined ;
43+ select : typeof select ;
44+ getExperimentalSelectOptions : typeof getExperimentalSelectOptions ;
45+ mapExperimentalMenuHotkey : typeof mapExperimentalMenuHotkey ;
46+ mapExperimentalStatusHotkey : typeof mapExperimentalStatusHotkey ;
2647 formatDashboardSettingState : ( enabled : boolean ) => string ;
27- copy : {
28- experimentalSync : string ;
29- experimentalBackup : string ;
30- experimentalRefreshGuard : string ;
31- experimentalRefreshInterval : string ;
32- experimentalDecreaseInterval : string ;
33- experimentalIncreaseInterval : string ;
34- saveAndBack : string ;
35- backNoSave : string ;
36- experimentalHelpMenu : string ;
37- experimentalBackupPrompt : string ;
38- back : string ;
39- experimentalHelpStatus : string ;
40- experimentalApplySync : string ;
41- experimentalHelpPreview : string ;
42- } ;
48+ copy : ExperimentalSettingsCopy ;
4349 input : NodeJS . ReadStream ;
4450 output : NodeJS . WriteStream ;
4551 runNamedBackupExport : ( args : {
4652 name : string ;
4753 } ) => Promise < { kind : string ; path ?: string ; error ?: unknown } > ;
48- loadAccounts : ( ) => Promise < unknown > ;
54+ loadAccounts : ( ) => Promise < AccountStorageV3 | null > ;
4955 loadExperimentalSyncTarget : ( ) => Promise < TTargetState > ;
50- planOcChatgptSync : ( args : Record < string , unknown > ) => Promise < TPlan > ;
51- applyOcChatgptSync : ( args : Record < string , unknown > ) => Promise < TApplied > ;
56+ planOcChatgptSync : (
57+ args : PlanOcChatgptSyncOptions ,
58+ ) => Promise < OcChatgptSyncPlanResult > ;
59+ applyOcChatgptSync : (
60+ args : ApplyOcChatgptSyncOptions ,
61+ ) => Promise < OcChatgptSyncApplyResult > ;
5262 getTargetKind : ( targetState : TTargetState ) => string ;
53- getTargetDestination : ( targetState : TTargetState ) => unknown ;
54- getTargetDetection : ( targetState : TTargetState ) => unknown ;
63+ getTargetDestination : ( targetState : TTargetState ) => AccountStorageV3 | null ;
64+ getTargetDetection : (
65+ targetState : TTargetState ,
66+ ) => ReturnType <
67+ typeof import ( "../oc-chatgpt-target-detection.js" ) . detectOcChatgptMultiAuthTarget
68+ > ;
5569 getTargetErrorMessage : ( targetState : TTargetState ) => string | null ;
56- getPlanKind : ( plan : TPlan ) => string ;
57- getPlanBlockedReason : ( plan : TPlan ) => string ;
58- getPlanPreview : ( plan : TPlan ) => {
70+ getPlanKind : ( plan : OcChatgptSyncPlanResult ) => string ;
71+ getPlanBlockedReason : ( plan : OcChatgptSyncPlanResult ) => string ;
72+ getPlanPreview : ( plan : OcChatgptSyncPlanResult ) => {
5973 toAdd : unknown [ ] ;
6074 toUpdate : unknown [ ] ;
6175 toSkip : unknown [ ] ;
6276 unchangedDestinationOnly : unknown [ ] ;
6377 activeSelectionBehavior : string ;
6478 } ;
65- getAppliedLabel : ( applied : TApplied ) => { label : string ; color : string } ;
66- } ) : Promise < PluginConfig | null > {
79+ getAppliedLabel : (
80+ applied : OcChatgptSyncApplyResult ,
81+ ) => { label : string ; color : MenuItem [ "color" ] } ;
82+ } ;
83+
84+ export async function promptExperimentalSettingsMenu < TTargetState > (
85+ params : ExperimentalSettingsPromptDeps < TTargetState > ,
86+ ) : Promise < PluginConfig | null > {
6787 if ( ! params . isInteractive ( ) ) return null ;
6888 let draft = params . cloneBackendPluginConfig ( params . initialConfig ) ;
6989 const copy = params . copy ;
7090
7191 while ( true ) {
72- const action = await params . select < TAction > (
92+ const action = await params . select < ExperimentalSettingsAction > (
7393 [
7494 {
7595 label : copy . experimentalSync ,
@@ -164,7 +184,7 @@ export async function promptExperimentalSettingsMenu<
164184 : backupResult . error instanceof Error
165185 ? backupResult . error . message
166186 : String ( backupResult . error ) ;
167- await params . select < TAction > (
187+ await params . select < ExperimentalSettingsAction > (
168188 [
169189 {
170190 label : backupLabel ,
@@ -184,7 +204,7 @@ export async function promptExperimentalSettingsMenu<
184204 } catch ( error ) {
185205 const message =
186206 error instanceof Error ? error . message : String ( error ) ;
187- await params . select < TAction > (
207+ await params . select < ExperimentalSettingsAction > (
188208 [
189209 {
190210 label : message ,
@@ -212,7 +232,7 @@ export async function promptExperimentalSettingsMenu<
212232 const targetState = await params . loadExperimentalSyncTarget ( ) ;
213233 const targetError = params . getTargetErrorMessage ( targetState ) ;
214234 if ( targetError ) {
215- await params . select < TAction > (
235+ await params . select < ExperimentalSettingsAction > (
216236 [
217237 {
218238 label : targetError ,
@@ -246,7 +266,7 @@ export async function promptExperimentalSettingsMenu<
246266 : undefined ,
247267 } ) ;
248268 if ( params . getPlanKind ( plan ) !== "ready" ) {
249- await params . select < TAction > (
269+ await params . select < ExperimentalSettingsAction > (
250270 [
251271 {
252272 label : params . getPlanBlockedReason ( plan ) ,
@@ -267,7 +287,7 @@ export async function promptExperimentalSettingsMenu<
267287 }
268288
269289 const preview = params . getPlanPreview ( plan ) ;
270- const review = await params . select < TAction > (
290+ const review = await params . select < ExperimentalSettingsAction > (
271291 [
272292 {
273293 label : `Preview: add ${ preview . toAdd . length } | update ${ preview . toUpdate . length } | skip ${ preview . toSkip . length } ` ,
@@ -299,15 +319,15 @@ export async function promptExperimentalSettingsMenu<
299319 ] ,
300320 params . getExperimentalSelectOptions (
301321 params . ui ,
302- copy . experimentalHelpPreview ,
303- ( raw ) => {
304- const lower = raw . toLowerCase ( ) ;
305- if ( lower === "q" ) return { type : "back" } as TAction ;
306- if ( lower === "a" ) return { type : "apply" } as TAction ;
307- return undefined ;
308- } ,
309- ) ,
310- ) ;
322+ copy . experimentalHelpPreview ,
323+ ( raw ) => {
324+ const lower = raw . toLowerCase ( ) ;
325+ if ( lower === "q" ) return { type : "back" } ;
326+ if ( lower === "a" ) return { type : "apply" } ;
327+ return undefined ;
328+ } ,
329+ ) ,
330+ ) ;
311331 if ( ! review || ( review as { type ?: string } ) . type === "back" ) continue ;
312332
313333 const applied = await params . applyOcChatgptSync ( {
@@ -322,7 +342,7 @@ export async function promptExperimentalSettingsMenu<
322342 : undefined ,
323343 } ) ;
324344 const appliedLabel = params . getAppliedLabel ( applied ) ;
325- await params . select < TAction > (
345+ await params . select < ExperimentalSettingsAction > (
326346 [
327347 {
328348 label : appliedLabel . label ,
0 commit comments