AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Cja Executive Briefing

skill-adobe-skills-cja-executive-briefing · by adobe

>

No reviews yet
0 installs
29 views
0.0% view→install

Install

$ agentstack add skill-adobe-skills-cja-executive-briefing

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-adobe-skills-cja-executive-briefing)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Cja Executive Briefing? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Executive Briefing (Customer Journey Analytics)

Produce a polished, leadership-ready performance document. Executives do not read data tables — they read narratives that answer "are we growing?", "what changed?", and "what do we do about it?"

This skill converts CJA data into a briefing that a VP or C-suite leader can read in under 3 minutes, with supporting data available for those who want to dig deeper.

Tone: business impact, not technical metrics. Write "Revenue grew 12% driven by a strong Paid Search week" not "metrics/revenue increased by 0.12 per metrics/sessions."


CJA MCP Tools Used

  • describeCja(DATAVIEW_CONTEXT_GUIDE) — understand the business context of the data view
  • listComponentUsage — identify the north-star and supporting KPIs
  • findMetrics — resolve user-specified or discovered metric IDs
  • findCalculatedMetrics — include custom business KPIs
  • runReport — pull KPI values for current and comparison period
  • searchDimensionItems — identify top driver dimension values

Phase 0 — Setup

  1. Call findDataViews to list available data views.
  2. If the user hasn't specified a data view, present the list and ask which to use.
  3. Call setDefaultSessionDataViewId with the chosen ID.
  4. Confirm the reporting period (default: last 7 days) and the audience for the briefing (executive, board, team lead).

Phase 1 — Establish Context

1.1 Load data view context

Call describeCja("DATAVIEW_CONTEXT_GUIDE") to understand:

  • What business the data view represents (e-commerce, media, SaaS, etc.)
  • The primary conversion event and revenue metric
  • Calendar conventions and timezone. Record these values — they are

inputs to every date computation in 1.2:

  • WEEK_START_DOW — day of week each week starts on (Sunday, Monday, …).

Default: Monday (ISO 8601) if the context guide doesn't specify.

  • FISCAL_YEAR_START_MONTH — month the fiscal year begins. Default:

January (calendar year) if the context guide doesn't specify.

  • TIMEZONE — for example, America/Los_Angeles.
  • CALENDAR_SOURCE — one of "context guide" (values came from describeCja),

