@agenticmail/claudecode 0.2.9 → 0.2.11

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.
@@ -10,7 +10,7 @@ import {
10
10
  deleteAccount,
11
11
  getAccountByName,
12
12
  resolveConfig
13
- } from "./chunk-4VQP57SO.js";
13
+ } from "./chunk-UI556UPF.js";
14
14
 
15
15
  // src/uninstall.ts
16
16
  import { existsSync, readdirSync, readFileSync, unlinkSync } from "fs";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  status
3
- } from "./chunk-Q5BA2J2C.js";
3
+ } from "./chunk-XI7P3WSC.js";
4
4
  import {
5
5
  uninstall
6
- } from "./chunk-2RVJ2Q3W.js";
6
+ } from "./chunk-GMYSDT2Y.js";
7
7
  import {
8
8
  install
9
- } from "./chunk-OUYPF4ER.js";
9
+ } from "./chunk-LKY2L2RR.js";
10
10
  import {
11
11
  AgenticMailApiError
12
- } from "./chunk-4VQP57SO.js";
12
+ } from "./chunk-UI556UPF.js";
13
13
 
14
14
  // src/http-routes.ts
15
15
  import { Router } from "express";
@@ -11,8 +11,9 @@ import {
11
11
  ensureAccount,
12
12
  listAccounts,
13
13
  renderSubagentMarkdown,
14
- resolveConfig
15
- } from "./chunk-4VQP57SO.js";
14
+ resolveConfig,
15
+ setAccountRole
16
+ } from "./chunk-UI556UPF.js";
16
17
 
17
18
  // src/install.ts
18
19
  import { existsSync, mkdirSync, readdirSync, writeFileSync, readFileSync, unlinkSync } from "fs";
