@solongate/proxy 0.81.41 → 0.81.43

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
@@ -7537,6 +7537,7 @@ function LivePanel({ active: active2 }) {
7537
7537
  const inspectFromRef = useRef2("stream");
7538
7538
  const seenRef = useRef2(/* @__PURE__ */ new Set());
7539
7539
  const lastLocalTs = useRef2(0);
7540
+ const localSeq = useRef2(0);
7540
7541
  const pausedUntil = useRef2(0);
7541
7542
  const sessRef = useRef2([]);
7542
7543
  const mergedRef = useRef2([]);
@@ -7582,7 +7583,7 @@ function LivePanel({ active: active2 }) {
7582
7583
  const at = Date.parse(j.ts ?? "");
7583
7584
  if (!Number.isFinite(at) || at <= lastLocalTs.current) continue;
7584
7585
  fresh.push({
7585
- id: "l:" + at + ":" + (j.tool ?? ""),
7586
+ id: "l:" + at + ":" + (j.tool ?? "") + ":" + localSeq.current++,
7586
7587
  at,
7587
7588
  tool: j.tool ?? "?",
7588
7589
  decision: j.decision ?? "ALLOW",
@@ -7704,11 +7705,14 @@ function LivePanel({ active: active2 }) {
7704
7705
  return () => clearInterval(t);
7705
7706
  }, [active2, frozen]);
7706
7707
  const startRef = useRef2(Date.now());
7708
+ const lastNotifyAt = useRef2(0);
7707
7709
  const fireAlert = useCallback2(
7708
- (id, title, msg, level = "warn") => {
7710
+ (id, title, msg, level = "warn", desktop = true) => {
7709
7711
  pushLog(`${level === "bad" ? "\u26D4" : "\u23F8"} ${msg}`, level);
7710
7712
  setAlerts((a) => [...a.filter((x) => x.id !== id), { id, msg, level, until: Date.now() + 15e3 }].slice(-4));
7711
- if (!CONFIG.notifications) return;
7713
+ if (!desktop || !CONFIG.notifications) return;
7714
+ if (Date.now() - lastNotifyAt.current < 3e3) return;
7715
+ lastNotifyAt.current = Date.now();
7712
7716
  try {
7713
7717
  process.stdout.write("\x07");
7714
7718
  } catch {
@@ -7723,7 +7727,7 @@ function LivePanel({ active: active2 }) {
7723
7727
  const prev = prevStatus.current.get(r.id);
7724
7728
  if (prev && prev === "active" && r.status === "idle") {
7725
7729
  const name = r.isMe ? `${r.agent} (this machine)` : r.agent;
7726
- fireAlert("idle:" + r.id, "Agent idle", `${name} went IDLE, no tool call for 60s`, "warn");
7730
+ fireAlert("idle:" + r.id, "Agent idle", `${name} went IDLE, no tool call for 60s`, "warn", false);
7727
7731
  }
7728
7732
  prevStatus.current.set(r.id, r.status);
7729
7733
  }
@@ -7820,7 +7824,7 @@ function LivePanel({ active: active2 }) {
7820
7824
  const bannerRows = (activeAlert ? 1 : 0) + (activeAction ? 1 : 0);
7821
7825
  const chartH = rows >= 36 ? 6 : 4;
7822
7826
  const colH = rows >= 32 ? 7 : 5;
7823
- const streamRows = Math.max(4, rows - 5 - (1 + chartH) - colH - bannerRows);
7827
+ const streamRows = Math.max(4, rows - 6 - (1 + chartH) - colH - bannerRows);
7824
7828
  const innerW = cols - 2;
7825
7829
  const leftW = Math.floor(innerW * 0.55);
7826
7830
  const rightW = innerW - leftW - 2;
@@ -10068,7 +10072,7 @@ function App() {
10068
10072
  const current = SECTIONS[effectiveSection];
10069
10073
  if (help) return /* @__PURE__ */ jsx9(HelpOverlay, { cols, rows });
10070
10074
  if (current.label === "Live" && focus === "panel") {
10071
- return /* @__PURE__ */ jsx9(Box9, { flexDirection: "column", width: cols, height: rows, children: /* @__PURE__ */ jsx9(LivePanel, { active: true, focused: true }, viewNonce) });
10075
+ return /* @__PURE__ */ jsx9(Box9, { flexDirection: "column", width: cols, height: rows - 1, overflow: "hidden", children: /* @__PURE__ */ jsx9(LivePanel, { active: true, focused: true }, viewNonce) });
10072
10076
  }
10073
10077
  const Panel = current.Panel;
10074
10078
  const panelBody = current.label === "Accounts" ? /* @__PURE__ */ jsx9(AccountsPanel, { active: true, focused: focus === "panel", viewApiKey: viewKey, onView: viewAccount }) : /* @__PURE__ */ jsx9(Panel, { active: focus === "panel" || current.label !== "Live", focused: focus === "panel" });
@@ -10147,6 +10151,9 @@ var tui_exports = {};
10147
10151
  __export(tui_exports, {
10148
10152
  launchTui: () => launchTui
10149
10153
  });
10154
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync6 } from "fs";
10155
+ import { homedir as homedir7 } from "os";
10156
+ import { join as join9 } from "path";
10150
10157
  import { render } from "ink";
10151
10158
  import { jsx as jsx10 } from "react/jsx-runtime";
10152
10159
  async function launchTui() {
@@ -10157,10 +10164,26 @@ async function launchTui() {
10157
10164
  return;
10158
10165
  }
10159
10166
  process.stdout.write("\x1B[?1049h\x1B[H");
10167
+ const debugLog = join9(homedir7(), ".solongate", "dataroom-debug.log");
10168
+ const saved = { log: console.log, warn: console.warn, error: console.error, info: console.info, debug: console.debug };
10169
+ const toFile = (level) => (...args) => {
10170
+ try {
10171
+ mkdirSync6(join9(homedir7(), ".solongate"), { recursive: true });
10172
+ appendFileSync2(debugLog, `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
10173
+ `);
10174
+ } catch {
10175
+ }
10176
+ };
10177
+ console.log = toFile("log");
10178
+ console.warn = toFile("warn");
10179
+ console.error = toFile("error");
10180
+ console.info = toFile("info");
10181
+ console.debug = toFile("debug");
10160
10182
  try {
10161
- const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}));
10183
+ const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}), { patchConsole: false });
10162
10184
  await waitUntilExit();
10163
10185
  } finally {
10186
+ Object.assign(console, saved);
10164
10187
  process.stdout.write("\x1B[?1049l");
10165
10188
  }
10166
10189
  }
@@ -10860,8 +10883,8 @@ var init_agents2 = __esm({
10860
10883
 
10861
10884
  // src/commands/doctor.ts
10862
10885
  import { existsSync as existsSync4, statSync as statSync2 } from "fs";
10863
- import { homedir as homedir7 } from "os";
10864
- import { join as join9 } from "path";
10886
+ import { homedir as homedir8 } from "os";
10887
+ import { join as join10 } from "path";
10865
10888
  async function run6(argv) {
10866
10889
  const { flags } = parse(argv);
10867
10890
  const json = flagBool(flags, "json");
@@ -10921,14 +10944,14 @@ var init_doctor = __esm({
10921
10944
  init_api_client();
10922
10945
  init_format();
10923
10946
  init_args();
10924
- LOCAL_LOG2 = join9(homedir7(), ".solongate", "local-logs", "solongate-audit.jsonl");
10947
+ LOCAL_LOG2 = join10(homedir8(), ".solongate", "local-logs", "solongate-audit.jsonl");
10925
10948
  }
10926
10949
  });
10927
10950
 
10928
10951
  // src/commands/watch.ts
10929
10952
  import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync2, readSync as readSync2, statSync as statSync3 } from "fs";
10930
- import { homedir as homedir8 } from "os";
10931
- import { join as join10 } from "path";
10953
+ import { homedir as homedir9 } from "os";
10954
+ import { join as join11 } from "path";
10932
10955
  function tailLocal(file, maxBytes = 131072) {
10933
10956
  try {
10934
10957
  const size = statSync3(file).size;
@@ -11035,7 +11058,7 @@ var init_watch = __esm({
11035
11058
  init_cli_utils();
11036
11059
  init_args();
11037
11060
  init_format();
11038
- LOCAL_LOG3 = join10(homedir8(), ".solongate", "local-logs", "solongate-audit.jsonl");
11061
+ LOCAL_LOG3 = join11(homedir9(), ".solongate", "local-logs", "solongate-audit.jsonl");
11039
11062
  trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
11040
11063
  time = (ms) => new Date(ms).toTimeString().slice(0, 8);
11041
11064
  }
@@ -11326,9 +11349,9 @@ var init_commands = __esm({
11326
11349
  });
11327
11350
 
11328
11351
  // src/global-install.ts
11329
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, existsSync as existsSync6, mkdirSync as mkdirSync6 } from "fs";
11330
- import { resolve as resolve4, join as join11, dirname } from "path";
11331
- import { homedir as homedir9 } from "os";
11352
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, existsSync as existsSync6, mkdirSync as mkdirSync7 } from "fs";
11353
+ import { resolve as resolve4, join as join12, dirname } from "path";
11354
+ import { homedir as homedir10 } from "os";
11332
11355
  import { fileURLToPath } from "url";
11333
11356
  import { createInterface } from "readline";
11334
11357
  import { execFileSync as execFileSync2 } from "child_process";
@@ -11391,10 +11414,10 @@ function unlockFile(file) {
11391
11414
  function protectedTargets() {
11392
11415
  const p = globalPaths();
11393
11416
  return [
11394
- join11(p.hooksDir, "guard.mjs"),
11395
- join11(p.hooksDir, "audit.mjs"),
11396
- join11(p.hooksDir, "stop.mjs"),
11397
- join11(p.hooksDir, "shield.mjs"),
11417
+ join12(p.hooksDir, "guard.mjs"),
11418
+ join12(p.hooksDir, "audit.mjs"),
11419
+ join12(p.hooksDir, "stop.mjs"),
11420
+ join12(p.hooksDir, "shield.mjs"),
11398
11421
  p.configPath,
11399
11422
  p.settingsPath
11400
11423
  ];
@@ -11406,25 +11429,25 @@ function unlockProtected() {
11406
11429
  for (const f of protectedTargets()) unlockFile(f);
11407
11430
  }
11408
11431
  function globalPaths() {
11409
- const home = homedir9();
11410
- const sgDir = join11(home, ".solongate");
11411
- const hooksDir = join11(sgDir, "hooks");
11412
- const claudeDir = join11(home, ".claude");
11432
+ const home = homedir10();
11433
+ const sgDir = join12(home, ".solongate");
11434
+ const hooksDir = join12(sgDir, "hooks");
11435
+ const claudeDir = join12(home, ".claude");
11413
11436
  return {
11414
11437
  home,
11415
11438
  sgDir,
11416
11439
  hooksDir,
11417
11440
  claudeDir,
11418
- settingsPath: join11(claudeDir, "settings.json"),
11419
- backupPath: join11(claudeDir, "settings.solongate.bak"),
11420
- configPath: join11(sgDir, "cloud-guard.json")
11441
+ settingsPath: join12(claudeDir, "settings.json"),
11442
+ backupPath: join12(claudeDir, "settings.solongate.bak"),
11443
+ configPath: join12(sgDir, "cloud-guard.json")
11421
11444
  };
11422
11445
  }
11423
11446
  function readHook(filename) {
11424
- return readFileSync8(join11(HOOKS_DIR, filename), "utf-8");
11447
+ return readFileSync8(join12(HOOKS_DIR, filename), "utf-8");
11425
11448
  }
11426
11449
  function readGuard() {
11427
- const bundled = join11(HOOKS_DIR, "guard.bundled.mjs");
11450
+ const bundled = join12(HOOKS_DIR, "guard.bundled.mjs");
11428
11451
  return existsSync6(bundled) ? readFileSync8(bundled, "utf-8") : readHook("guard.mjs");
11429
11452
  }
11430
11453
  function ask(question) {
@@ -11459,7 +11482,7 @@ function shimTargets() {
11459
11482
  return [];
11460
11483
  }
11461
11484
  }
11462
- return [".bashrc", ".zshrc", ".profile"].map((f) => join11(homedir9(), f)).filter((f) => existsSync6(f));
11485
+ return [".bashrc", ".zshrc", ".profile"].map((f) => join12(homedir10(), f)).filter((f) => existsSync6(f));
11463
11486
  }
11464
11487
  function writeShimBlock(file, block2) {
11465
11488
  const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
@@ -11469,7 +11492,7 @@ function writeShimBlock(file, block2) {
11469
11492
  if (content.length && !content.endsWith("\n")) content += "\n";
11470
11493
  content += block2 + "\n";
11471
11494
  }
11472
- mkdirSync6(dirname(file), { recursive: true });
11495
+ mkdirSync7(dirname(file), { recursive: true });
11473
11496
  writeFileSync7(file, content);
11474
11497
  }
11475
11498
  function installClaudeShim(shieldPath) {
@@ -11513,15 +11536,15 @@ async function runGlobalInstall(opts = {}) {
11513
11536
  process.exit(1);
11514
11537
  }
11515
11538
  const apiUrl = opts.apiUrl || process.env["SOLONGATE_API_URL"] || "https://api.solongate.com";
11516
- mkdirSync6(p.hooksDir, { recursive: true });
11517
- mkdirSync6(p.claudeDir, { recursive: true });
11539
+ mkdirSync7(p.hooksDir, { recursive: true });
11540
+ mkdirSync7(p.claudeDir, { recursive: true });
11518
11541
  unlockProtected();
11519
- writeFileSync7(join11(p.hooksDir, "guard.mjs"), readGuard());
11520
- writeFileSync7(join11(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
11521
- writeFileSync7(join11(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
11522
- writeFileSync7(join11(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
11542
+ writeFileSync7(join12(p.hooksDir, "guard.mjs"), readGuard());
11543
+ writeFileSync7(join12(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
11544
+ writeFileSync7(join12(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
11545
+ writeFileSync7(join12(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
11523
11546
  console.log(` Installed hooks \u2192 ${p.hooksDir}`);
11524
- installClaudeShim(join11(p.hooksDir, "shield.mjs"));
11547
+ installClaudeShim(join12(p.hooksDir, "shield.mjs"));
11525
11548
  writeFileSync7(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
11526
11549
  console.log(` Wrote ${p.configPath}`);
11527
11550
  let existing = {};
@@ -11537,9 +11560,9 @@ async function runGlobalInstall(opts = {}) {
11537
11560
  existing = {};
11538
11561
  }
11539
11562
  }
11540
- const guardAbs = join11(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
11541
- const auditAbs = join11(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
11542
- const stopAbs = join11(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
11563
+ const guardAbs = join12(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
11564
+ const auditAbs = join12(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
11565
+ const stopAbs = join12(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
11543
11566
  const nodeBin = process.execPath.replace(/\\/g, "/");
11544
11567
  const call = process.platform === "win32" ? "& " : "";
11545
11568
  const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
@@ -11731,9 +11754,9 @@ import { spawn as spawn4 } from "child_process";
11731
11754
  import { URL as URL2 } from "url";
11732
11755
  import { readFileSync as readFileSync9, existsSync as existsSync7, readdirSync, statSync as statSync4 } from "fs";
11733
11756
  import { resolve as resolve5 } from "path";
11734
- import { homedir as homedir10 } from "os";
11757
+ import { homedir as homedir11 } from "os";
11735
11758
  function findCacheFile() {
11736
- const dir = resolve5(homedir10(), ".solongate");
11759
+ const dir = resolve5(homedir11(), ".solongate");
11737
11760
  const envSel = process.env.SOLONGATE_AGENT_ID;
11738
11761
  if (envSel) {
11739
11762
  const f = resolve5(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
@@ -12048,8 +12071,8 @@ __export(logs_server_exports, {
12048
12071
  });
12049
12072
  import { createServer as createServer2 } from "http";
12050
12073
  import { readFileSync as readFileSync10, statSync as statSync5 } from "fs";
12051
- import { resolve as resolve6, join as join12, isAbsolute } from "path";
12052
- import { homedir as homedir11 } from "os";
12074
+ import { resolve as resolve6, join as join13, isAbsolute } from "path";
12075
+ import { homedir as homedir12 } from "os";
12053
12076
  import { readdirSync as readdirSync2 } from "fs";
12054
12077
  function allowedOrigins() {
12055
12078
  const base = [
@@ -12066,15 +12089,15 @@ function resolveLocalLogDir(rawPath) {
12066
12089
  const dir = String(rawPath || "").trim().replace(/[\\/]+$/, "");
12067
12090
  if (!dir) return null;
12068
12091
  if (isAbsolute(dir)) return dir;
12069
- return resolve6(homedir11(), ".solongate", "local-logs");
12092
+ return resolve6(homedir12(), ".solongate", "local-logs");
12070
12093
  }
12071
12094
  async function findLogDir() {
12072
- const base = resolve6(homedir11(), ".solongate");
12095
+ const base = resolve6(homedir12(), ".solongate");
12073
12096
  try {
12074
12097
  const files = readdirSync2(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
12075
12098
  for (const f of files) {
12076
12099
  try {
12077
- const c2 = JSON.parse(readFileSync10(join12(base, f), "utf-8"));
12100
+ const c2 = JSON.parse(readFileSync10(join13(base, f), "utf-8"));
12078
12101
  const p = c2?.security?.localLogs?.path;
12079
12102
  if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
12080
12103
  } catch {
@@ -12083,7 +12106,7 @@ async function findLogDir() {
12083
12106
  } catch {
12084
12107
  }
12085
12108
  try {
12086
- const cfgRaw = readFileSync10(join12(base, "cloud-guard.json"), "utf-8");
12109
+ const cfgRaw = readFileSync10(join13(base, "cloud-guard.json"), "utf-8");
12087
12110
  const { apiKey, apiUrl } = JSON.parse(cfgRaw);
12088
12111
  if (apiKey) {
12089
12112
  const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
@@ -12112,7 +12135,7 @@ function setCors(req, res) {
12112
12135
  }
12113
12136
  function fileInfo(dir) {
12114
12137
  if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
12115
- const file = join12(dir, LOG_FILENAME);
12138
+ const file = join13(dir, LOG_FILENAME);
12116
12139
  try {
12117
12140
  const st = statSync5(file);
12118
12141
  return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
@@ -12562,8 +12585,8 @@ var init_inject = __esm({
12562
12585
 
12563
12586
  // src/create.ts
12564
12587
  var create_exports = {};
12565
- import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync9, existsSync as existsSync9 } from "fs";
12566
- import { resolve as resolve8, join as join13 } from "path";
12588
+ import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, existsSync as existsSync9 } from "fs";
12589
+ import { resolve as resolve8, join as join14 } from "path";
12567
12590
  import { execSync as execSync2 } from "child_process";
12568
12591
  function withSpinner(message, fn) {
12569
12592
  const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
@@ -12643,7 +12666,7 @@ EXAMPLES
12643
12666
  }
12644
12667
  function createProject(dir, name, _policy) {
12645
12668
  writeFileSync9(
12646
- join13(dir, "package.json"),
12669
+ join14(dir, "package.json"),
12647
12670
  JSON.stringify(
12648
12671
  {
12649
12672
  name,
@@ -12673,7 +12696,7 @@ function createProject(dir, name, _policy) {
12673
12696
  ) + "\n"
12674
12697
  );
12675
12698
  writeFileSync9(
12676
- join13(dir, "tsconfig.json"),
12699
+ join14(dir, "tsconfig.json"),
12677
12700
  JSON.stringify(
12678
12701
  {
12679
12702
  compilerOptions: {
@@ -12693,9 +12716,9 @@ function createProject(dir, name, _policy) {
12693
12716
  2
12694
12717
  ) + "\n"
12695
12718
  );
12696
- mkdirSync7(join13(dir, "src"), { recursive: true });
12719
+ mkdirSync8(join14(dir, "src"), { recursive: true });
12697
12720
  writeFileSync9(
12698
- join13(dir, "src", "index.ts"),
12721
+ join14(dir, "src", "index.ts"),
12699
12722
  `#!/usr/bin/env node
12700
12723
 
12701
12724
  console.log = (...args: unknown[]) => {
@@ -12737,7 +12760,7 @@ console.log('Press Ctrl+C to stop.');
12737
12760
  `
12738
12761
  );
12739
12762
  writeFileSync9(
12740
- join13(dir, ".mcp.json"),
12763
+ join14(dir, ".mcp.json"),
12741
12764
  JSON.stringify(
12742
12765
  {
12743
12766
  mcpServers: {
@@ -12755,12 +12778,12 @@ console.log('Press Ctrl+C to stop.');
12755
12778
  ) + "\n"
12756
12779
  );
12757
12780
  writeFileSync9(
12758
- join13(dir, ".env"),
12781
+ join14(dir, ".env"),
12759
12782
  `SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
12760
12783
  `
12761
12784
  );
12762
12785
  writeFileSync9(
12763
- join13(dir, ".gitignore"),
12786
+ join14(dir, ".gitignore"),
12764
12787
  `node_modules/
12765
12788
  dist/
12766
12789
  *.solongate-backup
@@ -12779,7 +12802,7 @@ async function main3() {
12779
12802
  process.exit(1);
12780
12803
  }
12781
12804
  withSpinner(`Setting up ${opts.name}...`, () => {
12782
- mkdirSync7(dir, { recursive: true });
12805
+ mkdirSync8(dir, { recursive: true });
12783
12806
  createProject(dir, opts.name, opts.policy);
12784
12807
  });
12785
12808
  if (!opts.noInstall) {
package/dist/tui/index.js CHANGED
@@ -5,6 +5,9 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/tui/index.tsx
8
+ import { appendFileSync, mkdirSync as mkdirSync4 } from "fs";
9
+ import { homedir as homedir6 } from "os";
10
+ import { join as join6 } from "path";
8
11
  import { render } from "ink";
9
12
 
10
13
  // src/tui/App.tsx
@@ -970,6 +973,7 @@ function LivePanel({ active: active2 }) {
970
973
  const inspectFromRef = useRef2("stream");
971
974
  const seenRef = useRef2(/* @__PURE__ */ new Set());
972
975
  const lastLocalTs = useRef2(0);
976
+ const localSeq = useRef2(0);
973
977
  const pausedUntil = useRef2(0);
974
978
  const sessRef = useRef2([]);
975
979
  const mergedRef = useRef2([]);
@@ -1015,7 +1019,7 @@ function LivePanel({ active: active2 }) {
1015
1019
  const at = Date.parse(j.ts ?? "");
1016
1020
  if (!Number.isFinite(at) || at <= lastLocalTs.current) continue;
1017
1021
  fresh.push({
1018
- id: "l:" + at + ":" + (j.tool ?? ""),
1022
+ id: "l:" + at + ":" + (j.tool ?? "") + ":" + localSeq.current++,
1019
1023
  at,
1020
1024
  tool: j.tool ?? "?",
1021
1025
  decision: j.decision ?? "ALLOW",
@@ -1137,11 +1141,14 @@ function LivePanel({ active: active2 }) {
1137
1141
  return () => clearInterval(t);
1138
1142
  }, [active2, frozen]);
1139
1143
  const startRef = useRef2(Date.now());
1144
+ const lastNotifyAt = useRef2(0);
1140
1145
  const fireAlert = useCallback2(
1141
- (id, title, msg, level = "warn") => {
1146
+ (id, title, msg, level = "warn", desktop = true) => {
1142
1147
  pushLog(`${level === "bad" ? "\u26D4" : "\u23F8"} ${msg}`, level);
1143
1148
  setAlerts((a) => [...a.filter((x) => x.id !== id), { id, msg, level, until: Date.now() + 15e3 }].slice(-4));
1144
- if (!CONFIG.notifications) return;
1149
+ if (!desktop || !CONFIG.notifications) return;
1150
+ if (Date.now() - lastNotifyAt.current < 3e3) return;
1151
+ lastNotifyAt.current = Date.now();
1145
1152
  try {
1146
1153
  process.stdout.write("\x07");
1147
1154
  } catch {
@@ -1156,7 +1163,7 @@ function LivePanel({ active: active2 }) {
1156
1163
  const prev = prevStatus.current.get(r.id);
1157
1164
  if (prev && prev === "active" && r.status === "idle") {
1158
1165
  const name = r.isMe ? `${r.agent} (this machine)` : r.agent;
1159
- fireAlert("idle:" + r.id, "Agent idle", `${name} went IDLE, no tool call for 60s`, "warn");
1166
+ fireAlert("idle:" + r.id, "Agent idle", `${name} went IDLE, no tool call for 60s`, "warn", false);
1160
1167
  }
1161
1168
  prevStatus.current.set(r.id, r.status);
1162
1169
  }
@@ -1253,7 +1260,7 @@ function LivePanel({ active: active2 }) {
1253
1260
  const bannerRows = (activeAlert ? 1 : 0) + (activeAction ? 1 : 0);
1254
1261
  const chartH = rows >= 36 ? 6 : 4;
1255
1262
  const colH = rows >= 32 ? 7 : 5;
1256
- const streamRows = Math.max(4, rows - 5 - (1 + chartH) - colH - bannerRows);
1263
+ const streamRows = Math.max(4, rows - 6 - (1 + chartH) - colH - bannerRows);
1257
1264
  const innerW = cols - 2;
1258
1265
  const leftW = Math.floor(innerW * 0.55);
1259
1266
  const rightW = innerW - leftW - 2;
@@ -3378,7 +3385,7 @@ function App() {
3378
3385
  const current = SECTIONS[effectiveSection];
3379
3386
  if (help) return /* @__PURE__ */ jsx9(HelpOverlay, { cols, rows });
3380
3387
  if (current.label === "Live" && focus === "panel") {
3381
- return /* @__PURE__ */ jsx9(Box9, { flexDirection: "column", width: cols, height: rows, children: /* @__PURE__ */ jsx9(LivePanel, { active: true, focused: true }, viewNonce) });
3388
+ return /* @__PURE__ */ jsx9(Box9, { flexDirection: "column", width: cols, height: rows - 1, overflow: "hidden", children: /* @__PURE__ */ jsx9(LivePanel, { active: true, focused: true }, viewNonce) });
3382
3389
  }
3383
3390
  const Panel = current.Panel;
3384
3391
  const panelBody = current.label === "Accounts" ? /* @__PURE__ */ jsx9(AccountsPanel, { active: true, focused: focus === "panel", viewApiKey: viewKey, onView: viewAccount }) : /* @__PURE__ */ jsx9(Panel, { active: focus === "panel" || current.label !== "Live", focused: focus === "panel" });
@@ -3433,10 +3440,26 @@ async function launchTui() {
3433
3440
  return;
3434
3441
  }
3435
3442
  process.stdout.write("\x1B[?1049h\x1B[H");
3443
+ const debugLog = join6(homedir6(), ".solongate", "dataroom-debug.log");
3444
+ const saved = { log: console.log, warn: console.warn, error: console.error, info: console.info, debug: console.debug };
3445
+ const toFile = (level) => (...args) => {
3446
+ try {
3447
+ mkdirSync4(join6(homedir6(), ".solongate"), { recursive: true });
3448
+ appendFileSync(debugLog, `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
3449
+ `);
3450
+ } catch {
3451
+ }
3452
+ };
3453
+ console.log = toFile("log");
3454
+ console.warn = toFile("warn");
3455
+ console.error = toFile("error");
3456
+ console.info = toFile("info");
3457
+ console.debug = toFile("debug");
3436
3458
  try {
3437
- const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}));
3459
+ const { waitUntilExit } = render(/* @__PURE__ */ jsx10(App, {}), { patchConsole: false });
3438
3460
  await waitUntilExit();
3439
3461
  } finally {
3462
+ Object.assign(console, saved);
3440
3463
  process.stdout.write("\x1B[?1049l");
3441
3464
  }
3442
3465
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.81.41",
3
+ "version": "0.81.43",
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": {