@pixerate/editor 0.163.0 → 0.165.0

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 (159) hide show
  1. package/dist/agent/index.cjs +54 -39
  2. package/dist/agent/index.js +24 -9
  3. package/dist/animation/index.cjs +6 -5
  4. package/dist/animation/index.js +5 -4
  5. package/dist/animation-editor/index.cjs +65 -64
  6. package/dist/animation-editor/index.js +8 -7
  7. package/dist/bridge/cli.cjs +3 -3
  8. package/dist/bridge/cli.js +2 -2
  9. package/dist/bridge/index.cjs +3 -3
  10. package/dist/bridge/index.js +2 -2
  11. package/dist/canvas/displacement.d.cts +34 -2
  12. package/dist/canvas/displacement.d.ts +34 -2
  13. package/dist/canvas/explosion-tools.d.cts +43 -0
  14. package/dist/canvas/explosion-tools.d.ts +43 -0
  15. package/dist/canvas/explosionLayout.d.cts +50 -0
  16. package/dist/canvas/explosionLayout.d.ts +50 -0
  17. package/dist/canvas/explosionState.d.cts +52 -0
  18. package/dist/canvas/explosionState.d.ts +52 -0
  19. package/dist/canvas/index.cjs +512 -168
  20. package/dist/canvas/index.d.cts +3 -0
  21. package/dist/canvas/index.d.ts +3 -0
  22. package/dist/canvas/index.js +434 -90
  23. package/dist/canvas/types.d.cts +27 -2
  24. package/dist/canvas/types.d.ts +27 -2
  25. package/dist/chart/controller.d.cts +31 -2
  26. package/dist/chart/controller.d.ts +31 -2
  27. package/dist/chart/index.cjs +504 -132
  28. package/dist/chart/index.d.cts +2 -0
  29. package/dist/chart/index.d.ts +2 -0
  30. package/dist/chart/index.js +386 -14
  31. package/dist/chart/layout-families.d.cts +7 -0
  32. package/dist/chart/layout-families.d.ts +7 -0
  33. package/dist/chart/links.d.cts +34 -0
  34. package/dist/chart/links.d.ts +34 -0
  35. package/dist/chart/mermaid.d.cts +9 -6
  36. package/dist/chart/mermaid.d.ts +9 -6
  37. package/dist/chart/schemas.d.cts +3 -0
  38. package/dist/chart/schemas.d.ts +3 -0
  39. package/dist/chart/spec.d.cts +3 -2
  40. package/dist/chart/spec.d.ts +3 -2
  41. package/dist/chart/style.d.cts +33 -0
  42. package/dist/chart/style.d.ts +33 -0
  43. package/dist/chart/types.d.cts +24 -2
  44. package/dist/chart/types.d.ts +24 -2
  45. package/dist/{chunk-TALQONZ5.js → chunk-2J5VLJHC.js} +3 -3
  46. package/dist/{chunk-3NEZJCBY.js → chunk-2ZRN43IN.js} +340 -201
  47. package/dist/{chunk-ZVNAMTFO.cjs → chunk-3FSUJIXN.cjs} +18 -174
  48. package/dist/{chunk-RQCMSEM5.cjs → chunk-4QUUHTGJ.cjs} +2 -2
  49. package/dist/{chunk-CIPIESX4.cjs → chunk-4ZC5QJE2.cjs} +3 -3
  50. package/dist/{chunk-S6X2QRVU.cjs → chunk-5UEFBM2M.cjs} +1 -138
  51. package/dist/{chunk-YSAGBIRW.cjs → chunk-64VWWR5U.cjs} +16 -16
  52. package/dist/{chunk-QYZGBVNC.js → chunk-7272D3K2.js} +10 -8
  53. package/dist/{chunk-462WGGXX.cjs → chunk-AMX23CSN.cjs} +27 -16
  54. package/dist/{chunk-3VLOOO3G.js → chunk-BDIM6NVW.js} +1 -1
  55. package/dist/{chunk-POR54B55.js → chunk-CRFSQWKQ.js} +4 -1
  56. package/dist/{chunk-GZ2FM3ZB.js → chunk-DKNEQX7T.js} +6 -162
  57. package/dist/{chunk-JCXMJUQO.cjs → chunk-EGZM52EO.cjs} +3 -3
  58. package/dist/{chunk-ES3UEVUT.cjs → chunk-EUIDTZNQ.cjs} +112 -110
  59. package/dist/{chunk-H3OEM3Q2.js → chunk-F6R67I3A.js} +1 -1
  60. package/dist/{chunk-5FNGLV2D.js → chunk-FEU2XVQH.js} +15 -3
  61. package/dist/{chunk-SZA42R4N.js → chunk-FRBRLKNQ.js} +154 -16
  62. package/dist/chunk-HIDFL5LQ.js +484 -0
  63. package/dist/{chunk-MKTDELCD.js → chunk-I5MRJW7B.js} +1 -1
  64. package/dist/{chunk-SDHZG5TF.js → chunk-ILP77UD6.js} +160 -2
  65. package/dist/{chunk-GKNEJ6EN.cjs → chunk-IMRXC7OA.cjs} +241 -103
  66. package/dist/chunk-KGRZMHZB.js +204 -0
  67. package/dist/{chunk-SET6KJOP.js → chunk-LPIKXPBM.js} +1 -1
  68. package/dist/{chunk-BQWGN5WH.js → chunk-M2TPMYJE.js} +1 -1
  69. package/dist/{chunk-GTELFJRE.cjs → chunk-M5GLQQWG.cjs} +2 -2
  70. package/dist/{chunk-4VU4CP7R.js → chunk-MHLU6GRJ.js} +1 -138
  71. package/dist/{chunk-D54JHQK2.cjs → chunk-MKXK6E4O.cjs} +51 -51
  72. package/dist/{chunk-DAPQGA55.js → chunk-N7NBGT2Y.js} +2 -2
  73. package/dist/chunk-O6OGNDND.js +164 -0
  74. package/dist/{chunk-22KLZZGH.cjs → chunk-ODFCS7HF.cjs} +8 -8
  75. package/dist/{chunk-PA3IMPPS.cjs → chunk-OVYQAYGH.cjs} +81 -81
  76. package/dist/{chunk-YXOW456B.js → chunk-PPEDZ5WR.js} +1 -1
  77. package/dist/{chunk-YGG7WDWT.cjs → chunk-Q25WAFTD.cjs} +21 -18
  78. package/dist/{chunk-SBQVEBSU.cjs → chunk-QO2T6KA5.cjs} +165 -67
  79. package/dist/{chunk-24M7VD6M.cjs → chunk-S4EIAIEW.cjs} +7 -7
  80. package/dist/{chunk-M4MIZPQI.cjs → chunk-SJ2CPTQC.cjs} +189 -15
  81. package/dist/chunk-TFF2GTGN.cjs +153 -0
  82. package/dist/chunk-TTCJPX4U.cjs +204 -0
  83. package/dist/{chunk-NZD2MZJC.cjs → chunk-TVQW26AV.cjs} +35 -23
  84. package/dist/{chunk-R3P2M7HU.cjs → chunk-UVXTOZ2B.cjs} +346 -207
  85. package/dist/{chunk-WI7QJA7A.cjs → chunk-UXETV2NC.cjs} +161 -3
  86. package/dist/{chunk-Z4P2RBMJ.js → chunk-V5GSY3NC.js} +101 -3
  87. package/dist/{chunk-QY4KUDMY.js → chunk-VRXXAXUT.js} +2 -2
  88. package/dist/chunk-VU6WQSMB.cjs +164 -0
  89. package/dist/{chunk-OXERWBKE.js → chunk-X5W645RI.js} +3 -3
  90. package/dist/{chunk-NHLYK3AX.js → chunk-XBQX76CT.js} +182 -8
  91. package/dist/{chunk-5AARIS3R.cjs → chunk-XCDGM7TD.cjs} +37 -37
  92. package/dist/{chunk-EVXQNQND.js → chunk-XZB3TJ6K.js} +16 -5
  93. package/dist/chunk-YBAPT7NL.js +153 -0
  94. package/dist/chunk-Z2UQYMPS.cjs +484 -0
  95. package/dist/color/index.cjs +5 -3
  96. package/dist/color/index.js +12 -10
  97. package/dist/diagram/index.cjs +55 -243
  98. package/dist/diagram/index.js +12 -200
  99. package/dist/export/index.cjs +7 -6
  100. package/dist/export/index.js +6 -5
  101. package/dist/extensions/index.cjs +12 -9
  102. package/dist/extensions/index.js +11 -8
  103. package/dist/gradient/index.cjs +29 -27
  104. package/dist/gradient/index.js +6 -4
  105. package/dist/image-editor/index.cjs +644 -643
  106. package/dist/image-editor/index.js +7 -6
  107. package/dist/index.cjs +21 -18
  108. package/dist/index.js +14 -11
  109. package/dist/paint-editor/index.cjs +19 -18
  110. package/dist/paint-editor/index.js +7 -6
  111. package/dist/parameters/index.cjs +2 -2
  112. package/dist/parameters/index.js +1 -1
  113. package/dist/persistence/assetWrites.d.cts +22 -0
  114. package/dist/persistence/assetWrites.d.ts +22 -0
  115. package/dist/persistence/assets.d.cts +71 -0
  116. package/dist/persistence/assets.d.ts +71 -0
  117. package/dist/persistence/documentStore.d.cts +17 -1
  118. package/dist/persistence/documentStore.d.ts +17 -1
  119. package/dist/persistence/documentTools.d.cts +5 -1
  120. package/dist/persistence/documentTools.d.ts +5 -1
  121. package/dist/persistence/editorAutosave.d.cts +7 -0
  122. package/dist/persistence/editorAutosave.d.ts +7 -0
  123. package/dist/persistence/index.cjs +141 -21
  124. package/dist/persistence/index.js +130 -10
  125. package/dist/persistence/storage.d.cts +13 -1
  126. package/dist/persistence/storage.d.ts +13 -1
  127. package/dist/spreadsheet/index.cjs +3 -3
  128. package/dist/spreadsheet/index.js +2 -2
  129. package/dist/tokens/index.cjs +11 -3
  130. package/dist/tokens/index.d.cts +1 -0
  131. package/dist/tokens/index.d.ts +1 -0
  132. package/dist/tokens/index.js +10 -2
  133. package/dist/tokens/style.d.cts +36 -0
  134. package/dist/tokens/style.d.ts +36 -0
  135. package/dist/tools/index.cjs +15 -3
  136. package/dist/tools/index.d.cts +2 -0
  137. package/dist/tools/index.d.ts +2 -0
  138. package/dist/tools/index.js +14 -2
  139. package/dist/tools/style-tools.d.cts +19 -0
  140. package/dist/tools/style-tools.d.ts +19 -0
  141. package/dist/tools/style.d.cts +212 -0
  142. package/dist/tools/style.d.ts +212 -0
  143. package/dist/tools/view.d.cts +6 -0
  144. package/dist/tools/view.d.ts +6 -0
  145. package/dist/typography/index.cjs +8 -6
  146. package/dist/typography/index.js +5 -3
  147. package/dist/vector/index.cjs +953 -952
  148. package/dist/vector/index.js +7 -6
  149. package/dist/video-editor/index.cjs +8 -7
  150. package/dist/video-editor/index.js +6 -5
  151. package/package.json +1 -1
  152. package/skills/README.md +12 -0
  153. package/skills/pixerate-agent-tools/SKILL.md +34 -1
  154. package/skills/pixerate-chart/SKILL.md +41 -9
  155. package/skills/pixerate-image-editor/SKILL.md +2 -0
  156. package/skills/pixerate-paint-editor/SKILL.md +2 -0
  157. package/skills/pixerate-tokens/SKILL.md +5 -0
  158. package/dist/chunk-ERAGQL2N.cjs +0 -68
  159. package/dist/chunk-KMU6QJB7.js +0 -68
