helm-env-delta 1.5.0 โ 1.6.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/README.md +122 -15
- package/dist/commandLine.d.ts +2 -0
- package/dist/commandLine.js +13 -1
- package/dist/fileDiff.d.ts +1 -0
- package/dist/fileDiff.js +3 -1
- package/dist/index.js +26 -0
- package/dist/suggestionEngine.d.ts +51 -0
- package/dist/suggestionEngine.js +556 -0
- package/dist/utils/index.d.ts +3 -1
- package/dist/utils/index.js +21 -2
- package/dist/utils/regexPatternFileLoader.js +15 -80
- package/dist/utils/suggestionConstants.d.ts +51 -0
- package/dist/utils/suggestionConstants.js +51 -0
- package/dist/utils/transformFileLoader.d.ts +0 -1
- package/dist/utils/transformFileLoader.js +10 -65
- package/dist/utils/yamlFileLoader.d.ts +25 -0
- package/dist/utils/yamlFileLoader.js +79 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -50,6 +50,8 @@ HelmEnvDelta (`hed`) automates environment synchronization for GitOps workflows
|
|
|
50
50
|
|
|
51
51
|
๐ **Discovery Tools** - Preview files (`--list-files`), inspect config (`--show-config`), validate with warnings.
|
|
52
52
|
|
|
53
|
+
๐ก **Smart Suggestions** - Heuristic analysis (`--suggest`) detects patterns and recommends transforms and stop rules automatically. Control sensitivity with `--suggest-threshold`.
|
|
54
|
+
|
|
53
55
|
๐ก๏ธ **Safety First** - Pre-execution summary, first-run tips, improved error messages with helpful examples.
|
|
54
56
|
|
|
55
57
|
โก **High Performance** - 45-60% faster than alternatives with intelligent caching and parallel processing.
|
|
@@ -107,6 +109,17 @@ helm-env-delta --config config.yaml
|
|
|
107
109
|
helm-env-delta --config config.yaml --diff-html
|
|
108
110
|
```
|
|
109
111
|
|
|
112
|
+
### 5๏ธโฃ Get Smart Suggestions (Optional)
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
helm-env-delta --config config.yaml --suggest
|
|
116
|
+
|
|
117
|
+
# Control suggestion sensitivity (0-1, default: 0.3)
|
|
118
|
+
helm-env-delta --config config.yaml --suggest --suggest-threshold 0.7
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Analyzes differences and suggests transforms and stop rules automatically with configurable confidence filtering.
|
|
122
|
+
|
|
110
123
|
**Done!** All files synced, production values preserved, changes validated.
|
|
111
124
|
|
|
112
125
|
---
|
|
@@ -241,6 +254,92 @@ helm-env-delta --config example/5-external-files/config.yaml --dry-run --diff
|
|
|
241
254
|
|
|
242
255
|
---
|
|
243
256
|
|
|
257
|
+
## ๐ก Smart Configuration Suggestions (Heuristic)
|
|
258
|
+
|
|
259
|
+
The `--suggest` flag uses heuristic analysis to examine differences between environments and automatically recommend configuration updates. This intelligent pattern detection helps bootstrap your config by discovering repeated changes and potential safety rules.
|
|
260
|
+
|
|
261
|
+
### How It Works
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
helm-env-delta --config config.yaml --suggest
|
|
265
|
+
|
|
266
|
+
# Control suggestion sensitivity (higher threshold = fewer, higher-confidence suggestions)
|
|
267
|
+
helm-env-delta --config config.yaml --suggest --suggest-threshold 0.7
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**How heuristic analysis works:**
|
|
271
|
+
|
|
272
|
+
- ๐ Intelligently detects repeated value changes across files
|
|
273
|
+
- ๐ฏ Suggests transform patterns (regex find/replace) based on semantic patterns
|
|
274
|
+
- ๐ก๏ธ Recommends stop rules for safety validation using pattern recognition
|
|
275
|
+
- ๐ Provides confidence scores and occurrence counts for each suggestion
|
|
276
|
+
- ๐๏ธ **NEW:** Configurable threshold filters suggestions by confidence level (0-1)
|
|
277
|
+
- ๐ Outputs copy-paste ready YAML configuration
|
|
278
|
+
- โจ **Enhanced noise filtering:**
|
|
279
|
+
- Ignores UUIDs, timestamps, single-character changes
|
|
280
|
+
- Filters antonym pairs (enable/disable, true/false, on/off)
|
|
281
|
+
- Filters regex special characters (unless semantic keywords present)
|
|
282
|
+
- Filters version-number-only changes (service-v1 โ service-v2)
|
|
283
|
+
- Allows semantic patterns even with special chars (db.uat.com โ db.prod.com)
|
|
284
|
+
|
|
285
|
+
### Example Output
|
|
286
|
+
|
|
287
|
+
```yaml
|
|
288
|
+
# Suggested Transforms
|
|
289
|
+
transforms:
|
|
290
|
+
'**/*.yaml':
|
|
291
|
+
content:
|
|
292
|
+
- find: 'uat-cluster'
|
|
293
|
+
replace: 'prod-cluster'
|
|
294
|
+
# Confidence: 95% (42 occurrences across 12 files)
|
|
295
|
+
|
|
296
|
+
# Suggested Stop Rules
|
|
297
|
+
stopRules:
|
|
298
|
+
'**/*.yaml':
|
|
299
|
+
- type: 'semverMajorUpgrade'
|
|
300
|
+
path: 'image.tag'
|
|
301
|
+
# Detected version changes: v1.2.3 โ v2.0.0
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### When to Use
|
|
305
|
+
|
|
306
|
+
- ๐ **First-time setup**: Let heuristics discover patterns automatically instead of manual analysis
|
|
307
|
+
- ๐ **Config refinement**: Find missing transforms or stop rules through smart detection
|
|
308
|
+
- ๐ **Learning tool**: Understand what's changing between environments
|
|
309
|
+
- โก **Quick start**: Bootstrap configuration from existing files using intelligent pattern matching
|
|
310
|
+
- ๐ง **Pattern discovery**: Leverage heuristic algorithms to identify semantic transformations (uatโprod, stagingโproduction)
|
|
311
|
+
- ๐ฏ **Confidence tuning**: Adjust threshold to balance between finding all patterns vs. high-confidence only
|
|
312
|
+
|
|
313
|
+
**Confidence threshold control:**
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# More suggestions (lower threshold = less strict)
|
|
317
|
+
helm-env-delta --config config.yaml --suggest --suggest-threshold 0.2
|
|
318
|
+
|
|
319
|
+
# Default balance (standard heuristics, threshold: 0.3)
|
|
320
|
+
helm-env-delta --config config.yaml --suggest
|
|
321
|
+
|
|
322
|
+
# Only high-confidence (higher threshold = more strict)
|
|
323
|
+
helm-env-delta --config config.yaml --suggest --suggest-threshold 0.8
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Workflow:**
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
# 1. Get suggestions (optionally with custom threshold)
|
|
330
|
+
helm-env-delta --config config.yaml --suggest --suggest-threshold 0.5 > suggestions.yaml
|
|
331
|
+
|
|
332
|
+
# 2. Review and copy relevant sections to config.yaml
|
|
333
|
+
|
|
334
|
+
# 3. Test with dry-run
|
|
335
|
+
helm-env-delta --config config.yaml --dry-run --diff
|
|
336
|
+
|
|
337
|
+
# 4. Execute
|
|
338
|
+
helm-env-delta --config config.yaml
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
244
343
|
## โ๏ธ Configuration Reference
|
|
245
344
|
|
|
246
345
|
### ๐ฏ Core Settings
|
|
@@ -511,21 +610,23 @@ hed --config <file> [options] # Short alias
|
|
|
511
610
|
|
|
512
611
|
### Options
|
|
513
612
|
|
|
514
|
-
| Flag
|
|
515
|
-
|
|
|
516
|
-
| `--config <path>`
|
|
517
|
-
| `--validate`
|
|
518
|
-
| `--
|
|
519
|
-
| `--
|
|
520
|
-
| `--
|
|
521
|
-
| `--
|
|
522
|
-
| `--diff
|
|
523
|
-
| `--
|
|
524
|
-
| `--
|
|
525
|
-
| `--
|
|
526
|
-
| `--
|
|
527
|
-
| `--
|
|
528
|
-
| `--
|
|
613
|
+
| Flag | Description |
|
|
614
|
+
| --------------------------- | ------------------------------------------------- |
|
|
615
|
+
| `--config <path>` | **Required** - Configuration file |
|
|
616
|
+
| `--validate` | Validate config and exit (shows warnings) |
|
|
617
|
+
| `--suggest` | Analyze differences and suggest config updates |
|
|
618
|
+
| `--suggest-threshold <0-1>` | Minimum confidence for suggestions (default: 0.3) |
|
|
619
|
+
| `--dry-run` | Preview changes without writing files |
|
|
620
|
+
| `--force` | Override stop rules |
|
|
621
|
+
| `--diff` | Show console diff |
|
|
622
|
+
| `--diff-html` | Generate HTML report (opens in browser) |
|
|
623
|
+
| `--diff-json` | Output JSON to stdout (pipe to jq) |
|
|
624
|
+
| `--list-files` | List source/destination files without processing |
|
|
625
|
+
| `--show-config` | Display resolved config after inheritance |
|
|
626
|
+
| `--skip-format` | Skip YAML formatting |
|
|
627
|
+
| `--no-color` | Disable colored output (CI/accessibility) |
|
|
628
|
+
| `--verbose` | Show detailed debug info |
|
|
629
|
+
| `--quiet` | Suppress output except errors |
|
|
529
630
|
|
|
530
631
|
### Examples
|
|
531
632
|
|
|
@@ -533,6 +634,12 @@ hed --config <file> [options] # Short alias
|
|
|
533
634
|
# Validate configuration (shows warnings)
|
|
534
635
|
hed --config config.yaml --validate
|
|
535
636
|
|
|
637
|
+
# Get smart configuration suggestions
|
|
638
|
+
hed --config config.yaml --suggest
|
|
639
|
+
|
|
640
|
+
# Get only high-confidence suggestions
|
|
641
|
+
hed --config config.yaml --suggest --suggest-threshold 0.7
|
|
642
|
+
|
|
536
643
|
# Preview files that will be synced
|
|
537
644
|
hed --config config.yaml --list-files
|
|
538
645
|
|
package/dist/commandLine.d.ts
CHANGED
package/dist/commandLine.js
CHANGED
|
@@ -22,6 +22,8 @@ const parseCommandLine = (argv) => {
|
|
|
22
22
|
.option('--validate', 'Validate configuration file and exit', false)
|
|
23
23
|
.option('--list-files', 'List files that would be synced without processing diffs', false)
|
|
24
24
|
.option('--show-config', 'Display resolved configuration after inheritance and exit', false)
|
|
25
|
+
.option('--suggest', 'Analyze differences and suggest transforms and stop rules', false)
|
|
26
|
+
.option('--suggest-threshold <number>', 'Minimum confidence for suggestions (0-1, default: 0.3)', '0.3')
|
|
25
27
|
.option('--no-color', 'Disable colored output')
|
|
26
28
|
.option('--verbose', 'Show detailed debug information', false)
|
|
27
29
|
.option('--quiet', 'Suppress all output except critical errors', false)
|
|
@@ -30,6 +32,9 @@ Examples:
|
|
|
30
32
|
# Preview changes before syncing
|
|
31
33
|
$ helm-env-delta --config config.yaml --dry-run --diff
|
|
32
34
|
|
|
35
|
+
# Get configuration suggestions
|
|
36
|
+
$ helm-env-delta --config config.yaml --suggest
|
|
37
|
+
|
|
33
38
|
# Sync with HTML diff report
|
|
34
39
|
$ helm-env-delta --config config.yaml --diff-html
|
|
35
40
|
|
|
@@ -48,6 +53,11 @@ Documentation: https://github.com/balazscsaba2006/helm-env-delta
|
|
|
48
53
|
console.error('Error: --verbose and --quiet flags are mutually exclusive');
|
|
49
54
|
process.exit(1);
|
|
50
55
|
}
|
|
56
|
+
const threshold = Number.parseFloat(options['suggestThreshold']);
|
|
57
|
+
if (Number.isNaN(threshold) || threshold < 0 || threshold > 1) {
|
|
58
|
+
console.error('Error: --suggest-threshold must be a number between 0 and 1');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
51
61
|
return {
|
|
52
62
|
config: options['config'],
|
|
53
63
|
dryRun: options['dryRun'],
|
|
@@ -61,7 +71,9 @@ Documentation: https://github.com/balazscsaba2006/helm-env-delta
|
|
|
61
71
|
showConfig: options['showConfig'],
|
|
62
72
|
noColor: !options['color'],
|
|
63
73
|
verbose: options['verbose'],
|
|
64
|
-
quiet: options['quiet']
|
|
74
|
+
quiet: options['quiet'],
|
|
75
|
+
suggest: options['suggest'],
|
|
76
|
+
suggestThreshold: threshold
|
|
65
77
|
};
|
|
66
78
|
};
|
|
67
79
|
exports.parseCommandLine = parseCommandLine;
|
package/dist/fileDiff.d.ts
CHANGED
package/dist/fileDiff.js
CHANGED
|
@@ -134,6 +134,7 @@ const processYamlFile = (filePath, sourceContent, destinationContent, skipPath,
|
|
|
134
134
|
processedDestContent: normalizedDestination,
|
|
135
135
|
rawParsedSource: sourceFiltered,
|
|
136
136
|
rawParsedDest: destinationFiltered,
|
|
137
|
+
skipPaths: pathsToSkip,
|
|
137
138
|
normalizedSource,
|
|
138
139
|
normalizedDest: normalizedDestination,
|
|
139
140
|
parsedSource: sourceParsed,
|
|
@@ -165,7 +166,8 @@ const processChangedFiles = (sourceFiles, destinationFiles, skipPath, transforms
|
|
|
165
166
|
processedSourceContent: sourceContent,
|
|
166
167
|
processedDestContent: destinationContent,
|
|
167
168
|
rawParsedSource: sourceContent,
|
|
168
|
-
rawParsedDest: destinationContent
|
|
169
|
+
rawParsedDest: destinationContent,
|
|
170
|
+
skipPaths: []
|
|
169
171
|
});
|
|
170
172
|
}
|
|
171
173
|
return { changedFiles, unchangedFiles };
|
package/dist/index.js
CHANGED
|
@@ -55,6 +55,7 @@ const htmlReporter_1 = require("./htmlReporter");
|
|
|
55
55
|
const jsonReporter_1 = require("./jsonReporter");
|
|
56
56
|
const logger_1 = require("./logger");
|
|
57
57
|
const stopRulesValidator_1 = require("./stopRulesValidator");
|
|
58
|
+
const suggestionEngine_1 = require("./suggestionEngine");
|
|
58
59
|
const collisionDetector_1 = require("./utils/collisionDetector");
|
|
59
60
|
const filenameTransformer_1 = require("./utils/filenameTransformer");
|
|
60
61
|
const versionChecker_1 = require("./utils/versionChecker");
|
|
@@ -147,6 +148,29 @@ const main = async () => {
|
|
|
147
148
|
logger.log(` Changed files: ${diffResult.changedFiles.length}`);
|
|
148
149
|
logger.log(` Unchanged files: ${diffResult.unchangedFiles.length}`);
|
|
149
150
|
}
|
|
151
|
+
if (command.suggest) {
|
|
152
|
+
logger.log('\n' + (0, consoleFormatter_1.formatProgressMessage)('Analyzing differences for suggestions...', 'info'));
|
|
153
|
+
try {
|
|
154
|
+
const suggestions = (0, suggestionEngine_1.analyzeDifferencesForSuggestions)(diffResult, config, command.suggestThreshold);
|
|
155
|
+
const yaml = (0, suggestionEngine_1.formatSuggestionsAsYaml)(suggestions);
|
|
156
|
+
console.log(chalk_1.default.cyan('\n๐ก Suggested Configuration:\n'));
|
|
157
|
+
console.log(yaml);
|
|
158
|
+
if (suggestions.metadata.changedFiles === 0)
|
|
159
|
+
console.log(chalk_1.default.yellow('\nโน๏ธ No changes detected. Files are already in sync.'));
|
|
160
|
+
else {
|
|
161
|
+
console.log(chalk_1.default.dim('\n---'));
|
|
162
|
+
console.log(chalk_1.default.dim('๐ก Tip: Copy relevant sections to your config.yaml and test with --dry-run'));
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
if ((0, suggestionEngine_1.isSuggestionEngineError)(error)) {
|
|
168
|
+
logger.error('\nFailed to generate suggestions: ' + error.message, 'critical');
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
150
174
|
const configFileDirectory = node_path_1.default.dirname(node_path_1.default.resolve(command.config));
|
|
151
175
|
const validationResult = (0, stopRulesValidator_1.validateStopRules)(diffResult, config.stopRules, configFileDirectory, logger);
|
|
152
176
|
if (validationResult.violations.length > 0)
|
|
@@ -204,6 +228,8 @@ const main = async () => {
|
|
|
204
228
|
console.error(error.message);
|
|
205
229
|
else if ((0, jsonReporter_1.isJsonReporterError)(error))
|
|
206
230
|
console.error(error.message);
|
|
231
|
+
else if ((0, suggestionEngine_1.isSuggestionEngineError)(error))
|
|
232
|
+
console.error(error.message);
|
|
207
233
|
else if (error instanceof Error)
|
|
208
234
|
console.error('Unexpected error:', error.message);
|
|
209
235
|
else
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Config, StopRule } from './configFile';
|
|
2
|
+
import { FileDiffResult } from './fileDiff';
|
|
3
|
+
export interface ValuePair {
|
|
4
|
+
oldValue: string;
|
|
5
|
+
targetValue: string;
|
|
6
|
+
path: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TransformSuggestion {
|
|
9
|
+
find: string;
|
|
10
|
+
replace: string;
|
|
11
|
+
confidence: number;
|
|
12
|
+
occurrences: number;
|
|
13
|
+
affectedFiles: string[];
|
|
14
|
+
examples: ValuePair[];
|
|
15
|
+
}
|
|
16
|
+
export interface StopRuleSuggestion {
|
|
17
|
+
rule: StopRule;
|
|
18
|
+
confidence: number;
|
|
19
|
+
reason: string;
|
|
20
|
+
affectedPaths: string[];
|
|
21
|
+
affectedFiles: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface SuggestionResult {
|
|
24
|
+
transforms: Map<string, TransformSuggestion[]>;
|
|
25
|
+
stopRules: Map<string, StopRuleSuggestion[]>;
|
|
26
|
+
metadata: {
|
|
27
|
+
filesAnalyzed: number;
|
|
28
|
+
changedFiles: number;
|
|
29
|
+
timestamp: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
declare const SuggestionEngineErrorClass: {
|
|
33
|
+
new (message: string, options?: import("./utils/errors").ErrorOptions): {
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
readonly code?: string;
|
|
36
|
+
readonly path?: string;
|
|
37
|
+
readonly cause?: Error;
|
|
38
|
+
name: string;
|
|
39
|
+
message: string;
|
|
40
|
+
stack?: string;
|
|
41
|
+
};
|
|
42
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
43
|
+
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
|
|
44
|
+
stackTraceLimit: number;
|
|
45
|
+
};
|
|
46
|
+
export declare class SuggestionEngineError extends SuggestionEngineErrorClass {
|
|
47
|
+
}
|
|
48
|
+
export declare const isSuggestionEngineError: (error: unknown) => error is SuggestionEngineError;
|
|
49
|
+
export declare const analyzeDifferencesForSuggestions: (diffResult: FileDiffResult, config: Config, confidenceThreshold?: number) => SuggestionResult;
|
|
50
|
+
export declare const formatSuggestionsAsYaml: (result: SuggestionResult) => string;
|
|
51
|
+
export {};
|