troxy-cli 1.29.52 → 1.29.53
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/package.json +1 -1
- package/src/daemon.js +3 -1
- package/src/init.js +13 -0
- package/src/tests/init-mods.test.js +18 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "troxy-cli",
|
|
3
|
-
"version": "1.29.
|
|
3
|
+
"version": "1.29.53",
|
|
4
4
|
"description": "A secure control layer for AI agents: policies across payments, messages, logins, destructive actions, model usage, and secrets, all enforceable from the CLI",
|
|
5
5
|
"homepage": "https://troxy.io",
|
|
6
6
|
"bugs": {
|
package/src/daemon.js
CHANGED
|
@@ -23,7 +23,7 @@ import { api } from './api.js';
|
|
|
23
23
|
import { createInterceptor } from './interceptor.js';
|
|
24
24
|
import { enabledProviders, interceptHostsFor, troxyRouteFor } from './providers.js';
|
|
25
25
|
import { ensureInterceptionCerts } from './tls-ca.js';
|
|
26
|
-
import { migrateBaseUrlProxyToInterception, claudeCodeSettingsPath } from './init.js';
|
|
26
|
+
import { migrateBaseUrlProxyToInterception, claudeCodeSettingsPath, refreshTroxyGuardMod } from './init.js';
|
|
27
27
|
|
|
28
28
|
const INTERVAL_MS = 60_000;
|
|
29
29
|
|
|
@@ -139,6 +139,8 @@ export async function runDaemon() {
|
|
|
139
139
|
process.on('unhandledRejection', (err) => {
|
|
140
140
|
process.stderr.write(`[troxy-daemon] unhandled rejection (continuing): ${err?.stack || err}\n`);
|
|
141
141
|
});
|
|
142
|
+
// A CLI upgrade (npm or troxy update) then a daemon restart brings the mod up to date.
|
|
143
|
+
refreshTroxyGuardMod().catch((err) => process.stderr.write(`[troxy-daemon] mod refresh failed: ${err.message}\n`));
|
|
142
144
|
|
|
143
145
|
const cfg = loadConfig();
|
|
144
146
|
if (!cfg?.apiKey) {
|
package/src/init.js
CHANGED
|
@@ -38,6 +38,18 @@ export async function installTroxyGuardMod(home = os.homedir(), detectFn = detec
|
|
|
38
38
|
return true;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
// Only `troxy init` used to install the mod, so a CLI upgrade left the old mod running.
|
|
42
|
+
// Re-copy it when the installed one is stamped with a different CLI version; a machine
|
|
43
|
+
// without the mod (never ran init, or uninstalled) is left alone.
|
|
44
|
+
export async function refreshTroxyGuardMod(home = os.homedir(), detectFn = detectInstalledClaudeCodeVersion) {
|
|
45
|
+
const manifest = path.join(home, '.claude', 'skills', 'troxy-guard', '.claude-plugin', 'plugin.json');
|
|
46
|
+
let installed;
|
|
47
|
+
try { installed = JSON.parse(fs.readFileSync(manifest, 'utf8')).version; } catch { return false; }
|
|
48
|
+
const { version } = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
|
|
49
|
+
if (installed === version) return false;
|
|
50
|
+
return installTroxyGuardMod(home, detectFn);
|
|
51
|
+
}
|
|
52
|
+
|
|
41
53
|
export function uninstallTroxyGuardMod(home = os.homedir()) {
|
|
42
54
|
fs.rmSync(path.join(home, '.claude', 'skills', 'troxy-guard'), { recursive: true, force: true });
|
|
43
55
|
}
|
|
@@ -113,6 +125,7 @@ export async function refreshHostedInstructions(key) {
|
|
|
113
125
|
|
|
114
126
|
export async function reprovisionKeyConsumers(key, agentName, proxyOptIn = null, conciseOptIn = null) {
|
|
115
127
|
const platform = process.platform;
|
|
128
|
+
try { if (await refreshTroxyGuardMod()) console.log(' • Troxy model routing updated ✓'); } catch {}
|
|
116
129
|
const { detected, hasOpenClaw, hasClaude, none } = detectMcpClients();
|
|
117
130
|
|
|
118
131
|
if (none) {
|
|
@@ -3,7 +3,7 @@ import assert from 'node:assert/strict';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import fs from 'node:fs';
|
|
6
|
-
import { installTroxyGuardMod, uninstallTroxyGuardMod } from '../init.js';
|
|
6
|
+
import { installTroxyGuardMod, uninstallTroxyGuardMod, refreshTroxyGuardMod } from '../init.js';
|
|
7
7
|
|
|
8
8
|
test('installTroxyGuardMod: copies the mod when the version supports it', async () => {
|
|
9
9
|
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'troxy-mod-home-'));
|
|
@@ -77,3 +77,20 @@ test('uninstallTroxyGuardMod: a no-op (not a throw) when nothing was installed',
|
|
|
77
77
|
fs.rmSync(tmpHome, { recursive: true, force: true });
|
|
78
78
|
}
|
|
79
79
|
});
|
|
80
|
+
|
|
81
|
+
test('refreshTroxyGuardMod: re-copies a stale mod, leaves a current or missing one alone', async () => {
|
|
82
|
+
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'troxy-mod-home-'));
|
|
83
|
+
const cc = async () => ({ major: 2, minor: 1, patch: 289 });
|
|
84
|
+
const manifest = path.join(tmpHome, '.claude', 'skills', 'troxy-guard', '.claude-plugin', 'plugin.json');
|
|
85
|
+
try {
|
|
86
|
+
assert.equal(await refreshTroxyGuardMod(tmpHome, cc), false); // never installed: stays off
|
|
87
|
+
assert.equal(fs.existsSync(manifest), false);
|
|
88
|
+
await installTroxyGuardMod(tmpHome, cc);
|
|
89
|
+
assert.equal(await refreshTroxyGuardMod(tmpHome, cc), false); // already current
|
|
90
|
+
fs.writeFileSync(manifest, JSON.stringify({ name: 'troxy-guard', version: '0.0.1' }));
|
|
91
|
+
assert.equal(await refreshTroxyGuardMod(tmpHome, cc), true); // stale: re-copied and re-stamped
|
|
92
|
+
assert.notEqual(JSON.parse(fs.readFileSync(manifest, 'utf8')).version, '0.0.1');
|
|
93
|
+
} finally {
|
|
94
|
+
fs.rmSync(tmpHome, { recursive: true, force: true });
|
|
95
|
+
}
|
|
96
|
+
});
|