troxy-cli 1.11.0 → 1.12.0

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 CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "troxy-cli",
3
- "version": "1.11.0",
4
- "description": "AI payment control protect your agent's payments with policies",
3
+ "version": "1.12.0",
4
+ "description": "Control layer for AI agents: check payments, emails, logins and destructive actions against your policies",
5
+ "homepage": "https://troxy.io",
6
+ "bugs": {
7
+ "email": "support@troxy.io"
8
+ },
5
9
  "type": "module",
6
10
  "bin": {
7
11
  "troxy": "bin/troxy.js"
package/src/api.js CHANGED
@@ -75,6 +75,7 @@ export const api = {
75
75
  evaluateLogin: (body, apiKey) => request('POST', '/evaluate/login', { apiKey, body }),
76
76
  evaluateAction: (body, apiKey) => request('POST', '/evaluate/action', { apiKey, body }),
77
77
  selfRevoke: (apiKey) => request('POST', '/mcp/self-revoke', { apiKey }),
78
+ revokeAllOthers: (apiKey) => request('POST', '/mcp/revoke-all-others', { apiKey }),
78
79
  confirmPayment: (auditId, body, apiKey) => request('POST', `/payments/${auditId}/confirm`, { apiKey, body }),
79
80
  waitApprovalStatus: (token) => request('GET', `/approvals/${encodeURIComponent(token)}/wait`),
80
81
 
package/src/init.js CHANGED
@@ -122,8 +122,7 @@ async function printHostedAgentSetup(key) {
122
122
  text = buildHostedInstructions(await api.agentInstructions(key), key);
123
123
  } catch {
124
124
  console.log(' Could not reach the Troxy API to fetch them.');
125
- console.log(' Get the block from dash.troxy.io API Keys → Cloud agents,');
126
- console.log(' or re-run this command once you are back online.\n');
125
+ console.log(' Re-run this command once you are back online.\n');
127
126
  return;
128
127
  }
129
128
 
package/src/uninstall.js CHANGED
@@ -87,12 +87,15 @@ function removeMcpEntries() {
87
87
  export async function runUninstall() {
88
88
  console.log('\n Troxy: Uninstall\n');
89
89
 
90
- const answer = await prompt(' This will remove Troxy from this machine. Continue? (y/N): ');
90
+ const answer = await prompt(' This will remove Troxy from this machine and revoke ALL your agent keys. Continue? (y/N): ');
91
91
  if (answer.toLowerCase() !== 'y') {
92
92
  console.log('\n Cancelled.\n');
93
93
  process.exit(0);
94
94
  }
95
95
 
96
+ const cfg = loadConfig();
97
+ const apiKey = cfg?.apiKey;
98
+
96
99
  // 1. Stop and remove background service
97
100
  process.stdout.write(' Stopping background service... ');
98
101
  const removed = removeService();
@@ -108,24 +111,45 @@ export async function runUninstall() {
108
111
  console.log('none found');
109
112
  }
110
113
 
111
- // 3. Revoke the API key. /mcp/self-revoke only lets a key revoke the exact
112
- // token it authenticates asit can't touch or list any other token — so
113
- // this doesn't need a login/JWT, the key on disk is enough.
114
- const cfg = loadConfig();
115
- if (cfg?.apiKey) {
116
- const prefix = cfg.apiKey.slice(0, 12) + '...';
117
- process.stdout.write(` Revoking API key ${prefix}... `);
114
+ // 3. Revoke all OTHER agent keys (cloud agents, other machines) using the
115
+ // local API key for auth no troxy login needed. The key proves identity
116
+ // to the server, and /mcp/revoke-all-others kills every other active token
117
+ // for the same user. We do this BEFORE self-revoke so the key is still valid
118
+ // to make the call.
119
+ if (apiKey) {
120
+ process.stdout.write(' Revoking other agents... ');
121
+ try {
122
+ const result = await api.revokeAllOthers(apiKey);
123
+ if (result.count > 0) {
124
+ console.log(`✓ (${result.count} agent${result.count > 1 ? 's' : ''})`);
125
+ for (const a of result.revoked) {
126
+ const conn = a.connection_type || 'local';
127
+ console.log(` • ${a.name} (${conn})`);
128
+ }
129
+ } else {
130
+ console.log('✓ (none found)');
131
+ }
132
+ } catch (err) {
133
+ console.log('✗');
134
+ console.log(` Couldn't revoke other agents (${err.message}).`);
135
+ console.log(' Go to dash.troxy.io → API Keys to revoke them manually.\n');
136
+ }
137
+
138
+ // 4. Revoke THIS machine's API key (self-revoke). Done after revoke-all-others
139
+ // because self-revoke kills the key we're using to authenticate.
140
+ const prefix = apiKey.slice(0, 12) + '...';
141
+ process.stdout.write(` Revoking local API key ${prefix}... `);
118
142
  try {
119
- await api.selfRevoke(cfg.apiKey);
143
+ await api.selfRevoke(apiKey);
120
144
  console.log('✓');
121
145
  } catch (err) {
122
146
  console.log('✗');
123
147
  console.log(` Couldn't revoke automatically (${err.message}).`);
124
- console.log(' Go to dash.troxy.io → Settings → API Keys to revoke it.\n');
148
+ console.log(' Go to dash.troxy.io → API Keys to revoke it.\n');
125
149
  }
126
150
  }
127
151
 
128
- // 4. Delete ~/.troxy config
152
+ // 5. Delete ~/.troxy config
129
153
  process.stdout.write(' Removing config (~/.troxy)... ');
130
154
  const configDir = path.join(os.homedir(), '.troxy');
131
155
  if (fs.existsSync(configDir)) {
@@ -135,7 +159,7 @@ export async function runUninstall() {
135
159
  console.log('not found');
136
160
  }
137
161
 
138
- // 5. Remove npm package
162
+ // 6. Remove npm package
139
163
  process.stdout.write(' Uninstalling troxy CLI... ');
140
164
  try {
141
165
  execSync('npm uninstall -g troxy-cli 2>/dev/null || npm uninstall -g troxy 2>/dev/null', { stdio: 'pipe' });
@@ -144,5 +168,5 @@ export async function runUninstall() {
144
168
  console.log('skipped (run manually: sudo npm uninstall -g troxy-cli)');
145
169
  }
146
170
 
147
- console.log('\n Troxy removed. Your payments are no longer protected by Troxy.\n');
171
+ console.log('\n Troxy removed. All agent keys revoked. Your AI agents are no longer protected by Troxy.\n');
148
172
  }