From ff0df99ea025d05dde3c94fe2452d3ef13330940 Mon Sep 17 00:00:00 2001 From: Ahmed Abushagur Date: Sat, 11 Apr 2026 09:04:38 -0700 Subject: [PATCH] fix: always fetch manifest from GitHub, 3s timeout for bad wifi Remove the 1h cache-first path that caused 14-day stale manifests. Every run now fetches fresh from GitHub (3s timeout). Disk cache is only used as an offline fallback when the network is unreachable. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/cli/package.json | 2 +- packages/cli/src/__tests__/manifest.test.ts | 5 +++-- packages/cli/src/manifest.ts | 22 ++------------------- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index ebefb0d63..0730675a8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openrouter/spawn", - "version": "1.0.3", + "version": "1.0.4", "type": "module", "bin": { "spawn": "cli.js" diff --git a/packages/cli/src/__tests__/manifest.test.ts b/packages/cli/src/__tests__/manifest.test.ts index 8afed3b91..7ace2e4a2 100644 --- a/packages/cli/src/__tests__/manifest.test.ts +++ b/packages/cli/src/__tests__/manifest.test.ts @@ -136,7 +136,7 @@ describe("manifest", () => { ); }); - it("should use disk cache when fresh", async () => { + it("should always fetch from GitHub even when cache exists", async () => { mkdirSync(join(env.testDir, "spawn"), { recursive: true, }); @@ -149,7 +149,8 @@ describe("manifest", () => { expect(manifest).toHaveProperty("agents"); expect(manifest).toHaveProperty("clouds"); expect(manifest).toHaveProperty("matrix"); - expect(global.fetch).not.toHaveBeenCalled(); + // Always fetches fresh — cache is only an offline fallback + expect(global.fetch).toHaveBeenCalled(); }); it("should refresh cache when forceRefresh is true", async () => { diff --git a/packages/cli/src/manifest.ts b/packages/cli/src/manifest.ts index 79e44bedb..74c28b4d8 100644 --- a/packages/cli/src/manifest.ts +++ b/packages/cli/src/manifest.ts @@ -117,8 +117,7 @@ const RAW_BASE = `https://raw.githubusercontent.com/${REPO}/main` as const; const SPAWN_CDN = "https://openrouter.ai/labs/spawn" as const; /** Static URL for version checks — GitHub release artifact, never changes with repo structure */ const VERSION_URL = `https://github.com/${REPO}/releases/download/cli-latest/version` as const; -const CACHE_TTL = 3600; // 1 hour in seconds -const FETCH_TIMEOUT = 10_000; // 10 seconds +const FETCH_TIMEOUT = 3_000; // 3 seconds — fast fallback on bad wifi // ── Cache helpers ────────────────────────────────────────────────────────────── @@ -236,13 +235,6 @@ async function fetchManifestFromGitHub(): Promise { let _cached: Manifest | null = null; let _staleCache = false; -function tryLoadFromDiskCache(): Manifest | null { - if (cacheAge() >= CACHE_TTL) { - return null; - } - return readCache(); -} - function updateCache(manifest: Manifest): Manifest { writeCache(manifest); _cached = manifest; @@ -287,17 +279,7 @@ export async function loadManifest(forceRefresh = false): Promise { return local; } - // Check disk cache first if not forcing refresh - if (!forceRefresh) { - const cached = tryLoadFromDiskCache(); - if (cached) { - _cached = cached; - _staleCache = false; - return cached; - } - } - - // Fetch from GitHub + // Always fetch fresh from GitHub — disk cache is offline-only fallback. const fetched = await fetchManifestFromGitHub(); if (fetched) { return updateCache(fetched);