@wundr.io/cli 1.0.1 → 1.0.2-dev.20260530174250.ef0ec927

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 (69) hide show
  1. package/bin/wundr.js +13 -5
  2. package/package.json +30 -9
  3. package/src/ai/ai-service.ts +6 -4
  4. package/src/ai/claude-client.ts +6 -2
  5. package/src/ai/conversation-manager.ts +12 -5
  6. package/src/cli.ts +42 -13
  7. package/src/commands/ai.ts +340 -64
  8. package/src/commands/alignment.ts +1212 -0
  9. package/src/commands/analyze-optimized.ts +371 -33
  10. package/src/commands/analyze.ts +8 -6
  11. package/src/commands/batch.ts +166 -26
  12. package/src/commands/chat.ts +20 -10
  13. package/src/commands/claude-init.ts +31 -27
  14. package/src/commands/claude-setup.ts +761 -81
  15. package/src/commands/computer-setup.ts +524 -12
  16. package/src/commands/create-command.ts +3 -3
  17. package/src/commands/create.ts +9 -6
  18. package/src/commands/dashboard.ts +11 -6
  19. package/src/commands/govern.ts +11 -6
  20. package/src/commands/governance.ts +1005 -0
  21. package/src/commands/guardian.ts +887 -0
  22. package/src/commands/init.ts +104 -11
  23. package/src/commands/orchestrator.ts +789 -0
  24. package/src/commands/performance-optimizer.ts +15 -10
  25. package/src/commands/plugins.ts +8 -5
  26. package/src/commands/project-update.ts +1156 -0
  27. package/src/commands/rag.ts +1011 -0
  28. package/src/commands/session.ts +631 -0
  29. package/src/commands/setup.ts +42 -344
  30. package/src/commands/test-init.ts +3 -2
  31. package/src/commands/test.ts +3 -2
  32. package/src/commands/watch.ts +21 -11
  33. package/src/commands/worktree.ts +1057 -0
  34. package/src/context/context-manager.ts +5 -2
  35. package/src/context/session-manager.ts +18 -7
  36. package/src/framework/command-interface.ts +520 -0
  37. package/src/framework/command-registry.ts +942 -0
  38. package/src/framework/completion-exporter.ts +383 -0
  39. package/src/framework/debug-logger.ts +519 -0
  40. package/src/framework/error-handler.ts +867 -0
  41. package/src/framework/help-generator.ts +540 -0
  42. package/src/framework/index.ts +169 -0
  43. package/src/framework/interactive-repl.ts +703 -0
  44. package/src/framework/output-formatter.ts +834 -0
  45. package/src/framework/progress-manager.ts +539 -0
  46. package/src/index.ts +3 -2
  47. package/src/interactive/interactive-mode.ts +14 -7
  48. package/src/lib/conflict-resolution.ts +818 -0
  49. package/src/lib/merge-strategy.ts +550 -0
  50. package/src/lib/safety-mechanisms.ts +451 -0
  51. package/src/lib/state-detection.ts +1030 -0
  52. package/src/nlp/command-mapper.ts +8 -3
  53. package/src/nlp/command-parser.ts +5 -2
  54. package/src/nlp/intent-parser.ts +23 -9
  55. package/src/plugins/plugin-manager.ts +50 -24
  56. package/src/tests/computer-setup-integration.test.ts +46 -15
  57. package/src/types/index.ts +1 -1
  58. package/src/types/modules.d.ts +425 -1
  59. package/src/utils/backup-rollback-manager.ts +19 -14
  60. package/src/utils/claude-config-installer.ts +119 -28
  61. package/src/utils/config-manager.ts +9 -6
  62. package/src/utils/error-handler.ts +3 -1
  63. package/src/utils/logger.ts +35 -12
  64. package/templates/batch/ci-cd.yaml +7 -7
  65. package/test-suites/api/health.spec.ts +20 -23
  66. package/test-suites/helpers/test-config.ts +14 -13
  67. package/test-suites/ui/accessibility.spec.ts +27 -22
  68. package/test-suites/ui/smoke.spec.ts +26 -21
  69. package/src/commands/computer-setup-commands.ts +0 -869
