@solongate/proxy 0.81.45 → 0.81.46
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 +291 -149
- package/dist/self-update.d.ts +6 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6554,15 +6554,151 @@ var init_cli_utils = __esm({
|
|
|
6554
6554
|
}
|
|
6555
6555
|
});
|
|
6556
6556
|
|
|
6557
|
-
// src/
|
|
6558
|
-
|
|
6557
|
+
// src/self-update.ts
|
|
6558
|
+
var self_update_exports = {};
|
|
6559
|
+
__export(self_update_exports, {
|
|
6560
|
+
currentVersion: () => currentVersion,
|
|
6561
|
+
maybeSelfUpdate: () => maybeSelfUpdate
|
|
6562
|
+
});
|
|
6563
|
+
import { execFile, spawn } from "child_process";
|
|
6564
|
+
import { mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync4, realpathSync, writeFileSync as writeFileSync3 } from "fs";
|
|
6559
6565
|
import { homedir as homedir2 } from "os";
|
|
6560
|
-
import { join as join4 } from "path";
|
|
6566
|
+
import { dirname, join as join4 } from "path";
|
|
6567
|
+
import { fileURLToPath } from "url";
|
|
6568
|
+
function readState() {
|
|
6569
|
+
try {
|
|
6570
|
+
const s = JSON.parse(readFileSync4(STATE_FILE, "utf-8"));
|
|
6571
|
+
return s && typeof s === "object" ? s : {};
|
|
6572
|
+
} catch {
|
|
6573
|
+
return {};
|
|
6574
|
+
}
|
|
6575
|
+
}
|
|
6576
|
+
function writeState(s) {
|
|
6577
|
+
try {
|
|
6578
|
+
mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
|
|
6579
|
+
writeFileSync3(STATE_FILE, JSON.stringify(s));
|
|
6580
|
+
} catch {
|
|
6581
|
+
}
|
|
6582
|
+
}
|
|
6583
|
+
function currentVersion() {
|
|
6584
|
+
try {
|
|
6585
|
+
const pkg = JSON.parse(readFileSync4(join4(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf-8"));
|
|
6586
|
+
return pkg.version ?? "0.0.0";
|
|
6587
|
+
} catch {
|
|
6588
|
+
return "0.0.0";
|
|
6589
|
+
}
|
|
6590
|
+
}
|
|
6591
|
+
function newerThan(b, a) {
|
|
6592
|
+
const pa = a.split(".").map((n) => parseInt(n, 10) || 0);
|
|
6593
|
+
const pb = b.split(".").map((n) => parseInt(n, 10) || 0);
|
|
6594
|
+
for (let i = 0; i < 3; i++) {
|
|
6595
|
+
if ((pb[i] ?? 0) > (pa[i] ?? 0)) return true;
|
|
6596
|
+
if ((pb[i] ?? 0) < (pa[i] ?? 0)) return false;
|
|
6597
|
+
}
|
|
6598
|
+
return false;
|
|
6599
|
+
}
|
|
6600
|
+
async function fetchLatest() {
|
|
6601
|
+
try {
|
|
6602
|
+
const res = await fetch(`https://registry.npmjs.org/${PKG}/latest`, { signal: AbortSignal.timeout(2e3) });
|
|
6603
|
+
if (!res.ok) return null;
|
|
6604
|
+
const j = await res.json();
|
|
6605
|
+
return typeof j.version === "string" ? j.version : null;
|
|
6606
|
+
} catch {
|
|
6607
|
+
return null;
|
|
6608
|
+
}
|
|
6609
|
+
}
|
|
6610
|
+
function npmGlobalRoot() {
|
|
6611
|
+
return new Promise((resolve10) => {
|
|
6612
|
+
try {
|
|
6613
|
+
execFile("npm", ["root", "-g"], { timeout: 5e3, windowsHide: true, shell: process.platform === "win32" }, (err2, stdout) => {
|
|
6614
|
+
resolve10(err2 ? null : stdout.trim() || null);
|
|
6615
|
+
});
|
|
6616
|
+
} catch {
|
|
6617
|
+
resolve10(null);
|
|
6618
|
+
}
|
|
6619
|
+
});
|
|
6620
|
+
}
|
|
6621
|
+
async function isGlobalInstall() {
|
|
6622
|
+
try {
|
|
6623
|
+
const script = realpathSync(process.argv[1] ?? "");
|
|
6624
|
+
if (!script) return false;
|
|
6625
|
+
const root = await npmGlobalRoot();
|
|
6626
|
+
if (!root) return false;
|
|
6627
|
+
return script.startsWith(realpathSync(root));
|
|
6628
|
+
} catch {
|
|
6629
|
+
return false;
|
|
6630
|
+
}
|
|
6631
|
+
}
|
|
6632
|
+
function spawnGlobalInstall(version) {
|
|
6633
|
+
try {
|
|
6634
|
+
mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
|
|
6635
|
+
const log6 = openSync(LOG_FILE, "a");
|
|
6636
|
+
const p = spawn("npm", ["install", "-g", `${PKG}@${version}`], {
|
|
6637
|
+
stdio: ["ignore", log6, log6],
|
|
6638
|
+
detached: true,
|
|
6639
|
+
windowsHide: true,
|
|
6640
|
+
shell: process.platform === "win32"
|
|
6641
|
+
});
|
|
6642
|
+
p.on("error", () => {
|
|
6643
|
+
});
|
|
6644
|
+
p.unref();
|
|
6645
|
+
return true;
|
|
6646
|
+
} catch {
|
|
6647
|
+
return false;
|
|
6648
|
+
}
|
|
6649
|
+
}
|
|
6650
|
+
function maybeSelfUpdate(notify = (l) => process.stderr.write(l + "\n")) {
|
|
6651
|
+
void (async () => {
|
|
6652
|
+
try {
|
|
6653
|
+
const state = readState();
|
|
6654
|
+
const now = Date.now();
|
|
6655
|
+
const current = currentVersion();
|
|
6656
|
+
let latest = state.latestSeen ?? null;
|
|
6657
|
+
if (now - (state.lastCheckAt ?? 0) >= CHECK_EVERY_MS) {
|
|
6658
|
+
latest = await fetchLatest();
|
|
6659
|
+
if (latest) writeState({ ...state, lastCheckAt: now, latestSeen: latest });
|
|
6660
|
+
else writeState({ ...state, lastCheckAt: now });
|
|
6661
|
+
}
|
|
6662
|
+
if (!latest || !newerThan(latest, current)) return;
|
|
6663
|
+
const attempts = readState().attempts ?? {};
|
|
6664
|
+
if (await isGlobalInstall()) {
|
|
6665
|
+
if (now - (attempts[latest] ?? 0) >= ATTEMPT_EVERY_MS) {
|
|
6666
|
+
writeState({ ...readState(), attempts: { [latest]: now } });
|
|
6667
|
+
if (spawnGlobalInstall(latest)) {
|
|
6668
|
+
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 updating in the background, next run uses it${c.reset}`);
|
|
6669
|
+
return;
|
|
6670
|
+
}
|
|
6671
|
+
} else {
|
|
6672
|
+
return;
|
|
6673
|
+
}
|
|
6674
|
+
}
|
|
6675
|
+
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 update: ${c.reset}${c.cyan}npm i -g ${PKG}@latest${c.reset}`);
|
|
6676
|
+
} catch {
|
|
6677
|
+
}
|
|
6678
|
+
})();
|
|
6679
|
+
}
|
|
6680
|
+
var PKG, CHECK_EVERY_MS, ATTEMPT_EVERY_MS, STATE_FILE, LOG_FILE;
|
|
6681
|
+
var init_self_update = __esm({
|
|
6682
|
+
"src/self-update.ts"() {
|
|
6683
|
+
"use strict";
|
|
6684
|
+
init_cli_utils();
|
|
6685
|
+
PKG = "@solongate/proxy";
|
|
6686
|
+
CHECK_EVERY_MS = 30 * 60 * 1e3;
|
|
6687
|
+
ATTEMPT_EVERY_MS = 6 * 60 * 60 * 1e3;
|
|
6688
|
+
STATE_FILE = join4(homedir2(), ".solongate", ".self-update.json");
|
|
6689
|
+
LOG_FILE = join4(homedir2(), ".solongate", "self-update.log");
|
|
6690
|
+
}
|
|
6691
|
+
});
|
|
6692
|
+
|
|
6693
|
+
// src/tui/config.ts
|
|
6694
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
6695
|
+
import { homedir as homedir3 } from "os";
|
|
6696
|
+
import { join as join5 } from "path";
|
|
6561
6697
|
function loadConfig() {
|
|
6562
6698
|
if (cached) return cached;
|
|
6563
6699
|
const defaults = { notifications: true };
|
|
6564
6700
|
try {
|
|
6565
|
-
const raw =
|
|
6701
|
+
const raw = readFileSync5(join5(homedir3(), ".solongate", "tui-config.json"), "utf-8");
|
|
6566
6702
|
const j = JSON.parse(raw);
|
|
6567
6703
|
cached = {
|
|
6568
6704
|
notifications: j.notifications !== false,
|
|
@@ -6688,14 +6824,14 @@ var init_components = __esm({
|
|
|
6688
6824
|
});
|
|
6689
6825
|
|
|
6690
6826
|
// src/tui/local-log.ts
|
|
6691
|
-
import { closeSync, openSync, readFileSync as
|
|
6692
|
-
import { homedir as
|
|
6693
|
-
import { join as
|
|
6827
|
+
import { closeSync, openSync as openSync2, readFileSync as readFileSync6, readSync, statSync, writeFileSync as writeFileSync4 } from "fs";
|
|
6828
|
+
import { homedir as homedir4 } from "os";
|
|
6829
|
+
import { join as join6 } from "path";
|
|
6694
6830
|
function tailLines(file, maxBytes = 131072) {
|
|
6695
6831
|
try {
|
|
6696
6832
|
const size = statSync(file).size;
|
|
6697
6833
|
const start = Math.max(0, size - maxBytes);
|
|
6698
|
-
const fd =
|
|
6834
|
+
const fd = openSync2(file, "r");
|
|
6699
6835
|
const buf = Buffer.alloc(size - start);
|
|
6700
6836
|
readSync(fd, buf, 0, buf.length, start);
|
|
6701
6837
|
closeSync(fd);
|
|
@@ -6708,7 +6844,7 @@ function tailLines(file, maxBytes = 131072) {
|
|
|
6708
6844
|
}
|
|
6709
6845
|
function deleteLocalEntry(at, tool, session) {
|
|
6710
6846
|
try {
|
|
6711
|
-
const lines =
|
|
6847
|
+
const lines = readFileSync6(LOCAL_LOG, "utf-8").split("\n");
|
|
6712
6848
|
let removed = 0;
|
|
6713
6849
|
const kept = lines.filter((line) => {
|
|
6714
6850
|
if (!line.trim()) return false;
|
|
@@ -6724,7 +6860,7 @@ function deleteLocalEntry(at, tool, session) {
|
|
|
6724
6860
|
}
|
|
6725
6861
|
return true;
|
|
6726
6862
|
});
|
|
6727
|
-
if (removed)
|
|
6863
|
+
if (removed) writeFileSync4(LOCAL_LOG, kept.length ? kept.join("\n") + "\n" : "");
|
|
6728
6864
|
return removed;
|
|
6729
6865
|
} catch {
|
|
6730
6866
|
return 0;
|
|
@@ -6732,8 +6868,8 @@ function deleteLocalEntry(at, tool, session) {
|
|
|
6732
6868
|
}
|
|
6733
6869
|
function clearLocalLog() {
|
|
6734
6870
|
try {
|
|
6735
|
-
const n =
|
|
6736
|
-
|
|
6871
|
+
const n = readFileSync6(LOCAL_LOG, "utf-8").split("\n").filter(Boolean).length;
|
|
6872
|
+
writeFileSync4(LOCAL_LOG, "");
|
|
6737
6873
|
return n;
|
|
6738
6874
|
} catch {
|
|
6739
6875
|
return 0;
|
|
@@ -6764,20 +6900,20 @@ var LOCAL_LOG, DLP_REASON, RL_REASON;
|
|
|
6764
6900
|
var init_local_log = __esm({
|
|
6765
6901
|
"src/tui/local-log.ts"() {
|
|
6766
6902
|
"use strict";
|
|
6767
|
-
LOCAL_LOG =
|
|
6903
|
+
LOCAL_LOG = join6(homedir4(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
6768
6904
|
DLP_REASON = /security layer \(dlp\)/i;
|
|
6769
6905
|
RL_REASON = /security layer \(rate limit\)|rate[- ]?limit(?:ed)?\b.*exceed|exceeded \d+ calls/i;
|
|
6770
6906
|
}
|
|
6771
6907
|
});
|
|
6772
6908
|
|
|
6773
6909
|
// src/api-client/client.ts
|
|
6774
|
-
import { readFileSync as
|
|
6775
|
-
import { resolve as resolve3, join as
|
|
6776
|
-
import { homedir as
|
|
6910
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync3 } from "fs";
|
|
6911
|
+
import { resolve as resolve3, join as join7 } from "path";
|
|
6912
|
+
import { homedir as homedir5 } from "os";
|
|
6777
6913
|
function listAccounts() {
|
|
6778
6914
|
let list6 = [];
|
|
6779
6915
|
try {
|
|
6780
|
-
const raw = JSON.parse(
|
|
6916
|
+
const raw = JSON.parse(readFileSync7(accountsFile(), "utf-8"));
|
|
6781
6917
|
if (Array.isArray(raw)) list6 = raw.filter((a) => a && typeof a.apiKey === "string");
|
|
6782
6918
|
} catch {
|
|
6783
6919
|
}
|
|
@@ -6791,7 +6927,7 @@ function saveAccount(acc) {
|
|
|
6791
6927
|
try {
|
|
6792
6928
|
const list6 = (() => {
|
|
6793
6929
|
try {
|
|
6794
|
-
const raw = JSON.parse(
|
|
6930
|
+
const raw = JSON.parse(readFileSync7(accountsFile(), "utf-8"));
|
|
6795
6931
|
return Array.isArray(raw) ? raw.filter((a) => a && a.apiKey) : [];
|
|
6796
6932
|
} catch {
|
|
6797
6933
|
return [];
|
|
@@ -6799,8 +6935,8 @@ function saveAccount(acc) {
|
|
|
6799
6935
|
})();
|
|
6800
6936
|
const next = list6.filter((a) => a.apiKey !== acc.apiKey);
|
|
6801
6937
|
next.unshift({ ...acc, addedAt: acc.addedAt ?? Date.now() });
|
|
6802
|
-
|
|
6803
|
-
|
|
6938
|
+
mkdirSync4(join7(homedir5(), ".solongate"), { recursive: true });
|
|
6939
|
+
writeFileSync5(accountsFile(), JSON.stringify(next, null, 2));
|
|
6804
6940
|
} catch {
|
|
6805
6941
|
}
|
|
6806
6942
|
}
|
|
@@ -6813,15 +6949,15 @@ function isActiveAccount(apiKey) {
|
|
|
6813
6949
|
}
|
|
6814
6950
|
function setActiveAccount(creds) {
|
|
6815
6951
|
try {
|
|
6816
|
-
const dir =
|
|
6817
|
-
|
|
6818
|
-
const p =
|
|
6952
|
+
const dir = join7(homedir5(), ".solongate");
|
|
6953
|
+
mkdirSync4(dir, { recursive: true });
|
|
6954
|
+
const p = join7(dir, ["cloud", "guard.json"].join("-"));
|
|
6819
6955
|
let existing = {};
|
|
6820
6956
|
try {
|
|
6821
|
-
existing = JSON.parse(
|
|
6957
|
+
existing = JSON.parse(readFileSync7(p, "utf-8"));
|
|
6822
6958
|
} catch {
|
|
6823
6959
|
}
|
|
6824
|
-
|
|
6960
|
+
writeFileSync5(p, JSON.stringify({ ...existing, apiKey: creds.apiKey, apiUrl: creds.apiUrl }, null, 2));
|
|
6825
6961
|
cached2 = null;
|
|
6826
6962
|
return true;
|
|
6827
6963
|
} catch {
|
|
@@ -6830,9 +6966,9 @@ function setActiveAccount(creds) {
|
|
|
6830
6966
|
}
|
|
6831
6967
|
function loginCredentialFile() {
|
|
6832
6968
|
try {
|
|
6833
|
-
const p =
|
|
6969
|
+
const p = join7(homedir5(), ".solongate", "cloud-guard.json");
|
|
6834
6970
|
if (!existsSync3(p)) return {};
|
|
6835
|
-
const c2 = JSON.parse(
|
|
6971
|
+
const c2 = JSON.parse(readFileSync7(p, "utf-8"));
|
|
6836
6972
|
return c2 && typeof c2 === "object" ? c2 : {};
|
|
6837
6973
|
} catch {
|
|
6838
6974
|
return {};
|
|
@@ -6842,7 +6978,7 @@ function dotenvApiKey() {
|
|
|
6842
6978
|
try {
|
|
6843
6979
|
const envPath = resolve3(".env");
|
|
6844
6980
|
if (!existsSync3(envPath)) return void 0;
|
|
6845
|
-
for (const line of
|
|
6981
|
+
for (const line of readFileSync7(envPath, "utf-8").split("\n")) {
|
|
6846
6982
|
const trimmed = line.trim();
|
|
6847
6983
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
6848
6984
|
const eq = trimmed.indexOf("=");
|
|
@@ -6944,7 +7080,7 @@ var init_client = __esm({
|
|
|
6944
7080
|
"src/api-client/client.ts"() {
|
|
6945
7081
|
"use strict";
|
|
6946
7082
|
DEFAULT_API_URL2 = "https://api.solongate.com";
|
|
6947
|
-
accountsFile = () =>
|
|
7083
|
+
accountsFile = () => join7(homedir5(), ".solongate", "accounts.json");
|
|
6948
7084
|
viewOverride = null;
|
|
6949
7085
|
ApiError = class extends Error {
|
|
6950
7086
|
status;
|
|
@@ -6974,12 +7110,12 @@ var init_types = __esm({
|
|
|
6974
7110
|
});
|
|
6975
7111
|
|
|
6976
7112
|
// src/api-client/device-login.ts
|
|
6977
|
-
import { spawn } from "child_process";
|
|
7113
|
+
import { spawn as spawn2 } from "child_process";
|
|
6978
7114
|
function openBrowser(url) {
|
|
6979
7115
|
try {
|
|
6980
7116
|
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
6981
7117
|
const args = process.platform === "win32" ? ["/c", "start", '""', url] : [url];
|
|
6982
|
-
const child =
|
|
7118
|
+
const child = spawn2(cmd, args, { stdio: "ignore", detached: true });
|
|
6983
7119
|
child.on("error", () => {
|
|
6984
7120
|
});
|
|
6985
7121
|
child.unref();
|
|
@@ -7304,24 +7440,24 @@ var init_api_client = __esm({
|
|
|
7304
7440
|
});
|
|
7305
7441
|
|
|
7306
7442
|
// src/tui/notify.ts
|
|
7307
|
-
import { spawn as
|
|
7443
|
+
import { spawn as spawn3 } from "child_process";
|
|
7308
7444
|
function desktopNotify(title, msg) {
|
|
7309
7445
|
try {
|
|
7310
7446
|
if (process.platform === "linux") {
|
|
7311
|
-
const p =
|
|
7447
|
+
const p = spawn3("notify-send", ["-a", "SolonGate", title, msg], { stdio: "ignore", detached: true });
|
|
7312
7448
|
p.on("error", () => {
|
|
7313
7449
|
});
|
|
7314
7450
|
p.unref();
|
|
7315
7451
|
} else if (process.platform === "win32") {
|
|
7316
7452
|
const q = (s) => s.replace(/'/g, "''");
|
|
7317
7453
|
const ps = `Add-Type -AssemblyName System.Windows.Forms;Add-Type -AssemblyName System.Drawing;$n=New-Object System.Windows.Forms.NotifyIcon;$n.Icon=[System.Drawing.SystemIcons]::Information;$n.Visible=$true;$n.ShowBalloonTip(6000,'${q(title)}','${q(msg)}',[System.Windows.Forms.ToolTipIcon]::Warning);Start-Sleep -Milliseconds 6500;$n.Dispose()`;
|
|
7318
|
-
const p =
|
|
7454
|
+
const p = spawn3("powershell", ["-NoProfile", "-NonInteractive", "-Command", ps], { stdio: "ignore", detached: true, windowsHide: true });
|
|
7319
7455
|
p.on("error", () => {
|
|
7320
7456
|
});
|
|
7321
7457
|
p.unref();
|
|
7322
7458
|
} else if (process.platform === "darwin") {
|
|
7323
7459
|
const esc = (s) => s.replace(/"/g, '\\"');
|
|
7324
|
-
const p =
|
|
7460
|
+
const p = spawn3("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
|
|
7325
7461
|
p.on("error", () => {
|
|
7326
7462
|
});
|
|
7327
7463
|
p.unref();
|
|
@@ -7407,9 +7543,9 @@ var init_hooks = __esm({
|
|
|
7407
7543
|
// src/tui/panels/Live.tsx
|
|
7408
7544
|
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
7409
7545
|
import TextInput from "ink-text-input";
|
|
7410
|
-
import { mkdirSync as
|
|
7411
|
-
import { homedir as
|
|
7412
|
-
import { join as
|
|
7546
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
7547
|
+
import { homedir as homedir6 } from "os";
|
|
7548
|
+
import { join as join8 } from "path";
|
|
7413
7549
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
7414
7550
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
7415
7551
|
function extractTarget(detail) {
|
|
@@ -8000,10 +8136,10 @@ function LivePanel({ active: active2 }) {
|
|
|
8000
8136
|
else if (input === "x") toggleSignal("dlp");
|
|
8001
8137
|
else if (input === "r") toggleSignal("ratelimit");
|
|
8002
8138
|
else if (input === "e") {
|
|
8003
|
-
const file =
|
|
8139
|
+
const file = join8(homedir6(), ".solongate", "live-export.jsonl");
|
|
8004
8140
|
try {
|
|
8005
|
-
|
|
8006
|
-
|
|
8141
|
+
mkdirSync5(join8(homedir6(), ".solongate"), { recursive: true });
|
|
8142
|
+
writeFileSync6(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
|
|
8007
8143
|
setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
|
|
8008
8144
|
} catch (err2) {
|
|
8009
8145
|
setActionMsg({ text: "\u2717 export failed: " + (err2 instanceof Error ? err2.message : String(err2)), level: "bad", until: Date.now() + 6e3 });
|
|
@@ -8413,7 +8549,7 @@ var init_Live = __esm({
|
|
|
8413
8549
|
SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
8414
8550
|
BG = "#12234f";
|
|
8415
8551
|
DIM_FLOOR = "#233457";
|
|
8416
|
-
RING =
|
|
8552
|
+
RING = join8(process.cwd(), ".solongate", ".eval-ring.jsonl");
|
|
8417
8553
|
hhmmss = (ts) => {
|
|
8418
8554
|
const d = new Date(ts);
|
|
8419
8555
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
@@ -9103,9 +9239,9 @@ var init_Dlp = __esm({
|
|
|
9103
9239
|
// src/tui/panels/Audit.tsx
|
|
9104
9240
|
import { Box as Box6, Text as Text6, useInput as useInput5 } from "ink";
|
|
9105
9241
|
import TextInput4 from "ink-text-input";
|
|
9106
|
-
import { mkdirSync as
|
|
9107
|
-
import { homedir as
|
|
9108
|
-
import { join as
|
|
9242
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
9243
|
+
import { homedir as homedir7 } from "os";
|
|
9244
|
+
import { join as join9 } from "path";
|
|
9109
9245
|
import { useState as useState6 } from "react";
|
|
9110
9246
|
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
9111
9247
|
function loadLocalRows() {
|
|
@@ -9259,16 +9395,16 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9259
9395
|
const doExport = (kind) => {
|
|
9260
9396
|
setMsg({ text: "exporting\u2026", level: "ok" });
|
|
9261
9397
|
const run12 = async () => {
|
|
9262
|
-
const dir =
|
|
9263
|
-
const file =
|
|
9398
|
+
const dir = join9(homedir7(), ".solongate");
|
|
9399
|
+
const file = join9(dir, `audit-export-${source}.jsonl`);
|
|
9264
9400
|
let rows2;
|
|
9265
9401
|
if (kind === "page") rows2 = pageRows;
|
|
9266
9402
|
else if (source === "cloud") {
|
|
9267
9403
|
const r = await api.audit.list({ ...query, limit: 1e4, offset: 0 });
|
|
9268
9404
|
rows2 = r.entries.map(cloudRow).sort((a, b) => b.at - a.at);
|
|
9269
9405
|
} else rows2 = localFiltered;
|
|
9270
|
-
|
|
9271
|
-
|
|
9406
|
+
mkdirSync6(dir, { recursive: true });
|
|
9407
|
+
writeFileSync7(file, rows2.map((x) => JSON.stringify(x)).join("\n") + (rows2.length ? "\n" : ""));
|
|
9272
9408
|
return { n: rows2.length, file };
|
|
9273
9409
|
};
|
|
9274
9410
|
run12().then(({ n, file }) => setMsg({ text: `\u2713 exported ${n} rows \u2192 ${file}`, level: "ok" })).catch((e) => setMsg({ text: "\u2717 export failed: " + (e instanceof Error ? e.message : String(e)), level: "bad" }));
|
|
@@ -10271,9 +10407,9 @@ var tui_exports = {};
|
|
|
10271
10407
|
__export(tui_exports, {
|
|
10272
10408
|
launchTui: () => launchTui
|
|
10273
10409
|
});
|
|
10274
|
-
import { appendFileSync as appendFileSync2, mkdirSync as
|
|
10275
|
-
import { homedir as
|
|
10276
|
-
import { join as
|
|
10410
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync7 } from "fs";
|
|
10411
|
+
import { homedir as homedir8 } from "os";
|
|
10412
|
+
import { join as join10 } from "path";
|
|
10277
10413
|
import { render } from "ink";
|
|
10278
10414
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
10279
10415
|
async function launchTui() {
|
|
@@ -10284,11 +10420,11 @@ async function launchTui() {
|
|
|
10284
10420
|
return;
|
|
10285
10421
|
}
|
|
10286
10422
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
10287
|
-
const debugLog =
|
|
10423
|
+
const debugLog = join10(homedir8(), ".solongate", "dataroom-debug.log");
|
|
10288
10424
|
const saved = { log: console.log, warn: console.warn, error: console.error, info: console.info, debug: console.debug };
|
|
10289
10425
|
const toFile = (level) => (...args) => {
|
|
10290
10426
|
try {
|
|
10291
|
-
|
|
10427
|
+
mkdirSync7(join10(homedir8(), ".solongate"), { recursive: true });
|
|
10292
10428
|
appendFileSync2(debugLog, `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
|
|
10293
10429
|
`);
|
|
10294
10430
|
} catch {
|
|
@@ -10412,7 +10548,7 @@ var init_args = __esm({
|
|
|
10412
10548
|
});
|
|
10413
10549
|
|
|
10414
10550
|
// src/commands/policy.ts
|
|
10415
|
-
import { readFileSync as
|
|
10551
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
10416
10552
|
async function run(argv) {
|
|
10417
10553
|
const { positionals, flags } = parse(argv);
|
|
10418
10554
|
const sub = positionals[0];
|
|
@@ -10587,7 +10723,7 @@ function printRules(rules) {
|
|
|
10587
10723
|
}
|
|
10588
10724
|
async function resolveRules(target) {
|
|
10589
10725
|
if (target.endsWith(".json")) {
|
|
10590
|
-
const parsed = JSON.parse(
|
|
10726
|
+
const parsed = JSON.parse(readFileSync8(target, "utf-8"));
|
|
10591
10727
|
return parsed.rules ?? [];
|
|
10592
10728
|
}
|
|
10593
10729
|
const p = await api.policies.get(target);
|
|
@@ -11003,8 +11139,8 @@ var init_agents2 = __esm({
|
|
|
11003
11139
|
|
|
11004
11140
|
// src/commands/doctor.ts
|
|
11005
11141
|
import { existsSync as existsSync4, statSync as statSync2 } from "fs";
|
|
11006
|
-
import { homedir as
|
|
11007
|
-
import { join as
|
|
11142
|
+
import { homedir as homedir9 } from "os";
|
|
11143
|
+
import { join as join11 } from "path";
|
|
11008
11144
|
async function run6(argv) {
|
|
11009
11145
|
const { flags } = parse(argv);
|
|
11010
11146
|
const json = flagBool(flags, "json");
|
|
@@ -11064,19 +11200,19 @@ var init_doctor = __esm({
|
|
|
11064
11200
|
init_api_client();
|
|
11065
11201
|
init_format();
|
|
11066
11202
|
init_args();
|
|
11067
|
-
LOCAL_LOG2 =
|
|
11203
|
+
LOCAL_LOG2 = join11(homedir9(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
11068
11204
|
}
|
|
11069
11205
|
});
|
|
11070
11206
|
|
|
11071
11207
|
// src/commands/watch.ts
|
|
11072
|
-
import { closeSync as closeSync2, existsSync as existsSync5, openSync as
|
|
11073
|
-
import { homedir as
|
|
11074
|
-
import { join as
|
|
11208
|
+
import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync3, readSync as readSync2, statSync as statSync3 } from "fs";
|
|
11209
|
+
import { homedir as homedir10 } from "os";
|
|
11210
|
+
import { join as join12 } from "path";
|
|
11075
11211
|
function tailLocal(file, maxBytes = 131072) {
|
|
11076
11212
|
try {
|
|
11077
11213
|
const size = statSync3(file).size;
|
|
11078
11214
|
const start = Math.max(0, size - maxBytes);
|
|
11079
|
-
const fd =
|
|
11215
|
+
const fd = openSync3(file, "r");
|
|
11080
11216
|
const buf = Buffer.alloc(size - start);
|
|
11081
11217
|
readSync2(fd, buf, 0, buf.length, start);
|
|
11082
11218
|
closeSync2(fd);
|
|
@@ -11178,7 +11314,7 @@ var init_watch = __esm({
|
|
|
11178
11314
|
init_cli_utils();
|
|
11179
11315
|
init_args();
|
|
11180
11316
|
init_format();
|
|
11181
|
-
LOCAL_LOG3 =
|
|
11317
|
+
LOCAL_LOG3 = join12(homedir10(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
11182
11318
|
trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
11183
11319
|
time = (ms) => new Date(ms).toTimeString().slice(0, 8);
|
|
11184
11320
|
}
|
|
@@ -11469,10 +11605,10 @@ var init_commands = __esm({
|
|
|
11469
11605
|
});
|
|
11470
11606
|
|
|
11471
11607
|
// src/global-install.ts
|
|
11472
|
-
import { readFileSync as
|
|
11473
|
-
import { resolve as resolve4, join as
|
|
11474
|
-
import { homedir as
|
|
11475
|
-
import { fileURLToPath } from "url";
|
|
11608
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync8, existsSync as existsSync6, mkdirSync as mkdirSync8 } from "fs";
|
|
11609
|
+
import { resolve as resolve4, join as join13, dirname as dirname2 } from "path";
|
|
11610
|
+
import { homedir as homedir11 } from "os";
|
|
11611
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
11476
11612
|
import { createInterface } from "readline";
|
|
11477
11613
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
11478
11614
|
function lockFile(file) {
|
|
@@ -11534,10 +11670,10 @@ function unlockFile(file) {
|
|
|
11534
11670
|
function protectedTargets() {
|
|
11535
11671
|
const p = globalPaths();
|
|
11536
11672
|
return [
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11673
|
+
join13(p.hooksDir, "guard.mjs"),
|
|
11674
|
+
join13(p.hooksDir, "audit.mjs"),
|
|
11675
|
+
join13(p.hooksDir, "stop.mjs"),
|
|
11676
|
+
join13(p.hooksDir, "shield.mjs"),
|
|
11541
11677
|
p.configPath,
|
|
11542
11678
|
p.settingsPath
|
|
11543
11679
|
];
|
|
@@ -11549,26 +11685,26 @@ function unlockProtected() {
|
|
|
11549
11685
|
for (const f of protectedTargets()) unlockFile(f);
|
|
11550
11686
|
}
|
|
11551
11687
|
function globalPaths() {
|
|
11552
|
-
const home =
|
|
11553
|
-
const sgDir =
|
|
11554
|
-
const hooksDir =
|
|
11555
|
-
const claudeDir =
|
|
11688
|
+
const home = homedir11();
|
|
11689
|
+
const sgDir = join13(home, ".solongate");
|
|
11690
|
+
const hooksDir = join13(sgDir, "hooks");
|
|
11691
|
+
const claudeDir = join13(home, ".claude");
|
|
11556
11692
|
return {
|
|
11557
11693
|
home,
|
|
11558
11694
|
sgDir,
|
|
11559
11695
|
hooksDir,
|
|
11560
11696
|
claudeDir,
|
|
11561
|
-
settingsPath:
|
|
11562
|
-
backupPath:
|
|
11563
|
-
configPath:
|
|
11697
|
+
settingsPath: join13(claudeDir, "settings.json"),
|
|
11698
|
+
backupPath: join13(claudeDir, "settings.solongate.bak"),
|
|
11699
|
+
configPath: join13(sgDir, "cloud-guard.json")
|
|
11564
11700
|
};
|
|
11565
11701
|
}
|
|
11566
11702
|
function readHook(filename) {
|
|
11567
|
-
return
|
|
11703
|
+
return readFileSync9(join13(HOOKS_DIR, filename), "utf-8");
|
|
11568
11704
|
}
|
|
11569
11705
|
function readGuard() {
|
|
11570
|
-
const bundled =
|
|
11571
|
-
return existsSync6(bundled) ?
|
|
11706
|
+
const bundled = join13(HOOKS_DIR, "guard.bundled.mjs");
|
|
11707
|
+
return existsSync6(bundled) ? readFileSync9(bundled, "utf-8") : readHook("guard.mjs");
|
|
11572
11708
|
}
|
|
11573
11709
|
function ask(question) {
|
|
11574
11710
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -11602,18 +11738,18 @@ function shimTargets() {
|
|
|
11602
11738
|
return [];
|
|
11603
11739
|
}
|
|
11604
11740
|
}
|
|
11605
|
-
return [".bashrc", ".zshrc", ".profile"].map((f) =>
|
|
11741
|
+
return [".bashrc", ".zshrc", ".profile"].map((f) => join13(homedir11(), f)).filter((f) => existsSync6(f));
|
|
11606
11742
|
}
|
|
11607
11743
|
function writeShimBlock(file, block2) {
|
|
11608
11744
|
const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
|
|
11609
|
-
let content = existsSync6(file) ?
|
|
11745
|
+
let content = existsSync6(file) ? readFileSync9(file, "utf-8") : "";
|
|
11610
11746
|
content = content.replace(re, "");
|
|
11611
11747
|
if (block2) {
|
|
11612
11748
|
if (content.length && !content.endsWith("\n")) content += "\n";
|
|
11613
11749
|
content += block2 + "\n";
|
|
11614
11750
|
}
|
|
11615
|
-
|
|
11616
|
-
|
|
11751
|
+
mkdirSync8(dirname2(file), { recursive: true });
|
|
11752
|
+
writeFileSync8(file, content);
|
|
11617
11753
|
}
|
|
11618
11754
|
function installClaudeShim(shieldPath) {
|
|
11619
11755
|
const real = resolveRealClaude();
|
|
@@ -11643,7 +11779,7 @@ async function runGlobalInstall(opts = {}) {
|
|
|
11643
11779
|
let apiKey = opts.apiKey || process.env["SOLONGATE_API_KEY"] || "";
|
|
11644
11780
|
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
11645
11781
|
try {
|
|
11646
|
-
const cfg = JSON.parse(
|
|
11782
|
+
const cfg = JSON.parse(readFileSync9(p.configPath, "utf-8"));
|
|
11647
11783
|
if (cfg && typeof cfg.apiKey === "string") apiKey = cfg.apiKey;
|
|
11648
11784
|
} catch {
|
|
11649
11785
|
}
|
|
@@ -11656,22 +11792,22 @@ async function runGlobalInstall(opts = {}) {
|
|
|
11656
11792
|
process.exit(1);
|
|
11657
11793
|
}
|
|
11658
11794
|
const apiUrl = opts.apiUrl || process.env["SOLONGATE_API_URL"] || "https://api.solongate.com";
|
|
11659
|
-
|
|
11660
|
-
|
|
11795
|
+
mkdirSync8(p.hooksDir, { recursive: true });
|
|
11796
|
+
mkdirSync8(p.claudeDir, { recursive: true });
|
|
11661
11797
|
unlockProtected();
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11798
|
+
writeFileSync8(join13(p.hooksDir, "guard.mjs"), readGuard());
|
|
11799
|
+
writeFileSync8(join13(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
|
|
11800
|
+
writeFileSync8(join13(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
|
|
11801
|
+
writeFileSync8(join13(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
|
|
11666
11802
|
console.log(` Installed hooks \u2192 ${p.hooksDir}`);
|
|
11667
|
-
installClaudeShim(
|
|
11668
|
-
|
|
11803
|
+
installClaudeShim(join13(p.hooksDir, "shield.mjs"));
|
|
11804
|
+
writeFileSync8(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
|
|
11669
11805
|
console.log(` Wrote ${p.configPath}`);
|
|
11670
11806
|
let existing = {};
|
|
11671
11807
|
if (existsSync6(p.settingsPath)) {
|
|
11672
|
-
const raw =
|
|
11808
|
+
const raw = readFileSync9(p.settingsPath, "utf-8");
|
|
11673
11809
|
if (!existsSync6(p.backupPath)) {
|
|
11674
|
-
|
|
11810
|
+
writeFileSync8(p.backupPath, raw);
|
|
11675
11811
|
console.log(` Backed up existing settings \u2192 ${p.backupPath}`);
|
|
11676
11812
|
}
|
|
11677
11813
|
try {
|
|
@@ -11680,9 +11816,9 @@ async function runGlobalInstall(opts = {}) {
|
|
|
11680
11816
|
existing = {};
|
|
11681
11817
|
}
|
|
11682
11818
|
}
|
|
11683
|
-
const guardAbs =
|
|
11684
|
-
const auditAbs =
|
|
11685
|
-
const stopAbs =
|
|
11819
|
+
const guardAbs = join13(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
|
|
11820
|
+
const auditAbs = join13(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
|
|
11821
|
+
const stopAbs = join13(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
|
|
11686
11822
|
const nodeBin = process.execPath.replace(/\\/g, "/");
|
|
11687
11823
|
const call = process.platform === "win32" ? "& " : "";
|
|
11688
11824
|
const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
|
|
@@ -11694,7 +11830,7 @@ async function runGlobalInstall(opts = {}) {
|
|
|
11694
11830
|
Stop: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(stopAbs) }] }]
|
|
11695
11831
|
}
|
|
11696
11832
|
};
|
|
11697
|
-
|
|
11833
|
+
writeFileSync8(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
11698
11834
|
console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
|
|
11699
11835
|
if (process.env["SOLONGATE_OS_LOCK"] === "1") {
|
|
11700
11836
|
lockProtected();
|
|
@@ -11705,7 +11841,7 @@ var __dirname, HOOKS_DIR, SHIM_BEGIN, SHIM_END;
|
|
|
11705
11841
|
var init_global_install = __esm({
|
|
11706
11842
|
"src/global-install.ts"() {
|
|
11707
11843
|
"use strict";
|
|
11708
|
-
__dirname =
|
|
11844
|
+
__dirname = dirname2(fileURLToPath2(import.meta.url));
|
|
11709
11845
|
HOOKS_DIR = resolve4(__dirname, "..", "hooks");
|
|
11710
11846
|
SHIM_BEGIN = "# >>> SolonGate shield (auto secret redaction) >>>";
|
|
11711
11847
|
SHIM_END = "# <<< SolonGate shield <<<";
|
|
@@ -11714,7 +11850,7 @@ var init_global_install = __esm({
|
|
|
11714
11850
|
|
|
11715
11851
|
// src/login.ts
|
|
11716
11852
|
var login_exports = {};
|
|
11717
|
-
import { spawn as
|
|
11853
|
+
import { spawn as spawn4 } from "child_process";
|
|
11718
11854
|
function startSpinner(text) {
|
|
11719
11855
|
if (!process.stderr.isTTY) {
|
|
11720
11856
|
process.stderr.write(` ${text}
|
|
@@ -11750,7 +11886,7 @@ function openBrowser2(url) {
|
|
|
11750
11886
|
try {
|
|
11751
11887
|
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
11752
11888
|
const args = process.platform === "win32" ? ["/c", "start", '""', url] : [url];
|
|
11753
|
-
const child =
|
|
11889
|
+
const child = spawn4(cmd, args, { stdio: "ignore", detached: true });
|
|
11754
11890
|
child.on("error", () => {
|
|
11755
11891
|
});
|
|
11756
11892
|
child.unref();
|
|
@@ -11870,13 +12006,13 @@ __export(shield_exports, {
|
|
|
11870
12006
|
});
|
|
11871
12007
|
import { createServer, request as httpRequest } from "http";
|
|
11872
12008
|
import { request as httpsRequest } from "https";
|
|
11873
|
-
import { spawn as
|
|
12009
|
+
import { spawn as spawn5 } from "child_process";
|
|
11874
12010
|
import { URL as URL2 } from "url";
|
|
11875
|
-
import { readFileSync as
|
|
12011
|
+
import { readFileSync as readFileSync10, existsSync as existsSync7, readdirSync, statSync as statSync4 } from "fs";
|
|
11876
12012
|
import { resolve as resolve5 } from "path";
|
|
11877
|
-
import { homedir as
|
|
12013
|
+
import { homedir as homedir12 } from "os";
|
|
11878
12014
|
function findCacheFile() {
|
|
11879
|
-
const dir = resolve5(
|
|
12015
|
+
const dir = resolve5(homedir12(), ".solongate");
|
|
11880
12016
|
const envSel = process.env.SOLONGATE_AGENT_ID;
|
|
11881
12017
|
if (envSel) {
|
|
11882
12018
|
const f = resolve5(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
|
|
@@ -11902,7 +12038,7 @@ function loadCfg() {
|
|
|
11902
12038
|
try {
|
|
11903
12039
|
const f = findCacheFile();
|
|
11904
12040
|
if (f && existsSync7(f)) {
|
|
11905
|
-
const c2 = JSON.parse(
|
|
12041
|
+
const c2 = JSON.parse(readFileSync10(f, "utf-8"));
|
|
11906
12042
|
const d = c2?.security?.dlpRedact;
|
|
11907
12043
|
const g = c2?.security?.ghost;
|
|
11908
12044
|
const ghost = g && Array.isArray(g.patterns) ? g.patterns : [];
|
|
@@ -12130,7 +12266,7 @@ async function runShield() {
|
|
|
12130
12266
|
const upstream = pickUpstream();
|
|
12131
12267
|
const { port, close } = await startProxy(upstream);
|
|
12132
12268
|
log4(`redacting secrets on the LLM path \u2192 masking before ${upstream.host} (127.0.0.1:${port})`);
|
|
12133
|
-
const child =
|
|
12269
|
+
const child = spawn5(cmd[0], cmd.slice(1), {
|
|
12134
12270
|
stdio: "inherit",
|
|
12135
12271
|
env: { ...process.env, ANTHROPIC_BASE_URL: `http://127.0.0.1:${port}` },
|
|
12136
12272
|
shell: process.platform === "win32"
|
|
@@ -12190,9 +12326,9 @@ __export(logs_server_exports, {
|
|
|
12190
12326
|
runLogsServer: () => runLogsServer
|
|
12191
12327
|
});
|
|
12192
12328
|
import { createServer as createServer2 } from "http";
|
|
12193
|
-
import { readFileSync as
|
|
12194
|
-
import { resolve as resolve6, join as
|
|
12195
|
-
import { homedir as
|
|
12329
|
+
import { readFileSync as readFileSync11, statSync as statSync5 } from "fs";
|
|
12330
|
+
import { resolve as resolve6, join as join14, isAbsolute } from "path";
|
|
12331
|
+
import { homedir as homedir13 } from "os";
|
|
12196
12332
|
import { readdirSync as readdirSync2 } from "fs";
|
|
12197
12333
|
function allowedOrigins() {
|
|
12198
12334
|
const base = [
|
|
@@ -12209,15 +12345,15 @@ function resolveLocalLogDir(rawPath) {
|
|
|
12209
12345
|
const dir = String(rawPath || "").trim().replace(/[\\/]+$/, "");
|
|
12210
12346
|
if (!dir) return null;
|
|
12211
12347
|
if (isAbsolute(dir)) return dir;
|
|
12212
|
-
return resolve6(
|
|
12348
|
+
return resolve6(homedir13(), ".solongate", "local-logs");
|
|
12213
12349
|
}
|
|
12214
12350
|
async function findLogDir() {
|
|
12215
|
-
const base = resolve6(
|
|
12351
|
+
const base = resolve6(homedir13(), ".solongate");
|
|
12216
12352
|
try {
|
|
12217
12353
|
const files = readdirSync2(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
|
|
12218
12354
|
for (const f of files) {
|
|
12219
12355
|
try {
|
|
12220
|
-
const c2 = JSON.parse(
|
|
12356
|
+
const c2 = JSON.parse(readFileSync11(join14(base, f), "utf-8"));
|
|
12221
12357
|
const p = c2?.security?.localLogs?.path;
|
|
12222
12358
|
if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
|
|
12223
12359
|
} catch {
|
|
@@ -12226,7 +12362,7 @@ async function findLogDir() {
|
|
|
12226
12362
|
} catch {
|
|
12227
12363
|
}
|
|
12228
12364
|
try {
|
|
12229
|
-
const cfgRaw =
|
|
12365
|
+
const cfgRaw = readFileSync11(join14(base, "cloud-guard.json"), "utf-8");
|
|
12230
12366
|
const { apiKey, apiUrl } = JSON.parse(cfgRaw);
|
|
12231
12367
|
if (apiKey) {
|
|
12232
12368
|
const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
|
|
@@ -12255,7 +12391,7 @@ function setCors(req, res) {
|
|
|
12255
12391
|
}
|
|
12256
12392
|
function fileInfo(dir) {
|
|
12257
12393
|
if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
|
|
12258
|
-
const file =
|
|
12394
|
+
const file = join14(dir, LOG_FILENAME);
|
|
12259
12395
|
try {
|
|
12260
12396
|
const st = statSync5(file);
|
|
12261
12397
|
return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
|
|
@@ -12316,7 +12452,7 @@ async function runLogsServer() {
|
|
|
12316
12452
|
return;
|
|
12317
12453
|
}
|
|
12318
12454
|
try {
|
|
12319
|
-
const text =
|
|
12455
|
+
const text = readFileSync11(info.file, "utf-8");
|
|
12320
12456
|
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8", "Last-Modified": lastMod, "X-Solongate-Exists": "1" });
|
|
12321
12457
|
res.end(text);
|
|
12322
12458
|
} catch {
|
|
@@ -12368,7 +12504,7 @@ var init_logs_server = __esm({
|
|
|
12368
12504
|
|
|
12369
12505
|
// src/inject.ts
|
|
12370
12506
|
var inject_exports = {};
|
|
12371
|
-
import { readFileSync as
|
|
12507
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, existsSync as existsSync8, copyFileSync } from "fs";
|
|
12372
12508
|
import { resolve as resolve7 } from "path";
|
|
12373
12509
|
import { execSync } from "child_process";
|
|
12374
12510
|
function parseInjectArgs(argv) {
|
|
@@ -12428,7 +12564,7 @@ WHAT IT DOES
|
|
|
12428
12564
|
function detectProject() {
|
|
12429
12565
|
if (!existsSync8(resolve7("package.json"))) return false;
|
|
12430
12566
|
try {
|
|
12431
|
-
const pkg = JSON.parse(
|
|
12567
|
+
const pkg = JSON.parse(readFileSync12(resolve7("package.json"), "utf-8"));
|
|
12432
12568
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12433
12569
|
return !!(allDeps["@modelcontextprotocol/sdk"] || allDeps["@modelcontextprotocol/server"]);
|
|
12434
12570
|
} catch {
|
|
@@ -12437,7 +12573,7 @@ function detectProject() {
|
|
|
12437
12573
|
}
|
|
12438
12574
|
function findTsEntryFile() {
|
|
12439
12575
|
try {
|
|
12440
|
-
const pkg = JSON.parse(
|
|
12576
|
+
const pkg = JSON.parse(readFileSync12(resolve7("package.json"), "utf-8"));
|
|
12441
12577
|
if (pkg.bin) {
|
|
12442
12578
|
const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
|
|
12443
12579
|
if (typeof binPath === "string") {
|
|
@@ -12464,7 +12600,7 @@ function findTsEntryFile() {
|
|
|
12464
12600
|
const full = resolve7(c2);
|
|
12465
12601
|
if (existsSync8(full)) {
|
|
12466
12602
|
try {
|
|
12467
|
-
const content =
|
|
12603
|
+
const content = readFileSync12(full, "utf-8");
|
|
12468
12604
|
if (content.includes("McpServer") || content.includes("McpServer")) {
|
|
12469
12605
|
return full;
|
|
12470
12606
|
}
|
|
@@ -12484,7 +12620,7 @@ function detectPackageManager() {
|
|
|
12484
12620
|
}
|
|
12485
12621
|
function installSdk() {
|
|
12486
12622
|
try {
|
|
12487
|
-
const pkg = JSON.parse(
|
|
12623
|
+
const pkg = JSON.parse(readFileSync12(resolve7("package.json"), "utf-8"));
|
|
12488
12624
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12489
12625
|
if (allDeps["@solongate/proxy"]) {
|
|
12490
12626
|
log3(" @solongate/proxy already installed");
|
|
@@ -12505,7 +12641,7 @@ function installSdk() {
|
|
|
12505
12641
|
}
|
|
12506
12642
|
}
|
|
12507
12643
|
function injectTypeScript(filePath) {
|
|
12508
|
-
const original =
|
|
12644
|
+
const original = readFileSync12(filePath, "utf-8");
|
|
12509
12645
|
const changes = [];
|
|
12510
12646
|
let modified = original;
|
|
12511
12647
|
if (modified.includes("SecureMcpServer")) {
|
|
@@ -12676,7 +12812,7 @@ async function main2() {
|
|
|
12676
12812
|
log3("");
|
|
12677
12813
|
log3(` Backup: ${backupPath}`);
|
|
12678
12814
|
}
|
|
12679
|
-
|
|
12815
|
+
writeFileSync9(entryFile, result.modified);
|
|
12680
12816
|
log3("");
|
|
12681
12817
|
log3(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
12682
12818
|
log3(" \u2502 SolonGate SDK injected successfully! \u2502");
|
|
@@ -12705,8 +12841,8 @@ var init_inject = __esm({
|
|
|
12705
12841
|
|
|
12706
12842
|
// src/create.ts
|
|
12707
12843
|
var create_exports = {};
|
|
12708
|
-
import { mkdirSync as
|
|
12709
|
-
import { resolve as resolve8, join as
|
|
12844
|
+
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync10, existsSync as existsSync9 } from "fs";
|
|
12845
|
+
import { resolve as resolve8, join as join15 } from "path";
|
|
12710
12846
|
import { execSync as execSync2 } from "child_process";
|
|
12711
12847
|
function withSpinner(message, fn) {
|
|
12712
12848
|
const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
|
|
@@ -12785,8 +12921,8 @@ EXAMPLES
|
|
|
12785
12921
|
`);
|
|
12786
12922
|
}
|
|
12787
12923
|
function createProject(dir, name, _policy) {
|
|
12788
|
-
|
|
12789
|
-
|
|
12924
|
+
writeFileSync10(
|
|
12925
|
+
join15(dir, "package.json"),
|
|
12790
12926
|
JSON.stringify(
|
|
12791
12927
|
{
|
|
12792
12928
|
name,
|
|
@@ -12815,8 +12951,8 @@ function createProject(dir, name, _policy) {
|
|
|
12815
12951
|
2
|
|
12816
12952
|
) + "\n"
|
|
12817
12953
|
);
|
|
12818
|
-
|
|
12819
|
-
|
|
12954
|
+
writeFileSync10(
|
|
12955
|
+
join15(dir, "tsconfig.json"),
|
|
12820
12956
|
JSON.stringify(
|
|
12821
12957
|
{
|
|
12822
12958
|
compilerOptions: {
|
|
@@ -12836,9 +12972,9 @@ function createProject(dir, name, _policy) {
|
|
|
12836
12972
|
2
|
|
12837
12973
|
) + "\n"
|
|
12838
12974
|
);
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
12975
|
+
mkdirSync9(join15(dir, "src"), { recursive: true });
|
|
12976
|
+
writeFileSync10(
|
|
12977
|
+
join15(dir, "src", "index.ts"),
|
|
12842
12978
|
`#!/usr/bin/env node
|
|
12843
12979
|
|
|
12844
12980
|
console.log = (...args: unknown[]) => {
|
|
@@ -12879,8 +13015,8 @@ console.log('');
|
|
|
12879
13015
|
console.log('Press Ctrl+C to stop.');
|
|
12880
13016
|
`
|
|
12881
13017
|
);
|
|
12882
|
-
|
|
12883
|
-
|
|
13018
|
+
writeFileSync10(
|
|
13019
|
+
join15(dir, ".mcp.json"),
|
|
12884
13020
|
JSON.stringify(
|
|
12885
13021
|
{
|
|
12886
13022
|
mcpServers: {
|
|
@@ -12897,13 +13033,13 @@ console.log('Press Ctrl+C to stop.');
|
|
|
12897
13033
|
2
|
|
12898
13034
|
) + "\n"
|
|
12899
13035
|
);
|
|
12900
|
-
|
|
12901
|
-
|
|
13036
|
+
writeFileSync10(
|
|
13037
|
+
join15(dir, ".env"),
|
|
12902
13038
|
`SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
|
|
12903
13039
|
`
|
|
12904
13040
|
);
|
|
12905
|
-
|
|
12906
|
-
|
|
13041
|
+
writeFileSync10(
|
|
13042
|
+
join15(dir, ".gitignore"),
|
|
12907
13043
|
`node_modules/
|
|
12908
13044
|
dist/
|
|
12909
13045
|
*.solongate-backup
|
|
@@ -12922,7 +13058,7 @@ async function main3() {
|
|
|
12922
13058
|
process.exit(1);
|
|
12923
13059
|
}
|
|
12924
13060
|
withSpinner(`Setting up ${opts.name}...`, () => {
|
|
12925
|
-
|
|
13061
|
+
mkdirSync9(dir, { recursive: true });
|
|
12926
13062
|
createProject(dir, opts.name, opts.policy);
|
|
12927
13063
|
});
|
|
12928
13064
|
if (!opts.noInstall) {
|
|
@@ -12996,14 +13132,14 @@ var init_create = __esm({
|
|
|
12996
13132
|
|
|
12997
13133
|
// src/pull-push.ts
|
|
12998
13134
|
var pull_push_exports = {};
|
|
12999
|
-
import { readFileSync as
|
|
13135
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync11, existsSync as existsSync10 } from "fs";
|
|
13000
13136
|
import { resolve as resolve9 } from "path";
|
|
13001
13137
|
function loadEnv() {
|
|
13002
13138
|
if (process.env.SOLONGATE_API_KEY) return;
|
|
13003
13139
|
const envPath = resolve9(".env");
|
|
13004
13140
|
if (!existsSync10(envPath)) return;
|
|
13005
13141
|
try {
|
|
13006
|
-
const content =
|
|
13142
|
+
const content = readFileSync13(envPath, "utf-8");
|
|
13007
13143
|
for (const line of content.split("\n")) {
|
|
13008
13144
|
const trimmed = line.trim();
|
|
13009
13145
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -13191,7 +13327,7 @@ async function pull(apiKey, file, policyId) {
|
|
|
13191
13327
|
const policy = await fetchCloudPolicy(apiKey, API_URL, policyId);
|
|
13192
13328
|
const { id: _id, ...policyWithoutId } = policy;
|
|
13193
13329
|
const json = JSON.stringify(policyWithoutId, null, 2) + "\n";
|
|
13194
|
-
|
|
13330
|
+
writeFileSync11(file, json, "utf-8");
|
|
13195
13331
|
log5("");
|
|
13196
13332
|
log5(green2(" Saved to: ") + file);
|
|
13197
13333
|
log5(` ${dim2("Name:")} ${policy.name}`);
|
|
@@ -13220,7 +13356,7 @@ async function push(apiKey, file, policyId) {
|
|
|
13220
13356
|
log5(" solongate-proxy list");
|
|
13221
13357
|
process.exit(1);
|
|
13222
13358
|
}
|
|
13223
|
-
const content =
|
|
13359
|
+
const content = readFileSync13(file, "utf-8");
|
|
13224
13360
|
let policy;
|
|
13225
13361
|
try {
|
|
13226
13362
|
policy = JSON.parse(content);
|
|
@@ -15380,7 +15516,7 @@ var SolonGate = class {
|
|
|
15380
15516
|
*/
|
|
15381
15517
|
startPolicyPolling() {
|
|
15382
15518
|
const apiUrl = this.config.apiUrl ?? "https://api.solongate.com";
|
|
15383
|
-
let
|
|
15519
|
+
let currentVersion2 = 0;
|
|
15384
15520
|
const timer = setInterval(async () => {
|
|
15385
15521
|
try {
|
|
15386
15522
|
const res = await fetch(`${apiUrl}/api/v1/policies/default`, {
|
|
@@ -15390,7 +15526,7 @@ var SolonGate = class {
|
|
|
15390
15526
|
if (!res.ok) return;
|
|
15391
15527
|
const data = await res.json();
|
|
15392
15528
|
const version = Number(data._version ?? 0);
|
|
15393
|
-
if (version !==
|
|
15529
|
+
if (version !== currentVersion2 && version > 0) {
|
|
15394
15530
|
const policySet = {
|
|
15395
15531
|
id: String(data.id ?? "cloud"),
|
|
15396
15532
|
name: String(data.name ?? "Cloud Policy"),
|
|
@@ -15402,7 +15538,7 @@ var SolonGate = class {
|
|
|
15402
15538
|
};
|
|
15403
15539
|
this.policyEngine.loadPolicySet(policySet);
|
|
15404
15540
|
await this.loadCloudWasm(apiUrl, policySet.id);
|
|
15405
|
-
|
|
15541
|
+
currentVersion2 = version;
|
|
15406
15542
|
}
|
|
15407
15543
|
} catch {
|
|
15408
15544
|
}
|
|
@@ -16370,6 +16506,12 @@ function printWelcome() {
|
|
|
16370
16506
|
}
|
|
16371
16507
|
async function main5() {
|
|
16372
16508
|
const subcommand = process.argv[2];
|
|
16509
|
+
if (IS_HUMAN_CLI) {
|
|
16510
|
+
const tuiBound = subcommand === "dataroom" || process.argv.length <= 2 && process.stdout.isTTY && process.stdin.isTTY;
|
|
16511
|
+
const { maybeSelfUpdate: maybeSelfUpdate2 } = await Promise.resolve().then(() => (init_self_update(), self_update_exports));
|
|
16512
|
+
maybeSelfUpdate2(tuiBound ? () => {
|
|
16513
|
+
} : void 0);
|
|
16514
|
+
}
|
|
16373
16515
|
if (process.argv.length <= 2) {
|
|
16374
16516
|
if (process.stdout.isTTY && process.stdin.isTTY) {
|
|
16375
16517
|
const { launchTui: launchTui2 } = await Promise.resolve().then(() => (init_tui(), tui_exports));
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function currentVersion(): string;
|
|
2
|
+
/**
|
|
3
|
+
* Fire-and-forget startup hook. `notify` writes the human-facing one-liner —
|
|
4
|
+
* callers pass a stderr writer so the notice never lands in piped stdout.
|
|
5
|
+
*/
|
|
6
|
+
export declare function maybeSelfUpdate(notify?: (line: string) => void): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.46",
|
|
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": {
|