snow-flow 4.5.52 → 4.5.54
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.md +17 -5
- package/dist/cli.js +76 -12
- package/dist/mcp/servicenow-flow-workspace-mobile-mcp.js +194 -31
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -6,14 +6,26 @@
|
|
|
6
6
|
|
|
7
7
|
**❌ INFINITE LOOP (PROHIBITED):**
|
|
8
8
|
```
|
|
9
|
-
Task("
|
|
10
|
-
Task("
|
|
11
|
-
Task("
|
|
9
|
+
Task("UI Builder Tools Tester", "Test UI Builder tools");
|
|
10
|
+
Task("UI Builder Tools Tester", "Test UI Builder tools"); // ← DUPLICATE AGENT TYPE!
|
|
11
|
+
Task("Workspace Tools Tester", "Test workspace tools");
|
|
12
|
+
Task("Workspace Tools Tester", "Test workspace tools"); // ← CAUSES INFINITE LOOP!
|
|
13
|
+
|
|
14
|
+
// This pattern causes MCP server spam:
|
|
15
|
+
// • Task(UI Builder Tools Tester) → snow_validate_uib_page_structure (repeated 100x)
|
|
16
|
+
// • Task(Workspace Tools Tester) → snow_execute_script_with_output (repeated 100x)
|
|
12
17
|
```
|
|
13
18
|
|
|
14
19
|
**✅ CORRECT (Single Agent):**
|
|
15
|
-
```
|
|
16
|
-
|
|
20
|
+
```
|
|
21
|
+
// UNIQUE agent names prevent loops:
|
|
22
|
+
Task("workspace-architect", "Create ONE UX workspace for IT support using snow_create_complete_workspace. Store all sys_ids in Memory.");
|
|
23
|
+
Task("ui-specialist", "Design UI components AFTER workspace-architect completes. Use Memory to get workspace sys_ids.");
|
|
24
|
+
Task("testing-validator", "Test workspace functionality AFTER ui-specialist completes. No duplicate testing!");
|
|
25
|
+
|
|
26
|
+
// NEVER use generic names like:
|
|
27
|
+
// Task("Tester", ...) - TOO GENERIC, CAUSES LOOPS!
|
|
28
|
+
// Task("UI Builder Tools Tester", ...) - EXACTLY what caused the infinite loop!
|
|
17
29
|
```
|
|
18
30
|
|
|
19
31
|
**🎯 Anti-Loop Rules:**
|
package/dist/cli.js
CHANGED
|
@@ -643,6 +643,31 @@ function buildQueenAgentPrompt(objective, taskAnalysis, options, isAuthenticated
|
|
|
643
643
|
options.sharedMemory || options.progressMonitoring;
|
|
644
644
|
const prompt = `# 👑 Snow-Flow Queen Agent Orchestration
|
|
645
645
|
|
|
646
|
+
## 🚨 CRITICAL: PREVENT INFINITE LOOPS - READ FIRST!
|
|
647
|
+
|
|
648
|
+
**NEVER SPAWN DUPLICATE AGENTS!** This causes infinite loops that spam MCP servers and crash Codespaces!
|
|
649
|
+
|
|
650
|
+
**❌ INFINITE LOOP PATTERN (PROHIBITED):**
|
|
651
|
+
\`\`\`
|
|
652
|
+
Task(\"UI Builder Tools Tester\", \"Test UI Builder tools\");
|
|
653
|
+
Task(\"UI Builder Tools Tester\", \"Test UI Builder tools\"); // ← DUPLICATE AGENT TYPE!
|
|
654
|
+
Task(\"Workspace Tools Tester\", \"Test workspace tools\");
|
|
655
|
+
Task(\"Workspace Tools Tester\", \"Test workspace tools\"); // ← INFINITE LOOP!
|
|
656
|
+
\`\`\`
|
|
657
|
+
|
|
658
|
+
**✅ CORRECT PATTERN (REQUIRED):**
|
|
659
|
+
\`\`\`
|
|
660
|
+
Task(\"workspace-architect\", \"Create ONE UX workspace using snow_create_complete_workspace\");
|
|
661
|
+
Task(\"ui-designer\", \"Design UI components AFTER workspace is created\");
|
|
662
|
+
Task(\"validator\", \"Test AFTER both previous agents complete\");
|
|
663
|
+
\`\`\`
|
|
664
|
+
|
|
665
|
+
**GOLDEN RULES:**
|
|
666
|
+
1. **ONE agent per task type maximum**
|
|
667
|
+
2. **UNIQUE agent names** (not generic \"Tester\")
|
|
668
|
+
3. **SEQUENTIAL spawning** - wait for completion
|
|
669
|
+
4. **CHECK Memory** for existing agents first
|
|
670
|
+
|
|
646
671
|
## 🎯 Mission Brief
|
|
647
672
|
You are the Queen Agent, master coordinator of the Snow-Flow hive-mind. Your mission is to orchestrate a swarm of specialized agents to complete the following ServiceNow development objective:
|
|
648
673
|
|
|
@@ -838,29 +863,68 @@ TodoWrite([
|
|
|
838
863
|
]);
|
|
839
864
|
\`\`\`
|
|
840
865
|
|
|
841
|
-
### 4. Agent Spawning Strategy
|
|
842
|
-
|
|
866
|
+
### 4. Agent Spawning Strategy - 🚨 ANTI-LOOP PROTECTION 🚨
|
|
867
|
+
|
|
868
|
+
**CRITICAL: NO DUPLICATE AGENTS! ONLY SPAWN EACH AGENT TYPE ONCE!**
|
|
843
869
|
|
|
844
|
-
|
|
845
|
-
1. **Initialize Swarm**: \`swarm_init({ topology: 'hierarchical', maxAgents: ${parseInt(options.maxAgents)} })\`
|
|
846
|
-
2. **
|
|
847
|
-
|
|
848
|
-
4. **Coordination**: \`task_orchestrate({ task: '${objective}', strategy: 'adaptive' })\`
|
|
870
|
+
**✅ CORRECT (Single Agents Only):**
|
|
871
|
+
1. **Initialize Swarm ONCE**: \`swarm_init({ topology: 'hierarchical', maxAgents: ${parseInt(options.maxAgents)} })\`
|
|
872
|
+
2. **Spawn ${taskAnalysis.estimatedAgentCount} DIFFERENT agents**:
|
|
873
|
+
Spawn ONE agent of each required type based on the objective:
|
|
849
874
|
|
|
850
|
-
|
|
875
|
+
**${taskAnalysis.taskType} requires these UNIQUE agents:**
|
|
876
|
+
- **ONE researcher**: \`Task(\"researcher\", \"Research ServiceNow requirements for: ${objective}\")\`
|
|
877
|
+
- **ONE ${taskAnalysis.primaryAgent}**: \`Task(\"${taskAnalysis.primaryAgent}\", \"Implement main solution for: ${objective}\")\`
|
|
878
|
+
- **ONE tester**: \`Task(\"tester\", \"Test and validate solution for: ${objective}\")\`
|
|
851
879
|
|
|
852
|
-
|
|
853
|
-
|
|
880
|
+
**🚨 CRITICAL ANTI-LOOP RULES:**
|
|
881
|
+
- **NEVER spawn multiple agents of the same type**
|
|
882
|
+
- **NEVER spawn \"UI Builder Tools Tester\" multiple times**
|
|
883
|
+
- **NEVER spawn \"Workspace Tools Tester\" multiple times**
|
|
884
|
+
- **WAIT for agent completion** before spawning related agents
|
|
885
|
+
- **CHECK Memory** for existing agents before spawning new ones
|
|
886
|
+
|
|
887
|
+
**❌ PROHIBITED PATTERNS:**
|
|
888
|
+
\`\`\`
|
|
889
|
+
// DON'T DO THIS - CAUSES INFINITE LOOPS:
|
|
890
|
+
Task(\"UI Builder Tools Tester\", \"Test UI Builder tools\");
|
|
891
|
+
Task(\"UI Builder Tools Tester\", \"Test UI Builder tools\"); // ← DUPLICATE!
|
|
892
|
+
Task(\"UI Builder Tools Tester\", \"Test UI Builder tools\"); // ← INFINITE LOOP!
|
|
893
|
+
\`\`\`
|
|
894
|
+
|
|
895
|
+
**✅ CORRECT PATTERNS:**
|
|
896
|
+
\`\`\`
|
|
897
|
+
// DO THIS - SINGLE AGENTS WITH SPECIFIC TASKS:
|
|
898
|
+
Task(\"ui-builder-specialist\", \"Create specific UI Builder page for incident management\");
|
|
899
|
+
Task(\"workspace-architect\", \"Design UX workspace structure for IT support team\");
|
|
900
|
+
Task(\"testing-specialist\", \"Validate workspace functionality and report results\");
|
|
901
|
+
\`\`\`
|
|
902
|
+
|
|
903
|
+
### 5. Memory Coordination Pattern with Loop Detection
|
|
904
|
+
All agents MUST use this memory coordination WITH loop prevention:
|
|
854
905
|
|
|
855
906
|
\`\`\`javascript
|
|
856
|
-
//
|
|
907
|
+
// STEP 1: Check if agent type already exists (PREVENT LOOPS!)
|
|
908
|
+
const existingAgents = Memory.get('active_agents') || [];
|
|
909
|
+
const agentType = 'ui-builder-specialist';
|
|
910
|
+
|
|
911
|
+
if (existingAgents.includes(agentType)) {
|
|
912
|
+
console.log('Agent type already active - SKIPPING to prevent infinite loop');
|
|
913
|
+
return; // DON'T spawn duplicate agents!
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// STEP 2: Register agent as active
|
|
857
917
|
const agentId = \`agent_\${agentType}_\${sessionId}\`;
|
|
918
|
+
existingAgents.push(agentType);
|
|
919
|
+
Memory.store('active_agents', JSON.stringify(existingAgents));
|
|
858
920
|
|
|
859
|
-
// Agent stores progress
|
|
921
|
+
// STEP 3: Agent stores progress
|
|
860
922
|
Memory.store(\`\${agentId}_progress\`, JSON.stringify({
|
|
923
|
+
agent_type: agentType,
|
|
861
924
|
status: "working",
|
|
862
925
|
current_task: "description of current work",
|
|
863
926
|
completion_percentage: 45,
|
|
927
|
+
spawned_at: new Date().toISOString(),
|
|
864
928
|
last_update: new Date().toISOString()
|
|
865
929
|
}));
|
|
866
930
|
|
|
@@ -140,10 +140,10 @@ class ServiceNowFlowWorkspaceMobileMCP {
|
|
|
140
140
|
}
|
|
141
141
|
},
|
|
142
142
|
// 🏗️ COMPLETE UX WORKSPACE CREATION (6-Step Workflow)
|
|
143
|
-
// STEP 1: Experience Record (sys_ux_experience)
|
|
143
|
+
// STEP 1: Experience Record (sys_ux_experience) - REQUIRES NOW EXPERIENCE FRAMEWORK
|
|
144
144
|
{
|
|
145
145
|
name: 'snow_create_ux_experience',
|
|
146
|
-
description: 'STEP 1: Create UX Experience Record (sys_ux_experience) - The top-level container for the workspace.
|
|
146
|
+
description: 'STEP 1: Create UX Experience Record (sys_ux_experience) - The top-level container for the workspace. ⚠️ REQUIRES: Now Experience Framework (UXF) enabled. ALTERNATIVE: Use traditional form/list configurations if UXF unavailable.',
|
|
147
147
|
inputSchema: {
|
|
148
148
|
type: 'object',
|
|
149
149
|
properties: {
|
|
@@ -357,10 +357,10 @@ class ServiceNowFlowWorkspaceMobileMCP {
|
|
|
357
357
|
// UI BUILDER TOOLS - COMPLETE NOW EXPERIENCE FRAMEWORK INTEGRATION
|
|
358
358
|
// Official ServiceNow sys_ux_* APIs for conversational UI Builder development
|
|
359
359
|
// ==========================================
|
|
360
|
-
// UI Builder Page Management (sys_ux_page)
|
|
360
|
+
// UI Builder Page Management (sys_ux_page) - REQUIRES UI BUILDER PLUGIN
|
|
361
361
|
{
|
|
362
362
|
name: 'snow_create_uib_page',
|
|
363
|
-
description: 'Creates a new UI Builder page in the Now Experience Framework using official ServiceNow sys_ux_page API.
|
|
363
|
+
description: 'Creates a new UI Builder page in the Now Experience Framework using official ServiceNow sys_ux_page API. ⚠️ REQUIRES: UI Builder plugin + ui_builder_admin role. ALTERNATIVE: Use Service Portal pages if plugin unavailable.',
|
|
364
364
|
inputSchema: {
|
|
365
365
|
type: 'object',
|
|
366
366
|
properties: {
|
|
@@ -815,33 +815,33 @@ class ServiceNowFlowWorkspaceMobileMCP {
|
|
|
815
815
|
case 'snow_import_flow_from_xml':
|
|
816
816
|
result = await this.importFlowFromXml(args);
|
|
817
817
|
break;
|
|
818
|
-
// 🏗️ UX WORKSPACE CREATION (
|
|
818
|
+
// 🏗️ UX WORKSPACE CREATION (SAFE EXECUTION)
|
|
819
819
|
case 'snow_create_ux_experience':
|
|
820
|
-
result = await this.snow_create_ux_experience(args);
|
|
820
|
+
result = await this.safeToolExecution('snow_create_ux_experience', () => this.snow_create_ux_experience(args), 'now_experience_framework');
|
|
821
821
|
break;
|
|
822
822
|
case 'snow_create_ux_app_config':
|
|
823
|
-
result = await this.snow_create_ux_app_config(args);
|
|
823
|
+
result = await this.safeToolExecution('snow_create_ux_app_config', () => this.snow_create_ux_app_config(args), 'now_experience_framework');
|
|
824
824
|
break;
|
|
825
825
|
case 'snow_create_ux_page_macroponent':
|
|
826
|
-
result = await this.snow_create_ux_page_macroponent(args);
|
|
826
|
+
result = await this.safeToolExecution('snow_create_ux_page_macroponent', () => this.snow_create_ux_page_macroponent(args), 'now_experience_framework');
|
|
827
827
|
break;
|
|
828
828
|
case 'snow_create_ux_page_registry':
|
|
829
|
-
result = await this.snow_create_ux_page_registry(args);
|
|
829
|
+
result = await this.safeToolExecution('snow_create_ux_page_registry', () => this.snow_create_ux_page_registry(args), 'now_experience_framework');
|
|
830
830
|
break;
|
|
831
831
|
case 'snow_create_ux_app_route':
|
|
832
|
-
result = await this.snow_create_ux_app_route(args);
|
|
832
|
+
result = await this.safeToolExecution('snow_create_ux_app_route', () => this.snow_create_ux_app_route(args), 'now_experience_framework');
|
|
833
833
|
break;
|
|
834
834
|
case 'snow_update_ux_app_config_landing_page':
|
|
835
|
-
result = await this.snow_update_ux_app_config_landing_page(args);
|
|
835
|
+
result = await this.safeToolExecution('snow_update_ux_app_config_landing_page', () => this.snow_update_ux_app_config_landing_page(args), 'now_experience_framework');
|
|
836
836
|
break;
|
|
837
837
|
case 'snow_create_complete_workspace':
|
|
838
|
-
result = await this.snow_create_complete_workspace(args);
|
|
838
|
+
result = await this.safeToolExecution('snow_create_complete_workspace', () => this.snow_create_complete_workspace(args), 'now_experience_framework');
|
|
839
839
|
break;
|
|
840
840
|
case 'snow_create_configurable_agent_workspace':
|
|
841
|
-
result = await this.snow_create_configurable_agent_workspace(args);
|
|
841
|
+
result = await this.safeToolExecution('snow_create_configurable_agent_workspace', () => this.snow_create_configurable_agent_workspace(args), 'agent_workspace');
|
|
842
842
|
break;
|
|
843
843
|
case 'snow_discover_all_workspaces':
|
|
844
|
-
result = await this.discoverAllWorkspaces(args);
|
|
844
|
+
result = await this.safeToolExecution('snow_discover_all_workspaces', () => this.discoverAllWorkspaces(args), 'now_experience_framework');
|
|
845
845
|
break;
|
|
846
846
|
case 'snow_validate_workspace_configuration':
|
|
847
847
|
result = await this.validateWorkspaceConfiguration(args);
|
|
@@ -859,31 +859,31 @@ class ServiceNowFlowWorkspaceMobileMCP {
|
|
|
859
859
|
case 'snow_configure_offline_sync':
|
|
860
860
|
result = await this.configureOfflineSync(args);
|
|
861
861
|
break;
|
|
862
|
-
// UI Builder Page Management
|
|
862
|
+
// UI Builder Page Management (SAFE EXECUTION)
|
|
863
863
|
case 'snow_create_uib_page':
|
|
864
|
-
result = await this.createUIBPage(args);
|
|
864
|
+
result = await this.safeToolExecution('snow_create_uib_page', () => this.createUIBPage(args), 'ui_builder');
|
|
865
865
|
break;
|
|
866
866
|
case 'snow_update_uib_page':
|
|
867
|
-
result = await this.updateUIBPage(args);
|
|
867
|
+
result = await this.safeToolExecution('snow_update_uib_page', () => this.updateUIBPage(args), 'ui_builder');
|
|
868
868
|
break;
|
|
869
869
|
case 'snow_delete_uib_page':
|
|
870
|
-
result = await this.deleteUIBPage(args);
|
|
870
|
+
result = await this.safeToolExecution('snow_delete_uib_page', () => this.deleteUIBPage(args), 'ui_builder');
|
|
871
871
|
break;
|
|
872
872
|
case 'snow_discover_uib_pages':
|
|
873
|
-
result = await this.discoverUIBPages(args);
|
|
873
|
+
result = await this.safeToolExecution('snow_discover_uib_pages', () => this.discoverUIBPages(args), 'ui_builder');
|
|
874
874
|
break;
|
|
875
|
-
// UI Builder Component Management
|
|
875
|
+
// UI Builder Component Management (SAFE EXECUTION)
|
|
876
876
|
case 'snow_create_uib_component':
|
|
877
|
-
result = await this.createUIBComponent(args);
|
|
877
|
+
result = await this.safeToolExecution('snow_create_uib_component', () => this.createUIBComponent(args), 'ui_builder');
|
|
878
878
|
break;
|
|
879
879
|
case 'snow_update_uib_component':
|
|
880
|
-
result = await this.updateUIBComponent(args);
|
|
880
|
+
result = await this.safeToolExecution('snow_update_uib_component', () => this.updateUIBComponent(args), 'ui_builder');
|
|
881
881
|
break;
|
|
882
882
|
case 'snow_discover_uib_components':
|
|
883
|
-
result = await this.discoverUIBComponents(args);
|
|
883
|
+
result = await this.safeToolExecution('snow_discover_uib_components', () => this.discoverUIBComponents(args), 'ui_builder');
|
|
884
884
|
break;
|
|
885
885
|
case 'snow_clone_uib_component':
|
|
886
|
-
result = await this.cloneUIBComponent(args);
|
|
886
|
+
result = await this.safeToolExecution('snow_clone_uib_component', () => this.cloneUIBComponent(args), 'ui_builder');
|
|
887
887
|
break;
|
|
888
888
|
// UI Builder Data Broker Management
|
|
889
889
|
case 'snow_create_uib_data_broker':
|
|
@@ -1809,10 +1809,12 @@ ${configList}${layoutsText}${offlineText}
|
|
|
1809
1809
|
}
|
|
1810
1810
|
}
|
|
1811
1811
|
/**
|
|
1812
|
-
* Discover UI Builder Pages
|
|
1812
|
+
* Discover UI Builder Pages - ENHANCED with mandatory feedback
|
|
1813
1813
|
*/
|
|
1814
1814
|
async discoverUIBPages(args) {
|
|
1815
1815
|
try {
|
|
1816
|
+
// MANDATORY: Always log start of operation
|
|
1817
|
+
this.logger.info(`🔍 Starting UI Builder pages discovery...`);
|
|
1816
1818
|
this.logger.info('🔍 Discovering UI Builder pages...');
|
|
1817
1819
|
const conditions = [];
|
|
1818
1820
|
if (args.active_only)
|
|
@@ -1853,7 +1855,19 @@ ${configList}${layoutsText}${offlineText}
|
|
|
1853
1855
|
}
|
|
1854
1856
|
catch (error) {
|
|
1855
1857
|
this.logger.error('Failed to discover UI Builder pages:', error);
|
|
1856
|
-
throw error
|
|
1858
|
+
// NEVER throw - always return error object for MCP
|
|
1859
|
+
return {
|
|
1860
|
+
success: false,
|
|
1861
|
+
error: `UI Builder pages discovery failed: ${error}`,
|
|
1862
|
+
suggestion: 'UI Builder plugin not installed or insufficient permissions (need ui_builder_admin role)',
|
|
1863
|
+
plugin_required: 'UI Builder',
|
|
1864
|
+
table_attempted: 'sys_ux_page',
|
|
1865
|
+
operation_type: 'DISCOVERY',
|
|
1866
|
+
debug_info: {
|
|
1867
|
+
error_type: error instanceof Error ? error.constructor.name : 'Unknown',
|
|
1868
|
+
error_message: String(error)
|
|
1869
|
+
}
|
|
1870
|
+
};
|
|
1857
1871
|
}
|
|
1858
1872
|
}
|
|
1859
1873
|
/**
|
|
@@ -1869,9 +1883,27 @@ ${configList}${layoutsText}${offlineText}
|
|
|
1869
1883
|
version: args.version || '1.0.0',
|
|
1870
1884
|
active: true
|
|
1871
1885
|
};
|
|
1886
|
+
// PRE-CHECK: Verify UI Builder is available
|
|
1887
|
+
const uiBuilderCheck = await this.client.searchRecords('sys_ux_lib_source_script', '', 1);
|
|
1888
|
+
if (!uiBuilderCheck.success) {
|
|
1889
|
+
return {
|
|
1890
|
+
success: false,
|
|
1891
|
+
error: 'UI Builder plugin not available - sys_ux_lib_source_script table not accessible',
|
|
1892
|
+
suggestion: 'Install UI Builder plugin from ServiceNow Store. Requires ui_builder_admin role.',
|
|
1893
|
+
plugin_required: 'UI Builder',
|
|
1894
|
+
table_tested: 'sys_ux_lib_source_script',
|
|
1895
|
+
alternative: 'Use Service Portal widgets instead of UI Builder components'
|
|
1896
|
+
};
|
|
1897
|
+
}
|
|
1872
1898
|
const sourceResponse = await this.client.createRecord('sys_ux_lib_source_script', sourceData);
|
|
1873
1899
|
if (!sourceResponse.success) {
|
|
1874
|
-
|
|
1900
|
+
return {
|
|
1901
|
+
success: false,
|
|
1902
|
+
error: `Failed to create component source: ${sourceResponse.error}`,
|
|
1903
|
+
suggestion: 'Check UI Builder permissions and source script syntax',
|
|
1904
|
+
operation_attempted: 'CREATE sys_ux_lib_source_script',
|
|
1905
|
+
source_data_attempted: sourceData
|
|
1906
|
+
};
|
|
1875
1907
|
}
|
|
1876
1908
|
// Then create the component definition
|
|
1877
1909
|
const componentData = {
|
|
@@ -1891,8 +1923,18 @@ ${configList}${layoutsText}${offlineText}
|
|
|
1891
1923
|
const componentResponse = await this.client.createRecord('sys_ux_lib_component', componentData);
|
|
1892
1924
|
if (!componentResponse.success) {
|
|
1893
1925
|
// Cleanup source script on failure
|
|
1894
|
-
|
|
1895
|
-
|
|
1926
|
+
const sourceId = sourceResponse.data?.sys_id || sourceResponse.data?.result?.sys_id;
|
|
1927
|
+
if (sourceId) {
|
|
1928
|
+
await this.client.deleteRecord('sys_ux_lib_source_script', sourceId);
|
|
1929
|
+
}
|
|
1930
|
+
return {
|
|
1931
|
+
success: false,
|
|
1932
|
+
error: `Failed to create UI Builder component: ${componentResponse.error}`,
|
|
1933
|
+
suggestion: 'Check UI Builder permissions, component definition syntax, and plugin availability',
|
|
1934
|
+
operation_attempted: 'CREATE sys_ux_lib_component',
|
|
1935
|
+
component_data_attempted: componentData,
|
|
1936
|
+
cleanup_performed: !!sourceId
|
|
1937
|
+
};
|
|
1896
1938
|
}
|
|
1897
1939
|
this.logger.info('✅ UI Builder component created successfully');
|
|
1898
1940
|
return {
|
|
@@ -1957,10 +1999,12 @@ ${configList}${layoutsText}${offlineText}
|
|
|
1957
1999
|
}
|
|
1958
2000
|
}
|
|
1959
2001
|
/**
|
|
1960
|
-
* Discover UI Builder Components
|
|
2002
|
+
* Discover UI Builder Components - ENHANCED with mandatory feedback
|
|
1961
2003
|
*/
|
|
1962
2004
|
async discoverUIBComponents(args) {
|
|
1963
2005
|
try {
|
|
2006
|
+
// MANDATORY: Always log start of operation
|
|
2007
|
+
this.logger.info(`🔍 Starting UI Builder components discovery...`);
|
|
1964
2008
|
this.logger.info('🔍 Discovering UI Builder components...');
|
|
1965
2009
|
const conditions = [];
|
|
1966
2010
|
if (args.category)
|
|
@@ -2004,7 +2048,19 @@ ${configList}${layoutsText}${offlineText}
|
|
|
2004
2048
|
}
|
|
2005
2049
|
catch (error) {
|
|
2006
2050
|
this.logger.error('Failed to discover UI Builder components:', error);
|
|
2007
|
-
throw error
|
|
2051
|
+
// NEVER throw - always return error object for MCP
|
|
2052
|
+
return {
|
|
2053
|
+
success: false,
|
|
2054
|
+
error: `UI Builder components discovery failed: ${error}`,
|
|
2055
|
+
suggestion: 'UI Builder plugin not installed or insufficient permissions (need ui_builder_admin role)',
|
|
2056
|
+
plugin_required: 'UI Builder',
|
|
2057
|
+
table_attempted: 'sys_ux_lib_component',
|
|
2058
|
+
operation_type: 'DISCOVERY',
|
|
2059
|
+
debug_info: {
|
|
2060
|
+
error_type: error instanceof Error ? error.constructor.name : 'Unknown',
|
|
2061
|
+
error_message: String(error)
|
|
2062
|
+
}
|
|
2063
|
+
};
|
|
2008
2064
|
}
|
|
2009
2065
|
}
|
|
2010
2066
|
/**
|
|
@@ -3425,6 +3481,113 @@ ${configList}${layoutsText}${offlineText}
|
|
|
3425
3481
|
/**
|
|
3426
3482
|
* Validate workspace configuration (fix from user feedback)
|
|
3427
3483
|
*/
|
|
3484
|
+
/**
|
|
3485
|
+
* COMPREHENSIVE PLUGIN DETECTION SYSTEM
|
|
3486
|
+
* Checks all required plugins before tool execution
|
|
3487
|
+
*/
|
|
3488
|
+
async checkPluginAvailabilityForTool(toolType) {
|
|
3489
|
+
try {
|
|
3490
|
+
switch (toolType) {
|
|
3491
|
+
case 'ui_builder':
|
|
3492
|
+
const uiBuilderCheck = await this.client.searchRecords('sys_ux_page', '', 1);
|
|
3493
|
+
if (!uiBuilderCheck.success) {
|
|
3494
|
+
return {
|
|
3495
|
+
available: false,
|
|
3496
|
+
error: 'UI Builder plugin not installed or not accessible',
|
|
3497
|
+
suggestion: 'Install UI Builder plugin from ServiceNow Store. Requires ui_builder_admin + ui_builder_user roles.',
|
|
3498
|
+
alternative: 'Use Service Portal widgets for custom UI development instead'
|
|
3499
|
+
};
|
|
3500
|
+
}
|
|
3501
|
+
break;
|
|
3502
|
+
case 'now_experience_framework':
|
|
3503
|
+
const uxfCheck = await this.client.searchRecords('sys_ux_experience', '', 1);
|
|
3504
|
+
if (!uxfCheck.success) {
|
|
3505
|
+
return {
|
|
3506
|
+
available: false,
|
|
3507
|
+
error: 'Now Experience Framework (UXF) not available',
|
|
3508
|
+
suggestion: 'Enable Now Experience Framework in ServiceNow instance. May require additional licensing.',
|
|
3509
|
+
alternative: 'Use traditional ServiceNow interface development instead'
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
break;
|
|
3513
|
+
case 'agent_workspace':
|
|
3514
|
+
const agentWorkspaceCheck = await this.client.searchRecords('sys_ux_screen_type', '', 1);
|
|
3515
|
+
if (!agentWorkspaceCheck.success) {
|
|
3516
|
+
return {
|
|
3517
|
+
available: false,
|
|
3518
|
+
error: 'Agent Workspace plugin not installed',
|
|
3519
|
+
suggestion: 'Install Agent Workspace plugin from ServiceNow Store. Requires workspace_admin role.',
|
|
3520
|
+
alternative: 'Use traditional forms and lists for agent interfaces'
|
|
3521
|
+
};
|
|
3522
|
+
}
|
|
3523
|
+
break;
|
|
3524
|
+
case 'mobile_publishing':
|
|
3525
|
+
const mobileCheck = await this.client.searchRecords('sys_push_notif_msg', '', 1);
|
|
3526
|
+
if (!mobileCheck.success) {
|
|
3527
|
+
return {
|
|
3528
|
+
available: false,
|
|
3529
|
+
error: 'Mobile Publishing plugin not available',
|
|
3530
|
+
suggestion: 'Install Mobile Publishing plugin from ServiceNow Store. Requires additional licensing and mobile_admin role.',
|
|
3531
|
+
alternative: 'Use responsive Service Portal pages for mobile interfaces'
|
|
3532
|
+
};
|
|
3533
|
+
}
|
|
3534
|
+
break;
|
|
3535
|
+
}
|
|
3536
|
+
return { available: true };
|
|
3537
|
+
}
|
|
3538
|
+
catch (error) {
|
|
3539
|
+
return {
|
|
3540
|
+
available: false,
|
|
3541
|
+
error: `Plugin check failed: ${error}`,
|
|
3542
|
+
suggestion: 'Check ServiceNow connectivity and basic table access permissions'
|
|
3543
|
+
};
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
/**
|
|
3547
|
+
* SAFE TOOL EXECUTION WRAPPER
|
|
3548
|
+
* Ensures all tools return proper feedback instead of throwing
|
|
3549
|
+
*/
|
|
3550
|
+
async safeToolExecution(toolName, operation, pluginType) {
|
|
3551
|
+
try {
|
|
3552
|
+
this.logger.info(`🛠️ Executing tool: ${toolName}`);
|
|
3553
|
+
// Step 1: Check plugin availability
|
|
3554
|
+
const pluginCheck = await this.checkPluginAvailabilityForTool(pluginType);
|
|
3555
|
+
if (!pluginCheck.available) {
|
|
3556
|
+
this.logger.warn(`⚠️ Plugin check failed for ${toolName}`);
|
|
3557
|
+
return {
|
|
3558
|
+
success: false,
|
|
3559
|
+
tool_name: toolName,
|
|
3560
|
+
plugin_type: pluginType,
|
|
3561
|
+
...pluginCheck
|
|
3562
|
+
};
|
|
3563
|
+
}
|
|
3564
|
+
// Step 2: Execute operation
|
|
3565
|
+
const result = await operation();
|
|
3566
|
+
this.logger.info(`✅ Tool ${toolName} executed successfully`);
|
|
3567
|
+
return {
|
|
3568
|
+
...result,
|
|
3569
|
+
tool_name: toolName,
|
|
3570
|
+
plugin_verified: true,
|
|
3571
|
+
execution_timestamp: new Date().toISOString()
|
|
3572
|
+
};
|
|
3573
|
+
}
|
|
3574
|
+
catch (error) {
|
|
3575
|
+
this.logger.error(`❌ Tool ${toolName} failed with exception:`, error);
|
|
3576
|
+
// NEVER throw - always return error object
|
|
3577
|
+
return {
|
|
3578
|
+
success: false,
|
|
3579
|
+
tool_name: toolName,
|
|
3580
|
+
error: `Tool execution failed: ${error}`,
|
|
3581
|
+
suggestion: 'Check ServiceNow connectivity, permissions, and plugin installation',
|
|
3582
|
+
execution_type: 'EXCEPTION_CAUGHT',
|
|
3583
|
+
debug_info: {
|
|
3584
|
+
error_type: error instanceof Error ? error.constructor.name : 'Unknown',
|
|
3585
|
+
error_message: String(error),
|
|
3586
|
+
stack_trace: error instanceof Error ? error.stack : undefined
|
|
3587
|
+
}
|
|
3588
|
+
};
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3428
3591
|
validateWorkspaceConfig(config) {
|
|
3429
3592
|
const errors = [];
|
|
3430
3593
|
// Check required fields
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snow-flow",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.54",
|
|
4
4
|
"description": "Conversational ServiceNow development platform using Claude Code. Multi-agent orchestration with 20+ MCP servers providing 245+ ServiceNow tools including complete UX + Agent Workspace creation with official APIs.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "commonjs",
|