agent-relay 2.0.18 → 2.0.20

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 (165) hide show
  1. package/bin/relay-pty-darwin-arm64 +0 -0
  2. package/bin/relay-pty-darwin-x64 +0 -0
  3. package/bin/relay-pty-linux-x64 +0 -0
  4. package/dist/dashboard/out/404.html +1 -1
  5. package/dist/dashboard/out/_next/static/chunks/320-a6304232cd0ee2ce.js +1 -0
  6. package/dist/dashboard/out/_next/static/chunks/631-16b905e5920f9b59.js +1 -0
  7. package/dist/dashboard/out/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +1 -0
  8. package/dist/dashboard/out/_next/static/css/{45361ce86b2847c4.css → 6892f8422896ef7a.css} +1 -1
  9. package/dist/dashboard/out/app/onboarding.html +1 -1
  10. package/dist/dashboard/out/app/onboarding.txt +1 -1
  11. package/dist/dashboard/out/app.html +1 -1
  12. package/dist/dashboard/out/app.txt +2 -2
  13. package/dist/dashboard/out/cloud/link.html +1 -1
  14. package/dist/dashboard/out/cloud/link.txt +1 -1
  15. package/dist/dashboard/out/complete-profile.html +2 -2
  16. package/dist/dashboard/out/complete-profile.txt +1 -1
  17. package/dist/dashboard/out/connect-repos.html +1 -1
  18. package/dist/dashboard/out/connect-repos.txt +1 -1
  19. package/dist/dashboard/out/history.html +1 -1
  20. package/dist/dashboard/out/history.txt +1 -1
  21. package/dist/dashboard/out/index.html +1 -1
  22. package/dist/dashboard/out/index.txt +2 -2
  23. package/dist/dashboard/out/login.html +2 -2
  24. package/dist/dashboard/out/login.txt +1 -1
  25. package/dist/dashboard/out/metrics.html +1 -1
  26. package/dist/dashboard/out/metrics.txt +1 -1
  27. package/dist/dashboard/out/pricing.html +2 -2
  28. package/dist/dashboard/out/pricing.txt +1 -1
  29. package/dist/dashboard/out/providers/setup/claude.html +1 -1
  30. package/dist/dashboard/out/providers/setup/claude.txt +1 -1
  31. package/dist/dashboard/out/providers/setup/codex.html +1 -1
  32. package/dist/dashboard/out/providers/setup/codex.txt +1 -1
  33. package/dist/dashboard/out/providers/setup/cursor.html +1 -1
  34. package/dist/dashboard/out/providers/setup/cursor.txt +1 -1
  35. package/dist/dashboard/out/providers.html +1 -1
  36. package/dist/dashboard/out/providers.txt +2 -2
  37. package/dist/dashboard/out/signup.html +2 -2
  38. package/dist/dashboard/out/signup.txt +1 -1
  39. package/package.json +23 -17
  40. package/packages/api-types/package.json +2 -2
  41. package/packages/bridge/dist/spawner.d.ts +2 -0
  42. package/packages/bridge/dist/spawner.js +75 -23
  43. package/packages/bridge/package.json +8 -8
  44. package/packages/cli-tester/README.md +277 -0
  45. package/packages/cli-tester/dist/index.d.ts +21 -0
  46. package/packages/cli-tester/dist/index.js +21 -0
  47. package/packages/cli-tester/dist/utils/credential-check.d.ts +56 -0
  48. package/packages/cli-tester/dist/utils/credential-check.js +230 -0
  49. package/packages/cli-tester/dist/utils/socket-client.d.ts +76 -0
  50. package/packages/cli-tester/dist/utils/socket-client.js +153 -0
  51. package/packages/cli-tester/docker/entrypoint.sh +58 -0
  52. package/packages/cli-tester/package.json +32 -0
  53. package/packages/cli-tester/scripts/clear-auth.sh +101 -0
  54. package/packages/cli-tester/scripts/inject-message.sh +42 -0
  55. package/packages/cli-tester/scripts/start.sh +71 -0
  56. package/packages/cli-tester/scripts/test-cli.sh +56 -0
  57. package/packages/cli-tester/scripts/test-full-spawn.sh +238 -0
  58. package/packages/cli-tester/scripts/test-registration.sh +182 -0
  59. package/packages/cli-tester/scripts/test-setup-flow.sh +202 -0
  60. package/packages/cli-tester/scripts/test-spawn.sh +140 -0
  61. package/packages/cli-tester/scripts/test-with-daemon.sh +247 -0
  62. package/packages/cli-tester/scripts/verify-auth.sh +112 -0
  63. package/packages/cloud/dist/api/cli-pty-runner.js +9 -6
  64. package/packages/cloud/package.json +6 -6
  65. package/packages/config/dist/cli-auth-config.js +75 -0
  66. package/packages/config/package.json +2 -2
  67. package/packages/continuity/package.json +1 -1
  68. package/packages/daemon/dist/cli-auth.js +5 -1
  69. package/packages/daemon/dist/router.js +4 -4
  70. package/packages/daemon/dist/server.js +38 -19
  71. package/packages/daemon/dist/spawn-manager.d.ts +4 -0
  72. package/packages/daemon/dist/spawn-manager.js +2 -0
  73. package/packages/daemon/package.json +12 -12
  74. package/packages/dashboard/dist/server.js +4 -0
  75. package/packages/dashboard/package.json +14 -14
  76. package/packages/dashboard/ui/app/providers/page.tsx +2 -2
  77. package/packages/dashboard/ui/react-components/ProviderConnectionList.tsx +23 -8
  78. package/packages/dashboard/ui/react-components/SpawnModal.tsx +16 -6
  79. package/packages/dashboard/ui/react-components/settings/WorkspaceSettingsPanel.tsx +22 -6
  80. package/packages/dashboard/ui-dist/404.html +1 -1
  81. package/packages/dashboard/ui-dist/_next/static/chunks/320-a6304232cd0ee2ce.js +1 -0
  82. package/packages/dashboard/ui-dist/_next/static/chunks/631-16b905e5920f9b59.js +1 -0
  83. package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +1 -0
  84. package/packages/dashboard/ui-dist/_next/static/css/{45361ce86b2847c4.css → 6892f8422896ef7a.css} +1 -1
  85. package/packages/dashboard/ui-dist/app/onboarding.html +1 -1
  86. package/packages/dashboard/ui-dist/app/onboarding.txt +1 -1
  87. package/packages/dashboard/ui-dist/app.html +1 -1
  88. package/packages/dashboard/ui-dist/app.txt +2 -2
  89. package/packages/dashboard/ui-dist/cloud/link.html +1 -1
  90. package/packages/dashboard/ui-dist/cloud/link.txt +1 -1
  91. package/packages/dashboard/ui-dist/complete-profile.html +2 -2
  92. package/packages/dashboard/ui-dist/complete-profile.txt +1 -1
  93. package/packages/dashboard/ui-dist/connect-repos.html +1 -1
  94. package/packages/dashboard/ui-dist/connect-repos.txt +1 -1
  95. package/packages/dashboard/ui-dist/history.html +1 -1
  96. package/packages/dashboard/ui-dist/history.txt +1 -1
  97. package/packages/dashboard/ui-dist/index.html +1 -1
  98. package/packages/dashboard/ui-dist/index.txt +2 -2
  99. package/packages/dashboard/ui-dist/login.html +2 -2
  100. package/packages/dashboard/ui-dist/login.txt +1 -1
  101. package/packages/dashboard/ui-dist/metrics.html +1 -1
  102. package/packages/dashboard/ui-dist/metrics.txt +1 -1
  103. package/packages/dashboard/ui-dist/pricing.html +2 -2
  104. package/packages/dashboard/ui-dist/pricing.txt +1 -1
  105. package/packages/dashboard/ui-dist/providers/setup/claude.html +1 -1
  106. package/packages/dashboard/ui-dist/providers/setup/claude.txt +1 -1
  107. package/packages/dashboard/ui-dist/providers/setup/codex.html +1 -1
  108. package/packages/dashboard/ui-dist/providers/setup/codex.txt +1 -1
  109. package/packages/dashboard/ui-dist/providers/setup/cursor.html +1 -1
  110. package/packages/dashboard/ui-dist/providers/setup/cursor.txt +1 -1
  111. package/packages/dashboard/ui-dist/providers.html +1 -1
  112. package/packages/dashboard/ui-dist/providers.txt +2 -2
  113. package/packages/dashboard/ui-dist/signup.html +2 -2
  114. package/packages/dashboard/ui-dist/signup.txt +1 -1
  115. package/packages/dashboard-server/dist/server.js +4 -0
  116. package/packages/dashboard-server/package.json +12 -12
  117. package/packages/hooks/package.json +4 -4
  118. package/packages/mcp/package.json +2 -2
  119. package/packages/memory/package.json +2 -2
  120. package/packages/policy/package.json +2 -2
  121. package/packages/protocol/package.json +1 -1
  122. package/packages/resiliency/package.json +1 -1
  123. package/packages/sdk/README.md +512 -58
  124. package/packages/sdk/dist/client.d.ts +135 -1
  125. package/packages/sdk/dist/client.js +338 -0
  126. package/packages/sdk/dist/index.d.ts +2 -1
  127. package/packages/sdk/dist/index.js +2 -0
  128. package/packages/sdk/dist/logs.d.ts +61 -0
  129. package/packages/sdk/dist/logs.js +95 -0
  130. package/packages/sdk/dist/protocol/index.d.ts +1 -1
  131. package/packages/sdk/dist/protocol/types.d.ts +186 -1
  132. package/packages/sdk/package.json +3 -3
  133. package/packages/spawner/package.json +2 -2
  134. package/packages/state/package.json +1 -1
  135. package/packages/storage/dist/sqlite-adapter.js +2 -0
  136. package/packages/storage/package.json +2 -2
  137. package/packages/telemetry/package.json +1 -1
  138. package/packages/trajectory/package.json +2 -2
  139. package/packages/user-directory/package.json +2 -2
  140. package/packages/utils/package.json +1 -1
  141. package/packages/wrapper/dist/base-wrapper.js +27 -10
  142. package/packages/wrapper/dist/idle-detector.d.ts +4 -0
  143. package/packages/wrapper/dist/idle-detector.js +21 -8
  144. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts +5 -0
  145. package/packages/wrapper/dist/relay-pty-orchestrator.js +60 -5
  146. package/packages/wrapper/dist/tmux-wrapper.js +16 -0
  147. package/packages/wrapper/package.json +7 -7
  148. package/scripts/hooks/install.sh +16 -0
  149. package/scripts/hooks/pre-commit +60 -0
  150. package/scripts/postinstall.js +41 -1
  151. package/specs/PRIMITIVES_ROADMAP.md +2154 -0
  152. package/dist/dashboard/out/_next/static/chunks/320-402ffc8646b31da1.js +0 -1
  153. package/dist/dashboard/out/_next/static/chunks/631-af51bad94027527a.js +0 -1
  154. package/dist/dashboard/out/_next/static/chunks/app/providers/page-bcf46064ac4474ce.js +0 -1
  155. package/packages/dashboard/ui-dist/_next/static/chunks/320-402ffc8646b31da1.js +0 -1
  156. package/packages/dashboard/ui-dist/_next/static/chunks/631-af51bad94027527a.js +0 -1
  157. package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-bcf46064ac4474ce.js +0 -1
  158. /package/dist/dashboard/out/_next/static/{JIjqkuDKNeoSg7KaMMuhx → PwtT8u1tFMW_S1HUv0i5S}/_buildManifest.js +0 -0
  159. /package/dist/dashboard/out/_next/static/{JIjqkuDKNeoSg7KaMMuhx → PwtT8u1tFMW_S1HUv0i5S}/_ssgManifest.js +0 -0
  160. /package/packages/dashboard/ui-dist/_next/static/{JIjqkuDKNeoSg7KaMMuhx → 52xh7eSCZzG97BVf5zzLY}/_buildManifest.js +0 -0
  161. /package/packages/dashboard/ui-dist/_next/static/{JIjqkuDKNeoSg7KaMMuhx → 52xh7eSCZzG97BVf5zzLY}/_ssgManifest.js +0 -0
  162. /package/packages/dashboard/ui-dist/_next/static/{nmkOi7bqeDmLMoWBih8lz → NN1eZ4W4r5XU6mkmJWV2-}/_buildManifest.js +0 -0
  163. /package/packages/dashboard/ui-dist/_next/static/{nmkOi7bqeDmLMoWBih8lz → NN1eZ4W4r5XU6mkmJWV2-}/_ssgManifest.js +0 -0
  164. /package/packages/dashboard/ui-dist/_next/static/{wk_gKRNSPpWE-ZhGL6UMl → PwtT8u1tFMW_S1HUv0i5S}/_buildManifest.js +0 -0
  165. /package/packages/dashboard/ui-dist/_next/static/{wk_gKRNSPpWE-ZhGL6UMl → PwtT8u1tFMW_S1HUv0i5S}/_ssgManifest.js +0 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Log reading utilities for Agent Relay SDK.
