snow-flow 1.3.0 โ 1.3.2
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-flow/queen/queen-memory.db +0 -0
- package/.env.example +249 -14
- package/CLAUDE.md +185 -24
- package/README.md +55 -5
- package/dist/api/error-handling.js +898 -4
- package/dist/api/performance-optimizer.js +3 -2
- package/dist/cli.js +590 -200
- package/dist/config/snow-flow-config.js +320 -8
- package/dist/health/system-health.js +288 -21
- package/dist/mcp/base-mcp-server.js +2 -0
- package/dist/mcp/http-transport-wrapper.js +65 -4
- package/dist/mcp/servicenow-automation-mcp-refactored.js +90 -9
- package/dist/mcp/servicenow-deployment-mcp-refactored.js +151 -2
- package/dist/mcp/servicenow-deployment-mcp.js +828 -15
- package/dist/mcp/servicenow-integration-mcp-refactored.js +100 -9
- package/dist/mcp/servicenow-intelligent-mcp.js +198 -7
- package/dist/mcp/servicenow-memory-mcp.js +2 -1
- package/dist/mcp/servicenow-operations-mcp-refactored.js +3 -2
- package/dist/mcp/servicenow-xml-flow-mcp.js +671 -0
- package/dist/mcp/shared/base-mcp-server.js +1356 -8
- package/dist/mcp/shared/mcp-resource-manager.js +304 -0
- package/dist/queen/parallel-agent-engine.js +26 -8
- package/dist/queen/servicenow-queen.js +47 -44
- package/dist/sparc/sparc-help.js +37 -26
- package/dist/sparc/team-sparc.js +60 -16
- package/dist/utils/action-type-cache.js +2 -1
- package/dist/utils/mcp-config-manager.js +7 -3
- package/dist/utils/mcp-server-manager.js +7 -3
- package/dist/utils/servicenow-client.js +134 -107
- package/dist/utils/servicenow-id-generator.js +171 -0
- package/dist/utils/snow-oauth.js +13 -8
- package/dist/utils/widget-template-generator.js +1690 -0
- package/dist/utils/xml-first-flow-generator.js +473 -0
- package/dist/version.js +7 -1
- package/flow-update-sets/flow_build_automated_approval_flow_with_notifications_flow.xml +203 -0
- package/flow-update-sets/flow_create_approval_flow_for_equipment_requests_flow.xml +206 -0
- package/flow-update-sets/flow_create_equipment_approval_flow_with_manager_approv_flow.xml +254 -0
- package/flow-update-sets/iphone_15_pro_approval_flow.xml +203 -0
- package/flow-update-sets/test_iphone_approval_flow_flow.xml +303 -0
- package/package.json +2 -1
- package/test-config.js +55 -0
- package/test-real-monitoring.js +184 -0
package/dist/cli.js
CHANGED
|
@@ -49,9 +49,13 @@ const fs_2 = require("fs");
|
|
|
49
49
|
const snow_oauth_js_1 = require("./utils/snow-oauth.js");
|
|
50
50
|
const servicenow_client_js_1 = require("./utils/servicenow-client.js");
|
|
51
51
|
const agent_detector_js_1 = require("./utils/agent-detector.js");
|
|
52
|
+
const servicenow_id_generator_js_1 = require("./utils/servicenow-id-generator.js");
|
|
52
53
|
const version_js_1 = require("./version.js");
|
|
54
|
+
const logger_js_1 = require("./utils/logger.js");
|
|
53
55
|
// Load environment variables
|
|
54
56
|
dotenv_1.default.config();
|
|
57
|
+
// Create CLI logger instance
|
|
58
|
+
const cliLogger = new logger_js_1.Logger('cli');
|
|
55
59
|
const program = new commander_1.Command();
|
|
56
60
|
program
|
|
57
61
|
.name('snow-flow')
|
|
@@ -79,60 +83,62 @@ program
|
|
|
79
83
|
.option('--no-shared-memory', 'Disable shared memory')
|
|
80
84
|
.option('--progress-monitoring', 'Real-time progress monitoring (default: true)', true)
|
|
81
85
|
.option('--no-progress-monitoring', 'Disable progress monitoring')
|
|
86
|
+
.option('--xml-first', 'Use XML-first approach for flow creation (MOST RELIABLE!)')
|
|
87
|
+
.option('--xml-output <path>', 'Save generated XML to specific path (with --xml-first)')
|
|
82
88
|
.action(async (objective, options) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
cliLogger.info(`\n๐ Starting ServiceNow Multi-Agent Swarm v${version_js_1.VERSION} - รฉรฉn command voor alles!`);
|
|
90
|
+
cliLogger.info(`๐ Objective: ${objective}`);
|
|
91
|
+
cliLogger.info(`โ๏ธ Strategy: ${options.strategy} | Mode: ${options.mode} | Max Agents: ${options.maxAgents}`);
|
|
92
|
+
cliLogger.info(`๐ Parallel: ${options.parallel ? 'Yes' : 'No'} | Monitor: ${options.monitor ? 'Yes' : 'No'}`);
|
|
87
93
|
// Show new intelligent features
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
cliLogger.info(`\n๐ง Intelligent Features:`);
|
|
95
|
+
cliLogger.info(` ๐ Auto Permissions: ${options.autoPermissions ? 'โ
Yes' : 'โ No'}`);
|
|
96
|
+
cliLogger.info(` ๐ Smart Discovery: ${options.smartDiscovery ? 'โ
Yes' : 'โ No'}`);
|
|
97
|
+
cliLogger.info(` ๐งช Live Testing: ${options.liveTesting ? 'โ
Yes' : 'โ No'}`);
|
|
98
|
+
cliLogger.info(` ๐ Auto Deploy: ${options.autoDeploy ? 'โ
DEPLOYMENT MODE - WILL CREATE REAL ARTIFACTS' : 'โ PLANNING MODE - ANALYSIS ONLY'}`);
|
|
99
|
+
cliLogger.info(` ๐ Auto Rollback: ${options.autoRollback ? 'โ
Yes' : 'โ No'}`);
|
|
100
|
+
cliLogger.info(` ๐พ Shared Memory: ${options.sharedMemory ? 'โ
Yes' : 'โ No'}`);
|
|
101
|
+
cliLogger.info(` ๐ Progress Monitoring: ${options.progressMonitoring ? 'โ
Yes' : 'โ No'}\n`);
|
|
96
102
|
// Analyze the objective using intelligent agent detection
|
|
97
103
|
const taskAnalysis = analyzeObjective(objective, parseInt(options.maxAgents));
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
cliLogger.info(`๐ฏ Task Type: ${taskAnalysis.taskType}`);
|
|
105
|
+
cliLogger.info(`๐ง Primary Agent: ${taskAnalysis.primaryAgent}`);
|
|
106
|
+
cliLogger.info(`๐ฅ Supporting Agents: ${taskAnalysis.supportingAgents.join(', ')}`);
|
|
107
|
+
cliLogger.info(`๐ Complexity: ${taskAnalysis.complexity} | Estimated Agents: ${taskAnalysis.estimatedAgentCount}`);
|
|
108
|
+
cliLogger.info(`๐ง ServiceNow Artifacts: ${taskAnalysis.serviceNowArtifacts.join(', ')}`);
|
|
109
|
+
cliLogger.info(`๐ฆ Auto Update Set: ${taskAnalysis.requiresUpdateSet ? 'โ
Yes' : 'โ No'}`);
|
|
110
|
+
cliLogger.info(`๐๏ธ Auto Application: ${taskAnalysis.requiresApplication ? 'โ
Yes' : 'โ No'}`);
|
|
105
111
|
// Show timeout configuration
|
|
106
112
|
const timeoutMinutes = process.env.SNOW_FLOW_TIMEOUT_MINUTES ? parseInt(process.env.SNOW_FLOW_TIMEOUT_MINUTES) : 60;
|
|
107
113
|
if (timeoutMinutes > 0) {
|
|
108
|
-
|
|
114
|
+
cliLogger.info(`โฑ๏ธ Timeout: ${timeoutMinutes} minutes`);
|
|
109
115
|
}
|
|
110
116
|
else {
|
|
111
|
-
|
|
117
|
+
cliLogger.info('โฑ๏ธ Timeout: Disabled (infinite execution time)');
|
|
112
118
|
}
|
|
113
119
|
// Check ServiceNow authentication
|
|
114
120
|
const oauth = new snow_oauth_js_1.ServiceNowOAuth();
|
|
115
121
|
const isAuthenticated = await oauth.isAuthenticated();
|
|
116
122
|
if (isAuthenticated) {
|
|
117
|
-
|
|
123
|
+
cliLogger.info('๐ ServiceNow connection: โ
Authenticated');
|
|
118
124
|
// Test ServiceNow connection
|
|
119
125
|
const client = new servicenow_client_js_1.ServiceNowClient();
|
|
120
126
|
const testResult = await client.testConnection();
|
|
121
127
|
if (testResult.success) {
|
|
122
|
-
|
|
128
|
+
cliLogger.info(`๐ค Connected as: ${testResult.data.name} (${testResult.data.user_name})`);
|
|
123
129
|
}
|
|
124
130
|
}
|
|
125
131
|
else {
|
|
126
|
-
|
|
127
|
-
|
|
132
|
+
cliLogger.warn('๐ ServiceNow connection: โ Not authenticated');
|
|
133
|
+
cliLogger.info('๐ก Run "snow-flow auth login" to enable live ServiceNow integration');
|
|
128
134
|
}
|
|
129
135
|
// Initialize Queen Agent memory system
|
|
130
|
-
|
|
136
|
+
cliLogger.info('\n๐พ Initializing swarm memory system...');
|
|
131
137
|
const { QueenMemorySystem } = await Promise.resolve().then(() => __importStar(require('./queen/queen-memory.js')));
|
|
132
138
|
const memorySystem = new QueenMemorySystem();
|
|
133
139
|
// Generate swarm session ID
|
|
134
140
|
const sessionId = `swarm_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
135
|
-
|
|
141
|
+
cliLogger.info(`๐ Swarm Session ID: ${sessionId}`);
|
|
136
142
|
// Store swarm session in memory
|
|
137
143
|
memorySystem.storeLearning(`session_${sessionId}`, {
|
|
138
144
|
objective,
|
|
@@ -141,65 +147,193 @@ program
|
|
|
141
147
|
started_at: new Date().toISOString(),
|
|
142
148
|
is_authenticated: isAuthenticated
|
|
143
149
|
});
|
|
150
|
+
// Check if this is a Flow Designer flow request - ALWAYS use XML-first for flows!
|
|
151
|
+
const isFlowDesignerTask = taskAnalysis.taskType === 'flow_development' ||
|
|
152
|
+
taskAnalysis.primaryAgent === 'flow-builder' ||
|
|
153
|
+
(objective.toLowerCase().includes('flow') &&
|
|
154
|
+
!objective.toLowerCase().includes('workflow') &&
|
|
155
|
+
!objective.toLowerCase().includes('data flow'));
|
|
156
|
+
if (isFlowDesignerTask) {
|
|
157
|
+
cliLogger.info('\n๐ง Flow Designer Detected - Using XML-First Approach!');
|
|
158
|
+
cliLogger.info('๐ Creating production-ready ServiceNow flow XML...');
|
|
159
|
+
cliLogger.info('๐ก Reason: Flow Designer flows are most reliable with XML-first approach\n');
|
|
160
|
+
try {
|
|
161
|
+
// Import XML flow generator
|
|
162
|
+
const { generateProductionFlowXML } = await Promise.resolve().then(() => __importStar(require('./utils/xml-first-flow-generator.js')));
|
|
163
|
+
// Parse instruction to determine activities
|
|
164
|
+
const activities = [];
|
|
165
|
+
const objectiveLower = objective.toLowerCase();
|
|
166
|
+
// Auto-detect activities from objective
|
|
167
|
+
if (objectiveLower.includes('approval') || objectiveLower.includes('approve')) {
|
|
168
|
+
activities.push({
|
|
169
|
+
name: 'Request Approval',
|
|
170
|
+
type: 'approval',
|
|
171
|
+
order: 100,
|
|
172
|
+
inputs: {
|
|
173
|
+
table: taskAnalysis.serviceNowArtifacts.includes('sc_request') ? 'sc_request' : 'incident',
|
|
174
|
+
record: '{{trigger.current.sys_id}}',
|
|
175
|
+
approver: '{{trigger.current.requested_for.manager}}',
|
|
176
|
+
approval_field: 'approval',
|
|
177
|
+
message: `Please approve: {{trigger.current.number}}`
|
|
178
|
+
},
|
|
179
|
+
outputs: {
|
|
180
|
+
state: 'string',
|
|
181
|
+
approver_sys_id: 'string',
|
|
182
|
+
comments: 'string'
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
if (objectiveLower.includes('notification') || objectiveLower.includes('email') || objectiveLower.includes('notify')) {
|
|
187
|
+
activities.push({
|
|
188
|
+
name: 'Send Notification',
|
|
189
|
+
type: 'notification',
|
|
190
|
+
order: activities.length > 0 ? 200 : 100,
|
|
191
|
+
inputs: {
|
|
192
|
+
notification_id: (0, servicenow_id_generator_js_1.getNotificationTemplateSysId)('generic_notification'),
|
|
193
|
+
recipients: '{{trigger.current.requested_for}}',
|
|
194
|
+
values: {
|
|
195
|
+
request_number: '{{trigger.current.number}}',
|
|
196
|
+
status: 'Notification sent'
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
if (objectiveLower.includes('create') || objectiveLower.includes('task')) {
|
|
202
|
+
activities.push({
|
|
203
|
+
name: 'Create Task',
|
|
204
|
+
type: 'create_record',
|
|
205
|
+
order: activities.length > 0 ? (activities.length + 1) * 100 : 100,
|
|
206
|
+
inputs: {
|
|
207
|
+
table: 'task',
|
|
208
|
+
field_values: {
|
|
209
|
+
short_description: '{{trigger.current.short_description}} - Follow-up',
|
|
210
|
+
assigned_to: '{{trigger.current.assigned_to}}',
|
|
211
|
+
priority: '{{trigger.current.priority}}'
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
outputs: {
|
|
215
|
+
record_id: 'string',
|
|
216
|
+
number: 'string'
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
// Build flow definition
|
|
221
|
+
const flowName = objective.substring(0, 50).replace(/[^a-zA-Z0-9]/g, '_');
|
|
222
|
+
const flowDef = {
|
|
223
|
+
name: `Flow_${flowName}`,
|
|
224
|
+
description: objective,
|
|
225
|
+
table: taskAnalysis.serviceNowArtifacts.find(a => ['incident', 'sc_request', 'change_request', 'problem'].includes(a)) || 'incident',
|
|
226
|
+
trigger_type: 'record_created',
|
|
227
|
+
trigger_condition: '',
|
|
228
|
+
activities: activities.length > 0 ? activities : [{
|
|
229
|
+
name: 'Log Flow Start',
|
|
230
|
+
type: 'script',
|
|
231
|
+
order: 100,
|
|
232
|
+
inputs: {
|
|
233
|
+
script: `gs.info('Flow started for: ' + current.number, 'XMLFlow');\\nreturn { started: true };`
|
|
234
|
+
},
|
|
235
|
+
outputs: { started: 'boolean' }
|
|
236
|
+
}]
|
|
237
|
+
};
|
|
238
|
+
// Generate XML
|
|
239
|
+
cliLogger.info('๐๏ธ Generating production XML...');
|
|
240
|
+
const result = generateProductionFlowXML(flowDef);
|
|
241
|
+
cliLogger.info(`\nโ
XML Generated Successfully!`);
|
|
242
|
+
cliLogger.info(`๐ File saved to: ${result.filePath}`);
|
|
243
|
+
cliLogger.info(`๐ Flow structure:`);
|
|
244
|
+
cliLogger.info(` - Name: ${flowDef.name}`);
|
|
245
|
+
cliLogger.info(` - Table: ${flowDef.table}`);
|
|
246
|
+
cliLogger.info(` - Trigger: ${flowDef.trigger_type}`);
|
|
247
|
+
cliLogger.info(` - Activities: ${flowDef.activities.length}`);
|
|
248
|
+
// Show import instructions
|
|
249
|
+
cliLogger.info('\n' + '='.repeat(60));
|
|
250
|
+
cliLogger.info(result.instructions);
|
|
251
|
+
cliLogger.info('='.repeat(60));
|
|
252
|
+
// Store result in memory
|
|
253
|
+
memorySystem.storeLearning(`xml_flow_${sessionId}`, {
|
|
254
|
+
objective,
|
|
255
|
+
flow_definition: flowDef,
|
|
256
|
+
xml_file: result.filePath,
|
|
257
|
+
generated_at: new Date().toISOString()
|
|
258
|
+
});
|
|
259
|
+
cliLogger.info('\n๐ฏ XML Flow generated successfully!');
|
|
260
|
+
// Check if auto-deploy is enabled
|
|
261
|
+
if (options.autoDeploy !== false) { // Default is true from swarm command
|
|
262
|
+
cliLogger.info('\n๐ Auto-Deploy enabled - importing XML to ServiceNow...');
|
|
263
|
+
cliLogger.info('\n๐ก To deploy, use the following command:');
|
|
264
|
+
cliLogger.info(` snow-flow deploy-xml "${result.filePath}"`);
|
|
265
|
+
cliLogger.info('\nThis will automatically import, preview, and commit the flow to ServiceNow.');
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
cliLogger.info('๐ Use the import instructions above to deploy to ServiceNow');
|
|
269
|
+
}
|
|
270
|
+
cliLogger.info('\n๐ก Tip: For additional ServiceNow features beyond flows, run swarm again for widgets/scripts/etc.');
|
|
271
|
+
return; // Exit early for Flow Designer flows
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
cliLogger.error('โ XML flow generation failed:', error instanceof Error ? error.message : String(error));
|
|
275
|
+
cliLogger.info('๐ก Falling back to regular swarm orchestration...\n');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
144
278
|
// Start real Claude Code orchestration
|
|
145
279
|
try {
|
|
146
280
|
// Generate the Queen Agent orchestration prompt
|
|
147
281
|
const orchestrationPrompt = buildQueenAgentPrompt(objective, taskAnalysis, options, isAuthenticated, sessionId);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
282
|
+
cliLogger.info('\n๐ Initializing Queen Agent orchestration...');
|
|
283
|
+
cliLogger.info('๐ฏ Queen Agent will coordinate the following:');
|
|
284
|
+
cliLogger.info(` - Analyze objective: "${objective}"`);
|
|
285
|
+
cliLogger.info(` - Spawn ${taskAnalysis.estimatedAgentCount} specialized agents`);
|
|
286
|
+
cliLogger.info(` - Coordinate through shared memory (session: ${sessionId})`);
|
|
287
|
+
cliLogger.info(` - Monitor progress and adapt strategy`);
|
|
154
288
|
// Check if intelligent features are enabled
|
|
155
289
|
const hasIntelligentFeatures = options.autoPermissions || options.smartDiscovery ||
|
|
156
290
|
options.liveTesting || options.autoDeploy || options.autoRollback ||
|
|
157
291
|
options.sharedMemory || options.progressMonitoring;
|
|
158
292
|
if (hasIntelligentFeatures && isAuthenticated) {
|
|
159
|
-
|
|
160
|
-
|
|
293
|
+
cliLogger.info('\n๐ง INTELLIGENT ORCHESTRATION MODE ENABLED!');
|
|
294
|
+
cliLogger.info('โจ Queen Agent will use advanced features:');
|
|
161
295
|
if (options.autoPermissions) {
|
|
162
|
-
|
|
296
|
+
cliLogger.info(' ๐ Automatic permission escalation');
|
|
163
297
|
}
|
|
164
298
|
if (options.smartDiscovery) {
|
|
165
|
-
|
|
299
|
+
cliLogger.info(' ๐ Smart artifact discovery and reuse');
|
|
166
300
|
}
|
|
167
301
|
if (options.liveTesting) {
|
|
168
|
-
|
|
302
|
+
cliLogger.info(' ๐งช Real-time testing in ServiceNow');
|
|
169
303
|
}
|
|
170
304
|
if (options.autoDeploy) {
|
|
171
|
-
|
|
305
|
+
cliLogger.info(' ๐ Automatic deployment when ready');
|
|
172
306
|
}
|
|
173
307
|
if (options.autoRollback) {
|
|
174
|
-
|
|
308
|
+
cliLogger.info(' ๐ Automatic rollback on failures');
|
|
175
309
|
}
|
|
176
310
|
if (options.sharedMemory) {
|
|
177
|
-
|
|
311
|
+
cliLogger.info(' ๐พ Shared context across all agents');
|
|
178
312
|
}
|
|
179
313
|
if (options.progressMonitoring) {
|
|
180
|
-
|
|
314
|
+
cliLogger.info(' ๐ Real-time progress monitoring');
|
|
181
315
|
}
|
|
182
316
|
}
|
|
183
317
|
if (isAuthenticated) {
|
|
184
|
-
|
|
185
|
-
|
|
318
|
+
cliLogger.info('\n๐ Live ServiceNow integration: โ
Enabled');
|
|
319
|
+
cliLogger.info('๐ Artifacts will be created directly in ServiceNow');
|
|
186
320
|
}
|
|
187
321
|
else {
|
|
188
|
-
|
|
189
|
-
|
|
322
|
+
cliLogger.info('\n๐ Live ServiceNow integration: โ Disabled');
|
|
323
|
+
cliLogger.info('๐ Artifacts will be saved to servicenow/ directory');
|
|
190
324
|
}
|
|
191
|
-
|
|
325
|
+
cliLogger.info('\n๐ Launching Claude Code with Queen Agent...');
|
|
192
326
|
// Try to execute Claude Code directly with the prompt
|
|
193
327
|
const success = await executeClaudeCode(orchestrationPrompt);
|
|
194
328
|
if (success) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
329
|
+
cliLogger.info('\nโ
Queen Agent orchestration launched successfully!');
|
|
330
|
+
cliLogger.info('๐ Queen Agent is now coordinating your swarm');
|
|
331
|
+
cliLogger.info(`๐พ Monitor progress with session ID: ${sessionId}`);
|
|
198
332
|
if (isAuthenticated && options.autoDeploy) {
|
|
199
|
-
|
|
333
|
+
cliLogger.info('๐ Real artifacts will be created in ServiceNow');
|
|
200
334
|
}
|
|
201
335
|
else {
|
|
202
|
-
|
|
336
|
+
cliLogger.info('๐ Planning mode - analysis and recommendations only');
|
|
203
337
|
}
|
|
204
338
|
// Store successful launch in memory
|
|
205
339
|
memorySystem.storeLearning(`launch_${sessionId}`, {
|
|
@@ -208,28 +342,28 @@ program
|
|
|
208
342
|
});
|
|
209
343
|
}
|
|
210
344
|
else {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
345
|
+
cliLogger.info('\n๐ Claude Code manual execution required');
|
|
346
|
+
cliLogger.info('\n๐ QUEEN AGENT ORCHESTRATION PROMPT:');
|
|
347
|
+
cliLogger.info('='.repeat(80));
|
|
348
|
+
cliLogger.info(orchestrationPrompt);
|
|
349
|
+
cliLogger.info('='.repeat(80));
|
|
350
|
+
cliLogger.info('\nโ
Queen Agent orchestration prompt generated!');
|
|
351
|
+
cliLogger.info('๐ Next Steps:');
|
|
352
|
+
cliLogger.info(' 1. Copy the above prompt and paste it into Claude Code');
|
|
353
|
+
cliLogger.info(' 2. Queen Agent will analyze and spawn specialized agents');
|
|
354
|
+
cliLogger.info(' 3. Agents will coordinate through shared memory');
|
|
355
|
+
cliLogger.info(' 4. Monitor progress through TodoRead and Memory tools');
|
|
222
356
|
if (isAuthenticated && options.autoDeploy) {
|
|
223
|
-
|
|
357
|
+
cliLogger.info(' 5. Real artifacts will be created in ServiceNow');
|
|
224
358
|
}
|
|
225
359
|
else {
|
|
226
|
-
|
|
360
|
+
cliLogger.info(' 5. Planning mode - no real artifacts created');
|
|
227
361
|
}
|
|
228
|
-
|
|
362
|
+
cliLogger.info(`\n๐พ Session ID for monitoring: ${sessionId}`);
|
|
229
363
|
}
|
|
230
364
|
}
|
|
231
365
|
catch (error) {
|
|
232
|
-
|
|
366
|
+
cliLogger.error('โ Failed to execute Queen Agent orchestration:', error instanceof Error ? error.message : String(error));
|
|
233
367
|
// Store error in memory for learning
|
|
234
368
|
memorySystem.storeLearning(`error_${sessionId}`, {
|
|
235
369
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -240,18 +374,18 @@ program
|
|
|
240
374
|
// Helper function to execute Claude Code directly (FALLBACK ONLY)
|
|
241
375
|
async function executeClaudeCode(prompt) {
|
|
242
376
|
return new Promise((resolve) => {
|
|
243
|
-
|
|
377
|
+
cliLogger.info('๐ Checking for Claude Code availability...');
|
|
244
378
|
// Try to find Claude Code binary
|
|
245
379
|
const claudeCommands = ['claude', 'claude-code', 'npx claude-code'];
|
|
246
380
|
let currentCommand = 0;
|
|
247
381
|
const tryNextCommand = () => {
|
|
248
382
|
if (currentCommand >= claudeCommands.length) {
|
|
249
|
-
|
|
383
|
+
cliLogger.warn('โ Claude Code not found in PATH');
|
|
250
384
|
resolve(false);
|
|
251
385
|
return;
|
|
252
386
|
}
|
|
253
387
|
const command = claudeCommands[currentCommand];
|
|
254
|
-
|
|
388
|
+
cliLogger.debug(`๐ Trying: ${command}`);
|
|
255
389
|
const claudeArgs = [
|
|
256
390
|
'--version'
|
|
257
391
|
];
|
|
@@ -261,7 +395,7 @@ async function executeClaudeCode(prompt) {
|
|
|
261
395
|
});
|
|
262
396
|
testProcess.on('close', (code) => {
|
|
263
397
|
if (code === 0) {
|
|
264
|
-
|
|
398
|
+
cliLogger.info(`โ
Found Claude Code: ${command}`);
|
|
265
399
|
executeWithClaude(command, prompt, resolve);
|
|
266
400
|
}
|
|
267
401
|
else {
|
|
@@ -282,14 +416,14 @@ function startMonitoringDashboard(claudeProcess) {
|
|
|
282
416
|
let iterations = 0;
|
|
283
417
|
const startTime = Date.now();
|
|
284
418
|
// Show initial dashboard only once
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
419
|
+
cliLogger.info(`โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ`);
|
|
420
|
+
cliLogger.info(`โ ๐ Snow-Flow Dashboard v${version_js_1.VERSION} โ`);
|
|
421
|
+
cliLogger.info(`โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค`);
|
|
422
|
+
cliLogger.info(`โ ๐ค Claude Code Status: โ
Starting โ`);
|
|
423
|
+
cliLogger.info(`โ ๐ Process ID: ${claudeProcess.pid || 'N/A'} โ`);
|
|
424
|
+
cliLogger.info(`โ โฑ๏ธ Session Time: 00:00 โ`);
|
|
425
|
+
cliLogger.info(`โ ๐ Monitoring Cycles: 0 โ`);
|
|
426
|
+
cliLogger.info('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
293
427
|
// Silent monitoring - only log to file or memory, don't interfere with Claude Code UI
|
|
294
428
|
const monitoringInterval = setInterval(() => {
|
|
295
429
|
iterations++;
|
|
@@ -311,7 +445,7 @@ function startMonitoringDashboard(claudeProcess) {
|
|
|
311
445
|
return monitoringInterval;
|
|
312
446
|
}
|
|
313
447
|
async function executeWithClaude(claudeCommand, prompt, resolve) {
|
|
314
|
-
|
|
448
|
+
cliLogger.info('๐ Starting Claude Code execution...');
|
|
315
449
|
// Write prompt to temporary file for large prompts
|
|
316
450
|
const tempFile = (0, path_1.join)(process.cwd(), '.snow-flow-prompt.tmp');
|
|
317
451
|
await fs_1.promises.writeFile(tempFile, prompt);
|
|
@@ -321,16 +455,16 @@ async function executeWithClaude(claudeCommand, prompt, resolve) {
|
|
|
321
455
|
try {
|
|
322
456
|
await fs_1.promises.access(mcpConfigPath);
|
|
323
457
|
hasMcpConfig = true;
|
|
324
|
-
|
|
458
|
+
cliLogger.info('โ
Found MCP configuration in current directory');
|
|
325
459
|
}
|
|
326
460
|
catch {
|
|
327
|
-
|
|
461
|
+
cliLogger.warn('โ ๏ธ No MCP configuration found. Run "snow-flow init --sparc" to set up MCP servers');
|
|
328
462
|
}
|
|
329
463
|
const claudeArgs = hasMcpConfig
|
|
330
464
|
? ['--mcp-config', '.mcp.json', '.', '--dangerously-skip-permissions']
|
|
331
465
|
: ['--dangerously-skip-permissions'];
|
|
332
466
|
if (hasMcpConfig) {
|
|
333
|
-
|
|
467
|
+
cliLogger.info('๐ง Starting Claude Code with ServiceNow MCP servers...');
|
|
334
468
|
}
|
|
335
469
|
// Start Claude Code process in interactive mode
|
|
336
470
|
const claudeProcess = (0, child_process_1.spawn)(claudeCommand, claudeArgs, {
|
|
@@ -338,8 +472,8 @@ async function executeWithClaude(claudeCommand, prompt, resolve) {
|
|
|
338
472
|
cwd: process.cwd()
|
|
339
473
|
});
|
|
340
474
|
// Send the prompt via stdin
|
|
341
|
-
|
|
342
|
-
|
|
475
|
+
cliLogger.info('๐ Sending orchestration prompt to Claude Code...');
|
|
476
|
+
cliLogger.info('๐ Claude Code interactive interface opening...\n');
|
|
343
477
|
claudeProcess.stdin.write(prompt);
|
|
344
478
|
claudeProcess.stdin.end();
|
|
345
479
|
// Start silent monitoring dashboard (doesn't interfere with Claude Code UI)
|
|
@@ -347,29 +481,29 @@ async function executeWithClaude(claudeCommand, prompt, resolve) {
|
|
|
347
481
|
claudeProcess.on('close', (code) => {
|
|
348
482
|
clearInterval(monitoringInterval);
|
|
349
483
|
if (code === 0) {
|
|
350
|
-
|
|
484
|
+
cliLogger.info('\nโ
Claude Code session completed successfully!');
|
|
351
485
|
resolve(true);
|
|
352
486
|
}
|
|
353
487
|
else {
|
|
354
|
-
|
|
488
|
+
cliLogger.warn(`\nโ Claude Code session ended with code: ${code}`);
|
|
355
489
|
resolve(false);
|
|
356
490
|
}
|
|
357
491
|
});
|
|
358
492
|
claudeProcess.on('error', (error) => {
|
|
359
493
|
clearInterval(monitoringInterval);
|
|
360
|
-
|
|
494
|
+
cliLogger.error(`โ Failed to start Claude Code: ${error.message}`);
|
|
361
495
|
resolve(false);
|
|
362
496
|
});
|
|
363
497
|
// Set timeout for Claude Code execution (configurable via environment variable)
|
|
364
498
|
const timeoutMinutes = process.env.SNOW_FLOW_TIMEOUT_MINUTES ? parseInt(process.env.SNOW_FLOW_TIMEOUT_MINUTES) : 60;
|
|
365
499
|
const timeoutMs = timeoutMinutes * 60 * 1000;
|
|
366
|
-
|
|
500
|
+
cliLogger.info(`โฑ๏ธ Claude Code timeout set to ${timeoutMinutes} minutes (configure with SNOW_FLOW_TIMEOUT_MINUTES=0 for no timeout)`);
|
|
367
501
|
let timeout = null;
|
|
368
502
|
// Only set timeout if not disabled (0 = no timeout)
|
|
369
503
|
if (timeoutMinutes > 0) {
|
|
370
504
|
timeout = setTimeout(() => {
|
|
371
505
|
clearInterval(monitoringInterval);
|
|
372
|
-
|
|
506
|
+
cliLogger.warn(`โฑ๏ธ Claude Code session timeout (${timeoutMinutes} minutes), terminating...`);
|
|
373
507
|
claudeProcess.kill('SIGTERM');
|
|
374
508
|
// Force kill if it doesn't respond
|
|
375
509
|
setTimeout(() => {
|
|
@@ -536,7 +670,7 @@ if ("${objective}".toLowerCase().includes('knowledge')) {
|
|
|
536
670
|
detectedTables.add('kb_knowledge');
|
|
537
671
|
}
|
|
538
672
|
|
|
539
|
-
|
|
673
|
+
cliLogger.info(\`๐ Detected tables to discover: \${Array.from(detectedTables).join(', ')}\`);
|
|
540
674
|
|
|
541
675
|
// Discover schemas for all detected tables
|
|
542
676
|
const tableSchemas = {};
|
|
@@ -557,10 +691,10 @@ for (const tableName of detectedTables) {
|
|
|
557
691
|
field_count: schema.fields.length,
|
|
558
692
|
key_fields: schema.fields.filter(f => f.primary || f.reference).map(f => f.name)
|
|
559
693
|
};
|
|
560
|
-
|
|
694
|
+
cliLogger.info(\`โ
Discovered table '\${tableName}' with \${schema.fields.length} fields\`);
|
|
561
695
|
}
|
|
562
696
|
} catch (e) {
|
|
563
|
-
|
|
697
|
+
cliLogger.warn(\`โ ๏ธ Table '\${tableName}' not found or inaccessible\`);
|
|
564
698
|
}
|
|
565
699
|
}
|
|
566
700
|
|
|
@@ -943,7 +1077,7 @@ const coordinationInterval = setInterval(async () => {
|
|
|
943
1077
|
const agents = [${[taskAnalysis.primaryAgent, ...taskAnalysis.supportingAgents].map(a => `"${a}"`).join(', ')}];
|
|
944
1078
|
for (const agent of agents) {
|
|
945
1079
|
const progress = agentStates.find(s => s.includes(\`agent_\${agent}_progress\`));
|
|
946
|
-
|
|
1080
|
+
cliLogger.info(\`Agent \${agent}: \${progress ? 'active' : 'waiting'}\`);
|
|
947
1081
|
}
|
|
948
1082
|
}, 10000); // Every 10 seconds
|
|
949
1083
|
|
|
@@ -1021,8 +1155,8 @@ setInterval(() => {
|
|
|
1021
1155
|
const session = Memory.get("swarm_session_${sessionId}");
|
|
1022
1156
|
const todos = TodoRead();
|
|
1023
1157
|
|
|
1024
|
-
|
|
1025
|
-
|
|
1158
|
+
cliLogger.info(\`Swarm Status: \${session.status}\`);
|
|
1159
|
+
cliLogger.info(\`Tasks Completed: \${todos.filter(t => t.status === 'completed').length}/\${todos.length}\`);
|
|
1026
1160
|
|
|
1027
1161
|
// Check individual agent progress
|
|
1028
1162
|
checkAgentProgress();
|
|
@@ -1095,7 +1229,7 @@ if (flows.error?.includes("OAuth")) {
|
|
|
1095
1229
|
\`\`\`javascript
|
|
1096
1230
|
// Verify permissions
|
|
1097
1231
|
const permCheck = await snow_get_by_sysid({
|
|
1098
|
-
sys_id: "test",
|
|
1232
|
+
sys_id: "test", // Example sys_id - replace with actual value
|
|
1099
1233
|
table: "sys_script_include"
|
|
1100
1234
|
});
|
|
1101
1235
|
if (permCheck.error?.includes("OAuth")) {
|
|
@@ -1195,19 +1329,19 @@ program
|
|
|
1195
1329
|
.option('--watch', 'Continuously monitor the swarm progress')
|
|
1196
1330
|
.option('--interval <seconds>', 'Watch interval in seconds', '5')
|
|
1197
1331
|
.action(async (sessionId, options) => {
|
|
1198
|
-
|
|
1332
|
+
cliLogger.info('\n๐ Checking swarm status...\n');
|
|
1199
1333
|
try {
|
|
1200
1334
|
const { QueenMemorySystem } = await Promise.resolve().then(() => __importStar(require('./queen/queen-memory.js')));
|
|
1201
1335
|
const memorySystem = new QueenMemorySystem();
|
|
1202
1336
|
if (!sessionId) {
|
|
1203
1337
|
// List all recent swarm sessions
|
|
1204
|
-
|
|
1205
|
-
|
|
1338
|
+
cliLogger.info('๐ Recent swarm sessions:');
|
|
1339
|
+
cliLogger.info('(Provide a session ID to see detailed status)\n');
|
|
1206
1340
|
// Get all session keys from learnings
|
|
1207
1341
|
const sessionKeys = [];
|
|
1208
1342
|
// Note: This is a simplified approach - in production, you'd query the database directly
|
|
1209
|
-
|
|
1210
|
-
|
|
1343
|
+
cliLogger.info('๐ก Use: snow-flow swarm-status <sessionId> to see details');
|
|
1344
|
+
cliLogger.info('๐ก Session IDs are displayed when you start a swarm\n');
|
|
1211
1345
|
return;
|
|
1212
1346
|
}
|
|
1213
1347
|
// Get specific session data
|
|
@@ -1216,48 +1350,48 @@ program
|
|
|
1216
1350
|
const errorData = memorySystem.getLearning(`error_${sessionId}`);
|
|
1217
1351
|
if (!sessionData) {
|
|
1218
1352
|
console.error(`โ No swarm session found with ID: ${sessionId}`);
|
|
1219
|
-
|
|
1353
|
+
cliLogger.info('๐ก Make sure to use the exact session ID displayed when starting the swarm');
|
|
1220
1354
|
return;
|
|
1221
1355
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1356
|
+
cliLogger.info(`๐ Swarm Session: ${sessionId}`);
|
|
1357
|
+
cliLogger.info(`๐ Objective: ${sessionData.objective}`);
|
|
1358
|
+
cliLogger.info(`๐ Started: ${sessionData.started_at}`);
|
|
1359
|
+
cliLogger.info(`๐ Task Type: ${sessionData.taskAnalysis.taskType}`);
|
|
1360
|
+
cliLogger.info(`๐ค Agents: ${sessionData.taskAnalysis.estimatedAgentCount} total`);
|
|
1361
|
+
cliLogger.info(` - Primary: ${sessionData.taskAnalysis.primaryAgent}`);
|
|
1362
|
+
cliLogger.info(` - Supporting: ${sessionData.taskAnalysis.supportingAgents.join(', ')}`);
|
|
1229
1363
|
if (launchData && launchData.success) {
|
|
1230
|
-
|
|
1231
|
-
|
|
1364
|
+
cliLogger.info(`\nโ
Status: Claude Code launched successfully`);
|
|
1365
|
+
cliLogger.info(`๐ Launched at: ${launchData.launched_at}`);
|
|
1232
1366
|
}
|
|
1233
1367
|
else if (errorData) {
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1368
|
+
cliLogger.error(`\nโ Status: Error occurred`);
|
|
1369
|
+
cliLogger.error(`๐ฅ Error: ${errorData.error}`);
|
|
1370
|
+
cliLogger.error(`๐ Failed at: ${errorData.failed_at}`);
|
|
1237
1371
|
}
|
|
1238
1372
|
else {
|
|
1239
|
-
|
|
1373
|
+
cliLogger.info(`\nโณ Status: Awaiting manual Claude Code execution`);
|
|
1240
1374
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1375
|
+
cliLogger.info('\n๐ก Tips:');
|
|
1376
|
+
cliLogger.info(' - Check Claude Code for real-time agent progress');
|
|
1377
|
+
cliLogger.info(' - Use Memory.get("swarm_session_' + sessionId + '") in Claude Code');
|
|
1378
|
+
cliLogger.info(' - Monitor TodoRead for task completion status');
|
|
1245
1379
|
if (options.watch) {
|
|
1246
|
-
|
|
1247
|
-
|
|
1380
|
+
cliLogger.info(`\n๐ Watching for updates every ${options.interval} seconds...`);
|
|
1381
|
+
cliLogger.info('(Press Ctrl+C to stop)\n');
|
|
1248
1382
|
const watchInterval = setInterval(async () => {
|
|
1249
1383
|
// In a real implementation, this would query Claude Code's memory
|
|
1250
|
-
|
|
1384
|
+
cliLogger.info(`[${new Date().toLocaleTimeString()}] Checking for updates...`);
|
|
1251
1385
|
// Re-fetch session data to check for updates
|
|
1252
1386
|
const updatedSession = memorySystem.getLearning(`session_${sessionId}`);
|
|
1253
1387
|
if (updatedSession) {
|
|
1254
|
-
|
|
1388
|
+
cliLogger.info(' Status: Active - Check Claude Code for details');
|
|
1255
1389
|
}
|
|
1256
1390
|
}, parseInt(options.interval) * 1000);
|
|
1257
1391
|
// Handle graceful shutdown
|
|
1258
1392
|
process.on('SIGINT', () => {
|
|
1259
1393
|
clearInterval(watchInterval);
|
|
1260
|
-
|
|
1394
|
+
cliLogger.info('\n\nโ Stopped watching swarm status');
|
|
1261
1395
|
process.exit(0);
|
|
1262
1396
|
});
|
|
1263
1397
|
}
|
|
@@ -1272,26 +1406,26 @@ program
|
|
|
1272
1406
|
.description('Spawn a specific agent type')
|
|
1273
1407
|
.option('--name <name>', 'Custom agent name')
|
|
1274
1408
|
.action(async (type, options) => {
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1409
|
+
cliLogger.info(`๐ค Spawning ${type} agent${options.name ? ` with name "${options.name}"` : ''}...`);
|
|
1410
|
+
cliLogger.info(`โ
Agent spawned successfully`);
|
|
1411
|
+
cliLogger.info(`๐ Agent capabilities:`);
|
|
1278
1412
|
if (type === 'widget-builder') {
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1413
|
+
cliLogger.info(' โโโ Service Portal widget creation');
|
|
1414
|
+
cliLogger.info(' โโโ HTML/CSS template generation');
|
|
1415
|
+
cliLogger.info(' โโโ Client script development');
|
|
1416
|
+
cliLogger.info(' โโโ Server script implementation');
|
|
1283
1417
|
}
|
|
1284
1418
|
else if (type === 'workflow-designer') {
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1419
|
+
cliLogger.info(' โโโ Flow Designer workflow creation');
|
|
1420
|
+
cliLogger.info(' โโโ Process automation');
|
|
1421
|
+
cliLogger.info(' โโโ Approval routing');
|
|
1422
|
+
cliLogger.info(' โโโ Integration orchestration');
|
|
1289
1423
|
}
|
|
1290
1424
|
else {
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1425
|
+
cliLogger.info(' โโโ Generic ServiceNow development');
|
|
1426
|
+
cliLogger.info(' โโโ Script generation');
|
|
1427
|
+
cliLogger.info(' โโโ Configuration management');
|
|
1428
|
+
cliLogger.info(' โโโ API integration');
|
|
1295
1429
|
}
|
|
1296
1430
|
});
|
|
1297
1431
|
// Status command
|
|
@@ -1299,24 +1433,24 @@ program
|
|
|
1299
1433
|
.command('status')
|
|
1300
1434
|
.description('Show orchestrator status')
|
|
1301
1435
|
.action(async () => {
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1436
|
+
cliLogger.info('\n๐ ServiceNow Multi-Agent Orchestrator Status');
|
|
1437
|
+
cliLogger.info('=============================================');
|
|
1438
|
+
cliLogger.info('๐ System Status: โ
Online');
|
|
1439
|
+
cliLogger.info('๐ค Available Agents: 5');
|
|
1440
|
+
cliLogger.info('๐ Queue Status: Empty');
|
|
1441
|
+
cliLogger.info('๐ ServiceNow Connection: Not configured');
|
|
1442
|
+
cliLogger.info('๐พ Memory Usage: 45MB');
|
|
1443
|
+
cliLogger.info('๐ Uptime: 00:05:23');
|
|
1444
|
+
cliLogger.info('\n๐ค Agent Types:');
|
|
1445
|
+
cliLogger.info(' โโโ widget-builder: Available');
|
|
1446
|
+
cliLogger.info(' โโโ workflow-designer: Available');
|
|
1447
|
+
cliLogger.info(' โโโ script-generator: Available');
|
|
1448
|
+
cliLogger.info(' โโโ ui-builder: Available');
|
|
1449
|
+
cliLogger.info(' โโโ app-creator: Available');
|
|
1450
|
+
cliLogger.info('\nโ๏ธ Configuration:');
|
|
1451
|
+
cliLogger.info(' โโโ Instance: Not set');
|
|
1452
|
+
cliLogger.info(' โโโ Authentication: Not configured');
|
|
1453
|
+
cliLogger.info(' โโโ Mode: Development');
|
|
1320
1454
|
});
|
|
1321
1455
|
// Monitor command - real-time dashboard
|
|
1322
1456
|
program
|
|
@@ -1325,7 +1459,7 @@ program
|
|
|
1325
1459
|
.option('--duration <seconds>', 'Duration to monitor (default: 60)', '60')
|
|
1326
1460
|
.action(async (options) => {
|
|
1327
1461
|
const duration = parseInt(options.duration) * 1000;
|
|
1328
|
-
|
|
1462
|
+
cliLogger.info('๐ Starting Snow-Flow Real-Time Monitor...\n');
|
|
1329
1463
|
let iterations = 0;
|
|
1330
1464
|
const startTime = Date.now();
|
|
1331
1465
|
const monitoringInterval = setInterval(() => {
|
|
@@ -1338,7 +1472,7 @@ program
|
|
|
1338
1472
|
process.stdout.write('\x1B[12A'); // Move cursor up 12 lines
|
|
1339
1473
|
process.stdout.write('\x1B[2K'); // Clear line
|
|
1340
1474
|
}
|
|
1341
|
-
|
|
1475
|
+
cliLogger.info('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
1342
1476
|
console.log(`โ ๐ Snow-Flow Monitor v${version_js_1.VERSION} โ`);
|
|
1343
1477
|
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค');
|
|
1344
1478
|
console.log(`โ ๐ System Status: โ
Online โ`);
|
|
@@ -1349,13 +1483,13 @@ program
|
|
|
1349
1483
|
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค');
|
|
1350
1484
|
console.log('โ ๐ Recent Activity: โ');
|
|
1351
1485
|
console.log(`โ โข ${new Date().toLocaleTimeString()} - System monitoring active โ`);
|
|
1352
|
-
|
|
1486
|
+
cliLogger.info('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
1353
1487
|
// Check for active Claude Code processes
|
|
1354
1488
|
try {
|
|
1355
1489
|
const { execSync } = require('child_process');
|
|
1356
1490
|
const processes = execSync('ps aux | grep "claude" | grep -v grep', { encoding: 'utf8' }).toString();
|
|
1357
1491
|
if (processes.trim()) {
|
|
1358
|
-
|
|
1492
|
+
cliLogger.info('\n๐ค Active Claude Code Processes:');
|
|
1359
1493
|
const lines = processes.trim().split('\n');
|
|
1360
1494
|
lines.forEach((line, index) => {
|
|
1361
1495
|
if (index < 3) { // Show max 3 processes
|
|
@@ -1363,7 +1497,7 @@ program
|
|
|
1363
1497
|
const pid = parts[1];
|
|
1364
1498
|
const cpu = parts[2];
|
|
1365
1499
|
const mem = parts[3];
|
|
1366
|
-
|
|
1500
|
+
cliLogger.info(` Process ${pid}: CPU ${cpu}%, Memory ${mem}%`);
|
|
1367
1501
|
}
|
|
1368
1502
|
});
|
|
1369
1503
|
}
|
|
@@ -1376,12 +1510,12 @@ program
|
|
|
1376
1510
|
const serviceNowDir = (0, path_1.join)(process.cwd(), 'servicenow');
|
|
1377
1511
|
fs_1.promises.readdir(serviceNowDir).then(files => {
|
|
1378
1512
|
if (files.length > 0) {
|
|
1379
|
-
|
|
1513
|
+
cliLogger.info(`\n๐ Generated Artifacts: ${files.length} files in servicenow/`);
|
|
1380
1514
|
files.slice(0, 3).forEach(file => {
|
|
1381
|
-
|
|
1515
|
+
cliLogger.info(` โข ${file}`);
|
|
1382
1516
|
});
|
|
1383
1517
|
if (files.length > 3) {
|
|
1384
|
-
|
|
1518
|
+
cliLogger.info(` ... and ${files.length - 3} more files`);
|
|
1385
1519
|
}
|
|
1386
1520
|
}
|
|
1387
1521
|
}).catch(() => {
|
|
@@ -1395,7 +1529,7 @@ program
|
|
|
1395
1529
|
// Stop monitoring after duration
|
|
1396
1530
|
setTimeout(() => {
|
|
1397
1531
|
clearInterval(monitoringInterval);
|
|
1398
|
-
|
|
1532
|
+
cliLogger.info('\nโ
Monitoring completed. Use --duration <seconds> to monitor longer.');
|
|
1399
1533
|
}, duration);
|
|
1400
1534
|
});
|
|
1401
1535
|
// Memory commands
|
|
@@ -1403,21 +1537,21 @@ program
|
|
|
1403
1537
|
.command('memory <action> [key] [value]')
|
|
1404
1538
|
.description('Memory operations (store, get, list)')
|
|
1405
1539
|
.action(async (action, key, value) => {
|
|
1406
|
-
|
|
1540
|
+
cliLogger.info(`๐พ Memory ${action}${key ? `: ${key}` : ''}`);
|
|
1407
1541
|
if (action === 'store' && key && value) {
|
|
1408
|
-
|
|
1542
|
+
cliLogger.info(`โ
Stored: ${key} = ${value}`);
|
|
1409
1543
|
}
|
|
1410
1544
|
else if (action === 'get' && key) {
|
|
1411
|
-
|
|
1545
|
+
cliLogger.info(`๐ Retrieved: ${key} = [simulated value]`);
|
|
1412
1546
|
}
|
|
1413
1547
|
else if (action === 'list') {
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1548
|
+
cliLogger.info('๐ Memory contents:');
|
|
1549
|
+
cliLogger.info(' โโโ last_widget: incident_management_widget');
|
|
1550
|
+
cliLogger.info(' โโโ last_workflow: approval_process');
|
|
1551
|
+
cliLogger.info(' โโโ session_id: snow-flow-session-123');
|
|
1418
1552
|
}
|
|
1419
1553
|
else {
|
|
1420
|
-
|
|
1554
|
+
cliLogger.error('โ Invalid memory operation');
|
|
1421
1555
|
}
|
|
1422
1556
|
});
|
|
1423
1557
|
// Auth command - OAuth implementation
|
|
@@ -1430,37 +1564,37 @@ program
|
|
|
1430
1564
|
.action(async (action, options) => {
|
|
1431
1565
|
const oauth = new snow_oauth_js_1.ServiceNowOAuth();
|
|
1432
1566
|
if (action === 'login') {
|
|
1433
|
-
|
|
1567
|
+
cliLogger.info('๐ Starting ServiceNow OAuth authentication...');
|
|
1434
1568
|
// Get credentials from options or environment
|
|
1435
1569
|
const instance = options.instance || process.env.SNOW_INSTANCE;
|
|
1436
1570
|
const clientId = options.clientId || process.env.SNOW_CLIENT_ID;
|
|
1437
1571
|
const clientSecret = options.clientSecret || process.env.SNOW_CLIENT_SECRET;
|
|
1438
1572
|
if (!instance || !clientId || !clientSecret) {
|
|
1439
1573
|
console.error('โ Missing required OAuth credentials');
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1574
|
+
cliLogger.info('\n๐ Please provide:');
|
|
1575
|
+
cliLogger.info(' --instance: ServiceNow instance (e.g., dev12345.service-now.com)');
|
|
1576
|
+
cliLogger.info(' --client-id: OAuth Client ID');
|
|
1577
|
+
cliLogger.info(' --client-secret: OAuth Client Secret');
|
|
1578
|
+
cliLogger.info('\n๐ก Or set environment variables:');
|
|
1579
|
+
cliLogger.info(' export SNOW_INSTANCE=your-instance.service-now.com');
|
|
1580
|
+
cliLogger.info(' export SNOW_CLIENT_ID=your-client-id');
|
|
1581
|
+
cliLogger.info(' export SNOW_CLIENT_SECRET=your-client-secret');
|
|
1448
1582
|
return;
|
|
1449
1583
|
}
|
|
1450
1584
|
// Start OAuth flow
|
|
1451
1585
|
const result = await oauth.authenticate(instance, clientId, clientSecret);
|
|
1452
1586
|
if (result.success) {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1587
|
+
cliLogger.info('\nโ
Authentication successful!');
|
|
1588
|
+
cliLogger.info('๐ Snow-Flow is now connected to ServiceNow!');
|
|
1589
|
+
cliLogger.info('\n๐ Next steps:');
|
|
1590
|
+
cliLogger.info(' 1. Test connection: snow-flow auth status');
|
|
1591
|
+
cliLogger.info(' 2. Start development: snow-flow swarm "create a widget for incident management"');
|
|
1458
1592
|
// Test connection
|
|
1459
1593
|
const client = new servicenow_client_js_1.ServiceNowClient();
|
|
1460
1594
|
const testResult = await client.testConnection();
|
|
1461
1595
|
if (testResult.success) {
|
|
1462
|
-
|
|
1463
|
-
|
|
1596
|
+
cliLogger.info(`\n๐ Connection test successful!`);
|
|
1597
|
+
cliLogger.info(`๐ค Logged in as: ${testResult.data.name} (${testResult.data.user_name})`);
|
|
1464
1598
|
}
|
|
1465
1599
|
}
|
|
1466
1600
|
else {
|
|
@@ -1469,11 +1603,11 @@ program
|
|
|
1469
1603
|
}
|
|
1470
1604
|
}
|
|
1471
1605
|
else if (action === 'logout') {
|
|
1472
|
-
|
|
1606
|
+
cliLogger.info('๐ Logging out...');
|
|
1473
1607
|
await oauth.logout();
|
|
1474
1608
|
}
|
|
1475
1609
|
else if (action === 'status') {
|
|
1476
|
-
|
|
1610
|
+
cliLogger.info('๐ Authentication Status:');
|
|
1477
1611
|
const isAuthenticated = await oauth.isAuthenticated();
|
|
1478
1612
|
const credentials = await oauth.loadCredentials();
|
|
1479
1613
|
if (isAuthenticated && credentials) {
|
|
@@ -1511,6 +1645,122 @@ program
|
|
|
1511
1645
|
console.log('โ Invalid action. Use: login, logout, or status');
|
|
1512
1646
|
}
|
|
1513
1647
|
});
|
|
1648
|
+
// Deploy XML command
|
|
1649
|
+
program
|
|
1650
|
+
.command('deploy-xml <xmlFile>')
|
|
1651
|
+
.description('Deploy XML update set to ServiceNow (auto-import, preview, and commit)')
|
|
1652
|
+
.option('--no-preview', 'Skip preview step')
|
|
1653
|
+
.option('--no-commit', 'Skip auto-commit (preview only)')
|
|
1654
|
+
.action(async (xmlFile, options) => {
|
|
1655
|
+
console.log(`\n๐ฆ Deploying XML Update Set: ${xmlFile}`);
|
|
1656
|
+
console.log('='.repeat(60));
|
|
1657
|
+
const oauth = new snow_oauth_js_1.ServiceNowOAuth();
|
|
1658
|
+
const isAuthenticated = await oauth.getStoredTokens() !== null;
|
|
1659
|
+
if (!isAuthenticated) {
|
|
1660
|
+
console.log('โ Not authenticated. Please run: snow-flow auth login');
|
|
1661
|
+
return;
|
|
1662
|
+
}
|
|
1663
|
+
try {
|
|
1664
|
+
// Initialize ServiceNow client
|
|
1665
|
+
const client = new servicenow_client_js_1.ServiceNowClient();
|
|
1666
|
+
// Read XML file
|
|
1667
|
+
if (!(0, fs_2.existsSync)(xmlFile)) {
|
|
1668
|
+
console.error(`โ XML file not found: ${xmlFile}`);
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
console.log('๐ Reading XML file...');
|
|
1672
|
+
const xmlContent = await fs_1.promises.readFile(xmlFile, 'utf-8');
|
|
1673
|
+
// Import XML as remote update set
|
|
1674
|
+
console.log('๐ค Importing XML to ServiceNow...');
|
|
1675
|
+
const importResponse = await client.makeRequest({
|
|
1676
|
+
method: 'POST',
|
|
1677
|
+
url: '/api/now/table/sys_remote_update_set',
|
|
1678
|
+
headers: {
|
|
1679
|
+
'Content-Type': 'application/xml',
|
|
1680
|
+
'Accept': 'application/json'
|
|
1681
|
+
},
|
|
1682
|
+
data: xmlContent
|
|
1683
|
+
});
|
|
1684
|
+
if (!importResponse.result || !importResponse.result.sys_id) {
|
|
1685
|
+
throw new Error('Failed to import XML update set');
|
|
1686
|
+
}
|
|
1687
|
+
const remoteUpdateSetId = importResponse.result.sys_id;
|
|
1688
|
+
console.log(`โ
XML imported successfully (sys_id: ${remoteUpdateSetId})`);
|
|
1689
|
+
// Load the update set
|
|
1690
|
+
console.log('๐ Loading update set...');
|
|
1691
|
+
await client.makeRequest({
|
|
1692
|
+
method: 'PUT',
|
|
1693
|
+
url: `/api/now/table/sys_remote_update_set/${remoteUpdateSetId}`,
|
|
1694
|
+
data: {
|
|
1695
|
+
state: 'loaded'
|
|
1696
|
+
}
|
|
1697
|
+
});
|
|
1698
|
+
// Find the loaded update set
|
|
1699
|
+
const loadedResponse = await client.makeRequest({
|
|
1700
|
+
method: 'GET',
|
|
1701
|
+
url: '/api/now/table/sys_update_set',
|
|
1702
|
+
params: {
|
|
1703
|
+
sysparm_query: `remote_sys_id=${remoteUpdateSetId}`,
|
|
1704
|
+
sysparm_limit: 1
|
|
1705
|
+
}
|
|
1706
|
+
});
|
|
1707
|
+
if (!loadedResponse.result || loadedResponse.result.length === 0) {
|
|
1708
|
+
throw new Error('Failed to find loaded update set');
|
|
1709
|
+
}
|
|
1710
|
+
const updateSetId = loadedResponse.result[0].sys_id;
|
|
1711
|
+
const updateSetName = loadedResponse.result[0].name;
|
|
1712
|
+
console.log(`โ
Update set loaded: ${updateSetName}`);
|
|
1713
|
+
// Preview if requested
|
|
1714
|
+
if (options.preview !== false) {
|
|
1715
|
+
console.log('๐ Previewing update set...');
|
|
1716
|
+
await client.makeRequest({
|
|
1717
|
+
method: 'POST',
|
|
1718
|
+
url: `/api/now/table/sys_update_set/${updateSetId}/preview`
|
|
1719
|
+
});
|
|
1720
|
+
// Check preview results
|
|
1721
|
+
const previewProblems = await client.makeRequest({
|
|
1722
|
+
method: 'GET',
|
|
1723
|
+
url: '/api/now/table/sys_update_preview_problem',
|
|
1724
|
+
params: {
|
|
1725
|
+
sysparm_query: `update_set=${updateSetId}`,
|
|
1726
|
+
sysparm_limit: 100
|
|
1727
|
+
}
|
|
1728
|
+
});
|
|
1729
|
+
if (previewProblems.result && previewProblems.result.length > 0) {
|
|
1730
|
+
console.log('\nโ ๏ธ Preview found problems:');
|
|
1731
|
+
previewProblems.result.forEach((p) => {
|
|
1732
|
+
console.log(` - ${p.type}: ${p.description}`);
|
|
1733
|
+
});
|
|
1734
|
+
if (options.commit !== false) {
|
|
1735
|
+
console.log('\nโ ๏ธ Skipping auto-commit due to preview problems');
|
|
1736
|
+
console.log('๐ Review and resolve problems in ServiceNow, then commit manually');
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
else {
|
|
1741
|
+
console.log('โ
Preview successful - no problems found');
|
|
1742
|
+
}
|
|
1743
|
+
// Commit if clean and requested
|
|
1744
|
+
if (options.commit !== false && (!previewProblems.result || previewProblems.result.length === 0)) {
|
|
1745
|
+
console.log('๐ Committing update set...');
|
|
1746
|
+
await client.makeRequest({
|
|
1747
|
+
method: 'POST',
|
|
1748
|
+
url: `/api/now/table/sys_update_set/${updateSetId}/commit`
|
|
1749
|
+
});
|
|
1750
|
+
console.log('\nโ
Update Set committed successfully!');
|
|
1751
|
+
console.log('๐ Navigate to Flow Designer > Designer to see your flow');
|
|
1752
|
+
console.log('\n๐ Deployment complete!');
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
catch (error) {
|
|
1757
|
+
console.error('\nโ Deployment failed:', error instanceof Error ? error.message : String(error));
|
|
1758
|
+
console.log('\n๐ก Troubleshooting tips:');
|
|
1759
|
+
console.log(' 1. Check your authentication: snow-flow auth status');
|
|
1760
|
+
console.log(' 2. Verify XML file format is correct');
|
|
1761
|
+
console.log(' 3. Ensure you have required permissions in ServiceNow');
|
|
1762
|
+
}
|
|
1763
|
+
});
|
|
1514
1764
|
// Help command
|
|
1515
1765
|
program
|
|
1516
1766
|
.command('help')
|
|
@@ -1528,6 +1778,8 @@ program
|
|
|
1528
1778
|
auth <action> Authentication management
|
|
1529
1779
|
mcp <action> Manage ServiceNow MCP servers
|
|
1530
1780
|
create-flow <instruction> Create flows using natural language
|
|
1781
|
+
xml-flow <instruction> Create flows using XML-first approach
|
|
1782
|
+
deploy-xml <file> Deploy XML update set to ServiceNow
|
|
1531
1783
|
help Show this help
|
|
1532
1784
|
|
|
1533
1785
|
๐ฏ Example Usage:
|
|
@@ -1536,7 +1788,10 @@ program
|
|
|
1536
1788
|
snow-flow mcp start # Start MCP servers for Claude Code
|
|
1537
1789
|
snow-flow mcp status # Check MCP server status
|
|
1538
1790
|
snow-flow swarm "create a widget for incident management"
|
|
1791
|
+
snow-flow swarm "create approval flow" # ๐ง Auto-detects Flow Designer and uses XML!
|
|
1539
1792
|
snow-flow create-flow "approval flow for hardware purchases over โฌ1000"
|
|
1793
|
+
snow-flow xml-flow "create iPhone approval flow" --table sc_request
|
|
1794
|
+
snow-flow deploy-xml flow-update-sets/my_flow.xml # ๐ Auto-import to ServiceNow!
|
|
1540
1795
|
snow-flow spawn widget-builder --name "IncidentWidget"
|
|
1541
1796
|
snow-flow monitor --duration 120
|
|
1542
1797
|
snow-flow memory store "project" "incident_system"
|
|
@@ -2362,7 +2617,7 @@ snow_catalog_item_search({
|
|
|
2362
2617
|
### snow_get_by_sysid
|
|
2363
2618
|
\`\`\`javascript
|
|
2364
2619
|
snow_get_by_sysid({
|
|
2365
|
-
sys_id: "
|
|
2620
|
+
sys_id: "<artifact_sys_id>",
|
|
2366
2621
|
table: "sp_widget"
|
|
2367
2622
|
})
|
|
2368
2623
|
\`\`\`
|
|
@@ -2440,7 +2695,7 @@ snow_update_set_create({
|
|
|
2440
2695
|
\`\`\`javascript
|
|
2441
2696
|
snow_update_set_add_artifact({
|
|
2442
2697
|
type: "widget",
|
|
2443
|
-
sys_id: "
|
|
2698
|
+
sys_id: "<artifact_sys_id>",
|
|
2444
2699
|
name: "incident_dashboard"
|
|
2445
2700
|
})
|
|
2446
2701
|
\`\`\`
|
|
@@ -2930,7 +3185,7 @@ snow_catalog_item_search({
|
|
|
2930
3185
|
|
|
2931
3186
|
// Direct sys_id lookup (faster than search)
|
|
2932
3187
|
snow_get_by_sysid({
|
|
2933
|
-
sys_id: "
|
|
3188
|
+
sys_id: "<artifact_sys_id>",
|
|
2934
3189
|
table: "sp_widget"
|
|
2935
3190
|
});
|
|
2936
3191
|
\`\`\`
|
|
@@ -3276,7 +3531,7 @@ SNOW_CLIENT_ID=your-oauth-client-id
|
|
|
3276
3531
|
SNOW_CLIENT_SECRET=your-oauth-client-secret
|
|
3277
3532
|
|
|
3278
3533
|
# Optional: Additional Configuration
|
|
3279
|
-
# SNOW_REDIRECT_URI=http
|
|
3534
|
+
# SNOW_REDIRECT_URI=http://\${SNOW_REDIRECT_HOST:-localhost}:\${SNOW_REDIRECT_PORT:-3000}/callback
|
|
3280
3535
|
|
|
3281
3536
|
# ===========================================
|
|
3282
3537
|
# Snow-Flow Configuration
|
|
@@ -3306,7 +3561,7 @@ SNOW_FLOW_TIMEOUT_MINUTES=0
|
|
|
3306
3561
|
# - Name: Snow-Flow Development
|
|
3307
3562
|
# - Client ID: (will be generated)
|
|
3308
3563
|
# - Client Secret: (will be generated)
|
|
3309
|
-
# - Redirect URL: http
|
|
3564
|
+
# - Redirect URL: http://\${SNOW_REDIRECT_HOST:-localhost}:\${SNOW_REDIRECT_PORT:-3000}/callback
|
|
3310
3565
|
# - Grant Type: Authorization Code
|
|
3311
3566
|
# 5. Copy the Client ID and Client Secret to this file
|
|
3312
3567
|
# 6. Run: snow-flow auth login
|
|
@@ -3741,7 +3996,7 @@ async function handleMCPStatus(manager, options) {
|
|
|
3741
3996
|
async function handleMCPLogs(manager, options) {
|
|
3742
3997
|
const { join } = require('path');
|
|
3743
3998
|
const { promises: fs } = require('fs');
|
|
3744
|
-
const logDir = join(process.
|
|
3999
|
+
const logDir = join(process.env.SNOW_FLOW_HOME || join(os.homedir(), '.snow-flow'), 'logs');
|
|
3745
4000
|
try {
|
|
3746
4001
|
const logFiles = await fs.readdir(logDir);
|
|
3747
4002
|
if (options.server) {
|
|
@@ -3995,6 +4250,141 @@ Execute this intelligent flow composition using Snow-Flow's advanced orchestrati
|
|
|
3995
4250
|
console.error('โ Flow composition failed:', error instanceof Error ? error.message : String(error));
|
|
3996
4251
|
}
|
|
3997
4252
|
});
|
|
4253
|
+
// XML Flow command - Create flows using XML-first approach for maximum reliability
|
|
4254
|
+
program
|
|
4255
|
+
.command('xml-flow <instruction>')
|
|
4256
|
+
.description('๐ฏ Create ServiceNow flows using XML-first approach - MOST RELIABLE method!')
|
|
4257
|
+
.option('--name <name>', 'Flow name (auto-generated if not provided)')
|
|
4258
|
+
.option('--table <table>', 'Target table (e.g., incident, sc_request)')
|
|
4259
|
+
.option('--trigger <type>', 'Trigger type (record_created, record_updated, manual, scheduled)', 'record_created')
|
|
4260
|
+
.option('--output <path>', 'Output XML file path')
|
|
4261
|
+
.option('--import', 'Show import instructions after generation', true)
|
|
4262
|
+
.option('--no-import', 'Skip import instructions')
|
|
4263
|
+
.option('--test', 'Generate test flow with mock data')
|
|
4264
|
+
.option('--update-set <name>', 'Custom Update Set name')
|
|
4265
|
+
.action(async (instruction, options) => {
|
|
4266
|
+
console.log(`\n๐ง XML-First Flow Generator v${version_js_1.VERSION}`);
|
|
4267
|
+
console.log('๐ Creating production-ready ServiceNow flow XML...\n');
|
|
4268
|
+
try {
|
|
4269
|
+
// Import XML flow generator
|
|
4270
|
+
const { generateProductionFlowXML } = await Promise.resolve().then(() => __importStar(require('./utils/xml-first-flow-generator.js')));
|
|
4271
|
+
// Parse instruction to determine activities
|
|
4272
|
+
const activities = [];
|
|
4273
|
+
// Check for common patterns in instruction
|
|
4274
|
+
const instructionLower = instruction.toLowerCase();
|
|
4275
|
+
if (instructionLower.includes('approval') || instructionLower.includes('approve')) {
|
|
4276
|
+
activities.push({
|
|
4277
|
+
name: 'Request Approval',
|
|
4278
|
+
type: 'approval',
|
|
4279
|
+
order: 100,
|
|
4280
|
+
inputs: {
|
|
4281
|
+
table: options.table || 'sc_request',
|
|
4282
|
+
record: '{{trigger.current.sys_id}}',
|
|
4283
|
+
approver: '{{trigger.current.requested_for.manager}}',
|
|
4284
|
+
approval_field: 'approval',
|
|
4285
|
+
message: `Please approve: {{trigger.current.number}}`
|
|
4286
|
+
},
|
|
4287
|
+
outputs: {
|
|
4288
|
+
state: 'string',
|
|
4289
|
+
approver_sys_id: 'string',
|
|
4290
|
+
comments: 'string'
|
|
4291
|
+
}
|
|
4292
|
+
});
|
|
4293
|
+
}
|
|
4294
|
+
if (instructionLower.includes('notification') || instructionLower.includes('email') || instructionLower.includes('notify')) {
|
|
4295
|
+
activities.push({
|
|
4296
|
+
name: 'Send Notification',
|
|
4297
|
+
type: 'notification',
|
|
4298
|
+
order: activities.length > 0 ? 200 : 100,
|
|
4299
|
+
inputs: {
|
|
4300
|
+
notification_id: (0, servicenow_id_generator_js_1.getNotificationTemplateSysId)('generic_notification'),
|
|
4301
|
+
recipients: '{{trigger.current.requested_for}}',
|
|
4302
|
+
values: {
|
|
4303
|
+
request_number: '{{trigger.current.number}}',
|
|
4304
|
+
status: 'Notification sent'
|
|
4305
|
+
}
|
|
4306
|
+
}
|
|
4307
|
+
});
|
|
4308
|
+
}
|
|
4309
|
+
// Build flow definition
|
|
4310
|
+
const flowDef = {
|
|
4311
|
+
name: options.name || `Flow_${instruction.substring(0, 30).replace(/[^a-zA-Z0-9]/g, '_')}`,
|
|
4312
|
+
description: instruction,
|
|
4313
|
+
table: options.table || 'incident',
|
|
4314
|
+
trigger_type: options.trigger,
|
|
4315
|
+
trigger_condition: '',
|
|
4316
|
+
activities: activities.length > 0 ? activities : null
|
|
4317
|
+
};
|
|
4318
|
+
// Add default activities if none specified
|
|
4319
|
+
if (!flowDef.activities || flowDef.activities.length === 0) {
|
|
4320
|
+
// Default activities if none specified
|
|
4321
|
+
console.log('โ ๏ธ No specific activities detected, adding default workflow...');
|
|
4322
|
+
flowDef.activities = [
|
|
4323
|
+
{
|
|
4324
|
+
name: 'Log Flow Start',
|
|
4325
|
+
type: 'script',
|
|
4326
|
+
order: 100,
|
|
4327
|
+
inputs: {
|
|
4328
|
+
script: `gs.info('Flow started for: ' + current.number, 'XMLFlow');
|
|
4329
|
+
return { started: true };`
|
|
4330
|
+
},
|
|
4331
|
+
outputs: { started: 'boolean' }
|
|
4332
|
+
},
|
|
4333
|
+
{
|
|
4334
|
+
name: 'Send Notification',
|
|
4335
|
+
type: 'notification',
|
|
4336
|
+
order: 200,
|
|
4337
|
+
inputs: {
|
|
4338
|
+
notification_id: (0, servicenow_id_generator_js_1.getNotificationTemplateSysId)('generic_notification'),
|
|
4339
|
+
recipients: '{{trigger.current.opened_by}}',
|
|
4340
|
+
values: {
|
|
4341
|
+
record_number: '{{trigger.current.number}}',
|
|
4342
|
+
status: 'Flow triggered'
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
];
|
|
4347
|
+
}
|
|
4348
|
+
// Generate XML
|
|
4349
|
+
console.log('\n๐๏ธ Generating production XML...');
|
|
4350
|
+
const result = generateProductionFlowXML(flowDef);
|
|
4351
|
+
console.log(`\nโ
XML Generated Successfully!`);
|
|
4352
|
+
console.log(`๐ File saved to: ${result.filePath}`);
|
|
4353
|
+
console.log(`๐ Flow structure:`);
|
|
4354
|
+
console.log(` - Name: ${flowDef.name}`);
|
|
4355
|
+
console.log(` - Table: ${flowDef.table}`);
|
|
4356
|
+
console.log(` - Trigger: ${flowDef.trigger_type}`);
|
|
4357
|
+
console.log(` - Activities: ${flowDef.activities.length}`);
|
|
4358
|
+
if (options.import) {
|
|
4359
|
+
console.log('\n' + '='.repeat(60));
|
|
4360
|
+
console.log(result.instructions);
|
|
4361
|
+
console.log('='.repeat(60));
|
|
4362
|
+
}
|
|
4363
|
+
console.log('\n๐ฏ Next Steps:');
|
|
4364
|
+
console.log('1. Import the XML file into ServiceNow');
|
|
4365
|
+
console.log('2. Preview the Update Set');
|
|
4366
|
+
console.log('3. Commit the Update Set');
|
|
4367
|
+
console.log('4. Open Flow Designer to see your flow!');
|
|
4368
|
+
// Helper function to map action types
|
|
4369
|
+
function mapActionType(type) {
|
|
4370
|
+
const typeMap = {
|
|
4371
|
+
'email': 'notification',
|
|
4372
|
+
'notify': 'notification',
|
|
4373
|
+
'approve': 'approval',
|
|
4374
|
+
'script': 'script',
|
|
4375
|
+
'create': 'create_record',
|
|
4376
|
+
'update': 'update_record',
|
|
4377
|
+
'rest': 'rest_step',
|
|
4378
|
+
'api': 'rest_step'
|
|
4379
|
+
};
|
|
4380
|
+
return typeMap[type.toLowerCase()] || 'script';
|
|
4381
|
+
}
|
|
4382
|
+
}
|
|
4383
|
+
catch (error) {
|
|
4384
|
+
console.error('โ XML flow generation failed:', error instanceof Error ? error.message : String(error));
|
|
4385
|
+
process.exit(1);
|
|
4386
|
+
}
|
|
4387
|
+
});
|
|
3998
4388
|
// Parse command line arguments
|
|
3999
4389
|
// Init command - initialize a new Snow-Flow project
|
|
4000
4390
|
program
|
|
@@ -4745,7 +5135,7 @@ program
|
|
|
4745
5135
|
console.log(`\n๐ ServiceNow Queen Agent v${version_js_1.VERSION} - Hive-Mind Intelligence`);
|
|
4746
5136
|
console.log('๐ Elegant orchestration replacing complex team coordination\n');
|
|
4747
5137
|
try {
|
|
4748
|
-
const { QueenIntegration } = await Promise.resolve().then(() => __importStar(require('
|
|
5138
|
+
const { QueenIntegration } = await Promise.resolve().then(() => __importStar(require('../examples/queen/integration-example.js')));
|
|
4749
5139
|
const queenIntegration = new QueenIntegration({
|
|
4750
5140
|
debugMode: options.debug || false
|
|
4751
5141
|
});
|