@minniexcode/codex-switch 0.0.5 → 0.0.7

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.
Files changed (71) hide show
  1. package/README.AI.md +5 -2
  2. package/README.md +44 -100
  3. package/dist/app/add-provider.js +28 -4
  4. package/dist/app/edit-provider.js +47 -19
  5. package/dist/app/export-providers.js +2 -2
  6. package/dist/app/get-current-profile.js +1 -1
  7. package/dist/app/get-status.js +10 -3
  8. package/dist/app/import-providers.js +15 -7
  9. package/dist/app/init-codex.js +68 -0
  10. package/dist/app/list-backups.js +1 -1
  11. package/dist/app/list-config-profiles.js +3 -2
  12. package/dist/app/list-providers.js +2 -1
  13. package/dist/app/remove-provider.js +2 -2
  14. package/dist/app/rollback-backup.js +1 -1
  15. package/dist/app/rollback-latest.js +1 -1
  16. package/dist/app/run-doctor.js +83 -6
  17. package/dist/app/run-mutation.js +2 -2
  18. package/dist/app/setup-codex.js +21 -12
  19. package/dist/app/show-config.js +11 -3
  20. package/dist/app/show-provider.js +1 -1
  21. package/dist/app/switch-provider.js +16 -9
  22. package/dist/cli/add-interactive.js +7 -104
  23. package/dist/cli/args.js +6 -135
  24. package/dist/cli/help.js +8 -313
  25. package/dist/cli/interactive.js +17 -225
  26. package/dist/cli/output.js +21 -6
  27. package/dist/cli/prompt.js +4 -106
  28. package/dist/cli.js +10 -404
  29. package/dist/commands/args.js +132 -0
  30. package/dist/commands/dispatch.js +16 -0
  31. package/dist/commands/handlers.js +460 -0
  32. package/dist/commands/help.js +120 -0
  33. package/dist/commands/registry.js +351 -0
  34. package/dist/commands/types.js +2 -0
  35. package/dist/domain/config.js +235 -21
  36. package/dist/domain/providers.js +16 -2
  37. package/dist/domain/setup.js +1 -0
  38. package/dist/infra/backup-repo.js +9 -206
  39. package/dist/infra/codex-cli.js +9 -126
  40. package/dist/infra/codex-paths.js +6 -67
  41. package/dist/infra/config-repo.js +59 -0
  42. package/dist/infra/fs-utils.js +8 -93
  43. package/dist/infra/lock-repo.js +4 -95
  44. package/dist/infra/providers-repo.js +8 -94
  45. package/dist/interaction/add-interactive.js +99 -0
  46. package/dist/interaction/interactive.js +289 -0
  47. package/dist/interaction/prompt.js +110 -0
  48. package/dist/runtime/codex-cli.js +130 -0
  49. package/dist/runtime/codex-probe.js +57 -0
  50. package/dist/runtime/types.js +2 -0
  51. package/dist/storage/auth-repo.js +160 -0
  52. package/dist/storage/backup-repo.js +210 -0
  53. package/dist/storage/codex-paths.js +71 -0
  54. package/dist/storage/config-repo.js +266 -0
  55. package/dist/storage/fs-utils.js +97 -0
  56. package/dist/storage/lock-repo.js +99 -0
  57. package/dist/storage/providers-repo.js +98 -0
  58. package/docs/Design/codex-switch-v0.0.5-design.md +32 -22
  59. package/docs/Design/codex-switch-v0.0.6-design.md +708 -0
  60. package/docs/Design/codex-switch-v0.0.7-design.md +862 -0
  61. package/docs/PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md +227 -89
  62. package/docs/PRD/codex-switch-prd-v0.1.0.md +200 -226
  63. package/docs/PRD/codex-switch-prd.md +1 -1
  64. package/docs/Reference/codex-config-reference.md +604 -0
  65. package/docs/Reference/codex-config-reference.zh-CN.md +633 -0
  66. package/docs/cli-usage.md +78 -29
  67. package/docs/codex-switch-technical-architecture.md +73 -4
  68. package/docs/test-report-0.0.5.md +163 -0
  69. package/docs/test-report-0.0.7.md +118 -0
  70. package/docs/testing.md +151 -0
  71. package/package.json +1 -1
