agent-relay 2.0.24 → 2.0.26

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 (60) hide show
  1. package/dist/src/cli/index.js +100 -10
  2. package/package.json +16 -16
  3. package/packages/api-types/package.json +1 -1
  4. package/packages/bridge/package.json +8 -8
  5. package/packages/cli-tester/package.json +1 -1
  6. package/packages/config/package.json +2 -2
  7. package/packages/continuity/package.json +1 -1
  8. package/packages/daemon/dist/consensus-integration.d.ts +2 -1
  9. package/packages/daemon/dist/consensus.d.ts +1 -3
  10. package/packages/daemon/dist/enhanced-features.d.ts +2 -1
  11. package/packages/daemon/dist/orchestrator.js +4 -3
  12. package/packages/daemon/dist/server.js +48 -0
  13. package/packages/daemon/package.json +12 -12
  14. package/packages/hooks/dist/inbox-check/types.d.ts +6 -1
  15. package/packages/hooks/dist/inbox-check/utils.d.ts +3 -3
  16. package/packages/hooks/package.json +4 -4
  17. package/packages/mcp/dist/client.d.ts +57 -46
  18. package/packages/mcp/dist/client.js +107 -81
  19. package/packages/mcp/dist/server.js +61 -1
  20. package/packages/mcp/dist/tools/index.d.ts +5 -0
  21. package/packages/mcp/dist/tools/index.js +5 -0
  22. package/packages/mcp/dist/tools/relay-broadcast.d.ts +20 -0
  23. package/packages/mcp/dist/tools/relay-broadcast.js +25 -0
  24. package/packages/mcp/dist/tools/relay-channel.d.ts +49 -0
  25. package/packages/mcp/dist/tools/relay-channel.js +76 -0
  26. package/packages/mcp/dist/tools/relay-consensus.d.ts +45 -0
  27. package/packages/mcp/dist/tools/relay-consensus.js +80 -0
  28. package/packages/mcp/dist/tools/relay-inbox.d.ts +1 -1
  29. package/packages/mcp/dist/tools/relay-send.d.ts +2 -2
  30. package/packages/mcp/dist/tools/relay-shadow.d.ts +30 -0
  31. package/packages/mcp/dist/tools/relay-shadow.js +55 -0
  32. package/packages/mcp/dist/tools/relay-subscribe.d.ts +27 -0
  33. package/packages/mcp/dist/tools/relay-subscribe.js +49 -0
  34. package/packages/mcp/package.json +3 -2
  35. package/packages/memory/package.json +2 -2
  36. package/packages/policy/package.json +2 -2
  37. package/packages/protocol/dist/types.d.ts +130 -2
  38. package/packages/protocol/package.json +1 -1
  39. package/packages/resiliency/package.json +1 -1
  40. package/packages/sdk/dist/client.d.ts +21 -1
  41. package/packages/sdk/dist/client.js +26 -2
  42. package/packages/sdk/dist/index.d.ts +1 -1
  43. package/packages/sdk/dist/protocol/index.d.ts +4 -2
  44. package/packages/sdk/dist/protocol/index.js +4 -2
  45. package/packages/sdk/package.json +2 -2
  46. package/packages/spawner/package.json +1 -1
  47. package/packages/state/package.json +1 -1
  48. package/packages/storage/package.json +2 -2
  49. package/packages/telemetry/package.json +1 -1
  50. package/packages/trajectory/package.json +2 -2
  51. package/packages/user-directory/package.json +2 -2
  52. package/packages/utils/package.json +1 -1
  53. package/packages/wrapper/package.json +6 -6
  54. package/scripts/post-publish-verify/README.md +80 -0
  55. package/scripts/post-publish-verify/run-verify.sh +127 -0
  56. package/scripts/post-publish-verify/verify-install.sh +249 -0
  57. package/packages/sdk/dist/protocol/framing.d.ts +0 -80
  58. package/packages/sdk/dist/protocol/framing.js +0 -206
  59. package/packages/sdk/dist/protocol/types.d.ts +0 -560
  60. package/packages/sdk/dist/protocol/types.js +0 -8
@@ -26,12 +26,12 @@ import fs from 'node:fs';
26
26
  import path from 'node:path';
