proxitor 0.14.0 → 0.16.0

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/cli.mjs CHANGED
@@ -19,7 +19,14 @@ var __defProp = Object.defineProperty;
19
19
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
20
20
  var __getOwnPropNames = Object.getOwnPropertyNames;
21
21
  var __hasOwnProp = Object.prototype.hasOwnProperty;
22
- var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
22
+ var __esmMin = (fn, res, err) => () => {
23
+ if (err) throw err[0];
24
+ try {
25
+ return fn && (res = fn(fn = 0)), res;
26
+ } catch (e) {
27
+ throw err = [e], e;
28
+ }
29
+ };
23
30
  var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
24
31
  var __exportAll = (all, no_symbols) => {
25
32
  let target = {};
@@ -41,7 +48,7 @@ var __copyProps = (to, from, except, desc) => {
41
48
  return to;
42
49
  };
43
50
  var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
44
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
51
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
45
52
  //#endregion
46
53
  //#region node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
47
54
  function assembleStyles() {
@@ -4352,7 +4359,7 @@ function wrapAnsi(string, columns, options) {
4352
4359
  return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
4353
4360
  }
4354
4361
  //#endregion
4355
- //#region node_modules/.pnpm/@clack+core@1.4.1/node_modules/@clack/core/dist/index.mjs
4362
+ //#region node_modules/.pnpm/@clack+core@1.4.2/node_modules/@clack/core/dist/index.mjs
4356
4363
  var import_src = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
4357
4364
  const ESC = "\x1B";
4358
4365
  const CSI = `${ESC}[`;
@@ -4411,7 +4418,7 @@ function findCursor(s, o, l) {
4411
4418
  return l[e].disabled ? findCursor(e, o < 0 ? -1 : 1, l) : e;
4412
4419
  }
4413
4420
  const settings = {
4414
- actions: new Set([
4421
+ actions: /* @__PURE__ */ new Set([
4415
4422
  "up",
4416
4423
  "down",
4417
4424
  "left",
@@ -4713,7 +4720,7 @@ function p$1(l, e) {
4713
4720
  function g$1(l, e) {
4714
4721
  return (e.label ?? String(e.value)).toLowerCase().includes(l.toLowerCase());
4715
4722
  }
4716
- function m(l, e) {
4723
+ function m$1(l, e) {
4717
4724
  if (e) return l ? e : e[0];
4718
4725
  }
4719
4726
  let T$1 = class T extends V {
@@ -4759,7 +4766,7 @@ let T$1 = class T extends V {
4759
4766
  this.userInput === " " && this._clearUserInput(), this._setUserInput(u, true), this.isNavigating = false;
4760
4767
  return;
4761
4768
  }
4762
- i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = m(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== void 0 && (t.name === "tab" || this.isNavigating && t.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
4769
+ i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = m$1(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== void 0 && (t.name === "tab" || this.isNavigating && t.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
4763
4770
  }
4764
4771
  deselectAll() {
4765
4772
  this.selectedValues = [];
@@ -4892,8 +4899,10 @@ var n$1 = class extends V {
4892
4899
  }
4893
4900
  };
4894
4901
  //#endregion
4895
- //#region node_modules/.pnpm/@clack+prompts@1.5.1/node_modules/@clack/prompts/dist/index.mjs
4902
+ //#region node_modules/.pnpm/@clack+prompts@1.6.0/node_modules/@clack/prompts/dist/index.mjs
4896
4903
  var dist_exports = /* @__PURE__ */ __exportAll({
4904
+ MULTISELECT_INSTRUCTIONS: () => MULTISELECT_INSTRUCTIONS,
4905
+ SELECT_INSTRUCTIONS: () => SELECT_INSTRUCTIONS,
4897
4906
  S_BAR: () => S_BAR,
4898
4907
  S_BAR_END: () => S_BAR_END,
4899
4908
  S_BAR_H: () => S_BAR_H,
@@ -4917,6 +4926,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
4917
4926
  S_WARN: () => S_WARN,
4918
4927
  autocomplete: () => autocomplete,
4919
4928
  confirm: () => confirm,
4929
+ formatInstructionFooter: () => formatInstructionFooter,
4920
4930
  intro: () => intro,
4921
4931
  isCI: () => isCI$1,
4922
4932
  isCancel: () => isCancel,
@@ -4937,16 +4947,16 @@ function isUnicodeSupported$1() {
4937
4947
  if (process$1.platform !== "win32") return process$1.env.TERM !== "linux";
4938
4948
  return Boolean(process$1.env.CI) || Boolean(process$1.env.WT_SESSION) || Boolean(process$1.env.TERMINUS_SUBLIME) || process$1.env.ConEmuTask === "{cmd::Cmder}" || process$1.env.TERM_PROGRAM === "Terminus-Sublime" || process$1.env.TERM_PROGRAM === "vscode" || process$1.env.TERM === "xterm-256color" || process$1.env.TERM === "alacritty" || process$1.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
4939
4949
  }
4940
- const unicode$1 = isUnicodeSupported$1(), isCI$1 = () => process.env.CI === "true", unicodeOr = (e, o) => unicode$1 ? e : o, S_STEP_ACTIVE = unicodeOr("◆", "*"), S_STEP_CANCEL = unicodeOr("■", "x"), S_STEP_ERROR = unicodeOr("▲", "x"), S_STEP_SUBMIT = unicodeOr("◇", "o"), S_BAR_START = unicodeOr("┌", "T"), S_BAR = unicodeOr("│", "|"), S_BAR_END = unicodeOr("└", "—"), S_RADIO_ACTIVE = unicodeOr("●", ">"), S_RADIO_INACTIVE = unicodeOr("○", " "), S_CHECKBOX_ACTIVE = unicodeOr("◻", "[•]"), S_CHECKBOX_SELECTED = unicodeOr("◼", "[+]"), S_CHECKBOX_INACTIVE = unicodeOr("◻", "[ ]"), S_BAR_H = unicodeOr("─", "-"), S_CORNER_TOP_RIGHT = unicodeOr("╮", "+"), S_CONNECT_LEFT = unicodeOr("├", "+"), S_CORNER_BOTTOM_RIGHT = unicodeOr("╯", "+"), S_CORNER_BOTTOM_LEFT = unicodeOr("╰", "+"), S_INFO = unicodeOr("●", "•"), S_SUCCESS = unicodeOr("◆", "*"), S_WARN = unicodeOr("▲", "!"), S_ERROR = unicodeOr("■", "x"), symbol = (e) => {
4941
- switch (e) {
4950
+ const unicode$1 = isUnicodeSupported$1(), isCI$1 = () => process.env.CI === "true", unicodeOr = (o, e) => unicode$1 ? o : e, S_STEP_ACTIVE = unicodeOr("◆", "*"), S_STEP_CANCEL = unicodeOr("■", "x"), S_STEP_ERROR = unicodeOr("▲", "x"), S_STEP_SUBMIT = unicodeOr("◇", "o"), S_BAR_START = unicodeOr("┌", "T"), S_BAR = unicodeOr("│", "|"), S_BAR_END = unicodeOr("└", "—"), S_RADIO_ACTIVE = unicodeOr("●", ">"), S_RADIO_INACTIVE = unicodeOr("○", " "), S_CHECKBOX_ACTIVE = unicodeOr("◻", "[•]"), S_CHECKBOX_SELECTED = unicodeOr("◼", "[+]"), S_CHECKBOX_INACTIVE = unicodeOr("◻", "[ ]"), S_BAR_H = unicodeOr("─", "-"), S_CORNER_TOP_RIGHT = unicodeOr("╮", "+"), S_CONNECT_LEFT = unicodeOr("├", "+"), S_CORNER_BOTTOM_RIGHT = unicodeOr("╯", "+"), S_CORNER_BOTTOM_LEFT = unicodeOr("╰", "+"), S_INFO = unicodeOr("●", "•"), S_SUCCESS = unicodeOr("◆", "*"), S_WARN = unicodeOr("▲", "!"), S_ERROR = unicodeOr("■", "x"), symbol = (o) => {
4951
+ switch (o) {
4942
4952
  case "initial":
4943
4953
  case "active": return styleText("cyan", S_STEP_ACTIVE);
4944
4954
  case "cancel": return styleText("red", S_STEP_CANCEL);
4945
4955
  case "error": return styleText("yellow", S_STEP_ERROR);
4946
4956
  case "submit": return styleText("green", S_STEP_SUBMIT);
4947
4957
  }
4948
- }, symbolBar = (e) => {
4949
- switch (e) {
4958
+ }, symbolBar = (o) => {
4959
+ switch (o) {
4950
4960
  case "initial":
4951
4961
  case "active": return styleText("cyan", S_BAR);
4952
4962
  case "cancel": return styleText("red", S_BAR);
@@ -4954,6 +4964,10 @@ const unicode$1 = isUnicodeSupported$1(), isCI$1 = () => process.env.CI === "tru
4954
4964
  case "submit": return styleText("green", S_BAR);
4955
4965
  }
4956
4966
  };
4967
+ function formatInstructionFooter(o, e) {
4968
+ const r = [`${e ? `${styleText("cyan", S_BAR)} ` : ""}${o.join(" • ")}`];
4969
+ return e && r.push(styleText("cyan", S_BAR_END)), r;
4970
+ }
4957
4971
  const E$1 = (l, o, g, c, h, O = false) => {
4958
4972
  let r = o, w = 0;
4959
4973
  if (O) for (let i = c - 1; i >= g && (r -= l[i].length, w++, !(r <= h)); i--);
@@ -5098,84 +5112,29 @@ ${g}
5098
5112
  }
5099
5113
  }).prompt();
5100
5114
  };
5101
- const log = {
5102
- message: (s = [], { symbol: e = styleText("gray", S_BAR), secondarySymbol: r = styleText("gray", S_BAR), output: m = process.stdout, spacing: l = 1, withGuide: c } = {}) => {
5103
- const t = [], o = c ?? settings.withGuide, f = o ? r : "", O = o ? `${e} ` : "", u = o ? `${r} ` : "";
5104
- for (let i = 0; i < l; i++) t.push(f);
5105
- const g = Array.isArray(s) ? s : s.split(`
5106
- `);
5107
- if (g.length > 0) {
5108
- const [i, ...y] = g;
5109
- i.length > 0 ? t.push(`${O}${i}`) : t.push(o ? e : "");
5110
- for (const p of y) p.length > 0 ? t.push(`${u}${p}`) : t.push(o ? r : "");
5111
- }
5112
- m.write(`${t.join(`
5113
- `)}
5114
- `);
5115
- },
5116
- info: (s, e) => {
5117
- log.message(s, {
5118
- ...e,
5119
- symbol: styleText("blue", S_INFO)
5120
- });
5121
- },
5122
- success: (s, e) => {
5123
- log.message(s, {
5124
- ...e,
5125
- symbol: styleText("green", S_SUCCESS)
5126
- });
5127
- },
5128
- step: (s, e) => {
5129
- log.message(s, {
5130
- ...e,
5131
- symbol: styleText("green", S_STEP_SUBMIT)
5132
- });
5133
- },
5134
- warn: (s, e) => {
5135
- log.message(s, {
5136
- ...e,
5137
- symbol: styleText("yellow", S_WARN)
5138
- });
5139
- },
5140
- /** alias for `log.warn()`. */
5141
- warning: (s, e) => {
5142
- log.warn(s, e);
5143
- },
5144
- error: (s, e) => {
5145
- log.message(s, {
5146
- ...e,
5147
- symbol: styleText("red", S_ERROR)
5148
- });
5149
- }
5150
- }, intro = (o = "", t) => {
5151
- const i = t?.output ?? process.stdout, e = t?.withGuide ?? settings.withGuide ? `${styleText("gray", S_BAR_START)} ` : "";
5152
- i.write(`${e}${o}
5153
- `);
5154
- }, outro = (o = "", t) => {
5155
- const i = t?.output ?? process.stdout, e = t?.withGuide ?? settings.withGuide ? `${styleText("gray", S_BAR)}
5156
- ${styleText("gray", S_BAR_END)} ` : "";
5157
- i.write(`${e}${o}
5158
-
5159
- `);
5160
- };
5161
- const d = (n, a) => n.split(`
5162
- `).map((m) => a(m)).join(`
5115
+ const MULTISELECT_INSTRUCTIONS = [
5116
+ `${styleText("dim", "↑/↓")} to navigate`,
5117
+ `${styleText("dim", "Space:")} select`,
5118
+ `${styleText("dim", "Enter:")} confirm`
5119
+ ];
5120
+ const m = (n, o) => n.split(`
5121
+ `).map((d) => o(d)).join(`
5163
5122
  `);
5164
5123
  const multiselect = (n) => {
5165
- const a = (t, o) => {
5124
+ const o = (t, a) => {
5166
5125
  const r = t.label ?? String(t.value);
5167
- return o === "disabled" ? `${styleText("gray", S_CHECKBOX_INACTIVE)} ${d(r, (l) => styleText(["strikethrough", "gray"], l))}${t.hint ? ` ${styleText("dim", `(${t.hint ?? "disabled"})`)}` : ""}` : o === "active" ? `${styleText("cyan", S_CHECKBOX_ACTIVE)} ${r}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : o === "selected" ? `${styleText("green", S_CHECKBOX_SELECTED)} ${d(r, (l) => styleText("dim", l))}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : o === "cancelled" ? `${d(r, (l) => styleText(["strikethrough", "dim"], l))}` : o === "active-selected" ? `${styleText("green", S_CHECKBOX_SELECTED)} ${r}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : o === "submitted" ? `${d(r, (l) => styleText("dim", l))}` : `${styleText("dim", S_CHECKBOX_INACTIVE)} ${d(r, (l) => styleText("dim", l))}`;
5168
- }, m = n.required ?? true;
5126
+ return a === "disabled" ? `${styleText("gray", S_CHECKBOX_INACTIVE)} ${m(r, (l) => styleText(["strikethrough", "gray"], l))}${t.hint ? ` ${styleText("dim", `(${t.hint ?? "disabled"})`)}` : ""}` : a === "active" ? `${styleText("cyan", S_CHECKBOX_ACTIVE)} ${r}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "selected" ? `${styleText("green", S_CHECKBOX_SELECTED)} ${m(r, (l) => styleText("dim", l))}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "cancelled" ? `${m(r, (l) => styleText(["strikethrough", "dim"], l))}` : a === "active-selected" ? `${styleText("green", S_CHECKBOX_SELECTED)} ${r}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}` : a === "submitted" ? `${m(r, (l) => styleText("dim", l))}` : `${styleText("dim", S_CHECKBOX_INACTIVE)} ${m(r, (l) => styleText("dim", l))}`;
5127
+ }, d = n.required ?? true;
5169
5128
  return new a$1({
5170
5129
  options: n.options,
5171
5130
  signal: n.signal,
5172
5131
  input: n.input,
5173
5132
  output: n.output,
5174
5133
  initialValues: n.initialValues,
5175
- required: m,
5134
+ required: d,
5176
5135
  cursorAt: n.cursorAt,
5177
5136
  validate(t) {
5178
- if (m && (t === void 0 || t.length === 0)) return `Please select at least one option.
5137
+ if (d && (t === void 0 || t.length === 0)) return `Please select at least one option.
5179
5138
  ${styleText("reset", styleText("dim", `Press ${styleText([
5180
5139
  "gray",
5181
5140
  "bgWhite",
@@ -5183,29 +5142,29 @@ ${styleText("reset", styleText("dim", `Press ${styleText([
5183
5142
  ], " space ")} to select, ${styleText("gray", styleText("bgWhite", styleText("inverse", " enter ")))} to submit`))}`;
5184
5143
  },
5185
5144
  render() {
5186
- const t = n.withGuide ?? settings.withGuide, o = wrapTextWithPrefix(n.output, n.message, t ? `${symbolBar(this.state)} ` : "", `${symbol(this.state)} `), r = `${t ? `${styleText("gray", S_BAR)}
5187
- ` : ""}${o}
5188
- `, l = this.value ?? [], g = (i, u) => {
5189
- if (i.disabled) return a(i, "disabled");
5145
+ const t = n.withGuide ?? settings.withGuide, a = wrapTextWithPrefix(n.output, n.message, t ? `${symbolBar(this.state)} ` : "", `${symbol(this.state)} `), r = `${t ? `${styleText("gray", S_BAR)}
5146
+ ` : ""}${a}
5147
+ `, l = this.value ?? [], p = (i, u) => {
5148
+ if (i.disabled) return o(i, "disabled");
5190
5149
  const s = l.includes(i.value);
5191
- return u && s ? a(i, "active-selected") : s ? a(i, "selected") : a(i, u ? "active" : "inactive");
5150
+ return u && s ? o(i, "active-selected") : s ? o(i, "selected") : o(i, u ? "active" : "inactive");
5192
5151
  };
5193
5152
  switch (this.state) {
5194
5153
  case "submit": {
5195
- const i = this.options.filter(({ value: s }) => l.includes(s)).map((s) => a(s, "submitted")).join(styleText("dim", ", ")) || styleText("dim", "none");
5154
+ const i = this.options.filter(({ value: s }) => l.includes(s)).map((s) => o(s, "submitted")).join(styleText("dim", ", ")) || styleText("dim", "none");
5196
5155
  return `${r}${wrapTextWithPrefix(n.output, i, t ? `${styleText("gray", S_BAR)} ` : "")}`;
5197
5156
  }
5198
5157
  case "cancel": {
5199
- const i = this.options.filter(({ value: s }) => l.includes(s)).map((s) => a(s, "cancelled")).join(styleText("dim", ", "));
5158
+ const i = this.options.filter(({ value: s }) => l.includes(s)).map((s) => o(s, "cancelled")).join(styleText("dim", ", "));
5200
5159
  if (i.trim() === "") return `${r}${styleText("gray", S_BAR)}`;
5201
5160
  return `${r}${wrapTextWithPrefix(n.output, i, t ? `${styleText("gray", S_BAR)} ` : "")}${t ? `
5202
5161
  ${styleText("gray", S_BAR)}` : ""}`;
5203
5162
  }
5204
5163
  case "error": {
5205
5164
  const i = t ? `${styleText("yellow", S_BAR)} ` : "", u = this.error.split(`
5206
- `).map((h, x) => x === 0 ? `${t ? `${styleText("yellow", S_BAR_END)} ` : ""}${styleText("yellow", h)}` : ` ${h}`).join(`
5165
+ `).map(($, x) => x === 0 ? `${t ? `${styleText("yellow", S_BAR_END)} ` : ""}${styleText("yellow", $)}` : ` ${$}`).join(`
5207
5166
  `), s = r.split(`
5208
- `).length, v = u.split(`
5167
+ `).length, g = u.split(`
5209
5168
  `).length + 1;
5210
5169
  return `${r}${i}${limitOptions({
5211
5170
  output: n.output,
@@ -5213,8 +5172,8 @@ ${styleText("gray", S_BAR)}` : ""}`;
5213
5172
  cursor: this.cursor,
5214
5173
  maxItems: n.maxItems,
5215
5174
  columnPadding: i.length,
5216
- rowPadding: s + v,
5217
- style: g
5175
+ rowPadding: s + g,
5176
+ style: p
5218
5177
  }).join(`
5219
5178
  ${i}`)}
5220
5179
  ${u}
@@ -5222,31 +5181,92 @@ ${u}
5222
5181
  }
5223
5182
  default: {
5224
5183
  const i = t ? `${styleText("cyan", S_BAR)} ` : "", u = r.split(`
5225
- `).length, s = t ? 2 : 1;
5184
+ `).length, s = formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t), g = s.join(`
5185
+ `), $ = s.length + 1;
5226
5186
  return `${r}${i}${limitOptions({
5227
5187
  output: n.output,
5228
5188
  options: this.options,
5229
5189
  cursor: this.cursor,
5230
5190
  maxItems: n.maxItems,
5231
5191
  columnPadding: i.length,
5232
- rowPadding: u + s,
5233
- style: g
5192
+ rowPadding: u + $,
5193
+ style: p
5234
5194
  }).join(`
5235
5195
  ${i}`)}
5236
- ${t ? styleText("cyan", S_BAR_END) : ""}
5196
+ ${g}
5237
5197
  `;
5238
5198
  }
5239
5199
  }
5240
5200
  }
5241
5201
  }).prompt();
5242
5202
  };
5243
- const W$1 = (o) => styleText("dim", o), C$1 = (o, e, s) => {
5203
+ const log = {
5204
+ message: (s = [], { symbol: e = styleText("gray", S_BAR), secondarySymbol: r = styleText("gray", S_BAR), output: m = process.stdout, spacing: l = 1, withGuide: c } = {}) => {
5205
+ const t = [], o = c ?? settings.withGuide, f = o ? r : "", O = o ? `${e} ` : "", u = o ? `${r} ` : "";
5206
+ for (let i = 0; i < l; i++) t.push(f);
5207
+ const g = Array.isArray(s) ? s : s.split(`
5208
+ `);
5209
+ if (g.length > 0) {
5210
+ const [i, ...y] = g;
5211
+ i.length > 0 ? t.push(`${O}${i}`) : t.push(o ? e : "");
5212
+ for (const p of y) p.length > 0 ? t.push(`${u}${p}`) : t.push(o ? r : "");
5213
+ }
5214
+ m.write(`${t.join(`
5215
+ `)}
5216
+ `);
5217
+ },
5218
+ info: (s, e) => {
5219
+ log.message(s, {
5220
+ ...e,
5221
+ symbol: styleText("blue", S_INFO)
5222
+ });
5223
+ },
5224
+ success: (s, e) => {
5225
+ log.message(s, {
5226
+ ...e,
5227
+ symbol: styleText("green", S_SUCCESS)
5228
+ });
5229
+ },
5230
+ step: (s, e) => {
5231
+ log.message(s, {
5232
+ ...e,
5233
+ symbol: styleText("green", S_STEP_SUBMIT)
5234
+ });
5235
+ },
5236
+ warn: (s, e) => {
5237
+ log.message(s, {
5238
+ ...e,
5239
+ symbol: styleText("yellow", S_WARN)
5240
+ });
5241
+ },
5242
+ /** alias for `log.warn()`. */
5243
+ warning: (s, e) => {
5244
+ log.warn(s, e);
5245
+ },
5246
+ error: (s, e) => {
5247
+ log.message(s, {
5248
+ ...e,
5249
+ symbol: styleText("red", S_ERROR)
5250
+ });
5251
+ }
5252
+ }, intro = (o = "", t) => {
5253
+ const i = t?.output ?? process.stdout, e = t?.withGuide ?? settings.withGuide ? `${styleText("gray", S_BAR_START)} ` : "";
5254
+ i.write(`${e}${o}
5255
+ `);
5256
+ }, outro = (o = "", t) => {
5257
+ const i = t?.output ?? process.stdout, e = t?.withGuide ?? settings.withGuide ? `${styleText("gray", S_BAR)}
5258
+ ${styleText("gray", S_BAR_END)} ` : "";
5259
+ i.write(`${e}${o}
5260
+
5261
+ `);
5262
+ };
5263
+ const W$1 = (o) => o, C$1 = (o, e, s) => {
5244
5264
  const a = {
5245
5265
  hard: true,
5246
5266
  trim: false
5247
5267
  }, i = wrapAnsi(o, e, a).split(`
5248
- `), c = i.reduce((n, r) => Math.max(fastStringWidth(r), n), 0);
5249
- return wrapAnsi(o, e - (i.map(s).reduce((n, r) => Math.max(fastStringWidth(r), n), 0) - c), a);
5268
+ `), c = i.reduce((n, t) => Math.max(fastStringWidth(t), n), 0);
5269
+ return wrapAnsi(o, e - (i.map(s).reduce((n, t) => Math.max(fastStringWidth(t), n), 0) - c), a);
5250
5270
  };
5251
5271
  const note = (o = "", e = "", s) => {
5252
5272
  const a = s?.output ?? process$1.stdout, i = s?.withGuide ?? settings.withGuide, c = s?.format ?? W$1, g = [
@@ -5254,15 +5274,15 @@ const note = (o = "", e = "", s) => {
5254
5274
  ...C$1(o, getColumns(a) - 6, c).split(`
5255
5275
  `).map(c),
5256
5276
  ""
5257
- ], n = fastStringWidth(e), r = Math.max(g.reduce((m, F) => {
5277
+ ], n = fastStringWidth(e), t = Math.max(g.reduce((m, F) => {
5258
5278
  const O = fastStringWidth(F);
5259
5279
  return O > m ? O : m;
5260
- }, 0), n) + 2, h = g.map((m) => `${styleText("gray", S_BAR)} ${m}${" ".repeat(r - fastStringWidth(m))}${styleText("gray", S_BAR)}`).join(`
5280
+ }, 0), n) + 2, h = g.map((m) => `${styleText("gray", S_BAR)} ${m}${" ".repeat(t - fastStringWidth(m))}${styleText("gray", S_BAR)}`).join(`
5261
5281
  `), T = i ? `${styleText("gray", S_BAR)}
5262
5282
  ` : "", l$1 = i ? S_CONNECT_LEFT : S_CORNER_BOTTOM_LEFT;
5263
- a.write(`${T}${styleText("green", S_STEP_SUBMIT)} ${styleText("reset", e)} ${styleText("gray", S_BAR_H.repeat(Math.max(r - n - 1, 1)) + S_CORNER_TOP_RIGHT)}
5283
+ a.write(`${T}${styleText("green", S_STEP_SUBMIT)} ${styleText("reset", e)} ${styleText("gray", S_BAR_H.repeat(Math.max(t - n - 1, 1)) + S_CORNER_TOP_RIGHT)}
5264
5284
  ${h}
5265
- ${styleText("gray", l$1 + S_BAR_H.repeat(r + 2) + S_CORNER_BOTTOM_RIGHT)}
5285
+ ${styleText("gray", l$1 + S_BAR_H.repeat(t + 2) + S_CORNER_BOTTOM_RIGHT)}
5266
5286
  `);
5267
5287
  };
5268
5288
  const W = (l) => styleText("magenta", l);
@@ -5342,55 +5362,57 @@ const spinner = ({ indicator: l = "dots", onCancel: h, output: n = process.stdou
5342
5362
  }
5343
5363
  };
5344
5364
  };
5345
- const c$1 = (e, a) => e.includes(`
5346
- `) ? e.split(`
5347
- `).map((t) => a(t)).join(`
5348
- `) : a(e);
5349
- const select = (e) => {
5350
- const a = (t, d) => {
5351
- const s = t.label ?? String(t.value);
5352
- switch (d) {
5353
- case "disabled": return `${styleText("gray", S_RADIO_INACTIVE)} ${c$1(s, (n) => styleText("gray", n))}${t.hint ? ` ${styleText("dim", `(${t.hint ?? "disabled"})`)}` : ""}`;
5365
+ const SELECT_INSTRUCTIONS = [`${styleText("dim", "↑/↓")} to navigate`, `${styleText("dim", "Enter:")} confirm`];
5366
+ const c$1 = (t, a) => t.includes(`
5367
+ `) ? t.split(`
5368
+ `).map((i) => a(i)).join(`
5369
+ `) : a(t);
5370
+ const select = (t) => {
5371
+ const a = (i, m) => {
5372
+ const s = i.label ?? String(i.value);
5373
+ switch (m) {
5374
+ case "disabled": return `${styleText("gray", S_RADIO_INACTIVE)} ${c$1(s, (n) => styleText("gray", n))}${i.hint ? ` ${styleText("dim", `(${i.hint ?? "disabled"})`)}` : ""}`;
5354
5375
  case "selected": return `${c$1(s, (n) => styleText("dim", n))}`;
5355
- case "active": return `${styleText("green", S_RADIO_ACTIVE)} ${s}${t.hint ? ` ${styleText("dim", `(${t.hint})`)}` : ""}`;
5376
+ case "active": return `${styleText("green", S_RADIO_ACTIVE)} ${s}${i.hint ? ` ${styleText("dim", `(${i.hint})`)}` : ""}`;
5356
5377
  case "cancelled": return `${c$1(s, (n) => styleText(["strikethrough", "dim"], n))}`;
5357
5378
  default: return `${styleText("dim", S_RADIO_INACTIVE)} ${c$1(s, (n) => styleText("dim", n))}`;
5358
5379
  }
5359
5380
  };
5360
5381
  return new a$2({
5361
- options: e.options,
5362
- signal: e.signal,
5363
- input: e.input,
5364
- output: e.output,
5365
- initialValue: e.initialValue,
5382
+ options: t.options,
5383
+ signal: t.signal,
5384
+ input: t.input,
5385
+ output: t.output,
5386
+ initialValue: t.initialValue,
5366
5387
  render() {
5367
- const t = e.withGuide ?? settings.withGuide, d = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n = wrapTextWithPrefix(e.output, e.message, s, d), u = `${t ? `${styleText("gray", S_BAR)}
5388
+ const i = t.withGuide ?? settings.withGuide, m = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n = wrapTextWithPrefix(t.output, t.message, s, m), u = `${i ? `${styleText("gray", S_BAR)}
5368
5389
  ` : ""}${n}
5369
5390
  `;
5370
5391
  switch (this.state) {
5371
5392
  case "submit": {
5372
- const r = t ? `${styleText("gray", S_BAR)} ` : "";
5373
- return `${u}${wrapTextWithPrefix(e.output, a(this.options[this.cursor], "selected"), r)}`;
5393
+ const r = i ? `${styleText("gray", S_BAR)} ` : "";
5394
+ return `${u}${wrapTextWithPrefix(t.output, a(this.options[this.cursor], "selected"), r)}`;
5374
5395
  }
5375
5396
  case "cancel": {
5376
- const r = t ? `${styleText("gray", S_BAR)} ` : "";
5377
- return `${u}${wrapTextWithPrefix(e.output, a(this.options[this.cursor], "cancelled"), r)}${t ? `
5397
+ const r = i ? `${styleText("gray", S_BAR)} ` : "";
5398
+ return `${u}${wrapTextWithPrefix(t.output, a(this.options[this.cursor], "cancelled"), r)}${i ? `
5378
5399
  ${styleText("gray", S_BAR)}` : ""}`;
5379
5400
  }
5380
5401
  default: {
5381
- const r = t ? `${styleText("cyan", S_BAR)} ` : "", l = t ? styleText("cyan", S_BAR_END) : "", g = u.split(`
5382
- `).length, h = t ? 2 : 1;
5402
+ const r = i ? `${styleText("cyan", S_BAR)} ` : "", o = u.split(`
5403
+ `).length, $ = formatInstructionFooter(SELECT_INSTRUCTIONS, i), h = $.join(`
5404
+ `), b = $.length + 1;
5383
5405
  return `${u}${r}${limitOptions({
5384
- output: e.output,
5406
+ output: t.output,
5385
5407
  cursor: this.cursor,
5386
5408
  options: this.options,
5387
- maxItems: e.maxItems,
5409
+ maxItems: t.maxItems,
5388
5410
  columnPadding: r.length,
5389
- rowPadding: g + h,
5390
- style: (p, b) => a(p, p.disabled ? "disabled" : b ? "active" : "inactive")
5411
+ rowPadding: o + b,
5412
+ style: (p, x) => a(p, p.disabled ? "disabled" : x ? "active" : "inactive")
5391
5413
  }).join(`
5392
5414
  ${r}`)}
5393
- ${l}
5415
+ ${h}
5394
5416
  `;
5395
5417
  }
5396
5418
  }
@@ -6214,7 +6236,7 @@ var require_Collection = /* @__PURE__ */ __commonJSMin(((exports) => {
6214
6236
  const a = [];
6215
6237
  a[k] = v;
6216
6238
  v = a;
6217
- } else v = new Map([[k, v]]);
6239
+ } else v = /* @__PURE__ */ new Map([[k, v]]);
6218
6240
  }
6219
6241
  return createNode.createNode(v, void 0, {
6220
6242
  aliasDuplicateObjects: false,
@@ -6773,7 +6795,7 @@ var require_stringify = /* @__PURE__ */ __commonJSMin(((exports) => {
6773
6795
  if (ctx.resolvedAliases?.has(item)) throw new TypeError(`Cannot stringify circular structure without alias nodes`);
6774
6796
  else {
6775
6797
  if (ctx.resolvedAliases) ctx.resolvedAliases.add(item);
6776
- else ctx.resolvedAliases = new Set([item]);
6798
+ else ctx.resolvedAliases = /* @__PURE__ */ new Set([item]);
6777
6799
  item = item.resolve(ctx.doc);
6778
6800
  }
6779
6801
  }
@@ -8167,7 +8189,7 @@ var require_tags = /* @__PURE__ */ __commonJSMin(((exports) => {
8167
8189
  var schema$2 = require_schema();
8168
8190
  var set = require_set();
8169
8191
  var timestamp = require_timestamp();
8170
- const schemas = new Map([
8192
+ const schemas = /* @__PURE__ */ new Map([
8171
8193
  ["core", schema.schema],
8172
8194
  ["failsafe", [
8173
8195
  map.map,
@@ -8826,7 +8848,7 @@ var require_resolve_block_map = /* @__PURE__ */ __commonJSMin(((exports) => {
8826
8848
  var utilMapIncludes = require_util_map_includes();
8827
8849
  const startColMsg = "All mapping items must start at the same column";
8828
8850
  function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, tag) {
8829
- const map = new (tag?.nodeClass ?? YAMLMap.YAMLMap)(ctx.schema);
8851
+ const map = new ((tag?.nodeClass) ?? YAMLMap.YAMLMap)(ctx.schema);
8830
8852
  if (ctx.atRoot) ctx.atRoot = false;
8831
8853
  let offset = bm.offset;
8832
8854
  let commentEnd = null;
@@ -8906,7 +8928,7 @@ var require_resolve_block_seq = /* @__PURE__ */ __commonJSMin(((exports) => {
8906
8928
  var resolveProps = require_resolve_props();
8907
8929
  var utilFlowIndentCheck = require_util_flow_indent_check();
8908
8930
  function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, tag) {
8909
- const seq = new (tag?.nodeClass ?? YAMLSeq.YAMLSeq)(ctx.schema);
8931
+ const seq = new ((tag?.nodeClass) ?? YAMLSeq.YAMLSeq)(ctx.schema);
8910
8932
  if (ctx.atRoot) ctx.atRoot = false;
8911
8933
  if (ctx.atKey) ctx.atKey = false;
8912
8934
  let offset = bs.offset;
@@ -8995,7 +9017,7 @@ var require_resolve_flow_collection = /* @__PURE__ */ __commonJSMin(((exports) =
8995
9017
  function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onError, tag) {
8996
9018
  const isMap = fc.start.source === "{";
8997
9019
  const fcName = isMap ? "flow map" : "flow sequence";
8998
- const coll = new (tag?.nodeClass ?? (isMap ? YAMLMap.YAMLMap : YAMLSeq.YAMLSeq))(ctx.schema);
9020
+ const coll = new ((tag?.nodeClass) ?? (isMap ? YAMLMap.YAMLMap : YAMLSeq.YAMLSeq))(ctx.schema);
8999
9021
  coll.flow = true;
9000
9022
  const atRoot = ctx.atRoot;
9001
9023
  if (atRoot) ctx.atRoot = false;
@@ -12168,7 +12190,10 @@ function assignProp(target, prop, value) {
12168
12190
  }
12169
12191
  function mergeDefs(...defs) {
12170
12192
  const mergedDescriptors = {};
12171
- for (const def of defs) Object.assign(mergedDescriptors, Object.getOwnPropertyDescriptors(def));
12193
+ for (const def of defs) {
12194
+ const descriptors = Object.getOwnPropertyDescriptors(def);
12195
+ Object.assign(mergedDescriptors, descriptors);
12196
+ }
12172
12197
  return Object.defineProperties({}, mergedDescriptors);
12173
12198
  }
12174
12199
  function esc(str) {
@@ -12490,7 +12515,7 @@ const _parse = (_Err) => (schema, value, _ctx, _params) => {
12490
12515
  }, ctx);
12491
12516
  if (result instanceof Promise) throw new $ZodAsyncError();
12492
12517
  if (result.issues.length) {
12493
- const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
12518
+ const e = new ((_params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
12494
12519
  captureStackTrace(e, _params?.callee);
12495
12520
  throw e;
12496
12521
  }
@@ -12507,7 +12532,7 @@ const _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
12507
12532
  }, ctx);
12508
12533
  if (result instanceof Promise) result = await result;
12509
12534
  if (result.issues.length) {
12510
- const e = new (params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
12535
+ const e = new ((params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
12511
12536
  captureStackTrace(e, params?.callee);
12512
12537
  throw e;
12513
12538
  }
@@ -13599,13 +13624,13 @@ const $ZodObject = /*@__PURE__*/ $constructor("$ZodObject", (inst, def) => {
13599
13624
  }
13600
13625
  return propValues;
13601
13626
  });
13602
- const isObject$1 = isObject;
13627
+ const isObject$2 = isObject;
13603
13628
  const catchall = def.catchall;
13604
13629
  let value;
13605
13630
  inst._zod.parse = (payload, ctx) => {
13606
13631
  value ?? (value = _normalized.value);
13607
13632
  const input = payload.value;
13608
- if (!isObject$1(input)) {
13633
+ if (!isObject$2(input)) {
13609
13634
  payload.issues.push({
13610
13635
  expected: "object",
13611
13636
  code: "invalid_type",
@@ -13728,7 +13753,7 @@ const $ZodObjectJIT = /*@__PURE__*/ $constructor("$ZodObjectJIT", (inst, def) =>
13728
13753
  return (payload, ctx) => fn(shape, payload, ctx);
13729
13754
  };
13730
13755
  let fastpass;
13731
- const isObject$2 = isObject;
13756
+ const isObject$1 = isObject;
13732
13757
  const jit = !globalConfig.jitless;
13733
13758
  const fastEnabled = jit && allowsEval.value;
13734
13759
  const catchall = def.catchall;
@@ -13736,7 +13761,7 @@ const $ZodObjectJIT = /*@__PURE__*/ $constructor("$ZodObjectJIT", (inst, def) =>
13736
13761
  inst._zod.parse = (payload, ctx) => {
13737
13762
  value ?? (value = _normalized.value);
13738
13763
  const input = payload.value;
13739
- if (!isObject$2(input)) {
13764
+ if (!isObject$1(input)) {
13740
13765
  payload.issues.push({
13741
13766
  expected: "object",
13742
13767
  code: "invalid_type",
@@ -14064,7 +14089,7 @@ const $ZodOptional = /*@__PURE__*/ $constructor("$ZodOptional", (inst, def) => {
14064
14089
  inst._zod.optin = "optional";
14065
14090
  inst._zod.optout = "optional";
14066
14091
  defineLazy(inst._zod, "values", () => {
14067
- return def.innerType._zod.values ? new Set([...def.innerType._zod.values, void 0]) : void 0;
14092
+ return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, void 0]) : void 0;
14068
14093
  });
14069
14094
  defineLazy(inst._zod, "pattern", () => {
14070
14095
  const pattern = def.innerType._zod.pattern;
@@ -14098,7 +14123,7 @@ const $ZodNullable = /*@__PURE__*/ $constructor("$ZodNullable", (inst, def) => {
14098
14123
  return pattern ? new RegExp(`^(${cleanRegex(pattern.source)}|null)$`) : void 0;
14099
14124
  });
14100
14125
  defineLazy(inst._zod, "values", () => {
14101
- return def.innerType._zod.values ? new Set([...def.innerType._zod.values, null]) : void 0;
14126
+ return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, null]) : void 0;
14102
14127
  });
14103
14128
  inst._zod.parse = (payload, ctx) => {
14104
14129
  if (payload.value === null) return payload;
@@ -16304,6 +16329,16 @@ var MissingConfigError = class extends Error {
16304
16329
  }
16305
16330
  };
16306
16331
  //#endregion
16332
+ //#region src/model-id.ts
16333
+ /** `"anthropic/claude-sonnet-4"` → `"anthropic"`; a bare `"gpt-4o"` → `"gpt-4o"`. */
16334
+ function parseModelAuthor(modelId) {
16335
+ return modelId.split("/")[0] ?? "";
16336
+ }
16337
+ /** Text after the first `/`, or `""` for a bare id. `"openai/gpt-4o"` → `"gpt-4o"`. */
16338
+ function parseModelSlug(modelId) {
16339
+ return modelId.split("/").slice(1).join("/");
16340
+ }
16341
+ //#endregion
16307
16342
  //#region src/utils.ts
16308
16343
  /** Format an API key with the appropriate auth prefix based on authType. Defaults to Bearer. */
16309
16344
  function formatAuthHeader(key, authType) {
@@ -16386,14 +16421,49 @@ function buildProviderRouting(provider) {
16386
16421
  if (result.order) result.allow_fallbacks = provider.allowFallbacks ?? true;
16387
16422
  return Object.keys(result).length > 0 ? result : void 0;
16388
16423
  }
16424
+ /** Slug after the vendor prefix; bare ids keep their text. Delegates to parseModelSlug. */
16425
+ function modelSlug(s) {
16426
+ return parseModelSlug(s) || s;
16427
+ }
16389
16428
  function matchScore(pattern, modelName) {
16390
- if (pattern === modelName) return modelName.length + 1e3;
16391
- if (pattern.endsWith("*") && modelName.startsWith(pattern.slice(0, -1))) return pattern.length;
16429
+ if (pattern === modelName) return 3e3 + pattern.length;
16430
+ if (pattern.endsWith("*") && modelName.startsWith(pattern.slice(0, -1))) return 2e3 + pattern.length;
16431
+ if (pattern.includes("/") && modelName.includes("/")) return -1;
16432
+ const sp = modelSlug(pattern);
16433
+ const sm = modelSlug(modelName);
16434
+ if (sp === sm) return 1e3 + sp.length;
16435
+ if (sp.endsWith("*") && sm.startsWith(sp.slice(0, -1))) return sp.length;
16392
16436
  return -1;
16393
16437
  }
16394
16438
  function matchesPattern(pattern, modelName) {
16395
16439
  return matchScore(pattern, modelName) >= 0;
16396
16440
  }
16441
+ /** Override keys sharing a slug. `winner` is the key a bare name resolves to — not always `keys[0]`, since a bare key wins on the full-exact tier. Pure; callers log it. */
16442
+ function detectSlugCollisions(overrides) {
16443
+ if (!overrides) return [];
16444
+ const groups = /* @__PURE__ */ new Map();
16445
+ for (const key of Object.keys(overrides)) {
16446
+ const slug = modelSlug(key);
16447
+ const keys = groups.get(slug);
16448
+ if (keys) keys.push(key);
16449
+ else groups.set(slug, [key]);
16450
+ }
16451
+ const collisions = [];
16452
+ for (const [slug, keys] of groups) {
16453
+ if (keys.length <= 1) continue;
16454
+ const winner = findBestMatch(keys, slug);
16455
+ if (winner) collisions.push({
16456
+ slug,
16457
+ keys,
16458
+ winner
16459
+ });
16460
+ }
16461
+ return collisions;
16462
+ }
16463
+ /** Warning text for a same-slug collision. */
16464
+ function formatSlugCollisionWarning(c) {
16465
+ return `Overrides ${c.keys.map((k) => `"${k}"`).join(" and ")} share model slug "${c.slug}"; a bare name resolves to "${c.winner}". Use the vendor-prefixed name to pick a specific one.`;
16466
+ }
16397
16467
  function resolveModelConfig(config, modelName) {
16398
16468
  const result = {
16399
16469
  provider: config.provider,
@@ -16406,7 +16476,10 @@ function resolveModelConfig(config, modelName) {
16406
16476
  };
16407
16477
  if (!modelName || !config.modelOverrides) return result;
16408
16478
  const bestPattern = findBestMatch(Object.keys(config.modelOverrides), modelName);
16409
- if (bestPattern) applyOverride(result, config.modelOverrides[bestPattern]);
16479
+ if (bestPattern) {
16480
+ applyOverride(result, config.modelOverrides[bestPattern]);
16481
+ result.matchedOverride = bestPattern;
16482
+ }
16410
16483
  return result;
16411
16484
  }
16412
16485
  function findBestMatch(patterns, modelName) {
@@ -16519,6 +16592,106 @@ function readConfigFileRaw(filePath) {
16519
16592
  return raw ?? {};
16520
16593
  }
16521
16594
  //#endregion
16595
+ //#region src/openrouter/fuzzy.ts
16596
+ const SCORE_MATCH = 16;
16597
+ const BONUS_BOUNDARY = 7;
16598
+ const BONUS_CONSECUTIVE = 10;
16599
+ const PENALTY_GAP = 1;
16600
+ const DELIMITERS = /* @__PURE__ */ new Set([
16601
+ "/",
16602
+ "-",
16603
+ "_",
16604
+ ".",
16605
+ " "
16606
+ ]);
16607
+ const NINF = Number.NEGATIVE_INFINITY;
16608
+ function newRow(length) {
16609
+ return Array.from({ length }, () => NINF);
16610
+ }
16611
+ function isBoundary(target, index) {
16612
+ return index === 0 || DELIMITERS.has(target[index - 1] ?? "");
16613
+ }
16614
+ /**
16615
+ * Best score for carrying the first `i` query chars forward into a match placed
16616
+ * at target index `j` — i.e. the strongest preceding run plus gap/penalty math.
16617
+ * Does not include the score for the char placed at `j` itself.
16618
+ */
16619
+ function bestLink(prev, i, j) {
16620
+ let best = NINF;
16621
+ for (let k = i - 1; k < j; k++) {
16622
+ const base = prev[k] ?? NINF;
16623
+ if (base === NINF) continue;
16624
+ const gap = j - k - 1;
16625
+ const consecutive = gap === 0 ? BONUS_CONSECUTIVE : 0;
16626
+ const score = base - gap * PENALTY_GAP + consecutive;
16627
+ if (score > best) best = score;
16628
+ }
16629
+ return best;
16630
+ }
16631
+ /** One DP row: best scores matching q[0..i] with q[i] placed in target `t`. */
16632
+ function computeRow(t, q, i, prev) {
16633
+ const curr = newRow(t.length);
16634
+ const qi = q[i] ?? "";
16635
+ const maxJ = t.length - (q.length - i - 1);
16636
+ for (let j = i; j < maxJ; j++) {
16637
+ if (t[j] !== qi) continue;
16638
+ const placed = SCORE_MATCH + (isBoundary(t, j) ? BONUS_BOUNDARY : 0);
16639
+ if (i === 0) {
16640
+ curr[j] = placed;
16641
+ continue;
16642
+ }
16643
+ const link = bestLink(prev, i, j);
16644
+ curr[j] = link === NINF ? NINF : link + placed;
16645
+ }
16646
+ return curr;
16647
+ }
16648
+ function rowMax(row) {
16649
+ let best = NINF;
16650
+ for (let j = 0; j < row.length; j++) {
16651
+ const value = row[j] ?? NINF;
16652
+ if (value > best) best = value;
16653
+ }
16654
+ return best;
16655
+ }
16656
+ /**
16657
+ * Score `query` against `target` using fuzzy subsequence matching.
16658
+ *
16659
+ * Returns `null` when `query` is not a subsequence of `target`
16660
+ * (case-insensitive). Otherwise returns a non-negative score where higher
16661
+ * numbers indicate a better — more compact, boundary-aligned — match.
16662
+ *
16663
+ * A forward Smith-Waterman-style DP maximizes over every valid subsequence
16664
+ * alignment, so the best run of consecutive/boundary matches always wins.
16665
+ */
16666
+ function fuzzyScore(target, query) {
16667
+ const t = target.toLowerCase();
16668
+ const q = query.toLowerCase();
16669
+ const m = q.length;
16670
+ const n = t.length;
16671
+ if (m === 0) return 0;
16672
+ if (m > n) return null;
16673
+ let prev = newRow(n);
16674
+ for (let i = 0; i < m; i++) prev = computeRow(t, q, i, prev);
16675
+ const best = rowMax(prev);
16676
+ return best === NINF ? null : best;
16677
+ }
16678
+ /**
16679
+ * Rank models by fuzzy relevance to `query`, best match first.
16680
+ *
16681
+ * Models that do not contain `query` as a subsequence of `${id} ${name}` are
16682
+ * dropped. An empty query returns every model in its original order. Generic in
16683
+ * `T` so callers keep their full element type (the full `OpenRouterModel` at
16684
+ * the call sites, a two-field literal in tests).
16685
+ */
16686
+ function rankModels(models, query) {
16687
+ const q = query.trim();
16688
+ if (!q) return models;
16689
+ return models.map((model) => ({
16690
+ model,
16691
+ score: fuzzyScore(`${model.id} ${model.name}`, q)
16692
+ })).filter((entry) => entry.score !== null).sort((a, b) => b.score - a.score).map((entry) => entry.model);
16693
+ }
16694
+ //#endregion
16522
16695
  //#region src/openrouter/cache.ts
16523
16696
  const CACHE_DIR = join(homedir(), ".cache", "proxitor");
16524
16697
  /** Read a cached value. Returns `null` when missing, expired (older than `ttlMs`), or unparseable. */
@@ -16552,14 +16725,6 @@ async function fetchModels(client) {
16552
16725
  writeCache(CACHE_KEY$1, models);
16553
16726
  return models;
16554
16727
  }
16555
- /** `"anthropic/claude-sonnet-4"` → `"anthropic"` */
16556
- function parseModelAuthor(modelId) {
16557
- return modelId.split("/")[0] ?? "";
16558
- }
16559
- /** `"anthropic/claude-sonnet-4"` → `"claude-sonnet-4"` */
16560
- function parseModelSlug(modelId) {
16561
- return modelId.split("/").slice(1).join("/");
16562
- }
16563
16728
  /** `"0.000003"` → `"$3.00"`, `"0"` → `"free"` */
16564
16729
  function formatPrice(pricePerToken) {
16565
16730
  const per1M = Number.parseFloat(pricePerToken) * 1e6;
@@ -18133,9 +18298,7 @@ async function searchModel(models) {
18133
18298
  value: CUSTOM_PATTERN_VALUE,
18134
18299
  label: "✏️ Enter custom pattern (e.g. \"claude-*\")"
18135
18300
  }];
18136
- return [...models.filter((m) => {
18137
- return `${m.id} ${m.name}`.toLowerCase().includes(query);
18138
- }).slice(0, 14).map((m) => ({
18301
+ return [...rankModels(models, query).slice(0, 14).map((m) => ({
18139
18302
  value: m.id,
18140
18303
  label: formatModelLabel(m),
18141
18304
  hint: formatModelHint(m)
@@ -18321,9 +18484,7 @@ async function browseModelsCommand(client) {
18321
18484
  placeholder: "Type to search...",
18322
18485
  maxItems: 15,
18323
18486
  options() {
18324
- const query = this.userInput.trim().toLowerCase();
18325
- if (!query) return models.slice(0, 15).map(toOption);
18326
- return models.filter((m) => `${m.id} ${m.name}`.toLowerCase().includes(query)).slice(0, 15).map(toOption);
18487
+ return rankModels(models, this.userInput).slice(0, 15).map(toOption);
18327
18488
  },
18328
18489
  filter: (_search, _option) => true
18329
18490
  });
@@ -18771,8 +18932,8 @@ async function removeOverrideCommand(args = {}) {
18771
18932
  }
18772
18933
  //#endregion
18773
18934
  //#region src/commands/config/show.ts
18774
- const SEPARATE_KEYS = new Set([
18775
- ...new Set(["openrouterKey"]),
18935
+ const SEPARATE_KEYS = /* @__PURE__ */ new Set([
18936
+ .../* @__PURE__ */ new Set(["openrouterKey"]),
18776
18937
  "modelOverrides",
18777
18938
  "provider",
18778
18939
  "headers"
@@ -19393,7 +19554,7 @@ async function runConfigMenu(client) {
19393
19554
  }
19394
19555
  //#endregion
19395
19556
  //#region src/version.ts
19396
- const version = "0.14.0";
19557
+ const version = "0.16.0";
19397
19558
  //#endregion
19398
19559
  //#region src/commands/doctor.ts
19399
19560
  const DEFAULT_TIMEOUT_MS = 3e3;
@@ -19480,6 +19641,24 @@ function checkConfigValidity(path) {
19480
19641
  };
19481
19642
  }
19482
19643
  }
19644
+ function checkSlugCollisions(cfg) {
19645
+ if (!cfg?.modelOverrides) return {
19646
+ name: "override-collisions",
19647
+ status: "ok",
19648
+ message: "no model overrides"
19649
+ };
19650
+ const collisions = detectSlugCollisions(cfg.modelOverrides);
19651
+ if (collisions.length === 0) return {
19652
+ name: "override-collisions",
19653
+ status: "ok",
19654
+ message: "no slug collisions"
19655
+ };
19656
+ return {
19657
+ name: "override-collisions",
19658
+ status: "warn",
19659
+ message: collisions.map(formatSlugCollisionWarning).join(" | ")
19660
+ };
19661
+ }
19483
19662
  function checkApiKey(cfg) {
19484
19663
  const fromEnv = process.env.OPENROUTER_API_KEY ? "set" : "not set";
19485
19664
  const fromFile = cfg?.openrouterKey ? "set" : "not set";
@@ -19588,7 +19767,11 @@ async function doctorCommand(opts = {}) {
19588
19767
  ];
19589
19768
  const configPath = tryFindConfigFile();
19590
19769
  const { check: validityCheck, config: cfg } = checkConfigValidity(configPath);
19591
- const configChecks = [checkConfigDiscovery(), validityCheck];
19770
+ const configChecks = [
19771
+ checkConfigDiscovery(),
19772
+ validityCheck,
19773
+ checkSlugCollisions(cfg)
19774
+ ];
19592
19775
  const apiKeyCheck = checkApiKey(cfg);
19593
19776
  const upstreamCheck = await checkUpstream(cfg, timeoutMs, offline);
19594
19777
  const portCheck = cfg ? await checkPort(cfg.host, cfg.port) : {
@@ -19677,7 +19860,7 @@ function summarizeModelOverridesDiff(prev, next) {
19677
19860
  const prevKeys = new Set(Object.keys(prev ?? {}));
19678
19861
  const nextKeys = new Set(Object.keys(next ?? {}));
19679
19862
  const parts = [];
19680
- for (const key of [...new Set([...prevKeys, ...nextKeys])].sort()) {
19863
+ for (const key of [.../* @__PURE__ */ new Set([...prevKeys, ...nextKeys])].sort()) {
19681
19864
  const inPrev = prevKeys.has(key);
19682
19865
  const inNext = nextKeys.has(key);
19683
19866
  if (inPrev && inNext) {
@@ -19714,8 +19897,10 @@ var FileWatchingConfigSource = class {
19714
19897
  loading = false;
19715
19898
  pending = false;
19716
19899
  watching = false;
19900
+ lastCollisionSig = "";
19717
19901
  constructor(options) {
19718
19902
  this.current = options.initial;
19903
+ this.warnSlugCollisions(options.initial.modelOverrides);
19719
19904
  this.loadOptions = options.loadOptions;
19720
19905
  this.load = options.load ?? loadConfig;
19721
19906
  this.pollIntervalMs = options.pollIntervalMs ?? 1e3;
@@ -19727,6 +19912,18 @@ var FileWatchingConfigSource = class {
19727
19912
  get() {
19728
19913
  return this.current;
19729
19914
  }
19915
+ /** Warn only when the collision set changes, so reloading an unchanged config doesn't re-log. */
19916
+ warnSlugCollisions(overrides) {
19917
+ const collisions = detectSlugCollisions(overrides ?? void 0);
19918
+ const sig = collisions.map((c) => [
19919
+ c.slug,
19920
+ c.winner,
19921
+ [...c.keys].sort((a, b) => a.localeCompare(b)).join(",")
19922
+ ].join("|")).sort((a, b) => a.localeCompare(b)).join("||");
19923
+ if (sig === this.lastCollisionSig) return;
19924
+ this.lastCollisionSig = sig;
19925
+ for (const collision of collisions) logger.warn(formatSlugCollisionWarning(collision));
19926
+ }
19730
19927
  async reload() {
19731
19928
  if (this.loading) {
19732
19929
  this.pending = true;
@@ -19743,6 +19940,7 @@ var FileWatchingConfigSource = class {
19743
19940
  diff = "";
19744
19941
  }
19745
19942
  this.current = next;
19943
+ this.warnSlugCollisions(next.modelOverrides);
19746
19944
  if (restartNeeded) logger.warn("host/port changed — restart proxitor to apply (live reload does not re-bind the socket)");
19747
19945
  logger.info(`Config reloaded${diff ? ` — ${diff}` : " (no material changes)"}`);
19748
19946
  return { ok: true };
@@ -19792,7 +19990,7 @@ var FileWatchingConfigSource = class {
19792
19990
  }
19793
19991
  };
19794
19992
  //#endregion
19795
- //#region node_modules/.pnpm/@hono+node-server@2.0.4_hono@4.12.25/node_modules/@hono/node-server/dist/index.mjs
19993
+ //#region node_modules/.pnpm/@hono+node-server@2.0.5_hono@4.12.25/node_modules/@hono/node-server/dist/index.mjs
19796
19994
  var RequestError = class extends Error {
19797
19995
  constructor(message, options) {
19798
19996
  super(message, options);
@@ -20265,7 +20463,7 @@ const parseRedirectUrl = (url) => {
20265
20463
  if (validRedirectUrl.test(url)) return url;
20266
20464
  return new URL(url).href;
20267
20465
  };
20268
- const validRedirectStatuses = new Set([
20466
+ const validRedirectStatuses = /* @__PURE__ */ new Set([
20269
20467
  301,
20270
20468
  302,
20271
20469
  303,
@@ -20590,7 +20788,7 @@ const getRequestListener = (fetchCallback, options = {}) => {
20590
20788
  globalThis.CloseEvent;
20591
20789
  const CONNECTION_SYMBOL_KEY = Symbol("CONNECTION_SYMBOL_KEY");
20592
20790
  const WAIT_FOR_WEBSOCKET_SYMBOL = Symbol("WAIT_FOR_WEBSOCKET_SYMBOL");
20593
- const responseHeadersToSkip = new Set([
20791
+ const responseHeadersToSkip = /* @__PURE__ */ new Set([
20594
20792
  "connection",
20595
20793
  "content-length",
20596
20794
  "keep-alive",
@@ -22495,7 +22693,7 @@ var Hono = class extends Hono$1 {
22495
22693
  var createMiddleware = (middleware) => middleware;
22496
22694
  //#endregion
22497
22695
  //#region src/proxy/headers.ts
22498
- const HOP_BY_HOP = new Set([
22696
+ const HOP_BY_HOP = /* @__PURE__ */ new Set([
22499
22697
  "connection",
22500
22698
  "keep-alive",
22501
22699
  "proxy-authenticate",
@@ -22505,13 +22703,13 @@ const HOP_BY_HOP = new Set([
22505
22703
  "transfer-encoding",
22506
22704
  "upgrade"
22507
22705
  ]);
22508
- const STRIP_REQUEST = new Set([
22706
+ const STRIP_REQUEST = /* @__PURE__ */ new Set([
22509
22707
  "authorization",
22510
22708
  "x-api-key",
22511
22709
  "host",
22512
22710
  "content-length"
22513
22711
  ]);
22514
- const STRIP_RESPONSE = new Set(["content-length", "content-encoding"]);
22712
+ const STRIP_RESPONSE = /* @__PURE__ */ new Set(["content-length", "content-encoding"]);
22515
22713
  function filterHeaders(incoming, blocklist) {
22516
22714
  const headers = {};
22517
22715
  for (const [key, value] of incoming.entries()) {
@@ -22537,7 +22735,7 @@ function buildResponseHeaders(from) {
22537
22735
  //#endregion
22538
22736
  //#region src/proxy/middleware/build-upstream-req.ts
22539
22737
  const encoder = new TextEncoder();
22540
- const PROTO_POLLUTION_KEYS = new Set([
22738
+ const PROTO_POLLUTION_KEYS = /* @__PURE__ */ new Set([
22541
22739
  "__proto__",
22542
22740
  "constructor",
22543
22741
  "prototype"
@@ -22911,7 +23109,7 @@ const ENDPOINT_MAP = {
22911
23109
  };
22912
23110
  const INJECT_PATHS = new Set(Object.keys(ENDPOINT_MAP));
22913
23111
  /** Endpoints that are natively Anthropic (cache_control is always safe regardless of model). */
22914
- const ANTHROPIC_NATIVE_ENDPOINTS = new Set(["messages", "responses"]);
23112
+ const ANTHROPIC_NATIVE_ENDPOINTS = /* @__PURE__ */ new Set(["messages", "responses"]);
22915
23113
  function classifyEndpoint(pathname) {
22916
23114
  const queryIndex = pathname.indexOf("?");
22917
23115
  return ENDPOINT_MAP[queryIndex === -1 ? pathname : pathname.slice(0, queryIndex)] ?? "other";
@@ -23219,6 +23417,7 @@ const readBody = createMiddleware(async (c, next) => {
23219
23417
  const resolveConfig = createMiddleware(async (c, next) => {
23220
23418
  const resolved = resolveModelConfig(c.var.config, c.var.modelName);
23221
23419
  c.set("resolvedConfig", resolved);
23420
+ if (c.var.config.verbose && c.var.modelName) logger.info(resolved.matchedOverride ? `override "${resolved.matchedOverride}" matched incoming "${c.var.modelName}"` : `no override matched for "${c.var.modelName}"`);
23222
23421
  await next();
23223
23422
  });
23224
23423
  //#endregion
@@ -23633,14 +23832,14 @@ async function handleStartupError(err) {
23633
23832
  logger.error(err.message);
23634
23833
  process.exit(1);
23635
23834
  }
23636
- const KNOWN_SUBCOMMANDS = new Set([
23835
+ const KNOWN_SUBCOMMANDS = /* @__PURE__ */ new Set([
23637
23836
  "start",
23638
23837
  "up",
23639
23838
  "run",
23640
23839
  "config",
23641
23840
  "doctor"
23642
23841
  ]);
23643
- const KNOWN_CONFIG_SUBS = new Set([
23842
+ const KNOWN_CONFIG_SUBS = /* @__PURE__ */ new Set([
23644
23843
  "add",
23645
23844
  "edit",
23646
23845
  "remove",