nowaikit 4.4.0 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/servicenow/client.d.ts.map +1 -1
- package/dist/servicenow/client.js +13 -2
- package/dist/servicenow/client.js.map +1 -1
- package/dist/tools/blast-radius.d.ts.map +1 -1
- package/dist/tools/blast-radius.js +32 -12
- package/dist/tools/blast-radius.js.map +1 -1
- package/dist/tools/index.d.ts +708 -7
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/local-sync.d.ts +28 -0
- package/dist/tools/local-sync.d.ts.map +1 -1
- package/dist/tools/local-sync.js +68 -22
- package/dist/tools/local-sync.js.map +1 -1
- package/dist/tools/visualization.d.ts +84 -0
- package/dist/tools/visualization.d.ts.map +1 -0
- package/dist/tools/visualization.js +170 -0
- package/dist/tools/visualization.js.map +1 -0
- package/dist/tools-manifest.json +83 -10
- package/dist/utils/permissions.d.ts +5 -4
- package/dist/utils/permissions.d.ts.map +1 -1
- package/dist/utils/permissions.js +15 -19
- package/dist/utils/permissions.js.map +1 -1
- package/dist/utils/request-context.d.ts.map +1 -1
- package/dist/utils/request-context.js +22 -0
- package/dist/utils/request-context.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { ServiceNowError } from '../utils/errors.js';
|
|
2
|
+
const VISUALIZATION_TOOL_NAMES = new Set(['visualize_aggregate', 'visualize_trend']);
|
|
3
|
+
function toPoints(result) {
|
|
4
|
+
return (result || [])
|
|
5
|
+
.map((g) => {
|
|
6
|
+
const gf = (g.groupby_fields && g.groupby_fields[0]) || {};
|
|
7
|
+
const label = String(gf.display_value ?? gf.value ?? 'unknown');
|
|
8
|
+
const value = Number((g.stats && g.stats.count) ?? g.count ?? 0);
|
|
9
|
+
return { label, value };
|
|
10
|
+
})
|
|
11
|
+
.filter((p) => Number.isFinite(p.value));
|
|
12
|
+
}
|
|
13
|
+
function markdownTable(header, rows) {
|
|
14
|
+
const lines = [`| ${header[0]} | ${header[1]} |`, '| --- | ---: |'];
|
|
15
|
+
for (const r of rows)
|
|
16
|
+
lines.push(`| ${r.label} | ${r.value} |`);
|
|
17
|
+
return lines.join('\n');
|
|
18
|
+
}
|
|
19
|
+
function card(title, chart) {
|
|
20
|
+
return {
|
|
21
|
+
type: 'AdaptiveCard',
|
|
22
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
23
|
+
version: '1.5',
|
|
24
|
+
body: [
|
|
25
|
+
{ type: 'TextBlock', text: title, size: 'Large', weight: 'Bolder', wrap: true },
|
|
26
|
+
chart,
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function breakdownChart(chartType, title, points) {
|
|
31
|
+
const t = chartType.toLowerCase();
|
|
32
|
+
if (t === 'pie' || t === 'donut') {
|
|
33
|
+
const type = t === 'donut' ? 'Chart.Donut' : 'Chart.Pie';
|
|
34
|
+
return card(title, {
|
|
35
|
+
type,
|
|
36
|
+
colorSet: 'categorical',
|
|
37
|
+
data: points.map((p) => ({ legend: p.label, value: p.value })),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
// bar (horizontal) or column (vertical, default)
|
|
41
|
+
const type = t === 'bar' ? 'Chart.HorizontalBar' : 'Chart.VerticalBar';
|
|
42
|
+
return card(title, {
|
|
43
|
+
type,
|
|
44
|
+
colorSet: 'categorical',
|
|
45
|
+
showBarValues: true,
|
|
46
|
+
data: points.map((p) => ({ x: p.label, y: p.value })),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function truncateBucket(dateValue, interval) {
|
|
50
|
+
const v = String(dateValue);
|
|
51
|
+
if (interval === 'month')
|
|
52
|
+
return v.slice(0, 7);
|
|
53
|
+
if (interval === 'week') {
|
|
54
|
+
const d = new Date(v.replace(' ', 'T') + 'Z');
|
|
55
|
+
if (isNaN(d.getTime()))
|
|
56
|
+
return v.slice(0, 10);
|
|
57
|
+
const day = (d.getUTCDay() + 6) % 7; // Monday = 0
|
|
58
|
+
d.setUTCDate(d.getUTCDate() - day);
|
|
59
|
+
return d.toISOString().slice(0, 10);
|
|
60
|
+
}
|
|
61
|
+
return v.slice(0, 10); // day
|
|
62
|
+
}
|
|
63
|
+
export function getVisualizationToolDefinitions() {
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
name: 'visualize_aggregate',
|
|
67
|
+
description: 'Build a real-time chart of ServiceNow records grouped by a field (e.g. incidents by priority, cases by state). Returns chart-ready data, a Teams Adaptive Card (Chart.*) to drop into a Copilot Studio "Send an adaptive card" step, a markdown table, and a summary. Read-only.',
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
table: { type: 'string', description: 'Table to aggregate, e.g. "incident", "sn_customerservice_case"' },
|
|
72
|
+
group_by: { type: 'string', description: 'Field to group by, e.g. "priority", "state", "category", "assignment_group"' },
|
|
73
|
+
query: { type: 'string', description: 'Optional encoded query filter, e.g. "active=true"' },
|
|
74
|
+
chart_type: { type: 'string', description: 'column (default) | bar | pie | donut' },
|
|
75
|
+
title: { type: 'string', description: 'Optional chart title' },
|
|
76
|
+
limit: { type: 'number', description: 'Keep the top N groups by count (default 12)' },
|
|
77
|
+
},
|
|
78
|
+
required: ['table', 'group_by'],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'visualize_trend',
|
|
83
|
+
description: 'Build a real-time trend line of ServiceNow record counts over time (e.g. incidents opened per day). Returns chart-ready series, a Teams Adaptive Card line chart, a markdown table, and a summary. Read-only.',
|
|
84
|
+
inputSchema: {
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: {
|
|
87
|
+
table: { type: 'string', description: 'Table to count, e.g. "incident"' },
|
|
88
|
+
date_field: { type: 'string', description: 'Date/time field to bucket on (default "sys_created_on")' },
|
|
89
|
+
interval: { type: 'string', description: 'day (default) | week | month' },
|
|
90
|
+
query: { type: 'string', description: 'Recommended: a span filter, e.g. "sys_created_onONLast 30 days@..." or "active=true"' },
|
|
91
|
+
title: { type: 'string', description: 'Optional chart title' },
|
|
92
|
+
},
|
|
93
|
+
required: ['table'],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
export async function executeVisualizationToolCall(client, name, args) {
|
|
99
|
+
if (!VISUALIZATION_TOOL_NAMES.has(name))
|
|
100
|
+
return null;
|
|
101
|
+
switch (name) {
|
|
102
|
+
case 'visualize_aggregate': {
|
|
103
|
+
if (!args.table || !args.group_by)
|
|
104
|
+
throw new ServiceNowError('table and group_by are required', 'INVALID_REQUEST');
|
|
105
|
+
const chartType = String(args.chart_type || 'column');
|
|
106
|
+
const limit = typeof args.limit === 'number' ? args.limit : 12;
|
|
107
|
+
const result = await client.runAggregateQuery(String(args.table), String(args.group_by), 'COUNT', args.query ? String(args.query) : undefined);
|
|
108
|
+
let points = toPoints(result).sort((a, b) => b.value - a.value);
|
|
109
|
+
const total = points.reduce((a, p) => a + p.value, 0);
|
|
110
|
+
if (points.length > limit)
|
|
111
|
+
points = points.slice(0, limit);
|
|
112
|
+
const title = String(args.title || `${args.table} by ${args.group_by}`);
|
|
113
|
+
const summary = points.length
|
|
114
|
+
? `${title}: ${points.map((p) => `${p.label} (${p.value})`).join(', ')}. Total ${total}.`
|
|
115
|
+
: `No records found for ${args.table}${args.query ? ` where ${args.query}` : ''}.`;
|
|
116
|
+
return {
|
|
117
|
+
title,
|
|
118
|
+
table: args.table,
|
|
119
|
+
group_by: args.group_by,
|
|
120
|
+
chart_type: chartType,
|
|
121
|
+
total,
|
|
122
|
+
data: points,
|
|
123
|
+
table_markdown: markdownTable([String(args.group_by), 'count'], points),
|
|
124
|
+
adaptive_card: breakdownChart(chartType, title, points),
|
|
125
|
+
summary,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
case 'visualize_trend': {
|
|
129
|
+
if (!args.table)
|
|
130
|
+
throw new ServiceNowError('table is required', 'INVALID_REQUEST');
|
|
131
|
+
const dateField = String(args.date_field || 'sys_created_on');
|
|
132
|
+
const interval = String(args.interval || 'day');
|
|
133
|
+
const result = await client.runAggregateQuery(String(args.table), dateField, 'COUNT', args.query ? String(args.query) : undefined);
|
|
134
|
+
const buckets = new Map();
|
|
135
|
+
for (const p of toPoints(result)) {
|
|
136
|
+
const key = truncateBucket(p.label, interval);
|
|
137
|
+
buckets.set(key, (buckets.get(key) || 0) + p.value);
|
|
138
|
+
}
|
|
139
|
+
const series = Array.from(buckets.entries())
|
|
140
|
+
.map(([label, value]) => ({ label, value }))
|
|
141
|
+
.sort((a, b) => (a.label < b.label ? -1 : a.label > b.label ? 1 : 0));
|
|
142
|
+
const total = series.reduce((a, p) => a + p.value, 0);
|
|
143
|
+
const title = String(args.title || `${args.table} per ${interval}`);
|
|
144
|
+
const lineCard = card(title, {
|
|
145
|
+
type: 'Chart.Line',
|
|
146
|
+
colorSet: 'categorical',
|
|
147
|
+
xAxisTitle: interval,
|
|
148
|
+
yAxisTitle: 'count',
|
|
149
|
+
data: [{ legend: 'count', values: series.map((p) => ({ x: p.label, y: p.value })) }],
|
|
150
|
+
});
|
|
151
|
+
const summary = series.length
|
|
152
|
+
? `${title}: ${series.length} ${interval}s, total ${total} (from ${series[0].label} to ${series[series.length - 1].label}).`
|
|
153
|
+
: `No records found for ${args.table}${args.query ? ` where ${args.query}` : ''}.`;
|
|
154
|
+
return {
|
|
155
|
+
title,
|
|
156
|
+
table: args.table,
|
|
157
|
+
date_field: dateField,
|
|
158
|
+
interval,
|
|
159
|
+
total,
|
|
160
|
+
data: series,
|
|
161
|
+
table_markdown: markdownTable([interval, 'count'], series),
|
|
162
|
+
adaptive_card: lineCard,
|
|
163
|
+
summary,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
default:
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=visualization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualization.js","sourceRoot":"","sources":["../../src/tools/visualization.ts"],"names":[],"mappings":"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"}
|
package/dist/tools-manifest.json
CHANGED
|
@@ -9317,7 +9317,7 @@
|
|
|
9317
9317
|
},
|
|
9318
9318
|
{
|
|
9319
9319
|
"name": "blast_radius_table_configs",
|
|
9320
|
-
"description": "Blast radius: list every configuration artifact scoped to a table (business rules, client scripts, UI policies, ACLs, UI actions, data policies, dictionary fields). Run before altering or removing a table.",
|
|
9320
|
+
"description": "Blast radius (config/metadata impact, not CMDB CI impact): list every configuration artifact scoped to a table (business rules, client scripts, UI policies, ACLs, UI actions, data policies, dictionary fields), with per-type counts. Run before altering or removing a table. Each lane returns {count, records} or {error} if that table/plugin is unavailable.",
|
|
9321
9321
|
"inputSchema": {
|
|
9322
9322
|
"type": "object",
|
|
9323
9323
|
"properties": {
|
|
@@ -9337,7 +9337,7 @@
|
|
|
9337
9337
|
},
|
|
9338
9338
|
{
|
|
9339
9339
|
"name": "blast_radius_field_references",
|
|
9340
|
-
"description": "Blast radius: find where a table field is referenced — its dictionary entry plus any scripts (business rules, script includes, client scripts, UI actions, widgets) that mention the field name. Run before renaming or removing a field.",
|
|
9340
|
+
"description": "Blast radius: find where a table field is referenced — its dictionary entry plus any scripts (business rules, script includes, client scripts, UI actions, widgets) that mention the field name. Run before renaming or removing a field. Script matches are substring (LIKE) hits, so expect false positives (comments, similarly-named symbols) and misses for dynamically-built references; treat results as candidates to review, not a definitive list.",
|
|
9341
9341
|
"inputSchema": {
|
|
9342
9342
|
"type": "object",
|
|
9343
9343
|
"properties": {
|
|
@@ -9362,7 +9362,7 @@
|
|
|
9362
9362
|
},
|
|
9363
9363
|
{
|
|
9364
9364
|
"name": "blast_radius_script_dependents",
|
|
9365
|
-
"description": "Blast radius: find what references a script include / artifact by name — scans script-bearing config tables for textual use of the name. Run before renaming or deleting a Script Include, Script Action, etc.",
|
|
9365
|
+
"description": "Blast radius: find what references a script include / artifact by name — scans script-bearing config tables for textual use of the name. Run before renaming or deleting a Script Include, Script Action, etc. Matches are substring (LIKE) hits, so treat them as candidates to review (false positives from comments/similar names; misses for dynamic references).",
|
|
9366
9366
|
"inputSchema": {
|
|
9367
9367
|
"type": "object",
|
|
9368
9368
|
"properties": {
|
|
@@ -9402,7 +9402,7 @@
|
|
|
9402
9402
|
},
|
|
9403
9403
|
{
|
|
9404
9404
|
"name": "blast_radius_property_usage",
|
|
9405
|
-
"description": "Blast radius: find scripts that read a system property (sys_properties) by name, plus the property record itself. Run before changing or removing a property.",
|
|
9405
|
+
"description": "Blast radius: find scripts that read a system property (sys_properties) by name, plus the property record itself. Run before changing or removing a property. Matches are substring (LIKE) hits — candidates to review, not definitive.",
|
|
9406
9406
|
"inputSchema": {
|
|
9407
9407
|
"type": "object",
|
|
9408
9408
|
"properties": {
|
|
@@ -9431,7 +9431,7 @@
|
|
|
9431
9431
|
},
|
|
9432
9432
|
{
|
|
9433
9433
|
"name": "pull_artifact",
|
|
9434
|
-
"description": "Local sync: fetch an artifact's editable fields (e.g. a Service Portal widget's template/css/script). Returns the content inline; when NOWAIKIT_SYNC_DIR is set it also writes one file per field and returns the paths.",
|
|
9434
|
+
"description": "Local sync: fetch an artifact's editable fields (e.g. a Service Portal widget's template/css/script) for local editing. Returns the content inline; when NOWAIKIT_SYNC_DIR is set it also writes one file per field and returns the paths. This is config/pro-code editing of a single artifact, not an update-set export.",
|
|
9435
9435
|
"inputSchema": {
|
|
9436
9436
|
"type": "object",
|
|
9437
9437
|
"properties": {
|
|
@@ -9441,7 +9441,7 @@
|
|
|
9441
9441
|
},
|
|
9442
9442
|
"sys_id": {
|
|
9443
9443
|
"type": "string",
|
|
9444
|
-
"description": "sys_id of the record"
|
|
9444
|
+
"description": "sys_id OR name of the record (a name is resolved to its sys_id)"
|
|
9445
9445
|
}
|
|
9446
9446
|
},
|
|
9447
9447
|
"required": [
|
|
@@ -9452,7 +9452,7 @@
|
|
|
9452
9452
|
},
|
|
9453
9453
|
{
|
|
9454
9454
|
"name": "push_artifact",
|
|
9455
|
-
"description": "Local sync: write edited fields back to an artifact (requires WRITE_ENABLED=true). Pass fields inline as {field:value}; if omitted and NOWAIKIT_SYNC_DIR is set, reads them from the pulled files on disk.",
|
|
9455
|
+
"description": "Local sync: write edited fields back to an artifact (requires WRITE_ENABLED=true). Pass fields inline as {field:value}; if omitted and NOWAIKIT_SYNC_DIR is set, reads them from the pulled files on disk. Overwrites the listed fields with NO merge — run sync_status first, and pass expected_updated_on to abort if the instance changed since you pulled.",
|
|
9456
9456
|
"inputSchema": {
|
|
9457
9457
|
"type": "object",
|
|
9458
9458
|
"properties": {
|
|
@@ -9462,11 +9462,15 @@
|
|
|
9462
9462
|
},
|
|
9463
9463
|
"sys_id": {
|
|
9464
9464
|
"type": "string",
|
|
9465
|
-
"description": "sys_id of the record"
|
|
9465
|
+
"description": "sys_id OR name of the record"
|
|
9466
9466
|
},
|
|
9467
9467
|
"fields": {
|
|
9468
9468
|
"type": "object",
|
|
9469
9469
|
"description": "Optional map of {field: newValue} to update; defaults to the on-disk files under NOWAIKIT_SYNC_DIR"
|
|
9470
|
+
},
|
|
9471
|
+
"expected_updated_on": {
|
|
9472
|
+
"type": "string",
|
|
9473
|
+
"description": "Optional sys_updated_on from your last pull/sync_status; the push aborts with a CONFLICT if the record has changed since."
|
|
9470
9474
|
}
|
|
9471
9475
|
},
|
|
9472
9476
|
"required": [
|
|
@@ -9477,7 +9481,7 @@
|
|
|
9477
9481
|
},
|
|
9478
9482
|
{
|
|
9479
9483
|
"name": "sync_status",
|
|
9480
|
-
"description": "Local sync: compare an artifact's current instance content against your local/edited content field-by-field
|
|
9484
|
+
"description": "Local sync: compare an artifact's current instance content against your local/edited content field-by-field. Each field reports unchanged | changed | not_local (no local copy to compare). Also returns sys_updated_on to feed into push_artifact's conflict check.",
|
|
9481
9485
|
"inputSchema": {
|
|
9482
9486
|
"type": "object",
|
|
9483
9487
|
"properties": {
|
|
@@ -9487,7 +9491,7 @@
|
|
|
9487
9491
|
},
|
|
9488
9492
|
"sys_id": {
|
|
9489
9493
|
"type": "string",
|
|
9490
|
-
"description": "sys_id of the record"
|
|
9494
|
+
"description": "sys_id OR name of the record"
|
|
9491
9495
|
},
|
|
9492
9496
|
"fields": {
|
|
9493
9497
|
"type": "object",
|
|
@@ -9499,5 +9503,74 @@
|
|
|
9499
9503
|
"sys_id"
|
|
9500
9504
|
]
|
|
9501
9505
|
}
|
|
9506
|
+
},
|
|
9507
|
+
{
|
|
9508
|
+
"name": "visualize_aggregate",
|
|
9509
|
+
"description": "Build a real-time chart of ServiceNow records grouped by a field (e.g. incidents by priority, cases by state). Returns chart-ready data, a Teams Adaptive Card (Chart.*) to drop into a Copilot Studio \"Send an adaptive card\" step, a markdown table, and a summary. Read-only.",
|
|
9510
|
+
"inputSchema": {
|
|
9511
|
+
"type": "object",
|
|
9512
|
+
"properties": {
|
|
9513
|
+
"table": {
|
|
9514
|
+
"type": "string",
|
|
9515
|
+
"description": "Table to aggregate, e.g. \"incident\", \"sn_customerservice_case\""
|
|
9516
|
+
},
|
|
9517
|
+
"group_by": {
|
|
9518
|
+
"type": "string",
|
|
9519
|
+
"description": "Field to group by, e.g. \"priority\", \"state\", \"category\", \"assignment_group\""
|
|
9520
|
+
},
|
|
9521
|
+
"query": {
|
|
9522
|
+
"type": "string",
|
|
9523
|
+
"description": "Optional encoded query filter, e.g. \"active=true\""
|
|
9524
|
+
},
|
|
9525
|
+
"chart_type": {
|
|
9526
|
+
"type": "string",
|
|
9527
|
+
"description": "column (default) | bar | pie | donut"
|
|
9528
|
+
},
|
|
9529
|
+
"title": {
|
|
9530
|
+
"type": "string",
|
|
9531
|
+
"description": "Optional chart title"
|
|
9532
|
+
},
|
|
9533
|
+
"limit": {
|
|
9534
|
+
"type": "number",
|
|
9535
|
+
"description": "Keep the top N groups by count (default 12)"
|
|
9536
|
+
}
|
|
9537
|
+
},
|
|
9538
|
+
"required": [
|
|
9539
|
+
"table",
|
|
9540
|
+
"group_by"
|
|
9541
|
+
]
|
|
9542
|
+
}
|
|
9543
|
+
},
|
|
9544
|
+
{
|
|
9545
|
+
"name": "visualize_trend",
|
|
9546
|
+
"description": "Build a real-time trend line of ServiceNow record counts over time (e.g. incidents opened per day). Returns chart-ready series, a Teams Adaptive Card line chart, a markdown table, and a summary. Read-only.",
|
|
9547
|
+
"inputSchema": {
|
|
9548
|
+
"type": "object",
|
|
9549
|
+
"properties": {
|
|
9550
|
+
"table": {
|
|
9551
|
+
"type": "string",
|
|
9552
|
+
"description": "Table to count, e.g. \"incident\""
|
|
9553
|
+
},
|
|
9554
|
+
"date_field": {
|
|
9555
|
+
"type": "string",
|
|
9556
|
+
"description": "Date/time field to bucket on (default \"sys_created_on\")"
|
|
9557
|
+
},
|
|
9558
|
+
"interval": {
|
|
9559
|
+
"type": "string",
|
|
9560
|
+
"description": "day (default) | week | month"
|
|
9561
|
+
},
|
|
9562
|
+
"query": {
|
|
9563
|
+
"type": "string",
|
|
9564
|
+
"description": "Recommended: a span filter, e.g. \"sys_created_onONLast 30 days@...\" or \"active=true\""
|
|
9565
|
+
},
|
|
9566
|
+
"title": {
|
|
9567
|
+
"type": "string",
|
|
9568
|
+
"description": "Optional chart title"
|
|
9569
|
+
}
|
|
9570
|
+
},
|
|
9571
|
+
"required": [
|
|
9572
|
+
"table"
|
|
9573
|
+
]
|
|
9574
|
+
}
|
|
9502
9575
|
}
|
|
9503
9576
|
]
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
* Tier AI – NOW_ASSIST_ENABLED=true (generative AI tools)
|
|
9
9
|
* Tier ATF – ATF_ENABLED=true (test execution)
|
|
10
10
|
*
|
|
11
|
-
* Source of truth: process.env
|
|
12
|
-
* delegated-auth context (DELEGATED_AUTH mode, e.g. behind
|
|
13
|
-
* the per-user policy
|
|
14
|
-
*
|
|
11
|
+
* Source of truth: process.env sets the server's capability CEILING. When a request
|
|
12
|
+
* runs under a delegated-auth context (DELEGATED_AUTH mode, e.g. behind a trusted
|
|
13
|
+
* gateway), the per-user policy can only NARROW that ceiling, never widen it — a
|
|
14
|
+
* forged/over-permissive delegated flag can never enable a tier the operator left
|
|
15
|
+
* disabled. So the effective capability is (env AND delegated).
|
|
15
16
|
*/
|
|
16
17
|
export declare function isWriteEnabled(): boolean;
|
|
17
18
|
export declare function isCmdbWriteEnabled(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/utils/permissions.ts"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/utils/permissions.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AAEH,wBAAgB,cAAc,IAAI,OAAO,CAIxC;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED,wBAAgB,YAAY,IAAI,OAAO,CAItC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAOnC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAQvC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAQvC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAOvC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAOjC;AAID,wBAAgB,aAAa,IAAI,IAAI,CAOpC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}
|
|
@@ -10,40 +10,36 @@ import { getDelegatedAuth } from './request-context.js';
|
|
|
10
10
|
* Tier AI – NOW_ASSIST_ENABLED=true (generative AI tools)
|
|
11
11
|
* Tier ATF – ATF_ENABLED=true (test execution)
|
|
12
12
|
*
|
|
13
|
-
* Source of truth: process.env
|
|
14
|
-
* delegated-auth context (DELEGATED_AUTH mode, e.g. behind
|
|
15
|
-
* the per-user policy
|
|
16
|
-
*
|
|
13
|
+
* Source of truth: process.env sets the server's capability CEILING. When a request
|
|
14
|
+
* runs under a delegated-auth context (DELEGATED_AUTH mode, e.g. behind a trusted
|
|
15
|
+
* gateway), the per-user policy can only NARROW that ceiling, never widen it — a
|
|
16
|
+
* forged/over-permissive delegated flag can never enable a tier the operator left
|
|
17
|
+
* disabled. So the effective capability is (env AND delegated).
|
|
17
18
|
*/
|
|
18
19
|
export function isWriteEnabled() {
|
|
20
|
+
const env = process.env.WRITE_ENABLED === 'true';
|
|
19
21
|
const d = getDelegatedAuth();
|
|
20
|
-
|
|
21
|
-
return d.flags?.write === true;
|
|
22
|
-
return process.env.WRITE_ENABLED === 'true';
|
|
22
|
+
return d ? env && d.flags?.write === true : env;
|
|
23
23
|
}
|
|
24
24
|
export function isCmdbWriteEnabled() {
|
|
25
|
+
const env = process.env.WRITE_ENABLED === 'true' && process.env.CMDB_WRITE_ENABLED === 'true';
|
|
25
26
|
const d = getDelegatedAuth();
|
|
26
|
-
|
|
27
|
-
return d.flags?.write === true && d.flags?.cmdbWrite === true;
|
|
28
|
-
return process.env.WRITE_ENABLED === 'true' && process.env.CMDB_WRITE_ENABLED === 'true';
|
|
27
|
+
return d ? env && d.flags?.write === true && d.flags?.cmdbWrite === true : env;
|
|
29
28
|
}
|
|
30
29
|
export function isScriptingEnabled() {
|
|
30
|
+
const env = process.env.WRITE_ENABLED === 'true' && process.env.SCRIPTING_ENABLED === 'true';
|
|
31
31
|
const d = getDelegatedAuth();
|
|
32
|
-
|
|
33
|
-
return d.flags?.write === true && d.flags?.scripting === true;
|
|
34
|
-
return process.env.WRITE_ENABLED === 'true' && process.env.SCRIPTING_ENABLED === 'true';
|
|
32
|
+
return d ? env && d.flags?.write === true && d.flags?.scripting === true : env;
|
|
35
33
|
}
|
|
36
34
|
export function isNowAssistEnabled() {
|
|
35
|
+
const env = process.env.NOW_ASSIST_ENABLED === 'true';
|
|
37
36
|
const d = getDelegatedAuth();
|
|
38
|
-
|
|
39
|
-
return d.flags?.nowAssist === true;
|
|
40
|
-
return process.env.NOW_ASSIST_ENABLED === 'true';
|
|
37
|
+
return d ? env && d.flags?.nowAssist === true : env;
|
|
41
38
|
}
|
|
42
39
|
export function isAtfEnabled() {
|
|
40
|
+
const env = process.env.ATF_ENABLED === 'true';
|
|
43
41
|
const d = getDelegatedAuth();
|
|
44
|
-
|
|
45
|
-
return d.flags?.atf === true;
|
|
46
|
-
return process.env.ATF_ENABLED === 'true';
|
|
42
|
+
return d ? env && d.flags?.atf === true : env;
|
|
47
43
|
}
|
|
48
44
|
export function requireWrite() {
|
|
49
45
|
if (!isWriteEnabled()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/utils/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/utils/permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/utils/request-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/utils/request-context.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,oDAAoD;AACpD,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE1E;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,SAAS,CAE5D;AAkBD,6EAA6E;AAC7E,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,aAAa,CAwBf"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* identical to before (env-var driven).
|
|
13
13
|
*/
|
|
14
14
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
15
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
15
16
|
const store = new AsyncLocalStorage();
|
|
16
17
|
/** True when delegated-auth mode is switched on. */
|
|
17
18
|
export function isDelegatedAuthEnabled() {
|
|
@@ -25,12 +26,33 @@ export function runWithDelegatedAuth(ctx, fn) {
|
|
|
25
26
|
export function getDelegatedAuth() {
|
|
26
27
|
return store.getStore();
|
|
27
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* When NOWAIKIT_DELEGATED_SECRET is set, delegated-auth headers are only trusted if the
|
|
31
|
+
* request carries a matching x-nowaikit-gateway-secret (constant-time compared). This
|
|
32
|
+
* proves the request came from the trusted gateway and not from a client forging its own
|
|
33
|
+
* permission flags. If the secret is unset, behaviour is unchanged (back-compat), and the
|
|
34
|
+
* permission tiers still cap every delegated flag to the server's env ceiling.
|
|
35
|
+
*/
|
|
36
|
+
function gatewaySecretOk(get) {
|
|
37
|
+
const expected = process.env.NOWAIKIT_DELEGATED_SECRET;
|
|
38
|
+
if (!expected)
|
|
39
|
+
return true;
|
|
40
|
+
const got = get('x-nowaikit-gateway-secret') || '';
|
|
41
|
+
const a = Buffer.from(got);
|
|
42
|
+
const b = Buffer.from(expected);
|
|
43
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
44
|
+
}
|
|
28
45
|
/** Build a delegated-auth context from inbound (lowercased) HTTP headers. */
|
|
29
46
|
export function parseDelegatedAuthHeaders(headers) {
|
|
30
47
|
const h = (k) => {
|
|
31
48
|
const v = headers[k];
|
|
32
49
|
return Array.isArray(v) ? v[0] : v;
|
|
33
50
|
};
|
|
51
|
+
// Fail closed: a request without the gateway secret gets no token and no flags, so it
|
|
52
|
+
// can neither reach ServiceNow as a delegated user nor self-assert a capability tier.
|
|
53
|
+
if (!gatewaySecretOk(h)) {
|
|
54
|
+
return { flags: {} };
|
|
55
|
+
}
|
|
34
56
|
const bool = (k) => h(k) === 'true';
|
|
35
57
|
return {
|
|
36
58
|
bearerToken: h('x-servicenow-token'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/utils/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/utils/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAuB9C,MAAM,KAAK,GAAG,IAAI,iBAAiB,EAAiB,CAAC;AAErD,oDAAoD;AACpD,MAAM,UAAU,sBAAsB;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,CAAC;AAC/C,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,oBAAoB,CAAI,GAAkB,EAAE,EAAW;IACrE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB;IAC9B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,GAAsC;IAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;IACvD,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,2BAA2B,CAAC,IAAI,EAAE,CAAC;IACnD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,yBAAyB,CACvC,OAAsD;IAEtD,MAAM,CAAC,GAAG,CAAC,CAAS,EAAsB,EAAE;QAC1C,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC;IACF,sFAAsF;IACtF,sFAAsF;IACtF,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACvB,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,CAAS,EAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;IACrD,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,oBAAoB,CAAC;QACpC,WAAW,EAAE,CAAC,CAAC,2BAA2B,CAAC;QAC3C,WAAW,EAAE,CAAC,CAAC,yBAAyB,CAAC;QACzC,IAAI,EAAE,CAAC,CAAC,iBAAiB,CAAC;QAC1B,KAAK,EAAE;YACL,KAAK,EAAE,IAAI,CAAC,0BAA0B,CAAC;YACvC,SAAS,EAAE,IAAI,CAAC,+BAA+B,CAAC;YAChD,SAAS,EAAE,IAAI,CAAC,8BAA8B,CAAC;YAC/C,GAAG,EAAE,IAAI,CAAC,wBAAwB,CAAC;YACnC,SAAS,EAAE,IAAI,CAAC,+BAA+B,CAAC;SACjD;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nowaikit",
|
|
3
3
|
"mcpName": "io.github.aartiq/nowaikit",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.5.0",
|
|
5
5
|
"description": "The Most Comprehensive ServiceNow AI Toolkit — 450+ MCP tools + 26 AI capabilities (scan, review, build, ops, docs) + direct BYOK mode. Integrates with Claude, ChatGPT, Gemini, Cursor, GitHub Copilot and any LLM.",
|
|
6
6
|
"main": "dist/server.js",
|
|
7
7
|
"types": "dist/server.d.ts",
|