snow-flow 3.3.2 → 3.3.3

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 CHANGED
@@ -97,7 +97,7 @@ Snow-Flow provides 180+ tools across 17 specialized MCP servers:
97
97
  | Server | Tools | Primary Focus |
98
98
  |--------|-------|---------------|
99
99
  | servicenow-operations | 15 | CRUD operations, data management |
100
- | servicenow-deployment | 20 | Widget, portal, and application deployment |
100
+ | servicenow-deployment | 21 | Widget, portal, and application deployment (create & update) |
101
101
  | servicenow-platform-development | 12 | Table creation, field management |
102
102
  | servicenow-machine-learning | 15 | Neural networks, predictions, anomaly detection |
103
103
  | servicenow-reporting-analytics | 18 | Dashboards, reports, KPIs |
@@ -288,7 +288,7 @@ snow_query_table({
288
288
  ```
289
289
 
290
290
  ### Development Tools
291
- - Widget creation and deployment
291
+ - Widget creation and deployment (snow_deploy for new, snow_update for existing)
292
292
  - Business rule development
293
293
  - Script include management
294
294
  - Flow Designer automation
@@ -36,7 +36,7 @@ function getDynamicVersion() {
36
36
  console.warn('Warning: Could not read version from package.json:', error);
37
37
  }
38
38
  // Fallback to hardcoded version
39
- return '3.3.2';
39
+ return '3.3.3';
40
40
  }
41
41
  // Export a constant that uses the dynamic version
42
42
  exports.VERSION = getDynamicVersion();
@@ -234,9 +234,46 @@ class ServiceNowDeploymentMCP {
234
234
  required: ['name', 'artifacts'],
235
235
  },
236
236
  },
237
+ {
238
+ name: 'snow_update',
239
+ description: 'Updates existing ServiceNow artifacts (widgets, applications, etc.). Finds artifact by name or sys_id and modifies it. Use snow_deploy for creating new artifacts.',
240
+ inputSchema: {
241
+ type: 'object',
242
+ properties: {
243
+ type: {
244
+ type: 'string',
245
+ enum: ['widget', 'application', 'business_rule', 'script_include', 'ui_page'],
246
+ description: 'Type of artifact to update'
247
+ },
248
+ identifier: {
249
+ type: 'string',
250
+ description: 'sys_id or name of existing artifact to update'
251
+ },
252
+ config: {
253
+ type: 'object',
254
+ description: 'New configuration/content for the artifact'
255
+ },
256
+ instruction: {
257
+ type: 'string',
258
+ description: 'Natural language description of changes to make'
259
+ },
260
+ create_if_not_exists: {
261
+ type: 'boolean',
262
+ default: false,
263
+ description: 'Create artifact if it does not exist'
264
+ },
265
+ auto_update_set: {
266
+ type: 'boolean',
267
+ default: true,
268
+ description: 'Automatically manage update set'
269
+ }
270
+ },
271
+ required: ['type', 'identifier']
272
+ }
273
+ },
237
274
  {
238
275
  name: 'snow_deploy',
239
- description: 'Universal deployment tool for all ServiceNow artifacts. Features automatic update set management, permission escalation, retry logic, and comprehensive error recovery. Primary deployment method for v3.0.0+',
276
+ description: 'Universal deployment tool for creating NEW ServiceNow artifacts. For updating existing artifacts, use snow_update. Features automatic update set management, permission escalation, retry logic, and comprehensive error recovery.',
240
277
  inputSchema: {
241
278
  type: 'object',
242
279
  properties: {
@@ -313,6 +350,8 @@ class ServiceNowDeploymentMCP {
313
350
  return await this.createSolutionPackage(args);
314
351
  case 'snow_deploy':
315
352
  return await this.unifiedDeploy(args);
353
+ case 'snow_update':
354
+ return await this.updateArtifact(args);
316
355
  default:
317
356
  throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
318
357
  }
@@ -8092,6 +8131,260 @@ ${updateSetSession ? `📋 **Update Set**: ${updateSetSession.name}
8092
8131
  throw new Error(`Update Set session required for deployment. Error: ${error.message}`);
8093
8132
  }
8094
8133
  }
