Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
export type CaptureSelectionTransitionPhase =
|
|
| "before_present"
|
|
| "during_present"
|
|
| "after_present"
|
|
| "after_metadata";
|
|
|
|
export class CaptureSelectionSupersededError extends Error {
|
|
readonly captureId: string;
|
|
readonly phase: CaptureSelectionTransitionPhase;
|
|
|
|
constructor(captureId: string, phase: CaptureSelectionTransitionPhase) {
|
|
super(`Screenshot capture ${captureId} was superseded during ${phase}`);
|
|
this.name = "CaptureSelectionSupersededError";
|
|
this.captureId = captureId;
|
|
this.phase = phase;
|
|
}
|
|
}
|
|
|
|
export async function runCaptureSelectionTransition<T>({
|
|
captureId,
|
|
isCurrent,
|
|
metadata,
|
|
present
|
|
}: {
|
|
captureId: string;
|
|
isCurrent(): boolean;
|
|
metadata: Promise<T>;
|
|
present(assertCurrent: () => void): Promise<void>;
|
|
}): Promise<T> {
|
|
const assertCurrent = (phase: CaptureSelectionTransitionPhase) => {
|
|
if (!isCurrent()) {
|
|
throw new CaptureSelectionSupersededError(captureId, phase);
|
|
}
|
|
};
|
|
|
|
assertCurrent("before_present");
|
|
await present(() => assertCurrent("during_present"));
|
|
assertCurrent("after_present");
|
|
const resolvedMetadata = await metadata;
|
|
assertCurrent("after_metadata");
|
|
return resolvedMetadata;
|
|
}
|