import { defineAction } from "@agent-native/core"; import { readAppStateForCurrentTab } from "@agent-native/core/application-state"; import { accessFilter, assertAccess } from "@agent-native/core/sharing"; import { and, eq } from "drizzle-orm"; import { z } from "zod"; import { getDb, schema } from "../server/db/index.js"; import { readLiveSourceFile, writeInlineSourceFile, type SourceWorkspaceFile, } from "../server/source-workspace.js"; const schemaInput = z.object({ assetUrl: z .string() .url() .refine((value) => { try { const protocol = new URL(value).protocol; return protocol === "http:" || protocol === "https:"; } catch { return false; } }, "Asset URL must use http or https.") .describe("Chosen asset image/video URL."), assetId: z.string().optional().describe("Chosen Assets asset id."), title: z.string().optional().describe("Human-readable asset title."), altText: z.string().optional().describe("Alt text for an image asset."), mediaType: z.enum(["image", "video"]).default("image"), designId: z .string() .optional() .describe("Design id. Defaults to the current editor navigation state."), fileId: z .string() .optional() .describe("Design file id. Defaults to the active editor file."), ownerId: z .string() .optional() .describe("Design editor selection owner token from current screen state."), targetNodeId: z .string() .optional() .describe( "data-agent-native-node-id of an existing element to target. Required " + 'for mode "replace-src" and "background-fill". Ignored for the ' + 'default "figure" mode.', ), mode: z .enum(["figure", "replace-src", "background-fill"]) .optional() .default("figure") .describe( 'How to place the asset. "figure" (default) appends a new figure/section ' + "at the end of the file, styled with the design's own tokens — use " + 'this when there is no existing element to target. "replace-src" sets ' + "the src of the /