Skip to content
Open
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
30 changes: 22 additions & 8 deletions plugins/canvas-apps/agents/canvas-app-planner.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Read:

- `${PLUGIN_ROOT}/references/YamlSyntax.md` — file structure, syntax rules, parse-error triage
- `${PLUGIN_ROOT}/references/ControlGuide.md` — control selection, per-control properties, enums
- `${PLUGIN_ROOT}/references/LayoutGuide.md` — responsive layout, scrolling, colour contrast
- `${PLUGIN_ROOT}/references/LayoutGuide.md` — responsive layout, scrolling, color contrast
- `${PLUGIN_ROOT}/references/PowerFxGuide.md` — state, events, named formulas, mock data
- `${PLUGIN_ROOT}/references/DesignGuide.md` — aesthetic direction and design process
- `${PLUGIN_ROOT}/references/PlanTemplates.md` — the exact shape of every artifact you write
Expand Down Expand Up @@ -89,6 +89,13 @@ ManualLayout.
recorded, because the builder cannot look it up.
5. Call API and schema detail tools only for resources involved in the edit.

### Component refresh checkpoint

Immediately before auditing properties, re-run `describe_control` for
every Canvas or Code Component used by the plan to ensure any imported or updated components made in Studio are available.
Especially if a successful compile applied local component-definition changes, since the previous lookup.
Treat earlier component responses as stale; builders cannot refresh them.

## 3. Audit Control Properties

Before writing plans:
Expand Down Expand Up @@ -151,7 +158,7 @@ clear navigation is cheaper than a screen that no builder can write correctly in
and no user can scan. Prefer splitting by task (entry vs. history vs. analysis) rather
than by control count.

## 5. Specify the Narrow-Width Behaviour
## 5. Specify the Narrow-Width Behavior

Builders implement exactly what the brief specifies. If the brief describes only the
desktop composition, the screen will break on a phone — this is the most frequently
Expand All @@ -168,7 +175,7 @@ For every screen brief, state explicitly:
- That the root container scrolls (`LayoutOverflowY: =LayoutOverflow.Scroll`).
- That the screen-level `Children:` list contains only that root, with every visible
section nested under the root's `Children:` list.
- The foreground colour for text on every coloured surface, so nothing renders
- The foreground color for text on every colored surface, so nothing renders
dark-on-dark.
- A width or `LayoutMinWidth` for status badges and KPI values that fits the longest value
they can display.
Expand Down Expand Up @@ -244,6 +251,12 @@ Do not edit any `.pa.yaml` file. Put all required app-level edits in the plan in

If a group is empty, write `None` for it.

### All modes

Put requested screen or component-definition ordering in `## Editor State Changes` as
the exact final `ScreensOrder` and `ComponentDefinitionsOrder` lists. Write `None` when
the current Studio order should remain unchanged.

## 8. Write Progressive Plan Artifacts

Follow `${PLUGIN_ROOT}/references/PlanTemplates.md`.
Expand All @@ -257,6 +270,7 @@ Write only orchestration information:
- Compact discovery summary
- Dispatch table
- EDIT-mode App changes
- Editor state changes

The dispatch table columns are:

Expand Down Expand Up @@ -340,11 +354,11 @@ Planning complete.

| Action | Screen | Target File | YAML Key | Name Prefix | Screen Brief |
|--------|--------|-------------|----------|-------------|--------------|
| [Create / Modify] | [Screen] | [absolute file path] | [key] | [prefix] | [absolute brief path] |
| [Create / Modify] | [Screen] | `[working directory]/[file].pa.yaml` | [key] | [prefix] | `[working directory]/[file-base].screen-plan.md` |

