@cratis/pi 7.103.6 → 7.103.7

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.
Files changed (31) hide show
  1. package/package/corpus/agents/screenplay-modeler.md +1 -0
  2. package/package/corpus/harnesses/copilot/instructions/profiles.instructions.md +6 -2
  3. package/package/corpus/harnesses/pi/agents/screenplay-modeler.md +1 -0
  4. package/package/corpus/harnesses/pi/extensions/cratis-mcp/ServerBridge.ts +7 -5
  5. package/package/corpus/harnesses/pi/extensions/cratis-mcp/process.ts +15 -3
  6. package/package/corpus/rules/profiles.md +6 -2
  7. package/package/corpus/skills/cratis-screenplay-captures-and-reactions/SKILL.md +2 -2
  8. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +2 -2
  9. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +1 -1
  10. package/package/corpus/skills/cratis-screenplay-event-modeling/references/file-layout.md +15 -6
  11. package/package/corpus/skills/cratis-screenplay-event-modeling/verification.json +4 -1
  12. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +7 -3
  13. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +15 -4
  14. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +49 -3
  15. package/package/corpus/skills/cratis-screenplay-model-authoring/references/repairs.md +27 -3
  16. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +14 -0
  17. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +6 -0
  18. package/package/corpus/skills/cratis-screenplay-model-review/references/checklist.md +1 -1
  19. package/package/corpus/skills/cratis-screenplay-model-review/verification.json +2 -0
  20. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +4 -0
  21. package/package/corpus/skills/cratis-screenplay-projections/SKILL.md +4 -5
  22. package/package/corpus/skills/cratis-screenplay-read-surface/SKILL.md +4 -5
  23. package/package/corpus/skills/cratis-screenplay-specifications/SKILL.md +2 -2
  24. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +6 -0
  25. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet.md +13 -0
  26. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +10 -2
  27. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +3 -0
  28. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +8 -2
  29. package/package/corpus/skills/cratis-screenplay-ui-composition/references/ui-profile-and-theme.md +28 -0
  30. package/package/corpus/skills/cratis-screenplay-ui-composition/verification.json +4 -0
  31. package/package.json +1 -1
@@ -33,6 +33,7 @@ After reading these instructions, read each file listed under `process.agents.sc
33
33
 
34
34
  ## Method
35
35
 
36
+ - Reuse existing model/workspace roots. Code-only `Source/` or `src/` is not a model root; absent model/workspace state, use repository-root `Screenplay/`, never `.cratis/`. Read model-authoring's MCP root-selection/version guidance before switching roots.
36
37
  - Load `cratis-screenplay-modeling-lifecycle`, then exactly one phase skill per step: discovery, slice design, streams and consistency, automations and translations, scenario coverage. A legacy system enters through `cratis-screenplay-legacy-extraction` instead of discovery and modeling; later runs re-enter by recorded source identity, widen the candidate in layered passes, and promote locators, decisions and open questions into notes and `documentation` before acceptance (`references/re-entry-and-passes.md` there). Syntax, versions and verdict commands: `cratis-screenplay-toolchain`. Load the phase skill before authoring a construct family.
37
38
  - For a change to an existing model, start from an impact walkthrough (`cratis-screenplay-model-review` `references/walkthrough.md`) so the brief names every affected slice.
38
39
  - Write declarations in story order, one slice after another, never batched by kind. After each batch read `PLAY0516` and `PLAY0517` and repair, or record why the order stays (`cratis-screenplay-slice-design` `references/slicing.md`).
@@ -313,8 +313,12 @@ The profile also selects the corpus-owned Screenplay MCP declaration from
313
313
  `mcp-servers.json`. The Cratis CLI hosts the server as `cratis screenplay mcp`
314
314
  and registers a scoped entry for supported clients without replacing their other
315
315
  servers. Inspect install/status results for adapter support or configuration
316
- conflicts. The model is wherever the project keeps its `.play` files, else under `Source/` or
317
- `src/`, else in a `Screenplay/` folder at the repository root; never under `.cratis/`.
316
+ conflicts. Reuse the project's existing model/workspace root. A code-only `Source/`
317
+ or `src/` is not a model root; without model/workspace state use repository-root
318
+ `Screenplay/`, never `.cratis/`. Requires Cratis CLI 3.93.1 (`cratis --version`) for
319
+ CLI discovery and Screenplay 4.236.1 (`screenplay --version`) for standalone MCP
320
+ discovery; older versions can choose code-only folders. Fixed-root sibling admission
321
+ is narrowly scoped, not an arbitrary switch: see [root selection](../../../skills/cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model).
318
322
  Project-owned configuration can name a root explicitly.
319
323
 
320
324
  Like `allowDependencyManifestWrites`, `modelFirst` (`frozen`, `reason`) and `process` (`decisions`, `workItems`, `acceptance`, `agents`) are project-owned keys in `.cratis/ai.json` that install and update preserve. Only `modelFirst.frozen` is read by code; the lifecycle skill's `references/project-process.md` defines the keys, defaults and routing.
@@ -28,6 +28,7 @@ After reading these instructions, read each file listed under `process.agents.sc
28
28
 
29
29
  ## Method
30
30
 
31
+ - Reuse existing model/workspace roots. Code-only `Source/` or `src/` is not a model root; absent model/workspace state, use repository-root `Screenplay/`, never `.cratis/`. Read model-authoring's MCP root-selection/version guidance before switching roots.
31
32
  - Load `cratis-screenplay-modeling-lifecycle`, then exactly one phase skill per step: discovery, slice design, streams and consistency, automations and translations, scenario coverage. A legacy system enters through `cratis-screenplay-legacy-extraction` instead of discovery and modeling; later runs re-enter by recorded source identity, widen the candidate in layered passes, and promote locators, decisions and open questions into notes and `documentation` before acceptance (`references/re-entry-and-passes.md` there). Syntax, versions and verdict commands: `cratis-screenplay-toolchain`. Load the phase skill before authoring a construct family.
32
33
  - For a change to an existing model, start from an impact walkthrough (`cratis-screenplay-model-review` `references/walkthrough.md`) so the brief names every affected slice.
33
34
  - Write declarations in story order, one slice after another, never batched by kind. After each batch read `PLAY0516` and `PLAY0517` and repair, or record why the order stays (`cratis-screenplay-slice-design` `references/slicing.md`).
