snow-flow 1.3.10 → 1.3.12

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/cli.js CHANGED
@@ -61,6 +61,118 @@ program
61
61
  .name('snow-flow')
62
62
  .description('ServiceNow Multi-Agent Development Framework')
63
63
  .version(version_js_1.VERSION);
64
+ // Helper function to deploy XML to ServiceNow
65
+ async function deployXMLToServiceNow(xmlFile, options = {}) {
66
+ const oauth = new snow_oauth_js_1.ServiceNowOAuth();
67
+ const isAuthenticated = await oauth.getStoredTokens() !== null;
68
+ if (!isAuthenticated) {
69
+ cliLogger.error('❌ Not authenticated. Please run: snow-flow auth login');
70
+ return false;
71
+ }
72
+ try {
73
+ // Initialize ServiceNow client
74
+ const client = new servicenow_client_js_1.ServiceNowClient();
75
+ // Read XML file
76
+ if (!(0, fs_2.existsSync)(xmlFile)) {
77
+ cliLogger.error(`❌ XML file not found: ${xmlFile}`);
78
+ return false;
79
+ }
80
+ cliLogger.info('📄 Reading XML file...');
81
+ const xmlContent = await fs_1.promises.readFile(xmlFile, 'utf-8');
82
+ // Import XML as remote update set
83
+ cliLogger.info('📤 Importing XML to ServiceNow...');
84
+ const importResponse = await client.makeRequest({
85
+ method: 'POST',
86
+ url: '/api/now/table/sys_remote_update_set',
87
+ headers: {
88
+ 'Content-Type': 'application/xml',
89
+ 'Accept': 'application/json'
90
+ },
91
+ data: xmlContent
92
+ });
93
+ if (!importResponse.result || !importResponse.result.sys_id) {
94
+ throw new Error('Failed to import XML update set');
95
+ }
96
+ const remoteUpdateSetId = importResponse.result.sys_id;
97
+ cliLogger.info(`✅ XML imported successfully (sys_id: ${remoteUpdateSetId})`);
98
+ // Load the update set
99
+ cliLogger.info('🔄 Loading update set...');
100
+ await client.makeRequest({
101
+ method: 'PUT',
102
+ url: `/api/now/table/sys_remote_update_set/${remoteUpdateSetId}`,
103
+ data: {
104
+ state: 'loaded'
105
+ }
106
+ });
107
+ // Find the loaded update set
108
+ const loadedResponse = await client.makeRequest({
109
+ method: 'GET',
110
+ url: '/api/now/table/sys_update_set',
111
+ params: {
112
+ sysparm_query: `remote_sys_id=${remoteUpdateSetId}`,
113
+ sysparm_limit: 1
114
+ }
115
+ });
116
+ if (!loadedResponse.result || loadedResponse.result.length === 0) {
117
+ throw new Error('Failed to find loaded update set');
118
+ }
119
+ const updateSetId = loadedResponse.result[0].sys_id;
120
+ const updateSetName = loadedResponse.result[0].name;
121
+ cliLogger.info(`✅ Update set loaded: ${updateSetName}`);
122
+ // Preview if requested
123
+ if (options.preview !== false) {
124
+ cliLogger.info('🔍 Previewing update set...');
125
+ await client.makeRequest({
126
+ method: 'POST',
127
+ url: `/api/now/table/sys_update_set/${updateSetId}/preview`
128
+ });
129
+ // Check preview results
130
+ const previewProblems = await client.makeRequest({
131
+ method: 'GET',
132
+ url: '/api/now/table/sys_update_preview_problem',
133
+ params: {
134
+ sysparm_query: `update_set=${updateSetId}`,
135
+ sysparm_limit: 100
136
+ }
137
+ });
138
+ if (previewProblems.result && previewProblems.result.length > 0) {
139
+ cliLogger.warn('\n⚠️ Preview found problems:');
140
+ previewProblems.result.forEach((p) => {
141
+ cliLogger.warn(` - ${p.type}: ${p.description}`);
142
+ });
143
+ if (options.commit !== false) {
144
+ cliLogger.warn('\n⚠️ Skipping auto-commit due to preview problems');
145
+ cliLogger.info('📋 Review and resolve problems in ServiceNow, then commit manually');
146
+ return false;
147
+ }
148
+ }
149
+ else {
150
+ cliLogger.info('✅ Preview successful - no problems found');
151
+ }
152
+ // Commit if clean and requested
153
+ if (options.commit !== false && (!previewProblems.result || previewProblems.result.length === 0)) {
154
+ cliLogger.info('🚀 Committing update set...');
155
+ await client.makeRequest({
156
+ method: 'POST',
157
+ url: `/api/now/table/sys_update_set/${updateSetId}/commit`
158
+ });
159
+ cliLogger.info('\n✅ Update Set committed successfully!');
160
+ cliLogger.info('📍 Navigate to Flow Designer > Designer to see your flow');
161
+ cliLogger.info('\n🎉 Deployment complete!');
162
+ return true;
163
+ }
164
+ }
165
+ return true;
166
+ }
167
+ catch (error) {
168
+ cliLogger.error('\n❌ Deployment failed:', error instanceof Error ? error.message : String(error));
169
+ cliLogger.info('\n💡 Troubleshooting tips:');
170
+ cliLogger.info(' 1. Check your authentication: snow-flow auth status');
171
+ cliLogger.info(' 2. Verify XML file format is correct');
172
+ cliLogger.info(' 3. Ensure you have required permissions in ServiceNow');
173
+ return false;
174
+ }
175
+ }
64
176
  // Swarm command - the main orchestration command with EVERYTHING