Plan index: [absolute plan index path]
Shared plan: [absolute shared plan path]
App file: [[absolute App.pa.yaml path] for CREATE, "unchanged" for EDIT]
Plan index: `[working directory]/canvas-app-plan.md`
Shared plan: `[working directory]/canvas-app-shared.md`
App file: [`[working directory]/App.pa.yaml` for CREATE, "unchanged" for EDIT]
App compile: [Clean / diagnostics remaining, with detail]
```

Expand All @@ -354,7 +368,7 @@ App compile: [Clean / diagnostics remaining, with detail]
- Do not edit existing `.pa.yaml` files in EDIT mode.
- Call `compile_canvas` only to validate CREATE-mode `App.pa.yaml`. Do not use it to
chase screen-file diagnostics; the orchestrator owns full-app validation.
- Do not edit `[working directory]/_EditorState.pa.yaml`.
- Do not edit `[working directory]/_EditorState.pa.yaml`; record ordering work in `## Editor State Changes` for the top-level orchestrator.
- Do not embed all discovery output in the index or shared plan.
- Every screen brief must be self-sufficient when read with the shared plan.
- Never assign two screens the same control name prefix.
Expand Down
34 changes: 17 additions & 17 deletions plugins/canvas-apps/agents/canvas-screen-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ Your invocation includes:

- Action: `Create` or `Modify`
- Logical screen name
- Absolute target file under the working directory
- Absolute target file under `[working directory]`
- YAML screen key
- Control name prefix
- Shared plan: an absolute `canvas-app-shared.md` path
- Screen brief: an absolute `*.screen-plan.md` path
- Shared plan: `[working directory]/canvas-app-shared.md`
- Screen brief: an absolute `[working directory]/*.screen-plan.md` path

## 1. Read Only Assigned Context

Expand All @@ -37,7 +37,7 @@ Read:
2. The assigned screen brief
3. For `Modify`, the exact target `.pa.yaml`

Do not read `canvas-app-plan.md`, other screen briefs, or other screen YAML files.
Do not read `[working directory]/canvas-app-plan.md`, other screen briefs, or other screen YAML files.
Do not call discovery tools. The assigned documents contain all required context.

Before writing, verify that the screen brief includes definitions for every control type
Expand Down Expand Up @@ -66,10 +66,10 @@ Screens:
Screen1:
```

`Screen1.pa.yaml` always exists in a new app. When your target file already exists, the
create/write tool fails with `File already exists`. Read the file and replace its contents
with the edit tool instead — the action is still `Create` in the sense that you author the
whole screen.
`[working directory]/Screen1.pa.yaml` always exists in a new app. When your target file already exists,
`create` fails with `File already exists`. Read the file and replace its contents with
`edit` instead — the action is still `Create` in the sense that you author the whole
screen, but the tool call is `edit`.

Use meaningful child-control names derived from the logical screen, each carrying your
assigned control name prefix after the standard control-type abbreviation.
Expand Down Expand Up @@ -118,7 +118,7 @@ Do not fix unrelated pre-existing issues.
- Quote non-formula strings and YAML-sensitive formula values.
- Prefer the simplest correct formula.
- Write the file in as few tool calls as possible. Compose the complete screen, then write
it with one `Write` or one whole-file `Edit`. Dozens of incremental edits against a
it with one `create` or one whole-file `edit`. Dozens of incremental edits against a
file you keep re-reading is the dominant cost in this workflow and does not improve the
result.
- Keep the screen proportionate: roughly 40 controls is the practical ceiling for one
Expand All @@ -134,16 +134,16 @@ Do not fix unrelated pre-existing issues.

## 3. Self-QA

1. Read `${PLUGIN_ROOT}/references/QAChecks.md` **once** and keep it in context. It is a
long document; re-reading it between fixes is the largest avoidable cost in this role.
1. Read `${PLUGIN_ROOT}/references/QAChecks.md` **once** and keep it in context. It is a long document;
re-reading it between fixes is the largest avoidable cost in this role.
2. Re-read the target file.
3. Apply **every** check in order and fix issues inline. Checks are not optional and not
sampled: a check you skipped is a defect you shipped, and most of them have no compile
diagnostic behind them, so nothing downstream will catch it.
4. For Modify, scope checks to changed or added content.
5. Record an outcome for every check by number — `PASS`, `FIXED(n)` or `N/A` — as the
"Reporting" section in `${PLUGIN_ROOT}/references/QAChecks.md` describes. Report the
line; do not summarise it as a total.
5. Record an outcome for every check by number — `PASS`, `FIXED(n)` or `N/A` — as
`${PLUGIN_ROOT}/references/QAChecks.md` § "Reporting" describes. You report the line; do not
summarize it as a total.

Do not call `compile_canvas`; the orchestrator owns compilation. It compiles as soon as
the first builder returns, so return promptly rather than polishing indefinitely.
Expand All @@ -159,13 +159,13 @@ QA: 1 [outcome] · 2 [outcome] · …
Status: Done
```

