@agentcomms/events-daemon 0.16.0 → 0.18.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/README.md +138 -11
- package/THIRD_PARTY_LICENSES +2 -2
- package/dist/{b3-contract-03AO67VB.mjs → b3-contract-B6UBBK7F.mjs} +306 -55
- package/dist/cli.mjs +5083 -1385
- package/dist/index.d.mts +192 -35
- package/dist/index.mjs +1 -1
- package/dist/{mcp-DXXb3Vv3-B0sHZfig.mjs → mcp-DIH4cS6P-YuKZfqTg.mjs} +181 -68
- package/dist/records-DjE5a4_H.mjs +2 -0
- package/dist/{records-3rGS8spn.mjs → records-DsUxYBwb.mjs} +2 -2
- package/dist/{stdio-CD7QQBAh.mjs → stdio-Dp1EE6ok.mjs} +28 -3
- package/dist/{webhook-target-BkA_wHIu.mjs → webhook-target-DyDTwWhV.mjs} +38 -27
- package/package.json +11 -11
- package/dist/records-DojbuTaG.mjs +0 -2
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
import { i as serializeMessage, n as process, r as ReadBuffer } from "./mcp-
|
|
2
|
-
//#region ../../node_modules/.pnpm/@modelcontextprotocol+server@2.
|
|
1
|
+
import { i as serializeMessage, n as process, r as ReadBuffer } from "./mcp-DIH4cS6P-YuKZfqTg.mjs";
|
|
2
|
+
//#region ../../node_modules/.pnpm/@modelcontextprotocol+server@2.3.1/node_modules/@modelcontextprotocol/server/dist/stdio.mjs
|
|
3
|
+
/**
|
|
4
|
+
* Marks a stdout `'error'` listener that a closed transport left attached purely to
|
|
5
|
+
* swallow late write failures (see {@link StdioServerTransport.close}). A fresh
|
|
6
|
+
* transport taking over the same stream removes listeners carrying this tag in
|
|
7
|
+
* `start()`, so repeated create→close cycles on the process-global `process.stdout`
|
|
8
|
+
* don't accumulate listeners.
|
|
9
|
+
*/
|
|
10
|
+
const swallowsErrorsAfterClose = Symbol("swallowsErrorsAfterClose");
|
|
3
11
|
/**
|
|
4
12
|
* Server transport for stdio: this communicates with an MCP client by reading from the current process' `stdin` and writing to `stdout`.
|
|
5
13
|
*
|
|
6
14
|
* This transport is only available in Node.js environments.
|
|
7
15
|
*
|
|
16
|
+
* When the client closes its end of the pipe (stdin reaches end-of-file), the transport
|
|
17
|
+
* closes itself and fires `onclose`, per the MCP stdio binding's guidance that servers
|
|
18
|
+
* should exit promptly when their standard input is closed. A server that holds no other
|
|
19
|
+
* keep-alive handles will then exit naturally. Requests still in flight when stdin ends are
|
|
20
|
+
* aborted and not answered; a client that expects responses keeps stdin open until it has
|
|
21
|
+
* read them.
|
|
22
|
+
*
|
|
8
23
|
* @example
|
|
9
24
|
* ```ts source="./stdio.examples.ts#StdioServerTransport_basicUsage"
|
|
10
25
|
* const server = new McpServer({ name: 'my-server', version: '1.0.0' });
|
|
@@ -37,17 +52,25 @@ var StdioServerTransport = class {
|
|
|
37
52
|
this.onerror?.(error);
|
|
38
53
|
};
|
|
39
54
|
_onstdouterror = (error) => {
|
|
55
|
+
if (this._closed) return;
|
|
40
56
|
this.onerror?.(error);
|
|
41
57
|
this.close().catch(() => {});
|
|
42
58
|
};
|
|
59
|
+
_onstdinclose = () => {
|
|
60
|
+
this.close().catch(() => {});
|
|
61
|
+
};
|
|
43
62
|
/**
|
|
44
63
|
* Starts listening for messages on `stdin`.
|
|
45
64
|
*/
|
|
46
65
|
async start() {
|
|
47
66
|
if (this._started) throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
|
|
48
67
|
this._started = true;
|
|
68
|
+
for (const listener of this._stdout.listeners("error")) if (listener[swallowsErrorsAfterClose]) this._stdout.off("error", listener);
|
|
69
|
+
if (this._stdin.readableEnded || this._stdin.destroyed) setImmediate(this._onstdinclose);
|
|
49
70
|
this._stdin.on("data", this._ondata);
|
|
50
71
|
this._stdin.on("error", this._onerror);
|
|
72
|
+
this._stdin.on("end", this._onstdinclose);
|
|
73
|
+
this._stdin.on("close", this._onstdinclose);
|
|
51
74
|
this._stdout.on("error", this._onstdouterror);
|
|
52
75
|
}
|
|
53
76
|
processReadBuffer() {
|
|
@@ -64,7 +87,9 @@ var StdioServerTransport = class {
|
|
|
64
87
|
this._closed = true;
|
|
65
88
|
this._stdin.off("data", this._ondata);
|
|
66
89
|
this._stdin.off("error", this._onerror);
|
|
67
|
-
this.
|
|
90
|
+
this._stdin.off("end", this._onstdinclose);
|
|
91
|
+
this._stdin.off("close", this._onstdinclose);
|
|
92
|
+
this._onstdouterror[swallowsErrorsAfterClose] = true;
|
|
68
93
|
if (this._stdin.listenerCount("data") === 0) this._stdin.pause();
|
|
69
94
|
this._readBuffer.clear();
|
|
70
95
|
this.onclose?.();
|
|
@@ -1,25 +1,4 @@
|
|
|
1
1
|
import { canonicalJson, sha256Hex } from "@agentcomms/core";
|
|
2
|
-
//#region src/domain/lifecycle.ts
|
|
3
|
-
/** A content-free domain refusal. No caller should substitute an arbitrary Error message at a control boundary. */
|
|
4
|
-
var EventDomainError = class extends Error {
|
|
5
|
-
code;
|
|
6
|
-
constructor(code, message) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = "EventDomainError";
|
|
9
|
-
this.code = code;
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
const JUDGE_KINDS = [
|
|
13
|
-
"typesafe",
|
|
14
|
-
"laya",
|
|
15
|
-
"local-endpoint"
|
|
16
|
-
];
|
|
17
|
-
function isJudgeKind(value) {
|
|
18
|
-
return typeof value === "string" && JUDGE_KINDS.includes(value);
|
|
19
|
-
}
|
|
20
|
-
function assertJudgeKindEnabled(kind, enabled) {
|
|
21
|
-
if (!enabled) throw new EventDomainError("JUDGE_KIND_DISABLED", `the ${kind} judge kind is disabled`);
|
|
22
|
-
}
|
|
23
2
|
//#endregion
|
|
24
3
|
//#region src/network/iana-special-purpose.ts
|
|
25
4
|
/** Checked-in IANA policy; network code must never refresh or consult it at runtime. */
|
|
@@ -464,23 +443,30 @@ function embeddedAddresses(address, options) {
|
|
|
464
443
|
embedded.push(ipv4From(address.value >> 64n));
|
|
465
444
|
embedded.push(ipv4From((address.value ^ IPV4_MAX) & IPV4_MAX));
|
|
466
445
|
}
|
|
446
|
+
const isatapInterface = address.value >> 32n & IPV4_MAX;
|
|
447
|
+
if (isatapInterface === 24318n || isatapInterface === 33578750n) embedded.push(ipv4From(address.value));
|
|
467
448
|
return embedded;
|
|
468
449
|
}
|
|
469
450
|
function assertOne(address, approved, options, seen) {
|
|
470
451
|
if (seen.has(`${address.family}:${address.value}`)) return [];
|
|
471
452
|
seen.add(`${address.family}:${address.value}`);
|
|
472
453
|
if (isUnconditionallyDenied(address)) throw new AddressPolicyError(`address ${address.address} is metadata or link-local and is always refused`);
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
454
|
+
if (options.addressMode === "global-only") {
|
|
455
|
+
if (!globallyReachable(address)) throw new AddressPolicyError(`non-global address ${address.address} is refused by global-only policy`);
|
|
456
|
+
} else {
|
|
457
|
+
if (approved === void 0) throw new AddressPolicyError("approvedAddressSet was unavailable");
|
|
458
|
+
const explicitlyApproved = approved.some((entry) => inCidr(address, entry));
|
|
459
|
+
if (!globallyReachable(address) && !explicitlyApproved) throw new AddressPolicyError(`non-global address ${address.address} needs an exact approvedAddressSet entry`);
|
|
460
|
+
if (!explicitlyApproved) throw new AddressPolicyError(`address ${address.address} is not in the approvedAddressSet`);
|
|
461
|
+
}
|
|
476
462
|
const nested = embeddedAddresses(address, options);
|
|
477
463
|
for (const child of nested) assertOne(child, approved, options, seen);
|
|
478
464
|
return nested;
|
|
479
465
|
}
|
|
480
|
-
/** Validates the literal itself and every embedded transition address
|
|
466
|
+
/** Validates the literal itself and every embedded transition address under the selected exact-set or global-only policy. */
|
|
481
467
|
function assertAddressAllowed(input, options) {
|
|
482
468
|
const address = parseIpLiteral(input);
|
|
483
|
-
const embedded = assertOne(address, parseApprovedAddressSet(options.approvedAddressSet), options, /* @__PURE__ */ new Set());
|
|
469
|
+
const embedded = assertOne(address, options.addressMode === "global-only" ? void 0 : parseApprovedAddressSet(options.approvedAddressSet), options, /* @__PURE__ */ new Set());
|
|
484
470
|
return {
|
|
485
471
|
address: address.address,
|
|
486
472
|
family: address.family,
|
|
@@ -518,6 +504,31 @@ function validateLocalEndpoint(input, approvedAddressSet) {
|
|
|
518
504
|
};
|
|
519
505
|
}
|
|
520
506
|
//#endregion
|
|
507
|
+
//#region src/domain/lifecycle.ts
|
|
508
|
+
/** A content-free domain refusal. No caller should substitute an arbitrary Error message at a control boundary. */
|
|
509
|
+
var EventDomainError = class extends Error {
|
|
510
|
+
code;
|
|
511
|
+
constructor(code, message) {
|
|
512
|
+
super(message);
|
|
513
|
+
this.name = "EventDomainError";
|
|
514
|
+
this.code = code;
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
const JUDGE_KIND_TYPESAFE = "typesafe";
|
|
518
|
+
const JUDGE_KIND_LAYA = "laya";
|
|
519
|
+
const JUDGE_KIND_LOCAL_ENDPOINT = "local-endpoint";
|
|
520
|
+
const JUDGE_KINDS = [
|
|
521
|
+
JUDGE_KIND_TYPESAFE,
|
|
522
|
+
JUDGE_KIND_LAYA,
|
|
523
|
+
JUDGE_KIND_LOCAL_ENDPOINT
|
|
524
|
+
];
|
|
525
|
+
function isJudgeKind(value) {
|
|
526
|
+
return typeof value === "string" && JUDGE_KINDS.includes(value);
|
|
527
|
+
}
|
|
528
|
+
function assertJudgeKindEnabled(kind, enabled) {
|
|
529
|
+
if (!enabled) throw new EventDomainError("JUDGE_KIND_DISABLED", `the ${kind} judge kind is disabled`);
|
|
530
|
+
}
|
|
531
|
+
//#endregion
|
|
521
532
|
//#region src/domain/webhook-target.ts
|
|
522
533
|
function fail(message) {
|
|
523
534
|
throw new EventDomainError("VERSION_DOCUMENT_INVALID", message);
|
|
@@ -659,4 +670,4 @@ function webhookDeliveryTarget(document) {
|
|
|
659
670
|
};
|
|
660
671
|
}
|
|
661
672
|
//#endregion
|
|
662
|
-
export {
|
|
673
|
+
export { EventDomainError as a, JUDGE_KIND_LOCAL_ENDPOINT as c, isJudgeKind as d, validateLocalEndpoint as f, parseIpLiteral as g, assertApprovedAddressSet as h, webhookDeliveryTarget as i, JUDGE_KIND_TYPESAFE as l, assertAddressAllowed as m, canonicalWebhookTarget as n, JUDGE_KINDS as o, AddressPolicyError as p, secretWebhookUrlDescriptor as r, JUDGE_KIND_LAYA as s, canonicalSecretWebhookUrl as t, assertJudgeKindEnabled as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentcomms/events-daemon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "The local event service for agent-communications: rules you approve deliver Gmail, Slack, Resend and WhatsApp events to a signed webhook, a local live stream or a dry-run log.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,19 +34,19 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@agentcomms/
|
|
38
|
-
"@agentcomms/
|
|
39
|
-
"@agentcomms/
|
|
40
|
-
"@agentcomms/
|
|
41
|
-
"@agentcomms/core": "0.
|
|
42
|
-
"@agentcomms/
|
|
37
|
+
"@agentcomms/events": "0.18.0",
|
|
38
|
+
"@agentcomms/resend": "0.18.0",
|
|
39
|
+
"@agentcomms/gmail": "0.18.0",
|
|
40
|
+
"@agentcomms/slack": "0.18.0",
|
|
41
|
+
"@agentcomms/core": "0.18.0",
|
|
42
|
+
"@agentcomms/whatsapp": "0.18.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@modelcontextprotocol/client": "2.
|
|
46
|
-
"@modelcontextprotocol/server": "^2.
|
|
45
|
+
"@modelcontextprotocol/client": "2.3.1",
|
|
46
|
+
"@modelcontextprotocol/server": "^2.3.1",
|
|
47
47
|
"ajv": "8.20.0",
|
|
48
48
|
"commander": "^15.0.0",
|
|
49
|
-
"playwright": "1.
|
|
49
|
+
"playwright": "1.64.0",
|
|
50
50
|
"tsdown": "0.23.0",
|
|
51
51
|
"typescript": "7.0.2",
|
|
52
52
|
"zod": "^4.6.5"
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"typecheck": "tsc -p tsconfig.json",
|
|
71
71
|
"test": "node --import ../../test/helpers/loopback-seal-preload.mjs --experimental-strip-types --disable-warning=ExperimentalWarning --test \"test/**/*.test.ts\""
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "a55c5383b35a8214b9e481e2a148b0e29a663a9f"
|
|
74
74
|
}
|