3
+ *
4
+ * These utilities read agent logs from the local filesystem.
5
+ */
6
+ import { readFile, readdir, stat } from 'node:fs/promises';
7
+ import { join } from 'node:path';
8
+ /**
9
+ * Get the default logs directory path.
10
+ */
11
+ function getDefaultLogsDir() {
12
+ return join(process.cwd(), '.agent-relay', 'worker-logs');
13
+ }
14
+ /**
15
+ * Read the last N lines from a file.
16
+ */
17
+ async function tailFile(filePath, lines) {
18
+ try {
19
+ const content = await readFile(filePath, 'utf-8');
20
+ const allLines = content.split('\n');
21
+ const tailLines = allLines.slice(-lines);
22
+ return tailLines.join('\n').trim();
23
+ }
24
+ catch {
25
+ return '';
26
+ }
27
+ }
28
+ /**
29
+ * Get logs for a specific agent.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * import { getLogs } from '@agent-relay/sdk';
34
+ *
35
+ * const result = await getLogs('Worker1', { lines: 100 });
36
+ * if (result.found) {
37
+ * console.log(result.content);
38
+ * }
39
+ * ```
40
+ *
41
+ * @param agent - Agent name
42
+ * @param options - Options for reading logs
43
+ * @returns Log content and metadata
44
+ */
45
+ export async function getLogs(agent, options = {}) {
46
+ const logsDir = options.logsDir ?? getDefaultLogsDir();
47
+ const lines = options.lines ?? 50;
48
+ const logFile = join(logsDir, `${agent}.log`);
49
+ try {
50
+ await stat(logFile);
51
+ const content = await tailFile(logFile, lines);
52
+ const lineCount = content ? content.split('\n').length : 0;
53
+ return {
54
+ agent,
55
+ content,
56
+ found: true,
57
+ lineCount,
58
+ };
59
+ }
60
+ catch {
61
+ return {
62
+ agent,
63
+ content: '',
64
+ found: false,
65
+ lineCount: 0,
66
+ };
67
+ }
68
+ }
69
+ /**
70
+ * List all agents that have log files.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * import { listLoggedAgents } from '@agent-relay/sdk';
75
+ *
76
+ * const agents = await listLoggedAgents();
77
+ * console.log('Agents with logs:', agents);
78
+ * ```
79
+ *
80
+ * @param logsDir - Directory containing worker logs
81
+ * @returns Array of agent names
82
+ */
83
+ export async function listLoggedAgents(logsDir) {
84
+ const dir = logsDir ?? getDefaultLogsDir();
85
+ try {
86
+ const files = await readdir(dir);
87
+ return files
88
+ .filter((f) => f.endsWith('.log'))
89
+ .map((f) => f.replace('.log', ''));
90
+ }
91
+ catch {
92
+ return [];
93
+ }
94
+ }
95
+ //# sourceMappingURL=logs.js.map
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Protocol exports for @agent-relay/sdk
3
3
  */
