Skip to content
Agentmart
Submit a tool

lsc-custom-scripts

Guides Life Sciences Cloud (LSC) Custom Script configuration for validation, checklists, and Visit Action Validation.

Skill by SalesforceLabs

IndexedApache-2.0★ 7
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/salesforcelabs-lsc-custom-scripts

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

Guides Life Sciences Cloud (LSC) Custom Script configuration for validation, checklists, and Visit Action Validation. Use when user asks about custom scripts, visit validation scripts, CodeText, LifeScienceCustomScript, IIFE patterns, Locker Service proxy issues, or headless LWC validation components.

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 and code. 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/lsc-custom-scripts

What's inside

Skill name
lsc-custom-scripts
Description
Guides Life Sciences Cloud (LSC) Custom Script configuration for validation, checklists, and Visit Action Validation. Use when user asks about custom scripts, visit validation scripts, CodeText, LifeScienceCustomScript, IIFE patterns, Locker Service proxy issues, or headless LWC validation components.
License
Apache-2.0
Instructions
463 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

## How to Answer Custom Script Questions

**Always call MCP tools to get sourced documentation first.** Then supplement with the domain knowledge in this skill.

| User asks about... | Call this tool |
|---------------------|---------------|
| Custom script concepts, setup, documentation | `search_lsc_knowledge({ query: "custom scripts validation" })` |
| Current org custom script records | `run_soql({ query: "SELECT Id, Name, ComponentName, Type, ObjectName, OperationEventType FROM LifeScienceCustomScript ORDER BY Type, Name" })` |
| Workflow configuration / stage objects | `search_lsc_knowledge({ query: "workflow configuration stage objects" })` |
| Admin Console custom script settings | `list_admin_settings({ category: "CustomScript" })` |
| Object fields and relationships | `describe_sobject({ sobject: "LifeScienceCustomScript" })` |
| Mobile cache status | `check_mobile_cache_status()` |
| Visit configuration (related) | `check_visit_config()` |
| Visit validation passes for institutions, or does not run on Save | `search_lsc_knowledge({ query: "Visit Action Validation institution guard Save" })` then follow **Institution script guard** below. |

Always preserve the citation block (lines starting with > 📖, > 🔗, > 📂) from the tool response verbatim in your answer.

## Institution script guard

Load `knowledge/modules/visit-management/support-engineering-visit-script-institution-guard.md`. Finish only when the reply states every fact under **Required answer**. The primary cause is an inverted institution check in the customer's script. A Save path that does not run the script is a second cause, and only when neither account type runs it on Save.

---

## Choosing a Validation Mechanism

Before building a custom script, help the user choose the right mechanism:

| Mechanism | When to use | Online (Web) | Offline (iPad) |
|-----------|------------|--------------|----------------|
| **Validation Rule** | Simple, single-object, field-level checks expressible with standard formulas | Yes | Yes |
| **Custom Script (Visit Action Validation)** | Complex validations spanning multiple objects (samples, details, attendees, messages) | Yes | Yes |
| **Apex Trigger** | Last resort — validation requires data not available on mobile | Yes | No |

**Guidance:** Start with validation rules whenever possible. Move to Custom Script Visit Action Validation when the logic spans multiple objects or needs conditional checks that validation rules can't express. Use Apex triggers only when the required data isn't synced to the mobile app.

---

## Custom Script Types

| Type | When it runs | How it's assigned |
|------|-------------|-------------------|
| **Validation** | Any workflow action (Record Update) | Assigned to Stage Objects |
| **Checklist** | User clicks info icon on Record Update actions | Assigned to Stage Objects |
| **Visit Action Validation** | User clicks Sign or Submit on a visit | Runs automatically (only one script runs — first by ID/creation date) |

### Critical: Only One Visit Action Validation Runs

**Only one Visit Action Validation script runs per org.** If multiple scripts of this type exist, only the first one executes (based on ID or creation date). All validation rules must be combined in a single script returning multiple results in the array.

For Validation and Checklist scripts, different scripts can be assigned to different Stage Objects.

---

## Required Record Fields for LifeScienceCustomScript

| Field | Validation/Checklist | Visit Action Validation |
|-------|---------------------|------------------------|
| Name | Required | Required |
| ComponentName | LWC component name | LWC component name |
| Type | `Validation` or `Checklist` | `VisitActionValidation` |
| ObjectName | Not required | **`ProviderVisit`** (required!) |
| OperationEventType | Not required | **`OnUpdate`** (required!) |

**Without `ObjectName` and `OperationEventType`, Visit Action Validation scripts silently don't execute.**

---

## How Custom Scripts Work

Custom scripts are headless LWC components deployed to the org. The platform stores the JavaScript in the `CodeText` field of `LifeScienceCustomScript` records and executes it from there — **not** from the deployed LWC directly.

**After deploying an updated LWC, the user must click Refresh in Admin Console > Workflow Configuration > Custom Scripts to sync the code to the CodeText field.**

- `CodeText` is the runtime source of truth
- `CodeText` is read-only via API — it can only be updated through the Refresh button

---

## Two Runtimes: Web vs. iPad (Locker Service vs. JavaScriptCore)

The same `CodeText` script runs in two completely different JavaScript engines depending on platform:

| | Web (Lightning) | iPad (LSC Mobile) |
|---|---|---|
| Engine | Browser + **Locker Service** (WKWebView-style sandbox) | Native **JavaScriptCore** (`JSContext`) — no Locker Service |
| Globals (`record`, `user`, `db`, `env`) | Locker Service secure proxies | Native Swift objects bridged via JSExport |
| Return values | Wrapped in Locker Service **Proxy** objects | Bridged native objects (not Locker proxies) |
| Where `env.log()` / `console.log` goes | Browser devtools console | **Device logs** (Console.app / Xcode device console) — NOT a browser console |

**Why this matters:**
- The `unwrapProxy(results)` requirement (gotcha #2) exists to strip **Locker Service** proxies on web. On iPad there is no Locker Service, but `JSON.parse(JSON.stringify(results))` is still the correct way to return plain data across the JavaScriptCore bridge — keep it for both platforms.
- When debugging, look in the **browser console on web** and in **device logs on iPad**. A script that "works on web but not on iPad" usually differs because of the engine/bridge, not the logic — check the runtime before rewriting the validation.

---

## Confirmed Working IIFE Pattern (Visit Action Validation)

All Visit Action Validation scripts must follow this pattern. **Do not deviate.**

```javascript
(() => {
    function parseContextData(record) {
        try {
            if (!record || typeof record.getContextData !== 'function') return {};
            var contextData = record.getContextData();
            if (typeof contextData === 'string') return JSON.parse(contextData);
            if (typeof contextData === 'object' && contextData !== null) return contextData;
            return {};
        } catch (e) { return {}; }
    }

    function getFieldData(contextData, baseFieldName) {
        return contextData[baseFieldName + '.VisitId'] || contextData[baseFieldName];
    }

    function unwrapProxy(results) {
        return JSON.parse(JSON.stringify(results));
    }

From SalesforceLabs/lsc-for-claude, Apache-2.0.

More from SalesforceLabs/lsc-for-claude

Signals

Stars
7
Forks
2
Open issues
0
Last commit (this folder)
Oct 13, 2026 (15 days ago)
Last release
Oct 22, 2026 (6 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
Apache-2.0
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from SalesforceLabs

Cite this page

lsc-custom-scripts skill. Agent Mart. https://agentmart.dev/skills/salesforcelabs-lsc-custom-scripts (last updated 2026-10-24)