feat: implement Stories 3.4, 3.5, 3.6 — AI proposals, wizard, hover & palette
Some checks failed
CI / Tests / 🧪 Test (push) Has been cancelled
Some checks failed
CI / Tests / 🧪 Test (push) Has been cancelled
Story 3.4: AI semantic suggestions with accept/reject workflow - ProposalBar overlay with visual diff - Accept/reject flow with graph snapshot restore - useProposalDiff hook for change summary - System prompt scoping for selected elements Story 3.5: New diagram wizard with AI type inference - CreateDiagramDialog with AI type inference (Haiku) - initialDescription prop for chat-first flow - Auto-send on mount with hasSentInitial ref guard - DB migration for diagram description column Story 3.6: Hover affordances and command palette - HoverAffordances toolbar (5 AI actions, debounced) - CommandPalette (Cmd+K) with AI, nav, Go to Node - prefillChat/fitViewRequested/focusNodeId actions - Code review: getNodesBounds, onOpenRightPanel, timer cleanup, test count fix 374 tests passing (251 web + 123 AI). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import * as z from "zod";
|
||||
|
||||
import { getCopilotHistory, streamCopilot } from "@turbostarter/ai/copilot/api";
|
||||
import { copilotMessageSchema } from "@turbostarter/ai/copilot/schema";
|
||||
import { inferDiagramType } from "@turbostarter/ai/copilot/type-inference";
|
||||
|
||||
import { enforceAuth, deductCredits, rateLimiter, validate } from "../../../middleware";
|
||||
|
||||
@@ -12,6 +13,10 @@ const chatIdQuerySchema = z.object({
|
||||
chatId: z.string(),
|
||||
});
|
||||
|
||||
const inferTypeSchema = z.object({
|
||||
description: z.string().min(3).max(500),
|
||||
});
|
||||
|
||||
export const copilotRouter = new Hono<{
|
||||
Variables: {
|
||||
user: User;
|
||||
@@ -27,6 +32,17 @@ export const copilotRouter = new Hono<{
|
||||
return c.json(messages);
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/infer-type",
|
||||
enforceAuth,
|
||||
rateLimiter,
|
||||
validate("json", inferTypeSchema),
|
||||
async (c) => {
|
||||
const { description } = c.req.valid("json");
|
||||
const result = await inferDiagramType(description);
|
||||
return c.json(result);
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/",
|
||||
enforceAuth,
|
||||
|
||||
@@ -24,12 +24,14 @@ export const createDiagramSchema = z.object({
|
||||
"sequence",
|
||||
"flowchart",
|
||||
]),
|
||||
description: z.string().max(500).optional(),
|
||||
projectId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const updateDiagramBodySchema = z
|
||||
.object({
|
||||
title: z.string().min(1).max(255).optional(),
|
||||
description: z.string().max(500).optional(),
|
||||
projectId: z.string().nullable().optional(),
|
||||
sortOrder: z.number().int().min(0).optional(),
|
||||
graphData: z
|
||||
@@ -45,6 +47,7 @@ export const updateDiagramBodySchema = z
|
||||
.refine(
|
||||
(data) =>
|
||||
data.title !== undefined ||
|
||||
data.description !== undefined ||
|
||||
data.projectId !== undefined ||
|
||||
data.sortOrder !== undefined ||
|
||||
data.graphData !== undefined,
|
||||
|
||||
Reference in New Issue
Block a user