agenthub-multiagent-mcp 1.76.0 → 1.77.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.
- package/dist/commands/setup-shell.js +11 -11
- package/dist/currentCaptureSession.d.ts +31 -0
- package/dist/currentCaptureSession.d.ts.map +1 -0
- package/dist/currentCaptureSession.js +54 -0
- package/dist/currentCaptureSession.js.map +1 -0
- package/dist/currentCaptureSession.test.d.ts +2 -0
- package/dist/currentCaptureSession.test.d.ts.map +1 -0
- package/dist/currentCaptureSession.test.js +55 -0
- package/dist/currentCaptureSession.test.js.map +1 -0
- package/dist/session-capture.sh +21 -0
- package/dist/sessionCaptureScript.test.js +6 -5
- package/dist/sessionCaptureScript.test.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +24 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/tools.test.js +33 -3
- package/dist/tools/tools.test.js.map +1 -1
- package/dist/tools/whatsapp.d.ts +73 -0
- package/dist/tools/whatsapp.d.ts.map +1 -0
- package/dist/tools/whatsapp.js +278 -0
- package/dist/tools/whatsapp.js.map +1 -0
- package/dist/tools/whatsapp.test.d.ts +2 -0
- package/dist/tools/whatsapp.test.d.ts.map +1 -0
- package/dist/tools/whatsapp.test.js +139 -0
- package/dist/tools/whatsapp.test.js.map +1 -0
- package/package.json +79 -79
- package/skills/catalog.json +4 -2
- package/skills/commands/close-session.md +2 -2
- package/skills/commands/start-session.md +2 -2
- package/skills/manifest.json +4 -2
|
@@ -10,17 +10,17 @@ import * as path from "node:path";
|
|
|
10
10
|
import * as os from "node:os";
|
|
11
11
|
const BEGIN_MARKER = "# BEGIN agenthub — managed by agenthub-setup, do not edit inside markers";
|
|
12
12
|
const END_MARKER = "# END agenthub";
|
|
13
|
-
const SHELL_INIT_CONTENT = `# Auto-generated by \`agenthub-setup install-shell\`. Do not edit.
|
|
14
|
-
# Routes \`claude\` through tmux session \`agenthub-<agent_id>\` so the
|
|
15
|
-
# browser terminal (agenthub-tunneld) can attach. See:
|
|
16
|
-
# docs/plans/2026-04-21-browser-terminal-design.md D8.
|
|
17
|
-
claude() {
|
|
18
|
-
if [ -n "$TMUX" ] || [ ! -t 0 ]; then command claude "$@"; return; fi
|
|
19
|
-
local AGENT
|
|
20
|
-
AGENT=$(jq -r .agent_id "$HOME/.agenthub/config.json" 2>/dev/null)
|
|
21
|
-
if [ -z "$AGENT" ] || [ "$AGENT" = "null" ]; then command claude "$@"; return; fi
|
|
22
|
-
exec tmux new -A -s "agenthub-$AGENT" command claude "$@"
|
|
23
|
-
}
|
|
13
|
+
const SHELL_INIT_CONTENT = `# Auto-generated by \`agenthub-setup install-shell\`. Do not edit.
|
|
14
|
+
# Routes \`claude\` through tmux session \`agenthub-<agent_id>\` so the
|
|
15
|
+
# browser terminal (agenthub-tunneld) can attach. See:
|
|
16
|
+
# docs/plans/2026-04-21-browser-terminal-design.md D8.
|
|
17
|
+
claude() {
|
|
18
|
+
if [ -n "$TMUX" ] || [ ! -t 0 ]; then command claude "$@"; return; fi
|
|
19
|
+
local AGENT
|
|
20
|
+
AGENT=$(jq -r .agent_id "$HOME/.agenthub/config.json" 2>/dev/null)
|
|
21
|
+
if [ -z "$AGENT" ] || [ "$AGENT" = "null" ]; then command claude "$@"; return; fi
|
|
22
|
+
exec tmux new -A -s "agenthub-$AGENT" command claude "$@"
|
|
23
|
+
}
|
|
24
24
|
`;
|
|
25
25
|
export function detectShell() {
|
|
26
26
|
const shellPath = process.env.SHELL;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which coding session is this agent's work being captured into, if any
|
|
3
|
+
* (add-session-report-numbers).
|
|
4
|
+
*
|
|
5
|
+
* `session_close_report` attaches the answer when its caller did not pass a
|
|
6
|
+
* `session_id`, so a report from a captured session links to that session and
|
|
7
|
+
* shows its `s-YYYYMMDD-NNN` beside the report's own `h-` number. Before this,
|
|
8
|
+
* the `/close-session` skill never passed one, so no report ever linked.
|
|
9
|
+
*
|
|
10
|
+
* Two places can know, mirroring the two capture paths in session-capture.sh:
|
|
11
|
+
*
|
|
12
|
+
* 1. A daemon shift: the daemon opens the session and stamps
|
|
13
|
+
* `AGENTHUB_SESSION_ID` into the shift's environment, which this MCP
|
|
14
|
+
* process inherits.
|
|
15
|
+
* 2. An interactive session whose owner consented: the capture hook resolves
|
|
16
|
+
* a session per Claude Code session id and caches it beside the grant file
|
|
17
|
+
* (`<dir of grant>/agenthub-capture-state/<claude session id>.json`). The
|
|
18
|
+
* Claude session id is read from the activity marker the PostToolUse hook
|
|
19
|
+
* writes.
|
|
20
|
+
*
|
|
21
|
+
* Anything else — no capture, consent refused, a missing or unreadable file —
|
|
22
|
+
* answers `undefined`, and the report is filed without a session, exactly as
|
|
23
|
+
* before. This never throws and never calls the network.
|
|
24
|
+
*/
|
|
25
|
+
export interface CurrentCaptureSessionOptions {
|
|
26
|
+
env?: NodeJS.ProcessEnv;
|
|
27
|
+
workingDir?: string | null;
|
|
28
|
+
homeDir?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function currentCaptureSessionId(opts?: CurrentCaptureSessionOptions): string | undefined;
|
|
31
|
+
//# sourceMappingURL=currentCaptureSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currentCaptureSession.d.ts","sourceRoot":"","sources":["../src/currentCaptureSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAOH,MAAM,WAAW,4BAA4B;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,4BAAiC,GAAG,MAAM,GAAG,SAAS,CA8BnG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which coding session is this agent's work being captured into, if any
|
|
3
|
+
* (add-session-report-numbers).
|
|
4
|
+
*
|
|
5
|
+
* `session_close_report` attaches the answer when its caller did not pass a
|
|
6
|
+
* `session_id`, so a report from a captured session links to that session and
|
|
7
|
+
* shows its `s-YYYYMMDD-NNN` beside the report's own `h-` number. Before this,
|
|
8
|
+
* the `/close-session` skill never passed one, so no report ever linked.
|
|
9
|
+
*
|
|
10
|
+
* Two places can know, mirroring the two capture paths in session-capture.sh:
|
|
11
|
+
*
|
|
12
|
+
* 1. A daemon shift: the daemon opens the session and stamps
|
|
13
|
+
* `AGENTHUB_SESSION_ID` into the shift's environment, which this MCP
|
|
14
|
+
* process inherits.
|
|
15
|
+
* 2. An interactive session whose owner consented: the capture hook resolves
|
|
16
|
+
* a session per Claude Code session id and caches it beside the grant file
|
|
17
|
+
* (`<dir of grant>/agenthub-capture-state/<claude session id>.json`). The
|
|
18
|
+
* Claude session id is read from the activity marker the PostToolUse hook
|
|
19
|
+
* writes.
|
|
20
|
+
*
|
|
21
|
+
* Anything else — no capture, consent refused, a missing or unreadable file —
|
|
22
|
+
* answers `undefined`, and the report is filed without a session, exactly as
|
|
23
|
+
* before. This never throws and never calls the network.
|
|
24
|
+
*/
|
|
25
|
+
import * as fs from "fs";
|
|
26
|
+
import * as os from "os";
|
|
27
|
+
import * as path from "path";
|
|
28
|
+
import { readActivityMarker } from "./activityMarker.js";
|
|
29
|
+
export function currentCaptureSessionId(opts = {}) {
|
|
30
|
+
const env = opts.env ?? process.env;
|
|
31
|
+
const fromEnv = (env.AGENTHUB_SESSION_ID || "").trim();
|
|
32
|
+
if (fromEnv)
|
|
33
|
+
return fromEnv;
|
|
34
|
+
if (!opts.workingDir)
|
|
35
|
+
return undefined;
|
|
36
|
+
const claudeSessionId = readActivityMarker(opts.workingDir)?.session_id;
|
|
37
|
+
if (!claudeSessionId)
|
|
38
|
+
return undefined;
|
|
39
|
+
const grantPath = (env.AGENTHUB_CAPTURE_GRANT || "").trim() ||
|
|
40
|
+
path.join(opts.homeDir ?? os.homedir(), ".claude", "agenthub-capture.json");
|
|
41
|
+
// Same file name rule as session-capture.sh: os.sep replaced by "_".
|
|
42
|
+
const stateFile = path.join(path.dirname(grantPath), "agenthub-capture-state", claudeSessionId.split(path.sep).join("_") + ".json");
|
|
43
|
+
try {
|
|
44
|
+
const state = JSON.parse(fs.readFileSync(stateFile, "utf8"));
|
|
45
|
+
if (state.denied)
|
|
46
|
+
return undefined;
|
|
47
|
+
const id = typeof state.session_id === "string" ? state.session_id.trim() : "";
|
|
48
|
+
return id || undefined;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=currentCaptureSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currentCaptureSession.js","sourceRoot":"","sources":["../src/currentCaptureSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAQzD,MAAM,UAAU,uBAAuB,CAAC,OAAqC,EAAE;IAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAEpC,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,IAAI,CAAC,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,eAAe,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxE,IAAI,CAAC,eAAe;QAAE,OAAO,SAAS,CAAC;IAEvC,MAAM,SAAS,GACb,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,uBAAuB,CAAC,CAAC;IAC9E,qEAAqE;IACrE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CACzB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EACvB,wBAAwB,EACxB,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CACpD,CAAC;IACF,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAG1D,CAAC;QACF,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QACnC,MAAM,EAAE,GAAG,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,OAAO,EAAE,IAAI,SAAS,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currentCaptureSession.test.d.ts","sourceRoot":"","sources":["../src/currentCaptureSession.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
import { currentCaptureSessionId } from "./currentCaptureSession.js";
|
|
6
|
+
import { writeActivityMarker } from "./activityMarker.js";
|
|
7
|
+
let tmp;
|
|
8
|
+
let work;
|
|
9
|
+
let grant;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), "agenthub-capsess-"));
|
|
12
|
+
work = path.join(tmp, "work");
|
|
13
|
+
fs.mkdirSync(work);
|
|
14
|
+
grant = path.join(tmp, "claude", "agenthub-capture.json");
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
18
|
+
});
|
|
19
|
+
function writeState(claudeSid, state) {
|
|
20
|
+
const dir = path.join(path.dirname(grant), "agenthub-capture-state");
|
|
21
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
22
|
+
fs.writeFileSync(path.join(dir, `${claudeSid}.json`), JSON.stringify(state));
|
|
23
|
+
}
|
|
24
|
+
describe("currentCaptureSessionId", () => {
|
|
25
|
+
it("prefers AGENTHUB_SESSION_ID (a daemon shift)", () => {
|
|
26
|
+
writeActivityMarker(work, "editing", { session_id: "claude-1", transcript_path: "/t" });
|
|
27
|
+
writeState("claude-1", { session_id: "from-state" });
|
|
28
|
+
const env = { AGENTHUB_SESSION_ID: " shift-sess ", AGENTHUB_CAPTURE_GRANT: grant };
|
|
29
|
+
expect(currentCaptureSessionId({ env, workingDir: work })).toBe("shift-sess");
|
|
30
|
+
});
|
|
31
|
+
it("reads the capture hook's cached session for the current Claude session", () => {
|
|
32
|
+
writeActivityMarker(work, "editing", { session_id: "claude-1", transcript_path: "/t" });
|
|
33
|
+
writeState("claude-1", { session_id: "cs-uuid-1", notice_text: "x" });
|
|
34
|
+
expect(currentCaptureSessionId({ env: { AGENTHUB_CAPTURE_GRANT: grant }, workingDir: work })).toBe("cs-uuid-1");
|
|
35
|
+
});
|
|
36
|
+
it("answers nothing when capture was refused", () => {
|
|
37
|
+
writeActivityMarker(work, "editing", { session_id: "claude-1", transcript_path: "/t" });
|
|
38
|
+
writeState("claude-1", { denied: true, session_id: "stale" });
|
|
39
|
+
expect(currentCaptureSessionId({ env: { AGENTHUB_CAPTURE_GRANT: grant }, workingDir: work })).toBeUndefined();
|
|
40
|
+
});
|
|
41
|
+
it("answers nothing with no marker, no state file, or no working dir", () => {
|
|
42
|
+
expect(currentCaptureSessionId({ env: { AGENTHUB_CAPTURE_GRANT: grant }, workingDir: work })).toBeUndefined();
|
|
43
|
+
writeActivityMarker(work, "editing", { session_id: "claude-2", transcript_path: "/t" });
|
|
44
|
+
expect(currentCaptureSessionId({ env: { AGENTHUB_CAPTURE_GRANT: grant }, workingDir: work })).toBeUndefined();
|
|
45
|
+
expect(currentCaptureSessionId({ env: {}, workingDir: null })).toBeUndefined();
|
|
46
|
+
});
|
|
47
|
+
it("uses ~/.claude/agenthub-capture.json when no grant path is set", () => {
|
|
48
|
+
const home = path.join(tmp, "home");
|
|
49
|
+
grant = path.join(home, ".claude", "agenthub-capture.json");
|
|
50
|
+
writeActivityMarker(work, "editing", { session_id: "claude-3", transcript_path: "/t" });
|
|
51
|
+
writeState("claude-3", { session_id: "cs-home" });
|
|
52
|
+
expect(currentCaptureSessionId({ env: {}, workingDir: work, homeDir: home })).toBe("cs-home");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=currentCaptureSession.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currentCaptureSession.test.js","sourceRoot":"","sources":["../src/currentCaptureSession.test.ts"],"names":[],"mappings":"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"}
|
package/dist/session-capture.sh
CHANGED
|
@@ -36,6 +36,27 @@ CONNECT_TOKEN=""
|
|
|
36
36
|
PY=$(command -v python || command -v python3)
|
|
37
37
|
[ -z "$PY" ] && exit 0
|
|
38
38
|
|
|
39
|
+
# --- WhatsApp: a session that read WhatsApp is never captured again ----------
|
|
40
|
+
#
|
|
41
|
+
# The AgentHub MCP writes an empty marker named for the Claude Code session id
|
|
42
|
+
# before its first call to the local WhatsApp reader
|
|
43
|
+
# (add-whatsapp-personal-reader §3.5). From then on this hook uploads nothing
|
|
44
|
+
# for that session, on either path below, so the owner's messages cannot reach
|
|
45
|
+
# the server through session capture.
|
|
46
|
+
WA_READ=$(echo "$INPUT" | "$PY" -c "
|
|
47
|
+
import sys, json, os
|
|
48
|
+
try:
|
|
49
|
+
sid = json.load(sys.stdin).get('session_id') or ''
|
|
50
|
+
except Exception:
|
|
51
|
+
sid = ''
|
|
52
|
+
if sid:
|
|
53
|
+
name = sid.replace(os.sep, '_').replace('/', '_')
|
|
54
|
+
marker = os.path.join(os.path.expanduser('~'), '.claude', 'agenthub-whatsapp-sessions', name)
|
|
55
|
+
if os.path.exists(marker):
|
|
56
|
+
print('1')
|
|
57
|
+
" 2>/dev/null)
|
|
58
|
+
[ "$WA_READ" = "1" ] && exit 0
|
|
59
|
+
|
|
39
60
|
# --- Interactive (human) path: resolve a session id, consent permitting -------
|
|
40
61
|
#
|
|
41
62
|
# Emits four lines: session id, api url, connect token, and the notice JSON to
|
|
@@ -49,11 +49,12 @@ describe("session-capture.sh", () => {
|
|
|
49
49
|
// runs. A drift between them means one caller silently gets old behaviour.
|
|
50
50
|
expect(read(PACKAGE_COPY)).toBe(read(REPO_COPY));
|
|
51
51
|
});
|
|
52
|
-
it("embeds exactly the
|
|
53
|
-
// The
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
|
|
52
|
+
it("embeds exactly the three Python blocks the script is built around", () => {
|
|
53
|
+
// The WhatsApp marker check (add-whatsapp-personal-reader §3.5), the
|
|
54
|
+
// interactive bootstrap (§3.2) and the event builder (§1.5). A fourth
|
|
55
|
+
// would mean someone added a block that these guards have not been
|
|
56
|
+
// reviewed against.
|
|
57
|
+
expect(pythonBlocks(read(PACKAGE_COPY))).toHaveLength(3);
|
|
57
58
|
});
|
|
58
59
|
it("contains no backtick inside an embedded Python block", () => {
|
|
59
60
|
// Bash runs backticks inside a double-quoted string as a command, even in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionCaptureScript.test.js","sourceRoot":"","sources":["../src/sessionCaptureScript.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACxF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,oBAAoB,CAAC,CAAC;AAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC;AAEhF,SAAS,IAAI,CAAC,CAAS;IACrB,OAAO,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,MAAc;IAClC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,YAAY,CAAC;IAC5B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,SAAS,CAAC;QACR,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,MAAM;QACxB,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QACxD,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,MAAM;QACtB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;QAC1C,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,4EAA4E;QAC5E,2EAA2E;QAC3E,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"sessionCaptureScript.test.js","sourceRoot":"","sources":["../src/sessionCaptureScript.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAqD,MAAM,cAAc,CAAC;AAOrG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAqD,MAAM,cAAc,CAAC;AAOrG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAoH/D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,iBAAiB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;OAGG;IACH,cAAc,EAAE,MAAM,WAAW,CAAC;IAClC,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,WAAW,CAAC;IACpC,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,KAAK,IAAI,CAAC;CACZ;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyLD,wBAAgB,aAAa,IAAI,IAAI,EAAE,CAwhGtC;AAqCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAyzFlB"}
|
package/dist/tools/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { handleEmployeeTrainingToolCall, isEmployeeTrainingTool, registerEmploye
|
|
|
16
16
|
import { registerSessionControlTools, handleSessionControlToolCall, isSessionControlTool, } from "./sessionControl.js";
|
|
17
17
|
import { registerGoshtiReadTools, handleGoshtiReadToolCall, isGoshtiReadTool, } from "./goshtiRead.js";
|
|
18
18
|
import { registerRunTools, handleRunToolCall, isRunTool } from "./runs.js";
|
|
19
|
+
import { isWhatsAppTool, runWhatsAppTool, whatsappToolDefinitions } from "./whatsapp.js";
|
|
19
20
|
import { installPackFromArchive } from "../skillPackInstaller.js";
|
|
20
21
|
import { getServerTime, useTimeInjection } from "../lib/server-time.js";
|
|
21
22
|
import { getPendingItems } from "../lib/pending-items.js";
|
|
@@ -26,6 +27,7 @@ import * as path from "node:path";
|
|
|
26
27
|
import { describeSendResult } from "../messageIdempotency.js";
|
|
27
28
|
import { readZohoAttachments } from "../zohoAttachments.js";
|
|
28
29
|
import { isUnknownSendOutcome, unknownSendOutcomeError } from "../zohoSendOutcome.js";
|
|
30
|
+
import { currentCaptureSessionId } from "../currentCaptureSession.js";
|
|
29
31
|
// fix-message-send-idempotency — shared by the four message tools.
|
|
30
32
|
const IDEMPOTENCY_KEY_DESCRIPTION = "Optional. Leave unset: a key derived from the message content is sent, so " +
|
|
31
33
|
"re-issuing this exact call (e.g. after a timeout) never delivers it twice. " +
|
|
@@ -2221,6 +2223,9 @@ export function registerTools() {
|
|
|
2221
2223
|
...registerEmployeeTrainingTools(),
|
|
2222
2224
|
// Reading Goshti as the agent's owner (add-agent-goshti-read §3.1)
|
|
2223
2225
|
...registerGoshtiReadTools(),
|
|
2226
|
+
// Reading the owner's WhatsApp through the local reader on this PC
|
|
2227
|
+
// (add-whatsapp-personal-reader §3). Never touches the AgentHub server.
|
|
2228
|
+
...whatsappToolDefinitions(),
|
|
2224
2229
|
// Orchestrated runs for the dashboard Run view (add-live-animated-views §1.8)
|
|
2225
2230
|
...registerRunTools(),
|
|
2226
2231
|
// OpenSpec Visualizer tools
|
|
@@ -2461,13 +2466,13 @@ export function registerTools() {
|
|
|
2461
2466
|
// Session handoff tools (add-session-handoff)
|
|
2462
2467
|
{
|
|
2463
2468
|
name: "session_close_report",
|
|
2464
|
-
description: "Upload a session-close handoff report to AgentHub. Call this at the end of every session after running the close-session skill. Shares what shipped + what the next session should pick up, so /start-session on the next run (any machine) can resume cleanly.",
|
|
2469
|
+
description: "Upload a session-close handoff report to AgentHub. Call this at the end of every session after running the close-session skill. Shares what shipped + what the next session should pick up, so /start-session on the next run (any machine) can resume cleanly. The reply carries `display_number` (the report's own `h-YYYYMMDD-NNN`, always) and `session_display_number` (the captured coding session's `s-YYYYMMDD-NNN`, only when this session is captured).",
|
|
2465
2470
|
inputSchema: {
|
|
2466
2471
|
type: "object",
|
|
2467
2472
|
properties: {
|
|
2468
2473
|
summary: { type: "string", description: "Markdown summary of what shipped this session" },
|
|
2469
2474
|
next_plan: { type: "string", description: "Markdown of what the next session should pick up" },
|
|
2470
|
-
session_id: { type: "string", description: "Optional session UUID or display number `s-YYYYMMDD-NNN` for upsert keying. Server resolves either form to the canonical UUID before storing." },
|
|
2475
|
+
session_id: { type: "string", description: "Optional session UUID or display number `s-YYYYMMDD-NNN` for upsert keying. Server resolves either form to the canonical UUID before storing. Omit it normally: when this session is being captured, the tool attaches the capture session itself." },
|
|
2471
2476
|
commits: {
|
|
2472
2477
|
type: "array",
|
|
2473
2478
|
description: "Commits pushed this session",
|
|
@@ -3251,6 +3256,17 @@ export async function handleToolCall(name, args, client, context) {
|
|
|
3251
3256
|
if (isGoshtiReadTool(name)) {
|
|
3252
3257
|
return handleGoshtiReadToolCall(name, args, client);
|
|
3253
3258
|
}
|
|
3259
|
+
// WhatsApp reads (add-whatsapp-personal-reader §3). Local only: no agent
|
|
3260
|
+
// registration needed, no server call, refused unless the session is private.
|
|
3261
|
+
if (isWhatsAppTool(name)) {
|
|
3262
|
+
const out = await runWhatsAppTool(name, args, {
|
|
3263
|
+
env: process.env,
|
|
3264
|
+
homeDir: os.homedir(),
|
|
3265
|
+
workingDir: context.getWorkingDir(),
|
|
3266
|
+
fetch: (url, init) => fetch(url, init),
|
|
3267
|
+
});
|
|
3268
|
+
return { content: [{ type: "text", text: JSON.stringify(out, null, 2) }] };
|
|
3269
|
+
}
|
|
3254
3270
|
// Orchestrated runs (add-live-animated-views §1.8). Same module pattern. The
|
|
3255
3271
|
// run id run_open returns is kept in .agenthub/state, so the other run tools
|
|
3256
3272
|
// (and sub-agents sharing the checkout's state) default to it.
|
|
@@ -5348,8 +5364,12 @@ export async function handleToolCall(name, args, client, context) {
|
|
|
5348
5364
|
summary,
|
|
5349
5365
|
next_plan: nextPlan,
|
|
5350
5366
|
};
|
|
5351
|
-
|
|
5352
|
-
|
|
5367
|
+
// add-session-report-numbers: a caller's session_id wins; otherwise link
|
|
5368
|
+
// the session this work is being captured into, when there is one.
|
|
5369
|
+
const sessionId = args.session_id ||
|
|
5370
|
+
currentCaptureSessionId({ workingDir: context.getWorkingDir() });
|
|
5371
|
+
if (sessionId)
|
|
5372
|
+
body.session_id = sessionId;
|
|
5353
5373
|
if (args.commits)
|
|
5354
5374
|
body.commits = args.commits;
|
|
5355
5375
|
if (args.open_threads)
|