@solongate/proxy 0.58.0 → 0.59.1

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.
File without changes
package/dist/create.js CHANGED
File without changes
@@ -232,7 +232,7 @@ async function runGlobalInstall(opts = {}) {
232
232
  writeFileSync(join(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
233
233
  writeFileSync(join(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
234
234
  console.log(` Installed hooks \u2192 ${p.hooksDir}`);
235
- installClaudeShim(join(p.hooksDir, "shield.mjs"));
235
+ removeClaudeShim();
236
236
  writeFileSync(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
237
237
  console.log(` Wrote ${p.configPath}`);
238
238
  let existing = {};
package/dist/index.js CHANGED
@@ -3412,12 +3412,12 @@ ${ctx.indent}`;
3412
3412
  for (const {
3413
3413
  format,
3414
3414
  test,
3415
- resolve: resolve8
3415
+ resolve: resolve9
3416
3416
  } of tags) {
3417
3417
  if (test) {
3418
3418
  const match = str.match(test);
3419
3419
  if (match) {
3420
- let res = resolve8.apply(null, match);
3420
+ let res = resolve9.apply(null, match);
3421
3421
  if (!(res instanceof Scalar)) res = new Scalar(res);
3422
3422
  if (format) res.format = format;
3423
3423
  return res;
@@ -6809,7 +6809,7 @@ async function runGlobalInstall(opts = {}) {
6809
6809
  writeFileSync3(join4(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
6810
6810
  writeFileSync3(join4(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
6811
6811
  console.log(` Installed hooks \u2192 ${p.hooksDir}`);
6812
- installClaudeShim(join4(p.hooksDir, "shield.mjs"));
6812
+ removeClaudeShim();
6813
6813
  writeFileSync3(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
6814
6814
  console.log(` Wrote ${p.configPath}`);
6815
6815
  let existing = {};
@@ -7049,11 +7049,104 @@ function loadCfg() {
7049
7049
  if (f && existsSync5(f)) {
7050
7050
  const c3 = JSON.parse(readFileSync6(f, "utf-8"));
7051
7051
  const d = c3?.security?.dlpRedact;
7052
- if (d && Array.isArray(d.patterns)) return { patterns: d.patterns, custom: Array.isArray(d.custom) ? d.custom : [] };
7052
+ const g = c3?.security?.ghost;
7053
+ const ghost = g && Array.isArray(g.patterns) ? g.patterns : [];
7054
+ if (d && Array.isArray(d.patterns)) return { patterns: d.patterns, custom: Array.isArray(d.custom) ? d.custom : [], ghost };
7055
+ return { patterns: DLP_PATTERNS.map((p) => p.name), custom: [], ghost };
7053
7056
  }
7054
7057
  } catch {
7055
7058
  }
7056
- return { patterns: DLP_PATTERNS.map((p) => p.name), custom: [] };
7059
+ return { patterns: DLP_PATTERNS.map((p) => p.name), custom: [], ghost: [] };
7060
+ }
7061
+ function ghostGlobToRegExp(glob) {
7062
+ let re = "";
7063
+ for (let i = 0; i < glob.length; i++) {
7064
+ const c3 = glob[i];
7065
+ if (c3 === "*") {
7066
+ if (glob[i + 1] === "*") {
7067
+ re += ".*";
7068
+ i++;
7069
+ } else re += "[^/]*";
7070
+ } else if (c3 === "?") re += "[^/]";
7071
+ else if ("\\^$.|+()[]{}".indexOf(c3) !== -1) re += "\\" + c3;
7072
+ else re += c3;
7073
+ }
7074
+ try {
7075
+ return new RegExp("^" + re + "$");
7076
+ } catch {
7077
+ return null;
7078
+ }
7079
+ }
7080
+ function ghostMatch(targetPath, patterns) {
7081
+ if (!targetPath || !Array.isArray(patterns) || patterns.length === 0) return false;
7082
+ const norm = String(targetPath).replace(/\\/g, "/").replace(/\/+$/, "");
7083
+ if (!norm) return false;
7084
+ const segments = norm.split("/").filter(Boolean);
7085
+ const base = segments.length ? segments[segments.length - 1] : norm;
7086
+ for (let pat of patterns) {
7087
+ pat = String(pat || "").trim();
7088
+ if (!pat) continue;
7089
+ let dirOnly = false;
7090
+ if (pat.endsWith("/")) {
7091
+ dirOnly = true;
7092
+ pat = pat.slice(0, -1);
7093
+ }
7094
+ if (!pat) continue;
7095
+ const hasSlash = pat.indexOf("/") !== -1;
7096
+ const hasWild = /[*?]/.test(pat);
7097
+ const re = ghostGlobToRegExp(pat);
7098
+ if (!re) continue;
7099
+ if (dirOnly) {
7100
+ if (!hasSlash && !hasWild) {
7101
+ if (segments.indexOf(pat) !== -1) return true;
7102
+ continue;
7103
+ }
7104
+ let acc = "";
7105
+ for (const s of segments) {
7106
+ acc = acc ? acc + "/" + s : s;
7107
+ if (re.test(acc) || re.test(s)) return true;
7108
+ }
7109
+ continue;
7110
+ }
7111
+ if (!hasSlash) {
7112
+ if (re.test(base)) return true;
7113
+ if (segments.some((s) => re.test(s))) return true;
7114
+ continue;
7115
+ }
7116
+ if (re.test(norm)) return true;
7117
+ }
7118
+ return false;
7119
+ }
7120
+ function ghostCleanToken(tok) {
7121
+ let t = String(tok || "").trim();
7122
+ t = t.replace(/^[<>|;&(]+/, "").replace(/[);&|]+$/, "");
7123
+ t = t.replace(/^['"]+/, "").replace(/['"]+$/, "");
7124
+ t = t.replace(/^\d*>>?/, "");
7125
+ return t.trim();
7126
+ }
7127
+ function ghostStripLines(text, pats) {
7128
+ if (!Array.isArray(pats) || pats.length === 0) return text;
7129
+ const lines = String(text).split("\n");
7130
+ const kept = [];
7131
+ for (const line of lines) {
7132
+ const trimmed = line.trim();
7133
+ if (!trimmed) {
7134
+ kept.push(line);
7135
+ continue;
7136
+ }
7137
+ if (ghostMatch(trimmed, pats)) continue;
7138
+ const toks = trimmed.split(/\s+/);
7139
+ const anyHit = toks.some((t) => ghostMatch(ghostCleanToken(t), pats));
7140
+ if (!anyHit) {
7141
+ kept.push(line);
7142
+ continue;
7143
+ }
7144
+ if (toks.length > 3) continue;
7145
+ const remaining = toks.filter((t) => !ghostMatch(ghostCleanToken(t), pats));
7146
+ if (remaining.length === 0) continue;
7147
+ kept.push(remaining.join(" "));
7148
+ }
7149
+ return kept.join("\n");
7057
7150
  }
7058
7151
  function dlpGlobToRe(glob, flags) {
7059
7152
  let re = "";
@@ -7078,8 +7171,16 @@ function redactString(s, cfg) {
7078
7171
  return out;
7079
7172
  }
7080
7173
  function redactDeep(value, cfg) {
7081
- if (typeof value === "string") return redactString(value, cfg);
7082
- if (Array.isArray(value)) return value.map((v) => redactDeep(v, cfg));
7174
+ const ghost = cfg && Array.isArray(cfg.ghost) ? cfg.ghost : null;
7175
+ if (typeof value === "string") {
7176
+ let out = redactString(value, cfg);
7177
+ if (ghost && ghost.length) out = ghostStripLines(out, ghost);
7178
+ return out;
7179
+ }
7180
+ if (Array.isArray(value)) {
7181
+ const arr = ghost && ghost.length ? value.filter((v) => !(typeof v === "string" && ghostMatch(v.trim(), ghost))) : value;
7182
+ return arr.map((v) => redactDeep(v, cfg));
7183
+ }
7083
7184
  if (value && typeof value === "object") {
7084
7185
  const out = {};
7085
7186
  for (const [k, v] of Object.entries(value)) out[k] = redactDeep(v, cfg);
@@ -7206,22 +7307,202 @@ var init_shield = __esm({
7206
7307
  { name: "GitHub fine-grained PAT", re: /github_pat_[A-Za-z0-9_]{20,}/g },
7207
7308
  { name: "GitLab token", re: /glpat-[A-Za-z0-9_-]{20,}/g },
7208
7309
  { name: "Slack token", re: /xox[baprs]-[A-Za-z0-9-]{10,}/g },
7209
- { name: "Google API key", re: /AIza[0-9A-Za-z_-]{35}/g },
7210
7310
  { name: "Stripe key", re: /[sr]k_(live|test)_[A-Za-z0-9]{20,}/g },
7211
7311
  { name: "SendGrid key", re: /SG\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}/g },
7212
7312
  { name: "Twilio key", re: /SK[0-9a-fA-F]{32}/g },
7213
7313
  { name: "npm token", re: /npm_[A-Za-z0-9]{36}/g },
7214
7314
  { name: "JWT", re: /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g },
7215
- { name: "Bearer token", re: /bearer\s+[A-Za-z0-9._-]{20,}/gi },
7216
- { name: "secret assignment", re: /(api[_-]?key|secret|token|password|passwd|access[_-]?key)["']?\s*[:=]\s*["']?[A-Za-z0-9/+_.-]{12,}/gi }
7315
+ { name: "Bearer token", re: /bearer\s+[A-Za-z0-9._-]{20,}/gi }
7217
7316
  ];
7218
7317
  }
7219
7318
  });
7220
7319
 
7320
+ // src/logs-server.ts
7321
+ var logs_server_exports = {};
7322
+ __export(logs_server_exports, {
7323
+ runLogsServer: () => runLogsServer
7324
+ });
7325
+ import { createServer as createServer2 } from "http";
7326
+ import { readFileSync as readFileSync7, statSync as statSync2 } from "fs";
7327
+ import { resolve as resolve5, join as join5, isAbsolute } from "path";
7328
+ import { homedir as homedir4 } from "os";
7329
+ import { readdirSync as readdirSync2 } from "fs";
7330
+ function allowedOrigins() {
7331
+ const base = [
7332
+ "https://dashboard.solongate.com",
7333
+ "http://localhost:3000",
7334
+ "http://localhost:3005",
7335
+ "http://127.0.0.1:3000",
7336
+ "http://127.0.0.1:3005"
7337
+ ];
7338
+ const extra = (process.env.SOLONGATE_DASHBOARD_ORIGIN || "").split(",").map((s) => s.trim()).filter(Boolean);
7339
+ return /* @__PURE__ */ new Set([...base, ...extra]);
7340
+ }
7341
+ function resolveLocalLogDir(rawPath) {
7342
+ const dir = String(rawPath || "").trim().replace(/[\\/]+$/, "");
7343
+ if (!dir) return null;
7344
+ if (isAbsolute(dir)) return dir;
7345
+ return resolve5(homedir4(), ".solongate", "local-logs");
7346
+ }
7347
+ async function findLogDir() {
7348
+ const base = resolve5(homedir4(), ".solongate");
7349
+ try {
7350
+ const files = readdirSync2(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
7351
+ for (const f of files) {
7352
+ try {
7353
+ const c3 = JSON.parse(readFileSync7(join5(base, f), "utf-8"));
7354
+ const p = c3?.security?.localLogs?.path;
7355
+ if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
7356
+ } catch {
7357
+ }
7358
+ }
7359
+ } catch {
7360
+ }
7361
+ try {
7362
+ const cfgRaw = readFileSync7(join5(base, "cloud-guard.json"), "utf-8");
7363
+ const { apiKey, apiUrl } = JSON.parse(cfgRaw);
7364
+ if (apiKey) {
7365
+ const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
7366
+ const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
7367
+ if (res.ok) {
7368
+ const body = await res.json();
7369
+ const p = body?.security?.localLogs?.path;
7370
+ if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
7371
+ }
7372
+ }
7373
+ } catch {
7374
+ }
7375
+ return { dir: null, configured: null };
7376
+ }
7377
+ function setCors(req, res) {
7378
+ const origin = req.headers.origin;
7379
+ if (origin && allowedOrigins().has(origin)) {
7380
+ res.setHeader("Access-Control-Allow-Origin", origin);
7381
+ res.setHeader("Vary", "Origin");
7382
+ }
7383
+ if (req.headers["access-control-request-private-network"] === "true") {
7384
+ res.setHeader("Access-Control-Allow-Private-Network", "true");
7385
+ }
7386
+ res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
7387
+ res.setHeader("Access-Control-Allow-Headers", "If-Modified-Since, Content-Type");
7388
+ }
7389
+ function fileInfo(dir) {
7390
+ if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
7391
+ const file = join5(dir, LOG_FILENAME);
7392
+ try {
7393
+ const st = statSync2(file);
7394
+ return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
7395
+ } catch {
7396
+ return { file, exists: false, size: 0, mtimeMs: 0 };
7397
+ }
7398
+ }
7399
+ async function runLogsServer() {
7400
+ const argv = process.argv.slice(3);
7401
+ const portArg = argv[argv.indexOf("--port") + 1];
7402
+ const port = Number(process.env.SOLONGATE_LOGS_PORT || (argv.includes("--port") ? portArg : "") || DEFAULT_PORT) || DEFAULT_PORT;
7403
+ const server = createServer2(async (req, res) => {
7404
+ setCors(req, res);
7405
+ if (req.method === "OPTIONS") {
7406
+ res.writeHead(204);
7407
+ res.end();
7408
+ return;
7409
+ }
7410
+ if (req.method !== "GET") {
7411
+ res.writeHead(405);
7412
+ res.end();
7413
+ return;
7414
+ }
7415
+ const url = (req.url || "/").split("?")[0];
7416
+ const { dir, configured } = await findLogDir();
7417
+ if (url === "/health") {
7418
+ const info = fileInfo(dir);
7419
+ res.writeHead(200, { "Content-Type": "application/json" });
7420
+ res.end(JSON.stringify({
7421
+ ok: true,
7422
+ agent: "solongate-logs-server",
7423
+ configuredPath: configured,
7424
+ resolvedDir: dir,
7425
+ file: info.file,
7426
+ exists: info.exists,
7427
+ size: info.size,
7428
+ mtime: info.mtimeMs ? new Date(info.mtimeMs).toISOString() : null
7429
+ }));
7430
+ return;
7431
+ }
7432
+ if (url === "/local-logs") {
7433
+ const info = fileInfo(dir);
7434
+ if (!dir) {
7435
+ res.writeHead(200, { "Content-Type": "text/plain", "X-Solongate-Configured": "0" });
7436
+ res.end("");
7437
+ return;
7438
+ }
7439
+ if (!info.exists) {
7440
+ res.writeHead(200, { "Content-Type": "text/plain", "X-Solongate-Exists": "0" });
7441
+ res.end("");
7442
+ return;
7443
+ }
7444
+ const lastMod = new Date(info.mtimeMs).toUTCString();
7445
+ const since = req.headers["if-modified-since"];
7446
+ if (since && new Date(since).getTime() >= Math.floor(info.mtimeMs / 1e3) * 1e3) {
7447
+ res.writeHead(304, { "Last-Modified": lastMod });
7448
+ res.end();
7449
+ return;
7450
+ }
7451
+ try {
7452
+ const text = readFileSync7(info.file, "utf-8");
7453
+ res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8", "Last-Modified": lastMod, "X-Solongate-Exists": "1" });
7454
+ res.end(text);
7455
+ } catch {
7456
+ res.writeHead(500);
7457
+ res.end("read error");
7458
+ }
7459
+ return;
7460
+ }
7461
+ res.writeHead(404);
7462
+ res.end("not found");
7463
+ });
7464
+ server.listen(port, "127.0.0.1", async () => {
7465
+ const { dir, configured } = await findLogDir();
7466
+ process.stdout.write(`[SolonGate] Local logs agent listening on http://127.0.0.1:${port}
7467
+ `);
7468
+ if (configured) {
7469
+ process.stdout.write(`[SolonGate] Configured path: ${configured}
7470
+ `);
7471
+ if (dir && dir !== configured.trim().replace(/[\\/]+$/, "")) {
7472
+ process.stdout.write(`[SolonGate] That path isn't absolute on this machine \u2014 reading from: ${dir}
7473
+ `);
7474
+ }
7475
+ } else {
7476
+ process.stdout.write(`[SolonGate] Local log storage not configured yet (set it in dashboard Settings).
7477
+ `);
7478
+ }
7479
+ process.stdout.write(`[SolonGate] Keep this running; the dashboard reads your logs live from here. Ctrl+C to stop.
7480
+ `);
7481
+ });
7482
+ server.on("error", (err) => {
7483
+ if (err.code === "EADDRINUSE") {
7484
+ process.stderr.write(`[SolonGate] Port ${port} is already in use. Pass --port <n> or set SOLONGATE_LOGS_PORT.
7485
+ `);
7486
+ } else {
7487
+ process.stderr.write(`[SolonGate] Local logs agent error: ${err.message}
7488
+ `);
7489
+ }
7490
+ process.exit(1);
7491
+ });
7492
+ }
7493
+ var LOG_FILENAME, DEFAULT_PORT;
7494
+ var init_logs_server = __esm({
7495
+ "src/logs-server.ts"() {
7496
+ "use strict";
7497
+ LOG_FILENAME = "solongate-audit.jsonl";
7498
+ DEFAULT_PORT = 8788;
7499
+ }
7500
+ });
7501
+
7221
7502
  // src/inject.ts
7222
7503
  var inject_exports = {};
7223
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, existsSync as existsSync6, copyFileSync } from "fs";
7224
- import { resolve as resolve5 } from "path";
7504
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync4, existsSync as existsSync7, copyFileSync } from "fs";
7505
+ import { resolve as resolve6 } from "path";
7225
7506
  import { execSync } from "child_process";
7226
7507
  function parseInjectArgs(argv) {
7227
7508
  const args = argv.slice(2);
@@ -7278,9 +7559,9 @@ WHAT IT DOES
7278
7559
  `);
7279
7560
  }
7280
7561
  function detectProject() {
7281
- if (!existsSync6(resolve5("package.json"))) return false;
7562
+ if (!existsSync7(resolve6("package.json"))) return false;
7282
7563
  try {
7283
- const pkg = JSON.parse(readFileSync7(resolve5("package.json"), "utf-8"));
7564
+ const pkg = JSON.parse(readFileSync8(resolve6("package.json"), "utf-8"));
7284
7565
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
7285
7566
  return !!(allDeps["@modelcontextprotocol/sdk"] || allDeps["@modelcontextprotocol/server"]);
7286
7567
  } catch {
@@ -7289,18 +7570,18 @@ function detectProject() {
7289
7570
  }
7290
7571
  function findTsEntryFile() {
7291
7572
  try {
7292
- const pkg = JSON.parse(readFileSync7(resolve5("package.json"), "utf-8"));
7573
+ const pkg = JSON.parse(readFileSync8(resolve6("package.json"), "utf-8"));
7293
7574
  if (pkg.bin) {
7294
7575
  const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
7295
7576
  if (typeof binPath === "string") {
7296
7577
  const srcPath = binPath.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
7297
- if (existsSync6(resolve5(srcPath))) return resolve5(srcPath);
7298
- if (existsSync6(resolve5(binPath))) return resolve5(binPath);
7578
+ if (existsSync7(resolve6(srcPath))) return resolve6(srcPath);
7579
+ if (existsSync7(resolve6(binPath))) return resolve6(binPath);
7299
7580
  }
7300
7581
  }
7301
7582
  if (pkg.main) {
7302
7583
  const srcPath = pkg.main.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
7303
- if (existsSync6(resolve5(srcPath))) return resolve5(srcPath);
7584
+ if (existsSync7(resolve6(srcPath))) return resolve6(srcPath);
7304
7585
  }
7305
7586
  } catch {
7306
7587
  }
@@ -7313,10 +7594,10 @@ function findTsEntryFile() {
7313
7594
  "main.ts"
7314
7595
  ];
7315
7596
  for (const c3 of candidates) {
7316
- const full = resolve5(c3);
7317
- if (existsSync6(full)) {
7597
+ const full = resolve6(c3);
7598
+ if (existsSync7(full)) {
7318
7599
  try {
7319
- const content = readFileSync7(full, "utf-8");
7600
+ const content = readFileSync8(full, "utf-8");
7320
7601
  if (content.includes("McpServer") || content.includes("McpServer")) {
7321
7602
  return full;
7322
7603
  }
@@ -7325,18 +7606,18 @@ function findTsEntryFile() {
7325
7606
  }
7326
7607
  }
7327
7608
  for (const c3 of candidates) {
7328
- if (existsSync6(resolve5(c3))) return resolve5(c3);
7609
+ if (existsSync7(resolve6(c3))) return resolve6(c3);
7329
7610
  }
7330
7611
  return null;
7331
7612
  }
7332
7613
  function detectPackageManager() {
7333
- if (existsSync6(resolve5("pnpm-lock.yaml"))) return "pnpm";
7334
- if (existsSync6(resolve5("yarn.lock"))) return "yarn";
7614
+ if (existsSync7(resolve6("pnpm-lock.yaml"))) return "pnpm";
7615
+ if (existsSync7(resolve6("yarn.lock"))) return "yarn";
7335
7616
  return "npm";
7336
7617
  }
7337
7618
  function installSdk() {
7338
7619
  try {
7339
- const pkg = JSON.parse(readFileSync7(resolve5("package.json"), "utf-8"));
7620
+ const pkg = JSON.parse(readFileSync8(resolve6("package.json"), "utf-8"));
7340
7621
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
7341
7622
  if (allDeps["@solongate/proxy"]) {
7342
7623
  log3(" @solongate/proxy already installed");
@@ -7357,7 +7638,7 @@ function installSdk() {
7357
7638
  }
7358
7639
  }
7359
7640
  function injectTypeScript(filePath) {
7360
- const original = readFileSync7(filePath, "utf-8");
7641
+ const original = readFileSync8(filePath, "utf-8");
7361
7642
  const changes = [];
7362
7643
  let modified = original;
7363
7644
  if (modified.includes("SecureMcpServer")) {
@@ -7473,8 +7754,8 @@ async function main2() {
7473
7754
  process.exit(1);
7474
7755
  }
7475
7756
  log3(" Language: TypeScript");
7476
- const entryFile = opts.file ? resolve5(opts.file) : findTsEntryFile();
7477
- if (!entryFile || !existsSync6(entryFile)) {
7757
+ const entryFile = opts.file ? resolve6(opts.file) : findTsEntryFile();
7758
+ if (!entryFile || !existsSync7(entryFile)) {
7478
7759
  log3(` Could not find entry file.${opts.file ? ` File not found: ${opts.file}` : ""}`);
7479
7760
  log3("");
7480
7761
  log3(" Specify it manually: --file <path>");
@@ -7487,7 +7768,7 @@ async function main2() {
7487
7768
  log3("");
7488
7769
  const backupPath = entryFile + ".solongate-backup";
7489
7770
  if (opts.restore) {
7490
- if (!existsSync6(backupPath)) {
7771
+ if (!existsSync7(backupPath)) {
7491
7772
  log3(" No backup found. Nothing to restore.");
7492
7773
  process.exit(1);
7493
7774
  }
@@ -7523,7 +7804,7 @@ async function main2() {
7523
7804
  log3(" To apply: npx @solongate/proxy inject");
7524
7805
  process.exit(0);
7525
7806
  }
7526
- if (!existsSync6(backupPath)) {
7807
+ if (!existsSync7(backupPath)) {
7527
7808
  copyFileSync(entryFile, backupPath);
7528
7809
  log3("");
7529
7810
  log3(` Backup: ${backupPath}`);
@@ -7557,8 +7838,8 @@ var init_inject = __esm({
7557
7838
 
7558
7839
  // src/create.ts
7559
7840
  var create_exports = {};
7560
- import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, existsSync as existsSync7 } from "fs";
7561
- import { resolve as resolve6, join as join5 } from "path";
7841
+ import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, existsSync as existsSync8 } from "fs";
7842
+ import { resolve as resolve7, join as join6 } from "path";
7562
7843
  import { execSync as execSync2 } from "child_process";
7563
7844
  function withSpinner(message, fn) {
7564
7845
  const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
@@ -7638,7 +7919,7 @@ EXAMPLES
7638
7919
  }
7639
7920
  function createProject(dir, name, _policy) {
7640
7921
  writeFileSync5(
7641
- join5(dir, "package.json"),
7922
+ join6(dir, "package.json"),
7642
7923
  JSON.stringify(
7643
7924
  {
7644
7925
  name,
@@ -7668,7 +7949,7 @@ function createProject(dir, name, _policy) {
7668
7949
  ) + "\n"
7669
7950
  );
7670
7951
  writeFileSync5(
7671
- join5(dir, "tsconfig.json"),
7952
+ join6(dir, "tsconfig.json"),
7672
7953
  JSON.stringify(
7673
7954
  {
7674
7955
  compilerOptions: {
@@ -7688,9 +7969,9 @@ function createProject(dir, name, _policy) {
7688
7969
  2
7689
7970
  ) + "\n"
7690
7971
  );
7691
- mkdirSync5(join5(dir, "src"), { recursive: true });
7972
+ mkdirSync5(join6(dir, "src"), { recursive: true });
7692
7973
  writeFileSync5(
7693
- join5(dir, "src", "index.ts"),
7974
+ join6(dir, "src", "index.ts"),
7694
7975
  `#!/usr/bin/env node
7695
7976
 
7696
7977
  console.log = (...args: unknown[]) => {
@@ -7732,7 +8013,7 @@ console.log('Press Ctrl+C to stop.');
7732
8013
  `
7733
8014
  );
7734
8015
  writeFileSync5(
7735
- join5(dir, ".mcp.json"),
8016
+ join6(dir, ".mcp.json"),
7736
8017
  JSON.stringify(
7737
8018
  {
7738
8019
  mcpServers: {
@@ -7750,12 +8031,12 @@ console.log('Press Ctrl+C to stop.');
7750
8031
  ) + "\n"
7751
8032
  );
7752
8033
  writeFileSync5(
7753
- join5(dir, ".env"),
8034
+ join6(dir, ".env"),
7754
8035
  `SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
7755
8036
  `
7756
8037
  );
7757
8038
  writeFileSync5(
7758
- join5(dir, ".gitignore"),
8039
+ join6(dir, ".gitignore"),
7759
8040
  `node_modules/
7760
8041
  dist/
7761
8042
  *.solongate-backup
@@ -7767,9 +8048,9 @@ dist/
7767
8048
  }
7768
8049
  async function main3() {
7769
8050
  const opts = parseCreateArgs(process.argv);
7770
- const dir = resolve6(opts.name);
8051
+ const dir = resolve7(opts.name);
7771
8052
  printBanner("Create MCP Server");
7772
- if (existsSync7(dir)) {
8053
+ if (existsSync8(dir)) {
7773
8054
  log3(` ${c.red}Error:${c.reset} Directory "${opts.name}" already exists.`);
7774
8055
  process.exit(1);
7775
8056
  }
@@ -7848,14 +8129,14 @@ var init_create = __esm({
7848
8129
 
7849
8130
  // src/pull-push.ts
7850
8131
  var pull_push_exports = {};
7851
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync8 } from "fs";
7852
- import { resolve as resolve7 } from "path";
8132
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync9 } from "fs";
8133
+ import { resolve as resolve8 } from "path";
7853
8134
  function loadEnv() {
7854
8135
  if (process.env.SOLONGATE_API_KEY) return;
7855
- const envPath = resolve7(".env");
7856
- if (!existsSync8(envPath)) return;
8136
+ const envPath = resolve8(".env");
8137
+ if (!existsSync9(envPath)) return;
7857
8138
  try {
7858
- const content = readFileSync8(envPath, "utf-8");
8139
+ const content = readFileSync9(envPath, "utf-8");
7859
8140
  for (const line of content.split("\n")) {
7860
8141
  const trimmed = line.trim();
7861
8142
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -7910,7 +8191,7 @@ function parseCliArgs() {
7910
8191
  log5(red("ERROR: Pull/push/list requires a live API key (sg_live_...)."));
7911
8192
  process.exit(1);
7912
8193
  }
7913
- return { command, apiKey, file: resolve7(file), policyId };
8194
+ return { command, apiKey, file: resolve8(file), policyId };
7914
8195
  }
7915
8196
  async function listPolicies(apiKey) {
7916
8197
  const res = await fetch(`${API_URL}/api/v1/policies`, {
@@ -8055,7 +8336,7 @@ async function pull(apiKey, file, policyId) {
8055
8336
  log5("");
8056
8337
  }
8057
8338
  async function push(apiKey, file, policyId) {
8058
- if (!existsSync8(file)) {
8339
+ if (!existsSync9(file)) {
8059
8340
  log5(red(`ERROR: File not found: ${file}`));
8060
8341
  process.exit(1);
8061
8342
  }
@@ -8072,7 +8353,7 @@ async function push(apiKey, file, policyId) {
8072
8353
  log5(" solongate-proxy list");
8073
8354
  process.exit(1);
8074
8355
  }
8075
- const content = readFileSync8(file, "utf-8");
8356
+ const content = readFileSync9(file, "utf-8");
8076
8357
  let policy;
8077
8358
  try {
8078
8359
  policy = JSON.parse(content);
@@ -10589,7 +10870,7 @@ var Mutex = class {
10589
10870
  this.locked = true;
10590
10871
  return;
10591
10872
  }
10592
- return new Promise((resolve8, reject) => {
10873
+ return new Promise((resolve9, reject) => {
10593
10874
  const timer = setTimeout(() => {
10594
10875
  const idx = this.queue.indexOf(onReady);
10595
10876
  if (idx !== -1) this.queue.splice(idx, 1);
@@ -10597,7 +10878,7 @@ var Mutex = class {
10597
10878
  }, timeoutMs);
10598
10879
  const onReady = () => {
10599
10880
  clearTimeout(timer);
10600
- resolve8();
10881
+ resolve9();
10601
10882
  };
10602
10883
  this.queue.push(onReady);
10603
10884
  });
@@ -11217,7 +11498,7 @@ ${msg.content.text}`;
11217
11498
 
11218
11499
  // src/index.ts
11219
11500
  init_cli_utils();
11220
- var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["login", "logout", "shield", "create", "inject", "pull", "push", "list", "ls"]);
11501
+ var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["login", "logout", "shield", "create", "inject", "pull", "push", "list", "ls", "logs-server", "local-logs"]);
11221
11502
  var IS_HUMAN_CLI = process.argv.length <= 2 || CLI_SUBCOMMANDS.has(process.argv[2] ?? "");
11222
11503
  if (!IS_HUMAN_CLI) {
11223
11504
  console.log = (...args) => {
@@ -11245,6 +11526,9 @@ function printWelcome() {
11245
11526
  console.log(` ${c.dim}on this machine with your cloud policy. Manage it at${c.reset}`);
11246
11527
  console.log(` ${c.cyan}https://dashboard.solongate.com${c.reset}`);
11247
11528
  console.log("");
11529
+ console.log(` ${c.dim}Using local log storage? Show it live in the dashboard with${c.reset}`);
11530
+ console.log(` ${c.cyan}npx -y @solongate/proxy@latest logs-server${c.reset}`);
11531
+ console.log("");
11248
11532
  }
11249
11533
  async function main5() {
11250
11534
  const subcommand = process.argv[2];
@@ -11266,6 +11550,11 @@ async function main5() {
11266
11550
  await runShield2();
11267
11551
  return;
11268
11552
  }
11553
+ if (subcommand === "logs-server" || subcommand === "local-logs") {
11554
+ const { runLogsServer: runLogsServer2 } = await Promise.resolve().then(() => (init_logs_server(), logs_server_exports));
11555
+ await runLogsServer2();
11556
+ return;
11557
+ }
11269
11558
  if (subcommand === "inject") {
11270
11559
  process.argv.splice(2, 1);
11271
11560
  await Promise.resolve().then(() => (init_inject(), inject_exports));
package/dist/inject.js CHANGED
File without changes