snow-flow 1.1.0
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/.env.example +49 -0
- package/.mcp.json +106 -0
- package/.mcp.json.template +106 -0
- package/LICENSE +21 -0
- package/README.md +236 -0
- package/bin/snow-flow +4 -0
- package/bin/snow-flow.js +3 -0
- package/claude-flow +79 -0
- package/claude-flow.bat +18 -0
- package/claude-flow.config.json +20 -0
- package/claude-flow.ps1 +24 -0
- package/dist/agents/app-creator.agent.d.ts +55 -0
- package/dist/agents/app-creator.agent.d.ts.map +1 -0
- package/dist/agents/app-creator.agent.js +1292 -0
- package/dist/agents/app-creator.agent.js.map +1 -0
- package/dist/agents/base-snow-agent.d.ts +63 -0
- package/dist/agents/base-snow-agent.d.ts.map +1 -0
- package/dist/agents/base-snow-agent.js +296 -0
- package/dist/agents/base-snow-agent.js.map +1 -0
- package/dist/agents/script-generator.agent.d.ts +32 -0
- package/dist/agents/script-generator.agent.d.ts.map +1 -0
- package/dist/agents/script-generator.agent.js +772 -0
- package/dist/agents/script-generator.agent.js.map +1 -0
- package/dist/agents/ui-builder.agent.d.ts +50 -0
- package/dist/agents/ui-builder.agent.d.ts.map +1 -0
- package/dist/agents/ui-builder.agent.js +1539 -0
- package/dist/agents/ui-builder.agent.js.map +1 -0
- package/dist/agents/widget-builder.agent.d.ts +32 -0
- package/dist/agents/widget-builder.agent.d.ts.map +1 -0
- package/dist/agents/widget-builder.agent.js +439 -0
- package/dist/agents/widget-builder.agent.js.map +1 -0
- package/dist/agents/workflow-designer.agent.d.ts +31 -0
- package/dist/agents/workflow-designer.agent.d.ts.map +1 -0
- package/dist/agents/workflow-designer.agent.js +583 -0
- package/dist/agents/workflow-designer.agent.js.map +1 -0
- package/dist/api/error-handling.d.ts +214 -0
- package/dist/api/error-handling.d.ts.map +1 -0
- package/dist/api/error-handling.js +594 -0
- package/dist/api/error-handling.js.map +1 -0
- package/dist/api/flow-designer-api.d.ts +167 -0
- package/dist/api/flow-designer-api.d.ts.map +1 -0
- package/dist/api/flow-designer-api.js +555 -0
- package/dist/api/flow-designer-api.js.map +1 -0
- package/dist/api/natural-language-mapper.d.ts +126 -0
- package/dist/api/natural-language-mapper.d.ts.map +1 -0
- package/dist/api/natural-language-mapper.js +498 -0
- package/dist/api/natural-language-mapper.js.map +1 -0
- package/dist/api/performance-optimizer.d.ts +240 -0
- package/dist/api/performance-optimizer.d.ts.map +1 -0
- package/dist/api/performance-optimizer.js +701 -0
- package/dist/api/performance-optimizer.js.map +1 -0
- package/dist/api/transaction-manager.d.ts +189 -0
- package/dist/api/transaction-manager.d.ts.map +1 -0
- package/dist/api/transaction-manager.js +576 -0
- package/dist/api/transaction-manager.js.map +1 -0
- package/dist/cli/deploy-artifact.d.ts +7 -0
- package/dist/cli/deploy-artifact.d.ts.map +1 -0
- package/dist/cli/deploy-artifact.js +279 -0
- package/dist/cli/deploy-artifact.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2057 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/managers/scope-manager.d.ts +75 -0
- package/dist/managers/scope-manager.d.ts.map +1 -0
- package/dist/managers/scope-manager.js +448 -0
- package/dist/managers/scope-manager.js.map +1 -0
- package/dist/mcp/mcp-wrapper.d.ts +8 -0
- package/dist/mcp/mcp-wrapper.d.ts.map +1 -0
- package/dist/mcp/mcp-wrapper.js +77 -0
- package/dist/mcp/mcp-wrapper.js.map +1 -0
- package/dist/mcp/servicenow-automation-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-automation-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-automation-mcp.js +683 -0
- package/dist/mcp/servicenow-automation-mcp.js.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-deployment-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.js +972 -0
- package/dist/mcp/servicenow-deployment-mcp.js.map +1 -0
- package/dist/mcp/servicenow-flow-composer-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-flow-composer-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js +1121 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js.map +1 -0
- package/dist/mcp/servicenow-graph-memory-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-graph-memory-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js +703 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js.map +1 -0
- package/dist/mcp/servicenow-integration-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-integration-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-integration-mcp.js +689 -0
- package/dist/mcp/servicenow-integration-mcp.js.map +1 -0
- package/dist/mcp/servicenow-intelligent-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-intelligent-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-intelligent-mcp.js +1138 -0
- package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -0
- package/dist/mcp/servicenow-mcp-server.d.ts +37 -0
- package/dist/mcp/servicenow-mcp-server.d.ts.map +1 -0
- package/dist/mcp/servicenow-mcp-server.js +648 -0
- package/dist/mcp/servicenow-mcp-server.js.map +1 -0
- package/dist/mcp/servicenow-operations-mcp.d.ts +15 -0
- package/dist/mcp/servicenow-operations-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-operations-mcp.js +1287 -0
- package/dist/mcp/servicenow-operations-mcp.js.map +1 -0
- package/dist/mcp/servicenow-platform-development-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-platform-development-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-platform-development-mcp.js +557 -0
- package/dist/mcp/servicenow-platform-development-mcp.js.map +1 -0
- package/dist/mcp/servicenow-progressive-indexer.d.ts +79 -0
- package/dist/mcp/servicenow-progressive-indexer.d.ts.map +1 -0
- package/dist/mcp/servicenow-progressive-indexer.js +320 -0
- package/dist/mcp/servicenow-progressive-indexer.js.map +1 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.js +888 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.js.map +1 -0
- package/dist/mcp/servicenow-security-compliance-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-security-compliance-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-security-compliance-mcp.js +812 -0
- package/dist/mcp/servicenow-security-compliance-mcp.js.map +1 -0
- package/dist/mcp/servicenow-update-set-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-update-set-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-update-set-mcp.js +599 -0
- package/dist/mcp/servicenow-update-set-mcp.js.map +1 -0
- package/dist/mcp/start-all-mcp-servers.d.ts +6 -0
- package/dist/mcp/start-all-mcp-servers.d.ts.map +1 -0
- package/dist/mcp/start-all-mcp-servers.js +65 -0
- package/dist/mcp/start-all-mcp-servers.js.map +1 -0
- package/dist/mcp/start-servicenow-mcp.d.ts +7 -0
- package/dist/mcp/start-servicenow-mcp.d.ts.map +1 -0
- package/dist/mcp/start-servicenow-mcp.js +64 -0
- package/dist/mcp/start-servicenow-mcp.js.map +1 -0
- package/dist/mcp/test-simple-mcp.d.ts +6 -0
- package/dist/mcp/test-simple-mcp.d.ts.map +1 -0
- package/dist/mcp/test-simple-mcp.js +64 -0
- package/dist/mcp/test-simple-mcp.js.map +1 -0
- package/dist/orchestrator/flow-composer.d.ts +269 -0
- package/dist/orchestrator/flow-composer.d.ts.map +1 -0
- package/dist/orchestrator/flow-composer.js +2221 -0
- package/dist/orchestrator/flow-composer.js.map +1 -0
- package/dist/orchestrator/flow-pattern-templates.d.ts +260 -0
- package/dist/orchestrator/flow-pattern-templates.d.ts.map +1 -0
- package/dist/orchestrator/flow-pattern-templates.js +906 -0
- package/dist/orchestrator/flow-pattern-templates.js.map +1 -0
- package/dist/orchestrator/flow-subflow-decision-engine.d.ts +202 -0
- package/dist/orchestrator/flow-subflow-decision-engine.d.ts.map +1 -0
- package/dist/orchestrator/flow-subflow-decision-engine.js +769 -0
- package/dist/orchestrator/flow-subflow-decision-engine.js.map +1 -0
- package/dist/orchestrator/flow-validation-engine.d.ts +145 -0
- package/dist/orchestrator/flow-validation-engine.d.ts.map +1 -0
- package/dist/orchestrator/flow-validation-engine.js +663 -0
- package/dist/orchestrator/flow-validation-engine.js.map +1 -0
- package/dist/orchestrator/snow-orchestrator.d.ts +49 -0
- package/dist/orchestrator/snow-orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/snow-orchestrator.js +235 -0
- package/dist/orchestrator/snow-orchestrator.js.map +1 -0
- package/dist/orchestrator/subflow-creation-handler.d.ts +230 -0
- package/dist/orchestrator/subflow-creation-handler.d.ts.map +1 -0
- package/dist/orchestrator/subflow-creation-handler.js +791 -0
- package/dist/orchestrator/subflow-creation-handler.js.map +1 -0
- package/dist/strategies/global-scope-strategy.d.ts +123 -0
- package/dist/strategies/global-scope-strategy.d.ts.map +1 -0
- package/dist/strategies/global-scope-strategy.js +585 -0
- package/dist/strategies/global-scope-strategy.js.map +1 -0
- package/dist/types/index.d.ts +138 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/servicenow.types.d.ts +260 -0
- package/dist/types/servicenow.types.d.ts.map +1 -0
- package/dist/types/servicenow.types.js +3 -0
- package/dist/types/servicenow.types.js.map +1 -0
- package/dist/types/snow-flow.types.d.ts +114 -0
- package/dist/types/snow-flow.types.d.ts.map +1 -0
- package/dist/types/snow-flow.types.js +3 -0
- package/dist/types/snow-flow.types.js.map +1 -0
- package/dist/utils/action-type-cache.d.ts +66 -0
- package/dist/utils/action-type-cache.d.ts.map +1 -0
- package/dist/utils/action-type-cache.js +237 -0
- package/dist/utils/action-type-cache.js.map +1 -0
- package/dist/utils/agent-detector.d.ts +35 -0
- package/dist/utils/agent-detector.d.ts.map +1 -0
- package/dist/utils/agent-detector.js +353 -0
- package/dist/utils/agent-detector.js.map +1 -0
- package/dist/utils/flow-api-discovery.d.ts +151 -0
- package/dist/utils/flow-api-discovery.d.ts.map +1 -0
- package/dist/utils/flow-api-discovery.js +440 -0
- package/dist/utils/flow-api-discovery.js.map +1 -0
- package/dist/utils/flow-xml-generator.d.ts +41 -0
- package/dist/utils/flow-xml-generator.d.ts.map +1 -0
- package/dist/utils/flow-xml-generator.js +258 -0
- package/dist/utils/flow-xml-generator.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +51 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mcp-auth-middleware.d.ts +58 -0
- package/dist/utils/mcp-auth-middleware.d.ts.map +1 -0
- package/dist/utils/mcp-auth-middleware.js +227 -0
- package/dist/utils/mcp-auth-middleware.js.map +1 -0
- package/dist/utils/mcp-config-manager.d.ts +126 -0
- package/dist/utils/mcp-config-manager.d.ts.map +1 -0
- package/dist/utils/mcp-config-manager.js +209 -0
- package/dist/utils/mcp-config-manager.js.map +1 -0
- package/dist/utils/mcp-server-manager.d.ts +91 -0
- package/dist/utils/mcp-server-manager.d.ts.map +1 -0
- package/dist/utils/mcp-server-manager.js +338 -0
- package/dist/utils/mcp-server-manager.js.map +1 -0
- package/dist/utils/scope-utils.d.ts +72 -0
- package/dist/utils/scope-utils.d.ts.map +1 -0
- package/dist/utils/scope-utils.js +386 -0
- package/dist/utils/scope-utils.js.map +1 -0
- package/dist/utils/servicenow-client.d.ts +233 -0
- package/dist/utils/servicenow-client.d.ts.map +1 -0
- package/dist/utils/servicenow-client.js +1465 -0
- package/dist/utils/servicenow-client.js.map +1 -0
- package/dist/utils/snow-oauth-old.d.ts +65 -0
- package/dist/utils/snow-oauth-old.d.ts.map +1 -0
- package/dist/utils/snow-oauth-old.js +345 -0
- package/dist/utils/snow-oauth-old.js.map +1 -0
- package/dist/utils/snow-oauth.d.ts +85 -0
- package/dist/utils/snow-oauth.d.ts.map +1 -0
- package/dist/utils/snow-oauth.js +512 -0
- package/dist/utils/snow-oauth.js.map +1 -0
- package/dist/utils/template-engine.d.ts +76 -0
- package/dist/utils/template-engine.d.ts.map +1 -0
- package/dist/utils/template-engine.js +391 -0
- package/dist/utils/template-engine.js.map +1 -0
- package/dist/version.d.ts +35 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +72 -0
- package/dist/version.js.map +1 -0
- package/mcp-wrapper.sh +12 -0
- package/package.json +77 -0
- package/reports/swarm-auto-centralized-1752649029776.json +13 -0
- package/scripts/postinstall.js +30 -0
- package/scripts/setup-mcp.js +89 -0
|
@@ -0,0 +1,1138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* ServiceNow Intelligent MCP Server
|
|
5
|
+
* Natural language processing for ServiceNow artifacts with intelligent indexing
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
9
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
10
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
11
|
+
const servicenow_client_js_1 = require("../utils/servicenow-client.js");
|
|
12
|
+
const mcp_auth_middleware_js_1 = require("../utils/mcp-auth-middleware.js");
|
|
13
|
+
const mcp_config_manager_js_1 = require("../utils/mcp-config-manager.js");
|
|
14
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
15
|
+
const fs_1 = require("fs");
|
|
16
|
+
const path_1 = require("path");
|
|
17
|
+
class ServiceNowIntelligentMCP {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.server = new index_js_1.Server({
|
|
20
|
+
name: 'servicenow-intelligent',
|
|
21
|
+
version: '1.0.0',
|
|
22
|
+
}, {
|
|
23
|
+
capabilities: {
|
|
24
|
+
tools: {},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
this.client = new servicenow_client_js_1.ServiceNowClient();
|
|
28
|
+
this.logger = new logger_js_1.Logger('ServiceNowIntelligentMCP');
|
|
29
|
+
this.config = mcp_config_manager_js_1.mcpConfig.getMemoryConfig();
|
|
30
|
+
this.memoryPath = this.config.path || (0, path_1.join)(process.cwd(), 'memory', 'servicenow_artifacts');
|
|
31
|
+
this.setupHandlers();
|
|
32
|
+
}
|
|
33
|
+
setupHandlers() {
|
|
34
|
+
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
35
|
+
tools: [
|
|
36
|
+
{
|
|
37
|
+
name: 'snow_find_artifact',
|
|
38
|
+
description: 'AUTONOMOUS artifact discovery - finds ServiceNow artifacts using natural language, searches memory first, then ServiceNow. NO MANUAL SEARCH NEEDED.',
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {
|
|
42
|
+
query: { type: 'string', description: 'Natural language query (e.g., "the widget that shows incidents on homepage")' },
|
|
43
|
+
type: { type: 'string', enum: ['widget', 'flow', 'script', 'application', 'any'], description: 'Artifact type filter' },
|
|
44
|
+
},
|
|
45
|
+
required: ['query'],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'snow_edit_artifact',
|
|
50
|
+
description: 'AUTONOMOUS artifact modification - edits ServiceNow artifacts using natural language, handles errors automatically, retries on failure. DIRECT MODIFICATION.',
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: 'object',
|
|
53
|
+
properties: {
|
|
54
|
+
query: { type: 'string', description: 'Natural language edit instruction (e.g., "pas de flow aan met de naam approval request flow en zorg dat er na de approval stap een mailtje naar test@admin.nl wordt gestuurd")' },
|
|
55
|
+
},
|
|
56
|
+
required: ['query'],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'snow_analyze_artifact',
|
|
61
|
+
description: 'AUTONOMOUS deep analysis - intelligently indexes artifacts for optimal Claude understanding, stores in memory for future use. SELF-LEARNING SYSTEM.',
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
sys_id: { type: 'string', description: 'System ID of the artifact' },
|
|
66
|
+
table: { type: 'string', description: 'ServiceNow table name' },
|
|
67
|
+
},
|
|
68
|
+
required: ['sys_id', 'table'],
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'snow_memory_search',
|
|
73
|
+
description: 'Search indexed ServiceNow artifacts in memory',
|
|
74
|
+
inputSchema: {
|
|
75
|
+
type: 'object',
|
|
76
|
+
properties: {
|
|
77
|
+
query: { type: 'string', description: 'Search query' },
|
|
78
|
+
type: { type: 'string', enum: ['widget', 'flow', 'script', 'application'], description: 'Artifact type' },
|
|
79
|
+
},
|
|
80
|
+
required: ['query'],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'snow_comprehensive_search',
|
|
85
|
+
description: 'COMPREHENSIVE multi-table search - searches across all relevant ServiceNow tables for artifacts. Perfect for finding hard-to-locate items.',
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
properties: {
|
|
89
|
+
query: { type: 'string', description: 'Natural language search query' },
|
|
90
|
+
include_inactive: { type: 'boolean', description: 'Include inactive records', default: false },
|
|
91
|
+
},
|
|
92
|
+
required: ['query'],
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
}));
|
|
97
|
+
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
98
|
+
const { name, arguments: args } = request.params;
|
|
99
|
+
try {
|
|
100
|
+
switch (name) {
|
|
101
|
+
case 'snow_find_artifact':
|
|
102
|
+
return await this.findArtifact(args);
|
|
103
|
+
case 'snow_edit_artifact':
|
|
104
|
+
return await this.editArtifact(args);
|
|
105
|
+
case 'snow_analyze_artifact':
|
|
106
|
+
return await this.analyzeArtifact(args);
|
|
107
|
+
case 'snow_memory_search':
|
|
108
|
+
return await this.searchMemory(args);
|
|
109
|
+
case 'snow_comprehensive_search':
|
|
110
|
+
return await this.comprehensiveSearch(args);
|
|
111
|
+
default:
|
|
112
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
this.logger.error(`Tool execution failed: ${name}`, error);
|
|
117
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, error instanceof Error ? error.message : String(error));
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async findArtifact(args) {
|
|
122
|
+
// Check authentication first
|
|
123
|
+
const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
|
|
124
|
+
if (!authResult.success) {
|
|
125
|
+
return {
|
|
126
|
+
content: [
|
|
127
|
+
{
|
|
128
|
+
type: 'text',
|
|
129
|
+
text: authResult.error || 'ā Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
this.logger.info('Finding ServiceNow artifact', { query: args.query });
|
|
136
|
+
// 1. Parse natural language intent
|
|
137
|
+
const intent = await this.parseIntent(args.query);
|
|
138
|
+
// 2. Search in memory first
|
|
139
|
+
const memoryResults = await this.searchInMemory(intent);
|
|
140
|
+
if (memoryResults.length > 0) {
|
|
141
|
+
return {
|
|
142
|
+
content: [
|
|
143
|
+
{
|
|
144
|
+
type: 'text',
|
|
145
|
+
text: `š§ Found in memory:\n\n${this.formatResults(memoryResults)}\n\nš” Using cached intelligent index for optimal performance.`,
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// 3. Search ServiceNow live
|
|
151
|
+
this.logger.info(`Searching ServiceNow for: ${intent.identifier} (type: ${intent.artifactType})`);
|
|
152
|
+
const liveResults = await this.searchServiceNow(intent);
|
|
153
|
+
this.logger.info(`ServiceNow search returned ${liveResults?.length || 0} results`);
|
|
154
|
+
// Debug log
|
|
155
|
+
if (liveResults && liveResults.length > 0) {
|
|
156
|
+
this.logger.info(`First result: ${JSON.stringify(liveResults[0])}`);
|
|
157
|
+
}
|
|
158
|
+
// 4. Index results for future use (only if we have results)
|
|
159
|
+
if (liveResults && liveResults.length > 0) {
|
|
160
|
+
this.logger.info('Indexing found artifacts for future use...');
|
|
161
|
+
for (const result of liveResults) {
|
|
162
|
+
await this.intelligentlyIndex(result);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const instanceInfo = await mcp_auth_middleware_js_1.mcpAuth.getInstanceInfo();
|
|
166
|
+
const resultText = this.formatResults(liveResults);
|
|
167
|
+
this.logger.info(`Formatted result text: ${resultText.substring(0, 200)}...`);
|
|
168
|
+
const editSuggestion = this.generateEditSuggestion(liveResults?.[0]);
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: 'text',
|
|
173
|
+
text: `š ServiceNow Search Results:\n\n${resultText}\n\nš ServiceNow Instance: ${instanceInfo.instance}\n\n${editSuggestion}`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
throw new Error(`Artifact search failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async editArtifact(args) {
|
|
183
|
+
// Check authentication first
|
|
184
|
+
const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
|
|
185
|
+
if (!authResult.success) {
|
|
186
|
+
return {
|
|
187
|
+
content: [
|
|
188
|
+
{
|
|
189
|
+
type: 'text',
|
|
190
|
+
text: authResult.error || 'ā Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
this.logger.info('Editing ServiceNow artifact', { query: args.query });
|
|
197
|
+
// 1. Parse edit instruction
|
|
198
|
+
const editIntent = await this.parseEditIntent(args.query);
|
|
199
|
+
// 2. Find target artifact
|
|
200
|
+
const artifact = await this.findTargetArtifact(editIntent);
|
|
201
|
+
// 3. Analyze modification requirements
|
|
202
|
+
const modification = await this.analyzeModification(editIntent, artifact);
|
|
203
|
+
// 4. Apply intelligent modification
|
|
204
|
+
const editedArtifact = await this.applyModification(artifact, modification);
|
|
205
|
+
// 5. Deploy back to ServiceNow
|
|
206
|
+
const deployResult = await this.deployArtifact(editedArtifact);
|
|
207
|
+
// 6. Update memory with changes
|
|
208
|
+
await this.updateMemoryIndex(editedArtifact, modification);
|
|
209
|
+
const instanceInfo = await mcp_auth_middleware_js_1.mcpAuth.getInstanceInfo();
|
|
210
|
+
return {
|
|
211
|
+
content: [
|
|
212
|
+
{
|
|
213
|
+
type: 'text',
|
|
214
|
+
text: `ā
ServiceNow artifact successfully modified!\n\nšÆ Modification Details:\n- Artifact: ${artifact.name}\n- Type: ${artifact.type}\n- Changes: ${modification.description}\n\nš View in ServiceNow: ${instanceInfo.instance}/nav_to.do?uri=${this.getArtifactUrl(artifact)}\n\nš The artifact has been intelligently indexed and is now available for future natural language queries.`,
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
throw new Error(`Artifact editing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async analyzeArtifact(args) {
|
|
224
|
+
// Check authentication first
|
|
225
|
+
const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
|
|
226
|
+
if (!authResult.success) {
|
|
227
|
+
return {
|
|
228
|
+
content: [
|
|
229
|
+
{
|
|
230
|
+
type: 'text',
|
|
231
|
+
text: authResult.error || 'ā Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
try {
|
|
237
|
+
this.logger.info('Analyzing ServiceNow artifact', { sys_id: args.sys_id });
|
|
238
|
+
// Fetch complete artifact from ServiceNow
|
|
239
|
+
const artifact = await this.client.getRecord(args.table, args.sys_id);
|
|
240
|
+
// Perform intelligent indexing
|
|
241
|
+
const indexedArtifact = await this.intelligentlyIndex(artifact);
|
|
242
|
+
// Store in memory
|
|
243
|
+
await this.storeInMemory(indexedArtifact);
|
|
244
|
+
return {
|
|
245
|
+
content: [
|
|
246
|
+
{
|
|
247
|
+
type: 'text',
|
|
248
|
+
text: `š§ Artifact Analysis Complete!\n\nš Summary:\n${indexedArtifact.claudeSummary}\n\nšļø Structure:\n${JSON.stringify(indexedArtifact.structure, null, 2)}\n\nšÆ Modification Points:\n${indexedArtifact.modificationPoints.map(p => `- ${p.description}`).join('\n')}\n\nš¾ Artifact has been intelligently indexed and stored in memory for future natural language interactions.`,
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
throw new Error(`Artifact analysis failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
async searchMemory(args) {
|
|
258
|
+
try {
|
|
259
|
+
const results = await this.searchInMemory({
|
|
260
|
+
identifier: args.query,
|
|
261
|
+
artifactType: args.type || 'any',
|
|
262
|
+
action: 'find',
|
|
263
|
+
confidence: 0.8
|
|
264
|
+
});
|
|
265
|
+
return {
|
|
266
|
+
content: [
|
|
267
|
+
{
|
|
268
|
+
type: 'text',
|
|
269
|
+
text: `š§ Memory Search Results:\n\n${this.formatMemoryResults(results)}\n\nš” All results are from the intelligent index for instant access.`,
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
throw new Error(`Memory search failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async comprehensiveSearch(args) {
|
|
279
|
+
// Check authentication first
|
|
280
|
+
const authResult = await mcp_auth_middleware_js_1.mcpAuth.ensureAuthenticated();
|
|
281
|
+
if (!authResult.success) {
|
|
282
|
+
return {
|
|
283
|
+
content: [
|
|
284
|
+
{
|
|
285
|
+
type: 'text',
|
|
286
|
+
text: authResult.error || 'ā Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
this.logger.info('Starting comprehensive search', { query: args.query });
|
|
293
|
+
// Define tables to search with their descriptions
|
|
294
|
+
const searchTables = [
|
|
295
|
+
{ name: 'sys_script', desc: 'Business Rules', type: 'business_rule' },
|
|
296
|
+
{ name: 'sys_script_include', desc: 'Script Includes', type: 'script_include' },
|
|
297
|
+
{ name: 'sys_script_client', desc: 'Client Scripts', type: 'client_script' },
|
|
298
|
+
{ name: 'sys_ui_script', desc: 'UI Scripts', type: 'ui_script' },
|
|
299
|
+
{ name: 'sp_widget', desc: 'Service Portal Widgets', type: 'widget' },
|
|
300
|
+
{ name: 'sys_hub_flow', desc: 'Flow Designer Flows', type: 'flow' },
|
|
301
|
+
{ name: 'wf_workflow', desc: 'Workflows', type: 'workflow' },
|
|
302
|
+
{ name: 'sys_ui_action', desc: 'UI Actions', type: 'ui_action' },
|
|
303
|
+
{ name: 'sys_ui_policy', desc: 'UI Policies', type: 'ui_policy' },
|
|
304
|
+
{ name: 'sys_data_policy', desc: 'Data Policies', type: 'data_policy' },
|
|
305
|
+
{ name: 'sys_app_application', desc: 'Applications', type: 'application' },
|
|
306
|
+
{ name: 'sys_db_object', desc: 'Tables', type: 'table' },
|
|
307
|
+
{ name: 'sys_dictionary', desc: 'Dictionary/Fields', type: 'field' },
|
|
308
|
+
{ name: 'sysevent_email_action', desc: 'Notifications', type: 'notification' },
|
|
309
|
+
{ name: 'sys_transform_map', desc: 'Transform Maps', type: 'transform_map' },
|
|
310
|
+
{ name: 'sys_ws_definition', desc: 'REST APIs', type: 'rest_api' },
|
|
311
|
+
];
|
|
312
|
+
const searchString = args.query.trim();
|
|
313
|
+
const allResults = [];
|
|
314
|
+
// Generate multiple search strategies like Claude Code did
|
|
315
|
+
const searchStrategies = [
|
|
316
|
+
{ query: `name=${searchString}`, desc: 'Exact name match' },
|
|
317
|
+
{ query: `nameLIKE${searchString}`, desc: 'Name contains' },
|
|
318
|
+
{ query: `short_descriptionLIKE${searchString}`, desc: 'Description contains' },
|
|
319
|
+
{ query: `nameLIKE${searchString}^ORshort_descriptionLIKE${searchString}`, desc: 'Name or description' },
|
|
320
|
+
];
|
|
321
|
+
// Add wildcard searches if multiple words
|
|
322
|
+
const words = searchString.split(' ').filter((w) => w.length > 2);
|
|
323
|
+
if (words.length > 1) {
|
|
324
|
+
const firstWord = words[0];
|
|
325
|
+
const lastWord = words[words.length - 1];
|
|
326
|
+
searchStrategies.push({
|
|
327
|
+
query: `nameLIKE*${firstWord}*${lastWord}*`,
|
|
328
|
+
desc: 'First and last word match'
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
for (const table of searchTables) {
|
|
332
|
+
this.logger.info(`Searching ${table.desc} (${table.name})...`);
|
|
333
|
+
for (const strategy of searchStrategies) {
|
|
334
|
+
try {
|
|
335
|
+
const activeFilter = args.include_inactive ? '' : '^active=true';
|
|
336
|
+
const fullQuery = `${strategy.query}${activeFilter}^LIMIT5`;
|
|
337
|
+
const results = await this.client.searchRecords(table.name, fullQuery);
|
|
338
|
+
if (results && results.success && results.data.result.length > 0) {
|
|
339
|
+
// Add metadata to results
|
|
340
|
+
const enhancedResults = results.data.result.map((result) => ({
|
|
341
|
+
...result,
|
|
342
|
+
artifact_type: table.type,
|
|
343
|
+
table_name: table.name,
|
|
344
|
+
table_description: table.desc,
|
|
345
|
+
search_strategy: strategy.desc
|
|
346
|
+
}));
|
|
347
|
+
allResults.push(...enhancedResults);
|
|
348
|
+
// Stop searching this table if we found results
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
catch (error) {
|
|
353
|
+
this.logger.warn(`Error searching ${table.name}:`, error);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// Remove duplicates by sys_id
|
|
358
|
+
const uniqueResults = allResults.filter((result, index, self) => index === self.findIndex(r => r.sys_id === result.sys_id));
|
|
359
|
+
const instanceInfo = await mcp_auth_middleware_js_1.mcpAuth.getInstanceInfo();
|
|
360
|
+
const resultText = this.formatComprehensiveResults(uniqueResults);
|
|
361
|
+
return {
|
|
362
|
+
content: [
|
|
363
|
+
{
|
|
364
|
+
type: 'text',
|
|
365
|
+
text: `š Comprehensive ServiceNow Search Results:\n\n${resultText}\n\nš ServiceNow Instance: ${instanceInfo.instance}\n\nš” Searched across ${searchTables.length} table types with multiple strategies.`,
|
|
366
|
+
},
|
|
367
|
+
],
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
throw new Error(`Comprehensive search failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
async parseIntent(query) {
|
|
375
|
+
// Enhanced intent parsing with comprehensive type detection
|
|
376
|
+
const lowercaseQuery = query.toLowerCase();
|
|
377
|
+
let artifactType = 'any'; // Default to searching all types
|
|
378
|
+
// Check for specific artifact types (order matters - most specific first)
|
|
379
|
+
// Service Portal
|
|
380
|
+
if (lowercaseQuery.includes('widget'))
|
|
381
|
+
artifactType = 'widget';
|
|
382
|
+
else if (lowercaseQuery.includes('portal'))
|
|
383
|
+
artifactType = 'portal';
|
|
384
|
+
else if (lowercaseQuery.includes('page') && lowercaseQuery.includes('service'))
|
|
385
|
+
artifactType = 'page';
|
|
386
|
+
else if (lowercaseQuery.includes('theme'))
|
|
387
|
+
artifactType = 'theme';
|
|
388
|
+
// Flow Designer & Workflow
|
|
389
|
+
else if (lowercaseQuery.includes('flow designer') || lowercaseQuery.includes('sys_hub_flow'))
|
|
390
|
+
artifactType = 'flow';
|
|
391
|
+
else if (lowercaseQuery.includes('workflow') && !lowercaseQuery.includes('orchestration'))
|
|
392
|
+
artifactType = 'workflow';
|
|
393
|
+
else if (lowercaseQuery.includes('workflow activity'))
|
|
394
|
+
artifactType = 'workflow_activity';
|
|
395
|
+
else if (lowercaseQuery.includes('flow'))
|
|
396
|
+
artifactType = 'flow';
|
|
397
|
+
// Scripts & Automation (most specific first)
|
|
398
|
+
else if (lowercaseQuery.includes('script include'))
|
|
399
|
+
artifactType = 'script_include';
|
|
400
|
+
else if (lowercaseQuery.includes('business rule'))
|
|
401
|
+
artifactType = 'business_rule';
|
|
402
|
+
else if (lowercaseQuery.includes('client script'))
|
|
403
|
+
artifactType = 'client_script';
|
|
404
|
+
else if (lowercaseQuery.includes('ui script'))
|
|
405
|
+
artifactType = 'ui_script';
|
|
406
|
+
else if (lowercaseQuery.includes('ui action'))
|
|
407
|
+
artifactType = 'ui_action';
|
|
408
|
+
else if (lowercaseQuery.includes('ui policy action'))
|
|
409
|
+
artifactType = 'ui_policy_action';
|
|
410
|
+
else if (lowercaseQuery.includes('ui policy'))
|
|
411
|
+
artifactType = 'ui_policy';
|
|
412
|
+
else if (lowercaseQuery.includes('data policy rule'))
|
|
413
|
+
artifactType = 'data_policy_rule';
|
|
414
|
+
else if (lowercaseQuery.includes('data policy'))
|
|
415
|
+
artifactType = 'data_policy';
|
|
416
|
+
// Applications
|
|
417
|
+
else if (lowercaseQuery.includes('scoped app'))
|
|
418
|
+
artifactType = 'scoped_app';
|
|
419
|
+
else if (lowercaseQuery.includes('application') || lowercaseQuery.includes('app'))
|
|
420
|
+
artifactType = 'application';
|
|
421
|
+
// Tables & Fields
|
|
422
|
+
else if (lowercaseQuery.includes('field') || lowercaseQuery.includes('dictionary'))
|
|
423
|
+
artifactType = 'field';
|
|
424
|
+
else if (lowercaseQuery.includes('table'))
|
|
425
|
+
artifactType = 'table';
|
|
426
|
+
// Forms & UI
|
|
427
|
+
else if (lowercaseQuery.includes('form section'))
|
|
428
|
+
artifactType = 'form_section';
|
|
429
|
+
else if (lowercaseQuery.includes('list control'))
|
|
430
|
+
artifactType = 'list_control';
|
|
431
|
+
else if (lowercaseQuery.includes('related list'))
|
|
432
|
+
artifactType = 'related_list';
|
|
433
|
+
else if (lowercaseQuery.includes('form'))
|
|
434
|
+
artifactType = 'form';
|
|
435
|
+
else if (lowercaseQuery.includes('list'))
|
|
436
|
+
artifactType = 'list';
|
|
437
|
+
else if (lowercaseQuery.includes('view'))
|
|
438
|
+
artifactType = 'view';
|
|
439
|
+
else if (lowercaseQuery.includes('formatter'))
|
|
440
|
+
artifactType = 'formatter';
|
|
441
|
+
// Reports & Dashboards
|
|
442
|
+
else if (lowercaseQuery.includes('pa dashboard'))
|
|
443
|
+
artifactType = 'pa_dashboard';
|
|
444
|
+
else if (lowercaseQuery.includes('pa widget'))
|
|
445
|
+
artifactType = 'pa_widget';
|
|
446
|
+
else if (lowercaseQuery.includes('dashboard'))
|
|
447
|
+
artifactType = 'dashboard';
|
|
448
|
+
else if (lowercaseQuery.includes('report'))
|
|
449
|
+
artifactType = 'report';
|
|
450
|
+
else if (lowercaseQuery.includes('gauge'))
|
|
451
|
+
artifactType = 'gauge';
|
|
452
|
+
else if (lowercaseQuery.includes('chart'))
|
|
453
|
+
artifactType = 'chart';
|
|
454
|
+
else if (lowercaseQuery.includes('indicator'))
|
|
455
|
+
artifactType = 'indicator';
|
|
456
|
+
// Security & Access Control
|
|
457
|
+
else if (lowercaseQuery.includes('acl') || lowercaseQuery.includes('access control'))
|
|
458
|
+
artifactType = 'acl';
|
|
459
|
+
else if (lowercaseQuery.includes('role'))
|
|
460
|
+
artifactType = 'role';
|
|
461
|
+
else if (lowercaseQuery.includes('group'))
|
|
462
|
+
artifactType = 'group';
|
|
463
|
+
// Notifications & Communication
|
|
464
|
+
else if (lowercaseQuery.includes('email template'))
|
|
465
|
+
artifactType = 'email_template';
|
|
466
|
+
else if (lowercaseQuery.includes('notification'))
|
|
467
|
+
artifactType = 'notification';
|
|
468
|
+
// Import & Export
|
|
469
|
+
else if (lowercaseQuery.includes('import set'))
|
|
470
|
+
artifactType = 'import_set';
|
|
471
|
+
else if (lowercaseQuery.includes('transform map'))
|
|
472
|
+
artifactType = 'transform_map';
|
|
473
|
+
// Web Services
|
|
474
|
+
else if (lowercaseQuery.includes('rest api') || lowercaseQuery.includes('rest'))
|
|
475
|
+
artifactType = 'rest_api';
|
|
476
|
+
else if (lowercaseQuery.includes('soap api') || lowercaseQuery.includes('soap'))
|
|
477
|
+
artifactType = 'soap_api';
|
|
478
|
+
// Scheduled Jobs
|
|
479
|
+
else if (lowercaseQuery.includes('scheduled job'))
|
|
480
|
+
artifactType = 'scheduled_job';
|
|
481
|
+
else if (lowercaseQuery.includes('scheduled import'))
|
|
482
|
+
artifactType = 'scheduled_import';
|
|
483
|
+
// Knowledge Management
|
|
484
|
+
else if (lowercaseQuery.includes('knowledge base'))
|
|
485
|
+
artifactType = 'knowledge_base';
|
|
486
|
+
else if (lowercaseQuery.includes('knowledge article') || lowercaseQuery.includes('knowledge'))
|
|
487
|
+
artifactType = 'knowledge_article';
|
|
488
|
+
// System Administration
|
|
489
|
+
else if (lowercaseQuery.includes('system property') || lowercaseQuery.includes('property'))
|
|
490
|
+
artifactType = 'property';
|
|
491
|
+
// Mobile
|
|
492
|
+
else if (lowercaseQuery.includes('mobile app') || lowercaseQuery.includes('mobile'))
|
|
493
|
+
artifactType = 'mobile_app';
|
|
494
|
+
// Catalog
|
|
495
|
+
else if (lowercaseQuery.includes('catalog item'))
|
|
496
|
+
artifactType = 'catalog_item';
|
|
497
|
+
else if (lowercaseQuery.includes('catalog variable'))
|
|
498
|
+
artifactType = 'catalog_variable';
|
|
499
|
+
else if (lowercaseQuery.includes('catalog'))
|
|
500
|
+
artifactType = 'catalog';
|
|
501
|
+
// SLA & Metrics
|
|
502
|
+
else if (lowercaseQuery.includes('sla'))
|
|
503
|
+
artifactType = 'sla';
|
|
504
|
+
else if (lowercaseQuery.includes('metric'))
|
|
505
|
+
artifactType = 'metric';
|
|
506
|
+
// Other common types
|
|
507
|
+
else if (lowercaseQuery.includes('attachment'))
|
|
508
|
+
artifactType = 'attachment';
|
|
509
|
+
else if (lowercaseQuery.includes('language'))
|
|
510
|
+
artifactType = 'language';
|
|
511
|
+
else if (lowercaseQuery.includes('translation'))
|
|
512
|
+
artifactType = 'translated_text';
|
|
513
|
+
else if (lowercaseQuery.includes('processor'))
|
|
514
|
+
artifactType = 'processor';
|
|
515
|
+
else if (lowercaseQuery.includes('update set'))
|
|
516
|
+
artifactType = 'update_set';
|
|
517
|
+
else if (lowercaseQuery.includes('ml model') || lowercaseQuery.includes('machine learning'))
|
|
518
|
+
artifactType = 'ml_model';
|
|
519
|
+
else if (lowercaseQuery.includes('spoke'))
|
|
520
|
+
artifactType = 'spoke';
|
|
521
|
+
else if (lowercaseQuery.includes('connection'))
|
|
522
|
+
artifactType = 'connection';
|
|
523
|
+
else if (lowercaseQuery.includes('virtual agent') || lowercaseQuery.includes('chatbot'))
|
|
524
|
+
artifactType = 'virtual_agent';
|
|
525
|
+
else if (lowercaseQuery.includes('event rule'))
|
|
526
|
+
artifactType = 'event_rule';
|
|
527
|
+
else if (lowercaseQuery.includes('alert'))
|
|
528
|
+
artifactType = 'alert';
|
|
529
|
+
else if (lowercaseQuery.includes('discovery'))
|
|
530
|
+
artifactType = 'discovery_schedule';
|
|
531
|
+
else if (lowercaseQuery.includes('ci class'))
|
|
532
|
+
artifactType = 'ci_class';
|
|
533
|
+
else if (lowercaseQuery.includes('relationship'))
|
|
534
|
+
artifactType = 'relationship_type';
|
|
535
|
+
else if (lowercaseQuery.includes('service map'))
|
|
536
|
+
artifactType = 'service_map';
|
|
537
|
+
else if (lowercaseQuery.includes('orchestration workflow'))
|
|
538
|
+
artifactType = 'orchestration_workflow';
|
|
539
|
+
else if (lowercaseQuery.includes('pipeline'))
|
|
540
|
+
artifactType = 'pipeline';
|
|
541
|
+
else if (lowercaseQuery.includes('deployment'))
|
|
542
|
+
artifactType = 'deployment';
|
|
543
|
+
// Generic fallbacks
|
|
544
|
+
else if (lowercaseQuery.includes('script'))
|
|
545
|
+
artifactType = 'script_include';
|
|
546
|
+
return {
|
|
547
|
+
action: 'find',
|
|
548
|
+
artifactType,
|
|
549
|
+
identifier: query,
|
|
550
|
+
confidence: 0.9,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
async parseEditIntent(query) {
|
|
554
|
+
// Parse edit instructions - would be more sophisticated in real implementation
|
|
555
|
+
const intent = await this.parseIntent(query);
|
|
556
|
+
return {
|
|
557
|
+
...intent,
|
|
558
|
+
action: 'edit',
|
|
559
|
+
modification: query,
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
async searchServiceNow(intent) {
|
|
563
|
+
try {
|
|
564
|
+
const tableMapping = {
|
|
565
|
+
// Service Portal
|
|
566
|
+
widget: 'sp_widget',
|
|
567
|
+
portal: 'sp_portal',
|
|
568
|
+
page: 'sp_page',
|
|
569
|
+
theme: 'sp_theme',
|
|
570
|
+
// Flow Designer & Workflow
|
|
571
|
+
flow: 'sys_hub_flow',
|
|
572
|
+
workflow: 'wf_workflow',
|
|
573
|
+
workflow_activity: 'wf_activity',
|
|
574
|
+
// Scripts & Automation
|
|
575
|
+
script_include: 'sys_script_include',
|
|
576
|
+
script: 'sys_script_include',
|
|
577
|
+
business_rule: 'sys_script',
|
|
578
|
+
client_script: 'sys_script_client',
|
|
579
|
+
ui_script: 'sys_ui_script',
|
|
580
|
+
ui_action: 'sys_ui_action',
|
|
581
|
+
ui_policy: 'sys_ui_policy',
|
|
582
|
+
ui_policy_action: 'sys_ui_policy_action',
|
|
583
|
+
data_policy: 'sys_data_policy',
|
|
584
|
+
data_policy_rule: 'sys_data_policy_rule',
|
|
585
|
+
// Applications & Scoped Apps
|
|
586
|
+
application: 'sys_app_application',
|
|
587
|
+
app: 'sys_app_application',
|
|
588
|
+
scoped_app: 'sys_app',
|
|
589
|
+
// Tables & Fields
|
|
590
|
+
table: 'sys_db_object',
|
|
591
|
+
field: 'sys_dictionary',
|
|
592
|
+
dictionary: 'sys_dictionary',
|
|
593
|
+
// Forms & UI
|
|
594
|
+
form: 'sys_form',
|
|
595
|
+
form_section: 'sys_form_section',
|
|
596
|
+
list: 'sys_list',
|
|
597
|
+
list_control: 'sys_list_control',
|
|
598
|
+
view: 'sys_ui_view',
|
|
599
|
+
related_list: 'sys_ui_related_list',
|
|
600
|
+
formatter: 'sys_ui_formatter',
|
|
601
|
+
// Reports & Dashboards
|
|
602
|
+
report: 'sys_report',
|
|
603
|
+
dashboard: 'sys_dashboard',
|
|
604
|
+
gauge: 'pa_dashboards',
|
|
605
|
+
chart: 'sys_chart',
|
|
606
|
+
// Security & Access Control
|
|
607
|
+
acl: 'sys_security_acl',
|
|
608
|
+
role: 'sys_user_role',
|
|
609
|
+
group: 'sys_user_group',
|
|
610
|
+
// Notifications & Communication
|
|
611
|
+
notification: 'sysevent_email_action',
|
|
612
|
+
email_template: 'sysevent_email_template',
|
|
613
|
+
// Import & Export
|
|
614
|
+
import_set: 'sys_import_set',
|
|
615
|
+
transform_map: 'sys_transform_map',
|
|
616
|
+
// Web Services
|
|
617
|
+
rest_api: 'sys_ws_definition',
|
|
618
|
+
soap_api: 'sys_web_service',
|
|
619
|
+
// Scheduled Jobs
|
|
620
|
+
scheduled_job: 'sysauto_script',
|
|
621
|
+
scheduled_import: 'scheduled_import_set',
|
|
622
|
+
// Knowledge Management
|
|
623
|
+
knowledge_base: 'kb_knowledge_base',
|
|
624
|
+
knowledge_article: 'kb_knowledge',
|
|
625
|
+
// System Administration
|
|
626
|
+
property: 'sys_properties',
|
|
627
|
+
system_property: 'sys_properties',
|
|
628
|
+
// Mobile
|
|
629
|
+
mobile_app: 'sys_mobile_application',
|
|
630
|
+
// Catalog
|
|
631
|
+
catalog: 'sc_catalog',
|
|
632
|
+
catalog_item: 'sc_cat_item',
|
|
633
|
+
catalog_variable: 'item_option_new',
|
|
634
|
+
// SLA & Metrics
|
|
635
|
+
sla: 'contract_sla',
|
|
636
|
+
metric: 'sys_report_color',
|
|
637
|
+
// Attachments & Files
|
|
638
|
+
attachment: 'sys_attachment',
|
|
639
|
+
// Languages & Translations
|
|
640
|
+
language: 'sys_language',
|
|
641
|
+
translated_text: 'sys_translated',
|
|
642
|
+
// Processors & Servlets
|
|
643
|
+
processor: 'sys_processor',
|
|
644
|
+
// Update Sets & Deployment
|
|
645
|
+
update_set: 'sys_update_set',
|
|
646
|
+
// AI & ML
|
|
647
|
+
ml_model: 'ml_model',
|
|
648
|
+
// Integration Hub
|
|
649
|
+
spoke: 'sys_hub_action_type',
|
|
650
|
+
connection: 'sys_connection',
|
|
651
|
+
// Virtual Agent
|
|
652
|
+
virtual_agent: 'sys_cs_topic',
|
|
653
|
+
chatbot: 'sys_cs_topic',
|
|
654
|
+
// Performance Analytics
|
|
655
|
+
pa_dashboard: 'pa_dashboards',
|
|
656
|
+
pa_widget: 'pa_widgets',
|
|
657
|
+
indicator: 'pa_indicators',
|
|
658
|
+
// Event Management
|
|
659
|
+
event_rule: 'em_event_rule',
|
|
660
|
+
alert: 'em_alert',
|
|
661
|
+
// Discovery
|
|
662
|
+
discovery_schedule: 'discovery_schedule',
|
|
663
|
+
// CMDB
|
|
664
|
+
ci_class: 'sys_db_object',
|
|
665
|
+
relationship_type: 'cmdb_rel_type',
|
|
666
|
+
// Service Mapping
|
|
667
|
+
service_map: 'sa_pattern',
|
|
668
|
+
// Orchestration
|
|
669
|
+
orchestration_workflow: 'sc_ic_workflow',
|
|
670
|
+
// DevOps
|
|
671
|
+
pipeline: 'cicd_pipeline',
|
|
672
|
+
deployment: 'cicd_deployment',
|
|
673
|
+
};
|
|
674
|
+
// If searching for 'any' type, search only the most common tables
|
|
675
|
+
if (intent.artifactType === 'any') {
|
|
676
|
+
this.logger.info('Searching common artifact types...');
|
|
677
|
+
const allResults = [];
|
|
678
|
+
// Handle "list all" queries for any type
|
|
679
|
+
const searchString = intent.identifier.trim();
|
|
680
|
+
if (searchString.toLowerCase().includes('list all') ||
|
|
681
|
+
searchString.toLowerCase().includes('all artifacts') ||
|
|
682
|
+
searchString.toLowerCase().includes('show all') ||
|
|
683
|
+
searchString === '') {
|
|
684
|
+
this.logger.info('Fetching all common artifact types');
|
|
685
|
+
// Define most common tables to list when showing all
|
|
686
|
+
const commonTables = {
|
|
687
|
+
widget: 'sp_widget',
|
|
688
|
+
business_rule: 'sys_script',
|
|
689
|
+
client_script: 'sys_script_client',
|
|
690
|
+
script_include: 'sys_script_include',
|
|
691
|
+
flow: 'sys_hub_flow',
|
|
692
|
+
workflow: 'wf_workflow',
|
|
693
|
+
ui_action: 'sys_ui_action',
|
|
694
|
+
table: 'sys_db_object',
|
|
695
|
+
application: 'sys_app_application',
|
|
696
|
+
};
|
|
697
|
+
for (const [type, table] of Object.entries(commonTables)) {
|
|
698
|
+
try {
|
|
699
|
+
const results = await this.client.searchRecords(table, `active=true^ORDERBYname^LIMIT10`);
|
|
700
|
+
if (results && results.success && results.data.result.length > 0) {
|
|
701
|
+
const typedResults = results.data.result.map((result) => ({
|
|
702
|
+
...result,
|
|
703
|
+
artifact_type: type,
|
|
704
|
+
table_name: table
|
|
705
|
+
}));
|
|
706
|
+
allResults.push(...typedResults);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
catch (error) {
|
|
710
|
+
this.logger.warn(`Error fetching ${table}:`, error);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return allResults;
|
|
714
|
+
}
|
|
715
|
+
// Define most common tables to search when type is 'any'
|
|
716
|
+
const commonTables = {
|
|
717
|
+
widget: 'sp_widget',
|
|
718
|
+
business_rule: 'sys_script',
|
|
719
|
+
client_script: 'sys_script_client',
|
|
720
|
+
script_include: 'sys_script_include',
|
|
721
|
+
flow: 'sys_hub_flow',
|
|
722
|
+
workflow: 'wf_workflow',
|
|
723
|
+
ui_action: 'sys_ui_action',
|
|
724
|
+
table: 'sys_db_object',
|
|
725
|
+
application: 'sys_app_application',
|
|
726
|
+
};
|
|
727
|
+
for (const [type, table] of Object.entries(commonTables)) {
|
|
728
|
+
try {
|
|
729
|
+
// Try exact match first for each table
|
|
730
|
+
const searchString = intent.identifier.trim();
|
|
731
|
+
let results = await this.client.searchRecords(table, `name=${searchString}^LIMIT2`);
|
|
732
|
+
// If no exact match, try contains
|
|
733
|
+
if (!results || !results.success || results.data.result.length === 0) {
|
|
734
|
+
results = await this.client.searchRecords(table, `nameLIKE${searchString}^LIMIT3`);
|
|
735
|
+
}
|
|
736
|
+
// If still no results, try wildcards on first term only
|
|
737
|
+
if (!results || !results.success || results.data.result.length === 0) {
|
|
738
|
+
const firstTerm = searchString.split(' ')[0];
|
|
739
|
+
if (firstTerm && firstTerm.length > 2) {
|
|
740
|
+
results = await this.client.searchRecords(table, `nameLIKE*${firstTerm}*^LIMIT3`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
if (results && results.success && results.data.result.length > 0) {
|
|
744
|
+
// Add artifact type to results for identification
|
|
745
|
+
const typedResults = results.data.result.map((result) => ({
|
|
746
|
+
...result,
|
|
747
|
+
artifact_type: type,
|
|
748
|
+
table_name: table
|
|
749
|
+
}));
|
|
750
|
+
allResults.push(...typedResults);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
catch (error) {
|
|
754
|
+
this.logger.warn(`Error searching ${table}:`, error);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
// If still no results, try broader search in common tables only
|
|
758
|
+
if (allResults.length === 0) {
|
|
759
|
+
this.logger.info('No results found, trying broader search in common tables...');
|
|
760
|
+
const firstTerm = intent.identifier.split(' ')[0];
|
|
761
|
+
if (firstTerm && firstTerm.length > 2) {
|
|
762
|
+
for (const [type, table] of Object.entries(commonTables)) {
|
|
763
|
+
try {
|
|
764
|
+
const broadQuery = `(nameLIKE*${firstTerm}*^ORtitleLIKE*${firstTerm}*^ORshort_descriptionLIKE*${firstTerm}*)^LIMIT5`;
|
|
765
|
+
const results = await this.client.searchRecords(table, broadQuery, 5);
|
|
766
|
+
if (results && results.success && results.data.result.length > 0) {
|
|
767
|
+
const typedResults = results.data.result.map((result) => ({
|
|
768
|
+
...result,
|
|
769
|
+
artifact_type: type,
|
|
770
|
+
table_name: table
|
|
771
|
+
}));
|
|
772
|
+
allResults.push(...typedResults);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
catch (error) {
|
|
776
|
+
this.logger.warn(`Error in broad search ${table}:`, error);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return allResults;
|
|
782
|
+
}
|
|
783
|
+
// Search specific table
|
|
784
|
+
const table = tableMapping[intent.artifactType];
|
|
785
|
+
if (!table) {
|
|
786
|
+
this.logger.warn(`Unknown artifact type: ${intent.artifactType}`);
|
|
787
|
+
return [];
|
|
788
|
+
}
|
|
789
|
+
// First try exact match
|
|
790
|
+
const searchString = intent.identifier.trim();
|
|
791
|
+
let results;
|
|
792
|
+
// Handle "list all" queries
|
|
793
|
+
if (searchString.toLowerCase().includes('list all') ||
|
|
794
|
+
searchString.toLowerCase().includes('all flows') ||
|
|
795
|
+
searchString.toLowerCase().includes('show all') ||
|
|
796
|
+
searchString === '') {
|
|
797
|
+
this.logger.info(`Fetching all ${intent.artifactType} records`);
|
|
798
|
+
// Get all active records of this type, sorted by name
|
|
799
|
+
results = await this.client.searchRecords(table, `active=true^ORDERBYname^LIMIT50`);
|
|
800
|
+
// Add artifact type to results
|
|
801
|
+
if (results && results.success && results.data.result.length > 0) {
|
|
802
|
+
const enhancedResults = results.data.result.map((result) => ({
|
|
803
|
+
...result,
|
|
804
|
+
artifact_type: intent.artifactType,
|
|
805
|
+
table_name: table
|
|
806
|
+
}));
|
|
807
|
+
return enhancedResults;
|
|
808
|
+
}
|
|
809
|
+
return [];
|
|
810
|
+
}
|
|
811
|
+
// Try exact name match first
|
|
812
|
+
this.logger.info(`Trying exact match: name=${searchString}`);
|
|
813
|
+
results = await this.client.searchRecords(table, `name=${searchString}^LIMIT5`);
|
|
814
|
+
// If no exact match, try contains without wildcards (ServiceNow specific)
|
|
815
|
+
if (!results || !results.success || results.data.result.length === 0) {
|
|
816
|
+
this.logger.info(`No exact match, trying contains: nameLIKE${searchString}`);
|
|
817
|
+
results = await this.client.searchRecords(table, `nameLIKE${searchString}^LIMIT10`);
|
|
818
|
+
}
|
|
819
|
+
// Also try description fields
|
|
820
|
+
if (!results || !results.success || results.data.result.length === 0) {
|
|
821
|
+
this.logger.info(`No name match, trying description: short_descriptionLIKE${searchString}`);
|
|
822
|
+
results = await this.client.searchRecords(table, `short_descriptionLIKE${searchString}^ORdescriptionLIKE${searchString}^LIMIT10`);
|
|
823
|
+
}
|
|
824
|
+
// If still no results, use the complex query
|
|
825
|
+
if (!results || !results.success || results.data.result.length === 0) {
|
|
826
|
+
const query = this.buildServiceNowQuery(intent);
|
|
827
|
+
this.logger.info(`No contains match, trying complex query: ${query}`);
|
|
828
|
+
results = await this.client.searchRecords(table, query);
|
|
829
|
+
}
|
|
830
|
+
// If still no results, try a broader search
|
|
831
|
+
if (!results || !results.success || results.data.result.length === 0) {
|
|
832
|
+
this.logger.info(`No results found, trying broader search...`);
|
|
833
|
+
// Try searching with just the first search term with wildcards
|
|
834
|
+
const firstTerm = intent.identifier.split(' ')[0];
|
|
835
|
+
if (firstTerm && firstTerm.length > 2) {
|
|
836
|
+
const broadQuery = `(nameLIKE*${firstTerm}*^ORtitleLIKE*${firstTerm}*^ORshort_descriptionLIKE*${firstTerm}*)^LIMIT10`;
|
|
837
|
+
results = await this.client.searchRecords(table, broadQuery);
|
|
838
|
+
}
|
|
839
|
+
// If still no results, return empty array instead of sample records
|
|
840
|
+
if (!results || !results.success || results.data.result.length === 0) {
|
|
841
|
+
this.logger.info(`No results found for search term: ${searchString}`);
|
|
842
|
+
return [];
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
// Ensure we always return an array
|
|
846
|
+
return (results && results.success && results.data.result) ? results.data.result : [];
|
|
847
|
+
}
|
|
848
|
+
catch (error) {
|
|
849
|
+
this.logger.error('Error searching ServiceNow', error);
|
|
850
|
+
return [];
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
buildServiceNowQuery(intent) {
|
|
854
|
+
// Build proper ServiceNow encoded query
|
|
855
|
+
const searchString = intent.identifier.trim();
|
|
856
|
+
if (searchString.length === 0) {
|
|
857
|
+
// Return first 10 active records if no search terms
|
|
858
|
+
return 'active=true^LIMIT10';
|
|
859
|
+
}
|
|
860
|
+
// First try exact name match
|
|
861
|
+
const exactQuery = `name=${searchString}`;
|
|
862
|
+
// Then try name contains (without wildcards for multi-word)
|
|
863
|
+
const containsQuery = `nameLIKE${searchString}`;
|
|
864
|
+
// For single words, use wildcards (keep original case for better matching)
|
|
865
|
+
const searchTerms = searchString.split(' ').filter(term => term.length > 1);
|
|
866
|
+
const wildcardQueries = [];
|
|
867
|
+
if (searchTerms.length === 1) {
|
|
868
|
+
// Single word - use wildcards with both cases
|
|
869
|
+
const term = searchTerms[0];
|
|
870
|
+
const termLower = term.toLowerCase();
|
|
871
|
+
wildcardQueries.push(`nameLIKE*${term}*`);
|
|
872
|
+
wildcardQueries.push(`nameLIKE*${termLower}*`);
|
|
873
|
+
wildcardQueries.push(`titleLIKE*${term}*`);
|
|
874
|
+
wildcardQueries.push(`titleLIKE*${termLower}*`);
|
|
875
|
+
wildcardQueries.push(`short_descriptionLIKE*${termLower}*`);
|
|
876
|
+
}
|
|
877
|
+
else {
|
|
878
|
+
// Multiple words - search for first and last word with wildcards
|
|
879
|
+
const firstTerm = searchTerms[0];
|
|
880
|
+
const lastTerm = searchTerms[searchTerms.length - 1];
|
|
881
|
+
const firstLower = firstTerm.toLowerCase();
|
|
882
|
+
const lastLower = lastTerm.toLowerCase();
|
|
883
|
+
wildcardQueries.push(`nameLIKE*${firstTerm}*`);
|
|
884
|
+
wildcardQueries.push(`nameLIKE*${firstLower}*`);
|
|
885
|
+
wildcardQueries.push(`nameLIKE*${lastTerm}*`);
|
|
886
|
+
wildcardQueries.push(`nameLIKE*${lastLower}*`);
|
|
887
|
+
wildcardQueries.push(`titleLIKE*${firstTerm}*`);
|
|
888
|
+
wildcardQueries.push(`titleLIKE*${lastTerm}*`);
|
|
889
|
+
}
|
|
890
|
+
// Combine queries: try exact match OR contains OR wildcards
|
|
891
|
+
const allQueries = [exactQuery, containsQuery, ...wildcardQueries];
|
|
892
|
+
const query = `(${allQueries.join('^OR')})^LIMIT20`;
|
|
893
|
+
return query;
|
|
894
|
+
}
|
|
895
|
+
async intelligentlyIndex(artifact) {
|
|
896
|
+
// Intelligent indexing based on artifact type
|
|
897
|
+
const structure = await this.decomposeArtifact(artifact);
|
|
898
|
+
const context = await this.extractContext(artifact);
|
|
899
|
+
const relationships = await this.mapRelationships(artifact);
|
|
900
|
+
const claudeSummary = await this.createClaudeSummary(artifact);
|
|
901
|
+
const modificationPoints = await this.identifyModificationPoints(artifact);
|
|
902
|
+
return {
|
|
903
|
+
meta: {
|
|
904
|
+
sys_id: artifact.sys_id,
|
|
905
|
+
name: artifact.name || artifact.title,
|
|
906
|
+
title: artifact.title,
|
|
907
|
+
type: artifact.sys_class_name || 'unknown',
|
|
908
|
+
last_updated: artifact.sys_updated_on,
|
|
909
|
+
},
|
|
910
|
+
structure,
|
|
911
|
+
context,
|
|
912
|
+
relationships,
|
|
913
|
+
claudeSummary,
|
|
914
|
+
modificationPoints,
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
async decomposeArtifact(artifact) {
|
|
918
|
+
// Decompose artifact based on type
|
|
919
|
+
if (artifact.sys_class_name === 'sp_widget') {
|
|
920
|
+
return this.decomposeWidget(artifact);
|
|
921
|
+
}
|
|
922
|
+
else if (artifact.sys_class_name === 'sys_hub_flow') {
|
|
923
|
+
return this.decomposeFlow(artifact);
|
|
924
|
+
}
|
|
925
|
+
return { type: 'unknown', components: [] };
|
|
926
|
+
}
|
|
927
|
+
async decomposeWidget(widget) {
|
|
928
|
+
return {
|
|
929
|
+
type: 'widget',
|
|
930
|
+
components: {
|
|
931
|
+
template: widget.template ? 'HTML template present' : 'No template',
|
|
932
|
+
css: widget.css ? 'Custom CSS present' : 'No custom CSS',
|
|
933
|
+
client_script: widget.client_script ? 'Client script present' : 'No client script',
|
|
934
|
+
server_script: widget.server_script ? 'Server script present' : 'No server script',
|
|
935
|
+
options: widget.option_schema ? JSON.parse(widget.option_schema) : [],
|
|
936
|
+
},
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
async decomposeFlow(flow) {
|
|
940
|
+
return {
|
|
941
|
+
type: 'flow',
|
|
942
|
+
components: {
|
|
943
|
+
name: flow.name,
|
|
944
|
+
description: flow.description,
|
|
945
|
+
active: flow.active,
|
|
946
|
+
trigger: flow.trigger_conditions || 'Unknown trigger',
|
|
947
|
+
steps: 'Flow definition analysis would go here',
|
|
948
|
+
},
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
async extractContext(artifact) {
|
|
952
|
+
return {
|
|
953
|
+
usage: 'Context analysis would determine usage patterns',
|
|
954
|
+
dependencies: 'Related artifacts would be identified here',
|
|
955
|
+
impact: 'Impact analysis would be performed here',
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
async mapRelationships(artifact) {
|
|
959
|
+
return {
|
|
960
|
+
relatedArtifacts: [],
|
|
961
|
+
dependencies: [],
|
|
962
|
+
usage: [],
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
async createClaudeSummary(artifact) {
|
|
966
|
+
const name = artifact.name || artifact.title || 'Unknown';
|
|
967
|
+
const type = artifact.sys_class_name || 'artifact';
|
|
968
|
+
return `${name} is a ${type} in ServiceNow. It can be modified using natural language instructions through Snow-Flow.`;
|
|
969
|
+
}
|
|
970
|
+
async identifyModificationPoints(artifact) {
|
|
971
|
+
// Identify common modification points
|
|
972
|
+
return [
|
|
973
|
+
{
|
|
974
|
+
location: 'main_configuration',
|
|
975
|
+
type: 'modify_settings',
|
|
976
|
+
description: 'Main configuration can be modified',
|
|
977
|
+
},
|
|
978
|
+
];
|
|
979
|
+
}
|
|
980
|
+
async storeInMemory(artifact) {
|
|
981
|
+
// Store in memory for future access
|
|
982
|
+
await fs_1.promises.mkdir(this.memoryPath, { recursive: true });
|
|
983
|
+
const filePath = (0, path_1.join)(this.memoryPath, `${artifact.meta.sys_id}.json`);
|
|
984
|
+
await fs_1.promises.writeFile(filePath, JSON.stringify(artifact, null, 2));
|
|
985
|
+
}
|
|
986
|
+
async searchInMemory(intent) {
|
|
987
|
+
// Search in memory index
|
|
988
|
+
try {
|
|
989
|
+
const files = await fs_1.promises.readdir(this.memoryPath);
|
|
990
|
+
const results = [];
|
|
991
|
+
for (const file of files) {
|
|
992
|
+
if (file.endsWith('.json')) {
|
|
993
|
+
try {
|
|
994
|
+
const content = await fs_1.promises.readFile((0, path_1.join)(this.memoryPath, file), 'utf8');
|
|
995
|
+
const artifact = JSON.parse(content);
|
|
996
|
+
// Ensure artifact has basic structure
|
|
997
|
+
if (artifact && (artifact.meta || artifact.claudeSummary)) {
|
|
998
|
+
if (this.matchesIntent(artifact, intent)) {
|
|
999
|
+
results.push(artifact);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
catch (parseError) {
|
|
1004
|
+
this.logger.warn(`Failed to parse memory file: ${file}`, parseError);
|
|
1005
|
+
// Continue with next file
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
return results;
|
|
1010
|
+
}
|
|
1011
|
+
catch (error) {
|
|
1012
|
+
return [];
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
matchesIntent(artifact, intent) {
|
|
1016
|
+
const searchTerm = intent.identifier.toLowerCase();
|
|
1017
|
+
// Safe access to artifact properties with fallbacks
|
|
1018
|
+
const artifactName = (artifact.meta?.name || artifact.meta?.title || '').toLowerCase();
|
|
1019
|
+
const artifactSummary = (artifact.claudeSummary || '').toLowerCase();
|
|
1020
|
+
return artifactName.includes(searchTerm) || artifactSummary.includes(searchTerm);
|
|
1021
|
+
}
|
|
1022
|
+
formatResults(results) {
|
|
1023
|
+
if (!results || results.length === 0) {
|
|
1024
|
+
return 'ā No artifacts found matching your search criteria.\n\nš **Debugging Info:**\n- ServiceNow connection appears to be working\n- Try broader search terms\n- Check if widgets exist in your ServiceNow instance\n- Use snow_deploy_widget to create new widgets first';
|
|
1025
|
+
}
|
|
1026
|
+
const formattedResults = results.map((result, index) => {
|
|
1027
|
+
const name = result.name || result.title || result.display_name || result.sys_id || 'Unknown';
|
|
1028
|
+
const type = result.sys_class_name || result.type || 'Unknown';
|
|
1029
|
+
const artifactType = result.artifact_type || 'Unknown';
|
|
1030
|
+
const tableName = result.table_name || 'Unknown';
|
|
1031
|
+
const id = result.sys_id || 'Unknown';
|
|
1032
|
+
const updated = result.sys_updated_on || result.last_updated || 'Unknown';
|
|
1033
|
+
const active = result.active !== undefined ? (result.active ? 'Active' : 'Inactive') : 'Unknown';
|
|
1034
|
+
const description = result.short_description || result.description || 'No description';
|
|
1035
|
+
return `${index + 1}. **${name}**\n - Artifact Type: ${artifactType}\n - Table: ${tableName}\n - Class: ${type}\n - ID: ${id}\n - Status: ${active}\n - Description: ${description}\n - Updated: ${updated}`;
|
|
1036
|
+
}).join('\n\n');
|
|
1037
|
+
return `ā
Found ${results.length} artifact(s):\n\n${formattedResults}`;
|
|
1038
|
+
}
|
|
1039
|
+
formatMemoryResults(results) {
|
|
1040
|
+
return results.map((result, index) => `${index + 1}. **${result.meta.name}**\n - Type: ${result.meta.type}\n - Summary: ${result.claudeSummary}\n - Modification Points: ${result.modificationPoints.length}`).join('\n\n');
|
|
1041
|
+
}
|
|
1042
|
+
formatComprehensiveResults(results) {
|
|
1043
|
+
if (!results || results.length === 0) {
|
|
1044
|
+
return 'ā No artifacts found across all ServiceNow tables.\n\nš **Suggestions:**\n- Check spelling and try different terms\n- Include inactive records with include_inactive=true\n- Try broader search terms\n- The artifact might be in a scoped application';
|
|
1045
|
+
}
|
|
1046
|
+
// Group results by table type
|
|
1047
|
+
const groupedResults = results.reduce((groups, result) => {
|
|
1048
|
+
const tableDesc = result.table_description || result.table_name;
|
|
1049
|
+
if (!groups[tableDesc]) {
|
|
1050
|
+
groups[tableDesc] = [];
|
|
1051
|
+
}
|
|
1052
|
+
groups[tableDesc].push(result);
|
|
1053
|
+
return groups;
|
|
1054
|
+
}, {});
|
|
1055
|
+
let output = `ā
Found ${results.length} artifact(s) across ${Object.keys(groupedResults).length} table type(s):\n\n`;
|
|
1056
|
+
for (const [tableDesc, tableResults] of Object.entries(groupedResults)) {
|
|
1057
|
+
output += `## ${tableDesc}\n`;
|
|
1058
|
+
tableResults.forEach((result, index) => {
|
|
1059
|
+
const name = result.name || result.title || result.display_name || result.sys_id || 'Unknown';
|
|
1060
|
+
const active = result.active !== undefined ? (result.active ? 'Active' : 'Inactive') : 'Unknown';
|
|
1061
|
+
const description = result.short_description || result.description || 'No description';
|
|
1062
|
+
const strategy = result.search_strategy || 'Unknown';
|
|
1063
|
+
const collection = result.collection || result.table_name || 'Unknown';
|
|
1064
|
+
output += `${index + 1}. **${name}**\n`;
|
|
1065
|
+
output += ` - Table: ${collection}\n`;
|
|
1066
|
+
output += ` - Status: ${active}\n`;
|
|
1067
|
+
output += ` - Description: ${description}\n`;
|
|
1068
|
+
output += ` - Found via: ${strategy}\n`;
|
|
1069
|
+
output += ` - Sys ID: ${result.sys_id}\n`;
|
|
1070
|
+
if (result.when)
|
|
1071
|
+
output += ` - When: ${result.when}\n`;
|
|
1072
|
+
if (result.order)
|
|
1073
|
+
output += ` - Order: ${result.order}\n`;
|
|
1074
|
+
if (result.condition)
|
|
1075
|
+
output += ` - Condition: ${result.condition}\n`;
|
|
1076
|
+
output += '\n';
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
return output;
|
|
1080
|
+
}
|
|
1081
|
+
generateEditSuggestion(artifact) {
|
|
1082
|
+
if (!artifact) {
|
|
1083
|
+
return 'š” Use snow_edit_artifact to modify ServiceNow artifacts with natural language.';
|
|
1084
|
+
}
|
|
1085
|
+
const name = artifact.name || artifact.title || artifact.display_name || 'the artifact';
|
|
1086
|
+
return `š” To edit this artifact, use:\n\`snow-flow edit "modify ${name} to add [your requirements]"\``;
|
|
1087
|
+
}
|
|
1088
|
+
async findTargetArtifact(intent) {
|
|
1089
|
+
// Find the specific artifact to edit
|
|
1090
|
+
const results = await this.searchServiceNow(intent);
|
|
1091
|
+
if (results.length === 0) {
|
|
1092
|
+
throw new Error('No matching artifact found');
|
|
1093
|
+
}
|
|
1094
|
+
// Return the best match (first result for now)
|
|
1095
|
+
return results[0];
|
|
1096
|
+
}
|
|
1097
|
+
async analyzeModification(intent, artifact) {
|
|
1098
|
+
// Analyze what modification is needed
|
|
1099
|
+
return {
|
|
1100
|
+
type: 'configuration_change',
|
|
1101
|
+
description: intent.modification || 'General modification',
|
|
1102
|
+
target: artifact.sys_id,
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
async applyModification(artifact, modification) {
|
|
1106
|
+
// Apply the modification - this would be more sophisticated
|
|
1107
|
+
return {
|
|
1108
|
+
...artifact,
|
|
1109
|
+
modified: true,
|
|
1110
|
+
modification_applied: modification,
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
async deployArtifact(artifact) {
|
|
1114
|
+
// Deploy the modified artifact back to ServiceNow
|
|
1115
|
+
return { success: true, message: 'Artifact deployed successfully' };
|
|
1116
|
+
}
|
|
1117
|
+
async updateMemoryIndex(artifact, modification) {
|
|
1118
|
+
// Update the memory index with the changes
|
|
1119
|
+
const indexed = await this.intelligentlyIndex(artifact);
|
|
1120
|
+
await this.storeInMemory(indexed);
|
|
1121
|
+
}
|
|
1122
|
+
getArtifactUrl(artifact) {
|
|
1123
|
+
// Generate ServiceNow URL for the artifact
|
|
1124
|
+
return `sys_id=${artifact.sys_id}`;
|
|
1125
|
+
}
|
|
1126
|
+
async start() {
|
|
1127
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
1128
|
+
await this.server.connect(transport);
|
|
1129
|
+
this.logger.info('ServiceNow Intelligent MCP Server started');
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
// Start the server
|
|
1133
|
+
const server = new ServiceNowIntelligentMCP();
|
|
1134
|
+
server.start().catch((error) => {
|
|
1135
|
+
console.error('Failed to start ServiceNow Intelligent MCP:', error);
|
|
1136
|
+
process.exit(1);
|
|
1137
|
+
});
|
|
1138
|
+
//# sourceMappingURL=servicenow-intelligent-mcp.js.map
|