snow-flow 3.4.35 → 3.4.39

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.
Files changed (50) hide show
  1. package/README.md +412 -287
  2. package/dist/cli/deploy-artifact.js +2 -2
  3. package/dist/mcp/servicenow-deployment-mcp.js +1 -1
  4. package/dist/mcp/servicenow-mcp-server.js +2 -2
  5. package/dist/mcp/shared/mcp-logger.js +6 -12
  6. package/dist/queen/agent-factory.js +134 -52
  7. package/dist/queen/servicenow-queen.d.ts +127 -2
  8. package/dist/queen/servicenow-queen.js +978 -618
  9. package/dist/services/widget-deployment-service.d.ts +1 -1
  10. package/dist/services/widget-deployment-service.js +1 -1
  11. package/dist/templates/claude-md-template.d.ts +1 -1
  12. package/dist/templates/claude-md-template.js +2 -2
  13. package/dist/types/servicenow.types.d.ts +1 -1
  14. package/dist/utils/dependency-detector.d.ts +1 -1
  15. package/dist/utils/dependency-detector.js +1 -1
  16. package/dist/utils/servicenow-client.d.ts +1 -1
  17. package/dist/utils/servicenow-client.js +4 -8
  18. package/package.json +1 -1
  19. package/website/components/README.md +419 -0
  20. package/website/components/code-display/CodeDisplay.css +583 -0
  21. package/website/components/code-display/CodeDisplay.html +200 -0
  22. package/website/components/code-display/CodeDisplay.js +375 -0
  23. package/website/components/code-display/CodeDisplay.jsx +268 -0
  24. package/website/components/demo/ComponentLibraryDemo.html +845 -0
  25. package/website/components/feature-cards/FeatureCards.css +573 -0
  26. package/website/components/feature-cards/FeatureCards.html +247 -0
  27. package/website/components/feature-cards/FeatureCards.js +382 -0
  28. package/website/components/feature-cards/FeatureCards.jsx +235 -0
  29. package/website/components/hero/Hero.css +558 -0
  30. package/website/components/hero/Hero.html +98 -0
  31. package/website/components/hero/Hero.js +415 -0
  32. package/website/components/hero/Hero.jsx +214 -0
  33. package/website/components/interactive/InteractiveElements.css +776 -0
  34. package/website/components/interactive/InteractiveElements.html +283 -0
  35. package/website/components/interactive/InteractiveElements.js +489 -0
  36. package/website/components/interactive/InteractiveElements.jsx +444 -0
  37. package/website/components/layout/LayoutComponents.css +697 -0
  38. package/website/components/layout/LayoutComponents.html +374 -0
  39. package/website/components/layout/LayoutComponents.js +447 -0
  40. package/website/components/layout/LayoutComponents.jsx +379 -0
  41. package/website/components/navigation/Navigation.css +383 -0
  42. package/website/components/navigation/Navigation.html +89 -0
  43. package/website/components/navigation/Navigation.js +248 -0
  44. package/website/components/navigation/Navigation.jsx +124 -0
  45. package/website/css/animations.css +854 -0
  46. package/website/css/style.css +916 -948
  47. package/website/index.html +394 -424
  48. package/website/js/animations.js +707 -0
  49. package/website/js/main.js +310 -383
  50. package/website/mcp-servers.html +310 -0
