@solongate/proxy 0.81.48 → 0.81.50
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 +2 -0
- package/dist/api-client/device-login.d.ts +1 -0
- package/dist/index.js +258 -270
- package/dist/login.js +1 -1
- package/dist/tui/index.js +254 -258
- package/dist/tui/panels/Settings.d.ts +4 -1
- package/package.json +1 -1
- package/dist/tui/panels/Accounts.d.ts +0 -7
package/dist/index.js
CHANGED
|
@@ -7188,7 +7188,7 @@ async function pollDeviceLogin(apiUrl, deviceCode) {
|
|
|
7188
7188
|
});
|
|
7189
7189
|
const j = await res.json().catch(() => ({}));
|
|
7190
7190
|
if (j.status === "approved" && j.api_key) {
|
|
7191
|
-
return { status: "approved", apiKey: j.api_key, project: j.project?.name, user: j.user?.name || j.user?.email };
|
|
7191
|
+
return { status: "approved", apiKey: j.api_key, project: j.project?.name, user: j.user?.name || j.user?.email, email: j.user?.email };
|
|
7192
7192
|
}
|
|
7193
7193
|
if (j.status === "expired" || j.status === "not_found") return { status: j.status };
|
|
7194
7194
|
return { status: "pending" };
|
|
@@ -9956,8 +9956,8 @@ var init_Audit = __esm({
|
|
|
9956
9956
|
// src/tui/panels/Settings.tsx
|
|
9957
9957
|
import { Box as Box7, Text as Text7, useInput as useInput6 } from "ink";
|
|
9958
9958
|
import TextInput5 from "ink-text-input";
|
|
9959
|
-
import { useState as useState7 } from "react";
|
|
9960
|
-
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
9959
|
+
import { useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
|
|
9960
|
+
import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
9961
9961
|
function alertBodyFor(channel) {
|
|
9962
9962
|
const c2 = channel.trim();
|
|
9963
9963
|
const base = { name: "dataroom alert", threshold: 5, windowSeconds: 60, signal: "any" };
|
|
@@ -9965,7 +9965,12 @@ function alertBodyFor(channel) {
|
|
|
9965
9965
|
if (c2.includes("@")) return { ...base, emails: [c2] };
|
|
9966
9966
|
return { ...base, telegram: [c2] };
|
|
9967
9967
|
}
|
|
9968
|
-
function SettingsPanel({
|
|
9968
|
+
function SettingsPanel({
|
|
9969
|
+
active: active2,
|
|
9970
|
+
focused,
|
|
9971
|
+
viewApiKey,
|
|
9972
|
+
onView
|
|
9973
|
+
}) {
|
|
9969
9974
|
void active2;
|
|
9970
9975
|
const { cols, rows } = usePanelSize();
|
|
9971
9976
|
const [sel, setSel] = useState7(0);
|
|
@@ -9974,24 +9979,40 @@ function SettingsPanel({ active: active2, focused }) {
|
|
|
9974
9979
|
const [confirmDel, setConfirmDel] = useState7(null);
|
|
9975
9980
|
const [msg, setMsg] = useState7(null);
|
|
9976
9981
|
const [busy, setBusy] = useState7(false);
|
|
9977
|
-
const
|
|
9978
|
-
const
|
|
9979
|
-
const
|
|
9982
|
+
const [accounts, setAccounts] = useState7(() => listAccounts());
|
|
9983
|
+
const [login, setLogin] = useState7(null);
|
|
9984
|
+
const [tick, setTick] = useState7(0);
|
|
9985
|
+
const abort = useRef3(false);
|
|
9986
|
+
const refreshAccounts = () => setAccounts(listAccounts());
|
|
9987
|
+
const locked = accounts.length === 0;
|
|
9988
|
+
useEffect6(() => {
|
|
9989
|
+
if (!login || login.phase === "done" || login.phase === "error") return;
|
|
9990
|
+
const t = setInterval(() => setTick((n) => n + 1), 120);
|
|
9991
|
+
return () => clearInterval(t);
|
|
9992
|
+
}, [login]);
|
|
9993
|
+
const localQ = useLoader(() => listAccounts().length ? api.settings.getLocalLogs() : Promise.resolve(null));
|
|
9994
|
+
const whQ = useLoader(() => listAccounts().length ? api.settings.getWebhooks() : Promise.resolve(null));
|
|
9995
|
+
const alertQ = useLoader(() => listAccounts().length ? api.settings.getAlerts() : Promise.resolve(null));
|
|
9980
9996
|
const local = localQ.data;
|
|
9981
9997
|
const webhooks = whQ.data?.webhooks ?? [];
|
|
9982
9998
|
const alerts = alertQ.data?.rules ?? [];
|
|
9983
9999
|
const rowsAll = [
|
|
9984
|
-
{ kind: "
|
|
9985
|
-
{ kind: "
|
|
9986
|
-
...
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
|
|
10000
|
+
...accounts.map((acc) => ({ kind: "acct", acc })),
|
|
10001
|
+
{ kind: "acct-add" },
|
|
10002
|
+
...locked ? [] : [
|
|
10003
|
+
{ kind: "ll-enabled" },
|
|
10004
|
+
{ kind: "ll-path" },
|
|
10005
|
+
...webhooks.map((wh) => ({ kind: "wh", wh })),
|
|
10006
|
+
{ kind: "wh-add" },
|
|
10007
|
+
...alerts.map((rule) => ({ kind: "alert", rule })),
|
|
10008
|
+
{ kind: "alert-add" }
|
|
10009
|
+
]
|
|
9990
10010
|
];
|
|
9991
10011
|
const selClamped = Math.min(sel, rowsAll.length - 1);
|
|
9992
10012
|
const cur = rowsAll[selClamped];
|
|
9993
|
-
const keyOf = (r) => r.kind === "wh" ? "wh:" + r.wh.id : r.kind === "alert" ? "alert:" + r.rule.id : r.kind;
|
|
10013
|
+
const keyOf = (r) => r.kind === "acct" ? "acct:" + r.acc.apiKey : r.kind === "wh" ? "wh:" + r.wh.id : r.kind === "alert" ? "alert:" + r.rule.id : r.kind;
|
|
9994
10014
|
const reloadAll = () => {
|
|
10015
|
+
refreshAccounts();
|
|
9995
10016
|
localQ.reload();
|
|
9996
10017
|
whQ.reload();
|
|
9997
10018
|
alertQ.reload();
|
|
@@ -10005,8 +10026,48 @@ function SettingsPanel({ active: active2, focused }) {
|
|
|
10005
10026
|
reload();
|
|
10006
10027
|
}).catch((e) => setMsg({ text: "\u2717 " + (e instanceof Error ? e.message : String(e)), level: "bad" })).finally(() => setBusy(false));
|
|
10007
10028
|
};
|
|
10029
|
+
const beginLogin = () => {
|
|
10030
|
+
if (login && (login.phase === "starting" || login.phase === "waiting")) return;
|
|
10031
|
+
abort.current = false;
|
|
10032
|
+
setLogin({ phase: "starting" });
|
|
10033
|
+
void (async () => {
|
|
10034
|
+
let start2;
|
|
10035
|
+
try {
|
|
10036
|
+
start2 = await startDeviceLogin(DEFAULT_API_URL2);
|
|
10037
|
+
} catch (e) {
|
|
10038
|
+
setLogin({ phase: "error", msg: "could not reach SolonGate: " + (e instanceof Error ? e.message : String(e)) });
|
|
10039
|
+
return;
|
|
10040
|
+
}
|
|
10041
|
+
setLogin({ phase: "waiting", url: start2.verifyUrl });
|
|
10042
|
+
openBrowser(start2.verifyUrl);
|
|
10043
|
+
while (Date.now() < start2.expiresAt && !abort.current) {
|
|
10044
|
+
await new Promise((r) => setTimeout(r, start2.intervalMs));
|
|
10045
|
+
if (abort.current) return;
|
|
10046
|
+
const res = await pollDeviceLogin(DEFAULT_API_URL2, start2.deviceCode);
|
|
10047
|
+
if (res.status === "approved" && res.apiKey) {
|
|
10048
|
+
saveAccount({ apiKey: res.apiKey, apiUrl: DEFAULT_API_URL2, project: res.project, user: res.user, email: res.email });
|
|
10049
|
+
setLogin({ phase: "done", msg: `\u2713 added ${res.email || res.user || res.project || "account"}` });
|
|
10050
|
+
setViewCredentials({ apiKey: res.apiKey, apiUrl: DEFAULT_API_URL2 });
|
|
10051
|
+
onView?.({ apiKey: res.apiKey, apiUrl: DEFAULT_API_URL2, project: res.project, user: res.user, email: res.email });
|
|
10052
|
+
reloadAll();
|
|
10053
|
+
return;
|
|
10054
|
+
}
|
|
10055
|
+
if (res.status === "expired" || res.status === "not_found") {
|
|
10056
|
+
setLogin({ phase: "error", msg: "code expired \u2014 press n to retry" });
|
|
10057
|
+
return;
|
|
10058
|
+
}
|
|
10059
|
+
}
|
|
10060
|
+
if (!abort.current) setLogin({ phase: "error", msg: "timed out \u2014 press n to retry" });
|
|
10061
|
+
})();
|
|
10062
|
+
};
|
|
10008
10063
|
const activate = (r) => {
|
|
10009
|
-
if (r.kind === "
|
|
10064
|
+
if (r.kind === "acct") {
|
|
10065
|
+
setViewCredentials({ apiKey: r.acc.apiKey, apiUrl: r.acc.apiUrl });
|
|
10066
|
+
onView?.(r.acc);
|
|
10067
|
+
setMsg({ text: `viewing ${acctLabel(r.acc)}`, level: "ok" });
|
|
10068
|
+
} else if (r.kind === "acct-add") {
|
|
10069
|
+
beginLogin();
|
|
10070
|
+
} else if (r.kind === "ll-enabled") {
|
|
10010
10071
|
if (!local) return;
|
|
10011
10072
|
if (!local.enabled && !local.path.trim()) {
|
|
10012
10073
|
setMsg({ text: "set a path first (\u2193 then enter)", level: "bad" });
|
|
@@ -10045,6 +10106,13 @@ function SettingsPanel({ active: active2, focused }) {
|
|
|
10045
10106
|
};
|
|
10046
10107
|
useInput6(
|
|
10047
10108
|
(inp, key) => {
|
|
10109
|
+
if (login && (login.phase === "starting" || login.phase === "waiting")) {
|
|
10110
|
+
if (key.escape) {
|
|
10111
|
+
abort.current = true;
|
|
10112
|
+
setLogin(null);
|
|
10113
|
+
}
|
|
10114
|
+
return;
|
|
10115
|
+
}
|
|
10048
10116
|
setMsg(null);
|
|
10049
10117
|
if (key.upArrow) {
|
|
10050
10118
|
setSel((n) => Math.max(0, n - 1));
|
|
@@ -10053,6 +10121,11 @@ function SettingsPanel({ active: active2, focused }) {
|
|
|
10053
10121
|
setSel((n) => Math.min(rowsAll.length - 1, n + 1));
|
|
10054
10122
|
setConfirmDel(null);
|
|
10055
10123
|
} else if (key.return || inp === " ") activate(cur);
|
|
10124
|
+
else if (inp === "m" && cur.kind === "acct") {
|
|
10125
|
+
const ok = setActiveAccount({ apiKey: cur.acc.apiKey, apiUrl: cur.acc.apiUrl });
|
|
10126
|
+
setMsg(ok ? { text: `\u2713 ${acctLabel(cur.acc)} is now the ACTIVE key (guard + logging)`, level: "ok" } : { text: "\u2717 could not set active", level: "bad" });
|
|
10127
|
+
refreshAccounts();
|
|
10128
|
+
} else if (inp === "n") beginLogin();
|
|
10056
10129
|
else if (inp === "e" && cur.kind === "wh") {
|
|
10057
10130
|
const next = EVENTS[(EVENTS.indexOf(cur.wh.events) + 1) % EVENTS.length];
|
|
10058
10131
|
run12(`webhook events \u2192 ${next}`, () => api.settings.updateWebhook(cur.wh.id, { events: next }), whQ.reload);
|
|
@@ -10079,247 +10152,163 @@ function SettingsPanel({ active: active2, focused }) {
|
|
|
10079
10152
|
},
|
|
10080
10153
|
{ isActive: focused && !editing }
|
|
10081
10154
|
);
|
|
10082
|
-
const
|
|
10083
|
-
|
|
10155
|
+
const spin = SPIN2[tick % SPIN2.length];
|
|
10156
|
+
if (login && (login.phase === "starting" || login.phase === "waiting")) {
|
|
10157
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
10158
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.accentBright, children: "Add an account" }),
|
|
10159
|
+
login.phase === "starting" ? /* @__PURE__ */ jsxs7(Text7, { color: theme.dim, children: [
|
|
10160
|
+
spin,
|
|
10161
|
+
" starting device pairing\u2026"
|
|
10162
|
+
] }) : /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginTop: 1, children: [
|
|
10163
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "Opening your browser to authorize. If it didn't open, visit:" }),
|
|
10164
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accentBright, bold: true, wrap: "truncate", children: login.url }),
|
|
10165
|
+
/* @__PURE__ */ jsxs7(Box7, { marginTop: 1, children: [
|
|
10166
|
+
/* @__PURE__ */ jsxs7(Text7, { color: theme.warn, children: [
|
|
10167
|
+
spin,
|
|
10168
|
+
" waiting for authorization\u2026 "
|
|
10169
|
+
] }),
|
|
10170
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "esc to cancel" })
|
|
10171
|
+
] })
|
|
10172
|
+
] })
|
|
10173
|
+
] });
|
|
10174
|
+
}
|
|
10175
|
+
const loading = !locked && (localQ.loading && !localQ.data || whQ.loading && !whQ.data || alertQ.loading && !alertQ.data);
|
|
10176
|
+
const error = locked ? null : localQ.error ?? whQ.error ?? alertQ.error;
|
|
10084
10177
|
const mark = (r) => keyOf(r) === keyOf(cur) && focused ? "\u25B8 " : " ";
|
|
10085
10178
|
const onOff = (on) => on ? /* @__PURE__ */ jsx7(Text7, { color: theme.ok, children: "on " }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "off" });
|
|
10086
10179
|
const chanOf = (rule) => [...(rule.slackUrls ?? []).map((u) => "slack " + u), ...rule.emails ?? [], ...(rule.telegram ?? []).map((t) => "tg " + t)].join(", ") || "\u2014";
|
|
10087
|
-
const listBudget = Math.max(4, rows -
|
|
10180
|
+
const listBudget = Math.max(4, rows - 10);
|
|
10088
10181
|
const start = Math.min(Math.max(0, selClamped - Math.floor(listBudget / 2)), Math.max(0, rowsAll.length - listBudget));
|
|
10089
10182
|
const inWindow = (r) => {
|
|
10090
10183
|
const i = rowsAll.findIndex((x) => keyOf(x) === keyOf(r));
|
|
10091
10184
|
return i >= start && i < start + listBudget;
|
|
10092
10185
|
};
|
|
10093
10186
|
return /* @__PURE__ */ jsx7(DataView, { loading, error, children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
10094
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: focused ? "\u2191\u2193 move \xB7 enter
|
|
10187
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: focused ? "\u2191\u2193 move \xB7 enter view-toggle-edit \xB7 m make active \xB7 n add account \xB7 e events \xB7 d delete \xB7 r refresh" : "press \u2192 to configure" }),
|
|
10095
10188
|
editing ? /* @__PURE__ */ jsxs7(Box7, { children: [
|
|
10096
10189
|
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: editing === "path" ? "local log path: " : editing === "wh-url" ? "webhook url: " : "channel (slack url / email / telegram id): " }),
|
|
10097
10190
|
/* @__PURE__ */ jsx7(TextInput5, { value: input, onChange: setInput, onSubmit: submitInput })
|
|
10098
|
-
] }) : msg ? /* @__PURE__ */ jsx7(Text7, { color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate2(msg.text, cols) }) : /* @__PURE__ */ jsx7(Text7, { children: " " }),
|
|
10099
|
-
inWindow(rowsAll[0]) || inWindow(rowsAll[1]) ? /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10100
|
-
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accentBright, children: [
|
|
10101
|
-
"LOCAL LOGS ",
|
|
10102
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "\u2014 hooks mirror every decision to a file on the agent machine" })
|
|
10103
|
-
] }),
|
|
10104
|
-
/* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10105
|
-
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "ll-enabled" && focused ? theme.accentBright : theme.dim, children: mark(rowsAll[0]) }),
|
|
10106
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "enabled ".padEnd(10) }),
|
|
10107
|
-
onOff(!!local?.enabled),
|
|
10108
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " enter toggles" })
|
|
10109
|
-
] }),
|
|
10110
|
-
/* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10111
|
-
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "ll-path" && focused ? theme.accentBright : theme.dim, children: mark(rowsAll[1]) }),
|
|
10112
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "path ".padEnd(10) }),
|
|
10113
|
-
local?.path ? /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(local.path, cols - 14) }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "not set \u2014 enter to edit" })
|
|
10114
|
-
] })
|
|
10115
|
-
] }) : null,
|
|
10191
|
+
] }) : 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: " " }),
|
|
10116
10192
|
/* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10117
10193
|
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accentBright, children: [
|
|
10118
|
-
"
|
|
10194
|
+
"ACCOUNTS ",
|
|
10119
10195
|
/* @__PURE__ */ jsxs7(Text7, { color: theme.dim, children: [
|
|
10120
|
-
"\u2014
|
|
10121
|
-
|
|
10122
|
-
")"
|
|
10196
|
+
"\u2014 logged in on this device (",
|
|
10197
|
+
accounts.length,
|
|
10198
|
+
") \xB7 \u25CF viewing = shown here \xB7 ACTIVE = key the guard uses"
|
|
10123
10199
|
] })
|
|
10124
10200
|
] }),
|
|
10125
|
-
|
|
10126
|
-
/* @__PURE__ */ jsx7(Text7, { color:
|
|
10127
|
-
|
|
10128
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
/* @__PURE__ */
|
|
10201
|
+
accounts.length === 0 ? /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
10202
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " no accounts yet \u2014 " }),
|
|
10203
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: "n" }),
|
|
10204
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " (or enter) logs in, pairs this device and unlocks the dataroom" })
|
|
10205
|
+
] }) : null,
|
|
10206
|
+
accounts.filter((acc) => inWindow({ kind: "acct", acc })).map((a) => {
|
|
10207
|
+
const isView = viewApiKey ? a.apiKey === viewApiKey : accounts[0]?.apiKey === a.apiKey;
|
|
10208
|
+
const isActive = isActiveAccount(a.apiKey);
|
|
10209
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10210
|
+
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "acct:" + a.apiKey && focused ? theme.accentBright : theme.dim, children: mark({ kind: "acct", acc: a }) }),
|
|
10211
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(acctLabel(a), 30).padEnd(31) }),
|
|
10212
|
+
isView ? /* @__PURE__ */ jsx7(Text7, { color: theme.ok, children: "\u25CF viewing " }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " " }),
|
|
10213
|
+
isActive ? /* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: "ACTIVE " }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " " }),
|
|
10214
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: a.project ? truncate2(a.project, 24) : "" })
|
|
10215
|
+
] }, a.apiKey);
|
|
10216
|
+
}),
|
|
10217
|
+
inWindow({ kind: "acct-add" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
10218
|
+
/* @__PURE__ */ jsx7(Text7, { color: cur.kind === "acct-add" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "acct-add" }) }),
|
|
10219
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add account (enter \u2014 device login in the browser)" })
|
|
10134
10220
|
] }) : null
|
|
10135
10221
|
] }),
|
|
10136
|
-
/* @__PURE__ */ jsxs7(
|
|
10137
|
-
/* @__PURE__ */ jsxs7(
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
"\u2014
|
|
10141
|
-
|
|
10142
|
-
|
|
10222
|
+
locked ? null : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
10223
|
+
inWindow({ kind: "ll-enabled" }) || inWindow({ kind: "ll-path" }) ? /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10224
|
+
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accentBright, children: [
|
|
10225
|
+
"LOCAL LOGS ",
|
|
10226
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "\u2014 hooks mirror every decision to a file on the agent machine" })
|
|
10227
|
+
] }),
|
|
10228
|
+
/* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10229
|
+
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "ll-enabled" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "ll-enabled" }) }),
|
|
10230
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "enabled ".padEnd(10) }),
|
|
10231
|
+
onOff(!!local?.enabled),
|
|
10232
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " enter toggles" })
|
|
10233
|
+
] }),
|
|
10234
|
+
/* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10235
|
+
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "ll-path" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "ll-path" }) }),
|
|
10236
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "path ".padEnd(10) }),
|
|
10237
|
+
local?.path ? /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(local.path, cols - 14) }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "not set \u2014 enter to edit" })
|
|
10143
10238
|
] })
|
|
10239
|
+
] }) : null,
|
|
10240
|
+
/* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10241
|
+
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accentBright, children: [
|
|
10242
|
+
"WEBHOOKS ",
|
|
10243
|
+
/* @__PURE__ */ jsxs7(Text7, { color: theme.dim, children: [
|
|
10244
|
+
"\u2014 POST every matching event to your endpoint (",
|
|
10245
|
+
webhooks.length,
|
|
10246
|
+
")"
|
|
10247
|
+
] })
|
|
10248
|
+
] }),
|
|
10249
|
+
webhooks.filter((wh) => inWindow({ kind: "wh", wh })).map((wh) => /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10250
|
+
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "wh:" + wh.id && focused ? theme.accentBright : theme.dim, children: mark({ kind: "wh", wh }) }),
|
|
10251
|
+
onOff(wh.enabled),
|
|
10252
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: (" " + wh.events).padEnd(9) }),
|
|
10253
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(wh.url, cols - 16) })
|
|
10254
|
+
] }, wh.id)),
|
|
10255
|
+
inWindow({ kind: "wh-add" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
10256
|
+
/* @__PURE__ */ jsx7(Text7, { color: cur.kind === "wh-add" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "wh-add" }) }),
|
|
10257
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add webhook (enter)" })
|
|
10258
|
+
] }) : null
|
|
10144
10259
|
] }),
|
|
10145
|
-
|
|
10146
|
-
/* @__PURE__ */
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10260
|
+
/* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10261
|
+
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accentBright, children: [
|
|
10262
|
+
"ALERTS ",
|
|
10263
|
+
/* @__PURE__ */ jsxs7(Text7, { color: theme.dim, children: [
|
|
10264
|
+
"\u2014 notify on a signal spike (",
|
|
10265
|
+
alerts.length,
|
|
10266
|
+
")"
|
|
10267
|
+
] })
|
|
10268
|
+
] }),
|
|
10269
|
+
alerts.filter((rule) => inWindow({ kind: "alert", rule })).map((rule) => /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10270
|
+
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "alert:" + rule.id && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert", rule }) }),
|
|
10271
|
+
onOff(rule.enabled),
|
|
10272
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: (" " + rule.signal).padEnd(11) }),
|
|
10273
|
+
/* @__PURE__ */ jsx7(Text7, { children: `\u2265${rule.threshold}/${rule.windowSeconds}s ` }),
|
|
10274
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(chanOf(rule), cols - 26) })
|
|
10275
|
+
] }, rule.id)),
|
|
10276
|
+
inWindow({ kind: "alert-add" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
10277
|
+
/* @__PURE__ */ jsx7(Text7, { color: cur.kind === "alert-add" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert-add" }) }),
|
|
10278
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add alert (enter \u2014 one channel: slack url, email or telegram chat id)" })
|
|
10279
|
+
] }) : null
|
|
10280
|
+
] })
|
|
10156
10281
|
] })
|
|
10157
10282
|
] }) });
|
|
10158
10283
|
}
|
|
10159
|
-
var EVENTS;
|
|
10284
|
+
var EVENTS, SPIN2, acctLabel;
|
|
10160
10285
|
var init_Settings = __esm({
|
|
10161
10286
|
"src/tui/panels/Settings.tsx"() {
|
|
10162
10287
|
"use strict";
|
|
10163
10288
|
init_api_client();
|
|
10289
|
+
init_client();
|
|
10290
|
+
init_device_login();
|
|
10164
10291
|
init_components();
|
|
10165
10292
|
init_hooks();
|
|
10166
10293
|
init_theme();
|
|
10167
10294
|
EVENTS = ["denials", "allowed", "all"];
|
|
10168
|
-
}
|
|
10169
|
-
});
|
|
10170
|
-
|
|
10171
|
-
// src/tui/panels/Accounts.tsx
|
|
10172
|
-
import { Box as Box8, Text as Text8, useInput as useInput7 } from "ink";
|
|
10173
|
-
import { useEffect as useEffect6, useRef as useRef3, useState as useState8 } from "react";
|
|
10174
|
-
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
10175
|
-
function AccountsPanel({
|
|
10176
|
-
focused,
|
|
10177
|
-
viewApiKey,
|
|
10178
|
-
onView
|
|
10179
|
-
}) {
|
|
10180
|
-
const [accounts, setAccounts] = useState8(() => listAccounts());
|
|
10181
|
-
const [sel, setSel] = useState8(0);
|
|
10182
|
-
const [msg, setMsg] = useState8(null);
|
|
10183
|
-
const [login, setLogin] = useState8(null);
|
|
10184
|
-
const [tick, setTick] = useState8(0);
|
|
10185
|
-
const abort = useRef3(false);
|
|
10186
|
-
const refresh = () => setAccounts(listAccounts());
|
|
10187
|
-
useEffect6(() => {
|
|
10188
|
-
if (!login || login.phase === "done" || login.phase === "error") return;
|
|
10189
|
-
const t = setInterval(() => setTick((n) => n + 1), 120);
|
|
10190
|
-
return () => clearInterval(t);
|
|
10191
|
-
}, [login]);
|
|
10192
|
-
const beginLogin = () => {
|
|
10193
|
-
if (login && (login.phase === "starting" || login.phase === "waiting")) return;
|
|
10194
|
-
abort.current = false;
|
|
10195
|
-
setLogin({ phase: "starting" });
|
|
10196
|
-
void (async () => {
|
|
10197
|
-
let start;
|
|
10198
|
-
try {
|
|
10199
|
-
start = await startDeviceLogin(DEFAULT_API_URL2);
|
|
10200
|
-
} catch (e) {
|
|
10201
|
-
setLogin({ phase: "error", msg: "could not reach SolonGate: " + (e instanceof Error ? e.message : String(e)) });
|
|
10202
|
-
return;
|
|
10203
|
-
}
|
|
10204
|
-
setLogin({ phase: "waiting", url: start.verifyUrl });
|
|
10205
|
-
openBrowser(start.verifyUrl);
|
|
10206
|
-
while (Date.now() < start.expiresAt && !abort.current) {
|
|
10207
|
-
await new Promise((r) => setTimeout(r, start.intervalMs));
|
|
10208
|
-
if (abort.current) return;
|
|
10209
|
-
const res = await pollDeviceLogin(DEFAULT_API_URL2, start.deviceCode);
|
|
10210
|
-
if (res.status === "approved" && res.apiKey) {
|
|
10211
|
-
saveAccount({ apiKey: res.apiKey, apiUrl: DEFAULT_API_URL2, project: res.project, user: res.user });
|
|
10212
|
-
setLogin({ phase: "done", msg: `\u2713 added ${res.project || res.user || "account"}` });
|
|
10213
|
-
refresh();
|
|
10214
|
-
setViewCredentials({ apiKey: res.apiKey, apiUrl: DEFAULT_API_URL2 });
|
|
10215
|
-
onView?.({ apiKey: res.apiKey, apiUrl: DEFAULT_API_URL2, project: res.project, user: res.user });
|
|
10216
|
-
return;
|
|
10217
|
-
}
|
|
10218
|
-
if (res.status === "expired" || res.status === "not_found") {
|
|
10219
|
-
setLogin({ phase: "error", msg: "code expired \u2014 press n to retry" });
|
|
10220
|
-
return;
|
|
10221
|
-
}
|
|
10222
|
-
}
|
|
10223
|
-
if (!abort.current) setLogin({ phase: "error", msg: "timed out \u2014 press n to retry" });
|
|
10224
|
-
})();
|
|
10225
|
-
};
|
|
10226
|
-
useInput7(
|
|
10227
|
-
(input, key) => {
|
|
10228
|
-
if (login && (login.phase === "starting" || login.phase === "waiting")) {
|
|
10229
|
-
if (key.escape) {
|
|
10230
|
-
abort.current = true;
|
|
10231
|
-
setLogin(null);
|
|
10232
|
-
}
|
|
10233
|
-
return;
|
|
10234
|
-
}
|
|
10235
|
-
if (key.upArrow) setSel((n) => Math.max(0, n - 1));
|
|
10236
|
-
else if (key.downArrow) setSel((n) => Math.min(accounts.length - 1, n + 1));
|
|
10237
|
-
else if (key.return) {
|
|
10238
|
-
const a = accounts[sel];
|
|
10239
|
-
if (a) {
|
|
10240
|
-
setViewCredentials({ apiKey: a.apiKey, apiUrl: a.apiUrl });
|
|
10241
|
-
onView?.(a);
|
|
10242
|
-
setMsg({ text: `viewing ${a.project || a.user || "account \u2026" + a.apiKey.slice(-4)}`, level: "ok" });
|
|
10243
|
-
}
|
|
10244
|
-
} else if (input === "m") {
|
|
10245
|
-
const a = accounts[sel];
|
|
10246
|
-
if (a) {
|
|
10247
|
-
const ok = setActiveAccount({ apiKey: a.apiKey, apiUrl: a.apiUrl });
|
|
10248
|
-
setMsg(ok ? { text: `\u2713 ${a.project || a.user || "account"} is now the ACTIVE key (guard + logging)`, level: "ok" } : { text: "\u2717 could not set active", level: "bad" });
|
|
10249
|
-
refresh();
|
|
10250
|
-
}
|
|
10251
|
-
} else if (input === "n") beginLogin();
|
|
10252
|
-
else if (input === "r") refresh();
|
|
10253
|
-
},
|
|
10254
|
-
{ isActive: focused }
|
|
10255
|
-
);
|
|
10256
|
-
const spin = SPIN2[tick % SPIN2.length];
|
|
10257
|
-
if (login && (login.phase === "starting" || login.phase === "waiting")) {
|
|
10258
|
-
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
10259
|
-
/* @__PURE__ */ jsx8(Text8, { bold: true, color: theme.accentBright, children: "Add an account" }),
|
|
10260
|
-
login.phase === "starting" ? /* @__PURE__ */ jsxs8(Text8, { color: theme.dim, children: [
|
|
10261
|
-
spin,
|
|
10262
|
-
" starting device pairing\u2026"
|
|
10263
|
-
] }) : /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
|
|
10264
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "Opening your browser to authorize. If it didn't open, visit:" }),
|
|
10265
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, bold: true, wrap: "truncate", children: login.url }),
|
|
10266
|
-
/* @__PURE__ */ jsxs8(Box8, { marginTop: 1, children: [
|
|
10267
|
-
/* @__PURE__ */ jsxs8(Text8, { color: theme.warn, children: [
|
|
10268
|
-
spin,
|
|
10269
|
-
" waiting for authorization\u2026 "
|
|
10270
|
-
] }),
|
|
10271
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "esc to cancel" })
|
|
10272
|
-
] })
|
|
10273
|
-
] })
|
|
10274
|
-
] });
|
|
10275
|
-
}
|
|
10276
|
-
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
10277
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter view \xB7 m make active \xB7 n add account \xB7 r refresh" : "press \u2192 to manage accounts" }),
|
|
10278
|
-
msg ? /* @__PURE__ */ jsx8(Text8, { color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate2(msg.text, 70) }) : login?.msg ? /* @__PURE__ */ jsx8(Text8, { color: login.phase === "error" ? theme.bad : theme.ok, children: login.msg }) : /* @__PURE__ */ jsx8(Text8, { children: " " }),
|
|
10279
|
-
/* @__PURE__ */ jsx8(Box8, { marginTop: 1, flexDirection: "column", children: accounts.length === 0 ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
10280
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "No accounts on this device yet." }),
|
|
10281
|
-
/* @__PURE__ */ jsxs8(Text8, { children: [
|
|
10282
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.accent, children: "n" }),
|
|
10283
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " to log in \u2014 pairs this device and starts protecting your Claude Code sessions." })
|
|
10284
|
-
] })
|
|
10285
|
-
] }) : accounts.map((a, i) => {
|
|
10286
|
-
const isSel = i === sel && focused;
|
|
10287
|
-
const isView = viewApiKey ? a.apiKey === viewApiKey : i === 0;
|
|
10288
|
-
const isActive = isActiveAccount(a.apiKey);
|
|
10289
|
-
return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", backgroundColor: isSel ? "#333333" : void 0, bold: isSel, children: [
|
|
10290
|
-
/* @__PURE__ */ jsx8(Text8, { color: isSel ? theme.accentBright : theme.dim, children: isSel ? "\u25B8 " : " " }),
|
|
10291
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.accent, children: truncate2(a.project || a.user || "account \u2026" + a.apiKey.slice(-4), 30).padEnd(31) }),
|
|
10292
|
-
isView ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, children: "\u25CF viewing " }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " " }),
|
|
10293
|
-
isActive ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: "ACTIVE " }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " " }),
|
|
10294
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: a.user && a.project ? truncate2(a.user, 24) : "" })
|
|
10295
|
-
] }, a.apiKey);
|
|
10296
|
-
}) }),
|
|
10297
|
-
/* @__PURE__ */ jsx8(Box8, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "\u25CF viewing = the account the dataroom is showing \xB7 ACTIVE = the key the guard hooks + logging use" }) })
|
|
10298
|
-
] });
|
|
10299
|
-
}
|
|
10300
|
-
var SPIN2;
|
|
10301
|
-
var init_Accounts = __esm({
|
|
10302
|
-
"src/tui/panels/Accounts.tsx"() {
|
|
10303
|
-
"use strict";
|
|
10304
|
-
init_client();
|
|
10305
|
-
init_device_login();
|
|
10306
|
-
init_theme();
|
|
10307
10295
|
SPIN2 = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
10296
|
+
acctLabel = (a) => a.email || a.user || "account \u2026" + a.apiKey.slice(-4);
|
|
10308
10297
|
}
|
|
10309
10298
|
});
|
|
10310
10299
|
|
|
10311
10300
|
// src/tui/App.tsx
|
|
10312
|
-
import { Box as
|
|
10313
|
-
import { useEffect as useEffect7, useState as
|
|
10314
|
-
import { jsx as
|
|
10301
|
+
import { Box as Box8, Text as Text8, useApp, useInput as useInput7 } from "ink";
|
|
10302
|
+
import { useEffect as useEffect7, useState as useState8 } from "react";
|
|
10303
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
10315
10304
|
function LiveHint() {
|
|
10316
|
-
return /* @__PURE__ */
|
|
10317
|
-
/* @__PURE__ */
|
|
10318
|
-
/* @__PURE__ */
|
|
10319
|
-
/* @__PURE__ */
|
|
10320
|
-
/* @__PURE__ */
|
|
10305
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
10306
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, bold: true, children: "\u25B6 REALTIME CONSOLE" }),
|
|
10307
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "Fullscreen live monitor \u2014 streaming tool calls, active charts," }),
|
|
10308
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "counters, DLP hits and denial alerts. Updates every 2s." }),
|
|
10309
|
+
/* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
10321
10310
|
"press ",
|
|
10322
|
-
/* @__PURE__ */
|
|
10311
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.accent, children: "enter" }),
|
|
10323
10312
|
" to go live"
|
|
10324
10313
|
] }) })
|
|
10325
10314
|
] });
|
|
@@ -10327,25 +10316,25 @@ function LiveHint() {
|
|
|
10327
10316
|
function Banner({ cols }) {
|
|
10328
10317
|
const wide = cols >= 82;
|
|
10329
10318
|
if (!wide) {
|
|
10330
|
-
return /* @__PURE__ */
|
|
10331
|
-
/* @__PURE__ */
|
|
10332
|
-
/* @__PURE__ */
|
|
10319
|
+
return /* @__PURE__ */ jsxs8(Box8, { children: [
|
|
10320
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, color: theme.accentBright, children: "SolonGate" }),
|
|
10321
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \u2014 security control center" })
|
|
10333
10322
|
] });
|
|
10334
10323
|
}
|
|
10335
|
-
return /* @__PURE__ */
|
|
10336
|
-
BANNER_FULL.map((line, i) => /* @__PURE__ */
|
|
10337
|
-
/* @__PURE__ */
|
|
10324
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
10325
|
+
BANNER_FULL.map((line, i) => /* @__PURE__ */ jsx8(Text8, { bold: true, color: BANNER_HEX[i], children: line }, i)),
|
|
10326
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " security control center \xB7 manage policies, rate limits, DLP & more" })
|
|
10338
10327
|
] });
|
|
10339
10328
|
}
|
|
10340
10329
|
function App() {
|
|
10341
10330
|
const { exit } = useApp();
|
|
10342
|
-
const [accounts, setAccounts] =
|
|
10343
|
-
const [viewKey, setViewKey] =
|
|
10344
|
-
const [viewNonce, setViewNonce] =
|
|
10345
|
-
const [section, setSection] =
|
|
10346
|
-
const [focus, setFocus] =
|
|
10347
|
-
const [help, setHelp] =
|
|
10348
|
-
const [update2, setUpdate] =
|
|
10331
|
+
const [accounts, setAccounts] = useState8(() => listAccounts());
|
|
10332
|
+
const [viewKey, setViewKey] = useState8(() => accounts[0]?.apiKey);
|
|
10333
|
+
const [viewNonce, setViewNonce] = useState8(0);
|
|
10334
|
+
const [section, setSection] = useState8(accounts.length === 0 ? SETTINGS_SECTION : 0);
|
|
10335
|
+
const [focus, setFocus] = useState8("nav");
|
|
10336
|
+
const [help, setHelp] = useState8(false);
|
|
10337
|
+
const [update2, setUpdate] = useState8({ kind: "idle" });
|
|
10349
10338
|
useEffect7(() => {
|
|
10350
10339
|
let alive = true;
|
|
10351
10340
|
const run12 = () => void tuiUpdateFlow((s) => alive && setUpdate(s));
|
|
@@ -10358,15 +10347,16 @@ function App() {
|
|
|
10358
10347
|
}, []);
|
|
10359
10348
|
const acctIdx = Math.max(0, accounts.findIndex((a) => a.apiKey === viewKey));
|
|
10360
10349
|
const cur = accounts[acctIdx];
|
|
10361
|
-
const
|
|
10350
|
+
const acctLabel2 = cur ? cur.email || cur.user || cur.project || `account \u2026${cur.apiKey.slice(-4)}` : "not logged in";
|
|
10362
10351
|
useEffect7(() => {
|
|
10363
|
-
if (!cur || cur.
|
|
10352
|
+
if (!cur || cur.email) return;
|
|
10364
10353
|
let alive = true;
|
|
10365
10354
|
api.auth.me().then((r) => {
|
|
10366
|
-
const project = r.project?.name ||
|
|
10367
|
-
const user = r.user?.name ||
|
|
10368
|
-
|
|
10369
|
-
|
|
10355
|
+
const project = r.project?.name || cur.project;
|
|
10356
|
+
const user = r.user?.name || cur.user;
|
|
10357
|
+
const email = r.user?.email || void 0;
|
|
10358
|
+
if (!alive || !project && !user && !email) return;
|
|
10359
|
+
saveAccount({ ...cur, project, user, email });
|
|
10370
10360
|
setAccounts(listAccounts());
|
|
10371
10361
|
}).catch(() => {
|
|
10372
10362
|
});
|
|
@@ -10385,8 +10375,8 @@ function App() {
|
|
|
10385
10375
|
viewAccount(accounts[(acctIdx + 1) % accounts.length]);
|
|
10386
10376
|
};
|
|
10387
10377
|
const locked = accounts.length === 0;
|
|
10388
|
-
const effectiveSection = locked ?
|
|
10389
|
-
|
|
10378
|
+
const effectiveSection = locked ? SETTINGS_SECTION : section;
|
|
10379
|
+
useInput7((input, key) => {
|
|
10390
10380
|
if (help) {
|
|
10391
10381
|
setHelp(false);
|
|
10392
10382
|
return;
|
|
@@ -10414,45 +10404,45 @@ function App() {
|
|
|
10414
10404
|
});
|
|
10415
10405
|
const { cols, rows } = useTermSize();
|
|
10416
10406
|
const current = SECTIONS[effectiveSection];
|
|
10417
|
-
if (help) return /* @__PURE__ */
|
|
10407
|
+
if (help) return /* @__PURE__ */ jsx8(HelpOverlay, { cols, rows });
|
|
10418
10408
|
if (current.label === "Live" && focus === "panel") {
|
|
10419
|
-
return /* @__PURE__ */
|
|
10409
|
+
return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", width: cols, height: rows - 1, overflow: "hidden", children: /* @__PURE__ */ jsx8(LivePanel, { active: true, focused: true }, viewNonce) });
|
|
10420
10410
|
}
|
|
10421
10411
|
const Panel = current.Panel;
|
|
10422
|
-
const panelBody = current.label === "
|
|
10423
|
-
return /* @__PURE__ */
|
|
10424
|
-
/* @__PURE__ */
|
|
10425
|
-
/* @__PURE__ */
|
|
10426
|
-
/* @__PURE__ */
|
|
10427
|
-
/* @__PURE__ */
|
|
10428
|
-
locked ? /* @__PURE__ */
|
|
10429
|
-
update2.kind === "updating" ? /* @__PURE__ */
|
|
10412
|
+
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" });
|
|
10413
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", width: cols, height: rows, paddingX: 1, paddingTop: 1, children: [
|
|
10414
|
+
/* @__PURE__ */ jsx8(Banner, { cols }),
|
|
10415
|
+
/* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", children: [
|
|
10416
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "account: " }),
|
|
10417
|
+
/* @__PURE__ */ jsx8(Text8, { color: locked ? theme.warn : theme.accentBright, bold: true, children: acctLabel2 }),
|
|
10418
|
+
locked ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 log in from Settings to unlock the dataroom" }) : accounts.length > 1 ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: ` (${acctIdx + 1}/${accounts.length} \xB7 a switch \xB7 Settings to manage)` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 Settings to add another" }),
|
|
10419
|
+
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) : update2.kind === "manual" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 v${update2.version} available \u2014 npm i -g @solongate/proxy@latest` }) : null
|
|
10430
10420
|
] }),
|
|
10431
|
-
/* @__PURE__ */
|
|
10432
|
-
/* @__PURE__ */
|
|
10421
|
+
/* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexGrow: 1, children: [
|
|
10422
|
+
/* @__PURE__ */ jsx8(Box8, { flexDirection: "column", width: 16, borderStyle: "round", borderColor: focus === "nav" ? theme.accent : "gray", paddingX: 1, children: SECTIONS.map((s, i) => {
|
|
10433
10423
|
const isCur = i === effectiveSection;
|
|
10434
|
-
const disabled = locked && s.label !== "
|
|
10435
|
-
return /* @__PURE__ */
|
|
10424
|
+
const disabled = locked && s.label !== "Settings";
|
|
10425
|
+
return /* @__PURE__ */ jsx8(Text8, { color: isCur ? theme.accentBright : disabled ? theme.dim : void 0, bold: isCur, dimColor: disabled, children: (isCur ? "\u25B8 " : disabled ? "\u2298 " : " ") + s.label }, s.label);
|
|
10436
10426
|
}) }),
|
|
10437
|
-
/* @__PURE__ */
|
|
10427
|
+
/* @__PURE__ */ jsx8(Box8, { flexGrow: 1, borderStyle: "round", borderColor: focus === "panel" ? theme.accent : "gray", paddingX: 1, paddingY: 0, children: panelBody })
|
|
10438
10428
|
] }, viewNonce),
|
|
10439
|
-
/* @__PURE__ */
|
|
10429
|
+
/* @__PURE__ */ jsx8(Box8, { children: locked ? /* @__PURE__ */ jsx8(KeyHints, { hints: [["\u2192/enter", "open Settings"], ["n", "log in"], ["q", "quit"]] }) : focus === "nav" ? /* @__PURE__ */ jsx8(KeyHints, { hints: [["\u2191\u2193", "section"], ["\u2192/enter", "open"], ...accounts.length > 1 ? [["a", "account"]] : [], ["?", "help"], ["q", "quit"]] }) : /* @__PURE__ */ jsx8(KeyHints, { hints: [["\u2190/esc", "back"], ["\u2191\u2193", "in-panel"], ["space/s", "act"]] }) })
|
|
10440
10430
|
] });
|
|
10441
10431
|
}
|
|
10442
10432
|
function HelpOverlay({ cols, rows }) {
|
|
10443
|
-
return /* @__PURE__ */
|
|
10444
|
-
/* @__PURE__ */
|
|
10445
|
-
/* @__PURE__ */
|
|
10446
|
-
/* @__PURE__ */
|
|
10447
|
-
keys.map(([k, desc]) => /* @__PURE__ */
|
|
10448
|
-
/* @__PURE__ */
|
|
10449
|
-
/* @__PURE__ */
|
|
10433
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", width: cols, height: rows, paddingX: 2, paddingTop: 1, children: [
|
|
10434
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, color: theme.accentBright, children: "SolonGate \u2014 keyboard shortcuts" }),
|
|
10435
|
+
/* @__PURE__ */ jsx8(Box8, { marginTop: 1, flexDirection: "column", children: HELP.map(([group, keys]) => /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginBottom: 1, children: [
|
|
10436
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, color: theme.accent, children: group }),
|
|
10437
|
+
keys.map(([k, desc]) => /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
10438
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.accentBright, children: (" " + k).padEnd(16) }),
|
|
10439
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: desc })
|
|
10450
10440
|
] }, k))
|
|
10451
10441
|
] }, group)) }),
|
|
10452
|
-
/* @__PURE__ */
|
|
10442
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "press any key to close" })
|
|
10453
10443
|
] });
|
|
10454
10444
|
}
|
|
10455
|
-
var SECTIONS, BANNER_HEX,
|
|
10445
|
+
var SECTIONS, BANNER_HEX, SETTINGS_SECTION, HELP;
|
|
10456
10446
|
var init_App = __esm({
|
|
10457
10447
|
"src/tui/App.tsx"() {
|
|
10458
10448
|
"use strict";
|
|
@@ -10465,7 +10455,6 @@ var init_App = __esm({
|
|
|
10465
10455
|
init_Dlp();
|
|
10466
10456
|
init_Audit();
|
|
10467
10457
|
init_Settings();
|
|
10468
|
-
init_Accounts();
|
|
10469
10458
|
init_hooks();
|
|
10470
10459
|
init_client();
|
|
10471
10460
|
init_api_client();
|
|
@@ -10476,11 +10465,10 @@ var init_App = __esm({
|
|
|
10476
10465
|
{ label: "Rate Limit", Panel: RateLimitPanel },
|
|
10477
10466
|
{ label: "DLP", Panel: DlpPanel },
|
|
10478
10467
|
{ label: "Audit", Panel: AuditPanel },
|
|
10479
|
-
{ label: "Settings", Panel: SettingsPanel }
|
|
10480
|
-
{ label: "Accounts", Panel: AccountsPanel }
|
|
10468
|
+
{ label: "Settings", Panel: SettingsPanel }
|
|
10481
10469
|
];
|
|
10482
10470
|
BANNER_HEX = ["white", "white", "white", "white", "white", "white"];
|
|
10483
|
-
|
|
10471
|
+
SETTINGS_SECTION = SECTIONS.findIndex((s) => s.label === "Settings");
|
|
10484
10472
|
HELP = [
|
|
10485
10473
|
["Global", [["\u2191\u2193", "move between sections"], ["\u2192 / enter", "open a section"], ["\u2190 / esc", "back to the menu"], ["?", "this help"], ["q", "quit"]]],
|
|
10486
10474
|
["Live", [["\u2191\u2193", "select a stream row"], ["enter", "full entry content"], ["w", "whitelist the selected DENY"], ["b", "block the selected ALLOW"], ["d / x / r", "filter denies / dlp / rate-limit"], ["f", "local / cloud filter"], ["/", "search"], ["s", "sessions (\u2191\u2193 pick, enter open)"], ["space", "copy mode (freeze)"]]],
|
|
@@ -10502,7 +10490,7 @@ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync7 } from "fs";
|
|
|
10502
10490
|
import { homedir as homedir8 } from "os";
|
|
10503
10491
|
import { join as join10 } from "path";
|
|
10504
10492
|
import { render } from "ink";
|
|
10505
|
-
import { jsx as
|
|
10493
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
10506
10494
|
async function launchTui() {
|
|
10507
10495
|
if (!process.stdout.isTTY || !process.stdin.isTTY) {
|
|
10508
10496
|
process.stderr.write(
|
|
@@ -10527,7 +10515,7 @@ async function launchTui() {
|
|
|
10527
10515
|
console.info = toFile("info");
|
|
10528
10516
|
console.debug = toFile("debug");
|
|
10529
10517
|
try {
|
|
10530
|
-
const { waitUntilExit } = render(/* @__PURE__ */
|
|
10518
|
+
const { waitUntilExit } = render(/* @__PURE__ */ jsx9(App, {}), { patchConsole: false });
|
|
10531
10519
|
await waitUntilExit();
|
|
10532
10520
|
} finally {
|
|
10533
10521
|
Object.assign(console, saved);
|
|
@@ -12036,7 +12024,7 @@ async function main() {
|
|
|
12036
12024
|
if (data?.project?.name) {
|
|
12037
12025
|
console.log(` ${c.dim}Project:${c.reset} ${c.cyan}${data.project.name}${c.reset}`);
|
|
12038
12026
|
}
|
|
12039
|
-
saveAccount({ apiKey, apiUrl, project: data?.project?.name, user: data?.user?.name || data?.user?.email });
|
|
12027
|
+
saveAccount({ apiKey, apiUrl, project: data?.project?.name, user: data?.user?.name || data?.user?.email, email: data?.user?.email });
|
|
12040
12028
|
break;
|
|
12041
12029
|
}
|
|
12042
12030
|
if (data?.status === "expired" || data?.status === "not_found") {
|