@@ -8,23 +8,23 @@ import AxeBuilder from '@axe-core/playwright';
8
8
  test.describe('Accessibility Tests', () => {
9
9
  test('homepage meets WCAG standards', async ({ page }) => {
10
10
  await page.goto('/');
11
-
11
+
12
12
  const accessibilityScanResults = await new AxeBuilder({ page })
13
13
  .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
14
14
  .analyze();
15
-
15
+
16
16
  expect(accessibilityScanResults.violations).toEqual([]);
17
17
  });
18
18
 
19
19
  test('all images have alt text', async ({ page }) => {
20
20
  await page.goto('/');
21
-
21
+
22
22
  const images = await page.locator('img').all();
23
-
23
+
24
24
  for (const img of images) {
25
25
  const alt = await img.getAttribute('alt');
26
26
  const role = await img.getAttribute('role');
27
-
27
+
28
28
  // Images should have alt text or be marked as decorative
29
29
  expect(alt !== null || role === 'presentation').toBeTruthy();
30
30
  }
@@ -32,18 +32,19 @@ test.describe('Accessibility Tests', () => {
32
32
 
33
33
  test('forms have proper labels', async ({ page }) => {
34
34
  await page.goto('/');
35
-
35
+
36
36
  const inputs = await page.locator('input, select, textarea').all();
37
-
37
+
38
38
  for (const input of inputs) {
39
39
  const id = await input.getAttribute('id');
40
40
  const ariaLabel = await input.getAttribute('aria-label');
41
41
  const ariaLabelledBy = await input.getAttribute('aria-labelledby');
42
-
42
+
43
43
  if (id) {
44
44
  // Check for associated label
45
45
  const label = await page.locator(`label[for="${id}"]`).count();
46
- const hasLabel = label > 0 || ariaLabel !== null || ariaLabelledBy !== null;
46
+ const hasLabel =
47
+ label > 0 || ariaLabel !== null || ariaLabelledBy !== null;
47
48
  expect(hasLabel).toBeTruthy();
48
49
  }
49
50
  }
@@ -51,47 +52,51 @@ test.describe('Accessibility Tests', () => {
51
52
 
52
53
  test('focus is visible and logical', async ({ page }) => {
53
54
  await page.goto('/');
54
-
55
+
55
56
  // Tab through interactive elements
56
57
  await page.keyboard.press('Tab');
57
-
58
+
58
59
  // Check if focused element has visible outline
59
- const focusedElement = await page.evaluateHandle(() => document.activeElement);
60
- const hasOutline = await focusedElement.evaluate((el) => {
60
+ const focusedElement = await page.evaluateHandle(
61
+ () => document.activeElement
62
+ );
63
+ const hasOutline = await focusedElement.evaluate(el => {
61
64
  if (!el) return false;
62
65
  const styles = window.getComputedStyle(el as Element);
63
66
  return styles.outlineStyle !== 'none' || styles.boxShadow !== 'none';
64
67
  });
65
-
68
+
66
69
  expect(hasOutline).toBeTruthy();
67
70
  });
68
71
 
69
72
  test('color contrast meets standards', async ({ page }) => {
70
73
  await page.goto('/');
71
-
74
+
72
75
  const accessibilityScanResults = await new AxeBuilder({ page })
73
76
  .withTags(['color-contrast'])
74
77
  .analyze();
75
-
78
+
76
79
  expect(accessibilityScanResults.violations).toEqual([]);
77
80
  });
78
81
 
79
82
  test('page has proper heading structure', async ({ page }) => {
80
83
  await page.goto('/');
81
-
84
+
82
85
  // Check for h1
83
86
  const h1Count = await page.locator('h1').count();
84
87
  expect(h1Count).toBeGreaterThan(0);
85
-
88
+
86
89
  // Check heading hierarchy
87
90
  const headings = await page.evaluate(() => {
88
- const headingElements = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
91
+ const headingElements = document.querySelectorAll(
92
+ 'h1, h2, h3, h4, h5, h6'
93
+ );
89
94
  return Array.from(headingElements).map(h => ({
90
95
  level: parseInt(h.tagName[1]),
91
- text: h.textContent
96
+ text: h.textContent,
92
97
  }));
93
98
  });
94
-
99
+
95
100
  // Verify no skipped heading levels
96
101
  let previousLevel = 0;
97
102
  for (const heading of headings) {
@@ -99,4 +104,4 @@ test.describe('Accessibility Tests', () => {
99
104
  previousLevel = heading.level;
100
105
  }
101
106
  });
102
- });
107
+ });
@@ -8,8 +8,8 @@ import { test, expect } from '@playwright/test';
8
8
  test.describe('Portable Smoke Tests', () => {
9
9
  test('homepage loads without errors', async ({ page }) => {
10
10
  const jsErrors: string[] = [];
11
-
12
- page.on('pageerror', (error) => {
11
+
12
+ page.on('pageerror', error => {
13
13
  jsErrors.push(error.message);
14
14
  });
15
15
 
@@ -18,31 +18,33 @@ test.describe('Portable Smoke Tests', () => {
18
18
 
19
19
  // Basic structure should be present
20
20
  await expect(page.locator('body')).toBeVisible();
21
-
21
+
22
22
  // Should not have critical JavaScript errors
23
- const criticalErrors = jsErrors.filter(error =>
24
- error.includes('Cannot read') ||
25
- error.includes('undefined is not') ||
26
- error.includes('Uncaught')
23
+ const criticalErrors = jsErrors.filter(
24
+ error =>
25
+ error.includes('Cannot read') ||
26
+ error.includes('undefined is not') ||
27
+ error.includes('Uncaught')
27
28
  );
28
-
29
+
29
30
  expect(criticalErrors.length).toBe(0);
30
31
  });
31
32
 
32
33
  test('navigation elements are present', async ({ page }) => {
33
34
  await page.goto('/');
34
-
35
+
35
36
  // Check for common navigation patterns
36
- const hasNavigation = await page.locator('nav, [role="navigation"], header').count() > 0;
37
+ const hasNavigation =
38
+ (await page.locator('nav, [role="navigation"], header').count()) > 0;
37
39
  expect(hasNavigation).toBeTruthy();
38
40
  });
39
41
 
40
42
  test('interactive elements are clickable', async ({ page }) => {
41
43
  await page.goto('/');
42
-
44
+
43
45
  // Find clickable elements
44
46
  const buttons = await page.locator('button:visible, a:visible').all();
45
-
47
+
46
48
  if (buttons.length > 0) {
47
49
  // Test first button/link
48
50
  const firstElement = buttons[0];
@@ -52,10 +54,10 @@ test.describe('Portable Smoke Tests', () => {
52
54
 
53
55
  test('forms accept input', async ({ page }) => {
54
56
  await page.goto('/');
55
-
57
+
56
58
  // Look for form inputs
57
59
  const inputs = await page.locator('input:visible, textarea:visible').all();
58
-
60
+
59
61
  if (inputs.length > 0) {
60
62
  const firstInput = inputs[0];
61
63
  await firstInput.fill('test');
@@ -66,27 +68,30 @@ test.describe('Portable Smoke Tests', () => {
66
68
 
67
69
  test('responsive layout works', async ({ page }) => {
68
70
  await page.goto('/');
69
-
71
+
70
72
  // Test mobile viewport
71
73
  await page.setViewportSize({ width: 375, height: 667 });
72
-
74
+
73
75
  // Should not have horizontal scroll
74
76
  const hasHorizontalScroll = await page.evaluate(() => {
75
- return document.documentElement.scrollWidth > document.documentElement.clientWidth;
77
+ return (
78
+ document.documentElement.scrollWidth >
79
+ document.documentElement.clientWidth
80
+ );
76
81
  });
77
-
82
+
78
83
  expect(hasHorizontalScroll).toBeFalsy();
79
84
  });
80
85
 
81
86
  test('page has proper metadata', async ({ page }) => {
82
87
  await page.goto('/');
83
-
88
+
84
89
  // Check for title
85
90
  const title = await page.title();
86
91
  expect(title).toBeTruthy();
87
-
92
+
88
93
  // Check for language attribute
89
94
  const lang = await page.locator('html').getAttribute('lang');
90
95
  expect(lang).toBeTruthy();
91
96
  });
92
- });
97
+ });