snow-flow 3.3.3 → 3.3.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.
@@ -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.3';
39
+ return '3.3.4';
40
40
  }
41
41
  // Export a constant that uses the dynamic version
42
42
  exports.VERSION = getDynamicVersion();
@@ -242,7 +242,11 @@ class ServiceNowDeploymentMCP {
242
242
  properties: {
243
243
  type: {
244
244
  type: 'string',
245
- enum: ['widget', 'application', 'business_rule', 'script_include', 'ui_page'],
245
+ enum: [
246
+ 'widget', 'application', 'business_rule', 'script_include', 'ui_page',
247
+ 'client_script', 'ui_action', 'ui_policy', 'acl', 'table', 'field',
248
+ 'workflow', 'flow', 'notification', 'scheduled_job'
249
+ ],
246
250
  description: 'Type of artifact to update'
247
251
  },
248
252
  identifier: {
@@ -279,7 +283,11 @@ class ServiceNowDeploymentMCP {
279
283
  properties: {
280
284
  type: {
281
285
  type: 'string',
282
- enum: ['widget', 'portal_page', 'application', 'script', 'business_rule', 'table'],
286
+ enum: [
287
+ 'widget', 'portal_page', 'application', 'script', 'business_rule', 'table',
288
+ 'script_include', 'ui_page', 'client_script', 'ui_action', 'ui_policy',
289
+ 'acl', 'field', 'workflow', 'flow', 'notification', 'scheduled_job'
290
+ ],
283
291
  description: 'Type of artifact to deploy'
284
292
  },
285
293
  instruction: {
@@ -8172,6 +8180,36 @@ ${updateSetSession ? `📋 **Update Set**: ${updateSetSession.name}
8172
8180
  case 'ui_page':
8173
8181
  tableName = 'sys_ui_page';
8174
8182
  break;
8183
+ case 'client_script':
8184
+ tableName = 'sys_script_client';
8185
+ break;
8186
+ case 'ui_action':
8187
+ tableName = 'sys_ui_action';
8188
+ break;
8189
+ case 'ui_policy':
8190
+ tableName = 'sys_ui_policy';
8191
+ break;
8192
+ case 'acl':
8193
+ tableName = 'sys_security_acl';
8194
+ break;
8195
+ case 'table':
8196
+ tableName = 'sys_db_object';
8197
+ break;
8198
+ case 'field':
8199
+ tableName = 'sys_dictionary';
8200
+ break;
8201
+ case 'workflow':
8202
+ tableName = 'wf_workflow';
8203
+ break;
8204
+ case 'flow':
8205
+ tableName = 'sys_hub_flow';
8206
+ break;
8207
+ case 'notification':
8208
+ tableName = 'sysevent_email_action';
8209
+ break;
8210
+ case 'scheduled_job':
8211
+ tableName = 'sysauto_script';
8212
+ break;
8175
8213
  default:
8176
8214
  throw new Error(`Unsupported artifact type: ${type}`);
8177
8215
  }
@@ -8254,14 +8292,7 @@ ${updateSetSession ? `📋 **Update Set**: ${updateSetSession.name}
8254
8292
  }
8255
8293
  // Step 7: Track the update
8256
8294
  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
- });
8295
+ artifact_tracker_js_1.artifactTracker.trackArtifact(existingArtifact.sys_id, tableName, existingArtifact.name, type, 'update');
8265
8296
  }
8266
8297
  // Step 8: Return success response
8267
8298
  const updatedFields = Object.keys(updateData);
@@ -8316,55 +8347,465 @@ Use \`snow_deploy\` to create a new ${args.type} instead.`
8316
8347
  /**
8317
8348
  * Process natural language instruction for updates
8318
8349
  */
8350
+ /**
8351
+ * Intelligent Natural Language Processing for ServiceNow artifact updates
8352
+ * Converts natural language instructions into valid ServiceNow field updates
8353
+ */
8319
8354
  async processUpdateInstruction(type, instruction, existingArtifact) {
8320
8355
  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];
8356
+ const lowerInstruction = instruction.toLowerCase().trim();
8357
+ this.logger.info(`Processing update instruction for ${type}`, { instruction });
8358
+ try {
8359
+ // First, extract any code blocks or explicit values
8360
+ const codeBlocks = this.extractCodeBlocks(instruction);
8361
+ const explicitValues = this.extractExplicitValues(instruction);
8362
+ // Apply type-specific intelligent parsing
8363
+ switch (type) {
8364
+ case 'widget':
8365
+ await this.parseWidgetInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8366
+ break;
8367
+ case 'business_rule':
8368
+ case 'client_script':
8369
+ case 'script_include':
8370
+ await this.parseScriptInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8371
+ break;
8372
+ case 'ui_action':
8373
+ await this.parseUIActionInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8374
+ break;
8375
+ case 'ui_policy':
8376
+ await this.parseUIPolicyInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8377
+ break;
8378
+ case 'notification':
8379
+ await this.parseNotificationInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8380
+ break;
8381
+ case 'acl':
8382
+ await this.parseACLInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8383
+ break;
8384
+ case 'table':
8385
+ await this.parseTableInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8386
+ break;
8387
+ case 'field':
8388
+ await this.parseFieldInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8389
+ break;
8390
+ case 'workflow':
8391
+ await this.parseWorkflowInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8392
+ break;
8393
+ case 'flow':
8394
+ await this.parseFlowInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8395
+ break;
8396
+ case 'scheduled_job':
8397
+ await this.parseScheduledJobInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8398
+ break;
8399
+ default:
8400
+ // Generic parsing for unsupported types
8401
+ await this.parseGenericInstruction(updateData, lowerInstruction, codeBlocks, explicitValues, existingArtifact);
8402
+ }
8403
+ // Apply common field updates
8404
+ this.applyCommonUpdates(updateData, lowerInstruction, explicitValues);
8405
+ // Validate that we have valid updates
8406
+ if (Object.keys(updateData).length === 0) {
8407
+ throw new Error(`Unable to parse instruction: "${instruction}". Please use more specific language or provide explicit field values.
8408
+
8409
+ 📝 **Examples that work:**
8410
+ - "Change the title to 'New Widget Title'"
8411
+ - "Update the description to 'Updated description'"
8412
+ - "Add this CSS: .my-class { color: blue; }"
8413
+ - "Change the script to: function() { console.log('updated'); }"
8414
+ - "Set active to false"
8415
+
8416
+ 💡 **Or use the config parameter directly:**
8417
+ snow_update({
8418
+ type: "${type}",
8419
+ identifier: "${existingArtifact?.name || 'artifact_name'}",
8420
+ config: {
8421
+ field_name: "new_value"
8422
+ }
8423
+ })`);
8424
+ }
8425
+ this.logger.info(`Parsed ${Object.keys(updateData).length} field updates`, { updateData });
8426
+ return updateData;
8427
+ }
8428
+ catch (error) {
8429
+ this.logger.error('Failed to process update instruction', { error: error instanceof Error ? error.message : error });
8430
+ throw error;
8431
+ }
8432
+ }
8433
+ /**
8434
+ * Extract code blocks from instruction text
8435
+ */
8436
+ extractCodeBlocks(instruction) {
8437
+ const codeBlocks = {};
8438
+ // Extract different types of code blocks
8439
+ const htmlMatch = instruction.match(/```html\s*\n([\s\S]*?)\n```/i);
8440
+ if (htmlMatch)
8441
+ codeBlocks.html = htmlMatch[1].trim();
8442
+ const cssMatch = instruction.match(/```css\s*\n([\s\S]*?)\n```/i);
8443
+ if (cssMatch)
8444
+ codeBlocks.css = cssMatch[1].trim();
8445
+ const jsMatch = instruction.match(/```javascript\s*\n([\s\S]*?)\n```/i);
8446
+ if (jsMatch)
8447
+ codeBlocks.javascript = jsMatch[1].trim();
8448
+ const jsonMatch = instruction.match(/```json\s*\n([\s\S]*?)\n```/i);
8449
+ if (jsonMatch) {
8450
+ try {
8451
+ codeBlocks.json = JSON.parse(jsonMatch[1].trim());
8452
+ }
8453
+ catch (e) {
8454
+ codeBlocks.json = jsonMatch[1].trim();
8455
+ }
8456
+ }
8457
+ return codeBlocks;
8458
+ }
8459
+ /**
8460
+ * Extract explicit field values from instruction
8461
+ */
8462
+ extractExplicitValues(instruction) {
8463
+ const values = {};
8464
+ // Common patterns for explicit values
8465
+ const patterns = [
8466
+ { regex: /title[:\s]+["']([^"']+)["']/i, field: 'title' },
8467
+ { regex: /name[:\s]+["']([^"']+)["']/i, field: 'name' },
8468
+ { regex: /description[:\s]+["']([^"']+)["']/i, field: 'description' },
8469
+ { regex: /subject[:\s]+["']([^"']+)["']/i, field: 'subject' },
8470
+ { regex: /label[:\s]+["']([^"']+)["']/i, field: 'label' },
8471
+ { regex: /condition[:\s]+["']([^"']+)["']/i, field: 'condition' },
8472
+ { regex: /script[:\s]+["']([^"']+)["']/i, field: 'script' },
8473
+ { regex: /active[:\s]+(\w+)/i, field: 'active', transform: (v) => v.toLowerCase() === 'true' },
8474
+ { regex: /priority[:\s]+(\d+)/i, field: 'priority', transform: (v) => parseInt(v) },
8475
+ { regex: /order[:\s]+(\d+)/i, field: 'order', transform: (v) => parseInt(v) }
8476
+ ];
8477
+ for (const pattern of patterns) {
8478
+ const match = instruction.match(pattern.regex);
8479
+ if (match) {
8480
+ values[pattern.field] = pattern.transform ? pattern.transform(match[1]) : match[1];
8481
+ }
8482
+ }
8483
+ return values;
8484
+ }
8485
+ /**
8486
+ * Parse widget-specific instructions
8487
+ */
8488
+ async parseWidgetInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8489
+ // Handle code blocks
8490
+ if (codeBlocks.html)
8491
+ updateData.template = codeBlocks.html;
8492
+ if (codeBlocks.css)
8493
+ updateData.css = codeBlocks.css;
8494
+ if (codeBlocks.javascript)
8495
+ updateData.script = codeBlocks.javascript;
8496
+ // Handle semantic instructions for widgets
8497
+ if (instruction.includes('add') && instruction.includes('chart')) {
8498
+ // User wants to add a chart - enhance existing template
8499
+ if (existingArtifact?.template) {
8500
+ const currentTemplate = existingArtifact.template || '';
8501
+ if (!currentTemplate.includes('canvas') && !currentTemplate.includes('chart')) {
8502
+ updateData.template = currentTemplate + '\n<div class="chart-container">\n <canvas id="widget-chart"></canvas>\n</div>';
8503
+ }
8504
+ }
8505
+ // Add chart CSS if not present
8506
+ if (existingArtifact?.css && !existingArtifact.css.includes('chart-container')) {
8507
+ updateData.css = (existingArtifact.css || '') + '\n\n.chart-container {\n margin: 20px 0;\n height: 300px;\n}\n\ncanvas {\n width: 100% !important;\n height: 100% !important;\n}';
8508
+ }
8509
+ // Add chart script if not present
8510
+ if (existingArtifact?.script && !existingArtifact.script.includes('Chart')) {
8511
+ const chartScript = `
8512
+ // Chart functionality added
8513
+ c.initChart = function() {
8514
+ if (typeof Chart !== 'undefined' && document.getElementById('widget-chart')) {
8515
+ var ctx = document.getElementById('widget-chart').getContext('2d');
8516
+ c.chart = new Chart(ctx, {
8517
+ type: 'bar',
8518
+ data: c.data.chartData || { labels: [], datasets: [] },
8519
+ options: { responsive: true, maintainAspectRatio: false }
8520
+ });
8521
+ }
8522
+ };
8523
+
8524
+ // Add to existing onInit
8525
+ var originalInit = c.$onInit;
8526
+ c.$onInit = function() {
8527
+ if (originalInit) originalInit();
8528
+ c.initChart();
8529
+ };`;
8530
+ updateData.script = (existingArtifact.script || '') + chartScript;
8531
+ }
8532
+ }
8533
+ // Handle title/name changes
8534
+ if (instruction.includes('change') && instruction.includes('title')) {
8535
+ const titleMatch = instruction.match(/title[:\s]+["']([^"']+)["']/i) ||
8536
+ instruction.match(/to\s+["']([^"']+)["']/i);
8537
+ if (titleMatch)
8538
+ updateData.title = titleMatch[1];
8539
+ }
8540
+ // Handle style updates
8541
+ if (instruction.includes('style') || instruction.includes('css')) {
8542
+ if (!codeBlocks.css) {
8543
+ // Generate basic style updates based on instruction
8544
+ if (instruction.includes('color')) {
8545
+ const colorMatch = instruction.match(/color[:\s]+(\w+|#[a-fA-F0-9]{6}|#[a-fA-F0-9]{3})/i);
8546
+ if (colorMatch) {
8547
+ updateData.css = (existingArtifact?.css || '') + `\n\n.widget-content { color: ${colorMatch[1]}; }`;
8331
8548
  }
8332
8549
  }
8333
8550
  }
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];
8551
+ }
8552
+ // Apply explicit values
8553
+ Object.assign(updateData, explicitValues);
8554
+ }
8555
+ /**
8556
+ * Parse script-based artifact instructions (business_rule, script_include, client_script)
8557
+ */
8558
+ async parseScriptInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8559
+ if (codeBlocks.javascript) {
8560
+ updateData.script = codeBlocks.javascript;
8561
+ }
8562
+ // Handle condition updates
8563
+ if (instruction.includes('condition') && !codeBlocks.javascript) {
8564
+ const conditionMatch = instruction.match(/condition[:\s]+["']([^"']+)["']/i);
8565
+ if (conditionMatch)
8566
+ updateData.condition = conditionMatch[1];
8567
+ }
8568
+ // Handle when/trigger changes for business rules
8569
+ if (instruction.includes('when') || instruction.includes('trigger')) {
8570
+ const whenOptions = ['before', 'after', 'async', 'display'];
8571
+ for (const option of whenOptions) {
8572
+ if (instruction.includes(option)) {
8573
+ updateData.when = option;
8574
+ break;
8338
8575
  }
8339
8576
  }
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
- }
8577
+ }
8578
+ // Handle table changes
8579
+ if (instruction.includes('table')) {
8580
+ const tableMatch = instruction.match(/table[:\s]+["']?([a-z_]+)["']?/i);
8581
+ if (tableMatch)
8582
+ updateData.table = tableMatch[1];
8583
+ }
8584
+ Object.assign(updateData, explicitValues);
8585
+ }
8586
+ /**
8587
+ * Parse UI Action instructions
8588
+ */
8589
+ async parseUIActionInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8590
+ if (codeBlocks.javascript) {
8591
+ updateData.script = codeBlocks.javascript;
8592
+ }
8593
+ // Handle label/action name changes
8594
+ if (instruction.includes('label') || instruction.includes('button') || instruction.includes('action name')) {
8595
+ const labelMatch = instruction.match(/(?:label|button|action name)[:\s]+["']([^"']+)["']/i);
8596
+ if (labelMatch)
8597
+ updateData.action_name = labelMatch[1];
8598
+ }
8599
+ // Handle condition changes
8600
+ if (instruction.includes('condition')) {
8601
+ const conditionMatch = instruction.match(/condition[:\s]+["']([^"']+)["']/i);
8602
+ if (conditionMatch)
8603
+ updateData.condition = conditionMatch[1];
8604
+ }
8605
+ Object.assign(updateData, explicitValues);
8606
+ }
8607
+ /**
8608
+ * Parse UI Policy instructions
8609
+ */
8610
+ async parseUIPolicyInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8611
+ if (codeBlocks.javascript) {
8612
+ updateData.script_true = codeBlocks.javascript;
8613
+ }
8614
+ if (instruction.includes('condition')) {
8615
+ const conditionMatch = instruction.match(/condition[:\s]+["']([^"']+)["']/i);
8616
+ if (conditionMatch)
8617
+ updateData.conditions = conditionMatch[1];
8618
+ }
8619
+ Object.assign(updateData, explicitValues);
8620
+ }
8621
+ /**
8622
+ * Parse notification instructions
8623
+ */
8624
+ async parseNotificationInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8625
+ if (codeBlocks.html) {
8626
+ updateData.message_html = codeBlocks.html;
8627
+ }
8628
+ // Handle subject changes
8629
+ if (instruction.includes('subject')) {
8630
+ const subjectMatch = instruction.match(/subject[:\s]+["']([^"']+)["']/i);
8631
+ if (subjectMatch)
8632
+ updateData.subject = subjectMatch[1];
8633
+ }
8634
+ // Handle body/message changes
8635
+ if (instruction.includes('body') || instruction.includes('message')) {
8636
+ if (!codeBlocks.html) {
8637
+ const messageMatch = instruction.match(/(?:body|message)[:\s]+["']([^"']+)["']/i);
8638
+ if (messageMatch)
8639
+ updateData.message_html = messageMatch[1];
8640
+ }
8641
+ }
8642
+ // Handle recipient changes
8643
+ if (instruction.includes('recipient') || instruction.includes('to')) {
8644
+ const recipientMatch = instruction.match(/(?:recipient|to)[:\s]+["']([^"']+)["']/i);
8645
+ if (recipientMatch)
8646
+ updateData.recipient = recipientMatch[1];
8647
+ }
8648
+ Object.assign(updateData, explicitValues);
8649
+ }
8650
+ /**
8651
+ * Parse ACL instructions
8652
+ */
8653
+ async parseACLInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8654
+ if (codeBlocks.javascript) {
8655
+ updateData.script = codeBlocks.javascript;
8656
+ }
8657
+ // Handle operation changes
8658
+ const operations = ['read', 'write', 'create', 'delete', 'execute'];
8659
+ for (const op of operations) {
8660
+ if (instruction.includes(op)) {
8661
+ updateData.operation = op;
8662
+ break;
8345
8663
  }
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
- }
8664
+ }
8665
+ // Handle role changes
8666
+ if (instruction.includes('role')) {
8667
+ const roleMatch = instruction.match(/role[:\s]+["']([^"']+)["']/i);
8668
+ if (roleMatch)
8669
+ updateData.role = roleMatch[1];
8670
+ }
8671
+ Object.assign(updateData, explicitValues);
8672
+ }
8673
+ /**
8674
+ * Parse table instructions
8675
+ */
8676
+ async parseTableInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8677
+ if (instruction.includes('label')) {
8678
+ const labelMatch = instruction.match(/label[:\s]+["']([^"']+)["']/i);
8679
+ if (labelMatch)
8680
+ updateData.label = labelMatch[1];
8681
+ }
8682
+ if (instruction.includes('access')) {
8683
+ const accessMatch = instruction.match(/access[:\s]+["']([^"']+)["']/i);
8684
+ if (accessMatch)
8685
+ updateData.access = accessMatch[1];
8686
+ }
8687
+ Object.assign(updateData, explicitValues);
8688
+ }
8689
+ /**
8690
+ * Parse field instructions
8691
+ */
8692
+ async parseFieldInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8693
+ if (instruction.includes('label')) {
8694
+ const labelMatch = instruction.match(/label[:\s]+["']([^"']+)["']/i);
8695
+ if (labelMatch)
8696
+ updateData.column_label = labelMatch[1];
8697
+ }
8698
+ if (instruction.includes('type')) {
8699
+ const typeMatch = instruction.match(/type[:\s]+["']([^"']+)["']/i);
8700
+ if (typeMatch)
8701
+ updateData.internal_type = typeMatch[1];
8702
+ }
8703
+ // Handle mandatory/required changes
8704
+ if (instruction.includes('mandatory') || instruction.includes('required')) {
8705
+ if (instruction.includes('make mandatory') || instruction.includes('make required')) {
8706
+ updateData.mandatory = true;
8707
+ }
8708
+ else if (instruction.includes('remove mandatory') || instruction.includes('optional')) {
8709
+ updateData.mandatory = false;
8710
+ }
8711
+ }
8712
+ Object.assign(updateData, explicitValues);
8713
+ }
8714
+ /**
8715
+ * Parse workflow instructions
8716
+ */
8717
+ async parseWorkflowInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8718
+ if (instruction.includes('description')) {
8719
+ const descMatch = instruction.match(/description[:\s]+["']([^"']+)["']/i);
8720
+ if (descMatch)
8721
+ updateData.description = descMatch[1];
8722
+ }
8723
+ Object.assign(updateData, explicitValues);
8724
+ }
8725
+ /**
8726
+ * Parse flow instructions
8727
+ */
8728
+ async parseFlowInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8729
+ if (instruction.includes('description')) {
8730
+ const descMatch = instruction.match(/description[:\s]+["']([^"']+)["']/i);
8731
+ if (descMatch)
8732
+ updateData.description = descMatch[1];
8733
+ }
8734
+ if (instruction.includes('trigger')) {
8735
+ const triggerMatch = instruction.match(/trigger[:\s]+["']([^"']+)["']/i);
8736
+ if (triggerMatch)
8737
+ updateData.trigger = triggerMatch[1];
8738
+ }
8739
+ Object.assign(updateData, explicitValues);
8740
+ }
8741
+ /**
8742
+ * Parse scheduled job instructions
8743
+ */
8744
+ async parseScheduledJobInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8745
+ if (codeBlocks.javascript) {
8746
+ updateData.script = codeBlocks.javascript;
8747
+ }
8748
+ if (instruction.includes('schedule') || instruction.includes('cron')) {
8749
+ const scheduleMatch = instruction.match(/(?:schedule|cron)[:\s]+["']([^"']+)["']/i);
8750
+ if (scheduleMatch) {
8751
+ updateData.run_type = 'Periodically';
8752
+ updateData.run_period = scheduleMatch[1];
8351
8753
  }
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];
8754
+ // Handle time-based schedules
8755
+ if (instruction.includes('hour')) {
8756
+ const hourMatch = instruction.match(/(\d+)\s*hour/i);
8757
+ if (hourMatch) {
8758
+ updateData.run_type = 'Periodically';
8759
+ updateData.run_period = `0 0 */${hourMatch[1]} * * *`;
8357
8760
  }
8358
8761
  }
