agentleFS
fourteenwmfourteenwm/ppc-ai-skills/markdown-to-sheets-presenter/SKILL.md

markdown-to-sheets-presenter

Skill72 starsChanged 4 months agoMITView on GitHub

Transforms markdown reports into professionally formatted Google Sheets for client presentation. Auto-invoke when user wants to make a report presentable, share analysis with clients, convert markdown to Sheets, or export competitive analysis. Triggers include "make this presentable", "create a Google Sheet", "export to sheets", "format for client".

  • Installs packages

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 6 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    When triggered, identify the source:

    line 41
  2. Distinctive:

    If path provided: Use that path directly

    line 42
  3. Distinctive:

    If recent analysis in conversation: Use that content

    line 43
  4. Distinctive:

    If ambiguous: Ask user to specify

    line 44
  5. Distinctive:

    Document title and metadata

    line 49
  6. Very specific:

    Every presentation value — colors (with API-ready RGB decimals), typography tiers, conditional-formatting thresholds, row heights and …

    line 82
  7. Distinctive:

    Read it before composing any formatting call.

    line 86
  8. Very specific:

    Use the create_spreadsheet.py script from your project root (where google-ads.yaml lives):

    line 93

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Markdown to Google Sheets Presenter

Turn a markdown report (competitive analysis, ad recon, performance review) into a client-ready Google Sheet: multi-tab layout, themed formatting, conditional colors. The shipped script bootstraps the spreadsheet; everything the client actually sees is composed by the agent per references/presentation-contract.md's division of labor. Judgment calls — when to present vs hand over a CSV, theme handling, tab structure — live in rules.md.

What this skill deliberately does NOT do

  • Never edits report content. This is a formatting pass: numbers, ad copy, and quotes land verbatim, ad copy never truncates (rules, invariant 1). Wrong findings get fixed in the source report, not here.
  • Ships no converter. create_spreadsheet.py creates one header-formatted tab and exits — parsing, population, and conditional formatting are agent-composed API calls, not hidden code (contract).
  • No Drive operations. Sheets-only scope: the file lands in the Drive root of the authorized account and gets moved/shared manually.
  • Not a data pipeline. Recurring exports and re-import workflows belong to raw CSVs (rules.md § presenter vs raw CSV), not a presentation layer.

Prerequisites

  1. Credentials: google-ads.yaml at project root — see the google-ads-api-setup skill if you don't have one. The script reuses this same file's OAuth credentials for the Sheets API — its refresh token must carry the spreadsheets scope, which the setup skill's generator grants by default (token predates that? re-run the generator once)
  2. Python packages: pip install google-api-python-client google-auth pyyaml

Workflow

Step 1: Identify Input

When triggered, identify the source:

  • If path provided: Use that path directly
  • If recent analysis in conversation: Use that content
  • If ambiguous: Ask user to specify

Step 2: Parse Markdown Structure

Analyze the markdown to determine:

  • Document title and metadata
  • Section hierarchy (H1, H2, H3)
  • Tables with headers and data
  • Lists (bulleted, numbered, checkbox)
  • Scoring data (X/45, percentages, etc.)

Step 3: Determine Tab Structure

For Competitive Analysis / Ad Recon Reports:

SectionTab NameNotes
Executive SummarySummaryFirst tab, KPIs
Strategic AnalysisStrategic_Scores15-attribute scoring
Tactical ScanTactical_Scores7-attribute flags
Gap IdentificationGapsOpportunities list
Verified AnglesRecommendationsClient-ready angles
Per CompetitorCompetitor_[Name]If multiple competitors

For Performance Reports:

SectionTab NameNotes
OverviewDashboardKPI metrics
Campaign DataCampaignsMain data table
RecommendationsAction_ItemsNext steps

These are the standard maps. When to deviate — merging small sections, single-table reports, prose-only sources — is rules.md § table-structure judgment.

Step 4: Load the Theme