4
- export { PROTOCOL_VERSION, type MessageType, type PayloadKind, type Envelope, type EntityType, type HelloPayload, type WelcomePayload, type SendPayload, type SendMeta, type SyncMeta, type DeliveryInfo, type AckPayload, type NackPayload, type BusyPayload, type PingPayload, type PongPayload, type ErrorCode, type ErrorPayload, type LogPayload, type SyncStream, type SyncPayload, type SpeakOnTrigger, type ShadowConfig, type ShadowBindPayload, type ShadowUnbindPayload, type SpawnPayload, type SpawnPolicyDecision, type SpawnResultPayload, type ReleasePayload, type ReleaseResultPayload, type MessageAttachment, type ChannelJoinPayload, type ChannelLeavePayload, type ChannelMessagePayload, type HelloEnvelope, type WelcomeEnvelope, type SendEnvelope, type DeliverEnvelope, type AckEnvelope, type NackEnvelope, type PingEnvelope, type PongEnvelope, type ErrorEnvelope, type BusyEnvelope, type LogEnvelope, type SyncEnvelope, type ShadowBindEnvelope, type ShadowUnbindEnvelope, type SpawnEnvelope, type SpawnResultEnvelope, type ReleaseEnvelope, type ReleaseResultEnvelope, type ChannelJoinEnvelope, type ChannelLeaveEnvelope, type ChannelMessageEnvelope, } from './types.js';
4
+ export { PROTOCOL_VERSION, type MessageType, type PayloadKind, type Envelope, type EntityType, type HelloPayload, type WelcomePayload, type SendPayload, type SendMeta, type SyncMeta, type DeliveryInfo, type AckPayload, type NackPayload, type BusyPayload, type PingPayload, type PongPayload, type ErrorCode, type ErrorPayload, type LogPayload, type SyncStream, type SyncPayload, type SpeakOnTrigger, type ShadowConfig, type ShadowBindPayload, type ShadowUnbindPayload, type SpawnPayload, type SpawnPolicyDecision, type SpawnResultPayload, type ReleasePayload, type ReleaseResultPayload, type ConsensusType, type VoteValue, type ProposalStatus, type CreateProposalOptions, type VoteOptions, type MessageAttachment, type ChannelJoinPayload, type ChannelLeavePayload, type ChannelMessagePayload, type StatusPayload, type StatusResponsePayload, type InboxPayload, type InboxMessage, type InboxResponsePayload, type ListAgentsPayload, type AgentInfo, type ListAgentsResponsePayload, type HealthPayload, type CrashRecord, type AlertRecord, type HealthResponsePayload, type MetricsPayload, type AgentMetrics, type MetricsResponsePayload, type HelloEnvelope, type WelcomeEnvelope, type SendEnvelope, type DeliverEnvelope, type AckEnvelope, type NackEnvelope, type PingEnvelope, type PongEnvelope, type ErrorEnvelope, type BusyEnvelope, type LogEnvelope, type SyncEnvelope, type ShadowBindEnvelope, type ShadowUnbindEnvelope, type SpawnEnvelope, type SpawnResultEnvelope, type ReleaseEnvelope, type ReleaseResultEnvelope, type ChannelJoinEnvelope, type ChannelLeaveEnvelope, type ChannelMessageEnvelope, type StatusEnvelope, type StatusResponseEnvelope, type InboxEnvelope, type InboxResponseEnvelope, type ListAgentsEnvelope, type ListAgentsResponseEnvelope, type HealthEnvelope, type HealthResponseEnvelope, type MetricsEnvelope, type MetricsResponseEnvelope, } from './types.js';
5
5
  export { MAX_FRAME_BYTES, HEADER_SIZE, LEGACY_HEADER_SIZE, type WireFormat, initMessagePack, hasMessagePack, encodeFrame, encodeFrameLegacy, FrameParser, } from './framing.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -5,7 +5,7 @@
