Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
31 changes: 31 additions & 0 deletions src/intx-types-compat.test.ts
Original file line number Diff line number Diff line change
@@ -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",
);
});
});
25 changes: 25 additions & 0 deletions src/intx-types-compat.ts
Original file line number Diff line number Diff line change
@@ -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);
4 changes: 2 additions & 2 deletions src/recipients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -76,7 +76,7 @@ export function resolveMailboxRecipients(
// Instance addresses (`ins_<id>@…`) 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)
Expand Down
Loading