@solongate/proxy 0.81.16 → 0.81.17
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 +247 -112
- package/dist/tui/index.js +142 -15
- package/dist/tui/notify.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7089,6 +7089,145 @@ var init_api_client = __esm({
|
|
|
7089
7089
|
}
|
|
7090
7090
|
});
|
|
7091
7091
|
|
|
7092
|
+
// src/tui/notify.ts
|
|
7093
|
+
import { spawn, execFileSync as execFileSync2 } from "child_process";
|
|
7094
|
+
import { writeFileSync as writeFileSync3, existsSync as existsSync4 } from "fs";
|
|
7095
|
+
import { join as join6 } from "path";
|
|
7096
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
7097
|
+
function captureFocusTarget() {
|
|
7098
|
+
try {
|
|
7099
|
+
if (process.platform === "linux") {
|
|
7100
|
+
focusToken = (process.env.WINDOWID || "").trim() || null;
|
|
7101
|
+
if (!focusToken) {
|
|
7102
|
+
try {
|
|
7103
|
+
focusToken = execFileSync2("xdotool", ["getactivewindow"], { encoding: "utf-8", timeout: 1500, stdio: ["ignore", "pipe", "ignore"] }).trim() || null;
|
|
7104
|
+
} catch {
|
|
7105
|
+
focusToken = null;
|
|
7106
|
+
}
|
|
7107
|
+
}
|
|
7108
|
+
} else if (process.platform === "win32") {
|
|
7109
|
+
const ps = `Add-Type -Name W -Namespace N -MemberDefinition '[DllImport("user32.dll")]public static extern System.IntPtr GetForegroundWindow();' | Out-Null; [N.W]::GetForegroundWindow().ToInt64()`;
|
|
7110
|
+
try {
|
|
7111
|
+
focusToken = execFileSync2("powershell", ["-NoProfile", "-NonInteractive", "-Command", ps], { encoding: "utf-8", timeout: 4e3, stdio: ["ignore", "pipe", "ignore"] }).trim() || null;
|
|
7112
|
+
} catch {
|
|
7113
|
+
focusToken = null;
|
|
7114
|
+
}
|
|
7115
|
+
}
|
|
7116
|
+
} catch {
|
|
7117
|
+
focusToken = null;
|
|
7118
|
+
}
|
|
7119
|
+
}
|
|
7120
|
+
function desktopNotify(title, msg) {
|
|
7121
|
+
try {
|
|
7122
|
+
if (process.platform === "linux") linuxNotify(title, msg);
|
|
7123
|
+
else if (process.platform === "win32") winNotify(title, msg);
|
|
7124
|
+
else if (process.platform === "darwin") macNotify(title, msg);
|
|
7125
|
+
} catch {
|
|
7126
|
+
}
|
|
7127
|
+
}
|
|
7128
|
+
function linuxNotify(title, msg) {
|
|
7129
|
+
let p;
|
|
7130
|
+
try {
|
|
7131
|
+
p = spawn("notify-send", ["--wait", "--action=default=Open", "-a", "SolonGate", title, msg], { stdio: ["ignore", "pipe", "ignore"] });
|
|
7132
|
+
} catch {
|
|
7133
|
+
return;
|
|
7134
|
+
}
|
|
7135
|
+
p.on("error", () => {
|
|
7136
|
+
});
|
|
7137
|
+
p.stdout?.on("data", (d) => {
|
|
7138
|
+
if (String(d).trim() === "default") raiseLinuxWindow();
|
|
7139
|
+
});
|
|
7140
|
+
p.unref();
|
|
7141
|
+
}
|
|
7142
|
+
function raiseLinuxWindow() {
|
|
7143
|
+
if (!focusToken) return;
|
|
7144
|
+
try {
|
|
7145
|
+
const x = spawn("xdotool", ["windowactivate", focusToken], { stdio: "ignore" });
|
|
7146
|
+
x.on("error", () => {
|
|
7147
|
+
try {
|
|
7148
|
+
const hex = "0x" + Number(focusToken).toString(16);
|
|
7149
|
+
const w = spawn("wmctrl", ["-ia", hex], { stdio: "ignore" });
|
|
7150
|
+
w.on("error", () => {
|
|
7151
|
+
});
|
|
7152
|
+
w.unref();
|
|
7153
|
+
} catch {
|
|
7154
|
+
}
|
|
7155
|
+
});
|
|
7156
|
+
x.unref();
|
|
7157
|
+
} catch {
|
|
7158
|
+
}
|
|
7159
|
+
}
|
|
7160
|
+
function ensureWinScript() {
|
|
7161
|
+
if (winScriptPath && existsSync4(winScriptPath)) return winScriptPath;
|
|
7162
|
+
const p = join6(tmpdir2(), "solongate-toast.ps1");
|
|
7163
|
+
const script = [
|
|
7164
|
+
"param([string]$Title,[string]$Msg,[string]$Hwnd)",
|
|
7165
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
7166
|
+
"Add-Type -AssemblyName System.Drawing",
|
|
7167
|
+
`Add-Type -Name Win -Namespace Sg -MemberDefinition '[DllImport("user32.dll")]public static extern bool SetForegroundWindow(System.IntPtr h);[DllImport("user32.dll")]public static extern bool ShowWindow(System.IntPtr h,int c);'`,
|
|
7168
|
+
"$ni=New-Object System.Windows.Forms.NotifyIcon",
|
|
7169
|
+
"$ni.Icon=[System.Drawing.SystemIcons]::Information",
|
|
7170
|
+
"$ni.Visible=$true",
|
|
7171
|
+
"$script:clicked=$false",
|
|
7172
|
+
"$ni.add_BalloonTipClicked({$script:clicked=$true})",
|
|
7173
|
+
"$ni.ShowBalloonTip(8000,$Title,$Msg,[System.Windows.Forms.ToolTipIcon]::Warning)",
|
|
7174
|
+
"$sw=[System.Diagnostics.Stopwatch]::StartNew()",
|
|
7175
|
+
"while($sw.Elapsed.TotalSeconds -lt 9 -and -not $script:clicked){[System.Windows.Forms.Application]::DoEvents();Start-Sleep -Milliseconds 100}",
|
|
7176
|
+
"if($script:clicked -and $Hwnd){try{$h=[System.IntPtr][int64]$Hwnd;[Sg.Win]::ShowWindow($h,9)|Out-Null;[Sg.Win]::SetForegroundWindow($h)|Out-Null}catch{}}",
|
|
7177
|
+
"$ni.Visible=$false;$ni.Dispose()"
|
|
7178
|
+
].join("\n");
|
|
7179
|
+
try {
|
|
7180
|
+
writeFileSync3(p, script);
|
|
7181
|
+
winScriptPath = p;
|
|
7182
|
+
return p;
|
|
7183
|
+
} catch {
|
|
7184
|
+
return null;
|
|
7185
|
+
}
|
|
7186
|
+
}
|
|
7187
|
+
function winNotify(title, msg) {
|
|
7188
|
+
const script = ensureWinScript();
|
|
7189
|
+
if (!script) return;
|
|
7190
|
+
try {
|
|
7191
|
+
const p = spawn("powershell", ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, "-Title", title, "-Msg", msg, "-Hwnd", focusToken || ""], { stdio: "ignore", detached: true, windowsHide: true });
|
|
7192
|
+
p.on("error", () => {
|
|
7193
|
+
});
|
|
7194
|
+
p.unref();
|
|
7195
|
+
} catch {
|
|
7196
|
+
}
|
|
7197
|
+
}
|
|
7198
|
+
function macBundleId() {
|
|
7199
|
+
const prog = (process.env.TERM_PROGRAM || "").toLowerCase();
|
|
7200
|
+
if (prog.includes("iterm")) return "com.googlecode.iterm2";
|
|
7201
|
+
if (prog.includes("apple_terminal")) return "com.apple.Terminal";
|
|
7202
|
+
if (prog.includes("vscode")) return "com.microsoft.VSCode";
|
|
7203
|
+
return "com.apple.Terminal";
|
|
7204
|
+
}
|
|
7205
|
+
function macNotify(title, msg) {
|
|
7206
|
+
try {
|
|
7207
|
+
const p = spawn("terminal-notifier", ["-title", title, "-message", msg, "-activate", macBundleId(), "-sender", macBundleId()], { stdio: "ignore", detached: true });
|
|
7208
|
+
p.on("error", () => {
|
|
7209
|
+
try {
|
|
7210
|
+
const esc = (s) => s.replace(/"/g, '\\"');
|
|
7211
|
+
const a = spawn("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
|
|
7212
|
+
a.on("error", () => {
|
|
7213
|
+
});
|
|
7214
|
+
a.unref();
|
|
7215
|
+
} catch {
|
|
7216
|
+
}
|
|
7217
|
+
});
|
|
7218
|
+
p.unref();
|
|
7219
|
+
} catch {
|
|
7220
|
+
}
|
|
7221
|
+
}
|
|
7222
|
+
var focusToken, winScriptPath;
|
|
7223
|
+
var init_notify = __esm({
|
|
7224
|
+
"src/tui/notify.ts"() {
|
|
7225
|
+
"use strict";
|
|
7226
|
+
focusToken = null;
|
|
7227
|
+
winScriptPath = null;
|
|
7228
|
+
}
|
|
7229
|
+
});
|
|
7230
|
+
|
|
7092
7231
|
// src/tui/hooks.ts
|
|
7093
7232
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
7094
7233
|
function useLoader(fn, deps = []) {
|
|
@@ -7137,10 +7276,9 @@ var init_hooks = __esm({
|
|
|
7137
7276
|
// src/tui/panels/Live.tsx
|
|
7138
7277
|
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
7139
7278
|
import TextInput from "ink-text-input";
|
|
7140
|
-
import {
|
|
7141
|
-
import { closeSync, mkdirSync as mkdirSync3, openSync, readSync, statSync, writeFileSync as writeFileSync3 } from "fs";
|
|
7279
|
+
import { closeSync, mkdirSync as mkdirSync3, openSync, readSync, statSync, writeFileSync as writeFileSync4 } from "fs";
|
|
7142
7280
|
import { homedir as homedir4 } from "os";
|
|
7143
|
-
import { join as
|
|
7281
|
+
import { join as join7 } from "path";
|
|
7144
7282
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
7145
7283
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
7146
7284
|
function tailLines(file, maxBytes = 131072) {
|
|
@@ -7455,13 +7593,7 @@ function LivePanel({ active: active2 }) {
|
|
|
7455
7593
|
process.stdout.write("\x07");
|
|
7456
7594
|
} catch {
|
|
7457
7595
|
}
|
|
7458
|
-
|
|
7459
|
-
const child = spawn("notify-send", ["-a", "SolonGate", title, msg], { stdio: "ignore", detached: true });
|
|
7460
|
-
child.on("error", () => {
|
|
7461
|
-
});
|
|
7462
|
-
child.unref();
|
|
7463
|
-
} catch {
|
|
7464
|
-
}
|
|
7596
|
+
desktopNotify(title, msg);
|
|
7465
7597
|
},
|
|
7466
7598
|
[pushLog]
|
|
7467
7599
|
);
|
|
@@ -7675,10 +7807,10 @@ function LivePanel({ active: active2 }) {
|
|
|
7675
7807
|
else if (input === "x") toggleSignal("dlp");
|
|
7676
7808
|
else if (input === "r") toggleSignal("ratelimit");
|
|
7677
7809
|
else if (input === "e") {
|
|
7678
|
-
const file =
|
|
7810
|
+
const file = join7(homedir4(), ".solongate", "live-export.jsonl");
|
|
7679
7811
|
try {
|
|
7680
|
-
mkdirSync3(
|
|
7681
|
-
|
|
7812
|
+
mkdirSync3(join7(homedir4(), ".solongate"), { recursive: true });
|
|
7813
|
+
writeFileSync4(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
|
|
7682
7814
|
setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
|
|
7683
7815
|
} catch (err2) {
|
|
7684
7816
|
setActionMsg({ text: "\u2717 export failed: " + (err2 instanceof Error ? err2.message : String(err2)), level: "bad", until: Date.now() + 6e3 });
|
|
@@ -7938,14 +8070,15 @@ var init_Live = __esm({
|
|
|
7938
8070
|
"use strict";
|
|
7939
8071
|
init_api_client();
|
|
7940
8072
|
init_config2();
|
|
8073
|
+
init_notify();
|
|
7941
8074
|
init_hooks();
|
|
7942
8075
|
init_theme();
|
|
7943
8076
|
CONFIG = loadConfig();
|
|
7944
8077
|
SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
7945
8078
|
BG = "#12234f";
|
|
7946
8079
|
DIM_FLOOR = "#233457";
|
|
7947
|
-
LOCAL_LOG =
|
|
7948
|
-
RING =
|
|
8080
|
+
LOCAL_LOG = join7(homedir4(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
8081
|
+
RING = join7(process.cwd(), ".solongate", ".eval-ring.jsonl");
|
|
7949
8082
|
hhmmss = (ts) => {
|
|
7950
8083
|
const d = new Date(ts);
|
|
7951
8084
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
@@ -9161,6 +9294,7 @@ async function launchTui() {
|
|
|
9161
9294
|
process.stderr.write("Not logged in. Run `solongate login` first.\n");
|
|
9162
9295
|
return;
|
|
9163
9296
|
}
|
|
9297
|
+
captureFocusTarget();
|
|
9164
9298
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
9165
9299
|
try {
|
|
9166
9300
|
const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}));
|
|
@@ -9174,6 +9308,7 @@ var init_tui = __esm({
|
|
|
9174
9308
|
"use strict";
|
|
9175
9309
|
init_App();
|
|
9176
9310
|
init_client();
|
|
9311
|
+
init_notify();
|
|
9177
9312
|
}
|
|
9178
9313
|
});
|
|
9179
9314
|
|
|
@@ -9865,9 +10000,9 @@ var init_agents2 = __esm({
|
|
|
9865
10000
|
});
|
|
9866
10001
|
|
|
9867
10002
|
// src/commands/doctor.ts
|
|
9868
|
-
import { existsSync as
|
|
10003
|
+
import { existsSync as existsSync5, statSync as statSync2 } from "fs";
|
|
9869
10004
|
import { homedir as homedir5 } from "os";
|
|
9870
|
-
import { join as
|
|
10005
|
+
import { join as join8 } from "path";
|
|
9871
10006
|
async function run6(argv) {
|
|
9872
10007
|
const { flags } = parse(argv);
|
|
9873
10008
|
const json = flagBool(flags, "json");
|
|
@@ -9897,7 +10032,7 @@ async function run6(argv) {
|
|
|
9897
10032
|
} catch {
|
|
9898
10033
|
}
|
|
9899
10034
|
}
|
|
9900
|
-
if (
|
|
10035
|
+
if (existsSync5(LOCAL_LOG2)) {
|
|
9901
10036
|
const st = statSync2(LOCAL_LOG2);
|
|
9902
10037
|
const ageMin = (Date.now() - st.mtimeMs) / 6e4;
|
|
9903
10038
|
checks.push({ name: "local logs", ok: true, detail: `on \xB7 ${(st.size / 1024).toFixed(0)}KB \xB7 last write ${ageMin < 1 ? "just now" : Math.round(ageMin) + "m ago"}` });
|
|
@@ -9927,14 +10062,14 @@ var init_doctor = __esm({
|
|
|
9927
10062
|
init_api_client();
|
|
9928
10063
|
init_format();
|
|
9929
10064
|
init_args();
|
|
9930
|
-
LOCAL_LOG2 =
|
|
10065
|
+
LOCAL_LOG2 = join8(homedir5(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
9931
10066
|
}
|
|
9932
10067
|
});
|
|
9933
10068
|
|
|
9934
10069
|
// src/commands/watch.ts
|
|
9935
|
-
import { closeSync as closeSync2, existsSync as
|
|
10070
|
+
import { closeSync as closeSync2, existsSync as existsSync6, openSync as openSync2, readSync as readSync2, statSync as statSync3 } from "fs";
|
|
9936
10071
|
import { homedir as homedir6 } from "os";
|
|
9937
|
-
import { join as
|
|
10072
|
+
import { join as join9 } from "path";
|
|
9938
10073
|
function tailLocal(file, maxBytes = 131072) {
|
|
9939
10074
|
try {
|
|
9940
10075
|
const size = statSync3(file).size;
|
|
@@ -9978,7 +10113,7 @@ async function run7(argv) {
|
|
|
9978
10113
|
for (const r of rows) if (keep(r)) print(r, json);
|
|
9979
10114
|
};
|
|
9980
10115
|
const pollLocal = () => {
|
|
9981
|
-
if (cloudOnly || !
|
|
10116
|
+
if (cloudOnly || !existsSync6(LOCAL_LOG3)) return;
|
|
9982
10117
|
const rows = [];
|
|
9983
10118
|
for (const line of tailLocal(LOCAL_LOG3)) {
|
|
9984
10119
|
try {
|
|
@@ -10041,7 +10176,7 @@ var init_watch = __esm({
|
|
|
10041
10176
|
init_cli_utils();
|
|
10042
10177
|
init_args();
|
|
10043
10178
|
init_format();
|
|
10044
|
-
LOCAL_LOG3 =
|
|
10179
|
+
LOCAL_LOG3 = join9(homedir6(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
10045
10180
|
trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
10046
10181
|
time = (ms) => new Date(ms).toTimeString().slice(0, 8);
|
|
10047
10182
|
}
|
|
@@ -10343,32 +10478,32 @@ __export(global_install_exports, {
|
|
|
10343
10478
|
runGlobalRestore: () => runGlobalRestore,
|
|
10344
10479
|
unlockProtected: () => unlockProtected
|
|
10345
10480
|
});
|
|
10346
|
-
import { readFileSync as readFileSync7, writeFileSync as
|
|
10347
|
-
import { resolve as resolve4, join as
|
|
10481
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync7, mkdirSync as mkdirSync4 } from "fs";
|
|
10482
|
+
import { resolve as resolve4, join as join10, dirname } from "path";
|
|
10348
10483
|
import { homedir as homedir7 } from "os";
|
|
10349
10484
|
import { fileURLToPath } from "url";
|
|
10350
10485
|
import { createInterface } from "readline";
|
|
10351
|
-
import { execFileSync as
|
|
10486
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
10352
10487
|
function lockFile(file) {
|
|
10353
|
-
if (!
|
|
10488
|
+
if (!existsSync7(file)) return;
|
|
10354
10489
|
try {
|
|
10355
10490
|
if (process.platform === "win32") {
|
|
10356
10491
|
try {
|
|
10357
|
-
|
|
10492
|
+
execFileSync3("icacls", [file, "/deny", "*S-1-1-0:(WD,AD,DC,DE)"], { stdio: "ignore" });
|
|
10358
10493
|
} catch {
|
|
10359
10494
|
}
|
|
10360
10495
|
try {
|
|
10361
|
-
|
|
10496
|
+
execFileSync3("attrib", ["+R", file], { stdio: "ignore" });
|
|
10362
10497
|
} catch {
|
|
10363
10498
|
}
|
|
10364
10499
|
} else if (process.platform === "darwin") {
|
|
10365
10500
|
try {
|
|
10366
|
-
|
|
10501
|
+
execFileSync3("chflags", ["uchg", file], { stdio: "ignore" });
|
|
10367
10502
|
} catch {
|
|
10368
10503
|
}
|
|
10369
10504
|
} else {
|
|
10370
10505
|
try {
|
|
10371
|
-
|
|
10506
|
+
execFileSync3("chattr", ["+i", file], { stdio: "ignore" });
|
|
10372
10507
|
} catch {
|
|
10373
10508
|
}
|
|
10374
10509
|
}
|
|
@@ -10376,29 +10511,29 @@ function lockFile(file) {
|
|
|
10376
10511
|
}
|
|
10377
10512
|
}
|
|
10378
10513
|
function unlockFile(file) {
|
|
10379
|
-
if (!
|
|
10514
|
+
if (!existsSync7(file)) return;
|
|
10380
10515
|
try {
|
|
10381
10516
|
if (process.platform === "win32") {
|
|
10382
10517
|
try {
|
|
10383
|
-
|
|
10518
|
+
execFileSync3("icacls", [file, "/remove:d", "*S-1-1-0"], { stdio: "ignore" });
|
|
10384
10519
|
} catch {
|
|
10385
10520
|
}
|
|
10386
10521
|
try {
|
|
10387
|
-
|
|
10522
|
+
execFileSync3("icacls", [file, "/reset"], { stdio: "ignore" });
|
|
10388
10523
|
} catch {
|
|
10389
10524
|
}
|
|
10390
10525
|
try {
|
|
10391
|
-
|
|
10526
|
+
execFileSync3("attrib", ["-R", file], { stdio: "ignore" });
|
|
10392
10527
|
} catch {
|
|
10393
10528
|
}
|
|
10394
10529
|
} else if (process.platform === "darwin") {
|
|
10395
10530
|
try {
|
|
10396
|
-
|
|
10531
|
+
execFileSync3("chflags", ["nouchg", file], { stdio: "ignore" });
|
|
10397
10532
|
} catch {
|
|
10398
10533
|
}
|
|
10399
10534
|
} else {
|
|
10400
10535
|
try {
|
|
10401
|
-
|
|
10536
|
+
execFileSync3("chattr", ["-i", file], { stdio: "ignore" });
|
|
10402
10537
|
} catch {
|
|
10403
10538
|
}
|
|
10404
10539
|
}
|
|
@@ -10408,10 +10543,10 @@ function unlockFile(file) {
|
|
|
10408
10543
|
function protectedTargets() {
|
|
10409
10544
|
const p = globalPaths();
|
|
10410
10545
|
return [
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10546
|
+
join10(p.hooksDir, "guard.mjs"),
|
|
10547
|
+
join10(p.hooksDir, "audit.mjs"),
|
|
10548
|
+
join10(p.hooksDir, "stop.mjs"),
|
|
10549
|
+
join10(p.hooksDir, "shield.mjs"),
|
|
10415
10550
|
p.configPath,
|
|
10416
10551
|
p.settingsPath
|
|
10417
10552
|
];
|
|
@@ -10424,25 +10559,25 @@ function unlockProtected() {
|
|
|
10424
10559
|
}
|
|
10425
10560
|
function globalPaths() {
|
|
10426
10561
|
const home = homedir7();
|
|
10427
|
-
const sgDir =
|
|
10428
|
-
const hooksDir =
|
|
10429
|
-
const claudeDir =
|
|
10562
|
+
const sgDir = join10(home, ".solongate");
|
|
10563
|
+
const hooksDir = join10(sgDir, "hooks");
|
|
10564
|
+
const claudeDir = join10(home, ".claude");
|
|
10430
10565
|
return {
|
|
10431
10566
|
home,
|
|
10432
10567
|
sgDir,
|
|
10433
10568
|
hooksDir,
|
|
10434
10569
|
claudeDir,
|
|
10435
|
-
settingsPath:
|
|
10436
|
-
backupPath:
|
|
10437
|
-
configPath:
|
|
10570
|
+
settingsPath: join10(claudeDir, "settings.json"),
|
|
10571
|
+
backupPath: join10(claudeDir, "settings.solongate.bak"),
|
|
10572
|
+
configPath: join10(sgDir, "cloud-guard.json")
|
|
10438
10573
|
};
|
|
10439
10574
|
}
|
|
10440
10575
|
function readHook(filename) {
|
|
10441
|
-
return readFileSync7(
|
|
10576
|
+
return readFileSync7(join10(HOOKS_DIR, filename), "utf-8");
|
|
10442
10577
|
}
|
|
10443
10578
|
function readGuard() {
|
|
10444
|
-
const bundled =
|
|
10445
|
-
return
|
|
10579
|
+
const bundled = join10(HOOKS_DIR, "guard.bundled.mjs");
|
|
10580
|
+
return existsSync7(bundled) ? readFileSync7(bundled, "utf-8") : readHook("guard.mjs");
|
|
10446
10581
|
}
|
|
10447
10582
|
function ask(question) {
|
|
10448
10583
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -10455,14 +10590,14 @@ function runGlobalRestore() {
|
|
|
10455
10590
|
const p = globalPaths();
|
|
10456
10591
|
unlockProtected();
|
|
10457
10592
|
removeClaudeShim();
|
|
10458
|
-
if (
|
|
10459
|
-
|
|
10593
|
+
if (existsSync7(p.backupPath)) {
|
|
10594
|
+
writeFileSync5(p.settingsPath, readFileSync7(p.backupPath, "utf-8"));
|
|
10460
10595
|
console.log(` Restored ${p.settingsPath} from backup.`);
|
|
10461
|
-
} else if (
|
|
10596
|
+
} else if (existsSync7(p.settingsPath)) {
|
|
10462
10597
|
try {
|
|
10463
10598
|
const s = JSON.parse(readFileSync7(p.settingsPath, "utf-8"));
|
|
10464
10599
|
delete s.hooks;
|
|
10465
|
-
|
|
10600
|
+
writeFileSync5(p.settingsPath, JSON.stringify(s, null, 2) + "\n");
|
|
10466
10601
|
console.log(` Removed SolonGate hooks from ${p.settingsPath}.`);
|
|
10467
10602
|
} catch {
|
|
10468
10603
|
}
|
|
@@ -10477,7 +10612,7 @@ function escapeRe(s) {
|
|
|
10477
10612
|
function resolveRealClaude() {
|
|
10478
10613
|
try {
|
|
10479
10614
|
const finder = process.platform === "win32" ? "where" : "which";
|
|
10480
|
-
const out2 =
|
|
10615
|
+
const out2 = execFileSync3(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
10481
10616
|
if (process.platform === "win32") {
|
|
10482
10617
|
const low = (s) => s.toLowerCase();
|
|
10483
10618
|
return out2.find((l) => low(l).endsWith(".cmd")) || out2.find((l) => low(l).endsWith(".exe")) || out2.find((l) => low(l).endsWith(".bat")) || out2[0] || null;
|
|
@@ -10490,24 +10625,24 @@ function resolveRealClaude() {
|
|
|
10490
10625
|
function shimTargets() {
|
|
10491
10626
|
if (process.platform === "win32") {
|
|
10492
10627
|
try {
|
|
10493
|
-
const prof =
|
|
10628
|
+
const prof = execFileSync3("powershell", ["-NoProfile", "-Command", "$PROFILE.CurrentUserAllHosts"], { encoding: "utf-8" }).trim();
|
|
10494
10629
|
return prof ? [prof] : [];
|
|
10495
10630
|
} catch {
|
|
10496
10631
|
return [];
|
|
10497
10632
|
}
|
|
10498
10633
|
}
|
|
10499
|
-
return [".bashrc", ".zshrc", ".profile"].map((f) =>
|
|
10634
|
+
return [".bashrc", ".zshrc", ".profile"].map((f) => join10(homedir7(), f)).filter((f) => existsSync7(f));
|
|
10500
10635
|
}
|
|
10501
10636
|
function writeShimBlock(file, block2) {
|
|
10502
10637
|
const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
|
|
10503
|
-
let content =
|
|
10638
|
+
let content = existsSync7(file) ? readFileSync7(file, "utf-8") : "";
|
|
10504
10639
|
content = content.replace(re, "");
|
|
10505
10640
|
if (block2) {
|
|
10506
10641
|
if (content.length && !content.endsWith("\n")) content += "\n";
|
|
10507
10642
|
content += block2 + "\n";
|
|
10508
10643
|
}
|
|
10509
10644
|
mkdirSync4(dirname(file), { recursive: true });
|
|
10510
|
-
|
|
10645
|
+
writeFileSync5(file, content);
|
|
10511
10646
|
}
|
|
10512
10647
|
function installClaudeShim(shieldPath) {
|
|
10513
10648
|
const real = resolveRealClaude();
|
|
@@ -10561,19 +10696,19 @@ async function runGlobalInstall(opts = {}) {
|
|
|
10561
10696
|
mkdirSync4(p.hooksDir, { recursive: true });
|
|
10562
10697
|
mkdirSync4(p.claudeDir, { recursive: true });
|
|
10563
10698
|
unlockProtected();
|
|
10564
|
-
|
|
10565
|
-
|
|
10566
|
-
|
|
10567
|
-
|
|
10699
|
+
writeFileSync5(join10(p.hooksDir, "guard.mjs"), readGuard());
|
|
10700
|
+
writeFileSync5(join10(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
|
|
10701
|
+
writeFileSync5(join10(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
|
|
10702
|
+
writeFileSync5(join10(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
|
|
10568
10703
|
console.log(` Installed hooks \u2192 ${p.hooksDir}`);
|
|
10569
|
-
installClaudeShim(
|
|
10570
|
-
|
|
10704
|
+
installClaudeShim(join10(p.hooksDir, "shield.mjs"));
|
|
10705
|
+
writeFileSync5(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
|
|
10571
10706
|
console.log(` Wrote ${p.configPath}`);
|
|
10572
10707
|
let existing = {};
|
|
10573
|
-
if (
|
|
10708
|
+
if (existsSync7(p.settingsPath)) {
|
|
10574
10709
|
const raw = readFileSync7(p.settingsPath, "utf-8");
|
|
10575
|
-
if (!
|
|
10576
|
-
|
|
10710
|
+
if (!existsSync7(p.backupPath)) {
|
|
10711
|
+
writeFileSync5(p.backupPath, raw);
|
|
10577
10712
|
console.log(` Backed up existing settings \u2192 ${p.backupPath}`);
|
|
10578
10713
|
}
|
|
10579
10714
|
try {
|
|
@@ -10582,9 +10717,9 @@ async function runGlobalInstall(opts = {}) {
|
|
|
10582
10717
|
existing = {};
|
|
10583
10718
|
}
|
|
10584
10719
|
}
|
|
10585
|
-
const guardAbs =
|
|
10586
|
-
const auditAbs =
|
|
10587
|
-
const stopAbs =
|
|
10720
|
+
const guardAbs = join10(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
|
|
10721
|
+
const auditAbs = join10(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
|
|
10722
|
+
const stopAbs = join10(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
|
|
10588
10723
|
const nodeBin = process.execPath.replace(/\\/g, "/");
|
|
10589
10724
|
const call = process.platform === "win32" ? "& " : "";
|
|
10590
10725
|
const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
|
|
@@ -10596,7 +10731,7 @@ async function runGlobalInstall(opts = {}) {
|
|
|
10596
10731
|
Stop: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(stopAbs) }] }]
|
|
10597
10732
|
}
|
|
10598
10733
|
};
|
|
10599
|
-
|
|
10734
|
+
writeFileSync5(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
10600
10735
|
console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
|
|
10601
10736
|
if (process.env["SOLONGATE_OS_LOCK"] === "1") {
|
|
10602
10737
|
lockProtected();
|
|
@@ -10776,7 +10911,7 @@ import { createServer, request as httpRequest } from "http";
|
|
|
10776
10911
|
import { request as httpsRequest } from "https";
|
|
10777
10912
|
import { spawn as spawn3 } from "child_process";
|
|
10778
10913
|
import { URL as URL2 } from "url";
|
|
10779
|
-
import { readFileSync as readFileSync8, existsSync as
|
|
10914
|
+
import { readFileSync as readFileSync8, existsSync as existsSync8, readdirSync, statSync as statSync4 } from "fs";
|
|
10780
10915
|
import { resolve as resolve5 } from "path";
|
|
10781
10916
|
import { homedir as homedir8 } from "os";
|
|
10782
10917
|
function findCacheFile() {
|
|
@@ -10784,7 +10919,7 @@ function findCacheFile() {
|
|
|
10784
10919
|
const envSel = process.env.SOLONGATE_AGENT_ID;
|
|
10785
10920
|
if (envSel) {
|
|
10786
10921
|
const f = resolve5(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
|
|
10787
|
-
if (
|
|
10922
|
+
if (existsSync8(f)) return f;
|
|
10788
10923
|
}
|
|
10789
10924
|
let best = null, bestTs = -1;
|
|
10790
10925
|
try {
|
|
@@ -10805,7 +10940,7 @@ function findCacheFile() {
|
|
|
10805
10940
|
function loadCfg() {
|
|
10806
10941
|
try {
|
|
10807
10942
|
const f = findCacheFile();
|
|
10808
|
-
if (f &&
|
|
10943
|
+
if (f && existsSync8(f)) {
|
|
10809
10944
|
const c2 = JSON.parse(readFileSync8(f, "utf-8"));
|
|
10810
10945
|
const d = c2?.security?.dlpRedact;
|
|
10811
10946
|
const g = c2?.security?.ghost;
|
|
@@ -11095,7 +11230,7 @@ __export(logs_server_exports, {
|
|
|
11095
11230
|
});
|
|
11096
11231
|
import { createServer as createServer2 } from "http";
|
|
11097
11232
|
import { readFileSync as readFileSync9, statSync as statSync5 } from "fs";
|
|
11098
|
-
import { resolve as resolve6, join as
|
|
11233
|
+
import { resolve as resolve6, join as join11, isAbsolute } from "path";
|
|
11099
11234
|
import { homedir as homedir9 } from "os";
|
|
11100
11235
|
import { readdirSync as readdirSync2 } from "fs";
|
|
11101
11236
|
function allowedOrigins() {
|
|
@@ -11121,7 +11256,7 @@ async function findLogDir() {
|
|
|
11121
11256
|
const files = readdirSync2(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
|
|
11122
11257
|
for (const f of files) {
|
|
11123
11258
|
try {
|
|
11124
|
-
const c2 = JSON.parse(readFileSync9(
|
|
11259
|
+
const c2 = JSON.parse(readFileSync9(join11(base, f), "utf-8"));
|
|
11125
11260
|
const p = c2?.security?.localLogs?.path;
|
|
11126
11261
|
if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
|
|
11127
11262
|
} catch {
|
|
@@ -11130,7 +11265,7 @@ async function findLogDir() {
|
|
|
11130
11265
|
} catch {
|
|
11131
11266
|
}
|
|
11132
11267
|
try {
|
|
11133
|
-
const cfgRaw = readFileSync9(
|
|
11268
|
+
const cfgRaw = readFileSync9(join11(base, "cloud-guard.json"), "utf-8");
|
|
11134
11269
|
const { apiKey, apiUrl } = JSON.parse(cfgRaw);
|
|
11135
11270
|
if (apiKey) {
|
|
11136
11271
|
const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
|
|
@@ -11159,7 +11294,7 @@ function setCors(req, res) {
|
|
|
11159
11294
|
}
|
|
11160
11295
|
function fileInfo(dir) {
|
|
11161
11296
|
if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
|
|
11162
|
-
const file =
|
|
11297
|
+
const file = join11(dir, LOG_FILENAME);
|
|
11163
11298
|
try {
|
|
11164
11299
|
const st = statSync5(file);
|
|
11165
11300
|
return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
|
|
@@ -11272,7 +11407,7 @@ var init_logs_server = __esm({
|
|
|
11272
11407
|
|
|
11273
11408
|
// src/inject.ts
|
|
11274
11409
|
var inject_exports = {};
|
|
11275
|
-
import { readFileSync as readFileSync10, writeFileSync as
|
|
11410
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, existsSync as existsSync9, copyFileSync } from "fs";
|
|
11276
11411
|
import { resolve as resolve7 } from "path";
|
|
11277
11412
|
import { execSync } from "child_process";
|
|
11278
11413
|
function parseInjectArgs(argv) {
|
|
@@ -11330,7 +11465,7 @@ WHAT IT DOES
|
|
|
11330
11465
|
`);
|
|
11331
11466
|
}
|
|
11332
11467
|
function detectProject() {
|
|
11333
|
-
if (!
|
|
11468
|
+
if (!existsSync9(resolve7("package.json"))) return false;
|
|
11334
11469
|
try {
|
|
11335
11470
|
const pkg = JSON.parse(readFileSync10(resolve7("package.json"), "utf-8"));
|
|
11336
11471
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
@@ -11346,13 +11481,13 @@ function findTsEntryFile() {
|
|
|
11346
11481
|
const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
|
|
11347
11482
|
if (typeof binPath === "string") {
|
|
11348
11483
|
const srcPath = binPath.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
|
|
11349
|
-
if (
|
|
11350
|
-
if (
|
|
11484
|
+
if (existsSync9(resolve7(srcPath))) return resolve7(srcPath);
|
|
11485
|
+
if (existsSync9(resolve7(binPath))) return resolve7(binPath);
|
|
11351
11486
|
}
|
|
11352
11487
|
}
|
|
11353
11488
|
if (pkg.main) {
|
|
11354
11489
|
const srcPath = pkg.main.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
|
|
11355
|
-
if (
|
|
11490
|
+
if (existsSync9(resolve7(srcPath))) return resolve7(srcPath);
|
|
11356
11491
|
}
|
|
11357
11492
|
} catch {
|
|
11358
11493
|
}
|
|
@@ -11366,7 +11501,7 @@ function findTsEntryFile() {
|
|
|
11366
11501
|
];
|
|
11367
11502
|
for (const c2 of candidates) {
|
|
11368
11503
|
const full = resolve7(c2);
|
|
11369
|
-
if (
|
|
11504
|
+
if (existsSync9(full)) {
|
|
11370
11505
|
try {
|
|
11371
11506
|
const content = readFileSync10(full, "utf-8");
|
|
11372
11507
|
if (content.includes("McpServer") || content.includes("McpServer")) {
|
|
@@ -11377,13 +11512,13 @@ function findTsEntryFile() {
|
|
|
11377
11512
|
}
|
|
11378
11513
|
}
|
|
11379
11514
|
for (const c2 of candidates) {
|
|
11380
|
-
if (
|
|
11515
|
+
if (existsSync9(resolve7(c2))) return resolve7(c2);
|
|
11381
11516
|
}
|
|
11382
11517
|
return null;
|
|
11383
11518
|
}
|
|
11384
11519
|
function detectPackageManager() {
|
|
11385
|
-
if (
|
|
11386
|
-
if (
|
|
11520
|
+
if (existsSync9(resolve7("pnpm-lock.yaml"))) return "pnpm";
|
|
11521
|
+
if (existsSync9(resolve7("yarn.lock"))) return "yarn";
|
|
11387
11522
|
return "npm";
|
|
11388
11523
|
}
|
|
11389
11524
|
function installSdk() {
|
|
@@ -11526,7 +11661,7 @@ async function main2() {
|
|
|
11526
11661
|
}
|
|
11527
11662
|
log3(" Language: TypeScript");
|
|
11528
11663
|
const entryFile = opts.file ? resolve7(opts.file) : findTsEntryFile();
|
|
11529
|
-
if (!entryFile || !
|
|
11664
|
+
if (!entryFile || !existsSync9(entryFile)) {
|
|
11530
11665
|
log3(` Could not find entry file.${opts.file ? ` File not found: ${opts.file}` : ""}`);
|
|
11531
11666
|
log3("");
|
|
11532
11667
|
log3(" Specify it manually: --file <path>");
|
|
@@ -11539,7 +11674,7 @@ async function main2() {
|
|
|
11539
11674
|
log3("");
|
|
11540
11675
|
const backupPath = entryFile + ".solongate-backup";
|
|
11541
11676
|
if (opts.restore) {
|
|
11542
|
-
if (!
|
|
11677
|
+
if (!existsSync9(backupPath)) {
|
|
11543
11678
|
log3(" No backup found. Nothing to restore.");
|
|
11544
11679
|
process.exit(1);
|
|
11545
11680
|
}
|
|
@@ -11575,12 +11710,12 @@ async function main2() {
|
|
|
11575
11710
|
log3(" To apply: npx @solongate/proxy inject");
|
|
11576
11711
|
process.exit(0);
|
|
11577
11712
|
}
|
|
11578
|
-
if (!
|
|
11713
|
+
if (!existsSync9(backupPath)) {
|
|
11579
11714
|
copyFileSync(entryFile, backupPath);
|
|
11580
11715
|
log3("");
|
|
11581
11716
|
log3(` Backup: ${backupPath}`);
|
|
11582
11717
|
}
|
|
11583
|
-
|
|
11718
|
+
writeFileSync6(entryFile, result.modified);
|
|
11584
11719
|
log3("");
|
|
11585
11720
|
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");
|
|
11586
11721
|
log3(" \u2502 SolonGate SDK injected successfully! \u2502");
|
|
@@ -11609,8 +11744,8 @@ var init_inject = __esm({
|
|
|
11609
11744
|
|
|
11610
11745
|
// src/create.ts
|
|
11611
11746
|
var create_exports = {};
|
|
11612
|
-
import { mkdirSync as mkdirSync5, writeFileSync as
|
|
11613
|
-
import { resolve as resolve8, join as
|
|
11747
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync7, existsSync as existsSync10 } from "fs";
|
|
11748
|
+
import { resolve as resolve8, join as join12 } from "path";
|
|
11614
11749
|
import { execSync as execSync2 } from "child_process";
|
|
11615
11750
|
function withSpinner(message, fn) {
|
|
11616
11751
|
const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
|
|
@@ -11689,8 +11824,8 @@ EXAMPLES
|
|
|
11689
11824
|
`);
|
|
11690
11825
|
}
|
|
11691
11826
|
function createProject(dir, name, _policy) {
|
|
11692
|
-
|
|
11693
|
-
|
|
11827
|
+
writeFileSync7(
|
|
11828
|
+
join12(dir, "package.json"),
|
|
11694
11829
|
JSON.stringify(
|
|
11695
11830
|
{
|
|
11696
11831
|
name,
|
|
@@ -11719,8 +11854,8 @@ function createProject(dir, name, _policy) {
|
|
|
11719
11854
|
2
|
|
11720
11855
|
) + "\n"
|
|
11721
11856
|
);
|
|
11722
|
-
|
|
11723
|
-
|
|
11857
|
+
writeFileSync7(
|
|
11858
|
+
join12(dir, "tsconfig.json"),
|
|
11724
11859
|
JSON.stringify(
|
|
11725
11860
|
{
|
|
11726
11861
|
compilerOptions: {
|
|
@@ -11740,9 +11875,9 @@ function createProject(dir, name, _policy) {
|
|
|
11740
11875
|
2
|
|
11741
11876
|
) + "\n"
|
|
11742
11877
|
);
|
|
11743
|
-
mkdirSync5(
|
|
11744
|
-
|
|
11745
|
-
|
|
11878
|
+
mkdirSync5(join12(dir, "src"), { recursive: true });
|
|
11879
|
+
writeFileSync7(
|
|
11880
|
+
join12(dir, "src", "index.ts"),
|
|
11746
11881
|
`#!/usr/bin/env node
|
|
11747
11882
|
|
|
11748
11883
|
console.log = (...args: unknown[]) => {
|
|
@@ -11783,8 +11918,8 @@ console.log('');
|
|
|
11783
11918
|
console.log('Press Ctrl+C to stop.');
|
|
11784
11919
|
`
|
|
11785
11920
|
);
|
|
11786
|
-
|
|
11787
|
-
|
|
11921
|
+
writeFileSync7(
|
|
11922
|
+
join12(dir, ".mcp.json"),
|
|
11788
11923
|
JSON.stringify(
|
|
11789
11924
|
{
|
|
11790
11925
|
mcpServers: {
|
|
@@ -11801,13 +11936,13 @@ console.log('Press Ctrl+C to stop.');
|
|
|
11801
11936
|
2
|
|
11802
11937
|
) + "\n"
|
|
11803
11938
|
);
|
|
11804
|
-
|
|
11805
|
-
|
|
11939
|
+
writeFileSync7(
|
|
11940
|
+
join12(dir, ".env"),
|
|
11806
11941
|
`SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
|
|
11807
11942
|
`
|
|
11808
11943
|
);
|
|
11809
|
-
|
|
11810
|
-
|
|
11944
|
+
writeFileSync7(
|
|
11945
|
+
join12(dir, ".gitignore"),
|
|
11811
11946
|
`node_modules/
|
|
11812
11947
|
dist/
|
|
11813
11948
|
*.solongate-backup
|
|
@@ -11821,7 +11956,7 @@ async function main3() {
|
|
|
11821
11956
|
const opts = parseCreateArgs(process.argv);
|
|
11822
11957
|
const dir = resolve8(opts.name);
|
|
11823
11958
|
printBanner("Create MCP Server");
|
|
11824
|
-
if (
|
|
11959
|
+
if (existsSync10(dir)) {
|
|
11825
11960
|
log3(` ${c.red}Error:${c.reset} Directory "${opts.name}" already exists.`);
|
|
11826
11961
|
process.exit(1);
|
|
11827
11962
|
}
|
|
@@ -11900,12 +12035,12 @@ var init_create = __esm({
|
|
|
11900
12035
|
|
|
11901
12036
|
// src/pull-push.ts
|
|
11902
12037
|
var pull_push_exports = {};
|
|
11903
|
-
import { readFileSync as readFileSync11, writeFileSync as
|
|
12038
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, existsSync as existsSync11 } from "fs";
|
|
11904
12039
|
import { resolve as resolve9 } from "path";
|
|
11905
12040
|
function loadEnv() {
|
|
11906
12041
|
if (process.env.SOLONGATE_API_KEY) return;
|
|
11907
12042
|
const envPath = resolve9(".env");
|
|
11908
|
-
if (!
|
|
12043
|
+
if (!existsSync11(envPath)) return;
|
|
11909
12044
|
try {
|
|
11910
12045
|
const content = readFileSync11(envPath, "utf-8");
|
|
11911
12046
|
for (const line of content.split("\n")) {
|
|
@@ -12095,7 +12230,7 @@ async function pull(apiKey, file, policyId) {
|
|
|
12095
12230
|
const policy = await fetchCloudPolicy(apiKey, API_URL, policyId);
|
|
12096
12231
|
const { id: _id, ...policyWithoutId } = policy;
|
|
12097
12232
|
const json = JSON.stringify(policyWithoutId, null, 2) + "\n";
|
|
12098
|
-
|
|
12233
|
+
writeFileSync8(file, json, "utf-8");
|
|
12099
12234
|
log5("");
|
|
12100
12235
|
log5(green2(" Saved to: ") + file);
|
|
12101
12236
|
log5(` ${dim2("Name:")} ${policy.name}`);
|
|
@@ -12107,7 +12242,7 @@ async function pull(apiKey, file, policyId) {
|
|
|
12107
12242
|
log5("");
|
|
12108
12243
|
}
|
|
12109
12244
|
async function push(apiKey, file, policyId) {
|
|
12110
|
-
if (!
|
|
12245
|
+
if (!existsSync11(file)) {
|
|
12111
12246
|
log5(red2(`ERROR: File not found: ${file}`));
|
|
12112
12247
|
process.exit(1);
|
|
12113
12248
|
}
|
package/dist/tui/index.js
CHANGED
|
@@ -150,10 +150,9 @@ function KeyHints({ hints }) {
|
|
|
150
150
|
// src/tui/panels/Live.tsx
|
|
151
151
|
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
152
152
|
import TextInput from "ink-text-input";
|
|
153
|
-
import {
|
|
154
|
-
import { closeSync, mkdirSync, openSync, readSync, statSync, writeFileSync } from "fs";
|
|
153
|
+
import { closeSync, mkdirSync, openSync, readSync, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
155
154
|
import { homedir as homedir3 } from "os";
|
|
156
|
-
import { join as
|
|
155
|
+
import { join as join4 } from "path";
|
|
157
156
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
158
157
|
|
|
159
158
|
// src/api-client/client.ts
|
|
@@ -489,6 +488,139 @@ function list4() {
|
|
|
489
488
|
// src/api-client/index.ts
|
|
490
489
|
var api = { policies: policies_exports, settings: settings_exports, stats: stats_exports, audit: audit_exports, agents: agents_exports, keys: keys_exports, mcp: mcp_exports };
|
|
491
490
|
|
|
491
|
+
// src/tui/notify.ts
|
|
492
|
+
import { spawn, execFileSync } from "child_process";
|
|
493
|
+
import { writeFileSync, existsSync as existsSync2 } from "fs";
|
|
494
|
+
import { join as join3 } from "path";
|
|
495
|
+
import { tmpdir } from "os";
|
|
496
|
+
var focusToken = null;
|
|
497
|
+
function captureFocusTarget() {
|
|
498
|
+
try {
|
|
499
|
+
if (process.platform === "linux") {
|
|
500
|
+
focusToken = (process.env.WINDOWID || "").trim() || null;
|
|
501
|
+
if (!focusToken) {
|
|
502
|
+
try {
|
|
503
|
+
focusToken = execFileSync("xdotool", ["getactivewindow"], { encoding: "utf-8", timeout: 1500, stdio: ["ignore", "pipe", "ignore"] }).trim() || null;
|
|
504
|
+
} catch {
|
|
505
|
+
focusToken = null;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
} else if (process.platform === "win32") {
|
|
509
|
+
const ps = `Add-Type -Name W -Namespace N -MemberDefinition '[DllImport("user32.dll")]public static extern System.IntPtr GetForegroundWindow();' | Out-Null; [N.W]::GetForegroundWindow().ToInt64()`;
|
|
510
|
+
try {
|
|
511
|
+
focusToken = execFileSync("powershell", ["-NoProfile", "-NonInteractive", "-Command", ps], { encoding: "utf-8", timeout: 4e3, stdio: ["ignore", "pipe", "ignore"] }).trim() || null;
|
|
512
|
+
} catch {
|
|
513
|
+
focusToken = null;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
} catch {
|
|
517
|
+
focusToken = null;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function desktopNotify(title, msg) {
|
|
521
|
+
try {
|
|
522
|
+
if (process.platform === "linux") linuxNotify(title, msg);
|
|
523
|
+
else if (process.platform === "win32") winNotify(title, msg);
|
|
524
|
+
else if (process.platform === "darwin") macNotify(title, msg);
|
|
525
|
+
} catch {
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function linuxNotify(title, msg) {
|
|
529
|
+
let p;
|
|
530
|
+
try {
|
|
531
|
+
p = spawn("notify-send", ["--wait", "--action=default=Open", "-a", "SolonGate", title, msg], { stdio: ["ignore", "pipe", "ignore"] });
|
|
532
|
+
} catch {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
p.on("error", () => {
|
|
536
|
+
});
|
|
537
|
+
p.stdout?.on("data", (d) => {
|
|
538
|
+
if (String(d).trim() === "default") raiseLinuxWindow();
|
|
539
|
+
});
|
|
540
|
+
p.unref();
|
|
541
|
+
}
|
|
542
|
+
function raiseLinuxWindow() {
|
|
543
|
+
if (!focusToken) return;
|
|
544
|
+
try {
|
|
545
|
+
const x = spawn("xdotool", ["windowactivate", focusToken], { stdio: "ignore" });
|
|
546
|
+
x.on("error", () => {
|
|
547
|
+
try {
|
|
548
|
+
const hex = "0x" + Number(focusToken).toString(16);
|
|
549
|
+
const w = spawn("wmctrl", ["-ia", hex], { stdio: "ignore" });
|
|
550
|
+
w.on("error", () => {
|
|
551
|
+
});
|
|
552
|
+
w.unref();
|
|
553
|
+
} catch {
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
x.unref();
|
|
557
|
+
} catch {
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
var winScriptPath = null;
|
|
561
|
+
function ensureWinScript() {
|
|
562
|
+
if (winScriptPath && existsSync2(winScriptPath)) return winScriptPath;
|
|
563
|
+
const p = join3(tmpdir(), "solongate-toast.ps1");
|
|
564
|
+
const script = [
|
|
565
|
+
"param([string]$Title,[string]$Msg,[string]$Hwnd)",
|
|
566
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
567
|
+
"Add-Type -AssemblyName System.Drawing",
|
|
568
|
+
`Add-Type -Name Win -Namespace Sg -MemberDefinition '[DllImport("user32.dll")]public static extern bool SetForegroundWindow(System.IntPtr h);[DllImport("user32.dll")]public static extern bool ShowWindow(System.IntPtr h,int c);'`,
|
|
569
|
+
"$ni=New-Object System.Windows.Forms.NotifyIcon",
|
|
570
|
+
"$ni.Icon=[System.Drawing.SystemIcons]::Information",
|
|
571
|
+
"$ni.Visible=$true",
|
|
572
|
+
"$script:clicked=$false",
|
|
573
|
+
"$ni.add_BalloonTipClicked({$script:clicked=$true})",
|
|
574
|
+
"$ni.ShowBalloonTip(8000,$Title,$Msg,[System.Windows.Forms.ToolTipIcon]::Warning)",
|
|
575
|
+
"$sw=[System.Diagnostics.Stopwatch]::StartNew()",
|
|
576
|
+
"while($sw.Elapsed.TotalSeconds -lt 9 -and -not $script:clicked){[System.Windows.Forms.Application]::DoEvents();Start-Sleep -Milliseconds 100}",
|
|
577
|
+
"if($script:clicked -and $Hwnd){try{$h=[System.IntPtr][int64]$Hwnd;[Sg.Win]::ShowWindow($h,9)|Out-Null;[Sg.Win]::SetForegroundWindow($h)|Out-Null}catch{}}",
|
|
578
|
+
"$ni.Visible=$false;$ni.Dispose()"
|
|
579
|
+
].join("\n");
|
|
580
|
+
try {
|
|
581
|
+
writeFileSync(p, script);
|
|
582
|
+
winScriptPath = p;
|
|
583
|
+
return p;
|
|
584
|
+
} catch {
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
function winNotify(title, msg) {
|
|
589
|
+
const script = ensureWinScript();
|
|
590
|
+
if (!script) return;
|
|
591
|
+
try {
|
|
592
|
+
const p = spawn("powershell", ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, "-Title", title, "-Msg", msg, "-Hwnd", focusToken || ""], { stdio: "ignore", detached: true, windowsHide: true });
|
|
593
|
+
p.on("error", () => {
|
|
594
|
+
});
|
|
595
|
+
p.unref();
|
|
596
|
+
} catch {
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function macBundleId() {
|
|
600
|
+
const prog = (process.env.TERM_PROGRAM || "").toLowerCase();
|
|
601
|
+
if (prog.includes("iterm")) return "com.googlecode.iterm2";
|
|
602
|
+
if (prog.includes("apple_terminal")) return "com.apple.Terminal";
|
|
603
|
+
if (prog.includes("vscode")) return "com.microsoft.VSCode";
|
|
604
|
+
return "com.apple.Terminal";
|
|
605
|
+
}
|
|
606
|
+
function macNotify(title, msg) {
|
|
607
|
+
try {
|
|
608
|
+
const p = spawn("terminal-notifier", ["-title", title, "-message", msg, "-activate", macBundleId(), "-sender", macBundleId()], { stdio: "ignore", detached: true });
|
|
609
|
+
p.on("error", () => {
|
|
610
|
+
try {
|
|
611
|
+
const esc = (s) => s.replace(/"/g, '\\"');
|
|
612
|
+
const a = spawn("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
|
|
613
|
+
a.on("error", () => {
|
|
614
|
+
});
|
|
615
|
+
a.unref();
|
|
616
|
+
} catch {
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
p.unref();
|
|
620
|
+
} catch {
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
492
624
|
// src/tui/hooks.ts
|
|
493
625
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
494
626
|
function useLoader(fn, deps = []) {
|
|
@@ -535,8 +667,8 @@ var CONFIG = loadConfig();
|
|
|
535
667
|
var SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
536
668
|
var BG = "#12234f";
|
|
537
669
|
var DIM_FLOOR = "#233457";
|
|
538
|
-
var LOCAL_LOG =
|
|
539
|
-
var RING =
|
|
670
|
+
var LOCAL_LOG = join4(homedir3(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
671
|
+
var RING = join4(process.cwd(), ".solongate", ".eval-ring.jsonl");
|
|
540
672
|
var hhmmss = (ts) => {
|
|
541
673
|
const d = new Date(ts);
|
|
542
674
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
@@ -865,13 +997,7 @@ function LivePanel({ active: active2 }) {
|
|
|
865
997
|
process.stdout.write("\x07");
|
|
866
998
|
} catch {
|
|
867
999
|
}
|
|
868
|
-
|
|
869
|
-
const child = spawn("notify-send", ["-a", "SolonGate", title, msg], { stdio: "ignore", detached: true });
|
|
870
|
-
child.on("error", () => {
|
|
871
|
-
});
|
|
872
|
-
child.unref();
|
|
873
|
-
} catch {
|
|
874
|
-
}
|
|
1000
|
+
desktopNotify(title, msg);
|
|
875
1001
|
},
|
|
876
1002
|
[pushLog]
|
|
877
1003
|
);
|
|
@@ -1085,10 +1211,10 @@ function LivePanel({ active: active2 }) {
|
|
|
1085
1211
|
else if (input === "x") toggleSignal("dlp");
|
|
1086
1212
|
else if (input === "r") toggleSignal("ratelimit");
|
|
1087
1213
|
else if (input === "e") {
|
|
1088
|
-
const file =
|
|
1214
|
+
const file = join4(homedir3(), ".solongate", "live-export.jsonl");
|
|
1089
1215
|
try {
|
|
1090
|
-
mkdirSync(
|
|
1091
|
-
|
|
1216
|
+
mkdirSync(join4(homedir3(), ".solongate"), { recursive: true });
|
|
1217
|
+
writeFileSync2(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
|
|
1092
1218
|
setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
|
|
1093
1219
|
} catch (err) {
|
|
1094
1220
|
setActionMsg({ text: "\u2717 export failed: " + (err instanceof Error ? err.message : String(err)), level: "bad", until: Date.now() + 6e3 });
|
|
@@ -2457,6 +2583,7 @@ async function launchTui() {
|
|
|
2457
2583
|
process.stderr.write("Not logged in. Run `solongate login` first.\n");
|
|
2458
2584
|
return;
|
|
2459
2585
|
}
|
|
2586
|
+
captureFocusTarget();
|
|
2460
2587
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
2461
2588
|
try {
|
|
2462
2589
|
const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}));
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Capture the current terminal window once, at TUI startup. Cheap + best-effort. */
|
|
2
|
+
export declare function captureFocusTarget(): void;
|
|
3
|
+
/** Fire a desktop toast; clicking it raises the dataroom terminal. */
|
|
4
|
+
export declare function desktopNotify(title: string, msg: string): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.17",
|
|
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": {
|