nowaikit 4.0.5 → 4.1.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/dist/a2a/agent-card.d.ts.map +1 -1
- package/dist/a2a/agent-card.js +2 -1
- package/dist/a2a/agent-card.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +12 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +2 -1
- package/dist/dashboard/index.js.map +1 -1
- package/dist/direct/llm-client.d.ts +20 -2
- package/dist/direct/llm-client.d.ts.map +1 -1
- package/dist/direct/llm-client.js +257 -51
- package/dist/direct/llm-client.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +41 -3
- package/dist/server.js.map +1 -1
- package/dist/servicenow/client.d.ts +2 -0
- package/dist/servicenow/client.d.ts.map +1 -1
- package/dist/servicenow/client.js +1 -1
- package/dist/servicenow/client.js.map +1 -1
- package/dist/tools/core.d.ts +97 -0
- package/dist/tools/core.d.ts.map +1 -1
- package/dist/tools/core.js +111 -9
- package/dist/tools/core.js.map +1 -1
- package/dist/tools/governance.d.ts +107 -0
- package/dist/tools/governance.d.ts.map +1 -0
- package/dist/tools/governance.js +149 -0
- package/dist/tools/governance.js.map +1 -0
- package/dist/tools/index.d.ts +307 -1812
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +61 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/tools-manifest.json +147 -3
- package/dist/transport/auth-middleware.d.ts +3 -1
- package/dist/transport/auth-middleware.d.ts.map +1 -1
- package/dist/transport/auth-middleware.js +59 -5
- package/dist/transport/auth-middleware.js.map +1 -1
- package/dist/transport/index.d.ts.map +1 -1
- package/dist/transport/index.js +3 -2
- package/dist/transport/index.js.map +1 -1
- package/dist/utils/audit.d.ts +15 -0
- package/dist/utils/audit.d.ts.map +1 -0
- package/dist/utils/audit.js +48 -0
- package/dist/utils/audit.js.map +1 -0
- package/dist/utils/guardrails.d.ts +5 -0
- package/dist/utils/guardrails.d.ts.map +1 -0
- package/dist/utils/guardrails.js +50 -0
- package/dist/utils/guardrails.js.map +1 -0
- package/dist/utils/version.d.ts +3 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +25 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +3 -2
- package/skills/README.md +21 -0
- package/skills/servicenow-cmdb-health-audit/SKILL.md +23 -0
- package/skills/servicenow-incident-triage/SKILL.md +22 -0
- package/skills/servicenow-safe-deployment/SKILL.md +24 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Append-only audit log for mutating operations.
|
|
3
|
+
*
|
|
4
|
+
* Writes one JSON object per line to NOWAIKIT_AUDIT_LOG (default
|
|
5
|
+
* ~/.config/nowaikit/audit.jsonl). Records who/what/when without storing full
|
|
6
|
+
* payloads — field VALUES are hashed, only field NAMES are kept in the clear —
|
|
7
|
+
* so the log is safe to retain for compliance/MSP use.
|
|
8
|
+
*
|
|
9
|
+
* Set NOWAIKIT_AUDIT_DISABLED=true to turn it off.
|
|
10
|
+
*/
|
|
11
|
+
import { appendFile, mkdir } from 'node:fs/promises';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import { createHash } from 'node:crypto';
|
|
15
|
+
import { logger } from './logging.js';
|
|
16
|
+
function auditPath() {
|
|
17
|
+
return process.env.NOWAIKIT_AUDIT_LOG || join(homedir(), '.config', 'nowaikit', 'audit.jsonl');
|
|
18
|
+
}
|
|
19
|
+
function hashPayload(fields) {
|
|
20
|
+
if (!fields)
|
|
21
|
+
return undefined;
|
|
22
|
+
try {
|
|
23
|
+
return createHash('sha256').update(JSON.stringify(fields)).digest('hex').slice(0, 16);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Append an audit entry. Best-effort — never throws into the caller. */
|
|
30
|
+
export async function appendAudit(entry, fields) {
|
|
31
|
+
if (process.env.NOWAIKIT_AUDIT_DISABLED === 'true')
|
|
32
|
+
return;
|
|
33
|
+
const line = JSON.stringify({
|
|
34
|
+
ts: new Date().toISOString(),
|
|
35
|
+
...entry,
|
|
36
|
+
field_names: entry.field_names ?? (fields ? Object.keys(fields) : undefined),
|
|
37
|
+
payload_hash: entry.payload_hash ?? hashPayload(fields),
|
|
38
|
+
}) + '\n';
|
|
39
|
+
try {
|
|
40
|
+
const path = auditPath();
|
|
41
|
+
await mkdir(dirname(path), { recursive: true });
|
|
42
|
+
await appendFile(path, line, 'utf8');
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
logger.warn(`Audit log write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/utils/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAetC,SAAS,SAAS;IAChB,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,WAAW,CAAC,MAAgC;IACnD,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAiB,EAAE,MAAgC;IACnF,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,MAAM;QAAE,OAAO;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC1B,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,GAAG,KAAK;QACR,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,WAAW,CAAC,MAAM,CAAC;KACxD,CAAC,GAAG,IAAI,CAAC;IACV,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;QACzB,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7F,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Throw if writes to `table` (optionally touching `fields`) are blocked by guardrails. */
|
|
2
|
+
export declare function assertWriteAllowed(table: string, fields?: Record<string, unknown>): void;
|
|
3
|
+
/** Whether a table is on the delete denylist (delete is treated as a write to the table). */
|
|
4
|
+
export declare function assertDeleteAllowed(table: string): void;
|
|
5
|
+
//# sourceMappingURL=guardrails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails.d.ts","sourceRoot":"","sources":["../../src/utils/guardrails.ts"],"names":[],"mappings":"AA2BA,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA+BxF;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ServiceNowError } from './errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Write guardrails — defense-in-depth beyond the binary WRITE_ENABLED flag.
|
|
4
|
+
*
|
|
5
|
+
* Config (all optional, comma-separated):
|
|
6
|
+
* NOWAIKIT_TABLE_DENYLIST — tables that may never be written (e.g. sys_user,sys_properties)
|
|
7
|
+
* NOWAIKIT_FIELD_DENYLIST — fields that may never be written; "table.field" or bare "field"
|
|
8
|
+
* NOWAIKIT_WRITE_SCOPE_PREFIX — if set, only tables matching one of these prefixes may be written
|
|
9
|
+
* (e.g. "x_" to confine agents to scoped-app tables)
|
|
10
|
+
*
|
|
11
|
+
* Built-in always-denied fields protect credentials/security regardless of config.
|
|
12
|
+
*/
|
|
13
|
+
const BUILTIN_FIELD_DENYLIST = new Set([
|
|
14
|
+
'sys_user.user_password',
|
|
15
|
+
'sys_user.password',
|
|
16
|
+
'user_password',
|
|
17
|
+
'password',
|
|
18
|
+
]);
|
|
19
|
+
function parseList(envVar) {
|
|
20
|
+
const raw = process.env[envVar];
|
|
21
|
+
if (!raw)
|
|
22
|
+
return [];
|
|
23
|
+
return raw.split(',').map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
24
|
+
}
|
|
25
|
+
/** Throw if writes to `table` (optionally touching `fields`) are blocked by guardrails. */
|
|
26
|
+
export function assertWriteAllowed(table, fields) {
|
|
27
|
+
const t = table.toLowerCase();
|
|
28
|
+
const tableDenylist = parseList('NOWAIKIT_TABLE_DENYLIST');
|
|
29
|
+
if (tableDenylist.includes(t)) {
|
|
30
|
+
throw new ServiceNowError(`Writes to "${table}" are blocked by NOWAIKIT_TABLE_DENYLIST.`, 'WRITE_GUARDRAIL');
|
|
31
|
+
}
|
|
32
|
+
const scopePrefixes = parseList('NOWAIKIT_WRITE_SCOPE_PREFIX');
|
|
33
|
+
if (scopePrefixes.length > 0 && !scopePrefixes.some((p) => t.startsWith(p))) {
|
|
34
|
+
throw new ServiceNowError(`Writes to "${table}" are blocked: not within an allowed scope prefix (${scopePrefixes.join(', ')}).`, 'WRITE_GUARDRAIL');
|
|
35
|
+
}
|
|
36
|
+
if (fields) {
|
|
37
|
+
const fieldDenylist = new Set([...BUILTIN_FIELD_DENYLIST, ...parseList('NOWAIKIT_FIELD_DENYLIST')]);
|
|
38
|
+
for (const field of Object.keys(fields)) {
|
|
39
|
+
const f = field.toLowerCase();
|
|
40
|
+
if (fieldDenylist.has(f) || fieldDenylist.has(`${t}.${f}`)) {
|
|
41
|
+
throw new ServiceNowError(`Writing field "${field}" on "${table}" is blocked by the field denylist.`, 'WRITE_GUARDRAIL');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Whether a table is on the delete denylist (delete is treated as a write to the table). */
|
|
47
|
+
export function assertDeleteAllowed(table) {
|
|
48
|
+
assertWriteAllowed(table);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=guardrails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails.js","sourceRoot":"","sources":["../../src/utils/guardrails.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;GAUG;AAEH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAS;IAC7C,wBAAwB;IACxB,mBAAmB;IACnB,eAAe;IACf,UAAU;CACX,CAAC,CAAC;AAEH,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC3E,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,MAAgC;IAChF,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAE9B,MAAM,aAAa,GAAG,SAAS,CAAC,yBAAyB,CAAC,CAAC;IAC3D,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CACvB,cAAc,KAAK,2CAA2C,EAC9D,iBAAiB,CAClB,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,SAAS,CAAC,6BAA6B,CAAC,CAAC;IAC/D,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,eAAe,CACvB,cAAc,KAAK,sDAAsD,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EACrG,iBAAiB,CAClB,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,sBAAsB,EAAE,GAAG,SAAS,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC;QACpG,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9B,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC3D,MAAM,IAAI,eAAe,CACvB,kBAAkB,KAAK,SAAS,KAAK,qCAAqC,EAC1E,iBAAiB,CAClB,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,WAAW,aAAa,CAAC;AAetC,eAAO,MAAM,OAAO,QAAgB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the package version.
|
|
3
|
+
* Reads version from package.json at runtime so server.ts, transport,
|
|
4
|
+
* a2a agent card, and dashboard never drift from package.json again.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync } from 'node:fs';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { dirname, resolve } from 'node:path';
|
|
9
|
+
export const SERVER_NAME = 'nowaikit';
|
|
10
|
+
function readVersion() {
|
|
11
|
+
try {
|
|
12
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
// dist/utils/version.js -> ../../package.json (project root)
|
|
14
|
+
const pkgPath = resolve(here, '..', '..', 'package.json');
|
|
15
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
16
|
+
if (pkg.version)
|
|
17
|
+
return pkg.version;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// fall through to default
|
|
21
|
+
}
|
|
22
|
+
return '0.0.0';
|
|
23
|
+
}
|
|
24
|
+
export const VERSION = readVersion();
|
|
25
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;AAEtC,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,8DAA8D;QAC9D,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC9E,IAAI,GAAG,CAAC,OAAO;YAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nowaikit",
|
|
3
3
|
"mcpName": "io.github.aartiq/nowaikit",
|
|
4
|
-
"version": "4.0
|
|
5
|
-
"description": "The Most Comprehensive ServiceNow AI Toolkit
|
|
4
|
+
"version": "4.1.0",
|
|
5
|
+
"description": "The Most Comprehensive ServiceNow AI Toolkit \u2014 400+ 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",
|
|
8
8
|
"exports": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"dist/",
|
|
32
32
|
"desktop/serve.cjs",
|
|
33
33
|
"desktop/renderer/dist/",
|
|
34
|
+
"skills/",
|
|
34
35
|
"instances.example.json",
|
|
35
36
|
".env.example"
|
|
36
37
|
],
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# NowAIKit Agent Skills
|
|
2
|
+
|
|
3
|
+
Cross-platform [Agent Skills](https://www.anthropic.com/news/skills) that orchestrate the NowAIKit MCP tools for common ServiceNow workflows. Each skill is a folder with a `SKILL.md` (YAML frontmatter `name` + `description` for progressive disclosure, then concise instructions).
|
|
4
|
+
|
|
5
|
+
They work with any agent runtime that supports the Agent Skills format — **Claude Code, Cursor, OpenAI Codex, GitHub Copilot, Windsurf** — alongside the NowAIKit MCP server.
|
|
6
|
+
|
|
7
|
+
## Skills
|
|
8
|
+
|
|
9
|
+
| Skill | Use it when |
|
|
10
|
+
|-------|-------------|
|
|
11
|
+
| `servicenow-incident-triage` | Triage/investigate/prioritize an incident or a queue |
|
|
12
|
+
| `servicenow-cmdb-health-audit` | Check CMDB health, data quality, CSDM conformance, or clean up CIs |
|
|
13
|
+
| `servicenow-safe-deployment` | Build and promote artifacts across instances with update sets + ATF |
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
**Claude Code:** copy a skill folder into `~/.claude/skills/` (global) or `.claude/skills/` (project), or point your skills path at this directory.
|
|
18
|
+
|
|
19
|
+
**Cursor / Codex / others:** add this folder to the agent's skills/rules path per that tool's docs.
|
|
20
|
+
|
|
21
|
+
All three skills assume the NowAIKit MCP server is connected. They lean on the safety features built into NowAIKit: `dry_run` previews, the write audit log, and write guardrails. Skills never apply destructive changes without showing a dry-run diff first.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: servicenow-cmdb-health-audit
|
|
3
|
+
description: Audit ServiceNow CMDB health using NowAIKit MCP tools — find duplicate, orphaned, and stale CIs, score completeness, and propose remediation. Use when the user asks to check CMDB health, data quality, CSDM conformance, or clean up the CMDB.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ServiceNow CMDB Health Audit
|
|
7
|
+
|
|
8
|
+
Use the NowAIKit CMDB tools to assess and remediate. Discover exact tool names with `search_tools` (e.g. "cmdb health", "find duplicates").
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. **Snapshot.** Run `cmdb_health_dashboard` for the overall score and class breakdown.
|
|
13
|
+
2. **Find issues in parallel:** `cmdb_find_duplicates`, `cmdb_find_orphans`, `cmdb_find_stale`, and `analyze_data_quality` / `check_table_completeness` for key classes (cmdb_ci_server, cmdb_ci_appl, business apps).
|
|
14
|
+
3. **Assess impact** before any change with `cmdb_impact_analysis` on candidate CIs.
|
|
15
|
+
4. **CSDM lens.** Check that Application Services, Business Applications, and Service Offerings exist and are related per CSDM 4.0; flag gaps.
|
|
16
|
+
5. **Remediate safely.** For merges/retirements/updates, call write tools with **`dry_run: true` first**, present the diff, then apply. Prefer `cmdb_reconcile` for authoritative-source conflicts.
|
|
17
|
+
6. **Report.** Counts by issue type, the health score delta you expect, and a prioritized remediation list (highest blast-radius first).
|
|
18
|
+
|
|
19
|
+
## Rules
|
|
20
|
+
- Never merge or retire a CI without showing impact analysis + dry-run diff.
|
|
21
|
+
- CMDB writes require `WRITE_ENABLED=true` and `CMDB_WRITE_ENABLED=true`.
|
|
22
|
+
- CI relationships must have both parent and child defined (CSDM).
|
|
23
|
+
- All writes are captured in the NowAIKit audit log.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: servicenow-incident-triage
|
|
3
|
+
description: Triage a ServiceNow incident or a queue of incidents using NowAIKit MCP tools — gather context, find similar past incidents, suggest a resolution, set priority, and assign. Use when the user asks to triage, investigate, prioritize, or work an incident (by number or as a batch).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ServiceNow Incident Triage
|
|
7
|
+
|
|
8
|
+
Drive triage through the NowAIKit MCP tools. Discover tools with `search_tools` if a name is unknown.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. **Scope.** If given an incident number, fetch it (`get_incident`). For a queue, `query_records` on `incident` with an encoded query (validate it first with `validate_query`), e.g. `active=true^assignment_group=<grp>^priority<=2`.
|
|
13
|
+
2. **Context.** Pull the caller, CI, and recent activity. For grounding, use `generate_summary` and `ml_similar_incidents` (or `ai_search`) to find prior resolutions.
|
|
14
|
+
3. **Classify.** Use `categorize_incident` / `ml_auto_categorize` to confirm category and `suggest_resolution` for a candidate fix.
|
|
15
|
+
4. **Act safely.** Propose field changes (priority, assignment_group, work notes) and apply with `update_record`. **Always run with `dry_run: true` first** and show the before→after diff before applying for real. Add context with `add_work_note`.
|
|
16
|
+
5. **Summarize.** Report what changed, the suggested resolution, and links to the similar incidents you used.
|
|
17
|
+
|
|
18
|
+
## Rules
|
|
19
|
+
- Never set priority/assignment without showing the dry-run diff first.
|
|
20
|
+
- Requires `WRITE_ENABLED=true` for any update; if disabled, output the proposed changes instead of applying.
|
|
21
|
+
- Encoded queries use `^` (AND) and `^OR` (OR), never SQL `AND`/`OR`. Validate with `validate_query`.
|
|
22
|
+
- Writes are recorded in the NowAIKit audit log automatically.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: servicenow-safe-deployment
|
|
3
|
+
description: Safely build and deploy ServiceNow artifacts (business rules, scripts, flows, catalog items) across instances using NowAIKit MCP tools, with update sets, dry-run previews, and ATF verification. Use when the user asks to deploy, promote, build, or move changes between dev/test/prod.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ServiceNow Safe Deployment
|
|
7
|
+
|
|
8
|
+
Orchestrate build → verify → promote through NowAIKit MCP tools. Use `search_tools` to find exact names (e.g. "update set", "run atf", "create business rule").
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. **Capture scope.** Ensure an active update set: `ensure_active_update_set` (or create one). Confirm the target instance with `get_current_instance` — never assume prod.
|
|
13
|
+
2. **Build.** Create artifacts (`create_business_rule`, `create_script_include`, `create_flow`, `create_catalog_item`, …). For raw table writes, preview with `dry_run: true` and show the payload/diff before applying.
|
|
14
|
+
3. **Verify.** Run ATF: `run_atf_suite` / `run_atf_test` and read results (`get_atf_suite_result`, `get_atf_failure_insight`). Do not promote on failures.
|
|
15
|
+
4. **Review the set.** `preview_update_set` and list changes; check for collisions.
|
|
16
|
+
5. **Promote.** Move to the next environment with `switch_instance`, then `commit_update_set` / deployment tools. **Confirm explicitly before any prod commit.**
|
|
17
|
+
6. **Report.** Artifacts created, ATF pass/fail, update set name, and the promotion path taken.
|
|
18
|
+
|
|
19
|
+
## Rules
|
|
20
|
+
- Scripting writes require `WRITE_ENABLED=true` + `SCRIPTING_ENABLED=true`; ATF needs `ATF_ENABLED=true`.
|
|
21
|
+
- Always dry-run writes and run ATF before promoting.
|
|
22
|
+
- Treat any instance that is not an explicit dev/test as production — stop and confirm.
|
|
23
|
+
- New development goes in scoped apps (`x_vendor_app`), never global.
|
|
24
|
+
- All writes are captured in the NowAIKit audit log.
|