agent-comms 1.21.2 → 1.23.0

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.
@@ -1,21 +1,21 @@
1
1
  {
2
- "name": "agent-comms",
3
- "owner": {
4
- "name": "ExaDev"
5
- },
6
- "metadata": {
7
- "description": "Cross-harness communication mesh for LLM agents",
8
- "homepage": "https://github.com/ExaDev/agent-comms#readme"
9
- },
10
- "plugins": [
11
- {
12
- "name": "agent-comms",
13
- "source": {
14
- "source": "url",
15
- "url": "https://github.com/ExaDev/agent-comms.git"
16
- },
17
- "description": "Cross-harness LLM agent communication mesh — rooms, DMs, and presence",
18
- "version": "1.1.0"
19
- }
20
- ]
2
+ "name": "agent-comms",
3
+ "owner": {
4
+ "name": "ExaDev"
5
+ },
6
+ "metadata": {
7
+ "description": "Cross-harness communication mesh for LLM agents",
8
+ "homepage": "https://github.com/ExaDev/agent-comms#readme"
9
+ },
10
+ "plugins": [
11
+ {
12
+ "name": "agent-comms",
13
+ "source": {
14
+ "source": "url",
15
+ "url": "https://github.com/ExaDev/agent-comms.git"
16
+ },
17
+ "description": "Cross-harness LLM agent communication mesh — rooms, DMs, and presence",
18
+ "version": "1.23.0"
19
+ }
20
+ ]
21
21
  }
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "agent-comms",
3
3
  "description": "Cross-harness LLM agent communication mesh — rooms, DMs, and presence",
4
- "version": "1.21.2",
4
+ "version": "1.23.0",
5
5
  "author": {
6
6
  "name": "ExaDev"
7
7
  },
8
8
  "homepage": "https://github.com/ExaDev/agent-comms#readme",
9
9
  "repository": "https://github.com/ExaDev/agent-comms",
10
10
  "license": "MIT",
