345 lines
12 KiB
TypeScript
345 lines
12 KiB
TypeScript
import { create } from 'zustand';
|
|||
|
|
import { devtools } from 'zustand/middleware';
|
||
|
|
import { getRuntimeKey } from '@/lib/runtime-switch';
|
||
|
|
import {
|
||
|
|
cancelWalkthroughGeneration,
|
||
|
|
fetchWalkthrough,
|
||
|
|
fetchWalkthroughStage,
|
||
|
|
generateWalkthrough,
|
||
|
|
} from '@/lib/walkthrough/api';
|
||
|
|
import {
|
||
|
|
WalkthroughError,
|
||
|
|
type WalkthroughModel,
|
||
|
|
type WalkthroughReadiness,
|
||
|
|
type WalkthroughResult,
|
||
|
|
type WalkthroughSource,
|
||
|
|
type WalkthroughStage,
|
||
|
|
} from '@/lib/walkthrough/types';
|
||
|
|
|
||
|
|
// Walkthroughs live on the server, keyed by repository and source. This store
|
||
|
|
// is a view cache over that, keyed the same way plus the runtime, so switching
|
||
|
|
// between a local and a remote runtime never shows one runtime's walkthrough
|
||
|
|
// for the other's code.
|
||
|
|
|
||
|
|
export type WalkthroughEntryStatus = 'idle' | 'loading' | 'generating' | 'ready' | 'error';
|
||
|
|
|
||
|
|
export interface WalkthroughEntry {
|
||
|
|
status: WalkthroughEntryStatus;
|
||
|
|
stage: WalkthroughStage | null;
|
||
|
|
result: WalkthroughResult | null;
|
||
|
|
readiness: WalkthroughReadiness | null;
|
||
|
|
error: {
|
||
|
|
message: string;
|
||
|
|
code?: WalkthroughError['code'];
|
||
|
|
// Carried through so a blocker can name the model that was actually tried
|
||
|
|
// rather than the one that happens to be resolved now.
|
||
|
|
model?: WalkthroughModel;
|
||
|
|
requiredChars?: number;
|
||
|
|
availableChars?: number;
|
||
|
|
} | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const EMPTY_ENTRY: WalkthroughEntry = {
|
||
|
|
status: 'idle',
|
||
|
|
stage: null,
|
||
|
|
result: null,
|
||
|
|
readiness: null,
|
||
|
|
error: null,
|
||
|
|
};
|
||
|
|
|
||
|
|
export const walkthroughSourceKey = (source: WalkthroughSource): string => {
|
||
|
|
if (source.kind === 'working-tree') return `working-tree:${source.scope}`;
|
||
|
|
if (source.kind === 'branch') return `branch:${source.baseRef}...${source.headRef}`;
|
||
|
|
return `pr:${source.number}`;
|
||
|
|
};
|
||
|
|
|
||
|
|
const entryKey = (directory: string, source: WalkthroughSource): string =>
|
||
|
|
`${getRuntimeKey()} |