@cyber-dash-tech/revela 0.17.24 → 0.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +24 -25
  2. package/README.zh-CN.md +25 -26
  3. package/bin/revela.ts +2 -4
  4. package/lib/commands/help.ts +13 -13
  5. package/lib/commands/init.ts +24 -0
  6. package/lib/commands/png.ts +29 -0
  7. package/lib/commands/refine.ts +1 -1
  8. package/lib/commands/research.ts +24 -0
  9. package/lib/commands/review.ts +92 -14
  10. package/lib/decks-state.ts +7 -7
  11. package/lib/design/designs.ts +44 -0
  12. package/lib/narrative-state/deck-plan-artifact.ts +504 -99
  13. package/lib/narrative-state/render-plan.ts +13 -14
  14. package/lib/pdf/export.ts +84 -24
  15. package/lib/refine/server.ts +4 -3
  16. package/lib/runtime/index.ts +21 -14
  17. package/lib/runtime/review.ts +4 -104
  18. package/lib/workspace-state/render-targets.ts +2 -2
  19. package/lib/workspace-state/rendered-artifacts.ts +1 -1
  20. package/lib/workspace-state/types.ts +1 -1
  21. package/package.json +1 -1
  22. package/plugin.ts +31 -42
  23. package/plugins/revela/.codex-plugin/plugin.json +2 -2
  24. package/plugins/revela/.mcp.json +1 -1
  25. package/plugins/revela/mcp/revela-server.ts +58 -80
  26. package/plugins/revela/skills/revela-design/SKILL.md +4 -2
  27. package/plugins/revela/skills/revela-domain/SKILL.md +1 -1
  28. package/plugins/revela/skills/revela-export/SKILL.md +4 -5
  29. package/plugins/revela/skills/revela-init/SKILL.md +19 -34
  30. package/plugins/revela/skills/revela-make-deck/SKILL.md +15 -41
  31. package/plugins/revela/skills/revela-research/SKILL.md +17 -26
  32. package/plugins/revela/skills/revela-review-deck/SKILL.md +11 -29
  33. package/skill/SKILL.md +22 -19
  34. package/plugins/revela/skills/revela-story/SKILL.md +0 -24
