diff --git a/packages/core/src/canvas/canvasTemplates.ts b/packages/core/src/canvas/canvasTemplates.ts index d75cfba72b..f42e240c7e 100644 --- a/packages/core/src/canvas/canvasTemplates.ts +++ b/packages/core/src/canvas/canvasTemplates.ts @@ -1,5 +1,7 @@ -import { FREEFORM_TEMPLATE_ID } from "./freeformSchemas"; -import { FREEFORM_WHITELIST } from "./freeformWhitelist"; +import { + FREEFORM_SYSTEM_PROMPT, + FREEFORM_TEMPLATE_ID, +} from "@posthog/shared/canvas-freeform-prompt"; import type { CanvasSuggestion } from "./templateSchemas"; export interface CanvasTemplate { @@ -13,162 +15,6 @@ export interface CanvasTemplate { systemPrompt: string; } -// Freeform React canvas (Q1/Q12): the agent writes a real single-file React app -// that runs in a sandboxed iframe, instead of emitting json-render patches. This -// system prompt is a plain string (no catalog contract) — the contract here is -// "valid React + only these imports + the `ph` data shim". -const FREEFORM_WHITELIST_NAMES = FREEFORM_WHITELIST.map((e) => e.name).join( - ", ", -); - -// The shared React-tier contract: output format, the import whitelist, and the -// `ph` data shim. Both the generic freeform sandbox and the opinionated React -// templates (dashboard, web-analytics) are built from this base — the templates -// just append their own layout/metric rules via buildFreeformPrompt. -const FREEFORM_BASE = [ - "You are PostHog Canvas, an agent that builds a freeform React app for the user's current PostHog project. The app runs in a sandboxed iframe.", - "", - "OUTPUT FORMAT — every turn:", - "- Write a SHORT sentence of prose, then the COMPLETE app as ONE fenced code block tagged tsx (```tsx ... ```).", - "- FULL-FILE REWRITE: always output the entire file, even for a tiny change. Never output a partial file, a diff, or multiple code blocks.", - "- The file MUST `export default` a single React component that takes no props.", - "", - "IMPORTS — allowed packages ONLY:", - `- You may import ONLY from: ${FREEFORM_WHITELIST_NAMES}.`, - '- Import React hooks from "react" (e.g. `import React, { useState, useEffect } from "react"`). Do NOT import react-dom or call createRoot — the host mounts your default export.', - '- Use `@posthog/quill` for UI components, `recharts` for charts, `lucide-react` for icons (e.g. `import { Calendar, RefreshCw } from "lucide-react"`), and `dayjs` for dates.', - "- FORBIDDEN: any other import, dynamic import(), require(), fetch(), XMLHttpRequest,