The `QA:` line must list every check in `${PLUGIN_ROOT}/references/QAChecks.md`. A return
without it is incomplete, and the orchestrator will send the screen back.
The `QA:` line must list every check in `${PLUGIN_ROOT}/references/QAChecks.md`. A return without it is
incomplete, and the orchestrator will send the screen back.

## Constraints

- Modify exactly one screen file.
- Never edit `App.pa.yaml` or `_EditorState.pa.yaml`.
- Do not edit `[working directory]/App.pa.yaml` or `[working directory]/_EditorState.pa.yaml`; the top-level orchestrator owns app-level and cross-file ordering changes.
- Never substitute a filename, YAML key, or control name prefix.
- Never use a property absent from that control's definition.
- Never write a version suffix on a `Control:` value.
Expand Down
55 changes: 31 additions & 24 deletions plugins/canvas-apps/references/ControlGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Choosing a control type, and writing properties and enum values that the compile
## Contents

- Discover before you choose
- Interpret property defaults and requirements
- Layout containers
- Data display
- Selection controls — `ItemDisplayText` is a per-item formula
Expand All @@ -14,7 +15,7 @@ Choosing a control type, and writing properties and enum values that the compile
- Enum type names
- Enum member values
- Option set values
- Colour and button-state patterns
- Color and button-state patterns
- Timer lifecycle
- Read-only ancestors
- Cross-screen navigation
Expand All @@ -27,7 +28,26 @@ Choosing a control type, and writing properties and enum values that the compile
**⚠️ Required — not optional:** run `list_controls` before planning your layout. Controls
you don't know exist can't influence your design, and the catalog includes high-level
controls (`ModernTabList`, `ModernCard`, and others) that are easy to miss and expensive
to reinvent with primitives. Then run `describe_control` on every type you plan to use.
to reinvent with primitives.

The resulting list will also specify if any Code Components or Canvas Components are available as control instances in the app. The result identifies the `ComponentName` to pass to `describe_control`.

Run `describe_control` on every type you plan to use.

## Interpret property defaults and requirements

The `Default` shown for a property is the value the property takes when it is omitted from the YAML.
Properties marked `Required: true` must be provided, even when no default is shown.
Omit other properties to accept their default.

### Refresh Canvas and Code Component descriptions

`describe_control` results for Canvas and Code Components are snapshots of the current
Studio document, not durable catalog entries. Re-run `describe_control` for the returned
`ComponentName` after a successful `compile_canvas` applies changes to a local component
definition or its custom properties. Do not reuse component descriptions from an earlier
turn after any of those events. Refresh immediately before recording component properties
in a plan or editing a component instance.

## Layout containers

Expand All @@ -39,8 +59,7 @@ to reinvent with primitives. Then run `describe_control` on every type you plan

Default to AutoLayout. Use ManualLayout only when the user explicitly requests
pixel-perfect positioning or the app is a fixed-size desktop dashboard. Mobile and
cross-device apps MUST use AutoLayout. See `${PLUGIN_ROOT}/references/LayoutGuide.md` for
the patterns.
cross-device apps MUST use AutoLayout. See `${PLUGIN_ROOT}/references/LayoutGuide.md` for the patterns.