8762
+ if (instruction.includes('daily')) {
8763
+ updateData.run_type = 'Periodically';
8764
+ updateData.run_period = '0 0 0 * * *'; // Daily at midnight
8765
+ }
8766
+ if (instruction.includes('weekly')) {
8767
+ updateData.run_type = 'Periodically';
8768
+ updateData.run_period = '0 0 0 * * 0'; // Weekly on Sunday
8769
+ }
8359
8770
  }
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
8771
+ Object.assign(updateData, explicitValues);
8772
+ }
8773
+ /**
8774
+ * Generic parsing for unsupported types
8775
+ */
8776
+ async parseGenericInstruction(updateData, instruction, codeBlocks, explicitValues, existingArtifact) {
8777
+ // Apply only explicit values for unsupported types
8778
+ Object.assign(updateData, explicitValues);
8779
+ // Handle common script field
8780
+ if (codeBlocks.javascript && !updateData.script) {
8781
+ updateData.script = codeBlocks.javascript;
8782
+ }
8783
+ }
8784
+ /**
8785
+ * Apply common field updates across all artifact types
8786
+ */
8787
+ applyCommonUpdates(updateData, instruction, explicitValues) {
8788
+ // Handle active/inactive states
8789
+ if (instruction.includes('activate') || instruction.includes('enable')) {
8790
+ updateData.active = true;
8791
+ }
8792
+ else if (instruction.includes('deactivate') || instruction.includes('disable')) {
8793
+ updateData.active = false;
8794
+ }
8795
+ // Handle description updates (various field names)
8796
+ if (instruction.includes('description') && !updateData.description && !updateData.short_description) {
8797
+ const descMatch = instruction.match(/description[:\s]+["']([^"']+)["']/i);
8798
+ if (descMatch) {
8799
+ // Use appropriate description field based on common patterns
8800
+ updateData.short_description = descMatch[1];
8801
+ }
8802
+ }
8803
+ // Handle name updates
8804
+ if (instruction.includes('name') && instruction.includes('change')) {
8805
+ const nameMatch = instruction.match(/name[:\s]+["']([^"']+)["']/i);
8806
+ if (nameMatch)
8807
+ updateData.name = nameMatch[1];
8366
8808
  }
8367
- return updateData;
8368
8809
  }
8369
8810
  /**
8370
8811
  * Get table name for artifact type
@@ -8381,6 +8822,26 @@ Use \`snow_deploy\` to create a new ${args.type} instead.`
8381
8822
  return 'sys_script_include';
8382
8823
  case 'ui_page':
8383
8824
  return 'sys_ui_page';
8825
+ case 'client_script':
8826
+ return 'sys_script_client';
8827
+ case 'ui_action':
8828
+ return 'sys_ui_action';
8829
+ case 'ui_policy':
8830
+ return 'sys_ui_policy';
8831
+ case 'acl':
8832
+ return 'sys_security_acl';
8833
+ case 'table':
8834
+ return 'sys_db_object';
8835
+ case 'field':
8836
+ return 'sys_dictionary';
8837
+ case 'workflow':
8838
+ return 'wf_workflow';
8839
+ case 'flow':
8840
+ return 'sys_hub_flow';
8841
+ case 'notification':
8842
+ return 'sysevent_email_action';
8843
+ case 'scheduled_job':
8844
+ return 'sysauto_script';
8384
8845
  default:
8385
8846
  return 'sys_metadata';
8386
8847
  }