11
+ "hooks": "./hooks/hooks.json",
11
12
  "mcpServers": {
12
13
  "agent-comms": {
13
14
  "command": "npx",
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/agent-comms)
4
4
  [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/agent-comms)
5
- [![version](https://img.shields.io/badge/version-1.21.2-blue)](https://github.com/ExaDev/agent-comms/releases/tag/v1.21.2)
5
+ [![version](https://img.shields.io/badge/version-1.23.0-blue)](https://github.com/ExaDev/agent-comms/releases/tag/v1.23.0)
6
6
  [![CI](https://img.shields.io/github/actions/workflow/status/ExaDev/agent-comms/ci.yml?branch=main)](https://github.com/ExaDev/agent-comms/actions)
7
7
 
8
8
  Cross-harness communication mesh for LLM agents: rooms, DMs, presence, and visibility over TCP with zero filesystem dependencies.
@@ -217,7 +217,7 @@ agent_comms({ action: "update", visibility: "hidden" })
217
217
 
218
218
  When `streamingBehavior` is absent, each bridge falls back to its existing heuristic: actionable events (DMs, room messages, invites) are treated as `steer`; status changes and membership events are treated as `info`.
219
219
 
220
- **Limitations on non-native harnesses**: Claude Code's channel protocol is a single-lane push there is no runtime mechanism to force a mid-call interrupt. The `[STEER]` and `[FOLLOWUP]` markers are visible in the session and structured `meta.streamingBehavior` carries the intent, but acting on them is down to the receiving agent. The pi bridge honours the hint natively.
220
+ **Claude Code delivery mechanism**: Events are written to `~/.agents/bus/pending/claude-code--<cwd-slug>.jsonl`. Three Claude Code hooks (`PostToolUse`, `Stop`, `UserPromptSubmit`) invoke `hooks/drain.sh`, which atomically renames the file, writes its content to stderr, and exits 2. Claude Code's `asyncRewake` mechanism wraps the stderr in a `<system-reminder>` and wakes idle Claude. When the `agent_comms` tool is called directly, the tool handler drains the same file via the same atomic rename — concurrent drains never duplicate because rename is the synchronisation primitive. The `[STEER]` and `[FOLLOWUP]` markers and `meta.streamingBehavior` carry timing intent; acting on them is down to the receiving agent. The pi bridge honours the hint natively via `deliverAs`.
221
221
 
222
222
  ## Room types
223
223
 
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: List all known agents in the mesh
3
+ ---
4
+
5
+ Call the `agent_comms` MCP tool with `action: "list_agents"` and present the result as a compact list — one agent per line — with their status and any tags. Don't add commentary.
package/commands/dm.md ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Send a direct message to an agent
3
+ argument-hint: <agent-id-or-name> <message>
4
+ ---
5
+
6
+ Parse `$ARGUMENTS` as `<target> <message>` — first whitespace-separated token is the target agent id or name; everything after is the message body. Call the `agent_comms` MCP tool with `action: "dm"`, `target: <target>`, `content: <message>`, and `streamingBehavior: "steer"`. Confirm with a single line containing the returned message id. If the target is unknown, surface the error verbatim.
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: Hide this session from agent discovery (still DM-able if id is known)
3
+ ---
4
+
5
+ Call the `agent_comms` MCP tool with `action: "update"` and `visibility: "hidden"`. Confirm with a single line.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Join a room
3
+ argument-hint: <room-name>
4
+ ---
5
+
6
+ Call the `agent_comms` MCP tool with `action: "join_room"` and `room: "$ARGUMENTS"`. Confirm with a single line — room name and current member count. If the room doesn't exist, surface the error verbatim.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Leave a room
3
+ argument-hint: <room-name>
4
+ ---
5
+
6
+ Call the `agent_comms` MCP tool with `action: "leave_room"` and `room: "$ARGUMENTS"`. Confirm with a single line. If the room doesn't exist or you're not a member, surface the error verbatim.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Read recent messages from a room
3
+ argument-hint: <room>
4
+ ---
5
+
6
+ Call the `agent_comms` MCP tool with `action: "read_room"` and `room: "$ARGUMENTS"`. Present each message on its own line in chronological order, using the format `[HH:MM] <sender>: <content>`. If `<sender>` is a long fingerprint, truncate to the last 8 characters. No commentary.
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: List all rooms in the mesh
3
+ ---
4
+
5
+ Call the `agent_comms` MCP tool with `action: "list_rooms"` and present the result as a compact list — one room per line — showing the name, type, and member count, with a `[✓]` marker for rooms this session has joined. Don't add commentary.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Broadcast a message to a room
3
+ argument-hint: <room> <message>
4
+ ---
5
+
6
+ Parse `$ARGUMENTS` as `<room> <message>` — first whitespace-separated token is the room name; everything after is the message body. Call the `agent_comms` MCP tool with `action: "send"`, `target: <room>`, `content: <message>`, and `streamingBehavior: "info"`. Confirm with a single line containing the returned message id. If the room isn't joined, surface the error verbatim.
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: Make this session visible to agent discovery
3
+ ---
4
+
5
+ Call the `agent_comms` MCP tool with `action: "update"` and `visibility: "visible"`. Confirm with a single line.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Set this session's presence status
3
+ argument-hint: <active|idle|busy>
4
+ ---
5
+
6
+ Validate that `$ARGUMENTS` is one of `active`, `idle`, or `busy`. If invalid, print an error and stop. Otherwise call the `agent_comms` MCP tool with `action: "update"` and `status: "$ARGUMENTS"`. Confirm with a single line: the new status.
@@ -0,0 +1,5 @@
1
+ ---
2
+ description: Show this session's agent identity, status, and room memberships
3
+ ---
4
+
5
+ Call the `agent_comms` MCP tool with `action: "whoami"` and present the result concisely: agent ID (short form), name, current status, visibility, and the list of joined rooms. No commentary.
@@ -2,11 +2,14 @@
2
2
  * Agent Comms — Claude Code channel bridge.
3
3
  *
4
4
  * MCP channel server that provides the "agent_comms" tool and pushes
5
- * incoming messages into Claude's context via <channel> events.
5
+ * incoming messages into Claude's context via <channel> events and hooks.
6
6
  * Uses TCP mesh for real-time delivery — no filesystem polling.
7
7
  *
8
8
  * Run via: npx agent-comms bridge claude-code
9
- * Requires: claude --dangerously-load-development-channels
9
+ *
10
+ * Pending events are persisted to ~/.agents/bus/pending/claude-code--<slug>.jsonl
11
+ * so the asyncRewake hook scripts (hooks/drain.sh) can drain them out-of-process
12
+ * and wake idle Claude via exit code 2.
10
13
  */
11
14
  export declare function run(): Promise<void>;
12
15
  //# sourceMappingURL=channel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../../src/bridges/claude-code/channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAwBH,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAgHzC"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../../src/bridges/claude-code/channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA4IH,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAwHzC"}
@@ -2,12 +2,19 @@
2
2
  * Agent Comms — Claude Code channel bridge.
3
3
  *
4
4
  * MCP channel server that provides the "agent_comms" tool and pushes
5
- * incoming messages into Claude's context via <channel> events.
5
+ * incoming messages into Claude's context via <channel> events and hooks.
6
6
  * Uses TCP mesh for real-time delivery — no filesystem polling.
7
7
  *
8
8
  * Run via: npx agent-comms bridge claude-code
9
- * Requires: claude --dangerously-load-development-channels
9
+ *
10
+ * Pending events are persisted to ~/.agents/bus/pending/claude-code--<slug>.jsonl
11
+ * so the asyncRewake hook scripts (hooks/drain.sh) can drain them out-of-process
12
+ * and wake idle Claude via exit code 2.
10
13
  */
14
+ import { execFileSync } from "node:child_process";
15
+ import * as fs from "node:fs";
16
+ import * as os from "node:os";
17
+ import * as path from "node:path";
11
18
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
12
19
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
20
  import { MeshStore, CommsTool, buildAction, ensureRegistered, extractStreamingBehavior, formatDeliveryEvent, isActionableEvent, MCP_TOOL_PARAMS, } from "../../core/index.js";
@@ -18,6 +25,120 @@ import { nanoid } from "../../core/nanoid.js";
18
25
  function isRecord(value) {
19
26
  return typeof value === "object" && value !== null && !Array.isArray(value);
20
27
  }
28
+ function isErrnoException(err) {
29
+ return typeof err === "object" && err !== null && "code" in err;
30
+ }
31
+ function cwdSlug(cwd) {
32
+ return cwd.replace(/[^a-zA-Z0-9]/g, "_");
33
+ }
34
+ function pendingDir() {
35
+ return path.join(os.homedir(), ".agents", "bus", "pending");
36
+ }
37
+ /**
38
+ * Walk up the process tree to find the Claude Code CLI PID.
39
+ *
40
+ * The bridge runs ~3 hops below claude (tsx wrapper → tsx loader → bridge),
41
+ * so process.ppid alone isn't enough. We walk until we find an ancestor
42
+ * whose command basename is "claude".
43
+ *
44
+ * Two Claude Code instances in the same cwd would otherwise share one
45
+ * pending file and consume each other's messages. Keying by Claude PID
46
+ * isolates them. Returns undefined if no claude ancestor can be located
47
+ * within 10 hops — caller falls back to cwd-only path.
48
+ */
49
+ function findClaudeCodePid() {
50
+ let pid = process.ppid;
51
+ for (let i = 0; i < 10 && pid > 1; i++) {
52
+ let out;
53
+ try {
54
+ out = execFileSync("ps", ["-o", "ppid=,comm=", "-p", String(pid)], {
55
+ encoding: "utf-8",
56
+ });
57
+ }
58
+ catch {
59
+ return undefined;
60
+ }
61
+ const trimmed = out.trim();
62
+ const match = /^(\d+)\s+(.+)$/.exec(trimmed);
63
+ if (!match)
64
+ return undefined;
65
+ const parentPid = Number.parseInt(match[1] ?? "", 10);
66
+ const comm = (match[2] ?? "").trim();
67
+ if (/(^|\/)claude$/.test(comm))
68
+ return pid;
69
+ if (!Number.isFinite(parentPid))
70
+ return undefined;
71
+ pid = parentPid;
72
+ }
73
+ return undefined;
74
+ }
75
+ function pendingFilePath(cwd, claudePid) {
76
+ const slug = cwdSlug(cwd);
77
+ const name = claudePid !== undefined
78
+ ? `claude-code--${slug}--${String(claudePid)}.jsonl`
79
+ : `claude-code--${slug}.jsonl`;
80
+ return path.join(pendingDir(), name);
81
+ }
82
+ /**
83
+ * Drop pending files in this cwd whose owning Claude Code PID is no longer
84
+ * alive. Prevents accumulation when sessions exit without graceful shutdown.
85
+ */
86
+ function cleanupStalePendingFiles(cwd) {
87
+ const dir = pendingDir();
88
+ const slug = cwdSlug(cwd);
89
+ const prefix = `claude-code--${slug}--`;
90
+ let entries;
91
+ try {
92
+ entries = fs.readdirSync(dir);
93
+ }
94
+ catch (err) {
95
+ if (isErrnoException(err) && err.code === "ENOENT")
96
+ return;
97
+ return;
98
+ }
99
+ for (const entry of entries) {
100
+ if (!entry.startsWith(prefix) || !entry.endsWith(".jsonl"))
101
+ continue;
102
+ const pidStr = entry.slice(prefix.length, -".jsonl".length);
103
+ const pid = Number.parseInt(pidStr, 10);
104
+ if (!Number.isFinite(pid) || pid <= 1)
105
+ continue;
106
+ try {
107
+ process.kill(pid, 0);
108
+ }
109
+ catch (err) {
110
+ if (isErrnoException(err) && err.code === "ESRCH") {
111
+ try {
112
+ fs.unlinkSync(path.join(dir, entry));
113
+ }
114
+ catch {
115
+ // best-effort cleanup, ignore failures
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ function appendPending(filePath, line) {
122
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
123
+ fs.appendFileSync(filePath, line + "\n");
124
+ }
125
+ function drainPending(filePath) {
126
+ const drainPath = `${filePath}.draining-${String(process.pid)}-${String(Date.now())}`;
127
+ try {
128
+ fs.renameSync(filePath, drainPath);
129
+ }
130
+ catch (err) {
131
+ if (isErrnoException(err) && err.code === "ENOENT")
132
+ return [];
133
+ throw err;
134
+ }
135
+ const content = fs.readFileSync(drainPath, "utf-8");
136
+ fs.unlinkSync(drainPath);
137
+ return content
138
+ .split("\n")
139
+ .map((l) => l.trim())
140
+ .filter((l) => l.length > 0);
141
+ }
21
142
  export async function run() {
22
143
  const identity = generateIdentity();
23
144
  const store = new MeshStore();
@@ -25,21 +146,26 @@ export async function run() {
25
146
  store.setTransport(new TlsTransport(store.events, identity));
26
147
  const tool = new CommsTool(store, store.discovery);
27
148
  let agentId;
28
- const pendingBuffer = [];
149
+ const claudeCodePid = findClaudeCodePid();
150
+ if (claudeCodePid === undefined) {
151
+ process.stderr.write("agent-comms bridge: could not locate Claude Code PID; using shared cwd pending file (concurrent sessions in the same cwd will share messages)\n");
152
+ }
153
+ cleanupStalePendingFiles(process.cwd());
154
+ const pendingFile = pendingFilePath(process.cwd(), claudeCodePid);
29
155
  const mcp = new McpServer({ name: "agent-comms", version: "0.2.0" }, {
30
156
  capabilities: {
31
157
  experimental: { "claude/channel": {} },
32
158
  },
33
159
  });
34
- // All events land in the drain buffer so idle-Claude never silently misses
35
- // a message. Actionable events also get an eager channel push for mid-turn
36
- // delivery. If the push fired and Claude caught it, the drain will echo it
37
- // on the next tool call — acceptable duplication, far better than loss.
160
+ // All events are written to the pending file so the out-of-process hook
161
+ // drain script can surface them to idle Claude via asyncRewake exit 2.
162
+ // Actionable events also get an eager channel push for mid-turn delivery
163
+ // when channels are enabled (--dangerously-load-development-channels).
38
164
  store.onDelivery = async (_targetId, event) => {
39
165
  const line = formatDeliveryEvent(event);
40
166
  const hint = extractStreamingBehavior(event);
41
167
  const shouldPush = isActionableEvent(event) && hint !== "info";
42
- pendingBuffer.push(line);
168
+ appendPending(pendingFile, line);
43
169
  if (shouldPush) {
44
170
  await mcp.server.notification({
45
171
  method: "notifications/claude/channel",
@@ -58,7 +184,7 @@ export async function run() {
58
184
  "Cross-harness agent communication mesh. Actions:",
59
185
  "register, update, whoami, create_room, list_rooms, join_room, leave_room,",
60
186
  "send, dm, list_agents, read_room, invite, decline_invite, kick, destroy_room.",
61
- 'Incoming messages appear as <channel source="agent-comms"> events.',
187
+ 'Incoming messages appear as <channel source="agent-comms"> events or [comms] Pending prefix.',
62
188
  "Use streamingBehavior on send/dm: steer (act now), followUp (act when idle), info (whenever, default).",
63
189
  ].join(" "),
64
190
  inputSchema: MCP_TOOL_PARAMS,
@@ -84,7 +210,7 @@ export async function run() {
84
210
  cwd: process.cwd(),
85
211
  pid: process.pid,
86
212
  }, action);
87
- const pending = pendingBuffer.splice(0);
213
+ const pending = drainPending(pendingFile);
88
214
  const prefix = pending.length > 0
89
215
  ? `[comms] Pending:\n${pending.map((l) => ` 📬 ${l}`).join("\n")}\n\n`
90
216
  : "";
@@ -1 +1 @@
1
- {"version":3,"file":"channel.js","sourceRoot":"","sources":["../../../src/bridges/claude-code/channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../../../src/bridges/claude-code/channel.ts"],"names":[],"mappings":"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"}
package/hooks/drain.sh ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env bash
2
+ # Drain pending agent-comms events and exit 2 to wake idle Claude via asyncRewake.
3
+ #
4
+ # Called by Claude Code hooks (PostToolUse, Stop). If there are pending events,
5
+ # writes them to stderr and exits 2 — Claude Code wraps the stderr in a
6
+ # <system-reminder> and enqueues it as a task-notification, waking idle Claude.
7
+ #
8
+ # Uses atomic rename to drain so concurrent drains (in-process tool drain vs
9
+ # this out-of-process hook) never duplicate or lose events.
10
+
11
+ set -euo pipefail
12
+
13
+ SLUG="${PWD//[^a-zA-Z0-9]/_}"
14
+
15
+ # Walk up the process tree to find the Claude Code PID. Two Claude Code
16
+ # instances in the same cwd would otherwise share one pending file and consume
17
+ # each other's messages. Each Claude Code session has a unique PID; the bridge
18
+ # discovers and uses the same value, so each session gets its own file.
19
+ find_claude_pid() {
20
+ local pid=$PPID
21
+ for _ in 1 2 3 4 5 6 7 8 9 10; do
22
+ [ "$pid" -le 1 ] && return 1
23
+ local info ppid comm
24
+ info=$(ps -p "$pid" -o ppid=,comm= 2>/dev/null) || return 1
25
+ info=${info#"${info%%[![:space:]]*}"}
26
+ [ -z "$info" ] && return 1
27
+ ppid=${info%%[[:space:]]*}
28
+ comm=${info#*[[:space:]]}
29
+ comm=${comm#"${comm%%[![:space:]]*}"}
30
+ case "$comm" in
31
+ */claude|claude) echo "$pid"; return 0 ;;
32
+ esac
33
+ pid=$ppid
34
+ done
35
+ return 1
36
+ }
37
+
38
+ CLAUDE_PID=$(find_claude_pid 2>/dev/null || true)
39
+ if [ -n "$CLAUDE_PID" ]; then
40
+ PENDING="$HOME/.agents/bus/pending/claude-code--${SLUG}--${CLAUDE_PID}.jsonl"
41
+ else
42
+ echo "agent-comms drain.sh: could not locate Claude Code PID, falling back to shared cwd file" >&2
43
+ PENDING="$HOME/.agents/bus/pending/claude-code--${SLUG}.jsonl"
44
+ fi
45
+
46
+ DRAINING="${PENDING}.draining-$$-$(date +%s%N 2>/dev/null || date +%s)"
47
+
48
+ # Atomic drain — if rename fails (file absent), nothing to surface.
49
+ if ! mv "$PENDING" "$DRAINING" 2>/dev/null; then
50
+ exit 0
51
+ fi
52
+
53
+ CONTENT=$(cat "$DRAINING")
54
+ rm -f "$DRAINING"
55
+
56
+ if [ -z "$CONTENT" ]; then
57
+ exit 0
58
+ fi
59
+
60
+ echo "Pending agent-comms messages:" >&2
61
+ while IFS= read -r line; do
62
+ [ -n "$line" ] && echo " 📬 $line" >&2
63
+ done <<< "$CONTENT"
64
+
65
+ exit 2
@@ -0,0 +1,39 @@
1
+ {
2
+ "PostToolUse": [
3
+ {
4
+ "matcher": "*",
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/drain.sh",
9
+ "timeout": 5
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "Stop": [
15
+ {
16
+ "matcher": "*",
17
+ "hooks": [
18
+ {
19
+ "type": "command",
20
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/drain.sh",
21
+ "timeout": 5
22
+ }
23
+ ]
24
+ }
25
+ ],
26
+ "UserPromptSubmit": [
27
+ {
28
+ "matcher": "*",
29
+ "hooks": [
30
+ {
31
+ "type": "command",
32
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/drain.sh",
33
+ "asyncRewake": true,
34
+ "timeout": 5
35
+ }
36
+ ]
37
+ }
38
+ ]
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-comms",
3
- "version": "1.21.2",
3
+ "version": "1.23.0",
4
4
  "description": "Cross-harness communication mesh for LLM agents — rooms, DMs, presence, and real-time push delivery over TCP",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.33.0",
@@ -34,7 +34,9 @@
34
34
  },
35
35
  "files": [
36
36
  "dist",
37
- ".claude-plugin/"
37
+ ".claude-plugin/",
38
+ "commands/",
39
+ "hooks/"
38
40
  ],
39
41
  "bin": {
40
42
  "agent-comms": "dist/cli.js"