@solongate/proxy 0.81.78 → 0.81.80
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 +7 -0
- package/dist/global-install.js +14 -2
- package/dist/index.js +35 -35
- package/dist/tui/index.js +29 -27
- package/package.json +1 -1
package/dist/global-install.d.ts
CHANGED
|
@@ -11,6 +11,13 @@ export declare function globalPaths(): {
|
|
|
11
11
|
};
|
|
12
12
|
export declare function clearGuardUpdateCheck(): boolean;
|
|
13
13
|
export declare function runGlobalRestore(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Are the SolonGate guard hooks currently installed in the global Claude settings
|
|
16
|
+
* on THIS device? Reflects a local install/remove IMMEDIATELY — unlike the cloud
|
|
17
|
+
* guard-status (which shows the version this device last reported and lingers for
|
|
18
|
+
* ~14 days), so the dataroom can show "removed" the instant you remove it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isGuardInstalled(): boolean;
|
|
14
21
|
/**
|
|
15
22
|
* TUI-safe uninstall (dataroom Settings → guard → remove). Same effect as
|
|
16
23
|
* runGlobalRestore but returns a status string instead of writing to stdout —
|
package/dist/global-install.js
CHANGED
|
@@ -137,20 +137,31 @@ function runGlobalRestore() {
|
|
|
137
137
|
}
|
|
138
138
|
console.log(" Global SolonGate enforcement uninstalled. Restart Claude Code.");
|
|
139
139
|
}
|
|
140
|
+
function isGuardInstalled() {
|
|
141
|
+
try {
|
|
142
|
+
const p = globalPaths();
|
|
143
|
+
if (!existsSync(p.settingsPath)) return false;
|
|
144
|
+
const s = JSON.parse(readFileSync(p.settingsPath, "utf-8"));
|
|
145
|
+
return !!s.hooks && JSON.stringify(s.hooks).includes(".solongate");
|
|
146
|
+
} catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
140
150
|
function uninstallGlobalQuiet() {
|
|
141
151
|
try {
|
|
142
152
|
const p = globalPaths();
|
|
143
153
|
unlockProtected();
|
|
144
154
|
removeClaudeShim();
|
|
155
|
+
const applies = "applies to NEW Claude Code sessions \u2014 a session already running keeps its loaded hooks until it ends";
|
|
145
156
|
if (existsSync(p.backupPath)) {
|
|
146
157
|
writeFileSync(p.settingsPath, readFileSync(p.backupPath, "utf-8"));
|
|
147
|
-
return { ok: true, message:
|
|
158
|
+
return { ok: true, message: `guard removed \u2014 restored the pre-install settings \xB7 ${applies}` };
|
|
148
159
|
}
|
|
149
160
|
if (existsSync(p.settingsPath)) {
|
|
150
161
|
const s = JSON.parse(readFileSync(p.settingsPath, "utf-8"));
|
|
151
162
|
delete s.hooks;
|
|
152
163
|
writeFileSync(p.settingsPath, JSON.stringify(s, null, 2) + "\n");
|
|
153
|
-
return { ok: true, message:
|
|
164
|
+
return { ok: true, message: `guard removed \u2014 hooks cleared \xB7 ${applies}` };
|
|
154
165
|
}
|
|
155
166
|
return { ok: true, message: "nothing to remove \u2014 no global Claude Code settings found" };
|
|
156
167
|
} catch (e) {
|
|
@@ -299,6 +310,7 @@ export {
|
|
|
299
310
|
globalPaths,
|
|
300
311
|
installClaudeShim,
|
|
301
312
|
installGlobalWithKey,
|
|
313
|
+
isGuardInstalled,
|
|
302
314
|
lockProtected,
|
|
303
315
|
removeClaudeShim,
|
|
304
316
|
runGlobalInstall,
|
package/dist/index.js
CHANGED
|
@@ -6562,7 +6562,7 @@ __export(self_update_exports, {
|
|
|
6562
6562
|
tuiUpdateFlow: () => tuiUpdateFlow
|
|
6563
6563
|
});
|
|
6564
6564
|
import { execFile, spawn } from "child_process";
|
|
6565
|
-
import { mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync4,
|
|
6565
|
+
import { mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
6566
6566
|
import { homedir as homedir2 } from "os";
|
|
6567
6567
|
import { dirname, join as join4 } from "path";
|
|
6568
6568
|
import { fileURLToPath } from "url";
|
|
@@ -6614,28 +6614,6 @@ async function fetchLatest() {
|
|
|
6614
6614
|
return null;
|
|
6615
6615
|
}
|
|
6616
6616
|
}
|
|
6617
|
-
function npmGlobalRoot() {
|
|
6618
|
-
return new Promise((resolve10) => {
|
|
6619
|
-
try {
|
|
6620
|
-
execFile("npm", ["root", "-g"], { timeout: 5e3, windowsHide: true, shell: process.platform === "win32" }, (err2, stdout) => {
|
|
6621
|
-
resolve10(err2 ? null : stdout.trim() || null);
|
|
6622
|
-
});
|
|
6623
|
-
} catch {
|
|
6624
|
-
resolve10(null);
|
|
6625
|
-
}
|
|
6626
|
-
});
|
|
6627
|
-
}
|
|
6628
|
-
async function isGlobalInstall() {
|
|
6629
|
-
try {
|
|
6630
|
-
const script = realpathSync(process.argv[1] ?? "");
|
|
6631
|
-
if (!script) return false;
|
|
6632
|
-
const root = await npmGlobalRoot();
|
|
6633
|
-
if (!root) return false;
|
|
6634
|
-
return script.startsWith(realpathSync(root));
|
|
6635
|
-
} catch {
|
|
6636
|
-
return false;
|
|
6637
|
-
}
|
|
6638
|
-
}
|
|
6639
6617
|
function spawnGlobalInstall(version) {
|
|
6640
6618
|
try {
|
|
6641
6619
|
mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
|
|
@@ -6687,7 +6665,7 @@ async function tuiUpdateFlow(onStatus) {
|
|
|
6687
6665
|
if (!latest || !newerThan(latest, current)) return;
|
|
6688
6666
|
const attempts = readState().attempts ?? {};
|
|
6689
6667
|
const canRetry = Date.now() - (attempts[latest] ?? 0) >= ATTEMPT_EVERY_MS;
|
|
6690
|
-
if (
|
|
6668
|
+
if (canRetry) {
|
|
6691
6669
|
writeState({ ...readState(), attempts: { [latest]: Date.now() } });
|
|
6692
6670
|
onStatus({ kind: "updating", version: latest });
|
|
6693
6671
|
if (await runGlobalInstall(latest)) {
|
|
@@ -6713,16 +6691,14 @@ function maybeSelfUpdate(notify = (l) => process.stderr.write(l + "\n")) {
|
|
|
6713
6691
|
}
|
|
6714
6692
|
if (!latest || !newerThan(latest, current)) return;
|
|
6715
6693
|
const attempts = readState().attempts ?? {};
|
|
6716
|
-
if (
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 updating in the background, next run uses it${c.reset}`);
|
|
6721
|
-
return;
|
|
6722
|
-
}
|
|
6723
|
-
} else {
|
|
6694
|
+
if (now - (attempts[latest] ?? 0) >= ATTEMPT_EVERY_MS) {
|
|
6695
|
+
writeState({ ...readState(), attempts: { [latest]: now } });
|
|
6696
|
+
if (spawnGlobalInstall(latest)) {
|
|
6697
|
+
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 updating in the background, next run uses it${c.reset}`);
|
|
6724
6698
|
return;
|
|
6725
6699
|
}
|
|
6700
|
+
} else {
|
|
6701
|
+
return;
|
|
6726
6702
|
}
|
|
6727
6703
|
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 update: ${c.reset}${c.cyan}npm i -g ${PKG}@latest${c.reset}`);
|
|
6728
6704
|
} catch {
|
|
@@ -10182,20 +10158,31 @@ function clearGuardUpdateCheck() {
|
|
|
10182
10158
|
return false;
|
|
10183
10159
|
}
|
|
10184
10160
|
}
|
|
10161
|
+
function isGuardInstalled() {
|
|
10162
|
+
try {
|
|
10163
|
+
const p = globalPaths();
|
|
10164
|
+
if (!existsSync4(p.settingsPath)) return false;
|
|
10165
|
+
const s = JSON.parse(readFileSync9(p.settingsPath, "utf-8"));
|
|
10166
|
+
return !!s.hooks && JSON.stringify(s.hooks).includes(".solongate");
|
|
10167
|
+
} catch {
|
|
10168
|
+
return false;
|
|
10169
|
+
}
|
|
10170
|
+
}
|
|
10185
10171
|
function uninstallGlobalQuiet() {
|
|
10186
10172
|
try {
|
|
10187
10173
|
const p = globalPaths();
|
|
10188
10174
|
unlockProtected();
|
|
10189
10175
|
removeClaudeShim();
|
|
10176
|
+
const applies = "applies to NEW Claude Code sessions \u2014 a session already running keeps its loaded hooks until it ends";
|
|
10190
10177
|
if (existsSync4(p.backupPath)) {
|
|
10191
10178
|
writeFileSync9(p.settingsPath, readFileSync9(p.backupPath, "utf-8"));
|
|
10192
|
-
return { ok: true, message:
|
|
10179
|
+
return { ok: true, message: `guard removed \u2014 restored the pre-install settings \xB7 ${applies}` };
|
|
10193
10180
|
}
|
|
10194
10181
|
if (existsSync4(p.settingsPath)) {
|
|
10195
10182
|
const s = JSON.parse(readFileSync9(p.settingsPath, "utf-8"));
|
|
10196
10183
|
delete s.hooks;
|
|
10197
10184
|
writeFileSync9(p.settingsPath, JSON.stringify(s, null, 2) + "\n");
|
|
10198
|
-
return { ok: true, message:
|
|
10185
|
+
return { ok: true, message: `guard removed \u2014 hooks cleared \xB7 ${applies}` };
|
|
10199
10186
|
}
|
|
10200
10187
|
return { ok: true, message: "nothing to remove \u2014 no global Claude Code settings found" };
|
|
10201
10188
|
} catch (e) {
|
|
@@ -10272,6 +10259,7 @@ function SettingsPanel({
|
|
|
10272
10259
|
const [tick, setTick] = useState7(0);
|
|
10273
10260
|
const abort = useRef3(false);
|
|
10274
10261
|
const refreshAccounts = () => setAccounts(listAccounts());
|
|
10262
|
+
const [guardHere, setGuardHere] = useState7(() => isGuardInstalled());
|
|
10275
10263
|
const locked = accounts.length === 0;
|
|
10276
10264
|
const [srv, setSrv] = useState7(() => logsServerStatus());
|
|
10277
10265
|
useEffect6(() => {
|
|
@@ -10416,6 +10404,10 @@ function SettingsPanel({
|
|
|
10416
10404
|
} else if (r.kind === "acct-add") {
|
|
10417
10405
|
beginLogin();
|
|
10418
10406
|
} else if (r.kind === "guard") {
|
|
10407
|
+
if (!guardHere) {
|
|
10408
|
+
setMsg({ text: "guard is removed on this device \u2014 log in again (Accounts \u2192 + add) to reinstall it", level: "bad" });
|
|
10409
|
+
return;
|
|
10410
|
+
}
|
|
10419
10411
|
if (!guard) return;
|
|
10420
10412
|
if (guard.up_to_date) {
|
|
10421
10413
|
setMsg({ text: `guard already on the latest hook (v${guard.latest})`, level: "ok" });
|
|
@@ -10574,6 +10566,10 @@ function SettingsPanel({
|
|
|
10574
10566
|
} else if (cur.kind === "alert-add-email") openAlertEditor("email");
|
|
10575
10567
|
else if (cur.kind === "alert-add-tg") openAlertEditor("telegram");
|
|
10576
10568
|
} else if (inp === "d" && cur.kind === "guard") {
|
|
10569
|
+
if (!guardHere) {
|
|
10570
|
+
setMsg({ text: "guard already removed on this device", level: "ok" });
|
|
10571
|
+
return;
|
|
10572
|
+
}
|
|
10577
10573
|
const k = keyOf(cur);
|
|
10578
10574
|
if (confirmDel !== k) {
|
|
10579
10575
|
setConfirmDel(k);
|
|
@@ -10583,6 +10579,7 @@ function SettingsPanel({
|
|
|
10583
10579
|
setConfirmDel(null);
|
|
10584
10580
|
const res = uninstallGlobalQuiet();
|
|
10585
10581
|
setMsg({ text: (res.ok ? "\u2713 " : "\u2717 ") + res.message, level: res.ok ? "ok" : "bad" });
|
|
10582
|
+
setGuardHere(isGuardInstalled());
|
|
10586
10583
|
guardQ.reload();
|
|
10587
10584
|
} else if (inp === "d" && (cur.kind === "wh" || cur.kind === "alert")) {
|
|
10588
10585
|
const k = keyOf(cur);
|
|
@@ -10689,7 +10686,10 @@ function SettingsPanel({
|
|
|
10689
10686
|
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10690
10687
|
cursor(r),
|
|
10691
10688
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "guard".padEnd(11) }),
|
|
10692
|
-
|
|
10689
|
+
!guardHere ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
10690
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.bad, bold: true, children: "removed" }),
|
|
10691
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " \u2014 not installed on this device \xB7 new Claude Code sessions are unguarded" })
|
|
10692
|
+
] }) : guard ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
10693
10693
|
/* @__PURE__ */ jsx7(Text7, { color: guard.up_to_date ? theme.ok : theme.warn, children: `v${guard.installed ?? "?"}` }),
|
|
10694
10694
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: guard.up_to_date ? " (latest)" : ` \u2192 v${guard.latest} available \xB7 enter update` }),
|
|
10695
10695
|
/* @__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` : ""} \xB7 d remove` })
|
package/dist/tui/index.js
CHANGED
|
@@ -3215,20 +3215,31 @@ function clearGuardUpdateCheck() {
|
|
|
3215
3215
|
return false;
|
|
3216
3216
|
}
|
|
3217
3217
|
}
|
|
3218
|
+
function isGuardInstalled() {
|
|
3219
|
+
try {
|
|
3220
|
+
const p = globalPaths();
|
|
3221
|
+
if (!existsSync2(p.settingsPath)) return false;
|
|
3222
|
+
const s = JSON.parse(readFileSync4(p.settingsPath, "utf-8"));
|
|
3223
|
+
return !!s.hooks && JSON.stringify(s.hooks).includes(".solongate");
|
|
3224
|
+
} catch {
|
|
3225
|
+
return false;
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3218
3228
|
function uninstallGlobalQuiet() {
|
|
3219
3229
|
try {
|
|
3220
3230
|
const p = globalPaths();
|
|
3221
3231
|
unlockProtected();
|
|
3222
3232
|
removeClaudeShim();
|
|
3233
|
+
const applies = "applies to NEW Claude Code sessions \u2014 a session already running keeps its loaded hooks until it ends";
|
|
3223
3234
|
if (existsSync2(p.backupPath)) {
|
|
3224
3235
|
writeFileSync5(p.settingsPath, readFileSync4(p.backupPath, "utf-8"));
|
|
3225
|
-
return { ok: true, message:
|
|
3236
|
+
return { ok: true, message: `guard removed \u2014 restored the pre-install settings \xB7 ${applies}` };
|
|
3226
3237
|
}
|
|
3227
3238
|
if (existsSync2(p.settingsPath)) {
|
|
3228
3239
|
const s = JSON.parse(readFileSync4(p.settingsPath, "utf-8"));
|
|
3229
3240
|
delete s.hooks;
|
|
3230
3241
|
writeFileSync5(p.settingsPath, JSON.stringify(s, null, 2) + "\n");
|
|
3231
|
-
return { ok: true, message:
|
|
3242
|
+
return { ok: true, message: `guard removed \u2014 hooks cleared \xB7 ${applies}` };
|
|
3232
3243
|
}
|
|
3233
3244
|
return { ok: true, message: "nothing to remove \u2014 no global Claude Code settings found" };
|
|
3234
3245
|
} catch (e) {
|
|
@@ -3385,6 +3396,7 @@ function SettingsPanel({
|
|
|
3385
3396
|
const [tick, setTick] = useState7(0);
|
|
3386
3397
|
const abort = useRef3(false);
|
|
3387
3398
|
const refreshAccounts = () => setAccounts(listAccounts());
|
|
3399
|
+
const [guardHere, setGuardHere] = useState7(() => isGuardInstalled());
|
|
3388
3400
|
const locked = accounts.length === 0;
|
|
3389
3401
|
const [srv, setSrv] = useState7(() => logsServerStatus());
|
|
3390
3402
|
useEffect6(() => {
|
|
@@ -3529,6 +3541,10 @@ function SettingsPanel({
|
|
|
3529
3541
|
} else if (r.kind === "acct-add") {
|
|
3530
3542
|
beginLogin();
|
|
3531
3543
|
} else if (r.kind === "guard") {
|
|
3544
|
+
if (!guardHere) {
|
|
3545
|
+
setMsg({ text: "guard is removed on this device \u2014 log in again (Accounts \u2192 + add) to reinstall it", level: "bad" });
|
|
3546
|
+
return;
|
|
3547
|
+
}
|
|
3532
3548
|
if (!guard) return;
|
|
3533
3549
|
if (guard.up_to_date) {
|
|
3534
3550
|
setMsg({ text: `guard already on the latest hook (v${guard.latest})`, level: "ok" });
|
|
@@ -3687,6 +3703,10 @@ function SettingsPanel({
|
|
|
3687
3703
|
} else if (cur.kind === "alert-add-email") openAlertEditor("email");
|
|
3688
3704
|
else if (cur.kind === "alert-add-tg") openAlertEditor("telegram");
|
|
3689
3705
|
} else if (inp === "d" && cur.kind === "guard") {
|
|
3706
|
+
if (!guardHere) {
|
|
3707
|
+
setMsg({ text: "guard already removed on this device", level: "ok" });
|
|
3708
|
+
return;
|
|
3709
|
+
}
|
|
3690
3710
|
const k = keyOf(cur);
|
|
3691
3711
|
if (confirmDel !== k) {
|
|
3692
3712
|
setConfirmDel(k);
|
|
@@ -3696,6 +3716,7 @@ function SettingsPanel({
|
|
|
3696
3716
|
setConfirmDel(null);
|
|
3697
3717
|
const res = uninstallGlobalQuiet();
|
|
3698
3718
|
setMsg({ text: (res.ok ? "\u2713 " : "\u2717 ") + res.message, level: res.ok ? "ok" : "bad" });
|
|
3719
|
+
setGuardHere(isGuardInstalled());
|
|
3699
3720
|
guardQ.reload();
|
|
3700
3721
|
} else if (inp === "d" && (cur.kind === "wh" || cur.kind === "alert")) {
|
|
3701
3722
|
const k = keyOf(cur);
|
|
@@ -3802,7 +3823,10 @@ function SettingsPanel({
|
|
|
3802
3823
|
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
3803
3824
|
cursor(r),
|
|
3804
3825
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "guard".padEnd(11) }),
|
|
3805
|
-
|
|
3826
|
+
!guardHere ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
3827
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.bad, bold: true, children: "removed" }),
|
|
3828
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " \u2014 not installed on this device \xB7 new Claude Code sessions are unguarded" })
|
|
3829
|
+
] }) : guard ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
3806
3830
|
/* @__PURE__ */ jsx7(Text7, { color: guard.up_to_date ? theme.ok : theme.warn, children: `v${guard.installed ?? "?"}` }),
|
|
3807
3831
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: guard.up_to_date ? " (latest)" : ` \u2192 v${guard.latest} available \xB7 enter update` }),
|
|
3808
3832
|
/* @__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` : ""} \xB7 d remove` })
|
|
@@ -3928,7 +3952,7 @@ function SettingsPanel({
|
|
|
3928
3952
|
|
|
3929
3953
|
// src/self-update.ts
|
|
3930
3954
|
import { execFile, spawn as spawn4 } from "child_process";
|
|
3931
|
-
import { mkdirSync as mkdirSync6, openSync as openSync3, readFileSync as readFileSync6,
|
|
3955
|
+
import { mkdirSync as mkdirSync6, openSync as openSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
3932
3956
|
import { homedir as homedir8 } from "os";
|
|
3933
3957
|
import { dirname as dirname3, join as join8 } from "path";
|
|
3934
3958
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -3985,28 +4009,6 @@ async function fetchLatest() {
|
|
|
3985
4009
|
return null;
|
|
3986
4010
|
}
|
|
3987
4011
|
}
|
|
3988
|
-
function npmGlobalRoot() {
|
|
3989
|
-
return new Promise((resolve3) => {
|
|
3990
|
-
try {
|
|
3991
|
-
execFile("npm", ["root", "-g"], { timeout: 5e3, windowsHide: true, shell: process.platform === "win32" }, (err, stdout) => {
|
|
3992
|
-
resolve3(err ? null : stdout.trim() || null);
|
|
3993
|
-
});
|
|
3994
|
-
} catch {
|
|
3995
|
-
resolve3(null);
|
|
3996
|
-
}
|
|
3997
|
-
});
|
|
3998
|
-
}
|
|
3999
|
-
async function isGlobalInstall() {
|
|
4000
|
-
try {
|
|
4001
|
-
const script = realpathSync(process.argv[1] ?? "");
|
|
4002
|
-
if (!script) return false;
|
|
4003
|
-
const root = await npmGlobalRoot();
|
|
4004
|
-
if (!root) return false;
|
|
4005
|
-
return script.startsWith(realpathSync(root));
|
|
4006
|
-
} catch {
|
|
4007
|
-
return false;
|
|
4008
|
-
}
|
|
4009
|
-
}
|
|
4010
4012
|
function runGlobalInstall(version) {
|
|
4011
4013
|
return new Promise((resolve3) => {
|
|
4012
4014
|
try {
|
|
@@ -4040,7 +4042,7 @@ async function tuiUpdateFlow(onStatus) {
|
|
|
4040
4042
|
if (!latest || !newerThan(latest, current)) return;
|
|
4041
4043
|
const attempts = readState2().attempts ?? {};
|
|
4042
4044
|
const canRetry = Date.now() - (attempts[latest] ?? 0) >= ATTEMPT_EVERY_MS;
|
|
4043
|
-
if (
|
|
4045
|
+
if (canRetry) {
|
|
4044
4046
|
writeState2({ ...readState2(), attempts: { [latest]: Date.now() } });
|
|
4045
4047
|
onStatus({ kind: "updating", version: latest });
|
|
4046
4048
|
if (await runGlobalInstall(latest)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.80",
|
|
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": {
|