@solongate/proxy 0.81.17 → 0.81.19

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 CHANGED
@@ -7090,141 +7090,34 @@ var init_api_client = __esm({
7090
7090
  });
7091
7091
 
7092
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() {
7093
+ import { spawn } from "child_process";
7094
+ function desktopNotify(title, msg) {
7098
7095
  try {
7099
7096
  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
- }
7097
+ const p = spawn("notify-send", ["-a", "SolonGate", title, msg], { stdio: "ignore", detached: true });
7098
+ p.on("error", () => {
7099
+ });
7100
+ p.unref();
7108
7101
  } 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
- }
7102
+ const q = (s) => s.replace(/'/g, "''");
7103
+ const ps = `Add-Type -AssemblyName System.Windows.Forms;Add-Type -AssemblyName System.Drawing;$n=New-Object System.Windows.Forms.NotifyIcon;$n.Icon=[System.Drawing.SystemIcons]::Information;$n.Visible=$true;$n.ShowBalloonTip(6000,'${q(title)}','${q(msg)}',[System.Windows.Forms.ToolTipIcon]::Warning);Start-Sleep -Milliseconds 6500;$n.Dispose()`;
7104
+ const p = spawn("powershell", ["-NoProfile", "-NonInteractive", "-Command", ps], { stdio: "ignore", detached: true, windowsHide: true });
7105
+ p.on("error", () => {
7106
+ });
7107
+ p.unref();
7108
+ } else if (process.platform === "darwin") {
7109
+ const esc = (s) => s.replace(/"/g, '\\"');
7110
+ const p = spawn("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
7111
+ p.on("error", () => {
7112
+ });
7113
+ p.unref();
7115
7114
  }
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
7115
  } catch {
7220
7116
  }
7221
7117
  }
7222
- var focusToken, winScriptPath;
7223
7118
  var init_notify = __esm({
7224
7119
  "src/tui/notify.ts"() {
7225
7120
  "use strict";
7226
- focusToken = null;
7227
- winScriptPath = null;
7228
7121
  }
7229
7122
  });
7230
7123
 
