Phy Pipeline Contract Enforcer
LeoYeAI/openclaw-master-skills
Data pipeline contract enforcer. An agent skill from LeoYeAI/openclaw-master-skills.
A skill your agent uses to migrate course catalog data from external sources (CSV, PDF, website) and bulk-create Learning and LearningCourse records in Education Cloud.
$ npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install forcedotcom/sf-skills education-cloud-course-catalog-migrate --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/forcedotcom/sf-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/education-cloud-course-catalog-migrate .claude/skills/education-cloud-course-catalog-migrate && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "education-cloud-course-catalog-migrate" agent skill from https://github.com/forcedotcom/sf-skills/tree/main/skills/education-cloud-course-catalog-migrate into .claude/skills/education-cloud-course-catalog-migrate/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "education-cloud-course-catalog-migrate", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/forcedotcom/sf-skills/tree/main/skills/education-cloud-course-catalog-migrateType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install forcedotcom/sf-skills education-cloud-course-catalog-migrate --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/forcedotcom/sf-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/education-cloud-course-catalog-migrate .agents/skills/education-cloud-course-catalog-migrate && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "education-cloud-course-catalog-migrate" agent skill from https://github.com/forcedotcom/sf-skills/tree/main/skills/education-cloud-course-catalog-migrate into .agents/skills/education-cloud-course-catalog-migrate/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "education-cloud-course-catalog-migrate", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install forcedotcom/sf-skills education-cloud-course-catalog-migrate --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/forcedotcom/sf-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/education-cloud-course-catalog-migrate .cursor/skills/education-cloud-course-catalog-migrate && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "education-cloud-course-catalog-migrate" agent skill from https://github.com/forcedotcom/sf-skills/tree/main/skills/education-cloud-course-catalog-migrate into .cursor/skills/education-cloud-course-catalog-migrate/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "education-cloud-course-catalog-migrate", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/forcedotcom/sf-skills.git --path skills/education-cloud-course-catalog-migrate--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install forcedotcom/sf-skills education-cloud-course-catalog-migrate --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/forcedotcom/sf-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/education-cloud-course-catalog-migrate .gemini/skills/education-cloud-course-catalog-migrate && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "education-cloud-course-catalog-migrate" agent skill from https://github.com/forcedotcom/sf-skills/tree/main/skills/education-cloud-course-catalog-migrate into .gemini/skills/education-cloud-course-catalog-migrate/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "education-cloud-course-catalog-migrate", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install forcedotcom/sf-skills education-cloud-course-catalog-migrateInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/forcedotcom/sf-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/education-cloud-course-catalog-migrate .github/skills/education-cloud-course-catalog-migrate && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "education-cloud-course-catalog-migrate" agent skill from https://github.com/forcedotcom/sf-skills/tree/main/skills/education-cloud-course-catalog-migrate into .github/skills/education-cloud-course-catalog-migrate/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "education-cloud-course-catalog-migrate", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install forcedotcom/sf-skills education-cloud-course-catalog-migrate --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/forcedotcom/sf-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/education-cloud-course-catalog-migrate .opencode/skills/education-cloud-course-catalog-migrate && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "education-cloud-course-catalog-migrate" agent skill from https://github.com/forcedotcom/sf-skills/tree/main/skills/education-cloud-course-catalog-migrate into .opencode/skills/education-cloud-course-catalog-migrate/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "education-cloud-course-catalog-migrate", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
education-cloud-course-catalog-migrateA skill your agent uses to migrate course catalog data from external sources (CSV, PDF, website) and bulk-create Learning and LearningCourse records in Education Cloud.
Education Cloud Course Catalog Migrate is an agent skill from forcedotcom/sf-skills. Use this skill to migrate course catalog data from external sources (CSV, PDF, website) and bulk-create Learning and LearningCourse records in Education Cloud. Triggers when a user wants to import courses, parse course catalog documents, or set up a course catalog for an academic term. Handles multi-source data ingestion, intelligent interpretation of course structures (lecture+lab linked courses via IsLinkedOnly flag, credit hours, course types), batch creation via sObject REST API, data quality validation…
Its SKILL.md is about 5.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 11 other files, including scripts and reference files (for example `references/gotchas-detail.md`, `references/gotchas.md` and `references/large-catalog-handling.md`).
It sits in Data & Analytics, covering Data cleaning, CSV and tabular files and Data pipelines and ETL. It works with Salesforce. The repository describes itself as: Salesforce's curated collection of agent skills for building applications. Optimized for Agentforce Vibes, compatible with all AI tools. The licence is Apache-2.0.
5 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit e5164d9. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 6 files in scripts/ (Python), which the agent can run.
Shell commands in SKILL.md call:
python3From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Education Cloud Course Catalog Migrate loads about 5.4k tokens when it runs, and up to ~8.7k if it reads all its reference files. Until then it costs about 235 tokens; SKILL.md has 2,414 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from forcedotcom/sf-skills at commit e5164d9, republished under its Apache-2.0 licence (© forcedotcom). 2,414 words, ~5,427 tokens.
.claude/skills/education-cloud-course-catalog-migrate/SKILL.md (or your agent's skills folder). This skill also uses 9 other files; get the full folder from GitHub.Import course catalog data from multiple sources (CSV, PDF, website) and bulk-create Learning Course records with structure detection and data quality validation.
Gather or infer before proceeding:
Additional sources (gathered during workflow):
Defaults unless specified:
Resolve the API version first — do not hardcode. GET /services/data/ (no version segment) returns an endpoint map already resolved to the org's max version, not a {version, label, url} list. Pipe it into scripts/resolve_api_version.py to get {"version": "69.0"}; use as vXX.X everywhere below, including the transport probe.
Then probe transport health: GET /services/data/vXX.X/limits via headless-360 dispatch. 2xx → route all calls through it. On absent/4xx/5xx → probe other transports (other Salesforce MCP, custom MCP), use first healthy, announce it. None healthy → stop, ask user to connect one; never fabricate. (SOQL /query is routable on headless-360 — confirmed by live test; /tooling/query and ?fields= are unconfirmed, use describe + direct record reads instead.)
Never fall back to sf CLI or shell out for org credentials — a slow/oversized batch is a batch-size problem (shrink it, step 7), not a transport failure, and CLI shell-out trips an unbypassable approval gate on some surfaces. A version too new for the org returns 404 NOT_FOUND on an otherwise-healthy transport — re-read GET /services/data/, drop to the org's max version, retry, don't switch transport. See references/gotchas.md for both.
All steps are sequential. Do not skip or reorder. If blocked, stop and ask for missing context.
Identify data source type — determine if primary source is CSV, PDF, or website URL. Ask user to provide the source if not already specified.
Parse primary source — extract course data:
Read tool to load file, parse columnsRead tool (supports PDF extraction), parse text. Over 20 pages, read in sequential page-range chunks and merge parsed rows before validating completeness — see references/large-catalog-handling.md §1WebFetch tool to retrieve HTML, parse course listingsLook for: course codes (identity — split into SubjectAbbreviation + CourseNumber, see step 8/9), course names (Name), credit hours (Duration + DurationUnit), descriptions (Description), course types (Lecture/Lab/Exam/Drill/Recitation), prerequisites, corequisites, linked course indicators (IsLinkedOnly), delivery modality (if the same course code repeats with different Duration/DurationUnit — see references/large-catalog-handling.md §2).
Validate data completeness — pipe the parsed records into the completeness helper:
python3 scripts/validate_completeness.py --required "CourseCode,Name,Duration" --recommended "Description,CourseType" <<'JSON'
[ { "CourseCode": "...", "Name": "...", ... }, ... ]
JSONThe report gives present/missing counts per field. Optional fields (prerequisites, corequisites, linked courses) are not checked — their absence never blocks progress.
If any required field shows missing > 0, report error and stop. If recommended fields are missing, note the gaps and continue to Phase 2.
Report data quality — print a summary table showing which fields are present and which are missing. Example:
Data Quality Report:
• Course codes: 120/120 OK
• Course names: 120/120 OK
• Credit hours: 120/120 OK
• Descriptions: 115/120 (5 missing)
• Course types: 118/120 (2 missing)Request supplementary sources — if key fields are missing (descriptions, types), ask user: "Do you have additional sources — a website, department document, or mapping file?"
Repeat this step until all gaps are filled or user confirms to proceed with incomplete data.
If subject-to-Business-Account mapping is ambiguous, resolve every ambiguous case in one pass (source doc + live public catalog + course level/number patterns) and present them together, not one round at a time (see references/gotchas.md).
Detect multi-component courses — pipe the course codes into the lecture/lab pairing helper:
python3 scripts/detect_linked_courses.py --suffixes "L,LAB" <<'JSON'
[ "BIO-201", "BIO-201L", ... ]
JSONEach {"lecture", "lab"} pair returned is a candidate multi-component course.
If user selects "linked courses", request a mapping file or confirm the naming pattern is reliable.
Detect modality duplicates — group parsed rows by course code. Same code, different Duration/DurationUnit/Description = a modality variant (e.g. Online vs. On-Campus), not a duplicate — never silently dedupe/merge. Resolve the representation once per run, not per-course. See references/large-catalog-handling.md §2.
Prepare batch creation plan — pipe the parsed course records into the batching helper. The Composite API accepts up to 200 records/call, but an agent's tool-call payload has a smaller practical ceiling (~56KB/150 records). Use --batch-size 25 when executing as an agent (raise toward 200 only if the calling environment confirms it can handle larger payloads):
python3 scripts/batch_courses.py --batch-size 25 <<'JSON'
[ { "Name": "...", ... }, ... ]
JSONEach element of the returned array is one Composite API call's worth of records. Print: "Starting course catalog import. I'll use Composite API to create records in batches. Total: X courses."
If a batch still won't inline through a healthy dispatch transport, re-run with a smaller --batch-size (e.g. 10) instead of switching transport. Track dispatch vs. fallback counts and report both in the Phase 5 summary.
Over 200 courses (8+ batches): disclose total batch count upfront, print the Batch N complete line after every batch (not just at the end), and — only if the surface exposes a parallel-task/subagent tool — follow the fan-out rules in references/large-catalog-handling.md §3-4. Never assume that capability exists; default to sequential batches.
Check for existing courses — before creating Batch 1, scope the check to this batch's own course codes, never a global fetch (an unrelated catalog entry already in the org is not a conflict).
Split this batch's course codes first (scripts/split_course_code.py) — key the check on those identity fields, never CipCode (many orgs leave it null — see references/gotchas.md).
Headless-360 note: SOQL
/queryis routable via the headless-360 dispatch tool (confirmed by live test) — queryLearningCourse, matching each split{SubjectAbbreviation, CourseNumber}pair exactly (SOQL has no tupleIN, so OR the pairs):SELECT Id, LearningId, Name, SubjectAbbreviation, CourseNumber FROM LearningCourse WHERE (SubjectAbbreviation = 'BIO' AND CourseNumber = '201') OR .... If Ids are unknown and a SOQL lookup isn't available, ask the user to supply them (or a prior import manifest). Never do this via Bash/CLI — seereferences/gotchas.md.
If any rows come back (i.e. a SubjectAbbreviation+CourseNumber pair in this batch already exists in the org), pause and explain conflict:
Wait for user decision before proceeding.
Create Batch 1 — two-step process for each course:
Field placement (verified via describe):
CipCode,Duration,DurationUnit,ProviderIdare createable on Learning ONLY —ProviderIdon the child fails withINVALID_FIELD_FOR_INSERT_UPDATE. LearningCourse takesName,LearningId,CourseType,IsLinkedOnly,SubjectAbbreviation,CourseNumber,Description,CourseLevelDescription,FieldOfStudy— it inherits the account link viaLearningId. Confirm with describe before building the body.
CipCode is opt-in. Federal CIP taxonomy field, not the course's identity — leave unset unless the source supplies a real CIP code and the user confirms.
Step 1: Create Learning (parent) records via Composite API:
POST /services/data/vXX.X/composite/sobjects
{
"allOrNone": false,
"records": [
{
"attributes": {"type": "Learning", "referenceId": "learning1"},
"Name": "<course-name>",
"Type": "LearningCourse",
"Description": "<description>",
"ProviderId": "<account-id>",
"Duration": <hours>,
"DurationUnit": "Credit Hours",
"IsActive": true
},
...
]
}Capture each returned Id (order matches the records array) to use as LearningId in Step 2.
Step 2: Create LearningCourse (child) records via Composite API:
POST /services/data/vXX.X/composite/sobjects
{
"allOrNone": false,
"records": [
{
"attributes": {"type": "LearningCourse"},
"Name": "<course-record-name>",
"LearningId": "<learning-id-from-step-1>",
"SubjectAbbreviation": "<subject-prefix>",
"CourseNumber": "<course-number>",
"CourseType": "<parsed-course-type>",
"IsLinkedOnly": false
},
...
]
}Set CourseType from the parsed/mapped course type for that record (see the Gotchas table for value mapping) — do not hard-code it. A lab record must get CourseType: "Lab", not "Lecture".
CourseType picklist values (verified):
Lecture,Lab,Exam,Drill,Recitation.
restrictedPicklist: truemeans only today's values are valid to submit, not that the set is closed. If a source value (e.g.DurationUnit= "Program Points") isn't in describe's list, don't silently drop/remap it — offer adding the picklist value via metadata alongside remapping or a placeholder (seereferences/gotchas.md).
Print progress: Batch 1 complete — X Learning + X LearningCourse records created.
Handle multi-component courses — if user selected "linked courses" in step 6:
CourseType: "Lecture", IsLinkedOnly = falseCourseType: "Lab", IsLinkedOnly = truedetect_linked_courses.py pairs (or a user-supplied mapping file) to determine which labs are linked-onlyX linked lab courses created (IsLinkedOnly = true)Repeat for remaining batches — continue steps 8-10 for Batch 2, Batch 3, etc. until all courses created.
Scan for incomplete records — after all batches complete, read back each newly created record by the Id captured from its create response:
GET /services/data/vXX.X/sobjects/Learning/<id>
GET /services/data/vXX.X/sobjects/LearningCourse/<id>Headless-360 note: SOQL
/queryis routable via the headless-360 dispatch tool (confirmed by live test) — aCreatedDate = TODAYquery works as an alternative to iterating captured Ids with direct record GETs.
Run the completeness helper separately per sObject — CourseType exists only on LearningCourse, Description only on Learning; combining both shapes into one call false-positives every parent as missing CourseType:
python3 scripts/validate_completeness.py --required "Name" --recommended "Description" <<'JSON'
[ { "Name": "...", "Description": "...", ... }, ... ] # Learning read-backs only
JSONRepeat with --recommended "CourseType" against LearningCourse read-backs only. Identify courses with missing descriptions (Learning report) or missing types (LearningCourse report). Print data quality report (same format as step 4).
Detect conflicting data — if multiple sources provided different values for the same course, flag conflicts, e.g. "CHEM-301: website says X, PDF says Y — which should I use?" Wait for user decision, then update the conflicting courses.
Remediate gaps — if user provides additional sources to fill gaps, parse them and update the incomplete courses:
PATCH /services/data/vXX.X/sobjects/Learning/<id>
{"Description": "..."}
PATCH /services/data/vXX.X/sobjects/LearningCourse/<id>
{"CourseType": "<parsed-course-type>"}Generate import summary — print final report:
Course catalog import finished!
Summary:
• X Learning + X LearningCourse records created
• Y standalone, Z linked lab courses (IsLinkedOnly)
• All courses linked to <Business Account name>, set Active
Data sources used: 1. <primary> 2. <supplementary 1> 3. <supplementary 2>If any gaps were remediated from a supplementary source (step 5/14 ran), the final report MUST also include, in this order:
<primary source>)" and "After supplementary source (<supplementary source>)", each listing every field from step 4 with its present/total count. This is the before/after pair, not just the final counts.<source>)"), a numbered list of every remediated course with the value it received. One list per remediated field.Offer verification — ask user: "Would you like me to query specific courses to verify the data? For example, I can show you a course with its LearningCourse child record, or check for any remaining data quality issues."
Check the running user can actually see what was just created — don't just flag this, check it (see references/gotchas.md for the resolve-running-user + FLS/RecordTypeVisibility pattern), against every object touched (Learning, LearningCourse, Account if Person Accounts came up). Name any gap and its profile, offer the specific fix, and wait for confirmation before writing Profile/PermissionSet metadata. Default-Private OWD/sharing is org-wide, not per-user — flag it, don't offer to change it.
| Constraint | Rationale |
|---|---|
| Use Composite API, batched at 25 records/call for agent execution (API supports up to 200) | sObject REST standard in H360 MCP; a 150-record payload (~56KB) exceeds typical tool-call limits |
| Create Learning first, then LearningCourse | LearningCourse.LearningId requires parent to exist first |
| Always set Learning.Type = 'LearningCourse' | Learning is polymorphic — Type distinguishes courses from programs |
| Always query for existing courses before creating | Prevents duplicates; lets user decide on conflicts |
| Pause for clarification on multi-component courses | IsLinkedOnly flag affects enrollment behavior — user must confirm structure |
| Report data quality gaps before proceeding | Lets user provide complete data before committing to org |
| Wait for user decision on conflicting data | Agent cannot determine which source is authoritative |
| Do not invent missing data | Placeholder values must be explicitly approved by user |
| Set ProviderId (Business Account) on the parent Learning ONLY | Createable on Learning, not LearningCourse — see step 9 field-placement note |
| Set all courses to Active status by default (IsActive = true) | Must be Active to appear in catalog search/registration |
| Use sObject REST API, not CLI commands for org calls | H360 MCP skills have no execution environment for reaching the org. The scripts/ helpers are local data transforms (no org call) — if no Bash tool is available, perform the equivalent check inline instead of skipping it |
| Use tool-agnostic language | Skill ships to multiple AI surfaces beyond Claude Code |
Over 200 courses or 20+ source pages: follow references/large-catalog-handling.md, not ad hoc chunking | Improvised chunking risks split-page data loss or duplicate creates |
See references/gotchas.md for known failure modes and resolutions (parsing quirks, missing Business Account, picklist mapping, partial Composite failures, and more).
Deliverables:
/query (both routable via headless-360)No files are produced — all output is org records created via sObject REST API.
| Need | Delegate to |
|---|---|
| Create individual Learning Course manually | Platform metadata generation skills |
| Create Learning Programs | No dedicated skill yet — ask the user |
| Set up course sections/offerings | No dedicated skill yet — ask the user |
| Configure enrollment eligibility rules | No dedicated skill yet — ask the user |
references/gotchas.md — known failure modes and their resolutionsreferences/gotchas-detail.md — lower-frequency gotchas, linked from gotchas.mdreferences/large-catalog-handling.md — rules for >200 courses or >20-page source docs: paginated reads, modality-duplicate detection, checkpointing, gated parallel fan-out (steps 2, 6, 7)scripts/resolve_api_version.py — extracts org's max API version from the headless-360 endpoint map (Execution Transport)scripts/validate_completeness.py — required/recommended field presence check (steps 3, 12)scripts/detect_linked_courses.py — lecture/lab course-code pairing (step 6)scripts/detect_modality_variants.py — flags CourseCode rows differing by Duration/DurationUnit/Description, for large-catalog-handling.md §2scripts/batch_courses.py — Composite API batch splitting (step 7)scripts/split_course_code.py — SubjectAbbreviation/CourseNumber splitting (step 9)© forcedotcom, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 9 other files (scripts, references) in skills/education-cloud-course-catalog-migrate of forcedotcom/sf-skills.
Open the folder on GitHubat commit e5164d9
Education Cloud Course Catalog Migrate next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Education Cloud Course Catalog Migrate this skillforcedotcom/sf-skills | 1.1k | — | ~5.4k | Automated safety check: Pass | Apache-2.0 | |
| Phy Pipeline Contract EnforcerLeoYeAI/openclaw-master-skills | 2.2k | — | ~4.7k | Automated safety check: Pass | Apache-2.0 | |
| Portaljs Check Data Qualitydatopian/portaljs | 2.4k | 1 repos | ~1.5k | Automated safety check: Pass | MIT | |
| Dataset Quality Auditzebbern/claude-code-guide | 4.7k | — | ~996 | Automated safety check: Pass | MIT | |
| Multi Source Data Integration ExtractionDrchronx/ai-agent-research-starter-kit | 137 | — | ~671 | Automated safety check: Pass | Custom licence | |
| CSV Processingbenchflow-ai/skillsbench | 1.8k | — | ~455 | Automated safety check: Pass | Apache-2.0 |
LeoYeAI/openclaw-master-skills
Data pipeline contract enforcer. An agent skill from LeoYeAI/openclaw-master-skills.
datopian/portaljs
Audit a local or remote tabular file (CSV/TSV) for common data quality issues — schema, nulls, types, duplicates.
zebbern/claude-code-guide
Run comprehensive quality checks on tabular data (CSV/Excel/TSV/JSON), detecting missing values, duplicates, outliers, format issues, and type inconsistencies to produce an overall score, grade, and…
Drchronx/ai-agent-research-starter-kit
Automatically merge scattered Excel and CSV files, normalize column names, and extract structured tables from PDF, HTML, TXT, or Markdown documents.
benchflow-ai/skillsbench
A skill your agent uses when reading sensor data from CSV files, writing simulation results to CSV, processing time-series data with pandas, or handling missing values in datasets.
owid/etl
Create a brand-new OWID dataset in ETL from a data file the user provides — a local CSV/Excel, a downloaded file, or a web link to data (snapshot → meadow → garden → grapher → PR → staging server).
forcedotcom/sf-skills
Declared architecture snapshot for one Agentforce agent: planner, topics, actions, flows, Apex, prompt templates, and NGA plugins.
forcedotcom/sf-skills
Data Cloud 360° view of a single Agentforce session. An agent skill from forcedotcom/sf-skills.
forcedotcom/sf-skills
Apply a Salesforce sandbox post-copy automation JSON config against a target org.
forcedotcom/sf-skills
Apply a Salesforce sandbox post-copy automation JSON config against a target org.
forcedotcom/sf-skills
Apply SLDS-compliant UI using the correct blueprints, styling hooks, utility classes, and icons.
forcedotcom/sf-skills
Lightning Web Components with PICKLES methodology and 165-point scoring.
Works with
A skill your agent uses to migrate course catalog data from external sources (CSV, PDF, website) and bulk-create Learning and LearningCourse records in Education Cloud. Education Cloud Course Catalog Migrate is an agent skill from forcedotcom/sf-skills. Use this skill to migrate course catalog data from external sources (CSV, PDF, website) and bulk-create Learning and LearningCourse records in Education Cloud.
Education Cloud Course Catalog Migrate fits situations like: migrate course catalog data from external sources (CSV; website) and bulk-create Learning and LearningCourse records in Education Cloud; A user wants to import courses; parse course catalog documents.
Run `npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a claude-code`. Or copy the skill folder (skills/education-cloud-course-catalog-migrate in forcedotcom/sf-skills) into .claude/skills/education-cloud-course-catalog-migrate in your project. Claude Code loads it when a task matches its description.
Run `npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a codex`. Or copy the skill folder (skills/education-cloud-course-catalog-migrate in forcedotcom/sf-skills) into .agents/skills/education-cloud-course-catalog-migrate in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add forcedotcom/sf-skills --skill education-cloud-course-catalog-migrate -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/education-cloud-course-catalog-migrate, .gemini/skills/education-cloud-course-catalog-migrate, .github/skills/education-cloud-course-catalog-migrate and .opencode/skills/education-cloud-course-catalog-migrate in your project.
Going by SKILL.md and its folder, Education Cloud Course Catalog Migrate needs Python for the scripts in its folder and the command-line tools its instructions call (python3). Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Education Cloud Course Catalog Migrate is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.4k tokens (SKILL.md is roughly 22k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3.3k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Education Cloud Course Catalog Migrate: Phy Pipeline Contract Enforcer (LeoYeAI/openclaw-master-skills, 2.2k stars), Portaljs Check Data Quality (datopian/portaljs, 2.4k stars), Dataset Quality Audit (zebbern/claude-code-guide, 4.7k stars) and Multi Source Data Integration Extraction (Drchronx/ai-agent-research-starter-kit, 137 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
forcedotcom (a GitHub organization) maintains it in forcedotcom/sf-skills, which has 1,065 GitHub stars. The repository holds 251 skills in this directory. The repository was last updated on October 7, 2026.
Source: forcedotcom/sf-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.