proxitor 0.8.0 → 0.9.0-beta.1
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 +57 -4
- package/dist/add.mjs +26 -26
- package/dist/add.mjs.map +1 -1
- package/dist/browse.mjs +20 -20
- package/dist/browse.mjs.map +1 -1
- package/dist/cli.mjs +482 -233
- package/dist/cli.mjs.map +1 -1
- package/dist/config.mjs.map +1 -1
- package/dist/config2.mjs +5 -5
- package/dist/config2.mjs.map +1 -1
- package/dist/dist.mjs +558 -548
- package/dist/dist.mjs.map +1 -1
- package/dist/dist2.mjs.map +1 -1
- package/dist/edit.mjs +17 -17
- package/dist/edit.mjs.map +1 -1
- package/dist/list.mjs +4 -4
- package/dist/list.mjs.map +1 -1
- package/dist/prompt.mjs +9 -9
- package/dist/prompt.mjs.map +1 -1
- package/dist/providers.mjs +15 -15
- package/dist/providers.mjs.map +1 -1
- package/dist/remove.mjs +10 -10
- package/dist/remove.mjs.map +1 -1
- package/dist/validate.mjs +8 -8
- package/dist/validate.mjs.map +1 -1
- package/dist/wizard.mjs +31 -31
- package/dist/wizard.mjs.map +1 -1
- package/package.json +1 -1
package/dist/remove.mjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { confirm
|
|
1
|
+
import { confirm, intro, isCancel, log, multiselect, outro } from "./dist.mjs";
|
|
2
2
|
import { n as removeModelOverride, r as requireConfigPath, t as getModelOverrides } from "./config.mjs";
|
|
3
3
|
//#region src/commands/config/remove.ts
|
|
4
4
|
/** Run the interactive "Remove model override" flow. */
|
|
5
5
|
async function removeOverrideCommand() {
|
|
6
|
-
|
|
6
|
+
intro("Remove Model Override");
|
|
7
7
|
const configPath = requireConfigPath();
|
|
8
8
|
const overrides = getModelOverrides(configPath);
|
|
9
9
|
const keys = Object.keys(overrides);
|
|
10
10
|
if (keys.length === 0) {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
log.warn("No model overrides found.");
|
|
12
|
+
outro("");
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
|
-
const selected = await
|
|
15
|
+
const selected = await multiselect({
|
|
16
16
|
message: "Select overrides to remove",
|
|
17
17
|
options: keys.map((k) => ({
|
|
18
18
|
value: k,
|
|
@@ -20,15 +20,15 @@ async function removeOverrideCommand() {
|
|
|
20
20
|
})),
|
|
21
21
|
required: true
|
|
22
22
|
});
|
|
23
|
-
if (
|
|
23
|
+
if (isCancel(selected)) return;
|
|
24
24
|
const toRemove = selected;
|
|
25
|
-
const confirmed = await
|
|
26
|
-
if (
|
|
27
|
-
|
|
25
|
+
const confirmed = await confirm({ message: `Remove ${toRemove.length} override(s)?` });
|
|
26
|
+
if (isCancel(confirmed) || !confirmed) {
|
|
27
|
+
outro("Cancelled");
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
for (const key of toRemove) removeModelOverride(configPath, key);
|
|
31
|
-
|
|
31
|
+
outro(`✓ ${toRemove.length} override(s) removed`);
|
|
32
32
|
}
|
|
33
33
|
//#endregion
|
|
34
34
|
export { removeOverrideCommand };
|
package/dist/remove.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove.mjs","names":["clack.multiselect","
|
|
1
|
+
{"version":3,"file":"remove.mjs","names":["clack.multiselect","clack.confirm"],"sources":["../src/commands/config/remove.ts"],"sourcesContent":["import * as clack from '@clack/prompts';\nimport { isCancel } from '@clack/prompts';\nimport { getModelOverrides, removeModelOverride, requireConfigPath } from './config.js';\n\n/** Run the interactive \"Remove model override\" flow. */\nexport async function removeOverrideCommand(): Promise<void> {\n clack.intro('Remove Model Override');\n\n const configPath = requireConfigPath();\n const overrides = getModelOverrides(configPath);\n const keys = Object.keys(overrides);\n\n if (keys.length === 0) {\n clack.log.warn('No model overrides found.');\n clack.outro('');\n return;\n }\n\n const selected = await clack.multiselect({\n message: 'Select overrides to remove',\n options: keys.map(k => ({\n value: k,\n label: k,\n })),\n required: true,\n });\n\n if (isCancel(selected)) return;\n\n const toRemove = selected as string[];\n\n const confirmed = await clack.confirm({\n message: `Remove ${toRemove.length} override(s)?`,\n });\n\n if (isCancel(confirmed) || !confirmed) {\n clack.outro('Cancelled');\n return;\n }\n\n for (const key of toRemove) {\n removeModelOverride(configPath, key);\n }\n\n clack.outro(`✓ ${toRemove.length} override(s) removed`);\n}\n"],"mappings":";;;;AAKA,eAAsB,wBAAuC;CAC3D,MAAY,uBAAuB;CAEnC,MAAM,aAAa,kBAAkB;CACrC,MAAM,YAAY,kBAAkB,UAAU;CAC9C,MAAM,OAAO,OAAO,KAAK,SAAS;CAElC,IAAI,KAAK,WAAW,GAAG;EACrB,IAAU,KAAK,2BAA2B;EAC1C,MAAY,EAAE;EACd;CACF;CAEA,MAAM,WAAW,MAAMA,YAAkB;EACvC,SAAS;EACT,SAAS,KAAK,KAAI,OAAM;GACtB,OAAO;GACP,OAAO;EACT,EAAE;EACF,UAAU;CACZ,CAAC;CAED,IAAI,SAAS,QAAQ,GAAG;CAExB,MAAM,WAAW;CAEjB,MAAM,YAAY,MAAMC,QAAc,EACpC,SAAS,UAAU,SAAS,OAAO,eACrC,CAAC;CAED,IAAI,SAAS,SAAS,KAAK,CAAC,WAAW;EACrC,MAAY,WAAW;EACvB;CACF;CAEA,KAAK,MAAM,OAAO,UAChB,oBAAoB,YAAY,GAAG;CAGrC,MAAY,KAAK,SAAS,OAAO,qBAAqB;AACxD"}
|
package/dist/validate.mjs
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { i as readConfigFile, n as findConfigFile } from "./cli.mjs";
|
|
2
|
-
import { intro
|
|
2
|
+
import { intro, log, outro } from "./dist.mjs";
|
|
3
3
|
//#region src/commands/config/validate.ts
|
|
4
4
|
/** Run config validation and display results. */
|
|
5
5
|
async function validateConfigCommand() {
|
|
6
|
-
|
|
6
|
+
intro("Validate Config");
|
|
7
7
|
const configPath = findConfigFile();
|
|
8
8
|
if (!configPath) {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
log.error("No config file found.");
|
|
10
|
+
outro("");
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
log.info(`Checking ${configPath}...`);
|
|
14
14
|
try {
|
|
15
15
|
readConfigFile(configPath);
|
|
16
|
-
|
|
16
|
+
log.success("Config is valid ✓");
|
|
17
17
|
} catch (error) {
|
|
18
|
-
|
|
18
|
+
log.error(String(error));
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
outro("");
|
|
21
21
|
}
|
|
22
22
|
//#endregion
|
|
23
23
|
export { validateConfigCommand };
|
package/dist/validate.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.mjs","names":[],"sources":["../src/commands/config/validate.ts"],"sourcesContent":["import * as clack from '@clack/prompts';\nimport { findConfigFile, readConfigFile } from '../../config.js';\n\n/** Run config validation and display results. */\nexport async function validateConfigCommand(): Promise<void> {\n clack.intro('Validate Config');\n\n const configPath = findConfigFile();\n if (!configPath) {\n clack.log.error('No config file found.');\n clack.outro('');\n return;\n }\n\n clack.log.info(`Checking ${configPath}...`);\n\n try {\n readConfigFile(configPath);\n clack.log.success('Config is valid ✓');\n } catch (error) {\n clack.log.error(String(error));\n }\n\n clack.outro('');\n}\n"],"mappings":";;;;AAIA,eAAsB,wBAAuC;CAC3D,
|
|
1
|
+
{"version":3,"file":"validate.mjs","names":[],"sources":["../src/commands/config/validate.ts"],"sourcesContent":["import * as clack from '@clack/prompts';\nimport { findConfigFile, readConfigFile } from '../../config.js';\n\n/** Run config validation and display results. */\nexport async function validateConfigCommand(): Promise<void> {\n clack.intro('Validate Config');\n\n const configPath = findConfigFile();\n if (!configPath) {\n clack.log.error('No config file found.');\n clack.outro('');\n return;\n }\n\n clack.log.info(`Checking ${configPath}...`);\n\n try {\n readConfigFile(configPath);\n clack.log.success('Config is valid ✓');\n } catch (error) {\n clack.log.error(String(error));\n }\n\n clack.outro('');\n}\n"],"mappings":";;;;AAIA,eAAsB,wBAAuC;CAC3D,MAAY,iBAAiB;CAE7B,MAAM,aAAa,eAAe;CAClC,IAAI,CAAC,YAAY;EACf,IAAU,MAAM,uBAAuB;EACvC,MAAY,EAAE;EACd;CACF;CAEA,IAAU,KAAK,YAAY,WAAW,IAAI;CAE1C,IAAI;EACF,eAAe,UAAU;EACzB,IAAU,QAAQ,mBAAmB;CACvC,SAAS,OAAO;EACd,IAAU,MAAM,OAAO,KAAK,CAAC;CAC/B;CAEA,MAAY,EAAE;AAChB"}
|
package/dist/wizard.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as DEFAULTS, i as readConfigFile, n as findConfigFile, r as getXdgConfigDir } from "./cli.mjs";
|
|
2
|
-
import { confirm
|
|
2
|
+
import { confirm, intro, isCancel, log, note, outro, select, text } from "./dist.mjs";
|
|
3
3
|
import { t as require_dist } from "./dist2.mjs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
@@ -66,8 +66,8 @@ function buildYaml(apiKey, port, host, baseUrl, authType, existingRaw) {
|
|
|
66
66
|
return (0, import_dist.stringify)(config);
|
|
67
67
|
}
|
|
68
68
|
async function askApiKey(currentKey) {
|
|
69
|
-
if (currentKey)
|
|
70
|
-
const apiKey = await
|
|
69
|
+
if (currentKey) log.info(`Current key: ${maskKey(currentKey)}`);
|
|
70
|
+
const apiKey = await text({
|
|
71
71
|
message: "OpenRouter API key",
|
|
72
72
|
placeholder: "sk-or-v1-...",
|
|
73
73
|
initialValue: currentKey,
|
|
@@ -75,12 +75,12 @@ async function askApiKey(currentKey) {
|
|
|
75
75
|
if (!v?.trim()) return "API key is required";
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
|
-
if (
|
|
79
|
-
|
|
78
|
+
if (isCancel(apiKey)) return null;
|
|
79
|
+
note("You can also set the OPENROUTER_API_KEY environment variable\nto avoid storing the key in the config file.", "Tip");
|
|
80
80
|
return apiKey;
|
|
81
81
|
}
|
|
82
82
|
async function askPort(current) {
|
|
83
|
-
const input = await
|
|
83
|
+
const input = await text({
|
|
84
84
|
message: "Proxy port",
|
|
85
85
|
initialValue: String(current),
|
|
86
86
|
placeholder: String(DEFAULTS.port),
|
|
@@ -90,11 +90,11 @@ async function askPort(current) {
|
|
|
90
90
|
if (Number.isNaN(n) || n < 1 || n > 65535) return "Port must be 1–65535";
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
|
-
if (
|
|
93
|
+
if (isCancel(input)) return null;
|
|
94
94
|
return input.trim() ? Number.parseInt(input, 10) : DEFAULTS.port;
|
|
95
95
|
}
|
|
96
96
|
async function askBaseUrl(current) {
|
|
97
|
-
const url = await
|
|
97
|
+
const url = await text({
|
|
98
98
|
message: "OpenRouter API base URL",
|
|
99
99
|
placeholder: DEFAULTS.openrouterBaseUrl,
|
|
100
100
|
initialValue: current === DEFAULTS.openrouterBaseUrl ? "" : current,
|
|
@@ -107,11 +107,11 @@ async function askBaseUrl(current) {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
});
|
|
110
|
-
if (
|
|
110
|
+
if (isCancel(url)) return null;
|
|
111
111
|
return url.trim() || DEFAULTS.openrouterBaseUrl;
|
|
112
112
|
}
|
|
113
113
|
async function askAuthType(current) {
|
|
114
|
-
const authType = await
|
|
114
|
+
const authType = await select({
|
|
115
115
|
message: "Authentication type",
|
|
116
116
|
initialValue: current,
|
|
117
117
|
options: [{
|
|
@@ -124,11 +124,11 @@ async function askAuthType(current) {
|
|
|
124
124
|
hint: "Custom proxy providers"
|
|
125
125
|
}]
|
|
126
126
|
});
|
|
127
|
-
if (
|
|
127
|
+
if (isCancel(authType)) return null;
|
|
128
128
|
return authType;
|
|
129
129
|
}
|
|
130
130
|
async function askHost(current) {
|
|
131
|
-
const host = await
|
|
131
|
+
const host = await select({
|
|
132
132
|
message: "Listen address",
|
|
133
133
|
initialValue: current,
|
|
134
134
|
options: [{
|
|
@@ -141,17 +141,17 @@ async function askHost(current) {
|
|
|
141
141
|
hint: "More secure"
|
|
142
142
|
}]
|
|
143
143
|
});
|
|
144
|
-
if (
|
|
144
|
+
if (isCancel(host)) return null;
|
|
145
145
|
return host;
|
|
146
146
|
}
|
|
147
147
|
async function askSaveLocation(existingPath) {
|
|
148
148
|
const options = getSaveLocationOptions(existingPath);
|
|
149
|
-
const location = await
|
|
149
|
+
const location = await select({
|
|
150
150
|
message: "Save config to",
|
|
151
151
|
initialValue: (existingPath ? detectLocation(existingPath) : void 0) ?? "local",
|
|
152
152
|
options
|
|
153
153
|
});
|
|
154
|
-
if (
|
|
154
|
+
if (isCancel(location)) return null;
|
|
155
155
|
return location;
|
|
156
156
|
}
|
|
157
157
|
/** Load existing config using validated readConfigFile, falling back to defaults */
|
|
@@ -178,7 +178,7 @@ function loadExistingConfig(path) {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
async function runWizard() {
|
|
181
|
-
|
|
181
|
+
intro("Proxitor Setup Wizard");
|
|
182
182
|
const existingPath = findConfigFile();
|
|
183
183
|
let existingRaw;
|
|
184
184
|
let currentPort = DEFAULTS.port;
|
|
@@ -187,13 +187,13 @@ async function runWizard() {
|
|
|
187
187
|
let currentBaseUrl = DEFAULTS.openrouterBaseUrl;
|
|
188
188
|
let currentAuthType = DEFAULTS.authType;
|
|
189
189
|
if (existingPath) {
|
|
190
|
-
|
|
191
|
-
const reconfigure = await
|
|
190
|
+
note(existingPath, "Existing config found");
|
|
191
|
+
const reconfigure = await confirm({
|
|
192
192
|
message: "Reconfigure?",
|
|
193
193
|
initialValue: true
|
|
194
194
|
});
|
|
195
|
-
if (
|
|
196
|
-
|
|
195
|
+
if (isCancel(reconfigure) || !reconfigure) {
|
|
196
|
+
outro("Using existing configuration");
|
|
197
197
|
return;
|
|
198
198
|
}
|
|
199
199
|
const existing = loadExistingConfig(existingPath);
|
|
@@ -206,49 +206,49 @@ async function runWizard() {
|
|
|
206
206
|
}
|
|
207
207
|
const apiKey = await askApiKey(currentKey);
|
|
208
208
|
if (apiKey === null) {
|
|
209
|
-
|
|
209
|
+
outro("Cancelled");
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
212
|
const port = await askPort(currentPort);
|
|
213
213
|
if (port === null) {
|
|
214
|
-
|
|
214
|
+
outro("Cancelled");
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
217
|
const baseUrl = await askBaseUrl(currentBaseUrl);
|
|
218
218
|
if (baseUrl === null) {
|
|
219
|
-
|
|
219
|
+
outro("Cancelled");
|
|
220
220
|
return;
|
|
221
221
|
}
|
|
222
222
|
const authType = await askAuthType(currentAuthType);
|
|
223
223
|
if (authType === null) {
|
|
224
|
-
|
|
224
|
+
outro("Cancelled");
|
|
225
225
|
return;
|
|
226
226
|
}
|
|
227
227
|
const host = await askHost(currentHost);
|
|
228
228
|
if (host === null) {
|
|
229
|
-
|
|
229
|
+
outro("Cancelled");
|
|
230
230
|
return;
|
|
231
231
|
}
|
|
232
232
|
const location = await askSaveLocation(existingPath ?? void 0);
|
|
233
233
|
if (location === null) {
|
|
234
|
-
|
|
234
|
+
outro("Cancelled");
|
|
235
235
|
return;
|
|
236
236
|
}
|
|
237
237
|
const yaml = buildYaml(apiKey, port, host, baseUrl, authType, existingRaw);
|
|
238
|
-
|
|
239
|
-
const save = await
|
|
238
|
+
note(yaml, "Preview");
|
|
239
|
+
const save = await confirm({
|
|
240
240
|
message: "Save this configuration?",
|
|
241
241
|
initialValue: true
|
|
242
242
|
});
|
|
243
|
-
if (
|
|
244
|
-
|
|
243
|
+
if (isCancel(save) || !save) {
|
|
244
|
+
outro("Cancelled — no files written");
|
|
245
245
|
return;
|
|
246
246
|
}
|
|
247
247
|
const savePath = resolveSavePath(location);
|
|
248
248
|
const dir = dirname(savePath);
|
|
249
249
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
250
250
|
writeFileSync(savePath, yaml, "utf-8");
|
|
251
|
-
|
|
251
|
+
outro(`Config saved to ${savePath}`);
|
|
252
252
|
}
|
|
253
253
|
//#endregion
|
|
254
254
|
export { runWizard };
|
package/dist/wizard.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wizard.mjs","names":["clack.text","isCancel","clack.select","clack.confirm"],"sources":["../src/commands/config/wizard.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport * as clack from '@clack/prompts';\nimport { isCancel } from '@clack/prompts';\nimport { parseDocument, stringify } from 'yaml';\nimport {\n type AuthType,\n DEFAULTS,\n findConfigFile,\n getXdgConfigDir,\n readConfigFile,\n} from '../../config.js';\n\ntype SaveLocation = 'local' | 'user' | 'xdg';\n\nfunction maskKey(key: string): string {\n if (key.length <= 11) return '****';\n return `${key.slice(0, 7)}...${key.slice(-4)}`;\n}\n\nfunction resolveSavePath(location: SaveLocation): string {\n switch (location) {\n case 'local':\n return resolve('proxitor.config.yaml');\n case 'user':\n return join(homedir(), '.config', 'proxitor', 'config.yaml');\n case 'xdg':\n return join(getXdgConfigDir(), 'config.yaml');\n }\n}\n\nfunction getSaveLocationOptions(_existingPath?: string) {\n const opts: { value: SaveLocation; label: string; hint: string }[] = [\n { value: 'local', label: './proxitor.config.yaml', hint: 'Project directory' },\n { value: 'user', label: '~/.config/proxitor/config.yaml', hint: 'User config' },\n ];\n\n if (process.env.XDG_CONFIG_HOME) {\n opts.push({\n value: 'xdg',\n label: '$XDG_CONFIG_HOME/proxitor/config.yaml',\n hint: 'XDG config directory',\n });\n }\n\n return opts;\n}\n\nfunction detectLocation(path: string): SaveLocation | undefined {\n const cwd = resolve('.');\n if (path.startsWith(cwd)) return 'local';\n const userDir = join(homedir(), '.config', 'proxitor');\n if (path.startsWith(userDir)) {\n const xdgDir = process.env.XDG_CONFIG_HOME\n ? join(process.env.XDG_CONFIG_HOME, 'proxitor')\n : null;\n if (xdgDir && path.startsWith(xdgDir)) return 'xdg';\n return 'user';\n }\n return undefined;\n}\n\nfunction buildYaml(\n apiKey: string,\n port: number,\n host: string,\n baseUrl: string,\n authType: string,\n existingRaw?: string,\n): string {\n if (existingRaw) {\n const doc = parseDocument(existingRaw);\n doc.set('openrouterKey', apiKey);\n doc.set('port', port);\n doc.set('host', host);\n if (baseUrl !== DEFAULTS.openrouterBaseUrl) {\n doc.set('openrouterBaseUrl', baseUrl);\n } else {\n doc.delete('openrouterBaseUrl');\n }\n if (authType !== DEFAULTS.authType) {\n doc.set('authType', authType);\n } else {\n doc.delete('authType');\n }\n return doc.toString();\n }\n\n const config: Record<string, unknown> = { openrouterKey: apiKey, port, host };\n if (baseUrl !== DEFAULTS.openrouterBaseUrl) {\n config.openrouterBaseUrl = baseUrl;\n }\n if (authType !== DEFAULTS.authType) {\n config.authType = authType;\n }\n return stringify(config);\n}\n\nasync function askApiKey(currentKey: string): Promise<string | null> {\n if (currentKey) {\n clack.log.info(`Current key: ${maskKey(currentKey)}`);\n }\n const apiKey = await clack.text({\n message: 'OpenRouter API key',\n placeholder: 'sk-or-v1-...',\n initialValue: currentKey,\n validate: v => {\n if (!v?.trim()) return 'API key is required';\n return undefined;\n },\n });\n if (isCancel(apiKey)) return null;\n\n clack.note(\n 'You can also set the OPENROUTER_API_KEY environment variable\\nto avoid storing the key in the config file.',\n 'Tip',\n );\n return apiKey as string;\n}\n\nasync function askPort(current: number): Promise<number | null> {\n const input = await clack.text({\n message: 'Proxy port',\n initialValue: String(current),\n placeholder: String(DEFAULTS.port),\n validate: v => {\n if (!v?.trim()) return undefined;\n const n = Number.parseInt(v, 10);\n if (Number.isNaN(n) || n < 1 || n > 65535) return 'Port must be 1–65535';\n return undefined;\n },\n });\n if (isCancel(input)) return null;\n return (input as string).trim() ? Number.parseInt(input as string, 10) : DEFAULTS.port;\n}\n\nasync function askBaseUrl(current: string): Promise<string | null> {\n const url = await clack.text({\n message: 'OpenRouter API base URL',\n placeholder: DEFAULTS.openrouterBaseUrl,\n initialValue: current === DEFAULTS.openrouterBaseUrl ? '' : current,\n validate: v => {\n if (!v?.trim()) return undefined;\n try {\n const parsed = new URL(v.trim());\n if (!parsed.protocol.startsWith('http'))\n return 'URL must start with http:// or https://';\n } catch {\n return 'Invalid URL';\n }\n return undefined;\n },\n });\n if (isCancel(url)) return null;\n return (url as string).trim() || DEFAULTS.openrouterBaseUrl;\n}\n\nasync function askAuthType(current: string): Promise<string | null> {\n const authType = await clack.select({\n message: 'Authentication type',\n initialValue: current,\n options: [\n { value: 'bearer', label: 'Bearer token', hint: 'Standard OpenRouter' },\n { value: 'oauth', label: 'OAuth token', hint: 'Custom proxy providers' },\n ],\n });\n if (isCancel(authType)) return null;\n return authType as string;\n}\n\nasync function askHost(current: string): Promise<string | null> {\n const host = await clack.select({\n message: 'Listen address',\n initialValue: current as '0.0.0.0' | '127.0.0.1',\n options: [\n { value: '0.0.0.0', label: 'All interfaces (0.0.0.0)', hint: 'Default' },\n { value: '127.0.0.1', label: 'Localhost only (127.0.0.1)', hint: 'More secure' },\n ],\n });\n if (isCancel(host)) return null;\n return host as string;\n}\n\nasync function askSaveLocation(existingPath?: string): Promise<SaveLocation | null> {\n const options = getSaveLocationOptions(existingPath);\n const detected = existingPath ? detectLocation(existingPath) : undefined;\n\n const location = await clack.select({\n message: 'Save config to',\n initialValue: detected ?? 'local',\n options,\n });\n if (isCancel(location)) return null;\n return location as SaveLocation;\n}\n\ntype ExistingConfigState = {\n raw?: string;\n port: number;\n host: string;\n apiKey: string;\n baseUrl: string;\n authType: AuthType;\n};\n\n/** Load existing config using validated readConfigFile, falling back to defaults */\nfunction loadExistingConfig(path: string): ExistingConfigState {\n try {\n const fileConfig = readConfigFile(path);\n const raw = readFileSync(path, 'utf-8');\n return {\n raw,\n port: fileConfig.port ?? DEFAULTS.port,\n host: fileConfig.host ?? DEFAULTS.host,\n apiKey: fileConfig.openrouterKey ?? DEFAULTS.openrouterKey,\n baseUrl: fileConfig.openrouterBaseUrl ?? DEFAULTS.openrouterBaseUrl,\n authType: fileConfig.authType ?? DEFAULTS.authType,\n };\n } catch {\n return {\n raw: undefined,\n port: DEFAULTS.port,\n host: DEFAULTS.host,\n apiKey: DEFAULTS.openrouterKey,\n baseUrl: DEFAULTS.openrouterBaseUrl,\n authType: DEFAULTS.authType,\n };\n }\n}\n\nexport async function runWizard(): Promise<void> {\n clack.intro('Proxitor Setup Wizard');\n\n const existingPath = findConfigFile();\n let existingRaw: string | undefined;\n let currentPort = DEFAULTS.port;\n let currentHost = DEFAULTS.host;\n let currentKey = DEFAULTS.openrouterKey;\n let currentBaseUrl = DEFAULTS.openrouterBaseUrl;\n let currentAuthType = DEFAULTS.authType;\n\n if (existingPath) {\n clack.note(existingPath, 'Existing config found');\n\n const reconfigure = await clack.confirm({\n message: 'Reconfigure?',\n initialValue: true,\n });\n if (isCancel(reconfigure) || !reconfigure) {\n clack.outro('Using existing configuration');\n return;\n }\n\n const existing = loadExistingConfig(existingPath);\n existingRaw = existing.raw;\n currentPort = existing.port;\n currentHost = existing.host;\n currentKey = existing.apiKey;\n currentBaseUrl = existing.baseUrl;\n currentAuthType = existing.authType;\n }\n\n const apiKey = await askApiKey(currentKey);\n if (apiKey === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const port = await askPort(currentPort);\n if (port === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const baseUrl = await askBaseUrl(currentBaseUrl);\n if (baseUrl === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const authType = await askAuthType(currentAuthType);\n if (authType === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const host = await askHost(currentHost);\n if (host === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const location = await askSaveLocation(existingPath ?? undefined);\n if (location === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const yaml = buildYaml(apiKey, port, host, baseUrl, authType, existingRaw);\n clack.note(yaml, 'Preview');\n\n const save = await clack.confirm({\n message: 'Save this configuration?',\n initialValue: true,\n });\n if (isCancel(save) || !save) {\n clack.outro('Cancelled — no files written');\n return;\n }\n\n const savePath = resolveSavePath(location);\n const dir = dirname(savePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(savePath, yaml, 'utf-8');\n\n clack.outro(`Config saved to ${savePath}`);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wizard.mjs","names":["clack.text","clack.select","clack.confirm"],"sources":["../src/commands/config/wizard.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport * as clack from '@clack/prompts';\nimport { isCancel } from '@clack/prompts';\nimport { parseDocument, stringify } from 'yaml';\nimport {\n type AuthType,\n DEFAULTS,\n findConfigFile,\n getXdgConfigDir,\n readConfigFile,\n} from '../../config.js';\n\ntype SaveLocation = 'local' | 'user' | 'xdg';\n\nfunction maskKey(key: string): string {\n if (key.length <= 11) return '****';\n return `${key.slice(0, 7)}...${key.slice(-4)}`;\n}\n\nfunction resolveSavePath(location: SaveLocation): string {\n switch (location) {\n case 'local':\n return resolve('proxitor.config.yaml');\n case 'user':\n return join(homedir(), '.config', 'proxitor', 'config.yaml');\n case 'xdg':\n return join(getXdgConfigDir(), 'config.yaml');\n }\n}\n\nfunction getSaveLocationOptions(_existingPath?: string) {\n const opts: { value: SaveLocation; label: string; hint: string }[] = [\n { value: 'local', label: './proxitor.config.yaml', hint: 'Project directory' },\n { value: 'user', label: '~/.config/proxitor/config.yaml', hint: 'User config' },\n ];\n\n if (process.env.XDG_CONFIG_HOME) {\n opts.push({\n value: 'xdg',\n label: '$XDG_CONFIG_HOME/proxitor/config.yaml',\n hint: 'XDG config directory',\n });\n }\n\n return opts;\n}\n\nfunction detectLocation(path: string): SaveLocation | undefined {\n const cwd = resolve('.');\n if (path.startsWith(cwd)) return 'local';\n const userDir = join(homedir(), '.config', 'proxitor');\n if (path.startsWith(userDir)) {\n const xdgDir = process.env.XDG_CONFIG_HOME\n ? join(process.env.XDG_CONFIG_HOME, 'proxitor')\n : null;\n if (xdgDir && path.startsWith(xdgDir)) return 'xdg';\n return 'user';\n }\n return undefined;\n}\n\nfunction buildYaml(\n apiKey: string,\n port: number,\n host: string,\n baseUrl: string,\n authType: string,\n existingRaw?: string,\n): string {\n if (existingRaw) {\n const doc = parseDocument(existingRaw);\n doc.set('openrouterKey', apiKey);\n doc.set('port', port);\n doc.set('host', host);\n if (baseUrl !== DEFAULTS.openrouterBaseUrl) {\n doc.set('openrouterBaseUrl', baseUrl);\n } else {\n doc.delete('openrouterBaseUrl');\n }\n if (authType !== DEFAULTS.authType) {\n doc.set('authType', authType);\n } else {\n doc.delete('authType');\n }\n return doc.toString();\n }\n\n const config: Record<string, unknown> = { openrouterKey: apiKey, port, host };\n if (baseUrl !== DEFAULTS.openrouterBaseUrl) {\n config.openrouterBaseUrl = baseUrl;\n }\n if (authType !== DEFAULTS.authType) {\n config.authType = authType;\n }\n return stringify(config);\n}\n\nasync function askApiKey(currentKey: string): Promise<string | null> {\n if (currentKey) {\n clack.log.info(`Current key: ${maskKey(currentKey)}`);\n }\n const apiKey = await clack.text({\n message: 'OpenRouter API key',\n placeholder: 'sk-or-v1-...',\n initialValue: currentKey,\n validate: v => {\n if (!v?.trim()) return 'API key is required';\n return undefined;\n },\n });\n if (isCancel(apiKey)) return null;\n\n clack.note(\n 'You can also set the OPENROUTER_API_KEY environment variable\\nto avoid storing the key in the config file.',\n 'Tip',\n );\n return apiKey as string;\n}\n\nasync function askPort(current: number): Promise<number | null> {\n const input = await clack.text({\n message: 'Proxy port',\n initialValue: String(current),\n placeholder: String(DEFAULTS.port),\n validate: v => {\n if (!v?.trim()) return undefined;\n const n = Number.parseInt(v, 10);\n if (Number.isNaN(n) || n < 1 || n > 65535) return 'Port must be 1–65535';\n return undefined;\n },\n });\n if (isCancel(input)) return null;\n return (input as string).trim() ? Number.parseInt(input as string, 10) : DEFAULTS.port;\n}\n\nasync function askBaseUrl(current: string): Promise<string | null> {\n const url = await clack.text({\n message: 'OpenRouter API base URL',\n placeholder: DEFAULTS.openrouterBaseUrl,\n initialValue: current === DEFAULTS.openrouterBaseUrl ? '' : current,\n validate: v => {\n if (!v?.trim()) return undefined;\n try {\n const parsed = new URL(v.trim());\n if (!parsed.protocol.startsWith('http'))\n return 'URL must start with http:// or https://';\n } catch {\n return 'Invalid URL';\n }\n return undefined;\n },\n });\n if (isCancel(url)) return null;\n return (url as string).trim() || DEFAULTS.openrouterBaseUrl;\n}\n\nasync function askAuthType(current: string): Promise<string | null> {\n const authType = await clack.select({\n message: 'Authentication type',\n initialValue: current,\n options: [\n { value: 'bearer', label: 'Bearer token', hint: 'Standard OpenRouter' },\n { value: 'oauth', label: 'OAuth token', hint: 'Custom proxy providers' },\n ],\n });\n if (isCancel(authType)) return null;\n return authType as string;\n}\n\nasync function askHost(current: string): Promise<string | null> {\n const host = await clack.select({\n message: 'Listen address',\n initialValue: current as '0.0.0.0' | '127.0.0.1',\n options: [\n { value: '0.0.0.0', label: 'All interfaces (0.0.0.0)', hint: 'Default' },\n { value: '127.0.0.1', label: 'Localhost only (127.0.0.1)', hint: 'More secure' },\n ],\n });\n if (isCancel(host)) return null;\n return host as string;\n}\n\nasync function askSaveLocation(existingPath?: string): Promise<SaveLocation | null> {\n const options = getSaveLocationOptions(existingPath);\n const detected = existingPath ? detectLocation(existingPath) : undefined;\n\n const location = await clack.select({\n message: 'Save config to',\n initialValue: detected ?? 'local',\n options,\n });\n if (isCancel(location)) return null;\n return location as SaveLocation;\n}\n\ntype ExistingConfigState = {\n raw?: string;\n port: number;\n host: string;\n apiKey: string;\n baseUrl: string;\n authType: AuthType;\n};\n\n/** Load existing config using validated readConfigFile, falling back to defaults */\nfunction loadExistingConfig(path: string): ExistingConfigState {\n try {\n const fileConfig = readConfigFile(path);\n const raw = readFileSync(path, 'utf-8');\n return {\n raw,\n port: fileConfig.port ?? DEFAULTS.port,\n host: fileConfig.host ?? DEFAULTS.host,\n apiKey: fileConfig.openrouterKey ?? DEFAULTS.openrouterKey,\n baseUrl: fileConfig.openrouterBaseUrl ?? DEFAULTS.openrouterBaseUrl,\n authType: fileConfig.authType ?? DEFAULTS.authType,\n };\n } catch {\n return {\n raw: undefined,\n port: DEFAULTS.port,\n host: DEFAULTS.host,\n apiKey: DEFAULTS.openrouterKey,\n baseUrl: DEFAULTS.openrouterBaseUrl,\n authType: DEFAULTS.authType,\n };\n }\n}\n\nexport async function runWizard(): Promise<void> {\n clack.intro('Proxitor Setup Wizard');\n\n const existingPath = findConfigFile();\n let existingRaw: string | undefined;\n let currentPort = DEFAULTS.port;\n let currentHost = DEFAULTS.host;\n let currentKey = DEFAULTS.openrouterKey;\n let currentBaseUrl = DEFAULTS.openrouterBaseUrl;\n let currentAuthType = DEFAULTS.authType;\n\n if (existingPath) {\n clack.note(existingPath, 'Existing config found');\n\n const reconfigure = await clack.confirm({\n message: 'Reconfigure?',\n initialValue: true,\n });\n if (isCancel(reconfigure) || !reconfigure) {\n clack.outro('Using existing configuration');\n return;\n }\n\n const existing = loadExistingConfig(existingPath);\n existingRaw = existing.raw;\n currentPort = existing.port;\n currentHost = existing.host;\n currentKey = existing.apiKey;\n currentBaseUrl = existing.baseUrl;\n currentAuthType = existing.authType;\n }\n\n const apiKey = await askApiKey(currentKey);\n if (apiKey === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const port = await askPort(currentPort);\n if (port === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const baseUrl = await askBaseUrl(currentBaseUrl);\n if (baseUrl === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const authType = await askAuthType(currentAuthType);\n if (authType === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const host = await askHost(currentHost);\n if (host === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const location = await askSaveLocation(existingPath ?? undefined);\n if (location === null) {\n clack.outro('Cancelled');\n return;\n }\n\n const yaml = buildYaml(apiKey, port, host, baseUrl, authType, existingRaw);\n clack.note(yaml, 'Preview');\n\n const save = await clack.confirm({\n message: 'Save this configuration?',\n initialValue: true,\n });\n if (isCancel(save) || !save) {\n clack.outro('Cancelled — no files written');\n return;\n }\n\n const savePath = resolveSavePath(location);\n const dir = dirname(savePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(savePath, yaml, 'utf-8');\n\n clack.outro(`Config saved to ${savePath}`);\n}\n"],"mappings":"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"}
|