65
177
  program
66
178
  .command('swarm <objective>')
@@ -159,8 +271,8 @@ program
159
271
  cliLogger.info('📋 Creating production-ready ServiceNow flow XML...');
160
272
  cliLogger.info('💡 Reason: Flow Designer flows are most reliable with XML-first approach\n');
161
273
  try {
162
- // Import XML flow generator
163
- const { generateProductionFlowXML } = await Promise.resolve().then(() => __importStar(require('./utils/xml-first-flow-generator.js')));
274
+ // Import IMPROVED XML flow generator (fixes "too small to work" issue!)
275
+ const { generateImprovedFlowXML } = await Promise.resolve().then(() => __importStar(require('./utils/improved-flow-xml-generator.js')));
164
276
  // Parse instruction to determine activities
165
277
  const activities = [];
166
278
  const objectiveLower = objective.toLowerCase();
@@ -236,12 +348,25 @@ program
236
348
  outputs: { started: 'boolean' }
237
349
  }]
238
350
  };
239
- // Generate XML
240
- cliLogger.info('🏗️ Generating production XML...');
241
- const result = generateProductionFlowXML(flowDef);
351
+ // Generate IMPROVED XML with enhanced structure
352
+ cliLogger.info('🏗️ Generating IMPROVED production XML...');
353
+ // Convert to improved flow definition
354
+ const improvedFlowDef = {
355
+ ...flowDef,
356
+ run_as: 'user',
357
+ accessible_from: 'package_private',
358
+ category: 'custom',
359
+ tags: ['auto-generated'],
360
+ activities: flowDef.activities.map((act) => ({
361
+ ...act,
362
+ description: act.description || act.name
363
+ }))
364
+ };
365
+ const result = generateImprovedFlowXML(improvedFlowDef);
242
366
  xmlFlowResult = { ...result, flowDefinition: flowDef };
243
- cliLogger.info(`\n✅ XML Generated Successfully!`);
367
+ cliLogger.info(`\n✅ IMPROVED XML Generated Successfully!`);
244
368
  cliLogger.info(`📁 File saved to: ${result.filePath}`);
369
+ cliLogger.info(`🔥 IMPROVEMENTS: Uses v2 tables, Base64+gzip encoding, complete label_cache!`);
245
370
  cliLogger.info(`📊 Flow structure:`);
246
371
  cliLogger.info(` - Name: ${flowDef.name}`);
247
372
  cliLogger.info(` - Table: ${flowDef.table}`);
@@ -262,9 +387,27 @@ program
262
387
  // Check if auto-deploy is enabled
