neohive 6.4.0 → 6.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,55 @@
1
+ # Neohive Plugin for Claude Code
2
+
3
+ Turn Claude Code into a multi-agent team. Agents communicate, delegate tasks, and build together.
4
+
5
+ ## Skills (Slash Commands)
6
+
7
+ | Command | Description |
8
+ |---------|-------------|
9
+ | `/neohive:launch-team [template]` | Launch a team from a template (pair, team, review, managed, debate) |
10
+ | `/neohive:status` | Show agent status, active tasks, and workflow progress |
11
+ | `/neohive:send [agent] [message]` | Send a quick message to another agent |
12
+ | `/neohive:plan [description]` | Create a workflow plan from a natural language description |
13
+
14
+ ## Hooks
15
+
16
+ - **SessionStart** -- Detects Neohive projects and reminds agents to register
17
+ - **PreToolUse** -- Warns when editing files locked by another agent
18
+ - **PostToolUse** -- Tracks MCP tool usage for activity analytics
19
+
20
+ ## Subagents
21
+
22
+ - **coordinator** -- Project coordinator that plans, delegates, and tracks work (never writes code)
23
+
24
+ ## Installation
25
+
26
+ ### From GitHub (recommended)
27
+ ```
28
+ /plugin install neohive
29
+ ```
30
+
31
+ ### Manual
32
+ 1. Copy the `neohive-plugin/` directory to your Claude Code plugins folder
33
+ 2. Restart Claude Code
34
+
35
+ ### Via npm
36
+ ```bash
37
+ npx neohive init --plugin
38
+ ```
39
+
40
+ ## Gemini CLI
41
+
42
+ For Gemini CLI, use the instructions and config in `gemini-extension/`:
43
+ ```bash
44
+ npx neohive init --gemini
45
+ ```
46
+
47
+ ## Requirements
48
+
49
+ - Claude Code v1.0+
50
+ - Node.js 18+
51
+ - neohive npm package (`npx neohive` must work)
52
+
53
+ ## License
54
+
55
+ See LICENSE file.
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: coordinator
3
+ description: A project coordinator subagent that plans work, creates tasks, and delegates to team agents. Use when you need to orchestrate a multi-agent workflow.
4
+ model: sonnet
5
+ effort: high
6
+ maxTurns: 30
7
+ disallowedTools: Edit, Write, Bash
8
+ skills:
9
+ - neohive:launch-team
10
+ - neohive:status
11
+ - neohive:plan
12
+ - neohive:conventions
13
+ ---
14
+
15
+ You are a project coordinator. Your job is to plan, delegate, and track work — you NEVER write code.
16
+
17
+ Your tools: `register`, `get_briefing`, `send_message`, `broadcast`, `create_task`, `update_task`, `list_tasks`, `create_workflow`, `advance_workflow`, `workflow_status`, `distribute_prompt`, `start_plan`, `messages`, `kb_write`, `kb_read`, `log_decision`, `get_decisions`, `listen`.
18
+
19
+ Workflow:
20
+ 1. Call `register(name="Coordinator")` then `get_briefing()` to load context
21
+ 2. Break the user's request into research tasks and coding tasks
22
+ 3. Create tasks with `create_task` and assign to available agents
23
+ 4. Use `distribute_prompt` to dispatch task instructions to agents
24
+ 5. Call `messages(action="check")` to check for agent updates (non-blocking)
25
+ 6. Process reports, advance workflows with `advance_workflow`, assign next tasks
26
+ 7. Synthesize results and present to user
27
+ 8. **Always call `listen()` as the last tool call of every response**
@@ -0,0 +1,24 @@
1
+ # Neohive Multi-Agent Collaboration
2
+
3
+ You are part of a Neohive multi-agent team. Use the neohive MCP tools to communicate with other agents.
4
+
5
+ ## Getting Started
6
+ 1. Call `register` with your name to join the team
7
+ 2. Call `get_briefing` for project context and active work
8
+ 3. Call `listen` to wait for messages from other agents
9
+
10
+ ## Conventions
11
+ - Always call `listen()` after every action -- this is how you receive messages
12
+ - Update task status: `update_task(in_progress)` when starting, `update_task(done)` when finishing
13
+ - Lock files before editing: `lock_file()` before, `unlock_file()` after
14
+ - Report completions to the Coordinator with: what changed, files modified, decisions made
15
+ - Keep messages to 2-3 paragraphs max
16
+ - Use `kb_write()` for findings, `kb_read()` to check team knowledge
17
+ - Never work on another agent's task -- check `list_tasks()` first
18
+
19
+ ## Available Tools
20
+ - **Messaging:** register, send_message, broadcast, listen, messages, handoff
21
+ - **Tasks:** create_task, update_task, list_tasks
22
+ - **Workflows:** create_workflow, advance_workflow, workflow_status
23
+ - **Knowledge:** kb_write, kb_read, kb_list, log_decision
24
+ - **Coordination:** lock_file, unlock_file, update_progress, get_briefing
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "neohive": {
4
+ "command": "npx",
5
+ "args": ["-y", "neohive"],
6
+ "env": {
7
+ "NEOHIVE_DATA_DIR": ".neohive"
8
+ },
9
+ "timeout": 30
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,87 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "startup",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/auto-register.sh",
10
+ "timeout": 10,
11
+ "statusMessage": "Checking Neohive team status..."
12
+ }
13
+ ]
14
+ }
15
+ ],
16
+ "UserPromptSubmit": [
17
+ {
18
+ "hooks": [
19
+ {
20
+ "type": "command",
21
+ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/before-prompt.sh",
22
+ "timeout": 5,
23
+ "statusMessage": "Loading Neohive team context..."
24
+ }
25
+ ]
26
+ }
27
+ ],
28
+ "PreToolUse": [
29
+ {
30
+ "matcher": "Edit|Write",
31
+ "hooks": [
32
+ {
33
+ "type": "command",
34
+ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/enforce-locks.sh",
35
+ "timeout": 5,
36
+ "statusMessage": "Checking file locks..."
37
+ }
38
+ ]
39
+ }
40
+ ],
41
+ "PostToolUse": [
42
+ {
43
+ "matcher": "mcp__neohive__.*",
44
+ "hooks": [
45
+ {
46
+ "type": "command",
47
+ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/track-activity.sh",
48
+ "async": true,
49
+ "timeout": 5
50
+ }
51
+ ]
52
+ },
53
+ {
54
+ "matcher": "mcp__neohive__send_message|mcp__neohive__advance_workflow|mcp__neohive__update_task|mcp__neohive__broadcast|mcp__neohive__add_rule|mcp__neohive__remove_rule|mcp__neohive__toggle_rule",
55
+ "hooks": [
56
+ {
57
+ "type": "command",
58
+ "command": "echo '\\n📡 NEOHIVE: Call listen() now to receive your next task. Do not stop without calling listen().'",
59
+ "timeout": 3
60
+ }
61
+ ]
62
+ },
63
+ {
64
+ "matcher": "Edit|Write|MultiEdit|mcp__neohive__update_task",
65
+ "hooks": [
66
+ {
67
+ "type": "command",
68
+ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/post-tool-use.sh",
69
+ "async": true,
70
+ "timeout": 5
71
+ }
72
+ ]
73
+ }
74
+ ],
75
+ "Stop": [
76
+ {
77
+ "hooks": [
78
+ {
79
+ "type": "command",
80
+ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/enforce-listen.sh",
81
+ "timeout": 5
82
+ }
83
+ ]
84
+ }
85
+ ]
86
+ }
87
+ }
@@ -0,0 +1,48 @@
1
+ #!/bin/bash
2
+ # SessionStart hook: check if Neohive is active for this project.
3
+ # Outputs a dynamic context message — no hardcoded agent names.
4
+
5
+ NEOHIVE_DIR="${CLAUDE_PROJECT_DIR}/.neohive"
6
+
7
+ if [ -d "$NEOHIVE_DIR" ]; then
8
+ # Count registered agents
9
+ AGENT_COUNT=0
10
+ AGENT_NAMES=""
11
+ if [ -f "$NEOHIVE_DIR/agents.json" ]; then
12
+ AGENT_COUNT=$(jq 'length' "$NEOHIVE_DIR/agents.json" 2>/dev/null || echo "0")
13
+ # List alive agent names (dynamic — no hardcoding)
14
+ AGENT_NAMES=$(jq -r '[to_entries[] | select(.value.alive == true) | .key] | join(", ")' \
15
+ "$NEOHIVE_DIR/agents.json" 2>/dev/null || echo "")
16
+ fi
17
+
18
+ # Count active workflows
19
+ WF_COUNT=0
20
+ if [ -f "$NEOHIVE_DIR/workflows.json" ]; then
21
+ WF_COUNT=$(jq '[.[] | select(.status == "active")] | length' \
22
+ "$NEOHIVE_DIR/workflows.json" 2>/dev/null || echo "0")
23
+ fi
24
+
25
+ # Count pending tasks
26
+ PENDING_TASKS=0
27
+ if [ -f "$NEOHIVE_DIR/tasks.json" ]; then
28
+ PENDING_TASKS=$(jq '[.[] | select(.status == "pending" or .status == "in_progress")] | length' \
29
+ "$NEOHIVE_DIR/tasks.json" 2>/dev/null || echo "0")
30
+ fi
31
+
32
+ # Build the names hint (show only if agents are online)
33
+ NAMES_HINT=""
34
+ if [ -n "$AGENT_NAMES" ]; then
35
+ NAMES_HINT=" Online agents: $AGENT_NAMES."
36
+ fi
37
+
38
+ cat <<EOF
39
+ {
40
+ "hookSpecificOutput": {
41
+ "hookEventName": "SessionStart"
42
+ },
43
+ "systemMessage": "Neohive is active ($AGENT_COUNT agents registered, $WF_COUNT active workflows, $PENDING_TASKS pending/in-progress tasks).$NAMES_HINT\n\nTo join: call register() with the name you were assigned, then get_briefing(), then listen(). Do NOT invent a name — the user or Coordinator will tell you which name to use."
44
+ }
45
+ EOF
46
+ fi
47
+
48
+ exit 0
@@ -0,0 +1,47 @@
1
+ #!/bin/bash
2
+ # UserPromptSubmit hook: inject live neohive team context before every prompt.
3
+ # No hardcoded names — all data read dynamically from .neohive/ files.
4
+ # Exit 0 always (never blocks the prompt).
5
+
6
+ NEOHIVE_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}/.neohive"
7
+
8
+ # Not a neohive project — nothing to inject
9
+ [ -d "$NEOHIVE_DIR" ] || exit 0
10
+
11
+ # Agents: list alive agents with their roles (dynamic, no hardcoded names)
12
+ AGENTS_ONLINE=""
13
+ if [ -f "$NEOHIVE_DIR/agents.json" ]; then
14
+ AGENTS_ONLINE=$(jq -r '
15
+ [to_entries[]
16
+ | select(.value.alive == true)
17
+ | "\(.key)(\(.value.role // "agent"))"]
18
+ | join(", ")
19
+ ' "$NEOHIVE_DIR/agents.json" 2>/dev/null || echo "")
20
+ fi
21
+
22
+ # Task counts
23
+ PENDING_COUNT=0
24
+ IN_PROGRESS_COUNT=0
25
+ if [ -f "$NEOHIVE_DIR/tasks.json" ]; then
26
+ PENDING_COUNT=$(jq '[.[] | select(.status == "pending")] | length' \
27
+ "$NEOHIVE_DIR/tasks.json" 2>/dev/null || echo "0")
28
+ IN_PROGRESS_COUNT=$(jq '[.[] | select(.status == "in_progress")] | length' \
29
+ "$NEOHIVE_DIR/tasks.json" 2>/dev/null || echo "0")
30
+ fi
31
+
32
+ # Only inject if there is an active team
33
+ [ -z "$AGENTS_ONLINE" ] && exit 0
34
+
35
+ # Escape for JSON
36
+ AGENTS_ESCAPED=$(printf '%s' "$AGENTS_ONLINE" | sed 's/"/\\"/g')
37
+
38
+ cat <<EOF
39
+ {
40
+ "hookSpecificOutput": {
41
+ "hookEventName": "UserPromptSubmit"
42
+ },
43
+ "systemMessage": "Neohive team status: $AGENTS_ESCAPED | Tasks: $PENDING_COUNT pending, $IN_PROGRESS_COUNT in-progress. Reminder: call listen() after every action."
44
+ }
45
+ EOF
46
+
47
+ exit 0
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ # Stop hook: block agent from stopping if last neohive action wasn't listen()
3
+ # Also auto-reports to coordinator via /api/inject when blocking.
4
+ # Exit 2 = block stop (forces Claude to continue and call listen)
5
+ # Exit 0 = allow stop
6
+
7
+ NEOHIVE_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}/.neohive"
8
+ ACTIVITY_FILE="$NEOHIVE_DIR/activity.jsonl"
9
+ SESSION="${CLAUDE_SESSION_ID:-}"
10
+ NEOHIVE_URL="${NEOHIVE_SERVER_URL:-http://localhost:4321}"
11
+
12
+ # Allow exit: no tool calls this session (user cancelled before any tools ran)
13
+ LOOP_COUNT="${CLAUDE_LOOP_COUNT:-0}"
14
+ [ "$LOOP_COUNT" = "0" ] && exit 0
15
+
16
+ # Allow exit: user aborted — agent had no chance to call listen()
17
+ STOP_STATUS="${CLAUDE_STOP_HOOK_STATUS:-}"
18
+ [ "$STOP_STATUS" = "aborted" ] && exit 0
19
+
20
+ # Not a neohive project — allow stop
21
+ [ -f "$ACTIVITY_FILE" ] || exit 0
22
+
23
+ # Get the last neohive tool used in THIS session
24
+ LAST_TOOL=$(tail -100 "$ACTIVITY_FILE" 2>/dev/null | jq -r --arg session "$SESSION" '
25
+ select(.session == $session or $session == "") | .tool
26
+ ' | grep "^mcp__neohive__" | tail -1)
27
+
28
+ # No neohive tools used in this session — allow stop
29
+ [ -z "$LAST_TOOL" ] && exit 0
30
+
31
+ # Look up agent name from the last activity
32
+ AGENT_NAME=$(tail -100 "$ACTIVITY_FILE" 2>/dev/null | jq -r --arg session "$SESSION" '
33
+ select(.session == $session or $session == "") | .agent
34
+ ' | tail -1)
35
+ AGENT="${AGENT_NAME:-unknown}"
36
+
37
+ # All roles must call listen() — no exemptions
38
+
39
+ # Last action was listen/register/rules management — allow stop
40
+ case "$LAST_TOOL" in
41
+ mcp__neohive__listen|\
42
+ mcp__neohive__register|\
43
+ mcp__neohive__add_rule|mcp__neohive__remove_rule|mcp__neohive__toggle_rule)
44
+ exit 0
45
+ ;;
46
+ esac
47
+
48
+ # Last neohive action was something other than listen — report + block
49
+
50
+ # Auto-report to coordinator via neohive /api/inject (HTTP equivalent of send_message)
51
+ # Fire-and-forget: don't fail if dashboard isn't running
52
+ PAYLOAD=$(printf '{"from":"%s","to":"__user__","content":"[STOP HOOK] %s attempted to stop without calling listen(). Last tool: %s. Blocking stop — agent will be prompted to call listen() now.","priority":"normal"}' \
53
+ "$AGENT" "$AGENT" "$LAST_TOOL")
54
+ curl -s -X POST "${NEOHIVE_URL}/api/inject" \
55
+ -H "Content-Type: application/json" \
56
+ -d "$PAYLOAD" \
57
+ --max-time 2 \
58
+ > /dev/null 2>&1 || true
59
+
60
+ cat <<'EOF'
61
+
62
+ ⚠️ NEOHIVE — REQUIRED ACTION BEFORE STOPPING:
63
+
64
+ Your last neohive action was not listen(). You MUST call listen() before stopping.
65
+ This keeps you in the receive loop for your next task.
66
+ Your coordinator has been notified via the dashboard.
67
+
68
+ → Call: listen()
69
+
70
+ Do not respond with text. Call listen() now.
71
+ EOF
72
+ exit 2
@@ -0,0 +1,34 @@
1
+ #!/bin/bash
2
+ # PreToolUse hook: check if the file being edited is locked by another agent
3
+ # Input: JSON via stdin with tool_input.file_path or tool_input.file
4
+ # Exit 0 = allow (with optional context), Exit 2 = block
5
+
6
+ INPUT=$(cat)
7
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.file // empty' 2>/dev/null)
8
+ NEOHIVE_DIR="${CLAUDE_PROJECT_DIR}/.neohive"
9
+ LOCKS_FILE="$NEOHIVE_DIR/locks.json"
10
+
11
+ # No file path or no locks file — allow
12
+ if [ -z "$FILE_PATH" ] || [ ! -f "$LOCKS_FILE" ]; then
13
+ exit 0
14
+ fi
15
+
16
+ # Normalize: make path relative to project dir for matching
17
+ REL_PATH="${FILE_PATH#$CLAUDE_PROJECT_DIR/}"
18
+
19
+ # Check if file is locked (check both absolute and relative paths)
20
+ LOCKED_BY=$(jq -r --arg fp "$FILE_PATH" --arg rp "$REL_PATH" '(.[$fp].agent // .[$rp].agent) // empty' "$LOCKS_FILE" 2>/dev/null)
21
+
22
+ if [ -n "$LOCKED_BY" ]; then
23
+ # File is locked — soft enforcement (warn but don't block)
24
+ cat <<EOF
25
+ {
26
+ "hookSpecificOutput": {
27
+ "hookEventName": "PreToolUse",
28
+ "additionalContext": "WARNING: File '$REL_PATH' is locked by agent '$LOCKED_BY'. Consider coordinating with them or using lock_file() first to claim ownership."
29
+ }
30
+ }
31
+ EOF
32
+ fi
33
+
34
+ exit 0
@@ -0,0 +1,119 @@
1
+ #!/bin/bash
2
+ # PostToolUse hook — three jobs:
3
+ # 1. send_message → __user__: echo message content as a systemMessage in chat,
4
+ # and send the last assistant chat turn as report context to the dashboard.
5
+ # 2. File edits: fire-and-forget report to dashboard.
6
+ # 3. Task updates: fire-and-forget report to dashboard.
7
+ #
8
+ # Works with both Claude Code (mcp__neohive__*) and Cursor (MCP:*) tool name formats.
9
+
10
+ INPUT=$(cat)
11
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"' 2>/dev/null)
12
+ NEOHIVE_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}/.neohive"
13
+ NEOHIVE_URL="${NEOHIVE_SERVER_URL:-http://localhost:4321}"
14
+
15
+ [ -d "$NEOHIVE_DIR" ] || exit 0
16
+
17
+ # Normalize: strip "MCP:" or "mcp__<server>__" prefix → bare tool name
18
+ BARE=$(echo "$TOOL_NAME" | sed 's/^MCP://; s/^mcp__[^_]*__//')
19
+
20
+ # Resolve agent name from response or env
21
+ AGENT=$(echo "$INPUT" | jq -r '.tool_response.from // empty' 2>/dev/null)
22
+ [ -z "$AGENT" ] && AGENT="${CLAUDE_AGENT_NAME:-unknown}"
23
+
24
+ # ── Helper: extract last assistant text turn from the transcript JSONL ────────
25
+ last_chat_text() {
26
+ local transcript
27
+ transcript=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
28
+ [ -z "$transcript" ] && return
29
+ [ -f "$transcript" ] || return
30
+
31
+ # Use python3 (always available on macOS/Linux) to walk backward through the
32
+ # JSONL and find the last assistant turn that has a text content block.
33
+ # role is at the top level; content is inside .message.content or .content.
34
+ python3 - "$transcript" <<'PYEOF'
35
+ import sys, json
36
+
37
+ path = sys.argv[1]
38
+ with open(path, 'rb') as f:
39
+ lines = f.read().splitlines()
40
+
41
+ for line in reversed(lines):
42
+ try:
43
+ obj = json.loads(line)
44
+ except Exception:
45
+ continue
46
+ role = obj.get('role') or (obj.get('message') or {}).get('role', '')
47
+ if role != 'assistant':
48
+ continue
49
+ content = (obj.get('message') or {}).get('content') or obj.get('content') or []
50
+ if not isinstance(content, list):
51
+ continue
52
+ for block in content:
53
+ if isinstance(block, dict) and block.get('type') == 'text':
54
+ text = block.get('text', '').strip()
55
+ if text:
56
+ # Truncate to 500 chars so the JSON payload stays manageable
57
+ print(text[:500], end='')
58
+ sys.exit(0)
59
+ PYEOF
60
+ }
61
+
62
+ case "$BARE" in
63
+ # ── send_message to __user__ ────────────────────────────────────────────────
64
+ send_message)
65
+ TO=$(echo "$INPUT" | jq -r '.tool_input.to // ""' 2>/dev/null)
66
+ CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // ""' 2>/dev/null)
67
+
68
+ if [ "$TO" = "__user__" ] && [ -n "$CONTENT" ]; then
69
+ # Inject into chat as systemMessage
70
+ CONTENT_ESC=$(echo "$CONTENT" | sed 's/"/\\"/g; s/$/\\n/' | tr -d '\n')
71
+ printf '{"hookSpecificOutput":{"hookEventName":"PostToolUse"},"systemMessage":"[Neohive → you] %s"}\n' \
72
+ "$CONTENT_ESC"
73
+
74
+ # Also send last chat turn as context to the dashboard
75
+ LAST_CHAT=$(last_chat_text)
76
+ if [ -n "$LAST_CHAT" ]; then
77
+ LAST_ESC=$(printf '%s' "$LAST_CHAT" | sed 's/"/\\"/g')
78
+ REPORT="[REPORT] ${AGENT} sent message. Last chat turn: ${LAST_ESC}"
79
+ REPORT_ESC=$(printf '%s' "$REPORT" | sed 's/"/\\"/g')
80
+ curl -s -X POST "${NEOHIVE_URL}/api/inject" \
81
+ -H "Content-Type: application/json" \
82
+ -d "{\"from\":\"${AGENT}\",\"to\":\"__user__\",\"content\":\"${REPORT_ESC}\",\"priority\":\"normal\"}" \
83
+ --max-time 2 \
84
+ > /dev/null 2>&1 || true
85
+ fi
86
+ fi
87
+ exit 0
88
+ ;;
89
+
90
+ # ── File edits ───────────────────────────────────────────────────────────────
91
+ Edit|Write|MultiEdit)
92
+ FILE=$(echo "$INPUT" | jq -r \
93
+ '.tool_input.file_path // .tool_input.file // "unknown"' 2>/dev/null)
94
+ FILE="${FILE#$CLAUDE_PROJECT_DIR/}"
95
+ MSG="[POST-TOOL] ${AGENT} edited: ${FILE}"
96
+ ;;
97
+
98
+ # ── Task status updates ──────────────────────────────────────────────────────
99
+ update_task)
100
+ TASK_ID=$(echo "$INPUT" | jq -r '.tool_input.task_id // "?"' 2>/dev/null)
101
+ STATUS=$(echo "$INPUT" | jq -r '.tool_input.status // "?"' 2>/dev/null)
102
+ MSG="[POST-TOOL] ${AGENT} updated task ${TASK_ID} → ${STATUS}"
103
+ ;;
104
+
105
+ *)
106
+ exit 0
107
+ ;;
108
+ esac
109
+
110
+ [ -z "$MSG" ] && exit 0
111
+
112
+ MSG_ESCAPED=$(printf '%s' "$MSG" | sed 's/"/\\"/g')
113
+ curl -s -X POST "${NEOHIVE_URL}/api/inject" \
114
+ -H "Content-Type: application/json" \
115
+ -d "{\"from\":\"${AGENT}\",\"to\":\"__user__\",\"content\":\"${MSG_ESCAPED}\",\"priority\":\"normal\"}" \
116
+ --max-time 2 \
117
+ > /dev/null 2>&1 || true
118
+
119
+ exit 0
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+ # PostToolUse hook: log Neohive MCP tool calls for activity analytics
3
+ # Runs async — does not block tool execution
4
+ # Input: JSON via stdin with tool_name, tool_input, tool_response
5
+
6
+ INPUT=$(cat)
7
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"' 2>/dev/null)
8
+ NEOHIVE_DIR="${CLAUDE_PROJECT_DIR}/.neohive"
9
+ ACTIVITY_FILE="$NEOHIVE_DIR/activity.jsonl"
10
+
11
+ # Only log if neohive data dir exists
12
+ if [ -d "$NEOHIVE_DIR" ]; then
13
+ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
14
+ INPUT_SIZE=$(echo "$INPUT" | jq -r '.tool_input | tostring | length' 2>/dev/null || echo "0")
15
+ OUTPUT_SIZE=$(echo "$INPUT" | jq -r '.tool_response | tostring | length' 2>/dev/null || echo "0")
16
+
17
+ # Extract agent name from tool response if available
18
+ AGENT=$(echo "$INPUT" | jq -r '.tool_response.from // .tool_input.name // empty' 2>/dev/null)
19
+
20
+ echo "{\"tool\":\"$TOOL_NAME\",\"timestamp\":\"$TIMESTAMP\",\"input_size\":$INPUT_SIZE,\"output_size\":$OUTPUT_SIZE,\"agent\":\"${AGENT:-unknown}\",\"session\":\"${CLAUDE_SESSION_ID:-unknown}\"}" >> "$ACTIVITY_FILE"
21
+ fi
22
+
23
+ exit 0
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: conventions
3
+ description: Neohive multi-agent collaboration conventions. Automatically loaded when working in a multi-agent team to ensure proper tool usage, communication patterns, and workflow management.
4
+ user-invocable: false
5
+ ---
6
+
7
+ ## Neohive Collaboration Conventions
8
+
9
+ When working as part of a Neohive multi-agent team:
10
+
11
+ 1. **Register and get briefing first** — call `register()` then `get_briefing()` before any other action
12
+ 2. **Always call `listen()` as the LAST tool call of every response** — no exceptions, all agents
13
+ 3. **Handle `retry: true`** — if `listen()` returns `{retry: true}`, call `listen()` again immediately
14
+ 4. **Use `listen()` to complete tasks** — pass outcome params instead of a separate update_task call:
15
+ - `listen(outcome="completed", task_id="...", summary="one line of what was done")`
16
+ - `listen(outcome="blocked", task_id="...", summary="what is blocking you")`
17
+ 5. **Update task to in_progress when starting** — call `update_task(id, status="in_progress")` when you pick up a task
18
+ 6. **Lock files before editing** — call `lock_file(path)` before editing, `unlock_file(path)` after
19
+ 7. **Report completions via send_message** — after finishing a task send the coordinator: what changed, files modified, decisions made
20
+ 8. **Use KB for shared knowledge** — `kb_write()` for findings and decisions, `kb_read()` before starting work to avoid duplication
21
+ 9. **Never work on another agent's task** — check `list_tasks()` first
22
+ 10. **Keep messages concise** — 2–3 paragraphs max
23
+
24
+ ### listen() outcome loop
25
+
26
+ ```
27
+ register → get_briefing → listen → pick up task → update_task(in_progress)
28
+ → do work → send_message(coordinator, report) → listen(outcome="completed", task_id, summary)
29
+ ↑ always last
30
+ ```
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: launch-team
3
+ description: Launch a multi-agent team from a template. Lists available templates and generates prompts for each agent. Use when starting a new multi-agent collaboration, team session, or when the user says "launch team" or "start agents".
4
+ argument-hint: [template-name]
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ Launch a multi-agent team using Neohive templates.
9
+
10
+ 1. Call `list_agents` to see who's already online
11
+ 2. Call `workflow_status` to check if there's an active workflow
12
+ 3. If $ARGUMENTS is provided, use it as the template name
13
+ 4. If no template specified, list available templates:
14
+ - **pair** — 2 agents for brainstorming or Q&A
15
+ - **team** — Coordinator + Researcher + Coder for complex features
16
+ - **review** — Author + Reviewer for code review pipeline
17
+ - **managed** — Manager with floor control for structured sessions with large teams
18
+ - **debate** — Pro vs Con structured debate between two agents
19
+ 5. For the chosen template, generate the launch prompt for each agent role
20
+ 6. Each prompt must instruct the agent to:
21
+ - Call `register(name="<AgentName>")` first
22
+ - Call `get_briefing()` to load context
23
+ - Call `listen()` to enter the listen loop
24
+ 7. Display the prompts and instruct the user to paste each into a separate terminal running `claude` (or the relevant CLI)
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: plan
3
+ description: Create a multi-agent workflow plan from a natural language description. Breaks down the task into steps, assigns to agents, and creates the workflow. Use when the user describes a feature or task they want the team to build.
4
+ argument-hint: [task description]
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ Create a workflow plan for the multi-agent team.
9
+
10
+ 1. Call `list_agents` to see available agents and their roles/skills
11
+ 2. Call `kb_read` to check for existing decisions or context relevant to this task
12
+ 3. Analyze $ARGUMENTS to identify the steps needed
13
+ 4. Assign each step to the best-suited agent based on their skills
14
+ 5. Call `create_workflow` with the plan:
15
+ - name: derived from the task description
16
+ - steps: array of `{description, assignee, depends_on}`
17
+ - autonomous: true if all agents are online and no human checkpoints needed, false to let Coordinator manage step-by-step
18
+ 6. Call `create_task` for each step that can start immediately (no unresolved dependencies)
19
+ 7. Call `distribute_prompt` to dispatch task instructions to assigned agents
20
+ 8. Call `log_decision` to record the plan breakdown
21
+ 9. Display the created workflow in a clean format showing steps, assignees, and dependencies
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: send
3
+ description: Send a message to another agent or broadcast to all agents via Neohive. Use when the user wants to communicate with a specific agent or the whole team.
4
+ argument-hint: [agent-name|all] [message]
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ Send a message to an agent or the entire team.
9
+
10
+ 1. Parse $ARGUMENTS — first word is agent name (or `all`), rest is the message
11
+ 2. If no agent specified, call `list_agents` and ask the user which agent to target
12
+ 3. If agent is `all`, call `broadcast(content=<message>)`
13
+ 4. Otherwise call `send_message(to=<agent>, content=<message>)`
14
+ 5. Call `listen()` after sending to stay in the listen loop
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: status
3
+ description: Show the current status of the Neohive multi-agent team — who's online, active tasks, workflow progress, and recent messages. Use when the user asks about agent status, team progress, or "what's happening".
4
+ ---
5
+
6
+ Check the status of the multi-agent team:
7
+
8
+ 1. Call `list_agents` to see who's online/offline with their roles
9
+ 2. Call `list_tasks` to see all tasks and their statuses
10
+ 3. Call `workflow_status` to see workflow progress and current step
11
+ 4. Call `messages(action="check")` to surface any unread messages
12
+ 5. Call `get_decisions` to show recent decisions logged by the team
13
+ 6. Summarize in a clean format:
14
+ - **Agents:** name, status (online/offline), role, current task
15
+ - **Tasks:** title, assignee, status (`pending` / `in_progress` / `in_review` / `done` / `blocked`)
16
+ - **Workflows:** name, progress, current step, autonomous or managed
17
+ - **Recent decisions:** logged rationale from `get_decisions`