script-include-patterns skill
✓ 検証済みClass.create、AbstractAjaxProcessor、および継承パターンを使用して、ServiceNowのScript Includeを記述・管理します。
- GitHubスター
- 77
- ファイル
- 1
- 最終コミット
- 2026年10月20日
- ライセンス
- Apache-2.0
- 許可されたツール
- —
script-include-patterns skillは何をしますか
script-include-patternsはAgent Skillsです。 Class.create、AbstractAjaxProcessor、および継承パターンを使用して、ServiceNowのScript Includeを記述・管理します。.
skillのSKILL.mdから生成された要約。
script-include-patterns skill について
このSKILLは、ServiceNow向けの再利用可能なサーバーサイドJavaScriptライブラリを開発することを主な目的としています。標準的なユーティリティ、GlideAjax用のClient Callable API、オンデマンドの遅延読み込みクラスなど、さまざまな種類のScript Includeの記述と管理を支援します。また、Object.extendsObjectによる継承などの複雑なアーキテクチャパターンや、スコープ済みアプリケーション向けの特定の実装もサポートします。
開発者がServiceNowのロジックを構築または修正する必要がある場合に、エージェントはこのSKILLをロードする必要があります。新しいクラスを生成するsnow_create_script_include、既存のコードを検索または更新するsnow_artifact_manage、ロジックをテストするsnow_execute_scriptなど、開発ライフサイクルを自動化するための専用ツールを提供します。ES5標準に従うことでServiceNow環境との互換性を確保しつつ、クライアント・サーバー間通信のためのAbstractAjaxProcessorのような構造化されたパターンを通じて、クリーンなコードの維持を支援します。
エージェントができること
- 1クライアント呼び出し可能なAPIの構築AbstractAjaxProcessorを拡張したクラスを開発し、クライアントスクリプトがGlideAjaxを介してサーバーと通信できるようにします。
- 2クラス継承の実装ベースとなるtaskユーティリティクラスから機能を継承する派生クラスを作成します。
skill の SKILL.md から作成されています。すべてのユースケースは、その引用と照合されています。
script-include-patterns skillのインストール方法
各コマンドはskillフォルダをクライアントのskillsディレクトリにコピーします。読み込むには、クライアントを再起動するか新しいセッションを開始してください。Claude Codeにscript-include-patterns skillをインストールする
~/.claude/skills/script-include-patterns/SKILL.md
$ npx degit serac-labs/serac/packages/skills/script-include-patterns ~/.claude/skills/script-include-patternsClaude Code (project)にscript-include-patterns skillをインストールする
.claude/skills/script-include-patterns/SKILL.md
$ npx degit serac-labs/serac/packages/skills/script-include-patterns .claude/skills/script-include-patternsCodexにscript-include-patterns skillをインストールする
~/.agents/skills/script-include-patterns/SKILL.md
$ npx degit serac-labs/serac/packages/skills/script-include-patterns ~/.agents/skills/script-include-patternsGemini CLIにscript-include-patterns skillをインストールする
~/.gemini/skills/script-include-patterns/SKILL.md
$ npx degit serac-labs/serac/packages/skills/script-include-patterns ~/.gemini/skills/script-include-patternsClaude.aiにscript-include-patterns skillをインストールする
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
自動チェック
実行日 2026年11月14日完全なレポート →自動チェックに合格しました。これはセキュリティ監査ではありません。エージェントに実行させる前にスクリプトを読んでください。 チェックの仕組み · 点数を上げるための改善点
- ソースリポジトリがリンクされており、アクセス可能serac-labs/serac/packages/skills/script-include-patterns is public and reachablegithub.com/serac-labs/serac/tree/HEAD/packages/skills/script ↗合格
- オープンソースライセンス (OSI)Apache-2.0spdx.org/licenses/Apache-2.0.html ↗合格
- 過去1年以内にコミットまたはリリースありLast commit 2026-10-20github.com/serac-labs/serac/commits ↗合格
- スクリプトにダウンロード実行や認証情報の窃取がないNo scripts in the skill folder合格
- SKILL.md に隠れた指示がないNo override phrases, safeguard switches, credential requests or hidden charactersgithub.com/serac-labs/serac/blob/HEAD/packages/skills/script ↗合格
- 事前許可ツールが限定されているNo pre-approved tools; the agent asks before using onegithub.com/serac-labs/serac/blob/HEAD/packages/skills/script ↗合格
- SKILL.md が Agent Skills の形式に従っているthe description does not say when to use the skillgithub.com/serac-labs/serac/blob/HEAD/packages/skills/script ↗検出事項
SKILL.md
GitHubで表示Script 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
このスキルのファイル
1script-include-patterns skillに関する質問
Claude Codeにscript-include-patterns skillをインストールするには
npx degit serac-labs/serac/packages/skills/script-include-patterns ~/.claude/skills/script-include-patternsを実行してください。Claude Codeは~/.claude/skills(すべてのプロジェクト)または.claude/skills(単一プロジェクト)からskillsを読み込み、説明がタスクに一致する場合にskillを使用します。
script-include-patterns skillはどのクライアントで使用できますか
Agent Skills形式を読み込むすべてのクライアントで使用できます: Claude Code、Codex、Gemini CLI、claude.ai(ZIPとしてアップロード)。skill内のスクリプトは、クライアントがコード実行を許可した場合にのみ実行されます。
ServiceNowにおけるScript Includeの主な種類は何ですか?
Script Includeには、Standard(サーバーサイドユーティリティ)、Client Callable(GlideAjax用)、On-Demand(遅延読み込み)、AbstractAjaxProcessor(クライアント・サーバー間通信用)があります。
ServiceNowのScript Includeで継承を実装するにはどうすればよいですか?
Object.extendsObjectメソッドを使用することで、派生クラスがベースクラスを継承できるように設定できます。
Script Includeを記述する際に従うべきコーディング規約はありますか?
ES5構文を使用し(const、let、アロー関数は避ける)、単一責任の原則に従い、意味のある名前を付け、プライベートメソッドにはアンダースコアを接頭辞として付ける必要があります。