Every presentation value — colors (with API-ready RGB decimals), typography tiers, conditional-formatting thresholds, row heights and column widths — lives in templates/professional-blue-theme.json. Read it before composing any formatting call; don't improvise values inline. Client-brand variants are copies of that file (rules.md § theme judgment). What the file owns, block by block: references/presentation-contract.md.

Step 5: Create Google Sheet

Use the create_spreadsheet.py script from your project root (where google-ads.yaml lives):

python .claude/skills/markdown-to-sheets-presenter/scripts/create_spreadsheet.py "Report Name"

Pass --config path/to/google-ads.yaml if your credentials live elsewhere. The sheet is created in the Drive root of the authorized account — move it into a client folder in Drive afterward if needed. The script returns the spreadsheet ID and URL as JSON; use the ID for the data-population and formatting calls that follow.

Naming Convention:

[Client Name] - [Report Type] - [YYYY-MM-DD]
Example: "Example Client - Competitive Analysis - 2025-12-16"

Step 6: Populate and Format

The agent-composed pass (no shipped code — contract § division of labor): rename Data/add tabs per the Step 3 plan, write values, then format from the theme — header/subheader styling, alternating rows, conditional formatting on scores and status columns, column widths, number formats. Formatting decisions (truncation ban, currency and percentage handling, missing data as "—", large tables, chart placement) are rules.md's tables — apply them as you build.

Step 7: Return Results

Provide user with:

  1. Clickable Google Sheets link
  2. Summary of tabs created
  3. Data rows per tab

Output Format

## Google Sheet Created

**Sheet Name:** [Name]
**Link:** [URL]

### Tabs Created:
| Tab | Rows | Description |
|-----|------|-------------|
| Summary | 15 | Executive overview with KPIs |
| Strategic_Scores | 20 | 15-attribute competitive scoring |
| ... | ... | ... |

---
*Click the link above to open your Google Sheet.*

Error Handling

ErrorAction
No credentialsPoint at the google-ads-api-setup skill
403 / PERMISSION_DENIEDRefresh token predates the Sheets scope — re-run the api-setup generator once, paste the new refresh_token into google-ads.yaml
File not foundAsk user to verify path
API quotaSuggest waiting or manual copy
Parse failureFall back to raw text layout

Files

FilePurpose
SKILL.mdThis file — workflow + routing
rules.mdJudgment layer: presenter vs raw CSV, theme judgment, table structure, false alarms, escalation
examples.mdThree worked decisions incl. the asks this skill should decline
references/presentation-contract.mdThe script/agent division of labor, exact script behavior, the theme file's contract
SETUP.mdCredential setup + quick test + troubleshooting
scripts/create_spreadsheet.pyThe bootstrap: one spreadsheet, one formatted header row, JSON on stdout
templates/professional-blue-theme.jsonThe theme — single home of every presentation value, consumed by the agent (no script reads it)
README.mdUser-facing overview + install

After a Run

The Google Sheet is the artifact; nothing lands on local disk. The spreadsheet ID and URL print as JSON on stdout (contract) — capture them if you'll need the sheet programmatically later, because creation is never idempotent: re-running makes a second spreadsheet with the same name, and Drive allows that.

When to Load What

MomentLoad
Deciding sheet-vs-CSV, structuring tabs, themingrules.md
Exact script behavior, stdout/stderr contract, theme file blocksreferences/presentation-contract.md
First run, or the ask smells like a decline caseexamples.md
The input is a competitive analysiscompetitor-analysis-v2 produces it — its 15 strategic + 7 tactical scoring is what the Strategic/Tactical tab map was built for
The ask is machine-readable data, not presentationgoogle-ads-query — its CSVs are the re-import surface
The source skill already writes a Sheet nativelyUse it directly — e.g. account-diagnostic with --sheet-id; don't re-present a sheet
No credentials yet / 403 at the Sheets stepgoogle-ads-api-setup (SETUP.md has the short version)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.