5
5
  * These types define the wire protocol for agent-to-agent communication.
6
6
  */
7
7
  export declare const PROTOCOL_VERSION = 1;
8
- export type MessageType = 'HELLO' | 'WELCOME' | 'SEND' | 'DELIVER' | 'ACK' | 'NACK' | 'PING' | 'PONG' | 'ERROR' | 'BUSY' | 'RESUME' | 'BYE' | 'STATE' | 'SYNC' | 'SYNC_SNAPSHOT' | 'SYNC_DELTA' | 'SUBSCRIBE' | 'UNSUBSCRIBE' | 'SHADOW_BIND' | 'SHADOW_UNBIND' | 'LOG' | 'CHANNEL_JOIN' | 'CHANNEL_LEAVE' | 'CHANNEL_MESSAGE' | 'CHANNEL_INFO' | 'CHANNEL_MEMBERS' | 'CHANNEL_TYPING' | 'SPAWN' | 'SPAWN_RESULT' | 'RELEASE' | 'RELEASE_RESULT';
8
+ export type MessageType = 'HELLO' | 'WELCOME' | 'SEND' | 'DELIVER' | 'ACK' | 'NACK' | 'PING' | 'PONG' | 'ERROR' | 'BUSY' | 'RESUME' | 'BYE' | 'STATE' | 'SYNC' | 'SYNC_SNAPSHOT' | 'SYNC_DELTA' | 'SUBSCRIBE' | 'UNSUBSCRIBE' | 'SHADOW_BIND' | 'SHADOW_UNBIND' | 'LOG' | 'CHANNEL_JOIN' | 'CHANNEL_LEAVE' | 'CHANNEL_MESSAGE' | 'CHANNEL_INFO' | 'CHANNEL_MEMBERS' | 'CHANNEL_TYPING' | 'SPAWN' | 'SPAWN_RESULT' | 'RELEASE' | 'RELEASE_RESULT' | 'STATUS' | 'STATUS_RESPONSE' | 'INBOX' | 'INBOX_RESPONSE' | 'LIST_AGENTS' | 'LIST_AGENTS_RESPONSE' | 'HEALTH' | 'HEALTH_RESPONSE' | 'METRICS' | 'METRICS_RESPONSE';
9
9
  export type PayloadKind = 'message' | 'action' | 'state' | 'thinking';
