diff --git a/extensions/tlon/src/channel.ts b/extensions/tlon/src/channel.ts index e4c949452..74f4cb9f1 100644 --- a/extensions/tlon/src/channel.ts +++ b/extensions/tlon/src/channel.ts @@ -17,6 +17,48 @@ import { buildMediaText, sendDm, sendGroupMessage } from "./urbit/send.js"; import { monitorTlonProvider } from "./monitor/index.js"; import { tlonChannelConfigSchema } from "./config-schema.js"; import { tlonOnboardingAdapter } from "./onboarding.js"; +import { authenticate } from "./urbit/auth.js"; + +// Simple HTTP-only poke that doesn't open an EventSource (avoids conflict with monitor's SSE) +async function createHttpPokeApi(params: { url: string; code: string; ship: string }) { + const cookie = await authenticate(params.url, params.code); + const channelId = `${Math.floor(Date.now() / 1000)}-${Math.random().toString(36).substring(2, 8)}`; + const channelUrl = `${params.url}/~/channel/${channelId}`; + const shipName = params.ship.replace(/^~/, ""); + + return { + poke: async (pokeParams: { app: string; mark: string; json: unknown }) => { + const pokeId = Date.now(); + const pokeData = { + id: pokeId, + action: "poke", + ship: shipName, + app: pokeParams.app, + mark: pokeParams.mark, + json: pokeParams.json, + }; + + const response = await fetch(channelUrl, { + method: "PUT", + headers: { + "Content-Type": "application/json", + Cookie: cookie.split(";")[0], + }, + body: JSON.stringify([pokeData]), + }); + + if (!response.ok && response.status !== 204) { + const errorText = await response.text(); + throw new Error(`Poke failed: ${response.status} - ${errorText}`); + } + + return pokeId; + }, + delete: async () => { + // No-op for HTTP-only client + }, + }; +} const TLON_CHANNEL_ID = "tlon" as const; @@ -118,12 +160,11 @@ const tlonOutbound: ChannelOutboundAdapter = { throw new Error(`Invalid Tlon target. Use ${formatTargetHint()}`); } - ensureUrbitConnectPatched(); - const api = await Urbit.authenticate({ - ship: account.ship.replace(/^~/, ""), + // Use HTTP-only poke (no EventSource) to avoid conflicts with monitor's SSE connection + const api = await createHttpPokeApi({ url: account.url, + ship: account.ship, code: account.code, - verbose: false, }); try {