Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';

const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');

const repoRoot = path.resolve(__dirname, '..', '..', '..', '..');

function read(relativePath) {
return fs.readFileSync(path.join(repoRoot, relativePath), 'utf8');
}

test('shared rules prioritize user-directed visual design over MDA defaults', () => {
const rules = read('plugins/model-apps/references/rules.md');

assert.match(rules, /User design direction overrides default MDA styling/);
assert.match(rules, /User-provided screenshot or mockup[\s\S]+Fluent\/MDA defaults only when no direction exists/);
assert.match(rules, /Explicit design values may use CSS[\s\S]+literals or custom properties/);
});

test('create planning records a concrete design-fidelity contract', () => {
const planner = read('plugins/model-apps/agents/genpage-planner.md');
const schema = read('plugins/model-apps/references/plan-schema.md');

assert.match(planner, /capture it as a hard requirement/);
assert.match(planner, /Do not silently[\s\S]+fall back to MDA styling/);
assert.match(schema, /Design source:/);
assert.match(schema, /Fidelity notes:/);
});

test('single-page and multi-page builders enforce the same design precedence', () => {
const skill = read('plugins/model-apps/skills/genpage/SKILL.md');
const builder = read('plugins/model-apps/agents/genpage-page-builder.md');

assert.match(skill, /Treat `## Design Preferences` as acceptance criteria/);
assert.match(builder, /Treat the plan's Design Preferences as acceptance criteria/);
assert.match(builder, /rather[\s\S]+than normalizing the result to stock Fluent\/MDA/);
});

test('edit planning and execution preserve requested visual identity', () => {
const planner = read('plugins/model-apps/agents/genpage-edit-planner.md');
const editFlow = read('plugins/model-apps/skills/genpage/edit-flow.md');

assert.match(planner, /### Design Fidelity/);
assert.match(planner, /Preserve functionality, not obsolete visual defaults/);
assert.match(editFlow, /visual requirements in the approved[\s\S]+override default MDA styling/);
assert.match(editFlow, /do not normalize the[\s\S]+page back to stock MDA/);
});
6 changes: 6 additions & 0 deletions plugins/model-apps/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ All notable changes to the **model-apps** plugin.
Local-dev ergonomics, sample coverage, and an automated eval suite with
real and synthetic fixtures. Builds on v2.1; no breaking changes.

### Changed
- `/genpage` now treats user-provided screenshots, website/brand references, and
text styling descriptions as design acceptance criteria across create and edit
flows. Fluent UI remains the accessible component foundation, but no longer
implies resetting explicit visual direction to default model-driven app styling.

### Added
- **Phase 0.5 — local-dev manifest.** Working dirs now get `package.json`
and `genpage.d.ts` so `npm install` + editor IntelliSense work after
Expand Down
28 changes: 24 additions & 4 deletions plugins/model-apps/agents/genpage-edit-planner.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ Read the full source. Identify:
- **Data access:** is `dataApi` used? Which entities? Which columns?
- **Components in use:** Fluent UI V9 components, any D3.js charts, etc.
- **Styling approach:** `makeStyles` + tokens, layout (flex/grid)
- **Visual identity:** palette, typography, density, radii, borders/shadows, imagery,
and whether the current page follows MDA defaults or a distinct design language
- **Accessibility:** existing ARIA labels, keyboard handling

### 1d. `RuntimeTypes.ts` (optional)
Expand Down Expand Up @@ -115,8 +117,16 @@ Ask questions via `AskUserQuestion`, one at a time:
> code-only changes. Would you like to continue with code-only edits?"
- If code-only: continue.

4. **"Any specific requirements for the changes?"** — styling, accessibility,
behavior, or preservation constraints not yet covered.
4. **"Any specific requirements for the changes?"** — styling or design reference
(screenshot/mockup, website/brand, or text description), accessibility, behavior,
or preservation constraints not yet covered.
- Treat new visual direction as a hard requirement and record concrete layout,
palette, typography, density, shape, borders/shadows, imagery, and interaction
details in Design Notes.
- When the edit is a visual redesign, the new direction overrides the original
page's MDA styling. Preserve functionality, not obsolete visual defaults.
- If a website reference cannot be inspected, ask for a screenshot or concrete
style details rather than falling back to MDA styling.

> **Connector data changes** (SharePoint, weather, Office 365, SQL, custom REST):
> if the edit adds, replaces, or removes connector-backed data, capture it in the
Expand Down Expand Up @@ -152,6 +162,14 @@ Enter plan mode (`EnterPlanMode`) with:
### Preservation Constraints
- [What must remain unchanged — feature preservation, specific behaviors]

### Design Fidelity
- **Source:** [screenshot/mockup, website/brand reference, text description,
existing page, or "preserve current design"]
- **Must match:** [concrete hierarchy, layout, palette, typography, density, shape,
imagery, and interaction details]
- **Allowed deviations:** [accessibility/responsiveness/host-safety adjustments only,
or "none"]

### Risks
- [Any tension with the original prompt, or any risky aspects — or "None"]
```
Expand Down Expand Up @@ -203,8 +221,10 @@ Write `genpage-edit-plan.md` to the working directory root (NOT inside the
independently verifiable.>

## Design Notes
<Styling, accessibility, or behavior guidance the orchestrator should follow
when applying the changes.>
<Design source plus concrete hierarchy, layout, palette, typography, density, shape,
imagery, and interaction requirements. State that user-directed styling overrides
default MDA styling; list only the smallest deviations required for accessibility,
responsiveness, or genpage host safety. Include other behavior guidance.>

## Relevant Samples
<Optional. If a sample from ${PLUGIN_ROOT}/samples/ would help the
Expand Down
18 changes: 16 additions & 2 deletions plugins/model-apps/agents/genpage-page-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ Locate and extract:

- The **Per-Page Specification** subsection for your assigned page (purpose, entities,
features, components, layout, data binding, interactions)
- The **Design Preferences** section (styling, features, accessibility notes)
- The **Design Preferences** section (design source, concrete styling and fidelity
requirements, features, accessibility notes)
- The **Environment** section (languages for localization)
- The **Relevant Samples** table (which sample to read for your page)

Expand Down Expand Up @@ -159,6 +160,18 @@ Mark it as in_progress immediately.
Generate a complete, production-ready TypeScript file following ALL rules from
rules.md:

### Design Fidelity

Treat the plan's Design Preferences as acceptance criteria. User-provided screenshots,
mockups, website/brand references, and text styling descriptions override default MDA
visual conventions. Reproduce the specified hierarchy, layout, palette, typography,
density, radii, borders, shadows, imagery, and interaction states. Use Fluent UI V9
for supported components and accessible behavior, but style component slots with
`makeStyles` (including explicit CSS values or custom properties when required) rather
than normalizing the result to stock Fluent/MDA cards, command bars, form sections,
spacing, or blue accents. Only accessibility, responsiveness, and genpage host-safety
rules may require deviations; keep those deviations as small as possible.

### Component Structure

**Data mode = `dataverse`** — import types from RuntimeTypes:
Expand Down Expand Up @@ -231,7 +244,8 @@ export default GeneratedComponent;
- TimePicker from `@fluentui/react-timepicker-compat`
- **Single-file architecture** — all components, utilities, styles in one `.tsx` file
- **No external libraries** — only React, Fluent UI V9, approved Fluent icons, D3.js for charts
- **makeStyles with tokens** — no inline styles for static values
- **makeStyles** — no inline styles for static values. Use tokens for unspecified
defaults; preserve explicit design values with CSS literals/custom properties.
```typescript
const useStyles = makeStyles({
container: {
Expand Down
20 changes: 17 additions & 3 deletions plugins/model-apps/agents/genpage-planner.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,18 @@ when reporting the environment to the user.
- If entities: ask which entities and fields (use logical names — singular, lowercase)
- If mock data: confirm you'll generate realistic sample data

4. **"Any specific requirements?"** — styling, features (search, filtering, sorting),
accessibility, responsive behavior, interactions
4. **"Any specific requirements?"** — styling or design reference (screenshot/mockup,
existing website/brand, or text description), features (search, filtering, sorting),
accessibility, responsive behavior, interactions.
- If visual direction is provided, capture it as a hard requirement. Extract concrete
layout/hierarchy, palette, typography, density/spacing, shape, borders/shadows,
imagery/iconography, and interaction states instead of summarizing it as
"custom styling."
- If the user supplies only a website reference and it cannot be inspected with
available tools, ask for a screenshot or concrete style details. Do not silently
fall back to MDA styling.
- Do not ask for styling when the original request already provides enough visual
direction.

**Skip logic:**
- If the user provided a description with the `/genpage` command, skip question 2.
Expand Down Expand Up @@ -368,7 +378,11 @@ Enter plan mode (`EnterPlanMode`) and present:
- [list detected languages, or "English only — no localization needed"]

### Design
- [styling preferences, features, accessibility notes from requirements]
- Design source: [screenshot/mockup, website/brand reference, text description,
existing page, or "none — use Fluent defaults"]
- Fidelity requirements: [concrete layout, palette, typography, density, shape,
imagery, and interaction details that must survive code generation]
- [features and accessibility notes from requirements]
```

Then call `ExitPlanMode` to request user approval.
Expand Down
7 changes: 6 additions & 1 deletion plugins/model-apps/references/plan-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,14 @@ connector bindings." sentinel).]
- Connection references: [comma-separated connectionreference logical names to include, or "none"]

## Design Preferences
- Styling: [user's styling preferences — colors, theme, visual aesthetic]
- Design source: [screenshot/mockup, website/brand reference, text description,
existing page, or "none — use Fluent defaults"]
- Styling: [concrete visual requirements — layout/hierarchy, palette, typography,
density/spacing, radii, borders/shadows, imagery/iconography, and interaction states]
- Features: [specific features mentioned — search, filtering, sorting, navigation, etc.]
- Accessibility: [any specific accessibility requirements beyond WCAG AA defaults]
- Fidelity notes: [which details are essential to match; any smallest-necessary
deviations required for accessibility, responsiveness, or genpage host safety]

## Relevant Samples
| Page | Sample | Reason |
Expand Down
56 changes: 47 additions & 9 deletions plugins/model-apps/references/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ Comprehensive rules for generating generative page code. Read this file during c
4. **Limited Imports**: Only React, Fluent UI V9, FluentUI icons, and D3.js for charts
5. **DataAPI**: ONLY use when explicit TableRegistrations provided; otherwise use mocked data
6. **Entity Logical Names**: Use singular lowercase (e.g., `"account"` not `"accounts"`)
7. **Styling**: Use `makeStyles` with tokens; avoid inline styles except for dynamic values
7. **Styling**: Use `makeStyles`; avoid inline styles except for dynamic values. Theme
tokens are the default, not a visual constraint: when the user supplies a palette,
typography, spacing, shape, or other design values, encode those values in
`makeStyles` (or CSS custom properties) instead of replacing them with MDA defaults.
8. **Responsive Design**: Use flexbox and relative units; NEVER use `100vh`/`100vw`
9. **Icons — verified names only**: Import from `@fluentui/react-icons`; use unsized variants only (e.g., `AddRegular` not `Add24Regular`). Icon names are frequently hallucinated — names like `MedicalRegular`, `PawRegular`, `AnimalRabbitRegular`, `BirdRegular` do not exist. **Always Read `${PLUGIN_ROOT}/references/verified-icons.txt`** (~5000 names) and cross-check every icon import against that list. After writing, Grep your own output for `from "@fluentui/react-icons"` and verify each named import. If an icon you want is not in the list, pick the closest semantic substitute that is. Never guess a name.
10. **No External Libraries**: No routing libraries (React Router) or assumptions of implicit dependencies
Expand All @@ -25,6 +28,14 @@ Comprehensive rules for generating generative page code. Read this file during c
17. **No full-viewport modal scrims; prefer non-modal or in-page panels**: A default `<Dialog>` is `modalType="modal"` — it draws a `position: fixed` backdrop and traps focus across the whole window, which in the designer blankets the agent panel and locks the user out (they can't even ask the agent to remove it). Default dialogs to `modalType="non-modal"` **and** pass `mountNode`, or use an in-page absolutely-positioned panel. The page root must establish a containing block (`position: relative` + `contain: layout`) so even a fixed-position overlay is clipped to the page. Never size overlays to the viewport. See **Special Patterns > Dialogs and Overlays**.
18. **Never nest a `<Dialog>` inside another `<Dialog>`**: Stacked modal scrims and nested focus traps make dialogs impossible to dismiss reliably. Render sibling dialogs as separate top-level surfaces switched by state, never one `<Dialog>` as a child of another's JSX.
19. **All hooks above every early return — no conditional hook calls**: Detail/record pages crash with **minified React error #310** ("rendered more/fewer hooks than the previous render") on the *first* open of a record, then work on the second click. Cause: a hook — usually a `useMemo` deriving chart points or display rows from loaded data — sits *below* a loading/empty early return (`if (data.loading) return <Spinner/>`). On the first render data is still loading, the component early-returns and never reaches that `useMemo` (fewer hooks); when data arrives it renders past the return and calls the extra hook → the hook count differs between renders → #310. The "works the second time" intermittency (the cached render skips the loading branch) is the signature of this bug. **Fix:** place every `useMemo`/`useState`/`useEffect`/`useCallback` **above all early returns**, and make derived memos tolerate not-yet-loaded data (read from an always-initialized value, e.g. `data.rows ?? []`). Early returns are fine — they just must come *after* the last hook call. This is the React rules of hooks: never call a hook below a conditional `return`.
20. **User design direction overrides default MDA styling**: Treat screenshots,
mockups, website/brand references, and explicit text descriptions as requirements,
not suggestions. Match their visual hierarchy, layout, palette, typography, density,
radii, borders, shadows, and imagery as closely as the runtime permits. Fluent UI V9
remains the component/accessibility foundation; it does not require the page to look
like a stock model-driven app. Do not normalize a requested design into neutral cards,
standard form sections, command bars, default spacing, or the default blue accent.
Accessibility, responsiveness, and host-safety rules remain mandatory.

---

Expand Down Expand Up @@ -83,9 +94,16 @@ export default GeneratedComponent;
## Layout and Styling

### Design Principles
- Follow Microsoft Fluent Design System principles
- When the user gives no visual direction, follow Microsoft Fluent Design System
principles and the host theme.
- When the user gives visual direction, preserve it. Use Fluent components for
behavior and accessibility, then style their slots with `makeStyles` to achieve the
requested appearance.
- Use sentence case for all text
- Use theme tokens (e.g., `tokens.spacingVerticalXL`, `tokens.colorNeutralBackground1`)
- Use theme tokens (e.g., `tokens.spacingVerticalXL`,
`tokens.colorNeutralBackground1`) as defaults. Explicit design values may use CSS
literals or custom properties in `makeStyles`; do not substitute a near-enough token
when that substitution materially changes the requested design.
- `makeStyles` for styling; inline styles only for dynamic values
- Group content in sections for visual separation

Expand Down Expand Up @@ -138,12 +156,32 @@ const useStyles = makeStyles({
- Provide back/forward navigation for wizard flows
- No React Router or hash/history API routing

### User-Provided Mockups/Screenshots
- When user provides mockups, those take precedence for layout, structure, and visual design
- Follow the provided design closely while adapting to Fluent UI V9 components
- Maintain all technical constraints: accessibility (ARIA, keyboard nav, WCAG AA), responsive design, proper semantic HTML
- If the mockup conflicts with accessibility or responsive design requirements, prioritize accessibility while staying as close to the visual design as possible
- Translate design elements to equivalent Fluent UI components (e.g., custom buttons -> Fluent Button with appropriate styling)
### User-Directed Visual Design

Use this precedence order:

1. User-provided screenshot or mockup
2. User-provided website or brand reference
3. Explicit text description of the desired style
4. Existing page style for edits, unless the user asks to replace it
5. Fluent/MDA defaults only when no direction exists

- Translate the source into concrete implementation decisions: page regions, visual
hierarchy, palette, typography, spacing/density, corner treatment, borders/shadows,
iconography, imagery, and interaction states.
- Follow the design closely while adapting controls to Fluent UI V9. "Use Fluent UI"
means use supported components and accessible behavior; it does **not** mean reset
the visual treatment to default Fluent/MDA styling.
- Do not add generic MDA chrome that is absent from the reference, such as a stock
command bar, neutral section cards, or standard form-style field groups.
- If a website reference cannot be inspected, ask for a screenshot or concrete style
details during planning. Never claim fidelity to a reference that was not available.
- Maintain accessibility (ARIA, keyboard navigation, WCAG AA), responsive behavior,
semantic HTML, and genpage host constraints. If those conflict with the reference,
make the smallest necessary deviation and preserve the rest of the design.
- Translate custom controls to equivalent Fluent components and style their slots
(for example, a branded button becomes a Fluent `Button` with matching colors,
typography, radius, border, and interaction states).

---

Expand Down
11 changes: 8 additions & 3 deletions plugins/model-apps/skills/genpage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,17 @@ subagent. Inline the page-builder workflow directly in the orchestrator:
`${PLUGIN_ROOT}/references/localization.md`
6. Read `genpage-plan.md` (already in working directory) and `RuntimeTypes.ts`
if Data mode is dataverse
7. Write the `.tsx` file to `<working-dir>/<filename>.tsx` following all rules
8. After writing, Grep every named import from `@fluentui/react-icons` against
7. Treat `## Design Preferences` as acceptance criteria. User screenshots, mockups,
website/brand references, and explicit text styling override default MDA visuals.
Preserve their concrete hierarchy, layout, palette, typography, density, shape,
imagery, and interaction states; use Fluent components for behavior/accessibility,
not as a reason to reset the design to stock MDA styling.
8. Write the `.tsx` file to `<working-dir>/<filename>.tsx` following all rules
9. After writing, Grep every named import from `@fluentui/react-icons` against
`${PLUGIN_ROOT}/references/verified-icons.txt` (one Grep per name).
Rewrite any unverified names with the closest verified alternative; do not
load the full icon list into context
9. Proceed to Phase 6
10. Proceed to Phase 6

This saves ~5-15s of Task overhead and ~3K tokens that would otherwise be
duplicated in a subagent context.
Expand Down
Loading
Loading