troxy-cli 1.6.0 → 1.7.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/bin/troxy.js +7 -0
- package/package.json +1 -1
- package/src/daemon.js +33 -0
- package/src/init.js +3 -3
package/bin/troxy.js
CHANGED
|
@@ -147,6 +147,13 @@ switch (command) {
|
|
|
147
147
|
await runMcp();
|
|
148
148
|
break;
|
|
149
149
|
|
|
150
|
+
// ── Heartbeat daemon (background service) ─────────────────────
|
|
151
|
+
case 'daemon': {
|
|
152
|
+
const { runDaemon } = await import('../src/daemon.js');
|
|
153
|
+
await runDaemon();
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
|
|
150
157
|
// ── Pause / resume payment evaluations ───────────────────────
|
|
151
158
|
case 'pause':
|
|
152
159
|
await runPause();
|
package/package.json
CHANGED
package/src/daemon.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Troxy heartbeat daemon.
|
|
3
|
+
* Runs as a background service (systemd / launchd). Sends a heartbeat to the
|
|
4
|
+
* Troxy API every 60 seconds so the dashboard shows this agent as connected.
|
|
5
|
+
* Does NOT start an MCP stdio server — that only makes sense when an MCP client
|
|
6
|
+
* (Claude Desktop, Cursor, etc.) is present.
|
|
7
|
+
*/
|
|
8
|
+
import { loadConfig } from './config.js';
|
|
9
|
+
import * as api from './api.js';
|
|
10
|
+
|
|
11
|
+
const INTERVAL_MS = 60_000;
|
|
12
|
+
|
|
13
|
+
export async function runDaemon() {
|
|
14
|
+
const cfg = loadConfig();
|
|
15
|
+
if (!cfg?.apiKey) {
|
|
16
|
+
process.stderr.write('[troxy-daemon] No API key found. Run troxy init first.\n');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const { apiKey, agentName } = cfg;
|
|
21
|
+
|
|
22
|
+
const beat = () =>
|
|
23
|
+
api.mcpHeartbeat(apiKey, agentName)
|
|
24
|
+
.then(() => process.stderr.write(`[troxy-daemon] heartbeat ok\n`))
|
|
25
|
+
.catch(err => process.stderr.write(`[troxy-daemon] heartbeat failed: ${err.message}\n`));
|
|
26
|
+
|
|
27
|
+
process.stderr.write(`[troxy-daemon] starting (agent: ${agentName || 'unnamed'})\n`);
|
|
28
|
+
await beat();
|
|
29
|
+
setInterval(beat, INTERVAL_MS);
|
|
30
|
+
|
|
31
|
+
// Keep process alive indefinitely
|
|
32
|
+
process.stdin.resume();
|
|
33
|
+
}
|
package/src/init.js
CHANGED
|
@@ -154,7 +154,7 @@ export async function runInit({ key } = {}) {
|
|
|
154
154
|
console.log(' Background service installed ✓');
|
|
155
155
|
} catch (err) {
|
|
156
156
|
console.log(` Background service ✗ (${err.message})`);
|
|
157
|
-
console.log(' You can start it manually with: troxy
|
|
157
|
+
console.log(' You can start it manually with: troxy daemon &');
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
console.log('\n Your payments are now protected.');
|
|
@@ -179,7 +179,7 @@ Description=Troxy MCP Server
|
|
|
179
179
|
After=network.target
|
|
180
180
|
|
|
181
181
|
[Service]
|
|
182
|
-
ExecStart=${troxy}
|
|
182
|
+
ExecStart=${troxy} daemon
|
|
183
183
|
Restart=always
|
|
184
184
|
RestartSec=10
|
|
185
185
|
User=${os.userInfo().username}
|
|
@@ -205,7 +205,7 @@ WantedBy=multi-user.target
|
|
|
205
205
|
<key>ProgramArguments</key>
|
|
206
206
|
<array>
|
|
207
207
|
<string>${troxy}</string>
|
|
208
|
-
<string>
|
|
208
|
+
<string>daemon</string>
|
|
209
209
|
</array>
|
|
210
210
|
<key>EnvironmentVariables</key>
|
|
211
211
|
<dict>
|