v2.2-paseo-providers: Paseo provider stack + v2.2.1 pane-scoped chat fixes
Ship Paseo-equivalent provider snapshot, AgentComposerBar, ACP dispatch rewrite with streaming/persist, permission prompts, and agent commands. Follow-up: pane-scoped chat resolution, CoderMessageList tool timeline, WS user-delta replace, and inference orphan tool_call stripping. Archive openspec v2-2; update CHANGELOG and CURRENT. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
49
apps/web/src/hooks/useProviderSnapshot.ts
Normal file
49
apps/web/src/hooks/useProviderSnapshot.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { useEffect, useSyncExternalStore } from 'react';
|
||||
import { api } from '@/api/client';
|
||||
import type { ProviderSnapshotEntry } from '@/api/types';
|
||||
|
||||
let cached: ProviderSnapshotEntry[] | null = null;
|
||||
let inflight: Promise<ProviderSnapshotEntry[]> | null = null;
|
||||
const listeners = new Set<() => void>();
|
||||
|
||||
function notify(): void {
|
||||
for (const fn of listeners) fn();
|
||||
}
|
||||
|
||||
function subscribe(fn: () => void): () => void {
|
||||
listeners.add(fn);
|
||||
return () => listeners.delete(fn);
|
||||
}
|
||||
|
||||
function getSnapshot(): ProviderSnapshotEntry[] | null {
|
||||
return cached;
|
||||
}
|
||||
|
||||
async function doFetch(cwd?: string): Promise<ProviderSnapshotEntry[]> {
|
||||
const data = await api.coder.snapshot(cwd);
|
||||
cached = data;
|
||||
inflight = null;
|
||||
notify();
|
||||
return data;
|
||||
}
|
||||
|
||||
function ensureLoaded(cwd?: string): void {
|
||||
if (cached || inflight) return;
|
||||
inflight = doFetch(cwd).catch((err) => {
|
||||
inflight = null;
|
||||
console.error('provider snapshot fetch failed:', err);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
export function refreshProviderSnapshot(cwd?: string): Promise<ProviderSnapshotEntry[]> {
|
||||
cached = null;
|
||||
inflight = null;
|
||||
return doFetch(cwd);
|
||||
}
|
||||
|
||||
export function useProviderSnapshot(cwd?: string): ProviderSnapshotEntry[] | null {
|
||||
const entries = useSyncExternalStore(subscribe, getSnapshot);
|
||||
useEffect(() => { ensureLoaded(cwd); }, [cwd]);
|
||||
return entries;
|
||||
}
|
||||
Reference in New Issue
Block a user