@solongate/proxy 0.81.68 → 0.81.70
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/global-install.d.ts +1 -0
- package/dist/global-install.js +10 -1
- package/dist/index.js +395 -397
- package/dist/login.js +1 -1
- package/dist/tui/components.d.ts +31 -0
- package/dist/tui/index.js +189 -169
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6600,10 +6600,16 @@ function newerThan(b, a) {
|
|
|
6600
6600
|
}
|
|
6601
6601
|
async function fetchLatest() {
|
|
6602
6602
|
try {
|
|
6603
|
-
const res = await fetch(`https://registry.npmjs.org/${PKG}
|
|
6603
|
+
const res = await fetch(`https://registry.npmjs.org/${PKG}`, {
|
|
6604
|
+
headers: { accept: "application/vnd.npm.install-v1+json" },
|
|
6605
|
+
signal: AbortSignal.timeout(3e3)
|
|
6606
|
+
});
|
|
6604
6607
|
if (!res.ok) return null;
|
|
6605
6608
|
const j = await res.json();
|
|
6606
|
-
|
|
6609
|
+
const latest = j["dist-tags"]?.latest;
|
|
6610
|
+
if (typeof latest !== "string") return null;
|
|
6611
|
+
if (!j.versions || !(latest in j.versions)) return null;
|
|
6612
|
+
return latest;
|
|
6607
6613
|
} catch {
|
|
6608
6614
|
return null;
|
|
6609
6615
|
}
|
|
@@ -6928,6 +6934,39 @@ var init_theme = __esm({
|
|
|
6928
6934
|
// src/tui/components.tsx
|
|
6929
6935
|
import { Box, Text } from "ink";
|
|
6930
6936
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6937
|
+
function PaneTitle({ label, extra, width: width2 }) {
|
|
6938
|
+
const tail = extra ? ` ${extra} ` : " ";
|
|
6939
|
+
const used = 2 + 1 + label.length + tail.length;
|
|
6940
|
+
return /* @__PURE__ */ jsxs(Text, { wrap: "truncate", children: [
|
|
6941
|
+
/* @__PURE__ */ jsx(Text, { color: theme.dim, children: "\u2500 " }),
|
|
6942
|
+
/* @__PURE__ */ jsxs(Text, { color: theme.accentBright, bold: true, children: [
|
|
6943
|
+
"\u258E",
|
|
6944
|
+
label
|
|
6945
|
+
] }),
|
|
6946
|
+
/* @__PURE__ */ jsx(Text, { color: theme.dim, children: tail + "\u2500".repeat(Math.max(0, width2 - used)) })
|
|
6947
|
+
] });
|
|
6948
|
+
}
|
|
6949
|
+
function StreamLine({ e, loc, selected }) {
|
|
6950
|
+
return /* @__PURE__ */ jsxs(Text, { wrap: "truncate", backgroundColor: selected ? "#1c2f63" : void 0, children: [
|
|
6951
|
+
/* @__PURE__ */ jsx(Text, { color: selected ? theme.accentBright : theme.dim, children: selected ? "\u25B8" : " " }),
|
|
6952
|
+
/* @__PURE__ */ jsxs(Text, { color: theme.dim, children: [
|
|
6953
|
+
"[",
|
|
6954
|
+
hhmmss(e.at),
|
|
6955
|
+
" "
|
|
6956
|
+
] }),
|
|
6957
|
+
/* @__PURE__ */ jsx(Text, { color: loc ? theme.ok : "white", children: loc ? "LOC" : "CLD" }),
|
|
6958
|
+
/* @__PURE__ */ jsx(Text, { color: theme.dim, children: "] " }),
|
|
6959
|
+
/* @__PURE__ */ jsx(Text, { color: decisionColor(e.decision), bold: e.decision !== "ALLOW", children: e.decision.padEnd(6) }),
|
|
6960
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: truncate2(e.tool, 12).padEnd(13) }),
|
|
6961
|
+
/* @__PURE__ */ jsx(Text, { color: theme.dim, children: (e.permission ?? "").padEnd(5) }),
|
|
6962
|
+
/* @__PURE__ */ jsx(Text, { color: e.evalMs != null && e.evalMs > 500 ? theme.warn : theme.dim, children: (e.evalMs != null ? `${e.evalMs}ms` : "\u2014").padEnd(7) }),
|
|
6963
|
+
/* @__PURE__ */ jsx(Text, { color: theme.dim, children: truncate2(e.agent ?? "-", 11).padEnd(12) }),
|
|
6964
|
+
/* @__PURE__ */ jsx(Text, { color: e.dlp ? theme.bad : theme.dim, bold: e.dlp, children: ("dlp:" + (e.dlp ? "yes" : "no")).padEnd(8) }),
|
|
6965
|
+
/* @__PURE__ */ jsx(Text, { color: e.burst ? theme.warn : theme.dim, bold: e.burst, children: ("rl:" + (e.burst ? "yes" : "no")).padEnd(7) }),
|
|
6966
|
+
e.rule && e.decision !== "ALLOW" ? /* @__PURE__ */ jsx(Text, { color: theme.bad, children: truncate2(e.rule, 14) + " " }) : null,
|
|
6967
|
+
/* @__PURE__ */ jsx(Text, { color: theme.dim, children: e.detail })
|
|
6968
|
+
] });
|
|
6969
|
+
}
|
|
6931
6970
|
function DataView({
|
|
6932
6971
|
loading,
|
|
6933
6972
|
error,
|
|
@@ -6962,10 +7001,15 @@ function KeyHints({ hints }) {
|
|
|
6962
7001
|
i < hints.length - 1 ? " " : ""
|
|
6963
7002
|
] }, i)) });
|
|
6964
7003
|
}
|
|
7004
|
+
var hhmmss;
|
|
6965
7005
|
var init_components = __esm({
|
|
6966
7006
|
"src/tui/components.tsx"() {
|
|
6967
7007
|
"use strict";
|
|
6968
7008
|
init_theme();
|
|
7009
|
+
hhmmss = (ts) => {
|
|
7010
|
+
const d = new Date(ts);
|
|
7011
|
+
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
7012
|
+
};
|
|
6969
7013
|
}
|
|
6970
7014
|
});
|
|
6971
7015
|
|
|
@@ -7798,39 +7842,6 @@ function HBar({ label, value, max, width: width2, color }) {
|
|
|
7798
7842
|
/* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: " " + value })
|
|
7799
7843
|
] });
|
|
7800
7844
|
}
|
|
7801
|
-
function PaneTitle({ label, extra, width: width2 }) {
|
|
7802
|
-
const tail = extra ? ` ${extra} ` : " ";
|
|
7803
|
-
const used = 2 + 1 + label.length + tail.length;
|
|
7804
|
-
return /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
|
|
7805
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "\u2500 " }),
|
|
7806
|
-
/* @__PURE__ */ jsxs2(Text2, { color: theme.accentBright, bold: true, children: [
|
|
7807
|
-
"\u258E",
|
|
7808
|
-
label
|
|
7809
|
-
] }),
|
|
7810
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: tail + "\u2500".repeat(Math.max(0, width2 - used)) })
|
|
7811
|
-
] });
|
|
7812
|
-
}
|
|
7813
|
-
function StreamLine({ e, loc, selected }) {
|
|
7814
|
-
return /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", backgroundColor: selected ? "#1c2f63" : void 0, children: [
|
|
7815
|
-
/* @__PURE__ */ jsx2(Text2, { color: selected ? theme.accentBright : theme.dim, children: selected ? "\u25B8" : " " }),
|
|
7816
|
-
/* @__PURE__ */ jsxs2(Text2, { color: theme.dim, children: [
|
|
7817
|
-
"[",
|
|
7818
|
-
hhmmss(e.at),
|
|
7819
|
-
" "
|
|
7820
|
-
] }),
|
|
7821
|
-
/* @__PURE__ */ jsx2(Text2, { color: loc ? theme.ok : "white", children: loc ? "LOC" : "CLD" }),
|
|
7822
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: "] " }),
|
|
7823
|
-
/* @__PURE__ */ jsx2(Text2, { color: decisionColor(e.decision), bold: e.decision !== "ALLOW", children: e.decision.padEnd(6) }),
|
|
7824
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.accent, children: truncate2(e.tool, 12).padEnd(13) }),
|
|
7825
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: e.permission.padEnd(5) }),
|
|
7826
|
-
/* @__PURE__ */ jsx2(Text2, { color: e.evalMs != null && e.evalMs > 500 ? theme.warn : theme.dim, children: (e.evalMs != null ? `${e.evalMs}ms` : "\u2014").padEnd(7) }),
|
|
7827
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: truncate2(e.agent ?? "-", 11).padEnd(12) }),
|
|
7828
|
-
/* @__PURE__ */ jsx2(Text2, { color: e.dlp ? theme.bad : theme.dim, bold: e.dlp, children: ("dlp:" + (e.dlp ? "yes" : "no")).padEnd(8) }),
|
|
7829
|
-
/* @__PURE__ */ jsx2(Text2, { color: e.burst ? theme.warn : theme.dim, bold: e.burst, children: ("rl:" + (e.burst ? "yes" : "no")).padEnd(7) }),
|
|
7830
|
-
e.rule && e.decision !== "ALLOW" ? /* @__PURE__ */ jsx2(Text2, { color: theme.bad, children: truncate2(e.rule, 14) + " " }) : null,
|
|
7831
|
-
/* @__PURE__ */ jsx2(Text2, { color: theme.dim, children: e.detail })
|
|
7832
|
-
] });
|
|
7833
|
-
}
|
|
7834
7845
|
function LivePanel({ active: active2 }) {
|
|
7835
7846
|
const [s, setS] = useState2(null);
|
|
7836
7847
|
const [lat, setLat] = useState2([]);
|
|
@@ -8719,7 +8730,7 @@ function LivePanel({ active: active2 }) {
|
|
|
8719
8730
|
] })
|
|
8720
8731
|
] });
|
|
8721
8732
|
}
|
|
8722
|
-
var CONFIG, SPIN, BG, DIM_FLOOR, RING,
|
|
8733
|
+
var CONFIG, SPIN, BG, DIM_FLOOR, RING, fmtUp, FILTERS, sessStatus, STATUS_STYLE, LIVE_HELP;
|
|
8723
8734
|
var init_Live = __esm({
|
|
8724
8735
|
"src/tui/panels/Live.tsx"() {
|
|
8725
8736
|
"use strict";
|
|
@@ -8728,16 +8739,13 @@ var init_Live = __esm({
|
|
|
8728
8739
|
init_config2();
|
|
8729
8740
|
init_notify();
|
|
8730
8741
|
init_hooks();
|
|
8742
|
+
init_components();
|
|
8731
8743
|
init_theme();
|
|
8732
8744
|
CONFIG = loadConfig();
|
|
8733
8745
|
SPIN = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
8734
8746
|
BG = "#12234f";
|
|
8735
8747
|
DIM_FLOOR = "#233457";
|
|
8736
8748
|
RING = join9(process.cwd(), ".solongate", ".eval-ring.jsonl");
|
|
8737
|
-
hhmmss = (ts) => {
|
|
8738
|
-
const d = new Date(ts);
|
|
8739
|
-
return Number.isNaN(d.getTime()) ? "--:--:--" : d.toTimeString().slice(0, 8);
|
|
8740
|
-
};
|
|
8741
8749
|
fmtUp = (ms) => {
|
|
8742
8750
|
const s = Math.floor(ms / 1e3);
|
|
8743
8751
|
const p = (n) => String(n).padStart(2, "0");
|
|
@@ -9427,7 +9435,7 @@ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync8 } from "fs";
|
|
|
9427
9435
|
import { homedir as homedir8 } from "os";
|
|
9428
9436
|
import { join as join10 } from "path";
|
|
9429
9437
|
import { useState as useState6 } from "react";
|
|
9430
|
-
import {
|
|
9438
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
9431
9439
|
function loadLocalRows() {
|
|
9432
9440
|
return parseLocalLines(tailLines(LOCAL_LOG, LOCAL_MAX_BYTES)).map((j, i) => {
|
|
9433
9441
|
const rs = reasonSignals(j.reason);
|
|
@@ -9547,10 +9555,6 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9547
9555
|
const sq = sessSearch.trim().toLowerCase();
|
|
9548
9556
|
const sessionsFiltered = sessions.map((s) => ({ ...s, status: source === "cloud" ? s.status : sessStatus2(s.lastAt) })).filter((s) => SESS_STATUS[si] ? s.status === SESS_STATUS[si] : true).filter((s) => !sq || `${s.agent} ${s.id}`.toLowerCase().includes(sq)).sort((a, b) => b.lastAt - a.lastAt);
|
|
9549
9557
|
const currentSess = sessionsFiltered[Math.min(sessSel, Math.max(0, sessionsFiltered.length - 1))];
|
|
9550
|
-
const sessionQ = useLoader(
|
|
9551
|
-
() => view === "detail" && current?.session && source === "cloud" ? api.audit.list({ session_id: current.session, limit: 40 }) : Promise.resolve(null),
|
|
9552
|
-
[view, current?.session, source]
|
|
9553
|
-
);
|
|
9554
9558
|
const logsLoading = (source === "cloud" ? cloudQ.loading : localQ.loading) && !editing;
|
|
9555
9559
|
const sessLoading = source === "cloud" ? agentsQ.loading : localQ.loading;
|
|
9556
9560
|
const doDelete = (kind) => {
|
|
@@ -9776,61 +9780,56 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9776
9780
|
] });
|
|
9777
9781
|
}
|
|
9778
9782
|
if (view === "detail" && current) {
|
|
9779
|
-
const
|
|
9780
|
-
const
|
|
9781
|
-
const
|
|
9782
|
-
const
|
|
9783
|
-
const
|
|
9784
|
-
|
|
9785
|
-
const
|
|
9786
|
-
|
|
9783
|
+
const e = current;
|
|
9784
|
+
const loc = source === "local";
|
|
9785
|
+
const bodyW = Math.max(20, cols - 4);
|
|
9786
|
+
const innerW = cols - 2;
|
|
9787
|
+
const contentLines = [];
|
|
9788
|
+
if (e.reason && e.decision !== "ALLOW") contentLines.push(...wrapLines("reason: " + e.reason, bodyW), "");
|
|
9789
|
+
const argsText = e.args ? prettyJson(e.args) : e.reason && e.decision === "ALLOW" ? e.reason : "(no arguments recorded)";
|
|
9790
|
+
contentLines.push(...wrapLines(argsText, bodyW));
|
|
9791
|
+
const bodyRows = Math.max(4, rows - 7 - (frozen ? 1 : 0));
|
|
9792
|
+
const maxScroll = Math.max(0, contentLines.length - bodyRows);
|
|
9787
9793
|
const off = Math.min(detailScroll, maxScroll);
|
|
9788
|
-
const
|
|
9794
|
+
const win = contentLines.slice(off, off + bodyRows);
|
|
9789
9795
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
9790
9796
|
copyBanner,
|
|
9791
|
-
/* @__PURE__ */ jsxs6(
|
|
9792
|
-
/* @__PURE__ */ jsx6(Text6, { color:
|
|
9793
|
-
/* @__PURE__ */ jsx6(Text6, { color:
|
|
9794
|
-
/* @__PURE__ */ jsx6(Text6, { color: theme.
|
|
9795
|
-
|
|
9797
|
+
/* @__PURE__ */ jsxs6(Text6, { wrap: "truncate", children: [
|
|
9798
|
+
/* @__PURE__ */ jsx6(Text6, { backgroundColor: BG2, color: "white", bold: true, children: " ENTRY " }),
|
|
9799
|
+
/* @__PURE__ */ jsx6(Text6, { color: decisionColor(e.decision), bold: true, children: " " + e.decision }),
|
|
9800
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.accent, bold: true, children: " " + e.tool }),
|
|
9801
|
+
/* @__PURE__ */ jsx6(Text6, { color: loc ? theme.ok : "white", children: " " + (loc ? "LOC" : "CLD") }),
|
|
9802
|
+
e.dlp.length ? /* @__PURE__ */ jsx6(Text6, { color: theme.bad, children: " DLP!" }) : null,
|
|
9803
|
+
e.burst ? /* @__PURE__ */ jsx6(Text6, { color: theme.warn, children: " BURST" }) : null,
|
|
9804
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: " \u2190 back" })
|
|
9796
9805
|
] }),
|
|
9797
|
-
|
|
9798
|
-
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "
|
|
9799
|
-
/* @__PURE__ */ jsx6(Text6, { children:
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
/* @__PURE__ */ jsx6(
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
rows: sessionCalls.slice(0, Math.max(1, sessionRows - 2)).map((e) => [
|
|
9825
|
-
{ value: e.decision, color: decisionColor(e.decision) },
|
|
9826
|
-
{ value: truncate2(e.tool, 20), color: theme.accent },
|
|
9827
|
-
{ value: truncate2(e.reason ?? "\u2014", Math.max(16, cols - 48)) },
|
|
9828
|
-
{ value: ago(e.at), dim: true }
|
|
9829
|
-
])
|
|
9830
|
-
}
|
|
9831
|
-
)
|
|
9832
|
-
] }) : /* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "(no session id)" }),
|
|
9833
|
-
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "\u2191\u2193 scroll arguments \xB7 \u2190/esc back to logs" })
|
|
9806
|
+
/* @__PURE__ */ jsxs6(Text6, { wrap: "truncate", children: [
|
|
9807
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "\u2502 when " }),
|
|
9808
|
+
/* @__PURE__ */ jsx6(Text6, { children: new Date(e.at).toLocaleString() }),
|
|
9809
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: " \u2502 perm " }),
|
|
9810
|
+
/* @__PURE__ */ jsx6(Text6, { children: e.permission || "\u2014" }),
|
|
9811
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: " \u2502 trust " }),
|
|
9812
|
+
/* @__PURE__ */ jsx6(Text6, { children: e.trust || "\u2014" }),
|
|
9813
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: " \u2502 eval " }),
|
|
9814
|
+
/* @__PURE__ */ jsx6(Text6, { color: e.evalMs != null && e.evalMs > 500 ? theme.warn : void 0, children: e.evalMs != null ? `${e.evalMs}ms` : "\u2014" }),
|
|
9815
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: " \u2502 agent " }),
|
|
9816
|
+
/* @__PURE__ */ jsx6(Text6, { children: e.agent ?? "\u2014" }),
|
|
9817
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: " \u2502" })
|
|
9818
|
+
] }),
|
|
9819
|
+
/* @__PURE__ */ jsxs6(Text6, { wrap: "truncate", children: [
|
|
9820
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: "\u2502 session " }),
|
|
9821
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: e.session ?? "\u2014" }),
|
|
9822
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: " \u2502 rule " }),
|
|
9823
|
+
/* @__PURE__ */ jsx6(Text6, { color: e.rule && e.decision !== "ALLOW" ? theme.bad : theme.dim, children: e.rule ?? "\u2014" }),
|
|
9824
|
+
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: " \u2502" })
|
|
9825
|
+
] }),
|
|
9826
|
+
/* @__PURE__ */ jsx6(PaneTitle, { label: "FULL CONTENT", extra: `${contentLines.length} lines${maxScroll ? ` \xB7 \u25BC${maxScroll - off} more \xB7 \u2191\u2193 scroll` : ""} \xB7 space copy \xB7 \u2190 back`, width: innerW }),
|
|
9827
|
+
/* @__PURE__ */ jsx6(Box6, { flexDirection: "column", height: bodyRows, overflow: "hidden", children: win.map((l, i) => /* @__PURE__ */ jsx6(Text6, { wrap: "truncate", children: l || " " }, off + i)) }),
|
|
9828
|
+
/* @__PURE__ */ jsxs6(Text6, { wrap: "truncate", children: [
|
|
9829
|
+
/* @__PURE__ */ jsx6(Text6, { backgroundColor: BG2, color: "white", bold: true, children: " ENTRY " }),
|
|
9830
|
+
/* @__PURE__ */ jsx6(Text6, { backgroundColor: "#0b1530", color: "white", children: ` ${e.id} ` }),
|
|
9831
|
+
/* @__PURE__ */ jsx6(Text6, { backgroundColor: BG2, color: "white", children: " \u2191\u2193 scroll \xB7 space copy \xB7 ? all keys \xB7 \u2190 back \xB7 esc menu " })
|
|
9832
|
+
] })
|
|
9834
9833
|
] });
|
|
9835
9834
|
}
|
|
9836
9835
|
const chip = (label, val, on) => /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
@@ -9917,7 +9916,6 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9917
9916
|
const maxStart = Math.max(0, pageRows.length - listRows);
|
|
9918
9917
|
const start = Math.min(Math.max(0, selClamped - Math.floor((listRows - 1) / 2)), maxStart);
|
|
9919
9918
|
const windowed = pageRows.slice(start, start + listRows);
|
|
9920
|
-
const reasonW = Math.min(58, Math.max(12, cols - 71));
|
|
9921
9919
|
return /* @__PURE__ */ jsx6(DataView, { loading: logsLoading && !frozen, error: source === "cloud" ? cloudQ.error : localQ.error, children: /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
9922
9920
|
strip,
|
|
9923
9921
|
copyBanner,
|
|
@@ -9953,21 +9951,7 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9953
9951
|
)
|
|
9954
9952
|
] }) : null,
|
|
9955
9953
|
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, wrap: "truncate", children: `${total} matched \xB7 page ${Math.min(page + 1, pages)}/${pages} \xB7 ${PAGE}/page \xB7 ${pageRows.length ? selClamped + 1 : 0}/${pageRows.length}${start ? ` \xB7 \u25B2${start} newer` : ""}${start + listRows < pageRows.length ? ` \xB7 \u25BC${pageRows.length - start - listRows} older` : ""}` }),
|
|
9956
|
-
/* @__PURE__ */ jsx6(
|
|
9957
|
-
Table,
|
|
9958
|
-
{
|
|
9959
|
-
columns: [
|
|
9960
|
-
{ header: "", width: 2 },
|
|
9961
|
-
{ header: "DECISION", width: 9 },
|
|
9962
|
-
{ header: "TOOL", width: 18 },
|
|
9963
|
-
{ header: "AGENT", width: 14 },
|
|
9964
|
-
{ header: "REASON", width: reasonW },
|
|
9965
|
-
{ header: "SIGNAL", width: 8 },
|
|
9966
|
-
{ header: "WHEN", width: 6 }
|
|
9967
|
-
],
|
|
9968
|
-
rows: windowed.map((e, i) => rowFor(e, start + i === selClamped && focused, reasonW))
|
|
9969
|
-
}
|
|
9970
|
-
),
|
|
9954
|
+
/* @__PURE__ */ jsx6(Box6, { flexDirection: "column", overflow: "hidden", children: windowed.map((e, i) => /* @__PURE__ */ jsx6(StreamLine, { e: toStream(e), loc: source === "local", selected: start + i === selClamped && focused }, e.id)) }),
|
|
9971
9955
|
pageRows.length === 0 ? /* @__PURE__ */ jsxs6(Text6, { color: theme.dim, children: [
|
|
9972
9956
|
"(no entries",
|
|
9973
9957
|
source === "local" ? " in the local file" : "",
|
|
@@ -9975,25 +9959,7 @@ function AuditPanel({ active: active2, focused }) {
|
|
|
9975
9959
|
] }) : null
|
|
9976
9960
|
] }) });
|
|
9977
9961
|
}
|
|
9978
|
-
|
|
9979
|
-
const sig = [e.dlp.length ? `DLP${e.dlp.length > 1 ? e.dlp.length : ""}` : "", e.burst ? "RL" : ""].filter(Boolean).join(" ");
|
|
9980
|
-
return [
|
|
9981
|
-
{ value: active2 ? "\u25B8" : "", color: theme.accentBright },
|
|
9982
|
-
{ value: e.decision, color: decisionColor(e.decision) },
|
|
9983
|
-
{ value: truncate2(e.tool, 18), color: theme.accent },
|
|
9984
|
-
{ value: truncate2(e.agent ?? "\u2014", 14), dim: true },
|
|
9985
|
-
{ value: truncate2(e.reason ?? e.args ?? "\u2014", reasonW) },
|
|
9986
|
-
{ value: sig || "\xB7", color: sig ? theme.bad : void 0, dim: !sig },
|
|
9987
|
-
{ value: ago(e.at), dim: true }
|
|
9988
|
-
];
|
|
9989
|
-
}
|
|
9990
|
-
function Detail({ label, value, color }) {
|
|
9991
|
-
return /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
9992
|
-
/* @__PURE__ */ jsx6(Text6, { color: theme.dim, children: label.padEnd(9) }),
|
|
9993
|
-
/* @__PURE__ */ jsx6(Text6, { color, wrap: "truncate", children: value })
|
|
9994
|
-
] });
|
|
9995
|
-
}
|
|
9996
|
-
var DECISIONS, SIGNALS, SESS_STATUS, PAGE, LOCAL_MAX_BYTES, cloudRow, AUDIT_HELP, sessStatus2, STATUS_DOT;
|
|
9962
|
+
var DECISIONS, SIGNALS, SESS_STATUS, PAGE, LOCAL_MAX_BYTES, BG2, toStream, cloudRow, AUDIT_HELP, sessStatus2, STATUS_DOT;
|
|
9997
9963
|
var init_Audit = __esm({
|
|
9998
9964
|
"src/tui/panels/Audit.tsx"() {
|
|
9999
9965
|
"use strict";
|
|
@@ -10007,6 +9973,19 @@ var init_Audit = __esm({
|
|
|
10007
9973
|
SESS_STATUS = [void 0, "active", "idle", "ended"];
|
|
10008
9974
|
PAGE = 500;
|
|
10009
9975
|
LOCAL_MAX_BYTES = 16 * 1024 * 1024;
|
|
9976
|
+
BG2 = "#12234f";
|
|
9977
|
+
toStream = (e) => ({
|
|
9978
|
+
at: e.at,
|
|
9979
|
+
tool: e.tool,
|
|
9980
|
+
decision: e.decision,
|
|
9981
|
+
permission: (e.permission ?? "").slice(0, 4),
|
|
9982
|
+
detail: (e.args ?? e.reason ?? "").replace(/\s+/g, " "),
|
|
9983
|
+
dlp: e.dlp.length > 0,
|
|
9984
|
+
burst: e.burst,
|
|
9985
|
+
agent: e.agent,
|
|
9986
|
+
evalMs: e.evalMs,
|
|
9987
|
+
rule: e.rule
|
|
9988
|
+
});
|
|
10010
9989
|
cloudRow = (e) => {
|
|
10011
9990
|
const rs = reasonSignals(e.reason);
|
|
10012
9991
|
return {
|
|
@@ -10064,7 +10043,7 @@ var init_Audit = __esm({
|
|
|
10064
10043
|
["esc", "back to the menu"]
|
|
10065
10044
|
]
|
|
10066
10045
|
],
|
|
10067
|
-
["Entry
|
|
10046
|
+
["Entry (full content)", [["\u2191\u2193 / PgUp PgDn", "scroll the reason + arguments"], ["space", "copy mode (freeze, then select)"], ["\u2190 / esc", "back to the list"]]]
|
|
10068
10047
|
];
|
|
10069
10048
|
sessStatus2 = (lastAt) => Date.now() - lastAt < 6e4 ? "active" : Date.now() - lastAt < 3e5 ? "idle" : "ended";
|
|
10070
10049
|
STATUS_DOT = {
|
|
@@ -10075,11 +10054,263 @@ var init_Audit = __esm({
|
|
|
10075
10054
|
}
|
|
10076
10055
|
});
|
|
10077
10056
|
|
|
10057
|
+
// src/global-install.ts
|
|
10058
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync9, existsSync as existsSync4, mkdirSync as mkdirSync8, rmSync as rmSync2 } from "fs";
|
|
10059
|
+
import { resolve as resolve4, join as join11, dirname as dirname3 } from "path";
|
|
10060
|
+
import { homedir as homedir9 } from "os";
|
|
10061
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
10062
|
+
import { createInterface } from "readline";
|
|
10063
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
10064
|
+
function lockFile(file) {
|
|
10065
|
+
if (!existsSync4(file)) return;
|
|
10066
|
+
try {
|
|
10067
|
+
if (process.platform === "win32") {
|
|
10068
|
+
try {
|
|
10069
|
+
execFileSync2("icacls", [file, "/deny", "*S-1-1-0:(WD,AD,DC,DE)"], { stdio: "ignore" });
|
|
10070
|
+
} catch {
|
|
10071
|
+
}
|
|
10072
|
+
try {
|
|
10073
|
+
execFileSync2("attrib", ["+R", file], { stdio: "ignore" });
|
|
10074
|
+
} catch {
|
|
10075
|
+
}
|
|
10076
|
+
} else if (process.platform === "darwin") {
|
|
10077
|
+
try {
|
|
10078
|
+
execFileSync2("chflags", ["uchg", file], { stdio: "ignore" });
|
|
10079
|
+
} catch {
|
|
10080
|
+
}
|
|
10081
|
+
} else {
|
|
10082
|
+
try {
|
|
10083
|
+
execFileSync2("chattr", ["+i", file], { stdio: "ignore" });
|
|
10084
|
+
} catch {
|
|
10085
|
+
}
|
|
10086
|
+
}
|
|
10087
|
+
} catch {
|
|
10088
|
+
}
|
|
10089
|
+
}
|
|
10090
|
+
function unlockFile(file) {
|
|
10091
|
+
if (!existsSync4(file)) return;
|
|
10092
|
+
try {
|
|
10093
|
+
if (process.platform === "win32") {
|
|
10094
|
+
try {
|
|
10095
|
+
execFileSync2("icacls", [file, "/remove:d", "*S-1-1-0"], { stdio: "ignore" });
|
|
10096
|
+
} catch {
|
|
10097
|
+
}
|
|
10098
|
+
try {
|
|
10099
|
+
execFileSync2("icacls", [file, "/reset"], { stdio: "ignore" });
|
|
10100
|
+
} catch {
|
|
10101
|
+
}
|
|
10102
|
+
try {
|
|
10103
|
+
execFileSync2("attrib", ["-R", file], { stdio: "ignore" });
|
|
10104
|
+
} catch {
|
|
10105
|
+
}
|
|
10106
|
+
} else if (process.platform === "darwin") {
|
|
10107
|
+
try {
|
|
10108
|
+
execFileSync2("chflags", ["nouchg", file], { stdio: "ignore" });
|
|
10109
|
+
} catch {
|
|
10110
|
+
}
|
|
10111
|
+
} else {
|
|
10112
|
+
try {
|
|
10113
|
+
execFileSync2("chattr", ["-i", file], { stdio: "ignore" });
|
|
10114
|
+
} catch {
|
|
10115
|
+
}
|
|
10116
|
+
}
|
|
10117
|
+
} catch {
|
|
10118
|
+
}
|
|
10119
|
+
}
|
|
10120
|
+
function protectedTargets() {
|
|
10121
|
+
const p = globalPaths();
|
|
10122
|
+
return [
|
|
10123
|
+
join11(p.hooksDir, "guard.mjs"),
|
|
10124
|
+
join11(p.hooksDir, "audit.mjs"),
|
|
10125
|
+
join11(p.hooksDir, "stop.mjs"),
|
|
10126
|
+
join11(p.hooksDir, "shield.mjs"),
|
|
10127
|
+
p.configPath,
|
|
10128
|
+
p.settingsPath
|
|
10129
|
+
];
|
|
10130
|
+
}
|
|
10131
|
+
function lockProtected() {
|
|
10132
|
+
for (const f of protectedTargets()) lockFile(f);
|
|
10133
|
+
}
|
|
10134
|
+
function unlockProtected() {
|
|
10135
|
+
for (const f of protectedTargets()) unlockFile(f);
|
|
10136
|
+
}
|
|
10137
|
+
function globalPaths() {
|
|
10138
|
+
const home = homedir9();
|
|
10139
|
+
const sgDir = join11(home, ".solongate");
|
|
10140
|
+
const hooksDir = join11(sgDir, "hooks");
|
|
10141
|
+
const claudeDir = join11(home, ".claude");
|
|
10142
|
+
return {
|
|
10143
|
+
home,
|
|
10144
|
+
sgDir,
|
|
10145
|
+
hooksDir,
|
|
10146
|
+
claudeDir,
|
|
10147
|
+
settingsPath: join11(claudeDir, "settings.json"),
|
|
10148
|
+
backupPath: join11(claudeDir, "settings.solongate.bak"),
|
|
10149
|
+
configPath: join11(sgDir, "cloud-guard.json")
|
|
10150
|
+
};
|
|
10151
|
+
}
|
|
10152
|
+
function clearGuardUpdateCheck() {
|
|
10153
|
+
try {
|
|
10154
|
+
rmSync2(join11(globalPaths().sgDir, ".hook-update-check"), { force: true });
|
|
10155
|
+
return true;
|
|
10156
|
+
} catch {
|
|
10157
|
+
return false;
|
|
10158
|
+
}
|
|
10159
|
+
}
|
|
10160
|
+
function readHook(filename) {
|
|
10161
|
+
return readFileSync9(join11(HOOKS_DIR, filename), "utf-8");
|
|
10162
|
+
}
|
|
10163
|
+
function readGuard() {
|
|
10164
|
+
const bundled = join11(HOOKS_DIR, "guard.bundled.mjs");
|
|
10165
|
+
return existsSync4(bundled) ? readFileSync9(bundled, "utf-8") : readHook("guard.mjs");
|
|
10166
|
+
}
|
|
10167
|
+
function ask(question) {
|
|
10168
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
10169
|
+
return new Promise((res) => rl.question(question, (a) => {
|
|
10170
|
+
rl.close();
|
|
10171
|
+
res(a.trim());
|
|
10172
|
+
}));
|
|
10173
|
+
}
|
|
10174
|
+
function escapeRe(s) {
|
|
10175
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10176
|
+
}
|
|
10177
|
+
function resolveRealClaude() {
|
|
10178
|
+
try {
|
|
10179
|
+
const finder = process.platform === "win32" ? "where" : "which";
|
|
10180
|
+
const out2 = execFileSync2(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
10181
|
+
if (process.platform === "win32") {
|
|
10182
|
+
const low = (s) => s.toLowerCase();
|
|
10183
|
+
return out2.find((l) => low(l).endsWith(".cmd")) || out2.find((l) => low(l).endsWith(".exe")) || out2.find((l) => low(l).endsWith(".bat")) || out2[0] || null;
|
|
10184
|
+
}
|
|
10185
|
+
return out2[0] || null;
|
|
10186
|
+
} catch {
|
|
10187
|
+
return null;
|
|
10188
|
+
}
|
|
10189
|
+
}
|
|
10190
|
+
function shimTargets() {
|
|
10191
|
+
if (process.platform === "win32") {
|
|
10192
|
+
try {
|
|
10193
|
+
const prof = execFileSync2("powershell", ["-NoProfile", "-Command", "$PROFILE.CurrentUserAllHosts"], { encoding: "utf-8" }).trim();
|
|
10194
|
+
return prof ? [prof] : [];
|
|
10195
|
+
} catch {
|
|
10196
|
+
return [];
|
|
10197
|
+
}
|
|
10198
|
+
}
|
|
10199
|
+
return [".bashrc", ".zshrc", ".profile"].map((f) => join11(homedir9(), f)).filter((f) => existsSync4(f));
|
|
10200
|
+
}
|
|
10201
|
+
function writeShimBlock(file, block2) {
|
|
10202
|
+
const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
|
|
10203
|
+
let content = existsSync4(file) ? readFileSync9(file, "utf-8") : "";
|
|
10204
|
+
content = content.replace(re, "");
|
|
10205
|
+
if (block2) {
|
|
10206
|
+
if (content.length && !content.endsWith("\n")) content += "\n";
|
|
10207
|
+
content += block2 + "\n";
|
|
10208
|
+
}
|
|
10209
|
+
mkdirSync8(dirname3(file), { recursive: true });
|
|
10210
|
+
writeFileSync9(file, content);
|
|
10211
|
+
}
|
|
10212
|
+
function installClaudeShim(shieldPath) {
|
|
10213
|
+
const real = resolveRealClaude();
|
|
10214
|
+
if (!real) {
|
|
10215
|
+
console.log(" (Claude Code not found on PATH \u2014 skipped auto-shield. Install it, then re-run `login`.)");
|
|
10216
|
+
return;
|
|
10217
|
+
}
|
|
10218
|
+
const node = process.execPath.replace(/\\/g, "/");
|
|
10219
|
+
const shield = shieldPath.replace(/\\/g, "/");
|
|
10220
|
+
const win = process.platform === "win32";
|
|
10221
|
+
const block2 = win ? `${SHIM_BEGIN}
|
|
10222
|
+
function claude { & "${node}" "${shield}" -- "${real}" @args }
|
|
10223
|
+
${SHIM_END}` : `${SHIM_BEGIN}
|
|
10224
|
+
claude() { "${node}" "${shield}" -- "${real}" "$@"; }
|
|
10225
|
+
${SHIM_END}`;
|
|
10226
|
+
const targets = shimTargets();
|
|
10227
|
+
if (targets.length === 0) return;
|
|
10228
|
+
for (const file of targets) {
|
|
10229
|
+
try {
|
|
10230
|
+
writeShimBlock(file, block2);
|
|
10231
|
+
} catch {
|
|
10232
|
+
}
|
|
10233
|
+
}
|
|
10234
|
+
}
|
|
10235
|
+
async function runGlobalInstall2(opts = {}) {
|
|
10236
|
+
const p = globalPaths();
|
|
10237
|
+
let apiKey = opts.apiKey || process.env["SOLONGATE_API_KEY"] || "";
|
|
10238
|
+
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
10239
|
+
try {
|
|
10240
|
+
const cfg = JSON.parse(readFileSync9(p.configPath, "utf-8"));
|
|
10241
|
+
if (cfg && typeof cfg.apiKey === "string") apiKey = cfg.apiKey;
|
|
10242
|
+
} catch {
|
|
10243
|
+
}
|
|
10244
|
+
}
|
|
10245
|
+
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
10246
|
+
apiKey = await ask(" Enter your SolonGate API key (sg_live_\u2026 from https://dashboard.solongate.com): ");
|
|
10247
|
+
}
|
|
10248
|
+
if (!apiKey.startsWith("sg_live_") && !apiKey.startsWith("sg_test_")) {
|
|
10249
|
+
console.log(" Invalid API key. Must start with sg_live_ or sg_test_");
|
|
10250
|
+
process.exit(1);
|
|
10251
|
+
}
|
|
10252
|
+
const apiUrl = opts.apiUrl || process.env["SOLONGATE_API_URL"] || "https://api.solongate.com";
|
|
10253
|
+
mkdirSync8(p.hooksDir, { recursive: true });
|
|
10254
|
+
mkdirSync8(p.claudeDir, { recursive: true });
|
|
10255
|
+
unlockProtected();
|
|
10256
|
+
writeFileSync9(join11(p.hooksDir, "guard.mjs"), readGuard());
|
|
10257
|
+
writeFileSync9(join11(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
|
|
10258
|
+
writeFileSync9(join11(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
|
|
10259
|
+
writeFileSync9(join11(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
|
|
10260
|
+
console.log(` Installed hooks \u2192 ${p.hooksDir}`);
|
|
10261
|
+
installClaudeShim(join11(p.hooksDir, "shield.mjs"));
|
|
10262
|
+
writeFileSync9(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
|
|
10263
|
+
console.log(` Wrote ${p.configPath}`);
|
|
10264
|
+
let existing = {};
|
|
10265
|
+
if (existsSync4(p.settingsPath)) {
|
|
10266
|
+
const raw = readFileSync9(p.settingsPath, "utf-8");
|
|
10267
|
+
if (!existsSync4(p.backupPath)) {
|
|
10268
|
+
writeFileSync9(p.backupPath, raw);
|
|
10269
|
+
console.log(` Backed up existing settings \u2192 ${p.backupPath}`);
|
|
10270
|
+
}
|
|
10271
|
+
try {
|
|
10272
|
+
existing = JSON.parse(raw);
|
|
10273
|
+
} catch {
|
|
10274
|
+
existing = {};
|
|
10275
|
+
}
|
|
10276
|
+
}
|
|
10277
|
+
const guardAbs = join11(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
|
|
10278
|
+
const auditAbs = join11(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
|
|
10279
|
+
const stopAbs = join11(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
|
|
10280
|
+
const nodeBin = process.execPath.replace(/\\/g, "/");
|
|
10281
|
+
const call = process.platform === "win32" ? "& " : "";
|
|
10282
|
+
const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
|
|
10283
|
+
const merged = {
|
|
10284
|
+
...existing,
|
|
10285
|
+
hooks: {
|
|
10286
|
+
PreToolUse: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(guardAbs) }] }],
|
|
10287
|
+
PostToolUse: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(auditAbs) }] }],
|
|
10288
|
+
Stop: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(stopAbs) }] }]
|
|
10289
|
+
}
|
|
10290
|
+
};
|
|
10291
|
+
writeFileSync9(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
10292
|
+
console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
|
|
10293
|
+
if (process.env["SOLONGATE_OS_LOCK"] === "1") {
|
|
10294
|
+
lockProtected();
|
|
10295
|
+
console.log(" Locked protection files (OS-level read-only/immutable).");
|
|
10296
|
+
}
|
|
10297
|
+
}
|
|
10298
|
+
var __dirname, HOOKS_DIR, SHIM_BEGIN, SHIM_END;
|
|
10299
|
+
var init_global_install = __esm({
|
|
10300
|
+
"src/global-install.ts"() {
|
|
10301
|
+
"use strict";
|
|
10302
|
+
__dirname = dirname3(fileURLToPath3(import.meta.url));
|
|
10303
|
+
HOOKS_DIR = resolve4(__dirname, "..", "hooks");
|
|
10304
|
+
SHIM_BEGIN = "# >>> SolonGate shield (auto secret redaction) >>>";
|
|
10305
|
+
SHIM_END = "# <<< SolonGate shield <<<";
|
|
10306
|
+
}
|
|
10307
|
+
});
|
|
10308
|
+
|
|
10078
10309
|
// src/tui/panels/Settings.tsx
|
|
10079
10310
|
import { Box as Box7, Text as Text7, useInput as useInput6 } from "ink";
|
|
10080
10311
|
import TextInput5 from "ink-text-input";
|
|
10081
10312
|
import { useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
|
|
10082
|
-
import { Fragment as
|
|
10313
|
+
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
10083
10314
|
function SettingsPanel({
|
|
10084
10315
|
active: active2,
|
|
10085
10316
|
focused,
|
|
@@ -10243,6 +10474,16 @@ function SettingsPanel({
|
|
|
10243
10474
|
setMsg({ text: `viewing ${acctLabel(r.acc)}`, level: "ok" });
|
|
10244
10475
|
} else if (r.kind === "acct-add") {
|
|
10245
10476
|
beginLogin();
|
|
10477
|
+
} else if (r.kind === "guard") {
|
|
10478
|
+
if (!guard) return;
|
|
10479
|
+
if (guard.up_to_date) {
|
|
10480
|
+
setMsg({ text: `guard already on the latest hook (v${guard.latest})`, level: "ok" });
|
|
10481
|
+
return;
|
|
10482
|
+
}
|
|
10483
|
+
const armed = clearGuardUpdateCheck();
|
|
10484
|
+
setMsg(
|
|
10485
|
+
armed ? { text: `\u2713 update armed. now make your agent RUN any command (e.g. "echo ok"), not just chat; the guard installs v${guard.latest} on the next executed command`, level: "ok" } : { text: "\u2717 could not arm the update (check ~/.solongate permissions)", level: "bad" }
|
|
10486
|
+
);
|
|
10246
10487
|
} else if (r.kind === "self") {
|
|
10247
10488
|
if (!selfProt) return;
|
|
10248
10489
|
run12(selfProt.enabled ? "self-protection disabled" : "self-protection enabled", () => api.settings.setSelfProtection(!selfProt.enabled), selfQ.reload);
|
|
@@ -10481,9 +10722,9 @@ function SettingsPanel({
|
|
|
10481
10722
|
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10482
10723
|
cursor(r),
|
|
10483
10724
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "guard".padEnd(11) }),
|
|
10484
|
-
guard ? /* @__PURE__ */ jsxs7(
|
|
10725
|
+
guard ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
10485
10726
|
/* @__PURE__ */ jsx7(Text7, { color: guard.up_to_date ? theme.ok : theme.warn, children: `v${guard.installed ?? "?"}` }),
|
|
10486
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: guard.up_to_date ? " (latest)" : ` \u2192 v${guard.latest} available` }),
|
|
10727
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: guard.up_to_date ? " (latest)" : ` \u2192 v${guard.latest} available \xB7 enter to update` }),
|
|
10487
10728
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: ` \xB7 ${guard.device_count} device${guard.device_count === 1 ? "" : "s"}${guard.outdated_count ? ` \xB7 ${guard.outdated_count} outdated` : ""}` })
|
|
10488
10729
|
] }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "loading\u2026" })
|
|
10489
10730
|
] });
|
|
@@ -10549,7 +10790,7 @@ function SettingsPanel({
|
|
|
10549
10790
|
const sectionOf = (r) => r.kind === "acct" || r.kind === "acct-add" ? "ACCOUNTS" : r.kind === "guard" || r.kind === "self" ? "PROTECTION" : r.kind === "ll-enabled" || r.kind === "ll-path" || r.kind === "ll-server" ? "LOCAL LOGS" : r.kind === "wh" || r.kind === "wh-add" ? "WEBHOOKS" : "ALERTS";
|
|
10550
10791
|
const SECTION_DESC = {
|
|
10551
10792
|
ACCOUNTS: `on this device (${accounts.length}) \xB7 \u25CF viewing \xB7 ACTIVE = guard key \xB7 x removes`,
|
|
10552
|
-
PROTECTION: "guard hook version + self-protection toggle",
|
|
10793
|
+
PROTECTION: "guard hook version (enter to update) + self-protection toggle",
|
|
10553
10794
|
"LOCAL LOGS": "mirror every decision to a file + dashboard link",
|
|
10554
10795
|
WEBHOOKS: `POST events to a URL (${webhooks.length}) \xB7 t tests`,
|
|
10555
10796
|
ALERTS: `one email + one telegram (${alerts.length}) \xB7 enter edits \xB7 m on/off`
|
|
@@ -10611,6 +10852,7 @@ var init_Settings = __esm({
|
|
|
10611
10852
|
init_api_client();
|
|
10612
10853
|
init_client();
|
|
10613
10854
|
init_device_login();
|
|
10855
|
+
init_global_install();
|
|
10614
10856
|
init_logs_server_daemon();
|
|
10615
10857
|
init_components();
|
|
10616
10858
|
init_hooks();
|
|
@@ -10828,9 +11070,9 @@ var tui_exports = {};
|
|
|
10828
11070
|
__export(tui_exports, {
|
|
10829
11071
|
launchTui: () => launchTui
|
|
10830
11072
|
});
|
|
10831
|
-
import { appendFileSync as appendFileSync2, mkdirSync as
|
|
10832
|
-
import { homedir as
|
|
10833
|
-
import { join as
|
|
11073
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync9 } from "fs";
|
|
11074
|
+
import { homedir as homedir10 } from "os";
|
|
11075
|
+
import { join as join12 } from "path";
|
|
10834
11076
|
import { render } from "ink";
|
|
10835
11077
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
10836
11078
|
async function launchTui() {
|
|
@@ -10841,11 +11083,11 @@ async function launchTui() {
|
|
|
10841
11083
|
return;
|
|
10842
11084
|
}
|
|
10843
11085
|
process.stdout.write("\x1B[?1049h\x1B[H");
|
|
10844
|
-
const debugLog =
|
|
11086
|
+
const debugLog = join12(homedir10(), ".solongate", "dataroom-debug.log");
|
|
10845
11087
|
const saved = { log: console.log, warn: console.warn, error: console.error, info: console.info, debug: console.debug };
|
|
10846
11088
|
const toFile = (level) => (...args) => {
|
|
10847
11089
|
try {
|
|
10848
|
-
|
|
11090
|
+
mkdirSync9(join12(homedir10(), ".solongate"), { recursive: true });
|
|
10849
11091
|
appendFileSync2(debugLog, `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
|
|
10850
11092
|
`);
|
|
10851
11093
|
} catch {
|
|
@@ -10969,7 +11211,7 @@ var init_args = __esm({
|
|
|
10969
11211
|
});
|
|
10970
11212
|
|
|
10971
11213
|
// src/commands/policy.ts
|
|
10972
|
-
import { readFileSync as
|
|
11214
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
10973
11215
|
async function run(argv) {
|
|
10974
11216
|
const { positionals, flags } = parse(argv);
|
|
10975
11217
|
const sub = positionals[0];
|
|
@@ -11144,7 +11386,7 @@ function printRules(rules) {
|
|
|
11144
11386
|
}
|
|
11145
11387
|
async function resolveRules(target) {
|
|
11146
11388
|
if (target.endsWith(".json")) {
|
|
11147
|
-
const parsed = JSON.parse(
|
|
11389
|
+
const parsed = JSON.parse(readFileSync10(target, "utf-8"));
|
|
11148
11390
|
return parsed.rules ?? [];
|
|
11149
11391
|
}
|
|
11150
11392
|
const p = await api.policies.get(target);
|
|
@@ -11559,9 +11801,9 @@ var init_agents2 = __esm({
|
|
|
11559
11801
|
});
|
|
11560
11802
|
|
|
11561
11803
|
// src/commands/doctor.ts
|
|
11562
|
-
import { existsSync as
|
|
11563
|
-
import { homedir as
|
|
11564
|
-
import { join as
|
|
11804
|
+
import { existsSync as existsSync5, statSync as statSync2 } from "fs";
|
|
11805
|
+
import { homedir as homedir11 } from "os";
|
|
11806
|
+
import { join as join13 } from "path";
|
|
11565
11807
|
async function run6(argv) {
|
|
11566
11808
|
const { flags } = parse(argv);
|
|
11567
11809
|
const json = flagBool(flags, "json");
|
|
@@ -11591,7 +11833,7 @@ async function run6(argv) {
|
|
|
11591
11833
|
} catch {
|
|
11592
11834
|
}
|
|
11593
11835
|
}
|
|
11594
|
-
if (
|
|
11836
|
+
if (existsSync5(LOCAL_LOG2)) {
|
|
11595
11837
|
const st = statSync2(LOCAL_LOG2);
|
|
11596
11838
|
const ageMin = (Date.now() - st.mtimeMs) / 6e4;
|
|
11597
11839
|
checks.push({ name: "local logs", ok: true, detail: `on \xB7 ${(st.size / 1024).toFixed(0)}KB \xB7 last write ${ageMin < 1 ? "just now" : Math.round(ageMin) + "m ago"}` });
|
|
@@ -11621,14 +11863,14 @@ var init_doctor = __esm({
|
|
|
11621
11863
|
init_api_client();
|
|
11622
11864
|
init_format();
|
|
11623
11865
|
init_args();
|
|
11624
|
-
LOCAL_LOG2 =
|
|
11866
|
+
LOCAL_LOG2 = join13(homedir11(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
11625
11867
|
}
|
|
11626
11868
|
});
|
|
11627
11869
|
|
|
11628
11870
|
// src/commands/watch.ts
|
|
11629
|
-
import { closeSync as closeSync2, existsSync as
|
|
11630
|
-
import { homedir as
|
|
11631
|
-
import { join as
|
|
11871
|
+
import { closeSync as closeSync2, existsSync as existsSync6, openSync as openSync4, readSync as readSync2, statSync as statSync3 } from "fs";
|
|
11872
|
+
import { homedir as homedir12 } from "os";
|
|
11873
|
+
import { join as join14 } from "path";
|
|
11632
11874
|
function tailLocal(file, maxBytes = 131072) {
|
|
11633
11875
|
try {
|
|
11634
11876
|
const size = statSync3(file).size;
|
|
@@ -11672,7 +11914,7 @@ async function run7(argv) {
|
|
|
11672
11914
|
for (const r of rows) if (keep(r)) print(r, json);
|
|
11673
11915
|
};
|
|
11674
11916
|
const pollLocal = () => {
|
|
11675
|
-
if (cloudOnly || !
|
|
11917
|
+
if (cloudOnly || !existsSync6(LOCAL_LOG3)) return;
|
|
11676
11918
|
const rows = [];
|
|
11677
11919
|
for (const line of tailLocal(LOCAL_LOG3)) {
|
|
11678
11920
|
try {
|
|
@@ -11735,7 +11977,7 @@ var init_watch = __esm({
|
|
|
11735
11977
|
init_cli_utils();
|
|
11736
11978
|
init_args();
|
|
11737
11979
|
init_format();
|
|
11738
|
-
LOCAL_LOG3 =
|
|
11980
|
+
LOCAL_LOG3 = join14(homedir12(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
11739
11981
|
trunc = (s, n) => s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
11740
11982
|
time = (ms) => new Date(ms).toTimeString().slice(0, 8);
|
|
11741
11983
|
}
|
|
@@ -12025,250 +12267,6 @@ var init_commands = __esm({
|
|
|
12025
12267
|
}
|
|
12026
12268
|
});
|
|
12027
12269
|
|
|
12028
|
-
// src/global-install.ts
|
|
12029
|
-
import { readFileSync as readFileSync10, writeFileSync as writeFileSync9, existsSync as existsSync6, mkdirSync as mkdirSync9 } from "fs";
|
|
12030
|
-
import { resolve as resolve4, join as join14, dirname as dirname3 } from "path";
|
|
12031
|
-
import { homedir as homedir12 } from "os";
|
|
12032
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
12033
|
-
import { createInterface } from "readline";
|
|
12034
|
-
import { execFileSync as execFileSync2 } from "child_process";
|
|
12035
|
-
function lockFile(file) {
|
|
12036
|
-
if (!existsSync6(file)) return;
|
|
12037
|
-
try {
|
|
12038
|
-
if (process.platform === "win32") {
|
|
12039
|
-
try {
|
|
12040
|
-
execFileSync2("icacls", [file, "/deny", "*S-1-1-0:(WD,AD,DC,DE)"], { stdio: "ignore" });
|
|
12041
|
-
} catch {
|
|
12042
|
-
}
|
|
12043
|
-
try {
|
|
12044
|
-
execFileSync2("attrib", ["+R", file], { stdio: "ignore" });
|
|
12045
|
-
} catch {
|
|
12046
|
-
}
|
|
12047
|
-
} else if (process.platform === "darwin") {
|
|
12048
|
-
try {
|
|
12049
|
-
execFileSync2("chflags", ["uchg", file], { stdio: "ignore" });
|
|
12050
|
-
} catch {
|
|
12051
|
-
}
|
|
12052
|
-
} else {
|
|
12053
|
-
try {
|
|
12054
|
-
execFileSync2("chattr", ["+i", file], { stdio: "ignore" });
|
|
12055
|
-
} catch {
|
|
12056
|
-
}
|
|
12057
|
-
}
|
|
12058
|
-
} catch {
|
|
12059
|
-
}
|
|
12060
|
-
}
|
|
12061
|
-
function unlockFile(file) {
|
|
12062
|
-
if (!existsSync6(file)) return;
|
|
12063
|
-
try {
|
|
12064
|
-
if (process.platform === "win32") {
|
|
12065
|
-
try {
|
|
12066
|
-
execFileSync2("icacls", [file, "/remove:d", "*S-1-1-0"], { stdio: "ignore" });
|
|
12067
|
-
} catch {
|
|
12068
|
-
}
|
|
12069
|
-
try {
|
|
12070
|
-
execFileSync2("icacls", [file, "/reset"], { stdio: "ignore" });
|
|
12071
|
-
} catch {
|
|
12072
|
-
}
|
|
12073
|
-
try {
|
|
12074
|
-
execFileSync2("attrib", ["-R", file], { stdio: "ignore" });
|
|
12075
|
-
} catch {
|
|
12076
|
-
}
|
|
12077
|
-
} else if (process.platform === "darwin") {
|
|
12078
|
-
try {
|
|
12079
|
-
execFileSync2("chflags", ["nouchg", file], { stdio: "ignore" });
|
|
12080
|
-
} catch {
|
|
12081
|
-
}
|
|
12082
|
-
} else {
|
|
12083
|
-
try {
|
|
12084
|
-
execFileSync2("chattr", ["-i", file], { stdio: "ignore" });
|
|
12085
|
-
} catch {
|
|
12086
|
-
}
|
|
12087
|
-
}
|
|
12088
|
-
} catch {
|
|
12089
|
-
}
|
|
12090
|
-
}
|
|
12091
|
-
function protectedTargets() {
|
|
12092
|
-
const p = globalPaths();
|
|
12093
|
-
return [
|
|
12094
|
-
join14(p.hooksDir, "guard.mjs"),
|
|
12095
|
-
join14(p.hooksDir, "audit.mjs"),
|
|
12096
|
-
join14(p.hooksDir, "stop.mjs"),
|
|
12097
|
-
join14(p.hooksDir, "shield.mjs"),
|
|
12098
|
-
p.configPath,
|
|
12099
|
-
p.settingsPath
|
|
12100
|
-
];
|
|
12101
|
-
}
|
|
12102
|
-
function lockProtected() {
|
|
12103
|
-
for (const f of protectedTargets()) lockFile(f);
|
|
12104
|
-
}
|
|
12105
|
-
function unlockProtected() {
|
|
12106
|
-
for (const f of protectedTargets()) unlockFile(f);
|
|
12107
|
-
}
|
|
12108
|
-
function globalPaths() {
|
|
12109
|
-
const home = homedir12();
|
|
12110
|
-
const sgDir = join14(home, ".solongate");
|
|
12111
|
-
const hooksDir = join14(sgDir, "hooks");
|
|
12112
|
-
const claudeDir = join14(home, ".claude");
|
|
12113
|
-
return {
|
|
12114
|
-
home,
|
|
12115
|
-
sgDir,
|
|
12116
|
-
hooksDir,
|
|
12117
|
-
claudeDir,
|
|
12118
|
-
settingsPath: join14(claudeDir, "settings.json"),
|
|
12119
|
-
backupPath: join14(claudeDir, "settings.solongate.bak"),
|
|
12120
|
-
configPath: join14(sgDir, "cloud-guard.json")
|
|
12121
|
-
};
|
|
12122
|
-
}
|
|
12123
|
-
function readHook(filename) {
|
|
12124
|
-
return readFileSync10(join14(HOOKS_DIR, filename), "utf-8");
|
|
12125
|
-
}
|
|
12126
|
-
function readGuard() {
|
|
12127
|
-
const bundled = join14(HOOKS_DIR, "guard.bundled.mjs");
|
|
12128
|
-
return existsSync6(bundled) ? readFileSync10(bundled, "utf-8") : readHook("guard.mjs");
|
|
12129
|
-
}
|
|
12130
|
-
function ask(question) {
|
|
12131
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
12132
|
-
return new Promise((res) => rl.question(question, (a) => {
|
|
12133
|
-
rl.close();
|
|
12134
|
-
res(a.trim());
|
|
12135
|
-
}));
|
|
12136
|
-
}
|
|
12137
|
-
function escapeRe(s) {
|
|
12138
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12139
|
-
}
|
|
12140
|
-
function resolveRealClaude() {
|
|
12141
|
-
try {
|
|
12142
|
-
const finder = process.platform === "win32" ? "where" : "which";
|
|
12143
|
-
const out2 = execFileSync2(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
12144
|
-
if (process.platform === "win32") {
|
|
12145
|
-
const low = (s) => s.toLowerCase();
|
|
12146
|
-
return out2.find((l) => low(l).endsWith(".cmd")) || out2.find((l) => low(l).endsWith(".exe")) || out2.find((l) => low(l).endsWith(".bat")) || out2[0] || null;
|
|
12147
|
-
}
|
|
12148
|
-
return out2[0] || null;
|
|
12149
|
-
} catch {
|
|
12150
|
-
return null;
|
|
12151
|
-
}
|
|
12152
|
-
}
|
|
12153
|
-
function shimTargets() {
|
|
12154
|
-
if (process.platform === "win32") {
|
|
12155
|
-
try {
|
|
12156
|
-
const prof = execFileSync2("powershell", ["-NoProfile", "-Command", "$PROFILE.CurrentUserAllHosts"], { encoding: "utf-8" }).trim();
|
|
12157
|
-
return prof ? [prof] : [];
|
|
12158
|
-
} catch {
|
|
12159
|
-
return [];
|
|
12160
|
-
}
|
|
12161
|
-
}
|
|
12162
|
-
return [".bashrc", ".zshrc", ".profile"].map((f) => join14(homedir12(), f)).filter((f) => existsSync6(f));
|
|
12163
|
-
}
|
|
12164
|
-
function writeShimBlock(file, block2) {
|
|
12165
|
-
const re = new RegExp(escapeRe(SHIM_BEGIN) + "[\\s\\S]*?" + escapeRe(SHIM_END) + "\\r?\\n?", "g");
|
|
12166
|
-
let content = existsSync6(file) ? readFileSync10(file, "utf-8") : "";
|
|
12167
|
-
content = content.replace(re, "");
|
|
12168
|
-
if (block2) {
|
|
12169
|
-
if (content.length && !content.endsWith("\n")) content += "\n";
|
|
12170
|
-
content += block2 + "\n";
|
|
12171
|
-
}
|
|
12172
|
-
mkdirSync9(dirname3(file), { recursive: true });
|
|
12173
|
-
writeFileSync9(file, content);
|
|
12174
|
-
}
|
|
12175
|
-
function installClaudeShim(shieldPath) {
|
|
12176
|
-
const real = resolveRealClaude();
|
|
12177
|
-
if (!real) {
|
|
12178
|
-
console.log(" (Claude Code not found on PATH \u2014 skipped auto-shield. Install it, then re-run `login`.)");
|
|
12179
|
-
return;
|
|
12180
|
-
}
|
|
12181
|
-
const node = process.execPath.replace(/\\/g, "/");
|
|
12182
|
-
const shield = shieldPath.replace(/\\/g, "/");
|
|
12183
|
-
const win = process.platform === "win32";
|
|
12184
|
-
const block2 = win ? `${SHIM_BEGIN}
|
|
12185
|
-
function claude { & "${node}" "${shield}" -- "${real}" @args }
|
|
12186
|
-
${SHIM_END}` : `${SHIM_BEGIN}
|
|
12187
|
-
claude() { "${node}" "${shield}" -- "${real}" "$@"; }
|
|
12188
|
-
${SHIM_END}`;
|
|
12189
|
-
const targets = shimTargets();
|
|
12190
|
-
if (targets.length === 0) return;
|
|
12191
|
-
for (const file of targets) {
|
|
12192
|
-
try {
|
|
12193
|
-
writeShimBlock(file, block2);
|
|
12194
|
-
} catch {
|
|
12195
|
-
}
|
|
12196
|
-
}
|
|
12197
|
-
}
|
|
12198
|
-
async function runGlobalInstall2(opts = {}) {
|
|
12199
|
-
const p = globalPaths();
|
|
12200
|
-
let apiKey = opts.apiKey || process.env["SOLONGATE_API_KEY"] || "";
|
|
12201
|
-
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
12202
|
-
try {
|
|
12203
|
-
const cfg = JSON.parse(readFileSync10(p.configPath, "utf-8"));
|
|
12204
|
-
if (cfg && typeof cfg.apiKey === "string") apiKey = cfg.apiKey;
|
|
12205
|
-
} catch {
|
|
12206
|
-
}
|
|
12207
|
-
}
|
|
12208
|
-
if (!apiKey || apiKey === "sg_live_your_key_here") {
|
|
12209
|
-
apiKey = await ask(" Enter your SolonGate API key (sg_live_\u2026 from https://dashboard.solongate.com): ");
|
|
12210
|
-
}
|
|
12211
|
-
if (!apiKey.startsWith("sg_live_") && !apiKey.startsWith("sg_test_")) {
|
|
12212
|
-
console.log(" Invalid API key. Must start with sg_live_ or sg_test_");
|
|
12213
|
-
process.exit(1);
|
|
12214
|
-
}
|
|
12215
|
-
const apiUrl = opts.apiUrl || process.env["SOLONGATE_API_URL"] || "https://api.solongate.com";
|
|
12216
|
-
mkdirSync9(p.hooksDir, { recursive: true });
|
|
12217
|
-
mkdirSync9(p.claudeDir, { recursive: true });
|
|
12218
|
-
unlockProtected();
|
|
12219
|
-
writeFileSync9(join14(p.hooksDir, "guard.mjs"), readGuard());
|
|
12220
|
-
writeFileSync9(join14(p.hooksDir, "audit.mjs"), readHook("audit.mjs"));
|
|
12221
|
-
writeFileSync9(join14(p.hooksDir, "stop.mjs"), readHook("stop.mjs"));
|
|
12222
|
-
writeFileSync9(join14(p.hooksDir, "shield.mjs"), readHook("shield.mjs"));
|
|
12223
|
-
console.log(` Installed hooks \u2192 ${p.hooksDir}`);
|
|
12224
|
-
installClaudeShim(join14(p.hooksDir, "shield.mjs"));
|
|
12225
|
-
writeFileSync9(p.configPath, JSON.stringify({ apiKey, apiUrl }, null, 2) + "\n");
|
|
12226
|
-
console.log(` Wrote ${p.configPath}`);
|
|
12227
|
-
let existing = {};
|
|
12228
|
-
if (existsSync6(p.settingsPath)) {
|
|
12229
|
-
const raw = readFileSync10(p.settingsPath, "utf-8");
|
|
12230
|
-
if (!existsSync6(p.backupPath)) {
|
|
12231
|
-
writeFileSync9(p.backupPath, raw);
|
|
12232
|
-
console.log(` Backed up existing settings \u2192 ${p.backupPath}`);
|
|
12233
|
-
}
|
|
12234
|
-
try {
|
|
12235
|
-
existing = JSON.parse(raw);
|
|
12236
|
-
} catch {
|
|
12237
|
-
existing = {};
|
|
12238
|
-
}
|
|
12239
|
-
}
|
|
12240
|
-
const guardAbs = join14(p.hooksDir, "guard.mjs").replace(/\\/g, "/");
|
|
12241
|
-
const auditAbs = join14(p.hooksDir, "audit.mjs").replace(/\\/g, "/");
|
|
12242
|
-
const stopAbs = join14(p.hooksDir, "stop.mjs").replace(/\\/g, "/");
|
|
12243
|
-
const nodeBin = process.execPath.replace(/\\/g, "/");
|
|
12244
|
-
const call = process.platform === "win32" ? "& " : "";
|
|
12245
|
-
const hookCmd = (script) => `${call}"${nodeBin}" "${script}" claude-code "Claude Code"`;
|
|
12246
|
-
const merged = {
|
|
12247
|
-
...existing,
|
|
12248
|
-
hooks: {
|
|
12249
|
-
PreToolUse: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(guardAbs) }] }],
|
|
12250
|
-
PostToolUse: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(auditAbs) }] }],
|
|
12251
|
-
Stop: [{ matcher: "", hooks: [{ type: "command", command: hookCmd(stopAbs) }] }]
|
|
12252
|
-
}
|
|
12253
|
-
};
|
|
12254
|
-
writeFileSync9(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
|
|
12255
|
-
console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
|
|
12256
|
-
if (process.env["SOLONGATE_OS_LOCK"] === "1") {
|
|
12257
|
-
lockProtected();
|
|
12258
|
-
console.log(" Locked protection files (OS-level read-only/immutable).");
|
|
12259
|
-
}
|
|
12260
|
-
}
|
|
12261
|
-
var __dirname, HOOKS_DIR, SHIM_BEGIN, SHIM_END;
|
|
12262
|
-
var init_global_install = __esm({
|
|
12263
|
-
"src/global-install.ts"() {
|
|
12264
|
-
"use strict";
|
|
12265
|
-
__dirname = dirname3(fileURLToPath3(import.meta.url));
|
|
12266
|
-
HOOKS_DIR = resolve4(__dirname, "..", "hooks");
|
|
12267
|
-
SHIM_BEGIN = "# >>> SolonGate shield (auto secret redaction) >>>";
|
|
12268
|
-
SHIM_END = "# <<< SolonGate shield <<<";
|
|
12269
|
-
}
|
|
12270
|
-
});
|
|
12271
|
-
|
|
12272
12270
|
// src/login.ts
|
|
12273
12271
|
var login_exports = {};
|
|
12274
12272
|
import { spawn as spawn5 } from "child_process";
|