27
27
  import readline from 'node:readline';
28
28
  import { promisify } from 'node:util';
29
- import { exec } from 'node:child_process';
29
+ import { exec, spawn as spawnProcess } from 'node:child_process';
30
30
  import { fileURLToPath } from 'node:url';
31
31
  const RELAY_DASHBOARD_REPO = 'https://github.com/AgentWorkforce/relay-dashboard';
32
32
  /**
33
33
  * Prompt user to choose how to handle missing dashboard package.
34
- * Returns: 'install' | 'skip'
34
+ * Returns: 'npx' | 'install' | 'skip'
35
35
  */
36
36
  async function promptDashboardInstall() {
37
37
  const rl = readline.createInterface({
@@ -42,14 +42,18 @@ async function promptDashboardInstall() {
42
42
  The web dashboard requires @agent-relay/dashboard-server package.
43
43
 
44
44
  How would you like to proceed?
45
- 1. View installation instructions
46
- 2. Skip and continue without dashboard
45
+ 1. Start with npx (recommended - auto-installs temporarily)
46
+ 2. View installation instructions
47
+ 3. Skip and continue without dashboard
47
48
  `);
48
49
  return new Promise((resolve) => {
49
- rl.question('Choose [1/2]: ', (answer) => {
50
+ rl.question('Choose [1/2/3]: ', (answer) => {
50
51
  rl.close();
51
52
  const choice = answer.trim();
52
53
  if (choice === '1') {
54
+ resolve('npx');
55
+ }
56
+ else if (choice === '2') {
53
57
  resolve('install');
54
58
  }
55
59
  else {
@@ -74,6 +78,53 @@ Then restart with:
74
78
  For more options, see: ${RELAY_DASHBOARD_REPO}
75
79
  `);
76
80
  }
81
+ /**
82
+ * Start dashboard via npx (downloads and runs if not installed).
83
+ * Returns the spawned child process and port.
84
+ */
85
+ function startDashboardViaNpx(options) {
86
+ console.log('Starting dashboard via npx (this may take a moment on first run)...');
87
+ const dashboardProcess = spawnProcess('npx', [
88
+ '--yes',
89
+ '@agent-relay/dashboard-server',
90
+ '--integrated',
91
+ '--port', String(options.port),
92
+ '--data-dir', options.dataDir,
93
+ '--team-dir', options.teamDir,
94
+ '--project-root', options.projectRoot,
95
+ ], {
96
+ stdio: ['ignore', 'pipe', 'pipe'],
97
+ env: {
98
+ ...process.env,
99
+ // Pass any additional env vars needed
100
+ },
101
+ });
102
+ // Forward dashboard output with prefix
103
+ dashboardProcess.stdout?.on('data', (data) => {
104
+ const lines = data.toString().split('\n').filter(Boolean);
105
+ for (const line of lines) {
106
+ // Don't duplicate the "Dashboard:" line
107
+ if (!line.includes('Dashboard:')) {
108
+ console.log(`[dashboard] ${line}`);
109
+ }
110
+ }
111
+ });
112
+ dashboardProcess.stderr?.on('data', (data) => {
113
+ const lines = data.toString().split('\n').filter(Boolean);
114
+ for (const line of lines) {
115
+ console.error(`[dashboard] ${line}`);
116
+ }
117
+ });
118
+ dashboardProcess.on('error', (err) => {
119
+ console.error('Failed to start dashboard via npx:', err.message);
120
+ });
121
+ dashboardProcess.on('exit', (code) => {
122
+ if (code !== 0 && code !== null) {
123
+ console.error(`Dashboard process exited with code ${code}`);
124
+ }
125
+ });
126
+ return { process: dashboardProcess, port: options.port };
127
+ }
77
128
  dotenvConfig();
78
129
  const DEFAULT_DASHBOARD_PORT = process.env.AGENT_RELAY_DASHBOARD_PORT || '3888';
79
130
  // Read version from package.json
@@ -524,15 +575,54 @@ program
524
575
  if (process.stdin.isTTY) {
525
576
  console.log('');
526
577
  const action = await promptDashboardInstall();
527
- if (action === 'install') {
578
+ if (action === 'npx') {
579
+ // Start dashboard via npx
580
+ const { process: dashboardProcess, port: npxPort } = startDashboardViaNpx({
581
+ port,
582
+ dataDir: paths.dataDir,
583
+ teamDir: paths.teamDir,
584
+ projectRoot: paths.projectRoot,
585
+ });
586
+ dashboardPort = npxPort;
587
+ // Clean up dashboard process on exit
588
+ const cleanupDashboard = () => {
589
+ if (dashboardProcess && !dashboardProcess.killed) {
590
+ dashboardProcess.kill('SIGTERM');
591
+ }
592
+ };
593
+ process.on('SIGINT', cleanupDashboard);
594
+ process.on('SIGTERM', cleanupDashboard);
595
+ process.on('exit', cleanupDashboard);
596
+ // Wait a moment for dashboard to start
597
+ await new Promise(resolve => setTimeout(resolve, 2000));
598
+ console.log(`Dashboard: http://localhost:${dashboardPort}`);
599
+ }
600
+ else if (action === 'install') {
528
601
  showDashboardInstallInstructions();
529
602
  }
530
603
  }
531
604
  else {
532
- // Non-interactive: just show instructions and exit with error
533
- console.error('Dashboard package not installed.');
534
- showDashboardInstallInstructions();
535
- process.exit(1);
605
+ // Non-interactive: try npx automatically
606
+ console.log('Dashboard package not installed. Starting via npx...');
607
+ const { process: dashboardProcess, port: npxPort } = startDashboardViaNpx({
608
+ port,
609
+ dataDir: paths.dataDir,
610
+ teamDir: paths.teamDir,
611
+ projectRoot: paths.projectRoot,
612
+ });
613
+ dashboardPort = npxPort;
614
+ // Clean up dashboard process on exit
615
+ const cleanupDashboard = () => {
616
+ if (dashboardProcess && !dashboardProcess.killed) {
617
+ dashboardProcess.kill('SIGTERM');
618
+ }
619
+ };
620
+ process.on('SIGINT', cleanupDashboard);
621
+ process.on('SIGTERM', cleanupDashboard);
622
+ process.on('exit', cleanupDashboard);
623
+ // Wait a moment for dashboard to start
624
+ await new Promise(resolve => setTimeout(resolve, 3000));
625
+ console.log(`Dashboard: http://localhost:${dashboardPort}`);
536
626
  }
537
627
  }
538
628
  // Silent if user didn't explicitly request dashboard
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-relay",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Real-time agent-to-agent communication system",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -87,21 +87,21 @@
87
87
  },
88
88
  "homepage": "https://github.com/AgentWorkforce/relay#readme",
89
89
  "dependencies": {
90
- "@agent-relay/bridge": "2.0.24",
91
- "@agent-relay/config": "2.0.24",
92
- "@agent-relay/continuity": "2.0.24",
93
- "@agent-relay/daemon": "2.0.24",
94
- "@agent-relay/hooks": "2.0.24",
95
- "@agent-relay/mcp": "2.0.24",
96
- "@agent-relay/protocol": "2.0.24",
97
- "@agent-relay/resiliency": "2.0.24",
98
- "@agent-relay/sdk": "2.0.24",
99
- "@agent-relay/storage": "2.0.24",
100
- "@agent-relay/telemetry": "2.0.24",
101
- "@agent-relay/trajectory": "2.0.24",
102
- "@agent-relay/user-directory": "2.0.24",
103
- "@agent-relay/utils": "2.0.24",
104
- "@agent-relay/wrapper": "2.0.24",
90
+ "@agent-relay/bridge": "2.0.26",
91
+ "@agent-relay/config": "2.0.26",
92
+ "@agent-relay/continuity": "2.0.26",
93
+ "@agent-relay/daemon": "2.0.26",
94
+ "@agent-relay/hooks": "2.0.26",
95
+ "@agent-relay/mcp": "2.0.26",
96
+ "@agent-relay/protocol": "2.0.26",
97
+ "@agent-relay/resiliency": "2.0.26",
98
+ "@agent-relay/sdk": "2.0.26",
99
+ "@agent-relay/storage": "2.0.26",
100
+ "@agent-relay/telemetry": "2.0.26",
101
+ "@agent-relay/trajectory": "2.0.26",
102
+ "@agent-relay/user-directory": "2.0.26",
103
+ "@agent-relay/utils": "2.0.26",
104
+ "@agent-relay/wrapper": "2.0.26",
105
105
  "agent-trajectories": "^0.2.3",
106
106
  "better-sqlite3": "^12.6.2",
107
107
  "chokidar": "^5.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/api-types",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Shared API types and Zod schemas for Agent Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/bridge",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Multi-project bridge client utilities for Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,13 +22,13 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/protocol": "2.0.24",
26
- "@agent-relay/config": "2.0.24",
27
- "@agent-relay/utils": "2.0.24",
28
- "@agent-relay/policy": "2.0.24",
29
- "@agent-relay/user-directory": "2.0.24",
30
- "@agent-relay/wrapper": "2.0.24",
31
- "@agent-relay/mcp": "2.0.24"
25
+ "@agent-relay/protocol": "2.0.26",
26
+ "@agent-relay/config": "2.0.26",
27
+ "@agent-relay/utils": "2.0.26",
28
+ "@agent-relay/policy": "2.0.26",
29
+ "@agent-relay/user-directory": "2.0.26",
30
+ "@agent-relay/wrapper": "2.0.26",
31
+ "@agent-relay/mcp": "2.0.26"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^22.19.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/cli-tester",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Manual interactive testing for CLI authentication flows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/config",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Shared configuration schemas and loaders for Agent Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -83,7 +83,7 @@
83
83
  "test:watch": "vitest"
84
84
  },
85
85
  "dependencies": {
86
- "@agent-relay/protocol": "2.0.24",
86
+ "@agent-relay/protocol": "2.0.26",
87
87
  "zod": "^3.23.8",
88
88
  "zod-to-json-schema": "^3.23.1"
89
89
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/continuity",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Session continuity manager for Relay (ledgers, handoffs, resume)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -27,7 +27,8 @@
27
27
  * consensus.processIncomingMessage(from, body);
28
28
  * ```
29
29
  */
30
- import { ConsensusEngine, createConsensusEngine, formatProposalMessage, formatResultMessage, parseVoteCommand, parseProposalCommand, isConsensusCommand, type Proposal, type ConsensusResult, type ConsensusConfig, type VoteValue, type ConsensusType, type ParsedProposalCommand } from './consensus.js';
30
+ import type { VoteValue, ConsensusType } from '@agent-relay/protocol';
31
+ import { ConsensusEngine, createConsensusEngine, formatProposalMessage, formatResultMessage, parseVoteCommand, parseProposalCommand, isConsensusCommand, type Proposal, type ConsensusResult, type ConsensusConfig, type ParsedProposalCommand } from './consensus.js';
31
32
  import type { Router } from './router.js';
32
33
  export interface CloudSyncConfig {
33
34
  /** Cloud API base URL (defaults to AGENT_RELAY_CLOUD_URL or https://agent-relay.com) */
@@ -18,9 +18,7 @@
18
18
  * - Task assignment (weighted by expertise)
19
19
  */
20
20
  import { EventEmitter } from 'node:events';
21
- export type ConsensusType = 'majority' | 'supermajority' | 'unanimous' | 'weighted' | 'quorum';
22
- export type VoteValue = 'approve' | 'reject' | 'abstain';
23
- export type ProposalStatus = 'pending' | 'approved' | 'rejected' | 'expired' | 'cancelled';
21
+ import type { ConsensusType, VoteValue, ProposalStatus } from '@agent-relay/protocol';
24
22
  export interface AgentWeight {
25
23
  /** Agent name */
26
24
  agent: string;
@@ -17,7 +17,8 @@ import { getCompiledPatterns, isInstructionalTextFast, isPlaceholderTargetFast,
17
17
  import { AgentSigningManager, loadSigningConfig, attachSignature, extractSignature, type AgentSigningConfig, type SignedMessage } from './agent-signing.js';
18
18
  import { SQLiteDLQAdapter, PostgresDLQAdapter, InMemoryDLQAdapter, createDLQAdapter, DEFAULT_DLQ_CONFIG, type DLQStorageAdapter, type DLQConfig, type DeadLetter, type DLQStats } from '@agent-relay/storage/dlq-adapter';
19
19
  import { ContextCompactor, createContextCompactor, estimateTokens, estimateContextTokens, formatTokenCount, type Message, type CompactionConfig, type CompactionResult } from '@agent-relay/memory';
20
- import { ConsensusEngine, createConsensusEngine, formatProposalMessage, parseVoteCommand, formatResultMessage, type Proposal, type ConsensusResult, type ConsensusConfig, type VoteValue } from './consensus.js';
20
+ import type { VoteValue } from '@agent-relay/protocol';
21
+ import { ConsensusEngine, createConsensusEngine, formatProposalMessage, parseVoteCommand, formatResultMessage, type Proposal, type ConsensusResult, type ConsensusConfig } from './consensus.js';
21
22
  export interface EnhancedFeaturesConfig {
22
23
  /** Pattern matching configuration */
23
24
  patterns?: {
@@ -21,7 +21,7 @@ function generateId() {
21
21
  }
22
22
  /**
23
23
  * Determine the default host binding.
24
- * - In cloud environments (Fly.io, Docker with WORKSPACE_ID), bind to 0.0.0.0 for external access
24
+ * - In cloud environments, bind to '::' for IPv6+IPv4 dual-stack (required for Fly.io 6PN)
25
25
  * - Locally, bind to localhost for security
26
26
  * - Can be overridden with AGENT_RELAY_API_HOST env var
27
27
  */
@@ -30,12 +30,13 @@ function getDefaultHost() {
30
30
  if (process.env.AGENT_RELAY_API_HOST) {
31
31
  return process.env.AGENT_RELAY_API_HOST;
32
32
  }
33
- // Cloud environment detection - bind to all interfaces for load balancer access
33
+ // Cloud environment detection - bind to :: for IPv6 + IPv4 dual-stack
34
+ // Fly.io internal network uses IPv6 (fdaa:...), so 0.0.0.0 won't work
34
35
  const isCloudEnvironment = process.env.FLY_APP_NAME || // Fly.io
35
36
  process.env.WORKSPACE_ID || // Agent Relay workspace
36
37
  process.env.RELAY_WORKSPACE_ID || // Alternative workspace ID
37
38
  process.env.RUNNING_IN_DOCKER === 'true'; // Docker container
38
- return isCloudEnvironment ? '0.0.0.0' : 'localhost';
39
+ return isCloudEnvironment ? '::' : 'localhost';
39
40
  }
40
41
  const DEFAULT_CONFIG = {
41
42
  port: 3456,
@@ -1169,6 +1169,54 @@ export class Daemon {
1169
1169
  });
1170
1170
  break;
1171
1171
  }
1172
+ case 'MESSAGES_QUERY': {
1173
+ // Query all messages (used by dashboard) - not filtered by recipient
1174
+ const queryPayload = envelope.payload;
1175
+ const getMessages = async () => {
1176
+ if (!this.storage?.getMessages) {
1177
+ return [];
1178
+ }
1179
+ try {
1180
+ const messages = await this.storage.getMessages({
1181
+ limit: queryPayload.limit || 100,
1182
+ sinceTs: queryPayload.sinceTs,
1183
+ from: queryPayload.from,
1184
+ to: queryPayload.to,
1185
+ thread: queryPayload.thread,
1186
+ order: queryPayload.order || 'desc',
1187
+ });
1188
+ return messages.map(m => ({
1189
+ id: m.id,
1190
+ from: m.from,
1191
+ to: m.to,
1192
+ body: m.body,
1193
+ channel: m.data?.channel,
1194
+ thread: m.thread,
1195
+ timestamp: m.ts,
1196
+ status: m.status,
1197
+ isBroadcast: m.is_broadcast,
1198
+ replyCount: m.replyCount,
1199
+ data: m.data,
1200
+ }));
1201
+ }
1202
+ catch {
1203
+ return [];
1204
+ }
1205
+ };
1206
+ getMessages().then(messages => {
1207
+ const response = {
1208
+ v: PROTOCOL_VERSION,
1209
+ type: 'MESSAGES_RESPONSE',
1210
+ id: envelope.id,
1211
+ ts: Date.now(),
1212
+ payload: { messages },
1213
+ };
1214
+ connection.send(response);
1215
+ }).catch(err => {
1216
+ this.sendErrorEnvelope(connection, `Failed to get messages: ${err.message}`);
1217
+ });
1218
+ break;
1219
+ }
1172
1220
  case 'LIST_AGENTS': {
1173
1221
  const listPayload = envelope.payload;
1174
1222
  // Get connected agents from router
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/daemon",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Relay daemon server - agent coordination and message routing",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,17 +22,17 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/protocol": "2.0.24",
26
- "@agent-relay/config": "2.0.24",
27
- "@agent-relay/storage": "2.0.24",
28
- "@agent-relay/bridge": "2.0.24",
29
- "@agent-relay/utils": "2.0.24",
30
- "@agent-relay/policy": "2.0.24",
31
- "@agent-relay/memory": "2.0.24",
32
- "@agent-relay/resiliency": "2.0.24",
33
- "@agent-relay/user-directory": "2.0.24",
34
- "@agent-relay/wrapper": "2.0.24",
35
- "@agent-relay/telemetry": "2.0.24",
25
+ "@agent-relay/protocol": "2.0.26",
26
+ "@agent-relay/config": "2.0.26",
27
+ "@agent-relay/storage": "2.0.26",
28
+ "@agent-relay/bridge": "2.0.26",
29
+ "@agent-relay/utils": "2.0.26",
30
+ "@agent-relay/policy": "2.0.26",
31
+ "@agent-relay/memory": "2.0.26",
32
+ "@agent-relay/resiliency": "2.0.26",
33
+ "@agent-relay/user-directory": "2.0.26",
34
+ "@agent-relay/wrapper": "2.0.26",
35
+ "@agent-relay/telemetry": "2.0.26",
36
36
  "ws": "^8.18.3",
37
37
  "better-sqlite3": "^12.6.2",
38
38
  "pg": "^8.16.3",
@@ -17,7 +17,12 @@ export interface HookOutput {
17
17
  /** Reason for the decision (shown to Claude if blocked) */
18
18
  reason?: string;
19
19
  }
20
- export interface InboxMessage {
20
+ /**
21
+ * Parsed message from inbox file.
22
+ * Note: This is different from @agent-relay/protocol's InboxMessage
23
+ * which is for daemon communication.
24
+ */
25
+ export interface ParsedInboxMessage {
21
26
  from: string;
22
27
  timestamp: string;
23
28
  body: string;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Utility functions for Agent Relay Inbox Check Hook
3
3
  */
4
- import type { InboxConfig, InboxMessage } from './types.js';
4
+ import type { InboxConfig, ParsedInboxMessage } from './types.js';
5
5
  /** Default inbox directory */
6
6
  export declare const DEFAULT_INBOX_DIR = "/tmp/agent-relay";
7
7
  /**
@@ -32,11 +32,11 @@ export declare function countMessages(inboxPath: string): number;
32
32
  /**
33
33
  * Parse messages from inbox content
34
34
  */
35
- export declare function parseMessages(inboxPath: string): InboxMessage[];
35
+ export declare function parseMessages(inboxPath: string): ParsedInboxMessage[];
36
36
  /**
37
37
  * Format a message for display
38
38
  */
39
- export declare function formatMessagePreview(msg: InboxMessage, maxLength?: number): string;
39
+ export declare function formatMessagePreview(msg: ParsedInboxMessage, maxLength?: number): string;
40
40
  /**
41
41
  * Build the block reason message
42
42
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/hooks",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Hook emitter, registry, and trajectory hooks for Agent Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,9 +37,9 @@
37
37
  "test:watch": "vitest"
38
38
  },
39
39
  "dependencies": {
40
- "@agent-relay/protocol": "2.0.24",
41
- "@agent-relay/config": "2.0.24",
42
- "@agent-relay/trajectory": "2.0.24"
40
+ "@agent-relay/protocol": "2.0.26",
41
+ "@agent-relay/config": "2.0.26",
42
+ "@agent-relay/trajectory": "2.0.26"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^22.19.3",
@@ -1,52 +1,12 @@
1
1
  /**
2
2
  * RelayClient - Client for connecting to the Agent Relay daemon
3
+ *
4
+ * This module uses @agent-relay/protocol for wire format handling
5
+ * to avoid code duplication with the SDK.
3
6
  */
4
- export interface HealthResponse {
5
- healthScore: number;
6
- summary: string;
7
- issues: Array<{
8
- severity: string;
9
- message: string;
10
- }>;
11
- recommendations: string[];
12
- crashes: Array<{
13
- id: string;
14
- agentName: string;
15
- crashedAt: string;
16
- likelyCause: string;
17
- summary?: string;
18
- }>;
19
- alerts: Array<{
20
- id: string;
21
- agentName: string;
22
- alertType: string;
23
- message: string;
24
- createdAt: string;
25
- }>;
26
- stats: {
27
- totalCrashes24h: number;
28
- totalAlerts24h: number;
29
- agentCount: number;
30
- };
31
- }
32
- export interface MetricsResponse {
33
- agents: Array<{
34
- name: string;
35
- pid?: number;
36
- status: string;
37
- rssBytes?: number;
38
- cpuPercent?: number;
39
- trend?: string;
40
- alertLevel?: string;
41
- highWatermark?: number;
42
- uptimeMs?: number;
43
- }>;
44
- system: {
45
- totalMemory: number;
46
- freeMemory: number;
47
- heapUsed: number;
48
- };
49
- }
7
+ import { type HealthResponsePayload, type MetricsResponsePayload } from '@agent-relay/protocol';
8
+ export type HealthResponse = HealthResponsePayload;
9
+ export type MetricsResponse = MetricsResponsePayload;
50
10
  export interface RelayClient {
51
11
  send(to: string, message: string, options?: {
52
12
  thread?: string;
@@ -59,6 +19,9 @@ export interface RelayClient {
59
19
  content: string;
60
20
  thread?: string;
61
21
  }>;
22
+ broadcast(message: string, options?: {
23
+ kind?: string;
24
+ }): Promise<void>;
62
25
  spawn(options: {
63
26
  name: string;
64
27
  cli: string;
@@ -68,11 +31,59 @@ export interface RelayClient {
68
31
  }): Promise<{
69
32
  success: boolean;
70
33
  error?: string;
34
+ pid?: number;
71
35
  }>;
72
36
  release(name: string, reason?: string): Promise<{
73
37
  success: boolean;
74
38
  error?: string;
75
39
  }>;
40
+ subscribe(topic: string): Promise<{
41
+ success: boolean;
42
+ error?: string;
43
+ }>;
44
+ unsubscribe(topic: string): Promise<{
45
+ success: boolean;
46
+ error?: string;
47
+ }>;
48
+ joinChannel(channel: string, displayName?: string): Promise<{
49
+ success: boolean;
50
+ error?: string;
51
+ }>;
52
+ leaveChannel(channel: string, reason?: string): Promise<{
53
+ success: boolean;
54
+ error?: string;
55
+ }>;
56
+ sendChannelMessage(channel: string, message: string, options?: {
57
+ thread?: string;
58
+ }): Promise<void>;
59
+ bindAsShadow(primaryAgent: string, options?: {
60
+ speakOn?: string[];
61
+ }): Promise<{
62
+ success: boolean;
63
+ error?: string;
64
+ }>;
65
+ unbindAsShadow(primaryAgent: string): Promise<{
66
+ success: boolean;
67
+ error?: string;
68
+ }>;
69
+ createProposal(options: {
70
+ id: string;
71
+ description: string;
72
+ options: string[];
73
+ votingMethod?: string;
74
+ deadline?: number;
75
+ }): Promise<{
76
+ success: boolean;
77
+ error?: string;
78
+ }>;
79
+ vote(options: {
80
+ proposalId: string;
81
+ vote: string;
82
+ reason?: string;
83
+ }): Promise<{
84
+ success: boolean;
85
+ error?: string;
86
+ }>;
76
87
  getStatus(): Promise<{
77
88
  connected: boolean;
78
89
  agentName: string;