diff --git a/.oxfmtrc.json b/.oxfmtrc.json
index 7556276..2f73a26 100644
--- a/.oxfmtrc.json
+++ b/.oxfmtrc.json
@@ -8,4 +8,4 @@
"**/package.json",
"**/emdash-env.d.ts"
]
-}
\ No newline at end of file
+}
diff --git a/AGENTS.md b/AGENTS.md
index faefd1a..a0b3b56 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -97,7 +97,7 @@ EmDash is an Astro-native CMS that stores its schema in the database, not in cod
| File | Purpose |
| ----------------------------------- | ----------------------------------------------------- |
| `src/live.config.ts` | Collection schemas + admin config (user's site) |
-| `src/emdash-runtime.ts` | Central runtime; orchestrates DB, plugins, storage |
+| `src/emdash-runtime.ts` | Central runtime; orchestrates DB, plugins, storage |
| `src/schema/registry.ts` | Manages `ec_*` table creation/modification |
| `src/database/migrations/runner.ts` | StaticMigrationProvider; register new migrations here |
| `src/plugins/manager.ts` | Loads and orchestrates trusted plugins |
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4478483..6b5e790 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -51,8 +51,8 @@ pnpm --filter @emdash-cms/template-portfolio dev
Available templates:
-| Template | Filter Name |
-| --------- | ------------------------------ |
+| Template | Filter Name |
+| --------- | -------------------------------- |
| Blog | `@emdash-cms/template-blog` |
| Portfolio | `@emdash-cms/template-portfolio` |
| Marketing | `@emdash-cms/template-marketing` |
diff --git a/demos/cloudflare/tsconfig.json b/demos/cloudflare/tsconfig.json
index eb9ce79..d51cdf2 100644
--- a/demos/cloudflare/tsconfig.json
+++ b/demos/cloudflare/tsconfig.json
@@ -1,9 +1,4 @@
{
"extends": "astro/tsconfigs/strict",
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts",
- "worker-configuration.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts", "worker-configuration.d.ts"]
+}
diff --git a/demos/cloudflare/wrangler.jsonc b/demos/cloudflare/wrangler.jsonc
index 001c6a5..4193641 100644
--- a/demos/cloudflare/wrangler.jsonc
+++ b/demos/cloudflare/wrangler.jsonc
@@ -5,10 +5,7 @@
"compatibility_date": "2026-01-14",
// disable_nodejs_process_v2 needed until unenv fix lands in Pages
// See: https://github.com/withastro/astro/issues/14511
- "compatibility_flags": [
- "nodejs_compat",
- "disable_nodejs_process_v2"
- ],
+ "compatibility_flags": ["nodejs_compat", "disable_nodejs_process_v2"],
// Static assets served from dist/
"assets": {
"directory": "./dist",
@@ -24,7 +21,7 @@
"d1_databases": [
{
"binding": "DB",
- "database_name": "emdash_db"
+ "database_name": "emdash_db",
},
],
// R2 bucket for media storage
@@ -44,4 +41,4 @@
"binding": "LOADER",
},
],
-}
\ No newline at end of file
+}
diff --git a/demos/playground/tsconfig.json b/demos/playground/tsconfig.json
index 0217fb1..0903753 100644
--- a/demos/playground/tsconfig.json
+++ b/demos/playground/tsconfig.json
@@ -1,13 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
- "types": [
- "node"
- ]
+ "types": ["node"]
},
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts"]
+}
diff --git a/demos/playground/wrangler.jsonc b/demos/playground/wrangler.jsonc
index 19dd245..020f686 100644
--- a/demos/playground/wrangler.jsonc
+++ b/demos/playground/wrangler.jsonc
@@ -2,9 +2,7 @@
"$schema": "node_modules/wrangler/config-schema.json",
"name": "emdash-playground",
"compatibility_date": "2026-02-24",
- "compatibility_flags": [
- "nodejs_compat"
- ],
+ "compatibility_flags": ["nodejs_compat"],
// Custom entrypoint that exports EmDashPreviewDB
"main": "./src/worker.ts",
"assets": {
@@ -21,9 +19,7 @@
"migrations": [
{
"tag": "v1",
- "new_sqlite_classes": [
- "EmDashPreviewDB"
- ],
+ "new_sqlite_classes": ["EmDashPreviewDB"],
},
],
"observability": {
@@ -38,4 +34,4 @@
],
// No R2 -- media uploads are blocked in playground mode
// No D1 -- database is inside the Durable Object
-}
\ No newline at end of file
+}
diff --git a/demos/plugins-demo/tsconfig.json b/demos/plugins-demo/tsconfig.json
index d4e77c0..a058b51 100644
--- a/demos/plugins-demo/tsconfig.json
+++ b/demos/plugins-demo/tsconfig.json
@@ -3,9 +3,5 @@
"compilerOptions": {
"strictNullChecks": true
},
- "include": [
- "src/**/*",
- "astro.config.mjs",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src/**/*", "astro.config.mjs", "emdash-env.d.ts"]
+}
diff --git a/demos/postgres/tsconfig.json b/demos/postgres/tsconfig.json
index 0217fb1..0903753 100644
--- a/demos/postgres/tsconfig.json
+++ b/demos/postgres/tsconfig.json
@@ -1,13 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
- "types": [
- "node"
- ]
+ "types": ["node"]
},
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts"]
+}
diff --git a/demos/preview/tsconfig.json b/demos/preview/tsconfig.json
index eb9ce79..d51cdf2 100644
--- a/demos/preview/tsconfig.json
+++ b/demos/preview/tsconfig.json
@@ -1,9 +1,4 @@
{
"extends": "astro/tsconfigs/strict",
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts",
- "worker-configuration.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts", "worker-configuration.d.ts"]
+}
diff --git a/demos/preview/wrangler.jsonc b/demos/preview/wrangler.jsonc
index f8f7b7c..a6bcd28 100644
--- a/demos/preview/wrangler.jsonc
+++ b/demos/preview/wrangler.jsonc
@@ -4,10 +4,7 @@
// Custom entrypoint that exports EmDashPreviewDB
"main": "./src/worker.ts",
"compatibility_date": "2026-01-14",
- "compatibility_flags": [
- "nodejs_compat",
- "disable_nodejs_process_v2"
- ],
+ "compatibility_flags": ["nodejs_compat", "disable_nodejs_process_v2"],
"assets": {
"directory": "./dist",
},
@@ -24,12 +21,10 @@
"migrations": [
{
"tag": "v1",
- "new_sqlite_classes": [
- "EmDashPreviewDB"
- ],
+ "new_sqlite_classes": ["EmDashPreviewDB"],
},
],
"observability": {
"enabled": true,
},
-}
\ No newline at end of file
+}
diff --git a/demos/simple/tsconfig.json b/demos/simple/tsconfig.json
index 0217fb1..0903753 100644
--- a/demos/simple/tsconfig.json
+++ b/demos/simple/tsconfig.json
@@ -1,13 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
- "types": [
- "node"
- ]
+ "types": ["node"]
},
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts"]
+}
diff --git a/e2e/tests/allowed-domains.spec.ts b/e2e/tests/allowed-domains.spec.ts
index 1e9e482..d987793 100644
--- a/e2e/tests/allowed-domains.spec.ts
+++ b/e2e/tests/allowed-domains.spec.ts
@@ -109,10 +109,10 @@ test.describe("Allowed Domains Settings", () => {
await expect(successMsg).toBeVisible({ timeout: 5000 });
// Clean up via API
- await fetch(
- `${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`,
- { method: "DELETE", headers },
- ).catch(() => {});
+ await fetch(`${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`, {
+ method: "DELETE",
+ headers,
+ }).catch(() => {});
});
test("removes a domain via the UI", async ({ admin, page }) => {
@@ -193,10 +193,10 @@ test.describe("Allowed Domains Settings", () => {
await expect(page.locator(`.font-medium`, { hasText: testDomain })).toBeVisible();
// Clean up
- await fetch(
- `${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`,
- { method: "DELETE", headers },
- ).catch(() => {});
+ await fetch(`${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`, {
+ method: "DELETE",
+ headers,
+ }).catch(() => {});
});
test("toggling enabled/disabled updates the domain", async ({ admin, page }) => {
@@ -228,9 +228,9 @@ test.describe("Allowed Domains Settings", () => {
await expect(statusMsg).toBeVisible({ timeout: 5000 });
// Clean up
- await fetch(
- `${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`,
- { method: "DELETE", headers },
- ).catch(() => {});
+ await fetch(`${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`, {
+ method: "DELETE",
+ headers,
+ }).catch(() => {});
});
});
diff --git a/e2e/tests/revisions.spec.ts b/e2e/tests/revisions.spec.ts
index c4a93ad..a6a14bf 100644
--- a/e2e/tests/revisions.spec.ts
+++ b/e2e/tests/revisions.spec.ts
@@ -342,13 +342,10 @@ test.describe("Revisions", () => {
const olderRevisionId = revisions[1].id;
// Restore via API
- const restoreRes = await fetch(
- `${baseUrl}/_emdash/api/revisions/${olderRevisionId}/restore`,
- {
- method: "POST",
- headers,
- },
- );
+ const restoreRes = await fetch(`${baseUrl}/_emdash/api/revisions/${olderRevisionId}/restore`, {
+ method: "POST",
+ headers,
+ });
expect(restoreRes.status).toBe(200);
// Get revision count after restore -- should have increased
diff --git a/e2e/tests/search.spec.ts b/e2e/tests/search.spec.ts
index a4305e9..9255a08 100644
--- a/e2e/tests/search.spec.ts
+++ b/e2e/tests/search.spec.ts
@@ -272,11 +272,7 @@ test.describe("Search", () => {
// TODO: getSuggestions fails in dev mode -- needs investigation
await enableSearch(serverInfo, "posts");
- const res = await apiRequest(
- serverInfo,
- "GET",
- "/_emdash/api/search/suggest?q=Fir&limit=5",
- );
+ const res = await apiRequest(serverInfo, "GET", "/_emdash/api/search/suggest?q=Fir&limit=5");
expect(res.status).toBe(200);
const body = await res.json();
diff --git a/packages/admin/src/components/MarketplacePluginDetail.tsx b/packages/admin/src/components/MarketplacePluginDetail.tsx
index 31ae169..129c4a3 100644
--- a/packages/admin/src/components/MarketplacePluginDetail.tsx
+++ b/packages/admin/src/components/MarketplacePluginDetail.tsx
@@ -329,9 +329,7 @@ export function MarketplacePluginDetail({
Version
v{latest.version}
- {latest.minEmDashVersion && (
-
Requires EmDash {latest.minEmDashVersion}
- )}
+ {latest.minEmDashVersion &&
Requires EmDash {latest.minEmDashVersion}
}
Published {new Date(latest.publishedAt).toLocaleDateString()}
{latest.bundleSize > 0 &&
{formatBytes(latest.bundleSize)}
}
diff --git a/packages/admin/src/components/PortableTextEditor.tsx b/packages/admin/src/components/PortableTextEditor.tsx
index 536297d..d1e0f55 100644
--- a/packages/admin/src/components/PortableTextEditor.tsx
+++ b/packages/admin/src/components/PortableTextEditor.tsx
@@ -12,6 +12,7 @@
*/
import { Button, Dialog, Input } from "@cloudflare/kumo";
+import type { Element } from "@emdash-cms/blocks";
import { useFloating, offset, flip, shift, autoUpdate } from "@floating-ui/react";
import {
TextB,
@@ -41,7 +42,6 @@ import {
type Icon,
} from "@phosphor-icons/react";
import { X } from "@phosphor-icons/react";
-import type { Element } from "@emdash-cms/blocks";
import { Extension, type Range } from "@tiptap/core";
import CharacterCount from "@tiptap/extension-character-count";
import Focus from "@tiptap/extension-focus";
diff --git a/packages/admin/src/components/SandboxedPluginPage.tsx b/packages/admin/src/components/SandboxedPluginPage.tsx
index 588da73..e291652 100644
--- a/packages/admin/src/components/SandboxedPluginPage.tsx
+++ b/packages/admin/src/components/SandboxedPluginPage.tsx
@@ -5,9 +5,9 @@
* interactions to the plugin's admin route and renders the returned blocks.
*/
-import { CircleNotch, WarningCircle } from "@phosphor-icons/react";
import { BlockRenderer } from "@emdash-cms/blocks";
import type { Block, BlockInteraction, BlockResponse } from "@emdash-cms/blocks";
+import { CircleNotch, WarningCircle } from "@phosphor-icons/react";
import { useCallback, useEffect, useState } from "react";
import { apiFetch, API_BASE } from "../lib/api/client.js";
diff --git a/packages/admin/src/components/SandboxedPluginWidget.tsx b/packages/admin/src/components/SandboxedPluginWidget.tsx
index 1e105fa..97b97b2 100644
--- a/packages/admin/src/components/SandboxedPluginWidget.tsx
+++ b/packages/admin/src/components/SandboxedPluginWidget.tsx
@@ -5,9 +5,9 @@
* interaction with page="widget:" to the plugin's admin route.
*/
-import { CircleNotch } from "@phosphor-icons/react";
import { BlockRenderer } from "@emdash-cms/blocks";
import type { Block, BlockInteraction, BlockResponse } from "@emdash-cms/blocks";
+import { CircleNotch } from "@phosphor-icons/react";
import { useCallback, useEffect, useState } from "react";
import { apiFetch, API_BASE } from "../lib/api/client.js";
diff --git a/packages/admin/src/components/WordPressImport.tsx b/packages/admin/src/components/WordPressImport.tsx
index 72ea1b5..9492445 100644
--- a/packages/admin/src/components/WordPressImport.tsx
+++ b/packages/admin/src/components/WordPressImport.tsx
@@ -720,9 +720,7 @@ export function WordPressImport() {
Analyzing WordPress site...
-
- Fetching content from the EmDash Exporter API.
-
+
Fetching content from the EmDash Exporter API.
)}
diff --git a/packages/admin/src/components/editor/PluginBlockNode.tsx b/packages/admin/src/components/editor/PluginBlockNode.tsx
index 8f9eb64..3ead0fc 100644
--- a/packages/admin/src/components/editor/PluginBlockNode.tsx
+++ b/packages/admin/src/components/editor/PluginBlockNode.tsx
@@ -10,6 +10,7 @@
*/
import { Button, Input } from "@cloudflare/kumo";
+import type { Element } from "@emdash-cms/blocks";
import {
DotsSixVertical,
Trash,
@@ -24,7 +25,6 @@ import {
Cube,
ListBullets,
} from "@phosphor-icons/react";
-import type { Element } from "@emdash-cms/blocks";
import { Node, mergeAttributes } from "@tiptap/core";
import type { NodeViewProps } from "@tiptap/react";
import { ReactNodeViewRenderer, NodeViewWrapper } from "@tiptap/react";
diff --git a/packages/admin/tests/lib/url.test.ts b/packages/admin/tests/lib/url.test.ts
index d867207..9562208 100644
--- a/packages/admin/tests/lib/url.test.ts
+++ b/packages/admin/tests/lib/url.test.ts
@@ -18,9 +18,7 @@ describe("sanitizeRedirectUrl", () => {
});
it("allows paths with query strings", () => {
- expect(sanitizeRedirectUrl("/_emdash/admin?tab=settings")).toBe(
- "/_emdash/admin?tab=settings",
- );
+ expect(sanitizeRedirectUrl("/_emdash/admin?tab=settings")).toBe("/_emdash/admin?tab=settings");
});
it("allows paths with hash fragments", () => {
@@ -44,9 +42,7 @@ describe("sanitizeRedirectUrl", () => {
});
it("rejects data: scheme", () => {
- expect(sanitizeRedirectUrl("data:text/html,")).toBe(
- "/_emdash/admin",
- );
+ expect(sanitizeRedirectUrl("data:text/html,")).toBe("/_emdash/admin");
});
it("rejects backslash trick (/\\evil.com)", () => {
diff --git a/packages/blocks/playground/src/Playground.tsx b/packages/blocks/playground/src/Playground.tsx
index 4bf052b..d9a0331 100644
--- a/packages/blocks/playground/src/Playground.tsx
+++ b/packages/blocks/playground/src/Playground.tsx
@@ -1,6 +1,6 @@
-import { Sun, Moon, Share, Check, Trash, CaretDown, Warning, Plus } from "@phosphor-icons/react";
import { BlockRenderer, validateBlocks } from "@emdash-cms/blocks";
import type { Block, BlockInteraction } from "@emdash-cms/blocks";
+import { Sun, Moon, Share, Check, Trash, CaretDown, Warning, Plus } from "@phosphor-icons/react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { blockCatalog } from "./block-defaults";
diff --git a/packages/blocks/playground/wrangler.jsonc b/packages/blocks/playground/wrangler.jsonc
index 2048960..814881f 100644
--- a/packages/blocks/playground/wrangler.jsonc
+++ b/packages/blocks/playground/wrangler.jsonc
@@ -4,4 +4,4 @@
"assets": {
"directory": "./dist",
},
-}
\ No newline at end of file
+}
diff --git a/packages/cloudflare/src/auth/cloudflare-access.ts b/packages/cloudflare/src/auth/cloudflare-access.ts
index afc6c54..f8b3ad2 100644
--- a/packages/cloudflare/src/auth/cloudflare-access.ts
+++ b/packages/cloudflare/src/auth/cloudflare-access.ts
@@ -10,8 +10,8 @@
* Do not import at config time.
*/
-import { createRemoteJWKSet, jwtVerify, type JWTPayload } from "jose";
import type { AuthResult } from "emdash";
+import { createRemoteJWKSet, jwtVerify, type JWTPayload } from "jose";
/**
* Configuration for Cloudflare Access authentication
diff --git a/packages/cloudflare/src/db/do-preview.ts b/packages/cloudflare/src/db/do-preview.ts
index 6a9b0be..0f1feb9 100644
--- a/packages/cloudflare/src/db/do-preview.ts
+++ b/packages/cloudflare/src/db/do-preview.ts
@@ -22,8 +22,8 @@
import type { MiddlewareHandler } from "astro";
import { env } from "cloudflare:workers";
-import { Kysely } from "kysely";
import { runWithContext } from "emdash/request-context";
+import { Kysely } from "kysely";
import { ulid } from "ulidx";
import type { EmDashPreviewDB } from "./do-class.js";
diff --git a/packages/cloudflare/src/storage/r2.ts b/packages/cloudflare/src/storage/r2.ts
index 3970522..7b076b0 100644
--- a/packages/cloudflare/src/storage/r2.ts
+++ b/packages/cloudflare/src/storage/r2.ts
@@ -61,11 +61,7 @@ export class R2Storage implements Storage {
};
} catch (error) {
if (error instanceof EmDashStorageError) throw error;
- throw new EmDashStorageError(
- `Failed to upload file: ${options.key}`,
- "UPLOAD_FAILED",
- error,
- );
+ throw new EmDashStorageError(`Failed to upload file: ${options.key}`, "UPLOAD_FAILED", error);
}
}
@@ -107,11 +103,7 @@ export class R2Storage implements Storage {
const object = await this.bucket.head(key);
return object !== null;
} catch (error) {
- throw new EmDashStorageError(
- `Failed to check file existence: ${key}`,
- "HEAD_FAILED",
- error,
- );
+ throw new EmDashStorageError(`Failed to check file existence: ${key}`, "HEAD_FAILED", error);
}
}
diff --git a/packages/core/src/api/handlers/device-flow.ts b/packages/core/src/api/handlers/device-flow.ts
index 7ae2868..4d6a885 100644
--- a/packages/core/src/api/handlers/device-flow.ts
+++ b/packages/core/src/api/handlers/device-flow.ts
@@ -664,10 +664,7 @@ export async function handleTokenRevoke(
if (row.token_type === "refresh") {
// Revoke refresh token and all its access tokens
- await db
- .deleteFrom("_emdash_oauth_tokens")
- .where("refresh_token_hash", "=", hash)
- .execute();
+ await db.deleteFrom("_emdash_oauth_tokens").where("refresh_token_hash", "=", hash).execute();
await db.deleteFrom("_emdash_oauth_tokens").where("token_hash", "=", hash).execute();
} else {
// Revoke just the access token
diff --git a/packages/core/src/api/handlers/oauth-clients.ts b/packages/core/src/api/handlers/oauth-clients.ts
index 783e3c5..a13cecb 100644
--- a/packages/core/src/api/handlers/oauth-clients.ts
+++ b/packages/core/src/api/handlers/oauth-clients.ts
@@ -236,11 +236,7 @@ export async function handleOAuthClientUpdate(
updates.scopes = input.scopes ? JSON.stringify(input.scopes) : "";
}
- await db
- .updateTable("_emdash_oauth_clients")
- .set(updates)
- .where("id", "=", clientId)
- .execute();
+ await db.updateTable("_emdash_oauth_clients").set(updates).where("id", "=", clientId).execute();
// Fetch the updated row
const updated = await db
diff --git a/packages/core/src/astro/routes/api/admin/comments/[id]/status.ts b/packages/core/src/astro/routes/api/admin/comments/[id]/status.ts
index 7dbb191..6d8d2b4 100644
--- a/packages/core/src/astro/routes/api/admin/comments/[id]/status.ts
+++ b/packages/core/src/astro/routes/api/admin/comments/[id]/status.ts
@@ -95,11 +95,7 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
if (newStatus === "approved" && previousStatus !== "approved" && emdash.email) {
try {
const adminBaseUrl = await getSiteBaseUrl(emdash.db, request);
- const content = await lookupContentAuthor(
- emdash.db,
- updated.collection,
- updated.contentId,
- );
+ const content = await lookupContentAuthor(emdash.db, updated.collection, updated.contentId);
if (content?.author) {
await sendCommentNotification({
email: emdash.email,
diff --git a/packages/core/src/astro/routes/api/auth/passkey/register/verify.ts b/packages/core/src/astro/routes/api/auth/passkey/register/verify.ts
index 87ab5d5..8270988 100644
--- a/packages/core/src/astro/routes/api/auth/passkey/register/verify.ts
+++ b/packages/core/src/astro/routes/api/auth/passkey/register/verify.ts
@@ -71,9 +71,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
// Get passkey name - prefer body.name, then check stored pending name
let passKeyName: string | undefined = body.name ?? undefined;
if (!passKeyName) {
- const pending = await optionsRepo.get<{ name?: string }>(
- `emdash:passkey_pending:${user.id}`,
- );
+ const pending = await optionsRepo.get<{ name?: string }>(`emdash:passkey_pending:${user.id}`);
if (pending?.name) {
passKeyName = pending.name;
}
diff --git a/packages/core/src/astro/routes/api/content/[collection]/[id]/schedule.ts b/packages/core/src/astro/routes/api/content/[collection]/[id]/schedule.ts
index 0fc9f97..9bdc6a4 100644
--- a/packages/core/src/astro/routes/api/content/[collection]/[id]/schedule.ts
+++ b/packages/core/src/astro/routes/api/content/[collection]/[id]/schedule.ts
@@ -59,11 +59,7 @@ export const POST: APIRoute = async ({ params, request, locals, cache }) => {
const denied = requireOwnerPerm(user, authorId, "content:publish_own", "content:publish_any");
if (denied) return denied;
- const result = await emdash.handleContentSchedule(
- collection,
- resolvedId ?? id,
- body.scheduledAt,
- );
+ const result = await emdash.handleContentSchedule(collection, resolvedId ?? id, body.scheduledAt);
if (!result.success) return unwrapResult(result);
diff --git a/packages/core/src/astro/routes/api/import/wordpress/analyze.ts b/packages/core/src/astro/routes/api/import/wordpress/analyze.ts
index 22f6146..0e83d18 100644
--- a/packages/core/src/astro/routes/api/import/wordpress/analyze.ts
+++ b/packages/core/src/astro/routes/api/import/wordpress/analyze.ts
@@ -8,8 +8,8 @@
*/
import type { APIRoute } from "astro";
-import mime from "mime/lite";
import { parseWxrString, SchemaRegistry, type WxrData } from "emdash";
+import mime from "mime/lite";
import { requirePerm } from "#api/authorize.js";
import { apiError, apiSuccess, handleError } from "#api/error.js";
diff --git a/packages/core/src/astro/routes/api/import/wordpress/media.ts b/packages/core/src/astro/routes/api/import/wordpress/media.ts
index abcd5aa..d3a51fc 100644
--- a/packages/core/src/astro/routes/api/import/wordpress/media.ts
+++ b/packages/core/src/astro/routes/api/import/wordpress/media.ts
@@ -11,8 +11,8 @@
import * as path from "node:path";
import type { APIRoute } from "astro";
-import mime from "mime/lite";
import { MediaRepository, computeContentHash } from "emdash";
+import mime from "mime/lite";
import { ulid } from "ulidx";
import { requirePerm } from "#api/authorize.js";
diff --git a/packages/core/src/astro/routes/api/revisions/[revisionId]/restore.ts b/packages/core/src/astro/routes/api/revisions/[revisionId]/restore.ts
index f3bb488..81a9c83 100644
--- a/packages/core/src/astro/routes/api/revisions/[revisionId]/restore.ts
+++ b/packages/core/src/astro/routes/api/revisions/[revisionId]/restore.ts
@@ -15,11 +15,7 @@ export const POST: APIRoute = async ({ params, locals }) => {
const { emdash, user } = locals;
const revisionId = params.revisionId!;
- if (
- !emdash?.handleRevisionRestore ||
- !emdash?.handleRevisionGet ||
- !emdash?.handleContentGet
- ) {
+ if (!emdash?.handleRevisionRestore || !emdash?.handleRevisionGet || !emdash?.handleContentGet) {
return apiError("NOT_CONFIGURED", "EmDash not configured", 500);
}
diff --git a/packages/core/src/astro/routes/api/widget-areas/[name]/reorder.ts b/packages/core/src/astro/routes/api/widget-areas/[name]/reorder.ts
index 171cdf8..8403fef 100644
--- a/packages/core/src/astro/routes/api/widget-areas/[name]/reorder.ts
+++ b/packages/core/src/astro/routes/api/widget-areas/[name]/reorder.ts
@@ -57,11 +57,7 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
// Update sort_order for each widget
await Promise.all(
body.widgetIds.map((id, index) =>
- db
- .updateTable("_emdash_widgets")
- .set({ sort_order: index })
- .where("id", "=", id)
- .execute(),
+ db.updateTable("_emdash_widgets").set({ sort_order: index }).where("id", "=", id).execute(),
),
);
diff --git a/packages/core/src/cli/commands/publish.ts b/packages/core/src/cli/commands/publish.ts
index 254f9a4..959654d 100644
--- a/packages/core/src/cli/commands/publish.ts
+++ b/packages/core/src/cli/commands/publish.ts
@@ -418,9 +418,7 @@ export const publishCommand = defineCommand({
process.exit(1);
}
} catch {
- consola.error(
- "No dist/ directory found. Run `emdash plugin bundle` first or use --build.",
- );
+ consola.error("No dist/ directory found. Run `emdash plugin bundle` first or use --build.");
process.exit(1);
}
}
diff --git a/packages/core/src/cli/commands/seed.ts b/packages/core/src/cli/commands/seed.ts
index 8ea73fe..a6fcb87 100644
--- a/packages/core/src/cli/commands/seed.ts
+++ b/packages/core/src/cli/commands/seed.ts
@@ -135,9 +135,7 @@ export const seedCommand = defineCommand({
const seedPath = await resolveSeedPath(cwd, args.path);
if (!seedPath) {
consola.error("No seed file found");
- consola.info(
- "Provide a path, create .emdash/seed.json, or set emdash.seed in package.json",
- );
+ consola.info("Provide a path, create .emdash/seed.json, or set emdash.seed in package.json");
process.exit(1);
}
diff --git a/packages/core/src/database/migrations/032_rate_limits.ts b/packages/core/src/database/migrations/032_rate_limits.ts
index a49b447..0d74368 100644
--- a/packages/core/src/database/migrations/032_rate_limits.ts
+++ b/packages/core/src/database/migrations/032_rate_limits.ts
@@ -27,10 +27,7 @@ export async function up(db: Kysely): Promise {
.execute();
// ── Device code polling tracking ─────────────────────────────────
- await db.schema
- .alterTable("_emdash_device_codes")
- .addColumn("last_polled_at", "text")
- .execute();
+ await db.schema.alterTable("_emdash_device_codes").addColumn("last_polled_at", "text").execute();
}
export async function down(db: Kysely): Promise {
diff --git a/packages/core/src/mcp/server.ts b/packages/core/src/mcp/server.ts
index c847b03..1a73499 100644
--- a/packages/core/src/mcp/server.ts
+++ b/packages/core/src/mcp/server.ts
@@ -9,10 +9,10 @@
* The handlers instance is passed per-request via authInfo on the transport.
*/
-import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
-import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
import type { Permission, RoleLevel } from "@emdash-cms/auth";
import { canActOnOwn, Role } from "@emdash-cms/auth";
+import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
+import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
import type { EmDashHandlers } from "../astro/types.js";
diff --git a/packages/core/src/storage/local.ts b/packages/core/src/storage/local.ts
index aa1ac8e..8244874 100644
--- a/packages/core/src/storage/local.ts
+++ b/packages/core/src/storage/local.ts
@@ -103,11 +103,7 @@ export class LocalStorage implements Storage {
size: buffer.length,
};
} catch (error) {
- throw new EmDashStorageError(
- `Failed to upload file: ${options.key}`,
- "UPLOAD_FAILED",
- error,
- );
+ throw new EmDashStorageError(`Failed to upload file: ${options.key}`, "UPLOAD_FAILED", error);
}
}
diff --git a/packages/core/src/storage/s3.ts b/packages/core/src/storage/s3.ts
index c407b9f..80f81e5 100644
--- a/packages/core/src/storage/s3.ts
+++ b/packages/core/src/storage/s3.ts
@@ -97,11 +97,7 @@ export class S3Storage implements Storage {
size: body.length,
};
} catch (error) {
- throw new EmDashStorageError(
- `Failed to upload file: ${options.key}`,
- "UPLOAD_FAILED",
- error,
- );
+ throw new EmDashStorageError(`Failed to upload file: ${options.key}`, "UPLOAD_FAILED", error);
}
}
@@ -166,11 +162,7 @@ export class S3Storage implements Storage {
if (hasErrorName(error) && error.name === "NotFound") {
return false;
}
- throw new EmDashStorageError(
- `Failed to check file existence: ${key}`,
- "HEAD_FAILED",
- error,
- );
+ throw new EmDashStorageError(`Failed to check file existence: ${key}`, "HEAD_FAILED", error);
}
}
diff --git a/packages/core/tests/integration/auth/device-flow.test.ts b/packages/core/tests/integration/auth/device-flow.test.ts
index f5b39d6..e2873be 100644
--- a/packages/core/tests/integration/auth/device-flow.test.ts
+++ b/packages/core/tests/integration/auth/device-flow.test.ts
@@ -172,11 +172,7 @@ describe("Device Flow: Full Lifecycle", () => {
});
it("should handle denied authorization", async () => {
- const codeResult = await handleDeviceCodeRequest(
- db,
- {},
- "https://example.com/_emdash/device",
- );
+ const codeResult = await handleDeviceCodeRequest(db, {}, "https://example.com/_emdash/device");
expect(codeResult.success).toBe(true);
if (!codeResult.success) return;
@@ -199,11 +195,7 @@ describe("Device Flow: Full Lifecycle", () => {
});
it("should normalize user codes (strip hyphens, case-insensitive)", async () => {
- const codeResult = await handleDeviceCodeRequest(
- db,
- {},
- "https://example.com/_emdash/device",
- );
+ const codeResult = await handleDeviceCodeRequest(db, {}, "https://example.com/_emdash/device");
expect(codeResult.success).toBe(true);
if (!codeResult.success) return;
@@ -263,11 +255,7 @@ describe("Device Token Exchange: Error Cases", () => {
describe("Token Refresh", () => {
it("should exchange a refresh token for a new access token", async () => {
// Complete a device flow first to get tokens
- const codeResult = await handleDeviceCodeRequest(
- db,
- {},
- "https://example.com/_emdash/device",
- );
+ const codeResult = await handleDeviceCodeRequest(db, {}, "https://example.com/_emdash/device");
expect(codeResult.success).toBe(true);
if (!codeResult.success) return;
@@ -330,11 +318,7 @@ describe("Token Refresh", () => {
describe("Token Revoke", () => {
it("should revoke an access token", async () => {
// Get tokens via device flow
- const codeResult = await handleDeviceCodeRequest(
- db,
- {},
- "https://example.com/_emdash/device",
- );
+ const codeResult = await handleDeviceCodeRequest(db, {}, "https://example.com/_emdash/device");
if (!codeResult.success) return;
await handleDeviceAuthorize(db, "user-1", Role.ADMIN, {
@@ -365,11 +349,7 @@ describe("Token Revoke", () => {
it("should revoke a refresh token and its access tokens", async () => {
// Get tokens via device flow
- const codeResult = await handleDeviceCodeRequest(
- db,
- {},
- "https://example.com/_emdash/device",
- );
+ const codeResult = await handleDeviceCodeRequest(db, {}, "https://example.com/_emdash/device");
if (!codeResult.success) return;
await handleDeviceAuthorize(db, "user-1", Role.ADMIN, {
diff --git a/packages/core/tests/unit/mcp/authorization.test.ts b/packages/core/tests/unit/mcp/authorization.test.ts
index 3b34bac..9029896 100644
--- a/packages/core/tests/unit/mcp/authorization.test.ts
+++ b/packages/core/tests/unit/mcp/authorization.test.ts
@@ -8,10 +8,10 @@
* authInfo to simulate different users and roles.
*/
-import { Client } from "@modelcontextprotocol/sdk/client/index.js";
-import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
import { Role } from "@emdash-cms/auth";
import type { RoleLevel } from "@emdash-cms/auth";
+import { Client } from "@modelcontextprotocol/sdk/client/index.js";
+import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { EmDashHandlers } from "../../../src/astro/types.js";
diff --git a/packages/core/tests/unit/media/normalize.test.ts b/packages/core/tests/unit/media/normalize.test.ts
index 2697f70..b358a30 100644
--- a/packages/core/tests/unit/media/normalize.test.ts
+++ b/packages/core/tests/unit/media/normalize.test.ts
@@ -77,10 +77,7 @@ describe("normalizeMediaValue", () => {
});
it("falls back to external for internal URL when local provider unavailable", async () => {
- const result = await normalizeMediaValue(
- "/_emdash/api/media/file/01ABC.jpg",
- getProvider({}),
- );
+ const result = await normalizeMediaValue("/_emdash/api/media/file/01ABC.jpg", getProvider({}));
expect(result).toEqual({
provider: "external",
id: "",
diff --git a/packages/marketplace/wrangler.jsonc b/packages/marketplace/wrangler.jsonc
index e2ffe13..5f67a98 100644
--- a/packages/marketplace/wrangler.jsonc
+++ b/packages/marketplace/wrangler.jsonc
@@ -35,4 +35,4 @@
"class_name": "AuditWorkflow",
},
],
-}
\ No newline at end of file
+}
diff --git a/skills/creating-plugins/SKILL.md b/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/skills/creating-plugins/SKILL.md
+++ b/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/skills/creating-plugins/references/api-routes.md b/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/skills/creating-plugins/references/api-routes.md
+++ b/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/skills/wordpress-plugin-to-emdash/SKILL.md b/skills/wordpress-plugin-to-emdash/SKILL.md
index aaa23a1..5d22192 100644
--- a/skills/wordpress-plugin-to-emdash/SKILL.md
+++ b/skills/wordpress-plugin-to-emdash/SKILL.md
@@ -20,44 +20,44 @@ This skill maps WordPress concepts to their EmDash equivalents for plugin portin
### Content & Data
| WordPress | EmDash | Notes |
-| ----------------------- | ------------------------------------------- | --------------------------------------------- |
-| `register_post_type()` | `SchemaRegistry.createCollection()` | Via Admin API or seed file |
+| ----------------------- | ----------------------------------------- | --------------------------------------------- |
+| `register_post_type()` | `SchemaRegistry.createCollection()` | Via Admin API or seed file |
| `register_taxonomy()` | `_emdash_taxonomy_defs` table | Hierarchical or flat, attached to collections |
-| `register_meta()` / ACF | Collection fields via SchemaRegistry | All become typed schema fields |
-| `get_post_meta()` | `entry.data.fieldName` | Direct typed access |
-| `get_option()` | `getSiteSetting()` / `ctx.kv` | Site settings or plugin-namespaced KV |
+| `register_meta()` / ACF | Collection fields via SchemaRegistry | All become typed schema fields |
+| `get_post_meta()` | `entry.data.fieldName` | Direct typed access |
+| `get_option()` | `getSiteSetting()` / `ctx.kv` | Site settings or plugin-namespaced KV |
| `WP_Query` | `getEmDashCollection()` | Runtime queries with filters |
| `get_post($id)` | `getEmDashEntry(collection, slug)` | Returns entry or null |
| `wp_insert_post()` | `POST /_emdash/api/content/{type}` | REST API |
| `wp_update_post()` | `PUT /_emdash/api/content/{type}/{id}` | REST API |
| `wp_delete_post()` | `DELETE /_emdash/api/content/{type}/{id}` | Soft delete |
-| Custom tables | Plugin storage collections | `ctx.storage.collectionName.put/get/query` |
+| Custom tables | Plugin storage collections | `ctx.storage.collectionName.put/get/query` |
### Site Configuration
-| WordPress | EmDash | Notes |
+| WordPress | EmDash | Notes |
| ------------------------ | --------------------------- | ---------------------------------------- |
| `get_bloginfo('name')` | `getSiteSetting('title')` | From `options` table with `site:` prefix |
| `get_option('blogdesc')` | `getSiteSetting('tagline')` | Site settings API |
-| Theme Customizer | Site Settings admin page | `/_emdash/admin/settings` |
+| Theme Customizer | Site Settings admin page | `/_emdash/admin/settings` |
| `site_icon` | `getSiteSetting('favicon')` | Media reference |
| `custom_logo` | `getSiteSetting('logo')` | Media reference |
### Navigation Menus
-| WordPress | EmDash | Notes |
+| WordPress | EmDash | Notes |
| ---------------------- | --------------------------------------- | ----------------------------------- |
-| `register_nav_menu()` | Create menu via admin or seed | `_emdash_menus` table |
+| `register_nav_menu()` | Create menu via admin or seed | `_emdash_menus` table |
| `wp_nav_menu()` | `getMenu(name)` | Returns `{ items: MenuItem[] }` |
-| `wp_nav_menu_item` | `_emdash_menu_items` table | Type: custom, page, post, taxonomy |
+| `wp_nav_menu_item` | `_emdash_menu_items` table | Type: custom, page, post, taxonomy |
| `_menu_item_object_id` | `reference_id` + `reference_collection` | Links to content entries |
| Menu locations | Query by name in templates | No locations concept — direct query |
### Taxonomies
-| WordPress | EmDash | Notes |
+| WordPress | EmDash | Notes |
| --------------------- | --------------------------------------- | ------------------------------ |
-| `register_taxonomy()` | `_emdash_taxonomy_defs` table | Define via admin, seed, or API |
+| `register_taxonomy()` | `_emdash_taxonomy_defs` table | Define via admin, seed, or API |
| `get_terms()` | `getTaxonomyTerms(name)` | Returns tree for hierarchical |
| `get_the_terms()` | `getEntryTerms(collection, id, name)` | Terms for specific entry |
| `wp_set_post_terms()` | `TaxonomyRepository.setTermsForEntry()` | Replace terms for entry |
@@ -66,9 +66,9 @@ This skill maps WordPress concepts to their EmDash equivalents for plugin portin
### Widgets & Sidebars
-| WordPress | EmDash | Notes |
+| WordPress | EmDash | Notes |
| -------------------- | -------------------------------------- | ------------------------------- |
-| `register_sidebar()` | `_emdash_widget_areas` table | Create via admin or seed |
+| `register_sidebar()` | `_emdash_widget_areas` table | Create via admin or seed |
| `dynamic_sidebar()` | `getWidgetArea(name)` | Returns `{ widgets: Widget[] }` |
| `WP_Widget` class | Widget types: content, menu, component | Simplified — 3 types only |
| Text widget | `type: 'content'` + Portable Text | Rich text widget |
@@ -77,7 +77,7 @@ This skill maps WordPress concepts to their EmDash equivalents for plugin portin
### Admin UI
-| WordPress | EmDash | Notes |
+| WordPress | EmDash | Notes |
| ------------------------ | --------------------------------- | ---------------------------------------- |
| `add_menu_page()` | `admin.pages` in `definePlugin()` | Plugin config |
| `add_submenu_page()` | Nested admin pages | Parent determines hierarchy |
@@ -88,7 +88,7 @@ This skill maps WordPress concepts to their EmDash equivalents for plugin portin
### Hooks
-| WordPress | EmDash | Notes |
+| WordPress | EmDash | Notes |
| ---------------------------------- | --------------------------------------- | ----------------------------------------------------- |
| `add_action('init')` | `plugin:install` hook | Runs once on first install |
| `add_action('save_post')` | `content:afterSave` hook | Filter by `event.collection` |
@@ -100,7 +100,7 @@ This skill maps WordPress concepts to their EmDash equivalents for plugin portin
### Frontend Output
-| WordPress | EmDash | Notes |
+| WordPress | EmDash | Notes |
| ----------------------- | ---------------------------- | ---------------------------------------------------- |
| `add_shortcode()` | Portable Text custom block | Content → block. Template → component. Trusted only. |
| `register_block_type()` | PT block + `componentsEntry` | Block data → Astro component props. Trusted only. |
@@ -109,7 +109,7 @@ This skill maps WordPress concepts to their EmDash equivalents for plugin portin
### Plugin Storage
-| WordPress | EmDash | Notes |
+| WordPress | EmDash | Notes |
| ------------------------ | ------------------------ | ---------------------------------- |
| `get_option('plugin_*')` | `ctx.kv.get(key)` | Namespaced to plugin automatically |
| `update_option()` | `ctx.kv.set(key, value)` | Scoped KV storage |
diff --git a/skills/wordpress-theme-to-emdash/phases/2-design.md b/skills/wordpress-theme-to-emdash/phases/2-design.md
index 1ea2c0b..a9bad91 100644
--- a/skills/wordpress-theme-to-emdash/phases/2-design.md
+++ b/skills/wordpress-theme-to-emdash/phases/2-design.md
@@ -37,7 +37,7 @@ theme.json # Block themes (WP 5.9+) - structured design tokens
### CSS Variable Mapping
-| WP Pattern | EmDash Variable |
+| WP Pattern | EmDash Variable |
| ---------------- | ------------------ |
| Body font family | `--font-body` |
| Heading font | `--font-heading` |
diff --git a/skills/wordpress-theme-to-emdash/phases/4-dynamic.md b/skills/wordpress-theme-to-emdash/phases/4-dynamic.md
index ee8ab2f..9fb2255 100644
--- a/skills/wordpress-theme-to-emdash/phases/4-dynamic.md
+++ b/skills/wordpress-theme-to-emdash/phases/4-dynamic.md
@@ -7,13 +7,13 @@ Implement CMS-driven features: site settings, menus, taxonomies, and widgets.
Map WordPress customizer values to EmDash site settings:
| WP Customizer Setting | EmDash Site Setting |
-| --------------------- | --------------------- |
-| Site Title | `title` |
-| Tagline | `tagline` |
-| Site Icon | `favicon` |
-| Custom Logo | `logo` |
-| Posts per page | `postsPerPage` |
-| Date format | `dateFormat` |
+| --------------------- | ------------------- |
+| Site Title | `title` |
+| Tagline | `tagline` |
+| Site Icon | `favicon` |
+| Custom Logo | `logo` |
+| Posts per page | `postsPerPage` |
+| Date format | `dateFormat` |
```astro
---
@@ -134,7 +134,7 @@ const sidebar = await getWidgetArea("sidebar");
Map WP widgets to Astro components:
-| WP Widget | EmDash Component |
+| WP Widget | EmDash Component |
| ---------------- | ------------------- |
| Recent Posts | `core:recent-posts` |
| Categories | `core:categories` |
diff --git a/skills/wordpress-theme-to-emdash/references/astro-essentials.md b/skills/wordpress-theme-to-emdash/references/astro-essentials.md
index 92cef9b..b4ba0da 100644
--- a/skills/wordpress-theme-to-emdash/references/astro-essentials.md
+++ b/skills/wordpress-theme-to-emdash/references/astro-essentials.md
@@ -900,15 +900,15 @@ const { entry: page } = await getEmDashEntry("pages", "about");
### Key Differences
-| Aspect | Astro Collections | EmDash Collections |
-| ---------------------- | ------------------------------- | ----------------------------------------------- |
-| **Config file** | `src/content.config.ts` | `src/live.config.ts` |
-| **Schema definition** | In config file with Zod | In EmDash admin UI or seed file |
-| **Data source** | Files, APIs, custom loaders | SQLite database |
+| Aspect | Astro Collections | EmDash Collections |
+| ---------------------- | ------------------------------- | ------------------------------------------- |
+| **Config file** | `src/content.config.ts` | `src/live.config.ts` |
+| **Schema definition** | In config file with Zod | In EmDash admin UI or seed file |
+| **Data source** | Files, APIs, custom loaders | SQLite database |
| **Query functions** | `getCollection()`, `getEntry()` | `getEmDashCollection()`, `getEmDashEntry()` |
-| **Content editing** | Edit source files directly | Admin UI or API |
-| **Type safety** | Generated from schema | Runtime validation |
-| **Rendering Markdown** | `render()` from `astro:content` | `` component |
+| **Content editing** | Edit source files directly | Admin UI or API |
+| **Type safety** | Generated from schema | Runtime validation |
+| **Rendering Markdown** | `render()` from `astro:content` | `` component |
### When to Use Which
diff --git a/skills/wordpress-theme-to-emdash/references/concept-mapping.md b/skills/wordpress-theme-to-emdash/references/concept-mapping.md
index 5ebe849..7f628ff 100644
--- a/skills/wordpress-theme-to-emdash/references/concept-mapping.md
+++ b/skills/wordpress-theme-to-emdash/references/concept-mapping.md
@@ -2,7 +2,7 @@
## Template Hierarchy
-| WP Template | Purpose | EmDash Equivalent |
+| WP Template | Purpose | EmDash Equivalent |
| ------------------------- | ----------------------- | ------------------------------------------------------- |
| `index.php` | Fallback for everything | `src/pages/index.astro` |
| `front-page.php` | Static front page | `src/pages/index.astro` |
@@ -26,7 +26,7 @@
## Template Parts
-| WP Pattern | EmDash Pattern |
+| WP Pattern | EmDash Pattern |
| ---------------------------------------------------------- | ---------------------------- |
| `get_template_part('content', 'post')` | `` component |
| `get_template_part('template-parts/header/site-branding')` | `` component |
@@ -116,10 +116,10 @@ EmDash: Create collection via admin UI or API. The collection will be created du
### Content Retrieval
-| WP Function | EmDash Equivalent |
+| WP Function | EmDash Equivalent |
| ----------------------------- | ------------------------------------------------- |
-| `have_posts()` / `the_post()` | `getEmDashCollection()` |
-| `get_post()` | `getEmDashEntry()` |
+| `have_posts()` / `the_post()` | `getEmDashCollection()` |
+| `get_post()` | `getEmDashEntry()` |
| `the_title()` | `post.data.title` |
| `the_content()` | `` |
| `the_excerpt()` | `post.data.excerpt` |
@@ -132,7 +132,7 @@ EmDash: Create collection via admin UI or API. The collection will be created du
### Taxonomies
-| WP Function | EmDash Equivalent |
+| WP Function | EmDash Equivalent |
| ---------------------------- | -------------------------------------------------- |
| `get_categories()` | `getTaxonomyTerms("categories")` |
| `get_tags()` | `getTaxonomyTerms("tags")` |
@@ -149,7 +149,7 @@ EmDash supports hierarchical taxonomies (like categories) and flat taxonomies (l
### Site Info
-| WP Function | EmDash Equivalent |
+| WP Function | EmDash Equivalent |
| ------------------------- | --------------------------------------- |
| `bloginfo('name')` | `getSiteSetting("title")` |
| `bloginfo('description')` | `getSiteSetting("tagline")` |
@@ -173,7 +173,7 @@ EmDash supports hierarchical taxonomies (like categories) and flat taxonomies (l
### Media
-| WP Function | EmDash Equivalent |
+| WP Function | EmDash Equivalent |
| --------------------------- | -------------------------- |
| `wp_get_attachment_image()` | `
` |
| `wp_get_attachment_url()` | `media.url` |
@@ -181,7 +181,7 @@ EmDash supports hierarchical taxonomies (like categories) and flat taxonomies (l
### Navigation
-| WP Function | EmDash Equivalent |
+| WP Function | EmDash Equivalent |
| ------------------------ | ------------------------------------- |
| `wp_nav_menu()` | `getMenu("menu-name")` + render items |
| `wp_list_pages()` | Query pages collection or use menu |
@@ -198,10 +198,10 @@ WordPress hooks don't have direct equivalents. Most hook functionality becomes:
3. **Build-time logic** - In Astro config or components
| WP Hook | EmDash Approach |
-| -------------------- | ------------------------------------------ |
-| `wp_head` | Add to `` in layout |
-| `wp_footer` | Add before `` in layout |
-| `the_content` filter | PortableText components |
+| -------------------- | ---------------------------------------- |
+| `wp_head` | Add to `` in layout |
+| `wp_footer` | Add before `` in layout |
+| `the_content` filter | PortableText components |
| `pre_get_posts` | Query filters in `getEmDashCollection()` |
| `save_post` | EmDash plugin hook: `content:beforeSave` |
@@ -280,14 +280,14 @@ sidebar?.widgets.forEach((widget) => {
### Widget Types
-| WP Widget | EmDash Widget Type | Notes |
+| WP Widget | EmDash Widget Type | Notes |
| ------------ | ------------------------------- | ----------------------------- |
| Text/HTML | `content` | Portable Text (rich content) |
| Custom Menu | `menu` | References menu by name |
| Recent Posts | `component` `core:recent-posts` | Built-in component with props |
| Categories | `component` `core:categories` | Built-in component |
| Tag Cloud | `component` `core:tag-cloud` | Built-in component |
-| Search | `` component | Use `emdash/ui` LiveSearch |
+| Search | `` component | Use `emdash/ui` LiveSearch |
| Archives | `component` `core:archives` | Built-in component |
### Core Widget Components
@@ -358,7 +358,7 @@ const results = query ? await search(query, { limit: 20 }) : { results: [] };
### Search Features
-| WordPress | EmDash |
+| WordPress | EmDash |
| ---------------------------- | ------------------------------- |
| Basic keyword search | FTS5 with Porter stemming |
| Search all public post types | Per-collection search enable |
diff --git a/skills/wordpress-theme-to-emdash/references/design-extraction.md b/skills/wordpress-theme-to-emdash/references/design-extraction.md
index 5ec90b5..bf2d2e8 100644
--- a/skills/wordpress-theme-to-emdash/references/design-extraction.md
+++ b/skills/wordpress-theme-to-emdash/references/design-extraction.md
@@ -104,7 +104,7 @@ Common elements to check:
### Common Color Mapping
-| WP Pattern | EmDash Variable |
+| WP Pattern | EmDash Variable |
| ---------------- | ------------------- |
| Background | `--color-base` |
| Text | `--color-contrast` |
diff --git a/templates/blank/.agents/skills/creating-plugins/SKILL.md b/templates/blank/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/blank/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/blank/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/blank/.agents/skills/creating-plugins/references/api-routes.md b/templates/blank/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/blank/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/blank/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/blank/AGENTS.md b/templates/blank/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/blank/AGENTS.md
+++ b/templates/blank/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/blank/tsconfig.json b/templates/blank/tsconfig.json
index 0217fb1..0903753 100644
--- a/templates/blank/tsconfig.json
+++ b/templates/blank/tsconfig.json
@@ -1,13 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
- "types": [
- "node"
- ]
+ "types": ["node"]
},
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts"]
+}
diff --git a/templates/blog-cloudflare/.agents/skills/creating-plugins/SKILL.md b/templates/blog-cloudflare/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/blog-cloudflare/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/blog-cloudflare/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/blog-cloudflare/.agents/skills/creating-plugins/references/api-routes.md b/templates/blog-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/blog-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/blog-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/blog-cloudflare/AGENTS.md b/templates/blog-cloudflare/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/blog-cloudflare/AGENTS.md
+++ b/templates/blog-cloudflare/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/blog-cloudflare/tsconfig.json b/templates/blog-cloudflare/tsconfig.json
index 0217fb1..0903753 100644
--- a/templates/blog-cloudflare/tsconfig.json
+++ b/templates/blog-cloudflare/tsconfig.json
@@ -1,13 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
- "types": [
- "node"
- ]
+ "types": ["node"]
},
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts"]
+}
diff --git a/templates/blog-cloudflare/wrangler.jsonc b/templates/blog-cloudflare/wrangler.jsonc
index fc62c7f..9eb7d0c 100644
--- a/templates/blog-cloudflare/wrangler.jsonc
+++ b/templates/blog-cloudflare/wrangler.jsonc
@@ -2,9 +2,7 @@
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-emdash-site",
"compatibility_date": "2026-02-24",
- "compatibility_flags": [
- "nodejs_compat"
- ],
+ "compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": "./dist",
},
@@ -22,4 +20,4 @@
"bucket_name": "my-emdash-media",
},
],
-}
\ No newline at end of file
+}
diff --git a/templates/blog/.agents/skills/creating-plugins/SKILL.md b/templates/blog/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/blog/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/blog/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/blog/.agents/skills/creating-plugins/references/api-routes.md b/templates/blog/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/blog/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/blog/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/blog/AGENTS.md b/templates/blog/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/blog/AGENTS.md
+++ b/templates/blog/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/blog/tsconfig.json b/templates/blog/tsconfig.json
index 0217fb1..0903753 100644
--- a/templates/blog/tsconfig.json
+++ b/templates/blog/tsconfig.json
@@ -1,13 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
- "types": [
- "node"
- ]
+ "types": ["node"]
},
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts"]
+}
diff --git a/templates/marketing-cloudflare/.agents/skills/creating-plugins/SKILL.md b/templates/marketing-cloudflare/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/marketing-cloudflare/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/marketing-cloudflare/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/marketing-cloudflare/.agents/skills/creating-plugins/references/api-routes.md b/templates/marketing-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/marketing-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/marketing-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/marketing-cloudflare/AGENTS.md b/templates/marketing-cloudflare/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/marketing-cloudflare/AGENTS.md
+++ b/templates/marketing-cloudflare/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/marketing/.agents/skills/creating-plugins/SKILL.md b/templates/marketing/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/marketing/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/marketing/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/marketing/.agents/skills/creating-plugins/references/api-routes.md b/templates/marketing/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/marketing/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/marketing/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/marketing/AGENTS.md b/templates/marketing/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/marketing/AGENTS.md
+++ b/templates/marketing/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/portfolio-cloudflare/.agents/skills/creating-plugins/SKILL.md b/templates/portfolio-cloudflare/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/portfolio-cloudflare/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/portfolio-cloudflare/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/portfolio-cloudflare/.agents/skills/creating-plugins/references/api-routes.md b/templates/portfolio-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/portfolio-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/portfolio-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/portfolio-cloudflare/AGENTS.md b/templates/portfolio-cloudflare/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/portfolio-cloudflare/AGENTS.md
+++ b/templates/portfolio-cloudflare/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/portfolio/.agents/skills/creating-plugins/SKILL.md b/templates/portfolio/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/portfolio/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/portfolio/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/portfolio/.agents/skills/creating-plugins/references/api-routes.md b/templates/portfolio/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/portfolio/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/portfolio/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/portfolio/AGENTS.md b/templates/portfolio/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/portfolio/AGENTS.md
+++ b/templates/portfolio/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/starter-cloudflare/.agents/skills/creating-plugins/SKILL.md b/templates/starter-cloudflare/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/starter-cloudflare/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/starter-cloudflare/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/starter-cloudflare/.agents/skills/creating-plugins/references/api-routes.md b/templates/starter-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/starter-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/starter-cloudflare/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/starter-cloudflare/AGENTS.md b/templates/starter-cloudflare/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/starter-cloudflare/AGENTS.md
+++ b/templates/starter-cloudflare/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/starter-cloudflare/tsconfig.json b/templates/starter-cloudflare/tsconfig.json
index 0217fb1..0903753 100644
--- a/templates/starter-cloudflare/tsconfig.json
+++ b/templates/starter-cloudflare/tsconfig.json
@@ -1,13 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
- "types": [
- "node"
- ]
+ "types": ["node"]
},
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts"]
+}
diff --git a/templates/starter-cloudflare/wrangler.jsonc b/templates/starter-cloudflare/wrangler.jsonc
index fc62c7f..9eb7d0c 100644
--- a/templates/starter-cloudflare/wrangler.jsonc
+++ b/templates/starter-cloudflare/wrangler.jsonc
@@ -2,9 +2,7 @@
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-emdash-site",
"compatibility_date": "2026-02-24",
- "compatibility_flags": [
- "nodejs_compat"
- ],
+ "compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": "./dist",
},
@@ -22,4 +20,4 @@
"bucket_name": "my-emdash-media",
},
],
-}
\ No newline at end of file
+}
diff --git a/templates/starter/.agents/skills/creating-plugins/SKILL.md b/templates/starter/.agents/skills/creating-plugins/SKILL.md
index 5dc53d4..a9680dc 100644
--- a/templates/starter/.agents/skills/creating-plugins/SKILL.md
+++ b/templates/starter/.agents/skills/creating-plugins/SKILL.md
@@ -261,17 +261,17 @@ The `"."` export has the descriptor. The `"./sandbox"` export has the implementa
Each feature is optional. Add only what your plugin needs:
-| Feature | Where | Standard | Native | Purpose |
-| ------------------- | ---------------------------- | -------- | ------ | ------------------------------------------------------- |
-| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
-| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
-| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
+| Feature | Where | Standard | Native | Purpose |
+| ------------------- | ---------------------------- | -------- | ------ | ----------------------------------------------------- |
+| **Hooks** | `definePlugin({ hooks })` | Yes | Yes | React to content/media/lifecycle events |
+| **Storage** | descriptor `storage` | Yes | Yes | Document collections with indexed queries |
+| **KV** | `ctx.kv` in hooks/routes | Yes | Yes | Key-value store for internal state |
| **API Routes** | `definePlugin({ routes })` | Yes | Yes | REST endpoints at `/_emdash/api/plugins//` |
-| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
-| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
-| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
-| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
-| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
+| **Admin Pages** | Block Kit `admin` route | Yes | Yes | Admin pages via Block Kit (JSON blocks) |
+| **Widgets** | Block Kit `admin` route | Yes | Yes | Dashboard cards via Block Kit |
+| **React Admin** | `admin.entry` + React export | No | Yes | React-based admin pages and widgets (native only) |
+| **PT Blocks** | `admin.portableTextBlocks` | No | Yes | Custom block types in the Portable Text editor |
+| **Site Components** | `componentsEntry` | No | Yes | Astro components for rendering blocks on the site |
See the reference files for detailed syntax:
diff --git a/templates/starter/.agents/skills/creating-plugins/references/api-routes.md b/templates/starter/.agents/skills/creating-plugins/references/api-routes.md
index 941d688..c836fd6 100644
--- a/templates/starter/.agents/skills/creating-plugins/references/api-routes.md
+++ b/templates/starter/.agents/skills/creating-plugins/references/api-routes.md
@@ -66,8 +66,8 @@ definePlugin({
## Route URLs
-| Plugin ID | Route Name | URL |
-| --------- | --------------- | ------------------------------------------ |
+| Plugin ID | Route Name | URL |
+| --------- | --------------- | ---------------------------------------- |
| `forms` | `status` | `/_emdash/api/plugins/forms/status` |
| `forms` | `submissions` | `/_emdash/api/plugins/forms/submissions` |
| `seo` | `settings/save` | `/_emdash/api/plugins/seo/settings/save` |
diff --git a/templates/starter/AGENTS.md b/templates/starter/AGENTS.md
index b0a6556..9524aad 100644
--- a/templates/starter/AGENTS.md
+++ b/templates/starter/AGENTS.md
@@ -14,11 +14,11 @@ The admin UI is at `http://localhost:4321/_emdash/admin`.
| File | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
-| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
-| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
+| `astro.config.mjs` | Astro config with `emdash()` integration, database, and storage |
+| `src/live.config.ts` | EmDash loader registration (boilerplate -- don't modify) |
| `seed/seed.json` | Schema definition + demo content (collections, fields, taxonomies, menus, widgets) |
-| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
-| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
+| `emdash-env.d.ts` | Generated types for collections (auto-regenerated on dev server start) |
+| `src/layouts/Base.astro` | Base layout with EmDash wiring (menus, search, page contributions) |
| `src/pages/` | Astro pages -- all server-rendered |
## Skills
diff --git a/templates/starter/tsconfig.json b/templates/starter/tsconfig.json
index 0217fb1..0903753 100644
--- a/templates/starter/tsconfig.json
+++ b/templates/starter/tsconfig.json
@@ -1,13 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
- "types": [
- "node"
- ]
+ "types": ["node"]
},
- "include": [
- "src",
- ".astro/types.d.ts",
- "emdash-env.d.ts"
- ]
-}
\ No newline at end of file
+ "include": ["src", ".astro/types.d.ts", "emdash-env.d.ts"]
+}