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.
Files changed (131) hide show
  1. package/dist/dashboard/out/404.html +1 -1
  2. package/dist/dashboard/out/app/onboarding.html +1 -1
  3. package/dist/dashboard/out/app/onboarding.txt +1 -1
  4. package/dist/dashboard/out/app.html +1 -1
  5. package/dist/dashboard/out/app.txt +1 -1
  6. package/dist/dashboard/out/cloud/link.html +1 -1
  7. package/dist/dashboard/out/cloud/link.txt +1 -1
  8. package/dist/dashboard/out/connect-repos.html +1 -1
  9. package/dist/dashboard/out/connect-repos.txt +1 -1
  10. package/dist/dashboard/out/history.html +1 -1
  11. package/dist/dashboard/out/history.txt +1 -1
  12. package/dist/dashboard/out/index.html +1 -1
  13. package/dist/dashboard/out/index.txt +1 -1
  14. package/dist/dashboard/out/login.html +1 -1
  15. package/dist/dashboard/out/login.txt +1 -1
  16. package/dist/dashboard/out/metrics.html +1 -1
  17. package/dist/dashboard/out/metrics.txt +1 -1
  18. package/dist/dashboard/out/pricing.html +1 -1
  19. package/dist/dashboard/out/pricing.txt +1 -1
  20. package/dist/dashboard/out/providers/setup/claude.html +1 -1
  21. package/dist/dashboard/out/providers/setup/claude.txt +1 -1
  22. package/dist/dashboard/out/providers/setup/codex.html +1 -1
  23. package/dist/dashboard/out/providers/setup/codex.txt +1 -1
  24. package/dist/dashboard/out/providers/setup/cursor.html +1 -1
  25. package/dist/dashboard/out/providers/setup/cursor.txt +1 -1
  26. package/dist/dashboard/out/providers.html +1 -1
  27. package/dist/dashboard/out/providers.txt +1 -1
  28. package/dist/dashboard/out/signup.html +1 -1
  29. package/dist/dashboard/out/signup.txt +1 -1
  30. package/dist/src/cli/index.js +61 -3
  31. package/package.json +14 -12
  32. package/packages/api-types/package.json +1 -1
  33. package/packages/bridge/dist/spawner.d.ts +2 -0
  34. package/packages/bridge/dist/spawner.js +24 -6
  35. package/packages/bridge/dist/types.d.ts +2 -0
  36. package/packages/bridge/package.json +7 -7
  37. package/packages/cloud/package.json +6 -6
  38. package/packages/config/package.json +2 -2
  39. package/packages/continuity/package.json +1 -1
  40. package/packages/daemon/dist/router.d.ts +2 -1
  41. package/packages/daemon/dist/router.js +142 -52
  42. package/packages/daemon/dist/server.d.ts +3 -0
  43. package/packages/daemon/dist/server.js +31 -1
  44. package/packages/daemon/dist/spawn-manager.d.ts +5 -0
  45. package/packages/daemon/dist/spawn-manager.js +44 -1
  46. package/packages/daemon/package.json +12 -11
  47. package/packages/dashboard/dist/server.js +2 -0
  48. package/packages/dashboard/package.json +12 -12
  49. package/packages/dashboard/ui-dist/404.html +1 -1
  50. package/packages/dashboard/ui-dist/app/onboarding.html +1 -1
  51. package/packages/dashboard/ui-dist/app/onboarding.txt +1 -1
  52. package/packages/dashboard/ui-dist/app.html +1 -1
  53. package/packages/dashboard/ui-dist/app.txt +1 -1
  54. package/packages/dashboard/ui-dist/cloud/link.html +1 -1
  55. package/packages/dashboard/ui-dist/cloud/link.txt +1 -1
  56. package/packages/dashboard/ui-dist/connect-repos.html +1 -1
  57. package/packages/dashboard/ui-dist/connect-repos.txt +1 -1
  58. package/packages/dashboard/ui-dist/history.html +1 -1
  59. package/packages/dashboard/ui-dist/history.txt +1 -1
  60. package/packages/dashboard/ui-dist/index.html +1 -1
  61. package/packages/dashboard/ui-dist/index.txt +1 -1
  62. package/packages/dashboard/ui-dist/login.html +1 -1
  63. package/packages/dashboard/ui-dist/login.txt +1 -1
  64. package/packages/dashboard/ui-dist/metrics.html +1 -1
  65. package/packages/dashboard/ui-dist/metrics.txt +1 -1
  66. package/packages/dashboard/ui-dist/pricing.html +1 -1
  67. package/packages/dashboard/ui-dist/pricing.txt +1 -1
  68. package/packages/dashboard/ui-dist/providers/setup/claude.html +1 -1
  69. package/packages/dashboard/ui-dist/providers/setup/claude.txt +1 -1
  70. package/packages/dashboard/ui-dist/providers/setup/codex.html +1 -1
  71. package/packages/dashboard/ui-dist/providers/setup/codex.txt +1 -1
  72. package/packages/dashboard/ui-dist/providers/setup/cursor.html +1 -1
  73. package/packages/dashboard/ui-dist/providers/setup/cursor.txt +1 -1
  74. package/packages/dashboard/ui-dist/providers.html +1 -1
  75. package/packages/dashboard/ui-dist/providers.txt +1 -1
  76. package/packages/dashboard/ui-dist/signup.html +1 -1
  77. package/packages/dashboard/ui-dist/signup.txt +1 -1
  78. package/packages/dashboard-server/dist/server.js +2 -0
  79. package/packages/dashboard-server/dist/user-bridge.d.ts +7 -3
  80. package/packages/dashboard-server/dist/user-bridge.js +48 -30
  81. package/packages/dashboard-server/package.json +12 -12
  82. package/packages/hooks/package.json +4 -4
  83. package/packages/mcp/README.md +19 -135
  84. package/packages/mcp/dist/client.js +67 -27
  85. package/packages/mcp/dist/cloud.js +1 -18
  86. package/packages/mcp/dist/prompts/protocol.d.ts +1 -1
  87. package/packages/mcp/dist/prompts/protocol.js +6 -14
  88. package/packages/mcp/package.json +2 -1
  89. package/packages/memory/package.json +2 -2
  90. package/packages/policy/package.json +2 -2
  91. package/packages/protocol/dist/types.d.ts +2 -0
  92. package/packages/protocol/package.json +1 -1
  93. package/packages/resiliency/package.json +1 -1
  94. package/packages/sdk/README.md +43 -160
  95. package/packages/sdk/dist/client.d.ts +3 -99
  96. package/packages/sdk/dist/client.js +6 -113
  97. package/packages/sdk/dist/index.d.ts +0 -1
  98. package/packages/sdk/dist/index.js +0 -2
  99. package/packages/sdk/dist/standalone.js +0 -1
  100. package/packages/sdk/package.json +2 -2
  101. package/packages/spawner/package.json +1 -1
  102. package/packages/state/package.json +1 -1
  103. package/packages/storage/package.json +2 -2
  104. package/packages/telemetry/dist/client.d.ts +19 -0
  105. package/packages/telemetry/dist/client.js +126 -0
  106. package/packages/telemetry/dist/config.d.ts +29 -0
  107. package/packages/telemetry/dist/config.js +88 -0
  108. package/packages/telemetry/dist/events.d.ts +106 -0
  109. package/packages/telemetry/dist/events.js +10 -0
  110. package/packages/telemetry/dist/index.d.ts +8 -0
  111. package/packages/telemetry/dist/index.js +7 -0
  112. package/packages/telemetry/dist/machine-id.d.ts +12 -0
  113. package/packages/telemetry/dist/machine-id.js +58 -0
  114. package/packages/telemetry/dist/posthog-config.d.ts +16 -0
  115. package/packages/telemetry/dist/posthog-config.js +33 -0
  116. package/packages/telemetry/package.json +41 -0
  117. package/packages/trajectory/package.json +2 -2
  118. package/packages/user-directory/package.json +2 -2
  119. package/packages/utils/package.json +1 -1
  120. package/packages/wrapper/dist/relay-pty-orchestrator.js +38 -29
  121. package/packages/wrapper/package.json +6 -6
  122. package/packages/sdk/dist/discovery.d.ts +0 -29
  123. package/packages/sdk/dist/discovery.js +0 -126
  124. /package/dist/dashboard/out/_next/static/{72btMIJ64BCAB4UgVkpaq → lIJs7zSKBaI58kpqegulQ}/_buildManifest.js +0 -0
  125. /package/dist/dashboard/out/_next/static/{72btMIJ64BCAB4UgVkpaq → lIJs7zSKBaI58kpqegulQ}/_ssgManifest.js +0 -0
  126. /package/packages/dashboard/ui-dist/_next/static/{0AsOfRemPXJmtynCKT-rx → KIxE0Ds_zdGuDJDQu7_sb}/_buildManifest.js +0 -0
  127. /package/packages/dashboard/ui-dist/_next/static/{0AsOfRemPXJmtynCKT-rx → KIxE0Ds_zdGuDJDQu7_sb}/_ssgManifest.js +0 -0
  128. /package/packages/dashboard/ui-dist/_next/static/{72btMIJ64BCAB4UgVkpaq → SoK46dEi3IsNBVWXD9x0L}/_buildManifest.js +0 -0
  129. /package/packages/dashboard/ui-dist/_next/static/{72btMIJ64BCAB4UgVkpaq → SoK46dEi3IsNBVWXD9x0L}/_ssgManifest.js +0 -0
  130. /package/packages/dashboard/ui-dist/_next/static/{clUN2n0bz9HCjKI0qlOxU → lIJs7zSKBaI58kpqegulQ}/_buildManifest.js +0 -0
  131. /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
- // Socket path is discovered lazily to allow environment to be set up first
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: '', // Will be set in constructor if not provided
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 - Agent-to-agent communication client for Agent Relay.
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, channel, or broadcast.
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 acknowledgment response.
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.4",
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.4"
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/spawner",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Agent spawning types and utilities for Agent Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/state",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Agent state persistence for non-hook CLIs (Codex, Gemini, etc.)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/storage",
3
- "version": "2.0.4",
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.4"
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