@@ -0,0 +1,489 @@
1
+ // Snow-Flow Interactive Elements JavaScript
2
+
3
+ class SnowFlowInteractiveElements {
4
+ constructor(options = {}) {
5
+ this.config = {
6
+ selector: options.selector || '#sf-interactive-demo',
7
+
8
+ // State management
9
+ progress: 65,
10
+ tooltips: new Map(),
11
+
12
+ // Configuration
13
+ rippleDuration: 600,
14
+ tooltipDelay: 300
15
+ };
16
+
17
+ this.elements = {
18
+ container: document.querySelector(this.config.selector),
19
+ buttons: [],
20
+ inputs: [],
21
+ toggles: [],
22
+ progressBars: [],
23
+ tooltips: [],
24
+ spinners: []
25
+ };
26
+
27
+ this.init();
28
+ }
29
+
30
+ init() {
31
+ if (!this.elements.container) {
32
+ console.warn('SnowFlowInteractiveElements: Container not found');
33
+ return;
34
+ }
35
+
36
+ this.initializeButtons();
37
+ this.initializeInputs();
38
+ this.initializeToggles();
39
+ this.initializeProgressBars();
40
+ this.initializeTooltips();
41
+ this.initializeSpecialFeatures();
42
+ }
43
+
44
+ /* ============================================================================
45
+ Button Functionality
46
+ ============================================================================ */
47
+
48
+ initializeButtons() {
49
+ const buttons = this.elements.container.querySelectorAll('.sf-button:not(.sf-button--disabled)');
50
+
51
+ buttons.forEach(button => {
52
+ button.addEventListener('click', (e) => this.handleButtonClick(e, button));
53
+ button.addEventListener('mousedown', (e) => this.createRipple(e, button));
54
+ });
55
+
56
+ this.elements.buttons = Array.from(buttons);
57
+
58
+ // Special loading button
59
+ const loadingBtn = document.getElementById('loading-demo-btn');
60
+ if (loadingBtn) {
61
+ loadingBtn.addEventListener('click', () => this.handleLoadingDemo(loadingBtn));
62
+ }
63
+ }
64
+
65
+ handleButtonClick(event, button) {
66
+ // Prevent disabled button clicks
67
+ if (button.classList.contains('sf-button--disabled') ||
68
+ button.classList.contains('sf-button--loading')) {
69
+ event.preventDefault();
70
+ return;
71
+ }
72
+
73
+ // Custom button actions based on data attributes or IDs
74
+ const variant = button.getAttribute('data-variant');
75
+
76
+ // Optional: Add custom behavior for different button variants
77
+ console.log(`Button clicked: ${variant || 'unknown'}`);
78
+ }
79
+
80
+ createRipple(event, button) {
81
+ if (button.classList.contains('sf-button--disabled')) return;
82
+
83
+ const rect = button.getBoundingClientRect();
84
+ const size = Math.max(rect.width, rect.height);
85
+ const x = event.clientX - rect.left - size / 2;
86
+ const y = event.clientY - rect.top - size / 2;
87
+
88
+ const ripple = document.createElement('span');
89
+ ripple.className = 'sf-button__ripple';
90
+ ripple.style.cssText = `
91
+ left: ${x}px;
92
+ top: ${y}px;
93
+ width: ${size}px;
94
+ height: ${size}px;
95
+ `;
96
+
97
+ button.appendChild(ripple);
98
+
99
+ setTimeout(() => {
100
+ if (ripple.parentNode) {
101
+ ripple.parentNode.removeChild(ripple);
102
+ }
103
+ }, this.config.rippleDuration);
104
+ }
105
+
106
+ handleLoadingDemo(button) {
107
+ if (button.classList.contains('sf-button--loading')) return;
108
+
109
+ // Add loading state
110
+ button.classList.add('sf-button--loading');
111
+ const content = button.querySelector('.sf-button__content');
112
+ const originalText = content.textContent;
113
+
114
+ // Add spinner
115
+ const spinner = document.createElement('span');
116
+ spinner.className = 'sf-button__spinner';
117
+ content.insertBefore(spinner, content.firstChild);
118
+ content.lastChild.textContent = ' Loading...';
119
+
120
+ // Remove loading state after 3 seconds
121
+ setTimeout(() => {
122
+ button.classList.remove('sf-button--loading');
123
+ content.innerHTML = originalText;
124
+ }, 3000);
125
+ }
126
+
127
+ /* ============================================================================
128
+ Input Functionality
129
+ ============================================================================ */
130
+
131
+ initializeInputs() {
132
+ const inputs = this.elements.container.querySelectorAll('.sf-input');
133
+
134
+ inputs.forEach(inputWrapper => {
135
+ const input = inputWrapper.querySelector('.sf-input__field');
136
+ if (!input) return;
137
+
138
+ input.addEventListener('focus', () => this.handleInputFocus(inputWrapper));
139
+ input.addEventListener('blur', () => this.handleInputBlur(inputWrapper));
140
+ input.addEventListener('input', (e) => this.handleInputChange(e, inputWrapper));
141
+ });
142
+
143
+ this.elements.inputs = Array.from(inputs);
144
+ }
145
+
146
+ handleInputFocus(inputWrapper) {
147
+ inputWrapper.classList.add('sf-input--focused');
148
+ }
149
+
150
+ handleInputBlur(inputWrapper) {
151
+ inputWrapper.classList.remove('sf-input--focused');
152
+ }
153
+
154
+ handleInputChange(event, inputWrapper) {
155
+ const input = event.target;
156
+ const value = input.value;
157
+
158
+ // Optional: Add real-time validation
159
+ if (input.type === 'email' && value) {
160
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
161
+ const isValid = emailRegex.test(value);
162
+
163
+ if (isValid) {
164
+ inputWrapper.classList.remove('sf-input--error');
165
+ const errorElement = inputWrapper.querySelector('.sf-input__error');
166
+ if (errorElement) errorElement.remove();
167
+ } else {
168
+ inputWrapper.classList.add('sf-input--error');
169
+ if (!inputWrapper.querySelector('.sf-input__error')) {
170
+ const error = document.createElement('span');
171
+ error.className = 'sf-input__error';
172
+ error.textContent = 'Please enter a valid email address';
173
+ inputWrapper.appendChild(error);
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ /* ============================================================================
180
+ Toggle Functionality
181
+ ============================================================================ */
182
+
183
+ initializeToggles() {
184
+ const toggles = this.elements.container.querySelectorAll('.sf-toggle:not(.sf-toggle--disabled)');
185
+
186
+ toggles.forEach(toggle => {
187
+ const input = toggle.querySelector('.sf-toggle__input');
188
+ if (!input) return;
189
+
190
+ input.addEventListener('change', (e) => this.handleToggleChange(e, toggle));
191
+
192
+ // Keyboard support
193
+ input.addEventListener('keydown', (e) => {
194
+ if (e.key === ' ') {
195
+ e.preventDefault();
196
+ input.click();
197
+ }
198
+ });
199
+ });
200
+
201
+ this.elements.toggles = Array.from(toggles);
202
+ }
203
+
204
+ handleToggleChange(event, toggle) {
205
+ const input = event.target;
206
+ const toggleType = toggle.getAttribute('data-toggle');
207
+
208
+ console.log(`Toggle ${toggleType}: ${input.checked}`);
209
+
210
+ // Special handling for specific toggles
211
+ if (toggleType === 'darkmode') {
212
+ this.handleDarkModeToggle(input.checked);
213
+ }
214
+ }
215
+
216
+ handleDarkModeToggle(enabled) {
217
+ // Optional: Implement dark mode toggle functionality
218
+ console.log(`Dark mode ${enabled ? 'enabled' : 'disabled'}`);
219
+ }
220
+
221
+ /* ============================================================================
222
+ Progress Bar Functionality
223
+ ============================================================================ */
224
+
225
+ initializeProgressBars() {
226
+ const progressBars = this.elements.container.querySelectorAll('.sf-progress');
227
+ this.elements.progressBars = Array.from(progressBars);
228
+
229
+ // Initialize progress controls
230
+ const increaseBtn = document.getElementById('progress-increase');
231
+ const decreaseBtn = document.getElementById('progress-decrease');
232
+
233
+ if (increaseBtn) {
234
+ increaseBtn.addEventListener('click', () => this.changeProgress(10));
235
+ }
236
+
237
+ if (decreaseBtn) {
238
+ decreaseBtn.addEventListener('click', () => this.changeProgress(-10));
239
+ }
240
+ }
241
+
242
+ changeProgress(delta) {
243
+ this.config.progress = Math.min(100, Math.max(0, this.config.progress + delta));
244
+
245
+ const mainProgressBar = this.elements.container.querySelector('[data-progress="main"]');
246
+ if (mainProgressBar) {
247
+ const fill = mainProgressBar.querySelector('.sf-progress__fill');
248
+ const percent = mainProgressBar.querySelector('.sf-progress__percent');
249
+
250
+ if (fill) {
251
+ fill.style.width = `${this.config.progress}%`;
252
+ }
253
+ if (percent) {
254
+ percent.textContent = `${this.config.progress}%`;
255
+ }
256
+ }
257
+ }
258
+
259
+ /* ============================================================================
260
+ Tooltip Functionality
261
+ ============================================================================ */
262
+
263
+ initializeTooltips() {
264
+ const tooltipTriggers = this.elements.container.querySelectorAll('.sf-tooltip-trigger');
265
+
266
+ tooltipTriggers.forEach(trigger => {
267
+ const content = trigger.getAttribute('data-tooltip');
268
+ const position = trigger.getAttribute('data-position') || 'top';
269
+ const triggerType = trigger.getAttribute('data-trigger') || 'hover';
270
+
271
+ if (!content) return;
272
+
273
+ const tooltip = this.createTooltip(content, position);
274
+ this.config.tooltips.set(trigger, { tooltip, position, triggerType });
275
+
276
+ if (triggerType === 'hover') {
277
+ trigger.addEventListener('mouseenter', (e) => this.showTooltip(e, trigger));
278
+ trigger.addEventListener('mouseleave', () => this.hideTooltip(trigger));
279
+ } else if (triggerType === 'click') {
280
+ trigger.addEventListener('click', (e) => this.toggleTooltip(e, trigger));
281
+ }
282
+ });
283
+ }
284
+
285
+ createTooltip(content, position) {
286
+ const tooltip = document.createElement('div');
287
+ tooltip.className = `sf-tooltip sf-tooltip--${position}`;
288
+
289
+ const tooltipContent = document.createElement('div');
290
+ tooltipContent.className = 'sf-tooltip__content';
291
+ tooltipContent.textContent = content;
292
+
293
+ const tooltipArrow = document.createElement('div');
294
+ tooltipArrow.className = 'sf-tooltip__arrow';
295
+
296
+ tooltip.appendChild(tooltipContent);
297
+ tooltip.appendChild(tooltipArrow);
298
+
299
+ document.body.appendChild(tooltip);
300
+ return tooltip;
301
+ }
302
+
303
+ showTooltip(event, trigger) {
304
+ const tooltipData = this.config.tooltips.get(trigger);
305
+ if (!tooltipData) return;
306
+
307
+ const { tooltip, position } = tooltipData;
308
+ const rect = trigger.getBoundingClientRect();
309
+
310
+ // Calculate position
311
+ let x = rect.left + rect.width / 2;
312
+ let y = position === 'top' ? rect.top - 10 : rect.bottom + 10;
313
+
314
+ tooltip.style.left = `${x}px`;
315
+ tooltip.style.top = `${y}px`;
316
+ tooltip.classList.add('sf-tooltip--visible');
317
+ }
318
+
319
+ hideTooltip(trigger) {
320
+ const tooltipData = this.config.tooltips.get(trigger);
321
+ if (!tooltipData) return;
322
+
323
+ tooltipData.tooltip.classList.remove('sf-tooltip--visible');
324
+ }
325
+
326
+ toggleTooltip(event, trigger) {
327
+ event.stopPropagation();
328
+ const tooltipData = this.config.tooltips.get(trigger);
329
+ if (!tooltipData) return;
330
+
331
+ const { tooltip } = tooltipData;
332
+ const isVisible = tooltip.classList.contains('sf-tooltip--visible');
333
+
334
+ // Hide all other click tooltips
335
+ this.config.tooltips.forEach((data, otherTrigger) => {
336
+ if (otherTrigger !== trigger && data.triggerType === 'click') {
337
+ data.tooltip.classList.remove('sf-tooltip--visible');
338
+ }
339
+ });
340
+
341
+ if (isVisible) {
342
+ this.hideTooltip(trigger);
343
+ } else {
344
+ this.showTooltip(event, trigger);
345
+ }
346
+ }
347
+
348
+ /* ============================================================================
349
+ Special Features
350
+ ============================================================================ */
351
+
352
+ initializeSpecialFeatures() {
353
+ // Handle clicks outside tooltips to close them
354
+ document.addEventListener('click', (e) => {
355
+ this.config.tooltips.forEach((data, trigger) => {
356
+ if (data.triggerType === 'click' &&
357
+ !trigger.contains(e.target) &&
358
+ !data.tooltip.contains(e.target)) {
359
+ data.tooltip.classList.remove('sf-tooltip--visible');
360
+ }
361
+ });
362
+ });
363
+
364
+ // Handle keyboard navigation
365
+ document.addEventListener('keydown', (e) => {
366
+ if (e.key === 'Escape') {
367
+ // Close all tooltips on Escape
368
+ this.config.tooltips.forEach((data) => {
369
+ data.tooltip.classList.remove('sf-tooltip--visible');
370
+ });
371
+ }
372
+ });
373
+
374
+ // Handle window resize
375
+ let resizeTimeout;
376
+ window.addEventListener('resize', () => {
377
+ clearTimeout(resizeTimeout);
378
+ resizeTimeout = setTimeout(() => {
379
+ // Hide all tooltips on resize
380
+ this.config.tooltips.forEach((data) => {
381
+ data.tooltip.classList.remove('sf-tooltip--visible');
382
+ });
383
+ }, 250);
384
+ });
385
+ }
386
+
387
+ /* ============================================================================
388
+ Public API Methods
389
+ ============================================================================ */
390
+
391
+ // Button methods
392
+ setButtonLoading(button, loading = true) {
393
+ if (typeof button === 'string') {
394
+ button = document.querySelector(button);
395
+ }
396
+
397
+ if (loading) {
398
+ button.classList.add('sf-button--loading');
399
+ } else {
400
+ button.classList.remove('sf-button--loading');
401
+ }
402
+ }
403
+
404
+ // Input methods
405
+ setInputError(input, error) {
406
+ if (typeof input === 'string') {
407
+ input = document.querySelector(input);
408
+ }
409
+
410
+ const wrapper = input.closest('.sf-input');
411
+ if (!wrapper) return;
412
+
413
+ if (error) {
414
+ wrapper.classList.add('sf-input--error');
415
+ let errorElement = wrapper.querySelector('.sf-input__error');
416
+
417
+ if (!errorElement) {
418
+ errorElement = document.createElement('span');
419
+ errorElement.className = 'sf-input__error';
420
+ wrapper.appendChild(errorElement);
421
+ }
422
+
423
+ errorElement.textContent = error;
424
+ } else {
425
+ wrapper.classList.remove('sf-input--error');
426
+ const errorElement = wrapper.querySelector('.sf-input__error');
427
+ if (errorElement) {
428
+ errorElement.remove();
429
+ }
430
+ }
431
+ }
432
+
433
+ // Toggle methods
434
+ setToggleValue(toggle, checked) {
435
+ if (typeof toggle === 'string') {
436
+ toggle = document.querySelector(toggle);
437
+ }
438
+
439
+ const input = toggle.querySelector('.sf-toggle__input');
440
+ if (input) {
441
+ input.checked = checked;
442
+ }
443
+ }
444
+
445
+ // Progress methods
446
+ setProgress(progressBar, value) {
447
+ if (typeof progressBar === 'string') {
448
+ progressBar = document.querySelector(progressBar);
449
+ }
450
+
451
+ const fill = progressBar.querySelector('.sf-progress__fill');
452
+ const percent = progressBar.querySelector('.sf-progress__percent');
453
+
454
+ if (fill) {
455
+ fill.style.width = `${value}%`;
456
+ }
457
+ if (percent) {
458
+ percent.textContent = `${Math.round(value)}%`;
459
+ }
460
+ }
461
+
462
+ // Cleanup method
463
+ destroy() {
464
+ // Remove all tooltips from DOM
465
+ this.config.tooltips.forEach((data) => {
466
+ if (data.tooltip.parentNode) {
467
+ data.tooltip.parentNode.removeChild(data.tooltip);
468
+ }
469
+ });
470
+
471
+ this.config.tooltips.clear();
472
+ }
473
+ }
474
+
475
+ // Auto-initialize on DOM content loaded
476
+ document.addEventListener('DOMContentLoaded', () => {
477
+ const interactiveDemo = document.getElementById('sf-interactive-demo');
478
+ if (interactiveDemo) {
479
+ window.snowFlowInteractive = new SnowFlowInteractiveElements();
480
+ }
481
+ });
482
+
483
+ // Export for module usage
484
+ if (typeof module !== 'undefined' && module.exports) {
485
+ module.exports = SnowFlowInteractiveElements;
486
+ }
487
+
488
+ // Global access
489
+ window.SnowFlowInteractiveElements = SnowFlowInteractiveElements;