@sym-bot/sym 0.2.0 → 0.2.2

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.
package/README.md CHANGED
@@ -6,7 +6,7 @@ Your AI agents share everything or nothing. There's no intelligence in the decis
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/@sym-bot/sym)](https://www.npmjs.com/package/@sym-bot/sym)
8
8
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
9
- [![MMP](https://img.shields.io/badge/protocol-MMP%20v0.1.0-purple)](https://sym.bot/protocol)
9
+ [![MMP](https://img.shields.io/badge/protocol-MMP%20v0.2.0-purple)](https://sym.bot/protocol)
10
10
 
11
11
  ---
12
12
 
@@ -33,6 +33,48 @@ await node.stop();
33
33
 
34
34
  Peers on the same network discover each other automatically via Bonjour. Peers across the internet connect through the WebSocket relay. The coupling engine decides what to share.
35
35
 
36
+ ## sym-daemon
37
+
38
+ The daemon is your device's persistent mesh presence — a **physical node** that runs continuously as a background service. It maintains relay connections, Bonjour discovery, and peer state even when no apps are running.
39
+
40
+ ### Installation
41
+
42
+ ```bash
43
+ # Install the daemon as a launchd LaunchAgent (macOS)
44
+ node bin/sym-daemon.js --install
45
+
46
+ # Check daemon status
47
+ node bin/sym-daemon.js --status
48
+
49
+ # Remove the daemon
50
+ node bin/sym-daemon.js --uninstall
51
+ ```
52
+
53
+ On macOS, the daemon installs as a launchd LaunchAgent that:
54
+ - **Auto-starts on login** — mesh presence begins immediately
55
+ - **Auto-restarts on crash** — the mesh never goes down
56
+ - **Maintains relay connection permanently** — internet peers always reachable
57
+
58
+ ### Physical and Virtual Nodes
59
+
60
+ The daemon introduces a two-tier node model:
61
+
62
+ - **Physical node** (sym-daemon) — the device itself. One per machine. Always running. Owns the relay connection, Bonjour identity, and peer state.
63
+ - **Virtual nodes** (apps) — Claude Code, MeloTune Mac, or any app that connects to the daemon via Unix socket IPC at `/tmp/sym.sock`.
64
+
65
+ ```
66
+ MacBook (sym-daemon, always running)
67
+ ├── Claude Code (virtual node, via IPC)
68
+ ├── MeloTune Mac (virtual node, via IPC)
69
+
70
+ ├── Bonjour (LAN peers)
71
+ └── Relay (internet peers)
72
+ ├── MeloTune iPhone
73
+ └── Telegram bot
74
+ ```
75
+
76
+ When Claude Code restarts, the mesh doesn't break. The daemon holds the connection. When Claude Code starts again, it reconnects to the daemon via IPC and resumes where it left off. The mesh is the daemon — apps come and go.
77
+
36
78
  ## Cognitive Coupling
37
79
 
38
80
  SYM doesn't blindly broadcast. Each node encodes its memories into a hidden state vector. When peers connect, the coupling engine evaluates cognitive drift:
@@ -57,25 +99,20 @@ The blogger never sees the API bug. The architecture decided — no policy, no r
57
99
 
58
100
  ## How It Works
59
101
 
60
- There is no central service. Each agent embeds its own SymNode with its own identity, memory, and cognitive state. The mesh emerges from peer connections.
102
+ There is no central service. Each device runs a sym-daemon that maintains its mesh identity, memory, and cognitive state. Apps connect to the daemon as virtual nodes. The mesh emerges from peer connections between physical nodes.
61
103
 
62
104
  ```
63
- ┌────────────────┐ ┌────────────────┐ ┌────────────────┐
64
- Claude Code │ │ MeloTune │ │ Telegram Bot │
65
- │ (Mac/Windows) │ │ (iPhone) │ │ (any device)
66
- │ │ │ │ │
67
- │ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐
68
- │ │ SYM Node │ │ │ │ SYM Node │ │ │ │ SYM Node │ │
69
- │ │ Node.js │ │ │ │ Swift │ │ │ │ Node.js │ │
70
- │ └─────┬─────┘ │ └─────┬───────┘ │ │ └─────┬─────┘
71
- └────────┼────────┘ └──────┼────────┘ └────────┼───────┘
72
- │ │ │
73
- ├── Bonjour (LAN) ─┤ │
74
- │ │ │
75
- └──── WebSocket Relay (internet) ────────┘
105
+ MacBook (sym-daemon, always running)
106
+ ├── Claude Code (virtual node, via IPC)
107
+ ├── MeloTune Mac (virtual node, via IPC)
108
+
109
+ ├── Bonjour (LAN peers)
110
+ └── Relay (internet peers)
111
+ ├── MeloTune iPhone
112
+ └── Telegram bot
76
113
  ```
77
114
 
78
- Each node:
115
+ Each physical node:
79
116
  - Declares its cognitive identity via `cognitiveProfile`
80
117
  - Encodes context into a hidden state vector (context encoder)
81
118
  - Discovers local peers via Bonjour/mDNS (`_sym._tcp`)
@@ -84,6 +121,13 @@ Each node:
84
121
  - Shares memories only with aligned peers (drift ≤ 0.5)
85
122
  - Evaluates incoming mood with configurable `moodThreshold` (default 0.8)
86
123
  - Re-encodes periodically as context evolves
124
+ - Accepts virtual node connections via Unix socket IPC (`/tmp/sym.sock`)
125
+
126
+ Each virtual node:
127
+ - Connects to the local daemon via IPC — no direct network access needed
128
+ - Sends memories, moods, and messages through the daemon
129
+ - Receives mesh events (peer joins, coupling decisions, incoming memories)
130
+ - Can start and stop independently without disrupting the mesh
87
131
 
88
132
  One engine makes every decision. Memory sharing, peer coupling, and mood relevance all go through the [Mesh Cognition SDK](https://github.com/sym-bot/mesh-cognition-sdk)'s `SemanticCoupler`.
89
133
 
@@ -135,7 +179,7 @@ await node.stop();
135
179
 
136
180
  ## Transport
137
181
 
138
- SYM supports two transport modes that can run simultaneously:
182
+ SYM supports multiple transport layers that can run simultaneously:
139
183
 
140
184
  ### Bonjour (LAN)
141
185
 
@@ -143,7 +187,7 @@ Zero-configuration discovery on the local network. Peers find each other automat
143
187
 
144
188
  ### WebSocket Relay (Internet)
145
189
 
146
- For mesh cognition across the internet. A lightweight relay server forwards frames between authenticated nodes. The relay is dumb transportall coupling decisions remain on-device.
190
+ For mesh cognition across the internet. A lightweight relay server forwards frames between authenticated nodes. The relay is a **peer, not infrastructure** it participates in the mesh with its own identity but makes no coupling decisions on behalf of other nodes.
147
191
 
148
192
  ```bash
149
193
  # Deploy your own relay
@@ -170,6 +214,23 @@ The relay server provides:
170
214
  - Peer join/leave notifications
171
215
  - Targeted or broadcast frame forwarding
172
216
 
217
+ ### Peer Gossip
218
+
219
+ Wake channels propagate through the relay via **SWIM-style gossip**. When a node announces a wake channel (e.g., APNs device token), the relay gossips this to all connected peers. Peers cache wake routes so they can reach sleeping nodes without centralized routing tables. The relay participates in gossip as a peer — it doesn't manage routing, it just propagates what it hears.
220
+
221
+ ### Wake Transport (APNs)
222
+
223
+ For nodes that sleep — like MeloTune on a backgrounded iPhone. When an iOS app is suspended, it can't maintain a WebSocket connection. SYM solves this with **push notification wake**.
224
+
225
+ When Claude Code broadcasts a mood and MeloTune's iPhone is sleeping:
226
+ 1. Claude Code sends the mood frame to the relay
227
+ 2. The relay knows MeloTune's APNs device token (via gossip)
228
+ 3. The relay sends a push notification to wake MeloTune
229
+ 4. MeloTune wakes, reconnects to the relay, receives the mood frame
230
+ 5. The coupling engine evaluates drift — MeloTune decides whether to act
231
+
232
+ The mesh reaches every node, even sleeping ones. No polling. No battery drain. The push is a wake signal only — payload evaluation happens on-device after wake.
233
+
173
234
  ## Integrations
174
235
 
175
236
  ### Claude Code
@@ -182,6 +243,8 @@ cd node_modules/@sym-bot/sym
182
243
 
183
244
  One command. Adds MCP server, auto-approves `sym_mood` (no permission prompts), and installs CLAUDE.md instructions for autonomous mood detection. Restart Claude Code and it just works.
184
245
 
246
+ With sym-daemon running, Claude Code connects as a virtual node via IPC — no direct relay connection needed.
247
+
185
248
  **Outbound:** Claude Code saves a memory → SYM detects it → encodes cognitive state → shares with aligned peers only.
186
249
 
187
250
  **Inbound:** Peer memory arrives → coupling engine accepts it → SYM writes it to your Claude Code memory directory → Claude Code reads it in the next conversation.
@@ -237,7 +300,7 @@ You (in Claude Code): "I'm exhausted"
237
300
  Claude Code: detects fatigue → calls sym_mood silently
238
301
  → broadcasts "exhausted, persistently fatigued, urgently needs rest"
239
302
 
240
- SYM mesh (Bonjour + Relay)
303
+ SYM mesh (daemon Relay → APNs wake → MeloTune)
241
304
 
242
305
  MeloTune (iPhone): SymNode receives mood frame
243
306
  → SDK coupling engine evaluates drift: 0.62
@@ -267,10 +330,11 @@ You (in Telegram): @sym_mesh_bot → "Play classic music"
267
330
 
268
331
  ## Verified in Production
269
332
 
270
- - Mac Claude Code → iPhone MeloTune — autonomous mood-based playback via SYM mesh
333
+ - Mac Claude Code → iPhone MeloTune — autonomous mood-based playback via SYM mesh (APNs wake for backgrounded iOS)
271
334
  - Telegram [@sym_mesh_bot](https://t.me/sym_mesh_bot) → Relay → MeloTune — internet-scale mood relay (multi-tenant)
272
335
  - Mac Claude Code ↔ Windows Claude Code — P2P memory sharing via Bonjour
273
336
  - Node.js ↔ Swift — cross-platform mesh via Bonjour and WebSocket relay
337
+ - sym-daemon → Claude Code + MeloTune Mac — persistent mesh via IPC, survives app restarts
274
338
 
275
339
  ## Semantic vs Neural Coupling
276
340
 
@@ -305,11 +369,13 @@ The coupling engine blends peer state into the local trajectory at each inferenc
305
369
  ## Privacy
306
370
 
307
371
  - All coupling decisions stay on-device
308
- - The relay is dumb transport — it never inspects frame payloads
372
+ - The relay is a peer — it never inspects frame payloads
373
+ - The daemon runs locally — no cloud dependency
309
374
  - Memories stored locally — delete the directory, everything is gone
310
375
  - Bonjour discovery only on local network
311
376
  - Relay connections authenticated via shared token
312
377
  - Rejected peers never receive your memories
378
+ - APNs wake is a signal only — no payload leaves the device until the coupling engine approves
313
379
  - No cloud AI. No account. No telemetry.
314
380
 
315
381
  ## Platforms
@@ -321,7 +387,7 @@ The coupling engine blends peer state into the local trajectory at each inferenc
321
387
 
322
388
  SYM is the reference implementation of the [Mesh Memory Protocol (MMP)](https://sym.bot/protocol). MMP is the protocol for collective intelligence. SYM implements it.
323
389
 
324
- - [MMP Protocol Spec](https://sym.bot/protocol) — the protocol specification (v0.1.0)
390
+ - [MMP Protocol Spec](https://sym.bot/protocol) — the protocol specification (v0.2.0)
325
391
  - [Whitepaper](https://sym.bot/research/mesh-cognition) — the science behind cognitive coupling
326
392
  - [Mesh Cognition SDK](https://github.com/sym-bot/mesh-cognition-sdk) — the coupling engine (TypeScript, Python, Swift)
327
393
 
@@ -1,30 +1,83 @@
1
1
  #!/bin/bash
2
2
  # SYM — Setup for Claude Code
3
- # Adds MCP server + auto-approves sym_mood + installs CLAUDE.md instructions
4
- # Optionally configures WebSocket relay for internet-scale mesh
3
+ #
4
+ # Installs:
5
+ # 1. sym-daemon (persistent physical mesh node, launchd LaunchAgent)
6
+ # 2. MCP server for Claude Code (virtual node, connects to daemon via IPC)
7
+ # 3. Auto-approves sym_mood tool
8
+ # 4. CLAUDE.md instructions for autonomous mood detection
9
+ #
10
+ # Usage:
11
+ # npx @sym-bot/sym setup # or
12
+ # ./bin/setup-claude.sh [project-dir]
5
13
 
6
14
  set -e
7
15
 
8
16
  SYM_DIR="$(cd "$(dirname "$0")/.." && pwd)"
9
17
  MCP_SERVER="$SYM_DIR/integrations/claude-code/mcp-server.js"
18
+ DAEMON_SCRIPT="$SYM_DIR/bin/sym-daemon.js"
10
19
 
11
- echo "SYM Setup for Claude Code"
12
- echo "========================="
20
+ echo ""
21
+ echo " SYM Setup for Claude Code"
22
+ echo " ========================="
23
+ echo ""
24
+
25
+ # ── Step 1: Configure relay ─────────────────────────────────
26
+
27
+ RELAY_ENV="$HOME/.sym/relay.env"
28
+ mkdir -p "$HOME/.sym"
29
+
30
+ if [ -f "$RELAY_ENV" ]; then
31
+ echo " ✓ Relay config found: $RELAY_ENV"
32
+ else
33
+ echo " WebSocket Relay (connects your mesh across the internet)"
34
+ echo ""
35
+ read -p " Relay URL (e.g. wss://sym-relay.onrender.com, or empty to skip): " RELAY_URL
36
+ if [ -n "$RELAY_URL" ]; then
37
+ read -p " Relay token (or empty for open access): " RELAY_TOKEN
38
+ echo "SYM_RELAY_URL=$RELAY_URL" > "$RELAY_ENV"
39
+ if [ -n "$RELAY_TOKEN" ]; then
40
+ echo "SYM_RELAY_TOKEN=$RELAY_TOKEN" >> "$RELAY_ENV"
41
+ fi
42
+ echo " ✓ Relay config saved: $RELAY_ENV"
43
+ else
44
+ echo " → Skipping relay — using Bonjour (local network) only"
45
+ fi
46
+ fi
47
+
48
+ # ── Step 2: Install sym-daemon ──────────────────────────────
49
+
50
+ echo ""
51
+ echo " Installing sym-daemon (persistent mesh node)..."
13
52
 
14
- # 1. Add MCP server
15
- echo "Adding SYM MCP server..."
53
+ if [ "$(uname)" = "Darwin" ]; then
54
+ # macOS: install as launchd LaunchAgent
55
+ node "$DAEMON_SCRIPT" --install
56
+ echo " ✓ sym-daemon installed as launchd LaunchAgent"
57
+ echo " Auto-starts on login, auto-restarts on crash"
58
+ echo " Logs: ~/Library/Logs/sym-daemon/"
59
+ else
60
+ echo " → macOS not detected. Start the daemon manually:"
61
+ echo " node $DAEMON_SCRIPT"
62
+ echo " (On Linux, create a systemd service)"
63
+ fi
64
+
65
+ # ── Step 3: Add MCP server ──────────────────────────────────
66
+
67
+ echo ""
68
+ echo " Adding SYM MCP server to Claude Code..."
16
69
  claude mcp add --transport stdio sym --scope user -- node "$MCP_SERVER"
70
+ echo " ✓ MCP server registered"
17
71
 
18
- # 2. Auto-approve sym_mood (no permission prompt)
19
- echo "Auto-approving sym_mood tool..."
72
+ # ── Step 4: Auto-approve sym_mood ───────────────────────────
73
+
74
+ echo ""
75
+ echo " Auto-approving sym_mood tool..."
20
76
  CLAUDE_JSON="$HOME/.claude.json"
21
77
  if [ -f "$CLAUDE_JSON" ]; then
22
- # Use node to safely modify JSON
23
78
  node -e "
24
79
  const fs = require('fs');
25
80
  const config = JSON.parse(fs.readFileSync('$CLAUDE_JSON', 'utf8'));
26
-
27
- // Find all project entries and add sym_mood to allowedTools
28
81
  if (config.projects) {
29
82
  for (const [path, project] of Object.entries(config.projects)) {
30
83
  if (!project.allowedTools) project.allowedTools = [];
@@ -33,53 +86,36 @@ if [ -f "$CLAUDE_JSON" ]; then
33
86
  }
34
87
  }
35
88
  }
36
-
37
89
  fs.writeFileSync('$CLAUDE_JSON', JSON.stringify(config, null, 2));
38
- console.log(' sym_mood auto-approved for all projects');
39
90
  "
40
- fi
41
-
42
- # 3. Configure relay (optional)
43
- echo ""
44
- echo "WebSocket Relay (optional)"
45
- echo "Connects your mesh across the internet — not just local network."
46
- echo ""
47
-
48
- SHELL_RC="$HOME/.zshrc"
49
- [ -f "$HOME/.bashrc" ] && [ ! -f "$HOME/.zshrc" ] && SHELL_RC="$HOME/.bashrc"
50
-
51
- if grep -q "SYM_RELAY_URL" "$SHELL_RC" 2>/dev/null; then
52
- echo " Relay already configured in $SHELL_RC"
91
+ echo " ✓ sym_mood auto-approved"
53
92
  else
54
- read -p "Relay URL (leave empty to skip): " RELAY_URL
55
- if [ -n "$RELAY_URL" ]; then
56
- read -p "Relay token (leave empty for open access): " RELAY_TOKEN
57
- echo "" >> "$SHELL_RC"
58
- echo "# SYM Mesh" >> "$SHELL_RC"
59
- echo "export SYM_RELAY_URL=\"$RELAY_URL\"" >> "$SHELL_RC"
60
- if [ -n "$RELAY_TOKEN" ]; then
61
- echo "export SYM_RELAY_TOKEN=\"$RELAY_TOKEN\"" >> "$SHELL_RC"
62
- fi
63
- echo " Relay configured in $SHELL_RC"
64
- echo " Run 'source $SHELL_RC' or restart your terminal to activate."
65
- else
66
- echo " Skipping relay — using Bonjour (local network) only."
67
- fi
93
+ echo " No .claude.json found approve sym_mood manually when prompted"
68
94
  fi
69
95
 
70
- # 4. Append CLAUDE.md instructions if not already present
96
+ # ── Step 5: Install CLAUDE.md ───────────────────────────────
97
+
71
98
  echo ""
72
- echo "Installing CLAUDE.md instructions..."
73
99
  PROJECT_DIR="${1:-$(pwd)}"
74
100
  CLAUDE_MD="$PROJECT_DIR/CLAUDE.md"
75
101
 
76
102
  if [ -f "$CLAUDE_MD" ] && grep -q "SYM Mesh Agent" "$CLAUDE_MD"; then
77
- echo " CLAUDE.md already has SYM instructions"
103
+ echo " CLAUDE.md already has SYM instructions"
78
104
  else
79
105
  cat "$SYM_DIR/CLAUDE.md" >> "$CLAUDE_MD"
80
- echo " Added SYM instructions to $CLAUDE_MD"
106
+ echo " Added SYM instructions to $CLAUDE_MD"
81
107
  fi
82
108
 
109
+ # ── Done ────────────────────────────────────────────────────
110
+
111
+ echo ""
112
+ echo " ──────────────────────────────────────"
113
+ echo " SYM is ready."
114
+ echo ""
115
+ echo " • sym-daemon: running (check: node $DAEMON_SCRIPT --status)"
116
+ echo " • MCP server: registered (restart Claude Code to activate)"
117
+ echo " • Protocol spec: https://sym.bot/protocol"
118
+ echo ""
119
+ echo " Say 'I'm exhausted' in Claude Code —"
120
+ echo " MeloTune will start playing calming music."
83
121
  echo ""
84
- echo "Done. Restart Claude Code to activate SYM."
85
- echo "Say 'I'm exhausted' — MeloTune will start playing."