@@ -1,229 +1,21 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.canPrompt = canPrompt;
37
- exports.promptForProviderSelection = promptForProviderSelection;
38
- exports.confirmProviderRemoval = confirmProviderRemoval;
39
- exports.confirmImport = confirmImport;
40
- exports.confirmExportOverwrite = confirmExportOverwrite;
41
- exports.exportTargetExists = exportTargetExists;
42
- exports.getRollbackSummary = getRollbackSummary;
43
- exports.getRollbackSummaryById = getRollbackSummaryById;
44
- exports.confirmRollback = confirmRollback;
45
- exports.chooseSetupStrategy = chooseSetupStrategy;
46
- exports.chooseCodexDir = chooseCodexDir;
47
- exports.chooseSetupProfiles = chooseSetupProfiles;
48
- exports.collectSetupProviderDetails = collectSetupProviderDetails;
49
- exports.collectImportRepairDetails = collectImportRepairDetails;
50
- exports.collectEditInput = collectEditInput;
51
- const fs = __importStar(require("node:fs"));
52
- const path = __importStar(require("node:path"));
53
- const errors_1 = require("../domain/errors");
54
- const backups_1 = require("../domain/backups");
55
- const codex_paths_1 = require("../infra/codex-paths");
56
- const providers_repo_1 = require("../infra/providers-repo");
57
- const backup_repo_1 = require("../infra/backup-repo");
58
- const add_interactive_1 = require("./add-interactive");
3
+ exports.promptForProviderSelection = exports.getRollbackSummaryById = exports.getRollbackSummary = exports.exportTargetExists = exports.confirmRollback = exports.confirmProviderRemoval = exports.confirmImport = exports.confirmExportOverwrite = exports.collectSetupProviderDetails = exports.collectEditInput = exports.chooseSetupStrategy = exports.chooseSetupProfiles = exports.chooseCodexDir = exports.canPrompt = void 0;
59
4
  /**
60
- * Keeps CLI-side interactivity rules in one place so automation paths remain explicit.
5
+ * Compatibility facade that re-exports interactive command helpers.
61
6
  */