10
10
  /**
11
11
  * Base envelope structure for all protocol messages.
@@ -312,6 +312,181 @@ export interface ReleaseResultPayload {
312
312
  /** Error message (if failed) */
313
313
  error?: string;
314
314
  }
315
+ export type ConsensusType = 'majority' | 'supermajority' | 'unanimous' | 'weighted' | 'quorum';
316
+ export type VoteValue = 'approve' | 'reject' | 'abstain';
317
+ export type ProposalStatus = 'pending' | 'approved' | 'rejected' | 'expired' | 'cancelled';
318
+ /**
319
+ * Options for creating a consensus proposal.
320
+ */
321
+ export interface CreateProposalOptions {
322
+ /** Proposal title */
323
+ title: string;
324
+ /** Detailed description */
325
+ description: string;
326
+ /** Agents allowed to vote */
327
+ participants: string[];
328
+ /** Consensus type (default: majority) */
329
+ consensusType?: ConsensusType;
330
+ /** Timeout in milliseconds (default: 5 minutes) */
331
+ timeoutMs?: number;
332
+ /** Minimum votes required (for quorum type) */
333
+ quorum?: number;
334
+ /** Threshold for supermajority (0-1, default 0.67) */
335
+ threshold?: number;
336
+ }
337
+ /**
338
+ * Options for voting on a proposal.
339
+ */
340
+ export interface VoteOptions {
341
+ /** Proposal ID to vote on */
342
+ proposalId: string;
343
+ /** Vote value */
344
+ value: VoteValue;
345
+ /** Optional reason for the vote */
346
+ reason?: string;
347
+ }
348
+ /**
349
+ * Payload for STATUS request.
350
+ */
351
+ export interface StatusPayload {
352
+ }
353
+ /**
354
+ * Response payload for STATUS request.
355
+ */
356
+ export interface StatusResponsePayload {
357
+ version?: string;
358
+ uptime?: number;
359
+ agentCount?: number;
360
+ messageCount?: number;
361
+ }
362
+ /**
363
+ * Payload for INBOX request.
364
+ */
365
+ export interface InboxPayload {
366
+ agent: string;
367
+ limit?: number;
368
+ unreadOnly?: boolean;
369
+ from?: string;
370
+ channel?: string;
371
+ }
372
+ /**
373
+ * A stored message in the inbox.
374
+ */
375
+ export interface InboxMessage {
376
+ id: string;
377
+ from: string;
378
+ body: string;
379
+ channel?: string;
380
+ thread?: string;
381
+ timestamp: number;
382
+ }
383
+ /**
384
+ * Response payload for INBOX request.
385
+ */
386
+ export interface InboxResponsePayload {
387
+ messages: InboxMessage[];
388
+ }
389
+ /**
390
+ * Payload for LIST_AGENTS request.
391
+ */
392
+ export interface ListAgentsPayload {
393
+ includeIdle?: boolean;
394
+ project?: string;
395
+ }
396
+ /**
397
+ * Agent info returned by LIST_AGENTS.
398
+ */
399
+ export interface AgentInfo {
400
+ name: string;
401
+ cli?: string;
402
+ idle?: boolean;
403
+ parent?: string;
404
+ task?: string;
405
+ connectedAt?: number;
406
+ }
407
+ /**
408
+ * Response payload for LIST_AGENTS request.
409
+ */
410
+ export interface ListAgentsResponsePayload {
411
+ agents: AgentInfo[];
412
+ }
413
+ /**
414
+ * Payload for HEALTH request.
415
+ */
416
+ export interface HealthPayload {
417
+ includeCrashes?: boolean;
418
+ includeAlerts?: boolean;
419
+ }
420
+ /**
421
+ * A crash record.
422
+ */
423
+ export interface CrashRecord {
424
+ id: string;
425
+ agentName: string;
426
+ crashedAt: string;
427
+ likelyCause: string;
428
+ summary?: string;
429
+ }
430
+ /**
431
+ * An alert record.
432
+ */
433
+ export interface AlertRecord {
434
+ id: string;
435
+ agentName: string;
436
+ alertType: string;
437
+ message: string;
438
+ createdAt: string;
439
+ }
440
+ /**
441
+ * Response payload for HEALTH request.
442
+ */
443
+ export interface HealthResponsePayload {
444
+ healthScore: number;
445
+ summary: string;
446
+ issues: Array<{
447
+ severity: string;
448
+ message: string;
449
+ }>;
450
+ recommendations: string[];
451
+ crashes: CrashRecord[];
452
+ alerts: AlertRecord[];
453
+ stats: {
454
+ totalCrashes24h: number;
455
+ totalAlerts24h: number;
456
+ agentCount: number;
457
+ };
458
+ }
459
+ /**
460
+ * Payload for METRICS request.
461
+ */
462
+ export interface MetricsPayload {
463
+ agent?: string;
464
+ }
465
+ /**
466
+ * Metrics for a single agent.
467
+ */
468
+ export interface AgentMetrics {
469
+ name: string;
470
+ pid?: number;
471
+ status: string;
472
+ rssBytes?: number;
473
+ cpuPercent?: number;
474
+ trend?: string;
475
+ alertLevel?: string;
476
+ highWatermark?: number;
477
+ uptimeMs?: number;
478
+ }
479
+ /**
480
+ * Response payload for METRICS request.
481
+ */
482
+ export interface MetricsResponsePayload {
483
+ agents: AgentMetrics[];
484
+ system: {
485
+ totalMemory: number;
486
+ freeMemory: number;
487
+ heapUsed: number;
488
+ };
489
+ }
315
490
  export type HelloEnvelope = Envelope<HelloPayload>;
