agentsclimarketplace

Salesforce reports

Skill eprouveze/claude-skills/skills/salesforce-reports

A collection of practical Claude Code skills — multi-LLM evaluation, domain management, planning, writing quality, and pair-session patterns. MIT licensed.

Install
npx -y skills add eprouveze/claude-skills --skill salesforce-reports

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Create, clone, read, run, and delete Salesforce Reports from the command line via the Analytics REST API, driven by the Salesforce CLI (`sf`). Org-agnostic — works against any org you've authed with `sf`. Includes a `--setup` flow (installs the sf CLI if missing, saves a default org/API version, and an optional Global Company filter for GAM roles). Use when the user says "create a Salesforce report", "clone a report", "generate a report via sf CLI", "list/run/delete reports", "report API", or "Analytics REST reports".

SKILL.md

8.7 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

Salesforce Reports

Manage Salesforce Reports (the analytics object, not deploy/package "report" status commands) from the CLI. There is no native sf report create command — report CRUD lives in the Analytics REST API (/services/data/vXX.0/analytics/reports). This skill wraps that API through sf api request rest, which is the only path that authenticates correctly with the CLI's (masked) access token.

Everything routes through one script: scripts/sfreport.sh.

Quick start

S=~/.claude/skills/salesforce-reports/scripts/sfreport.sh

"$S" setup --org org62        # installs sf CLI if missing, saves config, checks auth
"$S" list                     # all reports you can see
"$S" types                    # report types (the 'type' you pass to create)
"$S" get  <id> --describe     # a report's metadata (filters, columns, format)
"$S" run  <id>                # run synchronously, return rows
"$S" clone --from <id> --name "Copy of X"   # most reliable way to create a report
"$S" create --type <apiName> --name "New" \
     --column <api> --filter '<col> <op> <value>' --group <api>   # report with columns/filters
"$S" delete <id> --yes        # delete (HTTP 204 on success)
"$S" --help                   # full reference

The script picks its target org from: --org flag → saved config (setup) → the sf CLI's configured target-org.

Setup

sfreport.sh setup is the front door:

  1. sf CLI presence. If sf is missing, setup offers to install it (npm → Homebrew → yarn, whichever is present). Non-interactively it installs without prompting.
  2. Default org + API version. Saved to ~/.config/claude-skills/salesforce-reports.env so you don't repeat --org every call. API version defaults to 62.0 (Analytics REST is stable there).
  3. Auth check. Confirms the Analytics REST endpoint is reachable; on failure it prints the sf org login web command to run.
  4. Global Company filter (GAM roles only — optional). See below.

Non-interactive form for scripts/CI:

"$S" setup --org myorg --api 62.0 --check-only      # check, don't write config
"$S" setup --org myorg --global-company "NTT, Inc." --gc-column Account.Global_Company__c

Global Company filter (GAM roles)

A Global Account Manager scopes reports to a single global parent account. This skill can re-point that filter on any clone so you don't hand-edit metadata:

"$S" clone --from <id> --name "NTT Pipeline" \
      --gc "NTT, Inc." --gc-column Account.Global_Company__c

Configure a default once at setup (GLOBAL_COMPANY + GC_COLUMN_DEFAULT) and every clone inherits it; override per-call with --gc / --gc-column. Resolution order for the value: --gc arg → $GLOBAL_COMPANY (env or saved config).

This is GAM-specific. Any other role can ignore it entirely — leave both blank at setup and the skill never touches report filters. To discover the right column on a report:

"$S" get <id> --describe | python3 -c \
  'import sys,json;[print(f["column"]) for f in json.load(sys.stdin)["reportMetadata"]["reportFilters"]]'

How creation actually works

