arnoudkooi/sn-scriptsync/snu-artifacts
Claude Code and agent skill by arnoudkooi/sn-scriptsync
- community
Checking that the SKILL.md file is still in the repository.
How sn-scriptsync maps ServiceNow artifacts to files: the instance/scope/table layout, naming conventions per artifact type, creating new artifacts, and the _map.json / structure.json files. Read this when creating, naming, or organizing ServiceNow files.
Install
npx vskill@latest install arnoudkooi/sn-scriptsync/snu-artifactsSKILL.md
SN ScriptSync — Artifacts & File Structure
Conventions for naming, creating, and organizing ServiceNow artifacts as local files.
File Naming Conventions
⚠️ CRITICAL: Do NOT Create Separate Field Files for Configuration
NEVER create separate files for configuration/metadata fields:
- ❌
MyBusinessRule.collection.js(table name - this is a STRING reference) - ❌
MyBusinessRule.when.js(when to run - this is a STRING choice) - ❌
MyBusinessRule.active.js(active status - this is a BOOLEAN) - ❌
MyUIAction.table.js(table reference - this is a STRING) - ❌
MyOperation.http_method.js(HTTP method - this is a STRING) - ❌
MyScript.action_insert.js(action flag - this is a BOOLEAN)
These configuration fields belong in the creation payload ONLY, not as separate files.
✅ DO create files for actual script/code/content fields:
- Script fields (contain executable code):
script→MyBusinessRule.script.jsoperation_script→MyOperation.operation_script.jsclient_script→MyWidget.client_script.jsserver_script→MyWidget.server_script.jsprocessing_script→MyUIPage.processing_script.js
- Template/HTML fields (contain markup):
template→MyWidget.template.htmlhtml→MyUIPage.html
- CSS fields (contain styles):
css→MyWidget.css.scss
- Special files:
option_schema.json(widget configuration schema)demo_data.json(widget demo data)link.js(widget link function)
Rule of thumb: If the field contains code, markup, or styles → create a file. If it's a configuration value (string, boolean, number, reference) → include in payload only.
Common Fields Reference Table
| Field Name | Type | Create File? | Example | |
|---|---|---|---|---|
script | CODE | ✅ Yes | MyBR.script.js | |
operation_script | CODE | ✅ Yes | MyOperation.operation_script.js | |
client_script | CODE | ✅ Yes | MyWidget.client_script.js | |
server_script | CODE | ✅ Yes | MyWidget.server_script.js | |
processing_script | CODE | ✅ Yes | MyUIPage.processing_script.js | |
template | MARKUP | ✅ Yes | MyWidget.template.html | |
html | MARKUP | ✅ Yes | MyUIPage.html | |
css | STYLES | ✅ Yes | MyWidget.css.scss | |
link | CODE | ✅ Yes | MyWidget.link.js | |
collection | CONFIG (string) | ❌ No | In payload: "collection": "incident" | |
when | CONFIG (string) | ❌ No | In payload: "when": "before" | |
active | CONFIG (boolean) | ❌ No | In payload: "active": "true" | |
http_method | CONFIG (string) | ❌ No | In payload: "http_method": "GET" | |
table | CONFIG (string) | ❌ No | In payload: "table": "incident" | |
action_insert | CONFIG (boolean) | ❌ No | In payload: "action_insert": "true" | |
action_update | CONFIG (boolean) | ❌ No | In payload: "action_update": "true" | |
priority | CONFIG (number) | ❌ No | In payload: "priority": "100" | |
order | CONFIG (number) | ❌ No | In payload: "order": "100" | |
web_service_definition | CONFIG (reference) | ❌ No | In payload: "web_service_definition": "abc123..." |
Standard Scripts
- Use the artifact name with
.script.jsextension - Example:
HelloWorldUtils.script.js,DummyIncidentBR.script.js
Calculation Fields
- Use field name with
.calculation.jsextension - Example:
Foreign.calculation.js
Client Scripts for UI Actions
- Use artifact name with
.client_script_v2.jsextension - Example:
LargeBold.client_script_v2.js
Service Portal Widgets
- Widgets are folders containing multiple files
- File names:
template.html,client_script.js,css.scss,script.js, etc.
Creating New Artifacts
Important: Understanding Table Metadata
When creating a new artifact, the extension needs to understand the table structure:
Key Considerations:
- Mandatory Reference Fields: Some tables require references to other records (cannot be empty)
- Field Mappings: Different tables store scripts in different fields
- Required Setup: Some artifacts need parent records to exist first
Example: Scripted REST API (sys_ws_operation)
A sys_ws_operation record requires:
- Mandatory Reference:
web_service_definitionfield must reference asys_ws_definitionrecord - Script Field: The script content is stored in the
operation_scriptfield - Parent Record Required: You must first create or have an existing REST API service definition
Workflow for Complex Artifacts:
- Extension detects new file
- Extension fetches table metadata from ServiceNow
- Extension analyzes mandatory fields and references
- Extension prompts user: "This requires a web_service_definition reference. Do you want to:
- Select an existing REST API service?
- Create a new REST API service?"
- User provides required information
- Extension creates the record with all required fields
- Extension updates
_map.jsonwith the new sys_id
Pulling Existing Records (pull_records)
Use `pull_records` to fetch existing records (Script Includes, Business Rules, Widgets, UI Pages, etc.) matching a query or specific sys_id / sys_ids and write their code fields to disk with automatic _map.json registration:
This is the recommended way to pull scripts in the Global scope (where "Load Scope" is not practical) or ad-hoc sets of records across any table.
Working with Scoped Applications
⚠️ IMPORTANT: Do NOT create scope folders manually
Before creating files in a new scope folder:
- Sync or pull at least one artifact first from ServiceNow for that scope (via
pull_recordsor the SN Utils sync button) - This ensures the scope exists and the folder structure is correct
- The extension will create the scope folder automatically during the first sync
Why this matters:
- Scope names must match exactly with ServiceNow
- The scope must exist in the instance
- Incorrect scope names will cause sync failures
Correct Workflow:
- Create or identify a scope in ServiceNow (e.g.,
x_abc_my_app) - Create at least one artifact in that scope in ServiceNow
- Pull that artifact using
pull_recordswith{"table": "sys_script_include", "query": "sys_scope.scope=x_abc_my_app"} - The extension creates:
<instance>/x_abc_my_app/<table>/ - Now you can create new files in that scope folder
Creating Custom Tables
Use the typed `create_table` command — don't drive create_artifact against sys_db_object by hand. ServiceNow auto-creates the physical table plus its base sys_* fields (sys_id, sys_created_on, sys_updated_on, …); you only add your own columns.
Recipe:
- `create_table` with
name,label, optionalscopeandextends. With a non-globalscope, the name is prefixed for you as<scope>_<name>(e.g.x_acme_myapp_project). The prefixed-vs-unprefixed naming is the usual stumbling block — let the command handle it, or pass an already-prefixedx_...name. - `add_column` for each field. Set
display: trueon the column you want as the display value (no separateupdate_recordneeded), and passmandatory/default/choicesinline so the column is usable in one call. - Seed data rows with
rest_requestPOST /api/now/table/<name>(requiressn-scriptsync.restRequest.enabled). This is the blessed path for plain data rows —create_artifactrequiresfields.name, which is awkward when the display field isn'tname.
Fallback (no typed command available): create the table via create_artifact/rest_request against sys_db_object using the full scoped name (x_<scope>_<name>); the base sys_* fields are created automatically; then add_column for the rest and set the display field.
Large / multi-field payloads (widgets)
When a payload has several large or multiline code fields — e.g. a widget's template / css / script / client_script — do not hand-build the JSON on a shell command line; the escaping is error-prone. Write the request body to a file with JSON.stringify (so newlines and quotes are encoded correctly) and send it with curl -d @body.json, or use the file transport. This applies to any artifact with multiline/large field values.
Verifying a widget preview (component-only screenshot)
To show just the rendered widget without a per-tab screenshot grant, combine activate_tab with the CDP capture_full_page selector:
activate_tabwithopenIfNotFound: trueandwaitForLoad: true(open/activate the widget preview).capture_full_pagewithselector: ".my-widget"(or the widget's root class) for a clean, component-only screenshot — no per-tab grant required.
(capture_full_page uses the browser debugger — preflight with get_capabilities → cdp.available.)
Step-by-Step: Creating Simple Artifacts
For simple artifacts like Script Includes (no mandatory references):
Step 1: Create the file in the correct location
Or for a scoped app (after syncing at least one artifact):
Step 2: Write your code
Step 3: Save the file
The sn-scriptsync extension will:
- Detect the new file
- Fetch table metadata to check for mandatory fields
- Create the record in ServiceNow (prompting for required info if needed)
- Automatically update
_map.jsonwith the new sys_id
⚠️ IMPORTANT: Only create the `.script.js` file
- Do NOT create separate files like
.collection.js,.when.js,.active.js - The extension will prompt for required fields (like
collectionfor Business Rules) - OR use
create_artifactcommand to include all fields in one payload
Common Table Requirements
| Table | Script Field | Mandatory References | Notes | |
|---|---|---|---|---|
sys_script_include | script | None | Simple creation | |
sys_script | script | collection (table name) | Must specify which table | |
sys_ws_operation | operation_script | web_service_definition | Needs parent REST API | |
sys_ui_action | script | table (table name) | Must specify which table | |
sys_script_client | script | table (table name) | Must specify which table | |
sp_widget | Multiple files | None | Widget folder structure | |
rm_story | N/A | None | See rm_story specific guidance below |
rm_story (Story) Table Specifics
Key Fields:
name- Required by create_artifact (can be same as short_description)short_description- The story title/summarydescription- Detailed description (plain text)acceptance_criteria- HTML field - use HTML formatting, not markdownstate- Story state (see values below)priority- Priority level (1-4)
State Values:
| State | Value | Description | |
|---|---|---|---|
| Draft | -6 | Initial state, not ready for work | |
| Ready | 1 | Ready for development | |
| Work in Progress | 2 | Currently being worked on | |
| Ready for Testing | -7 | Development complete, ready for QA | |
| Testing | -8 | Currently being tested | |
| Complete | 3 | Story is done | |
| Cancelled | 4 | Story was cancelled |
⚠️ IMPORTANT: acceptance_criteria is an HTML field!
Use HTML tags for formatting, NOT markdown:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 96 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingagentrules/skills/snu-artifacts/SKILL.md
Popularity
- Repository stars
- 51
- Repository forks
- 36
- 7-day trend score
- 20
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/arnoudkooi/sn-scriptsync/snu-artifacts)