@@ -25,7 +26,13 @@ function buildMcpEntry(cfg, bridgeKey, accountKeys) {
25
26
  const env = {
26
27
  AGENTICMAIL_API_URL: cfg.apiUrl,
27
28
  AGENTICMAIL_API_KEY: bridgeKey,
28
- AGENTICMAIL_MASTER_KEY: cfg.masterKey
29
+ AGENTICMAIL_MASTER_KEY: cfg.masterKey,
30
+ // Host ownership tag. The MCP server's create_account stamps this
31
+ // value onto every new account's metadata.host, and the dispatcher
32
+ // uses it to filter "agents that belong to ME" — preventing two
33
+ // dispatchers (claudecode + codex) from both waking the same
34
+ // teammate on every reply.
35
+ AGENTICMAIL_MCP_HOST: cfg.bridgeAgentName
29
36
  };
30
37
  if (Object.keys(accountKeys).length > 0) {
31
38
  env.AGENTICMAIL_ACCOUNT_KEYS_JSON = JSON.stringify(accountKeys);
@@ -98,7 +105,14 @@ async function install(opts = {}) {
98
105
  "AgenticMail master key not found. Run `agenticmail setup` first to generate one, or pass { masterKey } to install() explicitly."
99
106
  );
100
107
  }
101
- const bridge = await ensureAccount(cfg.apiUrl, cfg.masterKey, cfg.bridgeAgentName, "assistant");
108
+ let bridge = await ensureAccount(cfg.apiUrl, cfg.masterKey, cfg.bridgeAgentName, "bridge");
109
+ if (bridge.role && bridge.role !== "bridge") {
110
+ try {
111
+ await setAccountRole(cfg.apiUrl, cfg.masterKey, bridge.id, "bridge");
112
+ bridge = { ...bridge, role: "bridge" };
113
+ } catch {
114
+ }
115
+ }
102
116
  const everyAccount = await listAccounts(cfg.apiUrl, cfg.masterKey);
103
117
  const exposable = selectExposableAgents(everyAccount, cfg);
104
118
  const accountKeys = {};
@@ -82,6 +82,23 @@ async function ensureAccount(apiUrl, masterKey, name, role = "assistant") {
82
82
  async function deleteAccount(apiUrl, masterKey, id) {
83
83
  await request(apiUrl, masterKey, `/accounts/${encodeURIComponent(id)}`, { method: "DELETE" });
84
84
  }
85
+ async function setAccountRole(apiUrl, masterKey, id, role) {
86
+ const updated = await request(
87
+ apiUrl,
88
+ masterKey,
89
+ `/accounts/${encodeURIComponent(id)}/role`,
90
+ { method: "PATCH", body: { role } }
91
+ );
92
+ return updated ?? { role };
93
+ }
94
+ async function setAccountHost(apiUrl, masterKey, id, host) {
95
+ await request(
96
+ apiUrl,
97
+ masterKey,
98
+ `/accounts/${encodeURIComponent(id)}/host`,
99
+ { method: "PATCH", body: { host } }
100
+ );
101
+ }
85
102
  async function listInboxForAgent(apiUrl, agentApiKey, opts = {}) {
86
103
  const limit = Math.max(1, Math.min(opts.limit ?? 50, 100));
87
104
  const url = `${apiUrl.replace(/\/$/, "")}/api/agenticmail/mail/inbox?limit=${limit}`;
@@ -282,6 +299,8 @@ export {
282
299
  getAccountByName,
283
300
  ensureAccount,
284
301
  deleteAccount,
302
+ setAccountRole,
303
+ setAccountHost,
285
304
  listInboxForAgent,
286
305
  listPendingTasksForAgent,
287
306
  resolveConfig,
@@ -4,7 +4,7 @@ import {
4
4
  listPendingTasksForAgent,
5
5
  renderPersonaBody,
6
6
  resolveConfig
7
- } from "./chunk-4VQP57SO.js";
7
+ } from "./chunk-UI556UPF.js";
8
8
 
9
9
  // src/persona-loader.ts
10
10
  import { existsSync, readFileSync } from "fs";
@@ -838,8 +838,13 @@ var Dispatcher = class {
838
838
  */
839
839
  shouldWatch(account) {
840
840
  const bridgeName = this.cfg.bridgeAgentName.toLowerCase();
841
+ const meta = account.metadata;
841
842
  if (account.name.toLowerCase() === bridgeName) return false;
842
843
  if (account.role === "bridge") return false;
844
+ if (meta && meta.bridge === true) return false;
845
+ if (meta && typeof meta.host === "string" && meta.host.length > 0) {
846
+ return meta.host.toLowerCase() === bridgeName;
847
+ }
843
848
  return true;
844
849
  }
845
850
  /** Re-fetch /accounts; open SSE for new ones, close for vanished ones. */
@@ -7,7 +7,7 @@ import {
7
7
  MANAGED_BY_MARKER,
8
8
  getAccountByName,
9
9
  resolveConfig
10
- } from "./chunk-4VQP57SO.js";
10
+ } from "./chunk-UI556UPF.js";
11
11
 
12
12
  // src/status.ts
13
13
  import { existsSync, readFileSync, readdirSync } from "fs";
package/dist/cli.js CHANGED
@@ -6,18 +6,21 @@ import {
6
6
  } from "./chunk-B5JDOV32.js";
7
7
  import {
8
8
  status
9
- } from "./chunk-Q5BA2J2C.js";
9
+ } from "./chunk-XI7P3WSC.js";
10
10
  import {
11
11
  uninstall
12
- } from "./chunk-2RVJ2Q3W.js";
12
+ } from "./chunk-GMYSDT2Y.js";
13
13
  import {
14
14
  install
15
- } from "./chunk-OUYPF4ER.js";
15
+ } from "./chunk-LKY2L2RR.js";
16
16
  import "./chunk-LO5EQSQA.js";
17
17
  import "./chunk-US5FT2UB.js";
18
18
  import {
19
- AgenticMailApiError
20
- } from "./chunk-4VQP57SO.js";
19
+ AgenticMailApiError,
20
+ listAccounts,
21
+ resolveConfig,
22
+ setAccountHost
23
+ } from "./chunk-UI556UPF.js";
21
24
 
22
25
  // src/cli.ts
23
26
  var GREEN = (s) => `\x1B[32m${s}\x1B[0m`;
