@enfyra/mcp-server 0.0.111 → 0.0.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enfyra/mcp-server",
3
- "version": "0.0.111",
3
+ "version": "0.0.112",
4
4
  "description": "MCP server for Enfyra - manage Enfyra instances from MCP-compatible coding tools",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1531,7 +1531,7 @@ ensure_page_extension({
1531
1531
  name: "ReportsPage",
1532
1532
  description: "Reports dashboard",
1533
1533
  menuId: "<created-menu-id>",
1534
- code: "<template><section class=\\"min-h-full w-full space-y-4\\"><div class=\\"grid gap-4 md:grid-cols-3\\"><UCard><p class=\\"text-sm text-muted\\">Total</p><p class=\\"mt-2 text-2xl font-semibold\\">0</p></UCard></div></section></template><script setup>const { registerPageHeader } = usePageHeaderRegistry(); const { register: registerHeaderActions } = useHeaderActionRegistry(); registerPageHeader({ title: 'Reports', description: 'Operational report overview.', leadingIcon: 'lucide:bar-chart-3', gradient: 'cyan', variant: 'minimal' }); registerHeaderActions([{ id: 'refresh-reports', label: 'Refresh', icon: 'lucide:refresh-cw', onClick: () => {}, order: 0 }])</script>",
1534
+ code: "<template><section class=\\"min-h-full w-full space-y-4\\"><div class=\\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\\"><article class=\\"surface-card p-4\\"><p class=\\"text-sm font-medium text-[var(--text-tertiary)]\\">Total</p><p class=\\"mt-2 text-2xl font-semibold text-[var(--text-primary)]\\">0</p></article></div></section></template><script setup>const { registerPageHeader } = usePageHeaderRegistry(); const { register: registerHeaderActions } = useHeaderActionRegistry(); registerPageHeader({ title: 'Reports', description: 'Operational report overview.', leadingIcon: 'lucide:bar-chart-3', gradient: 'cyan', variant: 'minimal' }); registerHeaderActions([{ id: 'refresh-reports', label: 'Refresh', icon: 'lucide:refresh-cw', color: 'primary', variant: 'solid', onClick: () => {}, order: 0 }])</script>",
1535
1535
  isEnabled: true
1536
1536
  })`,
1537
1537
  notes: [
@@ -1546,7 +1546,11 @@ ensure_page_extension({
1546
1546
  'Put page-level actions in useHeaderActionRegistry or useSubHeaderActionRegistry, destructure register first, then call it with one action or an array.',
1547
1547
  'Page extensions should be full-bleed by default and responsive from the first version.',
1548
1548
  'The extension root is already inside Enfyra admin page main; do not add root-level page padding.',
1549
- 'Use existing eApp theme variables for panels, rows, badges, borders, and text. Pair border/divide utilities with border-[var(--border-default)] or divide-[var(--border-default)] so light and dark themes stay consistent.',
1549
+ 'Use existing eApp theme variables for panels, rows, badges, borders, controls, radius, and text. Pair border/divide utilities with border-[var(--border-default)] or divide-[var(--border-default)] so light and dark themes stay consistent.',
1550
+ 'Treat primary color as runtime-configurable: use UButton color="primary", var(--brand-*), --action-primary-*, and --badge-primary-* instead of hardcoded violet/purple/cyan.',
1551
+ 'For general card grids inside the shell, use md:grid-cols-2 xl:grid-cols-3 instead of lg:grid-cols-3 because the desktop sidebar leaves tablet-width content at 1024px.',
1552
+ 'Do not use Nuxt UI neutral semantic classes such as bg-default, text-muted, text-dimmed, border-default, or divide-default inside extension code; use eApp tokens/classes.',
1553
+ 'Do not pass ui.content: "surface-card" to UModal/CommonModal; modal content uses the app modal surface and caller content classes should only append z-index or width.',
1550
1554
  'Do not inject global CSS, create theme guards, redefine the app palette, or solve one extension by overriding the whole app shell.',
1551
1555
  'Keep list selection local and fetch detail rows only; do not refetch the whole list after a row click unless the list data changed.',
1552
1556
  'Page extension paths are admin app UI routes. Do not verify them with test_rest_endpoint against ENFYRA_API_URL unless inspect_route shows an API route with the same path.',
@@ -1558,16 +1562,16 @@ ensure_page_extension({
1558
1562
  code: `// Create reusable/bulky sections as widget extension records first.