263
388
  if (options.autoDeploy !== false) { // Default is true from swarm command
264
389
  cliLogger.info('\n🚀 Auto-Deploy enabled - importing XML to ServiceNow...');
265
- cliLogger.info('\n💡 To deploy, use the following command:');
266
- cliLogger.info(` snow-flow deploy-xml "${result.filePath}"`);
267
- cliLogger.info('\nThis will automatically import, preview, and commit the flow to ServiceNow.');
390
+ // Automatically deploy the XML file
391
+ const deploySuccess = await deployXMLToServiceNow(result.filePath, {
392
+ preview: true,
393
+ commit: true
394
+ });
395
+ if (deploySuccess) {
396
+ cliLogger.info('\n✅ Flow automatically deployed to ServiceNow!');
397
+ cliLogger.info('🎯 The flow is now available in Flow Designer');
398
+ // Store deployment success in memory
399
+ memorySystem.storeLearning(`deployment_${sessionId}`, {
400
+ success: true,
401
+ xml_file: result.filePath,
402
+ deployed_at: new Date().toISOString(),
403
+ flow_name: flowDef.name
404
+ });
405
+ }
406
+ else {
407
+ cliLogger.warn('\n⚠️ Automatic deployment encountered issues');
408
+ cliLogger.info('💡 You can manually deploy later with:');
409
+ cliLogger.info(` snow-flow deploy-xml "${result.filePath}"`);
410
+ }
268
411
  }
