snow-flow 2.0.2 → 2.0.4
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/{.claude/mcp-config.json → .mcp.json} +13 -12
- package/.releaserc.json +47 -0
- package/README.md +48 -1
- package/package.json +1 -1
- package/.claude/claude-settings.json +0 -15
- package/.claude/commands/analysis/README.md +0 -9
- package/.claude/commands/automation/README.md +0 -9
- package/.claude/commands/github/README.md +0 -11
- package/.claude/commands/helpers/standard-checkpoint-hooks.sh +0 -179
- package/.claude/commands/hooks/README.md +0 -11
- package/.claude/commands/monitoring/README.md +0 -9
- package/.claude/commands/optimization/README.md +0 -9
- package/.claude/commands/training/README.md +0 -9
- package/.claude/commands/workflows/README.md +0 -9
- package/.claude/config.json +0 -36
- package/.claude/helpers/github-setup.sh +0 -28
- package/.claude/helpers/quick-start.sh +0 -19
- package/.claude/helpers/setup-mcp.sh +0 -18
- package/.claude/settings.json +0 -114
- package/.claude/settings.local.json +0 -33
- package/.claude-flow/metrics/agent-metrics.json +0 -1
- package/.claude-flow/metrics/performance.json +0 -9
- package/.claude-flow/metrics/system-metrics.json +0 -15986
- package/.claude-flow/metrics/task-metrics.json +0 -10
- package/.roo/README.md +0 -402
- package/.roo/mcp-list.txt +0 -257
- package/.roo/mcp.json +0 -32
- package/.roo/workflows/basic-tdd.json +0 -32
- package/.roomodes +0 -201
- package/CLAUDE.md +0 -393
- package/bin/snow-flow.js +0 -3
- package/dist/cli.js.bak +0 -2052
- package/dist/config/snow-flow-config.d.ts +0 -1492
- package/dist/config/snow-flow-config.js +0 -938
- package/scripts/create-env.js +0 -91
- package/scripts/postinstall.js +0 -30
- package/scripts/register-mcp-servers.js +0 -210
- package/scripts/reset-mcp-servers.js +0 -246
- package/scripts/setup-mcp.js +0 -106
- package/scripts/update-version.js +0 -31
- package/src/agents/README.md +0 -192
- package/src/agents/base-agent.ts +0 -251
- package/src/agents/coordinator.ts +0 -971
- package/src/agents/index.ts +0 -18
- package/src/agents/queen-403-handler.ts +0 -230
- package/src/agents/queen-agent.ts +0 -1399
- package/src/agents/script-writer-agent.ts +0 -769
- package/src/agents/security-agent.ts +0 -726
- package/src/agents/widget-creator-agent.ts +0 -568
- package/src/api/error-handling.ts +0 -1758
- package/src/api/natural-language-mapper.ts +0 -630
- package/src/api/performance-optimizer.ts +0 -891
- package/src/api/transaction-manager.ts +0 -754
- package/src/cli/deploy-artifact.ts +0 -304
- package/src/cli/snow-flow-cli-integration.ts +0 -434
- package/src/cli.ts +0 -4455
- package/src/cli.ts.bak +0 -5616
- package/src/compliance/advanced-compliance-system.ts +0 -1268
- package/src/compliance/index.ts +0 -19
- package/src/config/snow-flow-config.ts +0 -1019
- package/src/documentation/index.ts +0 -16
- package/src/documentation/self-documenting-system.ts +0 -1421
- package/src/dynamic-version.ts +0 -44
- package/src/healing/index.ts +0 -20
- package/src/healing/self-healing-system.ts +0 -1435
- package/src/health/README.md +0 -161
- package/src/health/system-health.ts +0 -995
- package/src/index.ts +0 -60
- package/src/intelligence/acl-analyzer.ts +0 -377
- package/src/intelligence/auto-resolution-engine.ts +0 -643
- package/src/intelligence/gap-analysis-engine.ts +0 -488
- package/src/intelligence/manual-instructions-generator.ts +0 -744
- package/src/intelligence/mcp-coverage-analyzer.ts +0 -708
- package/src/intelligence/multi-pass-requirements-analyzer.ts +0 -603
- package/src/intelligence/performance-recommendations-engine.ts +0 -1223
- package/src/intelligence/requirements-analyzer.ts +0 -1148
- package/src/intelligence/task-analyzer.ts +0 -628
- package/src/managers/scope-manager.ts +0 -555
- package/src/mcp/advanced/servicenow-advanced-features-mcp.ts +0 -16110
- package/src/mcp/base-mcp-server.ts +0 -660
- package/src/mcp/http-transport-wrapper.ts +0 -426
- package/src/mcp/service-discovery-client.ts +0 -312
- package/src/mcp/servicenow-automation-mcp-refactored.ts +0 -678
- package/src/mcp/servicenow-automation-mcp.ts +0 -838
- package/src/mcp/servicenow-deployment-mcp-refactored.ts +0 -1292
- package/src/mcp/servicenow-deployment-mcp.ts +0 -7244
- package/src/mcp/servicenow-graph-memory-mcp-refactored.ts +0 -721
- package/src/mcp/servicenow-graph-memory-mcp.ts +0 -832
- package/src/mcp/servicenow-integration-mcp-refactored.ts +0 -655
- package/src/mcp/servicenow-integration-mcp.ts +0 -819
- package/src/mcp/servicenow-intelligent-mcp-refactored.ts +0 -977
- package/src/mcp/servicenow-intelligent-mcp.ts +0 -4638
- package/src/mcp/servicenow-mcp-server.ts +0 -728
- package/src/mcp/servicenow-memory-mcp.ts +0 -474
- package/src/mcp/servicenow-operations-mcp-refactored.ts +0 -1995
- package/src/mcp/servicenow-operations-mcp.ts +0 -3384
- package/src/mcp/servicenow-platform-development-mcp-refactored.ts +0 -611
- package/src/mcp/servicenow-platform-development-mcp.ts +0 -970
- package/src/mcp/servicenow-progressive-indexer.ts +0 -370
- package/src/mcp/servicenow-reporting-analytics-mcp-refactored.ts +0 -695
- package/src/mcp/servicenow-reporting-analytics-mcp.ts +0 -1123
- package/src/mcp/servicenow-security-compliance-mcp-refactored.ts +0 -642
- package/src/mcp/servicenow-security-compliance-mcp.ts +0 -1157
- package/src/mcp/servicenow-update-set-mcp-refactored.ts +0 -751
- package/src/mcp/servicenow-update-set-mcp.ts +0 -811
- package/src/mcp/shared/agent-context-provider.ts +0 -365
- package/src/mcp/shared/base-mcp-server.ts +0 -2463
- package/src/mcp/shared/mcp-memory-manager.ts +0 -540
- package/src/mcp/shared/mcp-resource-manager.ts +0 -367
- package/src/mcp/snow-flow-mcp.ts +0 -911
- package/src/mcp/start-all-mcp-servers.ts +0 -102
- package/src/mcp/start-servicenow-mcp.ts +0 -67
- package/src/monitoring/enhanced-monitoring-system.ts +0 -1345
- package/src/monitoring/performance-tracker.ts +0 -777
- package/src/optimization/cost-optimization-engine.ts +0 -1125
- package/src/optimization/index.ts +0 -10
- package/src/queen/README.md +0 -403
- package/src/queen/agent-factory.ts +0 -574
- package/src/queen/index.ts +0 -94
- package/src/queen/mcp-execution-bridge.ts +0 -681
- package/src/queen/neural-learning.ts +0 -319
- package/src/queen/parallel-agent-engine.ts +0 -848
- package/src/queen/queen-memory-system.ts +0 -490
- package/src/queen/queen-memory.ts +0 -456
- package/src/queen/servicenow-queen.ts +0 -1029
- package/src/queen/types.ts +0 -87
- package/src/rollback/smart-rollback-system.ts +0 -866
- package/src/schemas/deployment.schema.json +0 -58
- package/src/schemas/flow.schema.json +0 -79
- package/src/schemas/widget.schema.json +0 -72
- package/src/snow-flow-system.ts +0 -541
- package/src/sparc/sparc-help.ts +0 -49
- package/src/sparc/team-sparc.ts +0 -88
- package/src/strategies/global-scope-strategy.ts +0 -736
- package/src/templates/base/application.template.json +0 -45
- package/src/templates/base/business_rule.template.json +0 -33
- package/src/templates/base/script_include.template.json +0 -18
- package/src/templates/base/table.template.json +0 -64
- package/src/templates/base/widget.template.json +0 -25
- package/src/templates/patterns/composite.incident-management.template.json +0 -140
- package/src/templates/patterns/widget.dashboard.template.json +0 -238
- package/src/templates/patterns/widget.datatable.template.json +0 -292
- package/src/testing/integration-test-suite.ts +0 -1276
- package/src/types/index.ts +0 -183
- package/src/types/neo4j-driver.d.ts +0 -23
- package/src/types/servicenow.types.ts +0 -307
- package/src/types/snow-flow.types.ts +0 -186
- package/src/types/todo.types.ts +0 -70
- package/src/utils/action-type-cache.ts +0 -286
- package/src/utils/agent-detector.ts +0 -573
- package/src/utils/artifact-tracker.ts +0 -379
- package/src/utils/dependency-detector.ts +0 -233
- package/src/utils/deployment-metadata-handler.ts +0 -518
- package/src/utils/error-recovery.ts +0 -680
- package/src/utils/logger.ts +0 -60
- package/src/utils/mcp-auth-middleware.ts +0 -262
- package/src/utils/mcp-config-manager.ts +0 -270
- package/src/utils/mcp-server-manager.ts +0 -446
- package/src/utils/mcp-tool-registry.ts +0 -298
- package/src/utils/migrate-snow-flow.ts +0 -98
- package/src/utils/oauth-html-templates.ts +0 -188
- package/src/utils/scope-utils.ts +0 -443
- package/src/utils/servicenow-client.ts +0 -3321
- package/src/utils/servicenow-id-generator.ts +0 -181
- package/src/utils/snow-memory-manager.ts +0 -605
- package/src/utils/snow-oauth.ts +0 -797
- package/src/utils/template-engine.ts +0 -463
- package/src/utils/theme-manager.ts +0 -295
- package/src/utils/unified-auth-store.ts +0 -222
- package/src/utils/update-set-importer.ts +0 -422
- package/src/utils/update-set-xml-packager.ts +0 -371
- package/src/utils/widget-template-generator.ts +0 -1744
- package/src/version.ts +0 -1950
|
@@ -1,751 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* ServiceNow Update Set Management MCP Server - REFACTORED
|
|
4
|
-
* Uses BaseMCPServer to eliminate code duplication
|
|
5
|
-
* Ensures all changes are tracked in Update Sets for safe deployment
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { BaseMCPServer, ToolResult } from './base-mcp-server.js';
|
|
9
|
-
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
10
|
-
import { promises as fs } from 'fs';
|
|
11
|
-
import { join } from 'path';
|
|
12
|
-
|
|
13
|
-
interface UpdateSetSession {
|
|
14
|
-
update_set_id: string;
|
|
15
|
-
name: string;
|
|
16
|
-
description: string;
|
|
17
|
-
user_story?: string;
|
|
18
|
-
created_at: string;
|
|
19
|
-
state: 'in_progress' | 'complete' | 'released';
|
|
20
|
-
artifacts: Array<{
|
|
21
|
-
type: string;
|
|
22
|
-
sys_id: string;
|
|
23
|
-
name: string;
|
|
24
|
-
created_at: string;
|
|
25
|
-
}>;
|
|
26
|
-
auto_switched?: boolean;
|
|
27
|
-
active_session?: boolean;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export class ServiceNowUpdateSetMCP extends BaseMCPServer {
|
|
31
|
-
protected setupTools(): void {
|
|
32
|
-
// Tools are set up via getTools() method
|
|
33
|
-
}
|
|
34
|
-
private currentSession: UpdateSetSession | null = null;
|
|
35
|
-
private sessionsPath: string;
|
|
36
|
-
|
|
37
|
-
constructor() {
|
|
38
|
-
super({
|
|
39
|
-
name: 'servicenow-update-set',
|
|
40
|
-
version: '2.0.0',
|
|
41
|
-
description: 'Update Set management server with BaseMCPServer pattern'
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
this.sessionsPath = join(process.cwd(), 'memory', 'update-set-sessions');
|
|
45
|
-
this.ensureSessionsDirectory();
|
|
46
|
-
this.loadActiveSession();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
protected getTools(): Tool[] {
|
|
50
|
-
return [
|
|
51
|
-
{
|
|
52
|
-
name: 'snow_update_set_create',
|
|
53
|
-
description: 'Create a new Update Set for a user story or feature - ALWAYS use this before making changes',
|
|
54
|
-
inputSchema: {
|
|
55
|
-
type: 'object',
|
|
56
|
-
properties: {
|
|
57
|
-
name: { type: 'string', description: 'Update Set name (e.g., "STORY-123: Add incident widget")' },
|
|
58
|
-
description: { type: 'string', description: 'Detailed description of changes' },
|
|
59
|
-
user_story: { type: 'string', description: 'User story or ticket number' },
|
|
60
|
-
release_date: { type: 'string', description: 'Target release date (optional)' },
|
|
61
|
-
auto_switch: {
|
|
62
|
-
type: 'boolean',
|
|
63
|
-
default: true,
|
|
64
|
-
description: 'Automatically switch to the created Update Set (default: true)'
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
required: ['name', 'description']
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
name: 'snow_update_set_switch',
|
|
72
|
-
description: 'Switch to an existing Update Set - use this to continue work on a story',
|
|
73
|
-
inputSchema: {
|
|
74
|
-
type: 'object',
|
|
75
|
-
properties: {
|
|
76
|
-
update_set_id: { type: 'string', description: 'Update Set sys_id to switch to' }
|
|
77
|
-
},
|
|
78
|
-
required: ['update_set_id']
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: 'snow_update_set_current',
|
|
83
|
-
description: 'Get the current active Update Set session',
|
|
84
|
-
inputSchema: {
|
|
85
|
-
type: 'object',
|
|
86
|
-
properties: {}
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
name: 'snow_update_set_list',
|
|
91
|
-
description: 'List all Update Sets (in progress and recent)',
|
|
92
|
-
inputSchema: {
|
|
93
|
-
type: 'object',
|
|
94
|
-
properties: {
|
|
95
|
-
limit: { type: 'number', description: 'Maximum number of results (default: 10)' },
|
|
96
|
-
state: {
|
|
97
|
-
type: 'string',
|
|
98
|
-
enum: ['in_progress', 'complete', 'released'],
|
|
99
|
-
description: 'Filter by state'
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: 'snow_update_set_complete',
|
|
106
|
-
description: 'Mark Update Set as complete and ready for testing',
|
|
107
|
-
inputSchema: {
|
|
108
|
-
type: 'object',
|
|
109
|
-
properties: {
|
|
110
|
-
update_set_id: { type: 'string', description: 'Update Set sys_id to complete (uses current if not specified)' },
|
|
111
|
-
notes: { type: 'string', description: 'Completion notes or testing instructions' }
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
name: 'snow_update_set_add_artifact',
|
|
117
|
-
description: 'Track an artifact in the current Update Set session',
|
|
118
|
-
inputSchema: {
|
|
119
|
-
type: 'object',
|
|
120
|
-
properties: {
|
|
121
|
-
type: { type: 'string', description: 'Artifact type (widget, flow, script, etc.)' },
|
|
122
|
-
sys_id: { type: 'string', description: 'ServiceNow sys_id of the artifact' },
|
|
123
|
-
name: { type: 'string', description: 'Artifact name for tracking' }
|
|
124
|
-
},
|
|
125
|
-
required: ['type', 'sys_id', 'name']
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: 'snow_ensure_active_update_set',
|
|
130
|
-
description: 'Ensure there is an active Update Set session - creates one automatically if needed',
|
|
131
|
-
inputSchema: {
|
|
132
|
-
type: 'object',
|
|
133
|
-
properties: {
|
|
134
|
-
context: { type: 'string', description: 'Context for auto-created Update Set (e.g., "widget development", "flow creation")' },
|
|
135
|
-
auto_create: {
|
|
136
|
-
type: 'boolean',
|
|
137
|
-
default: true,
|
|
138
|
-
description: 'Automatically create Update Set if none exists (default: true)'
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
name: 'snow_update_set_preview',
|
|
145
|
-
description: 'Preview all changes in an Update Set',
|
|
146
|
-
inputSchema: {
|
|
147
|
-
type: 'object',
|
|
148
|
-
properties: {
|
|
149
|
-
update_set_id: { type: 'string', description: 'Update Set sys_id (uses current if not specified)' }
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
name: 'snow_update_set_export',
|
|
155
|
-
description: 'Export Update Set as XML for backup or migration',
|
|
156
|
-
inputSchema: {
|
|
157
|
-
type: 'object',
|
|
158
|
-
properties: {
|
|
159
|
-
update_set_id: { type: 'string', description: 'Update Set sys_id to export' },
|
|
160
|
-
output_path: { type: 'string', description: 'Path to save the XML file' }
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
];
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
protected async executeTool(name: string, args: any): Promise<ToolResult> {
|
|
168
|
-
switch (name) {
|
|
169
|
-
case 'snow_update_set_create':
|
|
170
|
-
return this.createUpdateSet(args);
|
|
171
|
-
case 'snow_update_set_switch':
|
|
172
|
-
return this.switchUpdateSet(args);
|
|
173
|
-
case 'snow_update_set_current':
|
|
174
|
-
return this.getCurrentUpdateSet();
|
|
175
|
-
case 'snow_update_set_list':
|
|
176
|
-
return this.listUpdateSets(args);
|
|
177
|
-
case 'snow_update_set_complete':
|
|
178
|
-
return this.completeUpdateSet(args);
|
|
179
|
-
case 'snow_update_set_add_artifact':
|
|
180
|
-
return this.addArtifactToSession(args);
|
|
181
|
-
case 'snow_ensure_active_update_set':
|
|
182
|
-
return this.ensureActiveUpdateSet(args);
|
|
183
|
-
case 'snow_update_set_preview':
|
|
184
|
-
return this.previewUpdateSet(args);
|
|
185
|
-
case 'snow_update_set_export':
|
|
186
|
-
return this.exportUpdateSet(args);
|
|
187
|
-
default:
|
|
188
|
-
return {
|
|
189
|
-
success: false,
|
|
190
|
-
error: `Unknown tool: ${name}`
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
private async createUpdateSet(args: any): Promise<ToolResult> {
|
|
196
|
-
const startTime = Date.now();
|
|
197
|
-
|
|
198
|
-
try {
|
|
199
|
-
const { name, description, user_story, release_date, auto_switch = true } = args;
|
|
200
|
-
|
|
201
|
-
// Create Update Set in ServiceNow
|
|
202
|
-
const updateSetData = {
|
|
203
|
-
name,
|
|
204
|
-
description,
|
|
205
|
-
user_story,
|
|
206
|
-
release_date: release_date || '',
|
|
207
|
-
state: 'in_progress',
|
|
208
|
-
application: 'global'
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
const response = await this.client.makeRequest({
|
|
212
|
-
method: 'POST',
|
|
213
|
-
url: '/api/now/table/sys_update_set',
|
|
214
|
-
data: updateSetData
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
// Validate response structure
|
|
218
|
-
if (!response || !response.result) {
|
|
219
|
-
throw new Error(`Invalid API response: ${JSON.stringify(response)}`);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const updateSet = response.result;
|
|
223
|
-
|
|
224
|
-
// Create session
|
|
225
|
-
const session: UpdateSetSession = {
|
|
226
|
-
update_set_id: updateSet.sys_id,
|
|
227
|
-
name: updateSet.name,
|
|
228
|
-
description: updateSet.description,
|
|
229
|
-
user_story: updateSet.user_story,
|
|
230
|
-
created_at: new Date().toISOString(),
|
|
231
|
-
state: 'in_progress',
|
|
232
|
-
artifacts: [],
|
|
233
|
-
auto_switched: auto_switch,
|
|
234
|
-
active_session: auto_switch
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
// Save session
|
|
238
|
-
await this.saveSession(session);
|
|
239
|
-
|
|
240
|
-
// Switch to new Update Set if requested
|
|
241
|
-
if (auto_switch) {
|
|
242
|
-
await this.switchToUpdateSet(updateSet.sys_id);
|
|
243
|
-
this.currentSession = session;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
this.logger.info(`Created Update Set: ${name} (${updateSet.sys_id})`);
|
|
247
|
-
|
|
248
|
-
return {
|
|
249
|
-
success: true,
|
|
250
|
-
result: {
|
|
251
|
-
update_set_id: updateSet.sys_id,
|
|
252
|
-
name: updateSet.name,
|
|
253
|
-
switched: auto_switch,
|
|
254
|
-
session_created: true
|
|
255
|
-
},
|
|
256
|
-
executionTime: Date.now() - startTime
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
} catch (error) {
|
|
260
|
-
this.logger.error('Failed to create Update Set', error);
|
|
261
|
-
return {
|
|
262
|
-
success: false,
|
|
263
|
-
error: error instanceof Error ? error.message : 'Failed to create Update Set',
|
|
264
|
-
retryable: false, // Simplified error handling
|
|
265
|
-
executionTime: Date.now() - startTime
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
private async switchUpdateSet(args: any): Promise<ToolResult> {
|
|
271
|
-
const startTime = Date.now();
|
|
272
|
-
|
|
273
|
-
try {
|
|
274
|
-
const { update_set_id } = args;
|
|
275
|
-
|
|
276
|
-
// Switch in ServiceNow
|
|
277
|
-
await this.switchToUpdateSet(update_set_id);
|
|
278
|
-
|
|
279
|
-
// Load or create session for this Update Set
|
|
280
|
-
let session = await this.loadSessionById(update_set_id);
|
|
281
|
-
|
|
282
|
-
if (!session) {
|
|
283
|
-
// Fetch Update Set details from ServiceNow
|
|
284
|
-
const response = await this.client.makeRequest({
|
|
285
|
-
method: 'GET',
|
|
286
|
-
url: `/api/now/table/sys_update_set/${update_set_id}`
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
const updateSet = response.result;
|
|
290
|
-
|
|
291
|
-
// Create new session
|
|
292
|
-
session = {
|
|
293
|
-
update_set_id: updateSet.sys_id,
|
|
294
|
-
name: updateSet.name,
|
|
295
|
-
description: updateSet.description,
|
|
296
|
-
user_story: updateSet.user_story,
|
|
297
|
-
created_at: updateSet.sys_created_on,
|
|
298
|
-
state: updateSet.state,
|
|
299
|
-
artifacts: [],
|
|
300
|
-
active_session: true
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
await this.saveSession(session);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Mark as current session
|
|
307
|
-
this.currentSession = session;
|
|
308
|
-
this.currentSession.active_session = true;
|
|
309
|
-
await this.saveSession(this.currentSession);
|
|
310
|
-
|
|
311
|
-
return {
|
|
312
|
-
success: true,
|
|
313
|
-
result: {
|
|
314
|
-
update_set_id: session.update_set_id,
|
|
315
|
-
name: session.name,
|
|
316
|
-
artifacts_count: session.artifacts.length
|
|
317
|
-
},
|
|
318
|
-
executionTime: Date.now() - startTime
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
} catch (error) {
|
|
322
|
-
this.logger.error('Failed to switch Update Set', error);
|
|
323
|
-
return {
|
|
324
|
-
success: false,
|
|
325
|
-
error: error instanceof Error ? error.message : 'Failed to switch Update Set',
|
|
326
|
-
retryable: false, // Simplified error handling
|
|
327
|
-
executionTime: Date.now() - startTime
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
private async getCurrentUpdateSet(): Promise<ToolResult> {
|
|
333
|
-
const startTime = Date.now();
|
|
334
|
-
|
|
335
|
-
try {
|
|
336
|
-
if (!this.currentSession) {
|
|
337
|
-
// Try to get from ServiceNow
|
|
338
|
-
const response = await this.client.makeRequest({
|
|
339
|
-
method: 'GET',
|
|
340
|
-
url: '/api/now/table/sys_update_set',
|
|
341
|
-
params: {
|
|
342
|
-
sysparm_query: 'state=in_progress^sys_created_byDYNAMIC90d1921e5f510100a9ad2572f2b477fe',
|
|
343
|
-
sysparm_limit: 1,
|
|
344
|
-
sysparm_fields: 'sys_id,name,description,state'
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
if (response.result && response.result.length > 0) {
|
|
349
|
-
const updateSet = response.result[0];
|
|
350
|
-
return {
|
|
351
|
-
success: true,
|
|
352
|
-
result: {
|
|
353
|
-
update_set_id: updateSet.sys_id,
|
|
354
|
-
name: updateSet.name,
|
|
355
|
-
description: updateSet.description,
|
|
356
|
-
state: updateSet.state,
|
|
357
|
-
session_active: false
|
|
358
|
-
},
|
|
359
|
-
executionTime: Date.now() - startTime
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
return {
|
|
364
|
-
success: true,
|
|
365
|
-
result: {
|
|
366
|
-
message: 'No active Update Set session found',
|
|
367
|
-
recommendation: 'Use snow_update_set_create to create a new Update Set'
|
|
368
|
-
},
|
|
369
|
-
executionTime: Date.now() - startTime
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return {
|
|
374
|
-
success: true,
|
|
375
|
-
result: {
|
|
376
|
-
update_set_id: this.currentSession.update_set_id,
|
|
377
|
-
name: this.currentSession.name,
|
|
378
|
-
description: this.currentSession.description,
|
|
379
|
-
state: this.currentSession.state,
|
|
380
|
-
artifacts_count: this.currentSession.artifacts.length,
|
|
381
|
-
artifacts: this.currentSession.artifacts,
|
|
382
|
-
session_active: true
|
|
383
|
-
},
|
|
384
|
-
executionTime: Date.now() - startTime
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
} catch (error) {
|
|
388
|
-
this.logger.error('Failed to get current Update Set', error);
|
|
389
|
-
return {
|
|
390
|
-
success: false,
|
|
391
|
-
error: error instanceof Error ? error.message : 'Failed to get current Update Set',
|
|
392
|
-
retryable: false, // Simplified error handling
|
|
393
|
-
executionTime: Date.now() - startTime
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
private async listUpdateSets(args: any): Promise<ToolResult> {
|
|
399
|
-
const startTime = Date.now();
|
|
400
|
-
|
|
401
|
-
try {
|
|
402
|
-
const { limit = 10, state } = args;
|
|
403
|
-
|
|
404
|
-
let query = 'ORDERBYDESCsys_created_on';
|
|
405
|
-
if (state) {
|
|
406
|
-
query = `state=${state}^${query}`;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const response = await this.client.makeRequest({
|
|
410
|
-
method: 'GET',
|
|
411
|
-
url: '/api/now/table/sys_update_set',
|
|
412
|
-
params: {
|
|
413
|
-
sysparm_query: query,
|
|
414
|
-
sysparm_limit: limit,
|
|
415
|
-
sysparm_fields: 'sys_id,name,description,state,sys_created_on,sys_created_by'
|
|
416
|
-
}
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
return {
|
|
420
|
-
success: true,
|
|
421
|
-
result: {
|
|
422
|
-
update_sets: response.result,
|
|
423
|
-
count: response.result.length,
|
|
424
|
-
current_session: this.currentSession?.update_set_id
|
|
425
|
-
},
|
|
426
|
-
executionTime: Date.now() - startTime
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
} catch (error) {
|
|
430
|
-
this.logger.error('Failed to list Update Sets', error);
|
|
431
|
-
return {
|
|
432
|
-
success: false,
|
|
433
|
-
error: error instanceof Error ? error.message : 'Failed to list Update Sets',
|
|
434
|
-
retryable: false, // Simplified error handling
|
|
435
|
-
executionTime: Date.now() - startTime
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
private async completeUpdateSet(args: any): Promise<ToolResult> {
|
|
441
|
-
const startTime = Date.now();
|
|
442
|
-
|
|
443
|
-
try {
|
|
444
|
-
const { update_set_id, notes } = args;
|
|
445
|
-
const targetId = update_set_id || this.currentSession?.update_set_id;
|
|
446
|
-
|
|
447
|
-
if (!targetId) {
|
|
448
|
-
throw new Error('No Update Set specified and no active session');
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// Update state in ServiceNow
|
|
452
|
-
const updateData = {
|
|
453
|
-
state: 'complete',
|
|
454
|
-
description: notes ? `${this.currentSession?.description}\n\nCompletion Notes: ${notes}` : undefined
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
await (this as any).makeAuthenticatedRequest({
|
|
458
|
-
method: 'PATCH',
|
|
459
|
-
url: `/api/now/table/sys_update_set/${targetId}`,
|
|
460
|
-
data: updateData
|
|
461
|
-
});
|
|
462
|
-
|
|
463
|
-
// Update session if it's the current one
|
|
464
|
-
if (this.currentSession && this.currentSession.update_set_id === targetId) {
|
|
465
|
-
this.currentSession.state = 'complete';
|
|
466
|
-
await this.saveSession(this.currentSession);
|
|
467
|
-
this.currentSession = null; // Clear current session
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
return {
|
|
471
|
-
success: true,
|
|
472
|
-
result: {
|
|
473
|
-
update_set_id: targetId,
|
|
474
|
-
state: 'complete',
|
|
475
|
-
notes: notes || 'Update Set completed'
|
|
476
|
-
},
|
|
477
|
-
executionTime: Date.now() - startTime
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
} catch (error) {
|
|
481
|
-
this.logger.error('Failed to complete Update Set', error);
|
|
482
|
-
return {
|
|
483
|
-
success: false,
|
|
484
|
-
error: error instanceof Error ? error.message : 'Failed to complete Update Set',
|
|
485
|
-
retryable: false, // Simplified error handling
|
|
486
|
-
executionTime: Date.now() - startTime
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
private async addArtifactToSession(args: any): Promise<ToolResult> {
|
|
492
|
-
const startTime = Date.now();
|
|
493
|
-
|
|
494
|
-
try {
|
|
495
|
-
const { type, sys_id, name } = args;
|
|
496
|
-
|
|
497
|
-
if (!this.currentSession) {
|
|
498
|
-
throw new Error('No active Update Set session. Create or switch to an Update Set first.');
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// Add artifact to session
|
|
502
|
-
const artifact = {
|
|
503
|
-
type,
|
|
504
|
-
sys_id,
|
|
505
|
-
name,
|
|
506
|
-
created_at: new Date().toISOString()
|
|
507
|
-
};
|
|
508
|
-
|
|
509
|
-
this.currentSession.artifacts.push(artifact);
|
|
510
|
-
await this.saveSession(this.currentSession);
|
|
511
|
-
|
|
512
|
-
this.logger.info(`Tracked artifact: ${type} - ${name} (${sys_id})`);
|
|
513
|
-
|
|
514
|
-
return {
|
|
515
|
-
success: true,
|
|
516
|
-
result: {
|
|
517
|
-
artifact_tracked: true,
|
|
518
|
-
update_set_id: this.currentSession.update_set_id,
|
|
519
|
-
total_artifacts: this.currentSession.artifacts.length
|
|
520
|
-
},
|
|
521
|
-
executionTime: Date.now() - startTime
|
|
522
|
-
};
|
|
523
|
-
|
|
524
|
-
} catch (error) {
|
|
525
|
-
this.logger.error('Failed to track artifact', error);
|
|
526
|
-
return {
|
|
527
|
-
success: false,
|
|
528
|
-
error: error instanceof Error ? error.message : 'Failed to track artifact',
|
|
529
|
-
retryable: false,
|
|
530
|
-
executionTime: Date.now() - startTime
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
private async ensureActiveUpdateSet(args: any): Promise<ToolResult> {
|
|
536
|
-
const startTime = Date.now();
|
|
537
|
-
|
|
538
|
-
try {
|
|
539
|
-
const { context = 'general development', auto_create = true } = args;
|
|
540
|
-
|
|
541
|
-
// Check if we have an active session
|
|
542
|
-
if (this.currentSession && this.currentSession.state === 'in_progress') {
|
|
543
|
-
return {
|
|
544
|
-
success: true,
|
|
545
|
-
result: {
|
|
546
|
-
update_set_id: this.currentSession.update_set_id,
|
|
547
|
-
name: this.currentSession.name,
|
|
548
|
-
already_active: true
|
|
549
|
-
},
|
|
550
|
-
executionTime: Date.now() - startTime
|
|
551
|
-
};
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
// Check ServiceNow for active Update Sets
|
|
555
|
-
const response = await this.client.makeRequest({
|
|
556
|
-
method: 'GET',
|
|
557
|
-
url: '/api/now/table/sys_update_set',
|
|
558
|
-
params: {
|
|
559
|
-
sysparm_query: 'state=in_progress',
|
|
560
|
-
sysparm_limit: 1,
|
|
561
|
-
sysparm_fields: 'sys_id,name,description'
|
|
562
|
-
}
|
|
563
|
-
});
|
|
564
|
-
|
|
565
|
-
if (response.result && response.result.length > 0) {
|
|
566
|
-
// Switch to existing Update Set
|
|
567
|
-
const updateSet = response.result[0];
|
|
568
|
-
return this.switchUpdateSet({ update_set_id: updateSet.sys_id });
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// Auto-create if enabled
|
|
572
|
-
if (auto_create) {
|
|
573
|
-
const timestamp = new Date().toISOString().split('T')[0];
|
|
574
|
-
return this.createUpdateSet({
|
|
575
|
-
name: `Auto-created: ${context} - ${timestamp}`,
|
|
576
|
-
description: `Automatically created Update Set for ${context}`,
|
|
577
|
-
auto_switch: true
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
return {
|
|
582
|
-
success: false,
|
|
583
|
-
error: 'No active Update Set and auto-create disabled',
|
|
584
|
-
result: {
|
|
585
|
-
recommendation: 'Create an Update Set with snow_update_set_create'
|
|
586
|
-
},
|
|
587
|
-
executionTime: Date.now() - startTime
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
} catch (error) {
|
|
591
|
-
this.logger.error('Failed to ensure active Update Set', error);
|
|
592
|
-
return {
|
|
593
|
-
success: false,
|
|
594
|
-
error: error instanceof Error ? error.message : 'Failed to ensure active Update Set',
|
|
595
|
-
retryable: false, // Simplified error handling
|
|
596
|
-
executionTime: Date.now() - startTime
|
|
597
|
-
};
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
private async previewUpdateSet(args: any): Promise<ToolResult> {
|
|
602
|
-
const startTime = Date.now();
|
|
603
|
-
|
|
604
|
-
try {
|
|
605
|
-
const update_set_id = args.update_set_id || this.currentSession?.update_set_id;
|
|
606
|
-
|
|
607
|
-
if (!update_set_id) {
|
|
608
|
-
throw new Error('No Update Set specified and no active session');
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// Get Update Set details
|
|
612
|
-
const response = await this.client.makeRequest({
|
|
613
|
-
method: 'GET',
|
|
614
|
-
url: `/api/now/table/sys_update_xml`,
|
|
615
|
-
params: {
|
|
616
|
-
sysparm_query: `update_set=${update_set_id}`,
|
|
617
|
-
sysparm_fields: 'sys_id,name,type,target_name,action,sys_created_on'
|
|
618
|
-
}
|
|
619
|
-
});
|
|
620
|
-
|
|
621
|
-
return {
|
|
622
|
-
success: true,
|
|
623
|
-
result: {
|
|
624
|
-
update_set_id,
|
|
625
|
-
changes_count: response.result.length,
|
|
626
|
-
changes: response.result
|
|
627
|
-
},
|
|
628
|
-
executionTime: Date.now() - startTime
|
|
629
|
-
};
|
|
630
|
-
|
|
631
|
-
} catch (error) {
|
|
632
|
-
this.logger.error('Failed to preview Update Set', error);
|
|
633
|
-
return {
|
|
634
|
-
success: false,
|
|
635
|
-
error: error instanceof Error ? error.message : 'Failed to preview Update Set',
|
|
636
|
-
retryable: false, // Simplified error handling
|
|
637
|
-
executionTime: Date.now() - startTime
|
|
638
|
-
};
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
private async exportUpdateSet(args: any): Promise<ToolResult> {
|
|
643
|
-
const startTime = Date.now();
|
|
644
|
-
|
|
645
|
-
try {
|
|
646
|
-
const { update_set_id, output_path } = args;
|
|
647
|
-
|
|
648
|
-
if (!update_set_id) {
|
|
649
|
-
throw new Error('Update Set ID is required for export');
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
// Export Update Set as XML
|
|
653
|
-
const response = await this.client.makeRequest({
|
|
654
|
-
method: 'GET',
|
|
655
|
-
url: `/api/now/table/sys_update_set/${update_set_id}/export`,
|
|
656
|
-
responseType: 'text'
|
|
657
|
-
});
|
|
658
|
-
|
|
659
|
-
// Save to file if path provided
|
|
660
|
-
if (output_path) {
|
|
661
|
-
await fs.writeFile(output_path, response.result);
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
return {
|
|
665
|
-
success: true,
|
|
666
|
-
result: {
|
|
667
|
-
update_set_id,
|
|
668
|
-
exported: true,
|
|
669
|
-
output_path: output_path || 'returned in response',
|
|
670
|
-
size: response.result.length
|
|
671
|
-
},
|
|
672
|
-
executionTime: Date.now() - startTime
|
|
673
|
-
};
|
|
674
|
-
|
|
675
|
-
} catch (error) {
|
|
676
|
-
this.logger.error('Failed to export Update Set', error);
|
|
677
|
-
return {
|
|
678
|
-
success: false,
|
|
679
|
-
error: error instanceof Error ? error.message : 'Failed to export Update Set',
|
|
680
|
-
retryable: false, // Simplified error handling
|
|
681
|
-
executionTime: Date.now() - startTime
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// Helper methods
|
|
687
|
-
|
|
688
|
-
private async switchToUpdateSet(updateSetId: string): Promise<void> {
|
|
689
|
-
// Switch Update Set context in ServiceNow
|
|
690
|
-
await this.client.makeRequest({
|
|
691
|
-
method: 'PUT',
|
|
692
|
-
url: `/api/now/table/sys_user_preference`,
|
|
693
|
-
data: {
|
|
694
|
-
name: 'sys_update_set',
|
|
695
|
-
value: updateSetId,
|
|
696
|
-
user: 'current'
|
|
697
|
-
}
|
|
698
|
-
});
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
private async ensureSessionsDirectory(): Promise<void> {
|
|
702
|
-
try {
|
|
703
|
-
await fs.mkdir(this.sessionsPath, { recursive: true });
|
|
704
|
-
} catch (error) {
|
|
705
|
-
this.logger.error('Failed to create sessions directory', error);
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
private async saveSession(session: UpdateSetSession): Promise<void> {
|
|
710
|
-
const sessionFile = join(this.sessionsPath, `${session.update_set_id}.json`);
|
|
711
|
-
await fs.writeFile(sessionFile, JSON.stringify(session, null, 2));
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
private async loadSessionById(updateSetId: string): Promise<UpdateSetSession | null> {
|
|
715
|
-
try {
|
|
716
|
-
const sessionFile = join(this.sessionsPath, `${updateSetId}.json`);
|
|
717
|
-
const content = await fs.readFile(sessionFile, 'utf-8');
|
|
718
|
-
return JSON.parse(content);
|
|
719
|
-
} catch (error) {
|
|
720
|
-
return null;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
private async loadActiveSession(): Promise<void> {
|
|
725
|
-
try {
|
|
726
|
-
const files = await fs.readdir(this.sessionsPath);
|
|
727
|
-
|
|
728
|
-
for (const file of files) {
|
|
729
|
-
if (file.endsWith('.json')) {
|
|
730
|
-
const sessionFile = join(this.sessionsPath, file);
|
|
731
|
-
const content = await fs.readFile(sessionFile, 'utf-8');
|
|
732
|
-
const session = JSON.parse(content) as UpdateSetSession;
|
|
733
|
-
|
|
734
|
-
if (session.active_session && session.state === 'in_progress') {
|
|
735
|
-
this.currentSession = session;
|
|
736
|
-
this.logger.info(`Loaded active Update Set session: ${session.name}`);
|
|
737
|
-
break;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
} catch (error) {
|
|
742
|
-
this.logger.warn('No active Update Set session found');
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
// Create and run the server
|
|
748
|
-
if (require.main === module) {
|
|
749
|
-
const server = new ServiceNowUpdateSetMCP();
|
|
750
|
-
server.start().catch(console.error);
|
|
751
|
-
}
|