Two create paths, in order of reliability:

  • Clone (recommended). POST /analytics/reports?cloneId=<id> with the source report's full reportMetadata (renamed). The skill fetches /describe, renames, optionally re-points the Global Company filter, and POSTs. This always yields a working report with columns and groupings already in place.

  • Create with metadata. POST /analytics/reports with a reportMetadata naming a reportType. Use types to find a valid reportType api name, and get <existing> --describe to discover that type's valid column / filter / grouping api names. The skill accepts:

    • --column <api> (repeatable) → detailColumns
    • --filter '<col> <operator> <value>' (repeatable) → reportFilters; the value is the remainder of the string, so spaces/commas are fine (--filter 'StageName equals Closed Won'). Operators: equals, notEqual, lessThan, greaterThan, contains, startsWith, etc.
    • --group <api> (repeatable) → groupingsDown (required for SUMMARY/MATRIX)
    • --boolean-filter '<expr>'reportBooleanFilter (e.g. '1 AND (2 OR 3)')
    • --gc <value> --gc-column <api> → adds the GAM Global Company equals-filter With no --column, create still produces an empty stub. Clone remains the easiest path when you want to start from an existing report's full layout.
    "$S" create --type Opportunity --name "My Q3 Pipeline" --format SUMMARY \
          --column StageName --column Amount --column CloseDate \
          --filter 'StageName equals Closed Won' --filter 'Amount greaterThan 50000' \
          --group StageName
    

Known gotchas

  • Clone still needs a metadata body. POST ...?cloneId=<id> with a bare {} returns BAD_REQUEST: "there is no metadata". You must POST the full reportMetadata. The skill handles this by fetching /describe first.
  • sf api request rest DELETE is finicky. A plain -X DELETE errors No 'mode' found in 'body' entry; -b '' and --body '{...}' don't help; an object-shaped header errors keyValPair.map is not a function. The working form (used internally) is -f <envelope.json> with header as an array of "k:v" strings and body: {"mode":"raw","raw":""}.
  • Don't curl with the CLI token. sf org display [--verbose] returns a masked 54-char access token; curl with it gives INVALID_AUTH_HEADER. Always go through sf api request rest, which authenticates internally.
  • API version. Defaults to 62.0. The CLI's default data API may be higher (e.g. 67.0) but Analytics REST report CRUD is verified on 62.0; bump with --api only if you've tested.

Anti-patterns

  • sf data delete record --sobject Report — fails with INSUFFICIENT_ACCESS_OR_READONLY even when the Analytics DELETE succeeds; the SObject path enforces different rights. Delete reports via the Analytics endpoint (sfreport.sh delete).
  • Hardcoding an org alias. The skill is org-agnostic; pass --org or save one via setup. Don't bake org62 into callers.
  • Treating sf commands | grep report hits as report CRUD. Those are package/deploy status commands (package version report, project deploy report). Unrelated.
  • Bare-create then expecting data. A create without columns is empty by design — clone when you want a usable report.

Validated patterns

  • Clone → verify returned 18-char Id → use/delete. Verified on org62: create HTTP 200, delete HTTP 204, post-delete getNOT_FOUND.
  • setup --check-only as a CI/pre-flight gate before any report automation.
  • GAM scoping by re-pointing one reportFilters entry on clone, rather than rebuilding the report — preserves columns, groupings, and report type.

Self-improvement

This skill ships with a lightweight feedback loop (learnings.md). Adopt or ignore — the skill works without it.

Trigger a review when:

  • The user corrects a created/cloned report's filter, name, or scope (strongest signal — log immediately; 2–3 corrections on the same theme → promote to the body).
  • The sf CLI changes its body/auth handling (e.g. the DELETE envelope bug gets fixed — the case-delete-envelope.sh golden case is the canary).
  • A new Analytics REST behavior or error code surfaces.
  • learnings.md crosses ~100 bullets (consolidation time).
  • The skill mis-triggers or fails to trigger.

Consolidation pass (5–10 min, weekly or threshold-driven): each learnings.md entry gets one fate — apply (merge into Known gotchas / Anti-patterns / Validated patterns), capture (leave in the log), or dismiss (delete). Bump last-consolidated: in frontmatter. Golden cases that previously passed and now fail are the loudest signal to consolidate early.

Golden cases live in golden/ — run ORG=<sandbox> golden/run-all.sh before changing the script.

What ships with it: 8 files

26.3 KB alongside SKILL.md, 6 of them executable

scripts/

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.