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
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Machine ID utilities for anonymous user identification.
3
+ * Uses existing machine-id file at ~/.local/share/agent-relay/machine-id
4
+ */
5
+ import { createHash, randomBytes } from 'node:crypto';
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import os from 'node:os';
9
+ export function getMachineIdPath() {
10
+ const dataDir = process.env.AGENT_RELAY_DATA_DIR ||
11
+ path.join(os.homedir(), '.local', 'share', 'agent-relay');
12
+ return path.join(dataDir, 'machine-id');
13
+ }
14
+ /**
15
+ * Load or generate machine ID using atomic file creation to avoid race conditions.
16
+ */
17
+ export function loadMachineId() {
18
+ const machineIdPath = getMachineIdPath();
19
+ try {
20
+ return fs.readFileSync(machineIdPath, 'utf-8').trim();
21
+ }
22
+ catch (readErr) {
23
+ if (readErr.code !== 'ENOENT') {
24
+ return `${os.hostname()}-${Date.now().toString(36)}`;
25
+ }
26
+ try {
27
+ const dataDir = path.dirname(machineIdPath);
28
+ fs.mkdirSync(dataDir, { recursive: true });
29
+ const machineId = `${os.hostname()}-${randomBytes(8).toString('hex')}`;
30
+ // O_CREAT | O_EXCL fails if file exists - prevents race condition
31
+ const fd = fs.openSync(machineIdPath, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY, 0o600);
32
+ fs.writeSync(fd, machineId);
33
+ fs.closeSync(fd);
34
+ return machineId;
35
+ }
36
+ catch (writeErr) {
37
+ // Another process created the file first
38
+ if (writeErr.code === 'EEXIST') {
39
+ try {
40
+ return fs.readFileSync(machineIdPath, 'utf-8').trim();
41
+ }
42
+ catch {
43
+ // Fall through
44
+ }
45
+ }
46
+ return `${os.hostname()}-${Date.now().toString(36)}`;
47
+ }
48
+ }
49
+ }
50
+ /** SHA256 hash of machine ID, truncated to 16 chars */
51
+ export function createAnonymousId() {
52
+ const machineId = loadMachineId();
53
+ return createHash('sha256')
54
+ .update(machineId)
55
+ .digest('hex')
56
+ .substring(0, 16);
57
+ }
58
+ //# sourceMappingURL=machine-id.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * PostHog configuration.
3
+ *
4
+ * Environment variables:
5
+ * POSTHOG_API_KEY - Override API key (any environment)
6
+ * POSTHOG_HOST - Override host URL
7
+ *
8
+ * Key selection:
9
+ * 1. POSTHOG_API_KEY (if set, always used)
10
+ * 3. PROD_API_KEY (fallback)
11
+ */
12
+ export declare function getPostHogConfig(): {
13
+ apiKey: string;
14
+ host: string;
15
+ } | null;
16
+ //# sourceMappingURL=posthog-config.d.ts.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * PostHog configuration.
3
+ *
4
+ * Environment variables:
5
+ * POSTHOG_API_KEY - Override API key (any environment)
6
+ * POSTHOG_HOST - Override host URL
7
+ *
8
+ * Key selection:
9
+ * 1. POSTHOG_API_KEY (if set, always used)
10
+ * 3. PROD_API_KEY (fallback)
11
+ */
12
+ // =============================================================================
13
+ // Configure your PostHog production key here
14
+ // =============================================================================
15
+ /** Production PostHog API key (write-only, safe for client-side) */
16
+ const PROD_API_KEY = 'phc_2uDu01GtnLABJpVkWw4ri1OgScLU90aEmXmDjufGdqr';
17
+ const HOST = 'https://us.i.posthog.com';
18
+ // =============================================================================
19
+ // Exports
20
+ // =============================================================================
21
+ export function getPostHogConfig() {
22
+ const host = process.env.POSTHOG_HOST || HOST;
23
+ // Explicit override for any environment
24
+ if (process.env.POSTHOG_API_KEY) {
25
+ return { apiKey: process.env.POSTHOG_API_KEY, host };
26
+ }
27
+ // Fallback to production key
28
+ if (!PROD_API_KEY) {
29
+ return null;
30
+ }
31
+ return { apiKey: PROD_API_KEY, host };
32
+ }
33
+ //# sourceMappingURL=posthog-config.js.map
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@agent-relay/telemetry",
3
+ "version": "2.0.6",
4
+ "description": "Anonymous telemetry for Agent Relay usage analytics",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "clean": "rm -rf dist",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest"
24
+ },
25
+ "dependencies": {
26
+ "posthog-node": "^4.0.1"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.19.3",
30
+ "typescript": "^5.9.3",
31
+ "vitest": "^3.0.0"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/AgentWorkforce/relay.git",
39
+ "directory": "packages/telemetry"
40
+ }
41
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/trajectory",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Trajectory integration utilities (trail/PDERO) for Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/config": "2.0.4"
25
+ "@agent-relay/config": "2.0.6"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.19.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/user-directory",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "User directory service for agent-relay (per-user credential storage)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/resiliency": "2.0.4"
25
+ "@agent-relay/resiliency": "2.0.6"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.19.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/utils",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Shared utilities for agent-relay: logging, name generation, command resolution, update checking",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -73,7 +73,7 @@ export class RelayPtyOrchestrator extends BaseWrapper {
73
73
  hasReceivedOutput = false;
74
74
  // Queue monitor for stuck message detection
75
75
  queueMonitorTimer;
76
- QUEUE_MONITOR_INTERVAL_MS = 30000; // Check every 30 seconds
76
+ QUEUE_MONITOR_INTERVAL_MS = 5000; // Check every 5 seconds
77
77
  injectionStartTime = 0; // Track when isInjecting was set to true
78
78
  MAX_INJECTION_STUCK_MS = 60000; // Force reset after 60 seconds
79
79
  // Protocol monitor for detecting agent mistakes (e.g., empty AGENT_RELAY_NAME)
@@ -93,6 +93,10 @@ export class RelayPtyOrchestrator extends BaseWrapper {
93
93
  constructor(config) {
94
94
  super(config);
95
95
  this.config = config;
96
+ // Validate agent name to prevent path traversal attacks
97
+ if (config.name.includes('..') || config.name.includes('/') || config.name.includes('\\')) {
98
+ throw new Error(`Invalid agent name: "${config.name}" contains path traversal characters`);
99
+ }
96
100
  // Get project paths (used for logs and local mode)
97
101
  const projectPaths = getProjectPaths(config.cwd);
98
102
  // Canonical outbox path - agents ALWAYS write here (transparent symlink in workspace mode)
@@ -141,8 +145,9 @@ export class RelayPtyOrchestrator extends BaseWrapper {
141
145
  localSocketPath = tmpSocketPath;
142
146
  }
143
147
  this.socketPath = localSocketPath;
144
- // No legacy path needed for local mode
145
- this._legacyOutboxPath = this._outboxPath;
148
+ // Legacy path for backwards compat (older agents might still use /tmp/relay-outbox)
149
+ // Even in local mode, we need this symlink for agents with stale instructions
150
+ this._legacyOutboxPath = `/tmp/relay-outbox/${config.name}`;
146
151
  }
147
152
  if (this.socketPath.length > MAX_SOCKET_PATH_LENGTH) {
148
153
  throw new Error(`Socket path exceeds ${MAX_SOCKET_PATH_LENGTH} chars: ${this.socketPath.length}`);
@@ -224,31 +229,31 @@ export class RelayPtyOrchestrator extends BaseWrapper {
224
229
  mkdirSync(this._outboxPath, { recursive: true });
225
230
  }
226
231
  this.log(` Created outbox directory: ${this._outboxPath}`);
227
- // In workspace mode, create symlinks so agents can use canonical path
228
- if (this._workspaceId) {
229
- // Helper to create a symlink, cleaning up existing path first
230
- const createSymlinkSafe = (linkPath, targetPath) => {
231
- const linkParent = dirname(linkPath);
232
- if (!existsSync(linkParent)) {
233
- mkdirSync(linkParent, { recursive: true });
234
- }
235
- if (existsSync(linkPath)) {
236
- try {
237
- const stats = lstatSync(linkPath);
238
- if (stats.isSymbolicLink() || stats.isFile()) {
239
- unlinkSync(linkPath);
240
- }
241
- else if (stats.isDirectory()) {
242
- rmSync(linkPath, { recursive: true, force: true });
243
- }
232
+ // Helper to create a symlink, cleaning up existing path first
233
+ const createSymlinkSafe = (linkPath, targetPath) => {
234
+ const linkParent = dirname(linkPath);
235
+ if (!existsSync(linkParent)) {
236
+ mkdirSync(linkParent, { recursive: true });
237
+ }
238
+ if (existsSync(linkPath)) {
239
+ try {
240
+ const stats = lstatSync(linkPath);
241
+ if (stats.isSymbolicLink() || stats.isFile()) {
242
+ unlinkSync(linkPath);
244
243
  }
245
- catch {
246
- // Ignore cleanup errors
244
+ else if (stats.isDirectory()) {
245
+ rmSync(linkPath, { recursive: true, force: true });
247
246
  }
248
247
  }
249
- symlinkSync(targetPath, linkPath);
250
- this.log(` Created symlink: ${linkPath} -> ${targetPath}`);
251
- };
248
+ catch {
249
+ // Ignore cleanup errors
250
+ }
251
+ }
252
+ symlinkSync(targetPath, linkPath);
253
+ this.log(` Created symlink: ${linkPath} -> ${targetPath}`);
254
+ };
255
+ // In workspace mode, create symlinks so agents can use canonical path
256
+ if (this._workspaceId) {
252
257
  // Symlink canonical path (~/.agent-relay/outbox/{name}) -> workspace path
253
258
  // This is the PRIMARY symlink - agents write to canonical path, relay-pty watches workspace path
254
259
  if (this._canonicalOutboxPath !== this._outboxPath) {
@@ -259,6 +264,10 @@ export class RelayPtyOrchestrator extends BaseWrapper {
259
264
  createSymlinkSafe(this._legacyOutboxPath, this._outboxPath);
260
265
  }
261
266
  }
267
+ // In local mode, also create legacy symlink for backwards compat with stale instructions
268
+ if (!this._workspaceId && this._legacyOutboxPath !== this._outboxPath) {
269
+ createSymlinkSafe(this._legacyOutboxPath, this._outboxPath);
270
+ }
262
271
  }
263
272
  catch (err) {
264
273
  this.logError(` Failed to set up outbox: ${err.message}`);
@@ -1485,10 +1494,10 @@ EOF
1485
1494
  \`\`\`
1486
1495
  Then output: \`->relay-file:spawn\`
1487
1496
 
1488
- **Protocol Tips:**
1489
- - Always ACK when you receive a task: "ACK: Brief description"
1490
- - Send DONE when complete: "DONE: What was accomplished"
1491
- - Keep your lead informed of progress
1497
+ **Message Format:**
1498
+ - \`TO: AgentName\` for direct messages
1499
+ - \`TO: *\` to broadcast to all agents
1500
+ - \`TO: #channel\` for channel messages
1492
1501
 
1493
1502
  📖 See **AGENTS.md** in the project root for full protocol documentation.`;
1494
1503
  this.log(` Sending periodic protocol reminder (session: ${sessionDurationMinutes}m)`);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/wrapper",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "CLI agent wrappers for Agent Relay - tmux, pty integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -30,11 +30,11 @@
30
30
  "clean": "rm -rf dist"
31
31
  },
32
32
  "dependencies": {
33
- "@agent-relay/api-types": "2.0.4",
34
- "@agent-relay/protocol": "2.0.4",
35
- "@agent-relay/config": "2.0.4",
36
- "@agent-relay/continuity": "2.0.4",
37
- "@agent-relay/resiliency": "2.0.4"
33
+ "@agent-relay/api-types": "2.0.6",
34
+ "@agent-relay/protocol": "2.0.6",
35
+ "@agent-relay/config": "2.0.6",
36
+ "@agent-relay/continuity": "2.0.6",
37
+ "@agent-relay/resiliency": "2.0.6"
38
38
  },
39
39
  "devDependencies": {
40
40
  "typescript": "^5.9.3",
@@ -1,29 +0,0 @@
1
- /**
2
- * Socket Discovery for Agent Relay SDK
3
- *
4
- * Discovers the daemon socket path for local development and cloud environments.
5
- */
6
- export interface DiscoveryResult {
7
- socketPath: string;
8
- projectId: string;
9
- source: 'env' | 'cloud' | 'project' | 'legacy';
10
- }
11
- /**
12
- * Discover the relay daemon socket path.
13
- *
14
- * Discovery order:
15
- * 1. RELAY_SOCKET environment variable (explicit override)
16
- * 2. Cloud workspace socket (if WORKSPACE_ID is set)
17
- * 3. Project-local socket ({projectRoot}/.agent-relay/relay.sock)
18
- * 4. Legacy fallback (/tmp/agent-relay.sock)
19
- *
20
- * @param cwd - Working directory to start search from (default: process.cwd())
21
- * @returns Discovery result with socket path and metadata
22
- */
23
- export declare function discoverSocket(cwd?: string): DiscoveryResult;
24
- /**
25
- * Get the default socket path using discovery.
26
- * Convenience function that returns just the path.
27
- */
28
- export declare function getDefaultSocketPath(cwd?: string): string;
29
- //# sourceMappingURL=discovery.d.ts.map
@@ -1,126 +0,0 @@
1
- /**
2
- * Socket Discovery for Agent Relay SDK
3
- *
4
- * Discovers the daemon socket path for local development and cloud environments.
5
- */
6
- import { existsSync, readFileSync } from 'node:fs';
7
- import { join } from 'node:path';
8
- import { homedir } from 'node:os';
9
- /**
10
- * Find project root by looking for common markers.
11
- * Scans up from startDir until it finds a marker or hits the filesystem root.
12
- */
13
- function findProjectRoot(startDir = process.cwd()) {
14
- let current = startDir;
15
- const markers = ['.git', 'package.json', 'Cargo.toml', 'go.mod', 'pyproject.toml', '.agent-relay'];
16
- // Limit iterations to prevent infinite loops
17
- for (let i = 0; i < 100; i++) {
18
- for (const marker of markers) {
19
- if (existsSync(join(current, marker))) {
20
- return current;
21
- }
22
- }
23
- const parent = join(current, '..');
24
- if (parent === current)
25
- break; // Reached root
26
- current = parent;
27
- }
28
- return null;
29
- }
30
- /**
31
- * Discover the relay daemon socket path.
32
- *
33
- * Discovery order:
34
- * 1. RELAY_SOCKET environment variable (explicit override)
35
- * 2. Cloud workspace socket (if WORKSPACE_ID is set)
36
- * 3. Project-local socket ({projectRoot}/.agent-relay/relay.sock)
37
- * 4. Legacy fallback (/tmp/agent-relay.sock)
38
- *
39
- * @param cwd - Working directory to start search from (default: process.cwd())
40
- * @returns Discovery result with socket path and metadata
41
- */
42
- export function discoverSocket(cwd) {
43
- const startDir = cwd || process.cwd();
44
- // 1. Explicit socket path from environment
45
- const socketEnv = process.env.RELAY_SOCKET;
46
- if (socketEnv && existsSync(socketEnv)) {
47
- return {
48
- socketPath: socketEnv,
49
- projectId: process.env.RELAY_PROJECT || 'env',
50
- source: 'env',
51
- };
52
- }
53
- // 2. Cloud workspace socket (if WORKSPACE_ID is set)
54
- const workspaceId = process.env.WORKSPACE_ID;
55
- if (workspaceId) {
56
- const cloudSocket = `/tmp/relay/${workspaceId}/sockets/daemon.sock`;
57
- if (existsSync(cloudSocket)) {
58
- return {
59
- socketPath: cloudSocket,
60
- projectId: workspaceId,
61
- source: 'cloud',
62
- };
63
- }
64
- }
65
- // 3. Project-local socket
66
- // First try cwd, then scan up to find project root
67
- const projectRoot = findProjectRoot(startDir);
68
- const searchDirs = [startDir];
69
- if (projectRoot && projectRoot !== startDir) {
70
- searchDirs.push(projectRoot);
71
- }
72
- for (const dir of searchDirs) {
73
- const projectLocalSocket = join(dir, '.agent-relay', 'relay.sock');
74
- if (existsSync(projectLocalSocket)) {
75
- // Read project ID from marker file if available
76
- let projectId = 'local';
77
- const markerPath = join(dir, '.agent-relay', '.project');
78
- if (existsSync(markerPath)) {
79
- try {
80
- const marker = JSON.parse(readFileSync(markerPath, 'utf-8'));
81
- projectId = marker.projectId || 'local';
82
- }
83
- catch {
84
- // Ignore marker read errors
85
- }
86
- }
87
- return {
88
- socketPath: projectLocalSocket,
89
- projectId,
90
- source: 'project',
91
- };
92
- }
93
- }
94
- // 4. Legacy fallback
95
- const legacySocket = '/tmp/agent-relay.sock';
96
- if (existsSync(legacySocket)) {
97
- return {
98
- socketPath: legacySocket,
99
- projectId: 'legacy',
100
- source: 'legacy',
101
- };
102
- }
103
- // Also check ~/.agent-relay for legacy global installations
104
- const homeSocket = join(homedir(), '.agent-relay', 'relay.sock');
105
- if (existsSync(homeSocket)) {
106
- return {
107
- socketPath: homeSocket,
108
- projectId: 'home',
109
- source: 'legacy',
110
- };
111
- }
112
- // Return legacy path even if it doesn't exist (will fail on connect)
113
- return {
114
- socketPath: legacySocket,
115
- projectId: 'unknown',
116
- source: 'legacy',
117
- };
118
- }
119
- /**
120
- * Get the default socket path using discovery.
121
- * Convenience function that returns just the path.
122
- */
123
- export function getDefaultSocketPath(cwd) {
124
- return discoverSocket(cwd).socketPath;
125
- }
126
- //# sourceMappingURL=discovery.js.map