@@ -0,0 +1,212 @@
1
+ /**
2
+ * House-style skills: preferences and rules a host hands agents at runtime, per editor domain.
3
+ *
4
+ * A style skill is a folder like a built-in agent skill: a `SKILL.md` of prose preferences
5
+ * (frontmatter `name`, `description` and optionally `domains`) plus one optional profile per
6
+ * domain (`chart.json`, `tokens.json`) holding structured rules. Hosts keep style skills in
7
+ * layers (org, workspace, user, ...); a {@link StyleResolver} merges them per domain, resolves
8
+ * `$token` references and runs the domain's checks. Dependency-free: domains bring their own
9
+ * profile schema and checks (`chartStyleDomain`, `tokensStyleDomain`).
10
+ */
11
+ import { type JsonSchema } from './schema.cjs';
12
+ import { type SkillFiles } from './skills.cjs';
13
+ type MaybePromise<T> = T | Promise<T>;
14
+ /** What a store records about one style skill, apart from its files. */
15
+ export interface StyleSkillState {
16
+ /** `false` switches the skill off (also for a skill another layer holds). Default on. */
17
+ enabled?: boolean;
18
+ /** Sort key among skills of the same layer (lower first, default 0). */
19
+ order?: number;
20
+ }
21
+ /** One entry of {@link StyleStore.list}: a skill this store holds, or state for another layer's. */
22
+ export interface StyleStoreEntry extends StyleSkillState {
23
+ name: string;
24
+ }
25
+ /**
26
+ * Where one layer's style skills live. Hosts implement it over their own storage (a database,
27
+ * a bucket, the file system); {@link memoryStyleStore} holds skills in memory.
28
+ */
29
+ export interface StyleStore {
30
+ /** Skill names with their state. An entry whose `SKILL.md` this store lacks only carries state. */
31
+ list(): MaybePromise<readonly StyleStoreEntry[]>;
32
+ /** A file of a skill (`SKILL.md`, `chart.json`, `references/x.md`), or `undefined`. */
33
+ read(name: string, file: string): MaybePromise<string | undefined>;
34
+ /** Every file of a skill, relative to its folder. */
35
+ files(name: string): MaybePromise<readonly string[]>;
36
+ /** Called when the store's skills or state change; returns an unsubscribe function. */
37
+ subscribe?(listener: () => void): () => void;
38
+ }
39
+ /** A layer of style skills, from general (first) to specific (last). */
40
+ export interface StyleLayer {
41
+ /** Layer id, shown to agents as where a rule came from: `org`, `workspace`, `user`, ... */
42
+ id: string;
43
+ store: StyleStore;
44
+ /**
45
+ * Later layers cannot replace this layer's skills or change the profile fields it sets.
46
+ * Their attempts are left out and reported as issues.
47
+ */
48
+ locked?: boolean;
49
+ /** Later layers cannot switch this layer's skills off. */
50
+ required?: boolean;
51
+ }
52
+ /** A finding: one house-style rule the current state breaks. */
53
+ export interface StyleFinding {
54
+ /** Id of the check that found it. */
55
+ check: string;
56
+ severity: 'error' | 'warning' | 'info';
57
+ /** What is wrong and how to fix it, in one sentence. */
58
+ message: string;
59
+ /** What it is about, in the shape the domain's write tools take (e.g. a chart selection). */
60
+ target?: unknown;
61
+ /** The layer whose profile asked for the check. */
62
+ layer?: string;
63
+ }
64
+ /**
65
+ * A rule a domain can check. A profile turns it on by id in its `checks` list, with options:
66
+ * `"palette-only"` or `{ "id": "min-contrast", "ratio": 4.5 }`.
67
+ */
68
+ export interface StyleCheck<State = unknown> {
69
+ id: string;
70
+ /** What it checks, for agents and admin screens. */
71
+ description: string;
72
+ /** Schema of its options (validated when a profile loads). Default: no options. */
73
+ optionsSchema?: JsonSchema;
74
+ /** The findings for `state` under the resolved `profile`. Throwing reports the check as skipped. */
75
+ run(state: State, profile: Readonly<Record<string, unknown>>, options: Readonly<Record<string, unknown>>): readonly Omit<StyleFinding, 'check' | 'layer'>[];
76
+ }
77
+ /** An editor domain that can have a house style: its profile file, schema and checks. */
78
+ export interface StyleDomain<State = unknown> {
79
+ /** Domain id, the domain skill's name without `pixerate-` (`chart`, `tokens`). The profile file is `<id>.json`. */
80
+ id: string;
81
+ title: string;
82
+ /** What a profile for this domain can set. */
83
+ description: string;
84
+ /** Schema of the profile (the `checks` property is validated separately). */
85
+ profileSchema: JsonSchema & {
86
+ type: 'object';
87
+ };
88
+ checks: readonly StyleCheck<State>[];
89
+ }
90
+ /** A `$token` reference in a profile: `{ "$token": "brand/primary", "mode": "Dark" }`. */
91
+ export interface StyleTokenRef {
92
+ /** Variable name (`brand/primary`) or id. */
93
+ token: string;
94
+ /** Mode name or id (default: the collection's default mode). */
95
+ mode?: string;
96
+ }
97
+ /** Resolves `$token` references in profiles (see `createTokenStyleSource` in `@pixerate/editor/tokens`). */
98
+ export interface StyleTokenSource {
99
+ /** The value, or an error saying why the reference does not resolve. */
100
+ resolve(ref: StyleTokenRef): {
101
+ ok: true;
102
+ value: string | number | boolean;
103
+ } | {
104
+ ok: false;
105
+ message: string;
106
+ };
107
+ subscribe?(listener: () => void): () => void;
108
+ }
109
+ export interface StyleIssue {
110
+ /** Skill the issue is about (absent for layer-wide issues). */
111
+ skill?: string;
112
+ layer?: string;
113
+ message: string;
114
+ }
115
+ /** A style skill as a resolver lists it. */
116
+ export interface StyleSkillInfo {
117
+ name: string;
118
+ description: string;
119
+ /** The layer whose copy is used. */
120
+ layer: string;
121
+ /** Domains it applies to (every registered domain when its frontmatter names none). */
122
+ domains: string[];
123
+ /** Domains it has a profile for. */
124
+ profiles: string[];
125
+ enabled: boolean;
126
+ order: number;
127
+ /** Why it, or part of it, is left out. A skill with issues and no usable part is not applied. */
128
+ issues: string[];
129
+ }
130
+ /** A skill's prose as it applies to one domain. */
131
+ export interface ResolvedStyleSkill {
132
+ name: string;
133
+ description: string;
134
+ layer: string;
135
+ /** The `SKILL.md` body (without frontmatter). */
136
+ body: string;
137
+ }
138
+ /** Everything that applies to one domain, merged. */
139
+ export interface ResolvedStyle {
140
+ domain: string;
141
+ /** Applicable skills, general to specific. */
142
+ skills: ResolvedStyleSkill[];
143
+ /** The merged profile, with `$token` references replaced by their values. */
144
+ profile: Record<string, unknown>;
145
+ /** Which layer set each profile field (`palette`, `theme.fontFamily`). */
146
+ sources: Record<string, string>;
147
+ issues: StyleIssue[];
148
+ }
149
+ /** The result of running a domain's checks. */
150
+ export interface StyleCheckReport {
151
+ findings: StyleFinding[];
152
+ /** Checks that ran. */
153
+ ran: string[];
154
+ /** Checks the profile asked for that could not run, with the reason. */
155
+ skipped: {
156
+ check: string;
157
+ reason: string;
158
+ }[];
159
+ }
160
+ export interface StyleResolverOptions {
161
+ /** Layers from general to specific. */
162
+ layers: readonly StyleLayer[];
163
+ /** Domains style skills may target. */
164
+ domains: readonly StyleDomain<any>[];
165
+ /** Resolves `$token` references; without it a profile with one is reported as an issue. */
166
+ tokens?: StyleTokenSource;
167
+ }
168
+ /** Merges house-style layers per domain. Build it with {@link createStyleResolver}. */
169
+ export interface StyleResolver {
170
+ readonly layers: readonly StyleLayer[];
171
+ readonly domains: readonly StyleDomain<any>[];
172
+ /** Every style skill across layers (switched-off ones too), general to specific. */
173
+ list(options?: {
174
+ domain?: string;
175
+ }): Promise<StyleSkillInfo[]>;
176
+ /** The resolved style for a domain. Throws for an unknown domain. */
177
+ resolve(domain: string): Promise<ResolvedStyle>;
178
+ /** A file of the skill copy in use. */
179
+ readFile(name: string, file: string): Promise<string | undefined>;
180
+ /** Files of the skill copy in use (`undefined` for an unknown skill). */
181
+ files(name: string): Promise<string[] | undefined>;
182
+ /** Runs the domain's checks that the resolved profile turns on against `state`. */
183
+ check<State>(domain: string, state: State): Promise<StyleCheckReport & {
184
+ style: ResolvedStyle;
185
+ }>;
186
+ /** Called when a store or the token source changes; returns an unsubscribe function. */
187
+ subscribe(listener: () => void): () => void;
188
+ }
189
+ /** The `domains` frontmatter field: `[chart, tokens]`, `chart, tokens` or one name. */
190
+ export declare function parseStyleDomains(markdown: string): string[] | undefined;
191
+ /**
192
+ * A style store in memory, from skill files keyed `<skill>/<file>` (the {@link SkillFiles}
193
+ * shape), with optional state per skill. `set`, `remove` and `setState` notify subscribers.
194
+ */
195
+ export declare function memoryStyleStore(initial?: SkillFiles, state?: Readonly<Record<string, StyleSkillState>>): StyleStore & {
196
+ set(name: string, files: Readonly<Record<string, string>>): void;
197
+ remove(name: string): void;
198
+ setState(name: string, state: StyleSkillState | undefined): void;
199
+ };
200
+ /**
201
+ * Builds a {@link StyleResolver} over layers of style skills. Reads go to the stores on every
202
+ * call, so a host's change shows up at once; `subscribe` tells open views to refresh.
203
+ */
204
+ export declare function createStyleResolver(options: StyleResolverOptions): StyleResolver;
205
+ /** Runs the checks a resolved profile turns on. A check that is unknown or throws is skipped with the reason. */
206
+ export declare function runStyleChecks<State>(domain: StyleDomain<State>, state: State, style: ResolvedStyle): StyleCheckReport;
207
+ /**
208
+ * A resolved style as text for a model: one `<style_skill>` block per skill (naming its layer;
209
+ * text that tries to open or close a block is escaped) and the merged profile as JSON.
210
+ */
211
+ export declare function renderStyle(style: ResolvedStyle): string;
212
+ export {};
@@ -0,0 +1,212 @@
1
+ /**
2
+ * House-style skills: preferences and rules a host hands agents at runtime, per editor domain.
3
+ *
4
+ * A style skill is a folder like a built-in agent skill: a `SKILL.md` of prose preferences
5
+ * (frontmatter `name`, `description` and optionally `domains`) plus one optional profile per
6
+ * domain (`chart.json`, `tokens.json`) holding structured rules. Hosts keep style skills in
7
+ * layers (org, workspace, user, ...); a {@link StyleResolver} merges them per domain, resolves
8
+ * `$token` references and runs the domain's checks. Dependency-free: domains bring their own
9
+ * profile schema and checks (`chartStyleDomain`, `tokensStyleDomain`).
10
+ */
11
+ import { type JsonSchema } from './schema.js';
12
+ import { type SkillFiles } from './skills.js';
13
+ type MaybePromise<T> = T | Promise<T>;
14
+ /** What a store records about one style skill, apart from its files. */
15
+ export interface StyleSkillState {
16
+ /** `false` switches the skill off (also for a skill another layer holds). Default on. */
17
+ enabled?: boolean;
18
+ /** Sort key among skills of the same layer (lower first, default 0). */
19
+ order?: number;
20
+ }
21
+ /** One entry of {@link StyleStore.list}: a skill this store holds, or state for another layer's. */
22
+ export interface StyleStoreEntry extends StyleSkillState {
23
+ name: string;
24
+ }
25
+ /**
26
+ * Where one layer's style skills live. Hosts implement it over their own storage (a database,
27
+ * a bucket, the file system); {@link memoryStyleStore} holds skills in memory.
28
+ */
29
+ export interface StyleStore {
30
+ /** Skill names with their state. An entry whose `SKILL.md` this store lacks only carries state. */
31
+ list(): MaybePromise<readonly StyleStoreEntry[]>;
32
+ /** A file of a skill (`SKILL.md`, `chart.json`, `references/x.md`), or `undefined`. */
33
+ read(name: string, file: string): MaybePromise<string | undefined>;
34
+ /** Every file of a skill, relative to its folder. */
35
+ files(name: string): MaybePromise<readonly string[]>;
36
+ /** Called when the store's skills or state change; returns an unsubscribe function. */
37
+ subscribe?(listener: () => void): () => void;
38
+ }
39
+ /** A layer of style skills, from general (first) to specific (last). */
40
+ export interface StyleLayer {
41
+ /** Layer id, shown to agents as where a rule came from: `org`, `workspace`, `user`, ... */
42
+ id: string;
43
+ store: StyleStore;
44
+ /**
45
+ * Later layers cannot replace this layer's skills or change the profile fields it sets.
46
+ * Their attempts are left out and reported as issues.
47
+ */
48
+ locked?: boolean;
49
+ /** Later layers cannot switch this layer's skills off. */
50
+ required?: boolean;
51
+ }
52
+ /** A finding: one house-style rule the current state breaks. */
53
+ export interface StyleFinding {
54
+ /** Id of the check that found it. */
55
+ check: string;
56
+ severity: 'error' | 'warning' | 'info';
57
+ /** What is wrong and how to fix it, in one sentence. */
58
+ message: string;
59
+ /** What it is about, in the shape the domain's write tools take (e.g. a chart selection). */
60
+ target?: unknown;
61
+ /** The layer whose profile asked for the check. */
62
+ layer?: string;
63
+ }
64
+ /**
65
+ * A rule a domain can check. A profile turns it on by id in its `checks` list, with options:
66
+ * `"palette-only"` or `{ "id": "min-contrast", "ratio": 4.5 }`.
67
+ */
68
+ export interface StyleCheck<State = unknown> {
69
+ id: string;
70
+ /** What it checks, for agents and admin screens. */
71
+ description: string;
72
+ /** Schema of its options (validated when a profile loads). Default: no options. */
73
+ optionsSchema?: JsonSchema;
74
+ /** The findings for `state` under the resolved `profile`. Throwing reports the check as skipped. */
75
+ run(state: State, profile: Readonly<Record<string, unknown>>, options: Readonly<Record<string, unknown>>): readonly Omit<StyleFinding, 'check' | 'layer'>[];
76
+ }
77
+ /** An editor domain that can have a house style: its profile file, schema and checks. */
78
+ export interface StyleDomain<State = unknown> {
79
+ /** Domain id, the domain skill's name without `pixerate-` (`chart`, `tokens`). The profile file is `<id>.json`. */
80
+ id: string;
81
+ title: string;
82
+ /** What a profile for this domain can set. */
83
+ description: string;
84
+ /** Schema of the profile (the `checks` property is validated separately). */
85
+ profileSchema: JsonSchema & {
86
+ type: 'object';
87
+ };
88
+ checks: readonly StyleCheck<State>[];
89
+ }
90
+ /** A `$token` reference in a profile: `{ "$token": "brand/primary", "mode": "Dark" }`. */
91
+ export interface StyleTokenRef {
92
+ /** Variable name (`brand/primary`) or id. */
93
+ token: string;
94
+ /** Mode name or id (default: the collection's default mode). */
95
+ mode?: string;
96
+ }
97
+ /** Resolves `$token` references in profiles (see `createTokenStyleSource` in `@pixerate/editor/tokens`). */
98
+ export interface StyleTokenSource {
99
+ /** The value, or an error saying why the reference does not resolve. */
100
+ resolve(ref: StyleTokenRef): {
101
+ ok: true;
102
+ value: string | number | boolean;
103
+ } | {
104
+ ok: false;
105
+ message: string;
106
+ };
107
+ subscribe?(listener: () => void): () => void;
108
+ }
109
+ export interface StyleIssue {
110
+ /** Skill the issue is about (absent for layer-wide issues). */
111
+ skill?: string;
112
+ layer?: string;
113
+ message: string;
114
+ }
115
+ /** A style skill as a resolver lists it. */
116
+ export interface StyleSkillInfo {
117
+ name: string;
118
+ description: string;
119
+ /** The layer whose copy is used. */
120
+ layer: string;
121
+ /** Domains it applies to (every registered domain when its frontmatter names none). */
122
+ domains: string[];
123
+ /** Domains it has a profile for. */
124
+ profiles: string[];
125
+ enabled: boolean;
126
+ order: number;
127
+ /** Why it, or part of it, is left out. A skill with issues and no usable part is not applied. */
128
+ issues: string[];
129
+ }
130
+ /** A skill's prose as it applies to one domain. */
131
+ export interface ResolvedStyleSkill {
132
+ name: string;
133
+ description: string;
134
+ layer: string;
135
+ /** The `SKILL.md` body (without frontmatter). */
136
+ body: string;
137
+ }
138
+ /** Everything that applies to one domain, merged. */
139
+ export interface ResolvedStyle {
140
+ domain: string;
141
+ /** Applicable skills, general to specific. */
142
+ skills: ResolvedStyleSkill[];
143
+ /** The merged profile, with `$token` references replaced by their values. */
144
+ profile: Record<string, unknown>;
145
+ /** Which layer set each profile field (`palette`, `theme.fontFamily`). */
146
+ sources: Record<string, string>;
147
+ issues: StyleIssue[];
148
+ }
149
+ /** The result of running a domain's checks. */
150
+ export interface StyleCheckReport {
151
+ findings: StyleFinding[];
152
+ /** Checks that ran. */
153
+ ran: string[];
154
+ /** Checks the profile asked for that could not run, with the reason. */
155
+ skipped: {
156
+ check: string;
157
+ reason: string;
158
+ }[];
159
+ }
160
+ export interface StyleResolverOptions {
161
+ /** Layers from general to specific. */
162
+ layers: readonly StyleLayer[];
163
+ /** Domains style skills may target. */
164
+ domains: readonly StyleDomain<any>[];
165
+ /** Resolves `$token` references; without it a profile with one is reported as an issue. */
166
+ tokens?: StyleTokenSource;
167
+ }
168
+ /** Merges house-style layers per domain. Build it with {@link createStyleResolver}. */
169
+ export interface StyleResolver {
170
+ readonly layers: readonly StyleLayer[];
171
+ readonly domains: readonly StyleDomain<any>[];
172
+ /** Every style skill across layers (switched-off ones too), general to specific. */
173
+ list(options?: {
174
+ domain?: string;
175
+ }): Promise<StyleSkillInfo[]>;
176
+ /** The resolved style for a domain. Throws for an unknown domain. */
177
+ resolve(domain: string): Promise<ResolvedStyle>;
178
+ /** A file of the skill copy in use. */
179
+ readFile(name: string, file: string): Promise<string | undefined>;
180
+ /** Files of the skill copy in use (`undefined` for an unknown skill). */
181
+ files(name: string): Promise<string[] | undefined>;
182
+ /** Runs the domain's checks that the resolved profile turns on against `state`. */
183
+ check<State>(domain: string, state: State): Promise<StyleCheckReport & {
184
+ style: ResolvedStyle;
185
+ }>;
186
+ /** Called when a store or the token source changes; returns an unsubscribe function. */
187
+ subscribe(listener: () => void): () => void;
188
+ }
189
+ /** The `domains` frontmatter field: `[chart, tokens]`, `chart, tokens` or one name. */
190
+ export declare function parseStyleDomains(markdown: string): string[] | undefined;
191
+ /**
192
+ * A style store in memory, from skill files keyed `<skill>/<file>` (the {@link SkillFiles}
193
+ * shape), with optional state per skill. `set`, `remove` and `setState` notify subscribers.
194
+ */
195
+ export declare function memoryStyleStore(initial?: SkillFiles, state?: Readonly<Record<string, StyleSkillState>>): StyleStore & {
196
+ set(name: string, files: Readonly<Record<string, string>>): void;
197
+ remove(name: string): void;
198
+ setState(name: string, state: StyleSkillState | undefined): void;
199
+ };
200
+ /**
201
+ * Builds a {@link StyleResolver} over layers of style skills. Reads go to the stores on every
202
+ * call, so a host's change shows up at once; `subscribe` tells open views to refresh.
203
+ */
204
+ export declare function createStyleResolver(options: StyleResolverOptions): StyleResolver;
205
+ /** Runs the checks a resolved profile turns on. A check that is unknown or throws is skipped with the reason. */
206
+ export declare function runStyleChecks<State>(domain: StyleDomain<State>, state: State, style: ResolvedStyle): StyleCheckReport;
207
+ /**
208
+ * A resolved style as text for a model: one `<style_skill>` block per skill (naming its layer;
209
+ * text that tries to open or close a block is escaped) and the merged profile as JSON.
210
+ */
211
+ export declare function renderStyle(style: ResolvedStyle): string;
212
+ export {};
@@ -1,5 +1,6 @@
1
1
  import type { McpListToolsResult, McpToolDefinition, McpToolResult, ToolCallOptions, ToolSource, ToolsetInfo } from './registry.cjs';