@@ -44,22 +44,24 @@ export function createServerBridge(pi: ExtensionAPI, corpus: string, connect: (p
44
44
  connections.clear();
45
45
  deactivate();
46
46
  };
47
- interface Started { server: CorpusServer; connection: StdioConnection; catalog?: ServerCatalog; messages: string[] }
47
+ interface Started { server: CorpusServer; connection?: StdioConnection; catalog?: ServerCatalog; messages: string[] }
48
48
  /** Connect and discover only; registration happens afterwards in selection order so name claims are deterministic. */
49
49
  const start = async (context: ExtensionContext, server: CorpusServer): Promise<Started> => {
50
- const connection = connect(context.cwd, server);
51
- connections.set(server.id, connection);
50
+ let connection: StdioConnection | undefined;
52
51
  try {
52
+ connection = connect(context.cwd, server);
53
+ connections.set(server.id, connection);
53
54
  const catalog = await withDeadline(discoverServer(connection, server.id), deadlineMilliseconds, server.id);
54
55
  if (connections.get(server.id) !== connection || connection.stopped) throw new Error(`MCP server '${server.id}' session ended during discovery.`);
55
56
  return { server, connection, catalog, messages: [...catalog.messages] };
56
57
  } catch (error) {
57
- connection.dispose();
58
- if (connections.get(server.id) === connection) connections.delete(server.id);
58
+ connection?.dispose();
59
+ if (connection && connections.get(server.id) === connection) connections.delete(server.id);
59
60
  return { server, connection, messages: [`MCP server '${server.id}' is unavailable: ${error instanceof Error ? error.message : String(error)}`] };
60
61
  }
61
62
  };
62
63
  const register = ({ server, connection, catalog, messages }: Started, claimed: Set<string>): void => {
64
+ if (!connection) return;
63
65
  const existing = new Set(pi.getAllTools().map(tool => tool.name));
64
66
  for (const tool of catalog?.tools ?? []) {
65
67
  if (claimed.has(tool.nativeName) || (existing.has(tool.nativeName) && !registered.has(tool.nativeName))) {
@@ -2,6 +2,8 @@
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
 
4
4
  import { execFile, spawn } from 'node:child_process';
5
+ import { existsSync } from 'node:fs';
6
+ import { dirname, join } from 'node:path';
5
7
  import type { CorpusServer } from './CorpusServer.ts';
6
8
  import { StdioConnection } from './StdioConnection.ts';
7
9
 
@@ -45,9 +47,19 @@ export function startConnection(project: string, launch: typeof spawn = spawn):
45
47
  }));
46
48
  }
47
49
 
