@agenticmail/claudecode 0.2.7 → 0.2.8
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/dist/{chunk-JUEHPFKY.js → chunk-2RVJ2Q3W.js} +1 -1
- package/dist/{chunk-DKTAW2N5.js → chunk-LO5EQSQA.js} +2 -2
- package/dist/{chunk-4EHV3I6W.js → chunk-OUYPF4ER.js} +1 -1
- package/dist/{chunk-ZFLOFC6P.js → chunk-TV7VG7YM.js} +2 -2
- package/dist/cli.js +3 -3
- package/dist/http-routes.js +4 -4
- package/dist/index.js +4 -4
- package/dist/install.js +2 -2
- package/dist/mail-hook.js +98 -18
- package/dist/uninstall.js +2 -2
- package/package.json +1 -1
|
@@ -5,8 +5,8 @@ function isAgenticMailHookCommand(command) {
|
|
|
5
5
|
if (typeof command !== "string") return false;
|
|
6
6
|
return command.includes("agenticmail-mail-hook") || command.includes("mail-hook.js");
|
|
7
7
|
}
|
|
8
|
-
var HOOK_EVENTS_TO_REGISTER = ["UserPromptSubmit", "Stop"];
|
|
9
|
-
var HOOK_EVENTS_TO_REMOVE = ["UserPromptSubmit", "Stop", "PreToolUse"];
|
|
8
|
+
var HOOK_EVENTS_TO_REGISTER = ["UserPromptSubmit", "Stop", "SessionStart"];
|
|
9
|
+
var HOOK_EVENTS_TO_REMOVE = ["UserPromptSubmit", "Stop", "PreToolUse", "SessionStart"];
|
|
10
10
|
function readSettings(path) {
|
|
11
11
|
if (!existsSync(path)) return {};
|
|
12
12
|
const raw = readFileSync(path, "utf-8");
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
uninstall
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2RVJ2Q3W.js";
|
|
5
5
|
import {
|
|
6
6
|
install
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-OUYPF4ER.js";
|
|
8
|
+
import "./chunk-LO5EQSQA.js";
|
|
9
9
|
import {
|
|
10
10
|
status
|
|
11
11
|
} from "./chunk-Q5BA2J2C.js";
|
package/dist/http-routes.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createIntegrationRoutes
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-TV7VG7YM.js";
|
|
4
|
+
import "./chunk-2RVJ2Q3W.js";
|
|
5
|
+
import "./chunk-OUYPF4ER.js";
|
|
6
|
+
import "./chunk-LO5EQSQA.js";
|
|
7
7
|
import "./chunk-Q5BA2J2C.js";
|
|
8
8
|
import "./chunk-US5FT2UB.js";
|
|
9
9
|
import "./chunk-4VQP57SO.js";
|
package/dist/index.js
CHANGED
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
} from "./chunk-JOK76WRC.js";
|
|
5
5
|
import {
|
|
6
6
|
createIntegrationRoutes
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TV7VG7YM.js";
|
|
8
8
|
import {
|
|
9
9
|
uninstall
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2RVJ2Q3W.js";
|
|
11
11
|
import {
|
|
12
12
|
install
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-OUYPF4ER.js";
|
|
14
|
+
import "./chunk-LO5EQSQA.js";
|
|
15
15
|
import {
|
|
16
16
|
status
|
|
17
17
|
} from "./chunk-Q5BA2J2C.js";
|
package/dist/install.js
CHANGED
package/dist/mail-hook.js
CHANGED
|
@@ -7,6 +7,8 @@ import { join, dirname } from "path";
|
|
|
7
7
|
var AGENTICMAIL_DIR = join(homedir(), ".agenticmail");
|
|
8
8
|
var CONFIG_PATH = join(AGENTICMAIL_DIR, "config.json");
|
|
9
9
|
var CURSOR_PATH = join(AGENTICMAIL_DIR, "claudecode-hook-cursor.json");
|
|
10
|
+
var SESSIONS_PATH = join(AGENTICMAIL_DIR, "claudecode-hook-sessions.json");
|
|
11
|
+
var SESSIONS_CAP = 100;
|
|
10
12
|
var HOOK_VERSION = "1";
|
|
11
13
|
var HTTP_TIMEOUT_MS = 800;
|
|
12
14
|
var GLOBAL_TIMEOUT_MS = 1500;
|
|
@@ -47,17 +49,95 @@ async function readStdinJson() {
|
|
|
47
49
|
setTimeout(() => finish(() => null), 200).unref();
|
|
48
50
|
});
|
|
49
51
|
}
|
|
52
|
+
function capabilitiesBlurb() {
|
|
53
|
+
return [
|
|
54
|
+
"\u{1F380} AgenticMail is available via MCP (mcp__agenticmail__*).",
|
|
55
|
+
"",
|
|
56
|
+
"When to reach for it:",
|
|
57
|
+
" \xB7 Building anything that benefits from MULTIPLE specialized roles working in parallel \u2014 designer + developer + reviewer, researcher + writer + fact-checker, planner + executor + critic.",
|
|
58
|
+
" \xB7 Coordinating long-running async work that survives across Claude Code restarts (email threads are durable; in-memory state is not).",
|
|
59
|
+
" \xB7 Anywhere you would otherwise spawn the Task tool repeatedly for sub-tasks \u2014 prefer AgenticMail when those sub-tasks need to talk to EACH OTHER, not just back to you.",
|
|
60
|
+
"",
|
|
61
|
+
"High-leverage tools:",
|
|
62
|
+
" \xB7 mcp__agenticmail__create_account({ name, role }) \u2014 spawn a fresh persistent agent identity with its own inbox + API key.",
|
|
63
|
+
' \xB7 mcp__agenticmail__send_email({ to, cc, subject, text, wake }) \u2014 kick off the work. CC the whole team; use `wake: ["alice"]` to give exactly one agent the next turn while others stay informed.',
|
|
64
|
+
" \xB7 mcp__agenticmail__call_agent({ agent, message }) / mcp__agenticmail__wait_for_email \u2014 blocking RPC when you need a specific answer back before continuing your own turn.",
|
|
65
|
+
"",
|
|
66
|
+
"Coordination pattern: one email thread = the shared workspace. Reply-all keeps the audit trail. Use `wake` to control whose turn it is.",
|
|
67
|
+
"",
|
|
68
|
+
"Other tools cover: inbox/folder management, drafts, templates, tasks, contacts, signatures, SMS, voice. Full list under mcp__agenticmail__* \u2014 discover on demand, don't front-load them all."
|
|
69
|
+
].join("\n");
|
|
70
|
+
}
|
|
71
|
+
function loadSeenSessions() {
|
|
72
|
+
if (!existsSync(SESSIONS_PATH)) return [];
|
|
73
|
+
try {
|
|
74
|
+
const parsed = JSON.parse(readFileSync(SESSIONS_PATH, "utf-8"));
|
|
75
|
+
const arr = Array.isArray(parsed?.seen) ? parsed.seen : [];
|
|
76
|
+
return arr.filter((s) => typeof s === "string");
|
|
77
|
+
} catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function rememberSession(sessionId, seen) {
|
|
82
|
+
const next = seen.filter((s) => s !== sessionId);
|
|
83
|
+
next.push(sessionId);
|
|
84
|
+
while (next.length > SESSIONS_CAP) next.shift();
|
|
85
|
+
try {
|
|
86
|
+
if (!existsSync(dirname(SESSIONS_PATH))) mkdirSync(dirname(SESSIONS_PATH), { recursive: true });
|
|
87
|
+
writeFileSync(SESSIONS_PATH, JSON.stringify({ seen: next, hookVersion: HOOK_VERSION }, null, 2));
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
}
|
|
50
91
|
async function main() {
|
|
51
92
|
const input = await readStdinJson();
|
|
52
93
|
const eventName = input?.hook_event_name ?? "UserPromptSubmit";
|
|
53
|
-
|
|
94
|
+
const sessionId = typeof input?.session_id === "string" ? input.session_id : "";
|
|
95
|
+
if (eventName === "SessionStart") {
|
|
96
|
+
process.stdout.write(JSON.stringify({
|
|
97
|
+
hookSpecificOutput: {
|
|
98
|
+
hookEventName: "SessionStart",
|
|
99
|
+
additionalContext: capabilitiesBlurb()
|
|
100
|
+
}
|
|
101
|
+
}));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
let blurbContext = "";
|
|
105
|
+
if (eventName === "UserPromptSubmit" && sessionId) {
|
|
106
|
+
const seen = loadSeenSessions();
|
|
107
|
+
if (!seen.includes(sessionId)) {
|
|
108
|
+
blurbContext = capabilitiesBlurb();
|
|
109
|
+
rememberSession(sessionId, seen);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const emitAndExit = (mailContext) => {
|
|
113
|
+
const combined = [blurbContext, mailContext].filter(Boolean).join("\n\n");
|
|
114
|
+
if (!combined) return;
|
|
115
|
+
if (eventName === "Stop") {
|
|
116
|
+
process.stdout.write(JSON.stringify({ decision: "block", reason: combined }));
|
|
117
|
+
} else {
|
|
118
|
+
process.stdout.write(JSON.stringify({
|
|
119
|
+
hookSpecificOutput: {
|
|
120
|
+
hookEventName: eventName,
|
|
121
|
+
additionalContext: combined
|
|
122
|
+
}
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
127
|
+
emitAndExit("");
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
54
130
|
let cfg;
|
|
55
131
|
try {
|
|
56
132
|
cfg = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
|
|
57
133
|
} catch {
|
|
134
|
+
emitAndExit("");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (!cfg.masterKey) {
|
|
138
|
+
emitAndExit("");
|
|
58
139
|
return;
|
|
59
140
|
}
|
|
60
|
-
if (!cfg.masterKey) return;
|
|
61
141
|
const apiHost = cfg.api?.host ?? "127.0.0.1";
|
|
62
142
|
const apiPort = cfg.api?.port ?? 3829;
|
|
63
143
|
const apiUrl = `http://${apiHost}:${apiPort}`;
|
|
@@ -67,15 +147,22 @@ async function main() {
|
|
|
67
147
|
headers: { Authorization: `Bearer ${cfg.masterKey}` },
|
|
68
148
|
signal: AbortSignal.timeout(HTTP_TIMEOUT_MS)
|
|
69
149
|
});
|
|
70
|
-
if (!r.ok)
|
|
150
|
+
if (!r.ok) {
|
|
151
|
+
emitAndExit("");
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
71
154
|
const data = await r.json();
|
|
72
155
|
bridge = (data.agents ?? []).find(
|
|
73
156
|
(a) => a.name === "claudecode" || a.name === "claude" || a.role === "bridge"
|
|
74
157
|
);
|
|
75
158
|
} catch {
|
|
159
|
+
emitAndExit("");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (!bridge?.apiKey) {
|
|
163
|
+
emitAndExit("");
|
|
76
164
|
return;
|
|
77
165
|
}
|
|
78
|
-
if (!bridge?.apiKey) return;
|
|
79
166
|
let cursorMs = 0;
|
|
80
167
|
let lastCheckedMs = 0;
|
|
81
168
|
if (existsSync(CURSOR_PATH)) {
|
|
@@ -96,10 +183,14 @@ async function main() {
|
|
|
96
183
|
headers: { Authorization: `Bearer ${bridge.apiKey}` },
|
|
97
184
|
signal: AbortSignal.timeout(HTTP_TIMEOUT_MS)
|
|
98
185
|
});
|
|
99
|
-
if (!r.ok)
|
|
186
|
+
if (!r.ok) {
|
|
187
|
+
emitAndExit("");
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
100
190
|
const data = await r.json();
|
|
101
191
|
messages = data.messages ?? [];
|
|
102
192
|
} catch {
|
|
193
|
+
emitAndExit("");
|
|
103
194
|
return;
|
|
104
195
|
}
|
|
105
196
|
const newOnes = messages.filter((m) => {
|
|
@@ -118,6 +209,7 @@ async function main() {
|
|
|
118
209
|
} catch {
|
|
119
210
|
}
|
|
120
211
|
}
|
|
212
|
+
emitAndExit("");
|
|
121
213
|
return;
|
|
122
214
|
}
|
|
123
215
|
newOnes.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
|
@@ -149,19 +241,7 @@ async function main() {
|
|
|
149
241
|
);
|
|
150
242
|
} catch {
|
|
151
243
|
}
|
|
152
|
-
|
|
153
|
-
process.stdout.write(JSON.stringify({
|
|
154
|
-
decision: "block",
|
|
155
|
-
reason: lines.join("\n")
|
|
156
|
-
}));
|
|
157
|
-
} else {
|
|
158
|
-
process.stdout.write(JSON.stringify({
|
|
159
|
-
hookSpecificOutput: {
|
|
160
|
-
hookEventName: eventName,
|
|
161
|
-
additionalContext: lines.join("\n")
|
|
162
|
-
}
|
|
163
|
-
}));
|
|
164
|
-
}
|
|
244
|
+
emitAndExit(lines.join("\n"));
|
|
165
245
|
}
|
|
166
246
|
var globalTimeout = new Promise((resolve) => {
|
|
167
247
|
setTimeout(() => resolve(), GLOBAL_TIMEOUT_MS).unref();
|
package/dist/uninstall.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agenticmail/claudecode",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
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",
|