Skip to content

Commit 35e71cb

Browse files
fix(cli): bypass stale cache on tag-based registry lookup (#648)
The add command's tag fallback (e.g. `hyperframes add html-in-canvas`) uses the same 24h cached manifest as single-item lookups. When new items are added to the registry, the stale cache returns an incomplete item list, causing tag resolution to find zero matches. Pass skipCache: true in the tag fallback path so it always fetches the latest manifest from the registry.
1 parent 64f3a4e commit 35e71cb

3 files changed

Lines changed: 9 additions & 4 deletions

File tree

packages/cli/src/commands/add.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ export default defineCommand({
248248

249249
let items: Awaited<ReturnType<typeof resolveItemsByTag>>;
250250
try {
251-
items = await resolveItemsByTag(args.name, { baseUrl: config.registry });
251+
items = await resolveItemsByTag(args.name, { baseUrl: config.registry, skipCache: true });
252252
} catch {
253253
items = [];
254254
}

packages/cli/src/registry/remote.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,13 @@ async function fetchJson<T>(url: string): Promise<T> {
8484
*/
8585
export async function fetchRegistryManifest(
8686
baseUrl: string = DEFAULT_REGISTRY_URL,
87+
options?: { skipCache?: boolean },
8788
): Promise<RegistryManifest | undefined> {
8889
const cacheFile = cachePath(baseUrl, "registry");
89-
const cached = readCache<RegistryManifest>(cacheFile);
90-
if (cached) return cached;
90+
if (!options?.skipCache) {
91+
const cached = readCache<RegistryManifest>(cacheFile);
92+
if (cached) return cached;
93+
}
9194

9295
try {
9396
const manifest = await fetchJson<RegistryManifest>(`${baseUrl}/registry.json`);

packages/cli/src/registry/resolver.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { fetchItemManifest, fetchRegistryManifest, DEFAULT_REGISTRY_URL } from "
99

1010
export interface ResolveOptions {
1111
baseUrl?: string;
12+
/** Bypass the 24h manifest cache and fetch fresh data from the registry. */
13+
skipCache?: boolean;
1214
/**
1315
* Called once per item that fails to load inside `loadAllItems`. Defaults
1416
* to writing a diagnostic line to stderr. Pass a quieter implementation
@@ -30,7 +32,7 @@ export async function listRegistryItems(
3032
options: ResolveOptions = {},
3133
): Promise<RegistryManifestEntry[]> {
3234
const baseUrl = options.baseUrl ?? DEFAULT_REGISTRY_URL;
33-
const manifest = await fetchRegistryManifest(baseUrl);
35+
const manifest = await fetchRegistryManifest(baseUrl, { skipCache: options.skipCache });
3436
if (!manifest) return [];
3537
if (!filter?.type) return manifest.items;
3638
return manifest.items.filter((item) => item.type === filter.type);

0 commit comments

Comments
 (0)