返回 ppt-master
spec_lock.schema.json
根目录 / skills / ppt-master / templates / schemas / spec_lock.schema.json
1 {
2 "$schema": "https://json-schema.org/draft/2020-12/schema",
3 "$id": "ppt-master://schemas/spec-lock/v1",
4 "title": "PPT Master spec_lock.md",
5 "description": "Schema for the Markdown section-and-data-line model emitted by the spec-lock parser.",
6 "type": "object",
7 "required": [
8 "canvas",
9 "communication",
10 "mode",
11 "visual_style",
12 "colors",
13 "typography",
14 "icons",
15 "page_rhythm",
16 "pptx_structure",
17 "forbidden"
18 ],
19 "properties": {
20 "canvas": {"type": "object"},
21 "communication": {"type": "object"},
22 "mode": {"type": "object"},
23 "visual_style": {"type": "object"},
24 "colors": {
25 "type": "object",
26 "properties": {
27 "image_rendering": {"type": "string"},
28 "image_rendering_behavior": {"type": "string"},
29 "image_rendering_references": {"type": "string"}
30 }
31 },
32 "typography": {
33 "type": "object",
34 "properties": {
35 "font_family": {"type": "string", "minLength": 1},
36 "title_family": {"type": "string", "minLength": 1},
37 "body_family": {"type": "string", "minLength": 1},
38 "subtitle_family": {"type": "string", "minLength": 1},
39 "annotation_family": {"type": "string", "minLength": 1},
40 "footer_family": {"type": "string", "minLength": 1},
41 "footnote_family": {"type": "string", "minLength": 1},
42 "data_family": {"type": "string", "minLength": 1},
43 "emphasis_family": {"type": "string", "minLength": 1},
44 "quote_family": {"type": "string", "minLength": 1},
45 "code_family": {"type": "string", "minLength": 1},
46 "body": {"type": "number"},
47 "title": {"type": "number"}
48 }
49 },
50 "icons": {
51 "type": "object",
52 "properties": {
53 "library": {"type": "string"},
54 "inventory": {"type": "string"},
55 "stroke_width": {"enum": [1.5, 2, 3]}
56 }
57 },
58 "images": {"type": "object"},
59 "page_rhythm": {"type": "object"},
60 "pptx_structure": {"type": "object"},
61 "pptx_masters": {"type": "object"},
62 "pptx_layouts": {"type": "object"},
63 "page_pptx_layouts": {"type": "object"},
64 "page_layouts": {"type": "object"},
65 "page_charts": {"type": "object"},
66 "forbidden": {"type": "string"}
67 },
68 "x-markdown": {
69 "version": 1,
70 "marker": "spec-lock/v1",
71 "parser": "heading-data-lines-v1",
72 "strict_lines": true,
73 "unresolved_patterns": ["(?i)\\[fill(?:[^\\]]*)\\]"],
74 "sections": [
75 {
76 "id": "canvas",
77 "pattern": "^canvas$",
78 "required": true,
79 "required_fields": ["viewBox", "format"],
80 "allowed_fields": ["viewBox", "format"]
81 },
82 {
83 "id": "communication",
84 "pattern": "^communication$",
85 "required": true,
86 "required_fields": [
87 "audience",
88 "objective",
89 "core_message"
90 ],
91 "allow_empty_fields": [
92 "audience",
93 "objective",
94 "core_message"
95 ],
96 "allowed_fields": [
97 "primary_language",
98 "audience",
99 "objective",
100 "core_message",
101 "consumption_mode"
102 ],
103 "field_patterns": {
104 "primary_language": "^(?!und(?:-|$))(?:(?:zh(?:-[a-z]{3}){0,3}(?:-[A-Z][a-z]{3}(?:-(?:[A-Z]{2}|[0-9]{3}))?|-(?:[A-Z]{2}|[0-9]{3})))|(?:(?!zh(?:-|$))(?:[a-z]{2,3}(?:-[a-z]{3}){0,3}|[a-z]{4}|[a-z]{5,8})(?:-[A-Z][a-z]{3})?(?:-(?:[A-Z]{2}|[0-9]{3}))?))(?:-(?:[a-z0-9]{5,8}|[0-9][a-z0-9]{3}))*(?:-[0-9a-wy-z](?:-[a-z0-9]{2,8})+)*(?:-x(?:-[a-z0-9]{1,8})+)?$"
105 },
106 "field_enums": {
107 "consumption_mode": ["text", "balanced", "presentation"]
108 }
109 },
110 {
111 "id": "mode",
112 "pattern": "^mode$",
113 "required": true,
114 "required_fields": ["mode"],
115 "allowed_fields": ["mode", "mode_behavior", "mode_references"],
116 "field_patterns": {
117 "mode_references": "^[a-z0-9][a-z0-9-]*(?:\\s*,\\s*[a-z0-9][a-z0-9-]*)*$"
118 },
119 "field_enums": {
120 "mode": ["pyramid", "narrative", "instructional", "showcase", "briefing", "custom"]
121 }
122 },
123 {
124 "id": "visual_style",
125 "pattern": "^visual_style$",
126 "required": true,
127 "required_fields": ["visual_style"],
128 "allowed_fields": ["visual_style", "visual_style_behavior", "visual_style_references"],
129 "field_patterns": {
130 "visual_style_references": "^[a-z0-9][a-z0-9-]*(?:\\s*,\\s*[a-z0-9][a-z0-9-]*)*$"
131 }
132 },
133 {
134 "id": "colors",
135 "pattern": "^colors$",
136 "required": true,
137 "min_entries": 1,
138 "field_patterns": {
139 "image_rendering_references": "^[a-z0-9][a-z0-9-]*(?:\\s*,\\s*[a-z0-9][a-z0-9-]*)*$"
140 }
141 },
142 {
143 "id": "typography",
144 "pattern": "^typography$",
145 "required": true,
146 "required_fields": ["font_family", "body", "title"],
147 "entry_key_pattern": "^[a-z][a-z0-9_]*$",
148 "field_value_rules": [
149 {
150 "key_pattern": "^(?:font_family|[a-z][a-z0-9_]*_family)$",
151 "value_pattern": "^\\S(?:.*\\S)?$",
152 "requirement": "be a non-empty font-family stack"
153 },
154 {
155 "key_pattern": "^(?!font_family$)(?![a-z][a-z0-9_]*_family$)[a-z][a-z0-9_]*$",
156 "value_pattern": "^(?=.*[1-9])(?:[0-9]+(?:\\.[0-9]+)?|\\.[0-9]+)$",
157 "normalize": false,
158 "numeric": "positive_finite",
159 "requirement": "be a positive finite unitless px number"
160 }
161 ]
162 },
163 {
164 "id": "icons",
165 "pattern": "^icons$",
166 "required": true,
167 "required_fields": ["library", "inventory"],
168 "allowed_fields": ["library", "inventory", "stroke_width"],
169 "field_enums": {
170 "stroke_width": ["1.5", "2", "3"]
171 }
172 },
173 {"id": "images", "pattern": "^images$", "required": false},
174 {
175 "id": "page_rhythm",
176 "pattern": "^page_rhythm$",
177 "required": true,
178 "min_entries": 1,
179 "entry_key_pattern": "^P[0-9]{2,}$",
180 "value_enum": ["anchor", "dense", "breathing"]
181 },
182 {
183 "id": "pptx_structure",
184 "pattern": "^pptx_structure$",
185 "required": true,
186 "required_fields": ["mode"],
187 "allowed_fields": ["mode", "template_reuse_scope", "template_adherence"],
188 "field_enums": {
189 "mode": ["flat", "structured"],
190 "template_reuse_scope": ["style", "layout", "mirror"],
191 "template_adherence": ["adaptive", "strict"]
192 }
193 },
194 {
195 "id": "pptx_masters",
196 "pattern": "^pptx_masters$",
197 "required": false,
198 "min_entries": 1,
199 "entry_key_pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$",
200 "value_pattern": "^\\S(?:.*\\S)?$"
201 },
202 {
203 "id": "pptx_layouts",
204 "pattern": "^pptx_layouts$",
205 "required": false,
206 "min_entries": 1,
207 "entry_key_pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$",
208 "value_pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}\\s*\\|\\s*[^|]+\\s*\\|\\s*(?:template:[A-Za-z0-9._-]+|P[0-9]{2,})$"
209 },
210 {
211 "id": "page_pptx_layouts",
212 "pattern": "^page_pptx_layouts$",
213 "required": false,
214 "min_entries": 1,
215 "entry_key_pattern": "^P[0-9]{2,}$",
216 "value_pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
217 },
218 {
219 "id": "page_layouts",
220 "pattern": "^page_layouts$",
221 "required": false,
222 "min_entries": 1,
223 "entry_key_pattern": "^P[0-9]{2,}$",
224 "value_pattern": "^[A-Za-z0-9._-]+$"
225 },
226 {
227 "id": "page_charts",
228 "pattern": "^page_charts$",
229 "required": false,
230 "min_entries": 1,
231 "entry_key_pattern": "^P[0-9]{2,}$",
232 "value_catalog": {
233 "path": "../charts/charts_index.json",
234 "pointer": ["charts"],
235 "asset_path_pattern": "../charts/{value}.svg"
236 }
237 },
238 {"id": "forbidden", "pattern": "^forbidden$", "required": true, "min_body_chars": 1}
239 ],
240 "conditions": [
241 {
242 "id": "custom-mode",
243 "when": {"section": "mode", "field": "mode", "equals": "custom"},
244 "then": {"required_fields": [{"section": "mode", "fields": ["mode_behavior"]}]}
245 },
246 {
247 "id": "custom-visual-style",
248 "when": {"section": "visual_style", "field": "visual_style", "equals": "custom"},
249 "then": {
250 "required_fields": [{"section": "visual_style", "fields": ["visual_style_behavior"]}]
251 }
252 },
253 {
254 "id": "custom-image-rendering",
255 "when": {"section": "colors", "field": "image_rendering", "equals": "custom"},
256 "then": {
257 "required_fields": [{"section": "colors", "fields": ["image_rendering_behavior"]}]
258 }
259 },
260 {
261 "id": "stroke-icon-weight",
262 "when": {"section": "icons", "field": "library", "equals": "tabler-outline"},
263 "then": {"required_fields": [{"section": "icons", "fields": ["stroke_width"]}]}
264 },
265 {
266 "id": "structured-pptx",
267 "when": {"section": "pptx_structure", "field": "mode", "equals": "structured"},
268 "then": {
269 "required_sections": ["pptx_masters", "pptx_layouts", "page_pptx_layouts", "page_layouts"],
270 "required_fields": [
271 {"section": "pptx_structure", "fields": ["template_reuse_scope", "template_adherence"]}
272 ],
273 "field_values": [
274 {
275 "section": "pptx_structure",
276 "field": "template_reuse_scope",
277 "enum": ["layout", "mirror"]
278 }
279 ]
280 }
281 },
282 {
283 "id": "style-is-flat",
284 "when": {"section": "pptx_structure", "field": "template_reuse_scope", "equals": "style"},
285 "then": {
286 "field_values": [{"section": "pptx_structure", "field": "mode", "enum": ["flat"]}]
287 }
288 },
289 {
290 "id": "layout-is-structured",
291 "when": {"section": "pptx_structure", "field": "template_reuse_scope", "equals": "layout"},
292 "then": {
293 "field_values": [{"section": "pptx_structure", "field": "mode", "enum": ["structured"]}]
294 }
295 },
296 {
297 "id": "mirror-is-strict",
298 "when": {"section": "pptx_structure", "field": "template_reuse_scope", "equals": "mirror"},
299 "then": {
300 "required_fields": [
301 {"section": "pptx_structure", "fields": ["template_adherence"]}
302 ],
303 "field_values": [
304 {"section": "pptx_structure", "field": "mode", "enum": ["structured"]},
305 {"section": "pptx_structure", "field": "template_adherence", "enum": ["strict"]}
306 ]
307 }
308 },
309 {
310 "id": "flat-has-no-structured-mappings",
311 "when": {"section": "pptx_structure", "field": "mode", "equals": "flat"},
312 "then": {
313 "forbidden_sections": [
314 "pptx_masters",
315 "pptx_layouts",
316 "page_pptx_layouts",
317 "page_layouts"
318 ],
319 "field_values": [
320 {"section": "pptx_structure", "field": "template_reuse_scope", "enum": ["style"]},
321 {"section": "pptx_structure", "field": "template_adherence", "enum": []}
322 ]
323 }
324 }
325 ],
326 "references": [
327 {
328 "id": "layout-master",
329 "from_section": "pptx_layouts",
330 "value_component": {"separator": "|", "index": 0},
331 "target_section": "pptx_masters"
332 },
333 {
334 "id": "page-pptx-layout",
335 "from_section": "page_pptx_layouts",
336 "target_section": "pptx_layouts"
337 },
338 {
339 "id": "page-input-prototype",
340 "from_section": "page_layouts",
341 "asset_path_pattern": "templates/{value}.svg"
342 }
343 ]
344 }
345 }
346
346 lines JSON