316
491
  export type WelcomeEnvelope = Envelope<WelcomePayload>;
317
492
  export type SendEnvelope = Envelope<SendPayload> & {
@@ -338,4 +513,14 @@ export type ReleaseResultEnvelope = Envelope<ReleaseResultPayload>;
338
513
  export type ChannelJoinEnvelope = Envelope<ChannelJoinPayload>;
339
514
  export type ChannelLeaveEnvelope = Envelope<ChannelLeavePayload>;
340
515
  export type ChannelMessageEnvelope = Envelope<ChannelMessagePayload>;
516
+ export type StatusEnvelope = Envelope<StatusPayload>;
517
+ export type StatusResponseEnvelope = Envelope<StatusResponsePayload>;
518
+ export type InboxEnvelope = Envelope<InboxPayload>;
519
+ export type InboxResponseEnvelope = Envelope<InboxResponsePayload>;
520
+ export type ListAgentsEnvelope = Envelope<ListAgentsPayload>;
521
+ export type ListAgentsResponseEnvelope = Envelope<ListAgentsResponsePayload>;
522
+ export type HealthEnvelope = Envelope<HealthPayload>;
523
+ export type HealthResponseEnvelope = Envelope<HealthResponsePayload>;
524
+ export type MetricsEnvelope = Envelope<MetricsPayload>;
525
+ export type MetricsResponseEnvelope = Envelope<MetricsResponsePayload>;
341
526
  //# sourceMappingURL=types.d.ts.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/sdk",
3
- "version": "2.0.18",
3
+ "version": "2.0.20",
4
4
  "description": "Lightweight SDK for agent-to-agent communication via Agent Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -45,7 +45,7 @@
45
45
  "sdk"
46
46
  ],
