CoDEVX / lib /chat-request-context.test.ts
CodexMacTiger
feat: live package-scoped chat and thinking logs
837e3ac
import { describe, expect, it } from "vitest";
import seedWorkPackages from "../agentic_pm_demo_codex_plans/data/work-packages.seed.json";
import type { ParsedCommand, WorkPackage } from "./work-package-types";
const workPackages = seedWorkPackages as WorkPackage[];
const { resolveChatRequestContext, buildResolvedContext } = await import(
"./chat-request-context"
).catch(() => ({
resolveChatRequestContext: undefined,
buildResolvedContext: undefined,
}));
describe("resolveChatRequestContext", () => {
it("converts plain text into an ask command when detail view is open", () => {
expect(resolveChatRequestContext).toBeTypeOf("function");
const parsed: ParsedCommand = {
instruction: "What does the validation of verbal concept output mean?",
};
const selectedWorkPackage = workPackages.find(
(workPackage) => workPackage.shortName === "Final Concept",
);
const result = resolveChatRequestContext?.({
parsed,
detailOpen: true,
selectedWorkPackage,
});
expect(result?.parsedCommand.mode).toBe("ask");
expect(result?.parsedCommand.referencedPackageName).toBe(
selectedWorkPackage?.title,
);
expect(result?.shouldAutomateBoard).toBe(false);
});
it("keeps plain text as product-idea automation when detail view is closed", () => {
expect(resolveChatRequestContext).toBeTypeOf("function");
const parsed: ParsedCommand = {
instruction: "Build an indoor air quality device for schools.",
};
const selectedWorkPackage = workPackages.find(
(workPackage) => workPackage.shortName === "Final Concept",
);
const result = resolveChatRequestContext?.({
parsed,
detailOpen: false,
selectedWorkPackage,
});
expect(result?.parsedCommand.mode).toBeUndefined();
expect(result?.shouldAutomateBoard).toBe(true);
});
it("treats slash commands as explicit commands for the selected package", () => {
expect(resolveChatRequestContext).toBeTypeOf("function");
const parsed: ParsedCommand = {
instruction: "/plan Break this into review tasks.",
};
const selectedWorkPackage = workPackages.find(
(workPackage) => workPackage.shortName === "SRS",
);
const result = resolveChatRequestContext?.({
parsed,
detailOpen: false,
selectedWorkPackage,
});
expect(result?.parsedCommand.mode).toBe("plan");
expect(result?.parsedCommand.referencedPackageName).toBe(
selectedWorkPackage?.title,
);
expect(result?.parsedCommand.instruction).toBe(
"Break this into review tasks.",
);
expect(result?.shouldAutomateBoard).toBe(false);
});
it("builds a package-scoped live ask context for detail-view plain text", () => {
expect(buildResolvedContext).toBeTypeOf("function");
const parsed: ParsedCommand = {
instruction: "What does the validation of verbal concept output mean?",
};
const selectedWorkPackage = workPackages.find(
(workPackage) => workPackage.shortName === "Final Concept",
);
const request = resolveChatRequestContext?.({
parsed,
detailOpen: true,
selectedWorkPackage,
});
const context = buildResolvedContext?.({
parsedCommand: request?.parsedCommand,
shouldAutomateBoard: request?.shouldAutomateBoard,
selectedWorkPackage,
provider: "live",
});
expect(context).toMatchObject({
scope: "package",
workPackageId: selectedWorkPackage?.id,
mode: "ask",
provider: "live",
boardMutationPolicy: "none",
});
});
it("builds a global mock board-automation context for overview plain text", () => {
expect(buildResolvedContext).toBeTypeOf("function");
const parsed: ParsedCommand = {
instruction: "Build an indoor air quality device for schools.",
};
const selectedWorkPackage = workPackages.find(
(workPackage) => workPackage.shortName === "SRS",
);
const request = resolveChatRequestContext?.({
parsed,
detailOpen: false,
selectedWorkPackage,
});
const context = buildResolvedContext?.({
parsedCommand: request?.parsedCommand,
shouldAutomateBoard: request?.shouldAutomateBoard,
selectedWorkPackage,
provider: "mock",
});
expect(context).toMatchObject({
scope: "global",
workPackageId: null,
mode: "board_automation",
provider: "mock",
boardMutationPolicy: "replace_all",
});
});
it("marks scoped plan commands as selected-package-only mutations", () => {
expect(buildResolvedContext).toBeTypeOf("function");
const parsed: ParsedCommand = {
instruction: "/plan Break this into review tasks.",
};
const selectedWorkPackage = workPackages.find(
(workPackage) => workPackage.shortName === "SRS",
);
const request = resolveChatRequestContext?.({
parsed,
detailOpen: false,
selectedWorkPackage,
});
const context = buildResolvedContext?.({
parsedCommand: request?.parsedCommand,
shouldAutomateBoard: request?.shouldAutomateBoard,
selectedWorkPackage,
provider: "live",
});
expect(context).toMatchObject({
scope: "package",
workPackageId: selectedWorkPackage?.id,
mode: "plan",
provider: "live",
boardMutationPolicy: "selected_package_only",
});
});
});