troxy-cli 1.4.5 → 1.4.7
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/bin/troxy.js +57 -16
- package/package.json +1 -1
- package/src/activity.js +24 -4
- package/src/api.js +1 -6
- package/src/mcps.js +10 -0
- package/src/policies.js +14 -0
package/bin/troxy.js
CHANGED
|
@@ -61,22 +61,6 @@ switch (command) {
|
|
|
61
61
|
break;
|
|
62
62
|
|
|
63
63
|
// ── Auth ──────────────────────────────────────────────────────
|
|
64
|
-
case 'connect': {
|
|
65
|
-
const k = flags.key;
|
|
66
|
-
if (!k || !k.startsWith('txy-')) {
|
|
67
|
-
console.error('\n Usage: troxy connect --key txy-...\n');
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
// Validate key before saving
|
|
71
|
-
process.stdout.write('\n Validating key... ');
|
|
72
|
-
await api.agentStatus(k);
|
|
73
|
-
console.log('✓');
|
|
74
|
-
const { saveConfig } = await import('../src/config.js');
|
|
75
|
-
saveConfig({ apiKey: k });
|
|
76
|
-
console.log(' Key saved to ~/.troxy/config.json\n');
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
64
|
case 'login':
|
|
81
65
|
await runLogin(flags);
|
|
82
66
|
break;
|
|
@@ -87,6 +71,26 @@ switch (command) {
|
|
|
87
71
|
break;
|
|
88
72
|
|
|
89
73
|
case 'rotate-key': {
|
|
74
|
+
if (flags.help || flags.h) {
|
|
75
|
+
console.log(`
|
|
76
|
+
troxy rotate-key [options]
|
|
77
|
+
|
|
78
|
+
Creates a new MCP API key, saves it to ~/.troxy/config.json, and optionally
|
|
79
|
+
revokes the old key. Login required.
|
|
80
|
+
|
|
81
|
+
Options:
|
|
82
|
+
--name <name> Name for the new key (default: "Rotated key")
|
|
83
|
+
--revoke-old Revoke the old key immediately after creating the new one
|
|
84
|
+
|
|
85
|
+
Examples:
|
|
86
|
+
troxy rotate-key
|
|
87
|
+
troxy rotate-key --revoke-old
|
|
88
|
+
troxy rotate-key --name "My Agent Key" --revoke-old
|
|
89
|
+
|
|
90
|
+
After rotating: update TROXY_API_KEY in your MCP config and restart the MCP server.
|
|
91
|
+
`);
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
90
94
|
const jwt = requireJwt();
|
|
91
95
|
const { loadConfig, saveConfig } = await import('../src/config.js');
|
|
92
96
|
const oldKey = loadConfig()?.apiKey;
|
|
@@ -143,6 +147,28 @@ switch (command) {
|
|
|
143
147
|
|
|
144
148
|
// ── Simulate a payment evaluation ────────────────────────────
|
|
145
149
|
case 'pay': {
|
|
150
|
+
if (flags.help || flags.h) {
|
|
151
|
+
console.log(`
|
|
152
|
+
troxy pay --merchant <name> --amount <n> [options]
|
|
153
|
+
|
|
154
|
+
Simulates a payment evaluation request — identical to what your AI agent sends.
|
|
155
|
+
Use this to test your policies. Login required.
|
|
156
|
+
|
|
157
|
+
Required:
|
|
158
|
+
--merchant <name> Merchant name (e.g. "Amazon")
|
|
159
|
+
--amount <n> Payment amount in USD
|
|
160
|
+
|
|
161
|
+
Optional:
|
|
162
|
+
--card <alias> Card alias (default: "Work")
|
|
163
|
+
--category <cat> Merchant category (e.g. travel, software, food)
|
|
164
|
+
|
|
165
|
+
Examples:
|
|
166
|
+
troxy pay --merchant "Amazon" --amount 50
|
|
167
|
+
troxy pay --merchant "Amazon" --amount 350 --card "Work"
|
|
168
|
+
troxy pay --merchant "Delta" --amount 250 --card "Work" --category travel
|
|
169
|
+
`);
|
|
170
|
+
process.exit(0);
|
|
171
|
+
}
|
|
146
172
|
requireJwt();
|
|
147
173
|
const apiKey = loadConfig()?.apiKey || process.env.TROXY_API_KEY;
|
|
148
174
|
if (!apiKey) { console.error(' No API key. Run: troxy init --key txy-...\n'); process.exit(1); }
|
|
@@ -179,6 +205,21 @@ switch (command) {
|
|
|
179
205
|
break;
|
|
180
206
|
|
|
181
207
|
case 'insights': {
|
|
208
|
+
if (flags.help || flags.h) {
|
|
209
|
+
console.log(`
|
|
210
|
+
troxy insights [options]
|
|
211
|
+
|
|
212
|
+
Shows a spending and decision summary for a given period. Login required.
|
|
213
|
+
|
|
214
|
+
Options:
|
|
215
|
+
--period <days> Number of days to look back (default: 30)
|
|
216
|
+
|
|
217
|
+
Examples:
|
|
218
|
+
troxy insights
|
|
219
|
+
troxy insights --period 7
|
|
220
|
+
`);
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
182
223
|
const jwt = requireJwt();
|
|
183
224
|
const period = Number(flags.period || 30);
|
|
184
225
|
const data = await api.agentInsights(jwt, period);
|
package/package.json
CHANGED
package/src/activity.js
CHANGED
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
import { api } from './api.js';
|
|
2
2
|
import { requireJwt } from './auth.js';
|
|
3
|
+
import { loadConfig } from './config.js';
|
|
3
4
|
import { table } from './print.js';
|
|
4
5
|
|
|
5
6
|
const ICON = { ALLOW: '✓', BLOCK: '✗', ESCALATE: '⏳', NOTIFY: '~' };
|
|
6
7
|
|
|
7
8
|
export async function runActivity(flags) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
if (flags.help || flags.h) {
|
|
10
|
+
console.log(`
|
|
11
|
+
troxy activity [options]
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
Shows recent payment decisions across all your MCPs. Login required.
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
--limit <n> Number of rows to show (default: 20, max: 200)
|
|
17
|
+
--mine Show only decisions from this machine's MCP
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
troxy activity
|
|
21
|
+
troxy activity --limit 50
|
|
22
|
+
troxy activity --mine
|
|
23
|
+
`);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const jwt = requireJwt();
|
|
28
|
+
const limit = Number(flags.limit || 20);
|
|
29
|
+
const mine = !!flags.mine;
|
|
30
|
+
const tokenPrefix = mine ? (loadConfig()?.apiKey || '').substring(0, 11) : undefined;
|
|
31
|
+
|
|
32
|
+
const data = await api.agentActivity(jwt, limit, mine, tokenPrefix);
|
|
13
33
|
const rows = data?.activity || [];
|
|
14
34
|
|
|
15
35
|
if (!rows.length) { console.log('\n No activity yet.\n'); return; }
|
package/src/api.js
CHANGED
|
@@ -66,17 +66,12 @@ export const api = {
|
|
|
66
66
|
resumeToken: (jwt, id) => request('POST', `/tokens/${id}/resume`, { jwt }),
|
|
67
67
|
renameToken: (jwt, id, name) => request('PATCH', `/tokens/${id}/name`, { jwt, body: { name } }),
|
|
68
68
|
|
|
69
|
-
// MCP daemon endpoints (agent API key — used by MCP server only)
|
|
70
|
-
mcpPause: (apiKey) => request('POST', '/mcp/pause', { apiKey }),
|
|
71
|
-
mcpResume: (apiKey) => request('POST', '/mcp/resume', { apiKey }),
|
|
72
|
-
mcpRename: (apiKey, name) => request('PATCH', '/mcp/name', { apiKey, body: { name } }),
|
|
73
|
-
|
|
74
69
|
// Agent read-only API (JWT session auth — run: troxy login)
|
|
75
70
|
agentStatus: (jwt) => request('GET', '/agent/status', { jwt }),
|
|
76
71
|
agentPolicies: (jwt) => request('GET', '/agent/policies', { jwt }),
|
|
77
72
|
agentMcps: (jwt) => request('GET', '/agent/mcps', { jwt }),
|
|
78
73
|
agentCards: (jwt) => request('GET', '/agent/cards', { jwt }),
|
|
79
|
-
agentActivity: (jwt, limit, mine) => request('GET', `/agent/activity?limit=${limit || 20}${mine ?
|
|
74
|
+
agentActivity: (jwt, limit, mine, tokenPrefix) => request('GET', `/agent/activity?limit=${limit || 20}${mine ? `&mine=true&token_prefix=${encodeURIComponent(tokenPrefix || '')}` : ''}`, { jwt }),
|
|
80
75
|
agentInsights: (jwt, period) => request('GET', `/agent/insights?period=${period || 30}`, { jwt }),
|
|
81
76
|
};
|
|
82
77
|
|
package/src/mcps.js
CHANGED
|
@@ -3,7 +3,17 @@ import { loadConfig, saveConfig } from './config.js';
|
|
|
3
3
|
import { requireJwt } from './auth.js';
|
|
4
4
|
import { table } from './print.js';
|
|
5
5
|
|
|
6
|
+
const HELP = {
|
|
7
|
+
list: ` troxy mcps list\n\n Lists all MCP connections on your account — name, prefix, status, last seen,\n policies assigned, default action, and which one is this machine.\n`,
|
|
8
|
+
rename: ` troxy mcps rename --name <new-name>\n\n Renames this machine's MCP. The new name appears in the dashboard immediately.\n\n Options:\n --name New name for this machine's MCP\n\n Example:\n troxy mcps rename --name "My Laptop"\n`,
|
|
9
|
+
};
|
|
10
|
+
|
|
6
11
|
export async function runMcps([sub], flags) {
|
|
12
|
+
if (flags.help || flags.h) {
|
|
13
|
+
console.log('\n' + (HELP[sub] || ` troxy mcps <subcommand> [options]\n\n Subcommands:\n list List all MCP connections\n rename Rename this machine's MCP\n\n Run 'troxy mcps <subcommand> --help' for subcommand help.\n`));
|
|
14
|
+
process.exit(0);
|
|
15
|
+
}
|
|
16
|
+
|
|
7
17
|
switch (sub || 'list') {
|
|
8
18
|
case 'list': {
|
|
9
19
|
const jwt = requireJwt();
|
package/src/policies.js
CHANGED
|
@@ -10,7 +10,21 @@ function _scope(p) {
|
|
|
10
10
|
return 'no MCPs applied';
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
const HELP = {
|
|
14
|
+
list: ` troxy policies list\n\n Lists all policies in your account with their action, scope, status, and conditions.\n`,
|
|
15
|
+
describe: ` troxy policies describe --name <policy-name>\n\n Shows full details for a single policy.\n\n Options:\n --name Name of the policy (use single quotes for names with special chars)\n`,
|
|
16
|
+
create: ` troxy policies create --name <name> --action <action> [options]\n\n Creates a new policy. Login required.\n\n Required:\n --name Policy name\n --action ALLOW, BLOCK, NOTIFY, or ESCALATE\n\n Optional conditions:\n --field Field to match: amount, merchant_name, merchant_category,\n merchant_country, currency, agent_name, hour, day_of_week\n --operator eq, neq, gt, gte, lt, lte, contains, between\n --value Comparison value (e.g. 500, amazon, Monday)\n --value2 Upper bound for 'between' operator\n\n Scope:\n --mcp <name> Scope policy to a specific MCP only (default: all MCPs)\n Run 'troxy mcps list' to see MCP names.\n\n Examples:\n troxy policies create --name "Block large" --action BLOCK --field amount --operator gte --value 500\n troxy policies create --name "Block Amazon" --action BLOCK --field merchant_name --operator contains --value amazon\n troxy policies create --name "Cap spend" --action BLOCK --mcp "My Laptop" --field amount --operator gte --value 200\n`,
|
|
17
|
+
enable: ` troxy policies enable --name <policy-name>\n\n Enables a disabled policy.\n\n Options:\n --name Name of the policy to enable\n`,
|
|
18
|
+
disable: ` troxy policies disable --name <policy-name>\n\n Disables a policy without deleting it.\n\n Options:\n --name Name of the policy to disable\n`,
|
|
19
|
+
delete: ` troxy policies delete --name <policy-name>\n\n Permanently deletes a policy.\n\n Options:\n --name Name of the policy to delete\n`,
|
|
20
|
+
};
|
|
21
|
+
|
|
13
22
|
export async function runPolicies([sub, ...args], flags) {
|
|
23
|
+
if (flags.help || flags.h) {
|
|
24
|
+
console.log('\n' + (HELP[sub] || ` troxy policies <subcommand> [options]\n\n Subcommands:\n list List all policies\n describe Show details for a policy\n create Create a new policy\n enable Enable a policy\n disable Disable a policy\n delete Delete a policy\n\n Run 'troxy policies <subcommand> --help' for subcommand help.\n`));
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
14
28
|
// Read-only subcommands work with a login session
|
|
15
29
|
const readOnly = !sub || sub === 'list' || sub === 'describe';
|
|
16
30
|
|