@solongate/proxy 0.81.45 → 0.81.47
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/api-client/auth.d.ts +12 -0
- package/dist/api-client/index.d.ts +2 -0
- package/dist/commands/index.js +10 -1
- package/dist/index.js +328 -154
- package/dist/self-update.d.ts +6 -0
- package/dist/tui/index.js +29 -5
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
export * from './client.js';
|
|
6
6
|
export * from './types.js';
|
|
7
7
|
export * from './device-login.js';
|
|
8
|
+
import * as auth from './auth.js';
|
|
8
9
|
import * as policies from './policies.js';
|
|
9
10
|
import * as settings from './settings.js';
|
|
10
11
|
import * as stats from './stats.js';
|
|
@@ -13,6 +14,7 @@ import * as agents from './agents.js';
|
|
|
13
14
|
import * as keys from './keys.js';
|
|
14
15
|
import * as mcp from './mcp.js';
|
|
15
16
|
export declare const api: {
|
|
17
|
+
auth: typeof auth;
|
|
16
18
|
policies: typeof policies;
|
|
17
19
|
settings: typeof settings;
|
|
18
20
|
stats: typeof stats;
|
package/dist/commands/index.js
CHANGED
|
@@ -142,6 +142,15 @@ async function request(method, path, opts = {}) {
|
|
|
142
142
|
// src/api-client/device-login.ts
|
|
143
143
|
import { spawn } from "child_process";
|
|
144
144
|
|
|
145
|
+
// src/api-client/auth.ts
|
|
146
|
+
var auth_exports = {};
|
|
147
|
+
__export(auth_exports, {
|
|
148
|
+
me: () => me
|
|
149
|
+
});
|
|
150
|
+
function me() {
|
|
151
|
+
return request("GET", "/auth/me");
|
|
152
|
+
}
|
|
153
|
+
|
|
145
154
|
// src/api-client/policies.ts
|
|
146
155
|
var policies_exports = {};
|
|
147
156
|
__export(policies_exports, {
|
|
@@ -364,7 +373,7 @@ function list4() {
|
|
|
364
373
|
}
|
|
365
374
|
|
|
366
375
|
// src/api-client/index.ts
|
|
367
|
-
var api = { policies: policies_exports, settings: settings_exports, stats: stats_exports, audit: audit_exports, agents: agents_exports, keys: keys_exports, mcp: mcp_exports };
|
|
376
|
+
var api = { auth: auth_exports, policies: policies_exports, settings: settings_exports, stats: stats_exports, audit: audit_exports, agents: agents_exports, keys: keys_exports, mcp: mcp_exports };
|
|
368
377
|
|
|
369
378
|
// src/cli-utils.ts
|
|
370
379
|
var c = {
|
package/dist/index.js
CHANGED
|
@@ -6554,15 +6554,151 @@ var init_cli_utils = __esm({
|
|
|
6554
6554
|
}
|
|
6555
6555
|
});
|
|
6556
6556
|
|
|
6557
|
-
// src/
|
|
6558
|
-
|
|
6557
|
+
// src/self-update.ts
|
|
6558
|
+
var self_update_exports = {};
|
|
6559
|
+
__export(self_update_exports, {
|
|
6560
|
+
currentVersion: () => currentVersion,
|
|
6561
|
+
maybeSelfUpdate: () => maybeSelfUpdate
|
|
6562
|
+
});
|
|
6563
|
+
import { execFile, spawn } from "child_process";
|
|
6564
|
+
import { mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync4, realpathSync, writeFileSync as writeFileSync3 } from "fs";
|
|
6559
6565
|
import { homedir as homedir2 } from "os";
|
|
6560
|
-
import { join as join4 } from "path";
|
|
6566
|
+
import { dirname, join as join4 } from "path";
|
|
6567
|
+
import { fileURLToPath } from "url";
|
|
6568
|
+
function readState() {
|
|
6569
|
+
try {
|
|
6570
|
+
const s = JSON.parse(readFileSync4(STATE_FILE, "utf-8"));
|
|
6571
|
+
return s && typeof s === "object" ? s : {};
|
|
6572
|
+
} catch {
|
|
6573
|
+
return {};
|
|
6574
|
+
}
|
|
6575
|
+
}
|
|
6576
|
+
function writeState(s) {
|
|
6577
|
+
try {
|
|
6578
|
+
mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
|
|
6579
|
+
writeFileSync3(STATE_FILE, JSON.stringify(s));
|
|
6580
|
+
} catch {
|
|
6581
|
+
}
|
|
6582
|
+
}
|
|
6583
|
+
function currentVersion() {
|
|
6584
|
+
try {
|
|
6585
|
+
const pkg = JSON.parse(readFileSync4(join4(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf-8"));
|
|
6586
|
+
return pkg.version ?? "0.0.0";
|
|
6587
|
+
} catch {
|
|
6588
|
+
return "0.0.0";
|
|
6589
|
+
}
|
|
6590
|
+
}
|
|
6591
|
+
function newerThan(b, a) {
|
|
6592
|
+
const pa = a.split(".").map((n) => parseInt(n, 10) || 0);
|
|
6593
|
+
const pb = b.split(".").map((n) => parseInt(n, 10) || 0);
|
|
6594
|
+
for (let i = 0; i < 3; i++) {
|
|
6595
|
+
if ((pb[i] ?? 0) > (pa[i] ?? 0)) return true;
|
|
6596
|
+
if ((pb[i] ?? 0) < (pa[i] ?? 0)) return false;
|
|
6597
|
+
}
|
|
6598
|
+
return false;
|
|
6599
|
+
}
|
|
6600
|
+
async function fetchLatest() {
|
|
6601
|
+
try {
|
|
6602
|
+
const res = await fetch(`https://registry.npmjs.org/${PKG}/latest`, { signal: AbortSignal.timeout(2e3) });
|
|
6603
|
+
if (!res.ok) return null;
|
|
6604
|
+
const j = await res.json();
|
|
6605
|
+
return typeof j.version === "string" ? j.version : null;
|
|
6606
|
+
} catch {
|
|
6607
|
+
return null;
|
|
6608
|
+
}
|
|
6609
|
+
}
|
|
6610
|
+
function npmGlobalRoot() {
|
|
6611
|
+
return new Promise((resolve10) => {
|
|
6612
|
+
try {
|
|
6613
|
+
execFile("npm", ["root", "-g"], { timeout: 5e3, windowsHide: true, shell: process.platform === "win32" }, (err2, stdout) => {
|
|
6614
|
+
resolve10(err2 ? null : stdout.trim() || null);
|
|
6615
|
+
});
|
|
6616
|
+
} catch {
|
|
6617
|
+
resolve10(null);
|
|
6618
|
+
}
|
|
6619
|
+
});
|
|
6620
|
+
}
|
|
6621
|
+
async function isGlobalInstall() {
|
|
6622
|
+
try {
|
|
6623
|
+
const script = realpathSync(process.argv[1] ?? "");
|
|
6624
|
+
if (!script) return false;
|
|
6625
|
+
const root = await npmGlobalRoot();
|
|
6626
|
+
if (!root) return false;
|
|
6627
|
+
return script.startsWith(realpathSync(root));
|
|
6628
|
+
} catch {
|
|
6629
|
+
return false;
|
|
6630
|
+
}
|
|
6631
|
+
}
|
|
6632
|
+
function spawnGlobalInstall(version) {
|
|
6633
|
+
try {
|
|
6634
|
+
mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
|
|
6635
|
+
const log6 = openSync(LOG_FILE, "a");
|
|
6636
|
+
const p = spawn("npm", ["install", "-g", `${PKG}@${version}`], {
|
|
6637
|
+
stdio: ["ignore", log6, log6],
|
|
6638
|
+
detached: true,
|
|
6639
|
+
windowsHide: true,
|
|
6640
|
+
shell: process.platform === "win32"
|
|
6641
|
+
});
|
|
6642
|
+
p.on("error", () => {
|
|
6643
|
+
});
|
|
6644
|
+
p.unref();
|
|
6645
|
+
return true;
|
|
6646
|
+
} catch {
|
|
6647
|
+
return false;
|
|
6648
|
+
}
|
|
6649
|
+
}
|
|
6650
|
+
function maybeSelfUpdate(notify = (l) => process.stderr.write(l + "\n")) {
|
|
6651
|
+
void (async () => {
|
|
6652
|
+
try {
|
|
6653
|
+
const state = readState();
|
|
6654
|
+
const now = Date.now();
|
|
6655
|
+
const current = currentVersion();
|
|
6656
|
+
let latest = state.latestSeen ?? null;
|
|
6657
|
+
if (now - (state.lastCheckAt ?? 0) >= CHECK_EVERY_MS) {
|
|
6658
|
+
latest = await fetchLatest();
|
|
6659
|
+
if (latest) writeState({ ...state, lastCheckAt: now, latestSeen: latest });
|
|
6660
|
+
else writeState({ ...state, lastCheckAt: now });
|
|
6661
|
+
}
|
|
6662
|
+
if (!latest || !newerThan(latest, current)) return;
|
|
6663
|
+
const attempts = readState().attempts ?? {};
|
|
6664
|
+
if (await isGlobalInstall()) {
|
|
6665
|
+
if (now - (attempts[latest] ?? 0) >= ATTEMPT_EVERY_MS) {
|
|
6666
|
+
writeState({ ...readState(), attempts: { [latest]: now } });
|
|
6667
|
+
if (spawnGlobalInstall(latest)) {
|
|
6668
|
+
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 updating in the background, next run uses it${c.reset}`);
|
|
6669
|
+
return;
|
|
6670
|
+
}
|
|
6671
|
+
} else {
|
|
6672
|
+
return;
|
|
6673
|
+
}
|
|
6674
|
+
}
|
|
6675
|
+
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 update: ${c.reset}${c.cyan}npm i -g ${PKG}@latest${c.reset}`);
|
|
6676
|
+
} catch {
|
|
6677
|
+
}
|
|
6678
|
+
})();
|
|
6679
|
+
}
|
|
6680
|
+
var PKG, CHECK_EVERY_MS, ATTEMPT_EVERY_MS, STATE_FILE, LOG_FILE;
|
|
6681
|
+
var init_self_update = __esm({
|
|
6682
|
+
"src/self-update.ts"() {
|
|
6683
|
+
"use strict";
|
|
6684
|
+
init_cli_utils();
|
|
6685
|
+
PKG = "@solongate/proxy";
|
|
6686
|
+
CHECK_EVERY_MS = 30 * 60 * 1e3;
|
|
6687
|
+
ATTEMPT_EVERY_MS = 6 * 60 * 60 * 1e3;
|
|
6688
|
+
STATE_FILE = join4(homedir2(), ".solongate", ".self-update.json");
|
|
6689
|
+
LOG_FILE = join4(homedir2(), ".solongate", "self-update.log");
|
|
6690
|
+
}
|
|
6691
|
+
});
|
|
6692
|
+
|
|
6693
|
+
// src/tui/config.ts
|
|
6694
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
6695
|
+
import { homedir as homedir3 } from "os";
|
|
6696
|
+
import { join as join5 } from "path";
|
|
6561
6697
|
function loadConfig() {
|
|
6562
6698
|
if (cached) return cached;
|
|
6563
6699
|
const defaults = { notifications: true };
|
|
6564
6700
|
try {
|
|
6565
|
-
const raw =
|
|
6701
|
+
const raw = readFileSync5(join5(homedir3(), ".solongate", "tui-config.json"), "utf-8");
|
|
6566
6702
|
const j = JSON.parse(raw);
|
|
6567
6703
|
cached = {
|
|
6568
6704
|
notifications: j.notifications !== false,
|
|
@@ -6688,14 +6824,14 @@ var init_components = __esm({
|
|
|
6688
6824
|
});
|
|
6689
6825
|
|
|
6690
6826
|
// src/tui/local-log.ts
|
|
6691
|
-
import { closeSync, openSync, readFileSync as
|
|
6692
|
-
import { homedir as
|
|
6693
|
-
import { join as
|
|
6827
|
+
import { closeSync, openSync as openSync2, readFileSync as readFileSync6, readSync, statSync, writeFileSync as writeFileSync4 } from "fs";
|
|
6828
|
+
import { homedir as homedir4 } from "os";
|
|
6829
|
+
import { join as join6 } from "path";
|
|
6694
6830
|
function tailLines(file, maxBytes = 131072) {
|
|
6695
6831
|
try {
|
|
6696
6832
|
const size = statSync(file).size;
|
|
6697
6833
|
const start = Math.max(0, size - maxBytes);
|
|
6698
|
-
const fd =
|
|
6834
|
+
const fd = openSync2(file, "r");
|
|
6699
6835
|
const buf = Buffer.alloc(size - start);
|
|
6700
6836
|
readSync(fd, buf, 0, buf.length, start);
|
|
6701
6837
|
closeSync(fd);
|
|
@@ -6708,7 +6844,7 @@ function tailLines(file, maxBytes = 131072) {
|
|
|
6708
6844
|
}
|
|
6709
6845
|
function deleteLocalEntry(at, tool, session) {
|
|
6710
6846
|
try {
|
|
6711
|
-
const lines =
|
|
6847
|
+
const lines = readFileSync6(LOCAL_LOG, "utf-8").split("\n");
|
|
6712
6848
|
let removed = 0;
|
|
6713
6849
|
const kept = lines.filter((line) => {
|
|
6714
6850
|
if (!line.trim()) return false;
|
|
@@ -6724,7 +6860,7 @@ function deleteLocalEntry(at, tool, session) {
|
|
|
6724
6860
|
}
|
|
6725
6861
|
return true;
|
|
6726
6862
|
});
|
|
6727
|
-
if (removed)
|
|
6863
|
+
if (removed) writeFileSync4(LOCAL_LOG, kept.length ? kept.join("\n") + "\n" : "");
|
|
6728
6864
|
return removed;
|
|
6729
6865
|
} catch {
|
|
6730
6866
|
return 0;
|
|
@@ -6732,8 +6868,8 @@ function deleteLocalEntry(at, tool, session) {
|
|
|
6732
6868
|
}
|
|
6733
6869
|
function clearLocalLog() {
|
|
6734
6870
|
try {
|
|
6735
|
-
const n =
|
|
6736
|
-
|
|
6871
|
+
const n = readFileSync6(LOCAL_LOG, "utf-8").split("\n").filter(Boolean).length;
|
|
6872
|
+
writeFileSync4(LOCAL_LOG, "");
|
|
6737
6873
|
return n;
|
|
6738
6874
|
} catch {
|
|
6739
6875
|
return 0;
|
|
@@ -6764,20 +6900,20 @@ var LOCAL_LOG, DLP_REASON, RL_REASON;
|
|
|
6764
6900
|
var init_local_log = __esm({
|
|
6765
6901
|
"src/tui/local-log.ts"() {
|
|
6766
6902
|
"use strict";
|
|
6767
|
-
LOCAL_LOG =
|
|
6903
|
+
LOCAL_LOG = join6(homedir4(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
6768
6904
|
DLP_REASON = /security layer \(dlp\)/i;
|
|
6769
6905
|
RL_REASON = /security layer \(rate limit\)|rate[- ]?limit(?:ed)?\b.*exceed|exceeded \d+ calls/i;
|
|
6770
6906
|
}
|
|
6771
6907
|
});
|
|
6772
6908
|
|
|
6773
6909
|
// src/api-client/client.ts
|
|
6774
|
-
import { readFileSync as
|
|
6775
|
-
import { resolve as resolve3, join as
|
|
6776
|
-
import { homedir as
|
|
6910
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync3 } from "fs";
|
|
6911
|
+
import { resolve as resolve3, join as join7 } from "path";
|
|
6912
|
+
import { homedir as homedir5 } from "os";
|
|
6777
6913
|
function listAccounts() {
|
|
6778
6914
|
let list6 = [];
|
|
6779
6915
|
try {
|
|
6780
|
-
const raw = JSON.parse(
|
|
6916
|
+
const raw = JSON.parse(readFileSync7(accountsFile(), "utf-8"));
|
|
6781
6917
|
if (Array.isArray(raw)) list6 = raw.filter((a) => a && typeof a.apiKey === "string");
|
|
6782
6918
|
} catch {
|
|
6783
6919
|
}
|
|
@@ -6791,7 +6927,7 @@ function saveAccount(acc) {
|
|
|
6791
6927
|
try {
|
|
6792
6928
|
const list6 = (() => {
|
|
6793
6929
|
try {
|
|
6794
|
-
const raw = JSON.parse(
|
|
6930
|
+
const raw = JSON.parse(readFileSync7(accountsFile(), "utf-8"));
|
|
6795
6931
|
return Array.isArray(raw) ? raw.filter((a) => a && a.apiKey) : [];
|
|
6796
6932
|
} catch {
|
|
6797
6933
|
return [];
|
|
@@ -6799,8 +6935,8 @@ function saveAccount(acc) {
|
|
|
6799
6935
|
})();
|
|
6800
6936
|
const next = list6.filter((a) => a.apiKey !== acc.apiKey);
|
|
6801
6937
|
next.unshift({ ...acc, addedAt: acc.addedAt ?? Date.now() });
|
|
6802
|
-
|
|
6803
|
-
|
|
6938
|
+
mkdirSync4(join7(homedir5(), ".solongate"), { recursive: true });
|
|
6939
|
+
writeFileSync5(accountsFile(), JSON.stringify(next, null, 2));
|
|
6804
6940
|
} catch {
|
|
6805
6941
|
}
|
|
6806
6942
|
}
|
|
@@ -6813,15 +6949,15 @@ function isActiveAccount(apiKey) {
|
|
|
6813
6949
|
}
|
|
6814
6950
|
function setActiveAccount(creds) {
|
|
6815
6951
|
try {
|
|
6816
|
-
const dir =
|
|
6817
|
-
|
|
6818
|
-
const p =
|
|
6952
|
+
const dir = join7(homedir5(), ".solongate");
|
|
6953
|
+
mkdirSync4(dir, { recursive: true });
|
|
6954
|
+
const p = join7(dir, ["cloud", "guard.json"].join("-"));
|
|
6819
6955
|
let existing = {};
|
|
6820
6956
|
try {
|
|
6821
|
-
existing = JSON.parse(
|
|
6957
|
+
existing = JSON.parse(readFileSync7(p, "utf-8"));
|
|
6822
6958
|
} catch {
|
|
6823
6959
|
}
|
|
6824
|
-
|
|
6960
|
+
writeFileSync5(p, JSON.stringify({ ...existing, apiKey: creds.apiKey, apiUrl: creds.apiUrl }, null, 2));
|
|
6825
6961
|
cached2 = null;
|
|
6826
6962
|
return true;
|
|
6827
6963
|
} catch {
|
|
@@ -6830,9 +6966,9 @@ function setActiveAccount(creds) {
|
|
|
6830
6966
|
}
|
|
6831
6967
|
function loginCredentialFile() {
|
|
6832
6968
|
try {
|
|
6833
|
-
const p =
|
|
6969
|
+
const p = join7(homedir5(), ".solongate", "cloud-guard.json");
|
|
6834
6970
|
if (!existsSync3(p)) return {};
|
|
6835
|
-
const c2 = JSON.parse(
|
|
6971
|
+
const c2 = JSON.parse(readFileSync7(p, "utf-8"));
|
|
6836
6972
|
return c2 && typeof c2 === "object" ? c2 : {};
|
|
6837
6973
|
} catch {
|
|
6838
6974
|
return {};
|
|
@@ -6842,7 +6978,7 @@ function dotenvApiKey() {
|
|
|
6842
6978
|
try {
|
|
6843
6979
|
const envPath = resolve3(".env");
|
|
6844
6980
|
if (!existsSync3(envPath)) return void 0;
|
|
6845
|
-
for (const line of
|
|
6981
|
+
for (const line of readFileSync7(envPath, "utf-8").split("\n")) {
|
|
6846
6982
|
const trimmed = line.trim();
|
|
6847
6983
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
6848
6984
|
const eq = trimmed.indexOf("=");
|
|
@@ -6944,7 +7080,7 @@ var init_client = __esm({
|
|
|
6944
7080
|
"src/api-client/client.ts"() {
|
|
6945
7081
|
"use strict";
|
|
6946
7082
|
DEFAULT_API_URL2 = "https://api.solongate.com";
|
|
6947
|
-
accountsFile = () =>
|
|
7083
|
+
accountsFile = () => join7(homedir5(), ".solongate", "accounts.json");
|
|
6948
7084
|
viewOverride = null;
|
|
6949
7085
|
ApiError = class extends Error {
|
|
6950
7086
|
status;
|
|
@@ -6974,12 +7110,12 @@ var init_types = __esm({
|
|
|
6974
7110
|
});
|
|
6975
7111
|
|
|
6976
7112
|
// src/api-client/device-login.ts
|
|
6977
|
-
import { spawn } from "child_process";
|
|
7113
|
+
import { spawn as spawn2 } from "child_process";
|
|
6978
7114
|
function openBrowser(url) {
|
|
6979
7115
|
try {
|
|
6980
7116
|
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
6981
7117
|
const args = process.platform === "win32" ? ["/c", "start", '""', url] : [url];
|
|
6982
|
-
const child =
|
|
7118
|
+
const child = spawn2(cmd, args, { stdio: "ignore", detached: true });
|
|
6983
7119
|
child.on("error", () => {
|
|
6984
7120
|
});
|
|
6985
7121
|
child.unref();
|
|
@@ -7021,6 +7157,21 @@ var init_device_login = __esm({
|
|
|
7021
7157
|
}
|
|
7022
7158
|
});
|
|
7023
7159
|
|
|
7160
|
+
// src/api-client/auth.ts
|
|
7161
|
+
var auth_exports = {};
|
|
7162
|
+
__export(auth_exports, {
|
|
7163
|
+
me: () => me
|
|
7164
|
+
});
|
|
7165
|
+
function me() {
|
|
7166
|
+
return request("GET", "/auth/me");
|
|
7167
|
+
}
|
|
7168
|
+
var init_auth = __esm({
|
|
7169
|
+
"src/api-client/auth.ts"() {
|
|
7170
|
+
"use strict";
|
|
7171
|
+
init_client();
|
|
7172
|
+
}
|
|
7173
|
+
});
|
|
7174
|
+
|
|
7024
7175
|
// src/api-client/policies.ts
|
|
7025
7176
|
var policies_exports = {};
|
|
7026
7177
|
__export(policies_exports, {
|
|
@@ -7292,6 +7443,7 @@ var init_api_client = __esm({
|
|
|
7292
7443
|
init_client();
|
|
7293
7444
|
init_types();
|
|
7294
7445
|
init_device_login();
|
|
7446
|
+
init_auth();
|
|
7295
7447
|
init_policies();
|
|
7296
7448
|
init_settings();
|
|
7297
7449
|
init_stats();
|
|
@@ -7299,29 +7451,29 @@ var init_api_client = __esm({
|
|
|
7299
7451
|
init_agents();
|
|
7300
7452
|
init_keys();
|
|
7301
7453
|
init_mcp();
|
|
7302
|
-
api = { policies: policies_exports, settings: settings_exports, stats: stats_exports, audit: audit_exports, agents: agents_exports, keys: keys_exports, mcp: mcp_exports };
|
|
7454
|
+
api = { auth: auth_exports, policies: policies_exports, settings: settings_exports, stats: stats_exports, audit: audit_exports, agents: agents_exports, keys: keys_exports, mcp: mcp_exports };
|
|
7303
7455
|
}
|
|
7304
7456
|
});
|
|
7305
7457
|
|
|
7306
7458
|
// src/tui/notify.ts
|
|
7307
|
-
import { spawn as
|
|
7459
|
+
import { spawn as spawn3 } from "child_process";
|
|
7308
7460
|
function desktopNotify(title, msg) {
|
|
7309
7461
|
try {
|
|
7310
7462
|
if (process.platform === "linux") {
|
|
7311
|
-
const p =
|
|
7463
|
+
const p = spawn3("notify-send", ["-a", "SolonGate", title, msg], { stdio: "ignore", detached: true });
|
|
7312
7464
|
p.on("error", () => {
|
|
7313
7465
|
});
|
|
7314
7466
|
p.unref();
|
|
7315
7467
|
} else if (process.platform === "win32") {
|
|
7316
7468
|
const q = (s) => s.replace(/'/g, "''");
|
|
7317
7469
|
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()`;
|
|
7318
|
-
const p =
|
|
7470
|
+
const p = spawn3("powershell", ["-NoProfile", "-NonInteractive", "-Command", ps], { stdio: "ignore", detached: true, windowsHide: true });
|
|
7319
7471
|
p.on("error", () => {
|
|
7320
7472
|
});
|
|
7321
7473
|
p.unref();
|
|
7322
7474
|
} else if (process.platform === "darwin") {
|
|
7323
7475
|
const esc = (s) => s.replace(/"/g, '\\"');
|
|
7324
|
-
const p =
|
|
7476
|
+
const p = spawn3("osascript", ["-e", `display notification "${esc(msg)}" with title "${esc(title)}"`], { stdio: "ignore", detached: true });
|
|
7325
7477
|
p.on("error", () => {
|
|
7326
7478
|
});
|
|
7327
7479
|
p.unref();
|
|
@@ -7407,9 +7559,9 @@ var init_hooks = __esm({
|
|
|
7407
7559
|
// src/tui/panels/Live.tsx
|
|
7408
7560
|
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
7409
7561
|
import TextInput from "ink-text-input";
|
|
7410
|
-
import { mkdirSync as
|
|
7411
|
-
import { homedir as
|
|
7412
|
-
import { join as
|
|
7562
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
7563
|
+
import { homedir as homedir6 } from "os";
|
|
7564
|
+
import { join as join8 } from "path";
|
|
7413
7565
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
7414
7566
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
7415
7567
|
function extractTarget(detail) {
|
|
@@ -8000,10 +8152,10 @@ function LivePanel({ active: active2 }) {
|
|
|
8000
8152
|
else if (input === "x") toggleSignal("dlp");
|
|
8001
8153
|
else if (input === "r") toggleSignal("ratelimit");
|
|
8002
8154
|
else if (input === "e") {
|
|
8003
|
-
const file =
|
|
8155
|
+
const file = join8(homedir6(), ".solongate", "live-export.jsonl");
|
|
8004
8156
|
try {
|
|
8005
|
-
|
|
8006
|
-
|
|
8157
|
+
mkdirSync5(join8(homedir6(), ".solongate"), { recursive: true });
|
|
8158
|
+
writeFileSync6(file, visibleDesc.map((x) => JSON.stringify(x)).join("\n") + "\n");
|
|
8007
8159
|
setActionMsg({ text: `\u2713 exported ${visibleDesc.length} lines \u2192 ${file}`, level: "ok", until: Date.now() + 6e3 });
|
|
8008
8160
|
} catch (err2) {
|
|
8009
8161
|
setActionMsg({ text: "\u2717 export failed: " + (err2 instanceof Error ? err2.message : String(err2)), level: "bad", until: Date.now() + 6e3 });
|
|
@@ -8413,7 +8565,7 @@ var init_Live = __esm({
|
|
|
8413
8565
|
SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
8414
8566
|
BG = "#12234f";
|
|
8415
8567
|
DIM_FLOOR = "#233457";
|
|
8416
|
-
RING =
|
|
8568
|
+
RING = join8(process.cwd(), ".solongate", ".eval-ring.jsonl");
|
|
8417
8569
|
hhmmss = (ts) => {
|
|
8418
8570
|
const d = new Date(ts);
|
|
8419
8571
|
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
@@ -9103,9 +9255,9 @@ var init_Dlp = __esm({
|
|
|
9103
9255
|
// src/tui/panels/Audit.tsx
|
|
9104
9256
|
import { Box as Box6, Text as Text6, useInput as useInput5 } from "ink";
|
|
9105
9257
|
import TextInput4 from "ink-text-input";
|
|
9106
|
-
import { mkdirSync as
|
|
9107
|
-
import { homedir as
|
|
9108
|
-
import { join as
|
|
9258
|
+
import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
9259
|
+
import { homedir as homedir7 } from "os";
|
|
9260
|
+
import { join as join9 } from "path";
|
|
9109
9261
|
import { useState as useState6 } from "react";
|
|
9110
9262
|
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
9111
9263
|
function loadLocalRows() {
|
|
@@ -9259,16 +9411,16 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9259
9411
|
const doExport = (kind) => {
|
|
9260
9412
|
setMsg({ text: "exporting\u2026", level: "ok" });
|
|
9261
9413
|
const run12 = async () => {
|
|
9262
|
-
const dir =
|
|
9263
|
-
const file =
|
|
9414
|
+
const dir = join9(homedir7(), ".solongate");
|
|
9415
|
+
const file = join9(dir, `audit-export-${source}.jsonl`);
|
|
9264
9416
|
let rows2;
|
|
9265
9417
|
if (kind === "page") rows2 = pageRows;
|
|
9266
9418
|
else if (source === "cloud") {
|
|
9267
9419
|
const r = await api.audit.list({ ...query, limit: 1e4, offset: 0 });
|
|
9268
9420
|
rows2 = r.entries.map(cloudRow).sort((a, b) => b.at - a.at);
|
|
9269
9421
|
} else rows2 = localFiltered;
|
|
9270
|
-
|
|
9271
|
-
|
|
9422
|
+
mkdirSync6(dir, { recursive: true });
|
|
9423
|
+
writeFileSync7(file, rows2.map((x) => JSON.stringify(x)).join("\n") + (rows2.length ? "\n" : ""));
|
|
9272
9424
|
return { n: rows2.length, file };
|
|
9273
9425
|
};
|
|
9274
9426
|
run12().then(({ n, file }) => setMsg({ text: `\u2713 exported ${n} rows \u2192 ${file}`, level: "ok" })).catch((e) => setMsg({ text: "\u2717 export failed: " + (e instanceof Error ? e.message : String(e)), level: "bad" }));
|
|
@@ -10041,7 +10193,7 @@ function AccountsPanel({
|
|
|
10041
10193
|
if (a) {
|
|
10042
10194
|
setViewCredentials({ apiKey: a.apiKey, apiUrl: a.apiUrl });
|
|
10043
10195
|
onView?.(a);
|
|
10044
|
-
setMsg({ text: `viewing ${a.project || a.user || a.apiKey.slice(
|
|
10196
|
+
setMsg({ text: `viewing ${a.project || a.user || "account \u2026" + a.apiKey.slice(-4)}`, level: "ok" });
|
|
10045
10197
|
}
|
|
10046
10198
|
} else if (input === "m") {
|
|
10047
10199
|
const a = accounts[sel];
|
|
@@ -10090,7 +10242,7 @@ function AccountsPanel({
|
|
|
10090
10242
|
const isActive = isActiveAccount(a.apiKey);
|
|
10091
10243
|
return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", backgroundColor: isSel ? "#333333" : void 0, bold: isSel, children: [
|
|
10092
10244
|
/* @__PURE__ */ jsx8(Text8, { color: isSel ? theme.accentBright : theme.dim, children: isSel ? "\u25B8 " : " " }),
|
|
10093
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.accent, children: truncate2(a.project || a.user || a.apiKey.slice(
|
|
10245
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.accent, children: truncate2(a.project || a.user || "account \u2026" + a.apiKey.slice(-4), 30).padEnd(31) }),
|
|
10094
10246
|
isView ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, children: "\u25CF viewing " }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " " }),
|
|
10095
10247
|
isActive ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: "ACTIVE " }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " " }),
|
|
10096
10248
|
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: a.user && a.project ? truncate2(a.user, 24) : "" })
|
|
@@ -10112,7 +10264,7 @@ var init_Accounts = __esm({
|
|
|
10112
10264
|
|
|
10113
10265
|
// src/tui/App.tsx
|
|
10114
10266
|
import { Box as Box9, Text as Text9, useApp, useInput as useInput8 } from "ink";
|
|
10115
|
-
import { useState as useState9 } from "react";
|
|
10267
|
+
import { useEffect as useEffect7, useState as useState9 } from "react";
|
|
10116
10268
|
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
10117
10269
|
function LiveHint() {
|
|
10118
10270
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
@@ -10149,7 +10301,22 @@ function App() {
|
|
|
10149
10301
|
const [help, setHelp] = useState9(false);
|
|
10150
10302
|
const acctIdx = Math.max(0, accounts.findIndex((a) => a.apiKey === viewKey));
|
|
10151
10303
|
const cur = accounts[acctIdx];
|
|
10152
|
-
const acctLabel = cur ? cur.project || cur.user || cur.apiKey.slice(
|
|
10304
|
+
const acctLabel = cur ? cur.project || cur.user || `account \u2026${cur.apiKey.slice(-4)}` : "not logged in";
|
|
10305
|
+
useEffect7(() => {
|
|
10306
|
+
if (!cur || cur.project || cur.user) return;
|
|
10307
|
+
let alive = true;
|
|
10308
|
+
api.auth.me().then((r) => {
|
|
10309
|
+
const project = r.project?.name || void 0;
|
|
10310
|
+
const user = r.user?.name || r.user?.email || void 0;
|
|
10311
|
+
if (!alive || !project && !user) return;
|
|
10312
|
+
saveAccount({ ...cur, project, user });
|
|
10313
|
+
setAccounts(listAccounts());
|
|
10314
|
+
}).catch(() => {
|
|
10315
|
+
});
|
|
10316
|
+
return () => {
|
|
10317
|
+
alive = false;
|
|
10318
|
+
};
|
|
10319
|
+
}, [cur]);
|
|
10153
10320
|
const viewAccount = (a) => {
|
|
10154
10321
|
setViewCredentials({ apiKey: a.apiKey, apiUrl: a.apiUrl });
|
|
10155
10322
|
setAccounts(listAccounts());
|
|
@@ -10243,6 +10410,7 @@ var init_App = __esm({
|
|
|
10243
10410
|
init_Accounts();
|
|
10244
10411
|
init_hooks();
|
|
10245
10412
|
init_client();
|
|
10413
|
+
init_api_client();
|
|
10246
10414
|
SECTIONS = [
|
|
10247
10415
|
{ label: "Live", Panel: LiveHint },
|
|
10248
10416
|
{ label: "Policies", Panel: PoliciesPanel },
|
|
@@ -10271,9 +10439,9 @@ var tui_exports = {};
|
|
|
10271
10439
|
__export(tui_exports, {
|
|
10272
10440
|
launchTui: () => launchTui
|
|
10273
10441
|
});
|
|
10274
|
-
import { appendFileSync as appendFileSync2, mkdirSync as
|
|
10275
|
-
import { homedir as
|
|
10276
|
-
import { join as
|
|
10442
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync7 } from "fs";
|
|
10443
|
+
import { homedir as homedir8 } from "os";
|
|
10444
|
+
import { join as join10 } from "path";
|
|
10277
10445
|
import { render } from "ink";
|
|
10278
10446
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
10279
10447
|
async function launchTui() {
|
|
@@ -10284,11 +10452,11 @@ async function launchTui() {
|
|
|
10284
10452
|
return;
|
|
10285
10453
|
}
|
|
10286
10454
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
10287
|
-
const debugLog =
|
|
10455
|
+
const debugLog = join10(homedir8(), ".solongate", "dataroom-debug.log");
|
|
10288
10456
|
const saved = { log: console.log, warn: console.warn, error: console.error, info: console.info, debug: console.debug };
|
|
10289
10457
|
const toFile = (level) => (...args) => {
|
|
10290
10458
|
try {
|
|
10291
|
-
|
|
10459
|
+
mkdirSync7(join10(homedir8(), ".solongate"), { recursive: true });
|
|
10292
10460
|
appendFileSync2(debugLog, `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
|
|
10293
10461
|
`);
|
|
10294
10462
|
} catch {
|
|
@@ -10412,7 +10580,7 @@ var init_args = __esm({
|
|
|
10412
10580
|
});
|
|
10413
10581
|
|
|
10414
10582
|
// src/commands/policy.ts
|
|
10415
|
-
import { readFileSync as
|
|
10583
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
10416
10584
|
async function run(argv) {
|
|
10417
10585
|
const { positionals, flags } = parse(argv);
|
|
10418
10586
|
const sub = positionals[0];
|
|
@@ -10587,7 +10755,7 @@ function printRules(rules) {
|
|
|
10587
10755
|
}
|
|
10588
10756
|
async function resolveRules(target) {
|
|
10589
10757
|
if (target.endsWith(".json")) {
|
|
10590
|
-
const parsed = JSON.parse(
|
|
10758
|
+
const parsed = JSON.parse(readFileSync8(target, "utf-8"));
|
|
10591
10759
|
return parsed.rules ?? [];
|
|
10592
10760
|
}
|
|
10593
10761
|
const p = await api.policies.get(target);
|
|
@@ -11003,8 +11171,8 @@ var init_agents2 = __esm({
|
|
|
11003
11171
|
|
|
11004
11172
|
// src/commands/doctor.ts
|
|
11005
11173
|
import { existsSync as existsSync4, statSync as statSync2 } from "fs";
|
|
11006
|
-
import { homedir as
|
|
11007
|
-
import { join as
|
|
11174
|
+
import { homedir as homedir9 } from "os";
|
|
11175
|
+
import { join as join11 } from "path";
|
|
11008
11176
|
async function run6(argv) {
|
|
11009
11177
|
const { flags } = parse(argv);
|
|
11010
11178
|
const json = flagBool(flags, "json");
|
|
@@ -11064,19 +11232,19 @@ var init_doctor = __esm({
|
|
|
11064
11232
|
init_api_client();
|
|
11065
11233
|
init_format();
|
|
11066
11234
|
init_args();
|
|
11067
|
-
LOCAL_LOG2 =
|
|
11235
|
+
LOCAL_LOG2 = join11(homedir9(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
11068
11236
|
}
|
|
11069
11237
|
});
|
|
11070
11238
|
|
|
11071
11239
|
// src/commands/watch.ts
|
|
11072
|
-
import { closeSync as closeSync2, existsSync as existsSync5, openSync as
|
|
11073
|
-
import { homedir as
|
|
11074
|
-
import { join as
|
|
11240
|
+
import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync3, readSync as readSync2, statSync as statSync3 } from "fs";
|
|
11241
|
+
import { homedir as homedir10 } from "os";
|
|
11242
|
+
import { join as join12 } from "path";
|
|
11075
11243
|
function tailLocal(file, maxBytes = 131072) {
|
|
11076
11244
|
try {
|
|
11077
11245
|
const size = statSync3(file).size;
|
|
11078
11246
|
const start = Math.max(0, size - maxBytes);
|
|
11079
|
-
const fd =
|
|
11247
|
+
const fd = openSync3(file, "r");
|
|
11080
11248
|
const buf = Buffer.alloc(size - start);
|
|
11081
11249
|
readSync2(fd, buf, 0, buf.length, start);
|
|
11082
11250
|
closeSync2(fd);
|
|
@@ -11178,7 +11346,7 @@ var init_watch = __esm({
|
|
|
11178
11346
|
init_cli_utils();
|
|
11179
11347
|
init_args();
|
|
11180
11348
|
init_format();
|
|
11181
|
-
LOCAL_LOG3 =
|
|
11349
|
+
LOCAL_LOG3 = join12(homedir10(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
11182
11350
|
trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
11183
11351
|
time = (ms) => new Date(ms).toTimeString().slice(0, 8);
|
|
11184
11352
|
}
|
|
@@ -11469,10 +11637,10 @@ var init_commands = __esm({
|
|
|
11469
11637
|
});
|
|
11470
11638
|
|
|
11471
11639
|
// src/global-install.ts
|
|
11472
|
-
import { readFileSync as
|
|
11473
|
-
import { resolve as resolve4, join as
|
|
11474
|
-
import { homedir as
|
|
11475
|
-
import { fileURLToPath } from "url";
|
|
11640
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync8, existsSync as existsSync6, mkdirSync as mkdirSync8 } from "fs";
|
|
11641
|
+
import { resolve as resolve4, join as join13, dirname as dirname2 } from "path";
|
|
11642
|
+
import { homedir as homedir11 } from "os";
|
|
11643
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
11476
11644
|
import { createInterface } from "readline";
|
|
11477
11645
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
11478
11646
|
function lockFile(file) {
|
|
@@ -11534,10 +11702,10 @@ function unlockFile(file) {
|
|
|
11534
11702
|
function protectedTargets() {
|
|
11535
11703
|
const p = globalPaths();
|
|
11536
11704
|
return [
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11705
|
+
join13(p.hooksDir, "guard.mjs"),
|
|
11706
|
+
join13(p.hooksDir, "audit.mjs"),
|
|
11707
|
+
join13(p.hooksDir, "stop.mjs"),
|
|
11708
|
+
join13(p.hooksDir, "shield.mjs"),
|
|
11541
11709
|
p.configPath,
|
|
11542
11710
|
p.settingsPath
|
|
11543
11711
|
];
|
|
@@ -11549,26 +11717,26 @@ function unlockProtected() {
|
|
|
11549
11717
|
for (const f of protectedTargets()) unlockFile(f);
|
|
11550
11718
|
}
|
|
11551
11719
|
function globalPaths() {
|
|
11552
|
-
const home =
|
|
11553
|
-
const sgDir =
|
|
11554
|
-
const hooksDir =
|
|
11555
|
-
const claudeDir =
|
|
11720
|
+
const home = homedir11();
|
|
11721
|
+
const sgDir = join13(home, ".solongate");
|
|
11722
|
+
const hooksDir = join13(sgDir, "hooks");
|
|
11723
|
+
const claudeDir = join13(home, ".claude");
|
|
11556
11724
|
return {
|
|
11557
11725
|
home,
|
|
11558
11726
|
sgDir,
|
|
11559
11727
|
hooksDir,
|
|
11560
11728
|
claudeDir,
|
|
11561
|
-
settingsPath:
|
|
11562
|
-
backupPath:
|
|
11563
|
-
configPath:
|
|
11729
|
+
settingsPath: join13(claudeDir, "settings.json"),
|
|
11730
|
+
backupPath: join13(claudeDir, "settings.solongate.bak"),
|
|
11731
|
+
configPath: join13(sgDir, "cloud-guard.json")
|
|
11564
11732
|
};
|
|
11565
11733
|
}
|
|
11566
11734
|
function readHook(filename) {
|
|
11567
|
-
return
|
|
11735
|
+
return readFileSync9(join13(HOOKS_DIR, filename), "utf-8");
|
|
11568
11736
|
}
|
|
11569
11737
|
function readGuard() {
|
|
11570
|
-
const bundled =
|
|
11571
|
-
return existsSync6(bundled) ?
|
|
11738
|
+
const bundled = join13(HOOKS_DIR, "guard.bundled.mjs");
|
|
11739
|
+
return existsSync6(bundled) ? readFileSync9(bundled, "utf-8") : readHook("guard.mjs");
|
|
11572
11740
|
}
|
|
11573
11741
|
function ask(question) {
|
|
11574
11742
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -11602,18 +11770,18 @@ function shimTargets() {
|
|
|
11602
11770
|
return [];
|
|
11603
11771
|
}
|
|
11604
11772
|
}
|
|
11605
|
-
return [".bashrc", ".zshrc", ".profile"].map((f) =>
|
|
11773
|
+
return [".bashrc", ".zshrc", ".profile"].map((f) => join13(homedir11(), f)).filter((f) => existsSync6(f));
|
|
11606
11774
|
}
|
|
11607
11775
|
function writeShimBlock(file, block2) {
|
|
11608
11776
|
const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
|
|
11609
|
-
let content = existsSync6(file) ?
|
|
11777
|
+
let content = existsSync6(file) ? readFileSync9(file, "utf-8") : "";
|
|
11610
11778
|
content = content.replace(re, "");
|
|
11611
11779
|
if (block2) {
|
|
11612
11780
|
if (content.length && !content.endsWith("\n")) content += "\n";
|
|
11613
11781
|
content += block2 + "\n";
|
|
11614
11782
|
}
|
|
11615
|
-
|
|
11616
|
-
|
|
11783
|
+
mkdirSync8(dirname2(file), { recursive: true });
|
|
11784
|
+
writeFileSync8(file, content);
|
|
11617
11785
|
}
|
|
11618
11786
|
function installClaudeShim(shieldPath) {
|
|
11619
11787
|
const real = resolveRealClaude();
|
|
@@ -11643,7 +11811,7 @@ async function runGlobalInstall(opts = {}) {
|
|
|
11643
11811
|
let apiKey = opts.apiKey || process.env["SOLONGATE_API_KEY"] || "";
|
|
11644
11812
|
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
11645
11813
|
try {
|
|
11646
|
-
const cfg = JSON.parse(
|
|
11814
|
+
const cfg = JSON.parse(readFileSync9(p.configPath, "utf-8"));
|
|
11647
11815
|
if (cfg && typeof cfg.apiKey === "string") apiKey = cfg.apiKey;
|
|
11648
11816
|
} catch {
|
|
11649
11817
|
}
|
|
@@ -11656,22 +11824,22 @@ async function runGlobalInstall(opts = {}) {
|
|
|
11656
11824
|
process.exit(1);
|
|
11657
11825
|
}
|
|
11658
11826
|
const apiUrl = opts.apiUrl || process.env["SOLONGATE_API_URL"] || "https://api.solongate.com";
|
|
11659
|
-
|
|
11660
|
-
|
|
11827
|
+
mkdirSync8(p.hooksDir, { recursive: true });
|
|
11828
|
+
mkdirSync8(p.claudeDir, { recursive: true });
|
|
11661
11829
|
unlockProtected();
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11830
|
+
writeFileSync8(join13(p.hooksDir, "guard.mjs"), readGuard());
|
|
11831
|
+
writeFileSync8(join13(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
|
|
11832
|
+
writeFileSync8(join13(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
|
|
11833
|
+
writeFileSync8(join13(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
|
|
11666
11834
|
console.log(` Installed hooks \u2192 ${p.hooksDir}`);
|
|
11667
|
-
installClaudeShim(
|
|
11668
|
-
|
|
11835
|
+
installClaudeShim(join13(p.hooksDir, "shield.mjs"));
|
|
11836
|
+
writeFileSync8(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
|
|
11669
11837
|
console.log(` Wrote ${p.configPath}`);
|
|
11670
11838
|
let existing = {};
|
|
11671
11839
|
if (existsSync6(p.settingsPath)) {
|
|
11672
|
-
const raw =
|
|
11840
|
+
const raw = readFileSync9(p.settingsPath, "utf-8");
|
|
11673
11841
|
if (!existsSync6(p.backupPath)) {
|
|
11674
|
-
|
|
11842
|
+
writeFileSync8(p.backupPath, raw);
|
|
11675
11843
|
console.log(` Backed up existing settings \u2192 ${p.backupPath}`);
|
|
11676
11844
|
}
|
|
11677
11845
|
try {
|
|
@@ -11680,9 +11848,9 @@ async function runGlobalInstall(opts = {}) {
|
|
|
11680
11848
|
existing = {};
|
|
11681
11849
|
}
|
|
11682
11850
|
}
|
|
11683
|
-
const guardAbs =
|
|
11684
|
-
const auditAbs =
|
|
11685
|
-
const stopAbs =
|
|
11851
|
+
const guardAbs = join13(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
|
|
11852
|
+
const auditAbs = join13(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
|
|
11853
|
+
const stopAbs = join13(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
|
|
11686
11854
|
const nodeBin = process.execPath.replace(/\\/g, "/");
|
|
11687
11855
|
const call = process.platform === "win32" ? "& " : "";
|
|
11688
11856
|
const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
|
|
@@ -11694,7 +11862,7 @@ async function runGlobalInstall(opts = {}) {
|
|
|
11694
11862
|
Stop: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(stopAbs) }] }]
|
|
11695
11863
|
}
|
|
11696
11864
|
};
|
|
11697
|
-
|
|
11865
|
+
writeFileSync8(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
11698
11866
|
console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
|
|
11699
11867
|
if (process.env["SOLONGATE_OS_LOCK"] === "1") {
|
|
11700
11868
|
lockProtected();
|
|
@@ -11705,7 +11873,7 @@ var __dirname, HOOKS_DIR, SHIM_BEGIN, SHIM_END;
|
|
|
11705
11873
|
var init_global_install = __esm({
|
|
11706
11874
|
"src/global-install.ts"() {
|
|
11707
11875
|
"use strict";
|
|
11708
|
-
__dirname =
|
|
11876
|
+
__dirname = dirname2(fileURLToPath2(import.meta.url));
|
|
11709
11877
|
HOOKS_DIR = resolve4(__dirname, "..", "hooks");
|
|
11710
11878
|
SHIM_BEGIN = "# >>> SolonGate shield (auto secret redaction) >>>";
|
|
11711
11879
|
SHIM_END = "# <<< SolonGate shield <<<";
|
|
@@ -11714,7 +11882,7 @@ var init_global_install = __esm({
|
|
|
11714
11882
|
|
|
11715
11883
|
// src/login.ts
|
|
11716
11884
|
var login_exports = {};
|
|
11717
|
-
import { spawn as
|
|
11885
|
+
import { spawn as spawn4 } from "child_process";
|
|
11718
11886
|
function startSpinner(text) {
|
|
11719
11887
|
if (!process.stderr.isTTY) {
|
|
11720
11888
|
process.stderr.write(` ${text}
|
|
@@ -11750,7 +11918,7 @@ function openBrowser2(url) {
|
|
|
11750
11918
|
try {
|
|
11751
11919
|
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
11752
11920
|
const args = process.platform === "win32" ? ["/c", "start", '""', url] : [url];
|
|
11753
|
-
const child =
|
|
11921
|
+
const child = spawn4(cmd, args, { stdio: "ignore", detached: true });
|
|
11754
11922
|
child.on("error", () => {
|
|
11755
11923
|
});
|
|
11756
11924
|
child.unref();
|
|
@@ -11870,13 +12038,13 @@ __export(shield_exports, {
|
|
|
11870
12038
|
});
|
|
11871
12039
|
import { createServer, request as httpRequest } from "http";
|
|
11872
12040
|
import { request as httpsRequest } from "https";
|
|
11873
|
-
import { spawn as
|
|
12041
|
+
import { spawn as spawn5 } from "child_process";
|
|
11874
12042
|
import { URL as URL2 } from "url";
|
|
11875
|
-
import { readFileSync as
|
|
12043
|
+
import { readFileSync as readFileSync10, existsSync as existsSync7, readdirSync, statSync as statSync4 } from "fs";
|
|
11876
12044
|
import { resolve as resolve5 } from "path";
|
|
11877
|
-
import { homedir as
|
|
12045
|
+
import { homedir as homedir12 } from "os";
|
|
11878
12046
|
function findCacheFile() {
|
|
11879
|
-
const dir = resolve5(
|
|
12047
|
+
const dir = resolve5(homedir12(), ".solongate");
|
|
11880
12048
|
const envSel = process.env.SOLONGATE_AGENT_ID;
|
|
11881
12049
|
if (envSel) {
|
|
11882
12050
|
const f = resolve5(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
|
|
@@ -11902,7 +12070,7 @@ function loadCfg() {
|
|
|
11902
12070
|
try {
|
|
11903
12071
|
const f = findCacheFile();
|
|
11904
12072
|
if (f && existsSync7(f)) {
|
|
11905
|
-
const c2 = JSON.parse(
|
|
12073
|
+
const c2 = JSON.parse(readFileSync10(f, "utf-8"));
|
|
11906
12074
|
const d = c2?.security?.dlpRedact;
|
|
11907
12075
|
const g = c2?.security?.ghost;
|
|
11908
12076
|
const ghost = g && Array.isArray(g.patterns) ? g.patterns : [];
|
|
@@ -12130,7 +12298,7 @@ async function runShield() {
|
|
|
12130
12298
|
const upstream = pickUpstream();
|
|
12131
12299
|
const { port, close } = await startProxy(upstream);
|
|
12132
12300
|
log4(`redacting secrets on the LLM path \u2192 masking before ${upstream.host} (127.0.0.1:${port})`);
|
|
12133
|
-
const child =
|
|
12301
|
+
const child = spawn5(cmd[0], cmd.slice(1), {
|
|
12134
12302
|
stdio: "inherit",
|
|
12135
12303
|
env: { ...process.env, ANTHROPIC_BASE_URL: `http://127.0.0.1:${port}` },
|
|
12136
12304
|
shell: process.platform === "win32"
|
|
@@ -12190,9 +12358,9 @@ __export(logs_server_exports, {
|
|
|
12190
12358
|
runLogsServer: () => runLogsServer
|
|
12191
12359
|
});
|
|
12192
12360
|
import { createServer as createServer2 } from "http";
|
|
12193
|
-
import { readFileSync as
|
|
12194
|
-
import { resolve as resolve6, join as
|
|
12195
|
-
import { homedir as
|
|
12361
|
+
import { readFileSync as readFileSync11, statSync as statSync5 } from "fs";
|
|
12362
|
+
import { resolve as resolve6, join as join14, isAbsolute } from "path";
|
|
12363
|
+
import { homedir as homedir13 } from "os";
|
|
12196
12364
|
import { readdirSync as readdirSync2 } from "fs";
|
|
12197
12365
|
function allowedOrigins() {
|
|
12198
12366
|
const base = [
|
|
@@ -12209,15 +12377,15 @@ function resolveLocalLogDir(rawPath) {
|
|
|
12209
12377
|
const dir = String(rawPath || "").trim().replace(/[\\/]+$/, "");
|
|
12210
12378
|
if (!dir) return null;
|
|
12211
12379
|
if (isAbsolute(dir)) return dir;
|
|
12212
|
-
return resolve6(
|
|
12380
|
+
return resolve6(homedir13(), ".solongate", "local-logs");
|
|
12213
12381
|
}
|
|
12214
12382
|
async function findLogDir() {
|
|
12215
|
-
const base = resolve6(
|
|
12383
|
+
const base = resolve6(homedir13(), ".solongate");
|
|
12216
12384
|
try {
|
|
12217
12385
|
const files = readdirSync2(base).filter((f) => f.startsWith(".policy-cache-") && f.endsWith(".json"));
|
|
12218
12386
|
for (const f of files) {
|
|
12219
12387
|
try {
|
|
12220
|
-
const c2 = JSON.parse(
|
|
12388
|
+
const c2 = JSON.parse(readFileSync11(join14(base, f), "utf-8"));
|
|
12221
12389
|
const p = c2?.security?.localLogs?.path;
|
|
12222
12390
|
if (typeof p === "string" && p.trim()) return { dir: resolveLocalLogDir(p), configured: p };
|
|
12223
12391
|
} catch {
|
|
@@ -12226,7 +12394,7 @@ async function findLogDir() {
|
|
|
12226
12394
|
} catch {
|
|
12227
12395
|
}
|
|
12228
12396
|
try {
|
|
12229
|
-
const cfgRaw =
|
|
12397
|
+
const cfgRaw = readFileSync11(join14(base, "cloud-guard.json"), "utf-8");
|
|
12230
12398
|
const { apiKey, apiUrl } = JSON.parse(cfgRaw);
|
|
12231
12399
|
if (apiKey) {
|
|
12232
12400
|
const url = `${apiUrl || "https://api.solongate.com"}/api/v1/policies/active`;
|
|
@@ -12255,7 +12423,7 @@ function setCors(req, res) {
|
|
|
12255
12423
|
}
|
|
12256
12424
|
function fileInfo(dir) {
|
|
12257
12425
|
if (!dir) return { file: null, exists: false, size: 0, mtimeMs: 0 };
|
|
12258
|
-
const file =
|
|
12426
|
+
const file = join14(dir, LOG_FILENAME);
|
|
12259
12427
|
try {
|
|
12260
12428
|
const st = statSync5(file);
|
|
12261
12429
|
return { file, exists: true, size: st.size, mtimeMs: st.mtimeMs };
|
|
@@ -12316,7 +12484,7 @@ async function runLogsServer() {
|
|
|
12316
12484
|
return;
|
|
12317
12485
|
}
|
|
12318
12486
|
try {
|
|
12319
|
-
const text =
|
|
12487
|
+
const text = readFileSync11(info.file, "utf-8");
|
|
12320
12488
|
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8", "Last-Modified": lastMod, "X-Solongate-Exists": "1" });
|
|
12321
12489
|
res.end(text);
|
|
12322
12490
|
} catch {
|
|
@@ -12368,7 +12536,7 @@ var init_logs_server = __esm({
|
|
|
12368
12536
|
|
|
12369
12537
|
// src/inject.ts
|
|
12370
12538
|
var inject_exports = {};
|
|
12371
|
-
import { readFileSync as
|
|
12539
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, existsSync as existsSync8, copyFileSync } from "fs";
|
|
12372
12540
|
import { resolve as resolve7 } from "path";
|
|
12373
12541
|
import { execSync } from "child_process";
|
|
12374
12542
|
function parseInjectArgs(argv) {
|
|
@@ -12428,7 +12596,7 @@ WHAT IT DOES
|
|
|
12428
12596
|
function detectProject() {
|
|
12429
12597
|
if (!existsSync8(resolve7("package.json"))) return false;
|
|
12430
12598
|
try {
|
|
12431
|
-
const pkg = JSON.parse(
|
|
12599
|
+
const pkg = JSON.parse(readFileSync12(resolve7("package.json"), "utf-8"));
|
|
12432
12600
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12433
12601
|
return !!(allDeps["@modelcontextprotocol/sdk"] || allDeps["@modelcontextprotocol/server"]);
|
|
12434
12602
|
} catch {
|
|
@@ -12437,7 +12605,7 @@ function detectProject() {
|
|
|
12437
12605
|
}
|
|
12438
12606
|
function findTsEntryFile() {
|
|
12439
12607
|
try {
|
|
12440
|
-
const pkg = JSON.parse(
|
|
12608
|
+
const pkg = JSON.parse(readFileSync12(resolve7("package.json"), "utf-8"));
|
|
12441
12609
|
if (pkg.bin) {
|
|
12442
12610
|
const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
|
|
12443
12611
|
if (typeof binPath === "string") {
|
|
@@ -12464,7 +12632,7 @@ function findTsEntryFile() {
|
|
|
12464
12632
|
const full = resolve7(c2);
|
|
12465
12633
|
if (existsSync8(full)) {
|
|
12466
12634
|
try {
|
|
12467
|
-
const content =
|
|
12635
|
+
const content = readFileSync12(full, "utf-8");
|
|
12468
12636
|
if (content.includes("McpServer") || content.includes("McpServer")) {
|
|
12469
12637
|
return full;
|
|
12470
12638
|
}
|
|
@@ -12484,7 +12652,7 @@ function detectPackageManager() {
|
|
|
12484
12652
|
}
|
|
12485
12653
|
function installSdk() {
|
|
12486
12654
|
try {
|
|
12487
|
-
const pkg = JSON.parse(
|
|
12655
|
+
const pkg = JSON.parse(readFileSync12(resolve7("package.json"), "utf-8"));
|
|
12488
12656
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12489
12657
|
if (allDeps["@solongate/proxy"]) {
|
|
12490
12658
|
log3(" @solongate/proxy already installed");
|
|
@@ -12505,7 +12673,7 @@ function installSdk() {
|
|
|
12505
12673
|
}
|
|
12506
12674
|
}
|
|
12507
12675
|
function injectTypeScript(filePath) {
|
|
12508
|
-
const original =
|
|
12676
|
+
const original = readFileSync12(filePath, "utf-8");
|
|
12509
12677
|
const changes = [];
|
|
12510
12678
|
let modified = original;
|
|
12511
12679
|
if (modified.includes("SecureMcpServer")) {
|
|
@@ -12676,7 +12844,7 @@ async function main2() {
|
|
|
12676
12844
|
log3("");
|
|
12677
12845
|
log3(` Backup: ${backupPath}`);
|
|
12678
12846
|
}
|
|
12679
|
-
|
|
12847
|
+
writeFileSync9(entryFile, result.modified);
|
|
12680
12848
|
log3("");
|
|
12681
12849
|
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");
|
|
12682
12850
|
log3(" \u2502 SolonGate SDK injected successfully! \u2502");
|
|
@@ -12705,8 +12873,8 @@ var init_inject = __esm({
|
|
|
12705
12873
|
|
|
12706
12874
|
// src/create.ts
|
|
12707
12875
|
var create_exports = {};
|
|
12708
|
-
import { mkdirSync as
|
|
12709
|
-
import { resolve as resolve8, join as
|
|
12876
|
+
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync10, existsSync as existsSync9 } from "fs";
|
|
12877
|
+
import { resolve as resolve8, join as join15 } from "path";
|
|
12710
12878
|
import { execSync as execSync2 } from "child_process";
|
|
12711
12879
|
function withSpinner(message, fn) {
|
|
12712
12880
|
const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
|
|
@@ -12785,8 +12953,8 @@ EXAMPLES
|
|
|
12785
12953
|
`);
|
|
12786
12954
|
}
|
|
12787
12955
|
function createProject(dir, name, _policy) {
|
|
12788
|
-
|
|
12789
|
-
|
|
12956
|
+
writeFileSync10(
|
|
12957
|
+
join15(dir, "package.json"),
|
|
12790
12958
|
JSON.stringify(
|
|
12791
12959
|
{
|
|
12792
12960
|
name,
|
|
@@ -12815,8 +12983,8 @@ function createProject(dir, name, _policy) {
|
|
|
12815
12983
|
2
|
|
12816
12984
|
) + "\n"
|
|
12817
12985
|
);
|
|
12818
|
-
|
|
12819
|
-
|
|
12986
|
+
writeFileSync10(
|
|
12987
|
+
join15(dir, "tsconfig.json"),
|
|
12820
12988
|
JSON.stringify(
|
|
12821
12989
|
{
|
|
12822
12990
|
compilerOptions: {
|
|
@@ -12836,9 +13004,9 @@ function createProject(dir, name, _policy) {
|
|
|
12836
13004
|
2
|
|
12837
13005
|
) + "\n"
|
|
12838
13006
|
);
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
13007
|
+
mkdirSync9(join15(dir, "src"), { recursive: true });
|
|
13008
|
+
writeFileSync10(
|
|
13009
|
+
join15(dir, "src", "index.ts"),
|
|
12842
13010
|
`#!/usr/bin/env node
|
|
12843
13011
|
|
|
12844
13012
|
console.log = (...args: unknown[]) => {
|
|
@@ -12879,8 +13047,8 @@ console.log('');
|
|
|
12879
13047
|
console.log('Press Ctrl+C to stop.');
|
|
12880
13048
|
`
|
|
12881
13049
|
);
|
|
12882
|
-
|
|
12883
|
-
|
|
13050
|
+
writeFileSync10(
|
|
13051
|
+
join15(dir, ".mcp.json"),
|
|
12884
13052
|
JSON.stringify(
|
|
12885
13053
|
{
|
|
12886
13054
|
mcpServers: {
|
|
@@ -12897,13 +13065,13 @@ console.log('Press Ctrl+C to stop.');
|
|
|
12897
13065
|
2
|
|
12898
13066
|
) + "\n"
|
|
12899
13067
|
);
|
|
12900
|
-
|
|
12901
|
-
|
|
13068
|
+
writeFileSync10(
|
|
13069
|
+
join15(dir, ".env"),
|
|
12902
13070
|
`SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
|
|
12903
13071
|
`
|
|
12904
13072
|
);
|
|
12905
|
-
|
|
12906
|
-
|
|
13073
|
+
writeFileSync10(
|
|
13074
|
+
join15(dir, ".gitignore"),
|
|
12907
13075
|
`node_modules/
|
|
12908
13076
|
dist/
|
|
12909
13077
|
*.solongate-backup
|
|
@@ -12922,7 +13090,7 @@ async function main3() {
|
|
|
12922
13090
|
process.exit(1);
|
|
12923
13091
|
}
|
|
12924
13092
|
withSpinner(`Setting up ${opts.name}...`, () => {
|
|
12925
|
-
|
|
13093
|
+
mkdirSync9(dir, { recursive: true });
|
|
12926
13094
|
createProject(dir, opts.name, opts.policy);
|
|
12927
13095
|
});
|
|
12928
13096
|
if (!opts.noInstall) {
|
|
@@ -12996,14 +13164,14 @@ var init_create = __esm({
|
|
|
12996
13164
|
|
|
12997
13165
|
// src/pull-push.ts
|
|
12998
13166
|
var pull_push_exports = {};
|
|
12999
|
-
import { readFileSync as
|
|
13167
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync11, existsSync as existsSync10 } from "fs";
|
|
13000
13168
|
import { resolve as resolve9 } from "path";
|
|
13001
13169
|
function loadEnv() {
|
|
13002
13170
|
if (process.env.SOLONGATE_API_KEY) return;
|
|
13003
13171
|
const envPath = resolve9(".env");
|
|
13004
13172
|
if (!existsSync10(envPath)) return;
|
|
13005
13173
|
try {
|
|
13006
|
-
const content =
|
|
13174
|
+
const content = readFileSync13(envPath, "utf-8");
|
|
13007
13175
|
for (const line of content.split("\n")) {
|
|
13008
13176
|
const trimmed = line.trim();
|
|
13009
13177
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -13191,7 +13359,7 @@ async function pull(apiKey, file, policyId) {
|
|
|
13191
13359
|
const policy = await fetchCloudPolicy(apiKey, API_URL, policyId);
|
|
13192
13360
|
const { id: _id, ...policyWithoutId } = policy;
|
|
13193
13361
|
const json = JSON.stringify(policyWithoutId, null, 2) + "\n";
|
|
13194
|
-
|
|
13362
|
+
writeFileSync11(file, json, "utf-8");
|
|
13195
13363
|
log5("");
|
|
13196
13364
|
log5(green2(" Saved to: ") + file);
|
|
13197
13365
|
log5(` ${dim2("Name:")} ${policy.name}`);
|
|
@@ -13220,7 +13388,7 @@ async function push(apiKey, file, policyId) {
|
|
|
13220
13388
|
log5(" solongate-proxy list");
|
|
13221
13389
|
process.exit(1);
|
|
13222
13390
|
}
|
|
13223
|
-
const content =
|
|
13391
|
+
const content = readFileSync13(file, "utf-8");
|
|
13224
13392
|
let policy;
|
|
13225
13393
|
try {
|
|
13226
13394
|
policy = JSON.parse(content);
|
|
@@ -15380,7 +15548,7 @@ var SolonGate = class {
|
|
|
15380
15548
|
*/
|
|
15381
15549
|
startPolicyPolling() {
|
|
15382
15550
|
const apiUrl = this.config.apiUrl ?? "https://api.solongate.com";
|
|
15383
|
-
let
|
|
15551
|
+
let currentVersion2 = 0;
|
|
15384
15552
|
const timer = setInterval(async () => {
|
|
15385
15553
|
try {
|
|
15386
15554
|
const res = await fetch(`${apiUrl}/api/v1/policies/default`, {
|
|
@@ -15390,7 +15558,7 @@ var SolonGate = class {
|
|
|
15390
15558
|
if (!res.ok) return;
|
|
15391
15559
|
const data = await res.json();
|
|
15392
15560
|
const version = Number(data._version ?? 0);
|
|
15393
|
-
if (version !==
|
|
15561
|
+
if (version !== currentVersion2 && version > 0) {
|
|
15394
15562
|
const policySet = {
|
|
15395
15563
|
id: String(data.id ?? "cloud"),
|
|
15396
15564
|
name: String(data.name ?? "Cloud Policy"),
|
|
@@ -15402,7 +15570,7 @@ var SolonGate = class {
|
|
|
15402
15570
|
};
|
|
15403
15571
|
this.policyEngine.loadPolicySet(policySet);
|
|
15404
15572
|
await this.loadCloudWasm(apiUrl, policySet.id);
|
|
15405
|
-
|
|
15573
|
+
currentVersion2 = version;
|
|
15406
15574
|
}
|
|
15407
15575
|
} catch {
|
|
15408
15576
|
}
|
|
@@ -16370,6 +16538,12 @@ function printWelcome() {
|
|
|
16370
16538
|
}
|
|
16371
16539
|
async function main5() {
|
|
16372
16540
|
const subcommand = process.argv[2];
|
|
16541
|
+
if (IS_HUMAN_CLI) {
|
|
16542
|
+
const tuiBound = subcommand === "dataroom" || process.argv.length <= 2 && process.stdout.isTTY && process.stdin.isTTY;
|
|
16543
|
+
const { maybeSelfUpdate: maybeSelfUpdate2 } = await Promise.resolve().then(() => (init_self_update(), self_update_exports));
|
|
16544
|
+
maybeSelfUpdate2(tuiBound ? () => {
|
|
16545
|
+
} : void 0);
|
|
16546
|
+
}
|
|
16373
16547
|
if (process.argv.length <= 2) {
|
|
16374
16548
|
if (process.stdout.isTTY && process.stdin.isTTY) {
|
|
16375
16549
|
const { launchTui: launchTui2 } = await Promise.resolve().then(() => (init_tui(), tui_exports));
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function currentVersion(): string;
|
|
2
|
+
/**
|
|
3
|
+
* Fire-and-forget startup hook. `notify` writes the human-facing one-liner —
|
|
4
|
+
* callers pass a stderr writer so the notice never lands in piped stdout.
|
|
5
|
+
*/
|
|
6
|
+
export declare function maybeSelfUpdate(notify?: (line: string) => void): void;
|
package/dist/tui/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { render } from "ink";
|
|
|
12
12
|
|
|
13
13
|
// src/tui/App.tsx
|
|
14
14
|
import { Box as Box9, Text as Text9, useApp, useInput as useInput8 } from "ink";
|
|
15
|
-
import { useState as useState9 } from "react";
|
|
15
|
+
import { useEffect as useEffect7, useState as useState9 } from "react";
|
|
16
16
|
|
|
17
17
|
// src/cli-utils.ts
|
|
18
18
|
var c = {
|
|
@@ -471,6 +471,15 @@ async function pollDeviceLogin(apiUrl, deviceCode) {
|
|
|
471
471
|
}
|
|
472
472
|
}
|
|
473
473
|
|
|
474
|
+
// src/api-client/auth.ts
|
|
475
|
+
var auth_exports = {};
|
|
476
|
+
__export(auth_exports, {
|
|
477
|
+
me: () => me
|
|
478
|
+
});
|
|
479
|
+
function me() {
|
|
480
|
+
return request("GET", "/auth/me");
|
|
481
|
+
}
|
|
482
|
+
|
|
474
483
|
// src/api-client/policies.ts
|
|
475
484
|
var policies_exports = {};
|
|
476
485
|
__export(policies_exports, {
|
|
@@ -693,7 +702,7 @@ function list4() {
|
|
|
693
702
|
}
|
|
694
703
|
|
|
695
704
|
// src/api-client/index.ts
|
|
696
|
-
var api = { policies: policies_exports, settings: settings_exports, stats: stats_exports, audit: audit_exports, agents: agents_exports, keys: keys_exports, mcp: mcp_exports };
|
|
705
|
+
var api = { auth: auth_exports, policies: policies_exports, settings: settings_exports, stats: stats_exports, audit: audit_exports, agents: agents_exports, keys: keys_exports, mcp: mcp_exports };
|
|
697
706
|
|
|
698
707
|
// src/tui/notify.ts
|
|
699
708
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -3355,7 +3364,7 @@ function AccountsPanel({
|
|
|
3355
3364
|
if (a) {
|
|
3356
3365
|
setViewCredentials({ apiKey: a.apiKey, apiUrl: a.apiUrl });
|
|
3357
3366
|
onView?.(a);
|
|
3358
|
-
setMsg({ text: `viewing ${a.project || a.user || a.apiKey.slice(
|
|
3367
|
+
setMsg({ text: `viewing ${a.project || a.user || "account \u2026" + a.apiKey.slice(-4)}`, level: "ok" });
|
|
3359
3368
|
}
|
|
3360
3369
|
} else if (input === "m") {
|
|
3361
3370
|
const a = accounts[sel];
|
|
@@ -3404,7 +3413,7 @@ function AccountsPanel({
|
|
|
3404
3413
|
const isActive = isActiveAccount(a.apiKey);
|
|
3405
3414
|
return /* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", backgroundColor: isSel ? "#333333" : void 0, bold: isSel, children: [
|
|
3406
3415
|
/* @__PURE__ */ jsx8(Text8, { color: isSel ? theme.accentBright : theme.dim, children: isSel ? "\u25B8 " : " " }),
|
|
3407
|
-
/* @__PURE__ */ jsx8(Text8, { color: theme.accent, children: truncate(a.project || a.user || a.apiKey.slice(
|
|
3416
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.accent, children: truncate(a.project || a.user || "account \u2026" + a.apiKey.slice(-4), 30).padEnd(31) }),
|
|
3408
3417
|
isView ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, children: "\u25CF viewing " }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " " }),
|
|
3409
3418
|
isActive ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: "ACTIVE " }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " " }),
|
|
3410
3419
|
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: a.user && a.project ? truncate(a.user, 24) : "" })
|
|
@@ -3462,7 +3471,22 @@ function App() {
|
|
|
3462
3471
|
const [help, setHelp] = useState9(false);
|
|
3463
3472
|
const acctIdx = Math.max(0, accounts.findIndex((a) => a.apiKey === viewKey));
|
|
3464
3473
|
const cur = accounts[acctIdx];
|
|
3465
|
-
const acctLabel = cur ? cur.project || cur.user || cur.apiKey.slice(
|
|
3474
|
+
const acctLabel = cur ? cur.project || cur.user || `account \u2026${cur.apiKey.slice(-4)}` : "not logged in";
|
|
3475
|
+
useEffect7(() => {
|
|
3476
|
+
if (!cur || cur.project || cur.user) return;
|
|
3477
|
+
let alive = true;
|
|
3478
|
+
api.auth.me().then((r) => {
|
|
3479
|
+
const project = r.project?.name || void 0;
|
|
3480
|
+
const user = r.user?.name || r.user?.email || void 0;
|
|
3481
|
+
if (!alive || !project && !user) return;
|
|
3482
|
+
saveAccount({ ...cur, project, user });
|
|
3483
|
+
setAccounts(listAccounts());
|
|
3484
|
+
}).catch(() => {
|
|
3485
|
+
});
|
|
3486
|
+
return () => {
|
|
3487
|
+
alive = false;
|
|
3488
|
+
};
|
|
3489
|
+
}, [cur]);
|
|
3466
3490
|
const viewAccount = (a) => {
|
|
3467
3491
|
setViewCredentials({ apiKey: a.apiKey, apiUrl: a.apiUrl });
|
|
3468
3492
|
setAccounts(listAccounts());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.47",
|
|
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": {
|