269
412
  else {
270
413
  cliLogger.info('📋 Use the import instructions above to deploy to ServiceNow');
@@ -1712,111 +1855,13 @@ program
1712
1855
  .action(async (xmlFile, options) => {
1713
1856
  console.log(`\n📦 Deploying XML Update Set: ${xmlFile}`);
1714
1857
  console.log('='.repeat(60));
1715
- const oauth = new snow_oauth_js_1.ServiceNowOAuth();
1716
- const isAuthenticated = await oauth.getStoredTokens() !== null;
1717
- if (!isAuthenticated) {
1718
- console.log('❌ Not authenticated. Please run: snow-flow auth login');
1719
- return;
1720
- }
1721
- try {
1722
- // Initialize ServiceNow client
1723
- const client = new servicenow_client_js_1.ServiceNowClient();
1724
- // Read XML file
1725
- if (!(0, fs_2.existsSync)(xmlFile)) {
1726
- console.error(`❌ XML file not found: ${xmlFile}`);
1727
- return;
1728
- }
1729
- console.log('📄 Reading XML file...');
1730
- const xmlContent = await fs_1.promises.readFile(xmlFile, 'utf-8');
1731
- // Import XML as remote update set
1732
- console.log('📤 Importing XML to ServiceNow...');
1733
- const importResponse = await client.makeRequest({
1734
- method: 'POST',
1735
- url: '/api/now/table/sys_remote_update_set',
1736
- headers: {
1737
- 'Content-Type': 'application/xml',
1738
- 'Accept': 'application/json'
1739
- },
1740
- data: xmlContent
1741
- });
1742
- if (!importResponse.result || !importResponse.result.sys_id) {
1743
- throw new Error('Failed to import XML update set');
1744
- }
1745
- const remoteUpdateSetId = importResponse.result.sys_id;
1746
- console.log(`✅ XML imported successfully (sys_id: ${remoteUpdateSetId})`);
1747
- // Load the update set
1748
- console.log('🔄 Loading update set...');
1749
- await client.makeRequest({
1750
- method: 'PUT',
1751
- url: `/api/now/table/sys_remote_update_set/${remoteUpdateSetId}`,
1752
- data: {
1753
- state: 'loaded'
1754
- }
1755
- });
1756
- // Find the loaded update set
1757
- const loadedResponse = await client.makeRequest({
1758
- method: 'GET',
1759
- url: '/api/now/table/sys_update_set',
1760
- params: {
1761
- sysparm_query: `remote_sys_id=${remoteUpdateSetId}`,
1762
- sysparm_limit: 1
1763
- }
1764
- });
1765
- if (!loadedResponse.result || loadedResponse.result.length === 0) {
1766
- throw new Error('Failed to find loaded update set');
1767
- }
1768
- const updateSetId = loadedResponse.result[0].sys_id;
1769
- const updateSetName = loadedResponse.result[0].name;
1770
- console.log(`✅ Update set loaded: ${updateSetName}`);
1771
- // Preview if requested
1772
- if (options.preview !== false) {
1773
- console.log('🔍 Previewing update set...');
1774
- await client.makeRequest({
1775
- method: 'POST',
1776
- url: `/api/now/table/sys_update_set/${updateSetId}/preview`
1777
- });
1778
- // Check preview results
1779
- const previewProblems = await client.makeRequest({
1780
- method: 'GET',
1781
- url: '/api/now/table/sys_update_preview_problem',
1782
- params: {
1783
- sysparm_query: `update_set=${updateSetId}`,
1784
- sysparm_limit: 100
1785
- }
1786
- });
1787
- if (previewProblems.result && previewProblems.result.length > 0) {
1788
- console.log('\n⚠️ Preview found problems:');
1789
- previewProblems.result.forEach((p) => {
1790
- console.log(` - ${p.type}: ${p.description}`);
1791
- });
1792
- if (options.commit !== false) {
1793
- console.log('\n⚠️ Skipping auto-commit due to preview problems');
1794
- console.log('📋 Review and resolve problems in ServiceNow, then commit manually');
1795
- return;
1796
- }
1797
- }
1798
- else {
1799
- console.log('✅ Preview successful - no problems found');
1800
- }
1801
- // Commit if clean and requested
1802
- if (options.commit !== false && (!previewProblems.result || previewProblems.result.length === 0)) {
1803
- console.log('🚀 Committing update set...');
1804
- await client.makeRequest({
1805
- method: 'POST',
1806
- url: `/api/now/table/sys_update_set/${updateSetId}/commit`
1807
- });
1808
- console.log('\n✅ Update Set committed successfully!');
1809
- console.log('📍 Navigate to Flow Designer > Designer to see your flow');
1810
- console.log('\n🎉 Deployment complete!');
1811
- }
1812
- }
1813
- }
1814
- catch (error) {
1815
- console.error('\n❌ Deployment failed:', error instanceof Error ? error.message : String(error));
1816
- console.log('\n💡 Troubleshooting tips:');
1817
- console.log(' 1. Check your authentication: snow-flow auth status');
1818
- console.log(' 2. Verify XML file format is correct');
1819
- console.log(' 3. Ensure you have required permissions in ServiceNow');
1858
+ // Use the shared deploy function
1859
+ const success = await deployXMLToServiceNow(xmlFile, {
1860
+ preview: options.preview,
1861
+ commit: options.commit
1862
+ });
1863
+ if (!success) {
1864
+ process.exit(1);
1820
1865
  }
1821
1866
  });
1822
1867
  // Help command
@@ -4324,8 +4369,8 @@ program
4324
4369
  console.log(`\n🔧 XML-First Flow Generator v${version_js_1.VERSION}`);
4325
4370
  console.log('📋 Creating production-ready ServiceNow flow XML...\n');
4326
4371
  try {
4327
- // Import XML flow generator
4328
- const { generateProductionFlowXML } = await Promise.resolve().then(() => __importStar(require('./utils/xml-first-flow-generator.js')));
4372
+ // Import IMPROVED XML flow generator (fixes "too small to work" issue!)
4373
+ const { generateImprovedFlowXML } = await Promise.resolve().then(() => __importStar(require('./utils/improved-flow-xml-generator.js')));
4329
4374
  // Parse instruction to determine activities
4330
4375
  const activities = [];
4331
4376
  // Check for common patterns in instruction
@@ -4403,11 +4448,24 @@ return { started: true };`
4403
4448
  }
4404
4449
  ];
4405
4450
  }
4406
- // Generate XML
4407
- console.log('\n🏗️ Generating production XML...');
4408
- const result = generateProductionFlowXML(flowDef);
4409
- console.log(`\n✅ XML Generated Successfully!`);
4451
+ // Generate IMPROVED XML with enhanced structure
4452
+ console.log('\n🏗️ Generating IMPROVED production XML...');
4453
+ // Convert to improved flow definition
4454
+ const improvedFlowDef = {
4455
+ ...flowDef,
4456
+ run_as: 'user',
4457
+ accessible_from: 'package_private',
4458
+ category: 'custom',
4459
+ tags: ['cli-generated'],
4460
+ activities: flowDef.activities.map((act) => ({
4461
+ ...act,
4462
+ description: act.description || act.name
4463
+ }))
4464
+ };
4465
+ const result = generateImprovedFlowXML(improvedFlowDef);
4466
+ console.log(`\n✅ IMPROVED XML Generated Successfully!`);
4410
4467
  console.log(`📁 File saved to: ${result.filePath}`);
4468
+ console.log(`🔥 IMPROVEMENTS: Uses v2 tables, Base64+gzip encoding, complete label_cache!`);
4411
4469
  console.log(`📊 Flow structure:`);
4412
4470
  console.log(` - Name: ${flowDef.name}`);
4413
4471
  console.log(` - Table: ${flowDef.table}`);