hoomanjs 1.11.3 → 1.11.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hoomanjs",
3
- "version": "1.11.3",
3
+ "version": "1.11.4",
4
4
  "description": "Bun-powered local AI agent CLI with chat, exec, ACP, MCP, and skills support.",
5
5
  "author": {
6
6
  "name": "Vaibhav Pandey",
@@ -5,11 +5,19 @@ import {
5
5
  HOOMAN_CHANNEL_PERMISSION,
6
6
  type ChannelMessage,
7
7
  type ChannelPermissionBehavior,
8
+ type ChannelSubscription,
9
+ type ChannelSubscriptionHandle,
8
10
  } from "./manager.ts";
9
11
 
10
12
  export { Config, Manager };
11
13
  export { HOOMAN_CHANNEL, HOOMAN_CHANNEL_PERMISSION };
12
- export type { ChannelMessage, ChannelPermissionBehavior, NamedMcpTransport };
14
+ export type {
15
+ ChannelMessage,
16
+ ChannelPermissionBehavior,
17
+ ChannelSubscription,
18
+ ChannelSubscriptionHandle,
19
+ NamedMcpTransport,
20
+ };
13
21
  export { createMcpTools } from "./tools.ts";
14
22
 
15
23
  export function createMcpConfig(path: string): Config {
@@ -33,6 +33,16 @@ export type ChannelMessage = {
33
33
 
34
34
  export type ChannelPermissionBehavior = "allow_once" | "allow_always" | "deny";
35
35
 
36
+ export type ChannelSubscription = {
37
+ server: string;
38
+ channel: string;
39
+ };
40
+
41
+ export type ChannelSubscriptionHandle = {
42
+ unsubscribe: () => void;
43
+ subscriptions: ChannelSubscription[];
44
+ };
45
+
36
46
  type ChannelPermissionRequest = {
37
47
  requestId: string;
38
48
  tool: string;
@@ -224,7 +234,7 @@ export class Manager {
224
234
  public async subscribeToChannels(
225
235
  channels: readonly string[],
226
236
  onMessage: (message: ChannelMessage) => void,
227
- ): Promise<() => void> {
237
+ ): Promise<ChannelSubscriptionHandle> {
228
238
  if (this.instances === null) {
229
239
  this.reload();
230
240
  }
@@ -234,10 +244,11 @@ export class Manager {
234
244
  ...new Set(channels.map((c) => c.trim()).filter(Boolean)),
235
245
  ];
236
246
  if (requested.length === 0) {
237
- return () => {};
247
+ return { unsubscribe: () => {}, subscriptions: [] };
238
248
  }
239
249
 
240
250
  const unsubs: Array<() => void> = [];
251
+ const subscriptions: ChannelSubscription[] = [];
241
252
  for (const [server, client] of map.entries()) {
242
253
  await client.connect();
243
254
  const experimental =
@@ -289,6 +300,8 @@ export class Manager {
289
300
  continue;
290
301
  }
291
302
 
303
+ subscriptions.push({ server, channel });
304
+
292
305
  const method = `notifications/${channel}`;
293
306
  const schema = z.object({
294
307
  method: z.literal(method),
@@ -327,10 +340,13 @@ export class Manager {
327
340
  }
328
341
  }
329
342
 
330
- return () => {
331
- for (const off of unsubs) {
332
- off();
333
- }
343
+ return {
344
+ subscriptions,
345
+ unsubscribe: () => {
346
+ for (const off of unsubs) {
347
+ off();
348
+ }
349
+ },
334
350
  };
335
351
  }
336
352
 
@@ -3,6 +3,7 @@ import type { Agent } from "@strands-agents/sdk";
3
3
  import { HOOMAN_CHANNEL } from "../core/mcp/index.ts";
4
4
  import type {
5
5
  ChannelMessage,
6
+ ChannelSubscription,
6
7
  Manager as McpManager,
7
8
  } from "../core/mcp/index.ts";
8
9
  import { createQueue } from "./queue.ts";
@@ -42,6 +43,18 @@ function resolveUserId(
42
43
  return `${message.meta.server}:${raw}`;
43
44
  }
44
45
 
46
+ function formatSubscriptions(
47
+ subscriptions: readonly ChannelSubscription[],
48
+ ): string {
49
+ if (subscriptions.length === 0) {
50
+ return "none";
51
+ }
52
+ const servers = [
53
+ ...new Set(subscriptions.map((subscription) => subscription.server)),
54
+ ].sort((left, right) => left.localeCompare(right));
55
+ return `${servers.length} MCP server(s): ${servers.join(", ")}`;
56
+ }
57
+
45
58
  export async function main(options: RunDaemonOptions): Promise<void> {
46
59
  if (!options.channels) {
47
60
  throw new Error("No daemon inputs enabled. Pass --channels.");
@@ -94,7 +107,7 @@ export async function main(options: RunDaemonOptions): Promise<void> {
94
107
  () => unsubscribe(),
95
108
  );
96
109
 
97
- unsubscribe = await options.manager.subscribeToChannels(
110
+ const handle = await options.manager.subscribeToChannels(
98
111
  channels,
99
112
  (message) => {
100
113
  debug(
@@ -103,7 +116,8 @@ export async function main(options: RunDaemonOptions): Promise<void> {
103
116
  void queue.push(message);
104
117
  },
105
118
  );
106
- debug(`subscribed to ${channels.length} channel(s)`);
119
+ unsubscribe = handle.unsubscribe;
120
+ debug(`subscribed → ${formatSubscriptions(handle.subscriptions)}`);
107
121
 
108
122
  try {
109
123
  await stop();