Skill v1.0.1
currentAutomated scan100/100+2 new
version: "1.0.1" name: snu-artifacts description: 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.
<!-- SN-SCRIPTSYNC:SKILL apiVersion=17 -->
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
Working with Scoped Applications
⚠️ IMPORTANT: Do NOT create scope folders manually
Before creating files in a new scope folder:
- Sync at least one artifact first from ServiceNow for that scope
- 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
- Use the extension to pull/sync that artifact
- 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 is part of the browser-debugger beta — 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
<your_instance>/global/sys_script_include/MyNewUtils.script.js
Or for a scoped app (after syncing at least one artifact):
<your_instance>/<your_scope>/sys_script_include/MyNewUtils.script.js
Step 2: Write your code
var MyNewUtils = Class.create();MyNewUtils.prototype = {initialize: function() {},myFunction: function() {return 'Hello World';},type: 'MyNewUtils'};
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:
<!-- ✅ CORRECT - HTML formatting --><b>Acceptance Criteria:</b><ul><li>Widget displays correctly</li><li>Score tracking works</li><li>No console errors</li></ul><b>Definition of Done:</b><ul><li>Code reviewed</li><li>Unit tests pass</li></ul>
<!-- ❌ INCORRECT - Markdown won't render -->**Acceptance Criteria:**-Widget displays correctly-Score tracking works
Example: Creating a Story
{"command": "create_artifact","params": {"table": "rm_story","scope": "global","fields": {"name": "Implement User Dashboard Widget","short_description": "Implement User Dashboard Widget","description": "Create a Service Portal widget that displays user statistics and recent activity.","acceptance_criteria": "<b>Acceptance Criteria:</b><ul><li>Widget shows user stats</li><li>Responsive design</li></ul><b>Definition of Done:</b><ul><li>Code reviewed</li><li>Tested in dev</li></ul>","state": "1","priority": "2"}}}
Updating Story State:
{"command": "update_record","params": {"table": "rm_story","sys_id": "abc123...","field": "state","content": "-7"}}
Note: State values are strings (e.g., "-7" not -7)
Handling Mandatory References
When the extension detects a mandatory reference field:
The extension should:
- Query ServiceNow for available reference options
- Present choices to the user
- Allow creation of a new reference record if needed
- Validate the reference exists before creating the artifact
The extension should NOT:
- Set reference fields to empty strings
- Create records without required references
- Assume default values for mandatory fields
Fetching Table Metadata
Before creating a new record, the extension should:
- Query the ServiceNow API to get table dictionary information:
`` GET /api/now/table/sys_dictionary?sysparm_query=name=<table_name>^ORDERBYelement ``
- Analyze mandatory fields: Check for fields where
mandatory=true
- Identify reference fields: Check
referencefield for reference table names
- Map script fields: Different tables use different field names:
- Most tables:
script - REST API Operations:
operation_script - UI Pages: Multiple fields (
html,client_script,processing_script)
- Consult ServiceNow documentation if needed for complex tables:
- ServiceNow Docs: https://docs.servicenow.com/
- Table API documentation
- Field specifications and requirements