@solongate/proxy 0.83.30 → 0.83.32

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
@@ -7125,6 +7125,30 @@ import { access, mkdirSync as mkdirSync4, openSync, readFileSync as readFileSync
7125
7125
  import { homedir as homedir3 } from "os";
7126
7126
  import { dirname as dirname2, join as join5, sep } from "path";
7127
7127
  import { fileURLToPath as fileURLToPath2 } from "url";
7128
+ function lockHeldAt() {
7129
+ try {
7130
+ const ts = Number(readFileSync5(LOCK_FILE, "utf-8").trim().split(/\s+/)[1] ?? 0);
7131
+ if (!Number.isFinite(ts) || Date.now() - ts >= LOCK_STALE_MS) return null;
7132
+ return ts;
7133
+ } catch {
7134
+ return null;
7135
+ }
7136
+ }
7137
+ function takeInstallLock() {
7138
+ try {
7139
+ mkdirSync4(join5(homedir3(), ".solongate"), { recursive: true });
7140
+ writeFileSync4(LOCK_FILE, `${process.pid} ${Date.now()}
7141
+ `);
7142
+ } catch {
7143
+ }
7144
+ }
7145
+ function releaseInstallLock() {
7146
+ try {
7147
+ writeFileSync4(LOCK_FILE, `${process.pid} 0
7148
+ `);
7149
+ } catch {
7150
+ }
7151
+ }
7128
7152
  function readState() {
7129
7153
  try {
7130
7154
  const s = JSON.parse(readFileSync5(STATE_FILE, "utf-8"));
@@ -7191,8 +7215,10 @@ async function fetchLatest() {
7191
7215
  }
7192
7216
  }
7193
7217
  function spawnGlobalInstall(version) {
7218
+ if (lockHeldAt() !== null) return false;
7194
7219
  try {
7195
7220
  mkdirSync4(join5(homedir3(), ".solongate"), { recursive: true });
7221
+ takeInstallLock();
7196
7222
  const log3 = openSync(LOG_FILE, "a");
7197
7223
  const p = spawn2("npm", ["install", "-g", `${PKG}@${version}`], {
7198
7224
  stdio: ["ignore", log3, log3],
@@ -7242,7 +7268,7 @@ async function runUpdateCommand() {
7242
7268
  return 1;
7243
7269
  }
7244
7270
  out2(` updating ${cur} -> ${latest} ...`);
7245
- const r = await runGlobalInstall2(latest);
7271
+ const r = await installGlobally(latest, out2);
7246
7272
  if (!r.ok) {
7247
7273
  if (r.needsAdmin) {
7248
7274
  writeState({ ...readState(), needsAdmin: latest });
@@ -7250,7 +7276,8 @@ async function runUpdateCommand() {
7250
7276
  out2(" Run these two:");
7251
7277
  for (const s of adminUpdateSteps()) out2(" " + s);
7252
7278
  } else {
7253
- out2(" update failed. Try: npm i -g @solongate/proxy@latest");
7279
+ out2(" update failed \u2014 the CLI may not be installed right now. Run:");
7280
+ out2(` npm i -g ${PKG}@${latest}`);
7254
7281
  }
7255
7282
  return 1;
7256
7283
  }
@@ -7300,6 +7327,26 @@ ${output}
7300
7327
  }
7301
7328
  });
7302
7329
  }
7330
+ async function installGlobally(version, out2) {
7331
+ const heldSince = lockHeldAt();
7332
+ if (heldSince !== null) {
7333
+ out2(" another install is already running \u2014 waiting for it to finish ...");
7334
+ const until = Date.now() + LOCK_WAIT_MS;
7335
+ while (Date.now() < until && lockHeldAt() !== null) await sleep(1e3);
7336
+ }
7337
+ takeInstallLock();
7338
+ try {
7339
+ let r = await runGlobalInstall2(version);
7340
+ if (!r.ok && !r.needsAdmin) {
7341
+ await sleep(2e3);
7342
+ out2(" install did not take \u2014 retrying once ...");
7343
+ r = await runGlobalInstall2(version);
7344
+ }
7345
+ return r;
7346
+ } finally {
7347
+ releaseInstallLock();
7348
+ }
7349
+ }
7303
7350
  function adminInstallCommand() {
7304
7351
  return process.platform === "win32" ? `npm i -g ${PKG}@latest (in an Administrator terminal)` : `sudo npm i -g ${PKG}@latest`;
7305
7352
  }
@@ -7443,7 +7490,7 @@ function maybeSelfUpdate(notify = (l) => process.stderr.write(l + "\n")) {
7443
7490
  }
7444
7491
  })();
7445
7492
  }