"default fallback" (the context guide didn't expose them and you used the defaults above), or "user override" (the user explicitly specified them).

This context determines what counts as the "north-star metric" and what language to use in the narrative (e.g., "subscribers" vs "customers" vs "users").

1.2 Determine reporting period

Infer the period type from the user's request. Do not stop to ask — proceed immediately.

The principle

Two runs of this skill on the same data view, period type, and prompt MUST produce identical current and comparison date ranges. Determinism comes from (a) reading calendar conventions from 1.1 instead of improvising, and (b) applying the alignment rule for the period type without taste calls.

Period type → alignment rule

Pick exactly one period type from the user's request:

| User request | PERIOD_TYPE | Current period | Comparison period | |---|---|---|---| | "last week" / unspecified | weekly | Most recent full week ending before today, aligned to WEEK_START_DOW (exactly 7 days) | The week immediately before, same alignment | | "this month" / "MTD" | month-to-date | 1st of current month → today | 1st of prior month → same day-of-month as today | | "last month" | monthly | Prior full calendar month (1st → last day) | The month before that | | "this quarter" / "QTD" | quarter-to-date | Start of current fiscal quarter → today; fiscal quarters derived from FISCAL_YEAR_START_MONTH | Same days into the prior fiscal quarter | | "last quarter" / "Q[N]" | quarterly | Prior full fiscal quarter | The fiscal quarter before that | | Custom date range | custom | Use as specified | Equal-length window ending the day before current.startDate |

Universal invariants (must hold for every period type)

Before calling runReport, verify all six:

  1. `current.startDate T00:00:00",

endDate: "T00:00:00", dimensionIds: "variables/daterangeday", metricIds: "metrics/visits,metrics/orders11,metrics/revenue1,...", page: 0, limit: 1 ) runReport( startDate: "T00:00:00", endDate: "T00:00:00", dimensionIds: "variables/daterangeday", metricIds: "metrics/visits,metrics/orders11,metrics/revenue1,...", page: 0, limit: 1 )


Read `summaryData.filteredTotals` from each response — the values correspond to
the metrics in the order they were specified in `metricIds`.

Compute for each KPI:
- `current` value
- `prior` value
- `delta` = current − prior
- `pctChange` = delta / prior × 100
- `direction`: up / down / flat (using ±3% threshold)
- `polarity`: positive if higher is better, negative if lower is better
- `signal`: green (favorable), red (unfavorable), yellow (mixed/flat)

---

## Phase 4 — Find What Drove the Movement

For the 2 KPIs with the largest absolute % change, find the top driver:

Run current and prior period breakdown reports in parallel:

runReport( startDate: "", endDate: "", dimensionIds: "variables/marketingchannel", metricIds: "", limit: 5 ) runReport( startDate: "", endDate: "", dimensionIds: "variables/marketingchannel", metricIds: "", limit: 5 )


Compare channel-level values between periods to find which dimension value's delta
most closely mirrors the overall metric change. This becomes the "driven by" phrase
in the narrative.

Only run dimension breakdowns for the 2 most-moved metrics (by absolute % change).
This constraint exists because: (a) more breakdowns add latency without adding
executive value, and (b) the two largest movers are what leadership will ask about
first. The remaining KPIs get context from the narrative without needing attribution.

If `variables/marketing_channel` returns no useful breakdown (e.g., only one
channel has data), try `variables/page_type` or `variables/product_category`
as alternative driver dimensions.

---

## Phase 5 — Write the Executive Narrative

Compose 3–5 bullet points as the narrative. Each bullet follows this structure:

**[Signal emoji] [Metric]: [Value] ([+/-pctChange%] vs [prior period]) — [Plain-English context]**

Guidelines:
- Open with the most important finding (highest-impact metric, positive or negative)
- Use business language: "revenue," "customers," "conversions" — not "metrics/revenue"
- Name the driver when known: "driven by Paid Search," "led by Product Page improvements"
- Include one forward-looking note if relevant: "This trend should be monitored..."
- For negative trends: be direct but not alarming. Suggest investigation, not panic.

Examples of well-written bullets:
- "Revenue reached $1.24M last week, up 8.2% vs prior week — Paid Search drove the majority of the gain (+$82K)."
- "Conversion Rate declined to 2.1% (−0.4pp), primarily on mobile. Desktop conversion remained stable at 3.4%."
- "Sessions were flat at 540K (+1.1%) — organic and direct traffic offset a reduction in email campaign sends."
- "Bounce Rate ticked up to 43% (+2pp). No single driver identified; worth monitoring through end of month."

---

## Phase 6 — Generate the HTML Briefing Document

Generate the briefing inline. Write to `/tmp/cja_executive_briefing_.html`.
This document should look polished enough to share with leadership — not a
developer tool output.

### Rendering rules — apply consistently across runs

Two runs of this skill on the same data view + period must render identically
(modulo the generation timestamp). The rules below pin the formatting choices
that the AI would otherwise drift on.

#### Number formatting

- **KPI values** (the big number in each tile) — use full digits with
  thousands separators (`8,160`, `77,584`, `1,250,000`). Do **NOT** use SI
  suffixes like `K` or `M`, even for large values. Executives want exact
  numbers, not abbreviations.
- **Percent change** (in pills and narrative bullets) — always one decimal
  place, rounded **half-away-from-zero**. For example, `−23.55%` displays as
  `−23.6%`, never `−23.5%`. Compute on full-precision values; round only at
  display time.
- **Percentage-point change** (for already-percentage metrics like Conversion
  Rate or Bounce Rate) — same rounding, suffix `pp`. Example: `+0.40 pp`.
- **Currency** — `$` prefix with thousands separators and no decimals for
  values ≥ $100 (`$1,240,000`); cents only when value 

Performance Briefing — {ORG_NAME} — {PERIOD}

  * { box-sizing: border-box; margin: 0; padding: 0; }
  :root {
    --bg: #f5f4f1;
    --surface: #ffffff;
    --ink: #1a1a1a;
    --ink-muted: #6b6b6b;
    --border: #e5e2dc;
    --header-bg: #0e0e10;
    --header-warm: #3a1010;
    --accent-red: #c8312f;
    --accent-red-bright: #ff6b68;
    --accent-red-soft: #fdecea;
    --accent-green: #1f7a4d;
    --accent-yellow: #d4a017;
  }
  body { font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
         background: var(--bg); color: var(--ink); line-height: 1.5;
         -webkit-font-smoothing: antialiased; }

  /* === Header === */
  header { background: linear-gradient(120deg, var(--header-bg) 0%, #1a0d0d 55%, var(--header-warm) 100%);
           color: #fff; padding: 56px 56px 44px; position: relative; overflow: hidden; }
  header::after { content: ""; position: absolute; right: -140px; top: -140px;
                  width: 460px; height: 460px;
                  background: radial-gradient(circle, rgba(200,49,47,.35) 0%, transparent 70%);
                  pointer-events: none; }
  .header-inner { max-width: 1080px; margin: 0 auto; position: relative; z-index: 1; }
  .eyebrow { display: inline-flex; align-items: center; gap: 8px;
             padding: 6px 14px; border: 1px solid rgba(255,107,104,.55);
             border-radius: 999px; color: var(--accent-red-bright);
             font-size: 11px; font-weight: 600; letter-spacing: 1.2px;
             text-transform: uppercase; margin-bottom: 24px;
             background: rgba(200,49,47,.10); }
  .eyebrow::before { content: ""; width: 6px; height: 6px;
                     background: var(--accent-red-bright); border-radius: 50%; }
  header h1 { font-family: "Playfair Display", Georgia, serif;
              font-size: 56px; font-weight: 700; letter-spacing: -1.5px;
              line-height: 1.05; margin-bottom: 14px; }
  header .lede { font-size: 16px; max-width: 560px;
                 color: rgba(255,255,255,.80); margin-bottom: 24px;
                 line-height: 1.55; }
  header .meta { display: flex; flex-wrap: wrap; gap: 22px;
                 font-size: 13px; color: rgba(255,255,255,.60); }
  header .meta span { display: inline-flex; align-items: center; gap: 6px; }
  header .meta .icon { opacity: .8; }

  /* === Tabs === */
  nav { background: var(--surface); border-bottom: 1px solid var(--border);
        padding: 0 56px; display: flex; gap: 28px;
        position: sticky; top: 0; z-index: 50; }
  nav a { display: block; padding: 16px 0; font-size: 14px;
          color: var(--ink); text-decoration: none;
          border-bottom: 2px solid transparent;
          transition: border-color .15s ease; }
  nav a:hover { border-bottom-color: var(--accent-red); }

  /* === Container === */
  .container { max-width: 1080px; margin: 0 auto; padding: 36px 56px 60px; }

  /* === Callout === */
  .callout { background: var(--accent-red-soft);
             border-left: 4px solid var(--accent-red);
             border-radius: 6px;
             padding: 18px 22px; margin-bottom: 32px;
             display: flex; gap: 14px; align-items: flex-start; }
  .callout .warn-icon { font-size: 22px; line-height: 1; flex-shrink: 0;
                        color: var(--accent-yellow); }
  .callout-title { font-weight: 700; color: var(--accent-red);
                   margin-bottom: 4px; font-size: 15px; }
  .callout-body { font-size: 14px; color: #4a2222; line-height: 1.55; }
  .callout.note { background: #fdf6e7; border-left-color: var(--accent-yellow); }
  .callout.note .callout-title { color: #8a5a08; }
  .callout.note .callout-body { color: #5a4108; }

  /* === Section label === */
  .section-label { font-size: 11px; font-weight: 700;
                   text-transform: uppercase; letter-spacing: 1.4px;
                   color: var(--ink-muted); margin-bottom: 14px;
                   padding-bottom: 10px; border-bottom: 1px solid var(--border); }

  /* === KPI grid === */
  .kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
             gap: 14px; margin-bottom: 36px; }
  .kpi-tile { background: var(--surface); border-radius: 8px;
              padding: 22px 22px 20px;
              border-top: 3px solid #b9b6ae;
              box-shadow: 0 1px 3px rgba(0,0,0,.05); }
  .kpi-tile.down { border-top-color: var(--accent-red); }
  .kpi-tile.up   { border-top-color: var(--accent-green); }
  .kpi-tile.flat { border-top-color: #b9b6ae; }
  .kpi-head { display: flex; justify-content: space-between;
              align-items: center; margin-bottom: 10px; }
  .kpi-label { font-size: 11px; font-weight: 700;
               text-transform: uppercase;
               color: var(--ink-muted); letter-spacing: 1px; }
  .kpi-value { font-family: "Playfair Display", Georgia, serif;
               font-weight: 700; font-size: 38px;
               line-height: 1; color: var(--ink);
               margin-bottom: 12px; }
  .pill { display: inline-flex; align-items: center; gap: 4px;
          padding: 3px 9px; border-radius: 4px;
          font-size: 12px; font-weight: 600; line-height: 1.4; }
  .pill.down { background: var(--accent-red-soft); color: var(--accent-red); }
  .pill.up   { background: #ebf5ef; color: var(--accent-green); }
  .pill.flat { background: #f1efea; color: var(--ink-muted); }
  .prior { display: block; margin-top: 10px;
           font-size: 12px; color: var(--ink-muted); }

  /* === Narrative === */
  .narrative-card { background: var(--surface); border-radius: 8px;
                    padding: 32px 36px;
                    box-shadow: 0 1px 3px rgba(0,0,0,.04);
                    margin-bottom: 24px; }
  .narrative-card h2 { font-family: "Playfair Display", Georgia, serif;
                       font-size: 24px; font-weight: 700;
                       margin-bottom: 18px;
                       padding-bottom: 12px;
                       border-bottom: 1px solid var(--border); }
  .bullet-list { list-style: none; }
  .bullet-list li { padding: 14px 0; font-size: 15px; line-height: 1.65;
                    border-bottom: 1px solid #f1eeea; }
  .bullet-list li:last-child { border-bottom: none; }
  .bullet-list .signal { margin-right: 6px; }
  .bullet-list .metric-highlight { font-weight: 700; }
  .bullet-list .driver { color: var(--accent-red); font-style: italic; }

  /* === Sections (collapsible tables) === */
  .section { background: var(--surface); border-radius: 8px;
             box-shadow: 0 1px 3px rgba(0,0,0,.04);
             margin-bottom: 22px; overflow: hidden; }
  .section-header { padding: 18px 28px; border-bottom: 1px solid var(--border);
                    display: flex; justify-content: space-between;
                    align-items: center; cursor: pointer; }
  .section-header h2 { font-family: "Playfair Display", Georgia, serif;
                       font-size: 18px; font-weight: 700; }
  table { width: 100%; border-collapse: collapse; font-size: 13px; }
  thead th { background: #faf8f4; padding: 12px 22px;
             text-align: left; font-weight: 600;
             text-transform: uppercase; letter-spacing: .6px;
             font-size: 11px; color: var(--ink-muted);
             border-bottom: 1px solid var(--border); }
  tbody td { padding: 12px 22px; border-bottom: 1px solid #f4f1eb; }
  tbody tr:last-child td { border-bottom: none; }

  .badge { display: inline-block; padding: 3px 9px; border-radius: 4px;
           font-size: 11px; font-weight: 600; }
  .badge.green  {

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [adobe](https://github.com/adobe)
- **Source:** [adobe/skills](https://github.com/adobe/skills)
- **License:** Apache-2.0
- **Homepage:** https://www.adobe.com/ai/overview.html

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.