@sym-bot/mesh-channel 0.3.13 → 0.3.14
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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +11 -0
- package/README.md +33 -19
- package/bin/install.js +97 -6
- package/package.json +1 -1
- package/server.js +4 -2
- package/.claude-plugin/marketplace.json +0 -46
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.14
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`sym-mesh-channel start` — one command to a live mesh session.** Configures the MCP server if needed, then launches Claude Code with the real-time Channels flag already on, so users never type `--dangerously-load-development-channels …` or have to choose between the `plugin:` and `server:` handle. `start --project --name <node> --group <team>` stands up a named mesh agent; `start --print` is a dry run; everything after `--` is forwarded to `claude`. Co-resident sessions don't collide (server.js auto-suffixes a live-identity clash since 0.3.10), so `start` in several terminals just works.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **CLI subcommand dispatch via the published bin.** The `bin` entrypoint (`server.js`) only routed `init` to the installer, so `npx @sym-bot/mesh-channel doctor` silently fell through and started the MCP server instead. Now `init`, `doctor`, and `start` all route to the installer/launcher.
|
|
12
|
+
- **`init --force` with an explicit `SYM_NODE_NAME` now relabels the entry** instead of always preserving the prior name (symmetric with how `--group` already behaves). A routine reinstall with no explicit name still preserves identity.
|
|
13
|
+
|
|
3
14
|
## 0.3.13
|
|
4
15
|
|
|
5
16
|
### Changed
|
package/README.md
CHANGED
|
@@ -66,37 +66,39 @@ They're **not alternatives** — the channel is built *on* sym and speaks the sa
|
|
|
66
66
|
|
|
67
67
|
## Quick start
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
**One command — it configures the mesh and launches Claude Code with real-time push already on:**
|
|
70
70
|
|
|
71
71
|
```
|
|
72
|
-
|
|
73
|
-
/plugin install sym-mesh-channel@claude-community
|
|
72
|
+
npx @sym-bot/mesh-channel@latest start
|
|
74
73
|
```
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
Run it in any repo, in as many terminals as you like — the sessions discover each other over loopback (or the same wifi) and **think together in real time**. No flag to remember, no `plugin:` vs `server:` to choose — `start` wires the channel for you. (First run configures the MCP server; after that it just launches. Co-resident sessions don't collide — each becomes its own peer.)
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
Want the always-latest build straight from the source repo? Add it as its own marketplace instead:
|
|
77
|
+
Stand up a persistent **named** agent, or join a team room:
|
|
81
78
|
|
|
82
79
|
```
|
|
83
|
-
|
|
84
|
-
/plugin install sym-mesh-channel@sym-mesh-channel
|
|
80
|
+
npx @sym-bot/mesh-channel@latest start --name cto --group my-team
|
|
85
81
|
```
|
|
86
82
|
|
|
87
|
-
|
|
83
|
+
(`start --print` shows the exact `claude …` command without launching; anything after `--` is passed straight to `claude`, e.g. `… start -- --resume`.)
|
|
84
|
+
|
|
85
|
+
### Prefer the Claude Code plugin UI?
|
|
88
86
|
|
|
89
|
-
|
|
87
|
+
Install the plugin and you get the 11 MCP tools immediately:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
/plugin install sym-mesh-channel@claude-community
|
|
91
|
+
```
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
For real-time push on this path, launch with the channel flag (the handle must match where you installed from):
|
|
92
94
|
|
|
93
95
|
```
|
|
94
96
|
claude --dangerously-load-development-channels plugin:sym-mesh-channel@claude-community
|
|
95
97
|
```
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
Want the latest build before the community directory syncs? Add SYM.BOT's own catalog instead — `/plugin marketplace add sym-bot/marketplace`, then `/plugin install sym-mesh-channel@sym-bot` (and launch with `plugin:sym-mesh-channel@sym-bot`).
|
|
98
100
|
|
|
99
|
-
The flag
|
|
101
|
+
> **The dev flag is temporary** — an Anthropic-side gate while the channel awaits the approved-channels allowlist ([anthropics/claude-plugins-official#1512](https://github.com/anthropics/claude-plugins-official/issues/1512)). `start` passes it under the hood today; once the channel is allowlisted it disappears. Curious when to use the npm/server install directly (named agents, repo-committed team config, the `sym` CLI)? See [Advanced](#advanced-named-agents-teams--the-cli).
|
|
100
102
|
|
|
101
103
|
## What you get
|
|
102
104
|
|
|
@@ -234,7 +236,9 @@ The plugin composes two open specs:
|
|
|
234
236
|
|
|
235
237
|
## Advanced: per-project node identity
|
|
236
238
|
|
|
237
|
-
|
|
239
|
+
*(npm / MCP-server install only — plugin sessions already get a distinct peer identity each.)*
|
|
240
|
+
|
|
241
|
+
With the global npm install, every Claude Code session on the machine shares one mesh identity (set in `~/.claude.json`). To give each project directory its own stable peer name instead — e.g. a "research" session and a "strategy" session on the same laptop — install per-project:
|
|
238
242
|
|
|
239
243
|
```bash
|
|
240
244
|
cd path/to/your/project
|
|
@@ -345,7 +349,7 @@ Some corporate networks block mDNS multicast entirely — try a hotspot or home
|
|
|
345
349
|
|
|
346
350
|
The 11 tools work without any flag. The real-time `<channel>` **push** is separate: Claude Code only delivers channel notifications for channels on its **approved-channels allowlist**, and sym-mesh-channel isn't on it yet — so push requires the development-channels flag matching your install path:
|
|
347
351
|
|
|
348
|
-
- plugin install: `--dangerously-load-development-channels plugin:sym-mesh-channel@claude-community` (or `@sym-
|
|
352
|
+
- plugin install: `--dangerously-load-development-channels plugin:sym-mesh-channel@claude-community` (or `@sym-bot` if you installed from the source-repo marketplace — the handle must match your install source)
|
|
349
353
|
- npm install: `--dangerously-load-development-channels server:claude-sym-mesh`
|
|
350
354
|
|
|
351
355
|
This is an Anthropic-side gate, not a bug here — once the channel is allowlisted the flag is no longer needed. Tracked in [anthropics/claude-plugins-official#1512](https://github.com/anthropics/claude-plugins-official/issues/1512).
|
|
@@ -358,15 +362,25 @@ Your shell profile (`~/.zshrc`, `~/.bashrc`) exports `SYM_RELAY_URL`. Claude Cod
|
|
|
358
362
|
|
|
359
363
|
Don't. Each session should have a distinct `SYM_NODE_NAME`. The SymNode acquires an exclusive lockfile on its identity (`~/.sym/nodes/<name>/lock.pid`) and refuses to start a second process with the same name. If you see `EIDENTITYLOCK`, kill the other process or pick a different name. For multiple parallel sessions with their own identities, use the per-project install above.
|
|
360
364
|
|
|
361
|
-
##
|
|
365
|
+
## Advanced: named agents, teams & the CLI
|
|
362
366
|
|
|
363
|
-
|
|
367
|
+
Everything above uses the plugin — all most users need. Install the engine as an npm package / MCP server instead **only** when you want one of these:
|
|
368
|
+
|
|
369
|
+
- **A persistent, *named* agent.** The plugin auto-names each session (`claude-myrepo-3f9a`); the server install lets you pin `SYM_NODE_NAME=cto` so the node always appears under the same name in `sym_peers`, mesh memory, and CMB lineage — a durable agent identity, not an anonymous session.
|
|
370
|
+
- **Team config committed to a repo.** Config lives in a project `.mcp.json`, so you can commit `SYM_GROUP=backend-team` (plus relay URL/token) into the repo — anyone who opens it in Claude Code auto-joins the team room with zero per-person setup.
|
|
371
|
+
- **The `sym` CLI and non-Claude agents.** This also installs [`@sym-bot/sym`](https://github.com/sym-bot/sym), giving you `sym ask` / `sym groups` in your terminal and an engine that other agents, scripts, and languages can share.
|
|
364
372
|
|
|
365
373
|
```bash
|
|
366
374
|
npm install -g @sym-bot/mesh-channel
|
|
367
375
|
```
|
|
368
376
|
|
|
369
|
-
|
|
377
|
+
This registers a raw MCP server keyed `claude-sym-mesh`. Because it's a server (not a plugin), its real-time channel handle is **`server:claude-sym-mesh`** — so launch with:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
claude --dangerously-load-development-channels server:claude-sym-mesh
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Pin a fixed per-session identity with [per-project node identity](#advanced-per-project-node-identity); set relay credentials in the env block per [cross-network setup](#cross-network-setup-own-hosted-relay).
|
|
370
384
|
|
|
371
385
|
## References
|
|
372
386
|
|
package/bin/install.js
CHANGED
|
@@ -55,8 +55,8 @@ const cmd = args.find((a) => !a.startsWith('--')) || 'init';
|
|
|
55
55
|
const groupArgIdx = args.indexOf('--group');
|
|
56
56
|
const groupArg = groupArgIdx !== -1 ? args[groupArgIdx + 1] : null;
|
|
57
57
|
|
|
58
|
-
if (cmd !== 'init' && cmd !== 'doctor') {
|
|
59
|
-
process.stderr.write(`Unknown command: ${cmd}\nUsage: sym-mesh-channel init [--project] [--force] [--group <name>]\n sym-mesh-channel doctor\n`);
|
|
58
|
+
if (cmd !== 'init' && cmd !== 'doctor' && cmd !== 'start') {
|
|
59
|
+
process.stderr.write(`Unknown command: ${cmd}\nUsage: sym-mesh-channel start [--project] [--name <node>] [--group <name>] [-- <claude args>]\n sym-mesh-channel init [--project] [--force] [--group <name>]\n sym-mesh-channel doctor\n`);
|
|
60
60
|
process.exit(1);
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -111,6 +111,92 @@ function preserveGroup(entry) {
|
|
|
111
111
|
return g || null;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
// ── start: one command to a live mesh session ─────────────────────
|
|
115
|
+
// `sym-mesh-channel start` configures the MCP server (only if needed)
|
|
116
|
+
// and then launches Claude Code with the real-time Channels flag
|
|
117
|
+
// already on — so the user never types `--dangerously-load-development-
|
|
118
|
+
// channels …` or has to choose between the plugin: and server: handle.
|
|
119
|
+
// The npx / MCP-server install path always exposes the channel as a raw
|
|
120
|
+
// server, so the handle is deterministically `server:claude-sym-mesh`.
|
|
121
|
+
//
|
|
122
|
+
// sym-mesh-channel start # this dir, real-time push on
|
|
123
|
+
// sym-mesh-channel start --project --name cto --group my-team
|
|
124
|
+
// sym-mesh-channel start --print # show the command, don't launch
|
|
125
|
+
// sym-mesh-channel start -- --resume # pass args through to claude
|
|
126
|
+
//
|
|
127
|
+
// Co-resident sessions sharing one config don't collide: server.js
|
|
128
|
+
// auto-suffixes a live-identity clash (since 0.3.10), so each session
|
|
129
|
+
// becomes its own peer.
|
|
130
|
+
if (cmd === 'start') {
|
|
131
|
+
const { spawnSync } = require('child_process');
|
|
132
|
+
|
|
133
|
+
const nameArgIdx = args.indexOf('--name');
|
|
134
|
+
const nameArg = nameArgIdx !== -1 ? args[nameArgIdx + 1] : null;
|
|
135
|
+
const printOnly = args.includes('--print') || args.includes('--dry-run');
|
|
136
|
+
|
|
137
|
+
// Everything after `--` is forwarded verbatim to `claude`.
|
|
138
|
+
const dashDash = args.indexOf('--');
|
|
139
|
+
const passthrough = dashDash !== -1 ? args.slice(dashDash + 1) : [];
|
|
140
|
+
|
|
141
|
+
const launchDir = process.cwd();
|
|
142
|
+
|
|
143
|
+
const handle = 'server:claude-sym-mesh';
|
|
144
|
+
const claudeArgs = ['--dangerously-load-development-channels', handle, ...passthrough];
|
|
145
|
+
|
|
146
|
+
// --print is a pure dry-run: show the launch command, change nothing.
|
|
147
|
+
if (printOnly) {
|
|
148
|
+
console.log(`claude ${claudeArgs.join(' ')}`);
|
|
149
|
+
process.exit(0);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Is the scope Claude Code will actually read already configured with a
|
|
153
|
+
// LIVE entry? --project → <cwd>/.mcp.json ; otherwise → ~/.claude.json
|
|
154
|
+
function liveEntryInScope() {
|
|
155
|
+
try {
|
|
156
|
+
const p = isProject
|
|
157
|
+
? path.join(launchDir, '.mcp.json')
|
|
158
|
+
: path.join(os.homedir(), '.claude.json');
|
|
159
|
+
if (!fs.existsSync(p)) return null;
|
|
160
|
+
const j = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
161
|
+
const e = j && j.mcpServers && j.mcpServers['claude-sym-mesh'];
|
|
162
|
+
return e && !isStaleEntry(e) ? e : null;
|
|
163
|
+
} catch { return null; }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const existing = liveEntryInScope();
|
|
167
|
+
const wantName = nameArg || null;
|
|
168
|
+
const wantGroup = groupArg || null;
|
|
169
|
+
const mismatch = !!existing && (
|
|
170
|
+
(wantName && preserveNodeName(existing) !== wantName) ||
|
|
171
|
+
(wantGroup && (preserveGroup(existing) || 'default') !== wantGroup)
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// Configure only when there's nothing live yet, an explicit --name/--group
|
|
175
|
+
// differs from the current entry, or --force was passed. Otherwise launch
|
|
176
|
+
// straight away — `start` stays cheap to run every session.
|
|
177
|
+
if (!existing || mismatch || force) {
|
|
178
|
+
const initArgs = ['init'];
|
|
179
|
+
if (isProject) initArgs.push('--project');
|
|
180
|
+
if (groupArg) initArgs.push('--group', groupArg);
|
|
181
|
+
if (existing && (mismatch || force)) initArgs.push('--force');
|
|
182
|
+
const childEnv = Object.assign({}, process.env);
|
|
183
|
+
if (nameArg) childEnv.SYM_NODE_NAME = nameArg;
|
|
184
|
+
const r = spawnSync(process.execPath, [__filename, ...initArgs], {
|
|
185
|
+
stdio: 'inherit', env: childEnv, cwd: launchDir,
|
|
186
|
+
});
|
|
187
|
+
if (r.status !== 0) process.exit(r.status == null ? 1 : r.status);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
console.log(`\n▶ Launching Claude Code on the SYM mesh — real-time push on.\n (channel: ${handle}; the dev flag is temporary until Anthropic allowlists it)\n`);
|
|
191
|
+
const run = spawnSync('claude', claudeArgs, { stdio: 'inherit', cwd: launchDir });
|
|
192
|
+
if (run.error && run.error.code === 'ENOENT') {
|
|
193
|
+
process.stderr.write('ERROR: `claude` was not found on your PATH.\n');
|
|
194
|
+
process.stderr.write('Install Claude Code (https://claude.com/code), make sure `claude` runs in your terminal, then re-run `sym-mesh-channel start`.\n');
|
|
195
|
+
process.exit(127);
|
|
196
|
+
}
|
|
197
|
+
process.exit(run.status == null ? 0 : run.status);
|
|
198
|
+
}
|
|
199
|
+
|
|
114
200
|
// --postinstall always runs global install (npm postinstall runs from
|
|
115
201
|
// npm's staging directory, not the user's project dir). If both flags
|
|
116
202
|
// are passed, the --project flag is ignored during postinstall.
|
|
@@ -219,9 +305,12 @@ if (useProjectMode) {
|
|
|
219
305
|
process.exit(2);
|
|
220
306
|
}
|
|
221
307
|
|
|
222
|
-
//
|
|
223
|
-
//
|
|
224
|
-
|
|
308
|
+
// --force + an explicit SYM_NODE_NAME deliberately relabels this entry
|
|
309
|
+
// (symmetric with resolveGroup). Otherwise preserve the prior name so the
|
|
310
|
+
// mesh identity doesn't drift back to the hostname default on a reinstall.
|
|
311
|
+
const projectNodeName = (force && process.env.SYM_NODE_NAME)
|
|
312
|
+
? process.env.SYM_NODE_NAME
|
|
313
|
+
: (preserveNodeName(existingProjectEntry) || nodeName);
|
|
225
314
|
|
|
226
315
|
// Group resolution priority — see resolveGroup() at top of file.
|
|
227
316
|
// Summary: --force + explicit flag/env wins; otherwise preserve, then
|
|
@@ -469,7 +558,9 @@ if (existingTopEntry && !force && !topEntryIsStale) {
|
|
|
469
558
|
}
|
|
470
559
|
|
|
471
560
|
// Preserve the prior node name on rewrite so mesh identity doesn't drift.
|
|
472
|
-
const topNodeName =
|
|
561
|
+
const topNodeName = (force && process.env.SYM_NODE_NAME)
|
|
562
|
+
? process.env.SYM_NODE_NAME
|
|
563
|
+
: (preserveNodeName(existingTopEntry) || nodeName);
|
|
473
564
|
|
|
474
565
|
// Resolve SYM_GROUP for the global entry — see resolveGroup() at top.
|
|
475
566
|
// Heal-path default preserves; --force lets the user explicitly switch
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
// Subcommand dispatch:
|
|
5
|
-
|
|
4
|
+
// Subcommand dispatch: CLI subcommands run the installer/launcher, not the
|
|
5
|
+
// MCP server. (When Claude Code spawns the server there is no subcommand, so
|
|
6
|
+
// argv[2] is undefined and this falls through to the MCP server below.)
|
|
7
|
+
if (['init', 'doctor', 'start'].includes(process.argv[2])) {
|
|
6
8
|
require('./bin/install.js');
|
|
7
9
|
return;
|
|
8
10
|
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "sym-mesh-channel",
|
|
3
|
-
"owner": {
|
|
4
|
-
"name": "SYM.BOT",
|
|
5
|
-
"email": "info@sym.bot"
|
|
6
|
-
},
|
|
7
|
-
"metadata": {
|
|
8
|
-
"description": "Real-time communication and collaboration among Claude Code sessions — agent-to-agent cognitive signals over Bonjour LAN or WebSocket relay, on the Mesh Memory Protocol (MMP).",
|
|
9
|
-
"version": "0.3.11"
|
|
10
|
-
},
|
|
11
|
-
"plugins": [
|
|
12
|
-
{
|
|
13
|
-
"name": "sym-mesh-channel",
|
|
14
|
-
"source": "./",
|
|
15
|
-
"description": "Real-time communication and collaboration among Claude Code sessions. Turns Claude Code into a peer node on the SYM mesh — two or more sessions discover each other via Bonjour (LAN) or a WebSocket relay (cross-network) and exchange structured cognitive signals as channel notifications. Each peer has its own Ed25519 identity, SVAF content gating, and local memory. Built on the Mesh Memory Protocol (MMP), an open peer-to-peer protocol for multi-agent collective intelligence.",
|
|
16
|
-
"version": "0.3.11",
|
|
17
|
-
"author": {
|
|
18
|
-
"name": "Hongwei Xu",
|
|
19
|
-
"email": "hongwei@sym.bot"
|
|
20
|
-
},
|
|
21
|
-
"homepage": "https://meshcognition.org/spec/mmp",
|
|
22
|
-
"repository": "https://github.com/sym-bot/sym-mesh-channel",
|
|
23
|
-
"license": "Apache-2.0",
|
|
24
|
-
"keywords": [
|
|
25
|
-
"mesh",
|
|
26
|
-
"p2p",
|
|
27
|
-
"mcp",
|
|
28
|
-
"channel",
|
|
29
|
-
"agents",
|
|
30
|
-
"multi-agent",
|
|
31
|
-
"bonjour",
|
|
32
|
-
"cognitive",
|
|
33
|
-
"svaf",
|
|
34
|
-
"mmp"
|
|
35
|
-
],
|
|
36
|
-
"category": "agents",
|
|
37
|
-
"tags": [
|
|
38
|
-
"mesh",
|
|
39
|
-
"cognitive",
|
|
40
|
-
"channel",
|
|
41
|
-
"mcp",
|
|
42
|
-
"multi-agent"
|
|
43
|
-
]
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
}
|