47
47
  "author": "Khaliq Gant",
48
- "license": "MIT",
48
+ "license": "Apache-2.0",
49
49
  "repository": {
50
50
  "type": "git",
51
51
  "url": "git+https://github.com/AgentWorkforce/relay.git",
@@ -55,7 +55,7 @@
55
55
  "access": "public"
56
56
  },
57
57
  "dependencies": {
58
- "@agent-relay/protocol": "2.0.18"
58
+ "@agent-relay/protocol": "2.0.20"
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.18",
3
+ "version": "2.0.20",
4
4
  "description": "Agent spawning types and utilities for Agent Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -43,5 +43,5 @@
43
43
  "url": "git+https://github.com/AgentWorkforce/relay.git",
44
44
  "directory": "packages/spawner"
45
45
  },
46
- "license": "MIT"
46
+ "license": "Apache-2.0"
47
47
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/state",
3
- "version": "2.0.18",
3
+ "version": "2.0.20",
4
4
  "description": "Agent state persistence for non-hook CLIs (Codex, Gemini, etc.)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -67,6 +67,8 @@ export class SqliteStorageAdapter {
67
67
  break;
68
68
  }
69
69
  catch (err) {
70
+ const msg = err instanceof Error ? err.message : String(err);
71
+ console.error(`[storage] SQLite driver "${driver}" failed: ${msg}`);
70
72
  lastError = err;
71
73
  }
72
74
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/storage",
3
- "version": "2.0.18",
3
+ "version": "2.0.20",
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.18"
59
+ "@agent-relay/protocol": "2.0.20"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/node": "^22.19.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/telemetry",
3
- "version": "2.0.18",
3
+ "version": "2.0.20",
4
4
  "description": "Anonymous telemetry for Agent Relay usage analytics",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/trajectory",
3
- "version": "2.0.18",
3
+ "version": "2.0.20",
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.18"
25
+ "@agent-relay/config": "2.0.20"
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.18",
3
+ "version": "2.0.20",
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.18"
25
+ "@agent-relay/resiliency": "2.0.20"
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.18",
3
+ "version": "2.0.20",
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",
@@ -317,14 +317,7 @@ export class BaseWrapper extends EventEmitter {
317
317
  console.error(`[base-wrapper] Skipped duplicate message to ${cmd.to}`);
318
318
  return;
319
319
  }
320
- this.sentMessageHashes.add(hash);
321
- // Limit hash set size
322
- if (this.sentMessageHashes.size > 500) {
323
- const oldest = this.sentMessageHashes.values().next().value;
324
- if (oldest)
325
- this.sentMessageHashes.delete(oldest);
326
- }
327
- // Only send if client ready
320
+ // Only send if client ready - check BEFORE adding hash to avoid blocking retries
328
321
  if (this.client.state !== 'READY') {
329
322
  console.error(`[base-wrapper] Client not ready (state=${this.client.state}), dropping message to ${cmd.to}`);
330
323
  return;
@@ -338,14 +331,30 @@ export class BaseWrapper extends EventEmitter {
338
331
  requires_ack: cmd.meta.ackRequired,
339
332
  };
340
333
  }
334
+ // Helper to mark message as sent (only after successful transmission)
335
+ const markSent = () => {
336
+ this.sentMessageHashes.add(hash);
337
+ // Limit hash set size
338
+ if (this.sentMessageHashes.size > 500) {
339
+ const oldest = this.sentMessageHashes.values().next().value;
340
+ if (oldest)
341
+ this.sentMessageHashes.delete(oldest);
342
+ }
343
+ };
341
344
  // Check if target is a channel (starts with #)
