@solongate/proxy 0.82.83 → 0.82.85

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
@@ -11347,6 +11347,22 @@ function SettingsPanel({
11347
11347
  const [latest, setLatest] = useState8(null);
11348
11348
  const [diagBusy, setDiagBusy] = useState8(null);
11349
11349
  const [diag, setDiag] = useState8(null);
11350
+ const [diagStep, setDiagStep] = useState8(0);
11351
+ const DIAG_STEPS = {
11352
+ doctor: ["login", "active policy", "guard hook", "agent hooks", "local logs"],
11353
+ repair: ["inspecting protection files", "rewriting hook files", "registering with agents", "re-locking"]
11354
+ };
11355
+ const settle = async (started, of) => {
11356
+ const min = DIAG_STEPS[of].length * 220 + 160;
11357
+ const left = min - (Date.now() - started);
11358
+ if (left > 0) await new Promise((res) => setTimeout(res, left));
11359
+ };
11360
+ useEffect7(() => {
11361
+ if (!diagBusy) return;
11362
+ const total = DIAG_STEPS[diagBusy].length;
11363
+ const step = setInterval(() => setDiagStep((s) => Math.min(s + 1, total - 1)), 220);
11364
+ return () => clearInterval(step);
11365
+ }, [diagBusy]);
11350
11366
  const ver = currentVersion();
11351
11367
  useEffect7(() => {
11352
11368
  let live2 = true;
@@ -11385,10 +11401,11 @@ function SettingsPanel({
11385
11401
  return () => clearInterval(t);
11386
11402
  }, []);
11387
11403
  useEffect7(() => {
11388
- if (!login || login.phase === "done" || login.phase === "error") return;
11404
+ const loggingIn = login && login.phase !== "done" && login.phase !== "error";
11405
+ if (!loggingIn && !diagBusy) return;
11389
11406
  const t = setInterval(() => setTick((n) => n + 1), 120);
11390
11407
  return () => clearInterval(t);
11391
- }, [login]);
11408
+ }, [login, diagBusy]);
11392
11409
  const localQ = useLoader(() => listAccounts().length ? api.settings.getLocalLogs() : Promise.resolve(null));
11393
11410
  const whQ = useLoader(() => listAccounts().length ? api.settings.getWebhooks() : Promise.resolve(null));
11394
11411
  const alertQ = useLoader(() => listAccounts().length ? api.settings.getAlerts() : Promise.resolve(null));
@@ -11543,10 +11560,13 @@ function SettingsPanel({
11543
11560
  } else if (r.kind === "doctor") {
11544
11561
  if (diagBusy) return;
11545
11562
  setDiagBusy("doctor");
11563
+ setDiagStep(0);
11546
11564
  setDiag(null);
11547
11565
  void (async () => {
11566
+ const started = Date.now();
11548
11567
  try {
11549
11568
  const checks = await collectChecks();
11569
+ await settle(started, "doctor");
11550
11570
  const bad = checks.filter((c2) => c2.ok === false).length;
11551
11571
  const warn = checks.filter((c2) => c2.ok === "warn").length;
11552
11572
  setDiag({
@@ -11568,27 +11588,33 @@ function SettingsPanel({
11568
11588
  } else if (r.kind === "repair") {
11569
11589
  if (diagBusy) return;
11570
11590
  setDiagBusy("repair");
11591
+ setDiagStep(0);
11571
11592
  setDiag(null);
11572
- try {
11573
- const rep = repairQuiet();
11574
- setDiag({
11575
- of: "repair",
11576
- lines: [
11577
- ...(rep.ok ? rep.after : rep.before).map((l) => ({
11578
- text: `${l.ok ? "\u2713" : "\u2717"} ${l.label.padEnd(20)} ${l.detail}`,
11579
- level: l.ok ? "ok" : "bad"
11580
- })),
11581
- ...rep.notes.map((n) => ({ text: n, level: "warn" }))
11582
- ]
11583
- });
11584
- setMsg({ text: (rep.ok ? "\u2713 " : "\u2717 ") + rep.message, level: rep.ok ? "ok" : "bad" });
11585
- refreshGuard();
11586
- guardQ.reload();
11587
- } catch (e) {
11588
- setMsg({ text: "\u2717 repair failed: " + (e instanceof Error ? e.message : String(e)), level: "bad" });
11589
- } finally {
11590
- setDiagBusy(null);
11591
- }
11593
+ void (async () => {
11594
+ try {
11595
+ const started = Date.now();
11596
+ await new Promise((res) => setTimeout(res, 60));
11597
+ const rep = repairQuiet();
11598
+ await settle(started, "repair");
11599
+ setDiag({
11600
+ of: "repair",
11601
+ lines: [
11602
+ ...(rep.ok ? rep.after : rep.before).map((l) => ({
11603
+ text: `${l.ok ? "\u2713" : "\u2717"} ${l.label.padEnd(20)} ${l.detail}`,
11604
+ level: l.ok ? "ok" : "bad"
11605
+ })),
11606
+ ...rep.notes.map((n) => ({ text: n, level: "warn" }))
11607
+ ]
11608
+ });
11609
+ setMsg({ text: (rep.ok ? "\u2713 " : "\u2717 ") + rep.message, level: rep.ok ? "ok" : "bad" });
11610
+ refreshGuard();
11611
+ guardQ.reload();
11612
+ } catch (e) {
11613
+ setMsg({ text: "\u2717 repair failed: " + (e instanceof Error ? e.message : String(e)), level: "bad" });
11614
+ } finally {
11615
+ setDiagBusy(null);
11616
+ }
11617
+ })();
11592
11618
  } else if (r.kind === "self") {
11593
11619
  if (!selfProt) return;
11594
11620
  run10(selfProt.enabled ? "self-protection disabled" : "self-protection enabled", () => api.settings.setSelfProtection(!selfProt.enabled), selfQ.reload);
@@ -11882,13 +11908,13 @@ function SettingsPanel({
11882
11908
  return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", children: [
11883
11909
  cursor(r),
11884
11910
  /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "doctor".padEnd(11) }),
11885
- diagBusy === "doctor" ? /* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: "checking\u2026" }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "health check: login, policy, guard, hooks, local logs \xB7 enter runs it" })
11911
+ diagBusy === "doctor" ? /* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: `${spin} running health check\u2026` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "health check: login, policy, guard, hooks, local logs \xB7 enter runs it" })
11886
11912
  ] });
11887
11913
  case "repair":
11888
11914
  return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", children: [
11889
11915
  cursor(r),
11890
11916
  /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "repair".padEnd(11) }),
11891
- diagBusy === "repair" ? /* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: "repairing\u2026" }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "restore every protection file after tampering or deletion \xB7 enter runs it" })
11917
+ diagBusy === "repair" ? /* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: `${spin} restoring protection\u2026` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "restore every protection file after tampering or deletion \xB7 enter runs it" })
11892
11918
  ] });
11893
11919
  case "ll-enabled":
11894
11920
  return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", children: [
@@ -11977,6 +12003,15 @@ function SettingsPanel({
11977
12003
  }
11978
12004
  lineEls.push(/* @__PURE__ */ jsx8(Box8, { children: rowLine(r) }, keyOf(r)));
11979
12005
  lineKey.push(keyOf(r));
12006
+ if ((r.kind === "doctor" || r.kind === "repair") && diagBusy === r.kind) {
12007
+ DIAG_STEPS[r.kind].forEach((label, i) => {
12008
+ const done = i < diagStep;
12009
+ lineEls.push(
12010
+ /* @__PURE__ */ jsx8(Text8, { wrap: "truncate", color: done ? theme.ok : i === diagStep ? theme.accentBright : theme.dim, children: ` ${done ? "\u2713" : i === diagStep ? spin : " "} ${label}` }, `step:${r.kind}:${i}`)
12011
+ );
12012
+ lineKey.push("");
12013
+ });
12014
+ }
11980
12015
  if (diag && (r.kind === "doctor" && diag.of === "doctor" || r.kind === "repair" && diag.of === "repair")) {
11981
12016
  diag.lines.forEach((l, i) => {
11982
12017
  lineEls.push(
@@ -12121,7 +12156,9 @@ function App() {
12121
12156
  }, []);
12122
12157
  const acctIdx = Math.max(0, accounts.findIndex((a) => a.apiKey === viewKey));
12123
12158
  const cur = accounts[acctIdx];
12124
- const acctLabel2 = cur ? cur.email || cur.user || cur.project || `account \u2026${cur.apiKey.slice(-4)}` : "not logged in";
12159
+ const rawEmail = cur?.email ?? "";
12160
+ const isGuestAccount = rawEmail.endsWith("@anonymous.solongate.invalid");
12161
+ const acctLabel2 = cur ? isGuestAccount ? "Anonymous" : rawEmail || cur.user || cur.project || `account \u2026${cur.apiKey.slice(-4)}` : "not logged in";
12125
12162
  useEffect8(() => {
12126
12163
  if (!cur || cur.email) return;
12127
12164
  let alive = true;
package/dist/tui/index.js CHANGED
@@ -4563,6 +4563,22 @@ function SettingsPanel({
4563
4563
  const [latest, setLatest] = useState8(null);
4564
4564
  const [diagBusy, setDiagBusy] = useState8(null);
4565
4565
  const [diag, setDiag] = useState8(null);
4566
+ const [diagStep, setDiagStep] = useState8(0);
4567
+ const DIAG_STEPS = {
4568
+ doctor: ["login", "active policy", "guard hook", "agent hooks", "local logs"],
4569
+ repair: ["inspecting protection files", "rewriting hook files", "registering with agents", "re-locking"]
4570
+ };
4571
+ const settle = async (started, of) => {
4572
+ const min = DIAG_STEPS[of].length * 220 + 160;
4573
+ const left = min - (Date.now() - started);
4574
+ if (left > 0) await new Promise((res) => setTimeout(res, left));
4575
+ };
4576
+ useEffect7(() => {
4577
+ if (!diagBusy) return;
4578
+ const total = DIAG_STEPS[diagBusy].length;
4579
+ const step = setInterval(() => setDiagStep((s) => Math.min(s + 1, total - 1)), 220);
4580
+ return () => clearInterval(step);
4581
+ }, [diagBusy]);
4566
4582
  const ver = currentVersion();
4567
4583
  useEffect7(() => {
4568
4584
  let live2 = true;
@@ -4601,10 +4617,11 @@ function SettingsPanel({
4601
4617
  return () => clearInterval(t);
4602
4618
  }, []);
4603
4619
  useEffect7(() => {
4604
- if (!login || login.phase === "done" || login.phase === "error") return;
4620
+ const loggingIn = login && login.phase !== "done" && login.phase !== "error";
4621
+ if (!loggingIn && !diagBusy) return;
4605
4622
  const t = setInterval(() => setTick((n) => n + 1), 120);
4606
4623
  return () => clearInterval(t);
4607
- }, [login]);
4624
+ }, [login, diagBusy]);
4608
4625
  const localQ = useLoader(() => listAccounts().length ? api.settings.getLocalLogs() : Promise.resolve(null));
4609
4626
  const whQ = useLoader(() => listAccounts().length ? api.settings.getWebhooks() : Promise.resolve(null));
4610
4627
  const alertQ = useLoader(() => listAccounts().length ? api.settings.getAlerts() : Promise.resolve(null));
@@ -4759,10 +4776,13 @@ function SettingsPanel({
4759
4776
  } else if (r.kind === "doctor") {
4760
4777
  if (diagBusy) return;
4761
4778
  setDiagBusy("doctor");
4779
+ setDiagStep(0);
4762
4780
  setDiag(null);
4763
4781
  void (async () => {
4782
+ const started = Date.now();
4764
4783
  try {
4765
4784
  const checks = await collectChecks();
4785
+ await settle(started, "doctor");
4766
4786
  const bad = checks.filter((c2) => c2.ok === false).length;
4767
4787
  const warn = checks.filter((c2) => c2.ok === "warn").length;
4768
4788
  setDiag({
@@ -4784,27 +4804,33 @@ function SettingsPanel({
4784
4804
  } else if (r.kind === "repair") {
4785
4805
  if (diagBusy) return;
4786
4806
  setDiagBusy("repair");
4807
+ setDiagStep(0);
4787
4808
  setDiag(null);
4788
- try {
4789
- const rep = repairQuiet();
4790
- setDiag({
4791
- of: "repair",
4792
- lines: [
4793
- ...(rep.ok ? rep.after : rep.before).map((l) => ({
4794
- text: `${l.ok ? "\u2713" : "\u2717"} ${l.label.padEnd(20)} ${l.detail}`,
4795
- level: l.ok ? "ok" : "bad"
4796
- })),
4797
- ...rep.notes.map((n) => ({ text: n, level: "warn" }))
4798
- ]
4799
- });
4800
- setMsg({ text: (rep.ok ? "\u2713 " : "\u2717 ") + rep.message, level: rep.ok ? "ok" : "bad" });
4801
- refreshGuard();
4802
- guardQ.reload();
4803
- } catch (e) {
4804
- setMsg({ text: "\u2717 repair failed: " + (e instanceof Error ? e.message : String(e)), level: "bad" });
4805
- } finally {
4806
- setDiagBusy(null);
4807
- }
4809
+ void (async () => {
4810
+ try {
4811
+ const started = Date.now();
4812
+ await new Promise((res) => setTimeout(res, 60));
4813
+ const rep = repairQuiet();
4814
+ await settle(started, "repair");
4815
+ setDiag({
4816
+ of: "repair",
4817
+ lines: [
4818
+ ...(rep.ok ? rep.after : rep.before).map((l) => ({
4819
+ text: `${l.ok ? "\u2713" : "\u2717"} ${l.label.padEnd(20)} ${l.detail}`,
4820
+ level: l.ok ? "ok" : "bad"
4821
+ })),
4822
+ ...rep.notes.map((n) => ({ text: n, level: "warn" }))
4823
+ ]
4824
+ });
4825
+ setMsg({ text: (rep.ok ? "\u2713 " : "\u2717 ") + rep.message, level: rep.ok ? "ok" : "bad" });
4826
+ refreshGuard();
4827
+ guardQ.reload();
4828
+ } catch (e) {
4829
+ setMsg({ text: "\u2717 repair failed: " + (e instanceof Error ? e.message : String(e)), level: "bad" });
4830
+ } finally {
4831
+ setDiagBusy(null);
4832
+ }
4833
+ })();
4808
4834
  } else if (r.kind === "self") {
4809
4835
  if (!selfProt) return;
4810
4836
  run(selfProt.enabled ? "self-protection disabled" : "self-protection enabled", () => api.settings.setSelfProtection(!selfProt.enabled), selfQ.reload);
@@ -5098,13 +5124,13 @@ function SettingsPanel({
5098
5124
  return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", children: [
5099
5125
  cursor(r),
5100
5126
  /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "doctor".padEnd(11) }),
5101
- diagBusy === "doctor" ? /* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: "checking\u2026" }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "health check: login, policy, guard, hooks, local logs \xB7 enter runs it" })
5127
+ diagBusy === "doctor" ? /* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: `${spin} running health check\u2026` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "health check: login, policy, guard, hooks, local logs \xB7 enter runs it" })
5102
5128
  ] });
5103
5129
  case "repair":
5104
5130
  return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", children: [
5105
5131
  cursor(r),
5106
5132
  /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "repair".padEnd(11) }),
5107
- diagBusy === "repair" ? /* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: "repairing\u2026" }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "restore every protection file after tampering or deletion \xB7 enter runs it" })
5133
+ diagBusy === "repair" ? /* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: `${spin} restoring protection\u2026` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "restore every protection file after tampering or deletion \xB7 enter runs it" })
5108
5134
  ] });
5109
5135
  case "ll-enabled":
5110
5136
  return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", children: [
@@ -5193,6 +5219,15 @@ function SettingsPanel({
5193
5219
  }
5194
5220
  lineEls.push(/* @__PURE__ */ jsx8(Box8, { children: rowLine(r) }, keyOf(r)));
5195
5221
  lineKey.push(keyOf(r));
5222
+ if ((r.kind === "doctor" || r.kind === "repair") && diagBusy === r.kind) {
5223
+ DIAG_STEPS[r.kind].forEach((label, i) => {
5224
+ const done = i < diagStep;
5225
+ lineEls.push(
5226
+ /* @__PURE__ */ jsx8(Text8, { wrap: "truncate", color: done ? theme.ok : i === diagStep ? theme.accentBright : theme.dim, children: ` ${done ? "\u2713" : i === diagStep ? spin : " "} ${label}` }, `step:${r.kind}:${i}`)
5227
+ );
5228
+ lineKey.push("");
5229
+ });
5230
+ }
5196
5231
  if (diag && (r.kind === "doctor" && diag.of === "doctor" || r.kind === "repair" && diag.of === "repair")) {
5197
5232
  diag.lines.forEach((l, i) => {
5198
5233
  lineEls.push(
@@ -5314,7 +5349,9 @@ function App() {
5314
5349
  }, []);
5315
5350
  const acctIdx = Math.max(0, accounts.findIndex((a) => a.apiKey === viewKey));
5316
5351
  const cur = accounts[acctIdx];
5317
- const acctLabel2 = cur ? cur.email || cur.user || cur.project || `account \u2026${cur.apiKey.slice(-4)}` : "not logged in";
5352
+ const rawEmail = cur?.email ?? "";
5353
+ const isGuestAccount = rawEmail.endsWith("@anonymous.solongate.invalid");
5354
+ const acctLabel2 = cur ? isGuestAccount ? "Anonymous" : rawEmail || cur.user || cur.project || `account \u2026${cur.apiKey.slice(-4)}` : "not logged in";
5318
5355
  useEffect8(() => {
5319
5356
  if (!cur || cur.email) return;
5320
5357
  let alive = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.82.83",
3
+ "version": "0.82.85",
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": {