feat: reframe presentation opening as agent roles
This commit is contained in:
@@ -53,7 +53,7 @@ const renderSceneBodyAtMainLocation = (sceneId: MainLocation["sceneId"], beatId:
|
||||
);
|
||||
|
||||
describe("SceneBody", () => {
|
||||
it("renders Scene 1 as an opening decomposition visual", () => {
|
||||
it("renders Scene 1 as an agent-shaped contribution visual", () => {
|
||||
const location: PresentationLocation = { kind: "main", sceneId: "thesis", beatId: "substrate", focusPath: [] };
|
||||
|
||||
render(
|
||||
@@ -71,10 +71,10 @@ describe("SceneBody", () => {
|
||||
|
||||
expect(screen.getByRole("region", { name: "thesis opening" })).toHaveAttribute(
|
||||
"data-opening-focus",
|
||||
"substrate",
|
||||
"contribution",
|
||||
);
|
||||
expect(screen.getByText("submitted substrate")).toBeInTheDocument();
|
||||
expect(screen.getByText("Typed · Durable · Inspectable")).toBeInTheDocument();
|
||||
expect(screen.getByText("Runner / platform")).toBeInTheDocument();
|
||||
expect(screen.getByText("Implemented contribution")).toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: /where is the ai agent/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -34,4 +34,15 @@ describe("ConceptPrimitives", () => {
|
||||
expect(screen.getByText("Design")).toBeInTheDocument();
|
||||
expect(screen.getByText("Run")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("keeps an optional scene-specific class on a concept rail", () => {
|
||||
render(
|
||||
<ConceptRail label="Agent roles" className="opening-thesis__agent-system">
|
||||
<ConceptNode title="Planner" icon="planner" />
|
||||
</ConceptRail>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole("group", { name: "Agent roles" }))
|
||||
.toHaveClass("opening-thesis__agent-system");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,10 +68,11 @@ export const ConceptNode = ({
|
||||
type ConceptRailProps = {
|
||||
readonly label: string;
|
||||
readonly children: ReactNode;
|
||||
readonly className?: string | undefined;
|
||||
};
|
||||
|
||||
export const ConceptRail = ({ label, children }: ConceptRailProps) => (
|
||||
<div className="concept-rail" role="group" aria-label={label}>
|
||||
export const ConceptRail = ({ label, children, className }: ConceptRailProps) => (
|
||||
<div className={["concept-rail", className].filter(Boolean).join(" ")} role="group" aria-label={label}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -8,31 +8,38 @@ const thesisScene = findScene("thesis")!;
|
||||
afterEach(() => cleanup());
|
||||
|
||||
describe("OpeningThesisScene", () => {
|
||||
it("makes the title boundary the opening focal artifact", () => {
|
||||
it("introduces the agent-shaped product goal", () => {
|
||||
render(<OpeningThesisScene scene={thesisScene} beat={findBeat("thesis", "title")!} />);
|
||||
|
||||
const opening = screen.getByRole("region", { name: /thesis opening/i });
|
||||
expect(opening).toHaveAttribute("data-opening-focus", "title");
|
||||
expect(opening).toHaveAttribute("data-support-state", "receded");
|
||||
expect(screen.getByRole("heading", { name: /Design and Implementation of lda\.chat/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole("heading", { name: "An AI Agent for Workspace Workflows" })).toBeInTheDocument();
|
||||
const roles = screen.getByRole("group", { name: "AI agent roles" });
|
||||
expect(roles).toHaveClass("opening-thesis__agent-system");
|
||||
expect(roles.querySelectorAll("[data-concept-emphasis]")).toHaveLength(3);
|
||||
expect(screen.getByText("Planner")).toBeInTheDocument();
|
||||
expect(screen.getByText("Tool Surface")).toBeInTheDocument();
|
||||
expect(screen.getByText("Workflow Platform")).toBeInTheDocument();
|
||||
expect(screen.getByText("Tool surface")).toBeInTheDocument();
|
||||
expect(screen.getByText("Runner / platform")).toBeInTheDocument();
|
||||
expect(screen.queryByRole("heading", { name: "Thesis" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Decomposed")).not.toBeInTheDocument();
|
||||
expect(screen.getByRole("img", { name: /Planner icon/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole("img", { name: /Tool Surface icon/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole("img", { name: /Workflow Platform icon/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole("img", { name: /Tool surface icon/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole("img", { name: /Runner \/ platform icon/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders contribution focus without relying on lda.chat as category label", () => {
|
||||
it("identifies runner and platform as the implemented contribution", () => {
|
||||
render(<OpeningThesisScene scene={thesisScene} beat={findBeat("thesis", "substrate")!} />);
|
||||
|
||||
const opening = screen.getByRole("region", { name: /thesis opening/i });
|
||||
expect(opening).toHaveAttribute("data-opening-focus", "substrate");
|
||||
expect(opening).toHaveAttribute("data-support-state", "revealed");
|
||||
expect(screen.getByText("Codex / Claude / OpenCode")).toBeInTheDocument();
|
||||
expect(screen.getByText("CLI / MCP / APIs")).toBeInTheDocument();
|
||||
expect(screen.getByText("submitted substrate")).toBeInTheDocument();
|
||||
expect(screen.getByText("Typed · Durable · Inspectable")).toBeInTheDocument();
|
||||
expect(opening).toHaveAttribute("data-opening-focus", "contribution");
|
||||
expect(screen.getByText("Codex, Claude, OpenCode")).toBeInTheDocument();
|
||||
expect(screen.getByText("CLI, MCP, JSON-RPC")).toBeInTheDocument();
|
||||
expect(screen.getByText("Implemented contribution")).toBeInTheDocument();
|
||||
expect(screen.getByText("Lifecycle, validation, records, traces, and interrupt/resume")).toBeInTheDocument();
|
||||
expect(screen.getByText("Planner")).toBeInTheDocument();
|
||||
expect(screen.getByText("Tool surface")).toBeInTheDocument();
|
||||
expect(screen.getByText("Runner / platform")).toBeInTheDocument();
|
||||
expect(screen.queryByText("wf")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,41 +13,46 @@ export const OpeningThesisScene = ({ scene, beat }: OpeningThesisSceneProps) =>
|
||||
const contributionBeat = beat.id === "substrate";
|
||||
return (
|
||||
<>
|
||||
<StageCaption eyebrow="Origin story" title={title}>
|
||||
<p>{beat.caption}</p>
|
||||
</StageCaption>
|
||||
<section
|
||||
className="opening-thesis"
|
||||
className="opening-thesis-scene"
|
||||
aria-label="thesis opening"
|
||||
data-opening-beat={beat.id}
|
||||
data-opening-focus={contributionBeat ? "substrate" : "title"}
|
||||
data-support-state={contributionBeat ? "revealed" : "receded"}
|
||||
data-opening-focus={contributionBeat ? "contribution" : "title"}
|
||||
>
|
||||
<div className="opening-thesis__title-card" data-opening-role="title">
|
||||
<span>AI agent for workspace workflows</span>
|
||||
<strong>{contributionBeat ? "Decomposed" : scene.title}</strong>
|
||||
</div>
|
||||
<div className="opening-thesis__decomposition">
|
||||
<ConceptRail label="AI agent components">
|
||||
<StageCaption eyebrow="Title" title={title}>
|
||||
<p>{beat.caption}</p>
|
||||
</StageCaption>
|
||||
<div
|
||||
className="opening-thesis"
|
||||
data-opening-beat={beat.id}
|
||||
data-opening-focus={contributionBeat ? "contribution" : "title"}
|
||||
>
|
||||
<header className="opening-thesis__statement">
|
||||
<p>Product goal</p>
|
||||
<h2>An AI Agent for Workspace Workflows</h2>
|
||||
</header>
|
||||
<ConceptRail label="AI agent roles" className="opening-thesis__agent-system">
|
||||
<ConceptNode
|
||||
title="Planner"
|
||||
subtitle="Codex / Claude / OpenCode"
|
||||
subtitle="Codex, Claude, OpenCode"
|
||||
icon="planner"
|
||||
emphasis={contributionBeat ? "muted" : "normal"}
|
||||
/>
|
||||
<ConceptNode
|
||||
title="Tool Surface"
|
||||
subtitle="CLI / MCP / APIs"
|
||||
title="Tool surface"
|
||||
subtitle="CLI, MCP, JSON-RPC"
|
||||
icon="tool"
|
||||
emphasis={contributionBeat ? "muted" : "normal"}
|
||||
/>
|
||||
<ConceptNode
|
||||
title="Workflow Platform"
|
||||
subtitle="submitted substrate"
|
||||
title="Runner / platform"
|
||||
subtitle="Workflow lifecycle and deterministic execution"
|
||||
icon="platform"
|
||||
emphasis="primary"
|
||||
emphasis={contributionBeat ? "primary" : "normal"}
|
||||
>
|
||||
<span>Typed · Durable · Inspectable</span>
|
||||
{contributionBeat ? (
|
||||
<>
|
||||
<span>Implemented contribution</span>
|
||||
<span>Lifecycle, validation, records, traces, and interrupt/resume</span>
|
||||
</>
|
||||
) : null}
|
||||
</ConceptNode>
|
||||
</ConceptRail>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user