⚠️ **`GroupContainer` has no `OnSelect` — it cannot be clicked.** This is a common dead
end when building card UI: the container lays out perfectly but tapping it does nothing.
Expand Down Expand Up @@ -284,18 +303,18 @@ or starts with a number:
Visible: =ThisItem.Status = 'Status (Assignments)'.Active
```

## Colour and button-state patterns
## Color and button-state patterns

```yaml
# Colour constants
# Color constants
Fill: =Color.White
BasePaletteColor: =Color.Blue

# RGBA
Fill: =RGBA(240, 240, 240, 1)
FontColor: =RGBA(0, 0, 0, 1)

# Conditional colour
# Conditional color
BasePaletteColor: =If(isActive, Color.Blue, Color.Gray)
```

Expand All @@ -304,18 +323,6 @@ and `Transparent` can remain light even when `Fill` is set. Pair those appearanc
dark `Color`, or switch to `Primary` and set `BasePaletteColor` for a dark surface. Do not
assume `Fill` overrides the variant.

```yaml
Properties:
DisplayMode: =If(isDisabled, DisplayMode.Disabled, DisplayMode.Edit)
Text: =buttonText
OnSelect: |-
=If(condition,
false, # Guard clause - do nothing
Set(variable, value); # Execute logic
Set(anotherVar, anotherValue)
)
```

## Timer lifecycle

An automatic Timer needs a start edge after the control exists. If `AutoStart: =false`
Expand Down Expand Up @@ -362,13 +369,13 @@ replace `Badge.Content`; omitting Content can render placeholder text such as `A

**Styling:**

- `Fill` — background colour (absent on `Badge` and `Progress`)
- `Color` — text colour on the modern React controls; `Badge` spells it `FontColor`
- `BasePaletteColor` — theme colour for `Badge`, `Progress`, and the modern inputs
- `Fill` — background color (absent on `Badge` and `Progress`)
- `Color` — text color on the modern React controls; `Badge` spells it `FontColor`
- `BasePaletteColor` — theme color for `Badge`, `Progress`, and the modern inputs
- `Size` — font size on the modern React controls; `Badge` spells it `FontSize`
- `FontWeight` — Bold, Semibold, Normal, Lighter

**Behaviour:**
**Behavior:**

