Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .beads/issues.jsonl

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ agent-relay -n Bob claude

## For Agents: How to Communicate

When wrapped with `agent-relay`, agents communicate by outputting `@relay:` patterns.
When wrapped with `agent-relay`, agents communicate by outputting `>>relay:` patterns.

### Send a Message

Output this in your response (not in a bash command):

```
@relay:AgentName Your message here
>>relay:AgentName Your message here
```

### Broadcast to All

```
@relay:* This message goes to everyone
>>relay:* This message goes to everyone
```

### Receiving Messages
Expand Down Expand Up @@ -87,48 +87,48 @@ agent-relay read abc12345
### Status Updates

```
@relay:* STATUS: Starting work on auth module
@relay:* DONE: Auth module complete
>>relay:* STATUS: Starting work on auth module
>>relay:* DONE: Auth module complete
```

### Task Assignment

```
@relay:Developer TASK: Implement /api/register endpoint
>>relay:Developer TASK: Implement /api/register endpoint
```

### Questions

```
@relay:Architect QUESTION: Should we use JWT or sessions?
>>relay:Architect QUESTION: Should we use JWT or sessions?
```

### Review Requests

```
@relay:Reviewer REVIEW: Please check src/auth/*.ts
>>relay:Reviewer REVIEW: Please check src/auth/*.ts
```

---

## Pattern Rules

The `@relay:` pattern must be at the start of a line:
The `>>relay:` pattern must be at the start of a line:

```
@relay:Name message # Works
@relay:Name message # Works (whitespace OK)
> @relay:Name message # Works (prompt OK)
- @relay:Name message # Works (list OK)
Some text @relay:Name msg # Won't work
>>relay:Name message # Works
>>relay:Name message # Works (whitespace OK)
> >>relay:Name message # Works (prompt OK)
- >>relay:Name message # Works (list OK)
Some text >>relay:Name msg # Won't work
```

### Escape

To output literal `@relay:` without sending:
To output literal `>>relay:` without sending:

```
\@relay: This won't be sent
\>>relay: This won't be sent
```

---
Expand Down
48 changes: 24 additions & 24 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Agent Relay is a real-time messaging system that enables autonomous agent-to-age

The system works by:
1. Wrapping agent CLI processes in monitored tmux sessions
2. Parsing agent output for `@relay:` commands
2. Parsing agent output for `>>relay:` commands
3. Routing messages through a central daemon via Unix domain sockets
4. Injecting incoming messages directly into agent terminal input

Expand Down Expand Up @@ -44,7 +44,7 @@ Agent Relay solves this by providing a communication layer that requires **zero

### 1.2 Core Principle: Output Parsing, Not API Integration

The fundamental insight is that AI agents already produce text output. By monitoring that output for specific patterns (`@relay:Target message`), we can extract communication intent without modifying the agent itself.
The fundamental insight is that AI agents already produce text output. By monitoring that output for specific patterns (`>>relay:Target message`), we can extract communication intent without modifying the agent itself.

