snow-flow 2.0.2 → 2.0.3
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/mcp-config.json → .mcp.json} +13 -12
- package/.releaserc.json +47 -0
- package/README.md +6 -0
- package/package.json +1 -1
- package/.claude/claude-settings.json +0 -15
- package/.claude/commands/analysis/README.md +0 -9
- package/.claude/commands/automation/README.md +0 -9
- package/.claude/commands/github/README.md +0 -11
- package/.claude/commands/helpers/standard-checkpoint-hooks.sh +0 -179
- package/.claude/commands/hooks/README.md +0 -11
- package/.claude/commands/monitoring/README.md +0 -9
- package/.claude/commands/optimization/README.md +0 -9
- package/.claude/commands/training/README.md +0 -9
- package/.claude/commands/workflows/README.md +0 -9
- package/.claude/config.json +0 -36
- package/.claude/helpers/github-setup.sh +0 -28
- package/.claude/helpers/quick-start.sh +0 -19
- package/.claude/helpers/setup-mcp.sh +0 -18
- package/.claude/settings.json +0 -114
- package/.claude/settings.local.json +0 -33
- package/.claude-flow/metrics/agent-metrics.json +0 -1
- package/.claude-flow/metrics/performance.json +0 -9
- package/.claude-flow/metrics/system-metrics.json +0 -15986
- package/.claude-flow/metrics/task-metrics.json +0 -10
- package/.roo/README.md +0 -402
- package/.roo/mcp-list.txt +0 -257
- package/.roo/mcp.json +0 -32
- package/.roo/workflows/basic-tdd.json +0 -32
- package/.roomodes +0 -201
- package/CLAUDE.md +0 -393
- package/bin/snow-flow.js +0 -3
- package/dist/cli.js.bak +0 -2052
- package/dist/config/snow-flow-config.d.ts +0 -1492
- package/dist/config/snow-flow-config.js +0 -938
- package/scripts/create-env.js +0 -91
- package/scripts/postinstall.js +0 -30
- package/scripts/register-mcp-servers.js +0 -210
- package/scripts/reset-mcp-servers.js +0 -246
- package/scripts/setup-mcp.js +0 -106
- package/scripts/update-version.js +0 -31
- package/src/agents/README.md +0 -192
- package/src/agents/base-agent.ts +0 -251
- package/src/agents/coordinator.ts +0 -971
- package/src/agents/index.ts +0 -18
- package/src/agents/queen-403-handler.ts +0 -230
- package/src/agents/queen-agent.ts +0 -1399
- package/src/agents/script-writer-agent.ts +0 -769
- package/src/agents/security-agent.ts +0 -726
- package/src/agents/widget-creator-agent.ts +0 -568
- package/src/api/error-handling.ts +0 -1758
- package/src/api/natural-language-mapper.ts +0 -630
- package/src/api/performance-optimizer.ts +0 -891
- package/src/api/transaction-manager.ts +0 -754
- package/src/cli/deploy-artifact.ts +0 -304
- package/src/cli/snow-flow-cli-integration.ts +0 -434
- package/src/cli.ts +0 -4455
- package/src/cli.ts.bak +0 -5616
- package/src/compliance/advanced-compliance-system.ts +0 -1268
- package/src/compliance/index.ts +0 -19
- package/src/config/snow-flow-config.ts +0 -1019
- package/src/documentation/index.ts +0 -16
- package/src/documentation/self-documenting-system.ts +0 -1421
- package/src/dynamic-version.ts +0 -44
- package/src/healing/index.ts +0 -20
- package/src/healing/self-healing-system.ts +0 -1435
- package/src/health/README.md +0 -161
- package/src/health/system-health.ts +0 -995
- package/src/index.ts +0 -60
- package/src/intelligence/acl-analyzer.ts +0 -377
- package/src/intelligence/auto-resolution-engine.ts +0 -643
- package/src/intelligence/gap-analysis-engine.ts +0 -488
- package/src/intelligence/manual-instructions-generator.ts +0 -744
- package/src/intelligence/mcp-coverage-analyzer.ts +0 -708
- package/src/intelligence/multi-pass-requirements-analyzer.ts +0 -603
- package/src/intelligence/performance-recommendations-engine.ts +0 -1223
- package/src/intelligence/requirements-analyzer.ts +0 -1148
- package/src/intelligence/task-analyzer.ts +0 -628
- package/src/managers/scope-manager.ts +0 -555
- package/src/mcp/advanced/servicenow-advanced-features-mcp.ts +0 -16110
- package/src/mcp/base-mcp-server.ts +0 -660
- package/src/mcp/http-transport-wrapper.ts +0 -426
- package/src/mcp/service-discovery-client.ts +0 -312
- package/src/mcp/servicenow-automation-mcp-refactored.ts +0 -678
- package/src/mcp/servicenow-automation-mcp.ts +0 -838
- package/src/mcp/servicenow-deployment-mcp-refactored.ts +0 -1292
- package/src/mcp/servicenow-deployment-mcp.ts +0 -7244
- package/src/mcp/servicenow-graph-memory-mcp-refactored.ts +0 -721
- package/src/mcp/servicenow-graph-memory-mcp.ts +0 -832
- package/src/mcp/servicenow-integration-mcp-refactored.ts +0 -655
- package/src/mcp/servicenow-integration-mcp.ts +0 -819
- package/src/mcp/servicenow-intelligent-mcp-refactored.ts +0 -977
- package/src/mcp/servicenow-intelligent-mcp.ts +0 -4638
- package/src/mcp/servicenow-mcp-server.ts +0 -728
- package/src/mcp/servicenow-memory-mcp.ts +0 -474
- package/src/mcp/servicenow-operations-mcp-refactored.ts +0 -1995
- package/src/mcp/servicenow-operations-mcp.ts +0 -3384
- package/src/mcp/servicenow-platform-development-mcp-refactored.ts +0 -611
- package/src/mcp/servicenow-platform-development-mcp.ts +0 -970
- package/src/mcp/servicenow-progressive-indexer.ts +0 -370
- package/src/mcp/servicenow-reporting-analytics-mcp-refactored.ts +0 -695
- package/src/mcp/servicenow-reporting-analytics-mcp.ts +0 -1123
- package/src/mcp/servicenow-security-compliance-mcp-refactored.ts +0 -642
- package/src/mcp/servicenow-security-compliance-mcp.ts +0 -1157
- package/src/mcp/servicenow-update-set-mcp-refactored.ts +0 -751
- package/src/mcp/servicenow-update-set-mcp.ts +0 -811
- package/src/mcp/shared/agent-context-provider.ts +0 -365
- package/src/mcp/shared/base-mcp-server.ts +0 -2463
- package/src/mcp/shared/mcp-memory-manager.ts +0 -540
- package/src/mcp/shared/mcp-resource-manager.ts +0 -367
- package/src/mcp/snow-flow-mcp.ts +0 -911
- package/src/mcp/start-all-mcp-servers.ts +0 -102
- package/src/mcp/start-servicenow-mcp.ts +0 -67
- package/src/monitoring/enhanced-monitoring-system.ts +0 -1345
- package/src/monitoring/performance-tracker.ts +0 -777
- package/src/optimization/cost-optimization-engine.ts +0 -1125
- package/src/optimization/index.ts +0 -10
- package/src/queen/README.md +0 -403
- package/src/queen/agent-factory.ts +0 -574
- package/src/queen/index.ts +0 -94
- package/src/queen/mcp-execution-bridge.ts +0 -681
- package/src/queen/neural-learning.ts +0 -319
- package/src/queen/parallel-agent-engine.ts +0 -848
- package/src/queen/queen-memory-system.ts +0 -490
- package/src/queen/queen-memory.ts +0 -456
- package/src/queen/servicenow-queen.ts +0 -1029
- package/src/queen/types.ts +0 -87
- package/src/rollback/smart-rollback-system.ts +0 -866
- package/src/schemas/deployment.schema.json +0 -58
- package/src/schemas/flow.schema.json +0 -79
- package/src/schemas/widget.schema.json +0 -72
- package/src/snow-flow-system.ts +0 -541
- package/src/sparc/sparc-help.ts +0 -49
- package/src/sparc/team-sparc.ts +0 -88
- package/src/strategies/global-scope-strategy.ts +0 -736
- package/src/templates/base/application.template.json +0 -45
- package/src/templates/base/business_rule.template.json +0 -33
- package/src/templates/base/script_include.template.json +0 -18
- package/src/templates/base/table.template.json +0 -64
- package/src/templates/base/widget.template.json +0 -25
- package/src/templates/patterns/composite.incident-management.template.json +0 -140
- package/src/templates/patterns/widget.dashboard.template.json +0 -238
- package/src/templates/patterns/widget.datatable.template.json +0 -292
- package/src/testing/integration-test-suite.ts +0 -1276
- package/src/types/index.ts +0 -183
- package/src/types/neo4j-driver.d.ts +0 -23
- package/src/types/servicenow.types.ts +0 -307
- package/src/types/snow-flow.types.ts +0 -186
- package/src/types/todo.types.ts +0 -70
- package/src/utils/action-type-cache.ts +0 -286
- package/src/utils/agent-detector.ts +0 -573
- package/src/utils/artifact-tracker.ts +0 -379
- package/src/utils/dependency-detector.ts +0 -233
- package/src/utils/deployment-metadata-handler.ts +0 -518
- package/src/utils/error-recovery.ts +0 -680
- package/src/utils/logger.ts +0 -60
- package/src/utils/mcp-auth-middleware.ts +0 -262
- package/src/utils/mcp-config-manager.ts +0 -270
- package/src/utils/mcp-server-manager.ts +0 -446
- package/src/utils/mcp-tool-registry.ts +0 -298
- package/src/utils/migrate-snow-flow.ts +0 -98
- package/src/utils/oauth-html-templates.ts +0 -188
- package/src/utils/scope-utils.ts +0 -443
- package/src/utils/servicenow-client.ts +0 -3321
- package/src/utils/servicenow-id-generator.ts +0 -181
- package/src/utils/snow-memory-manager.ts +0 -605
- package/src/utils/snow-oauth.ts +0 -797
- package/src/utils/template-engine.ts +0 -463
- package/src/utils/theme-manager.ts +0 -295
- package/src/utils/unified-auth-store.ts +0 -222
- package/src/utils/update-set-importer.ts +0 -422
- package/src/utils/update-set-xml-packager.ts +0 -371
- package/src/utils/widget-template-generator.ts +0 -1744
- package/src/version.ts +0 -1950
|
@@ -1,463 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Template Engine for Dynamic Artifact Generation
|
|
3
|
-
* Replaces hardcoded artifact implementations with flexible templates
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { promises as fs } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
8
|
-
|
|
9
|
-
export interface TemplateVariables {
|
|
10
|
-
[key: string]: string | number | boolean;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface Template {
|
|
14
|
-
type: string;
|
|
15
|
-
name: string;
|
|
16
|
-
description: string;
|
|
17
|
-
category?: string;
|
|
18
|
-
config: any;
|
|
19
|
-
variables?: TemplateVariables;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export class TemplateEngine {
|
|
23
|
-
private templatesPath: string;
|
|
24
|
-
|
|
25
|
-
constructor(templatesPath?: string) {
|
|
26
|
-
this.templatesPath = templatesPath || join(process.cwd(), 'src', 'templates');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Load a template from file
|
|
31
|
-
*/
|
|
32
|
-
async loadTemplate(templatePath: string): Promise<Template> {
|
|
33
|
-
const fullPath = join(this.templatesPath, templatePath);
|
|
34
|
-
const content = await fs.readFile(fullPath, 'utf-8');
|
|
35
|
-
return JSON.parse(content);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Process template with variables
|
|
40
|
-
*/
|
|
41
|
-
processTemplate(template: Template, variables: TemplateVariables = {}): any {
|
|
42
|
-
// Merge provided variables with defaults
|
|
43
|
-
const allVariables = {
|
|
44
|
-
...template.variables,
|
|
45
|
-
...variables
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// Convert template to string for processing
|
|
49
|
-
let templateStr = JSON.stringify(template.config);
|
|
50
|
-
|
|
51
|
-
// Replace all variable placeholders
|
|
52
|
-
for (const [key, value] of Object.entries(allVariables)) {
|
|
53
|
-
// Replace {{KEY}} with value
|
|
54
|
-
const regex = new RegExp(`{{${key}}}`, 'g');
|
|
55
|
-
templateStr = templateStr.replace(regex, String(value));
|
|
56
|
-
|
|
57
|
-
// Replace {{KEY|default}} with value or default
|
|
58
|
-
const defaultRegex = new RegExp(`{{${key}\\|([^}]+)}}`, 'g');
|
|
59
|
-
templateStr = templateStr.replace(defaultRegex, String(value));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Replace any remaining {{KEY|default}} patterns with defaults
|
|
63
|
-
templateStr = templateStr.replace(/{{[^|]+\|([^}]+)}}/g, '$1');
|
|
64
|
-
|
|
65
|
-
// Remove any unmatched placeholders
|
|
66
|
-
templateStr = templateStr.replace(/{{[^}]+}}/g, '');
|
|
67
|
-
|
|
68
|
-
// Parse back to object
|
|
69
|
-
const processed = JSON.parse(templateStr);
|
|
70
|
-
|
|
71
|
-
// Add metadata
|
|
72
|
-
return {
|
|
73
|
-
...processed,
|
|
74
|
-
_template: {
|
|
75
|
-
source: template.name,
|
|
76
|
-
type: template.type,
|
|
77
|
-
processed_at: new Date().toISOString()
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Create artifact from template
|
|
84
|
-
*/
|
|
85
|
-
async createFromTemplate(
|
|
86
|
-
templateName: string,
|
|
87
|
-
variables: TemplateVariables = {}
|
|
88
|
-
): Promise<any> {
|
|
89
|
-
// Load base template
|
|
90
|
-
const templatePath = `base/${templateName}.template.json`;
|
|
91
|
-
const template = await this.loadTemplate(templatePath);
|
|
92
|
-
|
|
93
|
-
// Process with variables
|
|
94
|
-
return this.processTemplate(template, variables);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Get available templates
|
|
99
|
-
*/
|
|
100
|
-
async getAvailableTemplates(type?: string, category?: string): Promise<Template[]> {
|
|
101
|
-
const templates: Template[] = [];
|
|
102
|
-
|
|
103
|
-
// Check base directory
|
|
104
|
-
const baseDir = join(this.templatesPath, 'base');
|
|
105
|
-
if (await this.directoryExists(baseDir)) {
|
|
106
|
-
const baseTemplates = await this.getTemplatesFromDirectory(baseDir);
|
|
107
|
-
templates.push(...baseTemplates);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Check patterns directory
|
|
111
|
-
const patternsDir = join(this.templatesPath, 'patterns');
|
|
112
|
-
if (await this.directoryExists(patternsDir)) {
|
|
113
|
-
const patternTemplates = await this.getTemplatesFromDirectory(patternsDir);
|
|
114
|
-
templates.push(...patternTemplates);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Filter by type and category if specified
|
|
118
|
-
return templates.filter(template => {
|
|
119
|
-
if (type && template.type !== type) return false;
|
|
120
|
-
if (category && template.category !== category) return false;
|
|
121
|
-
return true;
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Get templates from a directory
|
|
127
|
-
*/
|
|
128
|
-
private async getTemplatesFromDirectory(dir: string): Promise<Template[]> {
|
|
129
|
-
const templates: Template[] = [];
|
|
130
|
-
const files = await fs.readdir(dir);
|
|
131
|
-
|
|
132
|
-
for (const file of files) {
|
|
133
|
-
if (file.endsWith('.template.json')) {
|
|
134
|
-
try {
|
|
135
|
-
const relativePath = join(dir, file).replace(this.templatesPath + '/', '');
|
|
136
|
-
const template = await this.loadTemplate(relativePath);
|
|
137
|
-
templates.push(template);
|
|
138
|
-
} catch (error) {
|
|
139
|
-
console.error(`Error loading template ${file}:`, error);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return templates;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Check if directory exists
|
|
149
|
-
*/
|
|
150
|
-
private async directoryExists(path: string): Promise<boolean> {
|
|
151
|
-
try {
|
|
152
|
-
const stat = await fs.stat(path);
|
|
153
|
-
return stat.isDirectory();
|
|
154
|
-
} catch {
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Create example from template
|
|
161
|
-
*/
|
|
162
|
-
async createExample(
|
|
163
|
-
templateName: string,
|
|
164
|
-
exampleName: string,
|
|
165
|
-
variables: TemplateVariables
|
|
166
|
-
): Promise<void> {
|
|
167
|
-
const artifact = await this.createFromTemplate(templateName, variables);
|
|
168
|
-
|
|
169
|
-
// Save to examples directory
|
|
170
|
-
const exampleDir = join(this.templatesPath, 'examples', exampleName);
|
|
171
|
-
await fs.mkdir(exampleDir, { recursive: true });
|
|
172
|
-
|
|
173
|
-
const outputPath = join(exampleDir, `${exampleName}.json`);
|
|
174
|
-
await fs.writeFile(outputPath, JSON.stringify(artifact, null, 2));
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Validate template structure
|
|
179
|
-
*/
|
|
180
|
-
validateTemplate(template: Template): string[] {
|
|
181
|
-
const errors: string[] = [];
|
|
182
|
-
|
|
183
|
-
if (!template.type) {
|
|
184
|
-
errors.push('Template must have a type');
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (!template.name) {
|
|
188
|
-
errors.push('Template must have a name');
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (!template.config) {
|
|
192
|
-
errors.push('Template must have a config section');
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Type-specific validation
|
|
196
|
-
switch (template.type) {
|
|
197
|
-
case 'widget':
|
|
198
|
-
if (!template.config.template) {
|
|
199
|
-
errors.push('Widget template must have HTML template');
|
|
200
|
-
}
|
|
201
|
-
break;
|
|
202
|
-
case 'flow':
|
|
203
|
-
if (!template.config.flow_definition) {
|
|
204
|
-
errors.push('Flow template must have flow_definition');
|
|
205
|
-
}
|
|
206
|
-
break;
|
|
207
|
-
case 'script_include':
|
|
208
|
-
if (!template.config.script) {
|
|
209
|
-
errors.push('Script include template must have script');
|
|
210
|
-
}
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return errors;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Generate artifact from natural language
|
|
219
|
-
*/
|
|
220
|
-
async generateFromDescription(
|
|
221
|
-
description: string,
|
|
222
|
-
type?: string
|
|
223
|
-
): Promise<any> {
|
|
224
|
-
// Determine the best template based on description
|
|
225
|
-
const template = await this.selectBestTemplate(description, type);
|
|
226
|
-
|
|
227
|
-
// Extract variables from description
|
|
228
|
-
const variables = this.extractVariablesFromDescription(description, template);
|
|
229
|
-
|
|
230
|
-
// Process template with extracted variables
|
|
231
|
-
return this.processTemplate(template, variables);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Select the best template based on natural language description
|
|
236
|
-
*/
|
|
237
|
-
private async selectBestTemplate(description: string, preferredType?: string): Promise<Template> {
|
|
238
|
-
const lowerDesc = description.toLowerCase();
|
|
239
|
-
|
|
240
|
-
// Determine type if not specified
|
|
241
|
-
let type = preferredType;
|
|
242
|
-
if (!type) {
|
|
243
|
-
if (lowerDesc.includes('widget') || lowerDesc.includes('dashboard') || lowerDesc.includes('visualization')) {
|
|
244
|
-
type = 'widget';
|
|
245
|
-
} else if (lowerDesc.includes('flow') || lowerDesc.includes('workflow') || lowerDesc.includes('approval')) {
|
|
246
|
-
type = 'flow';
|
|
247
|
-
} else if (lowerDesc.includes('script') || lowerDesc.includes('utility') || lowerDesc.includes('function')) {
|
|
248
|
-
type = 'script_include';
|
|
249
|
-
} else if (lowerDesc.includes('rule') || lowerDesc.includes('trigger')) {
|
|
250
|
-
type = 'business_rule';
|
|
251
|
-
} else if (lowerDesc.includes('table') || lowerDesc.includes('data model')) {
|
|
252
|
-
type = 'table';
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Get available templates of this type
|
|
257
|
-
const templates = await this.getAvailableTemplates(type);
|
|
258
|
-
|
|
259
|
-
// Score templates based on description match
|
|
260
|
-
let bestTemplate: Template | null = null;
|
|
261
|
-
let bestScore = 0;
|
|
262
|
-
|
|
263
|
-
for (const template of templates) {
|
|
264
|
-
const score = this.scoreTemplate(template, description);
|
|
265
|
-
if (score > bestScore) {
|
|
266
|
-
bestScore = score;
|
|
267
|
-
bestTemplate = template;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Fallback to base template if no good match
|
|
272
|
-
if (!bestTemplate) {
|
|
273
|
-
const basePath = `base/${type}.template.json`;
|
|
274
|
-
bestTemplate = await this.loadTemplate(basePath);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
return bestTemplate;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Score a template based on how well it matches the description
|
|
282
|
-
*/
|
|
283
|
-
private scoreTemplate(template: Template, description: string): number {
|
|
284
|
-
let score = 0;
|
|
285
|
-
const lowerDesc = description.toLowerCase();
|
|
286
|
-
const lowerTemplateName = template.name.toLowerCase();
|
|
287
|
-
const lowerTemplateDesc = template.description.toLowerCase();
|
|
288
|
-
|
|
289
|
-
// Check template name
|
|
290
|
-
const nameWords = lowerTemplateName.split(/\s+/);
|
|
291
|
-
for (const word of nameWords) {
|
|
292
|
-
if (lowerDesc.includes(word) && word.length > 3) {
|
|
293
|
-
score += 2;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Check template description
|
|
298
|
-
const descWords = lowerTemplateDesc.split(/\s+/);
|
|
299
|
-
for (const word of descWords) {
|
|
300
|
-
if (lowerDesc.includes(word) && word.length > 3) {
|
|
301
|
-
score += 1;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Pattern-specific scoring
|
|
306
|
-
if (template.category) {
|
|
307
|
-
if (template.category.includes('dashboard') && lowerDesc.includes('dashboard')) score += 5;
|
|
308
|
-
if (template.category.includes('approval') && lowerDesc.includes('approval')) score += 5;
|
|
309
|
-
if (template.category.includes('integration') && (lowerDesc.includes('integrate') || lowerDesc.includes('api'))) score += 5;
|
|
310
|
-
if (template.category.includes('datatable') && (lowerDesc.includes('table') || lowerDesc.includes('list'))) score += 5;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return score;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Extract variables from natural language description
|
|
318
|
-
*/
|
|
319
|
-
private extractVariablesFromDescription(description: string, template: Template): TemplateVariables {
|
|
320
|
-
const variables: TemplateVariables = {};
|
|
321
|
-
const lowerDesc = description.toLowerCase();
|
|
322
|
-
|
|
323
|
-
// Extract name variants
|
|
324
|
-
const nameMatch = description.match(/(?:create|build|make)\s+(?:a|an)?\s*([^,.\s]+(?:\s+[^,.\s]+)*?)(?:\s+(?:widget|flow|script|for|with|that|$))/i);
|
|
325
|
-
if (nameMatch) {
|
|
326
|
-
const name = nameMatch[1].trim();
|
|
327
|
-
variables.NAME = name;
|
|
328
|
-
variables.WIDGET_NAME = name.replace(/\s+/g, '_').toLowerCase();
|
|
329
|
-
variables.FLOW_NAME = name.replace(/\s+/g, '_').toLowerCase();
|
|
330
|
-
variables.CLASS_NAME = name.split(/\s+/).map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('');
|
|
331
|
-
variables.WIDGET_TITLE = name.split(/\s+/).map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
332
|
-
variables.FLOW_DESCRIPTION = `${name} automation flow`;
|
|
333
|
-
variables.WIDGET_DESCRIPTION = `Widget for ${name.toLowerCase()}`;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Extract table name
|
|
337
|
-
const tablePatterns = [
|
|
338
|
-
/(?:for|on|from|of)\s+(\w+)\s+(?:table|records?|data)/i,
|
|
339
|
-
/(?:track|manage|display|show)\s+(\w+)(?:\s|$)/i,
|
|
340
|
-
/(\w+)\s+(?:management|tracking|dashboard)/i
|
|
341
|
-
];
|
|
342
|
-
|
|
343
|
-
for (const pattern of tablePatterns) {
|
|
344
|
-
const match = description.match(pattern);
|
|
345
|
-
if (match) {
|
|
346
|
-
variables.TABLE = match[1].toLowerCase();
|
|
347
|
-
variables.TABLE_NAME = match[1].toLowerCase();
|
|
348
|
-
break;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// Extract trigger conditions
|
|
353
|
-
if (lowerDesc.includes('when created') || lowerDesc.includes('on create')) {
|
|
354
|
-
variables.TRIGGER_TYPE = 'record_created';
|
|
355
|
-
} else if (lowerDesc.includes('when updated') || lowerDesc.includes('on update')) {
|
|
356
|
-
variables.TRIGGER_TYPE = 'record_updated';
|
|
357
|
-
} else if (lowerDesc.includes('when deleted') || lowerDesc.includes('on delete')) {
|
|
358
|
-
variables.TRIGGER_TYPE = 'record_deleted';
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// Extract approval-specific variables
|
|
362
|
-
if (template.type === 'flow' && lowerDesc.includes('approval')) {
|
|
363
|
-
// Extract amount thresholds
|
|
364
|
-
const amountMatch = description.match(/(?:over|above|greater than|more than)\s*[$€£]?\s*(\d+(?:,\d{3})*(?:\.\d{2})?)/i);
|
|
365
|
-
if (amountMatch) {
|
|
366
|
-
variables.HIGH_AMOUNT_THRESHOLD = amountMatch[1].replace(/,/g, '');
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// Extract approvers
|
|
370
|
-
if (lowerDesc.includes('manager')) variables.APPROVAL_TYPE = 'manager';
|
|
371
|
-
if (lowerDesc.includes('director')) variables.APPROVAL_TYPE = 'director';
|
|
372
|
-
if (lowerDesc.includes('group')) variables.APPROVAL_TYPE = 'group';
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// Extract integration-specific variables
|
|
376
|
-
if (template.type === 'flow' && lowerDesc.includes('integrat')) {
|
|
377
|
-
const apiMatch = description.match(/(?:api|endpoint|url):\s*([^\s]+)/i);
|
|
378
|
-
if (apiMatch) {
|
|
379
|
-
variables.API_ENDPOINT = apiMatch[1];
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Extract refresh intervals for dashboards
|
|
384
|
-
if (template.type === 'widget' && lowerDesc.includes('dashboard')) {
|
|
385
|
-
const intervalMatch = description.match(/(?:refresh|update)\s+(?:every|each)\s+(\d+)\s*(?:second|minute)/i);
|
|
386
|
-
if (intervalMatch) {
|
|
387
|
-
let interval = parseInt(intervalMatch[1]);
|
|
388
|
-
if (lowerDesc.includes('minute')) interval *= 60;
|
|
389
|
-
variables.REFRESH_INTERVAL = interval.toString();
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// Apply intelligent defaults based on context
|
|
394
|
-
this.applyIntelligentDefaults(variables, template, description);
|
|
395
|
-
|
|
396
|
-
return variables;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
/**
|
|
400
|
-
* Apply intelligent defaults based on context
|
|
401
|
-
*/
|
|
402
|
-
private applyIntelligentDefaults(variables: TemplateVariables, template: Template, description: string): void {
|
|
403
|
-
const lowerDesc = description.toLowerCase();
|
|
404
|
-
|
|
405
|
-
// Table-specific defaults
|
|
406
|
-
if (variables.TABLE) {
|
|
407
|
-
const table = variables.TABLE as string;
|
|
408
|
-
|
|
409
|
-
// Incident-specific defaults
|
|
410
|
-
if (table === 'incident') {
|
|
411
|
-
variables.PRIORITY_FIELD = variables.PRIORITY_FIELD || 'priority';
|
|
412
|
-
variables.STATE_FIELD = variables.STATE_FIELD || 'state';
|
|
413
|
-
variables.ASSIGNED_TO_FIELD = variables.ASSIGNED_TO_FIELD || 'assigned_to';
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// Request-specific defaults
|
|
417
|
-
if (table.includes('request')) {
|
|
418
|
-
variables.APPROVAL_FIELD = variables.APPROVAL_FIELD || 'approval';
|
|
419
|
-
variables.STAGE_FIELD = variables.STAGE_FIELD || 'stage';
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// Change-specific defaults
|
|
423
|
-
if (table.includes('change')) {
|
|
424
|
-
variables.RISK_FIELD = variables.RISK_FIELD || 'risk';
|
|
425
|
-
variables.CAB_REQUIRED_FIELD = variables.CAB_REQUIRED_FIELD || 'cab_required';
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// Apply ServiceNow best practices
|
|
430
|
-
if (template.type === 'widget') {
|
|
431
|
-
variables.WIDGET_ROLES = variables.WIDGET_ROLES || '';
|
|
432
|
-
variables.MAX_RECORDS = variables.MAX_RECORDS || '100';
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
if (template.type === 'flow') {
|
|
436
|
-
variables.ACTIVE = variables.ACTIVE || 'true';
|
|
437
|
-
variables.RUN_AS = variables.RUN_AS || 'system_user';
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
if (template.type === 'business_rule') {
|
|
441
|
-
variables.ORDER = variables.ORDER || '100';
|
|
442
|
-
variables.ACTIVE = variables.ACTIVE || 'true';
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Create from pattern template
|
|
448
|
-
*/
|
|
449
|
-
async createFromPattern(
|
|
450
|
-
pattern: string,
|
|
451
|
-
variables: TemplateVariables = {}
|
|
452
|
-
): Promise<any> {
|
|
453
|
-
// Load pattern template
|
|
454
|
-
const templatePath = `patterns/${pattern}.template.json`;
|
|
455
|
-
const template = await this.loadTemplate(templatePath);
|
|
456
|
-
|
|
457
|
-
// Apply intelligent defaults
|
|
458
|
-
this.applyIntelligentDefaults(variables, template, '');
|
|
459
|
-
|
|
460
|
-
// Process with variables
|
|
461
|
-
return this.processTemplate(template, variables);
|
|
462
|
-
}
|
|
463
|
-
}
|