62
- function canPrompt(runtime, jsonMode) {
63
- return !jsonMode && runtime.isInteractive();
64
- }
65
- async function promptForProviderSelection(runtime, providersPath, message) {
66
- const providers = (0, providers_repo_1.readProvidersFile)(providersPath);
67
- const choices = Object.entries(providers.providers)
68
- .sort(([left], [right]) => left.localeCompare(right))
69
- .map(([providerName, provider]) => ({
70
- value: providerName,
71
- label: providerName,
72
- hint: provider.profile,
73
- }));
74
- if (choices.length === 0) {
75
- throw (0, errors_1.cliError)("PROVIDER_NOT_FOUND", "No providers are configured.");
76
- }
77
- return runtime.selectOne(message, choices);
78
- }
79
- async function confirmProviderRemoval(runtime, providerName) {
80
- const confirmed = await runtime.confirmAction(`Remove provider "${providerName}"?`, {
81
- defaultValue: false,
82
- });
83
- if (!confirmed) {
84
- throw (0, errors_1.cliError)("PROMPT_CANCELLED", `Removal cancelled for provider "${providerName}".`);
85
- }
86
- }
87
- async function confirmImport(runtime, sourceFile, merge = false) {
88
- const confirmed = await runtime.confirmAction(merge
89
- ? `Import providers from ${path.resolve(sourceFile)} and merge into the current registry?`
90
- : `Import providers from ${path.resolve(sourceFile)} and replace the current registry?`, { defaultValue: false });
91
- if (!confirmed) {
92
- throw (0, errors_1.cliError)("PROMPT_CANCELLED", "Import cancelled.");
93
- }
94
- }
95
- async function confirmExportOverwrite(runtime, targetFile) {
96
- return runtime.confirmAction(`Overwrite existing export target ${path.resolve(targetFile)}?`, {
97
- defaultValue: false,
98
- });
99
- }
100
- function exportTargetExists(targetFile) {
101
- return fs.existsSync(path.resolve(targetFile));
102
- }
103
- function getRollbackSummary(latestBackupPath) {
104
- const manifest = (0, backup_repo_1.loadLatestManifest)(latestBackupPath);
105
- return buildRollbackSummary(manifest);
106
- }
107
- function getRollbackSummaryById(backupsDir, backupId) {
108
- const manifest = (0, backup_repo_1.loadManifestById)(backupsDir, backupId);
109
- return buildRollbackSummary(manifest);
110
- }
111
- function buildRollbackSummary(manifest) {
112
- const previewLines = [
113
- "Rollback preview",
114
- `Backup ID: ${(0, backups_1.getBackupId)(manifest.backupDir)}`,
115
- `Backup: ${manifest.backupDir}`,
116
- ...manifest.files.map((file) => {
117
- const suffix = file.existed ? "restore" : "remove";
118
- return `- ${file.relativePath} (${suffix})`;
119
- }),
120
- ];
121
- return { manifest, previewLines };
122
- }
123
- async function confirmRollback(runtime, latestBackupPath, backupsDir, backupId) {
124
- const { previewLines } = backupId && backupsDir
125
- ? getRollbackSummaryById(backupsDir, backupId)
126
- : getRollbackSummary(latestBackupPath);
127
- for (const line of previewLines) {
128
- runtime.writeLine(line);
129
- }
130
- const confirmed = await runtime.confirmAction(backupId ? `Restore files from backup "${backupId}"?` : "Restore files from the latest backup?", {
131
- defaultValue: false,
132
- });
133
- if (!confirmed) {
134
- throw (0, errors_1.cliError)("PROMPT_CANCELLED", "Rollback cancelled.");
135
- }
136
- }
137
- async function chooseSetupStrategy(runtime) {
138
- return runtime.selectOne("providers.json already exists. Choose a setup strategy.", [
139
- { value: "merge", label: "merge", hint: "keep existing providers and override by imported names" },
140
- { value: "overwrite", label: "overwrite", hint: "replace the existing registry" },
141
- { value: "cancel", label: "cancel", hint: "abort setup without writing" },
142
- ]);
143
- }
144
- async function chooseCodexDir(runtime, candidates) {
145
- if (candidates.length === 0) {
146
- const manual = (await runtime.inputText("Codex directory path")).trim();
147
- if (!manual) {
148
- throw (0, errors_1.cliError)("CODEX_DIR_NOT_FOUND", "No Codex directory was provided.");
149
- }
150
- return (0, codex_paths_1.resolveCodexDir)(manual);
151
- }
152
- if (candidates.length === 1) {
153
- return candidates[0];
154
- }
155
- const selected = await runtime.selectOne("Choose a Codex directory", [
156
- ...candidates.map((candidate) => ({
157
- value: candidate,
158
- label: candidate,
159
- })),
160
- {
161
- value: "__manual__",
162
- label: "Enter manually",
163
- },
164
- ]);
165
- if (selected !== "__manual__") {
166
- return selected;
167
- }
168
- const manual = (await runtime.inputText("Codex directory path")).trim();
169
- if (!manual) {
170
- throw (0, errors_1.cliError)("CODEX_DIR_NOT_FOUND", "No Codex directory was provided.");
171
- }
172
- return (0, codex_paths_1.resolveCodexDir)(manual);
173
- }
174
- async function chooseSetupProfiles(runtime, profiles) {
175
- if (profiles.length === 0) {
176
- return [];
177
- }
178
- return runtime.selectMany("Choose unmanaged config profiles to adopt into providers.json.", profiles.map((profile) => ({
179
- value: profile.name,
180
- label: profile.name,
181
- hint: `${profile.model} | ${profile.baseUrl}`,
182
- })));
183
- }
184
- async function collectSetupProviderDetails(runtime, profiles) {
185
- const result = {};
186
- for (const profile of profiles) {
187
- const providerName = (await runtime.inputText(`Provider name for profile "${profile}"`, {
188
- defaultValue: profile,
189
- })).trim();
190
- const apiKey = (await runtime.inputSecret(`API key for profile "${profile}"`)).trim();
191
- const baseUrl = (await runtime.inputText(`Base URL for profile "${profile}" (optional)`)).trim();
192
- const note = (await runtime.inputText(`Note for profile "${profile}" (optional)`)).trim();
193
- const tags = await (0, add_interactive_1.promptTags)(runtime);
194
- result[profile] = {
195
- providerName: providerName || profile,
196
- apiKey,
197
- baseUrl: baseUrl || undefined,
198
- note: note || undefined,
199
- tags: tags.length > 0 ? tags : undefined,
200
- };
201
- }
202
- return result;
203
- }
204
- async function collectImportRepairDetails(runtime, profiles) {
205
- const repairs = {};
206
- for (const profile of profiles) {
207
- const model = (await runtime.inputText(`Model for missing profile "${profile}"`)).trim();
208
- const baseUrl = (await runtime.inputText(`Base URL for missing profile "${profile}"`)).trim();
209
- repairs[profile] = {
210
- model: model || undefined,
211
- baseUrl: baseUrl || undefined,
212
- };
213
- }
214
- return repairs;
215
- }
216
- async function collectEditInput(runtime, current) {
217
- const profile = (await runtime.inputText("Profile", { defaultValue: current.profile })).trim();
218
- const apiKey = (await runtime.inputSecret("API key")).trim() || current.apiKey;
219
- const baseUrl = (await runtime.inputText("Base URL (optional)", { defaultValue: current.baseUrl ?? "" })).trim();
220
- const note = (await runtime.inputText("Note (optional)", { defaultValue: current.note ?? "" })).trim();
221
- const tags = await (0, add_interactive_1.promptTags)(runtime, current.tags ?? []);
222
- return {
223
- profile,
224
- apiKey,
225
- baseUrl: baseUrl || undefined,
226
- note: note || undefined,
227
- tags,
228
- };
229
- }
7
+ var interactive_1 = require("../interaction/interactive");
8
+ Object.defineProperty(exports, "canPrompt", { enumerable: true, get: function () { return interactive_1.canPrompt; } });
9
+ Object.defineProperty(exports, "chooseCodexDir", { enumerable: true, get: function () { return interactive_1.chooseCodexDir; } });
10
+ Object.defineProperty(exports, "chooseSetupProfiles", { enumerable: true, get: function () { return interactive_1.chooseSetupProfiles; } });
11
+ Object.defineProperty(exports, "chooseSetupStrategy", { enumerable: true, get: function () { return interactive_1.chooseSetupStrategy; } });
12
+ Object.defineProperty(exports, "collectEditInput", { enumerable: true, get: function () { return interactive_1.collectEditInput; } });
13
+ Object.defineProperty(exports, "collectSetupProviderDetails", { enumerable: true, get: function () { return interactive_1.collectSetupProviderDetails; } });
14
+ Object.defineProperty(exports, "confirmExportOverwrite", { enumerable: true, get: function () { return interactive_1.confirmExportOverwrite; } });
15
+ Object.defineProperty(exports, "confirmImport", { enumerable: true, get: function () { return interactive_1.confirmImport; } });
16
+ Object.defineProperty(exports, "confirmProviderRemoval", { enumerable: true, get: function () { return interactive_1.confirmProviderRemoval; } });
17
+ Object.defineProperty(exports, "confirmRollback", { enumerable: true, get: function () { return interactive_1.confirmRollback; } });
18
+ Object.defineProperty(exports, "exportTargetExists", { enumerable: true, get: function () { return interactive_1.exportTargetExists; } });
19
+ Object.defineProperty(exports, "getRollbackSummary", { enumerable: true, get: function () { return interactive_1.getRollbackSummary; } });
20
+ Object.defineProperty(exports, "getRollbackSummaryById", { enumerable: true, get: function () { return interactive_1.getRollbackSummaryById; } });
21
+ Object.defineProperty(exports, "promptForProviderSelection", { enumerable: true, get: function () { return interactive_1.promptForProviderSelection; } });
@@ -4,7 +4,7 @@ exports.renderSuccess = renderSuccess;
4
4
  exports.renderFailure = renderFailure;
