From 5aaaf1e6bc12c0f8863a41db2bb3cdc0d6f95658 Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Thu, 13 Aug 2026 18:42:27 -0700 Subject: [PATCH 1/2] Bridge @intx/types isAgentAddress -> isRunAddress rename (CL-6003) Interchange renamed isAgentAddress to isRunAddress (INTR-358). Import the address check through a small compat module that prefers the new export and falls back to the old one, so this package works against both the pre-rename and post-rename @intx/types without a hard version bump or an external patch. --- src/intx-types-compat.test.ts | 31 +++++++++++++++++++++++++++++++ src/intx-types-compat.ts | 25 +++++++++++++++++++++++++ src/recipients.ts | 4 ++-- 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/intx-types-compat.test.ts create mode 100644 src/intx-types-compat.ts diff --git a/src/intx-types-compat.test.ts b/src/intx-types-compat.test.ts new file mode 100644 index 0000000..7b362da --- /dev/null +++ b/src/intx-types-compat.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, test } from "bun:test"; +import { resolveIsRunAddress } from "./intx-types-compat.js"; + +describe("resolveIsRunAddress", () => { + test("uses isRunAddress on a post-rename module", () => { + const isRunAddress = (address: string) => address.startsWith("run_"); + const resolved = resolveIsRunAddress({ isRunAddress }); + expect(resolved("run_abc@x.example")).toBe(true); + expect(resolved("usr_abc@x.example")).toBe(false); + }); + + test("falls back to isAgentAddress on a pre-rename module", () => { + const isAgentAddress = (address: string) => address.startsWith("ins_"); + const resolved = resolveIsRunAddress({ isAgentAddress }); + expect(resolved("ins_run42@x.example")).toBe(true); + expect(resolved("usr_alice@x.example")).toBe(false); + }); + + test("prefers isRunAddress when a module exposes both", () => { + const isRunAddress = () => true; + const isAgentAddress = () => false; + const resolved = resolveIsRunAddress({ isRunAddress, isAgentAddress }); + expect(resolved("anything@x.example")).toBe(true); + }); + + test("throws when a module exposes neither export", () => { + expect(() => resolveIsRunAddress({})).toThrow( + "@intx/types exports neither isRunAddress nor isAgentAddress", + ); + }); +}); diff --git a/src/intx-types-compat.ts b/src/intx-types-compat.ts new file mode 100644 index 0000000..481aa9f --- /dev/null +++ b/src/intx-types-compat.ts @@ -0,0 +1,25 @@ +// `@intx/types` renamed `isAgentAddress` to `isRunAddress` (INTR-358). This +// module bridges both shapes so the package keeps working against the +// pre-rename (^0.2.2) and post-rename builds without a version bump — import +// from here instead of naming either export directly. +import * as intxTypes from "@intx/types"; + +export type IntxTypesCompatModule = { + isRunAddress?: (address: string) => boolean; + isAgentAddress?: (address: string) => boolean; +}; + +export function resolveIsRunAddress( + mod: IntxTypesCompatModule, +): (address: string) => boolean { + const resolved = mod.isRunAddress ?? mod.isAgentAddress; + if (!resolved) { + throw new Error( + "@intx/types exports neither isRunAddress nor isAgentAddress", + ); + } + return resolved; +} + +export const isRunAddress: (address: string) => boolean = + resolveIsRunAddress(intxTypes); diff --git a/src/recipients.ts b/src/recipients.ts index 1fa02d7..cb253d0 100644 --- a/src/recipients.ts +++ b/src/recipients.ts @@ -2,7 +2,7 @@ // deciding which of those addresses are principal mailboxes this tenant owns. import { extractAddrSpec } from "@intx/mime"; -import { isAgentAddress } from "@intx/types"; +import { isRunAddress } from "./intx-types-compat.js"; /** * Split an address-list header (`To:`, `Cc:`) into its individual addresses. @@ -76,7 +76,7 @@ export function resolveMailboxRecipients( // Instance addresses (`ins_@…`) belong to a running workflow instance, // not to a person, and have their own delivery path — they are never // principal mailboxes. `@intx/types` owns that format; do not re-derive it. - if (isAgentAddress(address)) continue; + if (isRunAddress(address)) continue; const local = address.slice(0, at); const principalId = local.startsWith(USER_PREFIX) ? local.slice(USER_PREFIX.length) From 0e89fa7f53da3133d10a8a8d7eab6ff763c5eaeb Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Thu, 13 Aug 2026 18:43:34 -0700 Subject: [PATCH 2/2] Document the isAgentAddress -> isRunAddress compat shim in the changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd1ff3a..b728206 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,11 @@ always called out under their own heading. rolls back every new row from that call. Bus publish and optional host `enqueue` run only after commit for newly inserted ids; enqueue throws are logged and swallowed (same posture as bus publish). +- **Instance-address detection tolerates the upstream `isAgentAddress` -> + `isRunAddress` rename in `@intx/types` (INTR-358).** `recipients.ts` now + imports through `intx-types-compat.ts`, which prefers `isRunAddress` and + falls back to `isAgentAddress`, so this package works against both the + pre-rename and post-rename `@intx/types` without a peer version bump. ### Breaking