diff --git a/apps/docs/content/docs/ai/agent-workflow.mdx b/apps/docs/content/docs/ai/agent-workflow.mdx index 22d90eac..c922547c 100644 --- a/apps/docs/content/docs/ai/agent-workflow.mdx +++ b/apps/docs/content/docs/ai/agent-workflow.mdx @@ -3,24 +3,17 @@ title: Agent Workflow description: How ProofKit closes the loop for coding agents building FileMaker apps. --- -import { Callout } from "fumadocs-ui/components/callout"; +import { AgentWorkflowLoop } from "@/components/AgentWorkflowLoop"; ProofKit is designed for agents that can do more than produce snippets. The workflow gives the agent real FileMaker context, a project it can edit, and feedback it can use to fix mistakes. ## The loop -```mermaid -flowchart LR - readSchema["Read FileMaker schema"] --> writeCode["Write app code"] - writeCode --> runChecks["Run typecheck and lint"] - runChecks --> previewApp["Preview in browser"] - previewApp --> fixIssues["Fix issues"] - fixIssues --> deployApp["Deploy to FileMaker"] - fixIssues --> writeCode -``` + ## What each step needs +- **Next change**: the user asks for a new screen, behavior, or refinement. - **Read FileMaker schema**: the MCP server exposes file metadata and data context to the agent. - **Write app code**: the agent edits a normal web project using React, TypeScript, Tailwind, and shadcn/ui. - **Run checks**: TypeGen and TypeScript catch many schema and field-name mistakes before runtime. @@ -28,10 +21,6 @@ flowchart LR - **Fix issues**: errors, screenshots, and build output become feedback for the next edit. - **Deploy to FileMaker**: the final bundle is pushed into the file and loaded by the Web Viewer. - - Replace or polish the Mermaid diagram with the final agent workflow visual if a branded SVG or React component is created. - - ## Why this matters Without the loop, you are usually copying FileMaker metadata into a chat, pasting code back into a project, discovering errors manually, and asking the model to try again. ProofKit gives the agent enough context and feedback to handle more of that cycle directly. diff --git a/apps/docs/content/docs/ai/build-a-webviewer-app.mdx b/apps/docs/content/docs/ai/build-a-webviewer-app.mdx index f82b02d3..851cd428 100644 --- a/apps/docs/content/docs/ai/build-a-webviewer-app.mdx +++ b/apps/docs/content/docs/ai/build-a-webviewer-app.mdx @@ -3,7 +3,6 @@ title: Build a Web Viewer App description: Scaffold and iterate on a FileMaker Web Viewer app with your coding agent. --- -import { Callout } from "fumadocs-ui/components/callout"; import { Step, Steps } from "fumadocs-ui/components/steps"; After ProofKit is connected and your agent understands the file, switch from exploration to building. The goal is a local web project that previews in the browser and can later be deployed into FileMaker. @@ -14,23 +13,39 @@ After ProofKit is connected and your agent understands the file, switch from exp **Ask the agent to scaffold a Web Viewer project.** + Open your coding agent, such as Cursor, Claude Code, Codex, OpenCode, or another MCP-compatible agent, in an empty project folder before you start. + + Copy this prompt into your agent: + + ```text title="Prompt" + Set up a ProofKit Web Viewer project in this folder. + ``` + The project should use the ProofKit CLI and the current ProofKit stack: React, TypeScript, Vite, Tailwind, shadcn/ui, TanStack Query, and TypeGen. **Run the local preview.** - The agent should start the dev server and open the app in a browser so it can inspect the result. + The agent should start the dev server and open the app in a browser so it can inspect the result. Agents also have embedded browsers, so they can inspect the result without leaving the agentic loop. If the agent doesn't open a browser, ask it to use it's preview browser. - - Capture the generated Web Viewer app running locally in a browser with FileMaker-backed data visible. - + ```text title="Prompt" + Use your embedded browser or preview browser to inspect and monitor your work. + ``` **Ask for a specific screen.** Start with one workflow: a dashboard, detail view, calendar, kanban board, rich form, or data grid. + + ```text title="Prompt" + Build a customer viewer with a searchable list view. + ``` + + ![Local preview of a generated ProofKit Web Viewer app showing FileMaker-backed customer data.](/screenshots/ai/local-preview-filemaker-webviewer.png) + + _After you ask the agent to build a screen, the desktop session can look like this: agent messages on the left and an embedded browser preview on the right, showing FileMaker data from the connected FileMaker file._ @@ -40,21 +55,19 @@ After ProofKit is connected and your agent understands the file, switch from exp -## Prompt shape - -```text -Build a ProofKit Web Viewer screen for the Contacts workflow. -Use the FileMaker layouts and fields you discovered earlier. -Start with a read-only list and detail view, then run checks and preview it in the browser. -``` - ## Style and theme ProofKit projects use shadcn/ui and Tailwind, so the agent can apply a theme or preset by editing normal project files. - - Capture a before/after of a generated screen after applying a shadcn/ui preset or branded theme. - +Use [shadcn/ui Create](https://ui.shadcn.com/create?) to explore visual presets. Copy a preset code, then ask your agent to apply it to the project to quickly change colors, typography, icons, and component styling. + +```text title="Prompt" +Apply this shadcn/ui preset to the project: +``` + +![The same generated customer viewer after applying a different visual preset.](/screenshots/ai/theme-preset-filemaker-webviewer.png) + +_The same generated screen after applying a different preset, with updated colors, typography, and corner radiuses._ ## Reference docs diff --git a/apps/docs/content/docs/ai/deploy-to-filemaker.mdx b/apps/docs/content/docs/ai/deploy-to-filemaker.mdx index 15ac6211..e5c1b8c5 100644 --- a/apps/docs/content/docs/ai/deploy-to-filemaker.mdx +++ b/apps/docs/content/docs/ai/deploy-to-filemaker.mdx @@ -3,32 +3,45 @@ title: Deploy to FileMaker description: Bundle your Web Viewer app and deploy it into a FileMaker file. --- -import { Callout } from "fumadocs-ui/components/callout"; import { Step, Steps } from "fumadocs-ui/components/steps"; Deployment for a ProofKit Web Viewer app means bundling the web app and storing it in your FileMaker file so it can load inside a Web Viewer layout. This is different from deploying a browser app to a hosting provider. The deployed artifact is HTML and JavaScript living in the FileMaker file. +## Ask the agent to deploy + +Once the app works locally and FileMaker is connected to ProofKit, you can ask the agent to handle deployment for you: + +```text title="Prompt" +Deploy the app to my connected file maker file. +``` + +The agent should treat deployment as a release step, not just a file copy. It should run available checks, build the production bundle, deploy the generated HTML through ProofKit, and then verify the result inside FileMaker. + +Because `deploy_html` writes the bundled app into the connected FileMaker file, only run it against the file you mean to update. If users are connected to a production file, they may see the change immediately, so prefer a development file or a controlled deployment window. Most MCP clients let you disable tools or toggle automatic prompting for individual tools; keep deployment approval on unless you are intentionally working in a safe dev environment. + ## Deploy the app +When you ask the agent to deploy the app, it should run through these steps for you. The final verification step is the one you should review yourself inside FileMaker. + **Run checks before deployment.** - Ask the agent to run the project checks it has available, such as typechecking, linting, and a production build. + The agent runs the project checks it has available, such as typechecking, linting, and a production build. **Bundle the Web Viewer app.** - The project build should produce a deployable single-file bundle for the FileMaker Web Viewer. + The agent builds the project into a deployable single-file bundle for the FileMaker Web Viewer. **Deploy through ProofKit.** - ProofKit sends the bundle through the local bridge and stores it in the FileMaker file. + The agent uses ProofKit to send the bundle through the local bridge and store it in the FileMaker file. @@ -36,9 +49,9 @@ This is different from deploying a browser app to a hosting provider. The deploy Navigate to the Web Viewer layout and confirm the deployed app loads with real data. - - Capture the finished app running inside a FileMaker Web Viewer layout. - + ![A deployed ProofKit dashboard running inside a FileMaker Web Viewer layout.](/screenshots/ai/deployed-filemaker-webviewer.png) + + _A deployed ProofKit app running inside FileMaker, with FileMaker's layout chrome around the Web Viewer and live FileMaker data rendered in the dashboard._ diff --git a/apps/docs/content/docs/ai/getting-started.mdx b/apps/docs/content/docs/ai/getting-started.mdx index 1155c482..6d106761 100644 --- a/apps/docs/content/docs/ai/getting-started.mdx +++ b/apps/docs/content/docs/ai/getting-started.mdx @@ -14,7 +14,9 @@ This guide is the happy path for ProofKit v2. It mirrors the planned video serie ## Before you start -You need FileMaker Pro, Node.js LTS, and an MCP-compatible coding agent such as Cursor, Claude Code, Codex, OpenCode, or another agent that can use MCP servers. +You need FileMaker Pro, a supported Node.js LTS release, and an MCP-compatible coding agent such as Cursor, Claude Code, Codex, OpenCode, or another agent that can use MCP servers. + +For Node.js, choose a release that is explicitly marked LTS. Today that means **Node.js 22**, **Node.js 24**, or **Node.js 26**. If you are setting up Node for the first time, start with the [official Node.js download page](https://nodejs.org/en/download/). See [Technical Requirements](/docs/ai/technical-requirements) for the full support matrix. diff --git a/apps/docs/content/docs/ai/technical-requirements.mdx b/apps/docs/content/docs/ai/technical-requirements.mdx index 4e444044..0e5ce6d9 100644 --- a/apps/docs/content/docs/ai/technical-requirements.mdx +++ b/apps/docs/content/docs/ai/technical-requirements.mdx @@ -3,6 +3,8 @@ title: Technical Requirements description: What you need to build and run ProofKit v2 apps. --- +import { Tab, Tabs } from "fumadocs-ui/components/tabs"; + ProofKit v2 is designed for FileMaker developers using agentic coding tools to build Web Viewer apps. ## FileMaker version @@ -16,11 +18,52 @@ Future ProofKit releases will track the next major FileMaker release cycle so Pr To build ProofKit apps, you need: - **FileMaker Pro** with the target file open. -- **Node.js LTS** installed locally. +- **Node.js LTS** installed locally. Choose a release that is explicitly marked LTS. Today that means **Node.js 22**, **Node.js 24**, or **Node.js 26**. - **An MCP-compatible coding agent**, such as Cursor, Claude Code, Codex, OpenCode, or another agent that supports MCP servers. FileMaker Server is not required for the development loop. ProofKit can work against a local or hosted file as long as it is open in FileMaker Pro. +## Node.js + +ProofKit projects use Node.js for the local development tools that scaffold, build, preview, and deploy Web Viewer apps. Pick an LTS release rather than the newest "Current" release. Node's odd-numbered releases are short-lived, and not every even-numbered release is the right choice forever; use a version that [nodejs.org marks as LTS](https://nodejs.org/en/download/). + +If you are not already managing Node versions, the native installer from nodejs.org is the simplest option. + + + + Download the LTS installer for macOS or Windows from [nodejs.org/download](https://nodejs.org/en/download/). Choose Node.js 26 LTS when available, or Node.js 24 LTS or Node.js 22 LTS if your environment standardizes on one of those versions. + + After installing, verify the version: + + ```sh + node -v + npm -v + ``` + + + + On macOS, Homebrew is convenient if you already use it. Install a versioned LTS formula instead of the unversioned `node` formula, which may track a newer non-LTS release. + + ```sh + brew install node@24 + node -v + ``` + + If `node` is not found after installation, run `brew info node@24` and follow Homebrew's PATH instructions. + + + + Use a version manager if you switch between projects with different Node requirements. + + ```sh + nvm install --lts + nvm use --lts + ``` + + `fnm` and Volta are good alternatives. The important part is pinning your project to an LTS line such as Node.js 26, Node.js 24, or Node.js 22. + + + ## Developer background You do not need to be a web developer to get started. Familiarity with React, TypeScript, a terminal, and Git will help, but the workflow is designed so the agent does much of the setup and implementation work. @@ -51,7 +94,7 @@ ProofKit v2 enables agentic coding of Web Viewer apps. It does not currently ena | --- | --- | | FileMaker version | FileMaker 22 or greater | | Agent environment | Any MCP-compatible agent | -| Development requirements | FileMaker Pro and Node.js LTS | +| Development requirements | FileMaker Pro and Node.js 22, 24, or 26 LTS | | FileMaker Server | Not required for local development | | Runtime platforms | FileMaker Pro, FileMaker Go, WebDirect | | Agent writing scope | Web Viewer app code | diff --git a/apps/docs/content/docs/webviewer/architecture.mdx b/apps/docs/content/docs/webviewer/architecture.mdx index 67e4937a..e9b8bdee 100644 --- a/apps/docs/content/docs/webviewer/architecture.mdx +++ b/apps/docs/content/docs/webviewer/architecture.mdx @@ -10,7 +10,7 @@ ProofKit has two related architectures: the development loop that lets an agent ## Development architecture ```mermaid -flowchart LR +flowchart TD agent["Coding agent"] <-->|"MCP"| mcp["ProofKit MCP server"] mcp <-->|"Local API"| plugin["FileMaker plug-in"] plugin <-->|"Script calls"| addon["ProofKit add-on"] @@ -20,30 +20,35 @@ flowchart LR bundle --> file ``` - - Replace or polish this Mermaid diagram with the final branded architecture visual if needed. + + - **MCP**: Model Context Protocol, the tool protocol the coding agent uses to talk to the ProofKit MCP server. + - **Local API**: The local bridge between the ProofKit MCP server and the FileMaker plug-in. + - **Script calls**: FileMaker script execution used by the plug-in and add-on to work with your FileMaker file. ## Runtime architecture ```mermaid flowchart LR - user["User"] <--> webviewer["Web Viewer React app"] - webviewer <-->|"JSON through script bridge"| scripts["FileMaker scripts"] - scripts <--> database["FileMaker database"] + webviewer["Web Viewer app"] + webviewer -->|"ProofKit type safe
client"| executeDataApi["Execute Data
API Step"] + webviewer -->|"fmFetch()"| scripts["FileMaker scripts"] + executeDataApi --> database["FileMaker database"] + scripts --> database scripts --> externalApis["External APIs"] scripts --> fileSystem["File system"] scripts --> printing["Printing and PDF"] ``` - - Replace or polish this Mermaid diagram with the final runtime/data-flow visual. + + - **ProofKit type safe client**: Generated client code that calls FileMaker's Data API through the Execute Data API script step. + - **fmFetch()**: A lightweight script bridge for calling FileMaker scripts from the Web Viewer app. ## How to think about it - During development, the agent uses ProofKit tools to understand the FileMaker file and deploy bundles. -- At runtime, the deployed web app talks to FileMaker scripts through the Web Viewer bridge. +- At runtime, the deployed web app talks to FileMaker through fmFetch scripts and the type-safe Data API path. - FileMaker scripts remain the secure place for privileged operations, external API secrets, filesystem work, and print/PDF flows. ## Related pages diff --git a/apps/docs/public/screenshots/ai/deployed-filemaker-webviewer.png b/apps/docs/public/screenshots/ai/deployed-filemaker-webviewer.png new file mode 100644 index 00000000..14120937 Binary files /dev/null and b/apps/docs/public/screenshots/ai/deployed-filemaker-webviewer.png differ diff --git a/apps/docs/public/screenshots/ai/local-preview-filemaker-webviewer.png b/apps/docs/public/screenshots/ai/local-preview-filemaker-webviewer.png new file mode 100644 index 00000000..0ba14d6a Binary files /dev/null and b/apps/docs/public/screenshots/ai/local-preview-filemaker-webviewer.png differ diff --git a/apps/docs/public/screenshots/ai/theme-preset-filemaker-webviewer.png b/apps/docs/public/screenshots/ai/theme-preset-filemaker-webviewer.png new file mode 100644 index 00000000..53a61bd3 Binary files /dev/null and b/apps/docs/public/screenshots/ai/theme-preset-filemaker-webviewer.png differ diff --git a/apps/docs/src/app/global.css b/apps/docs/src/app/global.css index c153e207..ab3df275 100644 --- a/apps/docs/src/app/global.css +++ b/apps/docs/src/app/global.css @@ -178,3 +178,10 @@ @apply bg-background text-foreground; } } + +@layer components { + .prose img { + background: var(--card); + border: 1px solid var(--border); + } +} diff --git a/apps/docs/src/components/AgentWorkflowLoop.tsx b/apps/docs/src/components/AgentWorkflowLoop.tsx new file mode 100644 index 00000000..bc30f873 --- /dev/null +++ b/apps/docs/src/components/AgentWorkflowLoop.tsx @@ -0,0 +1,113 @@ +import type { CSSProperties } from "react"; + +const nodeClass = "fill-[var(--surface)] stroke-[var(--border)]"; +const textClass = "fill-current text-[13px] font-medium"; +const labelClass = "fill-current text-[11px]"; +const arrowClass = "fill-none stroke-[var(--line)] stroke-[1.6]"; + +function Node({ + x, + y, + width, + height, + label, +}: { + x: number; + y: number; + width: number; + height: number; + label: string | string[]; +}) { + const lines = Array.isArray(label) ? label : [label]; + const lineHeight = 16; + const firstLineY = y + height / 2 - ((lines.length - 1) * lineHeight) / 2; + + return ( + + + + {lines.map((line, index) => ( + + {line} + + ))} + + + ); +} + +export function AgentWorkflowLoop() { + return ( +
+ + ProofKit agent workflow loop + + + + + + + + + + + + + + + + + iterate + + + ready + + + future change + + + + + + + + + Run typecheck + + and lint + + + + + + + +
+ ); +} diff --git a/apps/docs/src/components/Mermaid.tsx b/apps/docs/src/components/Mermaid.tsx index 36c6688a..d5ee5b3d 100644 --- a/apps/docs/src/components/Mermaid.tsx +++ b/apps/docs/src/components/Mermaid.tsx @@ -1,21 +1,62 @@ import { renderMermaidSVG } from "beautiful-mermaid"; // biome-ignore lint/performance/noNamespaceImport: fumadocs-ui/components/codeblock doesn't export named exports import * as BaseCodeBlock from "fumadocs-ui/components/codeblock"; +import type { CSSProperties } from "react"; + +const MIN_MULTILINE_EDGE_LABEL_WIDTH = 112; +const EDGE_LABEL_GROUP_REGEX = //g; +const EDGE_LABEL_RECT_REGEX = /]*\sx=")[^"]+/g; +const mermaidStyle = { + "--accent": "color-mix(in srgb, var(--color-fd-foreground) 90%, var(--color-fd-card))", + "--line": "color-mix(in srgb, var(--color-fd-foreground) 50%, var(--color-fd-card))", + "--surface": "color-mix(in srgb, var(--color-fd-foreground) 6%, var(--color-fd-card))", + "--border": "color-mix(in srgb, var(--color-fd-foreground) 22%, var(--color-fd-card))", +} as CSSProperties; + +function normalizeMultilineEdgeLabels(svg: string) { + return svg.replace(EDGE_LABEL_GROUP_REGEX, (group) => { + const rect = group.match(EDGE_LABEL_RECT_REGEX); + + if (!rect?.groups) { + return group; + } + + const x = Number(rect.groups.x); + const width = Number(rect.groups.width); + const height = Number(rect.groups.height); + + if (height < 40 || width >= MIN_MULTILINE_EDGE_LABEL_WIDTH) { + return group; + } + + const center = x + width / 2; + const normalizedX = center - MIN_MULTILINE_EDGE_LABEL_WIDTH / 2; + + return group + .replace(`x="${rect.groups.x}"`, `x="${normalizedX}"`) + .replace(`width="${rect.groups.width}"`, `width="${MIN_MULTILINE_EDGE_LABEL_WIDTH}"`) + .replace(EDGE_LABEL_TEXT_X_REGEX, `$1${center}`); + }); +} export function Mermaid({ chart }: { chart: string }) { try { - const svg = renderMermaidSVG(chart, { - bg: "var(--color-fd-background)", - fg: "var(--color-fd-foreground)", - interactive: true, - transparent: true, - }); + const svg = normalizeMultilineEdgeLabels( + renderMermaidSVG(chart, { + bg: "var(--color-fd-background)", + fg: "var(--color-fd-foreground)", + interactive: true, + transparent: true, + }), + ); return (
); } catch {