@solongate/proxy 0.81.50 → 0.81.52
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 +294 -147
- package/dist/logs-server-daemon.d.ts +19 -0
- package/dist/logs-server.js +143 -9
- package/dist/tui/index.js +120 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6736,15 +6736,115 @@ var init_self_update = __esm({
|
|
|
6736
6736
|
}
|
|
6737
6737
|
});
|
|
6738
6738
|
|
|
6739
|
-
// src/
|
|
6740
|
-
|
|
6739
|
+
// src/logs-server-daemon.ts
|
|
6740
|
+
var logs_server_daemon_exports = {};
|
|
6741
|
+
__export(logs_server_daemon_exports, {
|
|
6742
|
+
LOGS_SERVER_PORT: () => LOGS_SERVER_PORT,
|
|
6743
|
+
ensureLogsServerDaemon: () => ensureLogsServerDaemon,
|
|
6744
|
+
logsServerStatus: () => logsServerStatus,
|
|
6745
|
+
recordLogsServerStarted: () => recordLogsServerStarted,
|
|
6746
|
+
startLogsServerDaemon: () => startLogsServerDaemon,
|
|
6747
|
+
stopLogsServerDaemon: () => stopLogsServerDaemon
|
|
6748
|
+
});
|
|
6749
|
+
import { spawn as spawn2 } from "child_process";
|
|
6750
|
+
import { mkdirSync as mkdirSync4, openSync as openSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
6741
6751
|
import { homedir as homedir3 } from "os";
|
|
6742
|
-
import { join as join5 } from "path";
|
|
6752
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
6753
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6754
|
+
function readState2() {
|
|
6755
|
+
try {
|
|
6756
|
+
const s = JSON.parse(readFileSync5(STATE_FILE2, "utf-8"));
|
|
6757
|
+
return s && typeof s === "object" ? s : {};
|
|
6758
|
+
} catch {
|
|
6759
|
+
return {};
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
function writeState2(s) {
|
|
6763
|
+
try {
|
|
6764
|
+
mkdirSync4(DIR, { recursive: true });
|
|
6765
|
+
writeFileSync4(STATE_FILE2, JSON.stringify(s));
|
|
6766
|
+
} catch {
|
|
6767
|
+
}
|
|
6768
|
+
}
|
|
6769
|
+
function pidAlive(pid) {
|
|
6770
|
+
if (!pid || pid <= 0) return false;
|
|
6771
|
+
try {
|
|
6772
|
+
process.kill(pid, 0);
|
|
6773
|
+
return true;
|
|
6774
|
+
} catch (e) {
|
|
6775
|
+
return e.code === "EPERM";
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
function logsServerStatus() {
|
|
6779
|
+
const s = readState2();
|
|
6780
|
+
const running = pidAlive(s.pid);
|
|
6781
|
+
return { desired: s.desired === "on" ? "on" : "off", running, pid: running ? s.pid : void 0, port: s.port || LOGS_SERVER_PORT };
|
|
6782
|
+
}
|
|
6783
|
+
function recordLogsServerStarted(port) {
|
|
6784
|
+
writeState2({ desired: "on", pid: process.pid, port, startedAt: Date.now() });
|
|
6785
|
+
}
|
|
6786
|
+
function startLogsServerDaemon() {
|
|
6787
|
+
const cur = logsServerStatus();
|
|
6788
|
+
if (cur.running) {
|
|
6789
|
+
writeState2({ ...readState2(), desired: "on" });
|
|
6790
|
+
return { ...cur, desired: "on" };
|
|
6791
|
+
}
|
|
6792
|
+
try {
|
|
6793
|
+
mkdirSync4(DIR, { recursive: true });
|
|
6794
|
+
const log6 = openSync2(LOG_FILE2, "a");
|
|
6795
|
+
const cli = join5(dirname2(fileURLToPath2(import.meta.url)), "index.js");
|
|
6796
|
+
const p = spawn2(process.execPath, [cli, "logs-server"], {
|
|
6797
|
+
detached: true,
|
|
6798
|
+
stdio: ["ignore", log6, log6],
|
|
6799
|
+
windowsHide: true
|
|
6800
|
+
});
|
|
6801
|
+
p.on("error", () => {
|
|
6802
|
+
});
|
|
6803
|
+
p.unref();
|
|
6804
|
+
writeState2({ desired: "on", pid: p.pid, port: LOGS_SERVER_PORT, startedAt: Date.now() });
|
|
6805
|
+
return { desired: "on", running: true, pid: p.pid, port: LOGS_SERVER_PORT };
|
|
6806
|
+
} catch {
|
|
6807
|
+
return { ...cur, desired: "on", running: false };
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6810
|
+
function stopLogsServerDaemon() {
|
|
6811
|
+
const s = readState2();
|
|
6812
|
+
if (pidAlive(s.pid)) {
|
|
6813
|
+
try {
|
|
6814
|
+
process.kill(s.pid);
|
|
6815
|
+
} catch {
|
|
6816
|
+
}
|
|
6817
|
+
}
|
|
6818
|
+
writeState2({ desired: "off", port: s.port });
|
|
6819
|
+
return { desired: "off", running: false, port: s.port || LOGS_SERVER_PORT };
|
|
6820
|
+
}
|
|
6821
|
+
function ensureLogsServerDaemon() {
|
|
6822
|
+
try {
|
|
6823
|
+
const s = logsServerStatus();
|
|
6824
|
+
if (s.desired === "on" && !s.running) startLogsServerDaemon();
|
|
6825
|
+
} catch {
|
|
6826
|
+
}
|
|
6827
|
+
}
|
|
6828
|
+
var DIR, STATE_FILE2, LOG_FILE2, LOGS_SERVER_PORT;
|
|
6829
|
+
var init_logs_server_daemon = __esm({
|
|
6830
|
+
"src/logs-server-daemon.ts"() {
|
|
6831
|
+
"use strict";
|
|
6832
|
+
DIR = join5(homedir3(), ".solongate");
|
|
6833
|
+
STATE_FILE2 = join5(DIR, ".logs-server.json");
|
|
6834
|
+
LOG_FILE2 = join5(DIR, "logs-server.log");
|
|
6835
|
+
LOGS_SERVER_PORT = 8788;
|
|
6836
|
+
}
|
|
6837
|
+
});
|
|
6838
|
+
|
|
6839
|
+
// src/tui/config.ts
|
|
6840
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
6841
|
+
import { homedir as homedir4 } from "os";
|
|
6842
|
+
import { join as join6 } from "path";
|
|
6743
6843
|
function loadConfig() {
|
|
6744
6844
|
if (cached) return cached;
|
|
6745
6845
|
const defaults = { notifications: true };
|
|
6746
6846
|
try {
|
|
6747
|
-
const raw =
|
|
6847
|
+
const raw = readFileSync6(join6(homedir4(), ".solongate", "tui-config.json"), "utf-8");
|
|
6748
6848
|
const j = JSON.parse(raw);
|
|
6749
6849
|
cached = {
|
|
6750
6850
|
notifications: j.notifications !== false,
|
|
@@ -6870,14 +6970,14 @@ var init_components = __esm({
|
|
|
6870
6970
|
});
|
|
6871
6971
|
|
|
6872
6972
|
// src/tui/local-log.ts
|
|
6873
|
-
import { closeSync, openSync as
|
|
6874
|
-
import { homedir as
|
|
6875
|
-
import { join as
|
|
6973
|
+
import { closeSync, openSync as openSync3, readFileSync as readFileSync7, readSync, statSync, writeFileSync as writeFileSync5 } from "fs";
|
|
6974
|
+
import { homedir as homedir5 } from "os";
|
|
6975
|
+
import { join as join7 } from "path";
|
|
6876
6976
|
function tailLines(file, maxBytes = 131072) {
|
|
6877
6977
|
try {
|
|
6878
6978
|
const size = statSync(file).size;
|
|
6879
6979
|
const start = Math.max(0, size - maxBytes);
|
|
6880
|
-
const fd =
|
|
6980
|
+
const fd = openSync3(file, "r");
|
|
6881
6981
|
const buf = Buffer.alloc(size - start);
|
|
6882
6982
|
readSync(fd, buf, 0, buf.length, start);
|
|
6883
6983
|
closeSync(fd);
|
|
@@ -6890,7 +6990,7 @@ function tailLines(file, maxBytes = 131072) {
|
|
|
6890
6990
|
}
|
|
6891
6991
|
function deleteLocalEntry(at, tool, session) {
|
|
6892
6992
|
try {
|
|
6893
|
-
const lines =
|
|
6993
|
+
const lines = readFileSync7(LOCAL_LOG, "utf-8").split("\n");
|
|
6894
6994
|
let removed = 0;
|
|
6895
6995
|
const kept = lines.filter((line) => {
|
|
6896
6996
|
if (!line.trim()) return false;
|
|
@@ -6906,7 +7006,7 @@ function deleteLocalEntry(at, tool, session) {
|
|
|
6906
7006
|
}
|
|
6907
7007
|
return true;
|
|
6908
7008
|
});
|
|
6909
|
-
if (removed)
|
|
7009
|
+
if (removed) writeFileSync5(LOCAL_LOG, kept.length ? kept.join("\n") + "\n" : "");
|
|
6910
7010
|
return removed;
|
|
6911
7011
|
} catch {
|
|
6912
7012
|
return 0;
|
|
@@ -6914,8 +7014,8 @@ function deleteLocalEntry(at, tool, session) {
|
|
|
6914
7014
|
}
|
|
6915
7015
|
function clearLocalLog() {
|
|
6916
7016
|
try {
|
|
6917
|
-
const n =
|
|
6918
|
-
|
|
7017
|
+
const n = readFileSync7(LOCAL_LOG, "utf-8").split("\n").filter(Boolean).length;
|
|
7018
|
+
writeFileSync5(LOCAL_LOG, "");
|
|
6919
7019
|
return n;
|
|
6920
7020
|
} catch {
|
|
6921
7021
|
return 0;
|
|
@@ -6946,20 +7046,20 @@ var LOCAL_LOG, DLP_REASON, RL_REASON;
|
|
|
6946
7046
|
var init_local_log = __esm({
|
|
6947
7047
|
"src/tui/local-log.ts"() {
|
|
6948
7048
|
"use strict";
|
|
6949
|
-
LOCAL_LOG =
|
|
7049
|
+
LOCAL_LOG = join7(homedir5(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
6950
7050
|
DLP_REASON = /security layer \(dlp\)/i;
|
|
6951
7051
|
RL_REASON = /security layer \(rate limit\)|rate[- ]?limit(?:ed)?\b.*exceed|exceeded \d+ calls/i;
|
|
6952
7052
|
}
|
|
6953
7053
|
});
|
|
6954
7054
|
|
|
6955
7055
|
// src/api-client/client.ts
|
|
6956
|
-
import { readFileSync as
|
|
6957
|
-
import { resolve as resolve3, join as
|
|
6958
|
-
import { homedir as
|
|
7056
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync3 } from "fs";
|
|
7057
|
+
import { resolve as resolve3, join as join8 } from "path";
|
|
7058
|
+
import { homedir as homedir6 } from "os";
|
|
6959
7059
|
function listAccounts() {
|
|
6960
7060
|
let list6 = [];
|
|
6961
7061
|
try {
|
|
6962
|
-
const raw = JSON.parse(
|
|
7062
|
+
const raw = JSON.parse(readFileSync8(accountsFile(), "utf-8"));
|
|
6963
7063
|
if (Array.isArray(raw)) list6 = raw.filter((a) => a && typeof a.apiKey === "string");
|
|
6964
7064
|
} catch {
|
|
6965
7065
|
}
|
|
@@ -6973,7 +7073,7 @@ function saveAccount(acc) {
|
|
|
6973
7073
|
try {
|
|
6974
7074
|
const list6 = (() => {
|
|
6975
7075
|
try {
|
|
6976
|
-
const raw = JSON.parse(
|
|
7076
|
+
const raw = JSON.parse(readFileSync8(accountsFile(), "utf-8"));
|
|
6977
7077
|
return Array.isArray(raw) ? raw.filter((a) => a && a.apiKey) : [];
|
|
6978
7078
|
} catch {
|
|
6979
7079
|
return [];
|
|
@@ -6981,8 +7081,8 @@ function saveAccount(acc) {
|
|
|
6981
7081
|
})();
|
|
6982
7082
|
const next = list6.filter((a) => a.apiKey !== acc.apiKey);
|
|
6983
7083
|
next.unshift({ ...acc, addedAt: acc.addedAt ?? Date.now() });
|
|
6984
|
-
|
|
6985
|
-
|
|
7084
|
+
mkdirSync5(join8(homedir6(), ".solongate"), { recursive: true });
|
|
7085
|
+
writeFileSync6(accountsFile(), JSON.stringify(next, null, 2));
|
|
6986
7086
|
} catch {
|
|
6987
7087
|
}
|
|
6988
7088
|
}
|
|
@@ -6995,15 +7095,15 @@ function isActiveAccount(apiKey) {
|
|
|
6995
7095
|
}
|
|
6996
7096
|
function setActiveAccount(creds) {
|
|
6997
7097
|
try {
|
|
6998
|
-
const dir =
|
|
6999
|
-
|
|
7000
|
-
const p =
|
|
7098
|
+
const dir = join8(homedir6(), ".solongate");
|
|
7099
|
+
mkdirSync5(dir, { recursive: true });
|
|
7100
|
+
const p = join8(dir, ["cloud", "guard.json"].join("-"));
|
|
7001
7101
|
let existing = {};
|
|
7002
7102
|
try {
|
|
7003
|
-
existing = JSON.parse(
|
|
7103
|
+
existing = JSON.parse(readFileSync8(p, "utf-8"));
|
|
7004
7104
|
} catch {
|
|
7005
7105
|
}
|
|
7006
|
-
|
|
7106
|
+
writeFileSync6(p, JSON.stringify({ ...existing, apiKey: creds.apiKey, apiUrl: creds.apiUrl }, null, 2));
|
|
7007
7107
|
cached2 = null;
|
|
7008
7108
|
return true;
|
|
7009
7109
|
} catch {
|
|
@@ -7012,9 +7112,9 @@ function setActiveAccount(creds) {
|
|
|
7012
7112
|
}
|
|
7013
7113
|
function loginCredentialFile() {
|
|
7014
7114
|
try {
|
|
7015
|
-
const p =
|
|
7115
|
+
const p = join8(homedir6(), ".solongate", "cloud-guard.json");
|
|
7016
7116
|
if (!existsSync3(p)) return {};
|
|
7017
|
-
const c2 = JSON.parse(
|
|
7117
|
+
const c2 = JSON.parse(readFileSync8(p, "utf-8"));
|
|
7018
7118
|
return c2 && typeof c2 === "object" ? c2 : {};
|
|
7019
7119
|
} catch {
|
|
7020
7120
|
return {};
|
|
@@ -7024,7 +7124,7 @@ function dotenvApiKey() {
|
|
|
7024
7124
|
try {
|
|
7025
7125
|
const envPath = resolve3(".env");
|
|
7026
7126
|
if (!existsSync3(envPath)) return void 0;
|
|
7027
|
-
for (const line of
|
|
7127
|
+
for (const line of readFileSync8(envPath, "utf-8").split("\n")) {
|
|
7028
7128
|
const trimmed = line.trim();
|
|
7029
7129
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
7030
7130
|
const eq = trimmed.indexOf("=");
|
|
@@ -7126,7 +7226,7 @@ var init_client = __esm({
|
|
|
7126
7226
|
"src/api-client/client.ts"() {
|
|
7127
7227
|
"use strict";
|
|
7128
7228
|
DEFAULT_API_URL2 = "https://api.solongate.com";
|
|
7129
|
-
accountsFile = () =>
|
|
7229
|
+
accountsFile = () => join8(homedir6(), ".solongate", "accounts.json");
|
|
7130
7230
|
viewOverride = null;
|
|
7131
7231
|
ApiError = class extends Error {
|
|
7132
7232
|
status;
|
|
@@ -7156,12 +7256,12 @@ var init_types = __esm({
|
|
|
7156
7256
|
});
|
|
7157
7257
|
|
|
7158
7258
|
// src/api-client/device-login.ts
|
|
7159
|
-
import { spawn as
|
|
7259
|
+
import { spawn as spawn3 } from "child_process";
|
|
7160
7260
|
function openBrowser(url) {
|
|
7161
7261
|
try {
|
|
7162
7262
|
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
7163
7263
|
const args = process.platform === "win32" ? ["/c", "start", '""', url] : [url];
|
|
7164
|
-
const child =
|
|
7264
|
+
const child = spawn3(cmd, args, { stdio: "ignore", detached: true });
|
|
7165
7265
|
child.on("error", () => {
|
|
7166
7266
|
});
|
|
7167
7267
|
child.unref();
|
|
@@ -7502,24 +7602,24 @@ var init_api_client = __esm({
|
|
|
7502
7602
|
});
|
|
7503
7603
|
|
|
7504
7604
|
// src/tui/notify.ts
|
|
7505
|
-
import { spawn as
|
|
7605
|
+
import { spawn as spawn4 } from "child_process";
|
|
7506
7606
|
function desktopNotify(title, msg) {
|
|
7507
7607
|
try {
|
|
7508
7608
|
if (process.platform === "linux") {
|
|
7509
|
-
const p =
|
|
7609
|
+
const p = spawn4("notify-send", ["-a", "SolonGate", title, msg], { stdio: "ignore", detached: true });
|
|
7510
7610
|
p.on("error", () => {
|
|
7511
7611
|
});
|
|
7512
7612
|
p.unref();
|
|
7513
7613
|
} else if (process.platform === "win32") {
|
|
7514
7614
|
const q = (s) => s.replace(/'/g, "''");
|
|
7515
7615
|
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()`;
|
|
7516
|
-
const p =
|
|
7616
|
+
const p = spawn4("powershell", ["-NoProfile", "-NonInteractive", "-Command", ps], { stdio: "ignore", detached: true, windowsHide: true });
|
|
7517
7617
|
p.on("error", () => {
|
|
7518
7618
|
});
|
|
7519
7619
|
p.unref();
|
|
7520
7620
|
} else if (process.platform === "darwin") {
|
|
7521
7621
|
const esc = (s) => s.replace(/"/g, '\\"');
|
|
7522
|
-
const p =
|
|
7622
|
+
const p = spawn4("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
|
|
7523
7623
|
p.on("error", () => {
|
|
7524
7624
|
});
|
|
7525
7625
|
p.unref();
|
|
@@ -7605,9 +7705,9 @@ var init_hooks = __esm({
|
|
|
7605
7705
|
// src/tui/panels/Live.tsx
|
|
7606
7706
|
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
7607
7707
|
import TextInput from "ink-text-input";
|
|
7608
|
-
import { mkdirSync as
|
|
7609
|
-
import { homedir as
|
|
7610
|
-
import { join as
|
|
7708
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
7709
|
+
import { homedir as homedir7 } from "os";
|
|
7710
|
+
import { join as join9 } from "path";
|
|
7611
7711
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
7612
7712
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
7613
7713
|
function extractTarget(detail) {
|
|
@@ -8198,10 +8298,10 @@ function LivePanel({ active: active2 }) {
|
|
|
8198
8298
|
else if (input === "x") toggleSignal("dlp");
|
|
8199
8299
|
else if (input === "r") toggleSignal("ratelimit");
|
|
8200
8300
|
else if (input === "e") {
|
|
8201
|
-
const file =
|
|
8301
|
+
const file = join9(homedir7(), ".solongate", "live-export.jsonl");
|
|
8202
8302
|
try {
|
|
8203
|
-
|
|
8204
|
-
|
|
8303
|
+
mkdirSync6(join9(homedir7(), ".solongate"), { recursive: true });
|
|
8304
|
+
writeFileSync7(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
|
|
8205
8305
|
setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
|
|
8206
8306
|
} catch (err2) {
|
|
8207
8307
|
setActionMsg({ text: "\u2717 export failed: " + (err2 instanceof Error ? err2.message : String(err2)), level: "bad", until: Date.now() + 6e3 });
|
|
@@ -8611,7 +8711,7 @@ var init_Live = __esm({
|
|
|
8611
8711
|
SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
8612
8712
|
BG = "#12234f";
|
|
8613
8713
|
DIM_FLOOR = "#233457";
|
|
8614
|
-
RING =
|
|
8714
|
+
RING = join9(process.cwd(), ".solongate", ".eval-ring.jsonl");
|
|
8615
8715
|
hhmmss = (ts) => {
|
|
8616
8716
|
const d = new Date(ts);
|
|
8617
8717
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
@@ -9301,9 +9401,9 @@ var init_Dlp = __esm({
|
|
|
9301
9401
|
// src/tui/panels/Audit.tsx
|
|
9302
9402
|
import { Box as Box6, Text as Text6, useInput as useInput5 } from "ink";
|
|
9303
9403
|
import TextInput4 from "ink-text-input";
|
|
9304
|
-
import { mkdirSync as
|
|
9305
|
-
import { homedir as
|
|
9306
|
-
import { join as
|
|
9404
|
+
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync8 } from "fs";
|
|
9405
|
+
import { homedir as homedir8 } from "os";
|
|
9406
|
+
import { join as join10 } from "path";
|
|
9307
9407
|
import { useState as useState6 } from "react";
|
|
9308
9408
|
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
9309
9409
|
function loadLocalRows() {
|
|
@@ -9457,16 +9557,16 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9457
9557
|
const doExport = (kind) => {
|
|
9458
9558
|
setMsg({ text: "exporting\u2026", level: "ok" });
|
|
9459
9559
|
const run12 = async () => {
|
|
9460
|
-
const dir =
|
|
9461
|
-
const file =
|
|
9560
|
+
const dir = join10(homedir8(), ".solongate");
|
|
9561
|
+
const file = join10(dir, `audit-export-${source}.jsonl`);
|
|
9462
9562
|
let rows2;
|
|
9463
9563
|
if (kind === "page") rows2 = pageRows;
|
|
9464
9564
|
else if (source === "cloud") {
|
|
9465
9565
|
const r = await api.audit.list({ ...query, limit: 1e4, offset: 0 });
|
|
9466
9566
|
rows2 = r.entries.map(cloudRow).sort((a, b) => b.at - a.at);
|
|
9467
9567
|
} else rows2 = localFiltered;
|
|
9468
|
-
|
|
9469
|
-
|
|
9568
|
+
mkdirSync7(dir, { recursive: true });
|
|
9569
|
+
writeFileSync8(file, rows2.map((x) => JSON.stringify(x)).join("\n") + (rows2.length ? "\n" : ""));
|
|
9470
9570
|
return { n: rows2.length, file };
|
|
9471
9571
|
};
|
|
9472
9572
|
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" }));
|
|
@@ -9985,6 +10085,11 @@ function SettingsPanel({
|
|
|
9985
10085
|
const abort = useRef3(false);
|
|
9986
10086
|
const refreshAccounts = () => setAccounts(listAccounts());
|
|
9987
10087
|
const locked = accounts.length === 0;
|
|
10088
|
+
const [srv, setSrv] = useState7(() => logsServerStatus());
|
|
10089
|
+
useEffect6(() => {
|
|
10090
|
+
const t = setInterval(() => setSrv(logsServerStatus()), 3e3);
|
|
10091
|
+
return () => clearInterval(t);
|
|
10092
|
+
}, []);
|
|
9988
10093
|
useEffect6(() => {
|
|
9989
10094
|
if (!login || login.phase === "done" || login.phase === "error") return;
|
|
9990
10095
|
const t = setInterval(() => setTick((n) => n + 1), 120);
|
|
@@ -10002,6 +10107,7 @@ function SettingsPanel({
|
|
|
10002
10107
|
...locked ? [] : [
|
|
10003
10108
|
{ kind: "ll-enabled" },
|
|
10004
10109
|
{ kind: "ll-path" },
|
|
10110
|
+
{ kind: "ll-server" },
|
|
10005
10111
|
...webhooks.map((wh) => ({ kind: "wh", wh })),
|
|
10006
10112
|
{ kind: "wh-add" },
|
|
10007
10113
|
...alerts.map((rule) => ({ kind: "alert", rule })),
|
|
@@ -10077,6 +10183,12 @@ function SettingsPanel({
|
|
|
10077
10183
|
} else if (r.kind === "ll-path") {
|
|
10078
10184
|
setInput(local?.path ?? "");
|
|
10079
10185
|
setEditing("path");
|
|
10186
|
+
} else if (r.kind === "ll-server") {
|
|
10187
|
+
const next = srv.running ? stopLogsServerDaemon() : startLogsServerDaemon();
|
|
10188
|
+
setSrv(next);
|
|
10189
|
+
setMsg(
|
|
10190
|
+
next.running ? { text: `\u2713 dashboard link running on 127.0.0.1:${next.port} \u2014 keeps running after you close the dataroom`, level: "ok" } : { text: "\u2713 dashboard link stopped (disabled until you start it again)", level: "ok" }
|
|
10191
|
+
);
|
|
10080
10192
|
} else if (r.kind === "wh") {
|
|
10081
10193
|
run12(r.wh.enabled ? "webhook disabled" : "webhook enabled", () => api.settings.updateWebhook(r.wh.id, { enabled: !r.wh.enabled }), whQ.reload);
|
|
10082
10194
|
} else if (r.kind === "wh-add") {
|
|
@@ -10220,7 +10332,7 @@ function SettingsPanel({
|
|
|
10220
10332
|
] }) : null
|
|
10221
10333
|
] }),
|
|
10222
10334
|
locked ? null : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
10223
|
-
inWindow({ kind: "ll-enabled" }) || inWindow({ kind: "ll-path" }) ? /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10335
|
+
inWindow({ kind: "ll-enabled" }) || inWindow({ kind: "ll-path" }) || inWindow({ kind: "ll-server" }) ? /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10224
10336
|
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accentBright, children: [
|
|
10225
10337
|
"LOCAL LOGS ",
|
|
10226
10338
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "\u2014 hooks mirror every decision to a file on the agent machine" })
|
|
@@ -10235,6 +10347,12 @@ function SettingsPanel({
|
|
|
10235
10347
|
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "ll-path" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "ll-path" }) }),
|
|
10236
10348
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "path ".padEnd(10) }),
|
|
10237
10349
|
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" })
|
|
10350
|
+
] }),
|
|
10351
|
+
/* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10352
|
+
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "ll-server" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "ll-server" }) }),
|
|
10353
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "dashboard".padEnd(10) }),
|
|
10354
|
+
srv.running ? /* @__PURE__ */ jsx7(Text7, { color: theme.ok, children: `running 127.0.0.1:${srv.port}` }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "stopped" }),
|
|
10355
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: srv.running ? " serves local logs to the dashboard \xB7 survives closing the dataroom \xB7 enter stops" : " enter starts the local-logs link for the dashboard" })
|
|
10238
10356
|
] })
|
|
10239
10357
|
] }) : null,
|
|
10240
10358
|
/* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
@@ -10288,6 +10406,7 @@ var init_Settings = __esm({
|
|
|
10288
10406
|
init_api_client();
|
|
10289
10407
|
init_client();
|
|
10290
10408
|
init_device_login();
|
|
10409
|
+
init_logs_server_daemon();
|
|
10291
10410
|
init_components();
|
|
10292
10411
|
init_hooks();
|
|
10293
10412
|
init_theme();
|
|
@@ -10486,9 +10605,9 @@ var tui_exports = {};
|
|
|
10486
10605
|
__export(tui_exports, {
|
|
10487
10606
|
launchTui: () => launchTui
|
|
10488
10607
|
});
|
|
10489
|
-
import { appendFileSync as appendFileSync2, mkdirSync as
|
|
10490
|
-
import { homedir as
|
|
10491
|
-
import { join as
|
|
10608
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync8 } from "fs";
|
|
10609
|
+
import { homedir as homedir9 } from "os";
|
|
10610
|
+
import { join as join11 } from "path";
|
|
10492
10611
|
import { render } from "ink";
|
|
10493
10612
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
10494
10613
|
async function launchTui() {
|
|
@@ -10499,11 +10618,11 @@ async function launchTui() {
|
|
|
10499
10618
|
return;
|
|
10500
10619
|
}
|
|
10501
10620
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
10502
|
-
const debugLog =
|
|
10621
|
+
const debugLog = join11(homedir9(), ".solongate", "dataroom-debug.log");
|
|
10503
10622
|
const saved = { log: console.log, warn: console.warn, error: console.error, info: console.info, debug: console.debug };
|
|
10504
10623
|
const toFile = (level) => (...args) => {
|
|
10505
10624
|
try {
|
|
10506
|
-
|
|
10625
|
+
mkdirSync8(join11(homedir9(), ".solongate"), { recursive: true });
|
|
10507
10626
|
appendFileSync2(debugLog, `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
|
|
10508
10627
|
`);
|
|
10509
10628
|
} catch {
|
|
@@ -10627,7 +10746,7 @@ var init_args = __esm({
|
|
|
10627
10746
|
});
|
|
10628
10747
|
|
|
10629
10748
|
// src/commands/policy.ts
|
|
10630
|
-
import { readFileSync as
|
|
10749
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
10631
10750
|
async function run(argv) {
|
|
10632
10751
|
const { positionals, flags } = parse(argv);
|
|
10633
10752
|
const sub = positionals[0];
|
|
@@ -10802,7 +10921,7 @@ function printRules(rules) {
|
|
|
10802
10921
|
}
|
|
10803
10922
|
async function resolveRules(target) {
|
|
10804
10923
|
if (target.endsWith(".json")) {
|
|
10805
|
-
const parsed = JSON.parse(
|
|
10924
|
+
const parsed = JSON.parse(readFileSync9(target, "utf-8"));
|
|
10806
10925
|
return parsed.rules ?? [];
|
|
10807
10926
|
}
|
|
10808
10927
|
const p = await api.policies.get(target);
|
|
@@ -11218,8 +11337,8 @@ var init_agents2 = __esm({
|
|
|
11218
11337
|
|
|
11219
11338
|
// src/commands/doctor.ts
|
|
11220
11339
|
import { existsSync as existsSync4, statSync as statSync2 } from "fs";
|
|
11221
|
-
import { homedir as
|
|
11222
|
-
import { join as
|
|
11340
|
+
import { homedir as homedir10 } from "os";
|
|
11341
|
+
import { join as join12 } from "path";
|
|
11223
11342
|
async function run6(argv) {
|
|
11224
11343
|
const { flags } = parse(argv);
|
|
11225
11344
|
const json = flagBool(flags, "json");
|
|
@@ -11279,19 +11398,19 @@ var init_doctor = __esm({
|
|
|
11279
11398
|
init_api_client();
|
|
11280
11399
|
init_format();
|
|
11281
11400
|
init_args();
|
|
11282
|
-
LOCAL_LOG2 =
|
|
11401
|
+
LOCAL_LOG2 = join12(homedir10(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
11283
11402
|
}
|
|
11284
11403
|
});
|
|
11285
11404
|
|
|
11286
11405
|
// src/commands/watch.ts
|
|
11287
|
-
import { closeSync as closeSync2, existsSync as existsSync5, openSync as
|
|
11288
|
-
import { homedir as
|
|
11289
|
-
import { join as
|
|
11406
|
+
import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync4, readSync as readSync2, statSync as statSync3 } from "fs";
|
|
11407
|
+
import { homedir as homedir11 } from "os";
|
|
11408
|
+
import { join as join13 } from "path";
|
|
11290
11409
|
function tailLocal(file, maxBytes = 131072) {
|
|
11291
11410
|
try {
|
|
11292
11411
|
const size = statSync3(file).size;
|
|
11293
11412
|
const start = Math.max(0, size - maxBytes);
|
|
11294
|
-
const fd =
|
|
11413
|
+
const fd = openSync4(file, "r");
|
|
11295
11414
|
const buf = Buffer.alloc(size - start);
|
|
11296
11415
|
readSync2(fd, buf, 0, buf.length, start);
|
|
11297
11416
|
closeSync2(fd);
|
|
@@ -11393,7 +11512,7 @@ var init_watch = __esm({
|
|
|
11393
11512
|
init_cli_utils();
|
|
11394
11513
|
init_args();
|
|
11395
11514
|
init_format();
|
|
11396
|
-
LOCAL_LOG3 =
|
|
11515
|
+
LOCAL_LOG3 = join13(homedir11(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
11397
11516
|
trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
11398
11517
|
time = (ms) => new Date(ms).toTimeString().slice(0, 8);
|
|
11399
11518
|
}
|
|
@@ -11684,10 +11803,10 @@ var init_commands = __esm({
|
|
|
11684
11803
|
});
|
|
11685
11804
|
|
|
11686
11805
|
// src/global-install.ts
|
|
11687
|
-
import { readFileSync as
|
|
11688
|
-
import { resolve as resolve4, join as
|
|
11689
|
-
import { homedir as
|
|
11690
|
-
import { fileURLToPath as
|
|
11806
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync9, existsSync as existsSync6, mkdirSync as mkdirSync9 } from "fs";
|
|
11807
|
+
import { resolve as resolve4, join as join14, dirname as dirname3 } from "path";
|
|
11808
|
+
import { homedir as homedir12 } from "os";
|
|
11809
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
11691
11810
|
import { createInterface } from "readline";
|
|
11692
11811
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
11693
11812
|
function lockFile(file) {
|
|
@@ -11749,10 +11868,10 @@ function unlockFile(file) {
|
|
|
11749
11868
|
function protectedTargets() {
|
|
11750
11869
|
const p = globalPaths();
|
|
11751
11870
|
return [
|
|
11752
|
-
|
|
11753
|
-
|
|
11754
|
-
|
|
11755
|
-
|
|
11871
|
+
join14(p.hooksDir, "guard.mjs"),
|
|
11872
|
+
join14(p.hooksDir, "audit.mjs"),
|
|
11873
|
+
join14(p.hooksDir, "stop.mjs"),
|
|
11874
|
+
join14(p.hooksDir, "shield.mjs"),
|
|
11756
11875
|
p.configPath,
|
|
11757
11876
|
p.settingsPath
|
|
11758
11877
|
];
|
|
@@ -11764,26 +11883,26 @@ function unlockProtected() {
|
|
|
11764
11883
|
for (const f of protectedTargets()) unlockFile(f);
|
|
11765
11884
|
}
|
|
11766
11885
|
function globalPaths() {
|
|
11767
|
-
const home =
|
|
11768
|
-
const sgDir =
|
|
11769
|
-
const hooksDir =
|
|
11770
|
-
const claudeDir =
|
|
11886
|
+
const home = homedir12();
|
|
11887
|
+
const sgDir = join14(home, ".solongate");
|
|
11888
|
+
const hooksDir = join14(sgDir, "hooks");
|
|
11889
|
+
const claudeDir = join14(home, ".claude");
|
|
11771
11890
|
return {
|
|
11772
11891
|
home,
|
|
11773
11892
|
sgDir,
|
|
11774
11893
|
hooksDir,
|
|
11775
11894
|
claudeDir,
|
|
11776
|
-
settingsPath:
|
|
11777
|
-
backupPath:
|
|
11778
|
-
configPath:
|
|
11895
|
+
settingsPath: join14(claudeDir, "settings.json"),
|
|
11896
|
+
backupPath: join14(claudeDir, "settings.solongate.bak"),
|
|
11897
|
+
configPath: join14(sgDir, "cloud-guard.json")
|
|
11779
11898
|
};
|
|
11780
11899
|
}
|
|
11781
11900
|
function readHook(filename) {
|
|
11782
|
-
return
|
|
11901
|
+
return readFileSync10(join14(HOOKS_DIR, filename), "utf-8");
|
|
11783
11902
|
}
|
|
11784
11903
|
function readGuard() {
|
|
11785
|
-
const bundled =
|
|
11786
|
-
return existsSync6(bundled) ?
|
|
11904
|
+
const bundled = join14(HOOKS_DIR, "guard.bundled.mjs");
|
|
11905
|
+
return existsSync6(bundled) ? readFileSync10(bundled, "utf-8") : readHook("guard.mjs");
|
|
11787
11906
|
}
|
|
11788
11907
|
function ask(question) {
|
|
11789
11908
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -11817,18 +11936,18 @@ function shimTargets() {
|
|
|
11817
11936
|
return [];
|
|
11818
11937
|
}
|
|
11819
11938
|
}
|
|
11820
|
-
return [".bashrc", ".zshrc", ".profile"].map((f) =>
|
|
11939
|
+
return [".bashrc", ".zshrc", ".profile"].map((f) => join14(homedir12(), f)).filter((f) => existsSync6(f));
|
|
11821
11940
|
}
|
|
11822
11941
|
function writeShimBlock(file, block2) {
|
|
11823
11942
|
const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
|
|
11824
|
-
let content = existsSync6(file) ?
|
|
11943
|
+
let content = existsSync6(file) ? readFileSync10(file, "utf-8") : "";
|
|
11825
11944
|
content = content.replace(re, "");
|
|
11826
11945
|
if (block2) {
|
|
11827
11946
|
if (content.length && !content.endsWith("\n")) content += "\n";
|
|
11828
11947
|
content += block2 + "\n";
|
|
11829
11948
|
}
|
|
11830
|
-
|
|
11831
|
-
|
|
11949
|
+
mkdirSync9(dirname3(file), { recursive: true });
|
|
11950
|
+
writeFileSync9(file, content);
|
|
11832
11951
|
}
|
|
11833
11952
|
function installClaudeShim(shieldPath) {
|
|
11834
11953
|
const real = resolveRealClaude();
|
|
@@ -11858,7 +11977,7 @@ async function runGlobalInstall2(opts = {}) {
|
|
|
11858
11977
|
let apiKey = opts.apiKey || process.env["SOLONGATE_API_KEY"] || "";
|
|
11859
11978
|
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
11860
11979
|
try {
|
|
11861
|
-
const cfg = JSON.parse(
|
|
11980
|
+
const cfg = JSON.parse(readFileSync10(p.configPath, "utf-8"));
|
|
11862
11981
|
if (cfg && typeof cfg.apiKey === "string") apiKey = cfg.apiKey;
|
|
11863
11982
|
} catch {
|
|
11864
11983
|
}
|
|
@@ -11871,22 +11990,22 @@ async function runGlobalInstall2(opts = {}) {
|
|
|
11871
11990
|
process.exit(1);
|
|
11872
11991
|
}
|
|
11873
11992
|
const apiUrl = opts.apiUrl || process.env["SOLONGATE_API_URL"] || "https://api.solongate.com";
|
|
11874
|
-
|
|
11875
|
-
|
|
11993
|
+
mkdirSync9(p.hooksDir, { recursive: true });
|
|
11994
|
+
mkdirSync9(p.claudeDir, { recursive: true });
|
|
11876
11995
|
unlockProtected();
|
|
11877
|
-
|
|
11878
|
-
|
|
11879
|
-
|
|
11880
|
-
|
|
11996
|
+
writeFileSync9(join14(p.hooksDir, "guard.mjs"), readGuard());
|
|
11997
|
+
writeFileSync9(join14(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
|
|
11998
|
+
writeFileSync9(join14(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
|
|
11999
|
+
writeFileSync9(join14(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
|
|
11881
12000
|
console.log(` Installed hooks \u2192 ${p.hooksDir}`);
|
|
11882
|
-
installClaudeShim(
|
|
11883
|
-
|
|
12001
|
+
installClaudeShim(join14(p.hooksDir, "shield.mjs"));
|
|
12002
|
+
writeFileSync9(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
|
|
11884
12003
|
console.log(` Wrote ${p.configPath}`);
|
|
11885
12004
|
let existing = {};
|
|
11886
12005
|
if (existsSync6(p.settingsPath)) {
|
|
11887
|
-
const raw =
|
|
12006
|
+
const raw = readFileSync10(p.settingsPath, "utf-8");
|
|
11888
12007
|
if (!existsSync6(p.backupPath)) {
|
|
11889
|
-
|
|
12008
|
+
writeFileSync9(p.backupPath, raw);
|
|
11890
12009
|
console.log(` Backed up existing settings \u2192 ${p.backupPath}`);
|
|
11891
12010
|
}
|
|
11892
12011
|
try {
|
|
@@ -11895,9 +12014,9 @@ async function runGlobalInstall2(opts = {}) {
|
|
|
11895
12014
|
existing = {};
|
|
11896
12015
|
}
|
|
11897
12016
|
}
|
|
11898
|
-
const guardAbs =
|
|
11899
|
-
const auditAbs =
|
|
11900
|
-
const stopAbs =
|
|
12017
|
+
const guardAbs = join14(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
|
|
12018
|
+
const auditAbs = join14(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
|
|
12019
|
+
const stopAbs = join14(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
|
|
11901
12020
|
const nodeBin = process.execPath.replace(/\\/g, "/");
|
|
11902
12021
|
const call = process.platform === "win32" ? "& " : "";
|
|
11903
12022
|
const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
|
|
@@ -11909,7 +12028,7 @@ async function runGlobalInstall2(opts = {}) {
|
|
|
11909
12028
|
Stop: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(stopAbs) }] }]
|
|
11910
12029
|
}
|
|
11911
12030
|
};
|
|
11912
|
-
|
|
12031
|
+
writeFileSync9(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
11913
12032
|
console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
|
|
11914
12033
|
if (process.env["SOLONGATE_OS_LOCK"] === "1") {
|
|
11915
12034
|
lockProtected();
|
|
@@ -11920,7 +12039,7 @@ var __dirname, HOOKS_DIR, SHIM_BEGIN, SHIM_END;
|
|
|
11920
12039
|
var init_global_install = __esm({
|
|
11921
12040
|
"src/global-install.ts"() {
|
|
11922
12041
|
"use strict";
|
|
11923
|
-
__dirname =
|
|
12042
|
+
__dirname = dirname3(fileURLToPath3(import.meta.url));
|
|
11924
12043
|
HOOKS_DIR = resolve4(__dirname, "..", "hooks");
|
|
11925
12044
|
SHIM_BEGIN = "# >>> SolonGate shield (auto secret redaction) >>>";
|
|
11926
12045
|
SHIM_END = "# <<< SolonGate shield <<<";
|
|
@@ -11929,7 +12048,7 @@ var init_global_install = __esm({
|
|
|
11929
12048
|
|
|
11930
12049
|
// src/login.ts
|
|
11931
12050
|
var login_exports = {};
|
|
11932
|
-
import { spawn as
|
|
12051
|
+
import { spawn as spawn5 } from "child_process";
|
|
11933
12052
|
function startSpinner(text) {
|
|
11934
12053
|
if (!process.stderr.isTTY) {
|
|
11935
12054
|
process.stderr.write(` ${text}
|
|
@@ -11965,7 +12084,7 @@ function openBrowser2(url) {
|
|
|
11965
12084
|
try {
|
|
11966
12085
|
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
11967
12086
|
const args = process.platform === "win32" ? ["/c", "start", '""', url] : [url];
|
|
11968
|
-
const child =
|
|
12087
|
+
const child = spawn5(cmd, args, { stdio: "ignore", detached: true });
|
|
11969
12088
|
child.on("error", () => {
|
|
11970
12089
|
});
|
|
11971
12090
|
child.unref();
|
|
@@ -12085,13 +12204,13 @@ __export(shield_exports, {
|
|
|
12085
12204
|
});
|
|
12086
12205
|
import { createServer, request as httpRequest } from "http";
|
|
12087
12206
|
import { request as httpsRequest } from "https";
|
|
12088
|
-
import { spawn as
|
|
12207
|
+
import { spawn as spawn6 } from "child_process";
|
|
12089
12208
|
import { URL as URL2 } from "url";
|
|
12090
|
-
import { readFileSync as
|
|
12209
|
+
import { readFileSync as readFileSync11, existsSync as existsSync7, readdirSync, statSync as statSync4 } from "fs";
|
|
12091
12210
|
import { resolve as resolve5 } from "path";
|
|
12092
|
-
import { homedir as
|
|
12211
|
+
import { homedir as homedir13 } from "os";
|
|
12093
12212
|
function findCacheFile() {
|
|
12094
|
-
const dir = resolve5(
|
|
12213
|
+
const dir = resolve5(homedir13(), ".solongate");
|
|
12095
12214
|
const envSel = process.env.SOLONGATE_AGENT_ID;
|
|
12096
12215
|
if (envSel) {
|
|
12097
12216
|
const f = resolve5(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
|
|
@@ -12117,7 +12236,7 @@ function loadCfg() {
|
|
|
12117
12236
|
try {
|
|
12118
12237
|
const f = findCacheFile();
|
|
12119
12238
|
if (f && existsSync7(f)) {
|
|
12120
|
-
const c2 = JSON.parse(
|
|
12239
|
+
const c2 = JSON.parse(readFileSync11(f, "utf-8"));
|
|
12121
12240
|
const d = c2?.security?.dlpRedact;
|
|
12122
12241
|
const g = c2?.security?.ghost;
|
|
12123
12242
|
const ghost = g && Array.isArray(g.patterns) ? g.patterns : [];
|
|
@@ -12345,7 +12464,7 @@ async function runShield() {
|
|
|
12345
12464
|
const upstream = pickUpstream();
|
|
12346
12465
|
const { port, close } = await startProxy(upstream);
|
|
12347
12466
|
log4(`redacting secrets on the LLM path \u2192 masking before ${upstream.host} (127.0.0.1:${port})`);
|
|
12348
|
-
const child =
|
|
12467
|
+
const child = spawn6(cmd[0], cmd.slice(1), {
|
|
12349
12468
|
stdio: "inherit",
|
|
12350
12469
|
env: { ...process.env, ANTHROPIC_BASE_URL: `http://127.0.0.1:${port}` },
|
|
12351
12470
|
shell: process.platform === "win32"
|
|
@@ -12405,9 +12524,9 @@ __export(logs_server_exports, {
|
|
|
12405
12524
|
runLogsServer: () => runLogsServer
|
|
12406
12525
|
});
|
|
12407
12526
|
import { createServer as createServer2 } from "http";
|
|
12408
|
-
import { readFileSync as
|
|
12409
|
-
import { resolve as resolve6, join as
|
|
12410
|
-
import { homedir as
|
|
12527
|
+
import { readFileSync as readFileSync12, statSync as statSync5 } from "fs";
|
|
12528
|
+
import { resolve as resolve6, join as join15, isAbsolute } from "path";
|
|
12529
|
+
import { homedir as homedir14 } from "os";
|
|
12411
12530
|
import { readdirSync as readdirSync2 } from "fs";
|
|
12412
12531
|
function allowedOrigins() {
|
|
12413
12532
|
const base = [
|
|
@@ -12424,15 +12543,15 @@ function resolveLocalLogDir(rawPath) {
|
|
|
12424
12543
|
const dir = String(rawPath || "").trim().replace(/[\\/]+$/, "");
|
|
12425
12544
|
if (!dir) return null;
|
|
12426
12545
|
if (isAbsolute(dir)) return dir;
|
|
12427
|
-
return resolve6(
|
|
12546
|
+
return resolve6(homedir14(), ".solongate", "local-logs");
|
|
12428
12547
|
}
|
|
12429
12548
|
async function findLogDir() {
|
|
12430
|
-
const base = resolve6(
|
|
12549
|
+
const base = resolve6(homedir14(), ".solongate");
|
|
12431
12550
|
try {
|
|
12432
12551
|
const files = readdirSync2(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
|
|
12433
12552
|
for (const f of files) {
|
|
12434
12553
|
try {
|
|
12435
|
-
const c2 = JSON.parse(
|
|
12554
|
+
const c2 = JSON.parse(readFileSync12(join15(base, f), "utf-8"));
|
|
12436
12555
|
const p = c2?.security?.localLogs?.path;
|
|
12437
12556
|
if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
|
|
12438
12557
|
} catch {
|
|
@@ -12441,7 +12560,7 @@ async function findLogDir() {
|
|
|
12441
12560
|
} catch {
|
|
12442
12561
|
}
|
|
12443
12562
|
try {
|
|
12444
|
-
const cfgRaw =
|
|
12563
|
+
const cfgRaw = readFileSync12(join15(base, "cloud-guard.json"), "utf-8");
|
|
12445
12564
|
const { apiKey, apiUrl } = JSON.parse(cfgRaw);
|
|
12446
12565
|
if (apiKey) {
|
|
12447
12566
|
const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
|
|
@@ -12470,7 +12589,7 @@ function setCors(req, res) {
|
|
|
12470
12589
|
}
|
|
12471
12590
|
function fileInfo(dir) {
|
|
12472
12591
|
if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
|
|
12473
|
-
const file =
|
|
12592
|
+
const file = join15(dir, LOG_FILENAME);
|
|
12474
12593
|
try {
|
|
12475
12594
|
const st = statSync5(file);
|
|
12476
12595
|
return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
|
|
@@ -12480,6 +12599,28 @@ function fileInfo(dir) {
|
|
|
12480
12599
|
}
|
|
12481
12600
|
async function runLogsServer() {
|
|
12482
12601
|
const argv = process.argv.slice(3);
|
|
12602
|
+
const verb = argv[0];
|
|
12603
|
+
if (verb === "start" || verb === "stop" || verb === "status") {
|
|
12604
|
+
const d = await Promise.resolve().then(() => (init_logs_server_daemon(), logs_server_daemon_exports));
|
|
12605
|
+
if (verb === "start") {
|
|
12606
|
+
d.startLogsServerDaemon();
|
|
12607
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
12608
|
+
const st = d.logsServerStatus();
|
|
12609
|
+
process.stdout.write(
|
|
12610
|
+
st.running ? `[SolonGate] Local logs service running on http://127.0.0.1:${st.port} \u2014 background service, survives closing this terminal. Disable: solongate logs-server stop
|
|
12611
|
+
` : `[SolonGate] Could not start the local logs service \u2014 see ~/.solongate/logs-server.log
|
|
12612
|
+
`
|
|
12613
|
+
);
|
|
12614
|
+
} else if (verb === "stop") {
|
|
12615
|
+
d.stopLogsServerDaemon();
|
|
12616
|
+
process.stdout.write("[SolonGate] Local logs service stopped and disabled (re-enable from the dataroom Settings or with `solongate logs-server start`).\n");
|
|
12617
|
+
} else {
|
|
12618
|
+
const st = d.logsServerStatus();
|
|
12619
|
+
process.stdout.write(`[SolonGate] Local logs service: ${st.running ? `running on http://127.0.0.1:${st.port} (pid ${st.pid})` : "stopped"} \xB7 desired ${st.desired}
|
|
12620
|
+
`);
|
|
12621
|
+
}
|
|
12622
|
+
return;
|
|
12623
|
+
}
|
|
12483
12624
|
const portArg = argv[argv.indexOf("--port") + 1];
|
|
12484
12625
|
const port = Number(process.env.SOLONGATE_LOGS_PORT || (argv.includes("--port") ? portArg : "") || DEFAULT_PORT) || DEFAULT_PORT;
|
|
12485
12626
|
const server = createServer2(async (req, res) => {
|
|
@@ -12531,7 +12672,7 @@ async function runLogsServer() {
|
|
|
12531
12672
|
return;
|
|
12532
12673
|
}
|
|
12533
12674
|
try {
|
|
12534
|
-
const text =
|
|
12675
|
+
const text = readFileSync12(info.file, "utf-8");
|
|
12535
12676
|
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8", "Last-Modified": lastMod, "X-Solongate-Exists": "1" });
|
|
12536
12677
|
res.end(text);
|
|
12537
12678
|
} catch {
|
|
@@ -12544,6 +12685,8 @@ async function runLogsServer() {
|
|
|
12544
12685
|
res.end("not found");
|
|
12545
12686
|
});
|
|
12546
12687
|
server.listen(port, "127.0.0.1", async () => {
|
|
12688
|
+
const { recordLogsServerStarted: recordLogsServerStarted2 } = await Promise.resolve().then(() => (init_logs_server_daemon(), logs_server_daemon_exports));
|
|
12689
|
+
recordLogsServerStarted2(port);
|
|
12547
12690
|
const { dir, configured } = await findLogDir();
|
|
12548
12691
|
process.stdout.write(`[SolonGate] Local logs agent listening on http://127.0.0.1:${port}
|
|
12549
12692
|
`);
|
|
@@ -12583,7 +12726,7 @@ var init_logs_server = __esm({
|
|
|
12583
12726
|
|
|
12584
12727
|
// src/inject.ts
|
|
12585
12728
|
var inject_exports = {};
|
|
12586
|
-
import { readFileSync as
|
|
12729
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync10, existsSync as existsSync8, copyFileSync } from "fs";
|
|
12587
12730
|
import { resolve as resolve7 } from "path";
|
|
12588
12731
|
import { execSync } from "child_process";
|
|
12589
12732
|
function parseInjectArgs(argv) {
|
|
@@ -12643,7 +12786,7 @@ WHAT IT DOES
|
|
|
12643
12786
|
function detectProject() {
|
|
12644
12787
|
if (!existsSync8(resolve7("package.json"))) return false;
|
|
12645
12788
|
try {
|
|
12646
|
-
const pkg = JSON.parse(
|
|
12789
|
+
const pkg = JSON.parse(readFileSync13(resolve7("package.json"), "utf-8"));
|
|
12647
12790
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12648
12791
|
return !!(allDeps["@modelcontextprotocol/sdk"] || allDeps["@modelcontextprotocol/server"]);
|
|
12649
12792
|
} catch {
|
|
@@ -12652,7 +12795,7 @@ function detectProject() {
|
|
|
12652
12795
|
}
|
|
12653
12796
|
function findTsEntryFile() {
|
|
12654
12797
|
try {
|
|
12655
|
-
const pkg = JSON.parse(
|
|
12798
|
+
const pkg = JSON.parse(readFileSync13(resolve7("package.json"), "utf-8"));
|
|
12656
12799
|
if (pkg.bin) {
|
|
12657
12800
|
const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
|
|
12658
12801
|
if (typeof binPath === "string") {
|
|
@@ -12679,7 +12822,7 @@ function findTsEntryFile() {
|
|
|
12679
12822
|
const full = resolve7(c2);
|
|
12680
12823
|
if (existsSync8(full)) {
|
|
12681
12824
|
try {
|
|
12682
|
-
const content =
|
|
12825
|
+
const content = readFileSync13(full, "utf-8");
|
|
12683
12826
|
if (content.includes("McpServer") || content.includes("McpServer")) {
|
|
12684
12827
|
return full;
|
|
12685
12828
|
}
|
|
@@ -12699,7 +12842,7 @@ function detectPackageManager() {
|
|
|
12699
12842
|
}
|
|
12700
12843
|
function installSdk() {
|
|
12701
12844
|
try {
|
|
12702
|
-
const pkg = JSON.parse(
|
|
12845
|
+
const pkg = JSON.parse(readFileSync13(resolve7("package.json"), "utf-8"));
|
|
12703
12846
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12704
12847
|
if (allDeps["@solongate/proxy"]) {
|
|
12705
12848
|
log3(" @solongate/proxy already installed");
|
|
@@ -12720,7 +12863,7 @@ function installSdk() {
|
|
|
12720
12863
|
}
|
|
12721
12864
|
}
|
|
12722
12865
|
function injectTypeScript(filePath) {
|
|
12723
|
-
const original =
|
|
12866
|
+
const original = readFileSync13(filePath, "utf-8");
|
|
12724
12867
|
const changes = [];
|
|
12725
12868
|
let modified = original;
|
|
12726
12869
|
if (modified.includes("SecureMcpServer")) {
|
|
@@ -12891,7 +13034,7 @@ async function main2() {
|
|
|
12891
13034
|
log3("");
|
|
12892
13035
|
log3(` Backup: ${backupPath}`);
|
|
12893
13036
|
}
|
|
12894
|
-
|
|
13037
|
+
writeFileSync10(entryFile, result.modified);
|
|
12895
13038
|
log3("");
|
|
12896
13039
|
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");
|
|
12897
13040
|
log3(" \u2502 SolonGate SDK injected successfully! \u2502");
|
|
@@ -12920,8 +13063,8 @@ var init_inject = __esm({
|
|
|
12920
13063
|
|
|
12921
13064
|
// src/create.ts
|
|
12922
13065
|
var create_exports = {};
|
|
12923
|
-
import { mkdirSync as
|
|
12924
|
-
import { resolve as resolve8, join as
|
|
13066
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, existsSync as existsSync9 } from "fs";
|
|
13067
|
+
import { resolve as resolve8, join as join16 } from "path";
|
|
12925
13068
|
import { execSync as execSync2 } from "child_process";
|
|
12926
13069
|
function withSpinner(message, fn) {
|
|
12927
13070
|
const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
|
|
@@ -13000,8 +13143,8 @@ EXAMPLES
|
|
|
13000
13143
|
`);
|
|
13001
13144
|
}
|
|
13002
13145
|
function createProject(dir, name, _policy) {
|
|
13003
|
-
|
|
13004
|
-
|
|
13146
|
+
writeFileSync11(
|
|
13147
|
+
join16(dir, "package.json"),
|
|
13005
13148
|
JSON.stringify(
|
|
13006
13149
|
{
|
|
13007
13150
|
name,
|
|
@@ -13030,8 +13173,8 @@ function createProject(dir, name, _policy) {
|
|
|
13030
13173
|
2
|
|
13031
13174
|
) + "\n"
|
|
13032
13175
|
);
|
|
13033
|
-
|
|
13034
|
-
|
|
13176
|
+
writeFileSync11(
|
|
13177
|
+
join16(dir, "tsconfig.json"),
|
|
13035
13178
|
JSON.stringify(
|
|
13036
13179
|
{
|
|
13037
13180
|
compilerOptions: {
|
|
@@ -13051,9 +13194,9 @@ function createProject(dir, name, _policy) {
|
|
|
13051
13194
|
2
|
|
13052
13195
|
) + "\n"
|
|
13053
13196
|
);
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13197
|
+
mkdirSync10(join16(dir, "src"), { recursive: true });
|
|
13198
|
+
writeFileSync11(
|
|
13199
|
+
join16(dir, "src", "index.ts"),
|
|
13057
13200
|
`#!/usr/bin/env node
|
|
13058
13201
|
|
|
13059
13202
|
console.log = (...args: unknown[]) => {
|
|
@@ -13094,8 +13237,8 @@ console.log('');
|
|
|
13094
13237
|
console.log('Press Ctrl+C to stop.');
|
|
13095
13238
|
`
|
|
13096
13239
|
);
|
|
13097
|
-
|
|
13098
|
-
|
|
13240
|
+
writeFileSync11(
|
|
13241
|
+
join16(dir, ".mcp.json"),
|
|
13099
13242
|
JSON.stringify(
|
|
13100
13243
|
{
|
|
13101
13244
|
mcpServers: {
|
|
@@ -13112,13 +13255,13 @@ console.log('Press Ctrl+C to stop.');
|
|
|
13112
13255
|
2
|
|
13113
13256
|
) + "\n"
|
|
13114
13257
|
);
|
|
13115
|
-
|
|
13116
|
-
|
|
13258
|
+
writeFileSync11(
|
|
13259
|
+
join16(dir, ".env"),
|
|
13117
13260
|
`SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
|
|
13118
13261
|
`
|
|
13119
13262
|
);
|
|
13120
|
-
|
|
13121
|
-
|
|
13263
|
+
writeFileSync11(
|
|
13264
|
+
join16(dir, ".gitignore"),
|
|
13122
13265
|
`node_modules/
|
|
13123
13266
|
dist/
|
|
13124
13267
|
*.solongate-backup
|
|
@@ -13137,7 +13280,7 @@ async function main3() {
|
|
|
13137
13280
|
process.exit(1);
|
|
13138
13281
|
}
|
|
13139
13282
|
withSpinner(`Setting up ${opts.name}...`, () => {
|
|
13140
|
-
|
|
13283
|
+
mkdirSync10(dir, { recursive: true });
|
|
13141
13284
|
createProject(dir, opts.name, opts.policy);
|
|
13142
13285
|
});
|
|
13143
13286
|
if (!opts.noInstall) {
|
|
@@ -13211,14 +13354,14 @@ var init_create = __esm({
|
|
|
13211
13354
|
|
|
13212
13355
|
// src/pull-push.ts
|
|
13213
13356
|
var pull_push_exports = {};
|
|
13214
|
-
import { readFileSync as
|
|
13357
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync12, existsSync as existsSync10 } from "fs";
|
|
13215
13358
|
import { resolve as resolve9 } from "path";
|
|
13216
13359
|
function loadEnv() {
|
|
13217
13360
|
if (process.env.SOLONGATE_API_KEY) return;
|
|
13218
13361
|
const envPath = resolve9(".env");
|
|
13219
13362
|
if (!existsSync10(envPath)) return;
|
|
13220
13363
|
try {
|
|
13221
|
-
const content =
|
|
13364
|
+
const content = readFileSync14(envPath, "utf-8");
|
|
13222
13365
|
for (const line of content.split("\n")) {
|
|
13223
13366
|
const trimmed = line.trim();
|
|
13224
13367
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -13406,7 +13549,7 @@ async function pull(apiKey, file, policyId) {
|
|
|
13406
13549
|
const policy = await fetchCloudPolicy(apiKey, API_URL, policyId);
|
|
13407
13550
|
const { id: _id, ...policyWithoutId } = policy;
|
|
13408
13551
|
const json = JSON.stringify(policyWithoutId, null, 2) + "\n";
|
|
13409
|
-
|
|
13552
|
+
writeFileSync12(file, json, "utf-8");
|
|
13410
13553
|
log5("");
|
|
13411
13554
|
log5(green2(" Saved to: ") + file);
|
|
13412
13555
|
log5(` ${dim2("Name:")} ${policy.name}`);
|
|
@@ -13435,7 +13578,7 @@ async function push(apiKey, file, policyId) {
|
|
|
13435
13578
|
log5(" solongate-proxy list");
|
|
13436
13579
|
process.exit(1);
|
|
13437
13580
|
}
|
|
13438
|
-
const content =
|
|
13581
|
+
const content = readFileSync14(file, "utf-8");
|
|
13439
13582
|
let policy;
|
|
13440
13583
|
try {
|
|
13441
13584
|
policy = JSON.parse(content);
|
|
@@ -16591,6 +16734,10 @@ async function main5() {
|
|
|
16591
16734
|
const { maybeSelfUpdate: maybeSelfUpdate2 } = await Promise.resolve().then(() => (init_self_update(), self_update_exports));
|
|
16592
16735
|
maybeSelfUpdate2();
|
|
16593
16736
|
}
|
|
16737
|
+
if (subcommand !== "logs-server" && subcommand !== "local-logs") {
|
|
16738
|
+
const { ensureLogsServerDaemon: ensureLogsServerDaemon2 } = await Promise.resolve().then(() => (init_logs_server_daemon(), logs_server_daemon_exports));
|
|
16739
|
+
ensureLogsServerDaemon2();
|
|
16740
|
+
}
|
|
16594
16741
|
}
|
|
16595
16742
|
if (process.argv.length <= 2) {
|
|
16596
16743
|
if (process.stdout.isTTY && process.stdin.isTTY) {
|