@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.
- package/dist/audit/index.js +0 -0
- package/dist/create.js +0 -0
- package/dist/global-install.js +1 -1
- package/dist/index.js +341 -52
- package/dist/inject.js +0 -0
- package/dist/login.js +5 -39
- package/dist/logs-server.d.ts +1 -0
- package/dist/logs-server.js +174 -0
- package/dist/pull-push.js +0 -0
- package/dist/shield.js +106 -7
- package/hooks/.solongate/.last-deny +1 -0
- package/hooks/.solongate/.last-eval +1 -0
- package/hooks/.solongate/.last-tool-call +1 -0
- package/hooks/audit.mjs +565 -544
- package/hooks/guard.bundled.mjs +37 -6
- package/hooks/guard.mjs +1651 -1604
- package/hooks/shield.mjs +271 -271
- package/hooks/stop.mjs +75 -75
- package/package.json +74 -74
package/dist/audit/index.js
CHANGED
|
File without changes
|
package/dist/create.js
CHANGED
|
File without changes
|
package/dist/global-install.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7082
|
-
if (
|
|
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
|
|
7224
|
-
import { resolve as
|
|
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 (!
|
|
7562
|
+
if (!existsSync7(resolve6("package.json"))) return false;
|
|
7282
7563
|
try {
|
|
7283
|
-
const pkg = JSON.parse(
|
|
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(
|
|
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 (
|
|
7298
|
-
if (
|
|
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 (
|
|
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 =
|
|
7317
|
-
if (
|
|
7597
|
+
const full = resolve6(c3);
|
|
7598
|
+
if (existsSync7(full)) {
|
|
7318
7599
|
try {
|
|
7319
|
-
const content =
|
|
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 (
|
|
7609
|
+
if (existsSync7(resolve6(c3))) return resolve6(c3);
|
|
7329
7610
|
}
|
|
7330
7611
|
return null;
|
|
7331
7612
|
}
|
|
7332
7613
|
function detectPackageManager() {
|
|
7333
|
-
if (
|
|
7334
|
-
if (
|
|
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(
|
|
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 =
|
|
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 ?
|
|
7477
|
-
if (!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 (!
|
|
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 (!
|
|
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
|
|
7561
|
-
import { resolve as
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
7972
|
+
mkdirSync5(join6(dir, "src"), { recursive: true });
|
|
7692
7973
|
writeFileSync5(
|
|
7693
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8034
|
+
join6(dir, ".env"),
|
|
7754
8035
|
`SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
|
|
7755
8036
|
`
|
|
7756
8037
|
);
|
|
7757
8038
|
writeFileSync5(
|
|
7758
|
-
|
|
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 =
|
|
8051
|
+
const dir = resolve7(opts.name);
|
|
7771
8052
|
printBanner("Create MCP Server");
|
|
7772
|
-
if (
|
|
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
|
|
7852
|
-
import { resolve as
|
|
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 =
|
|
7856
|
-
if (!
|
|
8136
|
+
const envPath = resolve8(".env");
|
|
8137
|
+
if (!existsSync9(envPath)) return;
|
|
7857
8138
|
try {
|
|
7858
|
-
const content =
|
|
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:
|
|
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 (!
|
|
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 =
|
|
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((
|
|
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
|
-
|
|
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
|