@agent-native/core 0.59.1 → 0.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/a2a/index.d.ts +2 -0
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -0
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/invoke.d.ts +63 -0
- package/dist/a2a/invoke.d.ts.map +1 -0
- package/dist/a2a/invoke.js +157 -0
- package/dist/a2a/invoke.js.map +1 -0
- package/dist/agent/run-store.d.ts +15 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +28 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/chat-threads/store.d.ts +21 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +128 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/agent.d.ts +23 -0
- package/dist/cli/agent.d.ts.map +1 -0
- package/dist/cli/agent.js +300 -0
- package/dist/cli/agent.js.map +1 -0
- package/dist/cli/agents.d.ts +14 -0
- package/dist/cli/agents.d.ts.map +1 -0
- package/dist/cli/agents.js +95 -0
- package/dist/cli/agents.js.map +1 -0
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +264 -2
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/create.d.ts +3 -2
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +154 -83
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +50 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/invoke.d.ts +26 -0
- package/dist/cli/invoke.d.ts.map +1 -0
- package/dist/cli/invoke.js +227 -0
- package/dist/cli/invoke.js.map +1 -0
- package/dist/cli/templates-meta.d.ts +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +9 -8
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspacify.d.ts +1 -1
- package/dist/cli/workspacify.d.ts.map +1 -1
- package/dist/cli/workspacify.js +6 -6
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +5 -4
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/blocks/library/diagram.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.js +23 -17
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/types.d.ts +2 -0
- package/dist/client/blocks/types.d.ts.map +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts +13 -0
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +41 -0
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +2 -2
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +102 -0
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/provider-api/actions/github-repo-files.d.ts +84 -0
- package/dist/provider-api/actions/github-repo-files.d.ts.map +1 -0
- package/dist/provider-api/actions/github-repo-files.js +213 -0
- package/dist/provider-api/actions/github-repo-files.js.map +1 -0
- package/dist/provider-api/github-repo.d.ts +11 -0
- package/dist/provider-api/github-repo.d.ts.map +1 -0
- package/dist/provider-api/github-repo.js +553 -0
- package/dist/provider-api/github-repo.js.map +1 -0
- package/dist/provider-api/index.d.ts +184 -11
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +519 -0
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/docs/search.d.ts.map +1 -1
- package/dist/scripts/docs/search.js +38 -13
- package/dist/scripts/docs/search.js.map +1 -1
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +11 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +32 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +297 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth-marketing.d.ts.map +1 -1
- package/dist/server/auth-marketing.js +17 -7
- package/dist/server/auth-marketing.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +6 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +18 -98
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/styles/blocks.css +30 -8
- package/dist/styles/rich-markdown-editor.css +10 -4
- package/dist/templates/{starter-shell-sync.spec.ts → chat-shell-sync.spec.ts} +21 -21
- package/dist/templates/default/.agents/skills/actions/SKILL.md +5 -5
- package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/dist/templates/default/AGENTS.md +22 -1
- package/dist/templates/default/actions/hello.ts +1 -1
- package/dist/templates/default/actions/navigate.ts +1 -1
- package/dist/templates/default/actions/view-screen.ts +1 -1
- package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/dist/templates/headless/.env.example +4 -0
- package/dist/templates/headless/.prettierrc +5 -0
- package/dist/templates/headless/AGENTS.md +58 -0
- package/dist/templates/headless/DEVELOPING.md +22 -0
- package/dist/templates/headless/_gitignore +36 -0
- package/dist/templates/headless/actions/hello.ts +14 -0
- package/dist/templates/headless/actions/run.ts +3 -0
- package/dist/templates/headless/package.json +22 -0
- package/dist/templates/headless/tsconfig.json +7 -0
- package/dist/templates/ui-primitives-sync.spec.ts +2 -2
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -5
- package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +93 -0
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +1 -1
- package/dist/templates/workspace-core/AGENTS.md +20 -3
- package/dist/templates/workspace-core/src/server/index.ts +1 -1
- package/dist/templates/workspace-root/AGENTS.md +25 -5
- package/dist/templates/workspace-root/README.md +7 -7
- package/dist/triggers/dispatcher.d.ts +2 -3
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +2 -3
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/triggers/routes.d.ts +38 -0
- package/dist/triggers/routes.d.ts.map +1 -0
- package/dist/triggers/routes.js +202 -0
- package/dist/triggers/routes.js.map +1 -0
- package/docs/AGENTS.md +57 -0
- package/docs/SKILL.md +40 -0
- package/docs/content/a2a-protocol.md +1 -1
- package/docs/content/actions.md +48 -8
- package/docs/content/agent-surfaces.md +76 -14
- package/docs/content/cli-adapters.md +1 -1
- package/docs/content/cloneable-saas.md +5 -4
- package/docs/content/code-agents-ui.md +1 -1
- package/docs/content/components.md +1 -1
- package/docs/content/context-awareness.md +1 -1
- package/docs/content/creating-templates.md +9 -7
- package/docs/content/drop-in-agent.md +1 -1
- package/docs/content/faq.md +6 -4
- package/docs/content/getting-started.md +63 -73
- package/docs/content/key-concepts.md +24 -24
- package/docs/content/native-chat-ui.md +4 -4
- package/docs/content/pure-agent-apps.md +34 -10
- package/docs/content/security.md +1 -1
- package/docs/content/server.md +1 -1
- package/docs/content/template-chat.md +85 -0
- package/docs/content/template-dispatch.md +1 -1
- package/docs/content/tracking.md +1 -1
- package/docs/content/what-is-agent-native.md +7 -6
- package/package.json +10 -1
- package/src/templates/{starter-shell-sync.spec.ts → chat-shell-sync.spec.ts} +21 -21
- package/src/templates/default/.agents/skills/actions/SKILL.md +5 -5
- package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/src/templates/default/AGENTS.md +22 -1
- package/src/templates/default/actions/hello.ts +1 -1
- package/src/templates/default/actions/navigate.ts +1 -1
- package/src/templates/default/actions/view-screen.ts +1 -1
- package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/src/templates/headless/.env.example +4 -0
- package/src/templates/headless/.prettierrc +5 -0
- package/src/templates/headless/AGENTS.md +58 -0
- package/src/templates/headless/DEVELOPING.md +22 -0
- package/src/templates/headless/_gitignore +36 -0
- package/src/templates/headless/actions/hello.ts +14 -0
- package/src/templates/headless/actions/run.ts +3 -0
- package/src/templates/headless/package.json +22 -0
- package/src/templates/headless/tsconfig.json +7 -0
- package/src/templates/ui-primitives-sync.spec.ts +2 -2
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -5
- package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +63 -0
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +93 -0
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +1 -1
- package/src/templates/workspace-core/AGENTS.md +20 -3
- package/src/templates/workspace-core/src/server/index.ts +1 -1
- package/src/templates/workspace-root/AGENTS.md +25 -5
- package/src/templates/workspace-root/README.md +7 -7
- package/docs/content/template-starter.md +0 -78
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewWorkspaceAppFlow.js","sourceRoot":"","sources":["../../src/client/NewWorkspaceAppFlow.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport {\n IconArrowUpRight,\n IconBook,\n IconCheck,\n IconChevronDown,\n IconFileText,\n IconKey,\n} from \"@tabler/icons-react\";\nimport { agentNativePath, appBasePath } from \"./api-path.js\";\nimport { sendToAgentChat } from \"./agent-chat.js\";\nimport { isInBuilderFrame } from \"./builder-frame.js\";\nimport { useDevMode } from \"./use-dev-mode.js\";\nimport { getWorkspaceAppIdValidationError } from \"../shared/workspace-app-id.js\";\nimport { PromptComposer } from \"./composer/PromptComposer.js\";\n\nexport interface VaultSecretOption {\n id: string;\n name: string;\n credentialKey: string;\n provider?: string | null;\n description?: string | null;\n}\n\nexport interface WorkspaceResourceOption {\n id: string;\n kind: \"skill\" | \"instruction\" | \"agent\" | \"knowledge\";\n name: string;\n description?: string | null;\n path: string;\n scope: \"all\" | \"selected\";\n updatedAt?: number;\n}\n\ntype VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport interface NewWorkspaceAppFlowProps {\n sourceApp?: string;\n className?: string;\n dispatchBasePath?: string | null;\n}\n\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/^[^a-z]+/, \"\")\n .slice(0, 48);\n}\n\nfunction titleFromPrompt(prompt: string): string {\n const cleaned = prompt\n .replace(/\\b(build|create|make|an?|the|app|tool|dashboard)\\b/gi, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return slugify(cleaned || \"new-app\") || \"new-app\";\n}\n\nfunction actionUrl(basePath: string | null, action: string): string {\n const path = `/_agent-native/actions/${action}`;\n if (basePath === null) return agentNativePath(path);\n const normalized = basePath.replace(/\\/+$/, \"\");\n return `${normalized}${path}`;\n}\n\nfunction defaultDispatchBasePath(sourceApp?: string): string | null {\n if (sourceApp === \"dispatch\") return null;\n const base = appBasePath();\n if (base === \"/dispatch\") return null;\n return \"/dispatch\";\n}\n\nasync function fetchJson(url: string, init?: RequestInit): Promise<any> {\n const res = await fetch(url, init);\n const data = await res.json().catch(() => null);\n if (!res.ok) {\n throw new Error(\n data?.error || data?.message || `Request failed ${res.status}`,\n );\n }\n return data;\n}\n\nfunction buildNewWorkspaceAppPrompt(input: {\n appId: string;\n prompt: string;\n selectedKeys: string[];\n selectedResources: WorkspaceResourceOption[];\n vaultAccessMode: VaultAccessMode;\n}): string {\n const keyList = input.selectedKeys.join(\", \");\n const grantRequest =\n input.vaultAccessMode === \"all-apps\"\n ? `Dispatch vault access: all saved vault keys are available to every workspace app by default. No per-app vault grants are needed.`\n : keyList\n ? `Requested Dispatch vault key grants for this app: ${keyList}`\n : `Requested Dispatch vault key grants for this app: none`;\n const resourceList = input.selectedResources.length\n ? input.selectedResources\n .map(\n (resource) =>\n `- ${resource.name} (${resource.kind}, ${resource.path})`,\n )\n .join(\"\\n\")\n : \"none\";\n\n return [\n `Create a new agent-native app in this workspace.`,\n `This is a new workspace app request, not a feature request for the current app.`,\n ``,\n `Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,\n `User prompt: ${input.prompt.trim()}`,\n `Generate a concise one-sentence app description from the user prompt before coding; save it in apps/${input.appId}/package.json \"description\" so Dispatch and A2A can describe the app.`,\n `If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.`,\n grantRequest,\n `Requested Dispatch workspace resources for this app:\\n${resourceList}`,\n `Dispatch workspace resources with scope=all are inherited workspace context. Do not copy or sync them into the new app; every workspace app reads them at runtime and may override with app shared or personal resources.`,\n ``,\n `Pick a starter template that fits the user's prompt — analytics, assets, brain, calendar, content, design, dispatch, forms, mail, slides, clips, or starter when none of the others fit.`,\n `If you use the starter template, treat it as scaffolding only: the finished app must use the requested app's real name, home screen, navigation, package metadata, and manifest, and it must not leave visible \"Starter\", \"Blank app\", or \"New app\" UI behind.`,\n `Use the workspace app layout: create it under apps/${input.appId}, mount it at /${input.appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,\n `Important routing rule: from outside the app, link to /${input.appId}; inside apps/${input.appId}, React Router routes are app-local. Use <Link to=\"/review\"> and navigate(\"/review\"), not \"/${input.appId}/review\"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${input.appId}/${input.appId}/review.`,\n `Action-backed UI is mandatory for normal CRUD. Define reads/writes in actions/ with defineAction, expose read actions with http: { method: \"GET\" }, and call them from React with useActionQuery/useActionMutation or a named helper that uses callAction. Do not create duplicate JSON CRUD routes under /api/* for data the agent can mutate; those bypass the action cache contract and make agent-created records invisible until reload. If a rare raw non-action fetch is unavoidable, include useChangeVersions([\"action\", <domain-source>]) in the query key and wrap framework URLs with named client helpers so mounted apps call the right URL.`,\n `If the user's prompt mentions sibling apps like Mail, Calendar, Assets, Brain, Dispatch, or other templates, treat them as existing workspace neighbors or integrations. Do not scaffold those sibling apps inside apps/${input.appId} unless the user explicitly asks to create them too.`,\n `Do not satisfy this by adding a route, page, component, or file inside apps/starter or another existing app unless the user explicitly asks to modify that existing app.`,\n `Use relative workspace links like /${input.appId}. Do not hardcode localhost, 127.0.0.1, 8080, 8100, or any dev port; the active workspace gateway/browser origin owns the port.`,\n `Use the framework/template UI stack: shadcn/ui components and @tabler/icons-react. Do not add lucide-react or another icon library for standard UI.`,\n `Ensure the React Router client entry preserves APP_BASE_PATH/VITE_APP_BASE_PATH via appBasePath().`,\n input.vaultAccessMode === \"all-apps\"\n ? `Do not create per-app Dispatch vault grants unless the workspace switches vault access to manual or the user explicitly asks for manual grants.`\n : keyList\n ? `After the app exists, grant the selected Dispatch vault keys to appId \"${input.appId}\" and sync them once the app server is available. Treat these as requested grants, not active grants before creation succeeds.`\n : `Do not grant any Dispatch vault keys unless the user asks later.`,\n input.selectedResources.length\n ? `After the app exists, grant the selected Dispatch workspace resources to appId \"${input.appId}\". Do not sync all-app workspace resources; they are inherited.`\n : `Do not grant any selected-only Dispatch workspace resources unless the user asks later.`,\n ``,\n `App readiness requirements before handing off:`,\n `- Ensure apps/${input.appId}/package.json exists with displayName/name and a concise description so Dispatch and the workspace gateway discover it from the filesystem. There is no separate workspace app registry to edit.`,\n `- Update the app manifest/package/deploy metadata needed by the existing workspace deployment model; do not leave the app relying only on local discovery.`,\n `- Verify the app's agent card/A2A metadata is ready so Dispatch can discover and delegate to the app after deployment. Every sibling workspace app is available over A2A by default through call-agent, with names and descriptions from the workspace app registry.`,\n `- Include a final verification note covering filesystem discovery, manifest/deploy metadata, relative same-origin routing, and agent-card readiness.`,\n `When it is ready, start or update the workspace dev server and navigate the user to /${input.appId}.`,\n ].join(\"\\n\");\n}\n\nexport function NewWorkspaceAppFlow({\n sourceApp = \"starter\",\n className = \"\",\n dispatchBasePath,\n}: NewWorkspaceAppFlowProps) {\n const [selectedSecretIds, setSelectedSecretIds] = useState<string[]>([]);\n const [selectedResourceIds, setSelectedResourceIds] = useState<string[]>([]);\n const [secrets, setSecrets] = useState<VaultSecretOption[]>([]);\n const [resources, setResources] = useState<WorkspaceResourceOption[]>([]);\n const [vaultAccessMode, setVaultAccessMode] =\n useState<VaultAccessMode>(\"all-apps\");\n const [secretsError, setSecretsError] = useState<string | null>(null);\n const [resourcesError, setResourcesError] = useState<string | null>(null);\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [branchUrl, setBranchUrl] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const { isDevMode } = useDevMode();\n\n const effectiveDispatchBasePath =\n dispatchBasePath === undefined\n ? defaultDispatchBasePath(sourceApp)\n : dispatchBasePath;\n\n useEffect(() => {\n let cancelled = false;\n const secretsUrl = actionUrl(\n effectiveDispatchBasePath,\n \"list-vault-secret-options\",\n );\n const vaultAccessUrl = actionUrl(\n effectiveDispatchBasePath,\n \"get-vault-access-settings\",\n );\n const resourcesUrl = actionUrl(\n effectiveDispatchBasePath,\n \"list-workspace-resource-options\",\n );\n\n fetchJson(secretsUrl)\n .then((data) => {\n if (cancelled) return;\n setSecrets(Array.isArray(data) ? data : []);\n setSecretsError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setSecrets([]);\n setSecretsError(err?.message || \"Could not load Dispatch keys\");\n });\n\n fetchJson(vaultAccessUrl)\n .then((data) => {\n if (cancelled) return;\n setVaultAccessMode(data?.mode === \"manual\" ? \"manual\" : \"all-apps\");\n })\n .catch(() => {\n if (cancelled) return;\n setVaultAccessMode(\"manual\");\n });\n\n fetchJson(resourcesUrl)\n .then((data) => {\n if (cancelled) return;\n setResources(Array.isArray(data) ? data : []);\n setResourcesError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setResources([]);\n setResourcesError(err?.message || \"Could not load Dispatch resources\");\n });\n\n return () => {\n cancelled = true;\n };\n }, [effectiveDispatchBasePath]);\n\n const selectedSecrets = useMemo(\n () => secrets.filter((secret) => selectedSecretIds.includes(secret.id)),\n [secrets, selectedSecretIds],\n );\n const selectedResources = useMemo(\n () =>\n resources.filter((resource) => selectedResourceIds.includes(resource.id)),\n [resources, selectedResourceIds],\n );\n const selectedSecretLabel =\n vaultAccessMode === \"all-apps\"\n ? \"All keys included\"\n : selectedSecretIds.length === 0\n ? \"No keys selected\"\n : `${selectedSecretIds.length} key${selectedSecretIds.length === 1 ? \"\" : \"s\"} selected`;\n const selectedResourceLabel =\n selectedResourceIds.length === 0\n ? \"No resources selected\"\n : `${selectedResourceIds.length} resource${selectedResourceIds.length === 1 ? \"\" : \"s\"} selected`;\n\n async function submit(rawPrompt: string) {\n const prompt = rawPrompt.trim();\n if (!prompt || isSubmitting) return;\n const appId = titleFromPrompt(prompt);\n const validationError = getWorkspaceAppIdValidationError(appId);\n if (validationError) {\n setStatusMessage(validationError);\n return;\n }\n\n const message = buildNewWorkspaceAppPrompt({\n appId,\n prompt,\n selectedKeys:\n vaultAccessMode === \"manual\"\n ? selectedSecrets.map((s) => s.credentialKey)\n : [],\n selectedResources,\n vaultAccessMode,\n });\n setIsSubmitting(true);\n setStatusMessage(null);\n setBranchUrl(null);\n\n try {\n if (isInBuilderFrame()) {\n sendToAgentChat({ message, submit: true, type: \"code\" });\n setStatusMessage(\"Sent to Builder chat.\");\n } else if (isDevMode) {\n sendToAgentChat({ message, submit: true, type: \"code\", newTab: true });\n setStatusMessage(\"Sent to the local agent.\");\n } else {\n const result = await fetchJson(\n actionUrl(effectiveDispatchBasePath, \"start-workspace-app-creation\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n prompt,\n appId,\n secretIds: vaultAccessMode === \"manual\" ? selectedSecretIds : [],\n resourceIds: selectedResourceIds,\n }),\n },\n );\n if (result?.mode === \"builder\") {\n setBranchUrl(result?.url || null);\n setStatusMessage(\"Builder branch created.\");\n } else {\n setStatusMessage(\n result?.message ||\n \"Builder app creation is coming soon here. Open this workspace in Builder to create an app from this prompt.\",\n );\n }\n }\n } catch (err: any) {\n setStatusMessage(err?.message || \"Could not start the new app flow.\");\n } finally {\n setIsSubmitting(false);\n }\n }\n\n function toggleSecret(id: string) {\n setSelectedSecretIds((current) =>\n current.includes(id)\n ? current.filter((existing) => existing !== id)\n : [...current, id],\n );\n }\n\n function toggleResource(id: string) {\n setSelectedResourceIds((current) =>\n current.includes(id)\n ? current.filter((existing) => existing !== id)\n : [...current, id],\n );\n }\n\n return (\n <section\n className={`mx-auto flex w-full max-w-5xl flex-col gap-5 px-4 py-6 ${className}`}\n >\n <div className=\"grid gap-5 lg:grid-cols-[minmax(0,1fr)_320px]\">\n <div className=\"flex flex-col gap-3\">\n <PromptComposer\n autoFocus\n disabled={isSubmitting}\n placeholder=\"Describe the app your teammate should be able to use...\"\n draftScope=\"dispatch:new-app\"\n preserveDraftOnSubmit\n onSubmit={(text) => submit(text)}\n />\n\n {statusMessage ? (\n <div className=\"rounded-md border border-border bg-muted/40 px-3 py-2 text-sm text-muted-foreground\">\n {statusMessage}\n {branchUrl ? (\n <a\n href={branchUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"ml-2 inline-flex items-center gap-1 font-medium text-foreground underline\"\n >\n Open branch <IconArrowUpRight className=\"h-3 w-3\" />\n </a>\n ) : null}\n </div>\n ) : null}\n </div>\n\n <aside className=\"overflow-hidden rounded-lg border border-border bg-card\">\n <div className=\"border-b border-border px-4 py-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <IconKey className=\"h-4 w-4\" />\n Dispatch keys\n </div>\n <span className=\"shrink-0 rounded border border-border bg-background/40 px-2 py-0.5 text-[11px] text-muted-foreground\">\n {selectedSecretLabel}\n </span>\n </div>\n </div>\n <div className=\"max-h-[220px] space-y-2 overflow-y-auto p-3\">\n {vaultAccessMode === \"all-apps\" ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n Every saved Dispatch vault key is available to new apps.\n </p>\n ) : secretsError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {secretsError}\n </p>\n ) : secrets.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch vault keys found yet.\n </p>\n ) : (\n secrets.map((secret) => {\n const selected = selectedSecretIds.includes(secret.id);\n return (\n <div\n key={secret.id}\n className={`group rounded-md border text-sm transition ${\n selected\n ? \"border-primary/45 bg-primary/5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.08)]\"\n : \"border-border bg-background/25 text-foreground hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleSecret(secret.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent group-hover:border-muted-foreground/60\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">\n {secret.credentialKey}\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {selected\n ? \"Will be requested for this app\"\n : \"Click to request\"}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75 open:bg-background/10\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Provider: {secret.provider || \"Not specified\"}\n </div>\n <div className=\"truncate\">Name: {secret.name}</div>\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n\n <div className=\"border-y border-border px-4 py-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <IconBook className=\"h-4 w-4\" />\n Resource packs\n </div>\n <span className=\"shrink-0 rounded border border-border bg-background/40 px-2 py-0.5 text-[11px] text-muted-foreground\">\n {selectedResourceLabel}\n </span>\n </div>\n </div>\n <div className=\"max-h-[220px] space-y-2 overflow-y-auto p-3\">\n {resourcesError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {resourcesError}\n </p>\n ) : resources.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch resource packs found yet.\n </p>\n ) : (\n resources.map((resource) => {\n const selected = selectedResourceIds.includes(resource.id);\n return (\n <div\n key={resource.id}\n className={`group rounded-md border text-sm transition ${\n selected\n ? \"border-primary/45 bg-primary/5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.08)]\"\n : \"border-border bg-background/25 text-foreground hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleResource(resource.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent group-hover:border-muted-foreground/60\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <IconFileText className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground/70\" />\n <span className=\"block truncate font-medium\">\n {resource.name}\n </span>\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {resource.kind} · {resource.path}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75 open:bg-background/10\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Scope:{\" \"}\n {resource.scope === \"all\"\n ? \"All apps\"\n : \"Selected apps\"}\n </div>\n {resource.description ? (\n <div className=\"line-clamp-2\">\n {resource.description}\n </div>\n ) : null}\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n </aside>\n </div>\n </section>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"NewWorkspaceAppFlow.js","sourceRoot":"","sources":["../../src/client/NewWorkspaceAppFlow.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useState } from \"react\";\nimport {\n IconArrowUpRight,\n IconBook,\n IconCheck,\n IconChevronDown,\n IconFileText,\n IconKey,\n} from \"@tabler/icons-react\";\nimport { agentNativePath, appBasePath } from \"./api-path.js\";\nimport { sendToAgentChat } from \"./agent-chat.js\";\nimport { isInBuilderFrame } from \"./builder-frame.js\";\nimport { useDevMode } from \"./use-dev-mode.js\";\nimport { getWorkspaceAppIdValidationError } from \"../shared/workspace-app-id.js\";\nimport { PromptComposer } from \"./composer/PromptComposer.js\";\n\nexport interface VaultSecretOption {\n id: string;\n name: string;\n credentialKey: string;\n provider?: string | null;\n description?: string | null;\n}\n\nexport interface WorkspaceResourceOption {\n id: string;\n kind: \"skill\" | \"instruction\" | \"agent\" | \"knowledge\";\n name: string;\n description?: string | null;\n path: string;\n scope: \"all\" | \"selected\";\n updatedAt?: number;\n}\n\ntype VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport interface NewWorkspaceAppFlowProps {\n sourceApp?: string;\n className?: string;\n dispatchBasePath?: string | null;\n}\n\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .replace(/^[^a-z]+/, \"\")\n .slice(0, 48);\n}\n\nfunction titleFromPrompt(prompt: string): string {\n const cleaned = prompt\n .replace(/\\b(build|create|make|an?|the|app|tool|dashboard)\\b/gi, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n return slugify(cleaned || \"new-app\") || \"new-app\";\n}\n\nfunction actionUrl(basePath: string | null, action: string): string {\n const path = `/_agent-native/actions/${action}`;\n if (basePath === null) return agentNativePath(path);\n const normalized = basePath.replace(/\\/+$/, \"\");\n return `${normalized}${path}`;\n}\n\nfunction defaultDispatchBasePath(sourceApp?: string): string | null {\n if (sourceApp === \"dispatch\") return null;\n const base = appBasePath();\n if (base === \"/dispatch\") return null;\n return \"/dispatch\";\n}\n\nasync function fetchJson(url: string, init?: RequestInit): Promise<any> {\n const res = await fetch(url, init);\n const data = await res.json().catch(() => null);\n if (!res.ok) {\n throw new Error(\n data?.error || data?.message || `Request failed ${res.status}`,\n );\n }\n return data;\n}\n\nfunction buildNewWorkspaceAppPrompt(input: {\n appId: string;\n prompt: string;\n selectedKeys: string[];\n selectedResources: WorkspaceResourceOption[];\n vaultAccessMode: VaultAccessMode;\n}): string {\n const keyList = input.selectedKeys.join(\", \");\n const grantRequest =\n input.vaultAccessMode === \"all-apps\"\n ? `Dispatch vault access: all saved vault keys are available to every workspace app by default. No per-app vault grants are needed.`\n : keyList\n ? `Requested Dispatch vault key grants for this app: ${keyList}`\n : `Requested Dispatch vault key grants for this app: none`;\n const resourceList = input.selectedResources.length\n ? input.selectedResources\n .map(\n (resource) =>\n `- ${resource.name} (${resource.kind}, ${resource.path})`,\n )\n .join(\"\\n\")\n : \"none\";\n\n return [\n `Create a new agent-native app in this workspace.`,\n `This is a new workspace app request, not a feature request for the current app.`,\n ``,\n `Suggested app name: ${input.appId} (you may adjust the slug if it conflicts)`,\n `User prompt: ${input.prompt.trim()}`,\n `Generate a concise one-sentence app description from the user prompt before coding; save it in apps/${input.appId}/package.json \"description\" so Dispatch and A2A can describe the app.`,\n `If the user mentions a product or company such as Granola, Loom, Superhuman, Linear, or Notion, treat it as product inspiration unless they explicitly ask to connect to that service. Do not invent or require third-party API keys like GRANOLA_API_KEY just because a product is named.`,\n grantRequest,\n `Requested Dispatch workspace resources for this app:\\n${resourceList}`,\n `Dispatch workspace resources with scope=all are inherited workspace context. Do not copy or sync them into the new app; every workspace app reads them at runtime and may override with app shared or personal resources.`,\n ``,\n `Pick a UI template that fits the user's prompt — analytics, assets, brain, calendar, chat, content, design, dispatch, forms, mail, slides, or clips when the request needs custom UI but none of the domain templates fit.`,\n `Use the chat template as the minimal add-UI scaffold. Do not treat Chat as the required default for primitive/headless action-only workflows unless the user explicitly asks for a UI app.`,\n `If you use the chat template, treat it as scaffolding only: the finished app must use the requested app's real name, home screen, navigation, package metadata, and manifest, and it must not leave visible \"Chat\", \"Starter\", \"Blank app\", or \"New app\" UI behind.`,\n `Use the workspace app layout: create it under apps/${input.appId}, mount it at /${input.appId}, keep it on the shared workspace database/hosting model, and avoid table-name collisions by namespacing any new domain tables to the app.`,\n `Important routing rule: from outside the app, link to /${input.appId}; inside apps/${input.appId}, React Router routes are app-local. Use <Link to=\"/review\"> and navigate(\"/review\"), not \"/${input.appId}/review\"; APP_BASE_PATH supplies the mounted prefix, and hardcoding it causes doubled URLs like /${input.appId}/${input.appId}/review.`,\n `Action-backed UI is mandatory for normal CRUD. Define reads/writes in actions/ with defineAction, expose read actions with http: { method: \"GET\" }, and call them from React with useActionQuery/useActionMutation or a named helper that uses callAction. Do not create duplicate JSON CRUD routes under /api/* for data the agent can mutate; those bypass the action cache contract and make agent-created records invisible until reload. If a rare raw non-action fetch is unavoidable, include useChangeVersions([\"action\", <domain-source>]) in the query key and wrap framework URLs with named client helpers so mounted apps call the right URL.`,\n `If the user's prompt mentions sibling apps like Mail, Calendar, Assets, Brain, Dispatch, or other templates, treat them as existing workspace neighbors or integrations. Do not scaffold those sibling apps inside apps/${input.appId} unless the user explicitly asks to create them too.`,\n `Do not satisfy this by adding a route, page, component, or file inside apps/chat or another existing app unless the user explicitly asks to modify that existing app.`,\n `Use relative workspace links like /${input.appId}. Do not hardcode localhost, 127.0.0.1, 8080, 8100, or any dev port; the active workspace gateway/browser origin owns the port.`,\n `Use the framework/template UI stack: shadcn/ui components and @tabler/icons-react. Do not add lucide-react or another icon library for standard UI.`,\n `Ensure the React Router client entry preserves APP_BASE_PATH/VITE_APP_BASE_PATH via appBasePath().`,\n input.vaultAccessMode === \"all-apps\"\n ? `Do not create per-app Dispatch vault grants unless the workspace switches vault access to manual or the user explicitly asks for manual grants.`\n : keyList\n ? `After the app exists, grant the selected Dispatch vault keys to appId \"${input.appId}\" and sync them once the app server is available. Treat these as requested grants, not active grants before creation succeeds.`\n : `Do not grant any Dispatch vault keys unless the user asks later.`,\n input.selectedResources.length\n ? `After the app exists, grant the selected Dispatch workspace resources to appId \"${input.appId}\". Do not sync all-app workspace resources; they are inherited.`\n : `Do not grant any selected-only Dispatch workspace resources unless the user asks later.`,\n ``,\n `App readiness requirements before handing off:`,\n `- Ensure apps/${input.appId}/package.json exists with displayName/name and a concise description so Dispatch and the workspace gateway discover it from the filesystem. There is no separate workspace app registry to edit.`,\n `- Update the app manifest/package/deploy metadata needed by the existing workspace deployment model; do not leave the app relying only on local discovery.`,\n `- Verify the app's agent card/A2A metadata is ready so Dispatch can discover and delegate to the app after deployment. Every sibling workspace app is available over A2A by default through call-agent, with names and descriptions from the workspace app registry.`,\n `- Include a final verification note covering filesystem discovery, manifest/deploy metadata, relative same-origin routing, and agent-card readiness.`,\n `When it is ready, start or update the workspace dev server and navigate the user to /${input.appId}.`,\n ].join(\"\\n\");\n}\n\nexport function NewWorkspaceAppFlow({\n sourceApp = \"chat\",\n className = \"\",\n dispatchBasePath,\n}: NewWorkspaceAppFlowProps) {\n const [selectedSecretIds, setSelectedSecretIds] = useState<string[]>([]);\n const [selectedResourceIds, setSelectedResourceIds] = useState<string[]>([]);\n const [secrets, setSecrets] = useState<VaultSecretOption[]>([]);\n const [resources, setResources] = useState<WorkspaceResourceOption[]>([]);\n const [vaultAccessMode, setVaultAccessMode] =\n useState<VaultAccessMode>(\"all-apps\");\n const [secretsError, setSecretsError] = useState<string | null>(null);\n const [resourcesError, setResourcesError] = useState<string | null>(null);\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [branchUrl, setBranchUrl] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const { isDevMode } = useDevMode();\n\n const effectiveDispatchBasePath =\n dispatchBasePath === undefined\n ? defaultDispatchBasePath(sourceApp)\n : dispatchBasePath;\n\n useEffect(() => {\n let cancelled = false;\n const secretsUrl = actionUrl(\n effectiveDispatchBasePath,\n \"list-vault-secret-options\",\n );\n const vaultAccessUrl = actionUrl(\n effectiveDispatchBasePath,\n \"get-vault-access-settings\",\n );\n const resourcesUrl = actionUrl(\n effectiveDispatchBasePath,\n \"list-workspace-resource-options\",\n );\n\n fetchJson(secretsUrl)\n .then((data) => {\n if (cancelled) return;\n setSecrets(Array.isArray(data) ? data : []);\n setSecretsError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setSecrets([]);\n setSecretsError(err?.message || \"Could not load Dispatch keys\");\n });\n\n fetchJson(vaultAccessUrl)\n .then((data) => {\n if (cancelled) return;\n setVaultAccessMode(data?.mode === \"manual\" ? \"manual\" : \"all-apps\");\n })\n .catch(() => {\n if (cancelled) return;\n setVaultAccessMode(\"manual\");\n });\n\n fetchJson(resourcesUrl)\n .then((data) => {\n if (cancelled) return;\n setResources(Array.isArray(data) ? data : []);\n setResourcesError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setResources([]);\n setResourcesError(err?.message || \"Could not load Dispatch resources\");\n });\n\n return () => {\n cancelled = true;\n };\n }, [effectiveDispatchBasePath]);\n\n const selectedSecrets = useMemo(\n () => secrets.filter((secret) => selectedSecretIds.includes(secret.id)),\n [secrets, selectedSecretIds],\n );\n const selectedResources = useMemo(\n () =>\n resources.filter((resource) => selectedResourceIds.includes(resource.id)),\n [resources, selectedResourceIds],\n );\n const selectedSecretLabel =\n vaultAccessMode === \"all-apps\"\n ? \"All keys included\"\n : selectedSecretIds.length === 0\n ? \"No keys selected\"\n : `${selectedSecretIds.length} key${selectedSecretIds.length === 1 ? \"\" : \"s\"} selected`;\n const selectedResourceLabel =\n selectedResourceIds.length === 0\n ? \"No resources selected\"\n : `${selectedResourceIds.length} resource${selectedResourceIds.length === 1 ? \"\" : \"s\"} selected`;\n\n async function submit(rawPrompt: string) {\n const prompt = rawPrompt.trim();\n if (!prompt || isSubmitting) return;\n const appId = titleFromPrompt(prompt);\n const validationError = getWorkspaceAppIdValidationError(appId);\n if (validationError) {\n setStatusMessage(validationError);\n return;\n }\n\n const message = buildNewWorkspaceAppPrompt({\n appId,\n prompt,\n selectedKeys:\n vaultAccessMode === \"manual\"\n ? selectedSecrets.map((s) => s.credentialKey)\n : [],\n selectedResources,\n vaultAccessMode,\n });\n setIsSubmitting(true);\n setStatusMessage(null);\n setBranchUrl(null);\n\n try {\n if (isInBuilderFrame()) {\n sendToAgentChat({ message, submit: true, type: \"code\" });\n setStatusMessage(\"Sent to Builder chat.\");\n } else if (isDevMode) {\n sendToAgentChat({ message, submit: true, type: \"code\", newTab: true });\n setStatusMessage(\"Sent to the local agent.\");\n } else {\n const result = await fetchJson(\n actionUrl(effectiveDispatchBasePath, \"start-workspace-app-creation\"),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n prompt,\n appId,\n secretIds: vaultAccessMode === \"manual\" ? selectedSecretIds : [],\n resourceIds: selectedResourceIds,\n }),\n },\n );\n if (result?.mode === \"builder\") {\n setBranchUrl(result?.url || null);\n setStatusMessage(\"Builder branch created.\");\n } else {\n setStatusMessage(\n result?.message ||\n \"Builder app creation is coming soon here. Open this workspace in Builder to create an app from this prompt.\",\n );\n }\n }\n } catch (err: any) {\n setStatusMessage(err?.message || \"Could not start the new app flow.\");\n } finally {\n setIsSubmitting(false);\n }\n }\n\n function toggleSecret(id: string) {\n setSelectedSecretIds((current) =>\n current.includes(id)\n ? current.filter((existing) => existing !== id)\n : [...current, id],\n );\n }\n\n function toggleResource(id: string) {\n setSelectedResourceIds((current) =>\n current.includes(id)\n ? current.filter((existing) => existing !== id)\n : [...current, id],\n );\n }\n\n return (\n <section\n className={`mx-auto flex w-full max-w-5xl flex-col gap-5 px-4 py-6 ${className}`}\n >\n <div className=\"grid gap-5 lg:grid-cols-[minmax(0,1fr)_320px]\">\n <div className=\"flex flex-col gap-3\">\n <PromptComposer\n autoFocus\n disabled={isSubmitting}\n placeholder=\"Describe the app your teammate should be able to use...\"\n draftScope=\"dispatch:new-app\"\n preserveDraftOnSubmit\n onSubmit={(text) => submit(text)}\n />\n\n {statusMessage ? (\n <div className=\"rounded-md border border-border bg-muted/40 px-3 py-2 text-sm text-muted-foreground\">\n {statusMessage}\n {branchUrl ? (\n <a\n href={branchUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"ml-2 inline-flex items-center gap-1 font-medium text-foreground underline\"\n >\n Open branch <IconArrowUpRight className=\"h-3 w-3\" />\n </a>\n ) : null}\n </div>\n ) : null}\n </div>\n\n <aside className=\"overflow-hidden rounded-lg border border-border bg-card\">\n <div className=\"border-b border-border px-4 py-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <IconKey className=\"h-4 w-4\" />\n Dispatch keys\n </div>\n <span className=\"shrink-0 rounded border border-border bg-background/40 px-2 py-0.5 text-[11px] text-muted-foreground\">\n {selectedSecretLabel}\n </span>\n </div>\n </div>\n <div className=\"max-h-[220px] space-y-2 overflow-y-auto p-3\">\n {vaultAccessMode === \"all-apps\" ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n Every saved Dispatch vault key is available to new apps.\n </p>\n ) : secretsError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {secretsError}\n </p>\n ) : secrets.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch vault keys found yet.\n </p>\n ) : (\n secrets.map((secret) => {\n const selected = selectedSecretIds.includes(secret.id);\n return (\n <div\n key={secret.id}\n className={`group rounded-md border text-sm transition ${\n selected\n ? \"border-primary/45 bg-primary/5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.08)]\"\n : \"border-border bg-background/25 text-foreground hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleSecret(secret.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent group-hover:border-muted-foreground/60\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium\">\n {secret.credentialKey}\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {selected\n ? \"Will be requested for this app\"\n : \"Click to request\"}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75 open:bg-background/10\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Provider: {secret.provider || \"Not specified\"}\n </div>\n <div className=\"truncate\">Name: {secret.name}</div>\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n\n <div className=\"border-y border-border px-4 py-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <IconBook className=\"h-4 w-4\" />\n Resource packs\n </div>\n <span className=\"shrink-0 rounded border border-border bg-background/40 px-2 py-0.5 text-[11px] text-muted-foreground\">\n {selectedResourceLabel}\n </span>\n </div>\n </div>\n <div className=\"max-h-[220px] space-y-2 overflow-y-auto p-3\">\n {resourcesError ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n {resourcesError}\n </p>\n ) : resources.length === 0 ? (\n <p className=\"rounded-md border border-dashed border-border px-3 py-3 text-xs text-muted-foreground\">\n No Dispatch resource packs found yet.\n </p>\n ) : (\n resources.map((resource) => {\n const selected = selectedResourceIds.includes(resource.id);\n return (\n <div\n key={resource.id}\n className={`group rounded-md border text-sm transition ${\n selected\n ? \"border-primary/45 bg-primary/5 text-foreground shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.08)]\"\n : \"border-border bg-background/25 text-foreground hover:border-muted-foreground/40 hover:bg-accent/35\"\n }`}\n >\n <button\n type=\"button\"\n aria-pressed={selected}\n onClick={() => toggleResource(resource.id)}\n className=\"flex w-full cursor-pointer items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30\"\n >\n <span\n className={`mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition ${\n selected\n ? \"border-primary/60 bg-primary/10 text-primary\"\n : \"border-muted-foreground/35 text-transparent group-hover:border-muted-foreground/60\"\n }`}\n >\n {selected ? <IconCheck className=\"h-3 w-3\" /> : null}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <IconFileText className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground/70\" />\n <span className=\"block truncate font-medium\">\n {resource.name}\n </span>\n </span>\n <span className=\"block truncate text-xs text-muted-foreground/70\">\n {resource.kind} · {resource.path}\n </span>\n </span>\n </button>\n <details className=\"group/details border-t border-border/60 px-3 py-1.5 text-xs text-muted-foreground/75 open:bg-background/10\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 text-[11px] hover:text-muted-foreground [&::-webkit-details-marker]:hidden\">\n <IconChevronDown className=\"h-3 w-3 transition-transform group-open/details:rotate-180\" />\n Details\n </summary>\n <div className=\"mt-1.5 space-y-1 pb-0.5 pl-4\">\n <div className=\"truncate\">\n Scope:{\" \"}\n {resource.scope === \"all\"\n ? \"All apps\"\n : \"Selected apps\"}\n </div>\n {resource.description ? (\n <div className=\"line-clamp-2\">\n {resource.description}\n </div>\n ) : null}\n </div>\n </details>\n </div>\n );\n })\n )}\n </div>\n </aside>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagram.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/diagram.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AAQrB,OAAO,EAGL,KAAK,WAAW,EAGjB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"diagram.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/diagram.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AAQrB,OAAO,EAGL,KAAK,WAAW,EAGjB,MAAM,qBAAqB,CAAC;AA+f7B;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,2CAsCA;AA2CD,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAQ7B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE,cAAc,CAAC,WAAW,CAAC,2CAkL7B;AAED,kFAAkF;AAClF,eAAO,MAAM,YAAY,8CAgBvB,CAAC"}
|
|
@@ -39,7 +39,7 @@ import { diagramMdx, diagramSchema, } from "./diagram.config.js";
|
|
|
39
39
|
/* -------------------------------------------------------------------------- */
|
|
40
40
|
/** The rough-overlay selector for diagram bordered boxes (mirrors the plan). */
|
|
41
41
|
const DIAGRAM_ROUGH_SELECTOR = "[data-rough],.diagram-panel,.diagram-node,.diagram-box,.diagram-pill,.diagram-card,[class*='card'],[class*='box'],[class*='panel'],[class*='pill'],[class*='chip'],[class*='badge'],hr";
|
|
42
|
-
function HtmlDiagram({ data, ctx
|
|
42
|
+
function HtmlDiagram({ data, ctx, compact, }) {
|
|
43
43
|
const ref = useRef(null);
|
|
44
44
|
const isDark = useIsDark();
|
|
45
45
|
const style = useWireframeStyle();
|
|
@@ -57,7 +57,7 @@ function HtmlDiagram({ data, ctx: _ctx, compact, }) {
|
|
|
57
57
|
? scopeDesignCss(safeCss, `[data-plan-diagram-scope="${scopeId}"]`)
|
|
58
58
|
: "";
|
|
59
59
|
}, [data.css, scopeId]);
|
|
60
|
-
return (_jsxs("div", { ref: ref, className: cn("plan-diagram-shell", compact && "plan-diagram-compact"), children: [_jsxs("div", { className: "plan-diagram-frame", "data-theme": isDark ? "dark" : "light", "data-style": style, "data-plan-diagram-scope": scopeId, children: [scopedCss && _jsx("style", { children: scopedCss }), _jsx("div", { className: "plan-diagram-frame-content", dangerouslySetInnerHTML: { __html: safeHtml } })] }), _jsx(RoughOverlay, { scopeRef: ref, enabled: style === "sketchy", drawFrame: false, selector: DIAGRAM_ROUGH_SELECTOR }), data.caption && !compact && (_jsx("p", { className: "mt-3 text-sm leading-6 text-muted-foreground", children: data.caption }))] }));
|
|
60
|
+
return (_jsxs("div", { ref: ref, className: cn("plan-diagram-shell", compact && "plan-diagram-compact"), children: [_jsxs("div", { className: "plan-diagram-frame", dir: ctx.textDirection, "data-theme": isDark ? "dark" : "light", "data-style": style, "data-text-direction": ctx.textDirection, "data-plan-diagram-scope": scopeId, children: [scopedCss && _jsx("style", { children: scopedCss }), _jsx("div", { className: "plan-diagram-frame-content", dangerouslySetInnerHTML: { __html: safeHtml } })] }), _jsx(RoughOverlay, { scopeRef: ref, enabled: style === "sketchy", drawFrame: false, selector: DIAGRAM_ROUGH_SELECTOR }), data.caption && !compact && (_jsx("p", { className: "mt-3 text-sm leading-6 text-muted-foreground", children: data.caption }))] }));
|
|
61
61
|
}
|
|
62
62
|
/* -------------------------------------------------------------------------- */
|
|
63
63
|
/* Legacy node-graph paths */
|
|
@@ -98,7 +98,7 @@ function orderDiagramNodes(nodes, edges) {
|
|
|
98
98
|
ordered.push(node);
|
|
99
99
|
return ordered;
|
|
100
100
|
}
|
|
101
|
-
function PositionedDiagram({ data, compact, markerId, }) {
|
|
101
|
+
function PositionedDiagram({ data, compact, markerId, direction, }) {
|
|
102
102
|
const nodes = (data.nodes ?? []).map((node) => ({
|
|
103
103
|
...node,
|
|
104
104
|
x: clampDiagramPercent(node.x ?? 50),
|
|
@@ -117,27 +117,31 @@ function PositionedDiagram({ data, compact, markerId, }) {
|
|
|
117
117
|
const yMargin = compact ? 15 : 18;
|
|
118
118
|
const displayNodes = nodes.map((node) => ({
|
|
119
119
|
...node,
|
|
120
|
-
|
|
120
|
+
displayXBase: diagramPointPercent(node.x, paddedViewBox.x, paddedViewBox.width, xMargin),
|
|
121
121
|
displayY: diagramRowPointPercent(node.y, rows, paddedViewBox, yMargin),
|
|
122
122
|
}));
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
const displayNodesForDirection = displayNodes.map((node) => ({
|
|
124
|
+
...node,
|
|
125
|
+
displayX: direction === "rtl" ? 100 - node.displayXBase : node.displayXBase,
|
|
126
|
+
}));
|
|
127
|
+
const nodeByIdForDirection = new Map(displayNodesForDirection.map((node) => [node.id, node]));
|
|
128
|
+
return (_jsxs("div", { className: "plan-sketch rounded-[16px] border border-border bg-muted p-5", dir: direction, "data-text-direction": direction, children: [_jsx("div", { className: "overflow-auto rounded-xl border border-border bg-background", style: { minHeight: canvasHeight }, children: _jsxs("div", { className: "relative", style: { minHeight: canvasHeight, minWidth: canvasMinWidth }, children: [_jsxs("svg", { className: "pointer-events-none absolute inset-0 z-0 h-full w-full", viewBox: "0 0 100 100", preserveAspectRatio: "none", "aria-hidden": "true", children: [_jsx("defs", { children: _jsx("marker", { id: arrowId, viewBox: "0 0 10 10", refX: "8", refY: "5", markerWidth: "5", markerHeight: "5", orient: "auto-start-reverse", children: _jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", className: "fill-muted-foreground" }) }) }), edges.map((edge, index) => {
|
|
129
|
+
const from = nodeByIdForDirection.get(edge.from);
|
|
130
|
+
const to = nodeByIdForDirection.get(edge.to);
|
|
127
131
|
if (!from || !to)
|
|
128
132
|
return null;
|
|
129
133
|
return (_jsx("line", { x1: from.displayX, y1: from.displayY, x2: to.displayX, y2: to.displayY, markerEnd: `url(#${arrowId})`, vectorEffect: "non-scaling-stroke", className: "stroke-border", strokeWidth: 2, strokeDasharray: edge.label ? "0" : "6 5" }, `${edge.from}-${edge.to}-${index}`));
|
|
130
134
|
})] }), !compact &&
|
|
131
135
|
edges.map((edge, index) => {
|
|
132
|
-
const from =
|
|
133
|
-
const to =
|
|
136
|
+
const from = nodeByIdForDirection.get(edge.from);
|
|
137
|
+
const to = nodeByIdForDirection.get(edge.to);
|
|
134
138
|
if (!edge.label || !from || !to)
|
|
135
139
|
return null;
|
|
136
140
|
return (_jsx("span", { className: "absolute z-10 max-w-[130px] -translate-x-1/2 -translate-y-1/2 rounded-full border border-border bg-background px-2 py-0.5 text-center text-[11px] font-semibold text-muted-foreground shadow-sm", style: {
|
|
137
141
|
left: `${(from.displayX + to.displayX) / 2}%`,
|
|
138
142
|
top: `${(from.displayY + to.displayY) / 2}%`,
|
|
139
143
|
}, children: edge.label }, `${edge.from}-${edge.to}-${index}-label`));
|
|
140
|
-
}),
|
|
144
|
+
}), displayNodesForDirection.map((node, index) => (_jsxs("article", { className: "absolute z-20 -translate-x-1/2 -translate-y-1/2 rounded-xl border-2 border-border bg-background p-3 text-foreground shadow-sm", style: {
|
|
141
145
|
left: `${node.displayX}%`,
|
|
142
146
|
top: `${node.displayY}%`,
|
|
143
147
|
width: nodeWidth,
|
|
@@ -196,16 +200,18 @@ function diagramCanvasHeight(rows, compact) {
|
|
|
196
200
|
return base;
|
|
197
201
|
return Math.max(base, rows * (compact ? 140 : 190) + (compact ? 80 : 120));
|
|
198
202
|
}
|
|
199
|
-
function SequenceDiagram({ data, compact, }) {
|
|
203
|
+
function SequenceDiagram({ data, compact, direction, }) {
|
|
200
204
|
const edges = data.edges ?? [];
|
|
201
205
|
const nodes = orderDiagramNodes(data.nodes ?? [], edges);
|
|
202
206
|
if (nodes.length === 0) {
|
|
203
207
|
return (_jsx("div", { className: "rounded-[12px] border border-border bg-muted p-4 text-sm text-muted-foreground", children: "Diagram content is empty." }));
|
|
204
208
|
}
|
|
205
|
-
|
|
206
|
-
|
|
209
|
+
const visualNodes = direction === "rtl" ? [...nodes].reverse() : nodes;
|
|
210
|
+
return (_jsxs("div", { className: "plan-sketch rounded-[16px] border border-border bg-muted p-5", dir: direction, "data-text-direction": direction, children: [_jsx("div", { className: cn("flex gap-3 overflow-x-auto pb-2", compact ? "items-center" : "items-stretch"), children: visualNodes.map((node, index) => {
|
|
211
|
+
const next = visualNodes[index + 1];
|
|
207
212
|
const edge = next
|
|
208
|
-
? edges.find((candidate) => candidate.from === node.id && candidate.to === next.id)
|
|
213
|
+
? edges.find((candidate) => (candidate.from === node.id && candidate.to === next.id) ||
|
|
214
|
+
(candidate.from === next.id && candidate.to === node.id))
|
|
209
215
|
: undefined;
|
|
210
216
|
return (_jsxs("div", { className: "flex min-w-max items-center gap-3", children: [_jsxs("article", { className: cn("w-[180px] rounded-xl border-2 border-border bg-background p-3 text-foreground", compact && "w-[150px]"), children: [_jsx("p", { className: "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground", children: index + 1 }), _jsx("h3", { className: "mt-2 text-base font-semibold leading-tight", children: node.label }), node.detail && !compact && (_jsx("p", { className: "mt-2 text-xs leading-5 text-muted-foreground", children: node.detail }))] }), next && (_jsxs("div", { className: "grid min-w-[72px] justify-items-center gap-1 text-muted-foreground", children: [edge?.label && (_jsx("span", { className: "max-w-[96px] truncate rounded-full border border-border px-2 py-0.5 text-[11px] font-semibold", children: edge.label })), _jsx("span", { className: "h-0.5 w-full rounded-full border-t-2 border-dashed border-border" })] }))] }, node.id));
|
|
211
217
|
}) }), data.notes && data.notes.length > 0 && !compact && (_jsx("div", { className: "mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2", children: data.notes.map((note) => (_jsx("p", { children: note.text }, note.id))) }))] }));
|
|
@@ -223,9 +229,9 @@ function DiagramBody({ data, ctx, compact, }) {
|
|
|
223
229
|
return _jsx(HtmlDiagram, { data: data, ctx: ctx, compact: compact });
|
|
224
230
|
}
|
|
225
231
|
if (hasPositionedDiagramNodes(data)) {
|
|
226
|
-
return (_jsx(PositionedDiagram, { data: data, compact: compact, markerId: markerId }));
|
|
232
|
+
return (_jsx(PositionedDiagram, { data: data, compact: compact, markerId: markerId, direction: ctx.textDirection }));
|
|
227
233
|
}
|
|
228
|
-
return _jsx(SequenceDiagram, { data: data, compact: compact });
|
|
234
|
+
return (_jsx(SequenceDiagram, { data: data, compact: compact, direction: ctx.textDirection }));
|
|
229
235
|
}
|
|
230
236
|
/* -------------------------------------------------------------------------- */
|
|
231
237
|
/* Expand / lightbox */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagram.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/diagram.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { IconArrowsMaximize, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n} from \"../types.js\";\nimport { AiEditableFieldLabel } from \"../AiEditableField.js\";\nimport { RoughOverlay, useIsDark, useWireframeStyle } from \"./wireframe-kit.js\";\nimport {\n sanitizeDiagramHtml,\n sanitizeWireframeCss,\n scopeDesignCss,\n} from \"./sanitize-html.js\";\nimport {\n diagramMdx,\n diagramSchema,\n type DiagramData,\n type DiagramEdge,\n type DiagramNode,\n} from \"./diagram.config.js\";\n\n/**\n * Read + Edit renderers for the shared `diagram` block — a flexible inline\n * architecture/code diagram. The preferred authoring path is a scoped, inert\n * HTML/SVG fragment that leans on `.diagram-*` primitives and `--wf-*` tokens;\n * a legacy positional / sequence node-graph path is kept for older/simple plans.\n * Lives in core so any app can register it (it originated in the plan template).\n *\n * DECOUPLING from the plan original (mirrors the sibling `wireframe.tsx` port):\n * - Theme: `useIsDark()` reads `document.documentElement.classList` instead of\n * `next-themes`; `useWireframeStyle()` reads the viewer's sketchy/clean\n * preference from the shared `plan-wireframe-style` localStorage key — both\n * from `./wireframe-kit.js`, so core stays plan-free and shadcn-free.\n * - HTML sanitize: the HTML/SVG fragment + CSS run through the app-injected\n * `ctx.sanitizeHtml` at the render point (defense-in-depth against stored\n * XSS). Without a sanitizer wired, the HTML path emits nothing — core never\n * injects unsanitized author HTML. The React-free `diagramSchema` already\n * rejects active markup before storage.\n * - The rough.js sketch overlay reuses the kit's shared `RoughOverlay`, scoped\n * with the diagram selector and `drawFrame={false}` (the same call the plan\n * `HtmlDiagram` made). The `.plan-diagram-frame` / `.diagram-*` / `data-rough`\n * class contract is preserved exactly so the theme-token CSS in core's\n * `blocks.css` styles it in any app.\n *\n * The section carries the app-neutral `an-block` class plus the legacy\n * `plan-block` class so plan renders byte-identically while any other app gets\n * the theme-token treatment.\n */\n\n/* -------------------------------------------------------------------------- */\n/* HTML/SVG diagram path */\n/* -------------------------------------------------------------------------- */\n\n/** The rough-overlay selector for diagram bordered boxes (mirrors the plan). */\nconst DIAGRAM_ROUGH_SELECTOR =\n \"[data-rough],.diagram-panel,.diagram-node,.diagram-box,.diagram-pill,.diagram-card,[class*='card'],[class*='box'],[class*='panel'],[class*='pill'],[class*='chip'],[class*='badge'],hr\";\n\nfunction HtmlDiagram({\n data,\n ctx: _ctx,\n compact,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const isDark = useIsDark();\n const style = useWireframeStyle();\n const scopeId = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n // Sanitize author HTML/CSS at the render point (defense-in-depth against\n // stored XSS). Self-contained in core via the shared block sanitizer (DOM-based\n // in the browser, regex fallback on the server) so diagrams render in any app\n // without the host wiring a sanitizer hook.\n const safeHtml = useMemo(() => sanitizeDiagramHtml(data.html), [data.html]);\n const scopedCss = useMemo(() => {\n const safeCss = sanitizeWireframeCss(data.css);\n // Scope every author selector under this diagram instance so global\n // selectors (body, *, .app-shell, :root) can't escape and restyle the page.\n return safeCss\n ? scopeDesignCss(safeCss, `[data-plan-diagram-scope=\"${scopeId}\"]`)\n : \"\";\n }, [data.css, scopeId]);\n\n return (\n <div\n ref={ref}\n className={cn(\"plan-diagram-shell\", compact && \"plan-diagram-compact\")}\n >\n <div\n className=\"plan-diagram-frame\"\n data-theme={isDark ? \"dark\" : \"light\"}\n data-style={style}\n data-plan-diagram-scope={scopeId}\n >\n {scopedCss && <style>{scopedCss}</style>}\n <div\n className=\"plan-diagram-frame-content\"\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n <RoughOverlay\n scopeRef={ref}\n enabled={style === \"sketchy\"}\n drawFrame={false}\n selector={DIAGRAM_ROUGH_SELECTOR}\n />\n {data.caption && !compact && (\n <p className=\"mt-3 text-sm leading-6 text-muted-foreground\">\n {data.caption}\n </p>\n )}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Legacy node-graph paths */\n/* -------------------------------------------------------------------------- */\n\nfunction clampDiagramPercent(value: number) {\n if (!Number.isFinite(value)) return 50;\n return Math.max(4, Math.min(96, value));\n}\n\nfunction hasPositionedDiagramNodes(data: DiagramData): boolean {\n return (data.nodes ?? []).some(\n (node) => typeof node.x === \"number\" && typeof node.y === \"number\",\n );\n}\n\nfunction orderDiagramNodes(\n nodes: DiagramNode[],\n edges: DiagramEdge[],\n): DiagramNode[] {\n if (nodes.length === 0) return [];\n const byId = new Map(nodes.map((node) => [node.id, node]));\n const indegree = new Map(nodes.map((node) => [node.id, 0]));\n for (const edge of edges) {\n if (byId.has(edge.from) && byId.has(edge.to)) {\n indegree.set(edge.to, (indegree.get(edge.to) ?? 0) + 1);\n }\n }\n const start = nodes.find((node) => (indegree.get(node.id) ?? 0) === 0);\n if (!start) return nodes;\n const ordered: DiagramNode[] = [];\n const seen = new Set<string>();\n let current: DiagramNode | undefined = start;\n while (current && !seen.has(current.id)) {\n const node: DiagramNode = current;\n ordered.push(node);\n seen.add(node.id);\n const next = edges.find((edge) => edge.from === node.id);\n current = next ? byId.get(next.to) : undefined;\n }\n for (const node of nodes) if (!seen.has(node.id)) ordered.push(node);\n return ordered;\n}\n\nfunction PositionedDiagram({\n data,\n compact,\n markerId,\n}: {\n data: DiagramData;\n compact?: boolean;\n markerId: string;\n}) {\n const nodes = (data.nodes ?? []).map((node) => ({\n ...node,\n x: clampDiagramPercent(node.x ?? 50),\n y: clampDiagramPercent(node.y ?? 50),\n }));\n const edges = data.edges ?? [];\n const arrowId = `${markerId}-diagram-arrow`;\n const nodeWidth = compact ? 150 : 190;\n const rows = diagramRows(nodes, compact);\n const canvasHeight = diagramCanvasHeight(rows.length, compact);\n const canvasMinWidth = compact ? 560 : 720;\n const nodeWidthPct = compact ? 20 : 18;\n const nodeHeightPct = compact ? 14 : 18;\n const paddedViewBox = diagramViewBox(nodes, nodeWidthPct, nodeHeightPct);\n const xMargin = compact ? 13 : 14;\n const yMargin = compact ? 15 : 18;\n const displayNodes = nodes.map((node) => ({\n ...node,\n displayX: diagramPointPercent(\n node.x,\n paddedViewBox.x,\n paddedViewBox.width,\n xMargin,\n ),\n displayY: diagramRowPointPercent(node.y, rows, paddedViewBox, yMargin),\n }));\n const nodeById = new Map(displayNodes.map((node) => [node.id, node]));\n\n return (\n <div className=\"plan-sketch rounded-[16px] border border-border bg-muted p-5\">\n <div\n className=\"overflow-auto rounded-xl border border-border bg-background\"\n style={{ minHeight: canvasHeight }}\n >\n <div\n className=\"relative\"\n style={{ minHeight: canvasHeight, minWidth: canvasMinWidth }}\n >\n <svg\n className=\"pointer-events-none absolute inset-0 z-0 h-full w-full\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <defs>\n <marker\n id={arrowId}\n viewBox=\"0 0 10 10\"\n refX=\"8\"\n refY=\"5\"\n markerWidth=\"5\"\n markerHeight=\"5\"\n orient=\"auto-start-reverse\"\n >\n <path\n d=\"M 0 0 L 10 5 L 0 10 z\"\n className=\"fill-muted-foreground\"\n />\n </marker>\n </defs>\n {edges.map((edge, index) => {\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n if (!from || !to) return null;\n return (\n <line\n key={`${edge.from}-${edge.to}-${index}`}\n x1={from.displayX}\n y1={from.displayY}\n x2={to.displayX}\n y2={to.displayY}\n markerEnd={`url(#${arrowId})`}\n vectorEffect=\"non-scaling-stroke\"\n className=\"stroke-border\"\n strokeWidth={2}\n strokeDasharray={edge.label ? \"0\" : \"6 5\"}\n />\n );\n })}\n </svg>\n\n {!compact &&\n edges.map((edge, index) => {\n const from = nodeById.get(edge.from);\n const to = nodeById.get(edge.to);\n if (!edge.label || !from || !to) return null;\n return (\n <span\n key={`${edge.from}-${edge.to}-${index}-label`}\n className=\"absolute z-10 max-w-[130px] -translate-x-1/2 -translate-y-1/2 rounded-full border border-border bg-background px-2 py-0.5 text-center text-[11px] font-semibold text-muted-foreground shadow-sm\"\n style={{\n left: `${(from.displayX + to.displayX) / 2}%`,\n top: `${(from.displayY + to.displayY) / 2}%`,\n }}\n >\n {edge.label}\n </span>\n );\n })}\n\n {displayNodes.map((node, index) => (\n <article\n key={node.id}\n className=\"absolute z-20 -translate-x-1/2 -translate-y-1/2 rounded-xl border-2 border-border bg-background p-3 text-foreground shadow-sm\"\n style={{\n left: `${node.displayX}%`,\n top: `${node.displayY}%`,\n width: nodeWidth,\n }}\n >\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {index + 1}\n </p>\n <h3 className=\"mt-2 text-base font-semibold leading-tight\">\n {node.label}\n </h3>\n {node.detail && !compact && (\n <p className=\"mt-2 text-xs leading-5 text-muted-foreground\">\n {node.detail}\n </p>\n )}\n </article>\n ))}\n </div>\n </div>\n {data.notes && data.notes.length > 0 && !compact && (\n <div className=\"mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2\">\n {data.notes.map((note) => (\n <p key={note.id}>{note.text}</p>\n ))}\n </div>\n )}\n </div>\n );\n}\n\ntype DiagramViewBox = {\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nfunction diagramViewBox(\n nodes: Array<Pick<DiagramNode, \"x\" | \"y\">>,\n nodeWidthPct: number,\n nodeHeightPct: number,\n): DiagramViewBox {\n if (nodes.length === 0) return { x: 0, y: 0, width: 100, height: 100 };\n\n const halfWidth = nodeWidthPct / 2;\n const halfHeight = nodeHeightPct / 2;\n const left = Math.min(...nodes.map((node) => (node.x ?? 50) - halfWidth));\n const right = Math.max(...nodes.map((node) => (node.x ?? 50) + halfWidth));\n const top = Math.min(...nodes.map((node) => (node.y ?? 50) - halfHeight));\n const bottom = Math.max(...nodes.map((node) => (node.y ?? 50) + halfHeight));\n\n const x = Math.min(0, left);\n const y = Math.min(0, top);\n const width = Math.max(100, right) - x;\n const height = Math.max(100, bottom) - y;\n\n return { x, y, width, height };\n}\n\nfunction diagramPointPercent(\n value: number,\n viewBoxStart: number,\n viewBoxSize: number,\n margin = 0,\n): number {\n if (\n !Number.isFinite(value) ||\n !Number.isFinite(viewBoxSize) ||\n !viewBoxSize\n ) {\n return 50;\n }\n const percent = ((value - viewBoxStart) / viewBoxSize) * 100;\n return Math.min(100 - margin, Math.max(margin, percent));\n}\n\nfunction diagramRows(\n nodes: Array<Pick<DiagramNode, \"y\">>,\n compact?: boolean,\n): number[] {\n const rowGap = compact ? 8 : 10;\n return [...nodes]\n .sort((a, b) => (a.y ?? 50) - (b.y ?? 50))\n .reduce<number[]>((acc, node) => {\n const y = node.y ?? 50;\n const last = acc[acc.length - 1];\n if (last == null || Math.abs(y - last) >= rowGap) acc.push(y);\n return acc;\n }, []);\n}\n\nfunction diagramRowPointPercent(\n value: number,\n rows: number[],\n viewBox: DiagramViewBox,\n margin: number,\n): number {\n if (rows.length <= 2) {\n return diagramPointPercent(value, viewBox.y, viewBox.height, margin);\n }\n const closestIndex = rows.reduce((bestIndex, row, index) => {\n const bestDistance = Math.abs((rows[bestIndex] ?? 50) - value);\n return Math.abs(row - value) < bestDistance ? index : bestIndex;\n }, 0);\n const span = 100 - margin * 2;\n return margin + (span * closestIndex) / Math.max(1, rows.length - 1);\n}\n\nfunction diagramCanvasHeight(rows: number, compact?: boolean): number {\n const base = compact ? 280 : 430;\n if (rows <= 2) return base;\n return Math.max(base, rows * (compact ? 140 : 190) + (compact ? 80 : 120));\n}\n\nfunction SequenceDiagram({\n data,\n compact,\n}: {\n data: DiagramData;\n compact?: boolean;\n}) {\n const edges = data.edges ?? [];\n const nodes = orderDiagramNodes(data.nodes ?? [], edges);\n if (nodes.length === 0) {\n return (\n <div className=\"rounded-[12px] border border-border bg-muted p-4 text-sm text-muted-foreground\">\n Diagram content is empty.\n </div>\n );\n }\n return (\n <div className=\"plan-sketch rounded-[16px] border border-border bg-muted p-5\">\n <div\n className={cn(\n \"flex gap-3 overflow-x-auto pb-2\",\n compact ? \"items-center\" : \"items-stretch\",\n )}\n >\n {nodes.map((node, index) => {\n const next = nodes[index + 1];\n const edge = next\n ? edges.find(\n (candidate) =>\n candidate.from === node.id && candidate.to === next.id,\n )\n : undefined;\n return (\n <div key={node.id} className=\"flex min-w-max items-center gap-3\">\n <article\n className={cn(\n \"w-[180px] rounded-xl border-2 border-border bg-background p-3 text-foreground\",\n compact && \"w-[150px]\",\n )}\n >\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {index + 1}\n </p>\n <h3 className=\"mt-2 text-base font-semibold leading-tight\">\n {node.label}\n </h3>\n {node.detail && !compact && (\n <p className=\"mt-2 text-xs leading-5 text-muted-foreground\">\n {node.detail}\n </p>\n )}\n </article>\n {next && (\n <div className=\"grid min-w-[72px] justify-items-center gap-1 text-muted-foreground\">\n {edge?.label && (\n <span className=\"max-w-[96px] truncate rounded-full border border-border px-2 py-0.5 text-[11px] font-semibold\">\n {edge.label}\n </span>\n )}\n <span className=\"h-0.5 w-full rounded-full border-t-2 border-dashed border-border\" />\n </div>\n )}\n </div>\n );\n })}\n </div>\n {data.notes && data.notes.length > 0 && !compact && (\n <div className=\"mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2\">\n {data.notes.map((note) => (\n <p key={note.id}>{note.text}</p>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * The diagram body. Routes to the preferred HTML/SVG path (when `data.html` is\n * set) and otherwise to a legacy node-graph path (positioned canvas when nodes\n * carry x/y, else an ordered sequence). Used both inline and, scaled up, inside\n * the expand lightbox — so every variant (html/css, positioned, sequence)\n * enlarges through the same code path.\n */\nfunction DiagramBody({\n data,\n ctx,\n compact,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const markerId = useId().replace(/:/g, \"\");\n if (data.html?.trim()) {\n return <HtmlDiagram data={data} ctx={ctx} compact={compact} />;\n }\n if (hasPositionedDiagramNodes(data)) {\n return (\n <PositionedDiagram data={data} compact={compact} markerId={markerId} />\n );\n }\n return <SequenceDiagram data={data} compact={compact} />;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Expand / lightbox */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Enlarge overlay for a rendered diagram. Mirrors the image lightbox contract\n * used by the composer's `ImagePreviewLightbox` (PromptComposer.tsx) so the\n * expand affordance feels identical to viewing an image full-size: a fixed\n * `bg-black/80` backdrop, Escape to close, click-the-backdrop to close, and a\n * top-right close button. Unlike the image variant this renders arbitrary\n * children (the diagram body re-rendered larger) rather than an `<img>`, since a\n * diagram is live HTML/SVG/node-graph markup, not an image URL.\n *\n * Exported so the separate Mermaid block (`MermaidBlock.tsx`, which renders its\n * diagram to an SVG through a different runtime) can reuse the exact same\n * lightbox contract — one expand affordance shared across both diagram types.\n */\nexport function DiagramLightbox({\n children,\n onClose,\n}: {\n children: React.ReactNode;\n onClose: () => void;\n}) {\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n document.body.style.overflow = \"hidden\";\n return () => {\n document.removeEventListener(\"keydown\", handler);\n document.body.style.overflow = \"\";\n };\n }, [onClose]);\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Diagram preview\"\n onClick={onClose}\n data-plan-interactive\n className=\"fixed inset-0 z-[300] flex items-center justify-center overflow-auto bg-black/80 p-6 cursor-zoom-out\"\n >\n <div\n onClick={(e) => e.stopPropagation()}\n className=\"max-h-full w-full max-w-5xl cursor-default overflow-auto rounded-md bg-background p-6 shadow-2xl\"\n >\n {children}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close preview\"\n className=\"absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60\"\n >\n <IconX className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n\n/**\n * The diagram body plus a hover-revealed top-right \"expand\" button (like the\n * image attachment zoom). Opening the button re-renders the exact same\n * `DiagramBody` inside `DiagramLightbox` at a larger size, so html/css and\n * mermaid/legacy node-graph diagrams alike enlarge through one path. The inline\n * (non-expanded) render is otherwise unchanged.\n */\nfunction ExpandableDiagramBody({\n data,\n ctx,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n}) {\n const [expanded, setExpanded] = useState(false);\n return (\n <div className=\"group/diagram relative\">\n <DiagramBody data={data} ctx={ctx} />\n <button\n type=\"button\"\n data-plan-interactive\n onClick={() => setExpanded(true)}\n aria-label=\"Expand diagram\"\n title=\"Expand diagram\"\n className=\"an-diagram-expand-trigger absolute right-2 top-2 z-10 flex size-7 items-center justify-center rounded-md border border-border/60 bg-background/90 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover/diagram:opacity-100\"\n >\n <IconArrowsMaximize className=\"size-4\" />\n </button>\n {expanded ? (\n <DiagramLightbox onClose={() => setExpanded(false)}>\n <DiagramBody data={data} ctx={ctx} />\n </DiagramLightbox>\n ) : null}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Read + Edit */\n/* -------------------------------------------------------------------------- */\n\n/** Read-only renderer: the diagram body wrapped in the standard titled block. */\nexport function DiagramRead({\n data,\n blockId,\n title,\n summary,\n ctx,\n}: BlockReadProps<DiagramData>) {\n return (\n <section className=\"an-block plan-block\" data-block-id={blockId}>\n {title && <div className=\"an-block-label plan-block-label\">{title}</div>}\n <ExpandableDiagramBody data={data} ctx={ctx} />\n {summary && <p className=\"mt-5 text-muted-foreground\">{summary}</p>}\n </section>\n );\n}\n\n/**\n * Edit form (panel surface). The block can be an HTML/SVG fragment or a legacy\n * node/edge/note graph, so this exposes html/css/caption plus a collapsible\n * legacy node-graph JSON editor, each with an AI-edit affordance via\n * `ctx.renderAiFieldAction` (through `AiEditableFieldLabel`). `editSurface:\n * \"panel\"` means the registry renders the `Read` view with a corner edit button\n * that opens this form in the app-provided popover.\n */\nexport function DiagramEdit({\n data,\n onChange,\n editable,\n blockId,\n title,\n summary,\n ctx,\n}: BlockEditProps<DiagramData>) {\n const htmlId = useId();\n const cssId = useId();\n const captionId = useId();\n const legacyId = useId();\n const [html, setHtml] = useState(data.html ?? \"\");\n const [css, setCss] = useState(data.css ?? \"\");\n const [caption, setCaption] = useState(data.caption ?? \"\");\n const [legacyJson, setLegacyJson] = useState(() =>\n JSON.stringify(\n {\n nodes: data.nodes ?? [],\n edges: data.edges ?? [],\n notes: data.notes ?? [],\n },\n null,\n 2,\n ),\n );\n\n useEffect(() => {\n setHtml(data.html ?? \"\");\n setCss(data.css ?? \"\");\n setCaption(data.caption ?? \"\");\n setLegacyJson(\n JSON.stringify(\n {\n nodes: data.nodes ?? [],\n edges: data.edges ?? [],\n notes: data.notes ?? [],\n },\n null,\n 2,\n ),\n );\n }, [data]);\n\n const saveHtmlDiagram = () => {\n onChange({\n html: html.trim() || undefined,\n css: css.trim() || undefined,\n caption: caption.trim() || undefined,\n nodes: data.nodes,\n edges: data.edges,\n notes: data.notes,\n });\n };\n\n const saveLegacyDiagram = () => {\n const parsed = JSON.parse(legacyJson) as Pick<\n DiagramData,\n \"nodes\" | \"edges\" | \"notes\"\n >;\n onChange({\n ...data,\n nodes: parsed.nodes ?? [],\n edges: parsed.edges ?? [],\n notes: parsed.notes ?? [],\n });\n };\n\n const fieldAction = (\n field: \"HTML / SVG fragment\" | \"CSS\" | \"caption\" | \"legacy node graph JSON\",\n value: string,\n ) => ({\n blockId,\n blockType: \"diagram\",\n blockTitle: title,\n blockSummary: summary,\n fieldValue: value,\n draftScope: `block:diagram:${blockId}:${field.toLowerCase().replace(/[^a-z0-9]+/g, \"-\")}`,\n disabled: !editable,\n instructions:\n \"Update the plan with update-visual-plan using a targeted update-block content patch for this diagram block id. Preserve unrelated diagram fields unless the requested edit requires changing them. Keep diagram HTML/CSS on renderer-owned .diagram-* primitives and --wf-* tokens; do not introduce custom font-family or hard-coded hex/rgb/hsl colors.\",\n companionFields: [\n {\n label: \"HTML / SVG fragment\",\n value: html.trim() || \"(empty)\",\n language: \"html\",\n },\n { label: \"CSS\", value: css.trim() || \"(empty)\", language: \"css\" },\n {\n label: \"caption\",\n value: caption.trim() || \"(empty)\",\n language: \"text\",\n },\n ],\n });\n\n return (\n <div className=\"grid gap-4\" data-plan-interactive>\n <button\n type=\"button\"\n className=\"inline-flex h-8 w-fit items-center justify-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground disabled:opacity-50\"\n disabled={!editable}\n onClick={saveHtmlDiagram}\n >\n Save diagram\n </button>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={htmlId}\n label=\"HTML / SVG fragment\"\n ctx={ctx}\n action={fieldAction(\"HTML / SVG fragment\", html)}\n />\n <textarea\n id={htmlId}\n className=\"min-h-48 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={html}\n disabled={!editable}\n onChange={(event) => setHtml(event.target.value)}\n placeholder=\"<div class='diagram'>...</div>\"\n />\n </div>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={cssId}\n label=\"CSS\"\n ctx={ctx}\n action={fieldAction(\"CSS\", css)}\n />\n <textarea\n id={cssId}\n className=\"min-h-32 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={css}\n disabled={!editable}\n onChange={(event) => setCss(event.target.value)}\n placeholder=\".diagram { display: grid; }\"\n />\n </div>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={captionId}\n label=\"Caption\"\n ctx={ctx}\n action={fieldAction(\"caption\", caption)}\n />\n <input\n id={captionId}\n className=\"h-9 w-full rounded-md border border-input bg-background px-3 text-sm text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={caption}\n disabled={!editable}\n onChange={(event) => setCaption(event.target.value)}\n />\n </div>\n {!data.html && (\n <details className=\"rounded-md border border-border p-3\">\n <summary className=\"cursor-pointer text-xs font-semibold text-muted-foreground\">\n Legacy node graph data\n </summary>\n <div className=\"group/field mt-3 grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={legacyId}\n label=\"JSON\"\n ctx={ctx}\n action={fieldAction(\"legacy node graph JSON\", legacyJson)}\n />\n <textarea\n id={legacyId}\n className=\"min-h-44 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={legacyJson}\n disabled={!editable}\n onChange={(event) => setLegacyJson(event.target.value)}\n />\n </div>\n <button\n type=\"button\"\n className=\"mt-3 inline-flex h-8 items-center justify-center rounded-md border border-input px-3 text-xs font-medium text-foreground disabled:opacity-50\"\n disabled={!editable}\n onClick={saveLegacyDiagram}\n >\n Save graph data\n </button>\n </details>\n )}\n </div>\n );\n}\n\n/** Full client spec for the shared `diagram` block (schema + MDX + Read/Edit). */\nexport const diagramBlock = defineBlock<DiagramData>({\n type: \"diagram\",\n schema: diagramSchema,\n mdx: diagramMdx,\n Read: DiagramRead,\n Edit: DiagramEdit,\n placement: [\"block\"],\n // Config-driven: the rendered diagram differs from its raw html/css source, so\n // edit from a corner button + panel rather than inline.\n editSurface: \"panel\",\n label: \"Diagram\",\n description:\n \"A flexible inline architecture/code diagram. Prefer html/css with SVG or semantic HTML for polished two-dimensional layouts; use .diagram-* primitives and --wf-* tokens for theme/sketch compatibility. Legacy nodes/edges are only for simple previews.\",\n // Seed the legacy fallback shape so a fresh block validates while agents can\n // replace it with html/css when layout quality matters.\n empty: () => ({ nodes: [{ id: \"n1\", label: \"Module\" }], edges: [] }),\n});\n"]}
|
|
1
|
+
{"version":3,"file":"diagram.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/diagram.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { IconArrowsMaximize, IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n} from \"../types.js\";\nimport { AiEditableFieldLabel } from \"../AiEditableField.js\";\nimport { RoughOverlay, useIsDark, useWireframeStyle } from \"./wireframe-kit.js\";\nimport {\n sanitizeDiagramHtml,\n sanitizeWireframeCss,\n scopeDesignCss,\n} from \"./sanitize-html.js\";\nimport {\n diagramMdx,\n diagramSchema,\n type DiagramData,\n type DiagramEdge,\n type DiagramNode,\n} from \"./diagram.config.js\";\n\n/**\n * Read + Edit renderers for the shared `diagram` block — a flexible inline\n * architecture/code diagram. The preferred authoring path is a scoped, inert\n * HTML/SVG fragment that leans on `.diagram-*` primitives and `--wf-*` tokens;\n * a legacy positional / sequence node-graph path is kept for older/simple plans.\n * Lives in core so any app can register it (it originated in the plan template).\n *\n * DECOUPLING from the plan original (mirrors the sibling `wireframe.tsx` port):\n * - Theme: `useIsDark()` reads `document.documentElement.classList` instead of\n * `next-themes`; `useWireframeStyle()` reads the viewer's sketchy/clean\n * preference from the shared `plan-wireframe-style` localStorage key — both\n * from `./wireframe-kit.js`, so core stays plan-free and shadcn-free.\n * - HTML sanitize: the HTML/SVG fragment + CSS run through the app-injected\n * `ctx.sanitizeHtml` at the render point (defense-in-depth against stored\n * XSS). Without a sanitizer wired, the HTML path emits nothing — core never\n * injects unsanitized author HTML. The React-free `diagramSchema` already\n * rejects active markup before storage.\n * - The rough.js sketch overlay reuses the kit's shared `RoughOverlay`, scoped\n * with the diagram selector and `drawFrame={false}` (the same call the plan\n * `HtmlDiagram` made). The `.plan-diagram-frame` / `.diagram-*` / `data-rough`\n * class contract is preserved exactly so the theme-token CSS in core's\n * `blocks.css` styles it in any app.\n *\n * The section carries the app-neutral `an-block` class plus the legacy\n * `plan-block` class so plan renders byte-identically while any other app gets\n * the theme-token treatment.\n */\n\n/* -------------------------------------------------------------------------- */\n/* HTML/SVG diagram path */\n/* -------------------------------------------------------------------------- */\n\n/** The rough-overlay selector for diagram bordered boxes (mirrors the plan). */\nconst DIAGRAM_ROUGH_SELECTOR =\n \"[data-rough],.diagram-panel,.diagram-node,.diagram-box,.diagram-pill,.diagram-card,[class*='card'],[class*='box'],[class*='panel'],[class*='pill'],[class*='chip'],[class*='badge'],hr\";\n\nfunction HtmlDiagram({\n data,\n ctx,\n compact,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const isDark = useIsDark();\n const style = useWireframeStyle();\n const scopeId = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n // Sanitize author HTML/CSS at the render point (defense-in-depth against\n // stored XSS). Self-contained in core via the shared block sanitizer (DOM-based\n // in the browser, regex fallback on the server) so diagrams render in any app\n // without the host wiring a sanitizer hook.\n const safeHtml = useMemo(() => sanitizeDiagramHtml(data.html), [data.html]);\n const scopedCss = useMemo(() => {\n const safeCss = sanitizeWireframeCss(data.css);\n // Scope every author selector under this diagram instance so global\n // selectors (body, *, .app-shell, :root) can't escape and restyle the page.\n return safeCss\n ? scopeDesignCss(safeCss, `[data-plan-diagram-scope=\"${scopeId}\"]`)\n : \"\";\n }, [data.css, scopeId]);\n\n return (\n <div\n ref={ref}\n className={cn(\"plan-diagram-shell\", compact && \"plan-diagram-compact\")}\n >\n <div\n className=\"plan-diagram-frame\"\n dir={ctx.textDirection}\n data-theme={isDark ? \"dark\" : \"light\"}\n data-style={style}\n data-text-direction={ctx.textDirection}\n data-plan-diagram-scope={scopeId}\n >\n {scopedCss && <style>{scopedCss}</style>}\n <div\n className=\"plan-diagram-frame-content\"\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n <RoughOverlay\n scopeRef={ref}\n enabled={style === \"sketchy\"}\n drawFrame={false}\n selector={DIAGRAM_ROUGH_SELECTOR}\n />\n {data.caption && !compact && (\n <p className=\"mt-3 text-sm leading-6 text-muted-foreground\">\n {data.caption}\n </p>\n )}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Legacy node-graph paths */\n/* -------------------------------------------------------------------------- */\n\nfunction clampDiagramPercent(value: number) {\n if (!Number.isFinite(value)) return 50;\n return Math.max(4, Math.min(96, value));\n}\n\nfunction hasPositionedDiagramNodes(data: DiagramData): boolean {\n return (data.nodes ?? []).some(\n (node) => typeof node.x === \"number\" && typeof node.y === \"number\",\n );\n}\n\nfunction orderDiagramNodes(\n nodes: DiagramNode[],\n edges: DiagramEdge[],\n): DiagramNode[] {\n if (nodes.length === 0) return [];\n const byId = new Map(nodes.map((node) => [node.id, node]));\n const indegree = new Map(nodes.map((node) => [node.id, 0]));\n for (const edge of edges) {\n if (byId.has(edge.from) && byId.has(edge.to)) {\n indegree.set(edge.to, (indegree.get(edge.to) ?? 0) + 1);\n }\n }\n const start = nodes.find((node) => (indegree.get(node.id) ?? 0) === 0);\n if (!start) return nodes;\n const ordered: DiagramNode[] = [];\n const seen = new Set<string>();\n let current: DiagramNode | undefined = start;\n while (current && !seen.has(current.id)) {\n const node: DiagramNode = current;\n ordered.push(node);\n seen.add(node.id);\n const next = edges.find((edge) => edge.from === node.id);\n current = next ? byId.get(next.to) : undefined;\n }\n for (const node of nodes) if (!seen.has(node.id)) ordered.push(node);\n return ordered;\n}\n\nfunction PositionedDiagram({\n data,\n compact,\n markerId,\n direction,\n}: {\n data: DiagramData;\n compact?: boolean;\n markerId: string;\n direction?: BlockRenderContext[\"textDirection\"];\n}) {\n const nodes = (data.nodes ?? []).map((node) => ({\n ...node,\n x: clampDiagramPercent(node.x ?? 50),\n y: clampDiagramPercent(node.y ?? 50),\n }));\n const edges = data.edges ?? [];\n const arrowId = `${markerId}-diagram-arrow`;\n const nodeWidth = compact ? 150 : 190;\n const rows = diagramRows(nodes, compact);\n const canvasHeight = diagramCanvasHeight(rows.length, compact);\n const canvasMinWidth = compact ? 560 : 720;\n const nodeWidthPct = compact ? 20 : 18;\n const nodeHeightPct = compact ? 14 : 18;\n const paddedViewBox = diagramViewBox(nodes, nodeWidthPct, nodeHeightPct);\n const xMargin = compact ? 13 : 14;\n const yMargin = compact ? 15 : 18;\n const displayNodes = nodes.map((node) => ({\n ...node,\n displayXBase: diagramPointPercent(\n node.x,\n paddedViewBox.x,\n paddedViewBox.width,\n xMargin,\n ),\n displayY: diagramRowPointPercent(node.y, rows, paddedViewBox, yMargin),\n }));\n const displayNodesForDirection = displayNodes.map((node) => ({\n ...node,\n displayX: direction === \"rtl\" ? 100 - node.displayXBase : node.displayXBase,\n }));\n const nodeByIdForDirection = new Map(\n displayNodesForDirection.map((node) => [node.id, node]),\n );\n\n return (\n <div\n className=\"plan-sketch rounded-[16px] border border-border bg-muted p-5\"\n dir={direction}\n data-text-direction={direction}\n >\n <div\n className=\"overflow-auto rounded-xl border border-border bg-background\"\n style={{ minHeight: canvasHeight }}\n >\n <div\n className=\"relative\"\n style={{ minHeight: canvasHeight, minWidth: canvasMinWidth }}\n >\n <svg\n className=\"pointer-events-none absolute inset-0 z-0 h-full w-full\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <defs>\n <marker\n id={arrowId}\n viewBox=\"0 0 10 10\"\n refX=\"8\"\n refY=\"5\"\n markerWidth=\"5\"\n markerHeight=\"5\"\n orient=\"auto-start-reverse\"\n >\n <path\n d=\"M 0 0 L 10 5 L 0 10 z\"\n className=\"fill-muted-foreground\"\n />\n </marker>\n </defs>\n {edges.map((edge, index) => {\n const from = nodeByIdForDirection.get(edge.from);\n const to = nodeByIdForDirection.get(edge.to);\n if (!from || !to) return null;\n return (\n <line\n key={`${edge.from}-${edge.to}-${index}`}\n x1={from.displayX}\n y1={from.displayY}\n x2={to.displayX}\n y2={to.displayY}\n markerEnd={`url(#${arrowId})`}\n vectorEffect=\"non-scaling-stroke\"\n className=\"stroke-border\"\n strokeWidth={2}\n strokeDasharray={edge.label ? \"0\" : \"6 5\"}\n />\n );\n })}\n </svg>\n\n {!compact &&\n edges.map((edge, index) => {\n const from = nodeByIdForDirection.get(edge.from);\n const to = nodeByIdForDirection.get(edge.to);\n if (!edge.label || !from || !to) return null;\n return (\n <span\n key={`${edge.from}-${edge.to}-${index}-label`}\n className=\"absolute z-10 max-w-[130px] -translate-x-1/2 -translate-y-1/2 rounded-full border border-border bg-background px-2 py-0.5 text-center text-[11px] font-semibold text-muted-foreground shadow-sm\"\n style={{\n left: `${(from.displayX + to.displayX) / 2}%`,\n top: `${(from.displayY + to.displayY) / 2}%`,\n }}\n >\n {edge.label}\n </span>\n );\n })}\n\n {displayNodesForDirection.map((node, index) => (\n <article\n key={node.id}\n className=\"absolute z-20 -translate-x-1/2 -translate-y-1/2 rounded-xl border-2 border-border bg-background p-3 text-foreground shadow-sm\"\n style={{\n left: `${node.displayX}%`,\n top: `${node.displayY}%`,\n width: nodeWidth,\n }}\n >\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {index + 1}\n </p>\n <h3 className=\"mt-2 text-base font-semibold leading-tight\">\n {node.label}\n </h3>\n {node.detail && !compact && (\n <p className=\"mt-2 text-xs leading-5 text-muted-foreground\">\n {node.detail}\n </p>\n )}\n </article>\n ))}\n </div>\n </div>\n {data.notes && data.notes.length > 0 && !compact && (\n <div className=\"mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2\">\n {data.notes.map((note) => (\n <p key={note.id}>{note.text}</p>\n ))}\n </div>\n )}\n </div>\n );\n}\n\ntype DiagramViewBox = {\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nfunction diagramViewBox(\n nodes: Array<Pick<DiagramNode, \"x\" | \"y\">>,\n nodeWidthPct: number,\n nodeHeightPct: number,\n): DiagramViewBox {\n if (nodes.length === 0) return { x: 0, y: 0, width: 100, height: 100 };\n\n const halfWidth = nodeWidthPct / 2;\n const halfHeight = nodeHeightPct / 2;\n const left = Math.min(...nodes.map((node) => (node.x ?? 50) - halfWidth));\n const right = Math.max(...nodes.map((node) => (node.x ?? 50) + halfWidth));\n const top = Math.min(...nodes.map((node) => (node.y ?? 50) - halfHeight));\n const bottom = Math.max(...nodes.map((node) => (node.y ?? 50) + halfHeight));\n\n const x = Math.min(0, left);\n const y = Math.min(0, top);\n const width = Math.max(100, right) - x;\n const height = Math.max(100, bottom) - y;\n\n return { x, y, width, height };\n}\n\nfunction diagramPointPercent(\n value: number,\n viewBoxStart: number,\n viewBoxSize: number,\n margin = 0,\n): number {\n if (\n !Number.isFinite(value) ||\n !Number.isFinite(viewBoxSize) ||\n !viewBoxSize\n ) {\n return 50;\n }\n const percent = ((value - viewBoxStart) / viewBoxSize) * 100;\n return Math.min(100 - margin, Math.max(margin, percent));\n}\n\nfunction diagramRows(\n nodes: Array<Pick<DiagramNode, \"y\">>,\n compact?: boolean,\n): number[] {\n const rowGap = compact ? 8 : 10;\n return [...nodes]\n .sort((a, b) => (a.y ?? 50) - (b.y ?? 50))\n .reduce<number[]>((acc, node) => {\n const y = node.y ?? 50;\n const last = acc[acc.length - 1];\n if (last == null || Math.abs(y - last) >= rowGap) acc.push(y);\n return acc;\n }, []);\n}\n\nfunction diagramRowPointPercent(\n value: number,\n rows: number[],\n viewBox: DiagramViewBox,\n margin: number,\n): number {\n if (rows.length <= 2) {\n return diagramPointPercent(value, viewBox.y, viewBox.height, margin);\n }\n const closestIndex = rows.reduce((bestIndex, row, index) => {\n const bestDistance = Math.abs((rows[bestIndex] ?? 50) - value);\n return Math.abs(row - value) < bestDistance ? index : bestIndex;\n }, 0);\n const span = 100 - margin * 2;\n return margin + (span * closestIndex) / Math.max(1, rows.length - 1);\n}\n\nfunction diagramCanvasHeight(rows: number, compact?: boolean): number {\n const base = compact ? 280 : 430;\n if (rows <= 2) return base;\n return Math.max(base, rows * (compact ? 140 : 190) + (compact ? 80 : 120));\n}\n\nfunction SequenceDiagram({\n data,\n compact,\n direction,\n}: {\n data: DiagramData;\n compact?: boolean;\n direction?: BlockRenderContext[\"textDirection\"];\n}) {\n const edges = data.edges ?? [];\n const nodes = orderDiagramNodes(data.nodes ?? [], edges);\n if (nodes.length === 0) {\n return (\n <div className=\"rounded-[12px] border border-border bg-muted p-4 text-sm text-muted-foreground\">\n Diagram content is empty.\n </div>\n );\n }\n const visualNodes = direction === \"rtl\" ? [...nodes].reverse() : nodes;\n return (\n <div\n className=\"plan-sketch rounded-[16px] border border-border bg-muted p-5\"\n dir={direction}\n data-text-direction={direction}\n >\n <div\n className={cn(\n \"flex gap-3 overflow-x-auto pb-2\",\n compact ? \"items-center\" : \"items-stretch\",\n )}\n >\n {visualNodes.map((node, index) => {\n const next = visualNodes[index + 1];\n const edge = next\n ? edges.find(\n (candidate) =>\n (candidate.from === node.id && candidate.to === next.id) ||\n (candidate.from === next.id && candidate.to === node.id),\n )\n : undefined;\n return (\n <div key={node.id} className=\"flex min-w-max items-center gap-3\">\n <article\n className={cn(\n \"w-[180px] rounded-xl border-2 border-border bg-background p-3 text-foreground\",\n compact && \"w-[150px]\",\n )}\n >\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {index + 1}\n </p>\n <h3 className=\"mt-2 text-base font-semibold leading-tight\">\n {node.label}\n </h3>\n {node.detail && !compact && (\n <p className=\"mt-2 text-xs leading-5 text-muted-foreground\">\n {node.detail}\n </p>\n )}\n </article>\n {next && (\n <div className=\"grid min-w-[72px] justify-items-center gap-1 text-muted-foreground\">\n {edge?.label && (\n <span className=\"max-w-[96px] truncate rounded-full border border-border px-2 py-0.5 text-[11px] font-semibold\">\n {edge.label}\n </span>\n )}\n <span className=\"h-0.5 w-full rounded-full border-t-2 border-dashed border-border\" />\n </div>\n )}\n </div>\n );\n })}\n </div>\n {data.notes && data.notes.length > 0 && !compact && (\n <div className=\"mt-4 grid gap-2 border-t border-border pt-4 text-sm text-muted-foreground md:grid-cols-2\">\n {data.notes.map((note) => (\n <p key={note.id}>{note.text}</p>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * The diagram body. Routes to the preferred HTML/SVG path (when `data.html` is\n * set) and otherwise to a legacy node-graph path (positioned canvas when nodes\n * carry x/y, else an ordered sequence). Used both inline and, scaled up, inside\n * the expand lightbox — so every variant (html/css, positioned, sequence)\n * enlarges through the same code path.\n */\nfunction DiagramBody({\n data,\n ctx,\n compact,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const markerId = useId().replace(/:/g, \"\");\n if (data.html?.trim()) {\n return <HtmlDiagram data={data} ctx={ctx} compact={compact} />;\n }\n if (hasPositionedDiagramNodes(data)) {\n return (\n <PositionedDiagram\n data={data}\n compact={compact}\n markerId={markerId}\n direction={ctx.textDirection}\n />\n );\n }\n return (\n <SequenceDiagram\n data={data}\n compact={compact}\n direction={ctx.textDirection}\n />\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Expand / lightbox */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Enlarge overlay for a rendered diagram. Mirrors the image lightbox contract\n * used by the composer's `ImagePreviewLightbox` (PromptComposer.tsx) so the\n * expand affordance feels identical to viewing an image full-size: a fixed\n * `bg-black/80` backdrop, Escape to close, click-the-backdrop to close, and a\n * top-right close button. Unlike the image variant this renders arbitrary\n * children (the diagram body re-rendered larger) rather than an `<img>`, since a\n * diagram is live HTML/SVG/node-graph markup, not an image URL.\n *\n * Exported so the separate Mermaid block (`MermaidBlock.tsx`, which renders its\n * diagram to an SVG through a different runtime) can reuse the exact same\n * lightbox contract — one expand affordance shared across both diagram types.\n */\nexport function DiagramLightbox({\n children,\n onClose,\n}: {\n children: React.ReactNode;\n onClose: () => void;\n}) {\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n document.body.style.overflow = \"hidden\";\n return () => {\n document.removeEventListener(\"keydown\", handler);\n document.body.style.overflow = \"\";\n };\n }, [onClose]);\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Diagram preview\"\n onClick={onClose}\n data-plan-interactive\n className=\"fixed inset-0 z-[300] flex items-center justify-center overflow-auto bg-black/80 p-6 cursor-zoom-out\"\n >\n <div\n onClick={(e) => e.stopPropagation()}\n className=\"max-h-full w-full max-w-5xl cursor-default overflow-auto rounded-md bg-background p-6 shadow-2xl\"\n >\n {children}\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close preview\"\n className=\"absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60\"\n >\n <IconX className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n\n/**\n * The diagram body plus a hover-revealed top-right \"expand\" button (like the\n * image attachment zoom). Opening the button re-renders the exact same\n * `DiagramBody` inside `DiagramLightbox` at a larger size, so html/css and\n * mermaid/legacy node-graph diagrams alike enlarge through one path. The inline\n * (non-expanded) render is otherwise unchanged.\n */\nfunction ExpandableDiagramBody({\n data,\n ctx,\n}: {\n data: DiagramData;\n ctx: BlockRenderContext;\n}) {\n const [expanded, setExpanded] = useState(false);\n return (\n <div className=\"group/diagram relative\">\n <DiagramBody data={data} ctx={ctx} />\n <button\n type=\"button\"\n data-plan-interactive\n onClick={() => setExpanded(true)}\n aria-label=\"Expand diagram\"\n title=\"Expand diagram\"\n className=\"an-diagram-expand-trigger absolute right-2 top-2 z-10 flex size-7 items-center justify-center rounded-md border border-border/60 bg-background/90 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover/diagram:opacity-100\"\n >\n <IconArrowsMaximize className=\"size-4\" />\n </button>\n {expanded ? (\n <DiagramLightbox onClose={() => setExpanded(false)}>\n <DiagramBody data={data} ctx={ctx} />\n </DiagramLightbox>\n ) : null}\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Read + Edit */\n/* -------------------------------------------------------------------------- */\n\n/** Read-only renderer: the diagram body wrapped in the standard titled block. */\nexport function DiagramRead({\n data,\n blockId,\n title,\n summary,\n ctx,\n}: BlockReadProps<DiagramData>) {\n return (\n <section className=\"an-block plan-block\" data-block-id={blockId}>\n {title && <div className=\"an-block-label plan-block-label\">{title}</div>}\n <ExpandableDiagramBody data={data} ctx={ctx} />\n {summary && <p className=\"mt-5 text-muted-foreground\">{summary}</p>}\n </section>\n );\n}\n\n/**\n * Edit form (panel surface). The block can be an HTML/SVG fragment or a legacy\n * node/edge/note graph, so this exposes html/css/caption plus a collapsible\n * legacy node-graph JSON editor, each with an AI-edit affordance via\n * `ctx.renderAiFieldAction` (through `AiEditableFieldLabel`). `editSurface:\n * \"panel\"` means the registry renders the `Read` view with a corner edit button\n * that opens this form in the app-provided popover.\n */\nexport function DiagramEdit({\n data,\n onChange,\n editable,\n blockId,\n title,\n summary,\n ctx,\n}: BlockEditProps<DiagramData>) {\n const htmlId = useId();\n const cssId = useId();\n const captionId = useId();\n const legacyId = useId();\n const [html, setHtml] = useState(data.html ?? \"\");\n const [css, setCss] = useState(data.css ?? \"\");\n const [caption, setCaption] = useState(data.caption ?? \"\");\n const [legacyJson, setLegacyJson] = useState(() =>\n JSON.stringify(\n {\n nodes: data.nodes ?? [],\n edges: data.edges ?? [],\n notes: data.notes ?? [],\n },\n null,\n 2,\n ),\n );\n\n useEffect(() => {\n setHtml(data.html ?? \"\");\n setCss(data.css ?? \"\");\n setCaption(data.caption ?? \"\");\n setLegacyJson(\n JSON.stringify(\n {\n nodes: data.nodes ?? [],\n edges: data.edges ?? [],\n notes: data.notes ?? [],\n },\n null,\n 2,\n ),\n );\n }, [data]);\n\n const saveHtmlDiagram = () => {\n onChange({\n html: html.trim() || undefined,\n css: css.trim() || undefined,\n caption: caption.trim() || undefined,\n nodes: data.nodes,\n edges: data.edges,\n notes: data.notes,\n });\n };\n\n const saveLegacyDiagram = () => {\n const parsed = JSON.parse(legacyJson) as Pick<\n DiagramData,\n \"nodes\" | \"edges\" | \"notes\"\n >;\n onChange({\n ...data,\n nodes: parsed.nodes ?? [],\n edges: parsed.edges ?? [],\n notes: parsed.notes ?? [],\n });\n };\n\n const fieldAction = (\n field: \"HTML / SVG fragment\" | \"CSS\" | \"caption\" | \"legacy node graph JSON\",\n value: string,\n ) => ({\n blockId,\n blockType: \"diagram\",\n blockTitle: title,\n blockSummary: summary,\n fieldValue: value,\n draftScope: `block:diagram:${blockId}:${field.toLowerCase().replace(/[^a-z0-9]+/g, \"-\")}`,\n disabled: !editable,\n instructions:\n \"Update the plan with update-visual-plan using a targeted update-block content patch for this diagram block id. Preserve unrelated diagram fields unless the requested edit requires changing them. Keep diagram HTML/CSS on renderer-owned .diagram-* primitives and --wf-* tokens; do not introduce custom font-family or hard-coded hex/rgb/hsl colors.\",\n companionFields: [\n {\n label: \"HTML / SVG fragment\",\n value: html.trim() || \"(empty)\",\n language: \"html\",\n },\n { label: \"CSS\", value: css.trim() || \"(empty)\", language: \"css\" },\n {\n label: \"caption\",\n value: caption.trim() || \"(empty)\",\n language: \"text\",\n },\n ],\n });\n\n return (\n <div className=\"grid gap-4\" data-plan-interactive>\n <button\n type=\"button\"\n className=\"inline-flex h-8 w-fit items-center justify-center rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground disabled:opacity-50\"\n disabled={!editable}\n onClick={saveHtmlDiagram}\n >\n Save diagram\n </button>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={htmlId}\n label=\"HTML / SVG fragment\"\n ctx={ctx}\n action={fieldAction(\"HTML / SVG fragment\", html)}\n />\n <textarea\n id={htmlId}\n className=\"min-h-48 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={html}\n disabled={!editable}\n onChange={(event) => setHtml(event.target.value)}\n placeholder=\"<div class='diagram'>...</div>\"\n />\n </div>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={cssId}\n label=\"CSS\"\n ctx={ctx}\n action={fieldAction(\"CSS\", css)}\n />\n <textarea\n id={cssId}\n className=\"min-h-32 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={css}\n disabled={!editable}\n onChange={(event) => setCss(event.target.value)}\n placeholder=\".diagram { display: grid; }\"\n />\n </div>\n <div className=\"group/field grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={captionId}\n label=\"Caption\"\n ctx={ctx}\n action={fieldAction(\"caption\", caption)}\n />\n <input\n id={captionId}\n className=\"h-9 w-full rounded-md border border-input bg-background px-3 text-sm text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={caption}\n disabled={!editable}\n onChange={(event) => setCaption(event.target.value)}\n />\n </div>\n {!data.html && (\n <details className=\"rounded-md border border-border p-3\">\n <summary className=\"cursor-pointer text-xs font-semibold text-muted-foreground\">\n Legacy node graph data\n </summary>\n <div className=\"group/field mt-3 grid gap-1.5\">\n <AiEditableFieldLabel\n htmlFor={legacyId}\n label=\"JSON\"\n ctx={ctx}\n action={fieldAction(\"legacy node graph JSON\", legacyJson)}\n />\n <textarea\n id={legacyId}\n className=\"min-h-44 w-full rounded-md border border-input bg-background px-3 py-2 font-mono text-xs leading-5 text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={legacyJson}\n disabled={!editable}\n onChange={(event) => setLegacyJson(event.target.value)}\n />\n </div>\n <button\n type=\"button\"\n className=\"mt-3 inline-flex h-8 items-center justify-center rounded-md border border-input px-3 text-xs font-medium text-foreground disabled:opacity-50\"\n disabled={!editable}\n onClick={saveLegacyDiagram}\n >\n Save graph data\n </button>\n </details>\n )}\n </div>\n );\n}\n\n/** Full client spec for the shared `diagram` block (schema + MDX + Read/Edit). */\nexport const diagramBlock = defineBlock<DiagramData>({\n type: \"diagram\",\n schema: diagramSchema,\n mdx: diagramMdx,\n Read: DiagramRead,\n Edit: DiagramEdit,\n placement: [\"block\"],\n // Config-driven: the rendered diagram differs from its raw html/css source, so\n // edit from a corner button + panel rather than inline.\n editSurface: \"panel\",\n label: \"Diagram\",\n description:\n \"A flexible inline architecture/code diagram. Prefer html/css with SVG or semantic HTML for polished two-dimensional layouts; use .diagram-* primitives and --wf-* tokens for theme/sketch compatibility. Legacy nodes/edges are only for simple previews.\",\n // Seed the legacy fallback shape so a fresh block validates while agents can\n // replace it with html/css when layout quality matters.\n empty: () => ({ nodes: [{ id: \"n1\", label: \"Module\" }], edges: [] }),\n});\n"]}
|
|
@@ -82,6 +82,8 @@ export interface BlockMdxConfig<TData> {
|
|
|
82
82
|
export interface BlockRenderContext {
|
|
83
83
|
/** Markdown dialect for the auto-editor's rich-text field. */
|
|
84
84
|
dialect?: "gfm" | "nfm";
|
|
85
|
+
/** Document text direction inferred by the host app. */
|
|
86
|
+
textDirection?: "ltr" | "rtl";
|
|
85
87
|
/** Resolve an asset id → displayable URL. */
|
|
86
88
|
resolveAssetSrc?: (assetId: string) => string | undefined;
|
|
87
89
|
/** Open the shared asset picker (returns the chosen asset). */
|