342
345
  if (cmd.to.startsWith('#')) {
343
346
  // Use CHANNEL_MESSAGE protocol for channel targets
344
347
  console.error(`[base-wrapper] Sending CHANNEL_MESSAGE to ${cmd.to}`);
345
- this.client.sendChannelMessage(cmd.to, cmd.body, {
348
+ const success = this.client.sendChannelMessage(cmd.to, cmd.body, {
346
349
  thread: cmd.thread,
347
350
  data: cmd.data,
348
351
  });
352
+ if (success) {
353
+ markSent();
354
+ }
355
+ else {
356
+ console.error(`[base-wrapper] sendChannelMessage failed for ${cmd.to}`);
357
+ }
349
358
  }
350
359
  else {
351
360
  // Use SEND protocol for direct messages and broadcasts
@@ -355,12 +364,20 @@ export class BaseWrapper extends EventEmitter {
355
364
  kind: cmd.kind,
356
365
  data: cmd.data,
357
366
  thread: cmd.thread,
367
+ }).then(() => {
368
+ markSent();
358
369
  }).catch((err) => {
359
370
  console.error(`[base-wrapper] sendAndWait failed for ${cmd.to}: ${err.message}`);
360
371
  });
361
372
  }
362
373
  else {
363
- this.client.sendMessage(cmd.to, cmd.body, cmd.kind, cmd.data, cmd.thread, sendMeta);
374
+ const success = this.client.sendMessage(cmd.to, cmd.body, cmd.kind, cmd.data, cmd.thread, sendMeta);
375
+ if (success) {
376
+ markSent();
377
+ }
378
+ else {
379
+ console.error(`[base-wrapper] sendMessage failed for ${cmd.to}`);
380
+ }
364
381
  }
365
382
  }
366
383
  }
@@ -66,6 +66,10 @@ export declare class UniversalIdleDetector {
66
66
  /**
67
67
  * Check if the agent is in an editor mode (vim INSERT, REPLACE, etc.).
68
68
  * When in editor mode, message injection should be delayed.
69
+ *
70
+ * Note: Claude CLI shows "-- INSERT --" in its status bar (for vim keybindings mode)
71
+ * but this is NOT the same as being in vim. We exclude Claude CLI's status bar
72
+ * by checking for the "⏵" symbol that follows its mode indicator.
69
73
  */
70
74
  isInEditorMode(): boolean;
71
75
  /**
@@ -103,19 +103,32 @@ export class UniversalIdleDetector {
103
103
  /**
104
104
  * Check if the agent is in an editor mode (vim INSERT, REPLACE, etc.).
105
105
  * When in editor mode, message injection should be delayed.
106
+ *
107
+ * Note: Claude CLI shows "-- INSERT --" in its status bar (for vim keybindings mode)
108
+ * but this is NOT the same as being in vim. We exclude Claude CLI's status bar
109
+ * by checking for the "⏵" symbol that follows its mode indicator.
106
110
  */
107
111
  isInEditorMode() {
108
112
  // Check the last portion of output for editor mode indicators
109
113
  const lastOutput = this.outputBuffer.slice(-500);
110
- // Vim/Neovim mode indicators
114
+ // Claude CLI status bar pattern - this is NOT vim editor mode
115
+ // Example: "-- INSERT -- ⏵⏵ bypass permissions on (shift+tab to cycle)"
116
+ // Also match: "-- NORMAL --", "-- VISUAL --" followed by Claude's UI elements
117
+ const claudeCliStatusBar = /-- (?:INSERT|NORMAL|VISUAL|REPLACE) --\s*[⏵⏴►▶]/;
118
+ if (claudeCliStatusBar.test(lastOutput)) {
119
+ return false;
120
+ }
121
+ // Vim/Neovim mode indicators (standalone, not part of Claude CLI status)
122
+ // These patterns require the mode indicator to be at the end of a line
123
+ // or followed only by whitespace, which matches vim's actual display
111
124
  const editorModePatterns = [
112
- /-- INSERT --/i,
113
- /-- REPLACE --/i,
114
- /-- VISUAL --/i,
115
- /-- VISUAL LINE --/i,
116
- /-- VISUAL BLOCK --/i,
117
- /-- SELECT --/i,
118
- /-- TERMINAL --/i,
125
+ /-- INSERT --\s*$/m,
126
+ /-- REPLACE --\s*$/m,
127
+ /-- VISUAL --\s*$/m,
128
+ /-- VISUAL LINE --\s*$/m,
129
+ /-- VISUAL BLOCK --\s*$/m,
130
+ /-- SELECT --\s*$/m,
131
+ /-- TERMINAL --\s*$/m,
119
132
  // Emacs indicators
120
133
  /\*\*\* Emacs/,
121
134
  /M-x/,
@@ -110,6 +110,7 @@ export declare class RelayPtyOrchestrator extends BaseWrapper {
110
110
  private readonly PERIODIC_REMINDER_INTERVAL_MS;
111
111
  private sessionStartTime;
112
112
  private isGracefulStop;
113
+ private earlyExitInfo?;
113
114
  private memoryMonitor;
114
115
  private memoryAlertHandler;
115
116
  private cgroupManager;
@@ -201,6 +202,10 @@ export declare class RelayPtyOrchestrator extends BaseWrapper {
201
202
  * Release agent via dashboard API
202
203
  */
203
204
  private releaseViaDashboardApi;
205
+ /**
206
+ * Check if the relay-pty process is still alive
207
+ */
208
+ private isProcessAlive;
204
209
  /**
205
210
  * Connect to the relay-pty socket
206
211
  */