This approach:
- Works with any CLI-based agent
Expand Down Expand Up @@ -113,7 +113,7 @@ Web UI for monitoring. Shows connected agents, message flow, real-time updates.
│ Layer 2: Wrapper │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ TmuxWrapper │ │ OutputParser │ │ RelayClient │ │
│ │ (PTY mgmt) │ │ (@relay:) │ │ (Socket I/O) │ │
│ │ (PTY mgmt) │ │ (>>relay:) │ │ (Socket I/O) │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ Layer 3: Daemon │
Expand Down Expand Up @@ -162,7 +162,7 @@ The TmuxWrapper is the most complex component. It bridges the gap between agent
│ │ │ Agent Process (claude, etc.) │ │ │
│ │ │ │ │ │
│ │ │ Output: "I'll send a message to Bob" │ │ │
│ │ │ Output: "@relay:Bob Can you review auth.ts?" │ │ │
│ │ │ Output: ">>relay:Bob Can you review auth.ts?" │ │ │
│ │ │ │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
Expand All @@ -173,7 +173,7 @@ The TmuxWrapper is the most complex component. It bridges the gap between agent
│ │ OutputParser │ │
│ │ - Strip ANSI codes │ │
│ │ - Join continuation lines │ │
│ │ - Extract @relay: commands │ │
│ │ - Extract >>relay: commands │ │
│ │ - Deduplicate (hash-based) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
Expand Down Expand Up @@ -214,9 +214,9 @@ return str.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, '');
```

**3. Continuation Line Joining**
When TUIs wrap long lines, `@relay:` commands can span multiple lines:
When TUIs wrap long lines, `>>relay:` commands can span multiple lines:
```
@relay:Bob This is a very long message that gets
>>relay:Bob This is a very long message that gets
wrapped by the terminal and continues here
```
The wrapper joins these back together.
Expand Down Expand Up @@ -252,8 +252,8 @@ Extracts relay commands from agent output.

**1. Inline Format (Primary)**
```
@relay:AgentName Your message here
@relay:* Broadcast to everyone
>>relay:AgentName Your message here
>>relay:* Broadcast to everyone
@thinking:AgentName Share reasoning (not displayed to user)
```

Expand All @@ -268,15 +268,15 @@ The parser handles real-world terminal output complexity:

```typescript
// Allow common input prefixes: >, $, %, #, bullets, etc.
const INLINE_RELAY = /^(?:\s*(?:[>$%#→➜›»●•◦‣⁃\-*⏺◆◇○□■]\s*)*)?@relay:(\S+)\s+(.+)$/;
const INLINE_RELAY = /^(?:\s*(?:[>$%#→➜›»●•◦‣⁃\-*⏺◆◇○□■]\s*)*)?>>relay:(\S+)\s+(.+)$/;
```

This matches:
- `@relay:Bob hello` (plain)
- ` @relay:Bob hello` (indented)
- `> @relay:Bob hello` (quoted)
- `- @relay:Bob hello` (bullet point)
- `⏺ @relay:Bob hello` (Claude's bullet)
- `>>relay:Bob hello` (plain)
- ` >>relay:Bob hello` (indented)
- `> >>relay:Bob hello` (quoted)
- `- >>relay:Bob hello` (bullet point)
- `⏺ >>relay:Bob hello` (Claude's bullet)

#### Code Fence Awareness

Expand Down Expand Up @@ -601,7 +601,7 @@ Messages can have different semantic kinds:
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. AGENT OUTPUT │
│ Agent (Claude) produces text: "@relay:Bob Can you review auth.ts?" │
│ Agent (Claude) produces text: ">>relay:Bob Can you review auth.ts?" │
└─────────────────────────────────────────────────────────────────────────┘
Expand All @@ -617,7 +617,7 @@ Messages can have different semantic kinds:
│ OutputParser: │
│ - Strips ANSI escape codes │
│ - Joins continuation lines │
│ - Matches /^@relay:(\S+)\s+(.+)$/ │
│ - Matches /^>>relay:(\S+)\s+(.+)$/ │
│ - Returns: { to: "Bob", body: "Can you review auth.ts?" } │
└─────────────────────────────────────────────────────────────────────────┘
Expand Down Expand Up @@ -700,7 +700,7 @@ Messages can have different semantic kinds:

### 5.2 Broadcast Flow

When sending to `@relay:*`:
When sending to `>>relay:*`:

```
Alice Daemon Bob, Carol, Dave
Expand Down Expand Up @@ -800,7 +800,7 @@ Alice Daemon Bob, Carol, Dave
│ └─────────────┘ │
│ │
│ State Tracking: │
│ - inCodeFence: boolean - ignore @relay inside code fences
│ - inCodeFence: boolean - ignore >>relay inside code fences │
│ - inBlock: boolean - buffering [[RELAY]]...[[/RELAY]] │
│ - blockBuffer: string - accumulated block content │
│ │
Expand Down Expand Up @@ -958,7 +958,7 @@ For sensitive environments:

### 9.1 Why Output Parsing Instead of API Integration?

**Decision**: Parse agent stdout for `@relay:` patterns instead of modifying agent code.
**Decision**: Parse agent stdout for `>>relay:` patterns instead of modifying agent code.

**Rationale**:
- Works with any CLI agent without modification
Expand All @@ -971,7 +971,7 @@ For sensitive environments:
- ❌ Can miss messages in edge cases
- ❌ No structured validation of message content
- ✅ Zero changes to Claude, Codex, or other agents
- ✅ Transparent - users see `@relay:` in agent output
- ✅ Transparent - users see `>>relay:` in agent output

### 9.2 Why Tmux Instead of Direct PTY?

Expand Down Expand Up @@ -1162,7 +1162,7 @@ agent-relay/
│ ├── wrapper/
│ │ ├── tmux-wrapper.ts # Tmux session management
│ │ ├── client.ts # Daemon client connection
│ │ ├── parser.ts # Output parsing (@relay:)
│ │ ├── parser.ts # Output parsing (>>relay:)
│ │ ├── inbox.ts # File-based inbox
│ │ └── index.ts
│ ├── protocol/
Expand Down Expand Up @@ -1217,10 +1217,10 @@ agent-relay -n Bob claude

```
# Direct message
@relay:Bob Please review the auth module
>>relay:Bob Please review the auth module

# Broadcast
@relay:* I've finished the database migration
>>relay:* I've finished the database migration

# Structured (block format)
[[RELAY]]{"to":"Bob","type":"action","body":"Run tests"}[[/RELAY]]
Expand Down
28 changes: 14 additions & 14 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,20 @@ agent-relay -n Bob claude

## For Agents: How to Communicate

When wrapped with `agent-relay`, agents communicate by outputting `@relay:` patterns.
When wrapped with `agent-relay`, agents communicate by outputting `>>relay:` patterns.

### Send a Message

Output this in your response (not in a bash command):

```
@relay:AgentName Your message here
>>relay:AgentName Your message here
```

### Broadcast to All

```
@relay:* This message goes to everyone
>>relay:* This message goes to everyone
```

### Receiving Messages
Expand Down Expand Up @@ -115,24 +115,24 @@ agent-relay read abc12345...
## Communication Patterns

```
@relay:* STATUS: Starting work on auth module
@relay:* DONE: Auth module complete
@relay:Developer TASK: Implement /api/register
@relay:Reviewer REVIEW: Please check src/auth/*.ts
@relay:Architect QUESTION: JWT or sessions?
>>relay:* STATUS: Starting work on auth module
>>relay:* DONE: Auth module complete
>>relay:Developer TASK: Implement /api/register
>>relay:Reviewer REVIEW: Please check src/auth/*.ts
>>relay:Architect QUESTION: JWT or sessions?
```

---

## Pattern Rules

`@relay:` must be at the start of a line:
`>>relay:` must be at the start of a line:

```
@relay:Name message # Works
@relay:Name message # Works (whitespace OK)
- @relay:Name message # Works (list OK)
Some text @relay:Name msg # Won't work
>>relay:Name message # Works
>>relay:Name message # Works (whitespace OK)
- >>relay:Name message # Works (list OK)
Some text >>relay:Name msg # Won't work
```

Escape with `\@relay:` to output literally.
Escape with `\>>relay:` to output literally.
Loading