neohive 6.4.0 → 6.4.1

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
@@ -41,6 +41,14 @@
41
41
 
42
42
  <br />
43
43
 
44
+ <p align="center">
45
+ <img src="https://raw.githubusercontent.com/fakiho/neohive/master/assets/screenshots/hero-animation.gif" alt="Neohive — Terminal + IDE working together" width="100%" />
46
+ </p>
47
+
48
+ ---
49
+
50
+ <br />
51
+
44
52
  You open Claude Code in one terminal and Gemini CLI in another. Both are powerful — but they can't see each other. You copy context between windows, manually coordinate who does what.
45
53
 
46
54
  **Neohive removes that bottleneck.** Install once, and your AI agents discover each other, send messages, delegate tasks, review work, and execute multi-step workflows — automatically.
@@ -53,10 +61,12 @@ You open Claude Code in one terminal and Gemini CLI in another. Both are powerfu
53
61
 
54
62
  - [Quick Start](#-quick-start)
55
63
  - [Features](#-features)
64
+ - [Recommended Setup](#-recommended-setup)
56
65
  - [How It Works](#-how-it-works)
57
66
  - [Supported IDEs & CLIs](#-supported-ides--clis)
58
67
  - [Team Templates](#-team-templates)
59
68
  - [Dashboard](#-dashboard)
69
+ - [VS Code Extension](#-vs-code-extension)
60
70
  - [MCP Tools](#-mcp-tools)
61
71
  - [CLI Reference](#%EF%B8%8F-cli-reference)
62
72
  - [Configuration](#%EF%B8%8F-configuration)
@@ -77,14 +87,14 @@ That's it. Neohive auto-detects your CLI, writes the MCP config, and creates a `
77
87
 
78
88
  **MCP config:** `npx neohive init` writes the **absolute path** to the same Node binary that ran the command (so Volta, nvm, or custom installs work even when your IDE’s MCP subprocess has a minimal `PATH`). For **Claude Code**, the project file is `.mcp.json` in the repo root; you can merge the same `neohive` entry into `~/.claude/mcp.json` if you prefer a user-wide setup. Restart the IDE or reload MCP tools after init.
79
89
 
80
- Now open two terminals in the same project:
90
+ Now open two terminals in the same project and paste each prompt into a Claude Code session:
81
91
 
82
92
  ```
83
93
  # Terminal 1
84
- Register as "Alice" and send a greeting to Bob, then call listen()
94
+ Register as Alice. Send a greeting to Bob, then call listen().
85
95
 
86
96
  # Terminal 2
87
- Register as "Bob" and call listen()
97
+ Register as Bob, then call listen().
88
98
  ```
89
99
 
90
100
  Watch them communicate in real time:
@@ -120,6 +130,75 @@ npx neohive dashboard # opens http://localhost:3000
120
130
 
121
131
  <br />
122
132
 
133
+ ## ✅ Recommended Setup
134
+
135
+ Getting the most out of Neohive takes one extra minute after `init`. Here's what we recommend per tool.
136
+
137
+ ---
138
+
139
+ ### Claude Code
140
+
141
+ ```bash
142
+ npx neohive init --claude
143
+ ```
144
+
145
+ `init` handles MCP config, hooks, and skills in one step. For the smoothest experience:
146
+
147
+ - **VS Code Extension** — Install the [Neohive extension](https://marketplace.visualstudio.com/items?itemName=alionix.neohive) for automatic MCP setup, in-editor agent status, task board, workflow viewer, and `@neohive` chat participant. The extension configures hooks automatically on activation.
148
+ - **Without the extension** — Run `npx neohive hooks` to install listen-enforcement hooks into `.claude/settings.json`. This keeps agents in the listen loop and prevents them from stopping mid-session. Safe to re-run — your existing hooks are preserved.
149
+ - **Skills** — `init` installs neohive skills and the coordinator agent into `.claude/skills/neohive/`. These teach Claude how to use the MCP tools correctly.
150
+
151
+ ---
152
+
153
+ <img src="https://raw.githubusercontent.com/fakiho/neohive/master/vscode-extension/assets/screenshots/vscode-extension-overview.png" alt="Neohive VS Code Extension — Team Chat, Agent Sidebar, Task Board, and Workflows" width="100%" />
154
+
155
+ <br />
156
+
157
+ ### Cursor
158
+
159
+ ```bash
160
+ npx neohive init --cursor
161
+ ```
162
+
163
+ Installs MCP config, skills, commands, and agents into your project's `.cursor/` directory. After init:
164
+
165
+ - Open Cursor Settings → MCP and **verify that `neohive` is enabled**. Cursor sometimes disables newly added MCP servers by default — toggle it on if needed, then reload.
166
+ - Skills are available as slash commands (e.g. `/neohive-launch-team`, `/neohive-status`).
167
+
168
+ ---
169
+
170
+ ### Antigravity
171
+
172
+ ```bash
173
+ npx neohive init --antigravity
174
+ ```
175
+
176
+ Installs MCP config globally (`~/.gemini/antigravity/mcp_config.json`) and skills into `.agent/skills/neohive/`. After init:
177
+
178
+ - Open Antigravity Settings → MCP and **verify that `neohive` is enabled**. Like Cursor, Antigravity may disable new MCP servers by default.
179
+
180
+ ---
181
+
182
+ ### Everything at once
183
+
184
+ ```bash
185
+ npx neohive init --all
186
+ ```
187
+
188
+ Configures MCP, hooks, skills, agents, and commands for every detected CLI and IDE in one command.
189
+
190
+ ---
191
+
192
+ ### Troubleshooting
193
+
194
+ **Agent can't register / MCP tools not found**
195
+ The IDE has likely disabled the neohive MCP server. Restart the IDE first, then go to Settings → MCP (or Tools), find `neohive`, and enable it. After enabling, start a new agent thread — existing sessions won't pick up the newly registered tools.
196
+
197
+ **Agent stopped listening mid-session**
198
+ Due to a current IDE limitation, agents can occasionally drop out of the listen loop. Simply ask the agent: *"Call listen()"* to resume. We are actively working on a permanent fix.
199
+
200
+ ---
201
+
123
202
  ## 🏗 How It Works
124
203
 
125
204
  ```
@@ -225,8 +304,8 @@ The MCP server exposes **70+ built-in tools** in one registration list (no separ
225
304
  | Category | Tools |
226
305
  |----------|-------|
227
306
  | **Identity & briefing** | `register` · `list_agents` · `update_profile` · `get_briefing` · `get_guide` |
228
- | **Messaging** | `send_message` · `broadcast` · `listen` · `listen_group` · `listen_codex` · `wait_for_reply` · `check_messages` · `consume_messages` · `get_notifications` · `ack_message` |
229
- | **History & search** | `get_history` · `get_summary` · `search_messages` · `get_compressed_history` |
307
+ | **Messaging** | `send_message` · `broadcast` · `listen` · `wait_for_reply` · `messages` |
308
+ | **History & search** | `get_summary` · `get_compressed_history` · `messages` |
230
309
  | **Collaboration** | `handoff` · `share_file` · `lock_file` · `unlock_file` |
231
310
  | **Tasks** | `create_task` · `update_task` · `list_tasks` |
232
311
  | **Workflows** | `create_workflow` · `advance_workflow` · `workflow_status` |
@@ -257,11 +336,12 @@ neohive msg <agent> <text> # send message from CLI
257
336
  neohive doctor # diagnostic health check
258
337
  neohive templates # list available templates
259
338
  neohive hooks # install listen-enforcement hooks into .claude/settings.json
339
+ neohive skills # install neohive skills & agents for all detected IDEs
260
340
  neohive reset --force # clear data (auto-archives first)
261
341
  neohive uninstall # remove from all CLI configs
262
342
  ```
263
343
 
264
- > **Claude Code users:** Run `npx neohive hooks` after `init` to install listen-enforcement hooks into `.claude/settings.json`. This keeps agents in the listen loop automatically and prevents them from stopping mid-session. Safe to re-run your existing hooks are preserved.
344
+ > `init` runs `hooks` and `skills` automatically. Run them standalone at any time to update or repair your setup.
265
345
 
266
346
  <br />
267
347
 
@@ -276,6 +356,26 @@ neohive uninstall # remove from all CLI configs
276
356
 
277
357
  <br />
278
358
 
359
+ ## 🧩 VS Code Extension
360
+
361
+ The [Neohive extension](https://marketplace.visualstudio.com/items?itemName=alionix.neohive) brings agent monitoring and team coordination directly into your editor.
362
+
363
+ | Feature | Description |
364
+ |---------|-------------|
365
+ | **Agent Sidebar** | See all registered agents, their status (online/stale/offline), and provider in the activity bar |
366
+ | **Task Board** | In-editor kanban board — view and track tasks without opening the dashboard |
367
+ | **Workflow Viewer** | Monitor active workflows and step progress in real time |
368
+ | **`@neohive` Chat** | Query agent status, tasks, and messages directly from Copilot Chat |
369
+ | **Auto MCP Setup** | Configures MCP and hooks automatically on activation — no manual config needed |
370
+
371
+ **Install:** [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=alionix.neohive) — or search "Neohive" in the Extensions panel.
372
+
373
+ <br />
374
+
375
+ <img src="https://raw.githubusercontent.com/fakiho/neohive/master/vscode-extension/assets/screenshots/vscode-extension-overview.png" alt="Neohive VS Code Extension — Team Chat, Agent Sidebar, Task Board, and Workflows" width="100%" />
376
+
377
+ <br />
378
+
279
379
  ## 🔐 Security
280
380
 
281
381
  Neohive is a **local message broker**. It passes text between CLI terminals via shared files. It does not access the internet, store API keys, or run cloud services.
@@ -341,8 +441,9 @@ node dashboard.js # run the dashboard
341
441
  </p>
342
442
 
343
443
  <p align="center">
444
+ <a href="https://neohive.alionix.com">Website</a> &middot;
344
445
  <a href="https://github.com/fakiho/neohive">GitHub</a> &middot;
345
446
  <a href="https://www.npmjs.com/package/neohive">npm</a> &middot;
346
- <a href="docs/documentation.md">Docs</a> &middot;
447
+ <a href="../docs/documentation.md">Docs</a> &middot;
347
448
  <a href="mailto:contact@alionix.com">Contact</a>
348
449
  </p>
package/cli.js CHANGED
@@ -47,6 +47,7 @@ function printUsage() {
47
47
  npx neohive templates List available team templates
48
48
  npx neohive reset --force Clear all data (auto-archives first)
49
49
  npx neohive hooks Install listen-enforcement hooks into .claude/settings.json
50
+ npx neohive skills Install neohive skills & agents for all detected IDEs
50
51
  npx neohive uninstall Remove from all CLI configs
51
52
  npx neohive help Show this help
52
53
 
@@ -134,6 +135,117 @@ function setupClaude(serverPath, cwd) {
134
135
 
135
136
  fs.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + '\n');
136
137
  console.log(' [ok] Claude Code: .mcp.json updated');
138
+ installSkillsForClaude(cwd);
139
+ }
140
+
141
+ // ─── installSkills ────────────────────────────────────────────────────────────
142
+ // Installs neohive skills, agents, and commands into the appropriate IDE dirs.
143
+ // Safe to re-run: only writes files, never deletes user files outside neohive/.
144
+
145
+ const SKILLS_SRC = path.join(__dirname, 'neohive-plugin', 'skills');
146
+ const AGENTS_SRC = path.join(__dirname, 'neohive-plugin', 'agents');
147
+
148
+ function copySkillFile(src, dest, label) {
149
+ if (!fs.existsSync(src)) return;
150
+ const existing = fs.existsSync(dest) ? fs.readFileSync(dest, 'utf8') : null;
151
+ const incoming = fs.readFileSync(src, 'utf8');
152
+ if (existing === incoming) {
153
+ console.log(` [skip] ${label} (unchanged)`);
154
+ } else {
155
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
156
+ fs.writeFileSync(dest, incoming);
157
+ console.log(` [ok] ${label}`);
158
+ }
159
+ }
160
+
161
+ function installSkillsForClaude(cwd) {
162
+ // Project-level skills: .claude/skills/neohive/<skill>/SKILL.md
163
+ const skillsDir = path.join(cwd, '.claude', 'skills', 'neohive');
164
+ const agentsDir = path.join(cwd, '.claude', 'skills', 'neohive', 'agents');
165
+
166
+ if (!fs.existsSync(SKILLS_SRC)) {
167
+ console.log(' [skip] Claude skills: source not found (neohive-plugin/skills)');
168
+ return;
169
+ }
170
+
171
+ for (const skill of fs.readdirSync(SKILLS_SRC)) {
172
+ const src = path.join(SKILLS_SRC, skill, 'SKILL.md');
173
+ const dest = path.join(skillsDir, skill, 'SKILL.md');
174
+ copySkillFile(src, dest, `Claude skill: ${skill}`);
175
+ }
176
+
177
+ if (fs.existsSync(AGENTS_SRC)) {
178
+ for (const agent of fs.readdirSync(AGENTS_SRC)) {
179
+ const src = path.join(AGENTS_SRC, agent);
180
+ const dest = path.join(agentsDir, agent);
181
+ copySkillFile(src, dest, `Claude agent: ${agent}`);
182
+ }
183
+ }
184
+ }
185
+
186
+ function installSkillsForCursor(cwd) {
187
+ // .cursor/skills/neohive/<skill>/SKILL.md
188
+ // .cursor/agents/<agent>.md
189
+ // .cursor/commands/<command>.md (derived from skills)
190
+ if (!fs.existsSync(SKILLS_SRC)) {
191
+ console.log(' [skip] Cursor skills: source not found (neohive-plugin/skills)');
192
+ return;
193
+ }
194
+
195
+ for (const skill of fs.readdirSync(SKILLS_SRC)) {
196
+ const src = path.join(SKILLS_SRC, skill, 'SKILL.md');
197
+ const dest = path.join(cwd, '.cursor', 'skills', 'neohive', skill, 'SKILL.md');
198
+ copySkillFile(src, dest, `Cursor skill: ${skill}`);
199
+
200
+ // Also install as a command (slash-command style) for user-invocable skills
201
+ const content = fs.existsSync(src) ? fs.readFileSync(src, 'utf8') : '';
202
+ if (content.includes('user-invocable: true') || !content.includes('user-invocable: false')) {
203
+ const cmdDest = path.join(cwd, '.cursor', 'commands', `neohive-${skill}.md`);
204
+ copySkillFile(src, cmdDest, `Cursor command: neohive-${skill}`);
205
+ }
206
+ }
207
+
208
+ if (fs.existsSync(AGENTS_SRC)) {
209
+ for (const agent of fs.readdirSync(AGENTS_SRC)) {
210
+ const src = path.join(AGENTS_SRC, agent);
211
+ const dest = path.join(cwd, '.cursor', 'agents', `neohive-${agent}`);
212
+ copySkillFile(src, dest, `Cursor agent: neohive-${agent}`);
213
+ }
214
+ }
215
+ }
216
+
217
+ function installSkillsForAntigravity(cwd) {
218
+ // .agent/skills/neohive/<skill>/SKILL.md (already partially done in setupAntigravity)
219
+ if (!fs.existsSync(SKILLS_SRC)) {
220
+ console.log(' [skip] Antigravity skills: source not found (neohive-plugin/skills)');
221
+ return;
222
+ }
223
+
224
+ for (const skill of fs.readdirSync(SKILLS_SRC)) {
225
+ const src = path.join(SKILLS_SRC, skill, 'SKILL.md');
226
+ const dest = path.join(cwd, '.agent', 'skills', 'neohive', skill, 'SKILL.md');
227
+ copySkillFile(src, dest, `Antigravity skill: ${skill}`);
228
+ }
229
+
230
+ if (fs.existsSync(AGENTS_SRC)) {
231
+ for (const agent of fs.readdirSync(AGENTS_SRC)) {
232
+ const src = path.join(AGENTS_SRC, agent);
233
+ const dest = path.join(cwd, '.agent', 'agents', `neohive-${agent}`);
234
+ copySkillFile(src, dest, `Antigravity agent: neohive-${agent}`);
235
+ }
236
+ }
237
+ }
238
+
239
+ function installSkills(targets, cwd) {
240
+ console.log('');
241
+ console.log(' Installing Neohive skills & agents...');
242
+ for (const target of targets) {
243
+ switch (target) {
244
+ case 'claude': installSkillsForClaude(cwd); break;
245
+ case 'cursor': installSkillsForCursor(cwd); break;
246
+ case 'antigravity': installSkillsForAntigravity(cwd); break;
247
+ }
248
+ }
137
249
  }
138
250
 
139
251
  function setupGemini(serverPath, cwd) {
@@ -447,15 +559,7 @@ function setupAntigravity(cwd) {
447
559
 
448
560
  fs.writeFileSync(mcpPath, JSON.stringify(config, null, 2) + '\n');
449
561
  console.log(' [ok] Antigravity: ~/.gemini/antigravity/mcp_config.json updated');
450
-
451
- // Write skill
452
- const skillDir = path.join(cwd, '.agent', 'skills', 'neohive');
453
- if (!fs.existsSync(skillDir)) fs.mkdirSync(skillDir, { recursive: true });
454
- const skillPath = path.join(skillDir, 'SKILL.md');
455
- if (!fs.existsSync(skillPath)) {
456
- fs.writeFileSync(skillPath, neohiveAgentRules('Gemini'));
457
- console.log(' [ok] Antigravity: .agent/skills/neohive/SKILL.md created');
458
- }
562
+ installSkillsForAntigravity(cwd);
459
563
  }
460
564
 
461
565
  function neohiveAgentRules(defaultName) {
@@ -563,6 +667,7 @@ function setupCursor(serverPath, cwd) {
563
667
 
564
668
  fs.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + '\n');
565
669
  console.log(' [ok] Cursor IDE: .cursor/mcp.json updated');
670
+ installSkillsForCursor(cwd);
566
671
  }
567
672
 
568
673
  // Setup Ollama agent bridge script
@@ -765,6 +870,9 @@ function init() {
765
870
  }
766
871
  }
767
872
 
873
+ // Auto-install hooks for Claude targets
874
+ if (targets.includes('claude')) installHooks();
875
+
768
876
  // Add .neohive/ and MCP config files to .gitignore
769
877
  const gitignoreEntries = ['.neohive/', '.mcp.json', '.cursor/mcp.json', '.codex/', '.gemini/'];
770
878
  if (fs.existsSync(gitignorePath)) {
@@ -818,12 +926,6 @@ function init() {
818
926
  console.log(' npx neohive status');
819
927
  console.log(' npx neohive doctor');
820
928
  console.log('');
821
- if (targets.includes('claude')) {
822
- console.log(' \x1b[33m Tip (Claude Code):\x1b[0m Run `npx neohive hooks` to install listen-enforcement');
823
- console.log(' hooks into .claude/settings.json. Keeps agents in the listen loop automatically.');
824
- console.log(' Your existing hooks will not be removed.');
825
- console.log('');
826
- }
827
929
  }
828
930
  }
829
931
 
@@ -1504,6 +1606,9 @@ switch (command) {
1504
1606
  case 'hooks':
1505
1607
  installHooks();
1506
1608
  break;
1609
+ case 'skills':
1610
+ installSkills(detectCLIs().length ? detectCLIs() : ['claude', 'cursor', 'antigravity'], process.cwd());
1611
+ break;
1507
1612
  case 'uninstall':
1508
1613
  case 'remove':
1509
1614
  uninstall();
package/dashboard.html CHANGED
@@ -4,18 +4,6 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Neohive | Multi-Agent Coordination Dashboard</title>
7
- <meta name="description" content="Neohive — The ultimate multi-agent coordination and management dashboard. Orchestrate, monitor, and scale your AI workforce in real-time.">
8
- <meta name="keywords" content="AI, multi-agent systems, orchestration, dashboard, neohive, agents, automation">
9
- <meta name="author" content="Neohive Team">
10
- <meta property="og:title" content="Neohive | Multi-Agent Coordination Dashboard">
11
- <meta property="og:description" content="Orchestrate and scale your autonomous agent workforce with a stunning, high-performance real-time dashboard.">
12
- <meta property="og:type" content="website">
13
- <meta property="og:image" content="https://neohive.ai/og-image.png">
14
- <meta name="twitter:card" content="summary_large_image">
15
- <meta name="twitter:title" content="Neohive | Multi-Agent Coordination Dashboard">
16
- <meta name="twitter:description" content="The command center for your AI agent workforce. Real-time monitoring and scalable orchestration.">
17
- <meta name="twitter:image" content="https://neohive.ai/og-image.png">
18
- <meta name="robots" content="index, follow">
19
7
  <link rel="icon" href="favicon.png" type="image/png" sizes="16x16">
20
8
  <link rel="icon" href="logo.svg" type="image/svg+xml">
21
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
@@ -4603,7 +4591,7 @@
4603
4591
  </div>
4604
4592
  </div>
4605
4593
  <div class="app-footer">
4606
- <span>Neohive v6.0.0</span>
4594
+ <span>Neohive v6.4.1</span>
4607
4595
  </div>
4608
4596
  <div class="profile-popup" id="profile-popup" onclick="event.stopPropagation()">
4609
4597
  <div class="profile-popup-header">
@@ -5294,10 +5282,10 @@ function respawnAgent(agentName) {
5294
5282
  }
5295
5283
 
5296
5284
  function generateFallbackRespawnPrompt(agentName) {
5297
- return 'Register as \'' + agentName + '\', then call get_briefing() and listen_group() to rejoin the conversation. ' +
5285
+ return 'Register as \'' + agentName + '\', then call get_briefing() and listen() to rejoin the conversation. ' +
5298
5286
  'You are resuming a previous session — call get_compressed_history() to catch up on what you missed. ' +
5299
5287
  'Check your workspace with workspace_read() for any saved state. ' +
5300
- 'Then call listen_group() and respond to any pending messages.';
5288
+ 'Then call listen() and respond to any pending messages.';
5301
5289
  }
5302
5290
 
5303
5291
  function showRespawnModal(agentName, prompt) {
@@ -5503,7 +5491,7 @@ function renderMessages(messages) {
5503
5491
  } else {
5504
5492
  el.innerHTML = '<div class="empty-state">' +
5505
5493
  '<div class="empty-icon" style="font-size:40px;opacity:0.2">--</div>' +
5506
- '<div class="empty-text">Neohive v6.0</div>' +
5494
+ '<div class="empty-text">Neohive v6.4</div>' +
5507
5495
  '<div class="empty-sub">Autonomous AI agent teams — one command, zero babysitting</div>' +
5508
5496
  '<div class="onboard-steps">' +
5509
5497
  '<div class="onboard-step" style="margin-bottom:12px"><span class="onboard-num" style="background:var(--accent)"></span><span style="font-weight:600">Quickest start — one command:</span></div>' +
@@ -10313,7 +10301,7 @@ function doLaunch() {
10313
10301
  }
10314
10302
 
10315
10303
  // Use generated prompt if available, otherwise build a default
10316
- var launchPrompt = window._generatedLaunchPrompt || 'You are agent "' + agentName + '". Use the register tool to register as "' + agentName + '", then use listen_group() to join the conversation.';
10304
+ var launchPrompt = window._generatedLaunchPrompt || 'You are agent "' + agentName + '". Use the register tool to register as "' + agentName + '", then use listen() to join the conversation.';
10317
10305
  navigator.clipboard.writeText(launchPrompt).catch(function() {});
10318
10306
  selectedCli = cli;
10319
10307
 
@@ -10404,7 +10392,7 @@ function doLaunchAll() {
10404
10392
  w.state = 'launching';
10405
10393
  renderLaunchStatusTracker();
10406
10394
 
10407
- var agentPrompt = w.prompt || 'You are agent "' + w.name + '". Use the register tool to register as "' + w.name + '", then use listen_group() to join the conversation.';
10395
+ var agentPrompt = w.prompt || 'You are agent "' + w.name + '". Use the register tool to register as "' + w.name + '", then use listen() to join the conversation.';
10408
10396
 
10409
10397
  lttFetch('/api/launch', {
10410
10398
  method: 'POST',
@@ -10533,7 +10521,7 @@ function renderDocs() {
10533
10521
  el.innerHTML =
10534
10522
  '<div class="docs-container">' +
10535
10523
 
10536
- '<h2>Neohive v6.0</h2>' +
10524
+ '<h2>Neohive v6.4</h2>' +
10537
10525
  '<p class="docs-subtitle">True Autonomy Engine \u2014 AI agents that self-organize, self-verify, and never stop working. Works with Claude Code, Gemini CLI, Codex CLI, and Cursor IDE.</p>' +
10538
10526
 
10539
10527
  // Quick Start — One Command
@@ -10571,7 +10559,7 @@ function renderDocs() {
10571
10559
  '<p>Opens this web dashboard at <code>http://localhost:3777</code>. You can watch agents chat in real-time, send them messages, and manage your team.</p>' +
10572
10560
  '<h4>3. Start Your Agents</h4>' +
10573
10561
  '<p>Open two or more terminal windows in your project folder. In each one, start your AI CLI (e.g. type <code>claude</code>) and tell it to register:</p>' +
10574
- '<pre><code># Terminal 1\nRegister as "Alice" and use listen_group() to join the conversation.\n\n# Terminal 2\nRegister as "Bob" and use listen_group() to join the conversation.</code></pre>' +
10562
+ '<pre><code># Terminal 1\nRegister as "Alice" and use listen() to join the conversation.\n\n# Terminal 2\nRegister as "Bob" and use listen() to join the conversation.</code></pre>' +
10575
10563
  '<p>That\'s it! Your agents can now talk to each other. Or use the <strong>Launch</strong> tab to do this with one click.</p>' +
10576
10564
  '</div>' +
10577
10565
 
@@ -10655,7 +10643,7 @@ function renderDocs() {
10655
10643
  '<h4>Can I run multiple projects?</h4>' +
10656
10644
  '<p>Yes. Each project has its own <code>.neohive/</code> directory. The dashboard supports multiple projects \u2014 click the project selector in the header to switch between them.</p>' +
10657
10645
  '<h4>How do I send a message to agents from the dashboard?</h4>' +
10658
- '<p>Click any agent\'s avatar in the Messages tab. A dialog lets you type and send a message that agents will receive on their next <code>listen_group()</code> call.</p>' +
10646
+ '<p>Click any agent\'s avatar in the Messages tab. A dialog lets you type and send a message that agents will receive on their next <code>listen()</code> call.</p>' +
10659
10647
  '</div>' +
10660
10648
 
10661
10649
  '</div>';
@@ -10674,8 +10662,8 @@ function copyLaunchPrompt() {
10674
10662
  if (!prompt) {
10675
10663
  var agentName = document.getElementById('launch-name').value.trim();
10676
10664
  prompt = agentName
10677
- ? 'You are agent "' + agentName + '". Use the register tool to register as "' + agentName + '", then use listen_group() to join the conversation.'
10678
- : 'Register with the neohive MCP tools and use listen_group() to join the conversation.';
10665
+ ? 'You are agent "' + agentName + '". Use the register tool to register as "' + agentName + '", then use listen() to join the conversation.'
10666
+ : 'Register with the neohive MCP tools and use listen() to join the conversation.';
10679
10667
  }
10680
10668
  navigator.clipboard.writeText(prompt).then(function() {
10681
10669
  var resultEl = document.getElementById('launch-result');
package/dashboard.js CHANGED
@@ -2662,9 +2662,9 @@ const server = http.createServer(async (req, res) => {
2662
2662
  prompt += `**Instructions:**\n`;
2663
2663
  prompt += `1. Register as "${agentName}" using the register tool\n`;
2664
2664
  prompt += `2. Call get_briefing() for full project context\n`;
2665
- prompt += `3. Call listen_group() to rejoin the conversation\n`;
2665
+ prompt += `3. Call listen() to rejoin the conversation\n`;
2666
2666
  prompt += `4. Announce you're back and pick up your active tasks\n`;
2667
- prompt += `5. Stay in listen_group() loop — never stop listening\n`;
2667
+ prompt += `5. Stay in listen() loop — never stop listening\n`;
2668
2668
 
2669
2669
  res.writeHead(200, { 'Content-Type': 'application/json' });
2670
2670
  res.end(JSON.stringify({
@@ -2717,7 +2717,7 @@ const server = http.createServer(async (req, res) => {
2717
2717
  try {
2718
2718
  const messagesFile = filePath('messages.jsonl', projectPath);
2719
2719
  const historyFile = filePath('history.jsonl', projectPath);
2720
- const modeText = newMode === 'responsive' ? 'Coordinator stays with human, uses consume_messages().' : 'Coordinator runs autonomously in listen() loop.';
2720
+ const modeText = newMode === 'responsive' ? 'Coordinator stays with human, uses messages(action="check").' : 'Coordinator runs autonomously in listen() loop.';
2721
2721
  const sysMsg = { id: Date.now().toString(36) + Math.random().toString(36).slice(2, 8), from: '__system__', to: '__group__', content: `[MODE] Coordinator mode changed to "${newMode}". ${modeText} Coordinator: call get_guide() to update your instructions.`, timestamp: new Date().toISOString(), system: true };
2722
2722
  fs.appendFileSync(messagesFile, JSON.stringify(sysMsg) + '\n');
2723
2723
  fs.appendFileSync(historyFile, JSON.stringify(sysMsg) + '\n');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neohive",
3
- "version": "6.4.0",
3
+ "version": "6.4.1",
4
4
  "description": "The MCP collaboration layer for AI CLI tools. Turn Claude Code, Gemini CLI, and Codex CLI into a team.",
5
5
  "main": "server.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -1183,7 +1183,7 @@ function buildGuide(level = 'standard') {
1183
1183
  } else {
1184
1184
  rules.push('ROLE: Managed agent. The manager controls your turn.');
1185
1185
  rules.push('LOOP: listen() → receive work → update_task(id, "in_progress") → do work → update_task(id, "done") → send_message(manager, summary) → listen(). Never stop.');
1186
- rules.push('Never call get_work() or check_messages() in managed mode.');
1186
+ rules.push('Never call get_work() or messages() in managed mode.');
1187
1187
  }
1188
1188
  rules.push('Keep messages short (2-3 paragraphs). Report what you did and what files changed.');
1189
1189
  }
@@ -1260,16 +1260,16 @@ function buildGuide(level = 'standard') {
1260
1260
  if (isLeadRole) {
1261
1261
  const coordinatorMode = getConfig().coordinator_mode || 'responsive';
1262
1262
  if (coordinatorMode === 'responsive') {
1263
- rules.push('COORDINATOR: Use consume_messages() to check updates non-blockingly. Do NOT block in listen() — stay responsive to the user.');
1263
+ rules.push('COORDINATOR: Use messages(action="check") to check updates non-blockingly. Do NOT block in listen() — stay responsive to the user.');
1264
1264
  } else {
1265
1265
  rules.push('COORDINATOR: Use listen() to wait for agent results. Only return to human when all tasks are done or blocked.');
1266
1266
  }
1267
1267
  rules.push('Coordinators do NOT edit files or write code. Delegate ALL code work to other agents.');
1268
1268
  }
1269
1269
 
1270
- const listenCmd = isManagedMode() ? 'listen()' : (mode === 'group' ? 'listen_group()' : 'listen()');
1270
+ const listenCmd = isManagedMode() ? 'listen()' : (mode === 'group' ? 'listen(mode="group")' : 'listen()');
1271
1271
  if (!isLeadRole) {
1272
- rules.push(`After EVERY action, call ${listenCmd}. Never use sleep() or poll with check_messages().`);
1272
+ rules.push(`After EVERY action, call ${listenCmd}. Never use sleep() or poll with messages().`);
1273
1273
  }
1274
1274
 
1275
1275
  if (level === 'minimal') {
@@ -1570,7 +1570,7 @@ function toolRegister(name, provider = null, skills = null) {
1570
1570
  const coordinatorMode = getConfig().coordinator_mode || 'responsive';
1571
1571
  nextAction = coordinatorMode === 'autonomous'
1572
1572
  ? 'Call get_briefing() to load project context, then listen() to coordinate your team.'
1573
- : 'Call get_briefing() to load project context, then consume_messages() to check for pending work.';
1573
+ : 'Call get_briefing() to load project context, then messages(action="check") to check for pending work.';
1574
1574
  }
1575
1575
 
1576
1576
  // --- Build the result: next_action FIRST, then context ---
@@ -1695,7 +1695,7 @@ async function toolSendMessage(content, to = null, reply_to = null, channel = nu
1695
1695
  const effectiveSendLimit = isAutonomousMode() ? 5 : sendLimit;
1696
1696
  const myRole = (getProfiles()[registeredName] || {}).role;
1697
1697
  if (isGroupMode() && sendsSinceLastListen >= effectiveSendLimit && myRole !== 'Coordinator') {
1698
- return { error: `You must call listen_group() before sending again. You've sent ${sendsSinceLastListen} message(s) without listening (limit: ${effectiveSendLimit}). This prevents message storms.` };
1698
+ return { error: `You must call listen() before sending again. You've sent ${sendsSinceLastListen} message(s) without listening (limit: ${effectiveSendLimit}). This prevents message storms.` };
1699
1699
  }
1700
1700
 
1701
1701
  // Response budget: track unaddressed sends, hint when depleted
@@ -1993,7 +1993,7 @@ async function toolSendMessage(content, to = null, reply_to = null, channel = nu
1993
1993
  if (!recipientAlive) {
1994
1994
  result.warning = `Agent "${to}" appears offline (PID not running). Message queued but may not be received until they reconnect.`;
1995
1995
  } else if (to !== '__user__' && agents[to] && !agents[to].listening_since) {
1996
- result.note = `Agent "${to}" is currently working (not in listen mode). Message queued — they'll see it when they finish their current task and call listen_group().`;
1996
+ result.note = `Agent "${to}" is currently working (not in listen mode). Message queued — they'll see it when they finish their current task and call listen().`;
1997
1997
  }
1998
1998
 
1999
1999
  // Coordinator enforcement: warn if sending work assignment without creating a task first
@@ -2036,7 +2036,7 @@ function toolBroadcast(content) {
2036
2036
  const effectiveSendLimitBcast = isAutonomousMode() ? 5 : sendLimit;
2037
2037
  const myRole = (getProfiles()[registeredName] || {}).role;
2038
2038
  if (isGroupMode() && sendsSinceLastListen >= effectiveSendLimitBcast && myRole !== 'Coordinator') {
2039
- return { error: `You must call listen_group() before broadcasting again. You've sent ${sendsSinceLastListen} message(s) without listening (limit: ${effectiveSendLimitBcast}).` };
2039
+ return { error: `You must call listen() before broadcasting again. You've sent ${sendsSinceLastListen} message(s) without listening (limit: ${effectiveSendLimitBcast}).` };
2040
2040
  }
2041
2041
 
2042
2042
  const rateErr = checkRateLimit(content, '__broadcast__');
@@ -2355,10 +2355,10 @@ async function toolListenCodex(from = null, outcome = null, task_id = null, summ
2355
2355
  const taskList = getTasks();
2356
2356
  const task = taskList.find(t => t.id === task_id);
2357
2357
  if (!task) {
2358
- return { error: true, message: `Invalid task_id "${task_id}" — task does not exist. Check list_tasks() and call listen_codex() again with the correct task_id.` };
2358
+ return { error: true, message: `Invalid task_id "${task_id}" — task does not exist. Check list_tasks() and call listen(mode="codex") again with the correct task_id.` };
2359
2359
  }
2360
2360
  if (task.assignee && task.assignee !== registeredName) {
2361
- return { error: true, message: `Task "${task_id}" is assigned to ${task.assignee}, not to you (${registeredName}). You cannot update another agent's task via listen_codex().` };
2361
+ return { error: true, message: `Task "${task_id}" is assigned to ${task.assignee}, not to you (${registeredName}). You cannot update another agent's task via listen(mode="codex").` };
2362
2362
  }
2363
2363
  const statusMap = { completed: 'done', blocked: 'blocked', failed: 'blocked_permanent' };
2364
2364
  const newStatus = statusMap[outcome];
@@ -2486,9 +2486,9 @@ function toolSetConversationMode(mode) {
2486
2486
  }
2487
2487
 
2488
2488
  const messages = {
2489
- group: 'Group mode enabled. Use listen_group() to receive batched messages. All messages are shared with everyone.',
2489
+ group: 'Group mode enabled. Use listen(mode="group") to receive batched messages. All messages are shared with everyone.',
2490
2490
  direct: 'Direct mode enabled. Use listen() for point-to-point messaging.',
2491
- managed: 'Managed mode enabled. Call claim_manager() to become the manager, or wait for the manager to give you the floor via yield_floor(). Use listen() or listen_group() to receive messages.',
2491
+ managed: 'Managed mode enabled. Call claim_manager() to become the manager, or wait for the manager to give you the floor via yield_floor(). Use listen() to receive messages.',
2492
2492
  };
2493
2493
  return { success: true, mode, message: messages[mode] };
2494
2494
  }
@@ -2649,10 +2649,10 @@ async function toolListenGroup(outcome = null, task_id = null, summary = null) {
2649
2649
  const taskList = getTasks();
2650
2650
  const task = taskList.find(t => t.id === task_id);
2651
2651
  if (!task) {
2652
- return { error: true, message: `Invalid task_id "${task_id}" — task does not exist. Check list_tasks() and call listen_group() again with the correct task_id.` };
2652
+ return { error: true, message: `Invalid task_id "${task_id}" — task does not exist. Check list_tasks() and call listen() again with the correct task_id.` };
2653
2653
  }
2654
2654
  if (task.assignee && task.assignee !== registeredName) {
2655
- return { error: true, message: `Task "${task_id}" is assigned to ${task.assignee}, not to you (${registeredName}). You cannot update another agent's task via listen_group().` };
2655
+ return { error: true, message: `Task "${task_id}" is assigned to ${task.assignee}, not to you (${registeredName}). You cannot update another agent's task via listen().` };
2656
2656
  }
2657
2657
  const statusMap = { completed: 'done', blocked: 'blocked', failed: 'blocked_permanent' };
2658
2658
  const newStatus = statusMap[outcome];
@@ -2906,8 +2906,8 @@ function classifyPriority(msg) {
2906
2906
  return 'normal';
2907
2907
  }
2908
2908
 
2909
- // Build the response for listen_group — kept lean to reduce context accumulation
2910
- // Context/history removed: agents should call get_history() when they need it
2909
+ // Build the response for listen (group mode) — kept lean to reduce context accumulation
2910
+ // Context/history removed: agents should call messages(action="history") when they need it
2911
2911
  function buildListenGroupResponse(batch, consumed, agentName, listenStart) {
2912
2912
  saveConsumedIds(agentName, consumed);
2913
2913
  touchActivity();
@@ -5465,7 +5465,7 @@ function toolStartPlan(params) {
5465
5465
  broadcastSystemMessage(
5466
5466
  `[PLAN LAUNCHED] "${name}" — ${steps.length} steps, autonomous mode, ${useParallel ? 'parallel' : 'sequential'}. ` +
5467
5467
  `${startedSteps.length} step(s) started. ` +
5468
- `All agents: call get_work() to enter the autonomous work loop. Do NOT call listen_group().`
5468
+ `All agents: call get_work() to enter the autonomous work loop. Do NOT call listen().`
5469
5469
  );
5470
5470
 
5471
5471
  touchActivity();
@@ -5886,7 +5886,7 @@ function triggerStandupIfDue() {
5886
5886
  if (inProgress.length > 0) summary += ` In progress: ${inProgress.map(t => `"${t.title}" (${t.assignee || '?'})`).join(', ')}.`;
5887
5887
  if (blocked.length > 0) summary += ` BLOCKED: ${blocked.map(t => `"${t.title}" (${t.assignee || '?'})`).join(', ')}.`;
5888
5888
  if (recentDone.length > 0) summary += ` Recently done: ${recentDone.length} task(s).`;
5889
- summary += ' Each agent: report what you did, what\'s blocked, what\'s next. Then call listen_group().';
5889
+ summary += ' Each agent: report what you did, what\'s blocked, what\'s next. Then call listen().';
5890
5890
 
5891
5891
  broadcastSystemMessage(summary, registeredName);
5892
5892
  } catch (e) { log.warn("standup trigger failed:", e.message); }
@@ -6180,7 +6180,7 @@ function toolGetGuide(level = 'standard') {
6180
6180
  const guide = buildGuide(level);
6181
6181
  guide.your_name = registeredName;
6182
6182
  if (level !== 'minimal') {
6183
- guide.workflow = '1. get_briefing → 2. list_tasks/suggest_task → 3. claim task → 4. lock_file → 5. work → 6. unlock_file → 7. update_task done → 8. listen_group';
6183
+ guide.workflow = '1. get_briefing → 2. list_tasks/suggest_task → 3. claim task → 4. lock_file → 5. work → 6. unlock_file → 7. update_task done → 8. listen()';
6184
6184
  }
6185
6185
  return guide;
6186
6186
  }
@@ -7191,7 +7191,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
7191
7191
  tools: [
7192
7192
  {
7193
7193
  name: 'register',
7194
- description: 'Register this agent\'s identity. Must be called first. Returns a collaboration guide with all tool categories, critical rules, and workflow patterns — READ IT CAREFULLY before doing anything else. Then call get_briefing() for project context, then listen_group() to join the conversation.',
7194
+ description: 'Register this agent\'s identity. Must be called first. Returns a collaboration guide with all tool categories, critical rules, and workflow patterns — READ IT CAREFULLY before doing anything else. Then call get_briefing() for project context, then listen() to join the conversation.',
7195
7195
  inputSchema: {
7196
7196
  type: 'object',
7197
7197
  properties: {
@@ -7289,7 +7289,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
7289
7289
  },
7290
7290
  {
7291
7291
  name: 'listen',
7292
- description: 'Listen for messages. Use mode="standard" (default, direct 1:1), mode="group" (group/managed conversation, batched), or mode="codex" (Codex CLI — returns after 90s). Auto-detects mode from conversation state when mode is omitted. Replaces listen_group and listen_codex (now deprecated aliases).',
7292
+ description: 'Listen for messages. Use mode="standard" (default, direct 1:1), mode="group" (group/managed conversation, batched), or mode="codex" (Codex CLI — returns after 90s). Auto-detects mode from conversation state when mode is omitted.',
7293
7293
  inputSchema: {
7294
7294
  type: 'object',
7295
7295
  properties: {
@@ -7901,7 +7901,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
7901
7901
  try {
7902
7902
  const pending = getUnconsumedMessages(registeredName);
7903
7903
  const pendingHint = pending.length > 0
7904
- ? `${pending.length} agent update(s) waiting. Call consume_messages() to read them.`
7904
+ ? `${pending.length} agent update(s) waiting. Call messages(action="consume") to read them.`
7905
7905
  : null;
7906
7906
  if (!na || bareListenRe.test(na)) {
7907
7907
  // No guidance or bare listen() — replace with coordinator hint or nothing