Skip to content
Agentmart
Submit a tool

malloy-analysis-report

Combine validated Malloy queries into a report (a linear report, read top to bottom).

Skill by malloydata

IndexedMIT★ 118
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/malloydata-malloy-analysis-report

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Combine validated Malloy queries into a report (a linear report, read top to bottom). Use when the user asks to "create a report", "combine these into a report", or wants a persistent multi-query artifact.

Use cases: documents

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/malloy-analysis-report

What's inside

Skill name
malloy-analysis-report
Description
Combine validated Malloy queries into a report (a linear report, read top to bottom). Use when the user asks to "create a report", "combine these into a report", or wants a persistent multi-query artifact.
License
MIT
Instructions
191 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

<!--
Copyright (c) Credible Data Inc.
SPDX-License-Identifier: MIT
-->

# Creating Reports

An ad-hoc report is a Publisher **report** with `layout=linear`: a `.malloy` file at the package root, `<slug>.malloy` (unless the user asks for another location), that combines markdown narrative with live Malloy queries, as text tiles and query tiles read top to bottom. Load `skill:malloy-reports` for the full format and authoring rules; this skill covers when to build one and how to design good report content (tiles, chart annotations, narrative structure). Never write a new `.malloynb`, never write a report as bare `run:` statements (that older form is no longer read), and do not create a `notebooks/` or `dashboards/` directory for it.

## Before building a report

1. **Run each query first** via `execute_query` to verify it works and returns expected results.
2. **Explain the results** to the user as you go: walk through the analysis step by step.
3. **Then assemble the report** once the analysis is validated.

Do NOT build the report in the same turn as `execute_query`. Explain first, then build.

## Filters belong to the report, never to the source

An ad-hoc report usually needs no filters: it records an analysis already run. If the user wants one a reader can change (a manufacturer, a date range), declare the given in the report and bind it on its tiles, as `skill:malloy-reports` describes. Do not add a `given:` to the source for it: a model-level `where:` filters every read of the source, chat and every other report included, and the report builder can show such a filter but not change or remove it. A given the source already reads (a gate, a value every query must supply) shows in the report with no work, and stays in the model.

Never add a `#(filter)` annotation: it is deprecated, and every use has a `given:` form (`malloy-model` covers the migration).

## What goes in the report

Do NOT add an H1 heading in any markdown (use H2 and below for sections); the `title` in the `## artifact` tag serves as the title. To redo the structure rather than tweak one tile, rewrite the report file end-to-end.

Text tiles own narrative; query tiles own a single Malloy query whose chart annotation tells the renderer how to display the result. Markdown supports H2 headings, lists, bold, and inline code. Keep text tiles short, one idea per tile, so the rendered output reads as a story instead of a wall of text.

The file has four parts, in this order:

1. **The tag**, `##| artifact { layout=linear title="..." tiles=[…] }`, listing every tile in reading order. A text tile is `name { kind=text }`; a query tile is the quoted string `"<extension> -> <view>"`.
2. **The `import`** of the model file, relative to the report's own location (`"order_analysis.malloy"` from the package root).
3. **The text tiles**, each a `##|(markdown) name` block: the name on the opener line, the body on the lines below, `|##` closing it.
4. **One extension of the source**, `source: <source>_tiles is <source> extend { … }`, holding a `view:` per query tile. The view's chart tag and `# label="…"` (the tile's heading) go directly above it.

Compile the file with `/compile` (`"scope": "file"`, at the path `<slug>.malloy`) before saving; a report compiles as a model, so its errors come back there. After saving and reloading, read the package warnings: a tile that names a missing view is reported there, not by the compile. A complete report:

```malloy
##| artifact { layout=linear title="Sales report"
  tiles=[
    overview { kind=text },
    "order_analysis_tiles -> headline",
    trend { kind=text },
    "order_analysis_tiles -> revenue_by_month",
    breakdown { kind=text },
    "order_analysis_tiles -> top_categories",
    takeaways { kind=text }
  ]
}
|##
import "order_analysis.malloy"

##|(markdown) overview
## Overview
What is driving sales, and which categories carry it? The tiles below cover every order in the model.
|##

##|(markdown) trend
## Trend
How does revenue move over time?
|##

##|(markdown) breakdown
## Breakdown
Which categories account for the most revenue?
|##

##|(markdown) takeaways
## Key takeaways
What to look at next.
|##

source: order_analysis_tiles is order_analysis extend {
  # big_value
  # label="Headline"
  view: headline is {
    aggregate:
      # label="Revenue"
      # currency
      total_revenue

      # label="Orders"
      # number=auto
      order_count
  }

  # line_chart
  # label="Revenue by month"
  view: revenue_by_month is {
    group_by: order_date.month
    aggregate: total_revenue
    order_by: 1
  }

  # bar_chart
  # label="Top ten categories by revenue"
  view: top_categories is {
    group_by: category
    aggregate: total_revenue
    order_by: total_revenue desc
    limit: 10
  }
}
```

When the model already has the view you want, the tile view refines it rather than repeating it: `view: top_categories is by_category + { limit: 10 }`.

A well-structured report typically follows this pattern:

```
[Text]   ## Overview: what question are we answering, what data is in scope (date range, entity count)
[Query]  KPI tile: headline numbers (e.g., # big_value, or # dashboard with nested # big_value views)
[Text]   ## Trend: describe what we should look for over time
[Query]  Time-series tile (e.g., # line_chart on a date dimension)
[Text]   ## Breakdown: where the signal is
[Query]  Categorical tile (e.g., # bar_chart on a categorical dimension)
[Text]   ## Key takeaways: what the user should walk away with
```

From malloydata/publisher, MIT.

More from malloydata/publisher

Signals

Stars
118
Forks
31
Open issues
106
Last commit (this folder)
Oct 14, 2026 (12 days ago)
Last release
Oct 18, 2026 (8 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from malloydata

Cite this page

malloy-analysis-report skill. Agent Mart. https://agentmart.dev/skills/malloydata-malloy-analysis-report (last updated 2026-10-24)