- `DisplayMode` — Edit, View, Disabled
- `Visible` — boolean visibility
Expand All @@ -383,7 +390,7 @@ replace `Badge.Content`; omitting Content can render placeholder text such as `A
- `LayoutGap` — spacing between items
- `LayoutOverflowY` — vertical overflow (`Scroll` for scrollable containers)
- `FillPortions` — proportional sizing
- `PaddingTop/Bottom/Left/Right` — container padding
- `PaddingTop`/`Bottom`/`Left`/`Right` — container padding

## Troubleshooting

Expand Down
19 changes: 9 additions & 10 deletions plugins/canvas-apps/references/CreateWorkflow.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Create Workflow

Use this workflow only when the working directory has no meaningful screen content.
Use this workflow only when `[working directory]` has no meaningful screen content.

## 1. Read Guidance

Read:

- `${PLUGIN_ROOT}/references/YamlSyntax.md` — file structure, syntax rules, parse-error triage
- `${PLUGIN_ROOT}/references/ControlGuide.md` — control selection, per-control properties, enums
- `${PLUGIN_ROOT}/references/LayoutGuide.md` — responsive layout, scrolling, colour contrast
- `${PLUGIN_ROOT}/references/LayoutGuide.md` — responsive layout, scrolling, color contrast
- `${PLUGIN_ROOT}/references/PowerFxGuide.md` — state, events, named formulas, mock data
- `${PLUGIN_ROOT}/references/DesignGuide.md` — aesthetic direction and design process

Expand All @@ -25,8 +25,8 @@ Determine:
Use AutoLayout for phone, tablet, multi-device, or unknown targets. ManualLayout is
acceptable for desktop-only, fixed dashboards.

The landing screen must reuse `[working directory]/Screen1.pa.yaml`; every additional
screen gets a new file.
The landing screen must reuse `[working directory]/Screen1.pa.yaml`; every additional screen gets a new
file.

## 3. Present the Plan

Expand Down Expand Up @@ -56,17 +56,16 @@ Invoke the `canvas-app-planner` agent with `Task` and:

```text
Mode: CREATE
Working directory: [absolute working directory]
Plan index: [working directory]/canvas-app-plan.md
Shared plan: [working directory]/canvas-app-shared.md
Working directory: `[working directory]`
Plan index: `[working directory]/canvas-app-plan.md`
Shared plan: `[working directory]/canvas-app-shared.md`
Requirements: [user requirements]
Approved plan: [full approved plan]
Target users and device: [stated or inferred]
```

The planner discovers resources, writes `[working directory]/App.pa.yaml`, the plan index,
shared plan, and one screen brief per dispatch row. It does not redesign the approved
plan.
The planner discovers resources, writes `[working directory]/App.pa.yaml`, the plan index, shared plan,
and one screen brief per dispatch row. It does not redesign the approved plan.

Wait for the planner to finish, then return to **Planned Build Handoff** in the
`canvas-app` skill.
4 changes: 2 additions & 2 deletions plugins/canvas-apps/references/DesignGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ the real user experience.
- **Font Weight**: Use `ModernText` for headlines with `FontWeight: =FontWeight.Bold` and a large font size. Use `ModernText` with `FontWeight: =FontWeight.Normal` for body content.
- **Size Contrast**: Create dramatic hierarchy with size differences. Headers at 24-32, subheaders at 18-20, body at 14-16.
- **Alignment as Statement**: Mix `Align.Left`, `Align.Center`, `Align.Right` intentionally. Centered text for impact, left-aligned for readability.
- **Font Properties**: Leverage `Size`, `FontWeight`, `Align`, `VerticalAlign`, and `Color` to create visual interest. On the modern React controls the text colour property is `Color` and the font size property is `Size` — `FontColor` and `FontSize` exist only on `Badge`. Confirm with `describe_control` rather than assuming.
- **Font Properties**: Leverage `Size`, `FontWeight`, `Align`, `VerticalAlign`, and `Color` to create visual interest. On the modern React controls the text color property is `Color` and the font size property is `Size` — `FontColor` and `FontSize` exist only on `Badge`. Confirm with `describe_control` rather than assuming.

### Color & Visual Theme

Expand All @@ -80,7 +80,7 @@ the real user experience.
- **Design for the narrowest width you claim to support**: A layout composed at 1440px and never re-checked will clip at 1024px and collapse on a phone. Size layout containers with `Parent.Width` or `FillPortions`, never a literal like `Width: =1120`. Reserve fixed pixel sizes for icons, avatars, and steppers — and keep interactive ones at 44px or larger.
- **Every horizontal row of more than two controls needs a reflow strategy**: Set `LayoutWrap: =true`, or drive `LayoutDirection` from a width breakpoint, so rows stack instead of squeezing. This is the single most common defect in generated apps and it is invisible at the width you designed at.
- **The screen root must scroll** whenever it holds a gallery, a form, or more than about three stacked sections: canvas screens do not scroll on their own, so give the root container `LayoutOverflowY: =LayoutOverflow.Scroll` and content below the fold stays reachable on short viewports.
- **Set foreground wherever you set background**: Text does not inherit a contrasting colour. Every time you choose a container `Fill`, set `Color` on the text inside it — dark-on-dark passes every automated check and is unreadable.
- **Set foreground wherever you set background**: Text does not inherit a contrasting color. Every time you choose a container `Fill`, set `Color` on the text inside it — dark-on-dark passes every automated check and is unreadable.
- **Rows inside a `Gallery` need their own container**: `Gallery` is a Classic control and positions its template children absolutely, so a row authored at desktop width stays at desktop width everywhere. Put one AutoLayout `GroupContainer` in the template and build the row inside it. See `${PLUGIN_ROOT}/references/LayoutGuide.md`.
- **Asymmetry & Breaking Grid**: Don't center everything. Offset elements. Use unexpected positioning.
- **Spacing as Design**: Generous padding creates breathing room. Dense layouts create energy.
Expand Down
Loading
Loading