@@ -48,6 +51,7 @@ function usage() {
48
51
  print(` uninstall Remove the registration`);
49
52
  print(` status Show what's currently installed`);
50
53
  print(` tune View / change dispatcher tuning knobs (rate limits, concurrency)`);
54
+ print(` claim <name>... Claim agent(s) for the claudecode dispatcher (sets metadata.host)`);
51
55
  print("");
52
56
  print(` ${BOLD("Flags:")}`);
53
57
  print(` --json (status / tune) Emit machine-readable JSON instead of prose`);
@@ -253,6 +257,89 @@ async function runTune(args) {
253
257
  print("");
254
258
  return 0;
255
259
  }
260
+ async function runClaim(args) {
261
+ const cfg = resolveConfig({
262
+ apiUrl: process.env.AGENTICMAIL_API_URL,
263
+ masterKey: process.env.AGENTICMAIL_MASTER_KEY
264
+ });
265
+ if (!cfg.masterKey) {
266
+ fail("AgenticMail master key not found. Run `agenticmail setup` first.");
267
+ return 1;
268
+ }
269
+ const positional = args.filter((a) => !a.startsWith("-") && a !== "claim");
270
+ const asJson = args.includes("--json");
271
+ const unclaim = args.includes("--unclaim");
272
+ const claimAll = args.includes("--all");
273
+ let targets;
274
+ if (claimAll && positional.length === 0) {
275
+ try {
276
+ const all = await listAccounts(cfg.apiUrl, cfg.masterKey);
277
+ targets = all.filter((a) => a.role !== "bridge").filter((a) => {
278
+ const m = a.metadata;
279
+ if (m && m.bridge === true) return false;
280
+ if (m && typeof m.host === "string" && m.host.length > 0 && m.host.toLowerCase() !== cfg.bridgeAgentName.toLowerCase()) {
281
+ return false;
282
+ }
283
+ return true;
284
+ }).map((a) => a.name);
285
+ } catch (err) {
286
+ fail(`Could not list accounts: ${err.message}`);
287
+ return 1;
288
+ }
289
+ } else if (positional.length === 0) {
290
+ fail("claim: at least one agent name required (or pass --all)");
291
+ print(` ${DIM("Usage: agenticmail-claudecode claim <name> [<name> ...] [--unclaim] [--all]")}`);
292
+ return 64;
293
+ } else {
294
+ targets = positional;
295
+ }
296
+ let accounts;
297
+ try {
298
+ accounts = await listAccounts(cfg.apiUrl, cfg.masterKey);
299
+ } catch (err) {
300
+ fail(`Could not list accounts: ${err.message}`);
301
+ return 1;
302
+ }
303
+ const byName = new Map(accounts.map((a) => [a.name.toLowerCase(), a]));
304
+ const results = [];
305
+ for (const name of targets) {
306
+ const account = byName.get(name.toLowerCase());
307
+ if (!account) {
308
+ results.push({ name, ok: false, reason: "no such account" });
309
+ continue;
310
+ }
311
+ if (account.role === "bridge") {
312
+ results.push({ name, ok: false, reason: "is a bridge account (host-owned by definition)" });
313
+ continue;
314
+ }
315
+ try {
316
+ await setAccountHost(
317
+ cfg.apiUrl,
318
+ cfg.masterKey,
319
+ account.id,
320
+ unclaim ? null : cfg.bridgeAgentName
321
+ );
322
+ results.push({ name, ok: true });
323
+ } catch (err) {
324
+ results.push({ name, ok: false, reason: err.message });
325
+ }
326
+ }
327
+ if (asJson) {
328
+ print(JSON.stringify({ host: unclaim ? null : cfg.bridgeAgentName, results }, null, 2));
329
+ return results.every((r) => r.ok) ? 0 : 1;
330
+ }
331
+ print("");
332
+ print(` ${PINK(unclaim ? "\u{1F380} Unclaiming accounts" : `\u{1F380} Claiming accounts for ${cfg.bridgeAgentName}`)}`);
333
+ print("");
334
+ for (const r of results) {
335
+ if (r.ok) ok(`${r.name}`);
336
+ else fail(`${r.name} \u2014 ${r.reason}`);
337
+ }
338
+ print("");
339
+ print(` ${DIM("Restart the dispatcher to apply: pm2 restart agenticmail-claudecode-dispatcher")}`);
340
+ print("");
341
+ return results.every((r) => r.ok) ? 0 : 1;
342
+ }
256
343
  async function main() {
257
344
  const args = process.argv.slice(2);
258
345
  if (args.includes("-h") || args.includes("--help") || args[0] === "help") {
@@ -270,6 +357,8 @@ async function main() {
270
357
  return runStatus(args.includes("--json"));
271
358
  case "tune":
272
359
  return runTune(args);
360
+ case "claim":
361
+ return runClaim(args);
273
362
  default:
274
363
  fail(`Unknown command: ${command}`);
275
364
  usage();
@@ -4,8 +4,8 @@ import {
4
4
  } from "./chunk-B5JDOV32.js";
5
5
  import {
6
6
  Dispatcher
7
- } from "./chunk-LVYWYEFG.js";
8
- import "./chunk-4VQP57SO.js";
7
+ } from "./chunk-VAEQFJDW.js";
8
+ import "./chunk-UI556UPF.js";
9
9
 
10
10
  // src/dispatcher-bin.ts
11
11
  async function main() {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Dispatcher
3
- } from "./chunk-LVYWYEFG.js";
4
- import "./chunk-4VQP57SO.js";
3
+ } from "./chunk-VAEQFJDW.js";
4
+ import "./chunk-UI556UPF.js";
5
5
  export {
6
6
  Dispatcher
7
7
  };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createIntegrationRoutes
3
- } from "./chunk-UARFA4NI.js";
4
- import "./chunk-Q5BA2J2C.js";
5
- import "./chunk-2RVJ2Q3W.js";
6
- import "./chunk-OUYPF4ER.js";
3
+ } from "./chunk-LD3W7MUC.js";
4
+ import "./chunk-XI7P3WSC.js";
5
+ import "./chunk-GMYSDT2Y.js";
6
+ import "./chunk-LKY2L2RR.js";
7
7
  import "./chunk-LO5EQSQA.js";
