feat: add scene 8 entry state

This commit is contained in:
lda
2026-07-12 05:02:34 +07:00 Verified
parent 70e1241985
commit 640873a8a2
2 changed files with 79 additions and 0 deletions
@@ -0,0 +1,45 @@
import { describe, expect, it } from "vitest";
import {
SCENE8_REQUEST,
canSubmitScene8Entry,
initialScene8EntryState,
scene8EntryReducer,
} from "./scene8-entry-state.js";
describe("scene8EntryReducer", () => {
it("starts with the canonical request as the editable draft", () => {
expect(initialScene8EntryState).toEqual({ phase: "empty", draft: SCENE8_REQUEST });
expect(canSubmitScene8Entry(initialScene8EntryState)).toBe(true);
});
it("updates only the draft while the entry is empty", () => {
expect(scene8EntryReducer(initialScene8EntryState, {
type: "draft_changed",
draft: "A narrower request",
})).toEqual({ phase: "empty", draft: "A narrower request" });
});
it("rejects whitespace-only submissions", () => {
const state = { phase: "empty" as const, draft: " \n\t" };
expect(canSubmitScene8Entry(state)).toBe(false);
expect(scene8EntryReducer(state, { type: "submit" })).toBe(state);
});
it("stores the exact submitted text", () => {
const state = { phase: "empty" as const, draft: " Keep this spacing " };
expect(scene8EntryReducer(state, { type: "submit" })).toEqual({
phase: "submitted",
draft: state.draft,
request: state.draft,
});
});
it("keeps a submitted request stable on edits or repeated submits", () => {
const submitted = scene8EntryReducer(initialScene8EntryState, { type: "submit" });
expect(scene8EntryReducer(submitted, {
type: "draft_changed",
draft: "A different request",
})).toBe(submitted);
expect(scene8EntryReducer(submitted, { type: "submit" })).toBe(submitted);
});
});
@@ -0,0 +1,34 @@
export const SCENE8_REQUEST =
"We need to author a report workflow for the lda_report scenario. What sources and capabilities are available?";
export type Scene8EntryState =
| { readonly phase: "empty"; readonly draft: string }
| { readonly phase: "submitted"; readonly draft: string; readonly request: string };
export type Scene8EntryAction =
| { readonly type: "draft_changed"; readonly draft: string }
| { readonly type: "submit" };
export const initialScene8EntryState: Scene8EntryState = {
phase: "empty",
draft: SCENE8_REQUEST,
};
export const canSubmitScene8Entry = (state: Scene8EntryState): boolean =>
state.phase === "empty" && state.draft.trim().length > 0;
export const scene8EntryReducer = (
state: Scene8EntryState,
action: Scene8EntryAction,
): Scene8EntryState => {
if (state.phase === "submitted") return state;
switch (action.type) {
case "draft_changed":
return { phase: "empty", draft: action.draft };
case "submit":
return canSubmitScene8Entry(state)
? { phase: "submitted", draft: state.draft, request: state.draft }
: state;
}
};