1559
1563
  const reportStatusWidgetCode = \`
1560
1564
  <template>
1561
- <section class="rounded-xl border border-default bg-default p-4">
1565
+ <section class="surface-card p-4">
1562
1566
  <div class="flex items-start justify-between gap-3">
1563
1567
  <div>
1564
- <p class="text-sm text-muted">Total reports</p>
1565
- <p class="mt-2 text-2xl font-semibold">{{ total }}</p>
1566
- <p class="mt-1 text-xs text-muted">{{ latestLabel }}</p>
1568
+ <p class="text-sm font-medium text-[var(--text-tertiary)]">Total reports</p>
1569
+ <p class="mt-2 text-2xl font-semibold text-[var(--text-primary)]">{{ total }}</p>
1570
+ <p class="mt-1 text-xs text-[var(--text-tertiary)]">{{ latestLabel }}</p>
1567
1571
  </div>
1568
1572
  <UButton type="button" color="neutral" variant="outline" @click.stop.prevent="emit('refresh')">Refresh</UButton>
1569
1573
  </div>
1570
- <UButton v-if="hasLatest" type="button" class="mt-3" color="primary" variant="soft" @click.stop.prevent="openLatest">Open latest</UButton>
1574
+ <UButton v-if="hasLatest" type="button" class="mt-3" color="primary" variant="solid" @click.stop.prevent="openLatest">Open latest</UButton>
1571
1575
  </section>
1572
1576
  </template>
1573
1577
 
@@ -297,18 +297,37 @@ function getExtensionThemeContract() {
297
297
  'The extension is already mounted inside the Enfyra app shell. Do not add a duplicate page header, centered page wrapper, or root-level page padding.',
298
298
  'Page extensions should be full-bleed, responsive, and split large operations into focused pages or UTabs.',
299
299
  'Use usePageHeaderRegistry for the shell title and useHeaderActionRegistry/useSubHeaderActionRegistry for page actions.',
300
+ 'For detail/form workflows that should stay left-aligned with empty space on the right, wrap the body in eapp-page-constrained; use eapp-page-constrained-wide only when the workflow genuinely needs more width.',
301
+ 'Card/list grids inside the default shell must account for the 280px desktop sidebar. Do not switch general card grids to three columns at lg; use md:grid-cols-2 xl:grid-cols-3 unless a local container proves three columns have enough width.',
300
302
  ],
301
303
  theme: [
302
- 'Use existing eApp theme variables/classes, not hardcoded light or dark colors.',
304
+ 'Use existing eApp theme variables/classes, not hardcoded light or dark colors. The app theme source of truth is CSS variables, including --brand-*, --surface-*, --card-*, --control-*, --action-*, --badge-*, --radius-*, --border-*, and --text-*.',
305
+ 'Primary color is runtime-configurable and first-class. Use UButton color="primary", var(--brand-*), --action-primary-*, --state-primary-*, and --badge-primary-* instead of hardcoded violet/purple/cyan values.',
303
306
  'Do not inject global CSS, create theme guards, redefine the app palette, or solve one extension by overriding the whole app shell.',
304
- 'For dynamic admin extensions, prefer the eApp CSS variables already present in the app: var(--surface-default), var(--surface-muted), var(--border-default), var(--text-primary), var(--text-secondary), and var(--text-tertiary).',
305
- 'Never use bare border/divide-y for panels or rows: pair them with border-[var(--border-default)] or divide-[var(--border-default)]. Avoid border-black, black, slate-only, gray-only, and dark-only palettes.',
306
- 'Status colors must remain readable in both themes; warning badges need high contrast text and a visible but not harsh border/background.',
307
+ 'For panels/cards, prefer surface-card, surface-card-hover, surface-muted, or explicit token classes such as bg-[var(--card-bg)] border-[var(--card-border)] shadow-[var(--card-shadow)]. Use text-[var(--text-primary|secondary|tertiary)] for copy.',
308
+ 'Never use Nuxt UI neutral semantic classes such as bg-default, bg-muted, border-default, divide-default, text-muted, text-dimmed, or hardcoded dark palettes such as dark:bg-zinc-950, bg-slate-*, text-gray-*, border-black, or black.',
309
+ 'Never use bare border/divide-y for panels or rows: pair them with border-[var(--border-default)] or divide-[var(--border-default)].',
310
+ 'Use radius tokens or mapped rounded utilities consistently: --radius-card for cards, --radius-panel for nested panels, --radius-control for buttons/inputs, --radius-subcontrol for compact inner controls, and --radius-pill for pills.',
311
+ 'Status colors must remain readable in both themes. Use badge tokens such as --badge-success-soft-*, --badge-warning-soft-*, --badge-danger-soft-*, --badge-info-soft-*, --badge-neutral-soft-*, and --badge-primary-soft-* instead of neon translucent colors.',
312
+ 'Keep dark and light contrast comparable. Do not make dark mode more neon or lower-contrast than light mode; prefer muted soft backgrounds with clear text and visible borders.',
313
+ ],
314
+ components: [
315
+ 'Use Nuxt UI/eApp components for normal controls: UButton, UInput, UTextarea, USelectMenu/USelect, USwitch, UCheckbox, UTabs, UBadge, UModal, and CommonDrawer when available.',
316
+ 'Buttons should have stable geometry: hover may change color, border, or shadow but must not move the button or resize its content. Disabled buttons keep disabled cursor/visual state.',
317
+ 'Inputs and textareas should not add hover movement or decorative hover states; focus, invalid, disabled, and loading states must be explicit.',
318
+ 'Dynamic extensions resolve UModal to the app CommonModal. Do not pass ui.content: "surface-card" to UModal/CommonModal; modal content uses the app modal surface and caller ui.content should only append z-index, width, or max-width classes.',
319
+ 'Use CommonDrawer for side-panel editing. Open drawers immediately on user action and render loading/error/content inside the drawer instead of waiting for fetch before opening.',
320
+ 'Use UBadge or token-backed badge spans for status. Keep badges legible in both themes with tokenized background, text, and border.',
321
+ ],
322
+ loadingAndLists: [
323
+ 'For first load of card/list pages, render calm skeleton cards with a slow pulse. For subsequent pagination/filter refreshes, keep the card shells mounted and skeletonize card content until the new list is ready.',
324
+ 'Keep pagination inside the same transition/loading branch as the list. Do not show pagination before the list content has left loading.',
325
+ 'Use bounded pagination for operational lists. Do not replace pagination with arbitrary fixed caps such as 30 or 50.',
326
+ 'Empty states should use an app-matched card surface with compact icon tile, title, and description; do not use huge blank white panels or naked UEmpty chrome on page surfaces.',
307
327
  ],
308
328
  interaction: [
309
329
  'Every mutating button needs pending/disabled state, success/error feedback, and must close or update its modal when the operation completes.',
310
330
  'Do not refetch broad lists after selecting one row. Keep local selection state and fetch only the detail or mutation result needed.',
311
- 'Use bounded pagination for operational lists. Do not replace pagination with arbitrary fixed caps such as 30 or 50.',
312
331
  'Customer-facing toasts must describe the operation. Do not surface raw job ids, flow ids, or worker ids.',
313
332
  ],
314
333
  security: [
@@ -316,7 +335,7 @@ function getExtensionThemeContract() {
316
335
  'UI checks are only guidance; handlers/hooks must independently enforce owner/root-admin authorization.',
317
336
  'Use the most specific business route or MCP tool. Do not write directly to raw tables when a domain route exists.',
318
337
  ],
319
- compactExample: '<template><section class="min-h-full w-full space-y-4"><div class="rounded-lg border border-[var(--border-default)] bg-[var(--surface-default)]"><div class="border-b border-[var(--border-default)] px-4 py-3"><h2 class="text-base font-semibold text-[var(--text-primary)]">Title</h2><p class="text-sm text-[var(--text-tertiary)]">Short operational context.</p></div><div class="divide-y divide-[var(--border-default)]"><button class="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-[var(--surface-muted)]"><span class="text-sm font-medium text-[var(--text-primary)]">Row</span><span class="text-sm text-[var(--text-tertiary)]">Open</span></button></div></div></section></template>',
338
+ compactExample: '<template><section class="min-h-full w-full space-y-4"><div class="surface-card"><div class="border-b border-[var(--border-default)] px-4 py-3"><h2 class="text-base font-semibold text-[var(--text-primary)]">Title</h2><p class="text-sm text-[var(--text-tertiary)]">Short operational context.</p></div><div class="divide-y divide-[var(--border-default)]"><button class="flex w-full cursor-pointer items-center justify-between px-4 py-3 text-left transition-colors hover:bg-[var(--surface-muted)] disabled:cursor-not-allowed disabled:opacity-60"><span class="text-sm font-medium text-[var(--text-primary)]">Row</span><span class="rounded-[var(--radius-pill)] bg-[var(--badge-primary-soft-bg)] px-2 py-0.5 text-xs font-semibold text-[var(--badge-primary-soft-text)] ring-1 ring-inset ring-[var(--badge-primary-soft-border)]">Open</span></button></div></div></section></template>',
320
339
  };
321
340
  }
322
341