Sync third-party and MCP marketplace plugins
Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources. Confidence: high Scope-risk: narrow Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history. Tested: Marketplace validation passed.
This commit is contained in:
@@ -42,8 +42,8 @@
|
||||
"repo": "https://github.com/JuliusBrussee/caveman.git",
|
||||
"ref": "main",
|
||||
"adapter": "codex-plugin",
|
||||
"commit": "766dce6b1394ebb56a3090748d5a0240a5aefb36",
|
||||
"syncedAt": "2026-08-17T16:00:00Z"
|
||||
"commit": "ae405e872270acc57484693612ae038b16c8f6cd",
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "taste-skill",
|
||||
@@ -51,8 +51,8 @@
|
||||
"repo": "https://github.com/Leonxlnx/taste-skill.git",
|
||||
"ref": "main",
|
||||
"adapter": "skill-collection",
|
||||
"commit": "e988add20dab0fa97d7a76781c48961c8184288e",
|
||||
"syncedAt": "2026-07-24T06:18:20Z"
|
||||
"commit": "dfb6f9f9e93a39f673b1827c0889cc28326d1800",
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "shadcn",
|
||||
@@ -60,8 +60,8 @@
|
||||
"repo": "https://github.com/shadcn-ui/ui.git",
|
||||
"ref": "main",
|
||||
"adapter": "claude-skill",
|
||||
"commit": "8a7701ec27eb9cb8e0377db769fbe6d744113c52",
|
||||
"syncedAt": "2026-08-17T16:00:00Z"
|
||||
"commit": "5c8f5b06746ac445e97a50cbeb63253d657d7541",
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "frontend-slides",
|
||||
@@ -96,8 +96,8 @@
|
||||
"repo": "https://github.com/hugohe3/ppt-master.git",
|
||||
"ref": "main",
|
||||
"adapter": "claude-skill",
|
||||
"commit": "3b01e0cbe63c0dba316298e2d0aa6a09c4f3ef2d",
|
||||
"syncedAt": "2026-08-17T16:00:00Z"
|
||||
"commit": "2f6a06ce34365a999de1a34e13c1784a48d4f7d3",
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "grill-me",
|
||||
@@ -114,8 +114,8 @@
|
||||
"repo": "https://github.com/vercel/next.js.git",
|
||||
"ref": "canary",
|
||||
"adapter": "skill-collection",
|
||||
"commit": "10439f3c6f058794f7d395dc347663271bf780ce",
|
||||
"syncedAt": "2026-08-17T16:00:00Z"
|
||||
"commit": "b18acf67128591337eb8e50d07ba20cbbb239f34",
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"sourceId": "caveman",
|
||||
"repo": "https://github.com/JuliusBrussee/caveman.git",
|
||||
"ref": "main",
|
||||
"commit": "766dce6b1394ebb56a3090748d5a0240a5aefb36",
|
||||
"commit": "ae405e872270acc57484693612ae038b16c8f6cd",
|
||||
"adapter": "codex-plugin",
|
||||
"sourcePath": "plugins/caveman",
|
||||
"syncedAt": "2026-08-17T16:00:00Z"
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"name": "playwright浏览器自动化操作",
|
||||
"version": "20260605",
|
||||
"keySource": "none",
|
||||
"syncedAt": "2026-08-17T16:02:30Z"
|
||||
"syncedAt": "2026-08-18T16:02:13Z"
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"sourceId": "next-skills",
|
||||
"repo": "https://github.com/vercel/next.js.git",
|
||||
"ref": "canary",
|
||||
"commit": "10439f3c6f058794f7d395dc347663271bf780ce",
|
||||
"commit": "b18acf67128591337eb8e50d07ba20cbbb239f34",
|
||||
"adapter": "skill-collection",
|
||||
"sourcePath": "skills",
|
||||
"syncedAt": "2026-08-17T16:00:00Z"
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
}
|
||||
|
||||
@@ -56,11 +56,9 @@ Thanks to [Kimi](https://www.kimi.com/code/?aff=ppt-master) for sponsoring this
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<sub>The narrated deck and gallery below were generated in <strong>May 2026</strong> with Claude Opus 4.7 + <code>gpt-image-2</code> — one pass each, no manual polish.</sub>
|
||||
<sub>The gallery below was generated in <strong>May 2026</strong> with Claude Opus 4.7 + <code>gpt-image-2</code> — one pass each, no manual polish.</sub>
|
||||
</p>
|
||||
|
||||
<h3 align="center">Download the <a href="https://raw.githubusercontent.com/hugohe3/ppt-master/main/examples/ppt169_attention_is_all_you_need/exports/attention_is_all_you_need_narrated.pptx">narrated <em>Attention Is All You Need</em> deck</a> — play it in PowerPoint and every slide reads itself out loud. That's just the tip of what PPT Master can do.</h3>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" width="33%">
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"sourceId": "ppt-master",
|
||||
"repo": "https://github.com/hugohe3/ppt-master.git",
|
||||
"ref": "main",
|
||||
"commit": "3b01e0cbe63c0dba316298e2d0aa6a09c4f3ef2d",
|
||||
"commit": "2f6a06ce34365a999de1a34e13c1784a48d4f7d3",
|
||||
"adapter": "claude-skill",
|
||||
"sourcePath": "skills/ppt-master",
|
||||
"syncedAt": "2026-08-17T16:00:00Z"
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ history, or resumable planning state. Context loss restarts the Quick run.
|
||||
| `analysis/beautify_inventory.json` | Beautify frozen validation ledger | Complete self-contained per-slide ledger of frozen content/data and validation exceptions, deterministically inlined from the source extracts | Keep the complete file as the sole Beautify ledger. Models normally consume derived read-only stdout projections from `beautify_inventory.py --summary` or `--page`; add `--with-geometry` only when raw source geometry is required. Never persist a projection or treat it as a second authority. |
|
||||
| `analysis/image_analysis.csv` | Regenerated image fact view | Measured facts about the current `images/` folder | Re-run `analyze_images.py` before reading image facts after changes |
|
||||
| `analysis/reconstruction_inventory.json` | Image to PPTX source-evidence ledger | Source-container/frame mapping, hashes, page order/canvas, visible-region bboxes, observed text/graphic/image family, transcription confidence, overlap/z-order observations, and unresolved evidence | The active Codex Quick agent writes it before layer decisions. It contains no final realization, prompts, output filenames, or SVG bindings; those belong to Quick active context plus required operational image evidence. |
|
||||
| `design_spec.md` | Strategist design authority | Human-readable design intent, page brief, rationale, resources, and production mechanics | Consume final confirmation once, write/audit here, and apply enabled refinement to this same artifact. §I records effective Speaker Notes, Custom Animations, and Narration Audio outcomes plus provenance; a newer explicit user instruction updates only its owning outcome without reopening Confirm UI. After Gate 1 plus conditional approval, later roles read this file instead of `result.json`; §IX owns Executor page content. |
|
||||
| `design_spec.md` | Strategist design authority | Human-readable design intent, page brief, rationale, resources, and production mechanics | Consume final confirmation once, write/audit here, and apply enabled refinement to this same artifact. §I records effective Speaker Notes, Custom Animations, and Narration Audio outcomes plus provenance; a newer explicit user instruction updates only its owning outcome without reopening Confirm UI. After Gate 1 plus conditional approval, later roles read this file instead of `result.json`; §IX owns Executor page content, while its layout/composition/capability/motif recommendations remain References unless an explicit user/template/resource constraint promotes the named property. |
|
||||
| `spec_lock.md` | Execution anchor and routing contract | Machine-readable stable color/type roles, icons, images, page rhythm, charts, `template_reuse_scope`, and the route's PowerPoint structure mode; mirror/layout template routes additionally own input prototypes, the Master roster, and the complete page-to-Master/Layout mapping | Strategist authors the route-specific anchors from the audited Design Spec plus current project/page/template context. Executor retains the complete lock once per valid execution context; local uncertainty consults that retained copy before the owning Design Spec fragment. Sparse page-local color/font garnish needs no lock row; a recurring semantic role or new adaptive Layout identity requires Strategist repair before reuse. |
|
||||
| `project_manager.py page-context` stdout | Derived on-demand page context | Read-only model-facing anchor set + current-page delta + fingerprints for large references | Use only for explicit diagnostics/telemetry or an unresolved page/template/chart path-SHA projection. Never edit or persist it as a replacement source of truth, and never run it as a routine pre-page gate. `global` is a bounded anchor set, not a whitelist. `reference_set` carries path/SHA/load policy but never appends reference payloads. |
|
||||
| `analysis/page-context/P<NN>.usage.json` | Derived optional context telemetry | Measured on-demand page-context size plus hashes of owning inputs/references | `page-context --record-usage` deterministically replaces only the invoked page's snapshot; `page-context-report` summarizes existing snapshots. Telemetry may be partial. Use token data to evaluate context cost, never as content or an execution contract. |
|
||||
|
||||
@@ -9,7 +9,6 @@ Always-loaded Executor authority for flat SVG page authoring and behavior shared
|
||||
| `pptx_structure.mode: structured` | [`executor-structured.md`](./executor-structured.md) |
|
||||
| Any selected Chart/Table `family/key` reference, or a legacy `page_charts` row that resolves to a live Chart/Table SVG | [`executor-visualization.md`](./executor-visualization.md), then the resolver-returned Chart/Table branch |
|
||||
| Any value-driven geometry, including a chart-family reference, mini chart, sparkline, inset, or small multiple | [`executor-chart.md`](./executor-chart.md) |
|
||||
| The mandatory per-page Structure decision finds qualitative geometry | [`executor-structure.md`](./executor-structure.md) |
|
||||
| Any semantic cell grid, including a table-family reference | [`executor-table.md`](./executor-table.md) |
|
||||
| A page will use a preset pattern fill or an independent object is explicitly selected as native-ready | [`native-data-interface.md`](./native-data-interface.md) before emitting the pattern or replacement metadata |
|
||||
| Any image | [`executor-image.md`](./executor-image.md) + [`image-layout-spec.md`](./image-layout-spec.md) + [`image-layout-patterns.md`](./image-layout-patterns.md) + [`svg-image-embedding.md`](./svg-image-embedding.md) |
|
||||
@@ -20,7 +19,7 @@ Always-loaded Executor authority for flat SVG page authoring and behavior shared
|
||||
|
||||
Evaluate branches from each object's actual information model, not only from a Chart/Table reference. A catalog family selects construction guidance but never native readiness; `Native-ready` is an independent object-level decision. Page-local qualitative geometry also never implies package-level `pptx_structure.mode: structured`.
|
||||
|
||||
> Narrative skeleton and visual aesthetic come from the locked values routed through the [`modes/`](./modes/_index.md) and [`visual-styles/`](./visual-styles/_index.md) indexes. Executor reads one locked preset file or only the exact `*_references` of a custom synthesis; an unreferenced novel custom reads none. [`shared-standards-core.md`](./shared-standards-core.md) supplies the technical boundary plus the fallback visual-quality and leading defaults when those authorities are silent.
|
||||
> Narrative skeleton and visual aesthetic come from the locked values selected through the [`modes/`](./modes/_index.md) and [`visual-styles/`](./visual-styles/_index.md) planning indexes. Executor does not reopen those indexes: it reads one locked preset file or only the exact `*_references` of a custom synthesis; an unreferenced novel custom reads none. [`shared-standards-core.md`](./shared-standards-core.md) supplies the technical boundary plus the fallback visual-quality and leading defaults when those authorities are silent.
|
||||
|
||||
**Hard rule — Shape-first page authority**: Every visible object intended for the exported slide MUST exist in the final page SVG or be explicitly referenced by it. Templates and `spec_lock.md` guide construction; they are not export-time overlays for missing visible content. Optional native Chart/Table metadata belongs to an independently selected object and never replaces this visible fallback during authoring; [`native-data-interface.md`](./native-data-interface.md) alone defines that metadata and its export activation. Native formula markers require a matching SVG preview; export replaces only it under [`native-formula.md`](./native-formula.md).
|
||||
|
||||
@@ -72,7 +71,9 @@ Consume stdout directly; stop on non-zero exit. The projection is derived, not a
|
||||
|
||||
**Hard rule — exact page roster**: `design_spec.md §IX` is the ordered queue: one final slide per entry, with the same id/order. The UI range no longer applies. Never add, drop, merge, split, or reorder; repair/reconfirm the Design Spec first.
|
||||
|
||||
**Hard rule — binding selection vs realization**: use Strategist-selected semantic content, resources/paths, Chart/Table `family/key` references, template/layout routing keys, core fonts, palette anchors, icon-library/stroke anchors, and crop boundaries. Adapt realization—including which prepared project-local icon, if any, best serves each page—without changing those binding selections, except sparse local font/color garnish allowed below. A §VIII preferred image pattern is not a template/layout routing key; [`executor-image.md`](./executor-image.md) owns its realization freedom. Missing or unresolved material stops execution and returns to Strategist-owned acquisition/failure recovery; never search, generate, download, sync, invent, or substitute it. Binding selection changes require upstream repair.
|
||||
**Hard rule — binding selection vs realization**: use Strategist-selected semantic content, resources/paths, structured-template Master/Layout routing keys, core fonts, palette anchors, icon-library/stroke anchors, and crop boundaries. Adapt realization—including which prepared project-local icon, if any, best serves each page—without changing those binding selections, except sparse local font/color garnish allowed below. Missing or unresolved material stops execution and returns to Strategist-owned acquisition/failure recovery; never search, generate, download, sync, invent, or substitute it. Binding selection changes require upstream repair.
|
||||
|
||||
**Reference — planning advice, not a layout lock**: treat §V/§IX `Layout`, cover/closing composition, capability recommendations, §III motif direction, Chart/Table `family/key` construction references, and §VIII image-layout patterns as non-binding inputs. Consider each, then adopt, adapt, or decline it without upstream repair when the same semantic job and every binding user/template/resource constraint remain satisfied. Executor owns final carrier choice, page-scale composition, information-preserving visualization realization, geometry, spacing, coordinates, native preset/Boolean/freeform construction, and effects.
|
||||
|
||||
**Hard rule — content vs expression**: `design_spec.md §IX` owns each page's semantic content and supplies complete preferred wording and block texture; those expression choices are not verbatim requirements unless explicitly literal. Executor may paraphrase, condense repetition, regroup or reorder material within the same page, and switch among prose, bullets, keywords, labels, or visual annotation when fit or readability benefits. The result must remain information-equivalent: preserve the `Core message`, `Audience move`, and every substantive claim, fact, data value, proper name, qualifier or caveat, relationship, key argument or evidence, and literal requirement. Never add a claim, move content across pages, or drop information to make the layout fit; return an unfit or underspecified block for Design Spec repair.
|
||||
|
||||
@@ -82,7 +83,7 @@ Use named lock roles literally when that role applies, and use optional `Templat
|
||||
|
||||
**Per-page communication trace**: Read `communication.objective`, `communication.core_message`, and the current §IX `Core message` + `Audience move` before choosing composition. The page must advance the compact objective and move the audience as authored in §IX; the global core message remains the deck-wide north star. A page that cannot state this movement is an upstream outline defect — surface `warning: P<NN> has no communication move` instead of compensating with decorative layout. Do not invent a new purpose, ask, or outcome at execution time. Structural pages may advance the contract by establishing relevance / tension / decision frame or by completing the final commitment; they are not exempt from having a reason to exist.
|
||||
|
||||
**Mandatory — per-page Structure decision**: Before drawing, read the current §IX `Layout`, `Visualization`, and `Content` and decide whether geometry must carry any qualitative `order`, `link`, `parent`, `membership`, `contrast`, or `overlap` relationship. If none applies, continue on this shared base path. If any applies, load [`executor-structure.md`](./executor-structure.md) before constructing the page and retain the relationship statement in active page context; do not create a catalog reference, lock row, or new artifact. A Chart/Table reference never substitutes for this decision.
|
||||
**Mandatory — per-page Structure decision**: Before drawing, read the current §IX `Layout`, `Visualization`, and `Content` and decide whether geometry must carry any qualitative `order`, `link`, `parent`, `membership`, `contrast`, or `overlap` relationship. Derive the result from that semantic relationship with the already-loaded [`executor-structure.md`](./executor-structure.md); a suggested carrier, topology, or macro composition does not decide it. If none applies, continue on this shared base path. If any applies, use that grammar and retain the relationship statement in active page context; do not create a catalog reference, lock row, or new artifact. A Chart/Table reference never substitutes for this decision.
|
||||
|
||||
**Per-page reading-mode check**: Read `communication.consumption_mode` before choosing the page's composition. Apply it together with the authored §IX block texture and `page_rhythm`:
|
||||
|
||||
@@ -140,7 +141,7 @@ Before drawing each page, look up its entry in `page_rhythm` (key format `P<NN>`
|
||||
|
||||
| Tag | Layout discipline |
|
||||
|-----|-------------------|
|
||||
| `anchor` | Structural page (cover / chapter / TOC / ending). `mirror` follows its prototype; `layout` retains its structure system. `style` / free design preserves the §IX cover hook or closing takeaway but may adapt the recommended composition. Avoid an information-empty generic cover/sign-off unless content, user direction, or template requires it. |
|
||||
| `anchor` | Structural page (cover / chapter / TOC / ending). `mirror` follows its prototype; `layout` retains its structure system. `style` / free design preserves the §IX cover hook or closing takeaway but may adopt, adapt, or decline the recommended composition. Avoid an information-empty generic cover/sign-off unless content, user direction, or template requires it. |
|
||||
| `dense` | Information-heavy. Card grids, multi-column layouts, KPI dashboards, tables, and charts are all permitted. This is the baseline behavior. |
|
||||
| `breathing` | Low-density impact page. Avoid **multi-card grid layouts** — do not organize content as multiple parallel rounded containers (3-card row, 4-card KPI grid, 2×2 matrix rendered as cards). Use naked text blocks, dividers, whitespace, or full-bleed imagery as the content structure. Single rounded visual elements (hero image corners, callouts, tags, one emphasis block) are fine — the rule is about grid structure, not about the `rx` attribute. Proportions follow information weight (not a preset ratio). Typical forms: hero quote, single large number with one-line interpretation, full-bleed image with floating caption, section transition. |
|
||||
|
||||
@@ -158,14 +159,14 @@ Before drawing each page, look up its entry in `page_rhythm` (key format `P<NN>`
|
||||
- **Element grouping (Mandatory)**: wrap each logical Slide-local body unit in a descriptive, page-unique top-level `<g id>`. Every visible direct root `<g>` declares root-coordinate `data-pptx-bounds="x y width height"`; frame/native coordinates do not replace it, and placeholder bounds also supply the slot frame. Nested groups need no bounds and any such values are ignored. Checker compares root bounds with the `viewBox`, recursively checks estimable text against its root module with DrawingML wrapping headroom, and independently checks every estimable visible text carrier against the page without that headroom: through `1px` is ignored; module overflow warns through `5%` and fails above it, while larger page overflow always fails. Unestimable visible text receives an advisory warning. Only a wholly off-canvas direct-root Morph endpoint may set `data-pptx-morph-staging="true"`; keep its text inside its own module bounds, use an explicit pair when Morph remains enabled, and never use the marker for partial overflow. Images, shapes, paths, `<use>`, effects, and object frames remain geometrically free. Flat pages use ordinary groups; structured slots already qualify, while titles, direct Master/Layout atoms, and canvas-level static framing may remain root primitives. On flat pages, give a root background image or full-canvas scrim/decoration rectangle a stable `id` plus `data-pptx-role="background"` / `"decoration"`; never wrap it only to silence the advisory.
|
||||
- **Reference — not a constraint**: top-level groups set semantic and automatic-animation granularity, but they may contain descriptive nested `<g>` edit groups when the page has meaningful internal subunits. Nested groups need no bounds and create no automatic animation step; use or omit them from the page's actual editing semantics, with no default pattern, depth, or quota.
|
||||
- **Default — size `data-pptx-bounds` as the intended module zone, not a glyph box (may skip when no text is estimable)**: make the zone as generous as the canvas and sibling layout allow, without overlapping another module zone. An untransformed line spans `y - 0.85 × font_size` to `y + 0.35 × font_size`; width uses the shared SVG-to-PPTX per-run estimate and safety headroom. If text does not fit, first expand a zone that has unused non-overlapping space; otherwise reflow or adapt. Larger bounds do not repair off-canvas text.
|
||||
- **Spec adherence**: follow color, layout, canvas format, and typography in the spec
|
||||
- **Spec adherence**: follow binding color, canvas, typography, identity, resource, and template anchors; apply layout and other Reference directions under §2.1 without turning them into locks
|
||||
- **Template structure**: inherit the native visual framework only for `template_reuse_scope: mirror|layout`; `style` uses the flat route
|
||||
- **Main-agent ownership**: SVG generation must run in the main agent (not sub-agents) — pages share upstream context for cross-page visual continuity
|
||||
- **Generation rhythm**: P01 → first-page gate → uninterrupted remaining pages → final gate, in one context without batches or mid-run checker calls.
|
||||
- **Fact provenance**: when a §IX page lists `Fact IDs`, resolve each ID from `sources/*.facts.json` and keep the claim/value unchanged. Render a compact source footnote using the source name and a short URL/domain when space permits; when speaker notes are enabled, state the attribution naturally there too. When §IX says `Data class: scenario`, place a visible localized `Scenario data` / `情景数据` label adjacent to the affected KPI/chart and, when notes are enabled, state naturally there that the number is illustrative. Never attach an external fact ID to scenario data or let an unlabeled invented KPI look factual.
|
||||
- **Default — compose compatible carriers by page job (may use any suitable subset)**: background paint, native shapes, editable text, prepared photos/scenes, transparent illustration slices, decorative lettering, icons, and visualizations may share one page. Use only prepared resources; choose their combination, visual weight, and z-order from the page message, hierarchy, and resolved style rather than isolating each carrier in its own block.
|
||||
- **Default — stage each page with the style's composition geometry (may override when the content genuinely calls for a plain grid)**: an SVG page is a canvas, not a DOM. Resolve the page-scale move from `spec_lock.md`: a preset uses that selected style's §1 `Composition geometry`; `custom` executes `visual_style_behavior` first, then uses §1 geometry only from exact `visual_style_references` that the behavior assigns a shape or composition job. Other bases contribute only their assigned job, and an unreferenced novel custom follows its behavior alone. Before defaulting to stacked rounded-rect cards or uniform equal columns, use that resolved geometry to stage the page's primary zone. Card grids are one option among many, not the house layout.
|
||||
- **Default — realize the planned motif system's reuse mode (may omit where it has no page job)**: when §III `Theme` names a cross-page motif or element family, exact repetition is valid for deliberate title/corner chrome; adaptive elements may vary scale, crop, density, position, and content interaction by page role. Preserve the named invariant, apply it only where it supports hierarchy or continuity, and do not invent a competing recurring identity.
|
||||
- **Mandatory — resolve the page carrier mix before coordinates**: decide background paint/field, editable text and optional lettering, native geometry/lines, prepared photos/scenes/illustration/icon assets, and applicable visualizations in one page-level composition decision. Use any suitable subset; omitting a carrier remains valid. Do not finish a text/container layout and then treat the other families as optional decoration. Use only prepared external resources, preserve every binding resource job and constraint, and choose the actual combination, visual weight, z-order, and local native construction from the page message and hierarchy. The resolved style controls treatment and emphasis, never carrier eligibility, image source, or the complete native construction vocabulary.
|
||||
- **Default — stage each page with the style's composition geometry (may override when another page-fit move is stronger)**: an SVG page is a canvas, not a DOM. Resolve the page-scale move from `spec_lock.md`: a preset uses that selected style's §1 `Composition geometry`; `custom` executes `visual_style_behavior` first, then uses §1 geometry only from exact `visual_style_references` that the behavior assigns a shape or composition job. Other bases contribute only their assigned job, and an unreferenced novel custom follows its behavior alone. Treat every listed move as generative vocabulary rather than a finite menu, then apply [`native-shape-authoring.md`](./native-shape-authoring.md) §2.1's shared exact-fit geometry gate.
|
||||
- **Default — consider the planned motif direction (may override when another coherent expression better serves the deck)**: when §III `Theme` recommends a cross-page motif or element family, decide whether it earns a continuity job. If adopted, keep its reuse coherent while varying scale, crop, density, position, and content interaction by page role; otherwise adapt or decline it and establish a more fitting style-consistent expression. An explicit user/template motif remains binding.
|
||||
- **Inherited containers**: preserve meaningful template frames; restyle radius, fill, stroke, and depth from the active Design Spec and `spec_lock.md`. Selected Chart/Table reference adaptation is owned by [`executor-visualization.md`](./executor-visualization.md); preview effects never override project styling or structural roles.
|
||||
- **Reference — prefer semantic geometry over preset stacks**: for relationships such as ascending, converging, breaking through, or stacking, first compose faithful primitives and exact presets as one page geometry system; use a Boolean only when the contour itself must merge, open, or fragment. Only when neither construction works should one page-specific polygon/path replace a stack of generic arrows.
|
||||
- **Reference — create depth with restraint**: use rhythm, spacing, typography, accent bars, and subtle tints before shadows. Reserve lift for a few genuinely floating elements; keep peer grids, dividers, and ordinary body containers flat. When material layering itself is part of the resolved visual style, follow that style's hierarchy instead of flattening its body planes.
|
||||
@@ -174,6 +175,16 @@ Before drawing each page, look up its entry in `page_rhythm` (key format `P<NN>`
|
||||
2. **Quality Check Gate**: only after every planned SVG exists, run `python3 ${SKILL_DIR}/scripts/svg_quality_checker.py <project_path> --stage final --json` directly on `svg_output/` without `tail` / `head` / `grep` filtering. One run already reports all pages. Review its complete issue set, fix every `error` plus any selected advisory warnings in one consolidated edit pass, then perform one verification rerun. If it still fails, its complete output begins the next batch cycle; never use checker calls to discover or fix one next issue at a time. Every `warning` is advisory: it never sends the page back for required modification, never authorizes automatic rewriting of compatible user syntax, and needs no acknowledgement/disposition line. Recommendation warnings describe the generated-SVG default; fidelity/quality warnings may be surfaced when material, while the existing input remains releasable. Prototype-identical diagnostics are recorded as `inherited`, source conversion losses as `source-import`, changed/new advisories as `introduced`, and release failures as `blocking` in `validation/svg_quality_report.json`. If release truly depends on a condition, it belongs in `errors`. On success, use the exit status and terminal summary; do not open or `cat` the complete JSON into model context. If terminal output is truncated on failure, read only the relevant issue arrays from the report written by that same run. Do NOT defer error handling to after `finalize_svg.py` — finalize rewrites SVG and masks some violations.
|
||||
3. **Logic Construction Phase (conditional)**: after SVGs pass the quality check, batch-generate speaker notes for narrative continuity only when the effective Speaker Notes outcome is enabled.
|
||||
|
||||
**Mandatory — final carrier-receipt review**: The final checker prints one
|
||||
factual `[CARRIERS]` summary and stores per-page detail under
|
||||
`files[].info.carrier_receipt`. Compare the summary with the retained page jobs,
|
||||
chosen resource roles, and running geometry signatures before export. Counts
|
||||
and diversity never create a quota or prove quality; zero use remains valid.
|
||||
When the facts contradict an active decision—such as an adopted preset absent
|
||||
from output, a primary image reduced to a minor frame, or unrelated jobs
|
||||
collapsing to one neutral construction—read only the affected receipt rows,
|
||||
repair those pages in one consolidated pass, and rerun the final checker.
|
||||
|
||||
### 3.0 Native Shape Selection
|
||||
|
||||
**Hard rule — contour before encoding**: choose the page-fit contour from the
|
||||
@@ -189,43 +200,21 @@ Office symbols use `preset_shape_svg.py`, not plain paths or fake rectangles.
|
||||
Before the first page, complete [`native-shape-authoring.md`](./native-shape-authoring.md)'s
|
||||
unfiltered full-registry discovery. Decide every page-fit contour and its
|
||||
simplest exact authoring form directly from the page content and visual system;
|
||||
no Design Spec capability suggestion or material inventory gates this choice.
|
||||
no Design Spec construction selection or material inventory gates this choice.
|
||||
|
||||
**Mandatory — independent per-page geometry move**: after the Structure result
|
||||
and any applicable topology resolve, but before writing coordinates, choose one
|
||||
page-scale geometry move from the actual content, visual system, and complete
|
||||
native vocabulary. Compare a deliberate plain / neutral construction with
|
||||
[`native-shape-authoring.md`](./native-shape-authoring.md) §2.1's page-field,
|
||||
outline, nesting, continuity, depth / contrast, and contour-change lenses.
|
||||
Readability alone does not select the simple branch; a plain grid or no compound
|
||||
construction remains valid when it is the deliberate best fit for the page job.
|
||||
This applies to both `Structure=no` and `Structure=yes`, stays in active context
|
||||
until the page is complete, and never changes that result. Use §2.1 whenever the
|
||||
move adopts two or more native shapes. There is no coverage target or required
|
||||
explanation for a simple result.
|
||||
|
||||
**Default — do not use rectangles as the universal carrier (may use when a
|
||||
neutral field is the best fit)**: before drawing another `<rect>` / rounded
|
||||
`<rect>` container, test whether the content job calls for a more expressive
|
||||
preset, outline contour, or compound geometry. Choose one coherent shape
|
||||
language for the page; do not assign unrelated novelty shapes item by item.
|
||||
|
||||
**Default — give floating text a geometric owner when useful (may omit when
|
||||
typography and negative space already establish deliberate hierarchy)**: before
|
||||
leaving a key or repeated text cluster unbounded, consider a native outline,
|
||||
frame, arc, bracket, band, spine, or other content-fit carrier. `fill="none"`
|
||||
with a visible stroke is a first-class option and does not imply a filled card.
|
||||
|
||||
**Reference — use visual nesting for depth**: a larger field may contain or be
|
||||
crossed by an inset contour, secondary surface, badge, port, or focal shape.
|
||||
Keep these as independently editable siblings in the ordinary semantic group;
|
||||
visual containment never authorizes placing content inside an atomic preset
|
||||
fragment or merging shapes that do not require one contour.
|
||||
and any applicable topology resolve, apply
|
||||
[`native-shape-authoring.md`](./native-shape-authoring.md) §2.1 before writing
|
||||
coordinates. It owns the exact-fit geometry comparison, composition lenses,
|
||||
independent relationship / carrier fit, contour-family / exact-result choice,
|
||||
reader effect for a generic or undrawn result, running geometry signature, and
|
||||
materialization boundary for both `Structure=no` and `Structure=yes`. Keep the
|
||||
current decision in active context and never change the Structure result.
|
||||
|
||||
| Selected result | Authoring form |
|
||||
|---|---|
|
||||
| Selected exact non-Connector stock contour | Use ordinary SVG only when the exporter maps it to that same contour; otherwise call `preset_shape_svg.py render` and paste its complete stdout fragment. |
|
||||
| Straight relationship / divider / leader | Use `<line>`; add a registered marker only when direction is meaningful. |
|
||||
| Straight relationship / divider / leader | Use `<line>`; add a registered marker under [`shared-standards-core.md`](./shared-standards-core.md) §1.1 only when direction is meaningful. |
|
||||
| Bent / curved relationship exactly expressed by a stock Connector contour, with no required endpoint attachment | Use the matching `bentConnector*` / `curvedConnector*` preset through the helper as an unconnected native Connector shape. |
|
||||
| Selected text/content boundary needs no filled surface | Use its exact authoring form with `fill="none"` and a visible stroke; keep text and other content independent. |
|
||||
| Two or more native shapes should form one page-level geometry system | Follow [`native-shape-authoring.md`](./native-shape-authoring.md) §2.1: compose faithful primitives and presets as independent siblings first, then materialize only contours that require Boolean semantics. |
|
||||
|
||||
@@ -47,6 +47,12 @@ only when useful. Compare the resulting candidate with plain/`P`-only placement
|
||||
and implement the stronger legal composition. Create no artifact or extra pass,
|
||||
and do not reread the branch while its active context remains valid.
|
||||
|
||||
**Default — preserve the image job at final size (may override when the planned
|
||||
job is texture only)**: Before accepting a narrow band, small placement, or crop,
|
||||
keep the subject or relationship named by the image purpose recognizable at its
|
||||
final on-slide size. If it collapses into color texture, enlarge or recompose it;
|
||||
treat it as texture only when the upstream job permits that role.
|
||||
|
||||
**Reference — direction generators, not templates**:
|
||||
|
||||
| Generator | Behavior |
|
||||
@@ -67,11 +73,11 @@ to variety.
|
||||
|
||||
**Hard rule — visible-layer timing**: Any crop, lens, scrim, comparison, evidence, or annotation layer required by an adopted motion plan MUST already exist in the final SVG without violating structural contracts. The later stage may regroup ordinary Slide-local content visual-equivalently, but cannot invent or modify missing visible content. If no legal existing unit can serve a non-binding suggestion, simplify it to available units, a page transition, or `none`; an explicit requirement that cannot be represented follows failure recovery.
|
||||
|
||||
**Hard rule — narrow visual-inspection scope**: Start with §VIII `Reference` plus dimensions. If one `Existing`/`Sourced` asset still leaves focal-safe crop, overlay contrast, or a quiet region ambiguous, inspect only that asset/review copy for placement. This cannot reopen selection, change identity/must-use, infer provenance, substitute the asset, or invent focus; never routinely read back `Generated` images. If `adaptive` focus stays uncertain, use `meet`; conflicting binding constraints return upstream.
|
||||
**Hard rule — narrow visual-inspection scope**: Start with §VIII `Reference` plus dimensions. If one asset still leaves focal-safe crop, overlay contrast, a quiet region, or its planned subject relationship ambiguous, inspect only that asset/review copy once for placement. A `Generated` asset qualifies only when final placement depends on an ambiguity that its owned intent and dimensions cannot resolve; never routinely read generated images. Inspection cannot reopen selection, change identity/must-use, infer provenance, substitute the asset, or invent focus. If `adaptive` focus stays uncertain, use `meet`; conflicting binding constraints return upstream.
|
||||
|
||||
**Placeholder**: Dashed border `<rect stroke-dasharray="8,4" .../>` + description text
|
||||
|
||||
**Crop policy**: read the §VIII row and matching lock projection. On every slide that uses a `crop=no-crop` source (or a legacy trailing `| no-crop`), retain one visible complete instance using one of the nine legal anchors with `meet`, never `none`, and no `clip-path`, `mask`, clipping overflow, or nested `<svg>` crop viewport. An auxiliary same-slide detail or lens may crop the same source only while that complete instance remains visible. `crop=adaptive` permits but never requires cropping; choose `meet` or focal-safe `slice` from purpose, ratio, focus, and container. A missing or conflicting `source` / `pattern` / `crop` projection returns upstream instead of being inferred during execution; the accurately projected `pattern` remains a preferred expression that may be adapted without rewriting the lock.
|
||||
**Crop policy**: read the §VIII row and matching lock projection. On every slide that uses a `crop=no-crop` source (or a legacy trailing `| no-crop`), retain one visible complete instance using one of the nine legal anchors with `meet`, never `none`, and no `clip-path`, `mask`, clipping overflow, or nested `<svg>` crop viewport. An auxiliary same-slide detail or lens may crop the same source only while that complete instance remains visible. `crop=adaptive` permits but never requires cropping; choose `meet` or focal-safe `slice` from purpose, ratio, focus, and container. A missing or conflicting `source` / `pattern` / `crop` projection returns upstream instead of being inferred during execution; the accurately projected `pattern` remains a preferred expression that may be adopted, adapted, or declined without rewriting the lock.
|
||||
|
||||
**Hard rule — same-source addressable crops, only when adopted**: A layout
|
||||
suggestion, including pattern `#M1-11`, never activates this transport. Pattern
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
Runtime grammar for Slide-local qualitative relationships built from editable shapes; it is not a diagram/template catalog.
|
||||
|
||||
**Load**: Quick reads this grammar once before all SVG authoring and reuses it for every per-page decision. Default loads it before realizing the first page whose Structure decision is yes, then reuses it in that execution context.
|
||||
**Load**: Default and Quick read this grammar once with their fixed construction
|
||||
bundle before all SVG authoring and reuse it for every per-page decision. Loading
|
||||
the grammar does not select `Structure=yes` or create a geometry quota.
|
||||
|
||||
**Hard rule — no Structure catalog**: never recall or resolve `structure/<key>`. Compose from authoritative content, §IX relationships, the communication move, and the active visual system.
|
||||
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ New `page_visualizations` and Quick selections accept only canonical `chart/<key
|
||||
|
||||
**Legacy Structure boundary**: a retired Structure bare key is semantic intent, not a live visualization reference. Do not resolve it to an SVG or load this branch; recover the qualitative relationship from §IX and apply [`executor-structure.md`](./executor-structure.md) when the mandatory per-page Structure decision is yes. If §IX lacks enough meaning, return upstream for Design Spec repair.
|
||||
|
||||
Read the resolver-returned SVG once before its first use in the valid active context and reuse that reading until a known file change or context invalidation. Do not manually open indexes or scan family directories during Executor realization; the shared resolver owns live-catalog reads. Selection and bounded recall belong before this branch.
|
||||
Read the resolver-returned SVG once before its first use in the valid active context and reuse that reading until a known file change or context invalidation. Do not manually reopen indexes or scan family directories during Executor realization; the planning owner already reviewed the complete live registries, and the shared resolver owns canonical path resolution here.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ Derive color behavior from the available roles and image context: background / s
|
||||
|
||||
For each `Acquire Via: ai` row, use Strategist-owned §VIII/lock by default or the main agent's active-context Quick resource decision. Explicit values remain binding; Quick resolves omissions automatically.
|
||||
|
||||
`Layout pattern` is a page-realization preference and is not copied wholesale into the bitmap prompt. Any generation-time subject direction, focal placement, quiet region, or overlay-safety requirement must therefore be present in the row's `Reference`, the matching §IX block, or Quick's active-context visual intent.
|
||||
`Layout pattern` is a page-realization preference and is not copied wholesale into the bitmap prompt. When page use depends on stable composition, consume the compact contract already owned by the row's `Reference`, matching §IX block, or Quick active context: subject/quiet zones, boundary or direction, intended overlap/seam, and approximate share only when needed. Do not invent or replace page layout here; return a missing required relationship to its owning decision.
|
||||
|
||||
1. **Determine `page_role`** — the owning row's explicit value wins; a blank or omitted value resolves to `local`. In Default Generate, `hero_page` must be Strategist-explicit; in Quick Generate, the main agent may resolve it before acquisition in active context.
|
||||
2. **Determine `text_policy`** — the owning row's value wins when set. **Declared-inference fallback for a blank or omitted value**: pick `none` or `embedded` from the row's `Purpose`, `Reference`, and page intent based on whether in-image text serves the page. Long body / data / lists stay in SVG.
|
||||
@@ -153,7 +153,7 @@ Every assembled prompt follows this paragraph structure. **Write prose, not tag
|
||||
[Deck color behavior — state the core anchors and any context-justified tonal treatment, e.g. "secondary background #F8F9FA provides the breathing field, primary #1E3A5F carries main forms, accent #D4AF37 marks one emphasis; subtle lighter/darker material transitions remain in the same visual family"].
|
||||
[Composition — from the chosen type file or §4.1 no-type prose].
|
||||
[Image-specific subject — translated from the row's Reference intent into concrete visual nouns].
|
||||
[Container note — "composed as a {W}x{H}px image for {page_role} use"; add composition cues only when the page actually needs them. SVG-overlay-reservation cues ("leave the lower band calm — SVG title overlays it", "keep the right third calmer for SVG text") are valid when `page_role: hero_page`, or when §VIII `Reference` / §IX `Layout` explicitly plans native labels, hotspots, lenses, or other SVG overlays inside a `local` image region. Otherwise an opaque `local` image reserves no interior overlay space; a transparent illustration slice is generated as an isolated element and composed with other carriers by SVG].
|
||||
[Container note — "composed as a {W}x{H}px image for {page_role} use"; when the owned composition contract exists, carry its subject/quiet zones, boundary/direction, overlap/seam, and optional approximate share into the prose. Reserve an SVG-overlay region for `hero_page`, or for a `local` image only when §VIII `Reference` / §IX `Layout` explicitly plans native labels, hotspots, lenses, or other overlays there. Otherwise an opaque `local` image reserves no interior overlay space; generate a transparent illustration slice as an isolated element for SVG composition].
|
||||
[Hard rules — see §5].
|
||||
```
|
||||
|
||||
|
||||
+117
-49
@@ -12,19 +12,35 @@ only when those constructions fail. Neither helper writes a page. The preset
|
||||
helper does not create the shape's own `p:txBody`; keep visible text outside the
|
||||
atomic fragment.
|
||||
|
||||
**Mandatory — complete registry discovery at authoring entry**: before the
|
||||
**Mandatory — semantic registry discovery at authoring entry**: before the
|
||||
first newly authored page or template contour in each valid context, run the
|
||||
following command unfiltered and retain its complete output (currently 187
|
||||
names). This is authoring-time capability discovery, never a Strategist task or
|
||||
Design Spec field. Rerun only after context invalidation or a registry change.
|
||||
following command unfiltered and retain its complete output. It organizes all
|
||||
187 presets by the official Office gallery categories, then adds semantic
|
||||
groups, scopes, and one-line intent summaries. This compact index is
|
||||
authoring-time capability discovery, never a Strategist task or Design Spec
|
||||
field. Rerun only after context invalidation or a registry change.
|
||||
|
||||
**Hard rule — direct structured calls**: `${SKILL_DIR}` below is the retained
|
||||
absolute Skill root. Invoke each JSON command once per concrete argument set
|
||||
and read stdout directly. Do not change CWD, encode executables or flag lists in
|
||||
scalar shell strings, batch these calls through shell loops, merge stderr, or
|
||||
add a downstream parser when `--compact` exists.
|
||||
|
||||
```bash
|
||||
python3 ${SKILL_DIR}/scripts/preset_shape_svg.py list
|
||||
python3 "${SKILL_DIR}/scripts/preset_shape_svg.py" list --grouped
|
||||
```
|
||||
|
||||
Choose from that full inventory by page job. Use `list --search` only to narrow
|
||||
the already-read inventory and `describe <name>` only after identifying a
|
||||
candidate; neither replaces the complete initial read.
|
||||
The plain `list` command remains a compatibility view of exact registry names;
|
||||
it does not replace grouped discovery. For each page entering ordinary contour
|
||||
selection, run `recommend --compact --limit 6` from the actual page role and
|
||||
applicable relationship, direction, aspect, text capacity, scope, or intent
|
||||
terms before choosing a contour, then run `describe <name> --compact` on the
|
||||
serious candidates. Grouped discovery followed by direct `describe` does not satisfy
|
||||
page-local recall. Those commands supply the full match reasons, intended uses,
|
||||
misuse boundaries, adjustments, and key geometry facts omitted from the compact
|
||||
entry index. Recommendation is diverse candidate recall, not a whitelist,
|
||||
automatic choice, or shape quota; a neutral primitive remains valid when it
|
||||
fits best. Each page still resolves the final contour through §§1–2.1.
|
||||
|
||||
## 1. Contour Selection and Materialization Gate
|
||||
|
||||
@@ -32,8 +48,28 @@ candidate; neither replaces the complete initial read.
|
||||
intended job and active visual system across the full native vocabulary before
|
||||
considering authoring syntax. Rectangle, rounded-rectangle, circle, and ellipse
|
||||
contours are not an earlier visual tier merely because SVG has short primitive
|
||||
syntax for them. A neutral contour is valid when neutrality is the job; easier
|
||||
syntax is never the reason to select it.
|
||||
syntax for them. Easier syntax is never the reason to select a contour.
|
||||
|
||||
**Default — exact page-fit geometry before generic neutrality (may override when
|
||||
neutrality itself communicates the page)**: Resolve relationship fit when the
|
||||
content carries direction, sequence, membership, hierarchy, convergence, reveal,
|
||||
or contrast. Independently resolve page-field / carrier fit from ownership,
|
||||
focal hierarchy, boundary strength, and the active deck's edge / opening
|
||||
language; `Structure=no` removes only relationship topology. Choose a plain
|
||||
primitive, uniform grid, or no drawn carrier only when that lack of inflection
|
||||
gives the reader a concrete benefit or avoids a false inference. Retain that
|
||||
reader effect through authoring. Before that neutral result wins, name the
|
||||
strongest fitting native / compound alternative and retain why its inflection
|
||||
would add no reader benefit, create a false inference, weaken hierarchy, or
|
||||
conflict with the page job. Quick speed, restrained style, readability, equal
|
||||
importance, precedent, and shorter syntax alone do not qualify.
|
||||
|
||||
**Hard rule — style does not narrow capability**: the active visual system may
|
||||
weight contour fit and control paint, stroke, texture, density, and recurrence.
|
||||
It never removes primitives, Office presets, independent composition, Boolean,
|
||||
or necessary freeform from consideration. Style-specific syntax guidance
|
||||
applies only to the named style-defining mark, not every functional page
|
||||
contour.
|
||||
|
||||
After contour selection, use the simplest exact materialization below. Do not
|
||||
hand-author a freeform merely because an SVG path is convenient.
|
||||
@@ -43,7 +79,7 @@ hand-author a freeform merely because an SVG path is convenient.
|
||||
| Mirror/preserve input already owns native-shape metadata | Keep the existing object and metadata; never reselect its preset. |
|
||||
| One exact non-Connector stock contour | Use an ordinary SVG primitive only when the exporter maps it to that same contour; otherwise run `preset_shape_svg.py render` and insert its complete stdout fragment. |
|
||||
| A stock `bentConnector*` / `curvedConnector*` contour exactly expresses a bent or curved relationship and endpoint attachment is not required | Run `preset_shape_svg.py render --object-kind connector`; the result is an unconnected native Connector shape. |
|
||||
| A straight relationship, divider, or leader | Write `<line>`; use a registered marker only when direction is meaningful. |
|
||||
| A straight relationship, divider, or leader | Write `<line>`; use a registered marker under [`shared-standards-core.md`](./shared-standards-core.md) §1.1 only when direction is meaningful. |
|
||||
| A selected text/content boundary needs no filled surface | Use its exact authoring form with `fill="none"` and a visible stroke; keep its content as independent siblings. |
|
||||
| Two or more selected native contours form the page construction but do not need one contour | Keep them as independently editable siblings in one ordinary semantic group; use §2.1 to compose the page-level geometry system. |
|
||||
| Two or more supported closed-shape / resolvable-text operands require Union, Combine, Fragment, Intersect, or Subtract | Run `shape_boolean_svg.py render`, then replace the operands with every stdout path; the result remains ordinary editable custom geometry. |
|
||||
@@ -54,38 +90,56 @@ hand-author a freeform merely because an SVG path is convenient.
|
||||
`data-pptx-authoring="preset"`. Never add `data-pptx-prst`, frame, adjustment,
|
||||
or registry path data by hand. Insert the helper's complete compact `<g>` and
|
||||
rerun the helper whenever its geometry, paint, or filter reference changes.
|
||||
After selecting two or more objects for one current page or template
|
||||
construction, use `render-batch --input -` to validate and emit their
|
||||
independent fragments in one stdout round; the batch never chooses those
|
||||
objects or their composition.
|
||||
|
||||
---
|
||||
|
||||
## 2. Semantic Preset Candidate Guide
|
||||
## 2. Semantic Preset Selection
|
||||
|
||||
Use the table below as semantic navigation, not a shortlist: match the page's
|
||||
visual intent against the complete inventory already loaded above before
|
||||
settling on a neutral rectangle / ellipse or a freeform path. Do not let the
|
||||
examples or authoring convenience hide a more specific registered contour.
|
||||
The catalog's top level follows the Office gallery taxonomy: Lines,
|
||||
Rectangles, Basic Shapes, Block Arrows, Equation Shapes, Flowchart, Stars and
|
||||
Banners, Callouts, and Action Buttons. The bundled semantic layer at
|
||||
`scripts/pptx_shapes/data/presetShapeSemantics.json` adds authoring roles and
|
||||
use boundaries; it does not redefine the DrawingML registry.
|
||||
|
||||
"Automatic" means the Executor independently applies this semantic decision
|
||||
gate before drawing a new object. It does not scan existing SVG, classify
|
||||
paths or contours, or upgrade ordinary SVG during export.
|
||||
Apply this page-local sequence before drawing:
|
||||
|
||||
| Visual intent | Candidate presets | Boundary |
|
||||
| Pass | Action | Result |
|
||||
|---|---|---|
|
||||
| Literal geometric body | `triangle`, `diamond`, `pentagon`, `hexagon`, `octagon`, `star5` | Use only when the named geometry itself is the intent. |
|
||||
| Solid block direction | `rightArrow`, `leftArrow`, `upArrow`, `downArrow`, `leftRightArrow`, `upDownArrow`, `chevron` | Use `<line>` for a thin straight relationship; do not fake a solid directional object with a stroked path. |
|
||||
| Standard flowchart node | `flowChartProcess`, `flowChartDecision`, `flowChartInputOutput`, `flowChartTerminator`, `flowChartDocument` | Use only for an actual flowchart; ordinary content cards remain cards. |
|
||||
| Stock bent / curved relationship contour | `bentConnector*`, `curvedConnector*` | Prefer when the contour fits and endpoint attachment is not required. The authored object is an unconnected native Connector, so moving nodes does not reroute it. |
|
||||
| Stock callout | `wedgeRectCallout`, `wedgeRoundRectCallout`, `wedgeEllipseCallout`, `cloudCallout` | For a brand-specific or custom tail, continue through the Boolean gate; use freeform only if the result still cannot be expressed faithfully. |
|
||||
| Stock ribbon or scroll | `ribbon*`, `ellipseRibbon*`, `verticalScroll`, `horizontalScroll` | Select only when the stock contour is visually acceptable. |
|
||||
| Standalone math symbol | `mathPlus`, `mathMinus`, `mathMultiply`, `mathDivide`, `mathEqual`, `mathNotEqual` | Use only when the symbol itself is a diagram shape; simple notation remains text, while non-trivial inline or block mathematics follows [`native-formula.md`](./native-formula.md). |
|
||||
| Literal Office symbol | `heart`, `sun`, `moon`, `lightningBolt`, `gear6`, `gear9` | Never replace an icon required by `spec_lock.icons`. |
|
||||
| Job | State what the object must do for the reader before naming a shape. | Page role plus any real relationship, direction, aspect, text load, or literal scope. |
|
||||
| Recall | Run `recommend --compact` with the known criteria. Keep the default `general` scope unless the page truly needs `literal`, `flowchart`, or `navigation`. | A group-diverse candidate set with match reasons and misuse boundaries. |
|
||||
| Inspect | Run `describe --compact` for candidates whose contour could fit; compare `intent`, `recommended_for`, `avoid_for`, adjustments, text rectangle, and connection sites. | Evidence for choosing or rejecting each serious candidate. |
|
||||
| Select | Choose the contour whose inference and visual character fit the page, including a neutral primitive when neutrality is useful. | One page-fit contour; no syntax decision yet. |
|
||||
| Encode | Apply §1's materialization gate. | Ordinary SVG primitive, helper-authored preset, Boolean result, or necessary freeform. |
|
||||
|
||||
Narrow and inspect candidates from the already-loaded inventory:
|
||||
Example recall and inspection commands:
|
||||
|
||||
```bash
|
||||
python3 ${SKILL_DIR}/scripts/preset_shape_svg.py list --search arrow
|
||||
python3 ${SKILL_DIR}/scripts/preset_shape_svg.py describe rightArrow
|
||||
python3 "${SKILL_DIR}/scripts/preset_shape_svg.py" recommend --compact \
|
||||
--role spine --relationship order --directionality horizontal --aspect wide \
|
||||
--limit 6
|
||||
python3 "${SKILL_DIR}/scripts/preset_shape_svg.py" describe chevron --compact
|
||||
|
||||
python3 "${SKILL_DIR}/scripts/preset_shape_svg.py" recommend --compact \
|
||||
--scope flowchart --role node --relationship flow --query decision --limit 6
|
||||
```
|
||||
|
||||
**Hard rule — semantic fit, not name association**: a preset name, topic word,
|
||||
or metaphor is not evidence of use. Respect `literal_only` and `scope` before
|
||||
visual preference. For example, a scroll is not a generic playbook carrier, a
|
||||
lightning bolt is not generic price tension, `chartX` / `chartStar` /
|
||||
`chartPlus` are partition symbols rather than charts, and a flowchart symbol
|
||||
belongs only in an actual flowchart. An action-button preset supplies visual
|
||||
geometry only; it never creates an action or hyperlink.
|
||||
|
||||
The semantic catalog chooses contours, not syntax. It never requires `rect`,
|
||||
`ellipse`, `line`, or any other primitive to pass through the preset helper;
|
||||
after selection, the simplest exact authoring form in §1 remains authoritative.
|
||||
Export never scans or upgrades existing geometry.
|
||||
|
||||
**Shape-first diagram rule**: use `<line>` for straight thin relationships;
|
||||
use an exact connector-family preset for a stock bent or curved contour; use a
|
||||
block-arrow / chevron preset for a solid direction. Resort to an open freeform
|
||||
@@ -97,6 +151,8 @@ owned by the preserve/mirror round-trip contract.
|
||||
|
||||
**Forbidden — false native semantics**:
|
||||
|
||||
- a catalog entry with `literal_only=true` when the depicted literal concept is
|
||||
absent, or a `flowchart` / `navigation` scope outside that real context;
|
||||
- `actionButton*` when navigation or trigger behavior is expected; the helper
|
||||
maps its visual preset geometry only and never creates an action or hyperlink;
|
||||
- `chartX`, `chartStar`, or `chartPlus` as a substitute for native charts;
|
||||
@@ -108,19 +164,20 @@ owned by the preserve/mirror round-trip contract.
|
||||
anchors, and any applicable topology under
|
||||
[`executor-structure.md`](./executor-structure.md) are resolved, but before
|
||||
writing coordinates, resolve the page-scale geometry move that best carries its
|
||||
background field, content zoning, focal hierarchy, or reading path. Compare a
|
||||
deliberate plain / neutral composition with the useful lenses below. Readability
|
||||
of the first workable arrangement does not close this gate; a plain grid or no
|
||||
compound construction remains valid when it is the deliberate best fit for the
|
||||
page job.
|
||||
background field, content zoning, focal hierarchy, or reading path. Apply §1's
|
||||
exact-fit decision and compare the useful lenses below. Before repeating stacked
|
||||
rectangles / rounded cards or uniform equal columns, compare a page-field,
|
||||
outline, nesting, or continuity construction and the relevant contour family's
|
||||
exact members. Readability of the first workable arrangement does not close this
|
||||
gate.
|
||||
This applies whether the per-page Structure result is `no` or `yes`; it never
|
||||
creates a decoration requirement.
|
||||
|
||||
| Pass | Action | Result |
|
||||
|---|---|---|
|
||||
| Page job | Name the page-scale geometry move, then the geometric jobs already implied by the resolved page: surface, boundary, direction, reveal, focal mark, shared region, or counterweight. | One composition direction and a small set of functional zones; no shape names yet. |
|
||||
| Page job | Name the page-scale geometry move and its jobs: surface, boundary, focal mark, shared region, counterweight, or any source-backed direction / reveal. | One composition direction and a small set of functional zones; no shape names yet. |
|
||||
| Decompose | Separate visible content from geometric atoms. Identify which atoms need independent movement, paint, or reuse and which contour must become one object. | Editable siblings plus any explicit Boolean operand set. |
|
||||
| Select | Choose each atom's contour from its job and the full native vocabulary, then apply §1's simplest exact materialization. | Page-fit native atoms without syntax bias. |
|
||||
| Select | Choose the contour family, then its exact member from the job, full native vocabulary, and edge / corner / opening behavior; retain the reader effect when the result is generic or undrawn. | Page-fit native atoms without syntax bias. |
|
||||
| Compose | Establish page frame, scale, z-order, and negative space with independent atoms. Keep text, images, icons, data marks, and non-merged accents outside Boolean operands. | One page-level geometry system, not a collection of unrelated decorations. |
|
||||
| Materialize | Run the preset helper for each adopted preset. Run the Boolean helper only for contours that require Merge Shapes semantics, then replace those operands with its stdout paths. | Valid authoring SVG ready for native export. |
|
||||
|
||||
@@ -135,6 +192,14 @@ creates a decoration requirement.
|
||||
| Depth and contrast | Combine filled, outlined, offset, and negative-space atoms; use Boolean only when the contour itself must change. |
|
||||
| Deck language | Reuse a corner, arc, slant, notch, or layering logic with page-fit variation rather than cloning one composition. |
|
||||
|
||||
**Default — running deck geometry check (may override for literal pages or
|
||||
isolated template prototypes)**: After each generated page, retain
|
||||
`page job → composition move → contour / edge language`; append `relationship →
|
||||
topology` only for `Structure=yes`, then compare before the next. Repeat only for
|
||||
the same page job / relationship or deliberate continuity; section, equal
|
||||
weight/density, style, and precedent are insufficient. Create no artifact or
|
||||
second pass.
|
||||
|
||||
**Boolean decision gate**:
|
||||
|
||||
| Required result | Construction |
|
||||
@@ -169,11 +234,13 @@ siblings whenever one-object contour semantics are unnecessary.
|
||||
|
||||
## 3. Fragment Generation
|
||||
|
||||
Run one command for one selected object. Generated project pages choose the
|
||||
object's solid paint from the current page context, using `spec_lock.md` roles as
|
||||
reusable anchors rather than an exhaustive palette; `create-template` takes colors
|
||||
from the confirmed brief and template `design_spec.md`. Mirror/preserve input
|
||||
keeps the source object's paint instead of regenerating this authored form.
|
||||
`render` emits one selected object. `render-batch` atomically emits multiple
|
||||
already-selected objects for one current page or template construction.
|
||||
Generated project pages choose each object's solid paint from the current page
|
||||
context, using `spec_lock.md` roles as reusable anchors rather than an exhaustive
|
||||
palette; `create-template` takes colors from the confirmed brief and template
|
||||
`design_spec.md`. Mirror/preserve input keeps the source object's paint instead
|
||||
of regenerating this authored form.
|
||||
|
||||
```bash
|
||||
python3 ${SKILL_DIR}/scripts/preset_shape_svg.py render rightArrow \
|
||||
@@ -204,12 +271,13 @@ Every connector-family preset requires `--object-kind connector`, `--fill none`,
|
||||
and a visible stroke. It exports as an unconnected `p:cxnSp`; a connector
|
||||
preset can never be authored as an ordinary `shape`.
|
||||
|
||||
**Hard rule — stdout-only exception**: the helper prints one deterministic
|
||||
`<g>` fragment. Read that output and insert it with the normal page/template
|
||||
`apply_patch` edit. Do not redirect it into `svg_output/`, loop over pages or
|
||||
templates, batch shapes, or let it choose layout. The main Agent still authors
|
||||
every complete SVG page sequentially and maintains each reusable template
|
||||
explicitly.
|
||||
**Hard rule — stdout-only exception**: the helper prints one or more
|
||||
deterministic `<g>` fragments. Read that output and insert it with the normal
|
||||
page/template `apply_patch` edit. A batch JSON array is transient input for
|
||||
already-selected objects in the current construction, never a project resource
|
||||
or multi-page plan. Do not redirect output into `svg_output/`, loop over
|
||||
pages/templates, or let the helper choose layout. The main Agent still authors
|
||||
each complete SVG page and reusable template explicitly.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ Always-on Stage-2 rendering-candidate extension plus confirmed image elaboration
|
||||
|
||||
## 1. Proposed and Confirmed Image Plan
|
||||
|
||||
Before Stage 2, construct rendering candidates independently of the proposed source set. After confirmation, map the confirmed source set through [`strategist.md`](./strategist.md) §h and honor explicit `image_notes` roles; this module never adds a source. The confirmed non-`none` set is an allowed acquisition boundary, not coverage: use a suitable subset and leave irrelevant sources unused. Explicit must-use sources, assets, or page roles remain required. Asset inventory and judgment determine unconfirmed count, subject, placement, and composition without substituting an unconfirmed source.
|
||||
Before Stage 2, construct rendering candidates independently of the proposed source set. After confirmation, use this module within [`strategist.md`](./strategist.md)'s one-pass page carrier planning: run its eligibility and fit decisions inside that pass, then plan and route only the resulting image, lettering, and illustrated-icon jobs; map the confirmed source set through §h and honor explicit `image_notes` roles. This module never reopens the complete carrier mix as a separate pass, materializes a file, or adds a source. The confirmed non-`none` set is an allowed acquisition boundary, not coverage: use a suitable subset and leave irrelevant sources unused. Explicit must-use sources, assets, or page roles remain required. Asset inventory and judgment determine unconfirmed count, subject, placement, and composition without substituting an unconfirmed source.
|
||||
|
||||
For illustration, confirmed `none` stops and explicit user intent wins. Otherwise the locked visual style's `Illus.` propensity (`core` / `supportive` / `sparse`) tunes centrality and recurrence after the per-page composition scan; it never restricts eligible page types, element scale, or carrier combinations. When illustration is active, prefer one coherent family that can serve the actual page jobs, including recurring title/corner chrome, dominant anchors, supporting figures, and accents.
|
||||
For illustration, confirmed `none` stops and explicit user intent wins. Otherwise the locked visual style's `Illus.` propensity (`core` / `supportive` / `sparse`) tunes centrality and recurrence after the per-page composition scan; it never restricts eligible page types, element scale, or carrier combinations. When illustration is active, prefer one coherent family that can serve the actual page jobs, including recurring title/corner chrome, dominant anchors, supporting figures, and accents. A compact icon cue does not discharge a scene, subject, or visual-weight job that a photo or illustration family would serve.
|
||||
|
||||
**Context-first understanding for provided assets**: Do not visually scan `images/`. First infer identity, role, and crop / focus needs from source position and surrounding prose, captions / alt / titles, filename, user notes / confirmed `image_notes`, existing resource records, and CSV geometry. Inspect only one specific image when a remaining ambiguity would change selection, factual identity, page role, crop safety, or focal placement. Never inspect for inspiration, bulk-open the folder, or infer external facts / provenance from pixels. Record the result in §VIII. Leave an optional unresolved asset unused; route an unresolved must-use asset through failure recovery.
|
||||
|
||||
@@ -64,7 +64,7 @@ When a subject crosses a native title, panel, frame, or shape, the prepared path
|
||||
|
||||
## 2. AI Image Strategy — always propose three; lock only for confirmed `ai`
|
||||
|
||||
Before any rendering detail, read only [`image-renderings/_index.md`](./image-renderings/_index.md). First author exactly three complete, project-fit solution intents; use the index to freeze each intent's exact rendering bases, then read once only the deduplicated referenced sibling files. Project one complete `image_strategy` into each direction regardless of `recommend.image_usage`. Every candidate carries localized `name`, `rendering: custom`, `visual`, `mood`, and non-empty localized `behavior`. Mood includes a recognizable real-world analogy. All three must credibly serve their owning whole solution, but they need not use different bases or span artificial safe / shifted / bold extremes. Image colors always inherit that direction's deck HEX roles; never add an image palette or alter deck colors to rescue a rendering.
|
||||
Before any rendering detail, use the already-loaded [`image-renderings/_index.md`](./image-renderings/_index.md) as the sole rendering-basis catalog authority. First author exactly three complete, project-fit solution intents; use the index to freeze each intent's exact rendering bases, then read once only the deduplicated referenced sibling files. Project one complete `image_strategy` into each direction regardless of `recommend.image_usage`. Every candidate carries localized `name`, `rendering: custom`, `visual`, `mood`, and non-empty localized `behavior`. Mood includes a recognizable real-world analogy. All three must credibly serve their owning whole solution, but they need not use different bases or span artificial safe / shifted / bold extremes. Image colors always inherit that direction's deck HEX roles; never add an image palette or alter deck colors to rescue a rendering.
|
||||
|
||||
Every direction is a `custom` rendering. It may use zero, one, or many index-selected bases: one may own a specialized treatment, while several must each own a distinct line, texture, depth, material, or mood contribution. Name every actual id in the visible behavior and read only those files after selection; reference count has no fixed cap, and a second basis is never required. If the direction is genuinely novel, name no basis and read none. Under a template it obeys inherited identity and application. Only a confirmed custom locks its edited behavior as `image_rendering_behavior`; when catalog material is actually used, also project the exact ids as `image_rendering_references`, otherwise omit that field. Unselected candidates remain recommendation-only. Do not write a separate fourth `custom_candidates.image_strategy`; ignore legacy `image_palette`.
|
||||
|
||||
@@ -78,11 +78,11 @@ Add §VIII rows only for planned images; permitted unused sources create no row.
|
||||
|
||||
**Prepared derivatives**: Keep canonical; `Reference`: `Derived from <bare filename>; treatment=<operation>;`. Deterministic child: distinct `.png`, inherits acquisition; §4.4 follows `user`/`ai` above. Lock placed children; [`image-base.md`](./image-base.md) §2–3 owns preparation.
|
||||
|
||||
References describe visual intent: AI uses subject + intent + composition without repeating rendering or HEX; web records exact subject, view/mood, focal/quiet region, and crop safety with positive quality cues; Image_Searcher later derives a separate short, specific provider query without rewriting this locked intent, while complete entity names or necessary disambiguation may use more words. Any subject direction, focal placement, quiet region, or overlay-safety requirement that must affect acquisition/generation belongs in `Reference` or the matching §IX block, not only in `Layout pattern`.
|
||||
References describe visual intent: AI uses subject + intent + composition without repeating rendering or HEX; web records exact subject, view/mood, focal/quiet region, and crop safety with positive quality cues; Image_Searcher later derives a separate short, specific provider query without rewriting this locked intent, while complete entity names or necessary disambiguation may use more words. When page use depends on stable image composition, put its subject/quiet zones, boundary or direction, intended overlap/seam, and approximate share only when needed in `Reference` or the matching §IX block—not only in `Layout pattern`.
|
||||
|
||||
**Prepared-user fast path**: For initial imported or user-supplied assets confirmed as `provided`, copy the exact `Filename` basename and derive `Dimensions` / `Ratio` from that row's EXIF-corrected `Width` / `Height` / native `AspectRatio` in the latest `analysis/image_analysis.csv`; `SourceDisplayRatio` is source-context metadata, not the bitmap crop ratio. Drop source-side directories, set `Acquire Via: user` and `Status: Existing`, and decide the remaining §VIII fields normally. Existing §VIII / lock / provenance-manifest records override this inference. Assets declared as `ai`, `web`, `slice`, or manual fulfillment retain that provenance and advance through their own status lifecycle after entering `images/`; location never reclassifies them as `user / Existing`.
|
||||
|
||||
**Mandatory**: each placed row gets one executable `Layout pattern`. It is preferred expression, not locked geometry; optional hierarchical ids from the already-read [`image-layout-patterns.md`](./image-layout-patterns.md) must be exact. They are prompt lookup handles for Executor, not exporter effect codes. Executor may adapt the suggestion while preserving resource identity/source, must-use status, crop/content, and explicit user/template constraints; layout-only changes need no upstream rewrite.
|
||||
**Mandatory**: each placed row gets one executable `Layout pattern`. It is preferred expression, not locked geometry; optional hierarchical ids from the already-read [`image-layout-patterns.md`](./image-layout-patterns.md) must be exact. They are prompt lookup handles for Executor, not exporter effect codes. Executor may adopt, adapt, or decline the suggestion while preserving resource identity/source, must-use status, crop/content, and explicit user/template constraints; layout-only changes need no upstream rewrite.
|
||||
|
||||
**Default — action-bearing image plan (may override when restraint better serves the page)**: For a `hero_page` or other image-led row, name an image/content or image/shape action—not position, size, crop, or legibility scrim alone. Plain split and full bleed remain valid when clearest.
|
||||
|
||||
|
||||
@@ -55,10 +55,10 @@ Do not force communication intent into one catalog label; Stage 1 records compos
|
||||
| Literal requirement | Preserve the exact contracted value, pixels, wording, or topology. |
|
||||
| Semantic requirement | Preserve facts, relationships, intent, prohibitions, and completeness; expression may change. |
|
||||
| Identity anchor | Keep recurring identity stable without creating an exhaustive allowlist. |
|
||||
| Reference | Preserve the selected direction or role; adapt its realization to context. |
|
||||
| Reference | Consider the suggested direction or role; adopt, adapt, or decline it while preserving semantic and binding requirements. |
|
||||
| Permission / default | An allowed candidate/source boundary or preference; Strategist may leave it unused, with no quota. |
|
||||
|
||||
**Authority chain — materials → Strategist preparation → realization.** User inputs set materials/acquisition bounds. Strategist owns sufficiency, gap-filling, and selection: roster/content, semantic relationships, prepared resources/paths, Chart/Table and structured-template routing references, fonts, palette anchors, the icon library/stroke plus curated project pool, and crop bans. Topic research and import of its two-artifact research pair may precede confirmation; facts URLs are not auto-expanded. Only after normal image search fails may one adopted webpage become a reviewable Markdown + companion-image source package, with accepted files promoted individually. Independent AI/web/slice acquisition follows final confirmation plus completed §VIII/lock; icons are synced/validated during authoring without page assignment. Before Executor, each resource has a path and terminal/`Needs-Manual` state. Locally callable native construction is an Executor capability—not a resource or planning output. Executor owns its discovery and selection plus geometry, composition, hierarchy, spacing, treatment, and per-page choice among prepared icons; it never searches, generates, syncs, invents, or substitutes resources. Missing material/reselection returns upstream. Specificity defines freedom; References flex realization, never selection.
|
||||
**Authority chain — materials → Strategist preparation → realization.** User inputs set materials/acquisition bounds. Strategist owns sufficiency, gap-filling, and selection: roster/content, semantic relationships, prepared resources/paths, structured-template routing references, fonts, palette anchors, the icon library/stroke plus curated project pool, and crop bans; it owns optional Chart/Table construction-reference recommendations without locking their realization. It may recommend macro composition, visual focus, and cross-page continuity as Reference, but selects no element geometry or local authoring method. Topic research and import of its two-artifact research pair may precede confirmation; facts URLs are not auto-expanded. Only after normal image search fails may one adopted webpage become a reviewable Markdown + companion-image source package, with accepted files promoted individually. Independent AI/web/slice acquisition follows final confirmation plus completed §VIII/lock; icons are synced/validated during authoring without page assignment. Before Executor, each resource has a path and terminal/`Needs-Manual` state. Locally callable native construction is an Executor capability—not a resource or planning output. Executor owns its discovery and selection plus final geometry, composition, hierarchy, spacing, treatment, and per-page choice among prepared icons; it never searches, generates, syncs, invents, or substitutes resources. Missing material/reselection returns upstream. Specificity defines freedom; a Reference may be adopted, adapted, or declined without changing a binding selection.
|
||||
|
||||
Explicit *must*, *only*, *exactly*, *verbatim*, *do not*, or `no-crop` wording may strengthen only the named property into the appropriate Literal or Semantic requirement. Accepting an AI recommendation keeps the field's default type; it does not promote a Reference or Permission into a Literal requirement.
|
||||
|
||||
@@ -125,11 +125,11 @@ When authoring §IX, translate every purpose named in `communication_intent` int
|
||||
|
||||
Two independent layers, each locks one preset or `custom`. Output: `d. Mode: <mode> + Visual style: <visual_style>`.
|
||||
|
||||
> **Top-down custom direction construction.** Author three complete solution intents from the confirmed project contract and source before selecting any catalog basis; do not assemble three apparent solutions from independent mode/style/rendering picks. At that point only the three indexes may be in context. Use their summaries to freeze the exact reference ids for each direction, then read once only the deduplicated union of those referenced detail files and author the final behaviors. Every direction MUST serialize `mode: custom`, `visual_style: custom`, and `image_strategy.rendering: custom`, each with visible, non-empty behavior prose. A custom may use zero, one, or many catalog bases: one may specialize a strong dominant basis, several may divide distinct executable jobs, and a genuinely novel custom uses none. Reference count has no fixed cap and is an outcome, not a target; omit every basis whose contribution the behavior cannot state, and never add a second basis merely to make the result look synthesized. These three projections are the project-specific choices above the conservative fixed catalogs, not a fourth Custom proposal. Never glob a catalog, read an unselected sibling, or write bespoke prose as an enum value.
|
||||
> **Top-down custom direction construction.** Author three complete solution intents from the confirmed project contract and source before selecting any catalog basis; do not assemble three apparent solutions from independent mode/style/rendering picks. The fixed planning-capability batch may already be in context, but only the three mode/style/rendering indexes act as basis selectors. Use their summaries to freeze the exact reference ids for each direction, then read once only the deduplicated union of those referenced detail files and author the final behaviors. Every direction MUST serialize `mode: custom`, `visual_style: custom`, and `image_strategy.rendering: custom`, each with visible, non-empty behavior prose. A custom may use zero, one, or many catalog bases: one may specialize a strong dominant basis, several may divide distinct executable jobs, and a genuinely novel custom uses none. Reference count has no fixed cap and is an outcome, not a target; omit every basis whose contribution the behavior cannot state, and never add a second basis merely to make the result look synthesized. These three projections are the project-specific choices above the conservative fixed catalogs, not a fourth Custom proposal. Never glob a catalog, read an unselected sibling, or write bespoke prose as an enum value.
|
||||
|
||||
#### Layer 1 — Communication mode
|
||||
|
||||
🚧 **GATE**: before choosing a basis, read only [`modes/_index.md`](./modes/_index.md). After the three direction intents exist and their mode reference ids are frozen, read only those exact sibling files once; a novel mode reads none.
|
||||
🚧 **GATE**: use the already-loaded [`modes/_index.md`](./modes/_index.md) as the sole mode-basis catalog authority. After the three direction intents exist and their mode reference ids are frozen, read only those exact sibling files once; a novel mode reads none.
|
||||
|
||||
The deck's **narrative + persuasion skeleton** — how the argument is organized and advanced. Lock one preset from `pyramid` / `narrative` / `instructional` / `showcase` / `briefing`, or `custom` with behavior.
|
||||
|
||||
@@ -143,7 +143,7 @@ Record the confirmed mode and rationale in `design_spec.md` first, including eve
|
||||
|
||||
#### Layer 2 — Visual style
|
||||
|
||||
🚧 **GATE**: before choosing a basis, read only [`visual-styles/_index.md`](./visual-styles/_index.md). After the three direction intents exist and their style reference ids are frozen, read only those exact sibling files once; a novel style reads none.
|
||||
🚧 **GATE**: use the already-loaded [`visual-styles/_index.md`](./visual-styles/_index.md) as the sole style-basis catalog authority. After the three direction intents exist and their style reference ids are frozen, read only those exact sibling files once; a novel style reads none.
|
||||
|
||||
The deck's **visual aesthetic** — shape language, decoration density, whitespace rhythm, typographic character, texture. Anchors downstream fields e (Color), f (Icon), g (Typography), h (Image). Lock one preset from the catalog, or `custom`.
|
||||
|
||||
@@ -339,26 +339,50 @@ no-AI or editable-only requirements win. Execution follows
|
||||
|
||||
**Always-on decision module; conditional resource extension**:
|
||||
|
||||
1. Before authoring Stage-2 directions, read [`strategist-image.md`](./strategist-image.md) plus only [`image-renderings/_index.md`](./image-renderings/_index.md). After the three whole-direction intents exist and their rendering reference ids are frozen, read only those exact sibling files once and author one complete custom rendering inside each direction before deciding whether `recommend.image_usage` includes AI.
|
||||
2. Independently derive `recommend.image_usage` from source needs. Confirmed non-`none` sources activate the module's resource-planning sections and the image layout references. Confirmed `none` writes no image rows, but does not erase the three recommendation-only rendering candidates.
|
||||
1. Before authoring Stage-2 directions, load the workflow's complete fixed
|
||||
planning-capability batch. It includes this module, the image-layout
|
||||
authorities, all compact choice indexes, the icon-library contract, and the
|
||||
complete Chart/Table registries. After the three whole-direction intents
|
||||
exist and their mode/style/rendering reference ids are frozen, read only
|
||||
those exact detail siblings once and author one complete custom rendering
|
||||
inside each direction before deciding whether `recommend.image_usage`
|
||||
includes AI.
|
||||
2. Independently derive `recommend.image_usage` from source needs. Confirmed
|
||||
non-`none` sources activate the module's resource-planning sections.
|
||||
Confirmed `none` writes no image rows, but does not erase the three
|
||||
recommendation-only rendering candidates or the already-loaded composition
|
||||
vocabulary.
|
||||
|
||||
The module owns AI rendering alternatives, acquisition paths, resource rows, prompt depth, page roles, and placement intent.
|
||||
|
||||
### Presentation Capability & Visualization Recall (Non-blocking — Strategist recommends, no user confirmation needed)
|
||||
### Page Carrier and Capability Planning (Non-blocking — Strategist recommends, no user confirmation needed)
|
||||
|
||||
**Per-page capability recall**: Before §IX, consider this menu without a usage
|
||||
quota. Use existing fields for semantic intent; omit unused lines and
|
||||
implementation parameters. Executor may adapt/decline a `Motion suggestion`
|
||||
while preserving content and intent; explicit user/template requirements bind.
|
||||
**Mandatory — one-pass page carrier planning**: During the same §IX roster
|
||||
composition, resolve each page's complete semantic carrier mix—background
|
||||
field, editable text and optional lettering, native-geometry/relationship jobs,
|
||||
photos/scenes/illustrations/icons, and applicable visualizations—before
|
||||
deriving §VIII resource rows. Decide the primary, structural, and supporting
|
||||
jobs together; do not finish a text/container layout and then treat the other
|
||||
families as optional decoration. Use existing §VI/§VIII/§IX fields: keep the
|
||||
ordinary icon basis and prepared-pool plan in §VI, and add an image, lettering,
|
||||
or illustrated-icon resource to §VIII only when the page mix assigns it a
|
||||
plausible job. This creates no new field or candidate inventory; omitting any
|
||||
carrier remains valid after the same review. Macro composition recommendations
|
||||
remain Reference; planned resource identities/jobs and explicit user/template
|
||||
requirements retain their existing authority.
|
||||
|
||||
**Hard rule — native construction stays downstream**: record the page's
|
||||
semantic relationships and any prepared resource roles; add no native-
|
||||
construction recommendation. Executor independently discovers and selects local
|
||||
construction from the actual page content and visual system.
|
||||
semantic relationships, prepared resource roles, and any useful macro
|
||||
composition or visual-system recommendation. Do not inventory or bind a preset,
|
||||
primitive, Connector, Boolean/freeform operation, coordinates, or other local
|
||||
authoring method as the construction plan. A technique may appear only as
|
||||
optional inspiration inside a macro Reference; Executor independently
|
||||
discovers and selects construction from the actual page content and visual
|
||||
system.
|
||||
|
||||
| Capability | Opportunity signal | Design Spec handoff |
|
||||
|---|---|---|
|
||||
| Image composition | Image-as-canvas, editorial crop, collage, cutout, or meaningful focus / comparison / evidence units carry the page better than an adjacent rectangle | Propose a permitted source; when selected, apply the already-loaded [`strategist-image.md`](./strategist-image.md) resource contract plus the conditional image-layout references, record a concise §VIII `Layout pattern` suggestion, and describe page-level image/overlay relationships in §IX `Layout` / `Images` |
|
||||
| Image composition | Image-as-canvas, editorial crop, collage, cutout, or meaningful focus / comparison / evidence units carry the page better than an adjacent rectangle | Propose a permitted source; when selected, apply the already-loaded [`strategist-image.md`](./strategist-image.md) resource contract and image-layout references, record a concise §VIII `Layout pattern` suggestion, and describe page-level image/overlay relationships in §IX `Layout` / `Images` |
|
||||
| Composable illustration family | One or more pages benefit from coherent reusable title/corner ornaments, dominant anchors, supporting figures, compact illustrated-icon cues, or accents that can mix with text, shapes, photos, or lettering | Apply [`strategist-image.md`](./strategist-image.md): plan transparent elements by compatible family, record fixed reuse or adaptive variation in §VIII `Reference`, and describe each used page's carrier relationships in §IX `Layout` / `Images` |
|
||||
| Native paint / overlay | Gradient, translucency, scrim, vignette, or wash supports focus, hierarchy, depth, legibility, or image integration | Record purpose/layering in §IX `Layout`, plus `Images` when imagery participates; no new field or type/stops/opacity/coordinates—Executor chooses realization |
|
||||
| AI decorative lettering asset | Any stable display string in the deck — including a complete long or multi-line title, cover hook, chapter word, place or product name, dish or exhibit name, year, hero number, pull quote, or motif word — reads better with a material, dimensional, hand-rendered, or otherwise illustrative treatment than as ordinary text | Apply [`strategist-image.md`](./strategist-image.md): preserve every complete exact string, group compatible marks when useful, and keep chrome/body as native text. The lettering asset may carry the complete long or multi-line title as its display layer; keep an ordinary native title/subtitle in a separate text frame wherever the page needs a searchable, selectable, or outline-visible heading. Never shorten copy to make it look more like a wordmark |
|
||||
@@ -387,23 +411,17 @@ Classify by information model, never source PowerPoint object type:
|
||||
| Model | Planning action |
|
||||
|---|---|
|
||||
| Qualitative `order`, `link`, `parent`, `membership`, `contrast`, or `overlap` | Preserve units, relationship, and reading path as free §IX prose; no catalog key |
|
||||
| Values/dates/durations determine geometry | Chart; recall is optional |
|
||||
| Row header × column header addresses each fact | Table; recall is optional |
|
||||
| Values/dates/durations determine geometry | Chart; compare the complete loaded chart registry |
|
||||
| Row header × column header addresses each fact | Table; compare the complete loaded table registry |
|
||||
|
||||
**Mandatory — relationship handoff**: keep every qualitative relationship in §IX free prose; never serialize grammar atoms, coordinates, or named models. Executor makes the per-page Structure decision at runtime.
|
||||
|
||||
**Reference — not a constraint**: recall Chart/Table with 3–8 English tags when useful; add `--family chart|table` only when certain. Skip custom objects and qualitative composition.
|
||||
|
||||
```bash
|
||||
python3 skills/ppt-master/scripts/visualization_recall.py recall \
|
||||
--page P03 \
|
||||
--tag "time series" \
|
||||
--tag "three metrics" \
|
||||
--tag "direction over time" \
|
||||
--limit 6
|
||||
```
|
||||
|
||||
The command returns a bounded shortlist plus `no-template-match`. Read it unfiltered; `tail` / `head` / `grep` can hide ranked candidates. `confidence` is lexical only. At `high` / `medium`, keep no-match after candidate review. At `low` / `none`, use a fitting candidate directly; otherwise rerun once with `--semantic-fallback` before no-match. Do not open any family index separately.
|
||||
**Mandatory — complete Chart/Table capability review**: During the same §IX
|
||||
roster composition, compare every page's information model against every
|
||||
`Pick` / `Skip` rule in the two already-loaded live registries. The registries
|
||||
expose the possibility space; they are neither usage quotas nor whitelists.
|
||||
Skip custom objects and qualitative composition. Retain `no-template-match`
|
||||
when no registered reference fits.
|
||||
|
||||
**Selection**:
|
||||
|
||||
@@ -416,7 +434,8 @@ python3 skills/ppt-master/scripts/visualization_recall.py validate \
|
||||
<family>/<key> [<family>/<key> ...]
|
||||
```
|
||||
|
||||
Correct failed selections by recall; `no-template-match` never enters `page_visualizations`.
|
||||
Correct failed selections by re-reading the complete registries;
|
||||
`no-template-match` never enters `page_visualizations`.
|
||||
|
||||
**Section VII selection list**: write `Page | Family | Template | Usage` for each `chart|table` reference; Usage is semantic purpose. Omit empty/no-match detail. Qualitative composition stays in §IX; only Layout/Deck owns reusable PowerPoint structure.
|
||||
|
||||
@@ -461,7 +480,13 @@ Confirmation `d` locks two independent catalog items:
|
||||
- **Mode** — narrative skeleton: [`modes/_index.md`](./modes/_index.md) → `pyramid` / `narrative` / `instructional` / `showcase` / `briefing`.
|
||||
- **Visual style** — aesthetic: [`visual-styles/_index.md`](./visual-styles/_index.md) → presets + `custom`.
|
||||
|
||||
Strategist first reads only the three indexes, freezes the bases for the three whole directions, then reads only the deduplicated referenced detail files before authoring their custom behaviors. Executor reads one locked preset file or the exact references of a selected custom; neither role globs a catalog (see [`generate-pptx`](../workflows/generate-pptx.md) Step 6).
|
||||
Strategist first loads the fixed planning-capability batch. For
|
||||
mode/style/rendering basis selection it uses only the three corresponding
|
||||
indexes, freezes the bases for the three whole directions, then reads only the
|
||||
deduplicated referenced detail files before authoring their custom behaviors.
|
||||
Executor reads one locked preset file or the exact references of a selected
|
||||
custom; neither role globs a detail catalog (see
|
||||
[`generate-pptx`](../workflows/generate-pptx.md) Step 6).
|
||||
|
||||
---
|
||||
|
||||
@@ -475,35 +500,31 @@ Lock the stable role set the deck needs, including recurring neutrals such as `s
|
||||
|
||||
## 4. Layout Pattern Library
|
||||
|
||||
**Proportion follows information weight, not preset ratios.** Choose or combine the smallest structure that expresses the relationship; break the grid for a genuine `breathing` page. Repeating symmetric card grids is a failure mode.
|
||||
**Reference — not a constraint**: use these patterns as macro recommendation vocabulary. Proportion follows information weight, not preset ratios. Recommend or combine the smallest direction that expresses the relationship; Executor may adopt, adapt, or decline it after reading the actual page content and visual system. Repeating symmetric card grids without a page job is a failure mode.
|
||||
|
||||
| Content relationship | Useful starting structure |
|
||||
|---|---|
|
||||
| One focal claim | centered single column, negative space, or full-bleed + floating text |
|
||||
| Equal comparison | symmetric split or a true matrix |
|
||||
| Dominant evidence + takeaway | asymmetric split, typically 3:7 or 2:8 |
|
||||
| Dominant evidence + takeaway | asymmetric split with one dominant field |
|
||||
| Parallel sequence | three-column, process line, or Z-pattern |
|
||||
| Core + surrounding forces | center-radiating or hub-spoke |
|
||||
| Wide visual + explanation | top-bottom split |
|
||||
|
||||
**Default — define a cross-page visual motif system when it can carry identity or
|
||||
meaning (may omit when restraint serves the deck better)**: after the complete
|
||||
§IX roster and planned visual resources are known, choose or inherit a reusable
|
||||
motif or coherent element family—such as title/corner ornaments, a directional
|
||||
contour, opening, line lattice, or oversized numeral.
|
||||
Fold its invariant and reuse mode into §III `Theme`: exact repetition is valid
|
||||
for deliberate recurring chrome, while page-specific motifs may vary scale,
|
||||
crop, density, position, and content interaction. Mention it only in §IX
|
||||
`Layout` blocks that use it; create no motif field or lock row. This is a
|
||||
continuity Reference, not a decoration quota.
|
||||
|
||||
On PPT 16:9, start from a 1200×640 safe area with 40px outer margins, then adapt to content. Template workspaces may supply different geometry; when active, [`strategist-template.md`](./strategist-template.md) owns precedence.
|
||||
**Reference — not a constraint**: after the complete §IX roster and planned
|
||||
visual resources are known, recommend a cross-page motif or coherent element
|
||||
family when it can carry identity or meaning—such as title/corner ornaments, a
|
||||
directional contour, opening, line lattice, or oversized numeral. Record its
|
||||
continuity job and possible reuse mode in §III `Theme`; mention it only in §IX
|
||||
`Layout` blocks that benefit. Executor may adopt, adapt, or decline it and owns
|
||||
its geometry and construction. Create no motif field or lock row, and impose no
|
||||
decoration quota.
|
||||
|
||||
---
|
||||
|
||||
## 5. Template Flexibility Principle
|
||||
|
||||
Free-design patterns are starting points, not quotas. Adjust composition, spacing, and role sizes to the confirmed reading mode, page rhythm, and content. When a template workspace is active, do not reinterpret its reuse contract here; load [`strategist-template.md`](./strategist-template.md).
|
||||
**Reference — not a constraint**: free-design patterns are starting points, not quotas. Recommend a macro direction from the confirmed reading mode, page rhythm, and content; Executor owns exact composition and spacing within locked typography anchors. When a template workspace is active, do not reinterpret its reuse contract here; load [`strategist-template.md`](./strategist-template.md).
|
||||
|
||||
## 6. Workflow & Deliverables
|
||||
|
||||
@@ -544,7 +565,7 @@ final Stage 2 `false`, explicit objects-off, or explicit all-motion-off; only th
|
||||
includes transitions.
|
||||
|
||||
1. With Generate Step 4's retained complete final-confirmation state, read `${SKILL_DIR}/templates/design_spec_reference.md`.
|
||||
2. Compose the whole Design Spec in active context before touching the target path. Create `design_spec.md` once from the schema marker through §X; do not copy a scaffold into the project or patch placeholder fields. Record production mechanics in §I, including one effective outcome plus provenance for Speaker Notes, Custom Animations, and Narration Audio. Resolve them from latest explicit user instruction → matching final Stage 2 proactive value → workflow default `enabled` / `disabled` / `disabled`; Narration Audio enabled requires Speaker Notes enabled without rewriting the raw proactive evidence, and a dependency-driven notes outcome records that provenance. In §IX, create the complete ordered roster; each entry carries layout, title, core message, **Audience move**, complete preferred wording, exact mathematical content when applicable, capability recommendations, visualization/image references, sourced `Fact IDs`, and `Data class: scenario` for invented demo data. After Gate 1 plus conditional refine approval, roster ids/count/order and semantic content are authoritative; non-literal wording, block texture, layout, cover/closing composition, capability recommendations, and image/visualization patterns remain References unless promoted.
|
||||
2. Compose the whole Design Spec in active context before touching the target path. Create `design_spec.md` once from the schema marker through §X; do not copy a scaffold into the project or patch placeholder fields. Record production mechanics in §I, including one effective outcome plus provenance for Speaker Notes, Custom Animations, and Narration Audio. Resolve them from latest explicit user instruction → matching final Stage 2 proactive value → workflow default `enabled` / `disabled` / `disabled`; Narration Audio enabled requires Speaker Notes enabled without rewriting the raw proactive evidence, and a dependency-driven notes outcome records that provenance. In §IX, create the complete ordered roster; each entry carries layout, title, core message, **Audience move**, complete preferred wording, exact mathematical content when applicable, capability recommendations, visualization/image references, sourced `Fact IDs`, and `Data class: scenario` for invented demo data. After Gate 1 plus conditional refine approval, roster ids/count/order and semantic content are authoritative; non-literal wording, block texture, layout, cover/closing composition, capability recommendations, and image/visualization patterns remain References unless promoted, so Executor may adopt, adapt, or decline them without upstream repair while preserving their semantic jobs and all binding constraints.
|
||||
3. Compare `design_spec.md` against the final confirmation field by field. Repair every omission or deviation before entering an enabled refine-spec review or authoring `spec_lock.md`.
|
||||
4. If enabled, run [`refine-spec`](../workflows/stages/refine-spec.md) after Gate 1; edit only that Design Spec and create no lock before explicit approval.
|
||||
5. Read `${SKILL_DIR}/templates/spec_lock_reference.md`; create the lock once or resynchronize stale derived state from the approved Design Spec and context. Retain identity/refinements and stable roles/routing; omit unnamed page-local values, do not reopen evidence, and make no new recommendation.
|
||||
@@ -576,10 +597,10 @@ includes transitions.
|
||||
- **Custom behavior is concise and executable**: For confirmed `custom` mode or visual style, project one resolved `mode_behavior` / `visual_style_behavior` sentence or short paragraph. When the direction actually combines or borrows catalog entries, also project the exact, comma-separated `mode_references` / `visual_style_references`; omit the field for a genuinely novel direction and never fabricate a nearby reference. Preserve the confirmed direction, reference locked role names such as `colors.primary` when needed, and omit selection history, contradictions, precedence explanations, or other Design Spec provenance. Executor reads these fields from the retained lock and loads every referenced catalog entry once per valid context.
|
||||
- **page_rhythm is mandatory**: Based on the page list in §IX Content Outline, assign each page one of `anchor` / `dense` / `breathing`. This is what breaks the uniform "every page is a card grid" feel. New locks may not omit the section; consumer omission behavior is owned by [`executor-base.md`](executor-base.md) §2.1.
|
||||
- **Fact IDs and scenario labels are mandatory when applicable**: Read any `sources/*.facts.json`. For each §IX page, list the stable IDs actually used; never cite an ID whose claim is absent from the page. Mark invented KPIs/targets/internal ratios as `Data class: scenario` and state which values are scenario data. Executor carries external sources into notes/footnotes and renders a visible scenario label for scenario figures.
|
||||
- **Mandatory — whole-roster rhythm check**: During the same §IX composition, compare neighbors and section arcs to judge whether chapter entries visibly reset, extended same-density runs are intentional, extended same-carrier or same-topology runs form an intentional semantic sub-arc, repeated dominant geometry carries a continuity job, any qualifying §6.1 visible-state sequence preserves a recognizable mental map while making its next semantic change legible, each section follows a mode-fitting progression—including framework → explanation/evidence → judgment/action when it serves the objective—and the final arc resolves the communication objective before a genuine ending lowers information load. Repair the existing roster, `Layout`, and `page_rhythm` choices in place. This is judgment, not quota; preserve intentional continuity, legitimately all-`dense` material, and 1:1/literal order. Do not invent filler pages to manufacture rhythm; a `breathing` page marks a meaningful pause—chapter transition, standalone emphasis, or SCQA bridge—and must stand alone. Create no field, lock row, artifact, or second review/execution pass.
|
||||
- **Cover impact is mandatory**: In `design_spec.md §IX`, give `P01` one concrete hook from the source's strongest claim, metaphor, number, moment, or conflict plus a recommended composition. The hook binds; Executor may adapt the composition to prepared assets and explicit constraints. With no suitable image, recommend a native-SVG hook instead of a generic title treatment. Beautify / template-fill preservation paths are exempt.
|
||||
- **Mandatory — whole-roster rhythm check**: During the same §IX composition, compare neighbors and section arcs to judge whether chapter entries visibly reset, extended same-density runs are intentional, extended same-carrier or same-topology runs form an intentional semantic sub-arc, repeated dominant geometry carries a continuity job, any qualifying §6.1 visible-state sequence preserves a recognizable mental map while making its next semantic change legible, each section follows a mode-fitting progression—including framework → explanation/evidence → judgment/action when it serves the objective—and the final arc resolves the communication objective before a genuine ending lowers information load. Same section, equal weight or density, one style, and prior-page precedent do not establish a semantic sub-arc. Repair the existing roster, `Layout` recommendations, and `page_rhythm` choices in place. This is judgment, not quota; preserve intentional continuity, legitimately all-`dense` material, and 1:1/literal order. Do not invent filler pages to manufacture rhythm; a `breathing` page marks a meaningful pause—chapter transition, standalone emphasis, or SCQA bridge—and must stand alone. Create no field, lock row, artifact, or second review/execution pass.
|
||||
- **Cover impact is mandatory**: In `design_spec.md §IX`, give `P01` one concrete hook from the source's strongest claim, metaphor, number, moment, or conflict plus a recommended composition. The hook binds; Executor may adopt, adapt, or decline the composition while preserving the hook and explicit constraints. With no suitable image, recommend a native-SVG hook instead of a generic title treatment. Beautify / template-fill preservation paths are exempt.
|
||||
- **Cover rhythm lock**: `P01` remains `anchor`. Default away from generic content-page templates; a card grid, agenda, or equal-weight columns remains valid when content, user direction, or the template makes it the clearest cover.
|
||||
- **Closing impact (only when the deck closes)**: For a genuine conclusion / CTA / final takeaway, name the binding takeaway plus a recommended composition; Executor may adapt the latter. Do not default to an information-empty "Thank you", contact-only slide, or cover reprise; an explicit contact/event CTA may serve the purpose. **Do NOT invent a closing page to satisfy this**. Preservation paths are exempt.
|
||||
- **Closing impact (only when the deck closes)**: For a genuine conclusion / CTA / final takeaway, name the binding takeaway plus a recommended composition; Executor may adopt, adapt, or decline the latter while preserving the takeaway and explicit constraints. Do not default to an information-empty "Thank you", contact-only slide, or cover reprise; an explicit contact/event CTA may serve the purpose. **Do NOT invent a closing page to satisfy this**. Preservation paths are exempt.
|
||||
- **pptx_structure is mandatory**: Free-design, brand-only, and `template_reuse_scope: style` routes write `mode: flat`; a style-reference route may also record `template_reuse_scope: style` but omits every structure mapping and `template_adherence`. `template_reuse_scope: mirror|layout` writes `mode: structured` plus `template_adherence: strict|adaptive`. Do not write legacy `baseline`, `template`, `preserve`, `layout_strategy`, or Layout-kind rows into a new project.
|
||||
- **Flat-route boundary**: With `mode: flat`, omit `pptx_masters`, `pptx_layouts`, `page_pptx_layouts`, and `page_layouts`. Do not plan native Master/Layout families or reusable placeholder slots. Every generated SVG object remains Slide-local: omit root Master/Layout identity, `data-pptx-layer`, and `data-pptx-placeholder*` metadata. Export materializes one clean project-owned Master plus one Blank Layout from the current color/typography lock, removes stock content placeholders/Layout inventory, and retains only the standard date/footer/slide-number capability hooks.
|
||||
- **Structured template route**: When [`strategist-template.md`](./strategist-template.md) is active and reuse is `mirror|layout`, follow its complete Master/Layout/slot/prototype mapping rules.
|
||||
|
||||
+16
-2
@@ -2,6 +2,13 @@
|
||||
|
||||
A **visual style** is how the deck **looks** — shape language, decoration density, whitespace rhythm, typographic character, texture / elevation. Resolve **one per deck**; Default locks it, while Quick keeps it only in active context. It anchors the aesthetic of the SVG layout itself (cards, dividers, spacing, corner radius, shadow use).
|
||||
|
||||
**Hard rule — capability boundary**: A style governs treatment, visual weight,
|
||||
density, recurrence, and coherence. It never decides carrier eligibility or
|
||||
image source, and never narrows the complete primitive, Office-preset,
|
||||
independent-composition, Boolean, or necessary-freeform authoring vocabulary.
|
||||
Page purpose selects the carriers and construction; the style makes the chosen
|
||||
forms belong to one visual system.
|
||||
|
||||
> **Styles carry NO fixed HEX and define no palette.** Default core color identity and recurring role behavior live in `design_spec.colors` / `spec_lock.colors` (confirmation `e`); Quick resolves equivalent palette anchors in active context. A visual style describes how those anchors behave in SVG composition and may call for contextual tints, gradients, effects, or material transitions; it does not substitute an unrelated palette. Generated images follow the same anchor model through [`image-renderings/`](../image-renderings/). [`image-palettes/`](../image-palettes/) is legacy compatibility material only.
|
||||
>
|
||||
> A visual style is *not* a mode. **Visual style = how it looks; mode = how you argue** (see [`modes/_index.md`](../modes/_index.md)). Resolve them independently — any style pairs with any mode.
|
||||
@@ -15,12 +22,16 @@ Each style keeps its own authoritative file with: shape & decoration, typography
|
||||
> The **`visual_style` value is only ever a first-column `id`** (`swiss-minimal`, `editorial`, …). The "Paired rendering" column lists **image-rendering** names (`flat`, `minimalist-swiss`, `digital-dashboard`, …) — never treat one of those as the `visual_style`. Default records rendering under confirmation h; Quick keeps the selected rendering only in active context and any required image manifest.
|
||||
>
|
||||
> The **`Illus.`** column is each style's illustration propensity — `core` (illustration is intrinsic to the look), `supportive` (illustration can share the composition), or `sparse` (use selectively so the style's lead visual remains clear). It tunes centrality and recurrence, never eligible page types, element scale, or carrier combinations. An explicit user request to use / skip illustrations overrides it either way, and `image_usage: none` always writes no illustration rows. Full per-style rule in each file's §6.
|
||||
>
|
||||
> **Typography character applies to editable native text.** Decorative
|
||||
> lettering is a separate carrier decision; a selected style informs its
|
||||
> treatment, never its eligibility.
|
||||
|
||||
### 1.1 Corporate / product
|
||||
|
||||
| Visual style | Character | Best for | Paired rendering | Illus. |
|
||||
|---|---|---|---|---|
|
||||
| [`swiss-minimal`](./swiss-minimal.md) | Grid-locked, sharp, aggressive whitespace, no decoration | High-end consulting, architecture, type-led | `minimalist-swiss` | sparse |
|
||||
| [`swiss-minimal`](./swiss-minimal.md) | Grid-locked, sharp, aggressive whitespace, near-zero ornament | High-end consulting, architecture, type-led | `minimalist-swiss` | sparse |
|
||||
| [`soft-rounded`](./soft-rounded.md) | Rounded cards, gentle elevation, approachable | Product, SaaS, training, consumer | `flat` | supportive |
|
||||
| [`glassmorphism`](./glassmorphism.md) | Translucent glass panels, gradient light, floating depth | Modern SaaS, fintech, product launches, AI demos | `glassmorphism` | sparse |
|
||||
| [`dark-tech`](./dark-tech.md) | Dark canvas, glow accents, geometric precision | Tech, AI, data products, launches | `digital-dashboard` | sparse |
|
||||
@@ -110,4 +121,7 @@ Quick does not display a candidate spectrum. It reads this index, resolves one p
|
||||
| Default Generate | Strategist reads only this index while mapping three whole solution intents, freezes each custom direction's exact bases, then reads only their deduplicated detail files. Executor reads the confirmed preset file or exact custom references. |
|
||||
| Quick Generate | The current main agent reads only this index while deciding, then reads the resolved preset or exact custom bases and retains that one direction without Design Spec/lock. |
|
||||
|
||||
**Resolution scope**: deck-wide (one style per deck). It anchors taste as a **reference**, not a whitelist — pages may deviate with reason.
|
||||
**Resolution scope**: deck-wide (one style per deck). It anchors taste as a
|
||||
**reference**, not a whitelist. Each §1 `Composition geometry` list is
|
||||
generative vocabulary, not a finite layout menu; pages may synthesize or
|
||||
deviate when their communication job calls for it.
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Engineering schematic — thin line work on dark blueprint paper, isometric proj
|
||||
- Clean sans for labels and body; monospace for every component name / code / coordinate — mirroring how real technical docs read.
|
||||
- Small, precise annotation type; wide tracking on coordinate / dimension labels. Restraint over emphasis.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a clean sans + monospace pairing.
|
||||
> Families are chosen at confirmation `g`; this style asks for a clean sans + monospace pairing. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ Brutalist editorial newspaper. Wall-to-wall small type, irregular column widths,
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: hard rectangles and ruled boxes; thick black borders / cell frames; visible column dividers. Corner radius `rx="0"` — never rounded.
|
||||
- Shape language: favor hard-edged native contours, ruled boxes, thick black borders / cell frames, visible column dividers, brackets, block arrows, and raw stamps. Exact native shapes remain eligible when their semantic job fits; treat them with the same sharp print discipline. Corner radius `rx="0"` — never rounded.
|
||||
- Composition geometry: a masthead numeral or headline set so large it crosses column rules; one grid cell inverted to solid ink (light type on dark) as the focal cell; full-bleed rule bars slicing sections; a single rotated stamp-box breaking the grid at one deliberate point.
|
||||
- Decoration: the grid itself is the decoration — masthead bars, rule lines, boxed pull-quotes, halftone fills. No gradients, no soft cards, no shadows.
|
||||
- Whitespace: tight and deliberate — narrow margins, dense columns, a newspaper's packed rhythm. Density is the point; retain enough breathing room for hierarchy and readability without imposing a per-page count.
|
||||
@@ -17,7 +17,7 @@ Brutalist editorial newspaper. Wall-to-wall small type, irregular column widths,
|
||||
- Strong role contrast: a heavy display sans for headlines (poster-black weight), a serif character for column body, and monospace for figures / data can create the collision this style needs without imposing a family count.
|
||||
- Small body size, high density; strong size jump between masthead headline and body. Flush-left columns, tight leading.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a display-black × serif-body × monospace-data *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a display-black × serif-body × monospace-data *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ Classroom chalkboard — a dark slate field, soft chalk-stroke line work, powder
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: chalk-stroke line work with slightly diffused, dry-medium edges; sketched boxes, brackets, arrows in chalk. Confident but never mechanical — the sketched boxes and arrows are `<path>` with non-aligned points; a primitive `<rect>` / `<line>` snaps the chalk back to mechanical.
|
||||
- Shape language: chalk-stroke line work with slightly diffused, dry-medium edges; sketched boxes, brackets, arrows in chalk. When a mark must read as hand-drawn chalk, use a `<path>` with non-aligned points rather than a pristine primitive. Functional native contours remain eligible; keep their paint, weight, and hierarchy inside the chalkboard system.
|
||||
- Composition geometry: one big chalk ring around the term that matters; a radial mind-map spreading from a central concept; a hand-drawn arc timeline sweeping the board; an oversized chalk bracket grouping half the page; a boxed corner note holding the takeaway.
|
||||
- Decoration: underlines and emphasis marks; a few sprinkled chalk stars / dots. Blackboard pedagogy — organized sections, a clear central focus.
|
||||
- Whitespace: the dark board reads as room; let chalk marks breathe rather than crowd.
|
||||
@@ -15,7 +15,7 @@ Classroom chalkboard — a dark slate field, soft chalk-stroke line work, powder
|
||||
|
||||
- Hand-lettered chalk character for titles; legible body. Dry, nostalgic, classroom-warm.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a hand-lettered chalk title *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a hand-lettered chalk title *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Dark canvas, luminous accents, geometric precision. For tech, AI, dev tools, dat
|
||||
- Clean sans for body; monospace for labels / figures / code cues. Wide tracking on small-caps labels.
|
||||
- High-contrast hierarchy against the dark field.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a clean sans + monospace pairing.
|
||||
> Families are chosen at confirmation `g`; this style asks for a clean sans + monospace pairing. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ Bloomberg / Economist news-infographic — publication-grade information density
|
||||
|
||||
- Serif headline / hero-number for authority × a clean sans or monospace for numeric precision in tables and chart labels. Small captions and source lines; tight, deliberate hierarchy.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a serif-headline × precise-sans/mono-data *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a serif-headline × precise-sans/mono-data *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ Magazine-grade hierarchy. Columns, hairline rules, a serif / sans interplay, str
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: rectilinear; thin rules and column dividers instead of cards. Rounding, when used, stays visually minimal.
|
||||
- Shape language: a rectilinear editorial scaffold favors thin rules and column dividers over repeated cards. Outlined, compound, or exact native contours remain available when they clarify ownership, contrast, sequence, or emphasis; restraint controls their visual weight, not the contour vocabulary. Rounding, when used, stays visually minimal.
|
||||
- Composition geometry: an oversized drop cap or numeral anchoring the page; a pull quote breaking across columns; a full-height vertical rule the content hangs from; an asymmetric column split instead of mechanically even columns; a figure deliberately crossing a column edge.
|
||||
- Decoration: hairline rules, kickers / eyebrows, pull quotes, drop-style emphasis — typographic, not graphic. Sparing.
|
||||
- Whitespace: structured by columns and baseline rhythm; comfortable but information-rich.
|
||||
@@ -17,7 +17,7 @@ Magazine-grade hierarchy. Columns, hairline rules, a serif / sans interplay, str
|
||||
- Serif / sans interplay: a serif for headlines or pull quotes against a clean sans body (or the reverse). Clear role contrast.
|
||||
- Strong vertical hierarchy: kicker → headline → standfirst → body. Generous leading.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for an editorial serif/sans *pairing*, not specific fonts.
|
||||
> Families are chosen at confirmation `g`; this style asks for an editorial serif/sans *pairing*, not specific fonts. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ Frosted-glass SaaS — translucent layered panels, flowing gradient light, float
|
||||
|
||||
- Clean modern sans; regular with selective bold; airy. Exact Light/Black requires a user-confirmed installed face. Headlines can carry a luminous gradient on the dark field.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a clean, modern, airy sans *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a clean, modern, airy sans *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ Whiteboard-ink minimalism — a pale field, confident black hand-ink line work,
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: hand-drawn line work with slight, intentional wobble — boxes, arrows, dividers and brackets sketched as if on a thoughtful whiteboard; never mechanically straight — realize it as `<path>` / `<polyline>` with off-grid points, not `<rect>` / `<line>` primitives. Line defines structure; no filled cards.
|
||||
- Shape language: hand-drawn line work with slight, intentional wobble — boxes, arrows, dividers and brackets sketched as if on a thoughtful whiteboard. When a mark must read as hand-inked, realize it as `<path>` / `<polyline>` with off-grid points rather than a pristine primitive. Functional native contours remain eligible; line defines structure, while repeated filled-card grids are not the default grammar.
|
||||
- Composition geometry: a circled central concept with branch arrows carrying the page; a hand-drawn Venn or overlap sketch as the argument; strike-through-and-replace geometry for before/after; one oversized bracket grouping the evidence under the claim.
|
||||
- Decoration: minimal — a few doodle marks (stars, dashes, dots, underlines) for emphasis. Restraint is the look; clutter breaks the "considered" feel.
|
||||
- Whitespace: generous and empty; the pale field carries most of the canvas, elements float with room around them.
|
||||
@@ -16,7 +16,7 @@ Whiteboard-ink minimalism — a pale field, confident black hand-ink line work,
|
||||
- Hand-lettered / humanist character for titles — bold, slightly oversized, confident. Plain legible sans for body.
|
||||
- Reads as written-by-hand-but-deliberate, not corporate-precise.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a humanist / hand-lettered title *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a humanist / hand-lettered title *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ New-Chinese ink-wash — a rice-paper field, vast literati whitespace, restraine
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: minimal brush-stroke marks and hairline dividers; the occasional ink-dark block; a single seal-stamp (印章) square as a focal accent. No cards, no boxes — emptiness is the structure. The brush-stroke and ink-bleed marks are irregular `<path>` shapes with uneven control points — never an `<ellipse>` / `<circle>` standing in for a wash, which reads as fake ink. (The seal-stamp square is the one deliberate hard edge.)
|
||||
- Shape language: minimal brush-stroke marks and hairline dividers; the occasional ink-dark block; a single seal-stamp (印章) square as a focal accent. Avoid repeated card / box grids so emptiness remains the structure. A mark intended as brush stroke or ink bleed uses an irregular `<path>` with uneven control points rather than an `<ellipse>` / `<circle>` standing in for a wash. Functional native contours remain eligible when they serve meaning without turning the page into boxed UI.
|
||||
- Composition geometry: one broad brush sweep as the page's diagonal spine; an open ensō-like ring framing the core phrase; a vertical scroll band ordering a sequence; a low wash horizon with content floating in the emptiness above; the seal square placed to counterweight an asymmetric field.
|
||||
- Decoration: almost none; what little appears reads as brush and seal. Asymmetric, scroll-like composition with deliberate off-balance.
|
||||
- Whitespace: vast and intentional — the rice-paper field carries most of the page; a few elements float in great calm.
|
||||
@@ -15,7 +15,7 @@ New-Chinese ink-wash — a rice-paper field, vast literati whitespace, restraine
|
||||
|
||||
- Brush / serif character for titles (calligraphic, expressive) against a clean modern sans body — a Kai × Hei contrast axis. Large airy titles, generous leading, vertical rhythm welcome.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a calligraphic-brush title × clean-sans body *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a calligraphic-brush title × clean-sans body *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Memphis / Pop — clashing color blocks, geometric confetti, bold outlines, 80s-
|
||||
- Display poster type for headlines (heavy, attention-grabbing); a neutral readable sans for body so density stays legible under the visual energy.
|
||||
- Big, confident headline scale; tight to the artwork. Body kept clean and quiet by contrast.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a display-poster headline × neutral-sans body *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a display-poster headline × neutral-sans body *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ Layered paper-craft — scissor-cut shapes stacked in tactile layers, soft shado
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: forms defined by crisp, slightly-irregular cut edges (no outlines); simplified, stylized shapes that read as cut paper rather than illustration. Those cut edges are irregular `<polygon>` / `<path>` outlines, not a clean `<rect>` / `<circle>`, which reads as a digital box rather than torn paper.
|
||||
- Shape language: forms defined by crisp, slightly-irregular cut edges (no outlines); simplified, stylized shapes that read as cut paper rather than illustration. A silhouette intended to read as hand-cut uses an irregular `<polygon>` / `<path>` instead of a pristine digital box. Functional native contours and deliberately machine-cut layers remain eligible inside the same paper system.
|
||||
- Composition geometry: stacked wave sheets building the page bottom-up; a die-cut window revealing the layer beneath; one large cut disc (sun / moon) anchoring the composition; tabbed sheet edges ordering steps; a foreground frame layer with the content on the sheet behind it.
|
||||
- Decoration: layering itself is the device — each element is a "sheet" stacked over the one beneath; small cut-out accents on the top layer.
|
||||
- Whitespace: cozy, composed — the backing sheet shows through as breathing room.
|
||||
@@ -15,7 +15,7 @@ Layered paper-craft — scissor-cut shapes stacked in tactile layers, soft shado
|
||||
|
||||
- Clean friendly sans; warm, not severe. Titles can sit on a cut-paper banner shape.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a warm, rounded, approachable sans *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a warm, rounded, approachable sans *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ Photo-led editorial — large full-bleed photography dominates the page, text po
|
||||
|
||||
- Editorial serif / CJK title × clean sans body; magazine-column cadence; small precise captions and figure notes. Words are concise — they point, they don't fill.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for an editorial serif-title × clean-sans-body *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for an editorial serif-title × clean-sans-body *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: everything aligns to a visible pixel grid — blocky shapes, stepped edges, sharp transitions, no smooth curves; optional 1-pixel darker outlines for definition.
|
||||
- Shape language: style-defining visible forms align to a pixel grid — blocky shapes, stepped edges, sharp transitions, no smooth curves; optional 1-pixel darker outlines for definition. Exact native presets remain eligible when their semantic contour survives this blocky treatment; otherwise use a faithful stepped construction.
|
||||
- Composition geometry: a stepped pixel staircase as the divider; an oversized sprite anchoring the page; a HUD frame with corner brackets zoning content; a tile ground-band along the bottom edge; a pixel progress bar as the sequence device.
|
||||
- Decoration: classic game framing — HUD bars, tile floors, sprite icons, chunky pixel borders. References NES / SNES / arcade composition.
|
||||
- Whitespace: grid-disciplined; let blocks sit on clean tiled ground rather than crowd.
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
- Pixel / bitmap display character for headlines; keep body in a clean legible face — full-pixel body type strains at reading length.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a pixel / bitmap display *character* for titles, legible body alongside.
|
||||
> Families are chosen at confirmation `g`; this style asks for a pixel / bitmap display *character* for titles, legible body alongside. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ Warm hand-drawn sketchnote — soft paper field, black ink doodle line work, gen
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: rounded shapes drawn with a slight wobble; pastel block fills that slightly overshoot their outlines (hand-painted feel); simple cartoon icons. Draw that wobble as a `<path>` with non-aligned points — a `<rect rx>` is not wobble.
|
||||
- Shape language: rounded shapes drawn with a slight wobble; pastel block fills that slightly overshoot their outlines (hand-painted feel); simple cartoon icons. When a contour must read as doodled, draw the wobble as a `<path>` with non-aligned points rather than treating `<rect rx>` as hand drawing. Functional native contours remain eligible and may share the page with hand-drawn marks.
|
||||
- Composition geometry: a wavy-arrow journey path structuring the whole page; a radial mind-map around a central doodle; a hand-drawn banner ribbon carrying the title; numbered circles hopping along a dotted route; one cloud frame around the idea that matters.
|
||||
- Decoration: small doodles — stars, sparkles, dots, underlines — sprinkled sparingly for warmth; wavy hand-drawn arrows connecting ideas with short inline labels.
|
||||
- Whitespace: airy and well-organized; generous gaps between elements keep it friendly, never dense.
|
||||
@@ -15,7 +15,7 @@ Warm hand-drawn sketchnote — soft paper field, black ink doodle line work, gen
|
||||
|
||||
- Friendly hand-lettered titles; clear humanist body. Warmth and legibility over corporate severity.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a warm hand-lettered / humanist *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a warm hand-lettered / humanist *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Approachable and modern. Rounded cards, gentle elevation, friendly rhythm. For p
|
||||
- Friendly sans (humanist or geometric); medium weights; clear but not severe hierarchy.
|
||||
- Rounded, open letterforms suit; avoid condensed / industrial faces.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for an approachable sans *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for an approachable sans *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+3
-3
@@ -6,9 +6,9 @@ Strict Swiss-grid discipline. Modular grid, sharp geometry, aggressive whitespac
|
||||
|
||||
## 1. Shape & decoration
|
||||
|
||||
- Shape language: sharp rectangles, true circles, single-weight rules. Use square corners by default; any rounding stays barely perceptible.
|
||||
- Shape language: favor sharp, exact native contours, true circles, single-weight rules, and a small number of large geometric planes. Use square corners by default; any rounding stays barely perceptible. The full native vocabulary remains eligible when the selected contour stays purposeful, exact, and sparse.
|
||||
- Composition geometry: one oversized geometric plane — a full-height color column, a giant disc, a heavy bar — zoning the page; an asymmetric split with content flush to one axis; a hero numeral at architectural scale; a single diagonal rule or type line as the deliberate grid break. Few, large, exact — geometry at poster scale is Swiss, clutter is not.
|
||||
- Decoration: none. No gradient fills, no decorative blocks, no badges — structure carries the page.
|
||||
- Decoration: omit ornament without an information or composition job. No ornamental gradients, decorative blocks, or badges — structure carries the page. Content-bearing imagery, illustration, decorative lettering, and native geometry remain eligible when they strengthen that structure.
|
||||
- Whitespace: vast and deliberate; negative space carries as much weight as content. Wide margins, generous gutters.
|
||||
- Layout snaps to a visible or implied modular grid; rigorous column / row alignment.
|
||||
|
||||
@@ -17,7 +17,7 @@ Strict Swiss-grid discipline. Modular grid, sharp geometry, aggressive whitespac
|
||||
- Sans-serif, single family; regular/bold contrast. Exact Light/Black requires a user-confirmed installed face. Tight, rigorous spacing.
|
||||
- Strong size hierarchy — large headlines, small precise body. Left-aligned, flush.
|
||||
|
||||
> Family is chosen at confirmation `g` by subject fit — this style asks for a grotesque / neo-grotesque *character*, not a specific font.
|
||||
> Family is chosen at confirmation `g` by subject fit — this style asks for a grotesque / neo-grotesque *character*, not a specific font. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
+2
-2
@@ -8,14 +8,14 @@ Mid-century print poster (1950s–1970s) — bold rounded-geometric shapes, limi
|
||||
|
||||
- Shape language: bold geometric shapes with rounded organic edges, often slightly off-axis for retro tension; overlapping flat blocks; thick hand-aware lines; stylized, reduced iconography (a stylized sun, an angular mountain).
|
||||
- Composition geometry: a giant sun disc or arch as the backdrop anchor; ray wedges radiating from the focal point; off-axis overlapping blocks staging the content; a horizon band splitting the page into field and sky zones; one badge or rosette seal at the emphasis point.
|
||||
- Decoration: the print artifacts — halftone dot overlays, slight ink misregistration — carry the character; imagery stays reduced and graphic, never photoreal.
|
||||
- Decoration: the print artifacts — halftone dot overlays, slight ink misregistration — carry the character. Generated illustration stays reduced and graphic. Required documentary photography remains eligible; integrate it through crop, tonal reduction, halftone, or another print treatment instead of replacing the real subject with invented imagery.
|
||||
- Whitespace: confident poster composition — a few large blocks, deliberate negative space.
|
||||
|
||||
## 2. Typography character
|
||||
|
||||
- Retro display character for headlines (mid-century geometric, confident); a simple legible body by contrast.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a mid-century display *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a mid-century display *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Risograph zine / DIY poster — misregistered color layers, halftone dots, a tig
|
||||
- Punk-DIY contrast: a heavy poster display face for headlines, a plain readable sans for body, monospace for annotation (typewriter / photocopier feel).
|
||||
- Big headline tension against quiet body; slight intentional looseness reads as hand-set rather than mechanical.
|
||||
|
||||
> Families are chosen at confirmation `g`; this style asks for a display-poster × plain-sans × monospace-annotation *character*.
|
||||
> Families are chosen at confirmation `g`; this style asks for a display-poster × plain-sans × monospace-annotation *character*. This governs editable native text; decorative-lettering eligibility remains a separate carrier decision.
|
||||
|
||||
## 3. Using the deck's colors
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
# Install / 安装方式:
|
||||
# pip install -r requirements.txt
|
||||
|
||||
# Template registration / 模板注册 (scripts/register_template.py)
|
||||
PyYAML>=6.0
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# SVG to PPTX tool / SVG 转 PPTX 工具 (skills/ppt-master/scripts/svg_to_pptx.py)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -98,7 +98,7 @@ deprecated compatibility no-op. `--record-usage` writes one derived snapshot
|
||||
under `analysis/page-context/`; exact `o200k_base` token counts are optional and
|
||||
degrade to `tokens: null` when `tiktoken` is absent. Telemetry may be partial.
|
||||
|
||||
Visualization candidate recall:
|
||||
Optional visualization-recall diagnostics and canonical validation:
|
||||
|
||||
```bash
|
||||
python3 scripts/visualization_recall.py recall --page P03 --tag "time series" --tag "three metrics" --tag "direction over time"
|
||||
@@ -194,22 +194,57 @@ python3 scripts/native_enhance_pptx.py apply <project_path>
|
||||
python3 scripts/pptx_delivery_check.py <finished.pptx>
|
||||
```
|
||||
|
||||
Native preset shape authoring (one registry-backed fragment on stdout):
|
||||
Native preset shape authoring (one or more registry-backed fragments on stdout):
|
||||
|
||||
```bash
|
||||
python3 scripts/preset_shape_svg.py list --search arrow
|
||||
python3 scripts/preset_shape_svg.py describe rightArrow
|
||||
python3 scripts/preset_shape_svg.py list --grouped
|
||||
python3 scripts/preset_shape_svg.py recommend --compact --role spine --relationship order \
|
||||
--directionality horizontal --aspect wide --limit 6
|
||||
python3 scripts/preset_shape_svg.py describe rightArrow --compact
|
||||
python3 scripts/preset_shape_svg.py render rightArrow --id process-arrow --frame 120 180 240 96 --fill '#2563EB'
|
||||
python3 scripts/preset_shape_svg.py render-batch --input - <<'JSON'
|
||||
[
|
||||
{"preset":"chevron","id":"step-1","frame":[120,180,220,96],
|
||||
"fill":"#2563EB","stroke":"none","adjustments":{"adj":"val 42000"}},
|
||||
{"preset":"leftBrace","id":"group-brace","frame":[380,170,48,240],"fill":"none","stroke":"#111827","stroke_width":3}
|
||||
]
|
||||
JSON
|
||||
```
|
||||
|
||||
`list --grouped` is the compact entry index: it organizes the exact 187-name
|
||||
registry under the official Office gallery categories, then exposes semantic
|
||||
groups, scopes, one-line intent summaries, and grouped preset names. Full match
|
||||
reasons, intended uses, and misuse boundaries remain page-local in `recommend`
|
||||
and `describe` instead of being repeated in the mandatory discovery output.
|
||||
`recommend` recalls candidates from page-job criteria; its default `general`
|
||||
scope excludes literal-only symbols, flowchart notation, and action controls.
|
||||
Its result is neither a whitelist nor an automatic selection.
|
||||
`recommend --compact` keeps criteria, counts, selection note, and each
|
||||
candidate's preset, scope, literal boundary, intent, match reasons, and misuse
|
||||
boundaries; plain `recommend` preserves the full payload. The
|
||||
`describe --compact` view returns one flat object with semantic boundaries,
|
||||
adjustments, connection/text facts, and path count. Plain `describe` preserves
|
||||
the full nested geometry/semantics payload. A zero-match recommendation is
|
||||
valid JSON with exit code 0 so the caller can relax its criteria; a zero-match
|
||||
`list --search` remains a failed lookup with exit code 1. Plain
|
||||
`list [--search QUERY]` remains the compatibility name view.
|
||||
|
||||
The helper never writes a page or project file. Select one exact semantic
|
||||
stock-shape match, inspect the emitted fragment, and insert it into the
|
||||
hand-authored SVG with the normal patch workflow. Its project-authored output
|
||||
is one compact atomic `<g>` with direct registry-generated visible paths. When
|
||||
one effect is justified, optional `--filter-id softShadow` references one
|
||||
existing direct page-level filter under the shared shadow/glow contract and
|
||||
applies it once to a shape preset. Connector presets do not accept that option.
|
||||
The helper does not create the filter definition.
|
||||
hand-authored SVG with the normal patch workflow. Semantic discovery does not
|
||||
force ordinary rectangles, ellipses, or lines through `render`; use the
|
||||
simplest exact authoring form from the native-shape reference. A rendered
|
||||
project-owned preset is one compact atomic `<g>` with direct registry-generated
|
||||
visible paths. When one effect is justified, optional `--filter-id softShadow`
|
||||
references one existing direct page-level filter under the shared shadow/glow
|
||||
contract and applies it once to a shape preset. Connector presets do not accept
|
||||
that option. The helper does not create the filter definition. `render-batch`
|
||||
accepts a non-empty JSON array using the snake_case forms of the single-render
|
||||
options; it validates every item and duplicate id before printing, so one
|
||||
invalid item produces no partial fragment output. The batch remains
|
||||
fragment-only input for one current construction, not a page generator or
|
||||
project manifest. `adjustments` is a JSON object keyed by guide name, unlike
|
||||
the repeatable single-render `--adjust NAME=FORMULA` option.
|
||||
Quality check and export rerender the registry instead of relying on a hidden
|
||||
carrier, preview wrapper, or stored preview fingerprint. PPTX import and
|
||||
round-trip SVGs deliberately keep their expanded carrier/preview evidence and
|
||||
|
||||
@@ -650,6 +650,7 @@ Behavior:
|
||||
- Native export writes to a temporary file first and publishes the requested PPTX only after conversion succeeds. A failed conversion does not replace the main output file.
|
||||
- `--conversion-trace` without a path writes `validation/<output_stem>.trace.json`. `--conversion-trace <path>` respects the explicit destination; relative paths are resolved from the project root, so `exports/<name>.trace.json` remains available when intentionally requested.
|
||||
- Formal default and `--quick-generate` release export compute the exact SVG source fingerprint and refuse a missing, unreadable, unsupported, non-final, blocking, stale, or unverifiable final quality report before PPTX creation. A project without `validation/svg_quality_report.json` exits nonzero with the `not-provided` gate status; run the final checker against its current `svg_output/` first. An explicit non-`output` `--source` remains a diagnostic override and bypasses this release gate; postflight still records any verifiable report linkage.
|
||||
- The final quality report carries an informational `carrier_receipt` aggregate plus each page's `files[].info.carrier_receipt`: actual text/image/icon counts, SVG geometry, native preset names, marker use, native Chart/Table/Formula markers, and largest image-frame share. The terminal prints only the compact aggregate. These facts never affect exit status, create coverage quotas, or score design; the active Generate profile compares them with its retained page decisions before export.
|
||||
- After publication, native export writes `validation/<output_stem>.report.json`. The report distinguishes authored Slides from internal Layout definitions, reruns ZIP integrity and published Slide-count checks, records slide/layout/master/notes part counts, labels relationship/structured/transition/animation validation as enforced at build time, links the final SVG quality report only when its SHA-256 source fingerprint matches the exact export inputs, and surfaces stale/unverified gates, unresolved template tokens, generic-only font stacks, and external image references. A matching final quality report with introduced warnings yields `passed-with-warnings` and a `quality_introduced_warnings=<N>` receipt instead of a clean `passed` claim.
|
||||
- By default, a successful command also prints a compact receipt instead of requiring a report read: `[POSTFLIGHT] status=<...> quality_gate=<...> slides=<N> warning_categories=<N>`, followed by one compact line per warning category and the `[PPTX]` / `[REPORT]` paths. Resource-warning lines carry counts; a non-passing quality gate carries its status. Routine agents use this receipt and do not load either complete validation JSON into model context. Full reports remain cold audit artifacts; failure investigation and explicit audits extract only the required fields. `--quiet` keeps suppressing successful-run output.
|
||||
- Before publishing structured template output, export reopens the temporary PPTX and validates the Slide → Layout → Master graph and registrations, Layout identity, placeholder identity, reusable bounds, and prompt/level-one sizes. A mismatch aborts publication. Flat release instead validates its single referenced Master/Layout shell and exact date/footer/slide-number hook roster before packaging.
|
||||
|
||||
+13
-9
@@ -1,10 +1,12 @@
|
||||
# Visualization Candidate Recall
|
||||
|
||||
`visualization_recall.py` gives Default Strategist or the Quick Generate main
|
||||
agent one bounded deterministic shortlist across the live Chart and Table
|
||||
family registries. It exposes the selected full catalog only when the
|
||||
caller explicitly requests semantic review. The tool reads these indexes on
|
||||
every invocation and maintains no second category or keyword index:
|
||||
Default Strategist and the Quick Generate main agent read both complete compact
|
||||
registries before planning. `visualization_recall.py validate` resolves their
|
||||
selected canonical references. Its `recall` command remains an optional
|
||||
deterministic diagnostic across the same live Chart and Table registries; it is
|
||||
not the runtime capability-discovery gate and cannot replace the complete
|
||||
registry review. The tool reads these indexes on every invocation and maintains
|
||||
no second category or keyword index:
|
||||
|
||||
- `templates/charts/charts_index.json`
|
||||
- `templates/tables/tables_index.json`
|
||||
@@ -13,7 +15,7 @@ Qualitative Structure does not enter recall. Default records its relationship
|
||||
model in §IX; Quick keeps the same decision in active context. Both load
|
||||
`executor-structure.md` and compose the shapes for the current page.
|
||||
|
||||
## Recall candidates
|
||||
## Optional recall diagnostics
|
||||
|
||||
Describe one page's information shape with 3-8 concise English semantic tags.
|
||||
Translate source-language or industry terms into structural meaning first.
|
||||
@@ -35,9 +37,9 @@ candidates. `confidence` reports lexical strength only and never decides fit.
|
||||
|
||||
At `high` / `medium`, retain `no-template-match` when none fits. At `low` /
|
||||
`none`, select a fitting bounded candidate directly; otherwise rerun the same
|
||||
command once with `--semantic-fallback`, compare the returned selection rules
|
||||
semantically, and only then retain `no-template-match`. The full-catalog review
|
||||
is a narrow low-confidence no-match gate, not a routine recall step.
|
||||
command once with `--semantic-fallback` to inspect its diagnostic payload. The
|
||||
runtime owner still bases selection on the complete registries already loaded
|
||||
before planning.
|
||||
|
||||
| Field | Contract |
|
||||
|---|---|
|
||||
@@ -82,6 +84,8 @@ it without catalog lookup.
|
||||
|
||||
## Selection boundary
|
||||
|
||||
- Runtime selection comes from the complete loaded registries; recall output is
|
||||
optional diagnostic evidence, while `validate` resolves positive selections.
|
||||
- Default records `Page | Family | Template | Usage` for each positive
|
||||
selection and projects `family/key` into `page_visualizations`.
|
||||
- Usage is one concise page-local purpose; detailed adaptation remains in §IX.
|
||||
|
||||
@@ -55,6 +55,18 @@ from .registry import (
|
||||
PresetShapeRegistry,
|
||||
get_preset_registry,
|
||||
)
|
||||
from .semantics import (
|
||||
BUNDLED_SEMANTICS_PATH,
|
||||
SEMANTIC_ASPECTS,
|
||||
SEMANTIC_DIRECTIONALITY,
|
||||
SEMANTIC_RELATIONSHIPS,
|
||||
SEMANTIC_ROLES,
|
||||
SEMANTIC_SCOPES,
|
||||
SEMANTIC_TEXT_CAPACITIES,
|
||||
SEMANTIC_VISUAL_WEIGHTS,
|
||||
PresetShapeSemantics,
|
||||
get_preset_shape_semantics,
|
||||
)
|
||||
from .semantic_hash import (
|
||||
NATIVE_FALLBACK_SHA256_ATTR,
|
||||
resolve_preset_preview_hash,
|
||||
@@ -69,6 +81,7 @@ from .xml_safety import RELATIONSHIPS_NS, has_relationship_attributes
|
||||
__all__ = [
|
||||
"BUNDLED_DEFINITIONS_PATH",
|
||||
"BUNDLED_DEFINITIONS_SHA256",
|
||||
"BUNDLED_SEMANTICS_PATH",
|
||||
"BUNDLED_SHAPE_TYPES_PATH",
|
||||
"BUNDLED_SHAPE_TYPES_SHA256",
|
||||
"CONNECTOR_PRESET_TYPES",
|
||||
@@ -89,12 +102,21 @@ __all__ = [
|
||||
"PresetShapeDefinition",
|
||||
"PresetShapeError",
|
||||
"PresetShapeRegistry",
|
||||
"PresetShapeSemantics",
|
||||
"RELATIONSHIPS_NS",
|
||||
"SEMANTIC_ASPECTS",
|
||||
"SEMANTIC_DIRECTIONALITY",
|
||||
"SEMANTIC_RELATIONSHIPS",
|
||||
"SEMANTIC_ROLES",
|
||||
"SEMANTIC_SCOPES",
|
||||
"SEMANTIC_TEXT_CAPACITIES",
|
||||
"SEMANTIC_VISUAL_WEIGHTS",
|
||||
"UnknownGuideError",
|
||||
"UnknownPresetShapeError",
|
||||
"build_builtin_guides",
|
||||
"evaluate_formula",
|
||||
"get_preset_registry",
|
||||
"get_preset_shape_semantics",
|
||||
"has_relationship_attributes",
|
||||
"load_preset_shape_definitions",
|
||||
"load_shape_type_values",
|
||||
|
||||
+1217
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,716 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
PPT Master - DrawingML Preset Shape Semantics
|
||||
|
||||
Load and validate the bundled Office-category and authoring-use catalog for
|
||||
DrawingML preset shapes.
|
||||
|
||||
Usage:
|
||||
Import get_preset_shape_semantics from pptx_shapes.semantics.
|
||||
|
||||
Examples:
|
||||
catalog = get_preset_shape_semantics()
|
||||
arrow = catalog.describe("rightArrow")
|
||||
|
||||
Dependencies:
|
||||
None (only uses standard library and local PPT Master modules)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Sequence
|
||||
|
||||
from .errors import PresetShapeDataError, UnknownPresetShapeError
|
||||
from .registry import get_preset_registry
|
||||
|
||||
|
||||
BUNDLED_SEMANTICS_PATH = (
|
||||
Path(__file__).resolve().parent / "data" / "presetShapeSemantics.json"
|
||||
)
|
||||
|
||||
SEMANTIC_ROLES = (
|
||||
"field",
|
||||
"carrier",
|
||||
"node",
|
||||
"edge",
|
||||
"spine",
|
||||
"boundary",
|
||||
"callout",
|
||||
"label",
|
||||
"symbol",
|
||||
"control",
|
||||
"accent",
|
||||
)
|
||||
SEMANTIC_RELATIONSHIPS = (
|
||||
"none",
|
||||
"membership",
|
||||
"order",
|
||||
"link",
|
||||
"hierarchy",
|
||||
"contrast",
|
||||
"convergence",
|
||||
"cycle",
|
||||
"overlap",
|
||||
"annotation",
|
||||
"flow",
|
||||
"literal",
|
||||
"navigation",
|
||||
)
|
||||
SEMANTIC_DIRECTIONALITY = (
|
||||
"none",
|
||||
"horizontal",
|
||||
"vertical",
|
||||
"diagonal",
|
||||
"bidirectional",
|
||||
"multidirectional",
|
||||
"bent",
|
||||
"curved",
|
||||
"radial",
|
||||
"callout",
|
||||
)
|
||||
SEMANTIC_ASPECTS = (
|
||||
"flexible",
|
||||
"wide",
|
||||
"tall",
|
||||
"square",
|
||||
"linear",
|
||||
)
|
||||
SEMANTIC_TEXT_CAPACITIES = ("none", "short", "medium", "high")
|
||||
SEMANTIC_VISUAL_WEIGHTS = ("quiet", "moderate", "strong", "emblematic")
|
||||
SEMANTIC_SCOPES = ("general", "literal", "flowchart", "navigation")
|
||||
|
||||
_TEXT_CAPACITY_RANK = {
|
||||
value: index for index, value in enumerate(SEMANTIC_TEXT_CAPACITIES)
|
||||
}
|
||||
_QUERY_TOKEN_RE = re.compile(r"[a-z0-9]+")
|
||||
_CAMEL_BOUNDARY_RE = re.compile(r"(?<=[a-z0-9])(?=[A-Z])")
|
||||
_QUERY_STOP_WORDS = frozenset({
|
||||
"a",
|
||||
"an",
|
||||
"and",
|
||||
"for",
|
||||
"of",
|
||||
"or",
|
||||
"the",
|
||||
"to",
|
||||
"with",
|
||||
})
|
||||
|
||||
|
||||
class PresetShapeSemantics:
|
||||
"""Read-only semantic catalog aligned exactly with the preset registry."""
|
||||
|
||||
def __init__(self, payload: object, expected_names: Sequence[str]) -> None:
|
||||
root = _require_dict(payload, "catalog")
|
||||
self.schema = _require_string(root.get("schema"), "catalog.schema")
|
||||
self.sources = tuple(
|
||||
_require_dict(item, f"catalog.sources[{index}]")
|
||||
for index, item in enumerate(
|
||||
_require_list(root.get("sources"), "catalog.sources")
|
||||
)
|
||||
)
|
||||
|
||||
categories = _require_list(
|
||||
root.get("office_categories"),
|
||||
"catalog.office_categories",
|
||||
)
|
||||
self._categories: list[dict[str, object]] = []
|
||||
self._category_by_id: dict[str, dict[str, object]] = {}
|
||||
for index, raw_category in enumerate(categories):
|
||||
label = f"catalog.office_categories[{index}]"
|
||||
category = _require_dict(raw_category, label)
|
||||
_reject_unknown_fields(category, label, {"id", "label", "summary"})
|
||||
category_id = _require_string(category.get("id"), f"{label}.id")
|
||||
if category_id in self._category_by_id:
|
||||
raise PresetShapeDataError(
|
||||
f"Duplicate Office shape category: {category_id!r}"
|
||||
)
|
||||
normalized = {
|
||||
"id": category_id,
|
||||
"label": _require_string(category.get("label"), f"{label}.label"),
|
||||
"summary": _require_string(
|
||||
category.get("summary"),
|
||||
f"{label}.summary",
|
||||
),
|
||||
}
|
||||
self._categories.append(normalized)
|
||||
self._category_by_id[category_id] = normalized
|
||||
|
||||
groups = _require_list(root.get("groups"), "catalog.groups")
|
||||
self._groups: list[dict[str, object]] = []
|
||||
self._preset_semantics: dict[str, dict[str, object]] = {}
|
||||
self._group_order: dict[str, int] = {}
|
||||
self._preset_order = {
|
||||
name: index for index, name in enumerate(expected_names)
|
||||
}
|
||||
for index, raw_group in enumerate(groups):
|
||||
group = self._normalize_group(raw_group, index)
|
||||
group_id = str(group["id"])
|
||||
if group_id in self._group_order:
|
||||
raise PresetShapeDataError(
|
||||
f"Duplicate preset semantic group: {group_id!r}"
|
||||
)
|
||||
self._group_order[group_id] = index
|
||||
self._groups.append(group)
|
||||
presets = group["presets"]
|
||||
assert isinstance(presets, dict)
|
||||
for preset_name, preset_details in presets.items():
|
||||
if preset_name in self._preset_semantics:
|
||||
raise PresetShapeDataError(
|
||||
f"Preset appears in multiple semantic groups: {preset_name!r}"
|
||||
)
|
||||
details = dict(group)
|
||||
details.pop("presets")
|
||||
details["preset"] = preset_name
|
||||
details.update(preset_details)
|
||||
details["recommended_for"] = _merge_strings(
|
||||
group["recommended_for"],
|
||||
preset_details.get("recommended_for", ()),
|
||||
)
|
||||
details["avoid_for"] = _merge_strings(
|
||||
group["avoid_for"],
|
||||
preset_details.get("avoid_for", ()),
|
||||
)
|
||||
self._preset_semantics[preset_name] = details
|
||||
|
||||
expected = set(expected_names)
|
||||
actual = set(self._preset_semantics)
|
||||
missing = sorted(expected - actual)
|
||||
extra = sorted(actual - expected)
|
||||
if missing or extra:
|
||||
raise PresetShapeDataError(
|
||||
"Preset semantic catalog differs from ShapeTypeValues: "
|
||||
f"missing={missing}, extra={extra}"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def bundled(cls) -> PresetShapeSemantics:
|
||||
"""Load the semantic catalog shipped with PPT Master."""
|
||||
|
||||
try:
|
||||
payload = json.loads(BUNDLED_SEMANTICS_PATH.read_text(encoding="utf-8"))
|
||||
except OSError as exc:
|
||||
raise PresetShapeDataError(
|
||||
f"Cannot read preset semantic catalog: {exc}"
|
||||
) from exc
|
||||
except json.JSONDecodeError as exc:
|
||||
raise PresetShapeDataError(
|
||||
"Invalid preset semantic JSON at "
|
||||
f"line {exc.lineno}, column {exc.colno}: {exc.msg}"
|
||||
) from exc
|
||||
return cls(payload, get_preset_registry().names)
|
||||
|
||||
@property
|
||||
def preset_count(self) -> int:
|
||||
"""Return the number of catalogued presets."""
|
||||
|
||||
return len(self._preset_semantics)
|
||||
|
||||
def describe(self, preset: str) -> dict[str, object]:
|
||||
"""Return the resolved semantic record for one preset."""
|
||||
|
||||
try:
|
||||
return dict(self._preset_semantics[preset])
|
||||
except KeyError as exc:
|
||||
raise UnknownPresetShapeError(
|
||||
f"Unknown DrawingML preset shape: {preset!r}"
|
||||
) from exc
|
||||
|
||||
def grouped(self, search: str = "") -> dict[str, object]:
|
||||
"""Return a compact Office/group index and matching preset names."""
|
||||
|
||||
query_tokens = _query_tokens(search)
|
||||
category_payloads: list[dict[str, object]] = []
|
||||
for category in self._categories:
|
||||
group_payloads: list[dict[str, object]] = []
|
||||
for group in self._groups:
|
||||
if group["office_category"] != category["id"]:
|
||||
continue
|
||||
presets = group["presets"]
|
||||
assert isinstance(presets, dict)
|
||||
matching_presets = []
|
||||
group_matches = _matches_query(
|
||||
{
|
||||
key: value
|
||||
for key, value in group.items()
|
||||
if key != "presets"
|
||||
},
|
||||
query_tokens,
|
||||
)
|
||||
for name, details in presets.items():
|
||||
if query_tokens and not group_matches and not _matches_query(
|
||||
{"preset": name, **details},
|
||||
query_tokens,
|
||||
):
|
||||
continue
|
||||
matching_presets.append(name)
|
||||
if not matching_presets:
|
||||
continue
|
||||
recommended_for = group["recommended_for"]
|
||||
assert isinstance(recommended_for, tuple)
|
||||
group_payload = {
|
||||
"id": group["id"],
|
||||
"label": group["label"],
|
||||
"scope": group["scope"],
|
||||
"intent": recommended_for[0],
|
||||
"presets": matching_presets,
|
||||
}
|
||||
group_payloads.append(group_payload)
|
||||
if group_payloads:
|
||||
category_payloads.append({**category, "groups": group_payloads})
|
||||
return {
|
||||
"schema": self.schema,
|
||||
"sources": [dict(source) for source in self.sources],
|
||||
"preset_count": sum(
|
||||
len(group["presets"])
|
||||
for category in category_payloads
|
||||
for group in category["groups"]
|
||||
),
|
||||
"search": search,
|
||||
"office_categories": category_payloads,
|
||||
}
|
||||
|
||||
def recommend(
|
||||
self,
|
||||
*,
|
||||
roles: Sequence[str],
|
||||
scope: str = "general",
|
||||
relationships: Sequence[str] = (),
|
||||
directionality: str | None = None,
|
||||
aspect: str | None = None,
|
||||
text_capacity: str | None = None,
|
||||
visual_weight: str | None = None,
|
||||
query: str = "",
|
||||
limit: int = 12,
|
||||
) -> dict[str, object]:
|
||||
"""Return a diverse, semantics-matched candidate recall set."""
|
||||
|
||||
query_tokens = _query_tokens(query)
|
||||
candidates: list[dict[str, object]] = []
|
||||
for details in self._preset_semantics.values():
|
||||
if scope != "all" and details["scope"] != scope:
|
||||
continue
|
||||
|
||||
role_matches = [role for role in roles if role in details["roles"]]
|
||||
if not role_matches:
|
||||
continue
|
||||
relationship_matches = [
|
||||
relationship
|
||||
for relationship in relationships
|
||||
if relationship in details["relationships"]
|
||||
]
|
||||
if relationships and not relationship_matches:
|
||||
continue
|
||||
if directionality and directionality not in details["directionality"]:
|
||||
continue
|
||||
if aspect and not _aspect_matches(details["aspects"], aspect):
|
||||
continue
|
||||
if text_capacity and not _capacity_matches(
|
||||
str(details["text_capacity"]),
|
||||
text_capacity,
|
||||
):
|
||||
continue
|
||||
if visual_weight and details["visual_weight"] != visual_weight:
|
||||
continue
|
||||
|
||||
query_score = _query_score(details, query_tokens, query)
|
||||
if query_tokens and query_score == 0:
|
||||
continue
|
||||
score = (
|
||||
len(role_matches) * 20
|
||||
+ len(relationship_matches) * 12
|
||||
+ (5 if directionality else 0)
|
||||
+ (4 if aspect else 0)
|
||||
+ (3 if text_capacity else 0)
|
||||
+ (2 if visual_weight else 0)
|
||||
+ query_score
|
||||
)
|
||||
why = [f"role={value}" for value in role_matches]
|
||||
why.extend(
|
||||
f"relationship={value}" for value in relationship_matches
|
||||
)
|
||||
if directionality:
|
||||
why.append(f"directionality={directionality}")
|
||||
if aspect:
|
||||
why.append(f"aspect={aspect}")
|
||||
if text_capacity:
|
||||
why.append(f"text_capacity>={text_capacity}")
|
||||
if visual_weight:
|
||||
why.append(f"visual_weight={visual_weight}")
|
||||
if query_tokens:
|
||||
why.append(f"query={query}")
|
||||
candidates.append({
|
||||
"score": score,
|
||||
"preset": details["preset"],
|
||||
"office_category": {
|
||||
"id": details["office_category"],
|
||||
"label": details["office_category_label"],
|
||||
},
|
||||
"group": details["id"],
|
||||
"scope": details["scope"],
|
||||
"intent": details["intent"],
|
||||
"why": why,
|
||||
"recommended_for": details["recommended_for"],
|
||||
"avoid_for": details["avoid_for"],
|
||||
"literal_only": details["literal_only"],
|
||||
})
|
||||
|
||||
ordered = self._diverse_order(candidates)
|
||||
return {
|
||||
"criteria": {
|
||||
"roles": list(roles),
|
||||
"scope": scope,
|
||||
"relationships": list(relationships),
|
||||
"directionality": directionality,
|
||||
"aspect": aspect,
|
||||
"text_capacity": text_capacity,
|
||||
"visual_weight": visual_weight,
|
||||
"query": query,
|
||||
},
|
||||
"candidate_count": len(candidates),
|
||||
"returned_count": min(len(ordered), limit),
|
||||
"selection_note": (
|
||||
"Candidate recall only. Compare contour, content fit, and avoid_for "
|
||||
"before choosing; this is neither a whitelist nor an automatic choice."
|
||||
if ordered
|
||||
else "No candidates matched. This is a valid recall result; relax or "
|
||||
"change the criteria before selecting a contour."
|
||||
),
|
||||
"candidates": ordered[:limit],
|
||||
}
|
||||
|
||||
def _normalize_group(
|
||||
self,
|
||||
raw_group: object,
|
||||
index: int,
|
||||
) -> dict[str, object]:
|
||||
label = f"catalog.groups[{index}]"
|
||||
group = _require_dict(raw_group, label)
|
||||
_reject_unknown_fields(
|
||||
group,
|
||||
label,
|
||||
{
|
||||
"id",
|
||||
"label",
|
||||
"office_category",
|
||||
"scope",
|
||||
"roles",
|
||||
"relationships",
|
||||
"directionality",
|
||||
"aspects",
|
||||
"text_capacity",
|
||||
"visual_weight",
|
||||
"literal_only",
|
||||
"recommended_for",
|
||||
"avoid_for",
|
||||
"presets",
|
||||
},
|
||||
)
|
||||
category_id = _require_string(
|
||||
group.get("office_category"),
|
||||
f"{label}.office_category",
|
||||
)
|
||||
if category_id not in self._category_by_id:
|
||||
raise PresetShapeDataError(
|
||||
f"{label} references unknown Office category {category_id!r}"
|
||||
)
|
||||
scope = _require_choice(group.get("scope"), f"{label}.scope", SEMANTIC_SCOPES)
|
||||
roles = _require_choices(group.get("roles"), f"{label}.roles", SEMANTIC_ROLES)
|
||||
relationships = _require_choices(
|
||||
group.get("relationships"),
|
||||
f"{label}.relationships",
|
||||
SEMANTIC_RELATIONSHIPS,
|
||||
)
|
||||
directionality = _require_choices(
|
||||
group.get("directionality"),
|
||||
f"{label}.directionality",
|
||||
SEMANTIC_DIRECTIONALITY,
|
||||
)
|
||||
aspects = _require_choices(
|
||||
group.get("aspects"),
|
||||
f"{label}.aspects",
|
||||
SEMANTIC_ASPECTS,
|
||||
)
|
||||
presets = _require_dict(group.get("presets"), f"{label}.presets")
|
||||
if not presets:
|
||||
raise PresetShapeDataError(f"{label}.presets must not be empty")
|
||||
normalized_presets: dict[str, dict[str, object]] = {}
|
||||
for preset_name, raw_details in presets.items():
|
||||
preset_label = f"{label}.presets[{preset_name!r}]"
|
||||
details = _require_dict(raw_details, preset_label)
|
||||
_reject_unknown_fields(
|
||||
details,
|
||||
preset_label,
|
||||
{
|
||||
"intent",
|
||||
"scope",
|
||||
"roles",
|
||||
"relationships",
|
||||
"directionality",
|
||||
"aspects",
|
||||
"text_capacity",
|
||||
"visual_weight",
|
||||
"literal_only",
|
||||
"recommended_for",
|
||||
"avoid_for",
|
||||
},
|
||||
)
|
||||
normalized_details: dict[str, object] = {
|
||||
"intent": _require_string(
|
||||
details.get("intent"),
|
||||
f"{preset_label}.intent",
|
||||
)
|
||||
}
|
||||
repeated_choices = {
|
||||
"roles": SEMANTIC_ROLES,
|
||||
"relationships": SEMANTIC_RELATIONSHIPS,
|
||||
"directionality": SEMANTIC_DIRECTIONALITY,
|
||||
"aspects": SEMANTIC_ASPECTS,
|
||||
}
|
||||
for field, choices in repeated_choices.items():
|
||||
if field in details:
|
||||
normalized_details[field] = _require_choices(
|
||||
details[field],
|
||||
f"{preset_label}.{field}",
|
||||
choices,
|
||||
)
|
||||
single_choices = {
|
||||
"scope": SEMANTIC_SCOPES,
|
||||
"text_capacity": SEMANTIC_TEXT_CAPACITIES,
|
||||
"visual_weight": SEMANTIC_VISUAL_WEIGHTS,
|
||||
}
|
||||
for field, choices in single_choices.items():
|
||||
if field in details:
|
||||
normalized_details[field] = _require_choice(
|
||||
details[field],
|
||||
f"{preset_label}.{field}",
|
||||
choices,
|
||||
)
|
||||
if "literal_only" in details:
|
||||
normalized_details["literal_only"] = _require_bool(
|
||||
details["literal_only"],
|
||||
f"{preset_label}.literal_only",
|
||||
)
|
||||
for field in ("recommended_for", "avoid_for"):
|
||||
if field in details:
|
||||
normalized_details[field] = _require_string_list(
|
||||
details[field],
|
||||
f"{preset_label}.{field}",
|
||||
)
|
||||
normalized_presets[preset_name] = normalized_details
|
||||
recommended_for = _require_string_list(
|
||||
group.get("recommended_for"),
|
||||
f"{label}.recommended_for",
|
||||
)
|
||||
avoid_for = _require_string_list(
|
||||
group.get("avoid_for"),
|
||||
f"{label}.avoid_for",
|
||||
)
|
||||
if not recommended_for or not avoid_for:
|
||||
raise PresetShapeDataError(
|
||||
f"{label}.recommended_for and avoid_for must not be empty"
|
||||
)
|
||||
return {
|
||||
"id": _require_string(group.get("id"), f"{label}.id"),
|
||||
"label": _require_string(group.get("label"), f"{label}.label"),
|
||||
"office_category": category_id,
|
||||
"office_category_label": self._category_by_id[category_id]["label"],
|
||||
"scope": scope,
|
||||
"roles": roles,
|
||||
"relationships": relationships,
|
||||
"directionality": directionality,
|
||||
"aspects": aspects,
|
||||
"text_capacity": _require_choice(
|
||||
group.get("text_capacity"),
|
||||
f"{label}.text_capacity",
|
||||
SEMANTIC_TEXT_CAPACITIES,
|
||||
),
|
||||
"visual_weight": _require_choice(
|
||||
group.get("visual_weight"),
|
||||
f"{label}.visual_weight",
|
||||
SEMANTIC_VISUAL_WEIGHTS,
|
||||
),
|
||||
"literal_only": _require_bool(
|
||||
group.get("literal_only"),
|
||||
f"{label}.literal_only",
|
||||
),
|
||||
"recommended_for": recommended_for,
|
||||
"avoid_for": avoid_for,
|
||||
"presets": normalized_presets,
|
||||
}
|
||||
|
||||
def _diverse_order(
|
||||
self,
|
||||
candidates: list[dict[str, object]],
|
||||
) -> list[dict[str, object]]:
|
||||
candidates.sort(
|
||||
key=lambda item: (
|
||||
-int(item["score"]),
|
||||
self._group_order[str(item["group"])],
|
||||
self._preset_order[str(item["preset"])],
|
||||
)
|
||||
)
|
||||
ordered: list[dict[str, object]] = []
|
||||
scores = sorted({int(item["score"]) for item in candidates}, reverse=True)
|
||||
for score in scores:
|
||||
score_items = [item for item in candidates if item["score"] == score]
|
||||
first_by_group: list[dict[str, object]] = []
|
||||
remaining: list[dict[str, object]] = []
|
||||
seen_groups: set[str] = set()
|
||||
for item in score_items:
|
||||
group_id = str(item["group"])
|
||||
target = first_by_group if group_id not in seen_groups else remaining
|
||||
target.append(item)
|
||||
seen_groups.add(group_id)
|
||||
ordered.extend(first_by_group)
|
||||
ordered.extend(remaining)
|
||||
return ordered
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def get_preset_shape_semantics() -> PresetShapeSemantics:
|
||||
"""Return the process-wide, lazily loaded bundled semantic catalog."""
|
||||
|
||||
return PresetShapeSemantics.bundled()
|
||||
|
||||
|
||||
def _require_dict(value: object, label: str) -> dict[str, object]:
|
||||
if not isinstance(value, dict):
|
||||
raise PresetShapeDataError(f"{label} must be a JSON object")
|
||||
return value
|
||||
|
||||
|
||||
def _reject_unknown_fields(
|
||||
value: dict[str, object],
|
||||
label: str,
|
||||
allowed: set[str],
|
||||
) -> None:
|
||||
unknown = sorted(set(value) - allowed)
|
||||
if unknown:
|
||||
raise PresetShapeDataError(
|
||||
f"{label} contains unsupported fields: {', '.join(unknown)}"
|
||||
)
|
||||
|
||||
|
||||
def _require_list(value: object, label: str) -> list[object]:
|
||||
if not isinstance(value, list):
|
||||
raise PresetShapeDataError(f"{label} must be a JSON array")
|
||||
return value
|
||||
|
||||
|
||||
def _require_string(value: object, label: str) -> str:
|
||||
if not isinstance(value, str) or not value.strip():
|
||||
raise PresetShapeDataError(f"{label} must be a non-empty string")
|
||||
return value.strip()
|
||||
|
||||
|
||||
def _require_bool(value: object, label: str) -> bool:
|
||||
if not isinstance(value, bool):
|
||||
raise PresetShapeDataError(f"{label} must be a boolean")
|
||||
return value
|
||||
|
||||
|
||||
def _require_choice(value: object, label: str, choices: Sequence[str]) -> str:
|
||||
text = _require_string(value, label)
|
||||
if text not in choices:
|
||||
raise PresetShapeDataError(
|
||||
f"{label} must be one of {', '.join(choices)}; got {text!r}"
|
||||
)
|
||||
return text
|
||||
|
||||
|
||||
def _require_choices(
|
||||
value: object,
|
||||
label: str,
|
||||
choices: Sequence[str],
|
||||
) -> tuple[str, ...]:
|
||||
values = _require_string_list(value, label)
|
||||
if not values:
|
||||
raise PresetShapeDataError(f"{label} must not be empty")
|
||||
unknown = sorted(set(values) - set(choices))
|
||||
if unknown:
|
||||
raise PresetShapeDataError(
|
||||
f"{label} contains unsupported values: {', '.join(unknown)}"
|
||||
)
|
||||
return values
|
||||
|
||||
|
||||
def _require_string_list(value: object, label: str) -> tuple[str, ...]:
|
||||
items = _require_list(value, label)
|
||||
values = tuple(
|
||||
_require_string(item, f"{label}[{index}]")
|
||||
for index, item in enumerate(items)
|
||||
)
|
||||
if len(values) != len(set(values)):
|
||||
raise PresetShapeDataError(f"{label} contains duplicate values")
|
||||
return values
|
||||
|
||||
|
||||
def _merge_strings(first: object, second: object) -> tuple[str, ...]:
|
||||
merged: list[str] = []
|
||||
for values in (first, second):
|
||||
assert isinstance(values, tuple)
|
||||
for value in values:
|
||||
if value not in merged:
|
||||
merged.append(value)
|
||||
return tuple(merged)
|
||||
|
||||
|
||||
def _query_tokens(query: str) -> tuple[str, ...]:
|
||||
normalized = _CAMEL_BOUNDARY_RE.sub(" ", query).casefold()
|
||||
return tuple(
|
||||
token
|
||||
for token in _QUERY_TOKEN_RE.findall(normalized)
|
||||
if token not in _QUERY_STOP_WORDS
|
||||
)
|
||||
|
||||
|
||||
def _search_text(value: object) -> str:
|
||||
if isinstance(value, str):
|
||||
return _CAMEL_BOUNDARY_RE.sub(" ", value).casefold()
|
||||
if isinstance(value, (list, tuple)):
|
||||
return " ".join(_search_text(item) for item in value)
|
||||
if isinstance(value, dict):
|
||||
return " ".join(_search_text(item) for item in value.values())
|
||||
return ""
|
||||
|
||||
|
||||
def _matches_query(details: dict[str, object], query_tokens: Sequence[str]) -> bool:
|
||||
if not query_tokens:
|
||||
return True
|
||||
haystack = _search_text(details)
|
||||
return all(token in haystack for token in query_tokens)
|
||||
|
||||
|
||||
def _query_score(
|
||||
details: dict[str, object],
|
||||
query_tokens: Sequence[str],
|
||||
query: str,
|
||||
) -> int:
|
||||
if not query_tokens:
|
||||
return 0
|
||||
haystack = _search_text(details)
|
||||
matches = sum(1 for token in query_tokens if token in haystack)
|
||||
if matches == 0:
|
||||
return 0
|
||||
score = matches * 4
|
||||
normalized_query = " ".join(_query_tokens(query))
|
||||
if normalized_query and normalized_query in haystack:
|
||||
score += 10
|
||||
preset = str(details["preset"])
|
||||
if query.casefold() == preset.casefold():
|
||||
score += 20
|
||||
return score
|
||||
|
||||
|
||||
def _aspect_matches(values: object, requested: str) -> bool:
|
||||
assert isinstance(values, tuple)
|
||||
return requested in values or "flexible" in values
|
||||
|
||||
|
||||
def _capacity_matches(actual: str, requested: str) -> bool:
|
||||
return _TEXT_CAPACITY_RANK[actual] >= _TEXT_CAPACITY_RANK[requested]
|
||||
@@ -2,19 +2,25 @@
|
||||
"""
|
||||
PPT Master - Preset Shape SVG Fragment Tool
|
||||
|
||||
List DrawingML presets or print one compact canonical native-preset SVG group to
|
||||
stdout for manual insertion into a hand-authored page or template.
|
||||
Browse and recommend DrawingML presets, or print compact canonical
|
||||
native-preset SVG groups to stdout for manual insertion into a hand-authored
|
||||
page or template.
|
||||
|
||||
Usage:
|
||||
python3 scripts/preset_shape_svg.py list [--search QUERY]
|
||||
python3 scripts/preset_shape_svg.py describe PRESET
|
||||
python3 scripts/preset_shape_svg.py list [--grouped] [--search QUERY]
|
||||
python3 scripts/preset_shape_svg.py describe PRESET [--compact]
|
||||
python3 scripts/preset_shape_svg.py recommend --role ROLE [options] [--compact]
|
||||
python3 scripts/preset_shape_svg.py render PRESET --id ID --frame X Y W H
|
||||
python3 scripts/preset_shape_svg.py render-batch --input FILE_OR_DASH
|
||||
|
||||
Examples:
|
||||
python3 scripts/preset_shape_svg.py list --search arrow
|
||||
python3 scripts/preset_shape_svg.py describe rightArrow
|
||||
python3 scripts/preset_shape_svg.py list --grouped
|
||||
python3 scripts/preset_shape_svg.py recommend --role spine \
|
||||
--relationship order --directionality horizontal --compact
|
||||
python3 scripts/preset_shape_svg.py describe rightArrow --compact
|
||||
python3 scripts/preset_shape_svg.py render rightArrow --id next-step \
|
||||
--frame 160 210 320 112 --fill "#2563EB" --stroke none
|
||||
python3 scripts/preset_shape_svg.py render-batch --input shapes.json
|
||||
|
||||
Dependencies:
|
||||
None (only uses standard library and local PPT Master modules)
|
||||
@@ -25,16 +31,45 @@ from __future__ import annotations
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Sequence
|
||||
|
||||
from console_encoding import configure_utf8_stdio
|
||||
from pptx_shapes import CONNECTOR_PRESET_TYPES, get_preset_registry
|
||||
from pptx_shapes.semantics import (
|
||||
SEMANTIC_ASPECTS,
|
||||
SEMANTIC_DIRECTIONALITY,
|
||||
SEMANTIC_RELATIONSHIPS,
|
||||
SEMANTIC_ROLES,
|
||||
SEMANTIC_SCOPES,
|
||||
SEMANTIC_TEXT_CAPACITIES,
|
||||
SEMANTIC_VISUAL_WEIGHTS,
|
||||
get_preset_shape_semantics,
|
||||
)
|
||||
from pptx_to_svg.preset_authoring import render_preset_shape_fragment
|
||||
|
||||
|
||||
configure_utf8_stdio()
|
||||
|
||||
|
||||
_BATCH_ITEM_FIELDS = frozenset({
|
||||
"preset",
|
||||
"id",
|
||||
"frame",
|
||||
"object_kind",
|
||||
"name",
|
||||
"fill",
|
||||
"fill_opacity",
|
||||
"stroke",
|
||||
"stroke_width",
|
||||
"stroke_opacity",
|
||||
"stroke_linecap",
|
||||
"stroke_linejoin",
|
||||
"filter_id",
|
||||
"adjustments",
|
||||
})
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
@@ -52,14 +87,100 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
list_parser.add_argument(
|
||||
"--search",
|
||||
default="",
|
||||
help="Case-insensitive preset-name substring.",
|
||||
help=(
|
||||
"Case-insensitive preset-name substring; grouped output also "
|
||||
"searches semantic text."
|
||||
),
|
||||
)
|
||||
list_parser.add_argument(
|
||||
"--grouped",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Print a compact Office-category and semantic-group index with "
|
||||
"one-line intent summaries and preset names as JSON."
|
||||
),
|
||||
)
|
||||
|
||||
describe_parser = subparsers.add_parser(
|
||||
"describe",
|
||||
help="Print preset adjustment and path metadata as JSON.",
|
||||
help="Print preset geometry and semantic metadata as JSON.",
|
||||
)
|
||||
describe_parser.add_argument("preset", help="DrawingML preset name.")
|
||||
describe_parser.add_argument(
|
||||
"--compact",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Print one flat selection view with semantic boundaries and key "
|
||||
"geometry facts."
|
||||
),
|
||||
)
|
||||
|
||||
recommend_parser = subparsers.add_parser(
|
||||
"recommend",
|
||||
help="Recall semantically matched preset candidates as JSON.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--role",
|
||||
action="append",
|
||||
required=True,
|
||||
choices=SEMANTIC_ROLES,
|
||||
help="Required page role; repeat to allow multiple roles.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--relationship",
|
||||
action="append",
|
||||
default=[],
|
||||
choices=SEMANTIC_RELATIONSHIPS,
|
||||
help="Required relationship fit; repeat to allow alternatives.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--scope",
|
||||
choices=("all", *SEMANTIC_SCOPES),
|
||||
default="general",
|
||||
help=(
|
||||
"Semantic scope. The general default excludes literal-only, "
|
||||
"flowchart, and navigation shapes."
|
||||
),
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--directionality",
|
||||
choices=SEMANTIC_DIRECTIONALITY,
|
||||
help="Required direction or route character.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--aspect",
|
||||
choices=SEMANTIC_ASPECTS,
|
||||
help="Required frame tendency; flexible candidates also match.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--text-capacity",
|
||||
choices=SEMANTIC_TEXT_CAPACITIES,
|
||||
help="Minimum useful text capacity.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--visual-weight",
|
||||
choices=SEMANTIC_VISUAL_WEIGHTS,
|
||||
help="Required visual-weight band.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--query",
|
||||
default="",
|
||||
help="Optional English intent terms used to refine the recall set.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--limit",
|
||||
type=_positive_integer,
|
||||
default=12,
|
||||
help="Maximum returned candidates; default: 12.",
|
||||
)
|
||||
recommend_parser.add_argument(
|
||||
"--compact",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Print a reduced recall view for direct inspection without "
|
||||
"downstream parsing."
|
||||
),
|
||||
)
|
||||
|
||||
render_parser = subparsers.add_parser(
|
||||
"render",
|
||||
@@ -140,6 +261,22 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
"for example --adjust 'adj1=val 50000'."
|
||||
),
|
||||
)
|
||||
|
||||
batch_parser = subparsers.add_parser(
|
||||
"render-batch",
|
||||
help="Print multiple canonical authored-preset fragments atomically.",
|
||||
)
|
||||
batch_parser.add_argument(
|
||||
"--input",
|
||||
required=True,
|
||||
metavar="FILE_OR_DASH",
|
||||
help=(
|
||||
"UTF-8 JSON array of shape objects; use - to read stdin. "
|
||||
"Use an 'adjustments' object such as "
|
||||
"{\"adj\": \"val 42000\"}; the command prints no fragments "
|
||||
"when any item is invalid."
|
||||
),
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
@@ -149,6 +286,13 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||
registry = get_preset_registry()
|
||||
|
||||
if args.command == "list":
|
||||
if args.grouped:
|
||||
payload = get_preset_shape_semantics().grouped(args.search)
|
||||
if payload["preset_count"] == 0:
|
||||
print(f"No preset semantics match {args.search!r}", file=sys.stderr)
|
||||
return 1
|
||||
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
||||
return 0
|
||||
query = args.search.casefold().strip()
|
||||
names = [
|
||||
name for name in registry.names
|
||||
@@ -165,20 +309,88 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||
print(f"Unknown DrawingML preset: {args.preset!r}", file=sys.stderr)
|
||||
return 1
|
||||
definition = registry.get(args.preset)
|
||||
payload = {
|
||||
adjustments = [
|
||||
{"name": guide.name, "formula": guide.formula}
|
||||
for guide in definition.adjustments
|
||||
]
|
||||
connector_preset = definition.name in CONNECTOR_PRESET_TYPES
|
||||
path_count = len(definition.paths)
|
||||
connection_site_count = len(definition.connections)
|
||||
has_text_rectangle = definition.text_rectangle is not None
|
||||
semantics = get_preset_shape_semantics().describe(args.preset)
|
||||
full_payload = {
|
||||
"preset": definition.name,
|
||||
"connector_preset": definition.name in CONNECTOR_PRESET_TYPES,
|
||||
"adjustments": [
|
||||
{"name": guide.name, "formula": guide.formula}
|
||||
for guide in definition.adjustments
|
||||
],
|
||||
"path_count": len(definition.paths),
|
||||
"connection_site_count": len(definition.connections),
|
||||
"has_text_rectangle": definition.text_rectangle is not None,
|
||||
"connector_preset": connector_preset,
|
||||
"adjustments": adjustments,
|
||||
"path_count": path_count,
|
||||
"connection_site_count": connection_site_count,
|
||||
"has_text_rectangle": has_text_rectangle,
|
||||
"semantics": semantics,
|
||||
}
|
||||
payload = (
|
||||
{
|
||||
"preset": definition.name,
|
||||
"intent": semantics["intent"],
|
||||
"recommended_for": semantics["recommended_for"],
|
||||
"avoid_for": semantics["avoid_for"],
|
||||
"adjustments": adjustments,
|
||||
"connector_preset": connector_preset,
|
||||
"path_count": path_count,
|
||||
"connection_site_count": connection_site_count,
|
||||
"has_text_rectangle": has_text_rectangle,
|
||||
}
|
||||
if args.compact
|
||||
else full_payload
|
||||
)
|
||||
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
||||
return 0
|
||||
|
||||
if args.command == "recommend":
|
||||
full_payload = get_preset_shape_semantics().recommend(
|
||||
roles=args.role,
|
||||
scope=args.scope,
|
||||
relationships=args.relationship,
|
||||
directionality=args.directionality,
|
||||
aspect=args.aspect,
|
||||
text_capacity=args.text_capacity,
|
||||
visual_weight=args.visual_weight,
|
||||
query=args.query,
|
||||
limit=args.limit,
|
||||
)
|
||||
payload = (
|
||||
{
|
||||
"criteria": full_payload["criteria"],
|
||||
"candidate_count": full_payload["candidate_count"],
|
||||
"returned_count": full_payload["returned_count"],
|
||||
"selection_note": full_payload["selection_note"],
|
||||
"candidates": [
|
||||
{
|
||||
"preset": candidate["preset"],
|
||||
"scope": candidate["scope"],
|
||||
"literal_only": candidate["literal_only"],
|
||||
"intent": candidate["intent"],
|
||||
"why": candidate["why"],
|
||||
"avoid_for": candidate["avoid_for"],
|
||||
}
|
||||
for candidate in full_payload["candidates"]
|
||||
],
|
||||
}
|
||||
if args.compact
|
||||
else full_payload
|
||||
)
|
||||
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
||||
return 0
|
||||
|
||||
if args.command == "render-batch":
|
||||
try:
|
||||
items = _read_batch_items(args.input)
|
||||
fragments = _render_batch_items(items)
|
||||
except ValueError as exc:
|
||||
print(f"Error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
print("\n".join(fragments))
|
||||
return 0
|
||||
|
||||
try:
|
||||
adjustments = _parse_adjustments(args.adjust)
|
||||
style = _style_from_args(args)
|
||||
@@ -215,27 +427,148 @@ def _parse_adjustments(values: Sequence[str]) -> dict[str, str]:
|
||||
return adjustments
|
||||
|
||||
|
||||
def _positive_integer(value: str) -> int:
|
||||
try:
|
||||
number = int(value)
|
||||
except ValueError as exc:
|
||||
raise argparse.ArgumentTypeError("expected a positive integer") from exc
|
||||
if number < 1:
|
||||
raise argparse.ArgumentTypeError("expected a positive integer")
|
||||
return number
|
||||
|
||||
|
||||
def _style_from_args(args: argparse.Namespace) -> dict[str, str]:
|
||||
return _style_from_values(
|
||||
fill=args.fill,
|
||||
fill_opacity=args.fill_opacity,
|
||||
stroke=args.stroke,
|
||||
stroke_width=args.stroke_width,
|
||||
stroke_opacity=args.stroke_opacity,
|
||||
stroke_linecap=args.stroke_linecap,
|
||||
stroke_linejoin=args.stroke_linejoin,
|
||||
)
|
||||
|
||||
|
||||
def _style_from_values(
|
||||
*,
|
||||
fill: object = "none",
|
||||
fill_opacity: object | None = None,
|
||||
stroke: object = "none",
|
||||
stroke_width: object | None = None,
|
||||
stroke_opacity: object | None = None,
|
||||
stroke_linecap: object | None = None,
|
||||
stroke_linejoin: object | None = None,
|
||||
) -> dict[str, str]:
|
||||
fill_text = str(fill)
|
||||
stroke_text = str(stroke)
|
||||
style = {
|
||||
"fill": args.fill,
|
||||
"stroke": args.stroke,
|
||||
"fill": fill_text,
|
||||
"stroke": stroke_text,
|
||||
}
|
||||
if args.fill_opacity is not None:
|
||||
style["fill-opacity"] = str(args.fill_opacity)
|
||||
if args.stroke != "none":
|
||||
if fill_opacity is not None:
|
||||
style["fill-opacity"] = str(fill_opacity)
|
||||
if stroke_text != "none":
|
||||
style["stroke-width"] = str(
|
||||
1.0 if args.stroke_width is None else args.stroke_width
|
||||
1.0 if stroke_width is None else stroke_width
|
||||
)
|
||||
elif args.stroke_width is not None:
|
||||
elif stroke_width is not None:
|
||||
raise ValueError("--stroke-width requires a non-none --stroke")
|
||||
if args.stroke_opacity is not None:
|
||||
style["stroke-opacity"] = str(args.stroke_opacity)
|
||||
if args.stroke_linecap is not None:
|
||||
style["stroke-linecap"] = args.stroke_linecap
|
||||
if args.stroke_linejoin is not None:
|
||||
style["stroke-linejoin"] = args.stroke_linejoin
|
||||
if stroke_opacity is not None:
|
||||
style["stroke-opacity"] = str(stroke_opacity)
|
||||
if stroke_linecap is not None:
|
||||
style["stroke-linecap"] = str(stroke_linecap)
|
||||
if stroke_linejoin is not None:
|
||||
style["stroke-linejoin"] = str(stroke_linejoin)
|
||||
return style
|
||||
|
||||
|
||||
def _read_batch_items(input_path: str) -> list[object]:
|
||||
"""Read one JSON array from a path or stdin."""
|
||||
try:
|
||||
raw = (
|
||||
sys.stdin.read()
|
||||
if input_path == "-"
|
||||
else Path(input_path).read_text(encoding="utf-8")
|
||||
)
|
||||
except OSError as exc:
|
||||
raise ValueError(f"Cannot read batch input {input_path!r}: {exc}") from exc
|
||||
try:
|
||||
payload = json.loads(raw)
|
||||
except json.JSONDecodeError as exc:
|
||||
raise ValueError(
|
||||
f"Invalid batch JSON at line {exc.lineno}, column {exc.colno}: {exc.msg}"
|
||||
) from exc
|
||||
if not isinstance(payload, list) or not payload:
|
||||
raise ValueError("Batch input must be a non-empty JSON array")
|
||||
return payload
|
||||
|
||||
|
||||
def _render_batch_items(items: Sequence[object]) -> list[str]:
|
||||
"""Validate every batch item, then return all fragments together."""
|
||||
fragments: list[str] = []
|
||||
element_ids = set()
|
||||
for index, raw_item in enumerate(items):
|
||||
label = f"items[{index}]"
|
||||
if not isinstance(raw_item, dict):
|
||||
raise ValueError(f"{label} must be a JSON object")
|
||||
unknown = sorted(set(raw_item) - _BATCH_ITEM_FIELDS)
|
||||
if unknown:
|
||||
supported = ", ".join(sorted(_BATCH_ITEM_FIELDS))
|
||||
raise ValueError(
|
||||
f"{label} has unsupported fields: {', '.join(unknown)}; "
|
||||
f"supported fields: {supported}"
|
||||
)
|
||||
missing = [
|
||||
name for name in ("preset", "id", "frame")
|
||||
if name not in raw_item
|
||||
]
|
||||
if missing:
|
||||
raise ValueError(f"{label} is missing: {', '.join(missing)}")
|
||||
|
||||
element_id = str(raw_item["id"])
|
||||
if element_id in element_ids:
|
||||
raise ValueError(f"{label} duplicates SVG element id {element_id!r}")
|
||||
element_ids.add(element_id)
|
||||
frame = raw_item["frame"]
|
||||
if not isinstance(frame, list) or len(frame) != 4:
|
||||
raise ValueError(f"{label}.frame must be a four-number JSON array")
|
||||
adjustments = raw_item.get("adjustments", {})
|
||||
if not isinstance(adjustments, dict):
|
||||
raise ValueError(f"{label}.adjustments must be a JSON object")
|
||||
|
||||
try:
|
||||
style = _style_from_values(
|
||||
fill=raw_item.get("fill", "none"),
|
||||
fill_opacity=raw_item.get("fill_opacity"),
|
||||
stroke=raw_item.get("stroke", "none"),
|
||||
stroke_width=raw_item.get("stroke_width"),
|
||||
stroke_opacity=raw_item.get("stroke_opacity"),
|
||||
stroke_linecap=raw_item.get("stroke_linecap"),
|
||||
stroke_linejoin=raw_item.get("stroke_linejoin"),
|
||||
)
|
||||
fragment = render_preset_shape_fragment(
|
||||
str(raw_item["preset"]),
|
||||
tuple(frame),
|
||||
adjustments=adjustments,
|
||||
object_kind=str(raw_item.get("object_kind", "shape")),
|
||||
element_id=element_id,
|
||||
name=(
|
||||
str(raw_item["name"])
|
||||
if raw_item.get("name") is not None
|
||||
else None
|
||||
),
|
||||
style=style,
|
||||
filter_id=(
|
||||
str(raw_item["filter_id"])
|
||||
if raw_item.get("filter_id") is not None
|
||||
else None
|
||||
),
|
||||
)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError(f"{label}: {exc}") from exc
|
||||
fragments.append(fragment)
|
||||
return fragments
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
||||
+93
-110
@@ -16,7 +16,7 @@
|
||||
"max_tokens": 555000
|
||||
},
|
||||
"file_budgets": {
|
||||
"AGENTS.md": 2750,
|
||||
"AGENTS.md": 3250,
|
||||
"skills/ppt-master/SKILL.md": 1250,
|
||||
"skills/ppt-master/references/executor-base.md": 12000,
|
||||
"skills/ppt-master/references/executor-structured.md": 5500,
|
||||
@@ -154,7 +154,7 @@
|
||||
"max_tokens": 14000
|
||||
},
|
||||
"route.generate.planning": {
|
||||
"description": "Generate-PPTX planning through Strategist, including reference-first whole-document authoring, the three compact decision indexes, and a conservative audit envelope for only the exact custom bases selected after those indexes; schemas and optional scaffolds are tool-consumed.",
|
||||
"description": "Generate-PPTX planning through Strategist, including the fixed capability-decision batch, complete compact Chart/Table registries, and a conservative audit envelope for only the exact custom bases selected afterward; schemas and optional scaffolds are tool-consumed. Ceiling raised after BUDGET_LOAD_SET reported 116384 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"bootstrap.routing"
|
||||
@@ -164,6 +164,9 @@
|
||||
"skills/ppt-master/references/artifact-ownership.md",
|
||||
"skills/ppt-master/references/strategist.md",
|
||||
"skills/ppt-master/references/strategist-image.md",
|
||||
"skills/ppt-master/references/canvas-formats.md",
|
||||
"skills/ppt-master/references/image-layout-spec.md",
|
||||
"skills/ppt-master/references/image-layout-patterns.md",
|
||||
"skills/ppt-master/templates/design_spec_reference.md",
|
||||
"skills/ppt-master/templates/spec_lock_reference.md",
|
||||
"skills/ppt-master/references/modes/_index.md",
|
||||
@@ -171,6 +174,8 @@
|
||||
"skills/ppt-master/references/image-renderings/_index.md",
|
||||
"skills/ppt-master/scripts/docs/confirm_ui.md",
|
||||
"skills/ppt-master/templates/icons/README.md",
|
||||
"skills/ppt-master/templates/charts/charts_index.json",
|
||||
"skills/ppt-master/templates/tables/tables_index.json",
|
||||
{
|
||||
"glob": "skills/ppt-master/references/modes/*.md",
|
||||
"exclude": [
|
||||
@@ -199,10 +204,10 @@
|
||||
"registry": "image-renderings"
|
||||
}
|
||||
],
|
||||
"max_tokens": 110000
|
||||
"max_tokens": 130000
|
||||
},
|
||||
"route.generate.quick-generate": {
|
||||
"description": "Self-contained one-pass Generate profile with source intake, the three compact decision indexes, a conservative audit envelope for only the resolved preset or exact custom bases, conditional resource preparation, and complete flat SVG visual-construction authorities.",
|
||||
"description": "Self-contained one-pass Generate profile with source intake, the fixed planning-capability batch, a conservative audit envelope for only the resolved preset or exact custom bases, conditional resource preparation, and complete flat SVG visual-construction authorities. Ceiling raised after BUDGET_LOAD_SET reported 108610 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"bootstrap.routing"
|
||||
@@ -215,9 +220,15 @@
|
||||
"skills/ppt-master/references/native-shape-authoring.md",
|
||||
"skills/ppt-master/references/semantic-svg.md",
|
||||
"skills/ppt-master/references/executor-structure.md",
|
||||
"skills/ppt-master/references/canvas-formats.md",
|
||||
"skills/ppt-master/references/image-layout-spec.md",
|
||||
"skills/ppt-master/references/image-layout-patterns.md",
|
||||
"skills/ppt-master/references/modes/_index.md",
|
||||
"skills/ppt-master/references/visual-styles/_index.md",
|
||||
"skills/ppt-master/references/image-renderings/_index.md",
|
||||
"skills/ppt-master/templates/icons/README.md",
|
||||
"skills/ppt-master/templates/charts/charts_index.json",
|
||||
"skills/ppt-master/templates/tables/tables_index.json",
|
||||
{
|
||||
"glob": "skills/ppt-master/references/modes/*.md",
|
||||
"exclude": [
|
||||
@@ -246,17 +257,17 @@
|
||||
"registry": "image-renderings"
|
||||
}
|
||||
],
|
||||
"max_tokens": 105000
|
||||
"max_tokens": 120000
|
||||
},
|
||||
"route.generate.quick-generate.beautify": {
|
||||
"description": "Quick Generate with the shared strict 1:1 Beautify profile.",
|
||||
"description": "Quick Generate with the shared strict 1:1 Beautify profile. Ceiling raised after BUDGET_LOAD_SET reported 116355 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
"profile.generate.beautify-pptx"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 115000
|
||||
"max_tokens": 130000
|
||||
},
|
||||
"route.generate.quick-generate.image-to-pptx": {
|
||||
"description": "Codex-supported Quick-only Image to PPTX with registered reference-image layers and shared plates.",
|
||||
@@ -269,10 +280,10 @@
|
||||
"skills/ppt-master/references/image-base.md",
|
||||
"skills/ppt-master/references/image-generator.md"
|
||||
],
|
||||
"max_tokens": 130000
|
||||
"max_tokens": 145000
|
||||
},
|
||||
"route.generate.quick-generate.video-design": {
|
||||
"description": "Quick Generate with conditional video-delivery design, frozen-script notes, custom animation, and narration/audio delivery.",
|
||||
"description": "Quick Generate with conditional video-delivery design, frozen-script notes, custom animation, and narration/audio delivery. Ceiling raised after BUDGET_LOAD_SET reported 154620 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
@@ -282,71 +293,69 @@
|
||||
"stage.shared.generate-audio"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 140000
|
||||
"max_tokens": 175000
|
||||
},
|
||||
"route.generate.quick-generate.template-fusion": {
|
||||
"description": "Quick Generate with the maximum Brand, Style, Layout, and Deck exact-root fusion loaded for flat authoring.",
|
||||
"description": "Quick Generate with the maximum Brand, Style, Layout, and Deck exact-root fusion loaded for flat authoring. Ceiling raised after BUDGET_LOAD_SET reported 125689 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
"stage.generate.template.fusion-brand-style-layout-deck"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 115000
|
||||
"max_tokens": 140000
|
||||
},
|
||||
"route.generate.quick-generate.topic-research": {
|
||||
"description": "Quick Generate with gap-targeted factual research before direct resource preparation and SVG authoring.",
|
||||
"description": "Quick Generate with gap-targeted factual research before direct resource preparation and SVG authoring. Ceiling raised after BUDGET_LOAD_SET reported 111104 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
"stage.generate.topic-research"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 105000
|
||||
"max_tokens": 125000
|
||||
},
|
||||
"route.generate.quick-generate.icon": {
|
||||
"description": "Quick Generate with project-local bundled icon selection and synchronization.",
|
||||
"description": "Quick Generate with project-local bundled icon selection and synchronization; the icon capability contract is already in the fixed planning context. Ceiling raised after BUDGET_LOAD_SET reported 108610 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate"
|
||||
],
|
||||
"files": [
|
||||
"skills/ppt-master/templates/icons/README.md"
|
||||
],
|
||||
"max_tokens": 105000
|
||||
"files": [],
|
||||
"max_tokens": 120000
|
||||
},
|
||||
"route.generate.quick-generate.in-hand-image": {
|
||||
"description": "Quick Generate with supplied, extracted, or placeholder image resources prepared before SVG authoring.",
|
||||
"description": "Quick Generate with supplied, extracted, or placeholder image resources prepared before SVG authoring. Ceiling raised after BUDGET_LOAD_SET reported 113046 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
"stage.generate.executor.image"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 110000
|
||||
"max_tokens": 125000
|
||||
},
|
||||
"route.generate.quick-generate.formula": {
|
||||
"description": "Quick Generate with direct PowerPoint-native formula marker authoring.",
|
||||
"description": "Quick Generate with direct PowerPoint-native formula marker authoring. Ceiling raised after BUDGET_LOAD_SET reported 110614 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
"stage.generate.executor.formula"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 110000
|
||||
"max_tokens": 125000
|
||||
},
|
||||
"route.generate.quick-generate.hyperlink": {
|
||||
"description": "Quick Generate with direct PowerPoint-native external and same-deck hyperlink authoring.",
|
||||
"description": "Quick Generate with direct PowerPoint-native external and same-deck hyperlink authoring. Ceiling raised after BUDGET_LOAD_SET reported 110212 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
"stage.generate.executor.hyperlink"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 110000
|
||||
"max_tokens": 125000
|
||||
},
|
||||
"route.generate.quick-generate.ai-two-types": {
|
||||
"description": "Quick Generate with AI resource preparation, representative rendering inputs, and two local image types.",
|
||||
"description": "Quick Generate with AI resource preparation, representative rendering inputs, and two local image types. Ceiling raised after BUDGET_LOAD_SET reported 140175 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
@@ -354,7 +363,7 @@
|
||||
"stage.generate.executor.image"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 135000
|
||||
"max_tokens": 155000
|
||||
},
|
||||
"route.generate.quick-generate.web-image": {
|
||||
"description": "Quick Generate with web resource preparation, provenance, attribution, and image execution. Ceiling raised after BUDGET_LOAD_SET reported 115146 tokens.",
|
||||
@@ -369,7 +378,7 @@
|
||||
"max_tokens": 130000
|
||||
},
|
||||
"route.generate.quick-generate.visualization": {
|
||||
"description": "Quick Generate with bounded Chart/Table recall, their data-object branches, optional native-data metadata, and chart-coordinate verification before the final checker; the fixed Quick context already carries Shape Composition Grammar.",
|
||||
"description": "Quick Generate with complete Chart/Table registries already in the fixed planning context, their data-object branches, optional native-data metadata, and chart-coordinate verification before the final checker; the fixed Quick context already carries Shape Composition Grammar. Ceiling raised after BUDGET_LOAD_SET reported 126726 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.quick-generate",
|
||||
@@ -379,38 +388,35 @@
|
||||
"stage.generate.executor.native-data",
|
||||
"stage.generate.verify-charts"
|
||||
],
|
||||
"files": [
|
||||
"skills/ppt-master/scripts/docs/visualization-recall.md"
|
||||
],
|
||||
"max_tokens": 120000
|
||||
"files": [],
|
||||
"max_tokens": 140000
|
||||
},
|
||||
"route.generate.planning-image": {
|
||||
"description": "Generate-PPTX planning context after a non-none image source is proposed or confirmed, including the compact layout math and vocabulary.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning",
|
||||
"stage.generate.strategist.image"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 115000
|
||||
},
|
||||
"route.generate.planning-formula": {
|
||||
"description": "Formula-bearing planning context; Strategist records exact mathematics without loading image-layout or formula-rendering resources.",
|
||||
"description": "Generate-PPTX planning context after a non-none image source is proposed or confirmed; image decision and layout authorities are already in the fixed planning context. Ceiling raised after BUDGET_LOAD_SET reported 116384 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 110000
|
||||
"max_tokens": 130000
|
||||
},
|
||||
"route.generate.planning-formula": {
|
||||
"description": "Formula-bearing planning context; Strategist records exact mathematics while using the fixed planning-capability context. Ceiling raised after BUDGET_LOAD_SET reported 116384 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 130000
|
||||
},
|
||||
"route.generate.planning-ai": {
|
||||
"description": "Generate-PPTX planning after AI imagery is confirmed, adding image-layout and resource-planning authorities to the rendering index and already-selected rendering bases.",
|
||||
"description": "Generate-PPTX planning after AI imagery is confirmed; the fixed context already carries image-layout and resource-planning decision authorities. Ceiling raised after BUDGET_LOAD_SET reported 116384 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-image"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 115000
|
||||
"max_tokens": 130000
|
||||
},
|
||||
"stage.generate.apply-template-workspace": {
|
||||
"description": "Post-Stage-1 Default or Quick exact-root workspace validation, installation, and fusion framework.",
|
||||
@@ -536,7 +542,7 @@
|
||||
"max_tokens": 19000
|
||||
},
|
||||
"route.generate.flat-no-image": {
|
||||
"description": "Default fixed Generate-PPTX context with no image-acquisition role.",
|
||||
"description": "Default fixed Generate-PPTX context with no image-acquisition role. Ceiling raised after BUDGET_LOAD_SET reported 177085 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning",
|
||||
@@ -544,10 +550,10 @@
|
||||
"stage.generate.executor.notes"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 165000
|
||||
"max_tokens": 195000
|
||||
},
|
||||
"route.generate.flat-formula": {
|
||||
"description": "Default flat Generate-PPTX context with direct PowerPoint-native formula marker authoring and no image branch.",
|
||||
"description": "Default flat Generate-PPTX context with direct PowerPoint-native formula marker authoring and no image branch. Ceiling raised after BUDGET_LOAD_SET reported 179089 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-formula",
|
||||
@@ -556,10 +562,10 @@
|
||||
"stage.generate.executor.notes"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 170000
|
||||
"max_tokens": 200000
|
||||
},
|
||||
"route.generate.flat-hyperlink": {
|
||||
"description": "Default flat Generate-PPTX context with PowerPoint-native external and same-deck hyperlink authoring.",
|
||||
"description": "Default flat Generate-PPTX context with PowerPoint-native external and same-deck hyperlink authoring. Ceiling raised after BUDGET_LOAD_SET reported 178236 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning",
|
||||
@@ -568,10 +574,10 @@
|
||||
"stage.generate.executor.notes"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 170000
|
||||
"max_tokens": 200000
|
||||
},
|
||||
"route.generate.flat-ai-two-types": {
|
||||
"description": "Generate-PPTX context with AI images, the selected preset or exact custom rendering bases, and two local types.",
|
||||
"description": "Generate-PPTX context with AI images, the selected preset or exact custom rendering bases, and two local types. Ceiling raised after BUDGET_LOAD_SET reported 208650 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-ai",
|
||||
@@ -581,10 +587,10 @@
|
||||
"stage.generate.image.ai-two-types"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 205000
|
||||
"max_tokens": 230000
|
||||
},
|
||||
"route.generate.flat-in-hand-image": {
|
||||
"description": "Generate-PPTX context with provided or placeholder images and no acquisition role.",
|
||||
"description": "Generate-PPTX context with provided or placeholder images and no acquisition role. Ceiling raised after BUDGET_LOAD_SET reported 181521 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-image",
|
||||
@@ -593,10 +599,10 @@
|
||||
"stage.generate.executor.notes"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 180000
|
||||
"max_tokens": 200000
|
||||
},
|
||||
"route.generate.flat-web-image": {
|
||||
"description": "Generate-PPTX context with web image acquisition.",
|
||||
"description": "Generate-PPTX context with web image acquisition. Ceiling raised after BUDGET_LOAD_SET reported 192432 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-image",
|
||||
@@ -607,7 +613,7 @@
|
||||
"stage.generate.image.web-review"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 190000
|
||||
"max_tokens": 215000
|
||||
},
|
||||
"route.enhance-native-pptx.audio": {
|
||||
"description": "Enhance Native PPTX with the shared narration-audio stage.",
|
||||
@@ -620,17 +626,17 @@
|
||||
"max_tokens": 21000
|
||||
},
|
||||
"route.generate.beautify-flat-no-image": {
|
||||
"description": "Generate-PPTX 1:1 beautify profile on the flat no-image path.",
|
||||
"description": "Generate-PPTX 1:1 beautify profile on the flat no-image path. Ceiling raised after BUDGET_LOAD_SET reported 184830 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.flat-no-image",
|
||||
"profile.generate.beautify-pptx"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 175000
|
||||
"max_tokens": 205000
|
||||
},
|
||||
"route.generate.flat-no-image.video-design": {
|
||||
"description": "Default flat Generate-PPTX path with conditional video-delivery design, custom animation, and narration/audio delivery.",
|
||||
"description": "Default flat Generate-PPTX path with conditional video-delivery design, custom animation, and narration/audio delivery. Ceiling raised after BUDGET_LOAD_SET reported 222116 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.flat-no-image",
|
||||
@@ -639,25 +645,24 @@
|
||||
"stage.shared.generate-audio"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 215000
|
||||
"max_tokens": 245000
|
||||
},
|
||||
"route.generate.flat-no-image-visualization": {
|
||||
"description": "Default flat Generate-PPTX path with visualization-reference consumption, all three information-model branches, optional native-data replacement, and chart verification.",
|
||||
"description": "Default flat Generate-PPTX path with visualization-reference consumption, all three information-model branches from the fixed Executor core, optional native-data replacement, and chart verification. Ceiling raised after BUDGET_LOAD_SET reported 194079 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.flat-no-image",
|
||||
"stage.generate.executor.visualization",
|
||||
"stage.generate.executor.chart",
|
||||
"stage.generate.executor.structure",
|
||||
"stage.generate.executor.table",
|
||||
"stage.generate.executor.native-data",
|
||||
"stage.generate.verify-charts"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 185000
|
||||
"max_tokens": 215000
|
||||
},
|
||||
"route.generate.brand-flat-no-image": {
|
||||
"description": "Brand-preset flat Generate-PPTX path without image acquisition.",
|
||||
"description": "Brand-preset flat Generate-PPTX path without image acquisition. Ceiling raised after BUDGET_LOAD_SET reported 187138 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-template",
|
||||
@@ -666,10 +671,10 @@
|
||||
"stage.generate.template.brand"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 180000
|
||||
"max_tokens": 210000
|
||||
},
|
||||
"route.generate.style-flat-no-image": {
|
||||
"description": "Style-workspace flat Generate-PPTX path without image acquisition.",
|
||||
"description": "Style-workspace flat Generate-PPTX path without image acquisition. Ceiling raised after BUDGET_LOAD_SET reported 188870 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-template",
|
||||
@@ -678,10 +683,10 @@
|
||||
"stage.generate.template.style"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 180000
|
||||
"max_tokens": 210000
|
||||
},
|
||||
"route.generate.deck-structured-no-image": {
|
||||
"description": "Deck-preset structured Generate-PPTX path without image acquisition.",
|
||||
"description": "Deck-preset structured Generate-PPTX path without image acquisition. Ceiling raised after BUDGET_LOAD_SET reported 197186 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-template",
|
||||
@@ -690,10 +695,10 @@
|
||||
"stage.generate.template.deck"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 190000
|
||||
"max_tokens": 220000
|
||||
},
|
||||
"route.generate.layout-structured-no-image": {
|
||||
"description": "Layout-preset structured Generate-PPTX path without image acquisition.",
|
||||
"description": "Layout-preset structured Generate-PPTX path without image acquisition. Ceiling raised after BUDGET_LOAD_SET reported 197888 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning-template",
|
||||
@@ -702,20 +707,20 @@
|
||||
"stage.generate.template.layout"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 190000
|
||||
"max_tokens": 220000
|
||||
},
|
||||
"route.generate.topic-only-flat-no-image": {
|
||||
"description": "Topic research followed by the default flat no-image Generate-PPTX path.",
|
||||
"description": "Topic research followed by the default flat no-image Generate-PPTX path. Ceiling raised after BUDGET_LOAD_SET reported 179579 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"stage.generate.topic-research",
|
||||
"route.generate.flat-no-image"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 170000
|
||||
"max_tokens": 200000
|
||||
},
|
||||
"stage.generate.executor.flat": {
|
||||
"description": "Incremental flat Executor core with complete visual-construction authorities, the compact mode/style indexes, and a conservative audit envelope for only the locked preset or exact custom references.",
|
||||
"description": "Incremental flat Executor core with complete visual-construction authorities and a conservative audit envelope for only the locked preset or exact custom references; selection indexes remain planning-only.",
|
||||
"scope": "incremental",
|
||||
"files": [
|
||||
"skills/ppt-master/references/executor-base.md",
|
||||
@@ -723,8 +728,7 @@
|
||||
"skills/ppt-master/references/svg-effects.md",
|
||||
"skills/ppt-master/references/native-shape-authoring.md",
|
||||
"skills/ppt-master/references/semantic-svg.md",
|
||||
"skills/ppt-master/references/modes/_index.md",
|
||||
"skills/ppt-master/references/visual-styles/_index.md",
|
||||
"skills/ppt-master/references/executor-structure.md",
|
||||
{
|
||||
"glob": "skills/ppt-master/references/modes/*.md",
|
||||
"exclude": [
|
||||
@@ -972,22 +976,22 @@
|
||||
"max_tokens": 1000
|
||||
},
|
||||
"stage.create-template.authored-preset": {
|
||||
"description": "Conditional native preset and Boolean shape authoring reference for Create Layout/Create Deck.",
|
||||
"description": "Conditional native preset and Boolean shape authoring reference for Create Layout/Create Deck. Ceiling raised after BUDGET_LOAD_SET reported 6618 tokens.",
|
||||
"scope": "incremental",
|
||||
"files": [
|
||||
"skills/ppt-master/references/native-shape-authoring.md"
|
||||
],
|
||||
"max_tokens": 6500
|
||||
"max_tokens": 7500
|
||||
},
|
||||
"route.generate.planning-template": {
|
||||
"description": "Generate-PPTX planning context after an explicit template workspace is installed.",
|
||||
"description": "Generate-PPTX planning context after an explicit template workspace is installed. Ceiling raised after BUDGET_LOAD_SET reported 119170 tokens.",
|
||||
"scope": "cumulative",
|
||||
"include": [
|
||||
"route.generate.planning",
|
||||
"stage.generate.strategist.template"
|
||||
],
|
||||
"files": [],
|
||||
"max_tokens": 110000
|
||||
"max_tokens": 135000
|
||||
},
|
||||
"route.generate.planning-template-ai": {
|
||||
"description": "Explicit template workspace plus confirmed AI-image planning.",
|
||||
@@ -1015,14 +1019,6 @@
|
||||
],
|
||||
"max_tokens": 1250
|
||||
},
|
||||
"stage.generate.executor.structure": {
|
||||
"description": "Conditional page-local qualitative-topology construction rules.",
|
||||
"scope": "incremental",
|
||||
"files": [
|
||||
"skills/ppt-master/references/executor-structure.md"
|
||||
],
|
||||
"max_tokens": 1500
|
||||
},
|
||||
"stage.generate.executor.table": {
|
||||
"description": "Conditional semantic cell-grid construction rules.",
|
||||
"scope": "incremental",
|
||||
@@ -1031,15 +1027,6 @@
|
||||
],
|
||||
"max_tokens": 1000
|
||||
},
|
||||
"stage.generate.strategist.image": {
|
||||
"description": "Conditional Strategist image layout math and compact composition vocabulary; the rendering decision core is already in base planning.",
|
||||
"scope": "incremental",
|
||||
"files": [
|
||||
"skills/ppt-master/references/image-layout-spec.md",
|
||||
"skills/ppt-master/references/image-layout-patterns.md"
|
||||
],
|
||||
"max_tokens": 11000
|
||||
},
|
||||
"stage.generate.strategist.template": {
|
||||
"description": "Conditional Strategist module for an explicitly installed template workspace.",
|
||||
"scope": "incremental",
|
||||
@@ -1103,12 +1090,12 @@
|
||||
"max_tokens": 1000
|
||||
},
|
||||
"stage.generate.executor.native-shape": {
|
||||
"description": "Stock PowerPoint shape selection and Boolean materialization authority, always included in Generate Executor contexts.",
|
||||
"description": "Stock PowerPoint shape selection and Boolean materialization authority, always included in Generate Executor contexts. Ceiling raised after BUDGET_LOAD_SET reported 6618 tokens.",
|
||||
"scope": "incremental",
|
||||
"files": [
|
||||
"skills/ppt-master/references/native-shape-authoring.md"
|
||||
],
|
||||
"max_tokens": 6500
|
||||
"max_tokens": 7500
|
||||
},
|
||||
"stage.shared.svg-effects": {
|
||||
"description": "Advanced SVG paint, effects, transforms, and geometry authority, always included in Generate Executor contexts and conditionally loaded by other SVG-authoring routes.",
|
||||
@@ -2100,7 +2087,11 @@
|
||||
},
|
||||
{
|
||||
"glob": "skills/ppt-master/scripts/docs/chart-recall.md",
|
||||
"reason": "Legacy compatibility note; current generation loads visualization-recall.md."
|
||||
"reason": "Legacy compatibility note; current planning reads the live Chart/Table registries directly."
|
||||
},
|
||||
{
|
||||
"glob": "skills/ppt-master/scripts/docs/visualization-recall.md",
|
||||
"reason": "Optional diagnostic-tool documentation; runtime planning reads the complete live registries directly and uses only canonical validation."
|
||||
},
|
||||
{
|
||||
"glob": "skills/ppt-master/scripts/pptx_shapes/data/NOTICE.md",
|
||||
@@ -2126,14 +2117,6 @@
|
||||
"glob": "skills/ppt-master/templates/scaffolds/*.md",
|
||||
"reason": "Optional versioned tool-copy assets; normal Generate authoring reads the reference guides and writes complete artifacts from scratch."
|
||||
},
|
||||
{
|
||||
"glob": "skills/ppt-master/templates/charts/charts_index.json",
|
||||
"reason": "Machine-consumed chart-family registry; Strategist receives only bounded visualization-recall candidates."
|
||||
},
|
||||
{
|
||||
"glob": "skills/ppt-master/templates/tables/tables_index.json",
|
||||
"reason": "Machine-consumed table-family registry; Strategist receives only bounded visualization-recall candidates."
|
||||
},
|
||||
{
|
||||
"glob": "skills/ppt-master/templates/schemas/*.json",
|
||||
"reason": "Machine-consumed validation schemas; they are not loaded into model runtime context."
|
||||
|
||||
@@ -1177,6 +1177,7 @@ class SVGQualityChecker:
|
||||
expected_viewbox_label=expected_viewbox_label,
|
||||
)
|
||||
self._check_legacy_pptx_attributes(root, svg_path, result)
|
||||
self._record_carrier_receipt(root, result)
|
||||
|
||||
# 1a. Validate exact importer transport before compatible
|
||||
# inline geometry is materialized on the shared tree.
|
||||
@@ -1438,6 +1439,208 @@ class SVGQualityChecker:
|
||||
)
|
||||
)
|
||||
|
||||
def _record_carrier_receipt(
|
||||
self,
|
||||
root: ET.Element,
|
||||
result: Dict,
|
||||
) -> None:
|
||||
"""Record factual visible-carrier use without grading the design."""
|
||||
parent_by_id = {
|
||||
id(child): parent
|
||||
for parent in root.iter()
|
||||
for child in list(parent)
|
||||
}
|
||||
geometry_tags = (
|
||||
'rect',
|
||||
'circle',
|
||||
'ellipse',
|
||||
'line',
|
||||
'polyline',
|
||||
'polygon',
|
||||
'path',
|
||||
)
|
||||
geometry_counts = Counter({tag: 0 for tag in geometry_tags})
|
||||
preset_names: Counter[str] = Counter()
|
||||
native_objects = Counter({
|
||||
'chart': 0,
|
||||
'table': 0,
|
||||
'formula_block': 0,
|
||||
'formula_inline': 0,
|
||||
'other': 0,
|
||||
})
|
||||
marker_counts = Counter({'start': 0, 'mid': 0, 'end': 0})
|
||||
text_count = 0
|
||||
icon_count = 0
|
||||
page_frame_geometry = 0
|
||||
|
||||
for element in root.iter():
|
||||
if (
|
||||
element is root
|
||||
or self._is_hidden_element(element, parent_by_id)
|
||||
or self._has_non_visual_ancestor(element, root, parent_by_id)
|
||||
or self._has_zero_opacity(element, parent_by_id)
|
||||
):
|
||||
continue
|
||||
|
||||
tag = _local_name(element)
|
||||
if tag == 'text':
|
||||
text_count += 1
|
||||
elif tag == 'use' and element.get('data-icon') is not None:
|
||||
icon_count += 1
|
||||
|
||||
if element.get(_INLINE_FORMULA_ATTR) is not None:
|
||||
native_objects['formula_inline'] += 1
|
||||
replacement_kind = self._carrier_native_replacement_kind(element)
|
||||
if replacement_kind:
|
||||
key = (
|
||||
'formula_block'
|
||||
if replacement_kind == 'formula'
|
||||
else replacement_kind
|
||||
)
|
||||
native_objects[key if key in native_objects else 'other'] += 1
|
||||
|
||||
preset = (element.get('data-pptx-prst') or '').strip()
|
||||
if preset:
|
||||
preset_names[preset] += 1
|
||||
if self._carrier_page_frame_role(element, root, parent_by_id):
|
||||
page_frame_geometry += 1
|
||||
continue
|
||||
if tag not in geometry_counts or self._has_preset_ancestor(
|
||||
element,
|
||||
root,
|
||||
parent_by_id,
|
||||
):
|
||||
continue
|
||||
|
||||
geometry_counts[tag] += 1
|
||||
if self._carrier_page_frame_role(element, root, parent_by_id):
|
||||
page_frame_geometry += 1
|
||||
style_values = (
|
||||
_parse_inline_style(element.get('style'))
|
||||
if _parse_inline_style is not None
|
||||
else {}
|
||||
)
|
||||
for position in ('start', 'mid', 'end'):
|
||||
raw_marker = (
|
||||
style_values.get(f'marker-{position}')
|
||||
or element.get(f'marker-{position}')
|
||||
or ''
|
||||
).strip().lower()
|
||||
if raw_marker and raw_marker != 'none':
|
||||
marker_counts[position] += 1
|
||||
|
||||
image_receipt = self._carrier_image_receipt(root)
|
||||
result['info']['carrier_receipt'] = {
|
||||
'text_elements': text_count,
|
||||
'images': image_receipt,
|
||||
'icons': icon_count,
|
||||
'geometry': {
|
||||
'svg_elements': dict(geometry_counts),
|
||||
'preset_shapes': sum(preset_names.values()),
|
||||
'preset_names': dict(sorted(preset_names.items())),
|
||||
'page_frame_elements': page_frame_geometry,
|
||||
'marker_uses': dict(marker_counts),
|
||||
},
|
||||
'native_objects': dict(native_objects),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _carrier_native_replacement_kind(element: ET.Element) -> str:
|
||||
"""Return one native replacement kind without turning bad data into a check."""
|
||||
if _native_replacement_kind is not None:
|
||||
try:
|
||||
return (_native_replacement_kind(element) or '').strip().lower()
|
||||
except ValueError:
|
||||
pass
|
||||
return (
|
||||
element.get('data-pptx-replace-with')
|
||||
or element.get('data-pptx-native')
|
||||
or ''
|
||||
).strip().lower()
|
||||
|
||||
@staticmethod
|
||||
def _has_preset_ancestor(
|
||||
element: ET.Element,
|
||||
root: ET.Element,
|
||||
parent_by_id: Dict[int, ET.Element],
|
||||
) -> bool:
|
||||
"""Return whether geometry is only the visible detail of a preset atom."""
|
||||
current = parent_by_id.get(id(element))
|
||||
while current is not None and current is not root:
|
||||
if (current.get('data-pptx-prst') or '').strip():
|
||||
return True
|
||||
current = parent_by_id.get(id(current))
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _carrier_page_frame_role(
|
||||
element: ET.Element,
|
||||
root: ET.Element,
|
||||
parent_by_id: Dict[int, ET.Element],
|
||||
) -> bool:
|
||||
"""Return whether an element belongs to declared page framing."""
|
||||
current: ET.Element | None = element
|
||||
while current is not None:
|
||||
role = (current.get('data-pptx-role') or '').strip().lower()
|
||||
if role in {'background', 'decoration'}:
|
||||
return True
|
||||
if current is root:
|
||||
break
|
||||
current = parent_by_id.get(id(current))
|
||||
return False
|
||||
|
||||
def _carrier_image_receipt(self, root: ET.Element) -> Dict:
|
||||
"""Summarize visible image placements and their frame share."""
|
||||
working_root, parent_by_id, images = self._visible_image_elements(root)
|
||||
viewbox = _parse_viewbox_values(working_root.get('viewBox') or '')
|
||||
canvas_area = (
|
||||
abs(viewbox[2] * viewbox[3])
|
||||
if viewbox is not None and viewbox[2] and viewbox[3]
|
||||
else 0.0
|
||||
)
|
||||
frame_shares: List[float] = []
|
||||
filenames = set()
|
||||
|
||||
for image in images:
|
||||
href = image.get('href') or image.get(f'{{{XLINK_NS}}}href') or ''
|
||||
if href.startswith('data:'):
|
||||
filenames.add('(embedded)')
|
||||
elif href:
|
||||
path_name = Path(unquote(urlsplit(href).path)).name
|
||||
filenames.add(path_name or href[:80])
|
||||
|
||||
display_owner = image
|
||||
parent = parent_by_id.get(id(image))
|
||||
if (
|
||||
parent is not None
|
||||
and parent is not working_root
|
||||
and _local_name(parent) == 'svg'
|
||||
):
|
||||
display_owner = parent
|
||||
try:
|
||||
x = float(display_owner.get('x') or '0')
|
||||
y = float(display_owner.get('y') or '0')
|
||||
width = float(display_owner.get('width') or '0')
|
||||
height = float(display_owner.get('height') or '0')
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
if width <= 0 or height <= 0 or canvas_area <= 0:
|
||||
continue
|
||||
transformed = self._transformed_rect_edge_lengths(
|
||||
display_owner,
|
||||
(x, y, width, height),
|
||||
parent_by_id,
|
||||
)
|
||||
if transformed is not None:
|
||||
width, height = transformed
|
||||
frame_shares.append(abs(width * height) / canvas_area)
|
||||
|
||||
return {
|
||||
'placements': len(images),
|
||||
'files': sorted(filenames),
|
||||
'max_frame_share': round(max(frame_shares), 4) if frame_shares else 0.0,
|
||||
}
|
||||
|
||||
def _check_fonts(self, content: str, result: Dict):
|
||||
"""Check font usage.
|
||||
|
||||
@@ -6941,6 +7144,7 @@ class SVGQualityChecker:
|
||||
f" [ERROR] With errors: {self.summary['errors']} ({self._percentage(self.summary['errors'])}%)")
|
||||
|
||||
self._print_provenance_category_summary()
|
||||
self._print_carrier_receipt_summary()
|
||||
|
||||
if self.issue_types:
|
||||
print(f"\nIssue categories:")
|
||||
@@ -6981,6 +7185,119 @@ class SVGQualityChecker:
|
||||
print(f" 4. foreignObject: Use <text> + <tspan> for manual line breaks")
|
||||
print(f" 5. Font issues: use PPT-safe exported typefaces (e.g. Microsoft YaHei / Arial / Consolas)")
|
||||
|
||||
def _carrier_receipt_summary(self) -> Dict:
|
||||
"""Aggregate factual per-page carrier receipts for compact review."""
|
||||
receipts = [
|
||||
result.get('info', {}).get('carrier_receipt')
|
||||
for result in self.results
|
||||
if result.get('info', {}).get('carrier_receipt')
|
||||
]
|
||||
totals = Counter({
|
||||
'text_elements': 0,
|
||||
'image_placements': 0,
|
||||
'icons': 0,
|
||||
'svg_geometry_elements': 0,
|
||||
'preset_shapes': 0,
|
||||
'page_frame_elements': 0,
|
||||
'marker_uses': 0,
|
||||
})
|
||||
pages_with = Counter({
|
||||
'images': 0,
|
||||
'icons': 0,
|
||||
'presets': 0,
|
||||
'charts': 0,
|
||||
'tables': 0,
|
||||
'formulas': 0,
|
||||
})
|
||||
geometry_counts: Counter[str] = Counter()
|
||||
preset_names: Counter[str] = Counter()
|
||||
native_objects: Counter[str] = Counter()
|
||||
image_frame_shares: List[float] = []
|
||||
|
||||
for receipt in receipts:
|
||||
images = receipt['images']
|
||||
geometry = receipt['geometry']
|
||||
native = receipt['native_objects']
|
||||
totals['text_elements'] += receipt['text_elements']
|
||||
totals['image_placements'] += images['placements']
|
||||
totals['icons'] += receipt['icons']
|
||||
totals['preset_shapes'] += geometry['preset_shapes']
|
||||
totals['page_frame_elements'] += geometry['page_frame_elements']
|
||||
totals['marker_uses'] += sum(geometry['marker_uses'].values())
|
||||
geometry_counts.update(geometry['svg_elements'])
|
||||
preset_names.update(geometry['preset_names'])
|
||||
native_objects.update(native)
|
||||
|
||||
if images['placements']:
|
||||
pages_with['images'] += 1
|
||||
image_frame_shares.append(images['max_frame_share'])
|
||||
if receipt['icons']:
|
||||
pages_with['icons'] += 1
|
||||
if geometry['preset_shapes']:
|
||||
pages_with['presets'] += 1
|
||||
if native.get('chart'):
|
||||
pages_with['charts'] += 1
|
||||
if native.get('table'):
|
||||
pages_with['tables'] += 1
|
||||
if native.get('formula_block') or native.get('formula_inline'):
|
||||
pages_with['formulas'] += 1
|
||||
|
||||
totals['svg_geometry_elements'] = sum(geometry_counts.values())
|
||||
frame_share_range = (
|
||||
[round(min(image_frame_shares), 4), round(max(image_frame_shares), 4)]
|
||||
if image_frame_shares
|
||||
else []
|
||||
)
|
||||
return {
|
||||
'scope': 'informational-not-a-quota',
|
||||
'pages': len(receipts),
|
||||
'totals': dict(totals),
|
||||
'pages_with': dict(pages_with),
|
||||
'geometry_elements': dict(sorted(geometry_counts.items())),
|
||||
'preset_names': dict(sorted(preset_names.items())),
|
||||
'native_objects': dict(sorted(native_objects.items())),
|
||||
'image_page_max_frame_share_range': frame_share_range,
|
||||
}
|
||||
|
||||
def _print_carrier_receipt_summary(self) -> None:
|
||||
"""Print a compact actual-use receipt without a score or threshold."""
|
||||
if self.template_mode:
|
||||
return
|
||||
receipt = self._carrier_receipt_summary()
|
||||
if not receipt['pages']:
|
||||
return
|
||||
totals = receipt['totals']
|
||||
native = receipt['native_objects']
|
||||
print("\n[CARRIERS] Actual-use receipt (informational; not a quota)")
|
||||
print(
|
||||
f" Pages: {receipt['pages']} | text: {totals['text_elements']} | "
|
||||
f"images: {totals['image_placements']} | icons: {totals['icons']}"
|
||||
)
|
||||
print(
|
||||
f" Geometry: SVG elements {totals['svg_geometry_elements']} | "
|
||||
f"native presets {totals['preset_shapes']} | "
|
||||
f"page-frame elements {totals['page_frame_elements']} | "
|
||||
f"marker uses {totals['marker_uses']}"
|
||||
)
|
||||
print(
|
||||
f" Native objects: charts {native.get('chart', 0)} | "
|
||||
f"tables {native.get('table', 0)} | formulas "
|
||||
f"{native.get('formula_block', 0) + native.get('formula_inline', 0)}"
|
||||
)
|
||||
presets = receipt['preset_names']
|
||||
preset_text = (
|
||||
', '.join(f'{name} x{count}' for name, count in presets.items())
|
||||
if presets
|
||||
else '(none)'
|
||||
)
|
||||
print(f" Presets: {preset_text}")
|
||||
image_range = receipt['image_page_max_frame_share_range']
|
||||
if image_range:
|
||||
print(
|
||||
" Largest image-frame share on image pages: "
|
||||
f"{image_range[0] * 100:.1f}%–{image_range[1] * 100:.1f}%"
|
||||
)
|
||||
|
||||
def _print_provenance_category_summary(self):
|
||||
"""Print compact JSON-equivalent counts for token-safe gate handling."""
|
||||
categories = self._provenance_categories()
|
||||
@@ -7386,6 +7703,7 @@ class SVGQualityChecker:
|
||||
},
|
||||
},
|
||||
'drift': drift,
|
||||
'carrier_receipt': self._carrier_receipt_summary(),
|
||||
'project_issues': project_issues,
|
||||
'files': self.results,
|
||||
}
|
||||
|
||||
@@ -16,8 +16,11 @@ Master/Layout, page-type, slot, and placeholder contracts belong in
|
||||
form `Pick for ... Skip if ...`. The key matches `<key>.svg`; `meta.total`
|
||||
matches the canonical SVG roster.
|
||||
|
||||
Use [`visualization_recall.py`](../../scripts/visualization_recall.py) for
|
||||
bounded Chart/Table or chart-only recall. New Default planning writes
|
||||
Default Strategist and Quick read this complete compact registry together with
|
||||
the Table registry before planning. They compare every `Pick` / `Skip` rule,
|
||||
then use [`visualization_recall.py`](../../scripts/visualization_recall.py)
|
||||
`validate` to resolve selected canonical references. Its `recall` mode remains
|
||||
an optional diagnostic helper, not the runtime capability gate. Default writes
|
||||
`chart/<key>` to `page_visualizations`; Quick keeps the selected reference in
|
||||
active context. [`chart_recall.py`](../../scripts/chart_recall.py) and bare keys
|
||||
remain legacy compatibility only.
|
||||
|
||||
+8
-15
@@ -113,19 +113,12 @@ Use these exact subsections and field shapes:
|
||||
|
||||
## V. Layout Principles
|
||||
|
||||
### Page Structure
|
||||
### Deck-wide Direction
|
||||
|
||||
- **Header area**: <rule>
|
||||
- **Content area**: <rule>
|
||||
- **Footer area**: <rule>
|
||||
|
||||
### Spacing Specification
|
||||
|
||||
| Element | Current Project |
|
||||
| --- | --- |
|
||||
| Safe margin | <value> |
|
||||
| Content block gap | <value> |
|
||||
| Icon-text gap | <value> |
|
||||
- **Hierarchy direction**: <how attention should move across a typical page>
|
||||
- **Composition tendency**: <non-binding macro direction; no coordinates or authoring method>
|
||||
- **Cross-page continuity**: <what may recur or vary across the roster>
|
||||
- **Spacing posture**: <dense, open, or variable behavior by page rhythm; no fixed gaps>
|
||||
|
||||
## VI. Icon Usage Specification
|
||||
|
||||
@@ -196,7 +189,7 @@ Write one ordered Slide block per page. Slide count and order must equal §I `Pa
|
||||
#### Slide 01 - <page name>
|
||||
|
||||
- **Audience move**: <audience state before → after>
|
||||
- **Layout**: <composition; include the chosen prototype when template-active>
|
||||
- **Layout**: <non-binding macro composition, hierarchy, and visual focus; include the chosen prototype when template-active>
|
||||
- **Title**: <preferred page title>
|
||||
- **Core message**: <one governing assertion>
|
||||
- **Content**: <complete intended on-slide content and hierarchy>
|
||||
@@ -227,9 +220,9 @@ empty or `none` placeholder:
|
||||
- **Motion suggestion**: <communication job plus desired page-entry or reveal relationship/order>
|
||||
```
|
||||
|
||||
Add `Mathematical content` whenever a Slide needs a mathematical expression preserved exactly. Store the expression body as valid LaTeX without `$...$`, `$$...$$`, `\(...\)`, or `\[...\]` source delimiters; the field does not classify inline versus structural use. This is content authority for [`native-formula.md`](../references/native-formula.md), not a formula policy, marker, or implementation request; Executor chooses ordinary text, inline native math, or block native math. Add `Visualization` / `Images` when a Slide consumes §VII/§VIII or uses a page-local visual model. Name every value-driven geometry, qualitative relationship, cell grid, and child visual here; only independent Chart/Table entries use object keys. Describe qualitative order, linkage, hierarchy, grouping, contrast, overlap, and reading path freely—not as a model name or grammar enum. §IX may choose a custom Chart/Table fallback. Native construction creates no Design Spec field; Executor discovers and selects it independently during realization. Add `Motion suggestion` whenever transition/reveal advice strengthens communication, regardless of the Custom Animations outcome; state purpose and semantic order/relationship, not registry keys, options, timing, ids, or coverage. The suggestion never activates animation execution by itself, creates content, or binds implementation. Describe required visible image states in `Layout` / `Images` only for an explicit motion requirement or an enabled Custom Animations outcome. Add keyed `Native-ready` only for independent data charts or pure text-grid tables, `Fact IDs` for sourced claims, and `Data class: scenario` for invented demo values. Except on preservation paths, `Cover impact` carries a binding hook and adaptable composition; apply the same split to `Closing impact` only when the deck genuinely resolves. Roster/order/content stay authoritative. §VIII image layout is non-empty free prose with optional library ids; §VII Chart/Table rows are references. Executor owns geometry, hierarchy, treatment, and sparse local garnish.
|
||||
Add `Mathematical content` whenever a Slide needs a mathematical expression preserved exactly. Store the expression body as valid LaTeX without `$...$`, `$$...$$`, `\(...\)`, or `\[...\]` source delimiters; the field does not classify inline versus structural use. This is content authority for [`native-formula.md`](../references/native-formula.md), not a formula policy, marker, or implementation request; Executor chooses ordinary text, inline native math, or block native math. Add `Visualization` / `Images` when a Slide consumes §VII/§VIII or uses a page-local visual model. Name every value-driven geometry, qualitative relationship, cell grid, and child visual here; only independent Chart/Table entries use object keys. Describe qualitative order, linkage, hierarchy, grouping, contrast, overlap, and reading path freely—not as a model name or grammar enum. §IX may choose a custom Chart/Table fallback. Native construction creates no Design Spec field; Executor discovers and selects it independently during realization. Add `Motion suggestion` whenever transition/reveal advice strengthens communication, regardless of the Custom Animations outcome; state purpose and semantic order/relationship, not registry keys, options, timing, ids, or coverage. The suggestion never activates animation execution by itself, creates content, or binds implementation. Describe required visible image states in `Layout` / `Images` only for an explicit motion requirement or an enabled Custom Animations outcome. Add keyed `Native-ready` only for independent data charts or pure text-grid tables, `Fact IDs` for sourced claims, and `Data class: scenario` for invented demo values. Except on preservation paths, `Cover impact` carries a binding hook and adaptable composition; apply the same split to `Closing impact` only when the deck genuinely resolves. Roster/order/content stay authoritative. §V/§IX layout, cover/closing composition, capability, motif, §VIII image-layout, and §VII Chart/Table directions remain References unless an explicit user/template/resource constraint promotes the named property; Executor considers each and may adopt, adapt, or decline it without upstream repair. Executor owns final geometry, hierarchy, treatment, and sparse local garnish.
|
||||
|
||||
For free-design pages, describe `Layout` through relationships, hierarchy, regions, and column spans; do not prescribe element-level `x`, `y`, `width`, or `height` or duplicate the global geometry in §II/§V. Exact coordinates belong to Executor SVG authoring. Preserve literal geometry only when the user explicitly requires it or a mirror/template preservation contract owns it.
|
||||
For free-design pages, describe `Layout` through relationships, hierarchy, visual focus, and optional macro region/span suggestions; do not prescribe element-level `x`, `y`, `width`, or `height`, fixed gaps, or an authoring method. Executor owns the final page composition and may depart from the recommendation while preserving its semantic job. Preserve literal geometry only when the user explicitly requires it or a mirror/template preservation contract owns it.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+6
-13
@@ -78,19 +78,12 @@
|
||||
|
||||
## V. Layout Principles
|
||||
|
||||
### Page Structure
|
||||
### Deck-wide Direction
|
||||
|
||||
- **Header area**: [fill]
|
||||
- **Content area**: [fill]
|
||||
- **Footer area**: [fill]
|
||||
|
||||
### Spacing Specification
|
||||
|
||||
| Element | Current Project |
|
||||
| --- | --- |
|
||||
| Safe margin | [fill] |
|
||||
| Content block gap | [fill] |
|
||||
| Icon-text gap | [fill] |
|
||||
- **Hierarchy direction**: [fill]
|
||||
- **Composition tendency**: [fill]
|
||||
- **Cross-page continuity**: [fill]
|
||||
- **Spacing posture**: [fill]
|
||||
|
||||
## VI. Icon Usage Specification
|
||||
|
||||
@@ -110,7 +103,7 @@
|
||||
#### Slide 01 - [fill]
|
||||
|
||||
- **Audience move**: [fill]
|
||||
- **Layout**: [fill]
|
||||
- **Layout**: [non-binding macro composition direction]
|
||||
- **Title**: [fill]
|
||||
- **Core message**: [fill]
|
||||
- **Content**: [fill]
|
||||
|
||||
@@ -109,7 +109,7 @@ New locks always write `title_family` and `body_family`, even when their values
|
||||
- `icons.library` records the primary stylistic library selected from `chunk-filled`, `tabler-filled`, `tabler-outline`, or `phosphor-duotone`, or `none` when no generic bundled icons are selected. Content-driven `simple-icons/*` brand marks may appear alone or alongside it in `inventory` without becoming a stylistic library or a separate confirmation choice. The inventory indexes the curated synced SVG pool without assigning page usage; every SVG already under `<project_path>/icons/` remains valid prepared execution material. Illustrated-icon slices create no icon-lock field: their exact paths belong under `images`, and the unplaced parent sheet stays out of the lock.
|
||||
- `objective` grammar: one concise sentence preserving the deck goal and audience success condition.
|
||||
- `image_rendering` grammar: one catalog id, or `custom` with `image_rendering_behavior`.
|
||||
- `images`: `- <key>: <path> | source=<via> | pattern=<layout> | crop=<adaptive|no-crop>`; e.g. `- p04: images/a.png | source=user | pattern=full-height image beside the evidence | crop=no-crop`. Use the canonical `images/<filename>` path; `source` and `crop` exactly project §VIII, while `pattern` preserves its non-empty normalized free-form suggestion and any optional hierarchical catalog ids. The pattern remains a recommendation for Executor recall, not a geometry or realization lock. Omit unplaced sheets.
|
||||
- `images`: `- <key>: <path> | source=<via> | pattern=<layout> | crop=<adaptive|no-crop>`; e.g. `- p04: images/a.png | source=user | pattern=full-height image beside the evidence | crop=no-crop`. Use the canonical `images/<filename>` path; `source` and `crop` exactly project §VIII, while `pattern` preserves its non-empty normalized free-form suggestion and any optional hierarchical catalog ids. The pattern remains a recommendation for Executor recall that may be adopted, adapted, or declined, not a geometry or realization lock. Omit unplaced sheets.
|
||||
- Custom reference grammar: comma-separated exact catalog ids with no duplicates. Reference fields are valid only for `custom`; omit them for a genuinely novel direction.
|
||||
- `stroke_width` grammar: `1.5`, `2`, or `3`; present only for `tabler-outline`.
|
||||
- `page_rhythm` grammar: `P` + at least two digits (`P01`, `P100`) followed by `anchor|dense|breathing`.
|
||||
|
||||
@@ -16,8 +16,11 @@ Master/Layout systems belong in [`layouts/`](../layouts/).
|
||||
`tables` object maps each canonical key to one selection-rule `summary`; keys
|
||||
match `<key>.svg`, and `meta.total` matches the canonical SVG roster.
|
||||
|
||||
Use [`visualization_recall.py`](../../scripts/visualization_recall.py) for
|
||||
bounded Chart/Table or table-only recall. New Default planning writes
|
||||
Default Strategist and Quick read this complete compact registry together with
|
||||
the Chart registry before planning. They compare every selection rule, then use
|
||||
[`visualization_recall.py`](../../scripts/visualization_recall.py) `validate`
|
||||
to resolve selected canonical references. Its `recall` mode remains an optional
|
||||
diagnostic helper, not the runtime capability gate. Default writes
|
||||
`table/<key>` to `page_visualizations`; Quick keeps the selected reference in
|
||||
active context.
|
||||
|
||||
|
||||
+9
-3
@@ -15,7 +15,7 @@ Enter this child workflow only after [`Create Template`](../create-template.md)
|
||||
|
||||
**Hard rule — child workflow, not a top-level route**: Create Style executes only inside Create Template. It uses the parent workflow's single shared confirmation/preflight/registration contract and never creates a competing entry route or second confirmation gate.
|
||||
|
||||
**Hard rule — method and defaults only**: A Style owns a reusable way to argue, express evidence, and coordinate non-binding design defaults. It owns no current-project communication contract, reusable brand identity, page geometry, canvas, SVG prototype, Master/Layout graph, placeholder contract, application contract, or visible asset inventory.
|
||||
**Hard rule — method and defaults only**: A Style owns a reusable way to argue, express evidence, and coordinate non-binding design defaults. It owns no current-project communication contract, reusable brand identity, page geometry, canvas, SVG prototype, Master/Layout graph, placeholder contract, application contract, visible asset inventory, carrier eligibility, image source, or local authoring-capability whitelist.
|
||||
|
||||
**Hard rule — no page prototypes**: A Style workspace contains only `templates/design_spec.md`. Do not create page SVGs, a review PPTX, or empty `images/`, `icons/`, or `exports/` directories.
|
||||
|
||||
@@ -54,8 +54,8 @@ Add these child-owned requirements to Create Template Step 2:
|
||||
| Communication method | Required; argument flow, page-message discipline, and claim/evidence treatment; a preferred mode is optional |
|
||||
| Page-role vocabulary | Required; reusable semantic roles and their jobs, evidence obligations, and composition tendencies; no order or inclusion policy |
|
||||
| Evidence and data expression | Required; chart, table, source, and editability guidance without numeric content quotas |
|
||||
| Visual-system defaults | Required; composition, density, decoration, color behavior, and typography character; catalog seeds and literal fallbacks are optional |
|
||||
| Image and icon direction | Required; rendering, usage, and treatment defaults without asset inventory or page mapping |
|
||||
| Visual-system defaults | Required; composition, density, decoration, color behavior, and native-text character; catalog seeds and literal fallbacks are optional, while carrier and native-construction eligibility remain downstream |
|
||||
| Image and icon direction | Required; rendering, centrality, recurrence, and treatment defaults without source restrictions, asset inventory, or page mapping |
|
||||
| Review focus | Required; extra checks to apply only if the user explicitly activates visual review |
|
||||
|
||||
Write this roster-free schema:
|
||||
@@ -139,6 +139,12 @@ keywords: [<three-to-five discovery tags>]
|
||||
|
||||
`Preferred Mode`, `Preferred Visual Style`, and `Preferred Image Rendering` are recommendation seeds. The current project's confirmed Stage-2 values remain authoritative. A preset value must be a real ID in its matching catalog. For `custom`, retain only real catalog references actually used as a comma-separated ID list and include the matching behavior prose.
|
||||
|
||||
**Hard rule — Style never becomes a capability policy**: Style prose may tune
|
||||
treatment, visual weight, density, recurrence, and coherence. It never bans a
|
||||
carrier or requires carrier coverage, never selects image source, and never
|
||||
narrows primitives, Office presets, independent composition, Boolean, or
|
||||
necessary freeform. Explicit current-project requirements remain upstream.
|
||||
|
||||
`Page Role Vocabulary` is a semantic vocabulary, not a Page Roster. Do not assign order, required/optional/repeatable status, page count, filenames, Master/Layout identities, slots, or fixed/replaceable/example-only content policy.
|
||||
|
||||
## 3. Materialize the Confirmed Style
|
||||
|
||||
@@ -258,6 +258,7 @@ arises.
|
||||
|
||||
```
|
||||
Read references/strategist.md
|
||||
Read references/canvas-formats.md
|
||||
```
|
||||
|
||||
Then load only the extra role modules triggered by the current plan:
|
||||
@@ -266,16 +267,31 @@ Then load only the extra role modules triggered by the current plan:
|
||||
|---|---|
|
||||
| Stage 1 is confirmed and its template choice installed a selected Brand/Style/Layout/Deck workspace into this project | `references/strategist-template.md` before Stage 2 |
|
||||
| The confirmed Stage-1 `delivery_context` identifies recorded/self-running/video delivery, or input is an explicit final/literal narration script | `references/video-design.md` before the three Stage-2 whole solutions and page roster |
|
||||
| The confirmed Stage 2 `image_usage` contains a source other than `none`, or the user supplied an explicit non-`none` image constraint | `references/image-layout-spec.md` + `references/image-layout-patterns.md` before production detail or §VIII |
|
||||
|
||||
After Stage 1 and template handoff, load `strategist-image.md` plus only the
|
||||
three `_index.md` files. Author the three whole solution intents before mapping
|
||||
any component basis. Freeze every referenced mode/style/rendering id from the
|
||||
indexes, then read once only the deduplicated union of those exact detail files
|
||||
and finish the three custom behaviors. A novel custom reads no detail file.
|
||||
Confirmed non-`none` loads the layout references and continues into resource
|
||||
planning; confirmed `none` writes no image rows while retaining
|
||||
recommendation-only rendering candidates. Only an installed
|
||||
After Stage 1 and template handoff, load the fixed planning-capability block
|
||||
below in one batch before authoring any Stage-2 whole-solution intent, image
|
||||
source recommendation, or page roster:
|
||||
|
||||
```
|
||||
Read references/strategist-image.md
|
||||
Read references/image-layout-spec.md
|
||||
Read references/image-layout-patterns.md
|
||||
Read references/modes/_index.md
|
||||
Read references/visual-styles/_index.md
|
||||
Read references/image-renderings/_index.md
|
||||
Read templates/icons/README.md
|
||||
Read templates/charts/charts_index.json
|
||||
Read templates/tables/tables_index.json
|
||||
```
|
||||
|
||||
This is a capability map, not a usage checklist: retain zero-use outcomes and
|
||||
the Strategist/Executor ownership boundary. Author the three whole solution
|
||||
intents before mapping any component basis. Freeze every referenced
|
||||
mode/style/rendering id from the indexes, then read once only the deduplicated
|
||||
union of those exact detail files and finish the three custom behaviors. A novel
|
||||
custom reads no detail file. Confirmed non-`none` uses the already-loaded image
|
||||
layout references and continues into resource planning; confirmed `none` writes
|
||||
no image rows while retaining recommendation-only rendering candidates. Only an installed
|
||||
project-local template state loads the template module, and only after Stage 1
|
||||
is confirmed; a bare template/style name does not.
|
||||
|
||||
@@ -363,11 +379,10 @@ or `templates` with at least one server-resolved root.
|
||||
it. The server requires this handoff before Stage 2.
|
||||
|
||||
2. Only now inspect installed template state and apply
|
||||
`strategist-template.md` when active. Read `strategist-image.md` plus only
|
||||
`modes/_index.md`, `visual-styles/_index.md`, and
|
||||
`image-renderings/_index.md`; author three whole solution intents, freeze
|
||||
their exact component references from those indexes, then read only the
|
||||
referenced detail files and complete the custom projections. Derive the
|
||||
`strategist-template.md` when active. Load the fixed Stage-2 planning-capability
|
||||
block above, author three whole solution intents, freeze their exact component
|
||||
references from its indexes, then read only the referenced detail files and
|
||||
complete the custom projections. Derive the
|
||||
remaining production defaults and create
|
||||
`confirm_ui/recommendations.stage2.json` without changing Stage 1; declare
|
||||
`stage: "stage2"`, then wait for the final confirmation:
|
||||
@@ -495,7 +510,7 @@ state and §X records its source/verbatim policy. After Gate 2, before Step 5 or
|
||||
split handoff, write the exact segments once to `notes/total.md`; split them only
|
||||
in Step 7.1. This is frozen production input, not a third planning artifact.
|
||||
|
||||
**✅ Internal checkpoint — Phase deliverables complete**: facts read; confirmation consumed once; final Stage-2 production fields resolved (generation mode, refine-spec, proactive choices, and conditional AI path); mathematical content recorded where applicable; Design Spec passed Gate 1; enabled refinement approved; lock derived from it; split handling resolved; communication and every §IX `Audience move` validated. Do not print this checklist; auto-proceed.
|
||||
**✅ Internal checkpoint — Phase deliverables complete**: facts read; confirmation consumed once; final Stage-2 production fields resolved (generation mode, refine-spec, proactive choices, and conditional AI path); mathematical content recorded where applicable; every §IX page resolved its one-pass carrier mix and §VIII contains only assigned external image-resource jobs; Design Spec passed Gate 1; enabled refinement approved; lock derived from it; split handling resolved; communication and every §IX `Audience move` validated. Do not print this checklist; auto-proceed.
|
||||
|
||||
---
|
||||
|
||||
@@ -503,7 +518,7 @@ in Step 7.1. This is frozen production input, not a third planning artifact.
|
||||
|
||||
🚧 **GATE**: Step 4 complete; `<project_path>/design_spec.md` and `<project_path>/spec_lock.md` both exist. If either required artifact is missing, stop before any acquisition or generation and follow [`failure-recovery.md`](governance/failure-recovery.md) §3.
|
||||
|
||||
> **Trigger**: At least one row in the resource list has `Acquire Via: ai`, `web`, and/or `slice`, or any row is a pending prepared derivative declared by `Reference: Derived from <canonical bare filename>; treatment=...`. A prepared-user-only plan skips this step only when it has no derivative to materialize; `placeholder` rows alone do not trigger it. A permitted but unused image source creates no row and does not trigger acquisition. If §VIII omits a source, asset, or page role that `image_notes` explicitly requires, the Design Spec is incomplete; return to Step 4 Gate 1, repair it from the retained final state, and re-author the affected lock anchors from context. Do not reopen `result.json` during this check.
|
||||
> **Trigger**: §VIII is Step 4's committed external image-resource result, not a candidate inventory. At least one row has `Acquire Via: ai`, `web`, and/or `slice`, or one row is a pending prepared derivative declared by `Reference: Derived from <canonical bare filename>; treatment=...`. A prepared-user-only plan skips this step only when it has no derivative to materialize; `placeholder` rows alone do not trigger it. A permitted but unused image source creates no row and does not trigger acquisition. If §VIII omits a source, asset, or page role that `image_notes` explicitly requires, the Design Spec is incomplete; return to Step 4 Gate 1, repair it from the retained final state, and re-author the affected lock anchors from context. Do not reopen `result.json` during this check.
|
||||
|
||||
**Failure recovery**: stop/continue behavior for AI/web/slice/image-readiness failures is defined in [`workflows/governance/failure-recovery.md`](governance/failure-recovery.md). This Step keeps the acquisition procedure.
|
||||
|
||||
@@ -569,6 +584,16 @@ Workflow:
|
||||
|
||||
🚧 **GATE**: Step 4 (and Step 5 if triggered) complete; all prerequisite deliverables are ready.
|
||||
|
||||
Read the Executor role core before applying its context policy:
|
||||
|
||||
```
|
||||
Read references/executor-base.md # REQUIRED: flat/shared execution core
|
||||
```
|
||||
|
||||
**Planning context**: follow [`executor-base.md`](../references/executor-base.md) §2.1. Reuse the complete Design Spec and lock in an unchanged, uncompacted context. Fresh/resumed/restarted, compacted/summary-only, or externally/unknown changed execution reads both once and reloads triggered inputs. For a local question, consult the retained lock first, then only the owning Design Spec fragment; do not poll files merely to prove validity.
|
||||
|
||||
**Scheduled lock re-read (Default Generate only)**: when another page follows, re-read `spec_lock.md` once after P05/P10/P15/… per [`executor-base.md`](../references/executor-base.md) §2.1.
|
||||
|
||||
**Exact page roster**: render `design_spec.md §IX` one-for-one, in order. Any add/drop/merge/split/reorder requires Spec repair/refinement first.
|
||||
|
||||
**Page content**: §IX is preferred wording and semantic authority. Use it when it works; adapt it when presentation benefits while preserving intent, facts, and explicit literal requirements. Read sources only to verify requested evidence; return incomplete blocks to Step 4 instead of enriching them during execution.
|
||||
@@ -577,36 +602,30 @@ Workflow:
|
||||
`notes/total.md` once before P01 and design each visible state/semantic group
|
||||
around its exact segment; never edit or pad it.
|
||||
|
||||
**Planning context**: follow [`executor-base.md`](../references/executor-base.md) §2.1. Reuse the complete Design Spec and lock in an unchanged, uncompacted context. Fresh/resumed/restarted, compacted/summary-only, or externally/unknown changed execution reads both once and reloads triggered inputs. For a local question, consult the retained lock first, then only the owning Design Spec fragment; do not poll files merely to prove validity.
|
||||
|
||||
**Scheduled lock re-read (Default Generate only)**: when another page follows, re-read `spec_lock.md` once after P05/P10/P15/… per [`executor-base.md`](../references/executor-base.md) §2.1.
|
||||
|
||||
**Artifact ownership**: `svg_output/` is the author source, `svg_final/` is derived, and image facts come from the regenerated `analysis/image_analysis.csv`; see [`references/artifact-ownership.md`](../references/artifact-ownership.md).
|
||||
|
||||
Read the execution references for this deck's locked `mode` + `visual_style`
|
||||
(from `spec_lock.md`). Load this fixed required block directly as one batch:
|
||||
Read the exact execution references named by this deck's retained
|
||||
`spec_lock.md`; do not reopen the planning indexes. Load the remaining fixed
|
||||
construction block plus the resolved mode/style detail files as one batch:
|
||||
```
|
||||
Read references/executor-base.md # REQUIRED: flat/shared execution core
|
||||
Read references/shared-standards-core.md # REQUIRED: SVG compatibility + shared aesthetic/leading baseline
|
||||
Read references/svg-effects.md # REQUIRED: Visual Job Router + effects/construction vocabulary
|
||||
Read references/native-shape-authoring.md # REQUIRED: native-shape selection and Boolean construction
|
||||
Read references/executor-structure.md # REQUIRED: qualitative relationship and topology grammar
|
||||
Read references/semantic-svg.md # REQUIRED: semantic metadata boundary
|
||||
Read references/modes/_index.md
|
||||
Read references/visual-styles/_index.md
|
||||
Read references/modes/<resolved-id>.md # one preset id, or each `mode_references` id
|
||||
Read references/visual-styles/<resolved-id>.md # one preset id, or each `visual_style_references` id
|
||||
```
|
||||
|
||||
Keep the core's shared visual-quality defaults and `svg-effects.md` §6.1 Visual Job Router active during page authoring; they are not passive compatibility reading. Explicit user/template requirements and the locked style override compatible aesthetic defaults, never technical Required / Forbidden boundaries.
|
||||
|
||||
> Read only the always-on references above plus the conditionally triggered modules below. The indexes provide routing information, not permission to open siblings. A preset reads its one locked file. For `custom`, read only the exact bases named by optional `mode_references` / `visual_style_references`, then synthesize them under the corresponding behavior. If absent, treat the direction as genuinely novel and read no preset file. Do not infer adjacent bases, glob a catalog, or blend unselected identities.
|
||||
> Read only the role core, always-on construction references, exact locked detail files, and conditionally triggered modules below. The selection indexes remain planning-only. A preset reads its one locked file. For `custom`, read only the exact bases named by optional `mode_references` / `visual_style_references`, then synthesize them under the corresponding behavior. If absent, treat the direction as genuinely novel and read no preset file. Do not infer adjacent bases, glob a catalog, or blend unselected identities.
|
||||
|
||||
| Deterministic trigger | Additional references |
|
||||
|---|---|
|
||||
| `pptx_structure.mode: structured` | `executor-structured.md` + `pptx-structure-interface.md` |
|
||||
| Selected §VII / `page_visualizations` Chart/Table `family/key`, or a legacy `page_charts` row resolving to a live Chart/Table SVG | `executor-visualization.md` + the selected Chart/Table branch |
|
||||
| Actual value-driven geometry, including mini/inset charts and sparklines | `executor-chart.md` |
|
||||
| Mandatory per-page Structure decision from §IX is `yes` | `executor-structure.md` before any geometry for the first applicable page |
|
||||
| Actual row × column fact grid | `executor-table.md` |
|
||||
| Used preset pattern fill, or independent Chart/Table with §IX `<object-key>=yes` | `native-data-interface.md` before that object |
|
||||
| §IX or current page content contains mathematical notation that may require native math | `native-formula.md` before choosing ordinary text, inline native math, or block native math |
|
||||
@@ -618,8 +637,9 @@ Keep the core's shared visual-quality defaults and `svg-effects.md` §6.1 Visual
|
||||
|
||||
No branch is loaded by analogy. For each page, after §IX content/communication
|
||||
but before geometry, apply [`executor-base.md`](../references/executor-base.md)'s
|
||||
mandatory Structure decision. `no` stays on base; before the first `yes`, read
|
||||
`executor-structure.md` completely and reuse it until file/context invalidation.
|
||||
mandatory Structure decision with the already-loaded
|
||||
`executor-structure.md`. `no` stays on the shared base; `yes` applies that
|
||||
grammar without another load gate.
|
||||
Create no catalog/lock/artifact. Chart/Table selection neither replaces this
|
||||
decision nor locks geometry/native readiness.
|
||||
|
||||
@@ -843,6 +863,7 @@ Before creating the PPTX, the exporter independently requires the current matchi
|
||||
## ✅ Generate PPTX Complete
|
||||
|
||||
- [x] Image readiness gate passed
|
||||
- [x] The final carrier receipt was compared with the retained page decisions, and any factual contradiction was repaired without treating counts as quotas
|
||||
- [x] Notes split completed when enabled; disabled exports used `--no-notes`
|
||||
- [x] `svg_final/` preview completed
|
||||
- [x] Native PPTX published and postflight report written
|
||||
|
||||
+105
-79
@@ -244,24 +244,30 @@ use; otherwise decide which prototypes to use, skip, repeat, reorder, or adapt
|
||||
while authoring. Persist no separate template-application artifact. If no
|
||||
template was installed, make the same design choices freely.
|
||||
|
||||
Before resolving the one-pass design, read the canvas authority and only these
|
||||
three choice indexes:
|
||||
Before resolving the one-pass design, read this fixed planning-capability batch
|
||||
in one pass:
|
||||
|
||||
```
|
||||
Read references/canvas-formats.md
|
||||
Read references/image-layout-spec.md
|
||||
Read references/image-layout-patterns.md
|
||||
Read references/modes/_index.md
|
||||
Read references/visual-styles/_index.md
|
||||
Read references/image-renderings/_index.md
|
||||
Read templates/icons/README.md
|
||||
Read templates/charts/charts_index.json
|
||||
Read templates/tables/tables_index.json
|
||||
```
|
||||
|
||||
Resolve the best whole solution from the project brief and index summaries,
|
||||
freeze its exact mode/style/rendering ids, then read only those selected preset
|
||||
files or custom-basis files. A novel custom reads none. Never open detail files
|
||||
to compare candidates, glob a catalog, or let an unselected sibling influence
|
||||
the decision. Decide whether AI images are useful as a separate source judgment;
|
||||
even when the answer is no, retain the chosen rendering direction for visual
|
||||
coherence. Keep the chosen mode, style, rendering, and exact bases in active
|
||||
context only.
|
||||
This batch is the complete capability map for planning, not a usage checklist:
|
||||
zero use of any capability remains valid. Resolve the best whole solution from
|
||||
the project brief and loaded decision authorities, freeze its exact
|
||||
mode/style/rendering ids, then read only those selected detail files or custom
|
||||
bases. A novel custom reads none. Never open unselected detail siblings to
|
||||
compare candidates, glob a catalog, or let them influence the decision. Decide
|
||||
whether AI images are useful as a separate source judgment; even when the
|
||||
answer is no, retain the chosen rendering direction for visual coherence. Keep
|
||||
the chosen mode, style, rendering, and exact bases in active context only.
|
||||
|
||||
**One-pass decision boundary**: resolve only what is needed to author this deck
|
||||
in the current context. Do not print a strategy summary, create a planning
|
||||
@@ -276,15 +282,17 @@ the roster after the whole-roster check:
|
||||
- the canvas, visual direction, wording, intended viewing distance, and effective reading mode: choose `presentation` for distance-first projected or recorded viewing, `balanced` for mixed viewing, or `text` for close content-heavy reading. Take the initial body anchor and sanity band from [`canvas-formats.md`](../../references/canvas-formats.md) § "Typography Scale Start" for the resolved canvas—PPT remains reading-mode-driven, while registered/custom non-PPT canvases use their canvas-derived start—then resolve one concrete typography plan for the delivery target defined by [`shared-standards-core.md`](../../references/shared-standards-core.md) §4.1, never from the authoring host's font inventory, with stable size anchors for title, body, annotation, and every other recurring role the roster uses. When content does not fit, preserve its core message and apply only fitting actions the source/profile invariants permit—restructure, shorten, or split; if none is permitted, surface the unresolved fit instead of shrinking a recurring role. Explicit user, template, fidelity-profile, or resolved-style requirements may call for a deliberate exception;
|
||||
- the semantic color roles actually needed by the roster, each with a concrete active-context color anchor, including background/surface, primary/secondary text, dominant/accent, and status roles as applicable. Honor explicit user, installed template/brand, fidelity-profile source-identity, and resolved-style color semantics before deriving only the missing roles that the active profile permits; decide which roles dominate, support, or remain rare, and preserve sufficient contrast for meaning-bearing text. Pair newly authored color-coded states, categories, or relationships with a label, symbol, line, or geometry cue; when fidelity forbids adding one, preserve the source encoding;
|
||||
- an ordinary body-content frame and a density judgment for every page, adapted to the canvas and any user / template / style geometry; use `anchor`, `dense`, `breathing`, or an equivalent active-context distinction instead of one uniform fill level;
|
||||
- for each page not bound to literal supplied geometry, a primary visual zone and one compact page-scale geometry job tied to its core message—what geometry must organize, without naming a preset or encoding form; keep it only in the transient roster for §3's authoring-time move. Use cards or equal grids when the content relationship calls for them, not as the automatic page grammar;
|
||||
- for each page not bound to literal supplied geometry, a primary visual zone and one compact page-scale geometry job tied to its core message—what geometry must organize, without naming a preset or encoding form; keep it only in the transient roster for §3's authoring-time move;
|
||||
- for each page, preserve its semantic units, source-stated qualitative relationships, intended entry, and outcome so §3 can make the sole Structure decision before geometry;
|
||||
- when useful, a transient deck-level visual motif system with an identity or
|
||||
communication job, a recognizable invariant, and a reuse mode: fixed chrome,
|
||||
adaptive variation, or both; omit it when restraint serves the deck better;
|
||||
- the resource decisions needed for immediate preparation. Required operational
|
||||
image manifests may carry filenames, page relationship, status, and
|
||||
generation/crop/focal cues, but do not create a general resource roster or an
|
||||
icon-to-page assignment. Keep each selected formula's source LaTeX in active
|
||||
generation/crop/focal cues. When page use depends on stable composition, also
|
||||
retain subject/quiet zones, boundary or direction, intended overlap/seam, and
|
||||
approximate share only when needed. Do not create a general resource roster
|
||||
or icon-to-page assignment. Keep each selected formula's source LaTeX in active
|
||||
context for direct marker authoring; retain each selected hyperlink's exact
|
||||
absolute URI or 1-based same-deck target; create no formula/link manifest;
|
||||
- the implementation path for each resource. An explicit user path wins;
|
||||
@@ -310,42 +318,58 @@ a floating cutout may use `#A2-01`. Finish assets before SVG per
|
||||
|
||||
**Mandatory — whole-roster rhythm check**: During the same active-context
|
||||
resolution, compare neighbors and section arcs to judge whether chapter entries
|
||||
visibly reset, extended same-density runs are intentional, extended same-carrier
|
||||
or same-topology runs form an intentional semantic sub-arc, repeated dominant
|
||||
geometry carries a continuity job, each section follows a mode-fitting
|
||||
visibly reset, extended same-density runs are intentional, extended repetitions
|
||||
of one carrier or composition move form an intentional page-job arc, repeated
|
||||
dominant geometry carries a continuity job, each section follows a mode-fitting
|
||||
progression—including framework → explanation/evidence → judgment/action when
|
||||
it serves the objective—and the final arc resolves the communication objective
|
||||
before a genuine ending lowers information load. Repair
|
||||
the transient roster, density, and composition choices in place. This is
|
||||
before a genuine ending lowers information load. Same section, equal weight or
|
||||
density, one style, and prior-page precedent do not establish a page-job arc.
|
||||
Repair the transient roster, density, and composition choices in place. This is
|
||||
judgment, not quota; preserve intentional continuity, legitimately all-`dense`
|
||||
material, and 1:1/literal order. Add no filler page: a `breathing` page marks a
|
||||
meaningful pause—chapter transition, standalone emphasis, or SCQA bridge—and
|
||||
must stand alone. Create no artifact, checkpoint, lock, or second
|
||||
authoring/review pass.
|
||||
|
||||
**Mandatory — capability scan, not a coverage quota**: for every page, consider
|
||||
the complete carrier menu once and choose only the forms that communicate its
|
||||
content best. A decision to use none of a carrier is valid; skipping the scan
|
||||
because Quick is expected to be faster is not.
|
||||
**Mandatory — one-pass page carrier resolution, not a coverage quota**: During
|
||||
the same transient-roster resolution and before resource preparation or
|
||||
coordinates, decide each page's complete mix of background, editable text and
|
||||
optional lettering, native geometry and lines, photos/scenes,
|
||||
illustrations/icons, and applicable visualizations. Decide their primary,
|
||||
structural, and supporting jobs together; do not finish a text/container layout
|
||||
and then treat the other families as optional decoration. Only selected image,
|
||||
lettering, or illustrated-icon jobs with plausible page roles create image
|
||||
resources; ordinary SVG/emoji icons retain their curated-pool boundary.
|
||||
Omitting any carrier is valid after this review; Quick speed, resolved style,
|
||||
or easier syntax never skips it.
|
||||
|
||||
**Reference — carriers compose, not compete**: Any page may combine a suitable subset of background paint, native shapes, editable text, photos/scenes, transparent illustration elements, decorative lettering, icons, and visualizations. Outside explicit requirements, no carrier is mandatory or mutually exclusive; choose the combination that makes the page coherent and visually resolved.
|
||||
**Reference — carriers compose, not compete**: Use any suitable subset from the resolved mix; outside explicit requirements, no carrier is mandatory or mutually exclusive. The resolved style controls treatment, visual weight, and recurrence; it never decides carrier eligibility, image source, or the complete native construction vocabulary. A compact icon cue does not discharge a scene, subject, or visual-weight job that a photo or illustration family would serve.
|
||||
|
||||
**Hard rule**: Credentials do not decide image need or the initial carrier plan. Do not inspect backend configuration or probe a provider before planning. Web acquisition retains zero-config providers; actual AI generation capability is resolved only during resource preparation, where the declared Quick no-AI replan below owns automated exhaustion.
|
||||
|
||||
**Default — visual grounding before a zero-image deck (may override when the user forbids images or charts / native SVG fully carry the visual burden)**: When the audience must recognize, experience, compare, or choose an externally verifiable subject, place, product, or setting, plan supplied/extracted or web images. Prepare AI imagery proactively where invented or deliberately stylized expression materially improves a planned visual job; this may be a complete image or transparent elements composed with other page carriers. This is a semantic decision, not an image-count quota.
|
||||
|
||||
**Default — prepare a composable illustration family when it strengthens the deck (may omit when no page benefits)**: Resolve the family before SVG authoring. Elements may repeat unchanged as title/corner chrome or vary as dominant anchors, supporting figures, and accents on any suitable page. Batch compatible elements through Illustration Sheets, split only for geometry/detail/quality conflicts, and keep final page composition in SVG under [`image-generator.md`](../../references/image-generator.md) §4.3.
|
||||
**Mandatory — materialize a selected composable illustration family**: When
|
||||
the carrier resolution selects one, resolve the family before SVG authoring.
|
||||
Elements may repeat unchanged as title/corner chrome or vary as dominant
|
||||
anchors, supporting figures, and accents on any suitable page. Batch compatible
|
||||
elements through Illustration Sheets, split only for geometry/detail/quality
|
||||
conflicts, and keep final page composition in SVG under
|
||||
[`image-generator.md`](../../references/image-generator.md) §4.3.
|
||||
|
||||
**Default — consider AI illustrated icons when they strengthen compact semantic
|
||||
cues**: When the user has not forbidden AI, prepare useful cues as transparent
|
||||
slices under `images/`. Leave grouping, count, and coexistence with SVG icons
|
||||
to the page and deck fit under [`image-generator.md`](../../references/image-generator.md)
|
||||
§4.3; apply no coverage quota and never treat the slices as SVG inventory.
|
||||
**Mandatory — materialize selected AI illustrated-icon jobs**: When the carrier
|
||||
resolution selects them and the user has not forbidden AI, prepare useful cues
|
||||
as transparent slices under `images/`. Leave grouping, count, and coexistence
|
||||
with SVG icons to the page and deck fit under
|
||||
[`image-generator.md`](../../references/image-generator.md) §4.3; apply no
|
||||
coverage quota and never treat the slices as SVG inventory.
|
||||
|
||||
**Mandatory — proactive AI decorative lettering**: When the user has not
|
||||
forbidden AI, scan the frozen roster for display strings
|
||||
anywhere in the deck. Exactly two questions decide eligibility: is that wording
|
||||
stable, and would an artistic treatment communicate better than native type?
|
||||
**Mandatory — proactive AI decorative lettering**: During that same one-pass
|
||||
carrier resolution, when the user has not forbidden AI, scan the frozen roster
|
||||
for display strings anywhere in the deck. Exactly two questions decide
|
||||
eligibility: is that wording stable, and would an artistic treatment
|
||||
communicate better than native type?
|
||||
Page role, string length, line count, and kind of noun never filter candidates —
|
||||
a cover hook, chapter word, place or product name, dish or exhibit name, year,
|
||||
hero number, pull quote, or recurring motif word all qualify when both answers
|
||||
@@ -391,30 +415,18 @@ generation capability is resolved during resource preparation, not eligibility.
|
||||
|
||||
This carrier menu does not satisfy or replace the per-page Structure decision in §3.
|
||||
|
||||
**Mandatory — per-image source decision, never inherited from the resolved style**: Outside Image to PPTX, whose closed page surface owns its reconstruction assets, decide each page image's source separately — supplied/extracted, web, AI, or slice. Prefer a supplied/extracted asset that already carries authority; use web when an externally verifiable subject must appear as itself; use AI when invented or deliberately stylized expression matters more than documentary identity. Mixed sources across one deck are normal.
|
||||
**Mandatory — per-image source decision, never inherited from the resolved style**: During that same carrier resolution, outside Image to PPTX whose closed page surface owns its reconstruction assets, decide each selected page image's source separately — supplied/extracted, web, AI, or slice. Prefer a supplied/extracted asset that already carries authority; use web when an externally verifiable subject must appear as itself; use AI when invented or deliberately stylized expression matters more than documentary identity. Mixed sources across one deck are normal.
|
||||
|
||||
Resolving one visual style, `Illus.` propensity, or generated-image rendering resolves how imagery **looks**; it resolves the source for no page. A named place, building, product, artwork, person, or other externally verifiable subject stays a web/supplied candidate no matter how illustrative the deck looks. When such a subject is deliberately not shown as itself, state that choice and its reason in the final report rather than leaving it implicit.
|
||||
|
||||
**Visualization recall — optional Chart/Table reference**: When a reusable
|
||||
Chart/Table reference would help, run recall with 3–8 English semantic tags.
|
||||
Use its default catalog search; add `--family chart|table` only when the page's
|
||||
information model is already certain. Do not run recall for qualitative shape
|
||||
composition.
|
||||
|
||||
```bash
|
||||
python3 skills/ppt-master/scripts/visualization_recall.py recall \
|
||||
--page P03 \
|
||||
--tag "time series" \
|
||||
--tag "three metrics" \
|
||||
--tag "direction over time" \
|
||||
--limit 6
|
||||
```
|
||||
|
||||
Read the result unfiltered and apply
|
||||
[`visualization-recall.md`](../../scripts/docs/visualization-recall.md)'s
|
||||
low-confidence semantic fallback before retaining `no-template-match`. Choose at most one primary
|
||||
Chart/Table `family/key` for a page, validate it with `visualization_recall.py validate`,
|
||||
and keep its short purpose only in active context. The reference remains
|
||||
**Mandatory — complete Chart/Table capability review**: During that same
|
||||
carrier resolution, compare every page's information model against every
|
||||
`Pick` / `Skip` rule in the two already-loaded live registries. The registries
|
||||
expose the possibility space; they are neither usage quotas nor whitelists. Do
|
||||
not select a catalog reference for qualitative shape composition. Choose at
|
||||
most one primary Chart/Table `family/key` for a page, validate it with
|
||||
`visualization_recall.py validate`, and keep its short purpose only in active
|
||||
context. Retain `no-template-match` when none fits. The reference remains
|
||||
flexible: it does not lock final type, geometry, style, or native output.
|
||||
Describe an embedded child Chart/Table and every qualitative relationship in
|
||||
the page's active decision rather than selecting another primary reference.
|
||||
@@ -493,12 +505,10 @@ without reading or inventing a nearby preset.
|
||||
Do not load `executor-base.md`: it owns Default's persisted-plan handoff,
|
||||
first-page gate, and completion routing. Excluding that file is not a capability
|
||||
exclusion; Quick loads the shared and conditional execution authorities here
|
||||
directly. When any image exists, read once before the first affected
|
||||
page and reuse throughout the valid execution context:
|
||||
[`executor-image.md`](../../references/executor-image.md),
|
||||
[`image-layout-spec.md`](../../references/image-layout-spec.md),
|
||||
[`image-layout-patterns.md`](../../references/image-layout-patterns.md), and
|
||||
[`svg-image-embedding.md`](../../references/svg-image-embedding.md); add
|
||||
directly. Reuse the already-loaded image-layout authorities. When any image
|
||||
exists, read once before the first affected page and reuse throughout the valid
|
||||
execution context: [`executor-image.md`](../../references/executor-image.md)
|
||||
and [`svg-image-embedding.md`](../../references/svg-image-embedding.md); add
|
||||
[`executor-web-image.md`](../../references/executor-web-image.md) for a placed
|
||||
`Status: Sourced` image or filename recorded in `image_sources.json`.
|
||||
Reread only after a known file change or context invalidation.
|
||||
@@ -552,17 +562,20 @@ This decision is mandatory on every page and cannot be satisfied by the
|
||||
capability menu, visualization recall, template geometry, or a later check.
|
||||
|
||||
**Mandatory — independent per-page geometry move**: after the Structure result
|
||||
and any applicable topology resolve, but before writing coordinates, resolve one
|
||||
page-scale geometry move from the transient geometry job, actual content,
|
||||
resolved style, and complete native vocabulary. Compare a deliberate plain /
|
||||
neutral construction with
|
||||
[`native-shape-authoring.md`](../../references/native-shape-authoring.md) §2.1's
|
||||
composition lenses. Readability alone does not select the simple branch; a plain
|
||||
grid or no compound construction remains valid when it is the deliberate best
|
||||
fit for the page job. This applies to both `no` and `yes`, stays in active context
|
||||
until the page is complete, and never changes the Structure result. Use §2.1
|
||||
whenever the move adopts two or more native shapes. There is no coverage target
|
||||
or required explanation for a simple result.
|
||||
and any applicable topology resolve, but before choosing any contour, run the
|
||||
page-local direct `recommend --compact --limit 6` invocation defined by
|
||||
[`native-shape-authoring.md`](../../references/native-shape-authoring.md) from
|
||||
the actual job, then invoke `describe --compact` directly only for serious
|
||||
candidates. Registry discovery followed by direct `describe` without
|
||||
`recommend` does not satisfy this recall. Apply §2.1 to the transient geometry
|
||||
job, actual content, resolved style, and complete native vocabulary before
|
||||
writing coordinates. It owns the exact-fit geometry gate, independent
|
||||
relationship / carrier fit,
|
||||
contour-family / exact-result choice, reader effect for a generic or undrawn
|
||||
result, running actual-geometry signature, and materialization boundary. A
|
||||
primitive remains valid when it wins this comparison; there is no preset quota.
|
||||
Apply the move to both `no` and `yes`; keep the current decision in active
|
||||
context and never change the Structure result.
|
||||
|
||||
| Deterministic trigger | Additional authority |
|
||||
|---|---|
|
||||
@@ -578,7 +591,7 @@ Chart/Table reference and final information model are independent loading
|
||||
signals; load every applicable authority. Selection never makes an object
|
||||
native-ready or replaces the per-page Structure decision.
|
||||
|
||||
Keep the core's shared visual-quality / leading defaults and `svg-effects.md` §6.1 Visual Job Router active while authoring. Explicit user/template requirements and the resolved style override compatible aesthetic defaults, never technical Required / Forbidden boundaries.
|
||||
Keep the core's shared visual-quality / leading defaults and `svg-effects.md` §6.1 Visual Job Router active while authoring. Explicit user/template requirements and the resolved style override compatible aesthetic defaults, never technical Required / Forbidden boundaries, carrier eligibility, or native capability discovery. Treat selected style composition examples as generative vocabulary rather than a finite layout menu.
|
||||
|
||||
**Per-page execution anchors**: apply the transient core-message, typography-role, semantic-color, body-frame, density, and composition anchors resolved in §2 while authoring; they guide the current run without creating a persisted planning artifact.
|
||||
|
||||
@@ -615,9 +628,11 @@ under [`shared-standards-core.md`](../../references/shared-standards-core.md)
|
||||
§4.1; do not depend on a lock or generated font asset.
|
||||
|
||||
**Generation pacing**: the current main agent hand-writes the SVG roster in
|
||||
order. Use P01 as the visual-system calibration baseline and continue
|
||||
directly through the remaining pages without a first-page checker or
|
||||
confirmation stop. When a motif was
|
||||
order. Use P01 to calibrate visual identity and cover-specific expression; use
|
||||
the first page that exercises ordinary content relationships to calibrate
|
||||
content geometry and carrier integration. Neither becomes a reusable topology
|
||||
template. Continue directly without a first-page checker or confirmation stop.
|
||||
When a motif was
|
||||
resolved, follow its reuse mode: exact repetition is valid for deliberate
|
||||
title/corner chrome, while adaptive motifs may vary scale, crop, density,
|
||||
position, or content interaction. Keep this choice only in active context;
|
||||
@@ -653,7 +668,16 @@ python3 ${SKILL_DIR}/scripts/svg_quality_checker.py <project_path> \
|
||||
--quick-generate --stage final --json
|
||||
```
|
||||
|
||||
Fix every blocking error and rerun the same command. Then export:
|
||||
Fix every blocking error and rerun the same command.
|
||||
|
||||
**Mandatory — final carrier-receipt review**: Review the factual
|
||||
`[CARRIERS]` summary against the retained page jobs, resource roles, and running
|
||||
geometry signatures before export. Counts and diversity are not quotas, and
|
||||
zero use is valid. When the summary contradicts an active decision, read only
|
||||
the affected `files[].info.carrier_receipt` rows from the current report, repair
|
||||
those pages in one consolidated pass, and rerun the same final checker.
|
||||
|
||||
Then export:
|
||||
|
||||
When Speaker Notes is enabled, load
|
||||
[`executor-notes.md`](../../references/executor-notes.md) after the passing final
|
||||
@@ -718,10 +742,11 @@ or lock.
|
||||
## ✅ Quick Generate Complete
|
||||
|
||||
- [x] All required source/resource preparation is complete
|
||||
- [x] One mode and visual style were resolved, and every catalog source actually used was read
|
||||
- [x] The complete native preset registry was read unfiltered before P01
|
||||
- [x] The fixed planning-capability batch was read before the roster, and every selected detail source was read
|
||||
- [x] The complete native preset registry was read unfiltered before P01; every page entering ordinary contour selection ran job-derived `recommend` before choosing a contour and described only serious candidates
|
||||
- [x] Every page considered suitable carrier combinations without a coverage quota or single-carrier assumption
|
||||
- [x] Every page not bound to literal supplied geometry carried its transient geometry job into an authoring-time page-scale move, and the whole-roster rhythm check confirmed that any extended same-carrier or same-topology run serves an intentional semantic arc
|
||||
- [x] The proactive decorative-lettering scan ran before capability resolution; every exact string passing both eligibility questions entered an AI item or lettering sheet/slice job unless the user forbade AI
|
||||
- [x] Every page not bound to literal supplied geometry carried its geometry job into authoring, resolved each drawn contour from its exact family and job, retained the reader effect for any generic or undrawn result, and compared its actual geometry signature before the next page; repetition served the same page job / relationship or continuity motif
|
||||
- [x] Image need was decided independently of credentials; any zero-image deck is backed by an explicit no-image requirement or a roster whose visual burden is fully carried by charts / native SVG
|
||||
- [x] Every `slice_names` output exists after an exit-0 strict-alpha run, and no page whose chosen composition depends on a slice was authored or exported without it
|
||||
- [x] Every image-bearing page made its one pre-geometry composition decision
|
||||
@@ -732,6 +757,7 @@ or lock.
|
||||
- [x] Resolved SVG pages and their project-local references exist
|
||||
- [x] Every role declared by an installed template spec is locatable in the finished pages, or its non-use is deliberate — checked per installed spec, not from memory
|
||||
- [x] Every triggered capability-specific preparation and pre-checker verification completed
|
||||
- [x] The current final report's carrier receipt was compared with the retained page jobs and any factual contradiction was repaired before export, without treating counts as quotas
|
||||
- [x] The lockless final SVG quality report passes and matches the current SVGs
|
||||
- [x] Enabled notes were validated/generated and split; enabled custom motion ran through its owning stage
|
||||
- [x] One native PPTX exists under `exports/` or the explicit output path
|
||||
|
||||
+41
-27
@@ -31,20 +31,47 @@ The user opens a new chat and gives a phrase that names a project path and signa
|
||||
|
||||
## Step 1: Sanity check
|
||||
|
||||
Verify the project's planning-session artifacts before doing anything else:
|
||||
Verify the two root planning artifacts exist before loading their contents:
|
||||
|
||||
| File | Required when | Reason |
|
||||
|---|---|---|
|
||||
| `<project_path>/design_spec.md` | Always | Upstream approved design narrative and §IX page outline; its complete read occurs after the Executor role core loads |
|
||||
| `<project_path>/spec_lock.md` | Always | Downstream execution anchors and routing contract; its complete read follows the Design Spec |
|
||||
|
||||
If either file is missing, report it and stop this stage. Recover through
|
||||
[`failure-recovery.md`](../governance/failure-recovery.md) §3; do not enter Step
|
||||
6, read an orphan lock as authority, or invent a replacement artifact.
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Load the Generate authority, proceed from Step 6
|
||||
|
||||
```
|
||||
Read skills/ppt-master/workflows/generate-pptx.md
|
||||
```
|
||||
|
||||
Then jump to `### Step 6: Executor Phase`. It first loads `executor-base.md`,
|
||||
then applies that role core's context policy:
|
||||
|
||||
- Read the complete project Design Spec, then the complete `spec_lock.md`, once to establish the fresh execution context
|
||||
- Resolve the effective Speaker Notes, Custom Animations, and Narration Audio
|
||||
outcomes from `design_spec.md §I`. Missing outcomes use the workflow defaults
|
||||
`enabled` / `disabled` / `disabled`; these production decisions never come
|
||||
from `spec_lock.md`
|
||||
|
||||
Before the first SVG, verify every conditional dependency now discoverable
|
||||
from that retained pair:
|
||||
|
||||
| File / Directory | Required when | Reason |
|
||||
|---|---|---|
|
||||
| `<project_path>/spec_lock.md` | Always | Strategist's execution anchors and routing contract; read it completely once in this fresh execution context |
|
||||
| `<project_path>/design_spec.md` | Always | Complete approved design narrative and Section IX page outline; read it completely once in this fresh execution context |
|
||||
| `<project_path>/notes/total.md` | Design Spec §X records a supplied final/literal narration script | Frozen verbatim narration input; read it once before SVG authoring and never reconstruct it from the planning chat |
|
||||
| `<project_path>/notes/total.md` | Design Spec §X records a supplied final/literal narration script | Frozen verbatim narration input; never reconstruct it from the planning chat |
|
||||
| `<project_path>/images/` plus files whose row status requires existence | `spec_lock images` references any image | `Existing` / `Generated` / `Sourced` files must exist; an absent `Needs-Manual` file remains allowed until the Step 7 readiness gate |
|
||||
| `<project_path>/templates/` | `spec_lock page_layouts` references any | Layout / mirror prototypes required by execution |
|
||||
| Resolver-returned Chart/Table SVG | `spec_lock page_visualizations` or legacy `page_charts` references a live Chart/Table key | Shared page-local SVG selected through the two live catalogs |
|
||||
|
||||
Resolve every live Chart/Table value through the shared catalog resolver before
|
||||
Step 6. Validate canonical `family/key` from `page_visualizations` directly;
|
||||
opt into bare-key resolution only for a live Chart/Table value read from legacy
|
||||
Resolve every live Chart/Table value through the shared catalog resolver.
|
||||
Validate canonical `family/key` from `page_visualizations` directly; opt into
|
||||
bare-key resolution only for a live Chart/Table value read from legacy
|
||||
`page_charts`:
|
||||
|
||||
```bash
|
||||
@@ -60,31 +87,18 @@ live resolution is a missing planning dependency and stops this stage. A
|
||||
retired Structure bare key carries semantic intent only and requires no SVG;
|
||||
recover its relationship from §IX, or return to Step 4 when §IX is insufficient.
|
||||
|
||||
If any required artifact is missing, report it and stop this stage. Do not enter Step 6 or invent a replacement artifact. Recover by artifact owner:
|
||||
If a conditional dependency is missing, stop before page authoring and recover
|
||||
by artifact owner:
|
||||
|
||||
- Missing `design_spec.md` / `spec_lock.md` → use [`failure-recovery.md`](../governance/failure-recovery.md) §3.
|
||||
- Missing frozen `notes/total.md` when §X declares a final/literal script → return to Generate Step 4's prepared final narration branch; never rewrite the script from memory.
|
||||
- Missing `images/`, or a file whose status requires existence → recover by provenance: an `Acquire Via: user` / `Status: Existing` file is a required manual artifact, so use `failure-recovery.md` §2 and wait for the user to restore that exact file; a template-bundled bitmap returns to [`generate-pptx`](../generate-pptx.md) Step 3 to restore the selected workspace; an AI, web, or slice output uses its matching row in `failure-recovery.md` §1 to reacquire or derive it. An absent `Needs-Manual` file is not a Step 1 failure. Formula markers are SVG authoring content and never create a required image file.
|
||||
- Missing `images/`, or a file whose status requires existence → recover by provenance: an `Acquire Via: user` / `Status: Existing` file is a required manual artifact, so use `failure-recovery.md` §2 and wait for the user to restore that exact file; a template-bundled bitmap returns to [`generate-pptx`](../generate-pptx.md) Step 3 to restore the selected workspace; an AI, web, or slice output uses its matching row in `failure-recovery.md` §1 to reacquire or derive it. An absent `Needs-Manual` file is not a resume failure. Formula markers are SVG authoring content and never create a required image file.
|
||||
- Missing `templates/` inputs → restore the selected workspace through [`generate-pptx`](../generate-pptx.md) Step 3 and [`apply-template-workspace`](apply-template-workspace.md). If the workspace is unavailable or invalid, run Create Template again rather than reconstructing a template inside this stage.
|
||||
|
||||
---
|
||||
Then continue the documented pipeline:
|
||||
|
||||
## Step 2: Load the Generate authority, proceed from Step 6
|
||||
|
||||
```
|
||||
Read skills/ppt-master/workflows/generate-pptx.md
|
||||
```
|
||||
|
||||
Then jump to `### Step 6: Executor Phase` and run the documented pipeline:
|
||||
|
||||
- Read the complete project Design Spec, then the complete `spec_lock.md`, once to establish the fresh execution context
|
||||
- When §X records a final/literal narration script, read the frozen `notes/total.md` once and retain its page segments through SVG authoring and the late notes validation
|
||||
- Resolve the effective Speaker Notes, Custom Animations, and Narration Audio
|
||||
outcomes from `design_spec.md §I`. Missing outcomes use the workflow defaults
|
||||
`enabled` / `disabled` / `disabled`; these production decisions never come
|
||||
from `spec_lock.md`
|
||||
- If resuming mid-deck, read the latest completed SVG and current image metadata when images are used
|
||||
- Read the complete Step 6 always-on core exactly as listed in [`generate-pptx.md`](../generate-pptx.md), then read one locked preset file or only the exact `*_references` of a custom synthesis; never glob the mode or visual-style catalogs, and load only the branches selected by the condition table
|
||||
- When §X records a final/literal narration script, read the verified frozen `notes/total.md` once and retain its page segments through SVG authoring and the late notes validation
|
||||
- If resuming mid-deck, read the latest completed SVG and current image metadata after their required paths have been verified
|
||||
- Read the remaining Step 6 construction core exactly as listed in [`generate-pptx.md`](../generate-pptx.md), then read one locked preset file or only the exact `*_references` of a custom synthesis; never reopen or glob the mode or visual-style catalogs, and load only the branches selected by the condition table
|
||||
- For each page, make the mandatory Structure decision from retained §IX after its content/communication move is established and before any geometry; a `yes` result loads `executor-structure.md` before realization and creates no artifact or lock row
|
||||
- Design Parameter Confirmation
|
||||
- When structured, read the template Design Spec and each selected prototype once; retain unchanged references in the fresh context. A later bounded repair follows [`executor-base.md`](../../references/executor-base.md) §2.1 only while that context remains valid and uncompacted
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"sourceId": "shadcn",
|
||||
"repo": "https://github.com/shadcn-ui/ui.git",
|
||||
"ref": "main",
|
||||
"commit": "8a7701ec27eb9cb8e0377db769fbe6d744113c52",
|
||||
"commit": "5c8f5b06746ac445e97a50cbeb63253d657d7541",
|
||||
"adapter": "claude-skill",
|
||||
"sourcePath": "skills/shadcn",
|
||||
"syncedAt": "2026-08-17T16:00:00Z"
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"sourceId": "taste-skill",
|
||||
"repo": "https://github.com/Leonxlnx/taste-skill.git",
|
||||
"ref": "main",
|
||||
"commit": "e988add20dab0fa97d7a76781c48961c8184288e",
|
||||
"commit": "dfb6f9f9e93a39f673b1827c0889cc28326d1800",
|
||||
"adapter": "skill-collection",
|
||||
"sourcePath": "skills",
|
||||
"syncedAt": "2026-07-24T06:18:20Z"
|
||||
"syncedAt": "2026-08-18T16:00:00Z"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user