5
5
  exports.outputSuccess = outputSuccess;
6
6
  exports.outputFailure = outputFailure;
7
- const fs_utils_1 = require("../infra/fs-utils");
7
+ const fs_utils_1 = require("../storage/fs-utils");
8
8
  /**
9
9
  * Renders a successful command result for either JSON or human-readable output.
10
10
  */
@@ -90,7 +90,8 @@ function renderHumanSuccess(command, data, warnings) {
90
90
  ? ` tags=${provider.tags.join(",")}`
91
91
  : "";
92
92
  const note = provider.note ? ` note=${provider.note}` : "";
93
- lines.push(`${provider.name} -> ${provider.profile}${tags}${note}`);
93
+ const envKey = provider.envKey ? ` envKey=${provider.envKey}` : "";
94
+ lines.push(`${provider.name} -> ${provider.profile}${envKey}${tags}${note}`);
94
95
  }
95
96
  }
96
97
  break;
@@ -100,6 +101,7 @@ function renderHumanSuccess(command, data, warnings) {
100
101
  lines.push(`Provider: ${String(data?.providerName ?? "")}`);
101
102
  lines.push(`profile: ${String(provider.profile ?? "")}`);
102
103
  lines.push(`apiKey: ${String(provider.apiKey ?? "")}`);
104
+ lines.push(`envKey: ${String(provider.envKey ?? "")}`);
103
105
  if (provider.baseUrl) {
104
106
  lines.push(`baseUrl: ${String(provider.baseUrl)}`);
105
107
  }
@@ -120,13 +122,17 @@ function renderHumanSuccess(command, data, warnings) {
120
122
  lines.push(`providersExists: ${String(data?.providersExists ?? false)}`);
121
123
  lines.push(`currentProfile: ${String(data?.currentProfile ?? "")}`);
122
124
  lines.push(`mappedProvider: ${String(data?.provider ?? "")}`);
125
+ lines.push(`activeProviderResolvable: ${String(data?.activeProviderResolvable ?? false)}`);
126
+ const auth = data?.auth ?? {};
127
+ lines.push(`authExists: ${String(auth.exists ?? false)}`);
128
+ lines.push(`authManagedKeys: ${Array.isArray(auth.managedSecretKeys) ? auth.managedSecretKeys.join(",") : ""}`);
123
129
  lines.push(`issues: ${Array.isArray(data?.issues) ? (data?.issues).length : 0}`);
124
130
  break;
125
131
  case "config-show": {
126
132
  lines.push(`activeProfile: ${String(data?.activeProfile ?? "")}`);
127
133
  const profiles = data?.profiles ?? [];
128
134
  for (const profile of profiles) {
129
- lines.push(`${String(profile.name)} managed=${String(profile.managed)} active=${String(profile.isActive)} source=${String(profile.source)} model=${String(profile.model ?? "")} baseUrl=${String(profile.baseUrl ?? "")}`);
135
+ lines.push(`${String(profile.name)} managed=${String(profile.managed)} active=${String(profile.isActive)} source=${String(profile.source)} model=${String(profile.model ?? "")} modelProvider=${String(profile.modelProvider ?? "")} baseUrl=${String(profile.baseUrl ?? "")} envKey=${String(profile.envKey ?? "")}`);
130
136
  }
131
137
  break;
132
138
  }
@@ -139,8 +145,8 @@ function renderHumanSuccess(command, data, warnings) {
139
145
  }
140
146
  case "switch":
141
147
  lines.push(`Switched to provider ${String(data?.provider ?? "")} using profile ${String(data?.profile ?? "")}.`);
148
+ lines.push(`envKey: ${String(data?.envKey ?? "")}`);
142
149
  lines.push(`Backup: ${String(data?.backupPath ?? "")}`);
143
- lines.push(`Login performed: ${String(data?.loginPerformed ?? false)}`);
144
150
  break;
145
151
  case "import":
146
152
  lines.push(`Imported providers from file using mode ${String(data?.mode ?? "replace")}. Backup: ${String(data?.backupPath ?? "")}`);
@@ -148,12 +154,21 @@ function renderHumanSuccess(command, data, warnings) {
148
154
  case "export":
149
155
  lines.push(`Exported providers to ${String(data?.exportedTo ?? "")}.`);
150
156
  break;
151
- case "setup":
152
- lines.push(`Initialized providers in ${String(data?.codexDir ?? "")} using ${String(data?.strategy ?? "")}.`);
157
+ case "init":
158
+ lines.push(`Initialized Codex directory ${String(data?.codexDir ?? "")}.`);
159
+ lines.push(`Created codexDir: ${String(data?.createdCodexDir ?? false)}`);
160
+ lines.push(`Created providers.json: ${String(data?.createdProvidersFile ?? false)}`);
161
+ lines.push(`providersAlreadyExisted: ${String(data?.providersAlreadyExisted ?? false)}`);
162
+ break;
163
+ case "migrate":
164
+ lines.push(`Migrated providers in ${String(data?.codexDir ?? "")} using ${String(data?.strategy ?? "")}.`);
153
165
  lines.push(`Providers initialized: ${String(data?.providersInitialized ?? 0)}`);
154
166
  lines.push(`Doctor healthy: ${String(data?.doctor?.healthy ?? false)}`);
155
167
  lines.push(`Backup: ${String(data?.backupPath ?? "")}`);
156
168
  break;
169
+ case "setup":
170
+ lines.push("setup is deprecated. Use `codexs init` or `codexs migrate`.");
171
+ break;
157
172
  case "edit":
158
173
  lines.push(`Updated provider ${String(data?.provider ?? "")}. Backup: ${String(data?.backupPath ?? "")}`);
159
174
  lines.push(`Updated fields: ${Array.isArray(data?.updatedFields) ? (data?.updatedFields).join(", ") : ""}`);
@@ -1,110 +1,8 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createPromptRuntime = createPromptRuntime;
7
- const inquirer_1 = __importDefault(require("inquirer"));
8
- const errors_1 = require("../domain/errors");
3
+ exports.createPromptRuntime = void 0;
9
4
  /**
10
- * Creates the default prompt runtime backed by inquirer on the current process TTY.
5
+ * Compatibility facade that re-exports the CLI prompt runtime types and factory.
11
6
  */
12
- function createPromptRuntime() {
13
- return {
14
- isInteractive: () => Boolean(process.stdin.isTTY && process.stdout.isTTY),
15
- inputText: async (message, options) => {
16
- return handlePromptCancellation(async () => {
17
- const answer = await inquirer_1.default.prompt([
18
- {
19
- type: "input",
20
- name: "value",
21
- message,
22
- default: options?.defaultValue ?? undefined,
23
- },
24
- ]);
25
- return String(answer.value ?? "");
26
- });
27
- },
28
- inputSecret: async (message) => {
29
- return handlePromptCancellation(async () => {
30
- const answer = await inquirer_1.default.prompt([
31
- {
32
- type: "password",
33
- name: "value",
34
- message,
35
- mask: "*",
36
- },
37
- ]);
38
- return String(answer.value ?? "");
39
- });
40
- },
41
- selectOne: async (message, choices) => {
42
- return handlePromptCancellation(async () => {
43
- const answer = await inquirer_1.default.prompt([
44
- {
45
- type: "select",
46
- name: "value",
47
- message,
48
- choices: choices.map((choice) => ({
49
- value: choice.value,
50
- name: choice.hint ? `${choice.label} (${choice.hint})` : choice.label,
51
- })),
52
- },
53
- ]);
54
- return answer.value;
55
- });
56
- },
57
- selectMany: async (message, choices, options) => {
58
- return handlePromptCancellation(async () => {
59
- const answer = await inquirer_1.default.prompt([
60
- {
61
- type: "checkbox",
62
- name: "value",
63
- message,
64
- choices: choices.map((choice) => ({
65
- value: choice.value,
66
- name: choice.hint ? `${choice.label} (${choice.hint})` : choice.label,
67
- checked: Boolean(options?.defaultValues?.includes(choice.value)),
68
- })),
69
- },
70
- ]);
71
- return (Array.isArray(answer.value) ? answer.value : []);
72
- });
73
- },
74
- confirmAction: async (message, options) => {
75
- return handlePromptCancellation(async () => {
76
- const answer = await inquirer_1.default.prompt([
77
- {
78
- type: "confirm",
79
- name: "value",
80
- message,
81
- default: options?.defaultValue ?? false,
82
- },
83
- ]);
84
- return Boolean(answer.value);
85
- });
86
- },
87
- writeLine: (message) => {
88
- process.stdout.write(`${message}\n`);
89
- },
90
- };
91
- }
92
- async function handlePromptCancellation(run) {
93
- try {
94
- return await run();
95
- }
96
- catch (error) {
97
- if (isPromptCancellation(error)) {
98
- throw (0, errors_1.cliError)("PROMPT_CANCELLED", "Interactive prompt was cancelled.");
99
- }
100
- throw (0, errors_1.cliError)("INVALID_ARGUMENT", "Interactive prompt failed.", {
101
- cause: error instanceof Error ? error.message : String(error),
102
- });
103
- }
104
- }
105
- function isPromptCancellation(error) {
106
- if (!(error instanceof Error)) {
107
- return false;
108
- }
109
- return error.name === "ExitPromptError" || error.message.includes("force closed");
110
- }
7
+ var prompt_1 = require("../interaction/prompt");
8
+ Object.defineProperty(exports, "createPromptRuntime", { enumerable: true, get: function () { return prompt_1.createPromptRuntime; } });