48
- /** Launch a corpus server verbatim (no shell, no interpolation): the default environment plus its declared literal env only. */
49
- export function startServer(project: string, server: CorpusServer, launch: typeof spawn = spawn): StdioConnection {
50
- return new StdioConnection(launch(server.command, server.args, {
50
+ /** Launch a corpus server without a shell or interpolation; Windows npx uses npm's JavaScript entry point. */
51
+ export function startServer(project: string, server: CorpusServer, launch: typeof spawn = spawn, platform: NodeJS.Platform = process.platform, fileExists: (path: string) => boolean = existsSync): StdioConnection {
52
+ let command = server.command;
53
+ let args = server.args;
54
+ if (platform === 'win32' && /^npx(?:\.cmd)?$/i.test(command)) {
55
+ const entryPoint = join(dirname(process.execPath), 'node_modules', 'npm', 'bin', 'npx-cli.js');
56
+ if (!fileExists(entryPoint)) {
57
+ throw new Error(`MCP server '${server.id}' requires npm's npx-cli.js at '${entryPoint}'. Install Node.js with npm; Windows command shims cannot be launched without a shell.`);
58
+ }
59
+ command = process.execPath;
60
+ args = [entryPoint, ...args];
61
+ }
62
+ return new StdioConnection(launch(command, args, {
51
63
  cwd: project,
52
64
  env: { ...childEnvironment(), ...server.env },
53
65
  shell: false,
@@ -312,8 +312,12 @@ The profile also selects the corpus-owned Screenplay MCP declaration from
312
312
  `mcp-servers.json`. The Cratis CLI hosts the server as `cratis screenplay mcp`
313
313
  and registers a scoped entry for supported clients without replacing their other
314
314
  servers. Inspect install/status results for adapter support or configuration
315
- conflicts. The model is wherever the project keeps its `.play` files, else under `Source/` or
316
- `src/`, else in a `Screenplay/` folder at the repository root; never under `.cratis/`.
315
+ conflicts. Reuse the project's existing model/workspace root. A code-only `Source/`
316
+ or `src/` is not a model root; without model/workspace state use repository-root
317
+ `Screenplay/`, never `.cratis/`. Requires Cratis CLI 3.93.1 (`cratis --version`) for
318
+ CLI discovery and Screenplay 4.236.1 (`screenplay --version`) for standalone MCP
319
+ discovery; older versions can choose code-only folders. Fixed-root sibling admission
320
+ is narrowly scoped, not an arbitrary switch: see [root selection](../skills/cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model).
317
321
  Project-owned configuration can name a root explicitly.
318
322
 
319
323
  Like `allowDependencyManifestWrites`, `modelFirst` (`frozen`, `reason`) and `process` (`decisions`, `workItems`, `acceptance`, `agents`) are project-owned keys in `.cratis/ai.json` that install and update preserve. Only `modelFirst.frozen` is read by code; the lifecycle skill's `references/project-process.md` defines the keys, defaults and routing.
@@ -14,8 +14,8 @@ Translate slices cross public boundaries; Automation slices cause private follow
14
14
  ## Locate the model
15
15
 
16
16
  Look first for the project's existing `.play` files: their folder is the model.
17
- For a new model, check `Source/` or `src/`, else use `Screenplay/` at the repository
18
- root. Never put a model under `.cratis/` or hand-copy it between repositories.
17
+ Reuse existing model/workspace roots; code-only `Source/` or `src/` does not
18
+ qualify. Otherwise use repository-root `Screenplay/` ([discovery/version gates](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model)). Never put a model under `.cratis/` or hand-copy it between repositories.
19
19
  `cratis ai install` manages `.cratis/ai/`, never model files. Keep explanatory
20
20
  Markdown in project documentation; `.play` is the single flow model.
21
21
 
@@ -15,8 +15,8 @@ they are all built from.
15
15
  ## Locate the model
16
16
 
17
17
  Look first for the project's existing `.play` files: their folder is the model.
18
- For a new model, check `Source/` or `src/`, else use `Screenplay/` at the repository
19
- root. Never put a model under `.cratis/` or hand-copy it between repositories.
18
+ Reuse existing model/workspace roots; code-only `Source/` or `src/` does not
19
+ qualify. Otherwise use repository-root `Screenplay/` ([discovery/version gates](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model)). Never put a model under `.cratis/` or hand-copy it between repositories.
20
20
  `cratis ai install` manages `.cratis/ai/`, never model files. Keep explanatory
21
21
  Markdown in project documentation; `.play` is the single flow model.
22
22
 
@@ -120,7 +120,7 @@ Stage, `cratis render` or Studio refusal as a platform gap rather than waiting f
120
120
 
121
121
  ## Locate the model
122
122
 
123
- Look first for the project's existing `.play` files: the folder holding them is the model; a new model goes under `Source/` or `src/`, else `Screenplay/`, never under `.cratis/`. Read [references/file-layout.md](references/file-layout.md) (section "Locate the model") when the location is unclear or source might be copied between repositories. `cratis ai install` manages `.cratis/ai/`, never model files.
123
+ Look first for the project's existing `.play` model and workspace state; reuse that root. Code-only `Source/` or `src/` is not a model root; otherwise use repository-root `Screenplay/`, never `.cratis/`. Read [references/file-layout.md](references/file-layout.md) (section "Locate the model") when the location is unclear or source might be copied between repositories. `cratis ai install` manages `.cratis/ai/`, never model files.
124
124
 
125
125
  ## Verified product sources
126
126
 
@@ -95,12 +95,21 @@ order of modules, features or slices.
95
95
 
96
96
  ## Locate the model
97
97
 
98
- Look first for the project's existing `.play` files: the folder holding them is the
99
- model. A new model goes under the repository's `Source/` or `src/` folder, else in a
100
- `Screenplay/` folder at the repository root; never under `.cratis/`, which holds
101
- configuration and the shared AI corpus only. This is the
102
- conventional home for consumer-owned `.play` source; do not invent another
103
- location or search the whole repository before checking it.
98
+ Look first for the project's existing `.play` model and Screenplay workspace state;
99
+ reuse that root. `Source/` or `src/` is a model root only when it already holds
100
+ model files or workspace state, not merely because application code lives there.
101
+ With neither, start at repository-root `Screenplay/`, never under `.cratis/`,
102
+ which holds configuration and the shared AI corpus only.
103
+
104
+ Requires Screenplay 4.236.1 (`screenplay --version`) for standalone MCP discovery.
105
+ Requires Cratis CLI 3.93.1 (`cratis --version`) for CLI discovery. Older tools can select
106
+ a code-only `Source/` or `src/`; inspect the opened root rather than assuming it
107
+ is correct. Existing workspace state can retain the served ancestor of a discovered
108
+ model; do not relocate it or create a second workspace implicitly. Discovery
109
+ selects a path without creating it; the first write creates the directory.
110
+ For fixed-root admission, see [MCP launch and sibling roots](../../cratis-screenplay-model-authoring/references/mcp-tools.md#working-with-the-screenplay-mcp).
111
+ Sources: [MCP discovery](https://github.com/Cratis/Screenplay/blob/main/Source/DotNET/Screenplay.Mcp/McpModelLocation.cs),
112
+ [CLI discovery](https://github.com/Cratis/cli/blob/main/Source/Cli/Commands/Screenplay/ScreenplayModelLocation.cs).
104
113
 
105
114
  `cratis ai install` manages `.cratis/ai/`, never model files. Never
106
115
  hand-copy Screenplay source between repositories. Keep Markdown that explains,
@@ -3,6 +3,9 @@
3
3
  "input": "Facilitate an event modeling session and land the model as .play source.",
4
4
  "fixtures": [],
5
5
  "assertions": [
6
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.236.1", "file": "references/file-layout.md" },
7
+ { "kind": "skill-contains", "value": "Cratis CLI 3.93.1", "file": "references/file-layout.md" },
8
+ { "kind": "skill-contains", "value": "not merely because application code lives there", "file": "references/file-layout.md" },
6
9
  { "kind": "play-compiles" },
7
10
  {
8
11
  "kind": "skill-contains",
@@ -16,7 +19,7 @@
16
19
  },
17
20
  {
18
21
  "kind": "skill-contains",
19
- "value": "Look first for the project's existing `.play` files"
22
+ "value": "Look first for the project's existing `.play` model and workspace state"
20
23
  },
21
24
  {
22
25
  "kind": "skill-contains",
@@ -50,8 +50,9 @@ it owns fallback discovery, fixed-root limits and the initialization protocol.
50
50
  Discover `tools/list` schemas.
51
51
 
52
52
  Look first for the project's existing `.play` files: their folder is the model.
53
- New models go in `Source/` or `src/`, else root `Screenplay/`, never `.cratis/`
54
- (configuration/shared corpus only). The source is the single flow model;
53
+ Reuse existing model/workspace roots; code-only `Source/` or `src/` is not a
54
+ model root. Otherwise use repository-root `Screenplay/`, never `.cratis/`
55
+ ([root selection and version gates](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model)). The source is the single flow model;
55
56
  explanatory Markdown belongs in repository documentation.
56
57
 
57
58
  `cratis ai install` manages `.cratis/ai/`, never model files. Select the
@@ -105,7 +106,10 @@ for handler views: `executableReady` means binding, not an implemented body.
105
106
  ## Compare models
106
107
 
107
108
  Compare with `main` through `semantic-diff` worktree `path`, not two exports.
108
- Read [comparison sources](references/mcp-tools.md#semantic-revision-comparison) for paging.
109
+ Read [comparison sources](references/mcp-tools.md#semantic-revision-comparison) for paging
110
+ and [enum numeric identity](references/mcp-tools.md#enum-numeric-identity) for
111
+ stored-value risks: implicit reorders can renumber values; stable explicit-number
112
+ reorders do not. Static comparison never proves storage or behavioral compatibility.
109
113
 
110
114
  ## Make one coherent proposal
111
115
 
@@ -30,13 +30,21 @@ Without a fixed root, it binds the client's single workspace root, else a launch
30
30
  directory holding `.play` files. Only after a no-root or multiple-roots response,
31
31
  pass `path`: the folder holding the project's models, otherwise the folder the
32
32
  user names. Without a project the server uses `Documents/Screenplay` in the user's
33
- home; do not invent a location. A fixed root can switch only to the same model
34
- folder in a registered Git worktree of the same repository.
33
+ home; do not invent a location. A fixed root can switch to the same model
34
+ folder in a registered Git worktree of the same repository. Screenplay 4.236.1
35
+ also admits an explicitly requested sibling from a code-only `Source/` or `src/`
36
+ root, not arbitrary root changes; existing model/workspace state prevents that
37
+ switch. An empty fixed root named `data` still cannot rebind; nested targets,
38
+ links and unrelated nonempty folders remain refused. `semantic-diff` path sources
39
+ share these checks. A Java project with only code in `src` selects
40
+ `<project>/Screenplay`, not `<project>/src`. Read [sibling admission boundaries](mcp-tools.md#working-with-the-screenplay-mcp).
35
41
 
36
42
  1. Launch with a **fixed root**: `screenplay mcp <model-folder>`, or
37
43
  `cratis screenplay mcp <model-folder>`, or `cratis screenplay mcp` inside a
38
- project, where the CLI locates the model (the project's `.play` files, else `Source/`
39
- or `src/`, else a new `Screenplay/` folder; what the `cratis/screenplay` profile registers). Stdio, newline-delimited
44
+ project, where the CLI reuses model/workspace roots, else chooses repository-root
45
+ `Screenplay/`; code-only `Source/` or `src/` does not qualify (Requires Cratis CLI
46
+ 3.93.1; `cratis --version`; older versions can select the code folder).
47
+ Discovery creates no directory; the first write does. Stdio, newline-delimited
40
48
  JSON-RPC, one sequential connection.
41
49
  2. Send `initialize`, then the `notifications/initialized` notification, **before
42
50
  any tool call**. Earlier calls fail with `-32600` "Initialize and send
@@ -176,6 +184,9 @@ connection. Passing `open-workspace.path` does **not** avoid it, because the err
176
184
  move or removal is that approval, also unattended: do not ask again per apply. Then `apply` with the **before**
177
185
  revisions. Every old handle and proposal is gone afterwards: re-read at the new
178
186
  revision.
187
+ For a PLAY0516 [wildcard-import repair](repairs.md#timeline-import-order), review
188
+ that future files will need explicit imports, then rediscover diagnostics and
189
+ repairs after the apply; never reuse the old ordering proposal.
179
190
  9. Verify: compile the whole folder (V1), read `executable-diagnostics` (V2,
180
191
  V3), and run `screenplay test <root> --format json` or workspace
181
192
  `run-specifications` (V4), naming the tool, version and source revision. A
@@ -28,8 +28,12 @@
28
28
  The standalone MCP server lists 46 tools from Screenplay 4.228.0 (including the MCP-Apps visualization tool); `tools/list` is the authority for the installed server, and the CLI-bundled MCP (`cratis screenplay mcp`) can be an older Screenplay that lacks newer tools.
29
29
 
30
30
  The supported CLI launch is `cratis screenplay mcp <model-root>`, or `cratis screenplay mcp`
31
- alone inside a project, where the CLI locates the model (the project's `.play` files, else
32
- `Source/` or `src/`, else a new `Screenplay/` folder). The standalone form is `screenplay mcp <model-folder>`. A
31
+ alone inside a project, where the CLI reuses existing model/workspace roots.
32
+ A code-only `Source/` or `src/` is not a model root; without model/workspace state,
33
+ use repository-root `Screenplay/`. Requires Cratis CLI 3.93.1 (`cratis --version`)
34
+ and Screenplay 4.236.1 (`screenplay --version`) for their respective discovery
35
+ paths; older versions can select code-only folders. See [root selection](../../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model).
36
+ The standalone form is `screenplay mcp <model-folder>`. A
33
37
  server started with no root at all binds one on first use from `open-workspace`'s
34
38
  `path`, the client's roots, or the working directory; that dynamic form depends on the client supplying roots (see the [MCP loop](mcp-loop.md#dynamic-roots-and-the-workaround)),
35
39
  so prefer a fixed root. Without a project the server works in `Documents/Screenplay`. Model files never go under `.cratis/`. AI distribution provides the
@@ -37,6 +41,19 @@ profile-selected declaration and guidance; the CLI owns executable hosting and
37
41
  client registration. Installation must preserve user-owned MCP servers and
38
42
  report unsupported adapters or drift.
39
43
 
44
+ From Screenplay 4.236.1, a fixed root at a code-only `Source/` or `src/` can admit
45
+ an explicitly requested direct sibling model folder via `open-workspace path`. The
46
+ configured code root must have no model or workspace state. The sibling must be
47
+ missing, empty, or already model/workspace-bearing; an unrelated nonempty folder,
48
+ a file or a symlink is refused. Existing model/workspace roots stay protected;
49
+ this is not permission to switch to arbitrary roots. Nested targets are refused;
50
+ an empty fixed root named `data` cannot rebind merely because it is empty.
51
+ `semantic-diff` path sources use the same admission checks. Inspect the returned
52
+ root and reuse its workspace/revisions. Path selection alone creates no directory.
53
+ For example, a Java project `/project` with code in `/project/src` but no model or
54
+ Screenplay state selects `/project/Screenplay`, not `/project/src`.
55
+ Source: [sibling admission](https://github.com/Cratis/Screenplay/blob/v4.236.1/Source/DotNET/Screenplay.Mcp/McpWorkspaces.ModelFolder.cs).
56
+
40
57
  ## Tool groups
41
58
 
42
59
  After `initialize` and `notifications/initialized`, discover current tools and
@@ -327,7 +344,11 @@ with `view: "diagnostics"`, then `view: "repairs"` at the current revision.
327
344
  | `PLAY0688` | Replace a refuted generated-concept rule with the strategy-derived `matches`; review every concept use affected by the changed rule. |
328
345
  | `PLAY0683/0684` | Raise NanoID size/bytes count using the concept subject; PLAY0683 also offers uniqueness using the command-property subject. Individual review, canonical formatting, no pinned evidence; see [concept generation](#concept-generation). |
329
346
  | `PLAY0664` | Remove an override identical to the command's complete source/stream/id route. |
330
- | `PLAY0516` | Move a producing sibling declaration/import before its consumer, or pin an already placed file before a retained glob. Preserve catalogs, comments, placement and executable readiness; introduce no timeline findings. Own-sub-feature edges, cycles, unranked members and mixed/different-parent boundaries have no repair. Rediscover after each move; pinned evidence is unsupported. |
347
+ | `PLAY0516` | Move a producing sibling declaration/import before its consumer, pin an already placed file before a retained glob, or, when those cannot safely fix the edge, replace a same-parent wildcard-import span with explicit ordered imports. The last repair changes future inclusion: new files need explicit imports. Preserve catalogs, comments, placement and executable readiness; introduce no timeline findings. Own-sub-feature edges, cycles, unranked members and mixed/different-parent boundaries have no repair. Rediscover after each move; pinned evidence is unsupported. |
348
+
349
+ Requires Screenplay 4.219.0 (`screenplay --version`) for wildcard-import expansion;
350
+ older tools do not offer that repair. Read [timeline repair](repairs.md#timeline-import-order)
351
+ for the future-import decision and refusal boundaries.
331
352
 
332
353
  These discoveries verify acceptance before listing a repair. Only compact
333
354
  acceptance/conflict verdicts are cached on the immutable snapshot, not diagnostics,
@@ -703,6 +724,31 @@ or transitive/runtime impact. Use `read-proposal` with `view: "semantic-diff"`
703
724
  for a retained proposal against its disk baseline without applying it; changed
704
725
  baseline bytes or pending recovery refuse that view too.
705
726
 
727
+ ### Enum numeric identity
728
+
729
+ Requires Screenplay 4.214.0 (`screenplay --version`); older comparison tools do not
730
+ report these enum-specific changes. Inspect `enum-*` items in `members`, especially
731
+ `stored: true`: the baseline enum is reachable from an event property (including
732
+ nested composite types), not proof that events were persisted. `beforeNumber`,
733
+ `afterNumber`, `beforeNumbering`, `afterNumbering` and `afterMember` expose the
734
+ numeric change; implicit numbers are zero-based declaration positions.
735
+
736
+ `enum-number-changed`, `enum-member-removed` and `enum-number-reused` are
737
+ contract-breaking. `enum-member-renamed` retains an explicit number on both sides
738
+ and is not breaking for default numeric storage, but renames generated C#/TypeScript
739
+ members and schema metadata; a name-based converter can still break. Explicit
740
+ removal/reuse is indistinguishable from that rename, so review intent. Positional
741
+ renames report number reuse. Appending members, reordering stable explicit numbers,
742
+ or pinning existing positions adds no enum records; structural hashes still change.
743
+ Before reordering a stored positional enum, use `propose-number-enum-members` to pin
744
+ its current values. Never migrate stored numbers automatically.
745
+
746
+ Duplicate names/numbers or inconsistent member/number counts report
747
+ `EnumerationNotComparable`; absence of enum items is not a clean comparison when
748
+ coverage is incomplete. Neither comparison view proves behavioral compatibility
749
+ or waives the separate release-baseline equality check.
750
+ Source: [model comparison](https://github.com/Cratis/Screenplay/blob/v4.214.0/Documentation/screenplay/model-comparison.md).
751
+
706
752
  Authority: `Source/DotNET/Screenplay.Mcp/{McpRevisionDiff,McpWorkspaces.Comparison,McpToolSchemas,McpToolCatalog}.cs`
707
753
  and `Documentation/screenplay/mcp/reference.md`.
708
754
 
@@ -14,9 +14,10 @@ from silently changing the reviewed candidate.
14
14
 
15
15
  - `PLAY0166` declares a missing produced event; `PLAY0478` is a routing decision
16
16
  (identifier destination, never fix-all); `PLAY0471` removes a redundant name-equal event pin.
17
- - `PLAY0516` repairs presentation order by moving a sibling or import, or pinning
18
- a producer before a glob. It preserves semantics/identities and introduces no
19
- new timeline findings; evidence pinning is unsupported for this repair.
17
+ - `PLAY0516` repairs presentation order by moving a sibling or import, pinning
18
+ a producer before a glob, or replacing wildcard imports with ordered imports
19
+ ([timeline import order](#timeline-import-order)). It preserves semantics/identities
20
+ and introduces no new timeline findings; evidence pinning is unsupported for this repair.
20
21
  - `PLAY0469` removes an inline identifier payload copy: it **changes the event
21
22
  contract**, refuses consumer/opaque impact, has no fix-all, and the catalog does
22
23
  not prove events were persisted, so ask about stored contracts first. For a
@@ -31,6 +32,29 @@ from silently changing the reviewed candidate.
31
32
  - Generation repairs PLAY0683/0684: [subjects, review and limits](mcp-tools.md#concept-generation).
32
33
  - Compliance repairs PLAY0565/0653: [MCP tool guide](mcp-tools.md).
33
34
 
35
+ ## Timeline import order
36
+
37
+ Requires Screenplay 4.219.0 (`screenplay --version`) for wildcard-import expansion;
38
+ older tools offer only the earlier safe moves/pins. When those cannot fix the
39
+ edge safely, the discovered repair can replace a same-parent import span
40
+ containing a wildcard with explicit imports in producer-before-consumer order.
41
+ **New files need explicit imports** afterwards: the replaced glob no longer
42
+ includes future files. Review and accept that inclusion-policy change before
43
+ applying; do not manufacture a reorder if discovery offers no repair.
44
+
45
+ The repair must preserve comments, catalog/identities, document set and placement,
46
+ executable readiness and existing error/warning counts, remove the target finding
47
+ and introduce no new timeline findings. Cycles, own-sub-feature edges, ambiguous
48
+ or duplicate imports, placement mismatches and unproven moves remain refused.
49
+ Rediscover diagnostics and repairs at the new revisions after applying.
50
+ The TypeScript compiler also exposes PLAY0516 as a quick fix (including edits in
51
+ the importing document); Monaco shows it as a code action. VS Code offers it as a
52
+ reviewed saved-file code action with preview, drift checks and recovery. These
53
+ editor routes share the safe repair, not permission to force a reorder.
54
+ Source: [workspace timeline repairs](https://github.com/Cratis/Screenplay/blob/main/Source/DotNET/Screenplay/Workspaces/WorkspaceTimelineRepairs.Expansion.cs).
55
+
56
+ ## Enum numbering and event extraction
57
+
34
58
  `propose-number-enum-members` pins an unnumbered enum to current positions.
35
59
  Opt-in MCP `checks: "enum-pinning"` / `--check enum-pinning` (PLAY0671) hints at
36
60
  stored enums, not correctness repairs. Arguments/review: `references/mcp-tools.md`.
@@ -3,6 +3,20 @@
3
3
  "input": "Author and organize a Screenplay model in a repository.",
4
4
  "fixtures": [],
5
5
  "assertions": [
6
+ { "kind": "skill-contains", "value": "Monaco shows it as a code action", "file": "references/repairs.md" },
7
+ { "kind": "skill-contains", "value": "reviewed saved-file code action", "file": "references/repairs.md" },
8
+ { "kind": "skill-contains", "value": "an empty fixed root named `data` cannot rebind", "file": "references/mcp-tools.md" },
9
+ { "kind": "skill-contains", "value": "selects `/project/Screenplay`, not `/project/src`", "file": "references/mcp-tools.md" },
10
+ { "kind": "skill-contains", "value": "`semantic-diff` path sources use the same admission checks", "file": "references/mcp-tools.md" },
11
+ { "kind": "skill-contains", "value": "Requires Cratis CLI 3.93.1", "file": "references/mcp-tools.md" },
12
+ { "kind": "skill-contains", "value": "configured code root must have no model or workspace state", "file": "references/mcp-tools.md" },
13
+ { "kind": "skill-contains", "value": "Path selection alone creates no directory", "file": "references/mcp-tools.md" },
14
+ { "kind": "skill-contains", "value": "New files need explicit imports", "file": "references/repairs.md" },
15
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.219.0", "file": "references/repairs.md" },
16
+ { "kind": "skill-contains", "value": "rediscover diagnostics and", "file": "references/mcp-loop.md" },
17
+ { "kind": "skill-contains", "value": "enum-number-reused", "file": "references/mcp-tools.md" },
18
+ { "kind": "skill-contains", "value": "EnumerationNotComparable", "file": "references/mcp-tools.md" },
19
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.214.0", "file": "references/mcp-tools.md" },
6
20
  { "kind": "skill-contains", "value": ".screenplay/release-baseline.json", "file": "references/release-baseline.md" },
7
21
  { "kind": "skill-contains", "value": "screenplay baseline admit", "file": "references/release-baseline.md" },
8
22
  { "kind": "skill-contains", "value": "screenplay baseline check", "file": "references/release-baseline.md" },
@@ -117,6 +117,12 @@ model's behalf.
117
117
 
118
118
  ## Comparing with a baseline
119
119
  For comparison with `main`, use `semantic-diff`; neither it nor `read-proposal view=semantic-diff` proves behavioral equivalence. Read [baseline comparison](references/baseline-comparison.md) for source selection, the baseline worktree check, identity matching and drift refusals.
120
+ Review [enum numeric identity](../cratis-screenplay-model-authoring/references/mcp-tools.md#enum-numeric-identity)
121
+ (Requires Screenplay 4.214.0; `screenplay --version`): inspect `stored: true` items.
122
+ Number change/removal/reuse is breaking; an explicit-number-preserving rename is
123
+ not breaking for numeric storage but renames generated code. Pin stored positional
124
+ enums with `propose-number-enum-members` before reordering. Treat
125
+ `EnumerationNotComparable` as unresolved comparison, never as unchanged.
120
126
 
121
127
  ## Audit pass (existing or extracted models)
122
128
  Read-only. Before the checklist produce the inventory in the fixed shape of
@@ -105,7 +105,7 @@ the format in `worked-example.md`.
105
105
  | C6 | No secret or bearer values as facts (tokens, magic links, signed URLs): record a keyed hash or a reference | event payloads | D |
106
106
  | C7 | No two events of one kind of event source mean the same thing (a shared property set is a signal, not a defect: distinct facts may share a shape and historical generations are exempt; major only when meaning is lost, a rule bypassed or consumers ambiguous); one fact is not recorded twice (aggregate event plus per-item fan-out) | event declarations side by side | D |
107
107
  | C8 | Corrections are new facts that name what they correct; redaction and crypto-erasure are compliance tools, not corrections | event names | D |
108
- | C9 | A changed event contract is a generation or a new event with a recorded reason; no past meaning is reinterpreted through a rename or payload cleanup | `id` pins, generations, documentation | D (major when history changes meaning) |
108
+ | C9 | A changed event contract is a generation or a new event with a recorded reason; no past meaning is reinterpreted through a rename or payload cleanup. For `enum-*` items with `stored: true`, number change/removal/reuse is breaking; explicit-number-preserving renames retain numeric storage compatibility but rename generated code. Pin positional enums before reordering; stable explicit-number reorders add no enum records. `EnumerationNotComparable` is unresolved, not unchanged | `id` pins, generations, documentation; [enum comparison](../../cratis-screenplay-model-authoring/references/mcp-tools.md#enum-numeric-identity) | D (major when history changes meaning) |
109
109
 
110
110
  ## Phase 6. Events versus views (7 checks, D1-D7)
111
111
  | Id | Check | Evidence | Tier |
@@ -3,6 +3,8 @@
3
3
  "input": "Review the marina berth .play model before we accept it: check the model and report findings, do not change anything.",
4
4
  "fixtures": [],
5
5
  "assertions": [
6
+ { "kind": "skill-contains", "value": "EnumerationNotComparable" },
7
+ { "kind": "skill-contains", "value": "number change/removal/reuse is breaking", "file": "references/checklist.md" },
6
8
  { "kind": "skill-contains", "value": "all *known* producers", "file": "references/public-keys-and-routes.md" },
7
9
  { "kind": "play-compiles" },
8
10
  { "kind": "skill-contains", "value": "A read-only reviewer returns `question` note requests" },
@@ -25,6 +25,10 @@ an unproven pass.
25
25
  A direct user request to model a scope is consent for that scope. A committed model the project marks `modelFirst.frozen` in `.cratis/ai.json` is generated evidence, not opted in (reason `frozen-model`): read it, never regenerate or edit it unless the request names that `.play` path or model; a generic "regenerate all" skips it and says so. Run `scripts/model-first-status.mjs` from the repository with Node.js and Git:
26
26
  `node <skill-directory>/scripts/model-first-status.mjs [--root <repository-relative-dir>] [--json]`.
27
27
  Read-only roots: `--root`, configuration, then discovery from HEAD project paths (drafts only if none). Discovery prefers legacy `.cratis/screenplay/`, else the common folder, else `Source/`, `src/`, `Screenplay/`. It excludes hidden/build/docs/samples/examples/scratch/test fixtures from discovery and acceptance, including at `.`; explicit roots include everything beneath them.
28
+ This read-only opt-in detector is not MCP/CLI workspace discovery. For a new
29
+ workspace use [root selection](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model):
30
+ code-only `Source/` or `src/` does not qualify; absent model/workspace state,
31
+ use repository-root `Screenplay/`.
28
32
  Output: root, reason, frozen marker, file counts, drafts, model changes and the resolved `process` block. Exits: **0 opted in**, **1 not opted in**, **2 could not run** (Git/configuration/arguments). Treat 2 as blocked, not code-first.
29
33
  Run `scripts/model-first-status.mjs --self-test` to plant and check verdict fixtures; it executes `scripts/model-first-self-test.mjs` and prints the checked count on success.
30
34
  Read `references/opt-in.md` when checking the project configuration mechanism.
@@ -15,11 +15,10 @@ text. This is half of every event model, and the half most easily got wrong.
15
15
  ## Locate the model
16
16
 
17
17
  Look first for the project's existing `.play` files: the folder holding them is the
18
- model. A new model goes under the repository's `Source/` or `src/` folder, else in a
19
- `Screenplay/` folder at the repository root; never under `.cratis/`, which holds
20
- configuration and the shared AI corpus only. This is the
21
- conventional home for consumer-owned `.play` source; do not invent another
22
- location or search the whole repository before checking it.
18
+ model. Reuse existing model/workspace roots; code-only `Source/` or `src/` does
19
+ not qualify. Otherwise use repository-root `Screenplay/`, never `.cratis/`
20
+ (configuration/shared corpus only). Read [discovery/version gates](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model)
21
+ when locating the model; do not invent another location.
23
22
 
24
23
  `cratis ai install` manages `.cratis/ai/`, never model files. Never
25
24
  hand-copy Screenplay source between repositories. Keep Markdown that explains,
@@ -14,11 +14,10 @@ shape, the `query` is the entry point, and the `screen` renders it.
14
14
  ## Locate the model
15
15
 
16
16
  Look first for the project's existing `.play` files: the folder holding them is the
17
- model. A new model goes under the repository's `Source/` or `src/` folder, else in a
18
- `Screenplay/` folder at the repository root; never under `.cratis/`, which holds
19
- configuration and the shared AI corpus only. This is the
20
- conventional home for consumer-owned `.play` source; do not invent another
21
- location or search the whole repository before checking it.
17
+ model. Reuse existing model/workspace roots; code-only `Source/` or `src/` does
18
+ not qualify. Otherwise use repository-root `Screenplay/`, never `.cratis/`
19
+ (configuration/shared corpus only). Read [discovery/version gates](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model)
20
+ when locating the model; do not invent another location.
22
21
 
23
22
  `cratis ai install` manages `.cratis/ai/`, never model files. Never
24
23
  hand-copy Screenplay source between repositories. Keep Markdown that explains,
@@ -15,8 +15,8 @@ concrete data.
15
15
  ## Locate the model
16
16
 
17
17
  Look first for the project's existing `.play` files: their folder is the model.
18
- For a new model, check `Source/` or `src/`, else use `Screenplay/` at the repository
19
- root. Never put a model under `.cratis/` or hand-copy it between repositories.
18
+ Reuse existing model/workspace roots; code-only `Source/` or `src/` does not
19
+ qualify. Otherwise use repository-root `Screenplay/` ([discovery/version gates](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model)). Never put a model under `.cratis/` or hand-copy it between repositories.
20
20
  `cratis ai install` manages `.cratis/ai/`, never model files. Keep explanatory
21
21
  Markdown in project documentation; `.play` is the single flow model.
22
22
 
@@ -15,6 +15,8 @@ This skill owns tool selection, verdicts and admission. Modeling method lives in
15
15
 
16
16
  Decide opt-in per `general.md` "Model first"; where `cratis-screenplay-modeling-lifecycle` is installed, run its `scripts/model-first-status.mjs` to locate the model root. A folder of `.play`
17
17
  files is one application: always check the folder, never one file of it.
18
+ MCP/CLI discovery reuses model/workspace roots, not code-only `Source/` or `src/`;
19
+ otherwise use repository-root `Screenplay/` ([version gates and root boundaries](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model)).
18
20
 
19
21
  ## Tool versions and the contract
20
22
 
@@ -98,6 +100,10 @@ not the source identity.
98
100
 
99
101
  Read [observation comparison](references/observation-comparison.md) when asking whether a running namespace holds what the model declares, or when reading a `conform-namespace` verdict. It differs from model comparison (model versus model) and `conform` (model versus code).
100
102
 
103
+ PLAY0516 ordering is presentation-only, not execution. For a wildcard-import
104
+ repair, read [timeline diagnostics](references/diagnostics.md): replacing globs
105
+ with ordered imports means future files need explicit imports.
106
+
101
107
  ## Subsets (write from the one your mode needs)
102
108
 
103
109
  - **Design**: every construct family parses; use it to model first. Compiled shapes:
@@ -12,6 +12,7 @@
12
12
  - `$eventContext.` (projections)
13
13
  - PDL quick reference (most forms are compiled in `pdl-example.md` or `cheat-sheet-example.md`; `remove via join` and `$eventContext.occurred` are not)
14
14
  - Generated values and proofs
15
+ - UI profile theme references
15
16
  - Specification forms
16
17
 
17
18
  Released boundary forms: `public event X`, `event X from "store"`, Translate
@@ -213,6 +214,18 @@ for v21 admission, all-Proven unpinned specs and the separate prerequisites for
213
214
  warning/info rules, checksum validation and pattern/random rendering.
214
215
  `generate rule` renders from Stage 4.136.0 (STAGE-ESM-028 in the Host). Reference binding is not rendering.
215
216
 
217
+ ## UI profile theme references
218
+
219
+ Inside `ui profile`, write `theme "Scene Default Light"` for a package theme's
220
+ display name. Requires Screenplay 4.227.0 (`screenplay --version`); older compilers
221
+ reject quoted references. Escapes resolve to the name. Undeclared quoted names
222
+ refer to package themes without `PLAY0231`; quoted names matching declarations
223
+ receive `PLAY0232` compatibility checks. Bare `theme Nordic` is unchanged.
224
+ Empty, blank or unterminated quoted names are `PLAY0229`; duplicates are `PLAY0230`.
225
+ Declaration headers remain identifiers, not quoted names. Package compatibility
226
+ is unchanged; parse acceptance does not prove rendering support. See [profile
227
+ examples](../../cratis-screenplay-ui-composition/references/ui-profile-and-theme.md#ui-profile-and-theme).
228
+
216
229
  ## Specification forms
217
230
  Full list with semantics: `Documentation/screenplay/specifications.md`. Compiled in the
218
231
  examples: `given caller` (+`authenticated`, `role`), `given clock`, `given <Event> for`,
@@ -348,8 +348,16 @@ presentation order, not execution: a backward event/read-model dependency or a
348
348
  mutually dependent sibling group. A cycle group replaces internal individual
349
349
  backward findings. Ordering roots are the sole source document, an importing
350
350
  `application.play`, or a unique importing root; without one, folder timeline
351
- checking is skipped. Safe PLAY0516 repairs move siblings/imports or pin files
352
- before a retained glob; cycles and own-sub-feature findings have no repair.
351
+ checking is skipped. Safe PLAY0516 repairs move siblings/imports, pin files
352
+ before a retained glob, or replace a same-parent wildcard-import span with explicit
353
+ ordered imports when earlier moves cannot safely fix it (Requires Screenplay
354
+ 4.219.0; `screenplay --version`). **New files need explicit imports** after that
355
+ replacement. Review comments, identities, placement and readiness preservation,
356
+ and no new timeline findings; cycles, own-sub-feature edges and ambiguous imports
357
+ remain refused. Use the [timeline repair loop](../../cratis-screenplay-model-authoring/references/repairs.md#timeline-import-order),
358
+ not a hand-written reorder; rediscover after applying. In the same release the
359
+ TypeScript compiler/Monaco expose the PLAY0516 quick fix, and VS Code provides a
360
+ reviewed saved-file code action (preview, drift checks and recovery).
353
361
 
354
362
  ## Editor versus C# verdicts
355
363
 
@@ -3,6 +3,9 @@
3
3
  "input": "Check a Screenplay model folder: which compiler should I run, what do V1 to V3 mean, and what does the cratis CLI do with my Automation slice?",
4
4
  "fixtures": [],
5
5
  "assertions": [
6
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.227.0", "file": "references/cheat-sheet.md" },
7
+ { "kind": "skill-contains", "value": "New files need explicit imports", "file": "references/diagnostics.md" },
8
+ { "kind": "skill-contains", "value": "cycles, own-sub-feature edges and ambiguous imports", "file": "references/diagnostics.md" },
6
9
  { "kind": "skill-contains", "value": "Uuid equality in command conditions (ESM v28)", "file": "references/executable-subset.md" },
7
10
  { "kind": "skill-contains", "value": "screenplay baseline check", "file": "references/verdicts.md" },
8
11
  { "kind": "skill-contains", "value": "independent of V1–V5", "file": "references/verdicts.md" },
@@ -20,8 +20,8 @@ a trigger value named `file` is written `@file`.
20
20
  ## Locate the model
21
21
 
22
22
  Look first for the project's existing `.play` files: their folder is the model.
23
- For a new model, check `Source/` or `src/`, else use `Screenplay/` at the repository
24
- root. Never put a model under `.cratis/` or hand-copy it between repositories.
23
+ Reuse existing model/workspace roots; code-only `Source/` or `src/` does not
24
+ qualify. Otherwise use repository-root `Screenplay/` ([discovery/version gates](../cratis-screenplay-event-modeling/references/file-layout.md#locate-the-model)). Never put a model under `.cratis/` or hand-copy it between repositories.
25
25
  `cratis ai install` manages `.cratis/ai/`, never model files. Keep explanatory
26
26
  Markdown in project documentation; `.play` is the single flow model.
27
27
 
@@ -268,6 +268,12 @@ precedence, PLAY0485 and examples.
268
268
 
269
269
  ## `ui profile` and `theme`
270
270
 
271
+ Requires Screenplay 4.227.0 (`screenplay --version`) for a quoted profile reference
272
+ such as `theme "Scene Default Light"`: an undeclared quoted name selects a package
273
+ theme without PLAY0231; a declared one gets PLAY0232 compatibility checks. Bare
274
+ `theme Nordic` still works; declaration headers stay identifier-only. See the
275
+ reference below for escaping and PLAY0229 malformed/blank-name refusals.
276
+
271
277
  A `ui profile` selects the application shell with `root template` (an own layout or application-scope screen template, or `blueprint <B> <Name>` with an optional `version` pin), its shell `option` lines, an `appearance` block (`color scheme`, `accent`), the template new screens start from (`new screens use template`), the theme and the `packages`, listed in override-priority order (a later package shadows an earlier one); `target platform` and `target size` accept any identifier, so a typo is silent. The legacy `layout <Name>` line inside a profile still reads but warns `PLAY0791`: write `root template`. `PLAY0790` to `PLAY0799` check the shell. Read [references/ui-profile-and-theme.md](references/ui-profile-and-theme.md) when writing a profile or theme, or fixing a shell diagnostic.
272
278
 
273
279
  ## A deliverable app declares its identity, titles and labels
@@ -148,6 +148,34 @@ theme Nordic
148
148
  compatible with Cratis.Components
149
149
  ```
150
150
 
151
+ A profile can select a package theme by its quoted display name, or quote a
152
+ locally declared name:
153
+
154
+ ```screenplay excerpt
155
+ ui profile PackageTheme
156
+ theme "Scene Default Light"
157
+
158
+ ui profile DesktopQuoted
159
+ root template AppShell
160
+ theme "Nordic"
161
+ packages
162
+ Cratis.Components
163
+ ```
164
+
165
+ Requires Screenplay 4.227.0 (`screenplay --version`) for quoted references; older
166
+ compilers reject them. Escapes resolve to the theme name. A quoted name not
167
+ declared in the document refers to a package theme and gets no unknown-theme
168
+ `PLAY0231`; do not invent an identifier alias for `"Scene Default Light"`. A
169
+ quoted name matching a declared theme resolves to it and receives the `PLAY0232`
170
+ package compatibility check, like the bare reference `theme Nordic`.
171
+
172
+ Empty, blank or unterminated quoted names are `PLAY0229`. Repeating a profile's
173
+ `theme` selection remains `PLAY0230`. This changes only references inside
174
+ `ui profile`; declaration headers remain identifiers (`theme Nordic`), not
175
+ `theme "Nordic"`. Package selection/compatibility rules are unchanged, and
176
+ parse acceptance does not prove that an installed package provides the theme.
177
+ Source: [UI profile parser](https://github.com/Cratis/Screenplay/blob/main/Source/DotNET/Screenplay/Parsing/UiProfileParser.cs).
178
+
151
179
  - `target platform` takes a comma-separated list. `web`, `ios` and `android` are
152
180
  the documented examples; ⚠️ **the parser accepts any identifier** — there is no
153
181
  enforced list, so a typo is silent.
@@ -3,6 +3,10 @@
3
3
  "input": "Declare the application shell, a screen template and a command form.",
4
4
  "fixtures": [],
5
5
  "assertions": [
6
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.227.0", "file": "references/ui-profile-and-theme.md" },
7
+ { "kind": "skill-contains", "value": "theme \"Scene Default Light\"", "file": "references/ui-profile-and-theme.md" },
8
+ { "kind": "skill-contains", "value": "Empty, blank or unterminated quoted names are `PLAY0229`", "file": "references/ui-profile-and-theme.md" },
9
+ { "kind": "skill-contains", "value": "package compatibility check", "file": "references/ui-profile-and-theme.md" },
6
10
  {
7
11
  "kind": "skill-contains",
8
12
  "value": "PLAY0685",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/pi",
3
- "version": "7.103.6",
3
+ "version": "7.103.7",
4
4
  "description": "Configuration-aware Cratis AI integration for Pi",
5
5
  "type": "module",
6
6
  "files": [