@solongate/proxy 0.81.53 → 0.81.55

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/index.js CHANGED
@@ -10062,13 +10062,6 @@ import { Box as Box7, Text as Text7, useInput as useInput6 } from "ink";
10062
10062
  import TextInput5 from "ink-text-input";
10063
10063
  import { useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
10064
10064
  import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
10065
- function alertBodyFor(channel) {
10066
- const c2 = channel.trim();
10067
- const base = { name: "dataroom alert", threshold: 5, windowSeconds: 60, signal: "any" };
10068
- if (/^https?:\/\//i.test(c2)) return { ...base, slackUrl: c2 };
10069
- if (c2.includes("@")) return { ...base, emails: [c2] };
10070
- return { ...base, telegram: [c2] };
10071
- }
10072
10065
  function SettingsPanel({
10073
10066
  active: active2,
10074
10067
  focused,
@@ -10103,8 +10096,9 @@ function SettingsPanel({
10103
10096
  const whQ = useLoader(() => listAccounts().length ? api.settings.getWebhooks() : Promise.resolve(null));
10104
10097
  const alertQ = useLoader(() => listAccounts().length ? api.settings.getAlerts() : Promise.resolve(null));
10105
10098
  const local = localQ.data;
10106
- const webhooks = whQ.data?.webhooks ?? [];
10107
- const alerts = alertQ.data?.rules ?? [];
10099
+ const [hidden, setHidden] = useState7(/* @__PURE__ */ new Set());
10100
+ const webhooks = (whQ.data?.webhooks ?? []).filter((w) => !hidden.has("wh:" + w.id));
10101
+ const alerts = (alertQ.data?.rules ?? []).filter((r) => !hidden.has("alert:" + r.id));
10108
10102
  const rowsAll = [
10109
10103
  ...accounts.map((acc) => ({ kind: "acct", acc })),
10110
10104
  { kind: "acct-add" },
@@ -10115,7 +10109,8 @@ function SettingsPanel({
10115
10109
  ...webhooks.map((wh) => ({ kind: "wh", wh })),
10116
10110
  { kind: "wh-add" },
10117
10111
  ...alerts.map((rule) => ({ kind: "alert", rule })),
10118
- { kind: "alert-add" }
10112
+ { kind: "alert-add-email" },
10113
+ { kind: "alert-add-tg" }
10119
10114
  ]
10120
10115
  ];
10121
10116
  const selClamped = Math.min(sel, rowsAll.length - 1);
@@ -10200,9 +10195,12 @@ function SettingsPanel({
10200
10195
  setEditing("wh-url");
10201
10196
  } else if (r.kind === "alert") {
10202
10197
  run12(r.rule.enabled ? "alert disabled" : "alert enabled", () => api.settings.setAlertEnabled(r.rule.id, !r.rule.enabled), alertQ.reload);
10198
+ } else if (r.kind === "alert-add-email") {
10199
+ setInput("");
10200
+ setEditing("alert-email");
10203
10201
  } else {
10204
10202
  setInput("");
10205
- setEditing("alert-channel");
10203
+ setEditing("alert-tg");
10206
10204
  }
10207
10205
  };
10208
10206
  const submitInput = () => {
@@ -10213,11 +10211,29 @@ function SettingsPanel({
10213
10211
  const enabled = (local?.enabled ?? false) && v.length > 0;
10214
10212
  run12(v ? `path saved${enabled ? "" : " (press enter on enabled to turn on)"}` : "path cleared (local logs off)", () => api.settings.setLocalLogs({ enabled, path: v }), localQ.reload);
10215
10213
  } else if (which === "wh-url") {
10214
+ const url = v.replace(/^["'<]+|["'>]+$/g, "").trim();
10215
+ if (!url) return;
10216
+ if (!/^https?:\/\/\S+$/i.test(url)) {
10217
+ setMsg({ text: "\u2717 webhook url must start with http:// or https://", level: "bad" });
10218
+ return;
10219
+ }
10220
+ run12("webhook added", () => api.settings.createWebhook({ url, events: "denials" }), whQ.reload);
10221
+ } else if (which === "alert-email") {
10216
10222
  if (!v) return;
10217
- run12("webhook added", () => api.settings.createWebhook({ url: v, events: "denials" }), whQ.reload);
10218
- } else if (which === "alert-channel") {
10223
+ const email = v.replace(/^mailto:/i, "").replace(/^["'<]+|["'>]+$/g, "").replace(/[.,;:]+$/, "").replace(/\s+/g, "").trim();
10224
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
10225
+ setMsg({ text: "\u2717 that does not look like an e-mail address", level: "bad" });
10226
+ return;
10227
+ }
10228
+ run12("email alert added", () => api.settings.createAlert({ ...ALERT_BASE, emails: [email] }), alertQ.reload);
10229
+ } else if (which === "alert-tg") {
10219
10230
  if (!v) return;
10220
- run12("alert rule added", () => api.settings.createAlert(alertBodyFor(v)), alertQ.reload);
10231
+ const tg = v.replace(/^@/, "").replace(/^(chat[\s_-]*)?id[:=\s]*/i, "").replace(/\s+/g, "").trim();
10232
+ if (!/^-?\d{5,}$/.test(tg)) {
10233
+ setMsg({ text: "\u2717 a telegram chat id is a number \u2014 get yours from @userinfobot", level: "bad" });
10234
+ return;
10235
+ }
10236
+ run12("telegram alert added", () => api.settings.createAlert({ ...ALERT_BASE, telegram: [tg] }), alertQ.reload);
10221
10237
  }
10222
10238
  };
10223
10239
  useInput6(
@@ -10260,9 +10276,9 @@ function SettingsPanel({
10260
10276
  if (cur.kind === "wh" || cur.kind === "wh-add") {
10261
10277
  setInput("");
10262
10278
  setEditing("wh-url");
10263
- } else if (cur.kind === "alert" || cur.kind === "alert-add") {
10279
+ } else if (cur.kind === "alert" || cur.kind === "alert-add-email" || cur.kind === "alert-add-tg") {
10264
10280
  setInput("");
10265
- setEditing("alert-channel");
10281
+ setEditing("alert-email");
10266
10282
  }
10267
10283
  } else if (inp === "d" && (cur.kind === "wh" || cur.kind === "alert")) {
10268
10284
  const k = keyOf(cur);
@@ -10272,8 +10288,13 @@ function SettingsPanel({
10272
10288
  return;
10273
10289
  }
10274
10290
  setConfirmDel(null);
10275
- if (cur.kind === "wh") run12("webhook deleted", () => api.settings.deleteWebhook(cur.wh.id), whQ.reload);
10276
- else run12("alert deleted", () => api.settings.deleteAlert(cur.rule.id), alertQ.reload);
10291
+ if (cur.kind === "wh") {
10292
+ const id = cur.wh.id;
10293
+ run12("webhook deleted", () => api.settings.deleteWebhook(id).then(() => setHidden((h) => new Set(h).add("wh:" + id))), whQ.reload);
10294
+ } else {
10295
+ const id = cur.rule.id;
10296
+ run12("alert deleted", () => api.settings.deleteAlert(id).then(() => setHidden((h) => new Set(h).add("alert:" + id))), alertQ.reload);
10297
+ }
10277
10298
  } else if (inp === "r") reloadAll();
10278
10299
  },
10279
10300
  { isActive: focused && !editing }
@@ -10302,7 +10323,7 @@ function SettingsPanel({
10302
10323
  const error = locked ? null : localQ.error ?? whQ.error ?? alertQ.error;
10303
10324
  const mark = (r) => keyOf(r) === keyOf(cur) && focused ? "\u25B8 " : " ";
10304
10325
  const onOff = (on) => on ? /* @__PURE__ */ jsx7(Text7, { color: theme.ok, children: "on " }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "off" });
10305
- const chanOf = (rule) => [...(rule.slackUrls ?? []).map((u) => "slack " + u), ...rule.emails ?? [], ...(rule.telegram ?? []).map((t) => "tg " + t)].join(", ") || "\u2014";
10326
+ const chanOf = (rule) => [...rule.emails ?? [], ...(rule.telegram ?? []).map((t) => "tg " + t)].join(", ") || "\u2014";
10306
10327
  const listBudget = Math.max(4, rows - 10);
10307
10328
  const start = Math.min(Math.max(0, selClamped - Math.floor(listBudget / 2)), Math.max(0, rowsAll.length - listBudget));
10308
10329
  const inWindow = (r) => {
@@ -10312,7 +10333,7 @@ function SettingsPanel({
10312
10333
  return /* @__PURE__ */ jsx7(DataView, { loading, error, children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
10313
10334
  /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: focused ? "\u2191\u2193 move \xB7 enter/m act \xB7 t test webhook \xB7 n add account \xB7 e events \xB7 d delete \xB7 r refresh" : "press \u2192 to configure" }),
10314
10335
  editing ? /* @__PURE__ */ jsxs7(Box7, { children: [
10315
- /* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: editing === "path" ? "local log path: " : editing === "wh-url" ? "webhook url: " : "channel (slack url / email / telegram id): " }),
10336
+ /* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: editing === "path" ? "local log path: " : editing === "wh-url" ? "webhook url: " : editing === "alert-email" ? "e-mail address: " : "telegram chat id (from @userinfobot): " }),
10316
10337
  /* @__PURE__ */ jsx7(TextInput5, { value: input, onChange: setInput, onSubmit: submitInput })
10317
10338
  ] }) : msg ? /* @__PURE__ */ jsx7(Text7, { color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate2(msg.text, cols) }) : login?.msg ? /* @__PURE__ */ jsx7(Text7, { color: login.phase === "error" ? theme.bad : theme.ok, children: login.msg }) : /* @__PURE__ */ jsx7(Text7, { children: " " }),
10318
10339
  /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
@@ -10405,15 +10426,19 @@ function SettingsPanel({
10405
10426
  /* @__PURE__ */ jsx7(Text7, { children: `\u2265${rule.threshold}/${rule.windowSeconds}s ` }),
10406
10427
  /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(chanOf(rule), cols - 26) })
10407
10428
  ] }, rule.id)),
10408
- inWindow({ kind: "alert-add" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
10409
- /* @__PURE__ */ jsx7(Text7, { color: cur.kind === "alert-add" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert-add" }) }),
10410
- /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add alert (enter \u2014 one channel: slack url, email or telegram chat id)" })
10429
+ inWindow({ kind: "alert-add-email" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
10430
+ /* @__PURE__ */ jsx7(Text7, { color: cur.kind === "alert-add-email" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert-add-email" }) }),
10431
+ /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add email alert (enter)" })
10432
+ ] }) : null,
10433
+ inWindow({ kind: "alert-add-tg" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
10434
+ /* @__PURE__ */ jsx7(Text7, { color: cur.kind === "alert-add-tg" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert-add-tg" }) }),
10435
+ /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add telegram alert (enter \u2014 numeric chat id, get it from @userinfobot)" })
10411
10436
  ] }) : null
10412
10437
  ] })
10413
10438
  ] })
10414
10439
  ] }) });
10415
10440
  }
10416
- var EVENTS, SPIN2, acctLabel;
10441
+ var EVENTS, SPIN2, ALERT_BASE, acctLabel;
10417
10442
  var init_Settings = __esm({
10418
10443
  "src/tui/panels/Settings.tsx"() {
10419
10444
  "use strict";
@@ -10426,6 +10451,7 @@ var init_Settings = __esm({
10426
10451
  init_theme();
10427
10452
  EVENTS = ["denials", "allowed", "all"];
10428
10453
  SPIN2 = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
10454
+ ALERT_BASE = { name: "dataroom alert", threshold: 5, windowSeconds: 60, signal: "any" };
10429
10455
  acctLabel = (a) => a.email || a.user || "account \u2026" + a.apiKey.slice(-4);
10430
10456
  }
10431
10457
  });
package/dist/tui/index.js CHANGED
@@ -3175,13 +3175,7 @@ function stopLogsServerDaemon() {
3175
3175
  import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
3176
3176
  var EVENTS = ["denials", "allowed", "all"];
3177
3177
  var SPIN2 = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
3178
- function alertBodyFor(channel) {
3179
- const c2 = channel.trim();
3180
- const base = { name: "dataroom alert", threshold: 5, windowSeconds: 60, signal: "any" };
3181
- if (/^https?:\/\//i.test(c2)) return { ...base, slackUrl: c2 };
3182
- if (c2.includes("@")) return { ...base, emails: [c2] };
3183
- return { ...base, telegram: [c2] };
3184
- }
3178
+ var ALERT_BASE = { name: "dataroom alert", threshold: 5, windowSeconds: 60, signal: "any" };
3185
3179
  var acctLabel = (a) => a.email || a.user || "account \u2026" + a.apiKey.slice(-4);
3186
3180
  function SettingsPanel({
3187
3181
  active: active2,
@@ -3217,8 +3211,9 @@ function SettingsPanel({
3217
3211
  const whQ = useLoader(() => listAccounts().length ? api.settings.getWebhooks() : Promise.resolve(null));
3218
3212
  const alertQ = useLoader(() => listAccounts().length ? api.settings.getAlerts() : Promise.resolve(null));
3219
3213
  const local = localQ.data;
3220
- const webhooks = whQ.data?.webhooks ?? [];
3221
- const alerts = alertQ.data?.rules ?? [];
3214
+ const [hidden, setHidden] = useState7(/* @__PURE__ */ new Set());
3215
+ const webhooks = (whQ.data?.webhooks ?? []).filter((w) => !hidden.has("wh:" + w.id));
3216
+ const alerts = (alertQ.data?.rules ?? []).filter((r) => !hidden.has("alert:" + r.id));
3222
3217
  const rowsAll = [
3223
3218
  ...accounts.map((acc) => ({ kind: "acct", acc })),
3224
3219
  { kind: "acct-add" },
@@ -3229,7 +3224,8 @@ function SettingsPanel({
3229
3224
  ...webhooks.map((wh) => ({ kind: "wh", wh })),
3230
3225
  { kind: "wh-add" },
3231
3226
  ...alerts.map((rule) => ({ kind: "alert", rule })),
3232
- { kind: "alert-add" }
3227
+ { kind: "alert-add-email" },
3228
+ { kind: "alert-add-tg" }
3233
3229
  ]
3234
3230
  ];
3235
3231
  const selClamped = Math.min(sel, rowsAll.length - 1);
@@ -3314,9 +3310,12 @@ function SettingsPanel({
3314
3310
  setEditing("wh-url");
3315
3311
  } else if (r.kind === "alert") {
3316
3312
  run(r.rule.enabled ? "alert disabled" : "alert enabled", () => api.settings.setAlertEnabled(r.rule.id, !r.rule.enabled), alertQ.reload);
3313
+ } else if (r.kind === "alert-add-email") {
3314
+ setInput("");
3315
+ setEditing("alert-email");
3317
3316
  } else {
3318
3317
  setInput("");
3319
- setEditing("alert-channel");
3318
+ setEditing("alert-tg");
3320
3319
  }
3321
3320
  };
3322
3321
  const submitInput = () => {
@@ -3327,11 +3326,29 @@ function SettingsPanel({
3327
3326
  const enabled = (local?.enabled ?? false) && v.length > 0;
3328
3327
  run(v ? `path saved${enabled ? "" : " (press enter on enabled to turn on)"}` : "path cleared (local logs off)", () => api.settings.setLocalLogs({ enabled, path: v }), localQ.reload);
3329
3328
  } else if (which === "wh-url") {
3329
+ const url = v.replace(/^["'<]+|["'>]+$/g, "").trim();
3330
+ if (!url) return;
3331
+ if (!/^https?:\/\/\S+$/i.test(url)) {
3332
+ setMsg({ text: "\u2717 webhook url must start with http:// or https://", level: "bad" });
3333
+ return;
3334
+ }
3335
+ run("webhook added", () => api.settings.createWebhook({ url, events: "denials" }), whQ.reload);
3336
+ } else if (which === "alert-email") {
3330
3337
  if (!v) return;
3331
- run("webhook added", () => api.settings.createWebhook({ url: v, events: "denials" }), whQ.reload);
3332
- } else if (which === "alert-channel") {
3338
+ const email = v.replace(/^mailto:/i, "").replace(/^["'<]+|["'>]+$/g, "").replace(/[.,;:]+$/, "").replace(/\s+/g, "").trim();
3339
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
3340
+ setMsg({ text: "\u2717 that does not look like an e-mail address", level: "bad" });
3341
+ return;
3342
+ }
3343
+ run("email alert added", () => api.settings.createAlert({ ...ALERT_BASE, emails: [email] }), alertQ.reload);
3344
+ } else if (which === "alert-tg") {
3333
3345
  if (!v) return;
3334
- run("alert rule added", () => api.settings.createAlert(alertBodyFor(v)), alertQ.reload);
3346
+ const tg = v.replace(/^@/, "").replace(/^(chat[\s_-]*)?id[:=\s]*/i, "").replace(/\s+/g, "").trim();
3347
+ if (!/^-?\d{5,}$/.test(tg)) {
3348
+ setMsg({ text: "\u2717 a telegram chat id is a number \u2014 get yours from @userinfobot", level: "bad" });
3349
+ return;
3350
+ }
3351
+ run("telegram alert added", () => api.settings.createAlert({ ...ALERT_BASE, telegram: [tg] }), alertQ.reload);
3335
3352
  }
3336
3353
  };
3337
3354
  useInput6(
@@ -3374,9 +3391,9 @@ function SettingsPanel({
3374
3391
  if (cur.kind === "wh" || cur.kind === "wh-add") {
3375
3392
  setInput("");
3376
3393
  setEditing("wh-url");
3377
- } else if (cur.kind === "alert" || cur.kind === "alert-add") {
3394
+ } else if (cur.kind === "alert" || cur.kind === "alert-add-email" || cur.kind === "alert-add-tg") {
3378
3395
  setInput("");
3379
- setEditing("alert-channel");
3396
+ setEditing("alert-email");
3380
3397
  }
3381
3398
  } else if (inp === "d" && (cur.kind === "wh" || cur.kind === "alert")) {
3382
3399
  const k = keyOf(cur);
@@ -3386,8 +3403,13 @@ function SettingsPanel({
3386
3403
  return;
3387
3404
  }
3388
3405
  setConfirmDel(null);
3389
- if (cur.kind === "wh") run("webhook deleted", () => api.settings.deleteWebhook(cur.wh.id), whQ.reload);
3390
- else run("alert deleted", () => api.settings.deleteAlert(cur.rule.id), alertQ.reload);
3406
+ if (cur.kind === "wh") {
3407
+ const id = cur.wh.id;
3408
+ run("webhook deleted", () => api.settings.deleteWebhook(id).then(() => setHidden((h) => new Set(h).add("wh:" + id))), whQ.reload);
3409
+ } else {
3410
+ const id = cur.rule.id;
3411
+ run("alert deleted", () => api.settings.deleteAlert(id).then(() => setHidden((h) => new Set(h).add("alert:" + id))), alertQ.reload);
3412
+ }
3391
3413
  } else if (inp === "r") reloadAll();
3392
3414
  },
3393
3415
  { isActive: focused && !editing }
@@ -3416,7 +3438,7 @@ function SettingsPanel({
3416
3438
  const error = locked ? null : localQ.error ?? whQ.error ?? alertQ.error;
3417
3439
  const mark = (r) => keyOf(r) === keyOf(cur) && focused ? "\u25B8 " : " ";
3418
3440
  const onOff = (on) => on ? /* @__PURE__ */ jsx7(Text7, { color: theme.ok, children: "on " }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "off" });
3419
- const chanOf = (rule) => [...(rule.slackUrls ?? []).map((u) => "slack " + u), ...rule.emails ?? [], ...(rule.telegram ?? []).map((t) => "tg " + t)].join(", ") || "\u2014";
3441
+ const chanOf = (rule) => [...rule.emails ?? [], ...(rule.telegram ?? []).map((t) => "tg " + t)].join(", ") || "\u2014";
3420
3442
  const listBudget = Math.max(4, rows - 10);
3421
3443
  const start = Math.min(Math.max(0, selClamped - Math.floor(listBudget / 2)), Math.max(0, rowsAll.length - listBudget));
3422
3444
  const inWindow = (r) => {
@@ -3426,7 +3448,7 @@ function SettingsPanel({
3426
3448
  return /* @__PURE__ */ jsx7(DataView, { loading, error, children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
3427
3449
  /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: focused ? "\u2191\u2193 move \xB7 enter/m act \xB7 t test webhook \xB7 n add account \xB7 e events \xB7 d delete \xB7 r refresh" : "press \u2192 to configure" }),
3428
3450
  editing ? /* @__PURE__ */ jsxs7(Box7, { children: [
3429
- /* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: editing === "path" ? "local log path: " : editing === "wh-url" ? "webhook url: " : "channel (slack url / email / telegram id): " }),
3451
+ /* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: editing === "path" ? "local log path: " : editing === "wh-url" ? "webhook url: " : editing === "alert-email" ? "e-mail address: " : "telegram chat id (from @userinfobot): " }),
3430
3452
  /* @__PURE__ */ jsx7(TextInput5, { value: input, onChange: setInput, onSubmit: submitInput })
3431
3453
  ] }) : msg ? /* @__PURE__ */ jsx7(Text7, { color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate(msg.text, cols) }) : login?.msg ? /* @__PURE__ */ jsx7(Text7, { color: login.phase === "error" ? theme.bad : theme.ok, children: login.msg }) : /* @__PURE__ */ jsx7(Text7, { children: " " }),
3432
3454
  /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
@@ -3519,9 +3541,13 @@ function SettingsPanel({
3519
3541
  /* @__PURE__ */ jsx7(Text7, { children: `\u2265${rule.threshold}/${rule.windowSeconds}s ` }),
3520
3542
  /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate(chanOf(rule), cols - 26) })
3521
3543
  ] }, rule.id)),
3522
- inWindow({ kind: "alert-add" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
3523
- /* @__PURE__ */ jsx7(Text7, { color: cur.kind === "alert-add" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert-add" }) }),
3524
- /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add alert (enter \u2014 one channel: slack url, email or telegram chat id)" })
3544
+ inWindow({ kind: "alert-add-email" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
3545
+ /* @__PURE__ */ jsx7(Text7, { color: cur.kind === "alert-add-email" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert-add-email" }) }),
3546
+ /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add email alert (enter)" })
3547
+ ] }) : null,
3548
+ inWindow({ kind: "alert-add-tg" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
3549
+ /* @__PURE__ */ jsx7(Text7, { color: cur.kind === "alert-add-tg" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert-add-tg" }) }),
3550
+ /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add telegram alert (enter \u2014 numeric chat id, get it from @userinfobot)" })
3525
3551
  ] }) : null
3526
3552
  ] })
3527
3553
  ] })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.81.53",
3
+ "version": "0.81.55",
4
4
  "description": "AI tool security proxy: protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. No code changes required.",
5
5
  "type": "module",
6
6
  "bin": {