skills/update-text-block/SKILL.md
Create or modify text blocks using update_text_block. Covers template syntax with variable references, LLM generation, and constrained outputs.
npx skillsauth add motleyai/agent-skills update-text-blockInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create or modify text blocks using the update_text_block MCP tool. Text blocks support variable substitution, LLM-generated content, and constrained outputs.
update_text_block with a user_prompt templateReturns: The resolved content of the text block.
The user_prompt supports:
{query_name} — substituted with query block results{Slide::Block} — pulls content from other slides{a + b}, {a / b}{percent(x)}, {currency(x)}, {integer(x)}, {number(x, decimals=N)}For full syntax details, see variable-reference-syntax.md.
{total_revenue}{Slide::Block} → {Sales::revenue_chart}{end_month} (universal), or any source-specific variable shown by get_doc_variablesget_doc_variables(doc_id=..., show_context_vars=true) to check available variables% after {variable} — use {percent(x)} instead{variable} must have a corresponding query block or context variablecall_llm=false, the default)Variables are replaced with their resolved values. No LLM is involved.
update_text_block(
location={doc_id: 42, slide_name: "Overview", block_name: "kpi_text"},
user_prompt="Revenue: {currency(total_revenue)}\nCustomers: {integer(active_customers)}\nGrowth: {percent(revenue_growth)}"
)
Use this when you have a fixed template and just need data values filled in.
call_llm=true)The LLM receives the resolved template (with variables already substituted) and generates content based on it.
update_text_block(
location={doc_id: 42, slide_name: "Summary", block_name: "analysis_text"},
user_prompt="Based on the following data, write a 2-sentence executive summary:\n\nRevenue: {currency(total_revenue)}\nGrowth: {percent(revenue_growth)}\nTop region: {top_region}\n\nChart data:\n{Revenue::revenue_chart}",
call_llm=true
)
Use this when you want the LLM to synthesize insights from data.
call_llm=true + allowed_outputs)The LLM must choose one of the specified outputs. Useful for conditional/dynamic content.
update_text_block(
location={doc_id: 42, slide_name: "Status", block_name: "trend_indicator"},
user_prompt="Based on the growth rate of {percent(revenue_growth)}, classify the trend.",
call_llm=true,
allowed_outputs=["Strong Growth", "Moderate Growth", "Stable", "Declining"]
)
Use this for status labels, categories, or any content that must be one of a fixed set of values.
Every reference in the template must exist before you call update_text_block. The block resolves immediately, so any {variable} that can't be found will cause a resolution failure.
{query_name} → call update_query_block first{Slide::Block} → the referenced slide/block must already have content{context_var} (e.g. {end_month}, or any source-specific key from get_doc_variables) → no setup needed if get_doc_variables lists itCreate query blocks first, then set the text template:
Create the data queries:
update_query_block(
parent_location={doc_id: 42, slide_name: "Overview", block_name: "summary_text"},
query_name="total_revenue",
prompt="Total revenue for the reporting period",
model_name="revenue"
)
update_query_block(
parent_location={doc_id: 42, slide_name: "Overview", block_name: "summary_text"},
query_name="customer_count",
prompt="Number of active customers",
model_name="customers"
)
Then set the template:
update_text_block(
location={doc_id: 42, slide_name: "Overview", block_name: "summary_text"},
user_prompt="In {end_month}, the business generated {currency(total_revenue)} in revenue across {integer(customer_count)} active customers."
)
update_text_block(
location={doc_id: 42, slide_name: "KPIs", block_name: "revenue_kpi"},
user_prompt="{currency(total_revenue)}"
)
update_text_block(
location={doc_id: 42, slide_name: "Performance", block_name: "metrics_text"},
user_prompt="**Performance — {end_month}**\n\n- Revenue: {currency(total_revenue)} ({percent(revenue_growth)} vs prior period)\n- Active users: {integer(active_users)}\n- Avg session duration: {number(avg_duration, decimals=1)} minutes"
)
update_text_block(
location={doc_id: 42, slide_name: "Insights", block_name: "chart_analysis"},
user_prompt="Analyze the revenue trend data below and provide 3 key insights as bullet points. Be concise — each bullet should be one sentence.\n\n{Revenue::revenue_chart}",
call_llm=true
)
update_text_block(
location={doc_id: 42, slide_name: "Status", block_name: "health_label"},
user_prompt="The customer's health score is {health_score} out of 100. Classify their status.",
call_llm=true,
allowed_outputs=["Healthy", "At Risk", "Critical"]
)
If the resolved text exceeds the element's size on the slide, the tool returns an overflow error. To fix:
behavior_if_query_failsControls what happens when a child query block fails to resolve:
"drop_slide" — The slide is silently skipped during export (useful for optional data)"fail_resolution" — Resolution raises an error (useful for required data)null (default) — Keeps the existing behavior unchangedupdate-query-block skilldevelopment
Create branded HTML presentations using structured slide specs. Outputs JSON DeckSpec instead of raw HTML — the server handles all rendering, styling, and viewport fitting.
data-ai
Create or modify table blocks using update_table_block. Covers template syntax, target_shape constraints, and table generation patterns.
data-ai
Create or modify numerical query blocks within text or table blocks using update_query_block. Queries provide data values referenced as {query_name} in parent templates.
data-ai
Create or modify charts using update_chart_block. Covers chart type selection, structured query and chart_details parameters, and verification with render_chart.