@solongate/proxy 0.81.16 → 0.81.18
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 +251 -112
- package/dist/tui/index.js +146 -15
- package/dist/tui/notify.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7089,6 +7089,149 @@ 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
|
+
try {
|
|
7144
|
+
process.stdout.write("\x1B[5t");
|
|
7145
|
+
} catch {
|
|
7146
|
+
}
|
|
7147
|
+
if (!focusToken) return;
|
|
7148
|
+
try {
|
|
7149
|
+
const x = spawn("xdotool", ["windowactivate", focusToken], { stdio: "ignore" });
|
|
7150
|
+
x.on("error", () => {
|
|
7151
|
+
try {
|
|
7152
|
+
const hex = "0x" + Number(focusToken).toString(16);
|
|
7153
|
+
const w = spawn("wmctrl", ["-ia", hex], { stdio: "ignore" });
|
|
7154
|
+
w.on("error", () => {
|
|
7155
|
+
});
|
|
7156
|
+
w.unref();
|
|
7157
|
+
} catch {
|
|
7158
|
+
}
|
|
7159
|
+
});
|
|
7160
|
+
x.unref();
|
|
7161
|
+
} catch {
|
|
7162
|
+
}
|
|
7163
|
+
}
|
|
7164
|
+
function ensureWinScript() {
|
|
7165
|
+
if (winScriptPath && existsSync4(winScriptPath)) return winScriptPath;
|
|
7166
|
+
const p = join6(tmpdir2(), "solongate-toast.ps1");
|
|
7167
|
+
const script = [
|
|
7168
|
+
"param([string]$Title,[string]$Msg,[string]$Hwnd)",
|
|
7169
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
7170
|
+
"Add-Type -AssemblyName System.Drawing",
|
|
7171
|
+
`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);'`,
|
|
7172
|
+
"$ni=New-Object System.Windows.Forms.NotifyIcon",
|
|
7173
|
+
"$ni.Icon=[System.Drawing.SystemIcons]::Information",
|
|
7174
|
+
"$ni.Visible=$true",
|
|
7175
|
+
"$script:clicked=$false",
|
|
7176
|
+
"$ni.add_BalloonTipClicked({$script:clicked=$true})",
|
|
7177
|
+
"$ni.ShowBalloonTip(8000,$Title,$Msg,[System.Windows.Forms.ToolTipIcon]::Warning)",
|
|
7178
|
+
"$sw=[System.Diagnostics.Stopwatch]::StartNew()",
|
|
7179
|
+
"while($sw.Elapsed.TotalSeconds -lt 9 -and -not $script:clicked){[System.Windows.Forms.Application]::DoEvents();Start-Sleep -Milliseconds 100}",
|
|
7180
|
+
"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{}}",
|
|
7181
|
+
"$ni.Visible=$false;$ni.Dispose()"
|
|
7182
|
+
].join("\n");
|
|
7183
|
+
try {
|
|
7184
|
+
writeFileSync3(p, script);
|
|
7185
|
+
winScriptPath = p;
|
|
7186
|
+
return p;
|
|
7187
|
+
} catch {
|
|
7188
|
+
return null;
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7191
|
+
function winNotify(title, msg) {
|
|
7192
|
+
const script = ensureWinScript();
|
|
7193
|
+
if (!script) return;
|
|
7194
|
+
try {
|
|
7195
|
+
const p = spawn("powershell", ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, "-Title", title, "-Msg", msg, "-Hwnd", focusToken || ""], { stdio: "ignore", detached: true, windowsHide: true });
|
|
7196
|
+
p.on("error", () => {
|
|
7197
|
+
});
|
|
7198
|
+
p.unref();
|
|
7199
|
+
} catch {
|
|
7200
|
+
}
|
|
7201
|
+
}
|
|
7202
|
+
function macBundleId() {
|
|
7203
|
+
const prog = (process.env.TERM_PROGRAM || "").toLowerCase();
|
|
7204
|
+
if (prog.includes("iterm")) return "com.googlecode.iterm2";
|
|
7205
|
+
if (prog.includes("apple_terminal")) return "com.apple.Terminal";
|
|
7206
|
+
if (prog.includes("vscode")) return "com.microsoft.VSCode";
|
|
7207
|
+
return "com.apple.Terminal";
|
|
7208
|
+
}
|
|
7209
|
+
function macNotify(title, msg) {
|
|
7210
|
+
try {
|
|
7211
|
+
const p = spawn("terminal-notifier", ["-title", title, "-message", msg, "-activate", macBundleId(), "-sender", macBundleId()], { stdio: "ignore", detached: true });
|
|
7212
|
+
p.on("error", () => {
|
|
7213
|
+
try {
|
|
7214
|
+
const esc = (s) => s.replace(/"/g, '\\"');
|
|
7215
|
+
const a = spawn("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
|
|
7216
|
+
a.on("error", () => {
|
|
7217
|
+
});
|
|
7218
|
+
a.unref();
|
|
7219
|
+
} catch {
|
|
7220
|
+
}
|
|
7221
|
+
});
|
|
7222
|
+
p.unref();
|
|
7223
|
+
} catch {
|
|
7224
|
+
}
|
|
7225
|
+
}
|
|
7226
|
+
var focusToken, winScriptPath;
|
|
7227
|
+
var init_notify = __esm({
|
|
7228
|
+
"src/tui/notify.ts"() {
|
|
7229
|
+
"use strict";
|
|
7230
|
+
focusToken = null;
|
|
7231
|
+
winScriptPath = null;
|
|
7232
|
+
}
|
|
7233
|
+
});
|
|
7234
|
+
|
|
7092
7235
|
// src/tui/hooks.ts
|
|
7093
7236
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
7094
7237
|
function useLoader(fn, deps = []) {
|
|
@@ -7137,10 +7280,9 @@ var init_hooks = __esm({
|
|
|
7137
7280
|
// src/tui/panels/Live.tsx
|
|
7138
7281
|
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
7139
7282
|
import TextInput from "ink-text-input";
|
|
7140
|
-
import {
|
|
7141
|
-
import { closeSync, mkdirSync as mkdirSync3, openSync, readSync, statSync, writeFileSync as writeFileSync3 } from "fs";
|
|
7283
|
+
import { closeSync, mkdirSync as mkdirSync3, openSync, readSync, statSync, writeFileSync as writeFileSync4 } from "fs";
|
|
7142
7284
|
import { homedir as homedir4 } from "os";
|
|
7143
|
-
import { join as
|
|
7285
|
+
import { join as join7 } from "path";
|
|
7144
7286
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
7145
7287
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
7146
7288
|
function tailLines(file, maxBytes = 131072) {
|
|
@@ -7455,13 +7597,7 @@ function LivePanel({ active: active2 }) {
|
|
|
7455
7597
|
process.stdout.write("\x07");
|
|
7456
7598
|
} catch {
|
|
7457
7599
|
}
|
|
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
|
-
}
|
|
7600
|
+
desktopNotify(title, msg);
|
|
7465
7601
|
},
|
|
7466
7602
|
[pushLog]
|
|
7467
7603
|
);
|
|
@@ -7675,10 +7811,10 @@ function LivePanel({ active: active2 }) {
|
|
|
7675
7811
|
else if (input === "x") toggleSignal("dlp");
|
|
7676
7812
|
else if (input === "r") toggleSignal("ratelimit");
|
|
7677
7813
|
else if (input === "e") {
|
|
7678
|
-
const file =
|
|
7814
|
+
const file = join7(homedir4(), ".solongate", "live-export.jsonl");
|
|
7679
7815
|
try {
|
|
7680
|
-
mkdirSync3(
|
|
7681
|
-
|
|
7816
|
+
mkdirSync3(join7(homedir4(), ".solongate"), { recursive: true });
|
|
7817
|
+
writeFileSync4(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
|
|
7682
7818
|
setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
|
|
7683
7819
|
} catch (err2) {
|
|
7684
7820
|
setActionMsg({ text: "\u2717 export failed: " + (err2 instanceof Error ? err2.message : String(err2)), level: "bad", until: Date.now() + 6e3 });
|
|
@@ -7938,14 +8074,15 @@ var init_Live = __esm({
|
|
|
7938
8074
|
"use strict";
|
|
7939
8075
|
init_api_client();
|
|
7940
8076
|
init_config2();
|
|
8077
|
+
init_notify();
|
|
7941
8078
|
init_hooks();
|
|
7942
8079
|
init_theme();
|
|
7943
8080
|
CONFIG = loadConfig();
|
|
7944
8081
|
SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
7945
8082
|
BG = "#12234f";
|
|
7946
8083
|
DIM_FLOOR = "#233457";
|
|
7947
|
-
LOCAL_LOG =
|
|
7948
|
-
RING =
|
|
8084
|
+
LOCAL_LOG = join7(homedir4(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
8085
|
+
RING = join7(process.cwd(), ".solongate", ".eval-ring.jsonl");
|
|
7949
8086
|
hhmmss = (ts) => {
|
|
7950
8087
|
const d = new Date(ts);
|
|
7951
8088
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
@@ -9161,6 +9298,7 @@ async function launchTui() {
|
|
|
9161
9298
|
process.stderr.write("Not logged in. Run `solongate login` first.\n");
|
|
9162
9299
|
return;
|
|
9163
9300
|
}
|
|
9301
|
+
captureFocusTarget();
|
|
9164
9302
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
9165
9303
|
try {
|
|
9166
9304
|
const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}));
|
|
@@ -9174,6 +9312,7 @@ var init_tui = __esm({
|
|
|
9174
9312
|
"use strict";
|
|
9175
9313
|
init_App();
|
|
9176
9314
|
init_client();
|
|
9315
|
+
init_notify();
|
|
9177
9316
|
}
|
|
9178
9317
|
});
|
|
9179
9318
|
|
|
@@ -9865,9 +10004,9 @@ var init_agents2 = __esm({
|
|
|
9865
10004
|
});
|
|
9866
10005
|
|
|
9867
10006
|
// src/commands/doctor.ts
|
|
9868
|
-
import { existsSync as
|
|
10007
|
+
import { existsSync as existsSync5, statSync as statSync2 } from "fs";
|
|
9869
10008
|
import { homedir as homedir5 } from "os";
|
|
9870
|
-
import { join as
|
|
10009
|
+
import { join as join8 } from "path";
|
|
9871
10010
|
async function run6(argv) {
|
|
9872
10011
|
const { flags } = parse(argv);
|
|
9873
10012
|
const json = flagBool(flags, "json");
|
|
@@ -9897,7 +10036,7 @@ async function run6(argv) {
|
|
|
9897
10036
|
} catch {
|
|
9898
10037
|
}
|
|
9899
10038
|
}
|
|
9900
|
-
if (
|
|
10039
|
+
if (existsSync5(LOCAL_LOG2)) {
|
|
9901
10040
|
const st = statSync2(LOCAL_LOG2);
|
|
9902
10041
|
const ageMin = (Date.now() - st.mtimeMs) / 6e4;
|
|
9903
10042
|
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 +10066,14 @@ var init_doctor = __esm({
|
|
|
9927
10066
|
init_api_client();
|
|
9928
10067
|
init_format();
|
|
9929
10068
|
init_args();
|
|
9930
|
-
LOCAL_LOG2 =
|
|
10069
|
+
LOCAL_LOG2 = join8(homedir5(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
9931
10070
|
}
|
|
9932
10071
|
});
|
|
9933
10072
|
|
|
9934
10073
|
// src/commands/watch.ts
|
|
9935
|
-
import { closeSync as closeSync2, existsSync as
|
|
10074
|
+
import { closeSync as closeSync2, existsSync as existsSync6, openSync as openSync2, readSync as readSync2, statSync as statSync3 } from "fs";
|
|
9936
10075
|
import { homedir as homedir6 } from "os";
|
|
9937
|
-
import { join as
|
|
10076
|
+
import { join as join9 } from "path";
|
|
9938
10077
|
function tailLocal(file, maxBytes = 131072) {
|
|
9939
10078
|
try {
|
|
9940
10079
|
const size = statSync3(file).size;
|
|
@@ -9978,7 +10117,7 @@ async function run7(argv) {
|
|
|
9978
10117
|
for (const r of rows) if (keep(r)) print(r, json);
|
|
9979
10118
|
};
|
|
9980
10119
|
const pollLocal = () => {
|
|
9981
|
-
if (cloudOnly || !
|
|
10120
|
+
if (cloudOnly || !existsSync6(LOCAL_LOG3)) return;
|
|
9982
10121
|
const rows = [];
|
|
9983
10122
|
for (const line of tailLocal(LOCAL_LOG3)) {
|
|
9984
10123
|
try {
|
|
@@ -10041,7 +10180,7 @@ var init_watch = __esm({
|
|
|
10041
10180
|
init_cli_utils();
|
|
10042
10181
|
init_args();
|
|
10043
10182
|
init_format();
|
|
10044
|
-
LOCAL_LOG3 =
|
|
10183
|
+
LOCAL_LOG3 = join9(homedir6(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
10045
10184
|
trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
10046
10185
|
time = (ms) => new Date(ms).toTimeString().slice(0, 8);
|
|
10047
10186
|
}
|
|
@@ -10343,32 +10482,32 @@ __export(global_install_exports, {
|
|
|
10343
10482
|
runGlobalRestore: () => runGlobalRestore,
|
|
10344
10483
|
unlockProtected: () => unlockProtected
|
|
10345
10484
|
});
|
|
10346
|
-
import { readFileSync as readFileSync7, writeFileSync as
|
|
10347
|
-
import { resolve as resolve4, join as
|
|
10485
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync7, mkdirSync as mkdirSync4 } from "fs";
|
|
10486
|
+
import { resolve as resolve4, join as join10, dirname } from "path";
|
|
10348
10487
|
import { homedir as homedir7 } from "os";
|
|
10349
10488
|
import { fileURLToPath } from "url";
|
|
10350
10489
|
import { createInterface } from "readline";
|
|
10351
|
-
import { execFileSync as
|
|
10490
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
10352
10491
|
function lockFile(file) {
|
|
10353
|
-
if (!
|
|
10492
|
+
if (!existsSync7(file)) return;
|
|
10354
10493
|
try {
|
|
10355
10494
|
if (process.platform === "win32") {
|
|
10356
10495
|
try {
|
|
10357
|
-
|
|
10496
|
+
execFileSync3("icacls", [file, "/deny", "*S-1-1-0:(WD,AD,DC,DE)"], { stdio: "ignore" });
|
|
10358
10497
|
} catch {
|
|
10359
10498
|
}
|
|
10360
10499
|
try {
|
|
10361
|
-
|
|
10500
|
+
execFileSync3("attrib", ["+R", file], { stdio: "ignore" });
|
|
10362
10501
|
} catch {
|
|
10363
10502
|
}
|
|
10364
10503
|
} else if (process.platform === "darwin") {
|
|
10365
10504
|
try {
|
|
10366
|
-
|
|
10505
|
+
execFileSync3("chflags", ["uchg", file], { stdio: "ignore" });
|
|
10367
10506
|
} catch {
|
|
10368
10507
|
}
|
|
10369
10508
|
} else {
|
|
10370
10509
|
try {
|
|
10371
|
-
|
|
10510
|
+
execFileSync3("chattr", ["+i", file], { stdio: "ignore" });
|
|
10372
10511
|
} catch {
|
|
10373
10512
|
}
|
|
10374
10513
|
}
|
|
@@ -10376,29 +10515,29 @@ function lockFile(file) {
|
|
|
10376
10515
|
}
|
|
10377
10516
|
}
|
|
10378
10517
|
function unlockFile(file) {
|
|
10379
|
-
if (!
|
|
10518
|
+
if (!existsSync7(file)) return;
|
|
10380
10519
|
try {
|
|
10381
10520
|
if (process.platform === "win32") {
|
|
10382
10521
|
try {
|
|
10383
|
-
|
|
10522
|
+
execFileSync3("icacls", [file, "/remove:d", "*S-1-1-0"], { stdio: "ignore" });
|
|
10384
10523
|
} catch {
|
|
10385
10524
|
}
|
|
10386
10525
|
try {
|
|
10387
|
-
|
|
10526
|
+
execFileSync3("icacls", [file, "/reset"], { stdio: "ignore" });
|
|
10388
10527
|
} catch {
|
|
10389
10528
|
}
|
|
10390
10529
|
try {
|
|
10391
|
-
|
|
10530
|
+
execFileSync3("attrib", ["-R", file], { stdio: "ignore" });
|
|
10392
10531
|
} catch {
|
|
10393
10532
|
}
|
|
10394
10533
|
} else if (process.platform === "darwin") {
|
|
10395
10534
|
try {
|
|
10396
|
-
|
|
10535
|
+
execFileSync3("chflags", ["nouchg", file], { stdio: "ignore" });
|
|
10397
10536
|
} catch {
|
|
10398
10537
|
}
|
|
10399
10538
|
} else {
|
|
10400
10539
|
try {
|
|
10401
|
-
|
|
10540
|
+
execFileSync3("chattr", ["-i", file], { stdio: "ignore" });
|
|
10402
10541
|
} catch {
|
|
10403
10542
|
}
|
|
10404
10543
|
}
|
|
@@ -10408,10 +10547,10 @@ function unlockFile(file) {
|
|
|
10408
10547
|
function protectedTargets() {
|
|
10409
10548
|
const p = globalPaths();
|
|
10410
10549
|
return [
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10550
|
+
join10(p.hooksDir, "guard.mjs"),
|
|
10551
|
+
join10(p.hooksDir, "audit.mjs"),
|
|
10552
|
+
join10(p.hooksDir, "stop.mjs"),
|
|
10553
|
+
join10(p.hooksDir, "shield.mjs"),
|
|
10415
10554
|
p.configPath,
|
|
10416
10555
|
p.settingsPath
|
|
10417
10556
|
];
|
|
@@ -10424,25 +10563,25 @@ function unlockProtected() {
|
|
|
10424
10563
|
}
|
|
10425
10564
|
function globalPaths() {
|
|
10426
10565
|
const home = homedir7();
|
|
10427
|
-
const sgDir =
|
|
10428
|
-
const hooksDir =
|
|
10429
|
-
const claudeDir =
|
|
10566
|
+
const sgDir = join10(home, ".solongate");
|
|
10567
|
+
const hooksDir = join10(sgDir, "hooks");
|
|
10568
|
+
const claudeDir = join10(home, ".claude");
|
|
10430
10569
|
return {
|
|
10431
10570
|
home,
|
|
10432
10571
|
sgDir,
|
|
10433
10572
|
hooksDir,
|
|
10434
10573
|
claudeDir,
|
|
10435
|
-
settingsPath:
|
|
10436
|
-
backupPath:
|
|
10437
|
-
configPath:
|
|
10574
|
+
settingsPath: join10(claudeDir, "settings.json"),
|
|
10575
|
+
backupPath: join10(claudeDir, "settings.solongate.bak"),
|
|
10576
|
+
configPath: join10(sgDir, "cloud-guard.json")
|
|
10438
10577
|
};
|
|
10439
10578
|
}
|
|
10440
10579
|
function readHook(filename) {
|
|
10441
|
-
return readFileSync7(
|
|
10580
|
+
return readFileSync7(join10(HOOKS_DIR, filename), "utf-8");
|
|
10442
10581
|
}
|
|
10443
10582
|
function readGuard() {
|
|
10444
|
-
const bundled =
|
|
10445
|
-
return
|
|
10583
|
+
const bundled = join10(HOOKS_DIR, "guard.bundled.mjs");
|
|
10584
|
+
return existsSync7(bundled) ? readFileSync7(bundled, "utf-8") : readHook("guard.mjs");
|
|
10446
10585
|
}
|
|
10447
10586
|
function ask(question) {
|
|
10448
10587
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -10455,14 +10594,14 @@ function runGlobalRestore() {
|
|
|
10455
10594
|
const p = globalPaths();
|
|
10456
10595
|
unlockProtected();
|
|
10457
10596
|
removeClaudeShim();
|
|
10458
|
-
if (
|
|
10459
|
-
|
|
10597
|
+
if (existsSync7(p.backupPath)) {
|
|
10598
|
+
writeFileSync5(p.settingsPath, readFileSync7(p.backupPath, "utf-8"));
|
|
10460
10599
|
console.log(` Restored ${p.settingsPath} from backup.`);
|
|
10461
|
-
} else if (
|
|
10600
|
+
} else if (existsSync7(p.settingsPath)) {
|
|
10462
10601
|
try {
|
|
10463
10602
|
const s = JSON.parse(readFileSync7(p.settingsPath, "utf-8"));
|
|
10464
10603
|
delete s.hooks;
|
|
10465
|
-
|
|
10604
|
+
writeFileSync5(p.settingsPath, JSON.stringify(s, null, 2) + "\n");
|
|
10466
10605
|
console.log(` Removed SolonGate hooks from ${p.settingsPath}.`);
|
|
10467
10606
|
} catch {
|
|
10468
10607
|
}
|
|
@@ -10477,7 +10616,7 @@ function escapeRe(s) {
|
|
|
10477
10616
|
function resolveRealClaude() {
|
|
10478
10617
|
try {
|
|
10479
10618
|
const finder = process.platform === "win32" ? "where" : "which";
|
|
10480
|
-
const out2 =
|
|
10619
|
+
const out2 = execFileSync3(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
10481
10620
|
if (process.platform === "win32") {
|
|
10482
10621
|
const low = (s) => s.toLowerCase();
|
|
10483
10622
|
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 +10629,24 @@ function resolveRealClaude() {
|
|
|
10490
10629
|
function shimTargets() {
|
|
10491
10630
|
if (process.platform === "win32") {
|
|
10492
10631
|
try {
|
|
10493
|
-
const prof =
|
|
10632
|
+
const prof = execFileSync3("powershell", ["-NoProfile", "-Command", "$PROFILE.CurrentUserAllHosts"], { encoding: "utf-8" }).trim();
|
|
10494
10633
|
return prof ? [prof] : [];
|
|
10495
10634
|
} catch {
|
|
10496
10635
|
return [];
|
|
10497
10636
|
}
|
|
10498
10637
|
}
|
|
10499
|
-
return [".bashrc", ".zshrc", ".profile"].map((f) =>
|
|
10638
|
+
return [".bashrc", ".zshrc", ".profile"].map((f) => join10(homedir7(), f)).filter((f) => existsSync7(f));
|
|
10500
10639
|
}
|
|
10501
10640
|
function writeShimBlock(file, block2) {
|
|
10502
10641
|
const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
|
|
10503
|
-
let content =
|
|
10642
|
+
let content = existsSync7(file) ? readFileSync7(file, "utf-8") : "";
|
|
10504
10643
|
content = content.replace(re, "");
|
|
10505
10644
|
if (block2) {
|
|
10506
10645
|
if (content.length && !content.endsWith("\n")) content += "\n";
|
|
10507
10646
|
content += block2 + "\n";
|
|
10508
10647
|
}
|
|
10509
10648
|
mkdirSync4(dirname(file), { recursive: true });
|
|
10510
|
-
|
|
10649
|
+
writeFileSync5(file, content);
|
|
10511
10650
|
}
|
|
10512
10651
|
function installClaudeShim(shieldPath) {
|
|
10513
10652
|
const real = resolveRealClaude();
|
|
@@ -10561,19 +10700,19 @@ async function runGlobalInstall(opts = {}) {
|
|
|
10561
10700
|
mkdirSync4(p.hooksDir, { recursive: true });
|
|
10562
10701
|
mkdirSync4(p.claudeDir, { recursive: true });
|
|
10563
10702
|
unlockProtected();
|
|
10564
|
-
|
|
10565
|
-
|
|
10566
|
-
|
|
10567
|
-
|
|
10703
|
+
writeFileSync5(join10(p.hooksDir, "guard.mjs"), readGuard());
|
|
10704
|
+
writeFileSync5(join10(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
|
|
10705
|
+
writeFileSync5(join10(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
|
|
10706
|
+
writeFileSync5(join10(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
|
|
10568
10707
|
console.log(` Installed hooks \u2192 ${p.hooksDir}`);
|
|
10569
|
-
installClaudeShim(
|
|
10570
|
-
|
|
10708
|
+
installClaudeShim(join10(p.hooksDir, "shield.mjs"));
|
|
10709
|
+
writeFileSync5(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
|
|
10571
10710
|
console.log(` Wrote ${p.configPath}`);
|
|
10572
10711
|
let existing = {};
|
|
10573
|
-
if (
|
|
10712
|
+
if (existsSync7(p.settingsPath)) {
|
|
10574
10713
|
const raw = readFileSync7(p.settingsPath, "utf-8");
|
|
10575
|
-
if (!
|
|
10576
|
-
|
|
10714
|
+
if (!existsSync7(p.backupPath)) {
|
|
10715
|
+
writeFileSync5(p.backupPath, raw);
|
|
10577
10716
|
console.log(` Backed up existing settings \u2192 ${p.backupPath}`);
|
|
10578
10717
|
}
|
|
10579
10718
|
try {
|
|
@@ -10582,9 +10721,9 @@ async function runGlobalInstall(opts = {}) {
|
|
|
10582
10721
|
existing = {};
|
|
10583
10722
|
}
|
|
10584
10723
|
}
|
|
10585
|
-
const guardAbs =
|
|
10586
|
-
const auditAbs =
|
|
10587
|
-
const stopAbs =
|
|
10724
|
+
const guardAbs = join10(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
|
|
10725
|
+
const auditAbs = join10(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
|
|
10726
|
+
const stopAbs = join10(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
|
|
10588
10727
|
const nodeBin = process.execPath.replace(/\\/g, "/");
|
|
10589
10728
|
const call = process.platform === "win32" ? "& " : "";
|
|
10590
10729
|
const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
|
|
@@ -10596,7 +10735,7 @@ async function runGlobalInstall(opts = {}) {
|
|
|
10596
10735
|
Stop: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(stopAbs) }] }]
|
|
10597
10736
|
}
|
|
10598
10737
|
};
|
|
10599
|
-
|
|
10738
|
+
writeFileSync5(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
10600
10739
|
console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
|
|
10601
10740
|
if (process.env["SOLONGATE_OS_LOCK"] === "1") {
|
|
10602
10741
|
lockProtected();
|
|
@@ -10776,7 +10915,7 @@ import { createServer, request as httpRequest } from "http";
|
|
|
10776
10915
|
import { request as httpsRequest } from "https";
|
|
10777
10916
|
import { spawn as spawn3 } from "child_process";
|
|
10778
10917
|
import { URL as URL2 } from "url";
|
|
10779
|
-
import { readFileSync as readFileSync8, existsSync as
|
|
10918
|
+
import { readFileSync as readFileSync8, existsSync as existsSync8, readdirSync, statSync as statSync4 } from "fs";
|
|
10780
10919
|
import { resolve as resolve5 } from "path";
|
|
10781
10920
|
import { homedir as homedir8 } from "os";
|
|
10782
10921
|
function findCacheFile() {
|
|
@@ -10784,7 +10923,7 @@ function findCacheFile() {
|
|
|
10784
10923
|
const envSel = process.env.SOLONGATE_AGENT_ID;
|
|
10785
10924
|
if (envSel) {
|
|
10786
10925
|
const f = resolve5(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
|
|
10787
|
-
if (
|
|
10926
|
+
if (existsSync8(f)) return f;
|
|
10788
10927
|
}
|
|
10789
10928
|
let best = null, bestTs = -1;
|
|
10790
10929
|
try {
|
|
@@ -10805,7 +10944,7 @@ function findCacheFile() {
|
|
|
10805
10944
|
function loadCfg() {
|
|
10806
10945
|
try {
|
|
10807
10946
|
const f = findCacheFile();
|
|
10808
|
-
if (f &&
|
|
10947
|
+
if (f && existsSync8(f)) {
|
|
10809
10948
|
const c2 = JSON.parse(readFileSync8(f, "utf-8"));
|
|
10810
10949
|
const d = c2?.security?.dlpRedact;
|
|
10811
10950
|
const g = c2?.security?.ghost;
|
|
@@ -11095,7 +11234,7 @@ __export(logs_server_exports, {
|
|
|
11095
11234
|
});
|
|
11096
11235
|
import { createServer as createServer2 } from "http";
|
|
11097
11236
|
import { readFileSync as readFileSync9, statSync as statSync5 } from "fs";
|
|
11098
|
-
import { resolve as resolve6, join as
|
|
11237
|
+
import { resolve as resolve6, join as join11, isAbsolute } from "path";
|
|
11099
11238
|
import { homedir as homedir9 } from "os";
|
|
11100
11239
|
import { readdirSync as readdirSync2 } from "fs";
|
|
11101
11240
|
function allowedOrigins() {
|
|
@@ -11121,7 +11260,7 @@ async function findLogDir() {
|
|
|
11121
11260
|
const files = readdirSync2(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
|
|
11122
11261
|
for (const f of files) {
|
|
11123
11262
|
try {
|
|
11124
|
-
const c2 = JSON.parse(readFileSync9(
|
|
11263
|
+
const c2 = JSON.parse(readFileSync9(join11(base, f), "utf-8"));
|
|
11125
11264
|
const p = c2?.security?.localLogs?.path;
|
|
11126
11265
|
if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
|
|
11127
11266
|
} catch {
|
|
@@ -11130,7 +11269,7 @@ async function findLogDir() {
|
|
|
11130
11269
|
} catch {
|
|
11131
11270
|
}
|
|
11132
11271
|
try {
|
|
11133
|
-
const cfgRaw = readFileSync9(
|
|
11272
|
+
const cfgRaw = readFileSync9(join11(base, "cloud-guard.json"), "utf-8");
|
|
11134
11273
|
const { apiKey, apiUrl } = JSON.parse(cfgRaw);
|
|
11135
11274
|
if (apiKey) {
|
|
11136
11275
|
const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
|
|
@@ -11159,7 +11298,7 @@ function setCors(req, res) {
|
|
|
11159
11298
|
}
|
|
11160
11299
|
function fileInfo(dir) {
|
|
11161
11300
|
if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
|
|
11162
|
-
const file =
|
|
11301
|
+
const file = join11(dir, LOG_FILENAME);
|
|
11163
11302
|
try {
|
|
11164
11303
|
const st = statSync5(file);
|
|
11165
11304
|
return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
|
|
@@ -11272,7 +11411,7 @@ var init_logs_server = __esm({
|
|
|
11272
11411
|
|
|
11273
11412
|
// src/inject.ts
|
|
11274
11413
|
var inject_exports = {};
|
|
11275
|
-
import { readFileSync as readFileSync10, writeFileSync as
|
|
11414
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, existsSync as existsSync9, copyFileSync } from "fs";
|
|
11276
11415
|
import { resolve as resolve7 } from "path";
|
|
11277
11416
|
import { execSync } from "child_process";
|
|
11278
11417
|
function parseInjectArgs(argv) {
|
|
@@ -11330,7 +11469,7 @@ WHAT IT DOES
|
|
|
11330
11469
|
`);
|
|
11331
11470
|
}
|
|
11332
11471
|
function detectProject() {
|
|
11333
|
-
if (!
|
|
11472
|
+
if (!existsSync9(resolve7("package.json"))) return false;
|
|
11334
11473
|
try {
|
|
11335
11474
|
const pkg = JSON.parse(readFileSync10(resolve7("package.json"), "utf-8"));
|
|
11336
11475
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
@@ -11346,13 +11485,13 @@ function findTsEntryFile() {
|
|
|
11346
11485
|
const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
|
|
11347
11486
|
if (typeof binPath === "string") {
|
|
11348
11487
|
const srcPath = binPath.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
|
|
11349
|
-
if (
|
|
11350
|
-
if (
|
|
11488
|
+
if (existsSync9(resolve7(srcPath))) return resolve7(srcPath);
|
|
11489
|
+
if (existsSync9(resolve7(binPath))) return resolve7(binPath);
|
|
11351
11490
|
}
|
|
11352
11491
|
}
|
|
11353
11492
|
if (pkg.main) {
|
|
11354
11493
|
const srcPath = pkg.main.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
|
|
11355
|
-
if (
|
|
11494
|
+
if (existsSync9(resolve7(srcPath))) return resolve7(srcPath);
|
|
11356
11495
|
}
|
|
11357
11496
|
} catch {
|
|
11358
11497
|
}
|
|
@@ -11366,7 +11505,7 @@ function findTsEntryFile() {
|
|
|
11366
11505
|
];
|
|
11367
11506
|
for (const c2 of candidates) {
|
|
11368
11507
|
const full = resolve7(c2);
|
|
11369
|
-
if (
|
|
11508
|
+
if (existsSync9(full)) {
|
|
11370
11509
|
try {
|
|
11371
11510
|
const content = readFileSync10(full, "utf-8");
|
|
11372
11511
|
if (content.includes("McpServer") || content.includes("McpServer")) {
|
|
@@ -11377,13 +11516,13 @@ function findTsEntryFile() {
|
|
|
11377
11516
|
}
|
|
11378
11517
|
}
|
|
11379
11518
|
for (const c2 of candidates) {
|
|
11380
|
-
if (
|
|
11519
|
+
if (existsSync9(resolve7(c2))) return resolve7(c2);
|
|
11381
11520
|
}
|
|
11382
11521
|
return null;
|
|
11383
11522
|
}
|
|
11384
11523
|
function detectPackageManager() {
|
|
11385
|
-
if (
|
|
11386
|
-
if (
|
|
11524
|
+
if (existsSync9(resolve7("pnpm-lock.yaml"))) return "pnpm";
|
|
11525
|
+
if (existsSync9(resolve7("yarn.lock"))) return "yarn";
|
|
11387
11526
|
return "npm";
|
|
11388
11527
|
}
|
|
11389
11528
|
function installSdk() {
|
|
@@ -11526,7 +11665,7 @@ async function main2() {
|
|
|
11526
11665
|
}
|
|
11527
11666
|
log3(" Language: TypeScript");
|
|
11528
11667
|
const entryFile = opts.file ? resolve7(opts.file) : findTsEntryFile();
|
|
11529
|
-
if (!entryFile || !
|
|
11668
|
+
if (!entryFile || !existsSync9(entryFile)) {
|
|
11530
11669
|
log3(` Could not find entry file.${opts.file ? ` File not found: ${opts.file}` : ""}`);
|
|
11531
11670
|
log3("");
|
|
11532
11671
|
log3(" Specify it manually: --file <path>");
|
|
@@ -11539,7 +11678,7 @@ async function main2() {
|
|
|
11539
11678
|
log3("");
|
|
11540
11679
|
const backupPath = entryFile + ".solongate-backup";
|
|
11541
11680
|
if (opts.restore) {
|
|
11542
|
-
if (!
|
|
11681
|
+
if (!existsSync9(backupPath)) {
|
|
11543
11682
|
log3(" No backup found. Nothing to restore.");
|
|
11544
11683
|
process.exit(1);
|
|
11545
11684
|
}
|
|
@@ -11575,12 +11714,12 @@ async function main2() {
|
|
|
11575
11714
|
log3(" To apply: npx @solongate/proxy inject");
|
|
11576
11715
|
process.exit(0);
|
|
11577
11716
|
}
|
|
11578
|
-
if (!
|
|
11717
|
+
if (!existsSync9(backupPath)) {
|
|
11579
11718
|
copyFileSync(entryFile, backupPath);
|
|
11580
11719
|
log3("");
|
|
11581
11720
|
log3(` Backup: ${backupPath}`);
|
|
11582
11721
|
}
|
|
11583
|
-
|
|
11722
|
+
writeFileSync6(entryFile, result.modified);
|
|
11584
11723
|
log3("");
|
|
11585
11724
|
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
11725
|
log3(" \u2502 SolonGate SDK injected successfully! \u2502");
|
|
@@ -11609,8 +11748,8 @@ var init_inject = __esm({
|
|
|
11609
11748
|
|
|
11610
11749
|
// src/create.ts
|
|
11611
11750
|
var create_exports = {};
|
|
11612
|
-
import { mkdirSync as mkdirSync5, writeFileSync as
|
|
11613
|
-
import { resolve as resolve8, join as
|
|
11751
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync7, existsSync as existsSync10 } from "fs";
|
|
11752
|
+
import { resolve as resolve8, join as join12 } from "path";
|
|
11614
11753
|
import { execSync as execSync2 } from "child_process";
|
|
11615
11754
|
function withSpinner(message, fn) {
|
|
11616
11755
|
const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
|
|
@@ -11689,8 +11828,8 @@ EXAMPLES
|
|
|
11689
11828
|
`);
|
|
11690
11829
|
}
|
|
11691
11830
|
function createProject(dir, name, _policy) {
|
|
11692
|
-
|
|
11693
|
-
|
|
11831
|
+
writeFileSync7(
|
|
11832
|
+
join12(dir, "package.json"),
|
|
11694
11833
|
JSON.stringify(
|
|
11695
11834
|
{
|
|
11696
11835
|
name,
|
|
@@ -11719,8 +11858,8 @@ function createProject(dir, name, _policy) {
|
|
|
11719
11858
|
2
|
|
11720
11859
|
) + "\n"
|
|
11721
11860
|
);
|
|
11722
|
-
|
|
11723
|
-
|
|
11861
|
+
writeFileSync7(
|
|
11862
|
+
join12(dir, "tsconfig.json"),
|
|
11724
11863
|
JSON.stringify(
|
|
11725
11864
|
{
|
|
11726
11865
|
compilerOptions: {
|
|
@@ -11740,9 +11879,9 @@ function createProject(dir, name, _policy) {
|
|
|
11740
11879
|
2
|
|
11741
11880
|
) + "\n"
|
|
11742
11881
|
);
|
|
11743
|
-
mkdirSync5(
|
|
11744
|
-
|
|
11745
|
-
|
|
11882
|
+
mkdirSync5(join12(dir, "src"), { recursive: true });
|
|
11883
|
+
writeFileSync7(
|
|
11884
|
+
join12(dir, "src", "index.ts"),
|
|
11746
11885
|
`#!/usr/bin/env node
|
|
11747
11886
|
|
|
11748
11887
|
console.log = (...args: unknown[]) => {
|
|
@@ -11783,8 +11922,8 @@ console.log('');
|
|
|
11783
11922
|
console.log('Press Ctrl+C to stop.');
|
|
11784
11923
|
`
|
|
11785
11924
|
);
|
|
11786
|
-
|
|
11787
|
-
|
|
11925
|
+
writeFileSync7(
|
|
11926
|
+
join12(dir, ".mcp.json"),
|
|
11788
11927
|
JSON.stringify(
|
|
11789
11928
|
{
|
|
11790
11929
|
mcpServers: {
|
|
@@ -11801,13 +11940,13 @@ console.log('Press Ctrl+C to stop.');
|
|
|
11801
11940
|
2
|
|
11802
11941
|
) + "\n"
|
|
11803
11942
|
);
|
|
11804
|
-
|
|
11805
|
-
|
|
11943
|
+
writeFileSync7(
|
|
11944
|
+
join12(dir, ".env"),
|
|
11806
11945
|
`SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
|
|
11807
11946
|
`
|
|
11808
11947
|
);
|
|
11809
|
-
|
|
11810
|
-
|
|
11948
|
+
writeFileSync7(
|
|
11949
|
+
join12(dir, ".gitignore"),
|
|
11811
11950
|
`node_modules/
|
|
11812
11951
|
dist/
|
|
11813
11952
|
*.solongate-backup
|
|
@@ -11821,7 +11960,7 @@ async function main3() {
|
|
|
11821
11960
|
const opts = parseCreateArgs(process.argv);
|
|
11822
11961
|
const dir = resolve8(opts.name);
|
|
11823
11962
|
printBanner("Create MCP Server");
|
|
11824
|
-
if (
|
|
11963
|
+
if (existsSync10(dir)) {
|
|
11825
11964
|
log3(` ${c.red}Error:${c.reset} Directory "${opts.name}" already exists.`);
|
|
11826
11965
|
process.exit(1);
|
|
11827
11966
|
}
|
|
@@ -11900,12 +12039,12 @@ var init_create = __esm({
|
|
|
11900
12039
|
|
|
11901
12040
|
// src/pull-push.ts
|
|
11902
12041
|
var pull_push_exports = {};
|
|
11903
|
-
import { readFileSync as readFileSync11, writeFileSync as
|
|
12042
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, existsSync as existsSync11 } from "fs";
|
|
11904
12043
|
import { resolve as resolve9 } from "path";
|
|
11905
12044
|
function loadEnv() {
|
|
11906
12045
|
if (process.env.SOLONGATE_API_KEY) return;
|
|
11907
12046
|
const envPath = resolve9(".env");
|
|
11908
|
-
if (!
|
|
12047
|
+
if (!existsSync11(envPath)) return;
|
|
11909
12048
|
try {
|
|
11910
12049
|
const content = readFileSync11(envPath, "utf-8");
|
|
11911
12050
|
for (const line of content.split("\n")) {
|
|
@@ -12095,7 +12234,7 @@ async function pull(apiKey, file, policyId) {
|
|
|
12095
12234
|
const policy = await fetchCloudPolicy(apiKey, API_URL, policyId);
|
|
12096
12235
|
const { id: _id, ...policyWithoutId } = policy;
|
|
12097
12236
|
const json = JSON.stringify(policyWithoutId, null, 2) + "\n";
|
|
12098
|
-
|
|
12237
|
+
writeFileSync8(file, json, "utf-8");
|
|
12099
12238
|
log5("");
|
|
12100
12239
|
log5(green2(" Saved to: ") + file);
|
|
12101
12240
|
log5(` ${dim2("Name:")} ${policy.name}`);
|
|
@@ -12107,7 +12246,7 @@ async function pull(apiKey, file, policyId) {
|
|
|
12107
12246
|
log5("");
|
|
12108
12247
|
}
|
|
12109
12248
|
async function push(apiKey, file, policyId) {
|
|
12110
|
-
if (!
|
|
12249
|
+
if (!existsSync11(file)) {
|
|
12111
12250
|
log5(red2(`ERROR: File not found: ${file}`));
|
|
12112
12251
|
process.exit(1);
|
|
12113
12252
|
}
|
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,143 @@ 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
|
+
try {
|
|
544
|
+
process.stdout.write("\x1B[5t");
|
|
545
|
+
} catch {
|
|
546
|
+
}
|
|
547
|
+
if (!focusToken) return;
|
|
548
|
+
try {
|
|
549
|
+
const x = spawn("xdotool", ["windowactivate", focusToken], { stdio: "ignore" });
|
|
550
|
+
x.on("error", () => {
|
|
551
|
+
try {
|
|
552
|
+
const hex = "0x" + Number(focusToken).toString(16);
|
|
553
|
+
const w = spawn("wmctrl", ["-ia", hex], { stdio: "ignore" });
|
|
554
|
+
w.on("error", () => {
|
|
555
|
+
});
|
|
556
|
+
w.unref();
|
|
557
|
+
} catch {
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
x.unref();
|
|
561
|
+
} catch {
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
var winScriptPath = null;
|
|
565
|
+
function ensureWinScript() {
|
|
566
|
+
if (winScriptPath && existsSync2(winScriptPath)) return winScriptPath;
|
|
567
|
+
const p = join3(tmpdir(), "solongate-toast.ps1");
|
|
568
|
+
const script = [
|
|
569
|
+
"param([string]$Title,[string]$Msg,[string]$Hwnd)",
|
|
570
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
571
|
+
"Add-Type -AssemblyName System.Drawing",
|
|
572
|
+
`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);'`,
|
|
573
|
+
"$ni=New-Object System.Windows.Forms.NotifyIcon",
|
|
574
|
+
"$ni.Icon=[System.Drawing.SystemIcons]::Information",
|
|
575
|
+
"$ni.Visible=$true",
|
|
576
|
+
"$script:clicked=$false",
|
|
577
|
+
"$ni.add_BalloonTipClicked({$script:clicked=$true})",
|
|
578
|
+
"$ni.ShowBalloonTip(8000,$Title,$Msg,[System.Windows.Forms.ToolTipIcon]::Warning)",
|
|
579
|
+
"$sw=[System.Diagnostics.Stopwatch]::StartNew()",
|
|
580
|
+
"while($sw.Elapsed.TotalSeconds -lt 9 -and -not $script:clicked){[System.Windows.Forms.Application]::DoEvents();Start-Sleep -Milliseconds 100}",
|
|
581
|
+
"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{}}",
|
|
582
|
+
"$ni.Visible=$false;$ni.Dispose()"
|
|
583
|
+
].join("\n");
|
|
584
|
+
try {
|
|
585
|
+
writeFileSync(p, script);
|
|
586
|
+
winScriptPath = p;
|
|
587
|
+
return p;
|
|
588
|
+
} catch {
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
function winNotify(title, msg) {
|
|
593
|
+
const script = ensureWinScript();
|
|
594
|
+
if (!script) return;
|
|
595
|
+
try {
|
|
596
|
+
const p = spawn("powershell", ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, "-Title", title, "-Msg", msg, "-Hwnd", focusToken || ""], { stdio: "ignore", detached: true, windowsHide: true });
|
|
597
|
+
p.on("error", () => {
|
|
598
|
+
});
|
|
599
|
+
p.unref();
|
|
600
|
+
} catch {
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
function macBundleId() {
|
|
604
|
+
const prog = (process.env.TERM_PROGRAM || "").toLowerCase();
|
|
605
|
+
if (prog.includes("iterm")) return "com.googlecode.iterm2";
|
|
606
|
+
if (prog.includes("apple_terminal")) return "com.apple.Terminal";
|
|
607
|
+
if (prog.includes("vscode")) return "com.microsoft.VSCode";
|
|
608
|
+
return "com.apple.Terminal";
|
|
609
|
+
}
|
|
610
|
+
function macNotify(title, msg) {
|
|
611
|
+
try {
|
|
612
|
+
const p = spawn("terminal-notifier", ["-title", title, "-message", msg, "-activate", macBundleId(), "-sender", macBundleId()], { stdio: "ignore", detached: true });
|
|
613
|
+
p.on("error", () => {
|
|
614
|
+
try {
|
|
615
|
+
const esc = (s) => s.replace(/"/g, '\\"');
|
|
616
|
+
const a = spawn("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
|
|
617
|
+
a.on("error", () => {
|
|
618
|
+
});
|
|
619
|
+
a.unref();
|
|
620
|
+
} catch {
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
p.unref();
|
|
624
|
+
} catch {
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
492
628
|
// src/tui/hooks.ts
|
|
493
629
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
494
630
|
function useLoader(fn, deps = []) {
|
|
@@ -535,8 +671,8 @@ var CONFIG = loadConfig();
|
|
|
535
671
|
var SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
536
672
|
var BG = "#12234f";
|
|
537
673
|
var DIM_FLOOR = "#233457";
|
|
538
|
-
var LOCAL_LOG =
|
|
539
|
-
var RING =
|
|
674
|
+
var LOCAL_LOG = join4(homedir3(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
675
|
+
var RING = join4(process.cwd(), ".solongate", ".eval-ring.jsonl");
|
|
540
676
|
var hhmmss = (ts) => {
|
|
541
677
|
const d = new Date(ts);
|
|
542
678
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
@@ -865,13 +1001,7 @@ function LivePanel({ active: active2 }) {
|
|
|
865
1001
|
process.stdout.write("\x07");
|
|
866
1002
|
} catch {
|
|
867
1003
|
}
|
|
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
|
-
}
|
|
1004
|
+
desktopNotify(title, msg);
|
|
875
1005
|
},
|
|
876
1006
|
[pushLog]
|
|
877
1007
|
);
|
|
@@ -1085,10 +1215,10 @@ function LivePanel({ active: active2 }) {
|
|
|
1085
1215
|
else if (input === "x") toggleSignal("dlp");
|
|
1086
1216
|
else if (input === "r") toggleSignal("ratelimit");
|
|
1087
1217
|
else if (input === "e") {
|
|
1088
|
-
const file =
|
|
1218
|
+
const file = join4(homedir3(), ".solongate", "live-export.jsonl");
|
|
1089
1219
|
try {
|
|
1090
|
-
mkdirSync(
|
|
1091
|
-
|
|
1220
|
+
mkdirSync(join4(homedir3(), ".solongate"), { recursive: true });
|
|
1221
|
+
writeFileSync2(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
|
|
1092
1222
|
setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
|
|
1093
1223
|
} catch (err) {
|
|
1094
1224
|
setActionMsg({ text: "\u2717 export failed: " + (err instanceof Error ? err.message : String(err)), level: "bad", until: Date.now() + 6e3 });
|
|
@@ -2457,6 +2587,7 @@ async function launchTui() {
|
|
|
2457
2587
|
process.stderr.write("Not logged in. Run `solongate login` first.\n");
|
|
2458
2588
|
return;
|
|
2459
2589
|
}
|
|
2590
|
+
captureFocusTarget();
|
|
2460
2591
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
2461
2592
|
try {
|
|
2462
2593
|
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.18",
|
|
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": {
|