7446
- var PKG, CHECK_EVERY_MS, ATTEMPT_EVERY_MS, STATE_FILE, LOG_FILE, NEEDS_ADMIN_RE, prefixCheck;
7493
+ var PKG, CHECK_EVERY_MS, ATTEMPT_EVERY_MS, STATE_FILE, LOG_FILE, LOCK_FILE, LOCK_STALE_MS, LOCK_WAIT_MS, sleep, NEEDS_ADMIN_RE, prefixCheck;
7447
7494
  var init_self_update = __esm({
7448
7495
  "src/self-update.ts"() {
7449
7496
  "use strict";
@@ -7453,6 +7500,10 @@ var init_self_update = __esm({
7453
7500
  ATTEMPT_EVERY_MS = 6 * 60 * 60 * 1e3;
7454
7501
  STATE_FILE = join5(homedir3(), ".solongate", ".self-update.json");
7455
7502
  LOG_FILE = join5(homedir3(), ".solongate", "self-update.log");
7503
+ LOCK_FILE = join5(homedir3(), ".solongate", ".update-install.lock");
7504
+ LOCK_STALE_MS = 3 * 6e4;
7505
+ LOCK_WAIT_MS = 9e4;
7506
+ sleep = (ms) => new Promise((r) => setTimeout(r, ms));
7456
7507
  NEEDS_ADMIN_RE = /\bEACCES\b|\bEPERM\b|permission denied|operation not permitted/i;
7457
7508
  prefixCheck = null;
7458
7509
  }
@@ -17553,7 +17604,7 @@ async function main() {
17553
17604
  }
17554
17605
  if (IS_HUMAN_CLI) {
17555
17606
  const tuiBound = subcommand === "dataroom" || process.argv.length <= 2 && process.stdout.isTTY && process.stdin.isTTY;
17556
- if (!tuiBound) {
17607
+ if (!tuiBound && subcommand !== "update") {
17557
17608
  const { maybeSelfUpdate: maybeSelfUpdate2 } = await Promise.resolve().then(() => (init_self_update(), self_update_exports));
17558
17609
  maybeSelfUpdate2();
17559
17610
  }
package/dist/tui/index.js CHANGED
@@ -4720,6 +4720,8 @@ var CHECK_EVERY_MS = 30 * 60 * 1e3;
4720
4720
  var ATTEMPT_EVERY_MS = 6 * 60 * 60 * 1e3;
4721
4721
  var STATE_FILE2 = join9(homedir9(), ".solongate", ".self-update.json");
4722
4722
  var LOG_FILE2 = join9(homedir9(), ".solongate", "self-update.log");
4723
+ var LOCK_FILE = join9(homedir9(), ".solongate", ".update-install.lock");
4724
+ var LOCK_STALE_MS = 3 * 6e4;
4723
4725
  var NEEDS_ADMIN_RE = /\bEACCES\b|\bEPERM\b|permission denied|operation not permitted/i;
4724
4726
  function readState2() {
4725
4727
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.83.30",
3
+ "version": "0.83.32",
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": {
@@ -61,12 +61,12 @@
61
61
  "node": ">=20.0.0"
62
62
  },
63
63
  "optionalDependencies": {
64
- "@solongate/guard-linux-x64": "0.83.30",
65
- "@solongate/guard-linux-arm64": "0.83.30",
66
- "@solongate/guard-darwin-x64": "0.83.30",
67
- "@solongate/guard-darwin-arm64": "0.83.30",
68
- "@solongate/guard-win32-x64": "0.83.30",
69
- "@solongate/guard-win32-arm64": "0.83.30"
64
+ "@solongate/guard-linux-x64": "0.83.32",
65
+ "@solongate/guard-linux-arm64": "0.83.32",
66
+ "@solongate/guard-darwin-x64": "0.83.32",
67
+ "@solongate/guard-darwin-arm64": "0.83.32",
68
+ "@solongate/guard-win32-x64": "0.83.32",
69
+ "@solongate/guard-win32-arm64": "0.83.32"
70
70
  },
71
71
  "dependencies": {
72
72
  "@modelcontextprotocol/sdk": "^1.26.0",