@sym-bot/mesh-channel 0.3.3 → 0.3.4

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/CHANGELOG.md CHANGED
@@ -1,489 +1,546 @@
1
- # Changelog
2
-
3
- ## 0.3.3
4
-
5
- ### Fixed
6
-
7
- - **Real-time duplex for CAT7 CMBs.** The `cmb-accepted` handler now
8
- stores the rendered CMB body under an `[mNNN]` ID and includes that
9
- ID in the channel notification, matching the contract stated in the
10
- MCP instructions ("Messages arrive as compact headers with [mNNN] IDs
11
- use sym_fetch to read the full content") and the behaviour of the
12
- raw-text `message` path.
13
-
14
- Previously only the legacy raw-text `message` event persisted bodies
15
- to `MESSAGE_STORE` the primary `cmb-accepted` event (fired for
16
- every structured CMB delivered via `sym_send` / `sym_observe`) pushed
17
- a headline with no `[mNNN]` and left no retrievable body. Inbound
18
- CMBs were admitted to the SVAF-backed memory store and surfaced by
19
- `sym_recall` as compact headlines, but `sym_fetch` could not return
20
- their content the duplex was effectively headline-only for the 99%
21
- case of real mesh traffic.
22
-
23
- Symptom: after the 0.3.2 Mac↔Win fix restored bidirectional packet
24
- flow, peers' structured replies appeared in `sym_recall` but returned
25
- *"expired or invalid ID"* from `sym_fetch` because `storeMessage()`
26
- had never been called for them. Now both the raw-text and CAT7 paths
27
- persist bodies identically.
28
-
29
- ## 0.3.2
30
-
31
- ### Fixed
32
-
33
- - **Pulls in `@sym-bot/sym` 0.5.1** — fixes Mac↔Windows peer connections
34
- over LAN. Prior releases shipped a Bonjour advertisement whose SRV
35
- target was the bare Windows NetBIOS hostname (e.g. `xmesh-hp.`) with
36
- no `.local` suffix. macOS mDNSResponder only resolves `.local.` mDNS
37
- names, so Macs could discover Windows peers via bonjour browse but
38
- failed to open the outbound TCP connection. CMBs targeted at Windows
39
- nodes never arrived; no replies came back. Full diagnosis in sym
40
- 0.5.1 CHANGELOG.
41
-
42
- Upgrade required on both sides to restore Mac↔Windows traffic.
43
- Existing Windows identities with a bare hostname are auto-migrated
44
- on next node start; no manual config edit needed.
45
-
46
- ## 0.3.1
47
-
48
- ### Fixed
49
-
50
- - **Installer no longer silently ships a broken MCP config.** Previously,
51
- if `~/.claude.json` already contained a `claude-sym-mesh` entry,
52
- `npm install -g @sym-bot/mesh-channel` (via postinstall) and
53
- `npx @sym-bot/mesh-channel init` both skipped with "already configured"
54
- even when the entry's `args[0]` server.js path no longer existed on
55
- disk (common after moving or reinstalling the repo). Users saw
56
- `/mcp` report "Failed to reconnect" with no diagnostic hint.
57
-
58
- The installer now classifies entries whose `args[0]` is missing as
59
- **stale** and rewrites them automatically without `--force`, preserving
60
- `SYM_NODE_NAME` from the prior entry so mesh identity doesn't drift
61
- back to the hostname-based default. Live entries continue to require
62
- `--force` for overwrite.
63
-
64
- - **Stale project-scoped entries are now healed too.** `~/.claude.json`
65
- can carry per-project `mcpServers` overrides under
66
- `projects.<dir>.mcpServers`, and Claude Code prefers those over the
67
- user-global entry when launched from that directory. A healthy
68
- user-global entry was therefore being silently shadowed by stale
69
- project entries. `init` now scans every project, rewrites any stale
70
- `claude-sym-mesh` entry, and preserves each project's `SYM_NODE_NAME`.
71
-
72
- ### Added
73
-
74
- - **`sym-mesh-channel doctor` subcommand.** Read-only diagnostic that
75
- lists every `claude-sym-mesh` entry in `~/.claude.json` (user-global
76
- and every project scope) with `[live]` or `[STALE]` plus its
77
- `SYM_NODE_NAME` and configured path. Point users here when `/mcp`
78
- reports "Failed to reconnect". No writes, safe to run any time.
79
-
80
- - **README troubleshooting section** covering the `/mcp` failure path,
81
- how to run `doctor`, and when restart is needed after a config change.
82
-
83
- ### Changed
84
-
85
- - `.claude-plugin/plugin.json` version field bumped to `0.3.1` to match
86
- `package.json`. Previous drift (`plugin.json` stuck at `0.2.0`, package
87
- at `0.3.0`) was caught by the in-repo version-parity test.
88
-
89
- ## 0.3.0
90
-
91
- ### Added
92
-
93
- - **Startup remix-memory primer automates agent memory recall on
94
- session/agent restart (MMP §4.2 O2, rejoin-without-replay).** As the
95
- final step of plugin initialisation (after `node.start()` and before
96
- the MCP transport connects), the plugin calls
97
- `node.buildStartupPrimer()` and appends the returned text to the MCP
98
- server's `instructions` field. A fresh Claude Code session wakes
99
- with the agent's own remix memory own observations plus peer
100
- observations admitted by SVAF already loaded into context. No
101
- first-turn `sym_recall` required; agent acts from prior state
102
- immediately.
103
-
104
- Default caps: last 24 hours OR 20 most recent CMBs, whichever is
105
- tighter. The primer lists each entry as `[timestamp] source · key —
106
- focus` and surfaces a dropped-count line when caps elide older
107
- entries. Empty store is a silent no-op.
108
-
109
- ### Changed
110
-
111
- - **`@sym-bot/sym` dep bumped to `^0.5.0`** to pick up the
112
- `buildStartupPrimer` helper and to keep every plugin on the
113
- sym.day platform pinned to the same substrate SDK version
114
- (no drift across mesh-channel / melotune-plugin / future
115
- specialised plugins).
116
-
117
- ## 0.2.0
118
-
119
- ### Breaking
120
-
121
- - **`sym_send` tool signature change.** `sym_send` now emits a structured
122
- CAT7 CMB (MMP §4.2) instead of a raw-text `type:'message'` frame, and
123
- accepts an optional `to` parameter for targeted single-peer delivery
124
- per MMP §4.4.4.
125
-
126
- Old signature: `sym_send(message: string)`
127
- New signature: `sym_send(focus: string (required), issue?, intent?,
128
- motivation?, commitment?, perspective?, mood?, to?)`
129
-
130
- Migration: agents that previously called `sym_send({message: "..."})`
131
- should now pass the CAT7 fields explicitly, with `focus` carrying the
132
- task anchor for the send. Prior ephemeral text-broadcast behaviour is
133
- no longer exposed at the tool surface `sym_send` and `sym_observe`
134
- both emit CMBs now, receivers run SVAF per §9.2, and admitted CMBs are
135
- remix-stored with lineage. The low-level `node.send(text)` SDK API is
136
- unchanged but no longer surfaced as a tool.
137
-
138
- ### Added
139
-
140
- - **Targeted CMB send.** `sym_send` resolves `to` against connected
141
- peers by full nodeId first, then display name, then 8-char prefix.
142
- Ambiguous matches return an error asking for the full nodeId; a
143
- disconnected target returns an error and suggests `sym_peers`.
144
- - **Tool descriptions** for `sym_send` and `sym_observe` now explicitly
145
- call out the SVAF receive path and lineage semantics, and the MCP
146
- server's `instructions` string reflects the new division of labour.
147
- - **`@sym-bot/sym` dependency bumped to `^0.3.81`** for
148
- `remember(fields, {to})` targeted variant and `peers().peerId`.
149
-
150
- ## 0.1.23
151
-
152
- ### Added
153
-
154
- - **`sym_join_group(group, relay_url?, relay_token?)`** hot-swap this
155
- node into a different mesh group at runtime, no Claude Code restart.
156
- Stops the current SymNode, reconstructs it on the new service type
157
- (and optional relay), re-registers event handlers, restarts. The
158
- "smooth way to join" that was missing in 0.1.22.
159
-
160
- - **`sym_invite_create(group, relay_url?, relay_token?)`** — generate
161
- a shareable invite URL for a named group. Two flavors:
162
- - LAN-only: `sym://group/{name}` (Bonjour isolation only)
163
- - Cross-network: `sym://team/{name}?relay=...&token=...` (routes via
164
- a WebSocket relay so teammates on different networks can join).
165
- Validates kebab-case group names, rejects token without URL.
166
-
167
- - **`sym_invite_info(url)`** extended to parse the new `sym://team/`
168
- path and the `relay=` + `token=` query-string parameters.
169
- Output now includes a ready-to-paste `sym_join_group` call as JSON.
170
-
171
- - **`sym_groups_discover()`** enumerate SYM-mesh groups currently
172
- advertising on the local LAN via Bonjour / mDNS. Shell-outs to
173
- `dns-sd` (macOS/Windows) or `avahi-browse` (Linux) with a 2-second
174
- timeout, filters to service types matching the SYM protocol family
175
- (global `_sym._tcp`, named groups, `{app}-{id}` rooms). Peer-to-peer
176
- means only groups with live members right now are visible — no
177
- central directory.
178
-
179
- - **README "Dev-team groups" walkthrough** with two concrete scenarios:
180
- LAN dev-team group (single office) and cross-network team group via
181
- the public `wss://sym-relay.onrender.com` relay. Shows exact tool
182
- calls from both the team lead and each teammate.
183
-
184
- - **13 new tests** covering invite URL parse, generate, round-trip, and
185
- validation (kebab-case, token-requires-URL guard). Test suite now at
186
- 35 tests total.
187
-
188
- ### Changed
189
-
190
- - Module-level `node`, `GROUP`, `SERVICE_TYPE`, `RELAY_URL`,
191
- `RELAY_TOKEN` declared as `let` (was `const`) so the hot-swap path
192
- can re-bind them. All node event handlers (`identity-collision`,
193
- `cmb-accepted`, `message`) extracted into a single
194
- `registerNodeHandlers(n)` function so the hot-swap path re-attaches
195
- them without duplicating logic.
196
-
197
- - Tool count in README corrected to 11 (was 8 in 0.1.22):
198
- + sym_invite_create, sym_join_group, sym_groups_discover.
199
-
200
- ## 0.1.22
201
-
202
- ### Added
203
-
204
- - **Plugin marketplace distribution**: `.claude-plugin/marketplace.json`
205
- enables direct install via the Claude Code plugin marketplace without
206
- waiting on the Anthropic Plugin Directory propagation pipeline:
207
-
208
- ```
209
- /plugin marketplace add sym-bot/sym-mesh-channel
210
- /plugin install sym-mesh-channel@sym-mesh-channel
211
- ```
212
-
213
- Validates cleanly with `claude plugin validate .` and installs
214
- end-to-end with no manual steps.
215
-
216
- - **`LICENSE`** file (Apache-2.0). `package.json` already declared
217
- Apache-2.0 but no LICENSE text was present in the repo; this
218
- aligns the distribution with SPDX expectations.
219
-
220
- - **MMP §5.8 mesh-group support** LAN isolation via Bonjour service
221
- type so Claude Code sessions can join app-specific meshes (e.g.
222
- MeloTune mood rooms on `_melotune._tcp`) instead of the global
223
- `_sym._tcp` mesh. Enables cross-app CMB delivery without cross-app
224
- noise: nodes in different groups never discover each other at mDNS.
225
-
226
- Config surface (two equivalent paths):
227
- - `SYM_GROUP=<name>` → service type `_<name>._tcp`
228
- - `SYM_SERVICE_TYPE=<st>` → explicit override (`_foo._tcp` form)
229
-
230
- Default remains `_sym._tcp` / `group=default` backward compatible.
231
-
232
- - **Two new MCP tools for mesh-group operations**:
233
- - `sym_group_info` reports current group + service type + peer
234
- roster scoped to this group.
235
- - `sym_invite_info` — parses app-specific invite URLs
236
- (`melotune://room/{id}/{name}`, `sym://group/{name}`) into service
237
- type + group + room name. Read-only inspection; caller opens a
238
- new session/env to join.
239
-
240
- `sym_status` output now includes `Group` + service type.
241
-
242
- ### Fixed
243
-
244
- - **`plugin.json` validation failure on install.** The three
245
- `channels[0].userConfig` entries (`relay_url`, `relay_token`,
246
- `allowed_peers`) were missing the required `type` and `title`
247
- fields per the Claude Code plugin schema. Install failed with:
248
-
249
- ```
250
- channels.0.userConfig.relay_url.type: Invalid option
251
- channels.0.userConfig.relay_url.title: expected string, received undefined
252
- ```
253
-
254
- Added `type: "string"` and a human-readable `title` to all three.
255
- Likely one of the root causes of the 10 Apr 2026 submission
256
- showing "Published" on the Anthropic submissions portal but not
257
- propagating to the public `claude-plugins-official` marketplace.
258
-
259
- ### Changed
260
-
261
- - **README**: self-hosted plugin-marketplace install path promoted to
262
- the primary install recommendation (works today, independent of
263
- Anthropic directory propagation). npm path kept as alternative.
264
- Tool table updated 5 → 8 entries to reflect the current surface.
265
- Clarified that plugin-directory approval and Channels-allowlist
266
- inclusion are independent gates — the MCP tools work without the
267
- `--dangerously-load-development-channels` flag; the flag is only
268
- needed for the `<channel>` async-push behaviour.
269
-
270
- - Pairs with `@sym-bot/sym` 0.3.78 which added the
271
- `discoveryServiceType` and `group` constructor params consumed by
272
- the mesh-group tools.
273
-
274
- ## 0.1.21
275
-
276
- ### Changed
277
-
278
- - **README: accurate `sym_status` / `sym_peers` example output.** The
279
- Quick Start sample output was a stylized one-line compression; the
280
- real output is multi-line with additional fields (nodeId suffix,
281
- Relay, Memories, one peer per line). Updated so users see in the
282
- README exactly what their terminal will show. Doc-only — no code
283
- changes.
284
-
285
- ## 0.1.20
286
-
287
- ### Added
288
-
289
- - **`sym-mesh-channel init --project`** — new flag to install the MCP
290
- server at project scope (`<cwd>/.mcp.json` + merged
291
- `<cwd>/.claude/settings.local.json`) instead of global
292
- `~/.claude.json`. Enables multi-identity-per-machine workflows where
293
- several Claude Code sessions run in parallel from distinct project
294
- directories and each appears as its own peer on the mesh. Project
295
- `.mcp.json` entries override the global `mcpServers` entry when
296
- Claude Code launches from that directory, so `SYM_NODE_NAME` can
297
- differ per project without siblings stepping on each other.
298
- - Project mode supports the same `--force` semantics as global install:
299
- backs up existing `.mcp.json` and `settings.local.json` next to
300
- themselves (`*.bak-<timestamp>`), merges `settings.local.json` so
301
- unrelated keys (permissions, custom settings) are preserved, atomic
302
- writes via tmp+rename, refuses to overwrite an existing
303
- `claude-sym-mesh` entry without `--force`.
304
- - `--postinstall` always runs global install regardless of `--project`
305
- (npm postinstall runs from npm's staging dir, not the user's
306
- project). Keeps `npm install -g` auto-configure behavior unchanged.
307
- - **5 new tests** covering project-mode install: writes `.mcp.json`
308
- and `settings.local.json`, merge preserves existing keys, refusal
309
- path exits 2, `--force` overwrite creates backup, postinstall
310
- fallback ignores `--project`. Test suite now 22 tests total.
311
-
312
- ### Why
313
-
314
- Default mode (single mesh identity per machine, global install) is
315
- correct for most users and unchanged. `--project` exists for the
316
- small but real set of users who run multiple Claude Code sessions
317
- in parallel from distinct project directories and want each session
318
- to show up as its own peer on the mesh. Previously this workflow
319
- required hand-editing `.mcp.json` and `.claude/settings.local.json`
320
- per project; now it's one command per project.
321
-
322
- ## 0.1.19
323
-
324
- ### Added
325
-
326
- - **Claude Code plugin manifest** for Anthropic Channels allowlist
327
- submission. `.claude-plugin/plugin.json` + `.mcp.json` following the
328
- official single-repo pattern (Telegram/Discord). Submitted to
329
- Anthropic Plugin Directory 10 Apr 2026.
330
- - **`SYM_ALLOWED_PEERS`** — optional peer allowlist (defense-in-depth).
331
- Comma-separated node names; only listed peers can push to Claude's
332
- context. Empty = accept all authenticated peers. SVAF still gates on
333
- content relevance regardless.
334
- - **`SECURITY.md`** — 3-layer defense model documentation (transport
335
- auth + SVAF content gate + peer allowlist) for Anthropic review.
336
- - **17 plugin tests** covering manifest validation, security checks
337
- (no permission relay, no code execution, self-echo filtering, peer
338
- allowlist), and lifecycle (shutdown handlers, identity collision).
339
-
340
- ## 0.1.18
341
-
342
- ### Changed
343
-
344
- - **Auto-configure on install.** `npm install -g` now runs `postinstall`
345
- that writes the MCP server config to global `mcpServers` in
346
- `~/.claude.json` automatically. No separate `sym-mesh-channel init`
347
- step needed two commands to mesh: install + launch.
348
- - **Global MCP config** — server entry is now written to top-level
349
- `mcpServers` (available in all Claude Code sessions), not
350
- project-scoped.
351
- - **Windows postinstall fixes** `require.resolve` for server.js path
352
- (handles npm staging directory on Windows), EBUSY handling when
353
- Claude Code has `~/.claude.json` locked, graceful skip if Claude
354
- Code not yet installed.
355
- - **README repositioned** lead with capability ("first non-Anthropic
356
- Claude Code Channels implementation"), not use case. Simplified
357
- Quick Start to two commands.
358
- - **0 vulnerabilities** fresh dependency rebuild resolves all 6
359
- moderate hono/node-server advisories.
360
- - Windows mDNS: built-in on Windows 10+, no Bonjour install needed.
361
-
362
- ## 0.1.7
363
-
364
- ### Added
365
-
366
- - **`npx @sym-bot/mesh-channel init`** interactive installer that
367
- writes `~/.claude.json` for the current project, picks a sensible
368
- default `SYM_NODE_NAME` (`claude-mac` / `claude-win` / `claude-linux`),
369
- resolves the absolute path to `server.js`, and prints the launch
370
- command including the `--dangerously-load-development-channels` flag.
371
- Backs up the existing config to `~/.claude.json.bak-<timestamp>`,
372
- validates JSON round-trip, atomic write via tmp+rename. Refuses to
373
- overwrite an existing entry without `--force`.
374
- - **README rewritten for LAN-first install.** Quick start is two
375
- minutes: install, init, launch. No relay required. Bonjour/mDNS
376
- is the default discovery path. Cross-network setup (relay) is now
377
- the optional advanced section.
378
-
379
- ### Changed
380
-
381
- - `package.json` `bin` now exposes both `sym-mesh-channel` (server
382
- entrypoint) and `sym-mesh-channel-init` (installer). The package
383
- description leads with "LAN-first via Bonjour, no relay required."
384
-
385
- ### Why
386
-
387
- The 0.1.5/0.1.6 install path required users to manually edit
388
- `~/.claude.json`, know about the Channels dev flag, set up a relay,
389
- and obtain a relay token. That gated the demo behind real friction.
390
- LAN-only mode has worked since day one in the underlying SymNode
391
- (`sym/lib/node.js:509-511` only connects to the relay if `SYM_RELAY_URL`
392
- is set; Bonjour discovery starts unconditionally), but no documentation
393
- or installer surfaced it. This release closes that gap: two users on
394
- the same wifi can join the same mesh in two minutes with three commands.
395
-
396
- ## 0.1.6
397
-
398
- ### Fixed
399
-
400
- - `sym_send` no longer double-delivers. Previously called both
401
- `node.send()` (broadcast as `event_type=message`) AND `node.remember()`
402
- (persist as CMB which gets gossiped as `event_type=cmb`), causing
403
- the same payload to arrive twice on receivers and double the
404
- context-window cost. Now broadcasts the message frame only. Hosts
405
- that want CMB persistence should call `sym_observe` separately
406
- with proper CAT7 fields.
407
- - `sym_send` now reports the actual delivered count, not
408
- `peers().length`. Requires `@sym-bot/sym >= 0.3.70` where `send()`
409
- returns the count of peer transports that successfully accepted
410
- the broadcast. The two can disagree when peers are tracked but
411
- have broken transports — the delivered count is the truth about
412
- what was actually sent.
413
-
414
- ### Changed
415
-
416
- - Bumped `@sym-bot/sym` dep `^0.3.69` → `^0.3.70`. 0.3.70 ships the
417
- identity lockfile that prevents two SymNode processes from
418
- claiming the same nodeId on a host (the cliHostMode-vs-MCP
419
- collision that broke real-time push on Windows during the
420
- 2026-04-09 round-trip test).
421
-
422
- ## 0.1.5
423
-
424
- ### Changed
425
-
426
- - Bumped `@sym-bot/sym` dep `^0.3.68` `^0.3.69` (0.3.68 deprecated;
427
- same code in 0.3.69 with a cleaner published tarball).
428
- - Added `files` whitelist to `package.json` and `.npmignore` for
429
- `*.bak`, `*.swp`, `.DS_Store` so future publishes can't accidentally
430
- ship local backup files. First NPM publish of this package.
431
-
432
- ## 0.1.4
433
-
434
- ### Changed
435
-
436
- - Bumped `@sym-bot/sym` dep `^0.3.43` → `^0.3.68` to pick up
437
- duplicate-identity refusal (close code 4004) and the new
438
- `identity-collision` event.
439
-
440
- ### Added
441
-
442
- - Wired `node.on('identity-collision', ...)` to `process.exit(2)` so
443
- the MCP dies cleanly when the relay reports a duplicate-identity
444
- race. Together with v0.1.3's clean shutdown, this fully resolves
445
- the host-side half of the duplicate-identity bug.
446
-
447
- ## 0.1.3
448
-
449
- ### Added
450
-
451
- - Clean shutdown handlers (SIGTERM/SIGINT/SIGHUP) that call
452
- `node.stop()` before exiting, so the SymNode disconnects from the
453
- relay before the process dies. Without this, restarts left zombie
454
- registrations on the relay until the next heartbeat tick (up to
455
- 30s), creating a duplicate-identity race window for the next MCP
456
- spawn. Idempotent re-entry guard.
457
-
458
- ## 0.1.2
459
-
460
- ### Fixed
461
-
462
- - Suppressed `peer-joined` / `peer-left` events from being pushed to
463
- Claude's context as `<channel>` notifications. Presence is high-
464
- frequency and low-signal a relay reconnect could fire one event
465
- per peer per cycle, flooding the context window. CMBs and direct
466
- messages still flow through.
467
-
468
- ## 0.1.1
469
-
470
- ### Changed
471
-
472
- - Replaced hardcoded `claude-code` / `claude-code-mac` literals with
473
- a single `NODE_NAME` constant sourced from `process.env.SYM_NODE_NAME`
474
- (default `claude-code-mac`). Enables platform-scoped naming per
475
- MMP §3.1.2 without source edits. Fixed stale display strings in
476
- the MCP instructions, `sym_send` perspective, `sym_status` header,
477
- and the self-echo dedup filter.
478
-
479
- ## 0.1.0
480
-
481
- ### Added
482
-
483
- - Initial release. MCP server that runs a `SymNode` peer node inside
484
- a Claude Code session own identity, own relay connection, own
485
- SVAF evaluation. Tools: `sym_send`, `sym_observe`, `sym_recall`,
486
- `sym_peers`, `sym_status`. Mesh events arrive as `<channel>`
487
- notifications when launched with
488
- `claude --dangerously-load-development-channels server:claude-sym-mesh`
489
- (allowlisted server name required by Claude Code Channels).
1
+ # Changelog
2
+
3
+ ## 0.3.4
4
+
5
+ ### Added
6
+
7
+ - **`SYM_GROUP` is now first-class in the installer.** `init` accepts a
8
+ `--group <name>` flag and reads the `SYM_GROUP` env var; both paths
9
+ persist the chosen group into the `~/.claude.json` (or project
10
+ `.mcp.json`) env block so every Claude Code launch auto-joins the
11
+ named group instead of the global `_sym._tcp` mesh.
12
+
13
+ Resolution order is `--force`-aware:
14
+ - With `--force` and an explicit `--group`/`SYM_GROUP`: flag/env wins
15
+ (one-command group switch on a live entry).
16
+ - Without `--force`, or with `--force` but no explicit value:
17
+ preserved value from any existing entry > explicit > none (omit).
18
+
19
+ `--force --group default` (or `SYM_GROUP=default`) is the explicit
20
+ escape hatch to revert a node from a named group back to the global
21
+ mesh removes `SYM_GROUP` from the env block entirely rather than
22
+ writing the literal string "default".
23
+
24
+ Both `--group` and `SYM_GROUP` env values are validated against the
25
+ same kebab-case regex; malformed values exit with a clear error
26
+ before any file write.
27
+
28
+ - **`doctor` now reports the persisted group per entry** and warns when
29
+ user-global and project-scoped entries disagree on `SYM_GROUP`.
30
+ Group-mismatch is the most common cause of "peers never appear in
31
+ `sym_peers`" with no other failure signal — surfacing it inline saves
32
+ the diagnostic walk that motivated this release.
33
+
34
+ - **README** gains a "Persisting your group across restarts" subsection
35
+ under Team mesh groups, plus a troubleshooting entry covering the
36
+ group-mismatch failure mode. Quick-start shows the `--group` flag.
37
+
38
+ ### Fixed
39
+
40
+ - **Stale-entry heal preserves `SYM_GROUP` alongside `SYM_NODE_NAME`.**
41
+ Previously, healing a stale `claude-sym-mesh` entry (args[0] points at
42
+ a missing server.js) silently dropped any persisted `SYM_GROUP`,
43
+ reverting the node to the default mesh on next launch and stranding
44
+ teammates who stayed in the named group. The heal path now copies
45
+ both fields from the prior entry into the rewrite.
46
+
47
+ Same fix applied to project-scoped entry healing under
48
+ `claudeJson.projects[<path>].mcpServers`.
49
+
50
+ ### Why this matters
51
+
52
+ Before 0.3.4, the only way to persist a group was to hand-edit
53
+ `~/.claude.json`. The README pitched `sym_join_group` as the team-mesh
54
+ UX, but that tool is runtime-only the next Claude Code launch reverted
55
+ the node to the default mesh, peer count dropped to zero, and the user
56
+ saw no diagnostic signal. The 2026-05-02 SYM.BOT incident (CMO in
57
+ `default`, COO in `sym-bot-team`, ~24h of silent duplex outage) traced
58
+ directly to this gap.
59
+
60
+ ## 0.3.3
61
+
62
+ ### Fixed
63
+
64
+ - **Real-time duplex for CAT7 CMBs.** The `cmb-accepted` handler now
65
+ stores the rendered CMB body under an `[mNNN]` ID and includes that
66
+ ID in the channel notification, matching the contract stated in the
67
+ MCP instructions ("Messages arrive as compact headers with [mNNN] IDs
68
+ use sym_fetch to read the full content") and the behaviour of the
69
+ raw-text `message` path.
70
+
71
+ Previously only the legacy raw-text `message` event persisted bodies
72
+ to `MESSAGE_STORE` — the primary `cmb-accepted` event (fired for
73
+ every structured CMB delivered via `sym_send` / `sym_observe`) pushed
74
+ a headline with no `[mNNN]` and left no retrievable body. Inbound
75
+ CMBs were admitted to the SVAF-backed memory store and surfaced by
76
+ `sym_recall` as compact headlines, but `sym_fetch` could not return
77
+ their content the duplex was effectively headline-only for the 99%
78
+ case of real mesh traffic.
79
+
80
+ Symptom: after the 0.3.2 Mac↔Win fix restored bidirectional packet
81
+ flow, peers' structured replies appeared in `sym_recall` but returned
82
+ *"expired or invalid ID"* from `sym_fetch` — because `storeMessage()`
83
+ had never been called for them. Now both the raw-text and CAT7 paths
84
+ persist bodies identically.
85
+
86
+ ## 0.3.2
87
+
88
+ ### Fixed
89
+
90
+ - **Pulls in `@sym-bot/sym` 0.5.1** — fixes Mac↔Windows peer connections
91
+ over LAN. Prior releases shipped a Bonjour advertisement whose SRV
92
+ target was the bare Windows NetBIOS hostname (e.g. `xmesh-hp.`) with
93
+ no `.local` suffix. macOS mDNSResponder only resolves `.local.` mDNS
94
+ names, so Macs could discover Windows peers via bonjour browse but
95
+ failed to open the outbound TCP connection. CMBs targeted at Windows
96
+ nodes never arrived; no replies came back. Full diagnosis in sym
97
+ 0.5.1 CHANGELOG.
98
+
99
+ Upgrade required on both sides to restore Mac↔Windows traffic.
100
+ Existing Windows identities with a bare hostname are auto-migrated
101
+ on next node start; no manual config edit needed.
102
+
103
+ ## 0.3.1
104
+
105
+ ### Fixed
106
+
107
+ - **Installer no longer silently ships a broken MCP config.** Previously,
108
+ if `~/.claude.json` already contained a `claude-sym-mesh` entry,
109
+ `npm install -g @sym-bot/mesh-channel` (via postinstall) and
110
+ `npx @sym-bot/mesh-channel init` both skipped with "already configured"
111
+ even when the entry's `args[0]` server.js path no longer existed on
112
+ disk (common after moving or reinstalling the repo). Users saw
113
+ `/mcp` report "Failed to reconnect" with no diagnostic hint.
114
+
115
+ The installer now classifies entries whose `args[0]` is missing as
116
+ **stale** and rewrites them automatically without `--force`, preserving
117
+ `SYM_NODE_NAME` from the prior entry so mesh identity doesn't drift
118
+ back to the hostname-based default. Live entries continue to require
119
+ `--force` for overwrite.
120
+
121
+ - **Stale project-scoped entries are now healed too.** `~/.claude.json`
122
+ can carry per-project `mcpServers` overrides under
123
+ `projects.<dir>.mcpServers`, and Claude Code prefers those over the
124
+ user-global entry when launched from that directory. A healthy
125
+ user-global entry was therefore being silently shadowed by stale
126
+ project entries. `init` now scans every project, rewrites any stale
127
+ `claude-sym-mesh` entry, and preserves each project's `SYM_NODE_NAME`.
128
+
129
+ ### Added
130
+
131
+ - **`sym-mesh-channel doctor` subcommand.** Read-only diagnostic that
132
+ lists every `claude-sym-mesh` entry in `~/.claude.json` (user-global
133
+ and every project scope) with `[live]` or `[STALE]` plus its
134
+ `SYM_NODE_NAME` and configured path. Point users here when `/mcp`
135
+ reports "Failed to reconnect". No writes, safe to run any time.
136
+
137
+ - **README troubleshooting section** covering the `/mcp` failure path,
138
+ how to run `doctor`, and when restart is needed after a config change.
139
+
140
+ ### Changed
141
+
142
+ - `.claude-plugin/plugin.json` version field bumped to `0.3.1` to match
143
+ `package.json`. Previous drift (`plugin.json` stuck at `0.2.0`, package
144
+ at `0.3.0`) was caught by the in-repo version-parity test.
145
+
146
+ ## 0.3.0
147
+
148
+ ### Added
149
+
150
+ - **Startup remix-memory primer — automates agent memory recall on
151
+ session/agent restart (MMP §4.2 O2, rejoin-without-replay).** As the
152
+ final step of plugin initialisation (after `node.start()` and before
153
+ the MCP transport connects), the plugin calls
154
+ `node.buildStartupPrimer()` and appends the returned text to the MCP
155
+ server's `instructions` field. A fresh Claude Code session wakes
156
+ with the agent's own remix memory own observations plus peer
157
+ observations admitted by SVAF already loaded into context. No
158
+ first-turn `sym_recall` required; agent acts from prior state
159
+ immediately.
160
+
161
+ Default caps: last 24 hours OR 20 most recent CMBs, whichever is
162
+ tighter. The primer lists each entry as `[timestamp] source · key —
163
+ focus` and surfaces a dropped-count line when caps elide older
164
+ entries. Empty store is a silent no-op.
165
+
166
+ ### Changed
167
+
168
+ - **`@sym-bot/sym` dep bumped to `^0.5.0`** to pick up the
169
+ `buildStartupPrimer` helper and to keep every plugin on the
170
+ sym.day platform pinned to the same substrate SDK version
171
+ (no drift across mesh-channel / melotune-plugin / future
172
+ specialised plugins).
173
+
174
+ ## 0.2.0
175
+
176
+ ### Breaking
177
+
178
+ - **`sym_send` tool signature change.** `sym_send` now emits a structured
179
+ CAT7 CMB (MMP §4.2) instead of a raw-text `type:'message'` frame, and
180
+ accepts an optional `to` parameter for targeted single-peer delivery
181
+ per MMP §4.4.4.
182
+
183
+ Old signature: `sym_send(message: string)`
184
+ New signature: `sym_send(focus: string (required), issue?, intent?,
185
+ motivation?, commitment?, perspective?, mood?, to?)`
186
+
187
+ Migration: agents that previously called `sym_send({message: "..."})`
188
+ should now pass the CAT7 fields explicitly, with `focus` carrying the
189
+ task anchor for the send. Prior ephemeral text-broadcast behaviour is
190
+ no longer exposed at the tool surface — `sym_send` and `sym_observe`
191
+ both emit CMBs now, receivers run SVAF per §9.2, and admitted CMBs are
192
+ remix-stored with lineage. The low-level `node.send(text)` SDK API is
193
+ unchanged but no longer surfaced as a tool.
194
+
195
+ ### Added
196
+
197
+ - **Targeted CMB send.** `sym_send` resolves `to` against connected
198
+ peers by full nodeId first, then display name, then 8-char prefix.
199
+ Ambiguous matches return an error asking for the full nodeId; a
200
+ disconnected target returns an error and suggests `sym_peers`.
201
+ - **Tool descriptions** for `sym_send` and `sym_observe` now explicitly
202
+ call out the SVAF receive path and lineage semantics, and the MCP
203
+ server's `instructions` string reflects the new division of labour.
204
+ - **`@sym-bot/sym` dependency bumped to `^0.3.81`** for
205
+ `remember(fields, {to})` targeted variant and `peers().peerId`.
206
+
207
+ ## 0.1.23
208
+
209
+ ### Added
210
+
211
+ - **`sym_join_group(group, relay_url?, relay_token?)`** — hot-swap this
212
+ node into a different mesh group at runtime, no Claude Code restart.
213
+ Stops the current SymNode, reconstructs it on the new service type
214
+ (and optional relay), re-registers event handlers, restarts. The
215
+ "smooth way to join" that was missing in 0.1.22.
216
+
217
+ - **`sym_invite_create(group, relay_url?, relay_token?)`** generate
218
+ a shareable invite URL for a named group. Two flavors:
219
+ - LAN-only: `sym://group/{name}` (Bonjour isolation only)
220
+ - Cross-network: `sym://team/{name}?relay=...&token=...` (routes via
221
+ a WebSocket relay so teammates on different networks can join).
222
+ Validates kebab-case group names, rejects token without URL.
223
+
224
+ - **`sym_invite_info(url)`** extended to parse the new `sym://team/`
225
+ path and the `relay=` + `token=` query-string parameters.
226
+ Output now includes a ready-to-paste `sym_join_group` call as JSON.
227
+
228
+ - **`sym_groups_discover()`** enumerate SYM-mesh groups currently
229
+ advertising on the local LAN via Bonjour / mDNS. Shell-outs to
230
+ `dns-sd` (macOS/Windows) or `avahi-browse` (Linux) with a 2-second
231
+ timeout, filters to service types matching the SYM protocol family
232
+ (global `_sym._tcp`, named groups, `{app}-{id}` rooms). Peer-to-peer
233
+ means only groups with live members right now are visible — no
234
+ central directory.
235
+
236
+ - **README "Dev-team groups" walkthrough** with two concrete scenarios:
237
+ LAN dev-team group (single office) and cross-network team group via
238
+ the public `wss://sym-relay.onrender.com` relay. Shows exact tool
239
+ calls from both the team lead and each teammate.
240
+
241
+ - **13 new tests** covering invite URL parse, generate, round-trip, and
242
+ validation (kebab-case, token-requires-URL guard). Test suite now at
243
+ 35 tests total.
244
+
245
+ ### Changed
246
+
247
+ - Module-level `node`, `GROUP`, `SERVICE_TYPE`, `RELAY_URL`,
248
+ `RELAY_TOKEN` declared as `let` (was `const`) so the hot-swap path
249
+ can re-bind them. All node event handlers (`identity-collision`,
250
+ `cmb-accepted`, `message`) extracted into a single
251
+ `registerNodeHandlers(n)` function so the hot-swap path re-attaches
252
+ them without duplicating logic.
253
+
254
+ - Tool count in README corrected to 11 (was 8 in 0.1.22):
255
+ + sym_invite_create, sym_join_group, sym_groups_discover.
256
+
257
+ ## 0.1.22
258
+
259
+ ### Added
260
+
261
+ - **Plugin marketplace distribution**: `.claude-plugin/marketplace.json`
262
+ enables direct install via the Claude Code plugin marketplace without
263
+ waiting on the Anthropic Plugin Directory propagation pipeline:
264
+
265
+ ```
266
+ /plugin marketplace add sym-bot/sym-mesh-channel
267
+ /plugin install sym-mesh-channel@sym-mesh-channel
268
+ ```
269
+
270
+ Validates cleanly with `claude plugin validate .` and installs
271
+ end-to-end with no manual steps.
272
+
273
+ - **`LICENSE`** file (Apache-2.0). `package.json` already declared
274
+ Apache-2.0 but no LICENSE text was present in the repo; this
275
+ aligns the distribution with SPDX expectations.
276
+
277
+ - **MMP §5.8 mesh-group support** — LAN isolation via Bonjour service
278
+ type so Claude Code sessions can join app-specific meshes (e.g.
279
+ MeloTune mood rooms on `_melotune._tcp`) instead of the global
280
+ `_sym._tcp` mesh. Enables cross-app CMB delivery without cross-app
281
+ noise: nodes in different groups never discover each other at mDNS.
282
+
283
+ Config surface (two equivalent paths):
284
+ - `SYM_GROUP=<name>` → service type `_<name>._tcp`
285
+ - `SYM_SERVICE_TYPE=<st>` → explicit override (`_foo._tcp` form)
286
+
287
+ Default remains `_sym._tcp` / `group=default` — backward compatible.
288
+
289
+ - **Two new MCP tools for mesh-group operations**:
290
+ - `sym_group_info` reports current group + service type + peer
291
+ roster scoped to this group.
292
+ - `sym_invite_info` — parses app-specific invite URLs
293
+ (`melotune://room/{id}/{name}`, `sym://group/{name}`) into service
294
+ type + group + room name. Read-only inspection; caller opens a
295
+ new session/env to join.
296
+
297
+ `sym_status` output now includes `Group` + service type.
298
+
299
+ ### Fixed
300
+
301
+ - **`plugin.json` validation failure on install.** The three
302
+ `channels[0].userConfig` entries (`relay_url`, `relay_token`,
303
+ `allowed_peers`) were missing the required `type` and `title`
304
+ fields per the Claude Code plugin schema. Install failed with:
305
+
306
+ ```
307
+ channels.0.userConfig.relay_url.type: Invalid option
308
+ channels.0.userConfig.relay_url.title: expected string, received undefined
309
+ ```
310
+
311
+ Added `type: "string"` and a human-readable `title` to all three.
312
+ Likely one of the root causes of the 10 Apr 2026 submission
313
+ showing "Published" on the Anthropic submissions portal but not
314
+ propagating to the public `claude-plugins-official` marketplace.
315
+
316
+ ### Changed
317
+
318
+ - **README**: self-hosted plugin-marketplace install path promoted to
319
+ the primary install recommendation (works today, independent of
320
+ Anthropic directory propagation). npm path kept as alternative.
321
+ Tool table updated 5 → 8 entries to reflect the current surface.
322
+ Clarified that plugin-directory approval and Channels-allowlist
323
+ inclusion are independent gates — the MCP tools work without the
324
+ `--dangerously-load-development-channels` flag; the flag is only
325
+ needed for the `<channel>` async-push behaviour.
326
+
327
+ - Pairs with `@sym-bot/sym` 0.3.78 which added the
328
+ `discoveryServiceType` and `group` constructor params consumed by
329
+ the mesh-group tools.
330
+
331
+ ## 0.1.21
332
+
333
+ ### Changed
334
+
335
+ - **README: accurate `sym_status` / `sym_peers` example output.** The
336
+ Quick Start sample output was a stylized one-line compression; the
337
+ real output is multi-line with additional fields (nodeId suffix,
338
+ Relay, Memories, one peer per line). Updated so users see in the
339
+ README exactly what their terminal will show. Doc-only — no code
340
+ changes.
341
+
342
+ ## 0.1.20
343
+
344
+ ### Added
345
+
346
+ - **`sym-mesh-channel init --project`** — new flag to install the MCP
347
+ server at project scope (`<cwd>/.mcp.json` + merged
348
+ `<cwd>/.claude/settings.local.json`) instead of global
349
+ `~/.claude.json`. Enables multi-identity-per-machine workflows where
350
+ several Claude Code sessions run in parallel from distinct project
351
+ directories and each appears as its own peer on the mesh. Project
352
+ `.mcp.json` entries override the global `mcpServers` entry when
353
+ Claude Code launches from that directory, so `SYM_NODE_NAME` can
354
+ differ per project without siblings stepping on each other.
355
+ - Project mode supports the same `--force` semantics as global install:
356
+ backs up existing `.mcp.json` and `settings.local.json` next to
357
+ themselves (`*.bak-<timestamp>`), merges `settings.local.json` so
358
+ unrelated keys (permissions, custom settings) are preserved, atomic
359
+ writes via tmp+rename, refuses to overwrite an existing
360
+ `claude-sym-mesh` entry without `--force`.
361
+ - `--postinstall` always runs global install regardless of `--project`
362
+ (npm postinstall runs from npm's staging dir, not the user's
363
+ project). Keeps `npm install -g` auto-configure behavior unchanged.
364
+ - **5 new tests** covering project-mode install: writes `.mcp.json`
365
+ and `settings.local.json`, merge preserves existing keys, refusal
366
+ path exits 2, `--force` overwrite creates backup, postinstall
367
+ fallback ignores `--project`. Test suite now 22 tests total.
368
+
369
+ ### Why
370
+
371
+ Default mode (single mesh identity per machine, global install) is
372
+ correct for most users and unchanged. `--project` exists for the
373
+ small but real set of users who run multiple Claude Code sessions
374
+ in parallel from distinct project directories and want each session
375
+ to show up as its own peer on the mesh. Previously this workflow
376
+ required hand-editing `.mcp.json` and `.claude/settings.local.json`
377
+ per project; now it's one command per project.
378
+
379
+ ## 0.1.19
380
+
381
+ ### Added
382
+
383
+ - **Claude Code plugin manifest** for Anthropic Channels allowlist
384
+ submission. `.claude-plugin/plugin.json` + `.mcp.json` following the
385
+ official single-repo pattern (Telegram/Discord). Submitted to
386
+ Anthropic Plugin Directory 10 Apr 2026.
387
+ - **`SYM_ALLOWED_PEERS`** optional peer allowlist (defense-in-depth).
388
+ Comma-separated node names; only listed peers can push to Claude's
389
+ context. Empty = accept all authenticated peers. SVAF still gates on
390
+ content relevance regardless.
391
+ - **`SECURITY.md`** 3-layer defense model documentation (transport
392
+ auth + SVAF content gate + peer allowlist) for Anthropic review.
393
+ - **17 plugin tests** covering manifest validation, security checks
394
+ (no permission relay, no code execution, self-echo filtering, peer
395
+ allowlist), and lifecycle (shutdown handlers, identity collision).
396
+
397
+ ## 0.1.18
398
+
399
+ ### Changed
400
+
401
+ - **Auto-configure on install.** `npm install -g` now runs `postinstall`
402
+ that writes the MCP server config to global `mcpServers` in
403
+ `~/.claude.json` automatically. No separate `sym-mesh-channel init`
404
+ step needed two commands to mesh: install + launch.
405
+ - **Global MCP config** server entry is now written to top-level
406
+ `mcpServers` (available in all Claude Code sessions), not
407
+ project-scoped.
408
+ - **Windows postinstall fixes** — `require.resolve` for server.js path
409
+ (handles npm staging directory on Windows), EBUSY handling when
410
+ Claude Code has `~/.claude.json` locked, graceful skip if Claude
411
+ Code not yet installed.
412
+ - **README repositioned** — lead with capability ("first non-Anthropic
413
+ Claude Code Channels implementation"), not use case. Simplified
414
+ Quick Start to two commands.
415
+ - **0 vulnerabilities** — fresh dependency rebuild resolves all 6
416
+ moderate hono/node-server advisories.
417
+ - Windows mDNS: built-in on Windows 10+, no Bonjour install needed.
418
+
419
+ ## 0.1.7
420
+
421
+ ### Added
422
+
423
+ - **`npx @sym-bot/mesh-channel init`** — interactive installer that
424
+ writes `~/.claude.json` for the current project, picks a sensible
425
+ default `SYM_NODE_NAME` (`claude-mac` / `claude-win` / `claude-linux`),
426
+ resolves the absolute path to `server.js`, and prints the launch
427
+ command including the `--dangerously-load-development-channels` flag.
428
+ Backs up the existing config to `~/.claude.json.bak-<timestamp>`,
429
+ validates JSON round-trip, atomic write via tmp+rename. Refuses to
430
+ overwrite an existing entry without `--force`.
431
+ - **README rewritten for LAN-first install.** Quick start is two
432
+ minutes: install, init, launch. No relay required. Bonjour/mDNS
433
+ is the default discovery path. Cross-network setup (relay) is now
434
+ the optional advanced section.
435
+
436
+ ### Changed
437
+
438
+ - `package.json` `bin` now exposes both `sym-mesh-channel` (server
439
+ entrypoint) and `sym-mesh-channel-init` (installer). The package
440
+ description leads with "LAN-first via Bonjour, no relay required."
441
+
442
+ ### Why
443
+
444
+ The 0.1.5/0.1.6 install path required users to manually edit
445
+ `~/.claude.json`, know about the Channels dev flag, set up a relay,
446
+ and obtain a relay token. That gated the demo behind real friction.
447
+ LAN-only mode has worked since day one in the underlying SymNode
448
+ (`sym/lib/node.js:509-511` only connects to the relay if `SYM_RELAY_URL`
449
+ is set; Bonjour discovery starts unconditionally), but no documentation
450
+ or installer surfaced it. This release closes that gap: two users on
451
+ the same wifi can join the same mesh in two minutes with three commands.
452
+
453
+ ## 0.1.6
454
+
455
+ ### Fixed
456
+
457
+ - `sym_send` no longer double-delivers. Previously called both
458
+ `node.send()` (broadcast as `event_type=message`) AND `node.remember()`
459
+ (persist as CMB which gets gossiped as `event_type=cmb`), causing
460
+ the same payload to arrive twice on receivers and double the
461
+ context-window cost. Now broadcasts the message frame only. Hosts
462
+ that want CMB persistence should call `sym_observe` separately
463
+ with proper CAT7 fields.
464
+ - `sym_send` now reports the actual delivered count, not
465
+ `peers().length`. Requires `@sym-bot/sym >= 0.3.70` where `send()`
466
+ returns the count of peer transports that successfully accepted
467
+ the broadcast. The two can disagree when peers are tracked but
468
+ have broken transports — the delivered count is the truth about
469
+ what was actually sent.
470
+
471
+ ### Changed
472
+
473
+ - Bumped `@sym-bot/sym` dep `^0.3.69` `^0.3.70`. 0.3.70 ships the
474
+ identity lockfile that prevents two SymNode processes from
475
+ claiming the same nodeId on a host (the cliHostMode-vs-MCP
476
+ collision that broke real-time push on Windows during the
477
+ 2026-04-09 round-trip test).
478
+
479
+ ## 0.1.5
480
+
481
+ ### Changed
482
+
483
+ - Bumped `@sym-bot/sym` dep `^0.3.68` `^0.3.69` (0.3.68 deprecated;
484
+ same code in 0.3.69 with a cleaner published tarball).
485
+ - Added `files` whitelist to `package.json` and `.npmignore` for
486
+ `*.bak`, `*.swp`, `.DS_Store` so future publishes can't accidentally
487
+ ship local backup files. First NPM publish of this package.
488
+
489
+ ## 0.1.4
490
+
491
+ ### Changed
492
+
493
+ - Bumped `@sym-bot/sym` dep `^0.3.43` → `^0.3.68` to pick up
494
+ duplicate-identity refusal (close code 4004) and the new
495
+ `identity-collision` event.
496
+
497
+ ### Added
498
+
499
+ - Wired `node.on('identity-collision', ...)` to `process.exit(2)` so
500
+ the MCP dies cleanly when the relay reports a duplicate-identity
501
+ race. Together with v0.1.3's clean shutdown, this fully resolves
502
+ the host-side half of the duplicate-identity bug.
503
+
504
+ ## 0.1.3
505
+
506
+ ### Added
507
+
508
+ - Clean shutdown handlers (SIGTERM/SIGINT/SIGHUP) that call
509
+ `node.stop()` before exiting, so the SymNode disconnects from the
510
+ relay before the process dies. Without this, restarts left zombie
511
+ registrations on the relay until the next heartbeat tick (up to
512
+ 30s), creating a duplicate-identity race window for the next MCP
513
+ spawn. Idempotent re-entry guard.
514
+
515
+ ## 0.1.2
516
+
517
+ ### Fixed
518
+
519
+ - Suppressed `peer-joined` / `peer-left` events from being pushed to
520
+ Claude's context as `<channel>` notifications. Presence is high-
521
+ frequency and low-signal — a relay reconnect could fire one event
522
+ per peer per cycle, flooding the context window. CMBs and direct
523
+ messages still flow through.
524
+
525
+ ## 0.1.1
526
+
527
+ ### Changed
528
+
529
+ - Replaced hardcoded `claude-code` / `claude-code-mac` literals with
530
+ a single `NODE_NAME` constant sourced from `process.env.SYM_NODE_NAME`
531
+ (default `claude-code-mac`). Enables platform-scoped naming per
532
+ MMP §3.1.2 without source edits. Fixed stale display strings in
533
+ the MCP instructions, `sym_send` perspective, `sym_status` header,
534
+ and the self-echo dedup filter.
535
+
536
+ ## 0.1.0
537
+
538
+ ### Added
539
+
540
+ - Initial release. MCP server that runs a `SymNode` peer node inside
541
+ a Claude Code session — own identity, own relay connection, own
542
+ SVAF evaluation. Tools: `sym_send`, `sym_observe`, `sym_recall`,
543
+ `sym_peers`, `sym_status`. Mesh events arrive as `<channel>`
544
+ notifications when launched with
545
+ `claude --dangerously-load-development-channels server:claude-sym-mesh`
546
+ (allowlisted server name required by Claude Code Channels).