@solongate/proxy 0.81.70 → 0.81.72
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/api-client/client.d.ts +8 -0
- package/dist/index.js +62 -9
- package/dist/tui/components.d.ts +4 -1
- package/dist/tui/index.js +61 -8
- package/dist/tui/panels/Settings.d.ts +4 -1
- package/package.json +1 -1
|
@@ -26,6 +26,14 @@ export declare function isActiveAccount(apiKey: string): boolean;
|
|
|
26
26
|
* account. Best-effort; returns false on failure.
|
|
27
27
|
*/
|
|
28
28
|
export declare function setActiveAccount(creds: Credentials): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Clear the ACTIVE login credential — a local sign-out. Removes the key/url from
|
|
31
|
+
* the active-key file so `listAccounts` no longer re-seeds it (the source of the
|
|
32
|
+
* "ghost account …xxxx" that lingers after removing the account you're logged in
|
|
33
|
+
* as). The guard hooks then have NO key until the next `solongate login`, so this
|
|
34
|
+
* only runs when the user removes their LAST account. Best-effort; false on error.
|
|
35
|
+
*/
|
|
36
|
+
export declare function clearActiveCredential(): boolean;
|
|
29
37
|
/**
|
|
30
38
|
* Thrown for any non-2xx response. `code`/`message` come from the API's
|
|
31
39
|
* `{ error: { code, message } }` envelope when present; `status` is the HTTP
|
package/dist/index.js
CHANGED
|
@@ -6946,11 +6946,12 @@ function PaneTitle({ label, extra, width: width2 }) {
|
|
|
6946
6946
|
/* @__PURE__ */ jsx(Text, { color: theme.dim, children: tail + "\u2500".repeat(Math.max(0, width2 - used)) })
|
|
6947
6947
|
] });
|
|
6948
6948
|
}
|
|
6949
|
-
function StreamLine({ e, loc, selected }) {
|
|
6949
|
+
function StreamLine({ e, loc, selected, date }) {
|
|
6950
6950
|
return /* @__PURE__ */ jsxs(Text, { wrap: "truncate", backgroundColor: selected ? "#1c2f63" : void 0, children: [
|
|
6951
6951
|
/* @__PURE__ */ jsx(Text, { color: selected ? theme.accentBright : theme.dim, children: selected ? "\u25B8" : " " }),
|
|
6952
6952
|
/* @__PURE__ */ jsxs(Text, { color: theme.dim, children: [
|
|
6953
6953
|
"[",
|
|
6954
|
+
date ? ymd(e.at) + " " : "",
|
|
6954
6955
|
hhmmss(e.at),
|
|
6955
6956
|
" "
|
|
6956
6957
|
] }),
|
|
@@ -7001,7 +7002,7 @@ function KeyHints({ hints }) {
|
|
|
7001
7002
|
i < hints.length - 1 ? " " : ""
|
|
7002
7003
|
] }, i)) });
|
|
7003
7004
|
}
|
|
7004
|
-
var hhmmss;
|
|
7005
|
+
var hhmmss, ymd;
|
|
7005
7006
|
var init_components = __esm({
|
|
7006
7007
|
"src/tui/components.tsx"() {
|
|
7007
7008
|
"use strict";
|
|
@@ -7010,6 +7011,12 @@ var init_components = __esm({
|
|
|
7010
7011
|
const d = new Date(ts);
|
|
7011
7012
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
7012
7013
|
};
|
|
7014
|
+
ymd = (ts) => {
|
|
7015
|
+
const d = new Date(ts);
|
|
7016
|
+
if (Number.isNaN(d.getTime())) return "----------";
|
|
7017
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
7018
|
+
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
|
|
7019
|
+
};
|
|
7013
7020
|
}
|
|
7014
7021
|
});
|
|
7015
7022
|
|
|
@@ -7168,6 +7175,28 @@ function setActiveAccount(creds) {
|
|
|
7168
7175
|
return false;
|
|
7169
7176
|
}
|
|
7170
7177
|
}
|
|
7178
|
+
function clearActiveCredential() {
|
|
7179
|
+
try {
|
|
7180
|
+
const p = join8(homedir6(), ".solongate", ["cloud", "guard.json"].join("-"));
|
|
7181
|
+
if (!existsSync3(p)) {
|
|
7182
|
+
cached2 = null;
|
|
7183
|
+
return true;
|
|
7184
|
+
}
|
|
7185
|
+
let existing = {};
|
|
7186
|
+
try {
|
|
7187
|
+
existing = JSON.parse(readFileSync8(p, "utf-8"));
|
|
7188
|
+
} catch {
|
|
7189
|
+
}
|
|
7190
|
+
delete existing.apiKey;
|
|
7191
|
+
delete existing.apiUrl;
|
|
7192
|
+
writeFileSync6(p, JSON.stringify(existing, null, 2));
|
|
7193
|
+
cached2 = null;
|
|
7194
|
+
viewOverride = null;
|
|
7195
|
+
return true;
|
|
7196
|
+
} catch {
|
|
7197
|
+
return false;
|
|
7198
|
+
}
|
|
7199
|
+
}
|
|
7171
7200
|
function loginCredentialFile() {
|
|
7172
7201
|
try {
|
|
7173
7202
|
const p = join8(homedir6(), ".solongate", "cloud-guard.json");
|
|
@@ -9951,7 +9980,7 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9951
9980
|
)
|
|
9952
9981
|
] }) : null,
|
|
9953
9982
|
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: `${total} matched \xB7 page ${Math.min(page + 1, pages)}/${pages} \xB7 ${PAGE}/page \xB7 ${pageRows.length ? selClamped + 1 : 0}/${pageRows.length}${start ? ` \xB7 \u25B2${start} newer` : ""}${start + listRows < pageRows.length ? ` \xB7 \u25BC${pageRows.length - start - listRows} older` : ""}` }),
|
|
9954
|
-
/* @__PURE__ */ jsx6(Box6, { flexDirection: "column", overflow: "hidden", children: windowed.map((e, i) => /* @__PURE__ */ jsx6(StreamLine, { e: toStream(e), loc: source === "local", selected: start + i === selClamped && focused }, e.id)) }),
|
|
9983
|
+
/* @__PURE__ */ jsx6(Box6, { flexDirection: "column", overflow: "hidden", children: windowed.map((e, i) => /* @__PURE__ */ jsx6(StreamLine, { e: toStream(e), loc: source === "local", selected: start + i === selClamped && focused, date: true }, e.id)) }),
|
|
9955
9984
|
pageRows.length === 0 ? /* @__PURE__ */ jsxs6(Text6, { color: theme.dim, children: [
|
|
9956
9985
|
"(no entries",
|
|
9957
9986
|
source === "local" ? " in the local file" : "",
|
|
@@ -10315,7 +10344,8 @@ function SettingsPanel({
|
|
|
10315
10344
|
active: active2,
|
|
10316
10345
|
focused,
|
|
10317
10346
|
viewApiKey,
|
|
10318
|
-
onView
|
|
10347
|
+
onView,
|
|
10348
|
+
onAccountsChanged
|
|
10319
10349
|
}) {
|
|
10320
10350
|
void active2;
|
|
10321
10351
|
const { cols, rows } = usePanelSize();
|
|
@@ -10589,16 +10619,31 @@ function SettingsPanel({
|
|
|
10589
10619
|
else activate(cur);
|
|
10590
10620
|
}
|
|
10591
10621
|
} else if (inp === "x" && cur.kind === "acct") {
|
|
10592
|
-
const
|
|
10622
|
+
const target = cur.acc;
|
|
10623
|
+
const k = "acct:" + target.apiKey;
|
|
10624
|
+
const wasActive = isActiveAccount(target.apiKey);
|
|
10625
|
+
const others = accounts.filter((a) => a.apiKey !== target.apiKey);
|
|
10593
10626
|
if (confirmDel !== k) {
|
|
10594
10627
|
setConfirmDel(k);
|
|
10595
|
-
|
|
10628
|
+
const note = wasActive ? others.length ? ` \u2014 the ACTIVE guard key; ${acctLabel(others[0])} takes over` : " \u2014 your ONLY account & the active guard key; this signs the device out (guard has no key until you log in again)" : " (the cloud account is untouched)";
|
|
10629
|
+
setMsg({ text: `press x again to remove ${acctLabel(target)} from this device${note}`, level: "bad" });
|
|
10596
10630
|
return;
|
|
10597
10631
|
}
|
|
10598
10632
|
setConfirmDel(null);
|
|
10599
|
-
removeAccount(
|
|
10600
|
-
|
|
10633
|
+
removeAccount(target.apiKey);
|
|
10634
|
+
let extra = " from this device";
|
|
10635
|
+
if (wasActive) {
|
|
10636
|
+
if (others.length) {
|
|
10637
|
+
setActiveAccount({ apiKey: others[0].apiKey, apiUrl: others[0].apiUrl });
|
|
10638
|
+
extra = ` \xB7 ${acctLabel(others[0])} is now the active key`;
|
|
10639
|
+
} else {
|
|
10640
|
+
clearActiveCredential();
|
|
10641
|
+
extra = " \xB7 signed out of this device";
|
|
10642
|
+
}
|
|
10643
|
+
}
|
|
10644
|
+
setMsg({ text: `\u2713 removed ${acctLabel(target)}${extra}`, level: "ok" });
|
|
10601
10645
|
refreshAccounts();
|
|
10646
|
+
onAccountsChanged?.();
|
|
10602
10647
|
} else if (inp === "t" && cur.kind === "wh") {
|
|
10603
10648
|
run12("webhook test sent \u2014 check your endpoint", () => api.settings.sendTestWebhook(cur.wh.id).then((r) => {
|
|
10604
10649
|
if (!r.delivered) throw new Error("endpoint rejected the test (non-2xx)");
|
|
@@ -10953,6 +10998,14 @@ function App() {
|
|
|
10953
10998
|
if (accounts.length < 2) return;
|
|
10954
10999
|
viewAccount(accounts[(acctIdx + 1) % accounts.length]);
|
|
10955
11000
|
};
|
|
11001
|
+
const syncAccounts = () => {
|
|
11002
|
+
const list6 = listAccounts();
|
|
11003
|
+
setAccounts(list6);
|
|
11004
|
+
const next = list6.find((a) => a.apiKey === viewKey) ?? list6[0];
|
|
11005
|
+
setViewCredentials(next ? { apiKey: next.apiKey, apiUrl: next.apiUrl } : null);
|
|
11006
|
+
setViewKey(next?.apiKey);
|
|
11007
|
+
setViewNonce((n) => n + 1);
|
|
11008
|
+
};
|
|
10956
11009
|
const locked = accounts.length === 0;
|
|
10957
11010
|
const effectiveSection = locked ? SETTINGS_SECTION : section;
|
|
10958
11011
|
useInput7((input, key) => {
|
|
@@ -10988,7 +11041,7 @@ function App() {
|
|
|
10988
11041
|
return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", width: cols, height: rows - 1, overflow: "hidden", children: /* @__PURE__ */ jsx8(LivePanel, { active: true, focused: true }, viewNonce) });
|
|
10989
11042
|
}
|
|
10990
11043
|
const Panel = current.Panel;
|
|
10991
|
-
const panelBody = current.label === "Settings" ? /* @__PURE__ */ jsx8(SettingsPanel, { active: true, focused: focus === "panel", viewApiKey: viewKey, onView: viewAccount }) : /* @__PURE__ */ jsx8(Panel, { active: focus === "panel" || current.label !== "Live", focused: focus === "panel" });
|
|
11044
|
+
const panelBody = current.label === "Settings" ? /* @__PURE__ */ jsx8(SettingsPanel, { active: true, focused: focus === "panel", viewApiKey: viewKey, onView: viewAccount, onAccountsChanged: syncAccounts }) : /* @__PURE__ */ jsx8(Panel, { active: focus === "panel" || current.label !== "Live", focused: focus === "panel" });
|
|
10992
11045
|
return (
|
|
10993
11046
|
// height rows-1 (not rows): once total output reaches stdout.rows ink stops
|
|
10994
11047
|
// diffing and clearTerminal-repaints every frame, which slides the banner.
|
package/dist/tui/components.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
/** HH:MM:SS for a timestamp (ms or ISO); `--:--:--` when unparseable. */
|
|
3
3
|
export declare const hhmmss: (ts: string | number) => string;
|
|
4
|
+
/** YYYY-MM-DD for a timestamp; `----------` when unparseable. */
|
|
5
|
+
export declare const ymd: (ts: string | number) => string;
|
|
4
6
|
/** Section divider title used across the Live/Audit consoles. */
|
|
5
7
|
export declare function PaneTitle({ label, extra, width }: {
|
|
6
8
|
label: string;
|
|
@@ -25,10 +27,11 @@ export interface StreamRow {
|
|
|
25
27
|
evalMs?: number | null;
|
|
26
28
|
rule?: string | null;
|
|
27
29
|
}
|
|
28
|
-
export declare function StreamLine({ e, loc, selected }: {
|
|
30
|
+
export declare function StreamLine({ e, loc, selected, date }: {
|
|
29
31
|
e: StreamRow;
|
|
30
32
|
loc: boolean;
|
|
31
33
|
selected?: boolean;
|
|
34
|
+
date?: boolean;
|
|
32
35
|
}): JSX.Element;
|
|
33
36
|
export declare function Panel({ title, subtitle, children }: {
|
|
34
37
|
title: string;
|
package/dist/tui/index.js
CHANGED
|
@@ -129,6 +129,12 @@ var hhmmss = (ts) => {
|
|
|
129
129
|
const d = new Date(ts);
|
|
130
130
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
131
131
|
};
|
|
132
|
+
var ymd = (ts) => {
|
|
133
|
+
const d = new Date(ts);
|
|
134
|
+
if (Number.isNaN(d.getTime())) return "----------";
|
|
135
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
136
|
+
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
|
|
137
|
+
};
|
|
132
138
|
function PaneTitle({ label, extra, width }) {
|
|
133
139
|
const tail = extra ? ` ${extra} ` : " ";
|
|
134
140
|
const used = 2 + 1 + label.length + tail.length;
|
|
@@ -141,11 +147,12 @@ function PaneTitle({ label, extra, width }) {
|
|
|
141
147
|
/* @__PURE__ */ jsx(Text, { color: theme.dim, children: tail + "\u2500".repeat(Math.max(0, width - used)) })
|
|
142
148
|
] });
|
|
143
149
|
}
|
|
144
|
-
function StreamLine({ e, loc, selected }) {
|
|
150
|
+
function StreamLine({ e, loc, selected, date }) {
|
|
145
151
|
return /* @__PURE__ */ jsxs(Text, { wrap: "truncate", backgroundColor: selected ? "#1c2f63" : void 0, children: [
|
|
146
152
|
/* @__PURE__ */ jsx(Text, { color: selected ? theme.accentBright : theme.dim, children: selected ? "\u25B8" : " " }),
|
|
147
153
|
/* @__PURE__ */ jsxs(Text, { color: theme.dim, children: [
|
|
148
154
|
"[",
|
|
155
|
+
date ? ymd(e.at) + " " : "",
|
|
149
156
|
hhmmss(e.at),
|
|
150
157
|
" "
|
|
151
158
|
] }),
|
|
@@ -359,6 +366,28 @@ function setActiveAccount(creds) {
|
|
|
359
366
|
return false;
|
|
360
367
|
}
|
|
361
368
|
}
|
|
369
|
+
function clearActiveCredential() {
|
|
370
|
+
try {
|
|
371
|
+
const p = join3(homedir3(), ".solongate", ["cloud", "guard.json"].join("-"));
|
|
372
|
+
if (!existsSync(p)) {
|
|
373
|
+
cached2 = null;
|
|
374
|
+
return true;
|
|
375
|
+
}
|
|
376
|
+
let existing = {};
|
|
377
|
+
try {
|
|
378
|
+
existing = JSON.parse(readFileSync3(p, "utf-8"));
|
|
379
|
+
} catch {
|
|
380
|
+
}
|
|
381
|
+
delete existing.apiKey;
|
|
382
|
+
delete existing.apiUrl;
|
|
383
|
+
writeFileSync2(p, JSON.stringify(existing, null, 2));
|
|
384
|
+
cached2 = null;
|
|
385
|
+
viewOverride = null;
|
|
386
|
+
return true;
|
|
387
|
+
} catch {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
362
391
|
var ApiError = class extends Error {
|
|
363
392
|
status;
|
|
364
393
|
code;
|
|
@@ -3071,7 +3100,7 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
3071
3100
|
)
|
|
3072
3101
|
] }) : null,
|
|
3073
3102
|
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: `${total} matched \xB7 page ${Math.min(page + 1, pages)}/${pages} \xB7 ${PAGE}/page \xB7 ${pageRows.length ? selClamped + 1 : 0}/${pageRows.length}${start ? ` \xB7 \u25B2${start} newer` : ""}${start + listRows < pageRows.length ? ` \xB7 \u25BC${pageRows.length - start - listRows} older` : ""}` }),
|
|
3074
|
-
/* @__PURE__ */ jsx6(Box6, { flexDirection: "column", overflow: "hidden", children: windowed.map((e, i) => /* @__PURE__ */ jsx6(StreamLine, { e: toStream(e), loc: source === "local", selected: start + i === selClamped && focused }, e.id)) }),
|
|
3103
|
+
/* @__PURE__ */ jsx6(Box6, { flexDirection: "column", overflow: "hidden", children: windowed.map((e, i) => /* @__PURE__ */ jsx6(StreamLine, { e: toStream(e), loc: source === "local", selected: start + i === selClamped && focused, date: true }, e.id)) }),
|
|
3075
3104
|
pageRows.length === 0 ? /* @__PURE__ */ jsxs6(Text6, { color: theme.dim, children: [
|
|
3076
3105
|
"(no entries",
|
|
3077
3106
|
source === "local" ? " in the local file" : "",
|
|
@@ -3215,7 +3244,8 @@ function SettingsPanel({
|
|
|
3215
3244
|
active: active2,
|
|
3216
3245
|
focused,
|
|
3217
3246
|
viewApiKey,
|
|
3218
|
-
onView
|
|
3247
|
+
onView,
|
|
3248
|
+
onAccountsChanged
|
|
3219
3249
|
}) {
|
|
3220
3250
|
void active2;
|
|
3221
3251
|
const { cols, rows } = usePanelSize();
|
|
@@ -3489,16 +3519,31 @@ function SettingsPanel({
|
|
|
3489
3519
|
else activate(cur);
|
|
3490
3520
|
}
|
|
3491
3521
|
} else if (inp === "x" && cur.kind === "acct") {
|
|
3492
|
-
const
|
|
3522
|
+
const target = cur.acc;
|
|
3523
|
+
const k = "acct:" + target.apiKey;
|
|
3524
|
+
const wasActive = isActiveAccount(target.apiKey);
|
|
3525
|
+
const others = accounts.filter((a) => a.apiKey !== target.apiKey);
|
|
3493
3526
|
if (confirmDel !== k) {
|
|
3494
3527
|
setConfirmDel(k);
|
|
3495
|
-
|
|
3528
|
+
const note = wasActive ? others.length ? ` \u2014 the ACTIVE guard key; ${acctLabel(others[0])} takes over` : " \u2014 your ONLY account & the active guard key; this signs the device out (guard has no key until you log in again)" : " (the cloud account is untouched)";
|
|
3529
|
+
setMsg({ text: `press x again to remove ${acctLabel(target)} from this device${note}`, level: "bad" });
|
|
3496
3530
|
return;
|
|
3497
3531
|
}
|
|
3498
3532
|
setConfirmDel(null);
|
|
3499
|
-
removeAccount(
|
|
3500
|
-
|
|
3533
|
+
removeAccount(target.apiKey);
|
|
3534
|
+
let extra = " from this device";
|
|
3535
|
+
if (wasActive) {
|
|
3536
|
+
if (others.length) {
|
|
3537
|
+
setActiveAccount({ apiKey: others[0].apiKey, apiUrl: others[0].apiUrl });
|
|
3538
|
+
extra = ` \xB7 ${acctLabel(others[0])} is now the active key`;
|
|
3539
|
+
} else {
|
|
3540
|
+
clearActiveCredential();
|
|
3541
|
+
extra = " \xB7 signed out of this device";
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
setMsg({ text: `\u2713 removed ${acctLabel(target)}${extra}`, level: "ok" });
|
|
3501
3545
|
refreshAccounts();
|
|
3546
|
+
onAccountsChanged?.();
|
|
3502
3547
|
} else if (inp === "t" && cur.kind === "wh") {
|
|
3503
3548
|
run("webhook test sent \u2014 check your endpoint", () => api.settings.sendTestWebhook(cur.wh.id).then((r) => {
|
|
3504
3549
|
if (!r.delivered) throw new Error("endpoint rejected the test (non-2xx)");
|
|
@@ -3958,6 +4003,14 @@ function App() {
|
|
|
3958
4003
|
if (accounts.length < 2) return;
|
|
3959
4004
|
viewAccount(accounts[(acctIdx + 1) % accounts.length]);
|
|
3960
4005
|
};
|
|
4006
|
+
const syncAccounts = () => {
|
|
4007
|
+
const list5 = listAccounts();
|
|
4008
|
+
setAccounts(list5);
|
|
4009
|
+
const next = list5.find((a) => a.apiKey === viewKey) ?? list5[0];
|
|
4010
|
+
setViewCredentials(next ? { apiKey: next.apiKey, apiUrl: next.apiUrl } : null);
|
|
4011
|
+
setViewKey(next?.apiKey);
|
|
4012
|
+
setViewNonce((n) => n + 1);
|
|
4013
|
+
};
|
|
3961
4014
|
const locked = accounts.length === 0;
|
|
3962
4015
|
const effectiveSection = locked ? SETTINGS_SECTION : section;
|
|
3963
4016
|
useInput7((input, key) => {
|
|
@@ -3993,7 +4046,7 @@ function App() {
|
|
|
3993
4046
|
return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", width: cols, height: rows - 1, overflow: "hidden", children: /* @__PURE__ */ jsx8(LivePanel, { active: true, focused: true }, viewNonce) });
|
|
3994
4047
|
}
|
|
3995
4048
|
const Panel = current.Panel;
|
|
3996
|
-
const panelBody = current.label === "Settings" ? /* @__PURE__ */ jsx8(SettingsPanel, { active: true, focused: focus === "panel", viewApiKey: viewKey, onView: viewAccount }) : /* @__PURE__ */ jsx8(Panel, { active: focus === "panel" || current.label !== "Live", focused: focus === "panel" });
|
|
4049
|
+
const panelBody = current.label === "Settings" ? /* @__PURE__ */ jsx8(SettingsPanel, { active: true, focused: focus === "panel", viewApiKey: viewKey, onView: viewAccount, onAccountsChanged: syncAccounts }) : /* @__PURE__ */ jsx8(Panel, { active: focus === "panel" || current.label !== "Live", focused: focus === "panel" });
|
|
3997
4050
|
return (
|
|
3998
4051
|
// height rows-1 (not rows): once total output reaches stdout.rows ink stops
|
|
3999
4052
|
// diffing and clearTerminal-repaints every frame, which slides the banner.
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { type SavedAccount } from '../../api-client/client.js';
|
|
2
|
-
export declare function SettingsPanel({ active, focused, viewApiKey, onView, }: {
|
|
2
|
+
export declare function SettingsPanel({ active, focused, viewApiKey, onView, onAccountsChanged, }: {
|
|
3
3
|
active: boolean;
|
|
4
4
|
focused: boolean;
|
|
5
5
|
viewApiKey?: string;
|
|
6
6
|
onView?: (acc: SavedAccount) => void;
|
|
7
|
+
/** Fired after this panel mutates the on-disk account set so the App shell can
|
|
8
|
+
* re-derive its header / view / locked state from disk. */
|
|
9
|
+
onAccountsChanged?: () => void;
|
|
7
10
|
}): JSX.Element;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.72",
|
|
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": {
|