script-include-patterns Skill
✓ VerifiziertSchreibe und verwalte ServiceNow Script Includes unter Verwendung von Class.create, AbstractAjaxProcessor und Vererbungsmustern.
- GitHub Stars
- 77
- Dateien
- 1
- Letzter Commit
- 20. Okt. 2026
- Lizenz
- Apache-2.0
- Erlaubte Tools
- —
Was macht der script-include-patterns Skill?
script-include-patterns ist ein Agent Skill. Schreibe und verwalte ServiceNow Script Includes unter Verwendung von Class.create, AbstractAjaxProcessor und Vererbungsmustern.
Zusammenfassung erzeugt aus der SKILL.md des Skills.
Über den script-include-patterns skill
Die Hauptfunktion dieses Skills ist die Entwicklung wiederverwendbarer serverseitiger JavaScript-Libraries für ServiceNow. Er unterstützt Entwickler beim Schreiben und Verwalten verschiedener Arten von Script Includes, einschließlich Standard-Utilities, Client-Callable APIs für GlideAjax und On-Demand Lazy Loading Klassen. Der Skill unterstützt komplexe Architekturmuster wie Vererbung via Object.extendsObject sowie spezifische Implementierungen für Scoped Applications.
Ein Agent sollte diesen Skill laden, wenn ein Entwickler ServiceNow-Logik aufbauen oder modifizieren muss. Er bietet spezifische Tools zur Automatisierung des Development Lifecycles, wie snow_create_script_include zum Generieren neuer Klassen, snow_artifact_manage zum Finden oder Aktualisieren von bestehendem Code und snow_execute_script zum Testen der Logik. Durch die Einhaltung von ES5-Standards wird die Kompatibilität mit der ServiceNow-Umgebung sichergestellt, während durch strukturierte Muster wie AbstractAjaxProcessor für die Client-Server-Kommunikation sauberer Code beibehalten wird.
Was ein agent damit machen kann
- 1Client-Callable APIs bauenEntwickle eine Klasse, die AbstractAjaxProcessor erweitert, um Client Scripts die Kommunikation mit dem Server via GlideAjax zu ermöglichen.
- 2Klassenvererbung implementierenErstelle eine abgeleitete Klasse, die Funktionalität von einer Basis-Task-Utility-Klasse erbt.
Geschrieben basierend auf dem SKILL.md des skills. Jeder use case wurde gegen ein zitat daraus geprüft.
So installierst du den script-include-patterns Skill
Jeder Befehl kopiert den Skill-Ordner in das Skills-Verzeichnis des Clients. Starte den Client neu oder beginne eine neue Session, um ihn zu laden.Den script-include-patterns Skill in Claude Code installieren
~/.claude/skills/script-include-patterns/SKILL.md
$ npx degit serac-labs/serac/packages/skills/script-include-patterns ~/.claude/skills/script-include-patternsDen script-include-patterns Skill in Claude Code (project) installieren
.claude/skills/script-include-patterns/SKILL.md
$ npx degit serac-labs/serac/packages/skills/script-include-patterns .claude/skills/script-include-patternsDen script-include-patterns Skill in Codex installieren
~/.agents/skills/script-include-patterns/SKILL.md
$ npx degit serac-labs/serac/packages/skills/script-include-patterns ~/.agents/skills/script-include-patternsDen script-include-patterns Skill in Gemini CLI installieren
~/.gemini/skills/script-include-patterns/SKILL.md
$ npx degit serac-labs/serac/packages/skills/script-include-patterns ~/.gemini/skills/script-include-patternsDen script-include-patterns Skill in Claude.ai installieren
npx degit serac-labs/serac/packages/skills/script-include-patterns script-include-patterns && zip -r script-include-patterns.zip script-include-patterns # claude.ai → Customize → Skills → + → Create skill → Upload a skill → script-include-patterns.zip
Automatisierte Checks
Geluften am 14. Nov. 2026Vollständiger Bericht →Hat unsere automatischen Prüfungen bestanden. Das ist kein Sicherheitsaudit: Lesen Sie die Skripte, bevor ein Agent sie ausführt. Wie die Checks funktionieren · Was du für mehr Punkte verbessern kannst
- Source Repository verknüpft und erreichbarserac-labs/serac/packages/skills/script-include-patterns is public and reachablegithub.com/serac-labs/serac/tree/HEAD/packages/skills/script ↗Bestanden
- Open Source Lizenz (OSI)Apache-2.0spdx.org/licenses/Apache-2.0.html ↗Bestanden
- Commit oder Release im letzten JahrLast commit 2026-10-20github.com/serac-labs/serac/commits ↗Bestanden
- Keine Download-und-Ausführen-Muster oder Zugangsdatendiebstahl in SkriptenNo scripts in the skill folderBestanden
- Keine versteckten Anweisungen in SKILL.mdNo override phrases, safeguard switches, credential requests or hidden charactersgithub.com/serac-labs/serac/blob/HEAD/packages/skills/script ↗Bestanden
- Vorab erlaubte Tools sind eingeschränktNo pre-approved tools; the agent asks before using onegithub.com/serac-labs/serac/blob/HEAD/packages/skills/script ↗Bestanden
- SKILL.md folgt dem Agent-Skills-Formatthe description does not say when to use the skillgithub.com/serac-labs/serac/blob/HEAD/packages/skills/script ↗Befund
SKILL.md
Auf GitHub ansehenScript Include Patterns for ServiceNow
Script Includes are reusable server-side JavaScript libraries that can be called from any server-side script.
Script Include Types
| Type | Use Case | Client Callable |
|---|---|---|
| Standard | Server-side utilities | No |
| Client Callable | GlideAjax from client | Yes |
| On-Demand | Lazy loading | No |
| AbstractAjaxProcessor | Client-server communication | Yes |
Standard Script Include (ES5)
// Basic utility class
var IncidentUtils = Class.create()
IncidentUtils.prototype = {
initialize: function () {
this.LOG_PREFIX = "[IncidentUtils] "
},
/**
* Get incident by number
* @param {string} number - Incident number (INC0010001)
* @returns {GlideRecord|null} - Incident record or null
*/
getByNumber: function (number) {
var gr = new GlideRecord("incident")
gr.addQuery("number", number)
gr.query()
if (gr.next()) {
return gr
}
return null
},
/**
* Calculate priority based on impact and urgency
* @param {number} impact - Impact value (1-3)
* @param {number} urgency - Urgency value (1-3)
* @returns {number} - Calculated priority (1-5)
*/
calculatePriority: function (impact, urgency) {
var matrix = {
"1-1": 1,
"1-2": 2,
"1-3": 3,
"2-1": 2,
"2-2": 3,
"2-3": 4,
"3-1": 3,
"3-2": 4,
"3-3": 5,
}
var key = impact + "-" + urgency
return matrix[key] || 4
},
/**
* Get open incidents for user
* @param {string} userSysId - User sys_id
* @returns {Array} - Array of incident objects
*/
getOpenIncidentsForUser: function (userSysId) {
var incidents = []
var gr = new GlideRecord("incident")
gr.addQuery("caller_id", userSysId)
gr.addQuery("active", true)
gr.orderByDesc("opened_at")
gr.query()
while (gr.next()) {
incidents.push({
sys_id: gr.getUniqueValue(),
number: gr.getValue("number"),
short_description: gr.getValue("short_description"),
state: gr.state.getDisplayValue(),
priority: gr.priority.getDisplayValue(),
})
}
return incidents
},
type: "IncidentUtils",
}
Client Callable Script Include (ES5)
// Extends AbstractAjaxProcessor for GlideAjax calls
var IncidentAjax = Class.create()
IncidentAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
/**
* Get incident details - callable from client
* Client calls: new GlideAjax('IncidentAjax').addParam('sysparm_name', 'getIncidentDetails')
*/
getIncidentDetails: function () {
var incidentId = this.getParameter("sysparm_incident_id")
var result = {}
var gr = new GlideRecord("incident")
if (gr.get(incidentId)) {
result.success = true
result.number = gr.getValue("number")
result.short_description = gr.getValue("short_description")
result.state = gr.state.getDisplayValue()
result.priority = gr.priority.getDisplayValue()
result.assigned_to = gr.assigned_to.getDisplayValue()
result.assignment_group = gr.assignment_group.getDisplayValue()
} else {
result.success = false
result.message = "Incident not found"
}
return JSON.stringify(result)
},
/**
* Search incidents by keyword
*/
searchIncidents: function () {
var keyword = this.getParameter("sysparm_keyword")
var limit = parseInt(this.getParameter("sysparm_limit"), 10) || 10
var incidents = []
var gr = new GlideRecord("incident")
gr.addQuery("short_description", "CONTAINS", keyword)
gr.addOrCondition("description", "CONTAINS", keyword)
gr.addQuery("active", true)
gr.setLimit(limit)
gr.orderByDesc("opened_at")
gr.query()
while (gr.next()) {
incidents.push({
sys_id: gr.getUniqueValue(),
number: gr.getValue("number"),
short_description: gr.getValue("short_description"),
})
}
return JSON.stringify(incidents)
},
/**
* Check if user can update incident
*/
canUserUpdate: function () {
var incidentId = this.getParameter("sysparm_incident_id")
var userId = gs.getUserID()
var gr = new GlideRecord("incident")
if (gr.get(incidentId)) {
// Check if user is assigned or in assignment group
var canUpdate =
gr.getValue("assigned_to") === userId || this._isUserInGroup(userId, gr.getValue("assignment_group"))
return JSON.stringify({ canUpdate: canUpdate })
}
return JSON.stringify({ canUpdate: false })
},
_isUserInGroup: function (userId, groupId) {
var member = new GlideRecord("sys_user_grmember")
member.addQuery("user", userId)
member.addQuery("group", groupId)
member.query()
return member.hasNext()
},
type: "IncidentAjax",
})
Client-Side GlideAjax Call (ES5)
// Client script calling Script Include
function getIncidentDetails(incidentSysId, callback) {
var ga = new GlideAjax("IncidentAjax")
ga.addParam("sysparm_name", "getIncidentDetails")
ga.addParam("sysparm_incident_id", incidentSysId)
ga.getXMLAnswer(function (answer) {
var result = JSON.parse(answer)
callback(result)
})
}
// Usage in client script
getIncidentDetails(g_form.getUniqueValue(), function (incident) {
if (incident.success) {
g_form.addInfoMessage("Incident: " + incident.number)
} else {
g_form.addErrorMessage(incident.message)
}
})
Inheritance Pattern (ES5)
// Base class
var TaskUtils = Class.create()
TaskUtils.prototype = {
initialize: function (tableName) {
this.tableName = tableName || "task"
},
getByState: function (state) {
var records = []
var gr = new GlideRecord(this.tableName)
gr.addQuery("state", state)
gr.query()
while (gr.next()) {
records.push(this._toObject(gr))
}
return records
},
_toObject: function (gr) {
return {
sys_id: gr.getUniqueValue(),
number: gr.getValue("number"),
short_description: gr.getValue("short_description"),
state: gr.getValue("state"),
}
},
type: "TaskUtils",
}
// Derived class
var IncidentUtilsExtended = Class.create()
IncidentUtilsExtended.prototype = Object.extendsObject(TaskUtils, {
initialize: function () {
TaskUtils.prototype.initialize.call(this, "incident")
},
getP1Incidents: function () {
var incidents = []
var gr = new GlideRecord("incident")
gr.addQuery("priority", 1)
gr.addQuery("active", true)
gr.query()
while (gr.next()) {
var obj = this._toObject(gr)
obj.caller = gr.caller_id.getDisplayValue()
incidents.push(obj)
}
return incidents
},
type: "IncidentUtilsExtended",
})
Scoped Script Include (ES5)
// In scoped application: x_myapp
var MyAppUtils = Class.create()
MyAppUtils.prototype = {
initialize: function () {
this.APP_SCOPE = "x_myapp"
},
/**
* Get application property
* @param {string} name - Property name (without scope prefix)
*/
getAppProperty: function (name) {
return gs.getProperty(this.APP_SCOPE + "." + name)
},
/**
* Log with application prefix
*/
log: function (message, source) {
gs.info("[" + this.APP_SCOPE + "][" + (source || "MyAppUtils") + "] " + message)
},
/**
* Access cross-scope table safely
*/
getGlobalUser: function (userId) {
var gr = new GlideRecord("sys_user")
if (gr.get(userId)) {
return {
name: gr.getValue("name"),
email: gr.getValue("email"),
}
}
return null
},
type: "MyAppUtils",
}
MCP Tool Integration
Available Script Include Tools
| Tool | Purpose |
|---|---|
snow_create_script_include |
Create new Script Include |
snow_artifact_manage (action='find') |
Find existing Script Includes |
snow_artifact_manage (action='update') |
Modify Script Include code |
snow_execute_script |
Test Script Include |
Example Workflow
// 1. Create Script Include
await snow_create_script_include({
name: "IncidentUtils",
script: "/* Script Include code */",
client_callable: false,
description: "Incident utility functions",
})
// 2. Test the Script Include
await snow_execute_script({
script: `
var utils = new IncidentUtils();
var incident = utils.getByNumber('INC0010001');
gs.info('Found: ' + (incident ? incident.number : 'null'));
`,
})
Best Practices
- Single Responsibility - One class, one purpose
- Meaningful Names - IncidentUtils not Utils
- Document Methods - JSDoc comments
- Error Handling - Try-catch with logging
- Private Methods - Prefix with underscore
- No Side Effects - Initialization should not modify data
- Testable - Write methods that can be unit tested
- ES5 Only - No const, let, arrow functions, template literals
Dateien in diesem Skill
1script-include-patterns Skill-Fragen
Wie installiere ich den script-include-patterns Skill in Claude Code?
Führe npx degit serac-labs/serac/packages/skills/script-include-patterns ~/.claude/skills/script-include-patterns aus. Claude Code lädt Skills aus ~/.claude/skills (alle Projekte) oder .claude/skills (ein Projekt) und nutzt einen Skill, wenn seine Beschreibung zur Aufgabe passt.
Welche Clients können den script-include-patterns Skill nutzen?
Jeder Client, der das Agent Skills-Format liest: Claude Code, Codex, Gemini CLI und claude.ai (als ZIP hochladen). Skripte im Skill laufen nur dort, wo der Client Codeausführung erlaubt.
Welche verschiedenen Typen von Script Includes gibt es in ServiceNow?
Script Includes können Standard (serverseitige Utilities), Client Callable (für GlideAjax), On-Demand (Lazy Loading) oder AbstractAjaxProcessor (für die Client-Server-Kommunikation) sein.
Wie implementiere ich Vererbung in einem ServiceNow Script Include?
Du kannst die Methode Object.extendsObject verwenden, um einer abgeleiteten Klasse die Vererbung von einer Basisklasse zu ermöglichen.
Welche Coding-Standards sollten beim Schreiben von Script Includes beachtet werden?
Entwickler sollten die ES5-Syntax verwenden (vermeide const, let oder Arrow-Functions), dem Single-Responsibility-Prinzip folgen, aussagekräftige Namen nutzen und private Methoden mit einem Unterstrich präfixen.