@@ -7276,9 +7169,9 @@ var init_hooks = __esm({
7276
7169
  // src/tui/panels/Live.tsx
7277
7170
  import { Box as Box2, Text as Text2, useInput } from "ink";
7278
7171
  import TextInput from "ink-text-input";
7279
- import { closeSync, mkdirSync as mkdirSync3, openSync, readSync, statSync, writeFileSync as writeFileSync4 } from "fs";
7172
+ import { closeSync, mkdirSync as mkdirSync3, openSync, readSync, statSync, writeFileSync as writeFileSync3 } from "fs";
7280
7173
  import { homedir as homedir4 } from "os";
7281
- import { join as join7 } from "path";
7174
+ import { join as join6 } from "path";
7282
7175
  import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
7283
7176
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
7284
7177
  function tailLines(file, maxBytes = 131072) {
@@ -7807,10 +7700,10 @@ function LivePanel({ active: active2 }) {
7807
7700
  else if (input === "x") toggleSignal("dlp");
7808
7701
  else if (input === "r") toggleSignal("ratelimit");
7809
7702
  else if (input === "e") {
7810
- const file = join7(homedir4(), ".solongate", "live-export.jsonl");
7703
+ const file = join6(homedir4(), ".solongate", "live-export.jsonl");
7811
7704
  try {
7812
- mkdirSync3(join7(homedir4(), ".solongate"), { recursive: true });
7813
- writeFileSync4(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
7705
+ mkdirSync3(join6(homedir4(), ".solongate"), { recursive: true });
7706
+ writeFileSync3(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
7814
7707
  setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
7815
7708
  } catch (err2) {
7816
7709
  setActionMsg({ text: "\u2717 export failed: " + (err2 instanceof Error ? err2.message : String(err2)), level: "bad", until: Date.now() + 6e3 });
@@ -8077,8 +7970,8 @@ var init_Live = __esm({
8077
7970
  SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
8078
7971
  BG = "#12234f";
8079
7972
  DIM_FLOOR = "#233457";
8080
- LOCAL_LOG = join7(homedir4(), ".solongate", "local-logs", "solongate-audit.jsonl");
8081
- RING = join7(process.cwd(), ".solongate", ".eval-ring.jsonl");
7973
+ LOCAL_LOG = join6(homedir4(), ".solongate", "local-logs", "solongate-audit.jsonl");
7974
+ RING = join6(process.cwd(), ".solongate", ".eval-ring.jsonl");
8082
7975
  hhmmss = (ts) => {
8083
7976
  const d = new Date(ts);
8084
7977
  return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
@@ -9294,7 +9187,6 @@ async function launchTui() {
9294
9187
  process.stderr.write("Not logged in. Run `solongate login` first.\n");
9295
9188
  return;
9296
9189
  }
9297
- captureFocusTarget();
9298
9190
  process.stdout.write("\x1B[?1049h\x1B[H");
9299
9191
  try {
9300
9192
  const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}));
@@ -9308,7 +9200,6 @@ var init_tui = __esm({
9308
9200
  "use strict";
9309
9201
  init_App();
9310
9202
  init_client();
9311
- init_notify();
9312
9203
  }
9313
9204
  });
9314
9205
 
@@ -10000,9 +9891,9 @@ var init_agents2 = __esm({
10000
9891
  });
10001
9892
 
10002
9893
  // src/commands/doctor.ts
10003
- import { existsSync as existsSync5, statSync as statSync2 } from "fs";
9894
+ import { existsSync as existsSync4, statSync as statSync2 } from "fs";
10004
9895
  import { homedir as homedir5 } from "os";
10005
- import { join as join8 } from "path";
9896
+ import { join as join7 } from "path";
10006
9897
  async function run6(argv) {
10007
9898
  const { flags } = parse(argv);
10008
9899
  const json = flagBool(flags, "json");
@@ -10032,7 +9923,7 @@ async function run6(argv) {
10032
9923
  } catch {
10033
9924
  }
10034
9925
  }
10035
- if (existsSync5(LOCAL_LOG2)) {
9926
+ if (existsSync4(LOCAL_LOG2)) {
10036
9927
  const st = statSync2(LOCAL_LOG2);
10037
9928
  const ageMin = (Date.now() - st.mtimeMs) / 6e4;
10038
9929
  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"}` });
@@ -10062,14 +9953,14 @@ var init_doctor = __esm({
10062
9953
  init_api_client();
10063
9954
  init_format();
10064
9955
  init_args();
10065
- LOCAL_LOG2 = join8(homedir5(), ".solongate", "local-logs", "solongate-audit.jsonl");
9956
+ LOCAL_LOG2 = join7(homedir5(), ".solongate", "local-logs", "solongate-audit.jsonl");
10066
9957
  }
10067
9958
  });
10068
9959
 
10069
9960
  // src/commands/watch.ts
10070
- import { closeSync as closeSync2, existsSync as existsSync6, openSync as openSync2, readSync as readSync2, statSync as statSync3 } from "fs";
9961
+ import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync2, readSync as readSync2, statSync as statSync3 } from "fs";
10071
9962
  import { homedir as homedir6 } from "os";
10072
- import { join as join9 } from "path";
9963
+ import { join as join8 } from "path";
10073
9964
  function tailLocal(file, maxBytes = 131072) {
10074
9965
  try {
10075
9966
  const size = statSync3(file).size;
@@ -10113,7 +10004,7 @@ async function run7(argv) {
10113
10004
  for (const r of rows) if (keep(r)) print(r, json);
10114
10005
  };
10115
10006
  const pollLocal = () => {
10116
- if (cloudOnly || !existsSync6(LOCAL_LOG3)) return;
10007
+ if (cloudOnly || !existsSync5(LOCAL_LOG3)) return;
10117
10008
  const rows = [];
10118
10009
  for (const line of tailLocal(LOCAL_LOG3)) {
10119
10010
  try {
@@ -10176,7 +10067,7 @@ var init_watch = __esm({
10176
10067
  init_cli_utils();
10177
10068
  init_args();
10178
10069
  init_format();
10179
- LOCAL_LOG3 = join9(homedir6(), ".solongate", "local-logs", "solongate-audit.jsonl");
10070
+ LOCAL_LOG3 = join8(homedir6(), ".solongate", "local-logs", "solongate-audit.jsonl");
10180
10071
  trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
10181
10072
  time = (ms) => new Date(ms).toTimeString().slice(0, 8);
10182
10073
  }
@@ -10478,32 +10369,32 @@ __export(global_install_exports, {
10478
10369
  runGlobalRestore: () => runGlobalRestore,
10479
10370
  unlockProtected: () => unlockProtected
10480
10371
  });
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";
10372
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
10373
+ import { resolve as resolve4, join as join9, dirname } from "path";
10483
10374
  import { homedir as homedir7 } from "os";
10484
10375
  import { fileURLToPath } from "url";
10485
10376
  import { createInterface } from "readline";
10486
- import { execFileSync as execFileSync3 } from "child_process";
10377
+ import { execFileSync as execFileSync2 } from "child_process";
10487
10378
  function lockFile(file) {
10488
- if (!existsSync7(file)) return;
10379
+ if (!existsSync6(file)) return;
10489
10380
  try {
10490
10381
  if (process.platform === "win32") {
10491
10382
  try {
10492
- execFileSync3("icacls", [file, "/deny", "*S-1-1-0:(WD,AD,DC,DE)"], { stdio: "ignore" });
10383
+ execFileSync2("icacls", [file, "/deny", "*S-1-1-0:(WD,AD,DC,DE)"], { stdio: "ignore" });
10493
10384
  } catch {
10494
10385
  }
10495
10386
  try {
10496
- execFileSync3("attrib", ["+R", file], { stdio: "ignore" });
10387
+ execFileSync2("attrib", ["+R", file], { stdio: "ignore" });
10497
10388
  } catch {
10498
10389
  }
10499
10390
  } else if (process.platform === "darwin") {
10500
10391
  try {
10501
- execFileSync3("chflags", ["uchg", file], { stdio: "ignore" });
10392
+ execFileSync2("chflags", ["uchg", file], { stdio: "ignore" });
10502
10393
  } catch {
10503
10394
  }
10504
10395
  } else {
10505
10396
  try {
10506
- execFileSync3("chattr", ["+i", file], { stdio: "ignore" });
10397
+ execFileSync2("chattr", ["+i", file], { stdio: "ignore" });
10507
10398
  } catch {
10508
10399
  }
10509
10400
  }
@@ -10511,29 +10402,29 @@ function lockFile(file) {
10511
10402
  }
10512
10403
  }
10513
10404
  function unlockFile(file) {
10514
- if (!existsSync7(file)) return;
10405
+ if (!existsSync6(file)) return;
10515
10406
  try {
10516
10407
  if (process.platform === "win32") {
10517
10408
  try {
10518
- execFileSync3("icacls", [file, "/remove:d", "*S-1-1-0"], { stdio: "ignore" });
10409
+ execFileSync2("icacls", [file, "/remove:d", "*S-1-1-0"], { stdio: "ignore" });
10519
10410
  } catch {
10520
10411
  }
10521
10412
  try {
10522
- execFileSync3("icacls", [file, "/reset"], { stdio: "ignore" });
10413
+ execFileSync2("icacls", [file, "/reset"], { stdio: "ignore" });
10523
10414
  } catch {
10524
10415
  }
10525
10416
  try {
10526
- execFileSync3("attrib", ["-R", file], { stdio: "ignore" });
10417
+ execFileSync2("attrib", ["-R", file], { stdio: "ignore" });
10527
10418
  } catch {
10528
10419
  }
10529
10420
  } else if (process.platform === "darwin") {
10530
10421
  try {
10531
- execFileSync3("chflags", ["nouchg", file], { stdio: "ignore" });
10422
+ execFileSync2("chflags", ["nouchg", file], { stdio: "ignore" });
10532
10423
  } catch {
10533
10424
  }
10534
10425
  } else {
10535
10426
  try {
10536
- execFileSync3("chattr", ["-i", file], { stdio: "ignore" });
10427
+ execFileSync2("chattr", ["-i", file], { stdio: "ignore" });
10537
10428
  } catch {
10538
10429
  }
10539
10430
  }
@@ -10543,10 +10434,10 @@ function unlockFile(file) {
10543
10434
  function protectedTargets() {
10544
10435
  const p = globalPaths();
10545
10436
  return [
10546
- join10(p.hooksDir, "guard.mjs"),
10547
- join10(p.hooksDir, "audit.mjs"),
10548
- join10(p.hooksDir, "stop.mjs"),
10549
- join10(p.hooksDir, "shield.mjs"),
10437
+ join9(p.hooksDir, "guard.mjs"),
10438
+ join9(p.hooksDir, "audit.mjs"),
10439
+ join9(p.hooksDir, "stop.mjs"),
10440
+ join9(p.hooksDir, "shield.mjs"),
10550
10441
  p.configPath,
10551
10442
  p.settingsPath
10552
10443
  ];
@@ -10559,25 +10450,25 @@ function unlockProtected() {
10559
10450
  }
10560
10451
  function globalPaths() {
10561
10452
  const home = homedir7();
10562
- const sgDir = join10(home, ".solongate");
10563
- const hooksDir = join10(sgDir, "hooks");
10564
- const claudeDir = join10(home, ".claude");
10453
+ const sgDir = join9(home, ".solongate");
10454
+ const hooksDir = join9(sgDir, "hooks");
10455
+ const claudeDir = join9(home, ".claude");
10565
10456
  return {
10566
10457
  home,
10567
10458
  sgDir,
10568
10459
  hooksDir,
10569
10460
  claudeDir,
10570
- settingsPath: join10(claudeDir, "settings.json"),
10571
- backupPath: join10(claudeDir, "settings.solongate.bak"),
10572
- configPath: join10(sgDir, "cloud-guard.json")
10461
+ settingsPath: join9(claudeDir, "settings.json"),
10462
+ backupPath: join9(claudeDir, "settings.solongate.bak"),
10463
+ configPath: join9(sgDir, "cloud-guard.json")
10573
10464
  };
10574
10465
  }
10575
10466
  function readHook(filename) {
10576
- return readFileSync7(join10(HOOKS_DIR, filename), "utf-8");
10467
+ return readFileSync7(join9(HOOKS_DIR, filename), "utf-8");
10577
10468
  }
10578
10469
  function readGuard() {
10579
- const bundled = join10(HOOKS_DIR, "guard.bundled.mjs");
10580
- return existsSync7(bundled) ? readFileSync7(bundled, "utf-8") : readHook("guard.mjs");
10470
+ const bundled = join9(HOOKS_DIR, "guard.bundled.mjs");
10471
+ return existsSync6(bundled) ? readFileSync7(bundled, "utf-8") : readHook("guard.mjs");
10581
10472
  }
10582
10473
  function ask(question) {
10583
10474
  const rl = createInterface({ input: process.stdin, output: process.stderr });
@@ -10590,14 +10481,14 @@ function runGlobalRestore() {
10590
10481
  const p = globalPaths();
10591
10482
  unlockProtected();
10592
10483
  removeClaudeShim();
10593
- if (existsSync7(p.backupPath)) {
10594
- writeFileSync5(p.settingsPath, readFileSync7(p.backupPath, "utf-8"));
10484
+ if (existsSync6(p.backupPath)) {
10485
+ writeFileSync4(p.settingsPath, readFileSync7(p.backupPath, "utf-8"));
10595
10486
  console.log(` Restored ${p.settingsPath} from backup.`);
10596
- } else if (existsSync7(p.settingsPath)) {
10487
+ } else if (existsSync6(p.settingsPath)) {
10597
10488
  try {
10598
10489
  const s = JSON.parse(readFileSync7(p.settingsPath, "utf-8"));
10599
10490
  delete s.hooks;
10600
- writeFileSync5(p.settingsPath, JSON.stringify(s, null, 2) + "\n");
10491
+ writeFileSync4(p.settingsPath, JSON.stringify(s, null, 2) + "\n");
10601
10492
  console.log(` Removed SolonGate hooks from ${p.settingsPath}.`);
10602
10493
  } catch {
10603
10494
  }
@@ -10612,7 +10503,7 @@ function escapeRe(s) {
10612
10503
  function resolveRealClaude() {
10613
10504
  try {
10614
10505
  const finder = process.platform === "win32" ? "where" : "which";
10615
- const out2 = execFileSync3(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
10506
+ const out2 = execFileSync2(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
10616
10507
  if (process.platform === "win32") {
10617
10508
  const low = (s) => s.toLowerCase();
10618
10509
  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;
@@ -10625,24 +10516,24 @@ function resolveRealClaude() {
10625
10516
  function shimTargets() {
10626
10517
  if (process.platform === "win32") {
10627
10518
  try {
10628
- const prof = execFileSync3("powershell", ["-NoProfile", "-Command", "$PROFILE.CurrentUserAllHosts"], { encoding: "utf-8" }).trim();
10519
+ const prof = execFileSync2("powershell", ["-NoProfile", "-Command", "$PROFILE.CurrentUserAllHosts"], { encoding: "utf-8" }).trim();
10629
10520
  return prof ? [prof] : [];
10630
10521
  } catch {
10631
10522
  return [];
10632
10523
  }
10633
10524
  }
10634
- return [".bashrc", ".zshrc", ".profile"].map((f) => join10(homedir7(), f)).filter((f) => existsSync7(f));
10525
+ return [".bashrc", ".zshrc", ".profile"].map((f) => join9(homedir7(), f)).filter((f) => existsSync6(f));
10635
10526
  }
10636
10527
  function writeShimBlock(file, block2) {
10637
10528
  const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
10638
- let content = existsSync7(file) ? readFileSync7(file, "utf-8") : "";
10529
+ let content = existsSync6(file) ? readFileSync7(file, "utf-8") : "";
10639
10530
  content = content.replace(re, "");
10640
10531
  if (block2) {
10641
10532
  if (content.length && !content.endsWith("\n")) content += "\n";
10642
10533
  content += block2 + "\n";
10643
10534
  }
10644
10535
  mkdirSync4(dirname(file), { recursive: true });
10645
- writeFileSync5(file, content);
10536
+ writeFileSync4(file, content);
10646
10537
  }
10647
10538
  function installClaudeShim(shieldPath) {
10648
10539
  const real = resolveRealClaude();
@@ -10696,19 +10587,19 @@ async function runGlobalInstall(opts = {}) {
10696
10587
  mkdirSync4(p.hooksDir, { recursive: true });
10697
10588
  mkdirSync4(p.claudeDir, { recursive: true });
10698
10589
  unlockProtected();
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"));
10590
+ writeFileSync4(join9(p.hooksDir, "guard.mjs"), readGuard());
10591
+ writeFileSync4(join9(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
10592
+ writeFileSync4(join9(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
10593
+ writeFileSync4(join9(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
10703
10594
  console.log(` Installed hooks \u2192 ${p.hooksDir}`);
10704
- installClaudeShim(join10(p.hooksDir, "shield.mjs"));
10705
- writeFileSync5(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
10595
+ installClaudeShim(join9(p.hooksDir, "shield.mjs"));
10596
+ writeFileSync4(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
10706
10597
  console.log(` Wrote ${p.configPath}`);
10707
10598
  let existing = {};
10708
- if (existsSync7(p.settingsPath)) {
10599
+ if (existsSync6(p.settingsPath)) {
10709
10600
  const raw = readFileSync7(p.settingsPath, "utf-8");
10710
- if (!existsSync7(p.backupPath)) {
10711
- writeFileSync5(p.backupPath, raw);
10601
+ if (!existsSync6(p.backupPath)) {
10602
+ writeFileSync4(p.backupPath, raw);
10712
10603
  console.log(` Backed up existing settings \u2192 ${p.backupPath}`);
10713
10604
  }
10714
10605
  try {
@@ -10717,9 +10608,9 @@ async function runGlobalInstall(opts = {}) {
10717
10608
  existing = {};
10718
10609
  }
10719
10610
  }
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, "/");
10611
+ const guardAbs = join9(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
10612
+ const auditAbs = join9(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
10613
+ const stopAbs = join9(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
10723
10614
  const nodeBin = process.execPath.replace(/\\/g, "/");
10724
10615
  const call = process.platform === "win32" ? "& " : "";
10725
10616
  const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
@@ -10731,7 +10622,7 @@ async function runGlobalInstall(opts = {}) {
10731
10622
  Stop: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(stopAbs) }] }]
10732
10623
  }
10733
10624
  };
10734
- writeFileSync5(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
10625
+ writeFileSync4(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
10735
10626
  console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
10736
10627
  if (process.env["SOLONGATE_OS_LOCK"] === "1") {
10737
10628
  lockProtected();
@@ -10911,7 +10802,7 @@ import { createServer, request as httpRequest } from "http";
10911
10802
  import { request as httpsRequest } from "https";
10912
10803
  import { spawn as spawn3 } from "child_process";
10913
10804
  import { URL as URL2 } from "url";
10914
- import { readFileSync as readFileSync8, existsSync as existsSync8, readdirSync, statSync as statSync4 } from "fs";
10805
+ import { readFileSync as readFileSync8, existsSync as existsSync7, readdirSync, statSync as statSync4 } from "fs";
10915
10806
  import { resolve as resolve5 } from "path";
10916
10807
  import { homedir as homedir8 } from "os";
10917
10808
  function findCacheFile() {
@@ -10919,7 +10810,7 @@ function findCacheFile() {
10919
10810
  const envSel = process.env.SOLONGATE_AGENT_ID;
10920
10811
  if (envSel) {
10921
10812
  const f = resolve5(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
10922
- if (existsSync8(f)) return f;
10813
+ if (existsSync7(f)) return f;
10923
10814
  }
10924
10815
  let best = null, bestTs = -1;
10925
10816
  try {
@@ -10940,7 +10831,7 @@ function findCacheFile() {
10940
10831
  function loadCfg() {
10941
10832
  try {
10942
10833
  const f = findCacheFile();
10943
- if (f && existsSync8(f)) {
10834
+ if (f && existsSync7(f)) {
10944
10835
  const c2 = JSON.parse(readFileSync8(f, "utf-8"));
10945
10836
  const d = c2?.security?.dlpRedact;
10946
10837
  const g = c2?.security?.ghost;
@@ -11230,7 +11121,7 @@ __export(logs_server_exports, {
11230
11121
  });
11231
11122
  import { createServer as createServer2 } from "http";
11232
11123
  import { readFileSync as readFileSync9, statSync as statSync5 } from "fs";
11233
- import { resolve as resolve6, join as join11, isAbsolute } from "path";
11124
+ import { resolve as resolve6, join as join10, isAbsolute } from "path";
11234
11125
  import { homedir as homedir9 } from "os";
11235
11126
  import { readdirSync as readdirSync2 } from "fs";
11236
11127
  function allowedOrigins() {
@@ -11256,7 +11147,7 @@ async function findLogDir() {
11256
11147
  const files = readdirSync2(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
11257
11148
  for (const f of files) {
11258
11149
  try {
11259
- const c2 = JSON.parse(readFileSync9(join11(base, f), "utf-8"));
11150
+ const c2 = JSON.parse(readFileSync9(join10(base, f), "utf-8"));
11260
11151
  const p = c2?.security?.localLogs?.path;
11261
11152
  if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
11262
11153
  } catch {
@@ -11265,7 +11156,7 @@ async function findLogDir() {
11265
11156
  } catch {
11266
11157
  }
11267
11158
  try {
11268
- const cfgRaw = readFileSync9(join11(base, "cloud-guard.json"), "utf-8");
11159
+ const cfgRaw = readFileSync9(join10(base, "cloud-guard.json"), "utf-8");
11269
11160
  const { apiKey, apiUrl } = JSON.parse(cfgRaw);
11270
11161
  if (apiKey) {
11271
11162
  const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
@@ -11294,7 +11185,7 @@ function setCors(req, res) {
11294
11185
  }
11295
11186
  function fileInfo(dir) {
11296
11187
  if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
11297
- const file = join11(dir, LOG_FILENAME);
11188
+ const file = join10(dir, LOG_FILENAME);
11298
11189
  try {
11299
11190
  const st = statSync5(file);
11300
11191
  return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
@@ -11407,7 +11298,7 @@ var init_logs_server = __esm({
11407
11298
 
11408
11299
  // src/inject.ts
11409
11300
  var inject_exports = {};
11410
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, existsSync as existsSync9, copyFileSync } from "fs";
11301
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync5, existsSync as existsSync8, copyFileSync } from "fs";
11411
11302
  import { resolve as resolve7 } from "path";
11412
11303
  import { execSync } from "child_process";
11413
11304
  function parseInjectArgs(argv) {
@@ -11465,7 +11356,7 @@ WHAT IT DOES
11465
11356
  `);
11466
11357
  }
11467
11358
  function detectProject() {
11468
- if (!existsSync9(resolve7("package.json"))) return false;
11359
+ if (!existsSync8(resolve7("package.json"))) return false;
11469
11360
  try {
11470
11361
  const pkg = JSON.parse(readFileSync10(resolve7("package.json"), "utf-8"));
11471
11362
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
@@ -11481,13 +11372,13 @@ function findTsEntryFile() {
11481
11372
  const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
11482
11373
  if (typeof binPath === "string") {
11483
11374
  const srcPath = binPath.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
11484
- if (existsSync9(resolve7(srcPath))) return resolve7(srcPath);
11485
- if (existsSync9(resolve7(binPath))) return resolve7(binPath);
11375
+ if (existsSync8(resolve7(srcPath))) return resolve7(srcPath);
11376
+ if (existsSync8(resolve7(binPath))) return resolve7(binPath);
11486
11377
  }
11487
11378
  }
11488
11379
  if (pkg.main) {
11489
11380
  const srcPath = pkg.main.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
11490
- if (existsSync9(resolve7(srcPath))) return resolve7(srcPath);
11381
+ if (existsSync8(resolve7(srcPath))) return resolve7(srcPath);
11491
11382
  }
11492
11383
  } catch {
11493
11384
  }
@@ -11501,7 +11392,7 @@ function findTsEntryFile() {
11501
11392
  ];
11502
11393
  for (const c2 of candidates) {
11503
11394
  const full = resolve7(c2);
11504
- if (existsSync9(full)) {
11395
+ if (existsSync8(full)) {
11505
11396
  try {
11506
11397
  const content = readFileSync10(full, "utf-8");
11507
11398
  if (content.includes("McpServer") || content.includes("McpServer")) {
@@ -11512,13 +11403,13 @@ function findTsEntryFile() {
11512
11403
  }
11513
11404
  }
11514
11405
  for (const c2 of candidates) {
11515
- if (existsSync9(resolve7(c2))) return resolve7(c2);
11406
+ if (existsSync8(resolve7(c2))) return resolve7(c2);
11516
11407
  }
11517
11408
  return null;
11518
11409
  }
11519
11410
  function detectPackageManager() {
11520
- if (existsSync9(resolve7("pnpm-lock.yaml"))) return "pnpm";
11521
- if (existsSync9(resolve7("yarn.lock"))) return "yarn";
11411
+ if (existsSync8(resolve7("pnpm-lock.yaml"))) return "pnpm";
11412
+ if (existsSync8(resolve7("yarn.lock"))) return "yarn";
11522
11413
  return "npm";
11523
11414
  }
11524
11415
  function installSdk() {
@@ -11661,7 +11552,7 @@ async function main2() {
11661
11552
  }
11662
11553
  log3(" Language: TypeScript");
11663
11554
  const entryFile = opts.file ? resolve7(opts.file) : findTsEntryFile();
11664
- if (!entryFile || !existsSync9(entryFile)) {
11555
+ if (!entryFile || !existsSync8(entryFile)) {
11665
11556
  log3(` Could not find entry file.${opts.file ? ` File not found: ${opts.file}` : ""}`);
11666
11557
  log3("");
11667
11558
  log3(" Specify it manually: --file <path>");
@@ -11674,7 +11565,7 @@ async function main2() {
11674
11565
  log3("");
11675
11566
  const backupPath = entryFile + ".solongate-backup";
11676
11567
  if (opts.restore) {
11677
- if (!existsSync9(backupPath)) {
11568
+ if (!existsSync8(backupPath)) {
11678
11569
  log3(" No backup found. Nothing to restore.");
11679
11570
  process.exit(1);
11680
11571
  }
@@ -11710,12 +11601,12 @@ async function main2() {
11710
11601
  log3(" To apply: npx @solongate/proxy inject");
11711
11602
  process.exit(0);
11712
11603
  }
11713
- if (!existsSync9(backupPath)) {
11604
+ if (!existsSync8(backupPath)) {
11714
11605
  copyFileSync(entryFile, backupPath);
11715
11606
  log3("");
11716
11607
  log3(` Backup: ${backupPath}`);
11717
11608
  }
11718
- writeFileSync6(entryFile, result.modified);
11609
+ writeFileSync5(entryFile, result.modified);
11719
11610
  log3("");
11720
11611
  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");
11721
11612
  log3(" \u2502 SolonGate SDK injected successfully! \u2502");
@@ -11744,8 +11635,8 @@ var init_inject = __esm({
11744
11635
 
11745
11636
  // src/create.ts
11746
11637
  var create_exports = {};
11747
- import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync7, existsSync as existsSync10 } from "fs";
11748
- import { resolve as resolve8, join as join12 } from "path";
11638
+ import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync6, existsSync as existsSync9 } from "fs";
11639
+ import { resolve as resolve8, join as join11 } from "path";
11749
11640
  import { execSync as execSync2 } from "child_process";
11750
11641
  function withSpinner(message, fn) {
11751
11642
  const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
@@ -11824,8 +11715,8 @@ EXAMPLES
11824
11715
  `);
11825
11716
  }
11826
11717
  function createProject(dir, name, _policy) {
11827
- writeFileSync7(
11828
- join12(dir, "package.json"),
11718
+ writeFileSync6(
11719
+ join11(dir, "package.json"),
11829
11720
  JSON.stringify(
11830
11721
  {
11831
11722
  name,
@@ -11854,8 +11745,8 @@ function createProject(dir, name, _policy) {
11854
11745
  2
11855
11746
  ) + "\n"
11856
11747
  );
11857
- writeFileSync7(
11858
- join12(dir, "tsconfig.json"),
11748
+ writeFileSync6(
11749
+ join11(dir, "tsconfig.json"),
11859
11750
  JSON.stringify(
11860
11751
  {
11861
11752
  compilerOptions: {
@@ -11875,9 +11766,9 @@ function createProject(dir, name, _policy) {
11875
11766
  2
11876
11767
  ) + "\n"
11877
11768
  );
11878
- mkdirSync5(join12(dir, "src"), { recursive: true });
11879
- writeFileSync7(
11880
- join12(dir, "src", "index.ts"),
11769
+ mkdirSync5(join11(dir, "src"), { recursive: true });
11770
+ writeFileSync6(
11771
+ join11(dir, "src", "index.ts"),
11881
11772
  `#!/usr/bin/env node
11882
11773
 
11883
11774
  console.log = (...args: unknown[]) => {
@@ -11918,8 +11809,8 @@ console.log('');
11918
11809
  console.log('Press Ctrl+C to stop.');
11919
11810
  `
11920
11811
  );
11921
- writeFileSync7(
11922
- join12(dir, ".mcp.json"),
11812
+ writeFileSync6(
11813
+ join11(dir, ".mcp.json"),
11923
11814
  JSON.stringify(
11924
11815
  {
11925
11816
  mcpServers: {
@@ -11936,13 +11827,13 @@ console.log('Press Ctrl+C to stop.');
11936
11827
  2
11937
11828
  ) + "\n"
11938
11829
  );
11939
- writeFileSync7(
11940
- join12(dir, ".env"),
11830
+ writeFileSync6(
11831
+ join11(dir, ".env"),
11941
11832
  `SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
11942
11833
  `
11943
11834
  );
11944
- writeFileSync7(
11945
- join12(dir, ".gitignore"),
11835
+ writeFileSync6(
11836
+ join11(dir, ".gitignore"),
11946
11837
  `node_modules/
11947
11838
  dist/
11948
11839
  *.solongate-backup
@@ -11956,7 +11847,7 @@ async function main3() {
11956
11847
  const opts = parseCreateArgs(process.argv);
11957
11848
  const dir = resolve8(opts.name);
11958
11849
  printBanner("Create MCP Server");
11959
- if (existsSync10(dir)) {
11850
+ if (existsSync9(dir)) {
11960
11851
  log3(` ${c.red}Error:${c.reset} Directory "${opts.name}" already exists.`);
11961
11852
  process.exit(1);
11962
11853
  }
@@ -12035,12 +11926,12 @@ var init_create = __esm({
12035
11926
 
12036
11927
  // src/pull-push.ts
12037
11928
  var pull_push_exports = {};
12038
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, existsSync as existsSync11 } from "fs";
11929
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, existsSync as existsSync10 } from "fs";
12039
11930
  import { resolve as resolve9 } from "path";
12040
11931
  function loadEnv() {
12041
11932
  if (process.env.SOLONGATE_API_KEY) return;
12042
11933
  const envPath = resolve9(".env");
12043
- if (!existsSync11(envPath)) return;
11934
+ if (!existsSync10(envPath)) return;
12044
11935
  try {
12045
11936
  const content = readFileSync11(envPath, "utf-8");
12046
11937
  for (const line of content.split("\n")) {
@@ -12230,7 +12121,7 @@ async function pull(apiKey, file, policyId) {
12230
12121
  const policy = await fetchCloudPolicy(apiKey, API_URL, policyId);
12231
12122
  const { id: _id, ...policyWithoutId } = policy;
12232
12123
  const json = JSON.stringify(policyWithoutId, null, 2) + "\n";
12233
- writeFileSync8(file, json, "utf-8");
12124
+ writeFileSync7(file, json, "utf-8");
12234
12125
  log5("");
12235
12126
  log5(green2(" Saved to: ") + file);
12236
12127
  log5(` ${dim2("Name:")} ${policy.name}`);
@@ -12242,7 +12133,7 @@ async function pull(apiKey, file, policyId) {
12242
12133
  log5("");
12243
12134
  }
12244
12135
  async function push(apiKey, file, policyId) {
12245
- if (!existsSync11(file)) {
12136
+ if (!existsSync10(file)) {
12246
12137
  log5(red2(`ERROR: File not found: ${file}`));
12247
12138
  process.exit(1);
12248
12139
  }
package/dist/tui/index.js CHANGED
@@ -150,9 +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 { closeSync, mkdirSync, openSync, readSync, statSync, writeFileSync as writeFileSync2 } from "fs";
153
+ import { closeSync, mkdirSync, openSync, readSync, statSync, writeFileSync } from "fs";
154
154
  import { homedir as homedir3 } from "os";
155
- import { join as join4 } from "path";
155
+ import { join as join3 } from "path";
156
156
  import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
157
157
 
158
158
  // src/api-client/client.ts
@@ -489,134 +489,28 @@ function list4() {
489
489
  var api = { policies: policies_exports, settings: settings_exports, stats: stats_exports, audit: audit_exports, agents: agents_exports, keys: keys_exports, mcp: mcp_exports };
490
490
 
491
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() {
492
+ import { spawn } from "child_process";
493
+ function desktopNotify(title, msg) {
498
494
  try {
499
495
  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
- }
496
+ const p = spawn("notify-send", ["-a", "SolonGate", title, msg], { stdio: "ignore", detached: true });
497
+ p.on("error", () => {
498
+ });
499
+ p.unref();
508
500
  } 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
- }
501
+ const q = (s) => s.replace(/'/g, "''");
502
+ const ps = `Add-Type -AssemblyName System.Windows.Forms;Add-Type -AssemblyName System.Drawing;$n=New-Object System.Windows.Forms.NotifyIcon;$n.Icon=[System.Drawing.SystemIcons]::Information;$n.Visible=$true;$n.ShowBalloonTip(6000,'${q(title)}','${q(msg)}',[System.Windows.Forms.ToolTipIcon]::Warning);Start-Sleep -Milliseconds 6500;$n.Dispose()`;
503
+ const p = spawn("powershell", ["-NoProfile", "-NonInteractive", "-Command", ps], { stdio: "ignore", detached: true, windowsHide: true });
504
+ p.on("error", () => {
505
+ });
506
+ p.unref();
507
+ } else if (process.platform === "darwin") {
508
+ const esc = (s) => s.replace(/"/g, '\\"');
509
+ const p = spawn("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
510
+ p.on("error", () => {
511
+ });
512
+ p.unref();
515
513
  }
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
514
  } catch {
621
515
  }
622
516
  }
@@ -667,8 +561,8 @@ var CONFIG = loadConfig();
667
561
  var SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
668
562
  var BG = "#12234f";
669
563
  var DIM_FLOOR = "#233457";
670
- var LOCAL_LOG = join4(homedir3(), ".solongate", "local-logs", "solongate-audit.jsonl");
671
- var RING = join4(process.cwd(), ".solongate", ".eval-ring.jsonl");
564
+ var LOCAL_LOG = join3(homedir3(), ".solongate", "local-logs", "solongate-audit.jsonl");
565
+ var RING = join3(process.cwd(), ".solongate", ".eval-ring.jsonl");
672
566
  var hhmmss = (ts) => {
673
567
  const d = new Date(ts);
674
568
  return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
@@ -1211,10 +1105,10 @@ function LivePanel({ active: active2 }) {
1211
1105
  else if (input === "x") toggleSignal("dlp");
1212
1106
  else if (input === "r") toggleSignal("ratelimit");
1213
1107
  else if (input === "e") {
1214
- const file = join4(homedir3(), ".solongate", "live-export.jsonl");
1108
+ const file = join3(homedir3(), ".solongate", "live-export.jsonl");
1215
1109
  try {
1216
- mkdirSync(join4(homedir3(), ".solongate"), { recursive: true });
1217
- writeFileSync2(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
1110
+ mkdirSync(join3(homedir3(), ".solongate"), { recursive: true });
1111
+ writeFileSync(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
1218
1112
  setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
1219
1113
  } catch (err) {
1220
1114
  setActionMsg({ text: "\u2717 export failed: " + (err instanceof Error ? err.message : String(err)), level: "bad", until: Date.now() + 6e3 });
@@ -2583,7 +2477,6 @@ async function launchTui() {
2583
2477
  process.stderr.write("Not logged in. Run `solongate login` first.\n");
2584
2478
  return;
2585
2479
  }
2586
- captureFocusTarget();
2587
2480
  process.stdout.write("\x1B[?1049h\x1B[H");
2588
2481
  try {
2589
2482
  const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}));
@@ -1,4 +1,2 @@
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. */
1
+ /** Fire a plain desktop toast. No-op-safe: missing tools just mean no toast. */
4
2
  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.17",
3
+ "version": "0.81.19",
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": {