@vatzzza/botintern 1.0.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.
@@ -0,0 +1,130 @@
1
+ import chalk from "chalk";
2
+ import fs from "fs";
3
+ import path from "path";
4
+
5
+ /**
6
+ * Validates YAML structure and checks for common issues
7
+ */
8
+ export function validateYamlStructure(yaml) {
9
+ const requiredSections = ['meta', 'scenarios'];
10
+ const lines = yaml.split('\n');
11
+
12
+ // Check for invalid keys that should be preserved from original
13
+ const invalidKeys = ['actions', 'assert_visible', 'assert_text', 'selector'];
14
+ const foundInvalidKeys = [];
15
+
16
+ for (const line of lines) {
17
+ for (const key of invalidKeys) {
18
+ if (line.includes(`${key}:`) || line.includes(`${key} `)) {
19
+ foundInvalidKeys.push(key);
20
+ }
21
+ }
22
+ }
23
+
24
+ return {
25
+ isValid: foundInvalidKeys.length === 0,
26
+ invalidKeys: foundInvalidKeys,
27
+ hasRequiredSections: requiredSections.some(section => yaml.includes(`${section}:`)),
28
+ lineCount: lines.length
29
+ };
30
+ }
31
+
32
+ /**
33
+ * Creates a timestamped backup of the YAML file
34
+ */
35
+ export function createBackup(filePath, content) {
36
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
37
+ const backupPath = filePath.replace('.yaml', `.backup.${timestamp}.yaml`);
38
+ fs.writeFileSync(backupPath, content);
39
+ return backupPath;
40
+ }
41
+
42
+ /**
43
+ * Performs safe YAML update preserving working sections
44
+ */
45
+ export function safeYamlUpdate(originalYaml, newYaml) {
46
+ // Preserve meta section completely unless user specifically asks to change it
47
+ const originalMeta = originalYaml.match(/meta:([\s\S]*?)(?=\n\w+:|$)/);
48
+ const newMeta = newYaml.match(/meta:([\s\S]*?)(?=\n\w+:|$)/);
49
+
50
+ let finalYaml = newYaml;
51
+
52
+ // If original has meta and new doesn't have baseUrl changes, preserve original
53
+ if (originalMeta && !newYaml.includes('baseUrl:')) {
54
+ finalYaml = newYaml.replace(/meta:([\s\S]*?)(?=\n\w+:|$)/, originalMeta[0]);
55
+ }
56
+
57
+ return finalYaml;
58
+ }
59
+
60
+ /**
61
+ * Calculates diff between original and new YAML to validate changes
62
+ */
63
+ export function calculateYamlDiff(original, updated) {
64
+ if (!original || !original.trim()) {
65
+ return {
66
+ changes: updated ? ['Full file created'] : [],
67
+ isMinimal: false,
68
+ changePercentage: 100
69
+ };
70
+ }
71
+
72
+ const originalLines = original.split('\n').filter(line => line.trim());
73
+ const updatedLines = updated.split('\n').filter(line => line.trim());
74
+
75
+ const unchanged = [];
76
+ const modified = [];
77
+ const added = [];
78
+ const removed = [];
79
+
80
+ // Simple diff analysis
81
+ for (const line of updatedLines) {
82
+ if (originalLines.includes(line)) {
83
+ unchanged.push(line);
84
+ } else {
85
+ added.push(line);
86
+ }
87
+ }
88
+
89
+ for (const line of originalLines) {
90
+ if (!updatedLines.includes(line)) {
91
+ removed.push(line);
92
+ }
93
+ }
94
+
95
+ const totalLines = Math.max(originalLines.length, updatedLines.length);
96
+ const changePercentage = totalLines > 0 ? ((added.length + removed.length) / totalLines) * 100 : 0;
97
+
98
+ return {
99
+ changes: [
100
+ ...added.map(line => `+ ${line}`),
101
+ ...removed.map(line => `- ${line}`)
102
+ ],
103
+ isMinimal: changePercentage < 50, // Consider minimal if less than 50% changed
104
+ changePercentage,
105
+ stats: {
106
+ total: totalLines,
107
+ unchanged: unchanged.length,
108
+ added: added.length,
109
+ removed: removed.length
110
+ }
111
+ };
112
+ }
113
+
114
+ /**
115
+ * Validates that changes are minimal and necessary
116
+ */
117
+ export function validateMinimalChanges(original, updated, userPrompt) {
118
+ const diff = calculateYamlDiff(original, updated);
119
+
120
+ // If user provided specific prompt, allow more changes
121
+ const maxChangePercentage = userPrompt && userPrompt.trim() ? 75 : 30;
122
+
123
+ return {
124
+ isValid: diff.isMinimal || diff.changePercentage <= maxChangePercentage,
125
+ diff,
126
+ recommendation: diff.changePercentage > maxChangePercentage
127
+ ? `🚨 Large change detected: ${diff.changePercentage.toFixed(1)}% modified. Consider more targeted edits.`
128
+ : `✅ Minimal changes: ${diff.changePercentage.toFixed(1)}% modified.`
129
+ };
130
+ }