@@ -58,6 +58,84 @@ Rules:
58
58
  Start now by reading canonical narrative files and reporting diagnostics. Do not create ${DECKS_STATE_FILE} or request approval.`
59
59
  }
60
60
 
61
+ export function buildDeckPlanPrompt({
62
+ exists,
63
+ workspaceRoot,
64
+ }: {
65
+ exists: boolean
66
+ workspaceRoot?: string
67
+ }): string {
68
+ const state = exists
69
+ ? "Legacy/cache state exists. Do not treat it as workflow authority."
70
+ : "No legacy/cache state exists. Keep the workflow file-native."
71
+
72
+ return `Create or update a Revela deck plan.
73
+
74
+ Goal:
75
+ - Build canonical deck-plan.md directly from the user's goal, reviewed local materials, saved research findings, and active design vocabulary.
76
+ - Do not create, read, repair, or require revela-narrative/.
77
+ - Use sourceLinks in deck-plan.md to reference material paths, material review files, research findings, asset paths, URLs, and caveats. These are source links, not narrative graph links.
78
+ - Use "unresolved inputs", "research tasks", "source limitations", or "caveats"; do not use the product concept of research gaps.
79
+ - Do not write HTML during planning.
80
+
81
+ Current state:
82
+ - ${state}
83
+ ${workspaceRoot ? `- Current workspace root: \`${workspaceRoot}\`` : ""}
84
+
85
+ Workflow:
86
+ 1. Call material intake tools as needed: prepare/check local materials, read extracted read views, and record material reviews for sources you rely on.
87
+ 2. Inspect existing researches/**/*.md, assets/, and deck-plan.md when present. Save new external findings with revela-research-save.
88
+ 3. Ask only for missing high-impact intent: audience, objective, decision/action, language, rough slide count, or source priority.
89
+ 4. Read active design inventory/rules before selecting layouts/components.
90
+ 5. Write deck-plan.md with deck objective, audience, output format, chapter outline, source authority, unresolved inputs, and an ordered slide plan.
91
+ 6. For every slide block, include positive 1-based slideIndex, title, chapter, purpose, layout, component plan, visual intent, sourceLinks, caveats, and speaker/content notes.
92
+ 7. Include Cover, Table of Contents, and Closing slides unless the user explicitly asks for a non-standard artifact.
93
+ 8. Run/read deck-plan diagnostics after writing and report technical issues separately from source limitations.
94
+
95
+ Report:
96
+ - Start with "Deck plan: drafted" or "Deck plan: updated".
97
+ - List deck-plan.md, chapter ranges, slide count, source/research files used, unresolved inputs, and the next command /revela make --deck.
98
+ - Do not ask for approval gates; users decide whether to proceed.`
99
+ }
100
+
101
+ export function buildDeckMakePrompt({
102
+ exists,
103
+ workspaceRoot,
104
+ }: {
105
+ exists: boolean
106
+ workspaceRoot?: string
107
+ }): string {
108
+ const state = exists
109
+ ? "Legacy/cache state exists. Do not treat it as workflow authority."
110
+ : "No legacy/cache state exists. Continue from deck-plan.md and artifact files."
111
+
112
+ return `Generate a Revela HTML deck from deck-plan.md.
113
+
114
+ Goal:
115
+ - Read the current deck-plan.md projection and generate or update decks/*.html.
116
+ - Do not create, compile, or require revela-narrative/.
117
+ - Use the deck-render prompt mode for design, layout, components, HTML, QA, and export preflight.
118
+ - Preserve source links and caveats from deck-plan in slide source notes or speaker notes where appropriate.
119
+
120
+ Current state:
121
+ - ${state}
122
+ ${workspaceRoot ? `- Current workspace root: \`${workspaceRoot}\`` : ""}
123
+
124
+ Workflow:
125
+ 1. Read deck-plan.md and treat it as the execution blueprint.
126
+ 2. If deck-plan.md is missing or structurally invalid, stop and tell the user to run /revela plan --deck.
127
+ 3. For a new deck, call revela-deck-foundation before adding slide content.
128
+ 4. Read active design rules and needed layouts/components before patching HTML.
129
+ 5. Generate chapter by chapter. Keep the HTML valid after every write and preserve existing completed slides.
130
+ 6. Each slide must have unique increasing 1-based data-slide-index, a 1920x1080 .slide-canvas, no text overflow, and no unsafe remote asset references.
131
+ 7. Run Artifact QA after writes and fix hard errors before reporting ready.
132
+
133
+ Report:
134
+ - Start with "Deck handoff: generated" or "Deck handoff: updated".
135
+ - Include output path, slide count, deck-plan.md path, current chapters generated, Artifact QA status, and next command /revela review --deck or /revela export --deck pdf|pptx|png.
136
+ - Report unresolved inputs as source limitations, not workflow blockers.`
137
+ }
138
+
61
139
  export function buildDeckPrompt({
62
140
  exists,
63
141
  workspaceRoot,
@@ -74,7 +152,7 @@ export function buildDeckPrompt({
74
152
  Goal:
75
153
  - Treat this as the explicit transition from canonical narrative state to user-directed deck planning.
76
154
  - Use the deck-render prompt mode for design, layout, component, HTML, QA, and deck artifact rules.
77
- - Default behavior is two-stage: first generate or update \`deck-plan/index.md\` plus \`deck-plan/slides/*.md\` with low-fidelity layout sketches and narrative wikilinks, then proceed only when the user chooses to continue.
155
+ - Default behavior is two-stage: first generate or update \`deck-plan.md\` with ordered slide blocks, low-fidelity layout notes, sourceLinks, and caveats, then proceed only when the user chooses to continue.
78
156
  - Every deck plan must include Cover, Table of Contents, and Closing slides. The TOC must show 3-5 chapter headings that match the deck's slide groups.
79
157
  - Do not write or overwrite \`decks/*.html\` until the user chooses to proceed from the current deck-plan projection.
80
158
  - Do not treat legacy \`writeReadiness.status\`, old review snapshots, approval fields, or existing HTML decks as workflow permission.
@@ -91,12 +169,12 @@ Workflow:
91
169
  4. Call \`revela-decks\` action \`compileDeckPlan\`. This returns a claim/evidence planning packet plus deck-plan authoring requirements; it must not write HTML and does not generate the final slide list. Do not infer render structure from \`DECKS.json.slides[]\`.
92
170
  5. If \`compileDeckPlan\` returns \`skipped\`, report the reason and ask the user whether to continue manually, repair narrative files, or provide missing intent.
93
171
  6. If target slide count, audience, language, output purpose, or visual style is unclear, ask the user for the smallest needed confirmation before writing the plan.
94
- 7. Write \`deck-plan/index.md\` and one file per planned slide under \`deck-plan/slides/*.md\` from the planning packet and requirements. The index must identify the chapter structure first: 3-5 chapter headings, each chapter's slide range, and which non-structural slides belong to each chapter. Each slide file must include frontmatter with positive 1-based \`slideIndex\` and \`## Narrative Links\` using plain wikilinks to canonical claim/evidence/risk/objection/gap ids. Include a low-fidelity ASCII/text layout sketch for every slide; do not generate visual images or HTML mockups.
172
+ 7. Write \`deck-plan.md\` directly from the planning packet and requirements. Do not use structured upsert tools for normal plan authoring. It must identify the chapter structure first: 3-5 chapter headings, each chapter's slide range, and which non-structural slides belong to each chapter. Each slide block must include positive 1-based \`slideIndex\`, layout, component plan, \`sourceLinks\` for materials/findings/assets/URLs/caveats, and low-fidelity render notes. Do not generate visual images or HTML mockups during planning.
95
173
  8. Stop after presenting the plan unless the user already asked to proceed. Ask whether to continue, revise the plan, or run more research. Do not require an Approval block or \`confirmDeckPlan\` gate; \`confirmDeckPlan\` is compatibility/provenance only.
96
174
  9. Ask for or confirm visual design only after the narrative deck plan exists. For a new deck HTML file, call \`revela-deck-foundation\` first to create the active-design foundation shell; it must not create narrative slide content, choose layouts/components, or read/write \`${DECKS_STATE_FILE}\`.
97
175
  10. Fetch active design rules plus required layouts/components with \`revela-designs read\` as needed before patching slides into the foundation shell. Fetch chart rules before ECharts.
98
- 11. Do not update cached \`DECKS.json\` slide specs for plan authoring. Use \`deck-plan/\` files and artifact files as the execution surface.
99
- 12. Call \`revela-decks\` action \`readDeckPlan\` before artifact review or HTML writing; use it to inspect the current deck-plan projection without regenerating it. Treat stale hashes, missing links, or incomplete coverage as advisory diagnostics unless the user asks to stop.
176
+ 11. Do not update cached \`DECKS.json\` slide specs for plan authoring. Use \`deck-plan.md\` and artifact files as the execution surface.
177
+ 12. Call \`revela-decks\` action \`readDeckPlan\` before artifact review or HTML writing; use it as QA/diagnostics for the current deck-plan projection, not as a writer or regeneration step. Treat stale hashes, missing links, or incomplete coverage as advisory diagnostics unless the user asks to stop.
100
178
  13. Run artifact diagnostics when useful, but do not treat \`writeReadiness\`, cached slide specs, unconfirmed plans, missing research, or stale coverage as workflow blockers.
101
179
  14. Write \`decks/*.html\` when the user chooses to proceed and all deck HTML contract requirements can be satisfied. For new files, patch slide sections between the \`revela-slides\` markers created by \`revela-deck-foundation\`. Generate the artifact chapter by chapter instead of drafting all content slides in one broad pass. Partial decks are allowed during chapter-by-chapter authoring when written slide sections have unique, increasing 1-based \`data-slide-index\` values and valid canvases; do not pad missing planned chapters with filler to match cached \`DECKS.json.slides[]\` length. Keep the HTML file valid after every write, preserve already-written slides, and update one chapter's slide sections at a time.
102
180
  15. For each chapter, make every content slide carry a distinct claim, evidence item, comparison, risk, or action. If a chapter lacks enough substance for its allocated slides, merge weak slides or reduce the slide count instead of creating sparse filler.
@@ -107,11 +185,11 @@ Deck plan report format:
107
185
  - Include narrative readiness status and narrative hash when available.
108
186
  - Include Markdown QA repair cards and vault diagnostic warnings when returned by \`read(summary: true)\`; user decides whether to repair before planning unless the file is malformed or unsafe to write.
109
187
  - Include whether \`compileDeckPlan\` prepared the planning packet or skipped.
110
- - Include the plan artifact paths \`deck-plan/index.md\` and \`deck-plan/slides/*.md\`, and explain that the LLM-authored plan is advisory render-layer projection state.
188
+ - Include the plan artifact path \`deck-plan.md\`, and explain that the LLM-authored plan is advisory render-layer projection state.
111
189
  - Include the required Source Authority and remind that \`DECKS.json.slides[]\` is cache/compatibility data, not the render contract.
112
190
  - Include \`Required structure: Cover + Table of Contents + Closing\` and do not omit any of those slides.
113
191
  - Include a \`Chapters\` section before the slide list. It must list 3-5 TOC headings, their slide ranges, and the non-structural slides assigned to each chapter.
114
- - For every slide file, include: slide index, title, purpose, narrative role, low-fidelity layout sketch, layout, components, primary/supporting claim ids, evidence binding ids or source summary, visual intent, visual brief, caveats/unsupported scope, and \`## Narrative Links\`.
192
+ - For every slide block, include: slide index, title, purpose, narrative role, low-fidelity layout note, layout, components, sourceLinks, visual intent, visual brief, caveats/unsupported scope, and render notes.
115
193
  - Use this sketch style or similarly simple ASCII boxes:
116
194
 
117
195
  \`\`\`text
@@ -142,27 +220,27 @@ Caveats / unsupported scope:
142
220
  Report format before any HTML write:
143
221
  - Start with \`Deck handoff: <status>\`.
144
222
  - Include which deck-plan projection and narrative hash are guiding artifact work.
145
- - State that \`revela-decks readDeckPlan\` was called and the current \`deck-plan/\` Chapter Writing Batches are being followed.
223
+ - State that \`revela-decks readDeckPlan\` was called and the current \`deck-plan.md\` slide order/chapter groups are being followed.
146
224
  - For new HTML files, state that \`revela-deck-foundation\` created the foundation shell and identify the output path/design before slide content is patched.
147
225
  - Include the chapter currently being generated and confirm already-written slides are being preserved.
148
226
  - If technical artifact checks cannot be satisfied, list those blockers separately from narrative/deck-plan diagnostics.
149
227
  - After writing HTML, read the appended \`Artifact QA\` report from the tool output. If it failed, fix hard errors before considering the deck ready for Review.
150
228
 
151
229
  Rules:
152
- - \`compileDeckPlan\` prepares the canonical narrative claim/evidence packet and deck-plan requirements. The LLM authors \`deck-plan/index.md\` and \`deck-plan/slides/*.md\` from that packet and asks the user for page count, audience, language, output purpose, or visual style when unclear.
153
- - \`deck-plan/\` is the execution blueprint for HTML generation when present. It must be read before writing HTML and followed chapter by chapter; \`DECKS.json.slides[]\` is compatibility/cache data, not the HTML slide-count authority.
230
+ - \`compileDeckPlan\` prepares compatibility planning context when available. The LLM authors \`deck-plan.md\` from user intent, source materials, research findings, and active design vocabulary.
231
+ - \`deck-plan.md\` is the execution blueprint for HTML generation when present. It must be read before writing HTML and followed chapter by chapter; legacy \`deck-plan/\` files are read-compatible fallback inputs only. \`DECKS.json.slides[]\` is compatibility/cache data, not the HTML slide-count authority.
154
232
  - \`revela-deck-foundation\` is the file-native foundation helper for new deck shells. Use it before adding slides to a new \`decks/*.html\` file; do not use \`DECKS.json\` or \`revela-decks\` to create the shell.
155
233
  - Visual intent is part of the deck-plan projection. During HTML generation, satisfy the planned component/visual brief using fetched design components; do not collapse planned visuals into prose-only bullets.
156
234
  - Cached deck slide specs in \`DECKS.json\` are legacy projections only. Canonical narrative remains the authority for audience, decision, claims, evidence boundaries, objections, and risks.
157
235
  - Cover, Table of Contents, and Closing are mandatory deck structure. TOC chapter headings must match the chapter grouping used for generation.
158
236
  - Do not generate the complete deck content in one broad pass. Work chapter by chapter while keeping the artifact valid after each write.
159
237
  - Applying evidence candidates or rewriting canonical claims requires explicit user instruction.
160
- - If the user requests slide order, layout, component, or visual-intent changes that do not alter meaning, update only the \`deck-plan/\` projection or artifact-level plan content.
238
+ - If the user requests slide order, layout, component, or visual-intent changes that do not alter meaning, update only \`deck-plan.md\` or artifact-level plan content.
161
239
  - If the user requests claim, evidence, caveat, decision, or recommendation meaning changes, update canonical narrative first, then report alignment diagnostics before compiling a new deck plan.
162
240
  - Do not store secrets, credentials, tokens, or sensitive personal information.
163
241
  - Artifact QA requires each slide to render exactly 1920x1080px, not merely any 16:9 ratio. It also checks component compliance, text overflow/clipping, page scrollbars, and whether normal QA-enabled content slides have enough claim/evidence/source substance.
164
242
 
165
- Start now by reading canonical narrative files, reporting diagnostics, compiling the planning packet, then writing or updating the \`deck-plan/\` projection with low-fidelity layout sketches and narrative wikilinks. Do not create ${DECKS_STATE_FILE} as workflow state.`
243
+ Start now by reading canonical narrative files, reporting diagnostics, compiling the planning packet, then writing or updating \`deck-plan.md\` with low-fidelity layout sketches and sourceLinks. Do not create ${DECKS_STATE_FILE} as workflow state.`
166
244
  }
167
245
 
168
246
  export function buildDeckReviewPrompt({
@@ -179,8 +257,8 @@ export function buildDeckReviewPrompt({
179
257
  return `Review Revela deck/artifact write readiness.
180
258
 
181
259
  Goal:
182
- - Review the current deck artifact and \`deck-plan/\` projection directly. ${DECKS_STATE_FILE}, when present, is legacy/cache state only.
183
- - When \`deck-plan/\` exists, treat it as the deck execution blueprint for slide order, chapter batches, visual intent, and evidence trace.
260
+ - Review the current deck artifact and \`deck-plan.md\` directly. ${DECKS_STATE_FILE}, when present, is legacy/cache state only.
261
+ - When \`deck-plan.md\` exists, treat it as the deck execution blueprint for slide order, chapter batches, visual intent, and evidence trace.
184
262
  - Treat this as artifact diagnostics, not workflow permission. Narrative, research, and deck-plan gaps are warnings unless they are malformed/unsafe files.
185
263
  - Do not create or update ${DECKS_STATE_FILE}; use file-native sources and explicit artifact paths.
186
264
  - Use technical blockers only for missing/ambiguous deck files, invalid HTML contract, invalid slide identity, canvas/overflow/export failures, malformed vault frontmatter, or unsafe writes.
@@ -204,7 +282,7 @@ Workspace boundary rules:
204
282
 
205
283
  Workflow:
206
284
  1. Resolve the deck artifact from an explicit user path or discover \`decks/*.html\` when unambiguous.
207
- 2. Read \`deck-plan/\` with \`readDeckPlan\` when present and report stale hashes, missing links, missing coverage, or slide-index issues as diagnostics.
285
+ 2. Read \`deck-plan.md\` with \`readDeckPlan\` when present and report stale hashes, missing links, missing coverage, or slide-index issues as diagnostics.
208
286
  3. Run HTML contract and Artifact QA checks for the artifact when the user is preparing to write, review, or export.
209
287
  4. Report evidence/source/narrative risks as diagnostics. Do not bind evidence, rewrite narrative, or update cached slide specs unless the user explicitly asks.
210
288
  5. If a technical blocker exists, report the exact blocker and smallest repair. Otherwise say the user can proceed and list residual diagnostics.
@@ -703,7 +703,7 @@ export function evaluateDeckStateWriteReadiness(state: DecksState, filePath: str
703
703
  type: "missing_slide_spec",
704
704
  severity: "warning",
705
705
  message: warning,
706
- suggestedAction: "Proceed from the file-native deck-plan/ projection or explicit user request; DECKS.json deck records are not required for artifact writing.",
706
+ suggestedAction: "Proceed from the file-native deck-plan.md or explicit user request; deck records are not required for artifact writing.",
707
707
  }],
708
708
  }
709
709
  }
@@ -798,7 +798,7 @@ export function buildDecksStatePromptLayer(workspaceRoot: string, maxChars = 140
798
798
  }
799
799
  let text = JSON.stringify(compact, null, 2)
800
800
  if (text.length > maxChars) text = text.slice(0, maxChars).trimEnd() + "\n[DECKS.json state truncated for prompt size.]"
801
- return `---\n\n# Revela Workspace State From ${DECKS_STATE_FILE}\n\n\`\`\`json\n${text}\n\`\`\`\n\nRules for this state layer:\n- Treat ${DECKS_STATE_FILE} as compatibility/render state: workspace context, active output path, render targets, reviews, readiness, provenance, artifact coverage, and cached projections.\n- Do not treat ${DECKS_STATE_FILE} \`slides[]\` as the authoritative HTML slide-count, slide-order, or slide-content contract. When \`deck-plan/\` exists, use \`deck-plan/index.md\` and \`deck-plan/slides/*.md\` as the deck execution blueprint for HTML generation/remake.\n- The decks map is compatibility storage; operate only on the current workspace deck.\n- HTML slide identity is artifact self-consistency: each \`<section class="slide">\` needs a positive 1-based \`data-slide-index\`, indexes must be unique and strictly increase in DOM order, and 0-based \`data-index\` is never canonical identity. Cached ${DECKS_STATE_FILE} \`slides[].index\` values are diagnostic context only.\n- The active HTML deck is represented as a \`renderTarget\` of type \`html_deck\`; PDF/PPTX exports should be recorded as derived render targets, not as separate deck specs.\n- \`writeReadiness\` and \`planReview\` are compatibility projections for the /revela make --deck generation workflow, not hard blockers for targeted artifact-level HTML fixes.\n- Do not edit ${DECKS_STATE_FILE} directly; use the revela-decks tool.\n- For /revela make --deck generated HTML, use the current deck's outputPath, read \`deck-plan/\` when present, and satisfy the deck HTML contract without padding missing chapters just to match cached ${DECKS_STATE_FILE} \`slides[]\`. Deck-plan diagnostics are advisory; for targeted artifact-level edits, patch the requested deck HTML directly without treating \`writeReadiness\` or \`planReview\` as a precondition.`
801
+ return `---\n\n# Revela Workspace State From ${DECKS_STATE_FILE}\n\n\`\`\`json\n${text}\n\`\`\`\n\nRules for this state layer:\n- Treat ${DECKS_STATE_FILE} as compatibility/render state: workspace context, active output path, render targets, reviews, readiness, provenance, artifact coverage, and cached projections.\n- Do not treat ${DECKS_STATE_FILE} \`slides[]\` as the authoritative HTML slide-count, slide-order, or slide-content contract. When \`deck-plan.md\` exists, use it as the deck execution blueprint for HTML generation/remake. Legacy \`deck-plan/index.md\` and \`deck-plan/slides/*.md\` are read-compatible fallback inputs only.\n- The decks map is compatibility storage; operate only on the current workspace deck.\n- HTML slide identity is artifact self-consistency: each \`<section class="slide">\` needs a positive 1-based \`data-slide-index\`, indexes must be unique and strictly increase in DOM order, and 0-based \`data-index\` is never canonical identity. Cached ${DECKS_STATE_FILE} \`slides[].index\` values are diagnostic context only.\n- The active HTML deck is represented as a \`renderTarget\` of type \`html_deck\`; PDF/PPTX exports should be recorded as derived render targets, not as separate deck specs.\n- \`writeReadiness\` and \`planReview\` are compatibility projections for the /revela make --deck generation workflow, not hard blockers for targeted artifact-level HTML fixes.\n- Do not edit ${DECKS_STATE_FILE} directly; use the revela-decks tool.\n- For /revela make --deck generated HTML, use the current deck's outputPath, read \`deck-plan.md\` when present, and satisfy the deck HTML contract without padding missing chapters just to match cached ${DECKS_STATE_FILE} \`slides[]\`. Deck-plan diagnostics are advisory; for targeted artifact-level edits, patch the requested deck HTML directly without treating \`writeReadiness\` or \`planReview\` as a precondition.`
802
802
  }
803
803
 
804
804
  function compactWorkspaceForPrompt(workspace: DecksState["workspace"]): DecksState["workspace"] {
@@ -968,7 +968,7 @@ function computeDeckReadinessIssues(state: DecksState, deck: DeckSpec, options:
968
968
  issues.push(warningIssue(
969
969
  "missing_slide_spec",
970
970
  `outputPath must be decks/*.html, got ${deck.outputPath || "missing"}`,
971
- "Resolve output path from the user request, deck-plan/index.md, or a deterministic decks/*.html default instead of treating cached state as permission.",
971
+ "Resolve output path from the user request, deck-plan.md, or a deterministic decks/*.html default instead of treating cached state as permission.",
972
972
  ))
973
973
  }
974
974
 
@@ -985,14 +985,14 @@ function computeDeckReadinessIssues(state: DecksState, deck: DeckSpec, options:
985
985
  issues.push(warningIssue(
986
986
  "slide_plan_unconfirmed",
987
987
  planReview.stale ? `Deck plan confirmation is stale: ${planReview.reason}` : `Deck plan is not confirmed: ${planReview.reason}`,
988
- "Write or read deck-plan/ projection Markdown if useful, then decide whether to continue. This is advisory and does not block artifact work.",
988
+ "Write or read deck-plan.md if useful, then decide whether to continue. This is advisory and does not block artifact work.",
989
989
  ))
990
990
  }
991
991
  issues.push(...deckPlanQualityIssues(deck))
992
992
  issues.push(...artifactCoverageIssues(state, deck))
993
993
  for (const slide of deck.slides) {
994
994
  const slideRef = { slideIndex: slide.index, slideTitle: slide.title }
995
- if (!slide.title.trim()) issues.push(warningIssue("missing_slide_spec", `Cached slide ${slide.index} title is missing`, "Use deck-plan/ and artifact content as source for rendering; cached slide specs are diagnostics only.", slideRef))
995
+ if (!slide.title.trim()) issues.push(warningIssue("missing_slide_spec", `Cached slide ${slide.index} title is missing`, "Use deck-plan.md and artifact content as source for rendering; cached slide specs are diagnostics only.", slideRef))
996
996
  if (!slide.layout.trim()) issues.push(warningIssue("missing_slide_spec", `Cached slide ${slide.index} layout is missing`, "Fetch needed design layouts before writing HTML, but do not block solely on cached slide specs.", slideRef))
997
997
  if (slide.components.length === 0) issues.push(warningIssue("missing_slide_spec", `Cached slide ${slide.index} components are missing`, "Fetch needed design components before writing HTML, but do not block solely on cached slide specs.", slideRef))
998
998
  if (!hasSlideContent(slide)) issues.push(warningIssue("missing_slide_spec", `Cached slide ${slide.index} content is missing`, "Use deck-plan/ and the artifact request as render guidance; cached slide specs are diagnostics only.", slideRef))
@@ -1080,7 +1080,7 @@ function artifactCoverageIssues(state: DecksState, deck: DeckSpec): ReadinessIss
1080
1080
  issues.push(warningIssue(
1081
1081
  "artifact_coverage",
1082
1082
  `Active deck plan is missing required narrative claims: ${coverage.missingClaimIds.join(", ")}`,
1083
- "Coverage gaps are diagnostic; revise deck-plan/ or proceed with the visible limitation if the user chooses.",
1083
+ "Coverage gaps are diagnostic; revise deck-plan.md or proceed with the visible limitation if the user chooses.",
1084
1084
  ))
1085
1085
  }
1086
1086
  if (coverage.coverageStatus === "stale") {
@@ -1136,7 +1136,7 @@ function readinessNextActions(issues: ReadinessIssue[], coverage?: ArtifactCover
1136
1136
  const actions = issues
1137
1137
  .filter((issue) => issue.severity === "blocker" || issue.type === "plan_quality" || issue.type === "artifact_coverage")
1138
1138
  .map((issue) => issue.suggestedAction)
1139
- if (coverage?.missingClaimIds.length) actions.unshift("Review missingClaimIds in artifactCoverage and decide whether to revise deck-plan/ or continue with the current artifact.")
1139
+ if (coverage?.missingClaimIds.length) actions.unshift("Review missingClaimIds in artifactCoverage and decide whether to revise deck-plan.md or continue with the current artifact.")
1140
1140
  if (coverage?.coverageStatus === "stale") actions.unshift("Artifact coverage is stale; decide whether to remake, review, or export the current artifact.")
1141
1141
  return [...new Set(actions)].slice(0, 5)
1142
1142
  }
@@ -523,11 +523,17 @@ export interface DesignInventoryLayout {
523
523
  name: string
524
524
  qa: boolean
525
525
  description: string
526
+ slots: string[]
526
527
  }
527
528
 
528
529
  export interface DesignInventoryComponent {
529
530
  name: string
530
531
  description: string
532
+ nesting: {
533
+ role: "container" | "content" | "fullbleed" | "utility"
534
+ acceptsChildren: boolean
535
+ allowedChildren?: string[]
536
+ }
531
537
  }
532
538
 
533
539
  export interface DesignInventory {
@@ -665,15 +671,53 @@ export function getDesignInventory(designName?: string): DesignInventory {
665
671
  name: layoutName,
666
672
  qa: layout.qa,
667
673
  description: designBlockDescription(layout.content),
674
+ slots: inferLayoutSlots(layoutName, layout.content),
668
675
  })),
669
676
  components: Object.entries(components).map(([componentName, content]) => ({
670
677
  name: componentName,
671
678
  description: designBlockDescription(content),
679
+ nesting: inferComponentNesting(componentName),
672
680
  })),
673
681
  hasMarkers,
674
682
  }
675
683
  }
676
684
 
685
+ function inferLayoutSlots(name: string, content: string): string[] {
686
+ const slots = new Set<string>()
687
+ const known = ["fullbleed", "left", "right", "top", "bottom", "main", "footer", "content", "overlay", "center"]
688
+ for (const slot of known) {
689
+ if (new RegExp(`\\b${slot}\\s+slot\\b|\\[slot:\\s*${slot}\\]|slot:\\s*\`${slot}\`|slot:\\s*${slot}\\b`, "i").test(content)) slots.add(slot)
690
+ }
691
+ for (const match of content.matchAll(/\[slot:\s*([a-z0-9-]+)\]/gi)) slots.add(match[1])
692
+ for (const match of content.matchAll(/\b(each|slot)\s+slot\b/gi)) {
693
+ if (match[0]) {
694
+ // highlight-cols and similar layouts use numbered peer slots in examples.
695
+ if (/highlight|cols|columns/i.test(name)) ["1", "2", "3", "4", "5"].forEach((slot) => slots.add(slot))
696
+ }
697
+ }
698
+ if (slots.size === 0) {
699
+ if (name === "fullbleed") slots.add("fullbleed")
700
+ else if (name === "halves" || name === "narrative" || name === "narrative-reverse") ["left", "right"].forEach((slot) => slots.add(slot))
701
+ else if (name === "stacked") ["top", "bottom"].forEach((slot) => slots.add(slot))
702
+ else if (name === "highlight-cols") ["1", "2", "3", "4", "5"].forEach((slot) => slots.add(slot))
703
+ else slots.add("main")
704
+ }
705
+ return [...slots]
706
+ }
707
+
708
+ function inferComponentNesting(name: string): DesignInventoryComponent["nesting"] {
709
+ if (name === "box") {
710
+ return {
711
+ role: "container",
712
+ acceptsChildren: true,
713
+ allowedChildren: ["text-panel", "media", "echart-panel", "data-table", "stat-card", "quote", "steps", "roadmap-horizontal", "roadmap-vertical", "toc"],
714
+ }
715
+ }
716
+ if (name === "hero") return { role: "fullbleed", acceptsChildren: false }
717
+ if (name === "page-number" || name === "brand-watermark") return { role: "utility", acceptsChildren: false }
718
+ return { role: "content", acceptsChildren: false }
719
+ }
720
+
677
721
  function designBlockDescription(body: string): string {
678
722
  const firstLine = body
679
723
  .split("\n")