diff --git a/content/docs/guide/objectos-integration.mdx b/content/docs/guide/objectos-integration.mdx index 367284eb8..edb797bc0 100644 --- a/content/docs/guide/objectos-integration.mdx +++ b/content/docs/guide/objectos-integration.mdx @@ -50,6 +50,8 @@ pnpm add @object-ui/plugin-form @object-ui/plugin-grid ### 2. Set Up ObjectStack Kernel +{/* doc-snippet: fragment — this file belongs to the ObjectStack SERVER project, not to an ObjectUI app. `@objectstack/runtime`, `@objectstack/objectql`, `@objectstack/plugin-app` and `@objectstack/plugin-hono-server` are dependencies of that project and are not declared by any package in this repository, so they do not resolve in this gate's program (measured: TS2307 x4). Correct documentation the gate cannot reach — the authoritative reference is the ObjectStack side, linked in the section below */} + ```typescript // src/kernel.ts import { Kernel } from '@objectstack/runtime'; @@ -156,19 +158,28 @@ ReactDOM.createRoot(document.getElementById('root')!).render( ### Multi-Tenancy Support +The adapter's constructor takes no `headers` option. Per-request headers go +through its `fetch` hook, which it uses for every call it makes: + ```typescript // Configure tenant isolation +import { ObjectStackAdapter } from '@object-ui/data-objectstack'; + const adapter = new ObjectStackAdapter({ baseUrl: 'http://localhost:3000/api', - headers: { - 'X-Tenant-ID': 'tenant-123', - 'X-Workspace-ID': 'workspace-456' + fetch: (input, init) => { + const headers = new Headers(init?.headers); + headers.set('X-Tenant-ID', 'tenant-123'); + headers.set('X-Workspace-ID', 'workspace-456'); + return globalThis.fetch(input, { ...init, headers }); } }); ``` ### Role-Based Access Control (RBAC) +{/* doc-snippet: fragment — a SHAPE excerpt of the ObjectStack SERVER's object metadata (the `objects` map of `defineStack()`), not an expression: a bare object literal at statement position parses as a block with labels (measured: TS1005 x4, TS1109 x1, TS1128 x1). This repo declares no type for it — ObjectUI is a pure consumer of what the server publishes */} + ```typescript // Define permissions in object schema { @@ -203,17 +214,26 @@ const adapter = new ObjectStackAdapter({ ObjectOS provides system objects like `sys_user`, `sys_organization`, `sys_role`, etc. Integrate them in your UI: ```typescript -{ +import { ObjectStackAdapter } from '@object-ui/data-objectstack'; +import type { ObjectViewSchema } from '@object-ui/types'; + +const objectStackAdapter = new ObjectStackAdapter({ + baseUrl: 'http://localhost:3000/api' +}); + +const sysUserView: ObjectViewSchema = { type: 'object-view', objectName: 'sys_user', dataSource: objectStackAdapter, - viewTypes: ['grid'], - fieldNames: ['username', 'email', 'role', 'status', 'last_login'] -} + defaultViewType: 'grid', + columns: ['username', 'email', 'role', 'status', 'last_login'] +}; ``` ### Workflow Integration +{/* doc-snippet: fragment — a SHAPE excerpt of the ObjectStack SERVER's object metadata, not an expression: a bare object literal at statement position parses as a block with labels (measured: TS1005 x4, TS1128 x1). `workflow` is a server-side object concern; this repo declares no type for it */} + ```typescript // Define workflow-enabled object { @@ -277,7 +297,7 @@ go through `useViewData` from `@object-ui/react`, which resolves the adapter from context and hands back both the rows and the `DataSource` to write with. ```typescript -import { useViewData } from '@object-ui/react'; +import { SchemaRenderer, useViewData } from '@object-ui/react'; function ContactList() { const { data, loading, error, dataSource, refresh } = useViewData({ @@ -315,6 +335,8 @@ function ContactList() { Deploy ObjectUI and ObjectStack together in a single Node.js process: +{/* doc-snippet: fragment — `./kernel` and `./console-plugin` are the READER's own project files (the kernel module is the one built in step 2 above), so the relative specifiers resolve nowhere in this gate's program (measured: TS2307 x2) */} + ```typescript // server.ts import { createKernel } from './kernel'; @@ -338,6 +360,9 @@ start(); Deploy ObjectUI (frontend) and ObjectStack (backend) separately: **Backend (ObjectStack API):** + +{/* doc-snippet: fragment — `./kernel` is the READER's own project file (the kernel module built in step 2 above), so the relative specifier resolves nowhere in this gate's program (measured: TS2307 x1) */} + ```typescript // backend/server.ts import { createKernel } from './kernel'; @@ -351,6 +376,9 @@ start(); ``` **Frontend (ObjectUI):** + +{/* doc-snippet: fragment — two files in one block, and it is `import.meta.env` that cannot compile here: the `env` member is a Vite ambient declaration carried by the READER's `vite/client` types, which this repository's gate program does not load (measured: TS2339 x1, plus TS2304 x1 for the adapter the second file imports in the reader's own entry point) */} + ```typescript // frontend/src/config.ts export const config = { @@ -424,6 +452,8 @@ spec: ### Custom Component Registration +{/* doc-snippet: fragment — `MyCustomWidget` is the READER's own component, and the block closes with a bare `{ type: 'my-custom-widget' }` SHAPE excerpt showing where the registered name is then used, which at statement position parses as a block with labels (measured: TS1005 x1) */} + ```typescript // Register custom components with ObjectUI import { ComponentRegistry } from '@object-ui/core'; @@ -444,6 +474,8 @@ ComponentRegistry.register('my-custom-widget', MyCustomWidget, { ### Event Handling & Callbacks +{/* doc-snippet: fragment — a SHAPE excerpt continuing the "Using ObjectQL for Queries" block above, which is where `dataSource` is constructed: a bare object literal at statement position parses as a block with labels (measured: TS1005 x3) */} + ```typescript { type: 'object-grid', @@ -464,31 +496,38 @@ ComponentRegistry.register('my-custom-widget', MyCustomWidget, { } ``` -### Real-time Updates with WebSockets +### Reacting to Data Changes + +⚠️ `@object-ui/data-objectstack` has **no WebSocket transport and no server-push +subscription**. What it offers is `onMutation`: a notification of the writes +*this adapter instance* performed, which is what a view needs to refresh itself +after its own create/update/delete. It returns its own unsubscribe function. ```typescript -// Configure WebSocket connection +import { ObjectStackAdapter } from '@object-ui/data-objectstack'; + const adapter = new ObjectStackAdapter({ - baseUrl: 'http://localhost:3000/api', - websocket: { - enabled: true, - url: 'ws://localhost:3000/ws' - } + baseUrl: 'http://localhost:3000/api' }); -// Subscribe to real-time updates -adapter.subscribe('contact', (event) => { +// Fires for writes this adapter performed. Filter by `resource` for one object. +const unsubscribe = adapter.onMutation((event) => { + if (event.resource !== 'contact') return; if (event.type === 'create' || event.type === 'update') { - // Refresh grid - gridRef.current?.refresh(); + // Refresh the view holding this object's rows } }); + +// Later, when the view unmounts: +unsubscribe(); ``` ## Migration from Other Platforms ### From Retool +{/* doc-snippet: fragment — a SHAPE excerpt showing the ObjectUI half of a side-by-side migration comparison; `dataSource` continues the "Using ObjectQL for Queries" block above, and a bare object literal at statement position parses as a block with labels (measured: TS1005 x4) */} + ```typescript // Retool table → ObjectUI Grid { @@ -503,6 +542,8 @@ adapter.subscribe('contact', (event) => { ### From Appsmith +{/* doc-snippet: fragment — a SHAPE excerpt showing the ObjectUI half of a side-by-side migration comparison; `dataSource` continues the "Using ObjectQL for Queries" block above, and a bare object literal at statement position parses as a block with labels (measured: TS1005 x4) */} + ```typescript // Appsmith form → ObjectUI form { @@ -519,6 +560,8 @@ adapter.subscribe('contact', (event) => { ### From Mendix +{/* doc-snippet: fragment — a SHAPE excerpt showing the ObjectUI half of a side-by-side migration comparison, with every slot body elided as a prose comment, so the object literal cannot parse as TypeScript (measured: TS1005 x2, TS1128 x2) */} + ```typescript // Mendix page → ObjectUI page { @@ -555,15 +598,13 @@ await plugins.grid(); ### Caching Strategy ```typescript +import { ObjectStackAdapter } from '@object-ui/data-objectstack'; + const adapter = new ObjectStackAdapter({ baseUrl: 'http://localhost:3000/api', cache: { - enabled: true, ttl: 60000, // 1 minute - strategies: { - 'contact': 'stale-while-revalidate', - 'sys_user': 'cache-first' - } + maxSize: 500 // entries retained } }); ``` @@ -572,6 +613,8 @@ const adapter = new ObjectStackAdapter({ ### Unit Tests +{/* doc-snippet: fragment — a test body: `test` / `expect` are the RUNNER's globals (Vitest or Jest, injected by the reader's own test config, not imported here) and `mockDataSource` is the reader's own fixture, so none of the three resolves in this gate's program (measured: TS2593 x1, TS2304 x2) */} + ```typescript import { render } from '@testing-library/react'; import { SchemaRenderer } from '@object-ui/react'; diff --git a/content/docs/plugins/plugin-chatbot.mdx b/content/docs/plugins/plugin-chatbot.mdx index ceecaf49e..c971b910c 100644 --- a/content/docs/plugins/plugin-chatbot.mdx +++ b/content/docs/plugins/plugin-chatbot.mdx @@ -49,9 +49,10 @@ npm install @object-ui/plugin-chatbot ```tsx // Import once in your app entry point import '@object-ui/plugin-chatbot' +import type { ChatbotSchema } from '@object-ui/types' // Use in schemas -const schema = { +const schema: ChatbotSchema = { type: 'chatbot', messages: [ { @@ -171,9 +172,11 @@ The chatbot supports two modes, automatically selected based on the `api` field: When `api` is not set, the chatbot operates in local mode with optional auto-response: ```tsx -const schema = { +import type { ChatbotSchema } from '@object-ui/types'; + +const schema: ChatbotSchema = { type: 'chatbot', - messages: [...], + messages: [], // seed with your own ChatMessage values autoResponse: true, autoResponseText: 'Thanks!', autoResponseDelay: 1000, @@ -185,7 +188,9 @@ const schema = { When `api` is set, the chatbot uses `@ai-sdk/react` for real SSE streaming: ```tsx -const schema = { +import type { ChatbotSchema } from '@object-ui/types'; + +const schema: ChatbotSchema = { type: 'chatbot', api: '/api/v1/ai/chat', model: 'gpt-4o', @@ -202,12 +207,14 @@ const schema = { Messages from the user appear on the right side with primary styling: ```tsx -{ +import type { ChatMessage } from '@object-ui/types'; + +const userMessage: ChatMessage = { id: '1', role: 'user', content: 'Hello!', - timestamp: '10:30 AM' -} + timestamp: '10:30 AM', +}; ``` ### Assistant Messages @@ -215,12 +222,14 @@ Messages from the user appear on the right side with primary styling: Messages from the assistant appear on the left side: ```tsx -{ +import type { ChatMessage } from '@object-ui/types'; + +const assistantMessage: ChatMessage = { id: '2', role: 'assistant', content: 'Hi! How can I help?', - timestamp: '10:30 AM' -} + timestamp: '10:30 AM', +}; ``` ### System Messages @@ -228,11 +237,13 @@ Messages from the assistant appear on the left side: System messages appear centered with muted styling: ```tsx -{ +import type { ChatMessage } from '@object-ui/types'; + +const systemMessage: ChatMessage = { id: '3', role: 'system', - content: 'Chat session started' -} + content: 'Chat session started', +}; ``` ### Tool Messages (AI Mode) @@ -252,7 +263,9 @@ states. Reasoning, tool parameters, and raw tool results are not stored in this cache. ```tsx -{ +import type { ChatMessage } from '@object-ui/types'; + +const toolMessage: ChatMessage = { id: '4', role: 'assistant', content: 'The weather in SF is 68°F.', @@ -263,9 +276,9 @@ cache. args: { city: 'San Francisco' }, result: { temp: 68, condition: 'Sunny' }, state: 'result', - } - ] -} + }, + ], +}; ``` ## Examples @@ -273,7 +286,9 @@ cache. ### Simple AI Chat ```tsx -const aiChat = { +import type { ChatbotSchema } from '@object-ui/types'; + +const aiChat: ChatbotSchema = { type: 'chatbot', messages: [ { @@ -382,12 +397,14 @@ const multiAgentChat = { ### Avatar Images ```tsx -const schema = { +import type { ChatbotSchema } from '@object-ui/types'; + +const schema: ChatbotSchema = { type: 'chatbot', userAvatarUrl: 'https://example.com/user-avatar.jpg', assistantAvatarUrl: 'https://example.com/bot-avatar.jpg', - messages: [...] -} + messages: [], // seed with your own ChatMessage values +}; ``` ### Avatar Fallbacks @@ -395,12 +412,14 @@ const schema = { When images aren't available, fallback text is displayed: ```tsx -const schema = { +import type { ChatbotSchema } from '@object-ui/types'; + +const schema: ChatbotSchema = { type: 'chatbot', - userAvatarFallback: 'JD', // User initials - assistantAvatarFallback: 'AI', // Bot identifier - messages: [...] -} + userAvatarFallback: 'JD', // User initials + assistantAvatarFallback: 'AI', // Bot identifier + messages: [], // seed with your own ChatMessage values +}; ``` ### Per-message Avatars @@ -408,13 +427,15 @@ const schema = { Override avatars for individual messages: ```tsx -{ +import type { ChatMessage } from '@object-ui/plugin-chatbot'; + +const message: ChatMessage = { id: '1', role: 'assistant', content: 'Message content', avatar: 'https://example.com/special-avatar.jpg', - avatarFallback: 'SP' -} + avatarFallback: 'SP', +}; ``` ## Event Handling @@ -424,20 +445,22 @@ Override avatars for individual messages: Handle message sending in your application: ```tsx -const schema = { +import type { ChatbotSchema } from '@object-ui/types'; + +const schema: ChatbotSchema = { type: 'chatbot', - messages: [...], + messages: [], // seed with your own ChatMessage values onSend: (content, allMessages) => { console.log('User sent:', content); console.log('All messages:', allMessages); - + // Send to your backend fetch('/api/chat', { method: 'POST', - body: JSON.stringify({ message: content }) + body: JSON.stringify({ message: content }), }); - } -} + }, +}; ``` ## Customization @@ -445,23 +468,27 @@ const schema = { ### Container Styling ```tsx -const schema = { +import type { ChatbotSchema } from '@object-ui/types'; + +const schema: ChatbotSchema = { type: 'chatbot', className: 'w-full max-w-2xl mx-auto border-2 rounded-xl shadow-lg', maxHeight: '600px', - messages: [...] -} + messages: [], // seed with your own ChatMessage values +}; ``` ### Responsive Heights ```tsx -const schema = { +import type { ChatbotSchema } from '@object-ui/types'; + +const schema: ChatbotSchema = { type: 'chatbot', maxHeight: '400px', // or use Tailwind: 'h-96' className: 'sm:max-h-[500px] lg:max-h-[600px]', - messages: [...] -} + messages: [], // seed with your own ChatMessage values +}; ``` ## TypeScript Support diff --git a/content/docs/plugins/plugin-map.mdx b/content/docs/plugins/plugin-map.mdx index 2eb0777c3..3adcddbdc 100644 --- a/content/docs/plugins/plugin-map.mdx +++ b/content/docs/plugins/plugin-map.mdx @@ -53,8 +53,9 @@ The `@object-ui/plugin-map` plugin provides map visualization for ObjectQL data ```tsx import '@object-ui/plugin-map' +import type { ObjectMapSchema } from '@object-ui/types' -const schema = { +const schema: ObjectMapSchema = { type: 'object-map', objectName: 'locations', // Your ObjectQL object map: { @@ -137,7 +138,9 @@ const schema = { When your data has separate latitude and longitude fields: ```tsx -{ +import type { ObjectMapSchema } from '@object-ui/types'; + +const storeMap: ObjectMapSchema = { type: 'object-map', objectName: 'stores', map: { @@ -146,7 +149,7 @@ When your data has separate latitude and longitude fields: titleField: 'storeName', descriptionField: 'storeAddress' } -} +}; ``` ### Field Mapping - Combined Location @@ -154,7 +157,9 @@ When your data has separate latitude and longitude fields: When your data has a combined location field: ```tsx -{ +import type { ObjectMapSchema } from '@object-ui/types'; + +const placeMap: ObjectMapSchema = { type: 'object-map', objectName: 'places', map: { @@ -162,7 +167,7 @@ When your data has a combined location field: titleField: 'placeName', descriptionField: 'description' } -} +}; ``` ### Initial Camera @@ -185,7 +190,9 @@ Two cases sit outside the fit: Declare either one to take the camera over and opt this view out of the auto-fit: ```tsx -{ +import type { ObjectMapSchema } from '@object-ui/types'; + +const cameraMap: ObjectMapSchema = { type: 'object-map', objectName: 'locations', map: { @@ -195,7 +202,7 @@ Declare either one to take the camera over and opt this view out of the auto-fit zoom: 12, // Zoom level (1-20) center: [37.7749, -122.4194] // [latitude, longitude] } -} +}; ``` Declaring only one half keeps the other derived: `zoom` on its own is applied at @@ -206,7 +213,9 @@ the centre of the records, `center` on its own at a continental zoom. ### Object Provider (Database) ```tsx -{ +import type { ObjectMapSchema } from '@object-ui/types'; + +const retailStores: ObjectMapSchema = { type: 'object-map', objectName: 'retail_stores', map: { @@ -215,13 +224,13 @@ the centre of the records, `center` on its own at a continental zoom. titleField: 'store_name', descriptionField: 'store_address' } -} +}; ``` ### Value Provider (Static) ```tsx -{ +const staticLocations = { type: 'object-map', staticData: [ { id: 1, name: 'Location 1', lat: 37.7749, lng: -122.4194 }, @@ -232,7 +241,7 @@ the centre of the records, `center` on its own at a continental zoom. longitudeField: 'lng', titleField: 'name' } -} +}; ``` ### API Provider — not implemented @@ -251,7 +260,9 @@ already hold with the **Value Provider**. ### Marker Click ```tsx -{ +import type { ObjectMapSchema } from '@object-ui/types'; + +const clickableMap: ObjectMapSchema = { type: 'object-map', objectName: 'locations', map: { @@ -259,13 +270,13 @@ already hold with the **Value Provider**. longitudeField: 'lng', titleField: 'name' }, - onMarkerClick: (location) => { + onMarkerClick: (location: Record) => { console.log('Marker clicked:', location); // Show location details // Navigate to location page // Open directions } -} +}; ``` ## Examples @@ -273,7 +284,9 @@ already hold with the **Value Provider**. ### Store Locator ```tsx -const storeLocator = { +import type { ObjectMapSchema } from '@object-ui/types'; + +const storeLocator: ObjectMapSchema = { type: 'object-map', objectName: 'retail_locations', map: { @@ -284,7 +297,7 @@ const storeLocator = { zoom: 10, center: [37.7749, -122.4194] // San Francisco }, - onMarkerClick: (store) => { + onMarkerClick: (store: Record) => { // Show store details // Display hours, phone, etc. } @@ -294,7 +307,9 @@ const storeLocator = { ### Delivery Tracking ```tsx -const deliveryMap = { +import type { ObjectMapSchema } from '@object-ui/types'; + +const deliveryMap: ObjectMapSchema = { type: 'object-map', objectName: 'active_deliveries', map: { @@ -303,7 +318,7 @@ const deliveryMap = { titleField: 'driver_name', descriptionField: 'delivery_address' }, - onMarkerClick: (delivery) => { + onMarkerClick: (delivery: Record) => { // Show delivery details // Contact driver } @@ -313,7 +328,9 @@ const deliveryMap = { ### Real Estate Listings ```tsx -const propertyMap = { +import type { ObjectMapSchema } from '@object-ui/types'; + +const propertyMap: ObjectMapSchema = { type: 'object-map', objectName: 'properties', map: { @@ -323,7 +340,7 @@ const propertyMap = { descriptionField: 'property_details', zoom: 12 }, - onMarkerClick: (property) => { + onMarkerClick: (property: Record) => { // Show property details // Display photos, price, etc. } @@ -365,7 +382,7 @@ const venueMap = { descriptionField: 'details', zoom: 11 }, - onMarkerClick: (venue) => { + onMarkerClick: (venue: Record) => { // Show venue details // Book venue } @@ -375,7 +392,9 @@ const venueMap = { ### Field Service Map ```tsx -const serviceMap = { +import type { ObjectMapSchema } from '@object-ui/types'; + +const serviceMap: ObjectMapSchema = { type: 'object-map', objectName: 'service_calls', map: { @@ -385,7 +404,7 @@ const serviceMap = { descriptionField: 'service_type', zoom: 10 }, - onMarkerClick: (serviceCall) => { + onMarkerClick: (serviceCall: Record) => { // Show service call details // Assign technician // Get directions @@ -407,6 +426,8 @@ const serviceMap = { ### Separate Fields +{/* doc-snippet: fragment — a SHAPE excerpt of one of the READER's own data records, not an expression: a bare object literal at statement position parses as a block with labels (measured: TS1005 x3). No ObjectUI type describes it — these are the caller's own row fields, named by `map.latitudeField` / `map.longitudeField` above */} + ```tsx { id: 1, @@ -418,6 +439,8 @@ const serviceMap = { ### Combined String +{/* doc-snippet: fragment — a SHAPE excerpt of one of the READER's own data records, not an expression: a bare object literal at statement position parses as a block with labels (measured: TS1005 x2). No ObjectUI type describes it — `coordinates` is the caller's own field, named by `map.locationField` above */} + ```tsx { id: 1, @@ -428,6 +451,8 @@ const serviceMap = { ### Object Format +{/* doc-snippet: fragment — a SHAPE excerpt of one of the READER's own data records, not an expression: a bare object literal at statement position parses as a block with labels (measured: TS1005 x3). No ObjectUI type describes it — `location` is the caller's own field, named by `map.locationField` above */} + ```tsx { id: 1, diff --git a/scripts/check-doc-snippet-types.mjs b/scripts/check-doc-snippet-types.mjs index c1fef0705..7fc16734d 100644 --- a/scripts/check-doc-snippet-types.mjs +++ b/scripts/check-doc-snippet-types.mjs @@ -444,17 +444,6 @@ const TS_FENCE_LANGUAGES = new Set(['ts', 'tsx', 'typescript']); * @type {Record} */ const UNGATED_DOCS = { - 'content/docs/guide/objectos-integration.mdx': - '36 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies; ' + - '10 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the ' + - 'page never defines; 7 unresolved-module diagnostic(s); plus TS2339x1 — candidate real defects, ' + - 'un-triaged. This entry read TS2305x1 until objectui#5160, whose last name was the ' + - '`AppManifest` annotation on an `objectstack.config.ts` literal. That block is gone rather ' + - 'than re-typed: the file is a server-project config this repo neither owns nor builds, so the ' + - 'section links to the ObjectStack documentation instead of restating its shape here. Covering ' + - 'this page still needs the 8 parse-failing blocks re-fenced or declared, the undefined-name ' + - 'blocks made self-contained, and the `@objectstack/*` runtime imports resolvable — none of ' + - 'which this repo can do from here.', 'content/docs/plugins/plugin-calendar-view.mdx': '2 unresolved-module diagnostic(s) — and NOT a defect: the page is a migration guide whose ' + '"Before" blocks quote the retired `@object-ui/plugin-calendar-view` import on purpose. Covering ' + @@ -462,16 +451,12 @@ const UNGATED_DOCS = { 'edit — the one entry here that would be closed by declaring blocks rather than by fixing them.', 'content/docs/plugins/plugin-calendar.mdx': '25 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies; 6 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; 2 unresolved-module diagnostic(s); plus TS2322x1 — candidate real defects, un-triaged', - 'content/docs/plugins/plugin-chatbot.mdx': - '21 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies', 'content/docs/plugins/plugin-detail.mdx': '16 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines', 'content/docs/plugins/plugin-gantt.mdx': '31 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies; 2 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines', 'content/docs/plugins/plugin-kanban.mdx': '6 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies; 8 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines', - 'content/docs/plugins/plugin-map.mdx': - '43 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies; 5 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines', 'content/docs/plugins/plugin-timeline.mdx': '1 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies', 'content/docs/utilities/create-plugin.mdx':