2
2
  import { type SkillFiles } from './skills.cjs';
3
+ import type { StyleResolver } from './style.cjs';
3
4
  export interface ToolDiscoveryOptions {
4
5
  /** Toolsets listed from the start (default none: the agent enables what it needs). */
5
6
  enabled?: readonly string[];
@@ -7,6 +8,11 @@ export interface ToolDiscoveryOptions {
7
8
  skills?: SkillFiles;
8
9
  /** Default and maximum number of `search_tools` results (default 10, at most 50). */
9
10
  searchLimit?: number;
11
+ /**
12
+ * House styles: `list_toolsets` marks each toolset whose domain (its skill's name without
13
+ * `pixerate-`) has style skills, and `enable_tools` says to read them with `get_style`.
14
+ */
15
+ styles?: StyleResolver;
10
16
  }
11
17
  export interface ToolViewOptions {
12
18
  /**
@@ -1,5 +1,6 @@
1
1
  import type { McpListToolsResult, McpToolDefinition, McpToolResult, ToolCallOptions, ToolSource, ToolsetInfo } from './registry.js';
2
2
  import { type SkillFiles } from './skills.js';
3
+ import type { StyleResolver } from './style.js';
3
4
  export interface ToolDiscoveryOptions {
4
5
  /** Toolsets listed from the start (default none: the agent enables what it needs). */
5
6
  enabled?: readonly string[];
@@ -7,6 +8,11 @@ export interface ToolDiscoveryOptions {
7
8
  skills?: SkillFiles;
8
9
  /** Default and maximum number of `search_tools` results (default 10, at most 50). */
9
10
  searchLimit?: number;
11
+ /**
12
+ * House styles: `list_toolsets` marks each toolset whose domain (its skill's name without
13
+ * `pixerate-`) has style skills, and `enable_tools` says to read them with `get_style`.
14
+ */
15
+ styles?: StyleResolver;
10
16
  }
11
17
  export interface ToolViewOptions {
12
18
  /**
@@ -18,10 +18,12 @@
18
18
  var _chunkFKUKJ3XAcjs = require('../chunk-FKUKJ3XA.cjs');
19
19
 
20
20
 
21
+ var _chunkTFF2GTGNcjs = require('../chunk-TFF2GTGN.cjs');
21
22
 
22
23
 
23
24
 
24
- var _chunkS6X2QRVUcjs = require('../chunk-S6X2QRVU.cjs');
25
+
26
+ var _chunk5UEFBM2Mcjs = require('../chunk-5UEFBM2M.cjs');
25
27
  require('../chunk-IPJ3TEYR.cjs');
26
28
 
27
29
  // src/typography/types.ts
@@ -418,13 +420,13 @@ function isLargeText(font) {
418
420
  function checkTypographyAccessibility(options) {
419
421
  const { font } = options;
420
422
  if (!Number.isFinite(font.size) || font.size <= 0) throw new Error(`Font size ${font.size} must be a positive number of px.`);
421
- const fg = _chunkS6X2QRVUcjs.parseColor.call(void 0, options.foreground);
423
+ const fg = _chunk5UEFBM2Mcjs.parseColor.call(void 0, options.foreground);
422
424
  if (!fg) throw new Error(`"${options.foreground}" is not a colour I can read; use hex (#2a4b8d), rgb(), hsl(), oklch() or a CSS colour name.`);
423
- const bg = _chunkS6X2QRVUcjs.parseColor.call(void 0, options.background);
425
+ const bg = _chunk5UEFBM2Mcjs.parseColor.call(void 0, options.background);
424
426
  if (!bg) throw new Error(`"${options.background}" is not a colour I can read; use hex (#ffffff), rgb(), hsl(), oklch() or a CSS colour name.`);
425
427
  const large = isLargeText(font);
426
- const ratio = Math.round(_chunkS6X2QRVUcjs.contrastRatio.call(void 0, fg, bg) * 100) / 100;
427
- const level = _chunkS6X2QRVUcjs.contrastLevel.call(void 0, ratio, { large });
428
+ const ratio = Math.round(_chunk5UEFBM2Mcjs.contrastRatio.call(void 0, fg, bg) * 100) / 100;
429
+ const level = _chunk5UEFBM2Mcjs.contrastLevel.call(void 0, ratio, { large });
428
430
  const passesAA = level !== "fail";
429
431
  const bold = _chunkFKUKJ3XAcjs.normalizeFontWeight.call(void 0, font.weight) >= 700;
430
432
  const issues = [];
@@ -433,7 +435,7 @@ function checkTypographyAccessibility(options) {
433
435
  if (font.size < 12) issues.push(`${font.size}px text is hard to read at any contrast; use 12px or more (16px for body text).`);
434
436
  const weight = _chunkFKUKJ3XAcjs.normalizeFontWeight.call(void 0, font.weight);
435
437
  if (weight <= 300 && font.size < 24) issues.push(`Weight ${weight} at ${font.size}px has thin strokes that lower effective contrast; use 400 or heavier below 24px.`);
436
- const suggestion = passesAA ? void 0 : _chunkS6X2QRVUcjs.suggestAccessibleForeground.call(void 0, fg, bg, { large });
438
+ const suggestion = passesAA ? void 0 : _chunkTFF2GTGNcjs.suggestAccessibleForeground.call(void 0, fg, bg, { large });
437
439
  return {
438
440
  ratio,
439
441
  large,
@@ -16,12 +16,14 @@ import {
16
16
  normalizeFontWeight,
17
17
  webFontSummary
18
18
  } from "../chunk-CJE5MOIS.js";
19
+ import {
20
+ suggestAccessibleForeground
21
+ } from "../chunk-YBAPT7NL.js";
19
22
  import {
20
23
  contrastLevel,
21
24
  contrastRatio,
22
- parseColor,
23
- suggestAccessibleForeground
24
- } from "../chunk-4VU4CP7R.js";
25
+ parseColor
26
+ } from "../chunk-MHLU6GRJ.js";
25
27
  import "../chunk-6ONMQ6WF.js";
26
28
 
27
29
  // src/typography/types.ts