agent-relay 2.0.4 → 2.0.6
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/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/app/onboarding.html +1 -1
- package/dist/dashboard/out/app/onboarding.txt +1 -1
- package/dist/dashboard/out/app.html +1 -1
- package/dist/dashboard/out/app.txt +1 -1
- package/dist/dashboard/out/cloud/link.html +1 -1
- package/dist/dashboard/out/cloud/link.txt +1 -1
- package/dist/dashboard/out/connect-repos.html +1 -1
- package/dist/dashboard/out/connect-repos.txt +1 -1
- package/dist/dashboard/out/history.html +1 -1
- package/dist/dashboard/out/history.txt +1 -1
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +1 -1
- package/dist/dashboard/out/login.html +1 -1
- package/dist/dashboard/out/login.txt +1 -1
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +1 -1
- package/dist/dashboard/out/pricing.html +1 -1
- package/dist/dashboard/out/pricing.txt +1 -1
- package/dist/dashboard/out/providers/setup/claude.html +1 -1
- package/dist/dashboard/out/providers/setup/claude.txt +1 -1
- package/dist/dashboard/out/providers/setup/codex.html +1 -1
- package/dist/dashboard/out/providers/setup/codex.txt +1 -1
- package/dist/dashboard/out/providers/setup/cursor.html +1 -1
- package/dist/dashboard/out/providers/setup/cursor.txt +1 -1
- package/dist/dashboard/out/providers.html +1 -1
- package/dist/dashboard/out/providers.txt +1 -1
- package/dist/dashboard/out/signup.html +1 -1
- package/dist/dashboard/out/signup.txt +1 -1
- package/dist/src/cli/index.js +61 -3
- package/package.json +14 -12
- package/packages/api-types/package.json +1 -1
- package/packages/bridge/dist/spawner.d.ts +2 -0
- package/packages/bridge/dist/spawner.js +24 -6
- package/packages/bridge/dist/types.d.ts +2 -0
- package/packages/bridge/package.json +7 -7
- package/packages/cloud/package.json +6 -6
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +1 -1
- package/packages/daemon/dist/router.d.ts +2 -1
- package/packages/daemon/dist/router.js +142 -52
- package/packages/daemon/dist/server.d.ts +3 -0
- package/packages/daemon/dist/server.js +31 -1
- package/packages/daemon/dist/spawn-manager.d.ts +5 -0
- package/packages/daemon/dist/spawn-manager.js +44 -1
- package/packages/daemon/package.json +12 -11
- package/packages/dashboard/dist/server.js +2 -0
- package/packages/dashboard/package.json +12 -12
- package/packages/dashboard/ui-dist/404.html +1 -1
- package/packages/dashboard/ui-dist/app/onboarding.html +1 -1
- package/packages/dashboard/ui-dist/app/onboarding.txt +1 -1
- package/packages/dashboard/ui-dist/app.html +1 -1
- package/packages/dashboard/ui-dist/app.txt +1 -1
- package/packages/dashboard/ui-dist/cloud/link.html +1 -1
- package/packages/dashboard/ui-dist/cloud/link.txt +1 -1
- package/packages/dashboard/ui-dist/connect-repos.html +1 -1
- package/packages/dashboard/ui-dist/connect-repos.txt +1 -1
- package/packages/dashboard/ui-dist/history.html +1 -1
- package/packages/dashboard/ui-dist/history.txt +1 -1
- package/packages/dashboard/ui-dist/index.html +1 -1
- package/packages/dashboard/ui-dist/index.txt +1 -1
- package/packages/dashboard/ui-dist/login.html +1 -1
- package/packages/dashboard/ui-dist/login.txt +1 -1
- package/packages/dashboard/ui-dist/metrics.html +1 -1
- package/packages/dashboard/ui-dist/metrics.txt +1 -1
- package/packages/dashboard/ui-dist/pricing.html +1 -1
- package/packages/dashboard/ui-dist/pricing.txt +1 -1
- package/packages/dashboard/ui-dist/providers/setup/claude.html +1 -1
- package/packages/dashboard/ui-dist/providers/setup/claude.txt +1 -1
- package/packages/dashboard/ui-dist/providers/setup/codex.html +1 -1
- package/packages/dashboard/ui-dist/providers/setup/codex.txt +1 -1
- package/packages/dashboard/ui-dist/providers/setup/cursor.html +1 -1
- package/packages/dashboard/ui-dist/providers/setup/cursor.txt +1 -1
- package/packages/dashboard/ui-dist/providers.html +1 -1
- package/packages/dashboard/ui-dist/providers.txt +1 -1
- package/packages/dashboard/ui-dist/signup.html +1 -1
- package/packages/dashboard/ui-dist/signup.txt +1 -1
- package/packages/dashboard-server/dist/server.js +2 -0
- package/packages/dashboard-server/dist/user-bridge.d.ts +7 -3
- package/packages/dashboard-server/dist/user-bridge.js +48 -30
- package/packages/dashboard-server/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/README.md +19 -135
- package/packages/mcp/dist/client.js +67 -27
- package/packages/mcp/dist/cloud.js +1 -18
- package/packages/mcp/dist/prompts/protocol.d.ts +1 -1
- package/packages/mcp/dist/prompts/protocol.js +6 -14
- package/packages/mcp/package.json +2 -1
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/dist/types.d.ts +2 -0
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/README.md +43 -160
- package/packages/sdk/dist/client.d.ts +3 -99
- package/packages/sdk/dist/client.js +6 -113
- package/packages/sdk/dist/index.d.ts +0 -1
- package/packages/sdk/dist/index.js +0 -2
- package/packages/sdk/dist/standalone.js +0 -1
- package/packages/sdk/package.json +2 -2
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/package.json +2 -2
- package/packages/telemetry/dist/client.d.ts +19 -0
- package/packages/telemetry/dist/client.js +126 -0
- package/packages/telemetry/dist/config.d.ts +29 -0
- package/packages/telemetry/dist/config.js +88 -0
- package/packages/telemetry/dist/events.d.ts +106 -0
- package/packages/telemetry/dist/events.js +10 -0
- package/packages/telemetry/dist/index.d.ts +8 -0
- package/packages/telemetry/dist/index.js +7 -0
- package/packages/telemetry/dist/machine-id.d.ts +12 -0
- package/packages/telemetry/dist/machine-id.js +58 -0
- package/packages/telemetry/dist/posthog-config.d.ts +16 -0
- package/packages/telemetry/dist/posthog-config.js +33 -0
- package/packages/telemetry/package.json +41 -0
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +1 -1
- package/packages/wrapper/dist/relay-pty-orchestrator.js +38 -29
- package/packages/wrapper/package.json +6 -6
- package/packages/sdk/dist/discovery.d.ts +0 -29
- package/packages/sdk/dist/discovery.js +0 -126
- /package/dist/dashboard/out/_next/static/{72btMIJ64BCAB4UgVkpaq → lIJs7zSKBaI58kpqegulQ}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{72btMIJ64BCAB4UgVkpaq → lIJs7zSKBaI58kpqegulQ}/_ssgManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{0AsOfRemPXJmtynCKT-rx → KIxE0Ds_zdGuDJDQu7_sb}/_buildManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{0AsOfRemPXJmtynCKT-rx → KIxE0Ds_zdGuDJDQu7_sb}/_ssgManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{72btMIJ64BCAB4UgVkpaq → SoK46dEi3IsNBVWXD9x0L}/_buildManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{72btMIJ64BCAB4UgVkpaq → SoK46dEi3IsNBVWXD9x0L}/_ssgManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{clUN2n0bz9HCjKI0qlOxU → lIJs7zSKBaI58kpqegulQ}/_buildManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{clUN2n0bz9HCjKI0qlOxU → lIJs7zSKBaI58kpqegulQ}/_ssgManifest.js +0 -0
|
@@ -6,19 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import net from 'node:net';
|
|
8
8
|
import { randomUUID } from 'node:crypto';
|
|
9
|
-
import { getDefaultSocketPath } from './discovery.js';
|
|
10
9
|
import { PROTOCOL_VERSION, } from './protocol/types.js';
|
|
11
10
|
import { encodeFrameLegacy, FrameParser } from './protocol/framing.js';
|
|
12
|
-
|
|
13
|
-
let _discoveredSocketPath = null;
|
|
14
|
-
function getDiscoveredSocketPath() {
|
|
15
|
-
if (_discoveredSocketPath === null) {
|
|
16
|
-
_discoveredSocketPath = getDefaultSocketPath();
|
|
17
|
-
}
|
|
18
|
-
return _discoveredSocketPath;
|
|
19
|
-
}
|
|
11
|
+
const DEFAULT_SOCKET_PATH = '/tmp/agent-relay.sock';
|
|
20
12
|
const DEFAULT_CLIENT_CONFIG = {
|
|
21
|
-
socketPath:
|
|
13
|
+
socketPath: DEFAULT_SOCKET_PATH,
|
|
22
14
|
agentName: 'agent',
|
|
23
15
|
cli: undefined,
|
|
24
16
|
quiet: false,
|
|
@@ -64,39 +56,7 @@ class CircularDedupeCache {
|
|
|
64
56
|
}
|
|
65
57
|
}
|
|
66
58
|
/**
|
|
67
|
-
* RelayClient
|
|
68
|
-
*
|
|
69
|
-
* The client automatically discovers the daemon socket path. You only need to provide
|
|
70
|
-
* your agent name. Use `connect()` to establish a connection, then send/receive messages.
|
|
71
|
-
*
|
|
72
|
-
* @example Basic Usage
|
|
73
|
-
* ```typescript
|
|
74
|
-
* import { RelayClient } from '@agent-relay/sdk';
|
|
75
|
-
*
|
|
76
|
-
* const client = new RelayClient({ agentName: 'MyAgent' });
|
|
77
|
-
* await client.connect();
|
|
78
|
-
*
|
|
79
|
-
* // Send messages
|
|
80
|
-
* client.sendMessage('OtherAgent', 'Hello!');
|
|
81
|
-
* client.sendMessage('#general', 'Channel message');
|
|
82
|
-
* client.sendMessage('*', 'Broadcast');
|
|
83
|
-
*
|
|
84
|
-
* // Receive messages
|
|
85
|
-
* client.onMessage = (from, payload) => {
|
|
86
|
-
* console.log(`${from}: ${payload.body}`);
|
|
87
|
-
* };
|
|
88
|
-
*
|
|
89
|
-
* // Disconnect when done
|
|
90
|
-
* client.disconnect();
|
|
91
|
-
* ```
|
|
92
|
-
*
|
|
93
|
-
* @example Wait for Response
|
|
94
|
-
* ```typescript
|
|
95
|
-
* const response = await client.sendAndWait('Worker', 'Do this task', {
|
|
96
|
-
* timeoutMs: 30000,
|
|
97
|
-
* });
|
|
98
|
-
* console.log(`Worker replied: ${response.content}`);
|
|
99
|
-
* ```
|
|
59
|
+
* RelayClient for agent-to-agent communication.
|
|
100
60
|
*/
|
|
101
61
|
export class RelayClient {
|
|
102
62
|
config;
|
|
@@ -113,39 +73,16 @@ export class RelayClient {
|
|
|
113
73
|
writeQueue = [];
|
|
114
74
|
writeScheduled = false;
|
|
115
75
|
pendingSyncAcks = new Map();
|
|
116
|
-
|
|
117
|
-
* Callback for receiving direct messages.
|
|
118
|
-
* @param from - Name of the sending agent
|
|
119
|
-
* @param payload - Message payload containing body, kind, and optional data
|
|
120
|
-
* @param messageId - Unique message identifier
|
|
121
|
-
* @param meta - Optional metadata (sync info, etc.)
|
|
122
|
-
* @param originalTo - Original recipient (useful for detecting broadcasts when originalTo='*')
|
|
123
|
-
*/
|
|
76
|
+
// Event handlers
|
|
124
77
|
onMessage;
|
|
125
78
|
/**
|
|
126
79
|
* Callback for channel messages.
|
|
127
|
-
* @param from - Name of the sending agent
|
|
128
|
-
* @param channel - Channel name (e.g., '#general')
|
|
129
|
-
* @param body - Message body text
|
|
130
|
-
* @param envelope - Full message envelope with metadata
|
|
131
80
|
*/
|
|
132
81
|
onChannelMessage;
|
|
133
|
-
/**
|
|
134
|
-
* Callback for connection state changes.
|
|
135
|
-
* @param state - New connection state: 'DISCONNECTED' | 'CONNECTING' | 'HANDSHAKING' | 'READY' | 'BACKOFF'
|
|
136
|
-
*/
|
|
137
82
|
onStateChange;
|
|
138
|
-
/**
|
|
139
|
-
* Callback for errors.
|
|
140
|
-
* @param error - The error that occurred
|
|
141
|
-
*/
|
|
142
83
|
onError;
|
|
143
84
|
constructor(config = {}) {
|
|
144
85
|
this.config = { ...DEFAULT_CLIENT_CONFIG, ...config };
|
|
145
|
-
// Use discovered socket path if not explicitly provided
|
|
146
|
-
if (!this.config.socketPath) {
|
|
147
|
-
this.config.socketPath = getDiscoveredSocketPath();
|
|
148
|
-
}
|
|
149
86
|
this.parser = new FrameParser();
|
|
150
87
|
this.parser.setLegacyMode(true);
|
|
151
88
|
this.reconnectDelay = this.config.reconnectDelayMs;
|
|
@@ -240,30 +177,7 @@ export class RelayClient {
|
|
|
240
177
|
this.disconnect();
|
|
241
178
|
}
|
|
242
179
|
/**
|
|
243
|
-
* Send a message to another agent
|
|
244
|
-
*
|
|
245
|
-
* @param to - Recipient: agent name, '#channel', or '*' for broadcast
|
|
246
|
-
* @param body - Message content
|
|
247
|
-
* @param kind - Message type (default: 'message')
|
|
248
|
-
* @param data - Optional structured data to include
|
|
249
|
-
* @param thread - Optional thread ID for conversation threading
|
|
250
|
-
* @param meta - Optional metadata (sync info, etc.)
|
|
251
|
-
* @returns true if message was queued, false if not connected
|
|
252
|
-
*
|
|
253
|
-
* @example
|
|
254
|
-
* ```typescript
|
|
255
|
-
* // Direct message
|
|
256
|
-
* client.sendMessage('Worker1', 'Start the task');
|
|
257
|
-
*
|
|
258
|
-
* // Channel message
|
|
259
|
-
* client.sendMessage('#general', 'Team update');
|
|
260
|
-
*
|
|
261
|
-
* // Broadcast to all agents
|
|
262
|
-
* client.sendMessage('*', 'System announcement');
|
|
263
|
-
*
|
|
264
|
-
* // With structured data
|
|
265
|
-
* client.sendMessage('Worker1', 'Process this', 'task', { priority: 'high' });
|
|
266
|
-
* ```
|
|
180
|
+
* Send a message to another agent.
|
|
267
181
|
*/
|
|
268
182
|
sendMessage(to, body, kind = 'message', data, thread, meta) {
|
|
269
183
|
if (this._state !== 'READY') {
|
|
@@ -302,28 +216,7 @@ export class RelayClient {
|
|
|
302
216
|
return this.send(envelope);
|
|
303
217
|
}
|
|
304
218
|
/**
|
|
305
|
-
* Send a message and wait for
|
|
306
|
-
*
|
|
307
|
-
* This is useful for request-response patterns where you need to wait for
|
|
308
|
-
* the recipient to process your message and reply.
|
|
309
|
-
*
|
|
310
|
-
* @param to - Recipient agent name
|
|
311
|
-
* @param body - Message content
|
|
312
|
-
* @param options - Options including timeout, thread, etc.
|
|
313
|
-
* @returns Promise that resolves with the ACK payload when recipient responds
|
|
314
|
-
* @throws Error if client not ready or timeout exceeded
|
|
315
|
-
*
|
|
316
|
-
* @example
|
|
317
|
-
* ```typescript
|
|
318
|
-
* try {
|
|
319
|
-
* const response = await client.sendAndWait('Worker', 'Process this task', {
|
|
320
|
-
* timeoutMs: 30000, // 30 second timeout
|
|
321
|
-
* });
|
|
322
|
-
* console.log('Worker responded:', response);
|
|
323
|
-
* } catch (err) {
|
|
324
|
-
* console.error('Worker did not respond in time');
|
|
325
|
-
* }
|
|
326
|
-
* ```
|
|
219
|
+
* Send a message and wait for ACK response.
|
|
327
220
|
*/
|
|
328
221
|
async sendAndWait(to, body, options = {}) {
|
|
329
222
|
if (this._state !== 'READY') {
|
|
@@ -29,5 +29,4 @@ export { RelayClient, type ClientState, type ClientConfig, type SyncOptions, } f
|
|
|
29
29
|
export { createRelay, createPair, type Relay, type RelayConfig, } from './standalone.js';
|
|
30
30
|
export { PROTOCOL_VERSION, type MessageType, type PayloadKind, type Envelope, type EntityType, type SendPayload, type SendMeta, type SyncMeta, type DeliveryInfo, type AckPayload, type ErrorCode, type ErrorPayload, type SpeakOnTrigger, type ShadowConfig, type SpawnPayload, type SpawnResultPayload, type ReleasePayload, type ReleaseResultPayload, type ChannelMessagePayload, type ChannelJoinPayload, type ChannelLeavePayload, } from './protocol/index.js';
|
|
31
31
|
export { encodeFrame, encodeFrameLegacy, FrameParser, MAX_FRAME_BYTES, } from './protocol/index.js';
|
|
32
|
-
export { discoverSocket, getDefaultSocketPath, type DiscoveryResult, } from './discovery.js';
|
|
33
32
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -33,6 +33,4 @@ export { createRelay, createPair, } from './standalone.js';
|
|
|
33
33
|
export { PROTOCOL_VERSION, } from './protocol/index.js';
|
|
34
34
|
// Framing utilities
|
|
35
35
|
export { encodeFrame, encodeFrameLegacy, FrameParser, MAX_FRAME_BYTES, } from './protocol/index.js';
|
|
36
|
-
// Socket discovery utilities
|
|
37
|
-
export { discoverSocket, getDefaultSocketPath, } from './discovery.js';
|
|
38
36
|
//# sourceMappingURL=index.js.map
|
|
@@ -52,7 +52,6 @@ export async function createRelay(config = {}) {
|
|
|
52
52
|
// Lazy-load daemon to keep SDK lightweight for client-only users
|
|
53
53
|
let Daemon;
|
|
54
54
|
try {
|
|
55
|
-
// @ts-ignore - daemon is an optional peer dependency, may not be installed
|
|
56
55
|
const daemonModule = await import('@agent-relay/daemon');
|
|
57
56
|
Daemon = daemonModule.Daemon;
|
|
58
57
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "Lightweight SDK for agent-to-agent communication via Agent Relay",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"access": "public"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@agent-relay/protocol": "2.0.
|
|
58
|
+
"@agent-relay/protocol": "2.0.6"
|
|
59
59
|
},
|
|
60
60
|
"engines": {
|
|
61
61
|
"node": ">=18.0.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/storage",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "Storage adapters and interfaces for Relay message/session persistence",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@agent-relay/protocol": "2.0.
|
|
59
|
+
"@agent-relay/protocol": "2.0.6"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/node": "^22.19.3",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostHog telemetry client singleton.
|
|
3
|
+
*/
|
|
4
|
+
import { getAnonymousId } from './config.js';
|
|
5
|
+
import type { TelemetryEventName, TelemetryEventMap } from './events.js';
|
|
6
|
+
export declare function initTelemetry(options?: {
|
|
7
|
+
showNotice?: boolean;
|
|
8
|
+
}): void;
|
|
9
|
+
export declare function track<E extends TelemetryEventName>(event: E, properties?: TelemetryEventMap[E]): void;
|
|
10
|
+
export declare function shutdown(): Promise<void>;
|
|
11
|
+
export declare function isEnabled(): boolean;
|
|
12
|
+
export { getAnonymousId };
|
|
13
|
+
export declare function getStatus(): {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
disabledByEnv: boolean;
|
|
16
|
+
anonymousId: string;
|
|
17
|
+
notifiedAt: string | undefined;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostHog telemetry client singleton.
|
|
3
|
+
*/
|
|
4
|
+
import { PostHog } from 'posthog-node';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import { isTelemetryEnabled, getAnonymousId, wasNotified, markNotified, isDisabledByEnv, loadPrefs, } from './config.js';
|
|
10
|
+
import { getPostHogConfig } from './posthog-config.js';
|
|
11
|
+
let client = null;
|
|
12
|
+
let commonProps = null;
|
|
13
|
+
let anonymousId = null;
|
|
14
|
+
let initialized = false;
|
|
15
|
+
function findPackageJson(startDir) {
|
|
16
|
+
let dir = startDir;
|
|
17
|
+
while (dir !== path.dirname(dir)) {
|
|
18
|
+
const candidate = path.join(dir, 'package.json');
|
|
19
|
+
if (fs.existsSync(candidate)) {
|
|
20
|
+
return candidate;
|
|
21
|
+
}
|
|
22
|
+
dir = path.dirname(dir);
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function getVersion() {
|
|
27
|
+
try {
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
const __dirname = path.dirname(__filename);
|
|
30
|
+
const packageJsonPath = findPackageJson(__dirname);
|
|
31
|
+
if (packageJsonPath) {
|
|
32
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
33
|
+
return pkg.version || 'unknown';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Fall through
|
|
38
|
+
}
|
|
39
|
+
return 'unknown';
|
|
40
|
+
}
|
|
41
|
+
function buildCommonProperties() {
|
|
42
|
+
return {
|
|
43
|
+
agent_relay_version: getVersion(),
|
|
44
|
+
os: process.platform,
|
|
45
|
+
os_version: os.release(),
|
|
46
|
+
node_version: process.version.slice(1),
|
|
47
|
+
arch: process.arch,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function showFirstRunNotice() {
|
|
51
|
+
if (wasNotified())
|
|
52
|
+
return;
|
|
53
|
+
if (isDisabledByEnv()) {
|
|
54
|
+
markNotified();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log('');
|
|
58
|
+
console.log('Agent Relay collects anonymous usage data to improve the product.');
|
|
59
|
+
console.log('Run `agent-relay telemetry disable` to opt out.');
|
|
60
|
+
console.log('Learn more: https://agent-relay.com/telemetry');
|
|
61
|
+
console.log('');
|
|
62
|
+
markNotified();
|
|
63
|
+
}
|
|
64
|
+
export function initTelemetry(options = {}) {
|
|
65
|
+
if (initialized)
|
|
66
|
+
return;
|
|
67
|
+
initialized = true;
|
|
68
|
+
if (options.showNotice !== false) {
|
|
69
|
+
showFirstRunNotice();
|
|
70
|
+
}
|
|
71
|
+
if (!isTelemetryEnabled())
|
|
72
|
+
return;
|
|
73
|
+
const posthogConfig = getPostHogConfig();
|
|
74
|
+
if (!posthogConfig)
|
|
75
|
+
return;
|
|
76
|
+
client = new PostHog(posthogConfig.apiKey, {
|
|
77
|
+
host: posthogConfig.host,
|
|
78
|
+
flushAt: 10,
|
|
79
|
+
flushInterval: 10000,
|
|
80
|
+
disableGeoip: false, // CLI runs on user's machine, so IP is correct for geo
|
|
81
|
+
});
|
|
82
|
+
commonProps = buildCommonProperties();
|
|
83
|
+
anonymousId = getAnonymousId();
|
|
84
|
+
}
|
|
85
|
+
export function track(event, properties) {
|
|
86
|
+
if (!client || !commonProps || !anonymousId)
|
|
87
|
+
return;
|
|
88
|
+
client.capture({
|
|
89
|
+
distinctId: anonymousId,
|
|
90
|
+
event,
|
|
91
|
+
properties: {
|
|
92
|
+
...commonProps,
|
|
93
|
+
...properties,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
export async function shutdown() {
|
|
98
|
+
if (!client)
|
|
99
|
+
return;
|
|
100
|
+
try {
|
|
101
|
+
await client.shutdown();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Ignore
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
client = null;
|
|
108
|
+
commonProps = null;
|
|
109
|
+
anonymousId = null;
|
|
110
|
+
initialized = false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function isEnabled() {
|
|
114
|
+
return isTelemetryEnabled();
|
|
115
|
+
}
|
|
116
|
+
export { getAnonymousId };
|
|
117
|
+
export function getStatus() {
|
|
118
|
+
const prefs = loadPrefs();
|
|
119
|
+
return {
|
|
120
|
+
enabled: isTelemetryEnabled(),
|
|
121
|
+
disabledByEnv: isDisabledByEnv(),
|
|
122
|
+
anonymousId: prefs.anonymousId,
|
|
123
|
+
notifiedAt: prefs.notifiedAt,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry preference storage (~/.agent-relay/telemetry.json)
|
|
3
|
+
*/
|
|
4
|
+
export interface TelemetryPrefs {
|
|
5
|
+
/** Whether telemetry is enabled (default: true) */
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
/** ISO timestamp when user was shown the first-run notice */
|
|
8
|
+
notifiedAt?: string;
|
|
9
|
+
/** Anonymous ID derived from machine-id hash */
|
|
10
|
+
anonymousId: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function getPrefsPath(): string;
|
|
13
|
+
export declare function loadPrefs(): TelemetryPrefs;
|
|
14
|
+
export declare function savePrefs(prefs: TelemetryPrefs): void;
|
|
15
|
+
export declare function isDisabledByEnv(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Check if telemetry is enabled.
|
|
18
|
+
* Order of precedence:
|
|
19
|
+
* 1. AGENT_RELAY_TELEMETRY_DISABLED=1 -> disabled
|
|
20
|
+
* 2. ~/.agent-relay/telemetry.json -> use stored pref
|
|
21
|
+
* 3. Default -> enabled
|
|
22
|
+
*/
|
|
23
|
+
export declare function isTelemetryEnabled(): boolean;
|
|
24
|
+
export declare function enableTelemetry(): void;
|
|
25
|
+
export declare function disableTelemetry(): void;
|
|
26
|
+
export declare function markNotified(): void;
|
|
27
|
+
export declare function wasNotified(): boolean;
|
|
28
|
+
export declare function getAnonymousId(): string;
|
|
29
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry preference storage (~/.agent-relay/telemetry.json)
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import os from 'node:os';
|
|
7
|
+
import { createAnonymousId } from './machine-id.js';
|
|
8
|
+
export function getPrefsPath() {
|
|
9
|
+
const configDir = process.env.AGENT_RELAY_DATA_DIR ||
|
|
10
|
+
path.join(os.homedir(), '.agent-relay');
|
|
11
|
+
return path.join(configDir, 'telemetry.json');
|
|
12
|
+
}
|
|
13
|
+
export function loadPrefs() {
|
|
14
|
+
const prefsPath = getPrefsPath();
|
|
15
|
+
try {
|
|
16
|
+
if (fs.existsSync(prefsPath)) {
|
|
17
|
+
const content = fs.readFileSync(prefsPath, 'utf-8');
|
|
18
|
+
const prefs = JSON.parse(content);
|
|
19
|
+
if (!prefs.anonymousId) {
|
|
20
|
+
prefs.anonymousId = createAnonymousId();
|
|
21
|
+
savePrefs(prefs);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
enabled: prefs.enabled ?? true,
|
|
25
|
+
notifiedAt: prefs.notifiedAt,
|
|
26
|
+
anonymousId: prefs.anonymousId,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Fall through to defaults
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
enabled: true,
|
|
35
|
+
anonymousId: createAnonymousId(),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function savePrefs(prefs) {
|
|
39
|
+
const prefsPath = getPrefsPath();
|
|
40
|
+
const configDir = path.dirname(prefsPath);
|
|
41
|
+
try {
|
|
42
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
43
|
+
fs.writeFileSync(prefsPath, JSON.stringify(prefs, null, 2), 'utf-8');
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
// Silently fail - telemetry shouldn't break the app
|
|
47
|
+
console.error('[telemetry] Failed to save preferences:', err);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function isDisabledByEnv() {
|
|
51
|
+
const envValue = process.env.AGENT_RELAY_TELEMETRY_DISABLED;
|
|
52
|
+
return envValue === '1' || envValue === 'true';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if telemetry is enabled.
|
|
56
|
+
* Order of precedence:
|
|
57
|
+
* 1. AGENT_RELAY_TELEMETRY_DISABLED=1 -> disabled
|
|
58
|
+
* 2. ~/.agent-relay/telemetry.json -> use stored pref
|
|
59
|
+
* 3. Default -> enabled
|
|
60
|
+
*/
|
|
61
|
+
export function isTelemetryEnabled() {
|
|
62
|
+
if (isDisabledByEnv()) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
return loadPrefs().enabled;
|
|
66
|
+
}
|
|
67
|
+
export function enableTelemetry() {
|
|
68
|
+
const prefs = loadPrefs();
|
|
69
|
+
prefs.enabled = true;
|
|
70
|
+
savePrefs(prefs);
|
|
71
|
+
}
|
|
72
|
+
export function disableTelemetry() {
|
|
73
|
+
const prefs = loadPrefs();
|
|
74
|
+
prefs.enabled = false;
|
|
75
|
+
savePrefs(prefs);
|
|
76
|
+
}
|
|
77
|
+
export function markNotified() {
|
|
78
|
+
const prefs = loadPrefs();
|
|
79
|
+
prefs.notifiedAt = new Date().toISOString();
|
|
80
|
+
savePrefs(prefs);
|
|
81
|
+
}
|
|
82
|
+
export function wasNotified() {
|
|
83
|
+
return loadPrefs().notifiedAt !== undefined;
|
|
84
|
+
}
|
|
85
|
+
export function getAnonymousId() {
|
|
86
|
+
return loadPrefs().anonymousId;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-safe telemetry event definitions.
|
|
3
|
+
*
|
|
4
|
+
* Following PostHog naming best practices:
|
|
5
|
+
* - snake_case for events and properties
|
|
6
|
+
* - Present tense verbs (spawn, not spawned)
|
|
7
|
+
* - object_action pattern
|
|
8
|
+
*/
|
|
9
|
+
/** Source of spawn/release action */
|
|
10
|
+
export type ActionSource = 'human_cli' | 'human_dashboard' | 'agent' | 'protocol';
|
|
11
|
+
/** Reason for agent release */
|
|
12
|
+
export type ReleaseReason = 'explicit' | 'crash' | 'timeout' | 'shutdown';
|
|
13
|
+
/**
|
|
14
|
+
* Common properties attached to every event.
|
|
15
|
+
*/
|
|
16
|
+
export interface CommonProperties {
|
|
17
|
+
/** Agent Relay version */
|
|
18
|
+
agent_relay_version: string;
|
|
19
|
+
/** Operating system (e.g., darwin, linux, win32) */
|
|
20
|
+
os: string;
|
|
21
|
+
/** OS release version */
|
|
22
|
+
os_version: string;
|
|
23
|
+
/** Node.js version (without 'v' prefix) */
|
|
24
|
+
node_version: string;
|
|
25
|
+
/** CPU architecture (e.g., arm64, x64) */
|
|
26
|
+
arch: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* daemon_start - Emitted when the daemon starts.
|
|
30
|
+
* No additional properties beyond common props.
|
|
31
|
+
*/
|
|
32
|
+
export interface DaemonStartEvent {
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* daemon_stop - Emitted when the daemon stops.
|
|
36
|
+
*/
|
|
37
|
+
export interface DaemonStopEvent {
|
|
38
|
+
/** How long the daemon was running, in seconds */
|
|
39
|
+
uptime_seconds: number;
|
|
40
|
+
/** Total agents spawned during this session */
|
|
41
|
+
agent_spawn_count: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* agent_spawn - Emitted when an agent is created.
|
|
45
|
+
*/
|
|
46
|
+
export interface AgentSpawnEvent {
|
|
47
|
+
/** CLI type (claude, codex, gemini, etc.) */
|
|
48
|
+
cli: string;
|
|
49
|
+
/** Where the spawn originated */
|
|
50
|
+
spawn_source: ActionSource;
|
|
51
|
+
/** Whether a task was provided */
|
|
52
|
+
has_task: boolean;
|
|
53
|
+
/** Whether this is a shadow agent */
|
|
54
|
+
is_shadow: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* agent_release - Emitted when an agent is stopped.
|
|
58
|
+
*/
|
|
59
|
+
export interface AgentReleaseEvent {
|
|
60
|
+
/** CLI type (claude, codex, gemini, etc.) */
|
|
61
|
+
cli: string;
|
|
62
|
+
/** Why the agent was released */
|
|
63
|
+
release_reason: ReleaseReason;
|
|
64
|
+
/** How long the agent was alive, in seconds */
|
|
65
|
+
lifetime_seconds: number;
|
|
66
|
+
/** Where the release originated */
|
|
67
|
+
release_source: ActionSource;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* agent_crash - Emitted when an agent dies unexpectedly.
|
|
71
|
+
*/
|
|
72
|
+
export interface AgentCrashEvent {
|
|
73
|
+
/** CLI type (claude, codex, gemini, etc.) */
|
|
74
|
+
cli: string;
|
|
75
|
+
/** How long the agent was alive, in seconds */
|
|
76
|
+
lifetime_seconds: number;
|
|
77
|
+
/** Exit code if available */
|
|
78
|
+
exit_code?: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* message_send - Emitted when an agent sends a relay message.
|
|
82
|
+
*/
|
|
83
|
+
export interface MessageSendEvent {
|
|
84
|
+
/** Whether this was a broadcast message */
|
|
85
|
+
is_broadcast: boolean;
|
|
86
|
+
/** Whether this message is part of a thread */
|
|
87
|
+
has_thread: boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* cli_command_run - Emitted when a CLI command is executed.
|
|
91
|
+
*/
|
|
92
|
+
export interface CliCommandRunEvent {
|
|
93
|
+
/** Name of the command (e.g., 'up', 'spawn', 'who') */
|
|
94
|
+
command_name: string;
|
|
95
|
+
}
|
|
96
|
+
export type TelemetryEventName = 'daemon_start' | 'daemon_stop' | 'agent_spawn' | 'agent_release' | 'agent_crash' | 'message_send' | 'cli_command_run';
|
|
97
|
+
export interface TelemetryEventMap {
|
|
98
|
+
daemon_start: DaemonStartEvent;
|
|
99
|
+
daemon_stop: DaemonStopEvent;
|
|
100
|
+
agent_spawn: AgentSpawnEvent;
|
|
101
|
+
agent_release: AgentReleaseEvent;
|
|
102
|
+
agent_crash: AgentCrashEvent;
|
|
103
|
+
message_send: MessageSendEvent;
|
|
104
|
+
cli_command_run: CliCommandRunEvent;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-safe telemetry event definitions.
|
|
3
|
+
*
|
|
4
|
+
* Following PostHog naming best practices:
|
|
5
|
+
* - snake_case for events and properties
|
|
6
|
+
* - Present tense verbs (spawn, not spawned)
|
|
7
|
+
* - object_action pattern
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agent-relay/telemetry - Anonymous usage analytics (opt-out via env or CLI)
|
|
3
|
+
*/
|
|
4
|
+
export { initTelemetry, track, shutdown, isEnabled, getAnonymousId, getStatus, } from './client.js';
|
|
5
|
+
export { isTelemetryEnabled, enableTelemetry, disableTelemetry, wasNotified, markNotified, loadPrefs, savePrefs, getPrefsPath, isDisabledByEnv, type TelemetryPrefs, } from './config.js';
|
|
6
|
+
export type { CommonProperties, ActionSource, ReleaseReason, DaemonStartEvent, DaemonStopEvent, AgentSpawnEvent, AgentReleaseEvent, AgentCrashEvent, MessageSendEvent, CliCommandRunEvent, TelemetryEventName, TelemetryEventMap, } from './events.js';
|
|
7
|
+
export { loadMachineId, createAnonymousId, getMachineIdPath, } from './machine-id.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agent-relay/telemetry - Anonymous usage analytics (opt-out via env or CLI)
|
|
3
|
+
*/
|
|
4
|
+
export { initTelemetry, track, shutdown, isEnabled, getAnonymousId, getStatus, } from './client.js';
|
|
5
|
+
export { isTelemetryEnabled, enableTelemetry, disableTelemetry, wasNotified, markNotified, loadPrefs, savePrefs, getPrefsPath, isDisabledByEnv, } from './config.js';
|
|
6
|
+
export { loadMachineId, createAnonymousId, getMachineIdPath, } from './machine-id.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine ID utilities for anonymous user identification.
|
|
3
|
+
* Uses existing machine-id file at ~/.local/share/agent-relay/machine-id
|
|
4
|
+
*/
|
|
5
|
+
export declare function getMachineIdPath(): string;
|
|
6
|
+
/**
|
|
7
|
+
* Load or generate machine ID using atomic file creation to avoid race conditions.
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadMachineId(): string;
|
|
10
|
+
/** SHA256 hash of machine ID, truncated to 16 chars */
|
|
11
|
+
export declare function createAnonymousId(): string;
|
|
12
|
+
//# sourceMappingURL=machine-id.d.ts.map
|