packages/opencode/src/bundled-skills/performance-analytics/SKILL.md
This skill should be used when the user asks to "create indicator", "performance analytics", "PA", "KPI", "dashboard widget", "breakdown", "threshold", "scorecard", or any ServiceNow Performance Analytics development.
npx skillsauth add groeimetai/snow-flow performance-analyticsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Performance Analytics (PA) provides advanced reporting and KPI tracking capabilities for measuring and improving business processes.
PA Dashboard
├── Widgets
│ ├── Scorecard Widget
│ ├── Time Series Chart
│ ├── Breakdown Pie Chart
│ └── Single Score
├── Indicators
│ ├── Number of Open Incidents
│ ├── Average Resolution Time
│ └── SLA Compliance Rate
├── Breakdowns
│ ├── By Priority
│ ├── By Assignment Group
│ └── By Category
└── Thresholds
├── Critical: > 100
└── Warning: > 50
| Table | Purpose |
| ------------------------- | ------------------------- |
| pa_indicators | KPI definitions |
| pa_indicator_breakdowns | Indicator-breakdown links |
| pa_breakdowns | Breakdown definitions |
| pa_thresholds | Threshold rules |
| pa_widgets | Dashboard widgets |
| pa_dashboards | Dashboard containers |
| Type | Aggregation | Example | | -------------- | ---------------- | ------------------- | | Count | COUNT(*) | Number of incidents | | Sum | SUM(field) | Total cost | | Average | AVG(field) | Avg resolution time | | Percentage | (A/B)*100 | SLA compliance % | | Duration | Time calculation | Avg time to resolve |
// Create "Open Incidents" indicator
var indicator = new GlideRecord("pa_indicators")
indicator.initialize()
indicator.setValue("name", "Open Incidents")
indicator.setValue("description", "Number of currently open incidents")
// Source configuration
indicator.setValue("cube", "pa_cubes_incident") // or table-based
indicator.setValue("facts_table", "incident")
indicator.setValue("conditions", "active=true")
// Aggregation
indicator.setValue("aggregate", "COUNT") // COUNT, SUM, AVG
// Display settings
indicator.setValue("direction", 2) // 1=Up is good, 2=Down is good
indicator.setValue("unit", "Incidents")
indicator.setValue("precision", 0) // Decimal places
// Scoring
indicator.setValue("frequency", "daily")
indicator.insert()
// Create "Average Resolution Time" indicator
var indicator = new GlideRecord("pa_indicators")
indicator.initialize()
indicator.setValue("name", "Avg Resolution Time")
indicator.setValue("description", "Average time to resolve incidents")
indicator.setValue("facts_table", "incident")
indicator.setValue("conditions", "state=6") // Resolved
// Aggregation on duration
indicator.setValue("aggregate", "AVG")
indicator.setValue("field", "calendar_duration") // Duration field
// Time unit
indicator.setValue("unit", "Hours")
indicator.setValue("unit_conversion", 3600) // Seconds to hours
indicator.setValue("direction", 2) // Lower is better
indicator.setValue("frequency", "daily")
indicator.insert()
// Create "SLA Compliance" percentage indicator
var indicator = new GlideRecord("pa_indicators")
indicator.initialize()
indicator.setValue("name", "SLA Compliance Rate")
indicator.setValue("description", "Percentage of incidents meeting SLA")
indicator.setValue("facts_table", "task_sla")
indicator.setValue("conditions", "task.sys_class_name=incident")
// Formula-based percentage
indicator.setValue("aggregate", "FORMULA")
indicator.setValue("formula", "(COUNT(has_breached=false) / COUNT(*)) * 100")
indicator.setValue("unit", "%")
indicator.setValue("direction", 1) // Higher is better
indicator.setValue("precision", 1)
indicator.insert()
| Breakdown | Field | Use Case | | --------- | ---------------- | --------------------- | | Priority | priority | Incidents by P1/P2/P3 | | Category | category | Incidents by type | | Group | assignment_group | Team performance | | Location | location | Geographic analysis | | Time | opened_at | Trend analysis |
// Create "Priority" breakdown
var breakdown = new GlideRecord("pa_breakdowns")
breakdown.initialize()
breakdown.setValue("name", "Priority")
breakdown.setValue("description", "Breakdown by incident priority")
breakdown.setValue("facts_table", "incident")
breakdown.setValue("dimension_field", "priority")
// Sorting
breakdown.setValue("sort_field", "priority")
breakdown.setValue("sort_order", "ASC")
// Element mapping (optional)
breakdown.setValue("use_element_mapping", true)
breakdown.insert()
// Link breakdown to indicator
var link = new GlideRecord("pa_indicator_breakdowns")
link.initialize()
link.setValue("indicator", indicatorSysId)
link.setValue("breakdown", breakdownSysId)
link.setValue("active", true)
link.insert()
// Create threshold for Open Incidents
var threshold = new GlideRecord("pa_thresholds")
threshold.initialize()
threshold.setValue("indicator", indicatorSysId)
threshold.setValue("name", "Critical Level")
// Threshold conditions
threshold.setValue("operator", ">=") // >=, <=, =, >, <
threshold.setValue("value", 100)
// Visual styling
threshold.setValue("color", "red")
threshold.setValue("icon", "exclamation-circle")
// Notification
threshold.setValue("notification_user", adminSysId)
threshold.setValue("notification_script", thresholdScript)
threshold.insert()
// Add warning threshold
var warning = new GlideRecord("pa_thresholds")
warning.initialize()
warning.setValue("indicator", indicatorSysId)
warning.setValue("name", "Warning Level")
warning.setValue("operator", ">=")
warning.setValue("value", 50)
warning.setValue("color", "orange")
warning.insert()
| Type | Use Case | Shows | | ---------------- | ------------------- | -------------------- | | Single Score | Current value | "127 Open Incidents" | | Scorecard | Value + trend | Current + sparkline | | Time Series | Trend over time | Line/bar chart | | Breakdown | By dimension | Pie/bar chart | | Comparison | Multiple indicators | Side-by-side |
// Create scorecard widget
var widget = new GlideRecord("pa_widgets")
widget.initialize()
widget.setValue("name", "Open Incidents Scorecard")
widget.setValue("type", "scorecard")
// Indicator
widget.setValue("indicator", indicatorSysId)
// Time range
widget.setValue("time_range", "last_30_days")
widget.setValue("show_trend", true)
widget.setValue("compare_to", "previous_period")
// Display
widget.setValue("show_breakdown", true)
widget.setValue("breakdown", priorityBreakdownSysId)
widget.setValue("chart_type", "bar")
widget.insert()
// Create PA Dashboard
var dashboard = new GlideRecord("pa_dashboards")
dashboard.initialize()
dashboard.setValue("name", "Incident Management Dashboard")
dashboard.setValue("description", "Key metrics for incident management")
// Layout
dashboard.setValue("layout", "2-column")
// Access control
dashboard.setValue("public", true)
dashboard.setValue("owner", gs.getUserID())
var dashboardSysId = dashboard.insert()
// Add widgets to dashboard
function addWidgetToDashboard(dashboardId, widgetId, row, column) {
var placement = new GlideRecord("pa_dashboard_widgets")
placement.initialize()
placement.setValue("dashboard", dashboardId)
placement.setValue("widget", widgetId)
placement.setValue("row", row)
placement.setValue("column", column)
placement.insert()
}
addWidgetToDashboard(dashboardSysId, openIncWidget, 0, 0)
addWidgetToDashboard(dashboardSysId, avgTimeWidget, 0, 1)
addWidgetToDashboard(dashboardSysId, slaWidget, 1, 0)
// Collect scores for an indicator
var job = new PAScoreCollector()
job.collectIndicatorScores(indicatorSysId)
// PA uses scheduled jobs for data collection
// Default: Daily at midnight
// Configure via: Performance Analytics > Data Collection > Jobs
| Tool | Purpose |
| ----------------------------- | ------------------ |
| snow_create_pa_indicator | Create indicator |
| snow_create_pa_breakdown | Create breakdown |
| snow_create_pa_threshold | Create threshold |
| snow_create_pa_widget | Create widget |
| snow_get_pa_scores | Retrieve scores |
| snow_collect_pa_data | Trigger collection |
| snow_discover_pa_indicators | Find indicators |
// 1. Create indicator
var indicatorId = await snow_create_pa_indicator({
name: "Open P1 Incidents",
table: "incident",
conditions: "active=true^priority=1",
aggregate: "COUNT",
direction: "down_is_good",
})
// 2. Create breakdown
var breakdownId = await snow_create_pa_breakdown({
name: "By Assignment Group",
table: "incident",
field: "assignment_group",
})
// 3. Link breakdown
await snow_create_pa_indicator_breakdown({
indicator: indicatorId,
breakdown: breakdownId,
})
// 4. Create threshold
await snow_create_pa_threshold({
indicator: indicatorId,
operator: ">=",
value: 10,
color: "red",
})
// 5. Create widget
await snow_create_pa_widget({
name: "P1 Incidents Scorecard",
type: "scorecard",
indicator: indicatorId,
breakdown: breakdownId,
})
// 6. Get current scores
var scores = await snow_get_pa_scores({
indicator: indicatorId,
time_range: "last_30_days",
})
development
This skill should be used when the user asks to "App Engine Studio", "workspace builder", "custom workspace", "AES", "low code", "app development", "studio", or any ServiceNow App Engine Studio development.
tools
This skill should be used when the user asks to "create a widget", "build a widget", "service portal widget", "sp_widget", "fix widget", "widget not working", "ng-click not working", or any Service Portal widget development.
development
This skill should be used when the user asks to "create chatbot", "virtual agent", "VA topic", "NLU", "conversation", "chat flow", "topic block", or any ServiceNow Virtual Agent development.
development
This skill should be used when the user asks to "vendor", "supplier", "contract", "procurement", "SLA", "vendor risk", "vendor performance", or any ServiceNow Vendor Management development.