8134
+ /**
8135
+ * Update existing ServiceNow artifact
8136
+ */
8137
+ async updateArtifact(args) {
8138
+ try {
8139
+ this.logger.info('Starting artifact update', args);
8140
+ // Check authentication first
8141
+ const isAuthenticated = await this.oauth.isAuthenticated();
8142
+ if (!isAuthenticated) {
8143
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidRequest, 'Not authenticated. Run "snow-flow auth login" first.');
8144
+ }
8145
+ const { type, identifier, config, instruction, create_if_not_exists = false, auto_update_set = true } = args;
8146
+ // Step 1: Ensure Update Set if requested
8147
+ let updateSetSession = null;
8148
+ if (auto_update_set) {
8149
+ try {
8150
+ const ensureResponse = await this.ensureActiveUpdateSet(`${type} update: ${identifier}`);
8151
+ updateSetSession = ensureResponse.session;
8152
+ }
8153
+ catch (error) {
8154
+ this.logger.warn('Failed to ensure Update Set, continuing without', error);
8155
+ }
8156
+ }
8157
+ // Step 2: Determine table name
8158
+ let tableName;
8159
+ switch (type) {
8160
+ case 'widget':
8161
+ tableName = 'sp_widget';
8162
+ break;
8163
+ case 'application':
8164
+ tableName = 'sys_app';
8165
+ break;
8166
+ case 'business_rule':
8167
+ tableName = 'sys_script';
8168
+ break;
8169
+ case 'script_include':
8170
+ tableName = 'sys_script_include';
8171
+ break;
8172
+ case 'ui_page':
8173
+ tableName = 'sys_ui_page';
8174
+ break;
8175
+ default:
8176
+ throw new Error(`Unsupported artifact type: ${type}`);
8177
+ }
8178
+ // Step 3: Find existing artifact
8179
+ let existingArtifact = null;
8180
+ let searchQuery = '';
8181
+ // Check if identifier is a sys_id (32 char hex) or a name
8182
+ const isSysId = /^[a-f0-9]{32}$/.test(identifier);
8183
+ if (isSysId) {
8184
+ searchQuery = `sys_id=${identifier}`;
8185
+ }
8186
+ else {
8187
+ searchQuery = `name=${identifier}`;
8188
+ }
8189
+ this.logger.info(`Searching for ${type} with query: ${searchQuery}`);
8190
+ try {
8191
+ const searchResponse = await this.client.searchRecords(tableName, searchQuery, 1);
8192
+ if (searchResponse?.data?.result?.length > 0) {
8193
+ existingArtifact = searchResponse.data.result[0];
8194
+ this.logger.info(`Found existing ${type}: ${existingArtifact.sys_id}`);
8195
+ }
8196
+ }
8197
+ catch (searchError) {
8198
+ this.logger.error(`Failed to search for ${type}:`, searchError);
8199
+ }
8200
+ // Step 4: Handle artifact not found
8201
+ if (!existingArtifact) {
8202
+ if (create_if_not_exists) {
8203
+ this.logger.info(`${type} not found, creating new one as requested`);
8204
+ // Delegate to snow_deploy for creation
8205
+ return await this.unifiedDeploy({
8206
+ type,
8207
+ config,
8208
+ instruction,
8209
+ auto_update_set
8210
+ });
8211
+ }
8212
+ else {
8213
+ return {
8214
+ content: [{
8215
+ type: 'text',
8216
+ text: `❌ ${type} not found: "${identifier}"
8217
+
8218
+ 🔍 **Search Details:**
8219
+ - Table: ${tableName}
8220
+ - Search Query: ${searchQuery}
8221
+ - Results: 0
8222
+
8223
+ 💡 **Suggestions:**
8224
+ 1. Check the ${isSysId ? 'sys_id' : 'name'} is correct
8225
+ 2. Verify you have read permissions for ${tableName}
8226
+ 3. Use exact ${isSysId ? 'sys_id format (32 char hex)' : 'name (case sensitive)'}
8227
+ 4. Add create_if_not_exists: true to create if missing
8228
+
8229
+ 🔧 **Alternative Commands:**
8230
+ - List existing: \`snow_query_table({ table: "${tableName}", limit: 10 })\`
8231
+ - Create new: \`snow_deploy({ type: "${type}", ... })\`
8232
+ - Find by name: \`snow_update({ type: "${type}", identifier: "exact_name" })\``
8233
+ }]
8234
+ };
8235
+ }
8236
+ }
8237
+ // Step 5: Process update configuration
8238
+ let updateData = {};
8239
+ if (instruction) {
8240
+ // Natural language instruction - convert to specific updates
8241
+ updateData = await this.processUpdateInstruction(type, instruction, existingArtifact);
8242
+ }
8243
+ else if (config) {
8244
+ updateData = config;
8245
+ }
8246
+ else {
8247
+ throw new Error('Either instruction or config must be provided for update');
8248
+ }
8249
+ // Step 6: Perform the update
8250
+ this.logger.info(`Updating ${type} ${existingArtifact.sys_id}`, updateData);
8251
+ const updateResponse = await this.client.updateRecord(tableName, existingArtifact.sys_id, updateData);
8252
+ if (!updateResponse?.success) {
8253
+ throw new Error(`Failed to update ${type}: ${updateResponse?.error || 'Unknown error'}`);
8254
+ }
8255
+ // Step 7: Track the update
8256
+ if (updateSetSession) {
8257
+ artifact_tracker_js_1.artifactTracker.trackArtifact({
8258
+ type: type,
8259
+ name: existingArtifact.name,
8260
+ sys_id: existingArtifact.sys_id,
8261
+ operation: 'update',
8262
+ table: tableName,
8263
+ update_set_id: updateSetSession.update_set_id
8264
+ });
8265
+ }
8266
+ // Step 8: Return success response
8267
+ const updatedFields = Object.keys(updateData);
8268
+ return {
8269
+ content: [{
8270
+ type: 'text',
8271
+ text: `✅ ${type} updated successfully!
8272
+
8273
+ 📝 **Updated Artifact:**
8274
+ - Name: ${existingArtifact.name}
8275
+ - sys_id: ${existingArtifact.sys_id}
8276
+ - Table: ${tableName}
8277
+
8278
+ 🔧 **Fields Updated:**
8279
+ ${updatedFields.map(field => `- ${field}`).join('\n')}
8280
+
8281
+ ${updateSetSession ? `📦 **Update Set:**
8282
+ - Name: ${updateSetSession.name}
8283
+ - sys_id: ${updateSetSession.update_set_id}
8284
+ - Ready for promotion to higher environments` : '🔄 Changes made outside Update Set - track manually'}
8285
+
8286
+ 💡 **Next Steps:**
8287
+ 1. Test the updated ${type} in your environment
8288
+ 2. ${updateSetSession ? 'Preview and commit Update Set when ready' : 'Create Update Set to track changes'}
8289
+ 3. Promote to production after validation
8290
+
8291
+ 🔗 **ServiceNow Links:**
8292
+ - View artifact: /nav_to.do?uri=${tableName}.do?sys_id=${existingArtifact.sys_id}
8293
+ ${updateSetSession ? `- View Update Set: /nav_to.do?uri=sys_update_set.do?sys_id=${updateSetSession.update_set_id}` : ''}`
8294
+ }]
8295
+ };
8296
+ }
8297
+ catch (error) {
8298
+ this.logger.error('Artifact update failed:', error);
8299
+ return {
8300
+ content: [{
8301
+ type: 'text',
8302
+ text: `❌ Failed to update ${args.type}: ${error.message}
8303
+
8304
+ 🔍 **Troubleshooting:**
8305
+ 1. Verify the artifact exists: \`snow_query_table({ table: "${this.getTableName(args.type)}", query: "name=${args.identifier}" })\`
8306
+ 2. Check permissions for ${this.getTableName(args.type)} table
8307
+ 3. Ensure Update Set is active (if required)
8308
+ 4. Try with create_if_not_exists: true if artifact might not exist
8309
+
8310
+ 💡 **Alternative:**
8311
+ Use \`snow_deploy\` to create a new ${args.type} instead.`
8312
+ }]
8313
+ };
8314
+ }
8315
+ }
8316
+ /**
8317
+ * Process natural language instruction for updates
8318
+ */
8319
+ async processUpdateInstruction(type, instruction, existingArtifact) {
8320
+ const updateData = {};
8321
+ // Simple natural language processing for common update patterns
8322
+ const lowerInstruction = instruction.toLowerCase();
8323
+ if (type === 'widget') {
8324
+ // Widget-specific updates
8325
+ if (lowerInstruction.includes('html') || lowerInstruction.includes('template')) {
8326
+ if (lowerInstruction.includes('add') || lowerInstruction.includes('update')) {
8327
+ // Extract HTML content if provided
8328
+ const htmlMatch = instruction.match(/```html\s*\n([\s\S]*?)\n```/);
8329
+ if (htmlMatch) {
8330
+ updateData.template = htmlMatch[1];
8331
+ }
8332
+ }
8333
+ }
8334
+ if (lowerInstruction.includes('css') || lowerInstruction.includes('style')) {
8335
+ const cssMatch = instruction.match(/```css\s*\n([\s\S]*?)\n```/);
8336
+ if (cssMatch) {
8337
+ updateData.css = cssMatch[1];
8338
+ }
8339
+ }
8340
+ if (lowerInstruction.includes('script') || lowerInstruction.includes('javascript')) {
8341
+ const jsMatch = instruction.match(/```javascript\s*\n([\s\S]*?)\n```/);
8342
+ if (jsMatch) {
8343
+ updateData.script = jsMatch[1];
8344
+ }
8345
+ }
8346
+ if (lowerInstruction.includes('server') || lowerInstruction.includes('server script')) {
8347
+ const serverMatch = instruction.match(/```javascript\s*\n([\s\S]*?)\n```/);
8348
+ if (serverMatch) {
8349
+ updateData.script = serverMatch[1];
8350
+ }
8351
+ }
8352
+ // Update description if mentioned
8353
+ if (lowerInstruction.includes('description')) {
8354
+ const descMatch = instruction.match(/description:?\s*["']([^"']+)["']/i);
8355
+ if (descMatch) {
8356
+ updateData.short_description = descMatch[1];
8357
+ }
8358
+ }
8359
+ }
8360
+ // If no specific patterns matched, add as general update
8361
+ if (Object.keys(updateData).length === 0) {
8362
+ // For now, return instruction for manual processing
8363
+ updateData._instruction = instruction;
8364
+ // You could add more sophisticated NLP processing here
8365
+ // or integrate with AI services to interpret the instruction
8366
+ }
8367
+ return updateData;
8368
+ }
8369
+ /**
8370
+ * Get table name for artifact type
8371
+ */
8372
+ getTableName(type) {
8373
+ switch (type) {
8374
+ case 'widget':
8375
+ return 'sp_widget';
8376
+ case 'application':
8377
+ return 'sys_app';
8378
+ case 'business_rule':
8379
+ return 'sys_script';
8380
+ case 'script_include':
8381
+ return 'sys_script_include';
8382
+ case 'ui_page':
8383
+ return 'sys_ui_page';
8384
+ default:
8385
+ return 'sys_metadata';
8386
+ }
8387
+ }
8095
8388
  async start() {
8096
8389
  const transport = new stdio_js_1.StdioServerTransport();
8097
8390
  await this.server.connect(transport);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "snow-flow",
3
- "version": "3.3.2",
4
- "description": "Snow-Flow v3.3.2: ServiceNow development platform with 180+ MCP tools. Enhanced MCP servers with real-time progress indicators, per-operation token tracking (tokens reset per call), and comprehensive operation logging. Supports ATF Testing, Knowledge Management, Service Catalog, Change Management, Virtual Agent, Performance Analytics, Flow Designer, Agent Workspace, Mobile, CMDB/Discovery, Event Management, HR Service Delivery, Customer Service Management, and DevOps integration. All tools use official ServiceNow REST APIs across 17 specialized MCP servers with full visibility into API operations.",
3
+ "version": "3.3.3",
4
+ "description": "Snow-Flow v3.3.3: ServiceNow development platform with 180+ MCP tools. NEW: snow_update tool for updating existing artifacts (vs snow_deploy for new). Enhanced MCP servers with real-time progress indicators, per-operation token tracking (tokens reset per call), and comprehensive operation logging. Supports ATF Testing, Knowledge Management, Service Catalog, Change Management, Virtual Agent, Performance Analytics, Flow Designer, Agent Workspace, Mobile, CMDB/Discovery, Event Management, HR Service Delivery, Customer Service Management, and DevOps integration. All tools use official ServiceNow REST APIs across 17 specialized MCP servers with full visibility into API operations.",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",
7
7
  "bin": {