agent-comms 8.15.10 → 8.15.12

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.
@@ -15,7 +15,7 @@
15
15
  "source": "url",
16
16
  "url": "https://github.com/ExaDev/agent-comms.git"
17
17
  },
18
- "version": "8.15.10"
18
+ "version": "8.15.12"
19
19
  }
20
20
  ]
21
21
  }
@@ -18,5 +18,5 @@
18
18
  },
19
19
  "name": "agent-comms",
20
20
  "repository": "https://github.com/ExaDev/agent-comms",
21
- "version": "8.15.10"
21
+ "version": "8.15.12"
22
22
  }
package/README.md CHANGED
@@ -117,7 +117,7 @@ An explicit `dataDir` wins over the environment and the existing `slot.dir` over
117
117
  pi install npm:agent-comms
118
118
  ```
119
119
 
120
- The [`pi` manifest](/package.json) registers the extension automatically.
120
+ The [`pi` manifest](/package.json) registers the extension automatically. It points at the TypeScript source, which pi loads without a build step, so the same entry serves `pi install npm:agent-comms` and `pi install git:github.com/ExaDev/agent-comms`; the npm package ships `src` for that reason. A git install has no build output, so the bridge, API and mesh work but the dashboard routes answer 503 naming the missing frontend build; the npm package includes the built dashboard.
121
121
 
122
122
  The extension imports from `@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai`, which the pi host provides, and its peer range requires `0.79.0` or later. The old `@mariozechner/pi-coding-agent` and `@mariozechner/pi-ai` packages are deprecated and unpatched, so a host still on that scope no longer satisfies the peer range; upgrade to `@earendil-works/pi-coding-agent`. A `@mariozechner` host at `0.73.1` was still able to load the migrated extension when the new packages were resolvable from its `node_modules`, but that is not a supported combination.
123
123
 
@@ -4,6 +4,6 @@ export declare const RETRY_BACKOFF_MULTIPLIER = 2;
4
4
  export declare const MAX_TOTAL_RETRY_MS: number;
5
5
  /** The next delay in the doubling-with-cap backoff schedule, given the delay just used. */
6
6
  export declare function nextRetryDelayMs(previousDelayMs: number): number;
7
- /** Recognises a publish failure worth retrying (npm propagation lag, a transient 5xx from the registry's own infrastructure, a connection-level failure that never reached the registry, a login JWT that expired mid-retry-window, or the registry's database running short of resources) as opposed to any other failure -- a genuinely invalid publish request or authorisation failure, for instance, which retrying can never fix. */
7
+ /** Recognises a publish failure worth retrying (npm propagation lag, a transient 5xx from the registry's own infrastructure, a connection-level failure that never reached the registry, a login JWT that expired mid-retry-window, the registry's database running short of resources, or the registry's own call to npm failing) as opposed to any other failure -- a genuinely invalid publish request or authorisation failure, for instance, which retrying can never fix. */
8
8
  export declare function isRetryablePublishFailure(output: string): boolean;
9
9
  //# sourceMappingURL=mcp-registry-retry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-registry-retry.d.ts","sourceRoot":"","sources":["../../src/core/mcp-registry-retry.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAC7C,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAI1C,eAAO,MAAM,kBAAkB,QAC+B,CAAC;AAE/D,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAKhE;AAuCD,2aAA2a;AAC3a,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQjE"}
1
+ {"version":3,"file":"mcp-registry-retry.d.ts","sourceRoot":"","sources":["../../src/core/mcp-registry-retry.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAC7C,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAI1C,eAAO,MAAM,kBAAkB,QAC+B,CAAC;AAE/D,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAKhE;AA+CD,mdAAmd;AACnd,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CASjE"}
@@ -38,12 +38,18 @@ const DATABASE_RESOURCE_SHORTAGE_PATTERN = /\bSQLSTATE 53\d{3}\b/;
38
38
  function isDatabaseResourceShortage(output) {
39
39
  return DATABASE_RESOURCE_SHORTAGE_PATTERN.test(output);
40
40
  }
41
- /** Recognises a publish failure worth retrying (npm propagation lag, a transient 5xx from the registry's own infrastructure, a connection-level failure that never reached the registry, a login JWT that expired mid-retry-window, or the registry's database running short of resources) as opposed to any other failure -- a genuinely invalid publish request or authorisation failure, for instance, which retrying can never fix. */
41
+ // Confirmed as a sixth retryable failure mode (ExaDev/agent-comms, 2026-10-22, release run 39737960080, v8.15.10): the registry validates a publish by fetching the package's metadata from npm itself, and when that call timed out ("context deadline exceeded (Client.Timeout exceeded while awaiting headers)") it reported the failure as an HTTP 400, so the status pattern did not match, and the propagation-lag text did not either because npm never answered. The registry's own outbound call to npm failing is a fault between two other services that says nothing about this request, so it is retryable whatever the cause it names (a timeout, a reset, a bad gateway).
42
+ const NPM_METADATA_FETCH_FAILURE_TEXT = "failed to fetch package metadata from NPM";
43
+ function isNpmMetadataFetchFailure(output) {
44
+ return output.includes(NPM_METADATA_FETCH_FAILURE_TEXT);
45
+ }
46
+ /** Recognises a publish failure worth retrying (npm propagation lag, a transient 5xx from the registry's own infrastructure, a connection-level failure that never reached the registry, a login JWT that expired mid-retry-window, the registry's database running short of resources, or the registry's own call to npm failing) as opposed to any other failure -- a genuinely invalid publish request or authorisation failure, for instance, which retrying can never fix. */
42
47
  export function isRetryablePublishFailure(output) {
43
48
  return (isNpmPropagationLag(output) ||
44
49
  isRetryableServerError(output) ||
45
50
  isConnectionError(output) ||
46
51
  isExpiredJwt(output) ||
47
- isDatabaseResourceShortage(output));
52
+ isDatabaseResourceShortage(output) ||
53
+ isNpmMetadataFetchFailure(output));
48
54
  }
49
55
  //# sourceMappingURL=mcp-registry-retry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-registry-retry.js","sourceRoot":"","sources":["../../src/core/mcp-registry-retry.ts"],"names":[],"mappings":"AAAA,mgBAAmgB;AAEngB,sSAAsS;AACtS,EAAE;AACF,6bAA6b;AAC7b,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAC1C,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,MAAM,CAAC,MAAM,kBAAkB,GAC7B,uBAAuB,GAAG,kBAAkB,GAAG,aAAa,CAAC;AAE/D,2FAA2F;AAC3F,MAAM,UAAU,gBAAgB,CAAC,eAAuB;IACtD,OAAO,IAAI,CAAC,GAAG,CACb,eAAe,GAAG,wBAAwB,EAC1C,kBAAkB,CACnB,CAAC;AACJ,CAAC;AAED,kLAAkL;AAClL,SAAS,mBAAmB,CAAC,MAAc;IACzC,OAAO,CACL,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;QAChC,MAAM,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,yxBAAyxB;AACzxB,MAAM,2BAA2B,GAAG,iCAAiC,CAAC;AAEtE,SAAS,sBAAsB,CAAC,MAAc;IAC5C,OAAO,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,mjBAAmjB;AACnjB,MAAM,wBAAwB,GAC5B,gFAAgF,CAAC;AAEnF,SAAS,iBAAiB,CAAC,MAAc;IACvC,OAAO,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,+vBAA+vB;AAC/vB,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AAElE,SAAS,YAAY,CAAC,MAAc;IAClC,OAAO,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC/E,CAAC;AAED,2xBAA2xB;AAC3xB,MAAM,kCAAkC,GAAG,sBAAsB,CAAC;AAElE,SAAS,0BAA0B,CAAC,MAAc;IAChD,OAAO,kCAAkC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,2aAA2a;AAC3a,MAAM,UAAU,yBAAyB,CAAC,MAAc;IACtD,OAAO,CACL,mBAAmB,CAAC,MAAM,CAAC;QAC3B,sBAAsB,CAAC,MAAM,CAAC;QAC9B,iBAAiB,CAAC,MAAM,CAAC;QACzB,YAAY,CAAC,MAAM,CAAC;QACpB,0BAA0B,CAAC,MAAM,CAAC,CACnC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"mcp-registry-retry.js","sourceRoot":"","sources":["../../src/core/mcp-registry-retry.ts"],"names":[],"mappings":"AAAA,mgBAAmgB;AAEngB,sSAAsS;AACtS,EAAE;AACF,6bAA6b;AAC7b,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAC1C,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,MAAM,CAAC,MAAM,kBAAkB,GAC7B,uBAAuB,GAAG,kBAAkB,GAAG,aAAa,CAAC;AAE/D,2FAA2F;AAC3F,MAAM,UAAU,gBAAgB,CAAC,eAAuB;IACtD,OAAO,IAAI,CAAC,GAAG,CACb,eAAe,GAAG,wBAAwB,EAC1C,kBAAkB,CACnB,CAAC;AACJ,CAAC;AAED,kLAAkL;AAClL,SAAS,mBAAmB,CAAC,MAAc;IACzC,OAAO,CACL,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;QAChC,MAAM,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,yxBAAyxB;AACzxB,MAAM,2BAA2B,GAAG,iCAAiC,CAAC;AAEtE,SAAS,sBAAsB,CAAC,MAAc;IAC5C,OAAO,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,mjBAAmjB;AACnjB,MAAM,wBAAwB,GAC5B,gFAAgF,CAAC;AAEnF,SAAS,iBAAiB,CAAC,MAAc;IACvC,OAAO,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,+vBAA+vB;AAC/vB,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AAElE,SAAS,YAAY,CAAC,MAAc;IAClC,OAAO,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC/E,CAAC;AAED,2xBAA2xB;AAC3xB,MAAM,kCAAkC,GAAG,sBAAsB,CAAC;AAElE,SAAS,0BAA0B,CAAC,MAAc;IAChD,OAAO,kCAAkC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,ypBAAypB;AACzpB,MAAM,+BAA+B,GACnC,2CAA2C,CAAC;AAE9C,SAAS,yBAAyB,CAAC,MAAc;IAC/C,OAAO,MAAM,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC;AAC1D,CAAC;AAED,mdAAmd;AACnd,MAAM,UAAU,yBAAyB,CAAC,MAAc;IACtD,OAAO,CACL,mBAAmB,CAAC,MAAM,CAAC;QAC3B,sBAAsB,CAAC,MAAM,CAAC;QAC9B,iBAAiB,CAAC,MAAM,CAAC;QACzB,YAAY,CAAC,MAAM,CAAC;QACpB,0BAA0B,CAAC,MAAM,CAAC;QAClC,yBAAyB,CAAC,MAAM,CAAC,CAClC,CAAC;AACJ,CAAC"}
@@ -44,6 +44,10 @@ describe("isRetryablePublishFailure", () => {
44
44
  const output = 'Error: publish failed: server returned status 400: {"title":"Bad Request","status":400,"detail":"Failed to publish server","errors":[{"message":"failed to begin transaction: failed to connect to `user=app database=app`:\\n\\t34.118.233.51:5432 (registry-pg-rw.default): server error: FATAL: remaining connection slots are reserved for roles with the SUPERUSER attribute (SQLSTATE 53300)"}]}';
45
45
  expect(isRetryablePublishFailure(output)).toBe(true);
46
46
  });
47
+ it("recognises the registry failing to fetch the package's metadata from npm, which it reports as an HTTP 400 naming a client timeout: the request was valid and the registry's own call to npm timed out (ExaDev/agent-comms release run 39737960080, v8.15.10), so neither the status pattern nor the propagation-lag text matched and the job failed on its second attempt", () => {
48
+ const output = 'Error: publish failed: server returned status 400: {"title":"Bad Request","status":400,"detail":"Failed to publish server","errors":[{"message":"registry validation failed for package 0 (agent-comms): failed to fetch package metadata from NPM: Get \\"https://registry.npmjs.org/agent-comms/8.15.10\\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)"}]}';
49
+ expect(isRetryablePublishFailure(output)).toBe(true);
50
+ });
47
51
  it("does not retry a database error that is not a resource shortage, such as a constraint violation, which a retry would hit again", () => {
48
52
  const output = 'Error: publish failed: server returned status 400: {"title":"Bad Request","status":400,"detail":"Failed to publish server","errors":[{"message":"duplicate key value violates unique constraint (SQLSTATE 23505)"}]}';
49
53
  expect(isRetryablePublishFailure(output)).toBe(false);
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-registry-retry.unit.test.js","sourceRoot":"","sources":["../../src/test/mcp-registry-retry.unit.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-registry-retry.unit.test.js","sourceRoot":"","sources":["../../src/test/mcp-registry-retry.unit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pi-manifest-packed.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-manifest-packed.integration.test.d.ts","sourceRoot":"","sources":["../../src/test/pi-manifest-packed.integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Every extension the `pi` manifest in package.json names must ship in the published package. `pi install npm:agent-comms` reported success and then could not load the extension when the manifest pointed at `src/`, which `files` did not publish (ExaDev/agent-comms#412, #440); nothing in the suite noticed, because the manifest and the tarball were never compared.
3
+ *
4
+ * The tarball contents come from `npm pack --dry-run`, the same file selection a publish uses, so a `files` entry or an ignore rule that drops the manifest's path fails here and not in a user's install.
5
+ */
6
+ import { spawnSync } from "node:child_process";
7
+ import * as fs from "node:fs";
8
+ import path from "node:path";
9
+ import { describe, expect, it } from "vitest";
10
+ const packageRoot = path.resolve(import.meta.dirname, "../..");
11
+ function isRecord(value) {
12
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13
+ }
14
+ function isStringArray(value) {
15
+ return (Array.isArray(value) && value.every((item) => typeof item === "string"));
16
+ }
17
+ function readJson(file) {
18
+ return JSON.parse(fs.readFileSync(file, "utf-8"));
19
+ }
20
+ function manifestExtensions() {
21
+ const manifest = readJson(path.join(packageRoot, "package.json"));
22
+ if (!isRecord(manifest) || !isRecord(manifest.pi)) {
23
+ throw new Error("package.json has no pi manifest");
24
+ }
25
+ const { extensions } = manifest.pi;
26
+ if (!isStringArray(extensions)) {
27
+ throw new Error("package.json pi.extensions is not a list of paths");
28
+ }
29
+ return extensions;
30
+ }
31
+ function packedPaths() {
32
+ // --ignore-scripts keeps prepack and prepare out of a listing that only needs the file selection.
33
+ const result = spawnSync("npm", ["pack", "--dry-run", "--json", "--ignore-scripts"], { cwd: packageRoot, encoding: "utf-8" });
34
+ if (result.status !== 0) {
35
+ throw new Error(`npm pack --dry-run failed: ${result.stderr}`);
36
+ }
37
+ const listing = JSON.parse(result.stdout);
38
+ if (!Array.isArray(listing) || !isRecord(listing[0])) {
39
+ throw new Error("npm pack --dry-run printed no package listing");
40
+ }
41
+ const { files } = listing[0];
42
+ if (!Array.isArray(files)) {
43
+ throw new Error("npm pack --dry-run listing has no files");
44
+ }
45
+ return files.map((file) => {
46
+ if (!isRecord(file) || typeof file.path !== "string") {
47
+ throw new Error("npm pack --dry-run listed a file without a path");
48
+ }
49
+ return file.path;
50
+ });
51
+ }
52
+ describe("the pi manifest", () => {
53
+ it("names at least one extension, so the loop below cannot pass by checking nothing", () => {
54
+ expect(manifestExtensions().length).toBeGreaterThan(0);
55
+ });
56
+ it("names only extensions that exist in the repository", () => {
57
+ for (const extension of manifestExtensions()) {
58
+ expect(fs.existsSync(path.join(packageRoot, extension)), extension).toBe(true);
59
+ }
60
+ });
61
+ it("names only extensions the published package contains", () => {
62
+ const packed = new Set(packedPaths());
63
+ for (const extension of manifestExtensions()) {
64
+ expect(packed.has(path.posix.normalize(extension)), extension).toBe(true);
65
+ }
66
+ });
67
+ });
68
+ //# sourceMappingURL=pi-manifest-packed.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-manifest-packed.integration.test.js","sourceRoot":"","sources":["../../src/test/pi-manifest-packed.integration.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-comms",
3
3
  "description": "Cross-harness communication mesh for LLM agents — rooms, DMs, presence, and real-time push delivery over TCP",
4
- "version": "8.15.10",
4
+ "version": "8.15.12",
5
5
  "bin": {
6
6
  "agent-comms": "dist/cli.js"
7
7
  },
@@ -57,13 +57,22 @@ function isDatabaseResourceShortage(output: string): boolean {
57
57
  return DATABASE_RESOURCE_SHORTAGE_PATTERN.test(output);
58
58
  }
59
59
 
60
- /** Recognises a publish failure worth retrying (npm propagation lag, a transient 5xx from the registry's own infrastructure, a connection-level failure that never reached the registry, a login JWT that expired mid-retry-window, or the registry's database running short of resources) as opposed to any other failure -- a genuinely invalid publish request or authorisation failure, for instance, which retrying can never fix. */
60
+ // Confirmed as a sixth retryable failure mode (ExaDev/agent-comms, 2026-10-22, release run 39737960080, v8.15.10): the registry validates a publish by fetching the package's metadata from npm itself, and when that call timed out ("context deadline exceeded (Client.Timeout exceeded while awaiting headers)") it reported the failure as an HTTP 400, so the status pattern did not match, and the propagation-lag text did not either because npm never answered. The registry's own outbound call to npm failing is a fault between two other services that says nothing about this request, so it is retryable whatever the cause it names (a timeout, a reset, a bad gateway).
61
+ const NPM_METADATA_FETCH_FAILURE_TEXT =
62
+ "failed to fetch package metadata from NPM";
63
+
64
+ function isNpmMetadataFetchFailure(output: string): boolean {
65
+ return output.includes(NPM_METADATA_FETCH_FAILURE_TEXT);
66
+ }
67
+
68
+ /** Recognises a publish failure worth retrying (npm propagation lag, a transient 5xx from the registry's own infrastructure, a connection-level failure that never reached the registry, a login JWT that expired mid-retry-window, the registry's database running short of resources, or the registry's own call to npm failing) as opposed to any other failure -- a genuinely invalid publish request or authorisation failure, for instance, which retrying can never fix. */
61
69
  export function isRetryablePublishFailure(output: string): boolean {
62
70
  return (
63
71
  isNpmPropagationLag(output) ||
64
72
  isRetryableServerError(output) ||
65
73
  isConnectionError(output) ||
66
74
  isExpiredJwt(output) ||
67
- isDatabaseResourceShortage(output)
75
+ isDatabaseResourceShortage(output) ||
76
+ isNpmMetadataFetchFailure(output)
68
77
  );
69
78
  }