{
+ if (e.target === e.currentTarget) onClose();
+ }}
+ >
+
+ The plan
+ live — statuses derive from your check outcomes
+
+
+
+ {tree ? (
+ <>
+
+
+
Drag to pan · scroll to zoom
+
+
+
+
+
+
+ >
+ ) : (
+
+ No plan in this session yet.
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/core/ui-message.ts b/src/core/ui-message.ts
index 1de809e..80d7ce0 100644
--- a/src/core/ui-message.ts
+++ b/src/core/ui-message.ts
@@ -1,5 +1,5 @@
import type { UIMessage } from "ai";
-import type { DemoToolInput, ResearchToolInput, SubagentArtifactData, VisualToolInput } from "./contracts.ts";
+import type { DemoToolInput, PlanBlockData, ResearchToolInput, SubagentArtifactData, VisualToolInput } from "./contracts.ts";
import type { AskToolInput, QuestionAnswerData, QuizToolInput } from "./question-core.ts";
/**
@@ -24,6 +24,8 @@ export type TeacherUITools = {
export type TeacherUIDataParts = {
"subagent-artifact": SubagentArtifactData;
+ /** Plan blocks (wave 4): frozen plan snapshots rendered in the chat flow. */
+ "plan-block": PlanBlockData;
};
export type TeacherUIMessage = UIMessage