8
8
  import "./chunk-US5FT2UB.js";
9
- import "./chunk-4VQP57SO.js";
9
+ import "./chunk-UI556UPF.js";
10
10
  export {
11
11
  createIntegrationRoutes
12
12
  };
package/dist/index.js CHANGED
@@ -6,19 +6,19 @@ import {
6
6
  import {
7
7
  Dispatcher,
8
8
  loadPersonaForAgent
9
- } from "./chunk-LVYWYEFG.js";
9
+ } from "./chunk-VAEQFJDW.js";
10
10
  import {
11
11
  createIntegrationRoutes
12
- } from "./chunk-UARFA4NI.js";
12
+ } from "./chunk-LD3W7MUC.js";
13
13
  import {
14
14
  status
15
- } from "./chunk-Q5BA2J2C.js";
15
+ } from "./chunk-XI7P3WSC.js";
16
16
  import {
17
17
  uninstall
18
- } from "./chunk-2RVJ2Q3W.js";
18
+ } from "./chunk-GMYSDT2Y.js";
19
19
  import {
20
20
  install
21
- } from "./chunk-OUYPF4ER.js";
21
+ } from "./chunk-LKY2L2RR.js";
22
22
  import "./chunk-LO5EQSQA.js";
23
23
  import "./chunk-US5FT2UB.js";
24
24
  import {
@@ -32,7 +32,7 @@ import {
32
32
  renderPersonaBody,
33
33
  renderSubagentMarkdown,
34
34
  resolveConfig
35
- } from "./chunk-4VQP57SO.js";
35
+ } from "./chunk-UI556UPF.js";
36
36
  export {
37
37
  AgenticMailApiError,
38
38
  Dispatcher,
package/dist/install.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  install,
3
3
  selectExposableAgents
4
- } from "./chunk-OUYPF4ER.js";
4
+ } from "./chunk-LKY2L2RR.js";
5
5
  import "./chunk-LO5EQSQA.js";
6
6
  import "./chunk-US5FT2UB.js";
7
- import "./chunk-4VQP57SO.js";
7
+ import "./chunk-UI556UPF.js";
8
8
  export {
9
9
  install,
10
10
  selectExposableAgents
package/dist/status.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  status
3
- } from "./chunk-Q5BA2J2C.js";
3
+ } from "./chunk-XI7P3WSC.js";
4
4
  import "./chunk-US5FT2UB.js";
5
- import "./chunk-4VQP57SO.js";
5
+ import "./chunk-UI556UPF.js";
6
6
  export {
7
7
  status
8
8
  };
package/dist/uninstall.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  uninstall
3
- } from "./chunk-2RVJ2Q3W.js";
3
+ } from "./chunk-GMYSDT2Y.js";
4
4
  import "./chunk-LO5EQSQA.js";
5
5
  import "./chunk-US5FT2UB.js";
6
- import "./chunk-4VQP57SO.js";
6
+ import "./chunk-UI556UPF.js";
7
7
  export {
8
8
  uninstall
9
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/claudecode",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Claude Code integration for AgenticMail — surfaces every AgenticMail agent as a native Claude Code subagent so any Claude Code session can delegate to them with the Agent tool",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -47,8 +47,8 @@
47
47
  "prepublishOnly": "npm run build"
48
48
  },
49
49
  "dependencies": {
50
- "@agenticmail/core": "^0.9.2",
51
- "@agenticmail/mcp": "^0.9.2",
50
+ "@agenticmail/core": "^0.9.3",
51
+ "@agenticmail/mcp": "^0.9.4",
52
52
  "@anthropic-ai/claude-agent-sdk": "^0.2.140"
53
53
  },
54
54
  "peerDependencies": {