diff --git a/packages/opencode/src/cli/cmd/github.ts b/packages/opencode/src/cli/cmd/github.ts index 927c964c9d8..cc0049b3177 100644 --- a/packages/opencode/src/cli/cmd/github.ts +++ b/packages/opencode/src/cli/cmd/github.ts @@ -475,6 +475,7 @@ export const GithubRunCommand = cmd({ let gitConfig: string let session: { id: string; title: string; version: string } let shareId: string | undefined + let unsubscribeSessionEvents: (() => void) | undefined let exitCode = 0 type PromptFiles = Awaited>["promptFiles"] const triggerCommentId = isCommentEvent @@ -814,6 +815,9 @@ export const GithubRunCommand = cmd({ } function subscribeSessionEvents() { + // Cleanup any existing subscription before creating a new one + unsubscribeSessionEvents?.() + const TOOL: Record = { todowrite: ["Todo", UI.Style.TEXT_WARNING_BOLD], todoread: ["Todo", UI.Style.TEXT_WARNING_BOLD], @@ -837,7 +841,7 @@ export const GithubRunCommand = cmd({ } let text = "" - Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => { + const unsubscribe = Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => { if (evt.properties.part.sessionID !== session.id) return //if (evt.properties.part.messageID === messageID) return const part = evt.properties.part @@ -864,6 +868,8 @@ export const GithubRunCommand = cmd({ } } }) + + unsubscribeSessionEvents = unsubscribe } async function summarize(response: string) { diff --git a/packages/opencode/src/provider/models.ts b/packages/opencode/src/provider/models.ts index c5465f9880e..5f1943ee10f 100644 --- a/packages/opencode/src/provider/models.ts +++ b/packages/opencode/src/provider/models.ts @@ -109,4 +109,26 @@ export namespace ModelsDev { } } -setInterval(() => ModelsDev.refresh(), 60 * 1000 * 60).unref() +let intervalId: ReturnType | undefined +let exitHandlerRegistered = false + +export function startRefreshInterval() { + if (intervalId) return + intervalId = setInterval(() => ModelsDev.refresh(), 60 * 1000 * 60).unref() + + // Register exit handler only once to prevent multiple registrations + if (!exitHandlerRegistered) { + exitHandlerRegistered = true + process.on("exit", stopRefreshInterval) + } +} + +export function stopRefreshInterval() { + if (intervalId) { + clearInterval(intervalId) + intervalId = undefined + } +} + +// Auto-start the interval on module load +startRefreshInterval() diff --git a/packages/opencode/src/tool/webfetch.ts b/packages/opencode/src/tool/webfetch.ts index e592caac23e..18432e745fe 100644 --- a/packages/opencode/src/tool/webfetch.ts +++ b/packages/opencode/src/tool/webfetch.ts @@ -56,17 +56,20 @@ export const WebFetchTool = Tool.define("webfetch", { "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8" } - const response = await fetch(params.url, { - signal: AbortSignal.any([controller.signal, ctx.abort]), - headers: { - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36", - Accept: acceptHeader, - "Accept-Language": "en-US,en;q=0.9", - }, - }) - - clearTimeout(timeoutId) + let response: Response + try { + response = await fetch(params.url, { + signal: AbortSignal.any([controller.signal, ctx.abort]), + headers: { + "User-Agent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36", + Accept: acceptHeader, + "Accept-Language": "en-US,en;q=0.9", + }, + }) + } finally { + clearTimeout(timeoutId) + } if (!response.ok) { throw new Error(`Request failed with status code: ${response.status}`)