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/dist/remove.mjs CHANGED
@@ -1,18 +1,18 @@
1
- import { confirm as le, intro as ye, isCancel as R$1, log as R, multiselect as we, outro as fe } from "./dist.mjs";
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
- ye("Remove Model Override");
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
- R.warn("No model overrides found.");
12
- fe("");
11
+ log.warn("No model overrides found.");
12
+ outro("");
13
13
  return;
14
14
  }
15
- const selected = await we({
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 (R$1(selected)) return;
23
+ if (isCancel(selected)) return;
24
24
  const toRemove = selected;
25
- const confirmed = await le({ message: `Remove ${toRemove.length} override(s)?` });
26
- if (R$1(confirmed) || !confirmed) {
27
- fe("Cancelled");
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
- fe(`✓ ${toRemove.length} override(s) removed`);
31
+ outro(`✓ ${toRemove.length} override(s) removed`);
32
32
  }
33
33
  //#endregion
34
34
  export { removeOverrideCommand };
@@ -1 +1 @@
1
- {"version":3,"file":"remove.mjs","names":["clack.multiselect","isCancel","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,GAAY,uBAAuB;CAEnC,MAAM,aAAa,kBAAkB;CACrC,MAAM,YAAY,kBAAkB,UAAU;CAC9C,MAAM,OAAO,OAAO,KAAK,SAAS;CAElC,IAAI,KAAK,WAAW,GAAG;EACrB,EAAU,KAAK,2BAA2B;EAC1C,GAAY,EAAE;EACd;CACF;CAEA,MAAM,WAAW,MAAMA,GAAkB;EACvC,SAAS;EACT,SAAS,KAAK,KAAI,OAAM;GACtB,OAAO;GACP,OAAO;EACT,EAAE;EACF,UAAU;CACZ,CAAC;CAED,IAAIC,IAAS,QAAQ,GAAG;CAExB,MAAM,WAAW;CAEjB,MAAM,YAAY,MAAMC,GAAc,EACpC,SAAS,UAAU,SAAS,OAAO,eACrC,CAAC;CAED,IAAID,IAAS,SAAS,KAAK,CAAC,WAAW;EACrC,GAAY,WAAW;EACvB;CACF;CAEA,KAAK,MAAM,OAAO,UAChB,oBAAoB,YAAY,GAAG;CAGrC,GAAY,KAAK,SAAS,OAAO,qBAAqB;AACxD"}
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 as ye, log as R, outro as fe } from "./dist.mjs";
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
- ye("Validate Config");
6
+ intro("Validate Config");
7
7
  const configPath = findConfigFile();
8
8
  if (!configPath) {
9
- R.error("No config file found.");
10
- fe("");
9
+ log.error("No config file found.");
10
+ outro("");
11
11
  return;
12
12
  }
13
- R.info(`Checking ${configPath}...`);
13
+ log.info(`Checking ${configPath}...`);
14
14
  try {
15
15
  readConfigFile(configPath);
16
- R.success("Config is valid ✓");
16
+ log.success("Config is valid ✓");
17
17
  } catch (error) {
18
- R.error(String(error));
18
+ log.error(String(error));
19
19
  }
20
- fe("");
20
+ outro("");
21
21
  }
22
22
  //#endregion
23
23
  export { validateConfigCommand };
@@ -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,GAAY,iBAAiB;CAE7B,MAAM,aAAa,eAAe;CAClC,IAAI,CAAC,YAAY;EACf,EAAU,MAAM,uBAAuB;EACvC,GAAY,EAAE;EACd;CACF;CAEA,EAAU,KAAK,YAAY,WAAW,IAAI;CAE1C,IAAI;EACF,eAAe,UAAU;EACzB,EAAU,QAAQ,mBAAmB;CACvC,SAAS,OAAO;EACd,EAAU,MAAM,OAAO,KAAK,CAAC;CAC/B;CAEA,GAAY,EAAE;AAChB"}
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 as le, intro as ye, isCancel as R$1, log as R, note as Ce, outro as fe, select as Ee, text as Re } from "./dist.mjs";
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) R.info(`Current key: ${maskKey(currentKey)}`);
70
- const apiKey = await Re({
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 (R$1(apiKey)) return null;
79
- Ce("You can also set the OPENROUTER_API_KEY environment variable\nto avoid storing the key in the config file.", "Tip");
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 Re({
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 (R$1(input)) return null;
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 Re({
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 (R$1(url)) return null;
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 Ee({
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 (R$1(authType)) return null;
127
+ if (isCancel(authType)) return null;
128
128
  return authType;
129
129
  }
130
130
  async function askHost(current) {
131
- const host = await Ee({
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 (R$1(host)) return null;
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 Ee({
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 (R$1(location)) return null;
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
- ye("Proxitor Setup Wizard");
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
- Ce(existingPath, "Existing config found");
191
- const reconfigure = await le({
190
+ note(existingPath, "Existing config found");
191
+ const reconfigure = await confirm({
192
192
  message: "Reconfigure?",
193
193
  initialValue: true
194
194
  });
195
- if (R$1(reconfigure) || !reconfigure) {
196
- fe("Using existing configuration");
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
- fe("Cancelled");
209
+ outro("Cancelled");
210
210
  return;
211
211
  }
212
212
  const port = await askPort(currentPort);
213
213
  if (port === null) {
214
- fe("Cancelled");
214
+ outro("Cancelled");
215
215
  return;
216
216
  }
217
217
  const baseUrl = await askBaseUrl(currentBaseUrl);
218
218
  if (baseUrl === null) {
219
- fe("Cancelled");
219
+ outro("Cancelled");
220
220
  return;
221
221
  }
222
222
  const authType = await askAuthType(currentAuthType);
223
223
  if (authType === null) {
224
- fe("Cancelled");
224
+ outro("Cancelled");
225
225
  return;
226
226
  }
227
227
  const host = await askHost(currentHost);
228
228
  if (host === null) {
229
- fe("Cancelled");
229
+ outro("Cancelled");
230
230
  return;
231
231
  }
232
232
  const location = await askSaveLocation(existingPath ?? void 0);
233
233
  if (location === null) {
234
- fe("Cancelled");
234
+ outro("Cancelled");
235
235
  return;
236
236
  }
237
237
  const yaml = buildYaml(apiKey, port, host, baseUrl, authType, existingRaw);
238
- Ce(yaml, "Preview");
239
- const save = await le({
238
+ note(yaml, "Preview");
239
+ const save = await confirm({
240
240
  message: "Save this configuration?",
241
241
  initialValue: true
242
242
  });
243
- if (R$1(save) || !save) {
244
- fe("Cancelled — no files written");
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
- fe(`Config saved to ${savePath}`);
251
+ outro(`Config saved to ${savePath}`);
252
252
  }
253
253
  //#endregion
254
254
  export { runWizard };
@@ -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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "proxitor",
3
- "version": "0.8.0",
3
+ "version": "0.9.0-beta.1",
4
4
  "type": "module",
5
5
  "description": "Lightweight proxy for routing CLI requests (claude-code, codex) to OpenRouter",
6
6
  "files": [