flecto 1.0.2 → 2.1.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/CHANGELOG.md +103 -0
- package/README.md +297 -109
- package/index.js +362 -35
- package/package.json +8 -6
- package/schemas/flecto-envelope-2.0.json +65 -0
- package/schemas/flecto-policy-pack-2.0.json +124 -0
- package/src/alerter.js +11 -10
- package/src/config.js +59 -2
- package/src/differ.js +153 -16
- package/src/envelope.js +6 -4
- package/src/packs/compose.json +45 -0
- package/src/packs/default.json +37 -0
- package/src/packs/node-runtime.json +44 -0
- package/src/packs/strict-prod.json +37 -0
- package/src/parser.js +80 -14
- package/src/policy-test.js +124 -0
- package/src/policy.js +541 -34
- package/src/renderer.js +62 -13
- package/src/watcher.js +28 -11
package/README.md
CHANGED
|
@@ -1,21 +1,56 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/flecto-hero.png" alt="Flecto — semantic config watcher" width="920"/>
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">Flecto</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Config changes, in plain English — with risk flags built in.</strong><br/>
|
|
9
|
+
Watch · Diff · Policy · CI · Webhooks
|
|
10
|
+
</p>
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/flecto"><img alt="npm" src="https://img.shields.io/npm/v/flecto?style=flat-square&color=34d399&labelColor=0b1220"/></a>
|
|
14
|
+
<a href="https://github.com/myselfsiddharth/Flecto/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/myselfsiddharth/Flecto/ci.yml?branch=main&style=flat-square&label=CI&labelColor=0b1220"/></a>
|
|
15
|
+
<a href="LICENSE"><img alt="MIT" src="https://img.shields.io/badge/license-MIT-8fa3bf?style=flat-square&labelColor=0b1220"/></a>
|
|
16
|
+
<a href="https://github.com/myselfsiddharth/Flecto/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/myselfsiddharth/Flecto?style=flat-square&color=fbbf24&labelColor=0b1220"/></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<a href="https://github.com/myselfsiddharth/Flecto/stargazers">⭐ Star this repo</a> if Flecto saves you from a noisy config diff — it helps others find the project.
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img src="docs/assets/flecto-demo.png" alt="Flecto watch demo in the terminal" width="920"/>
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<img src="docs/assets/demo-watch.svg" alt="Animated Flecto watch output" width="920"/>
|
|
29
|
+
</p>
|
|
13
30
|
|
|
14
31
|
---
|
|
15
32
|
|
|
16
|
-
## Why Flecto
|
|
33
|
+
## Why teams use Flecto
|
|
34
|
+
|
|
35
|
+
Line diffs lie about config. Formatting churn, key reorders, and “small” YAML edits hide the changes that actually matter in production.
|
|
36
|
+
|
|
37
|
+
**Flecto** turns structured config into semantic events:
|
|
17
38
|
|
|
18
|
-
|
|
39
|
+
- What changed (`pool_size: 5 → 20`)
|
|
40
|
+
- What was added or removed
|
|
41
|
+
- What looks risky (secrets, dangerous toggles, pool jumps)
|
|
42
|
+
- What to do next (CI gate, webhook, shell command)
|
|
43
|
+
|
|
44
|
+
See the [changelog and migration notes](CHANGELOG.md) for release history and
|
|
45
|
+
upcoming v2.1 behavior changes.
|
|
46
|
+
|
|
47
|
+
> Diff tools compare trees. **Flecto watches, scores risk, and alerts.**
|
|
48
|
+
|
|
49
|
+
| Without Flecto | With Flecto |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `+ 40 lines of YAML noise` | `~ database.pool_size: 5 → 20` |
|
|
52
|
+
| Hope someone notices `debug: true` | Policy finding → CI fails |
|
|
53
|
+
| “Something in `.env` changed” | Exact keys + optional secret masking |
|
|
19
54
|
|
|
20
55
|
---
|
|
21
56
|
|
|
@@ -25,47 +60,61 @@ Standard file watchers tell you *a file changed*. Flecto tells you *what* change
|
|
|
25
60
|
npm install -g flecto
|
|
26
61
|
```
|
|
27
62
|
|
|
28
|
-
|
|
63
|
+
Requires Node.js 20.19.0 or later.
|
|
29
64
|
|
|
30
|
-
|
|
65
|
+
```bash
|
|
66
|
+
flecto --version
|
|
67
|
+
flecto doctor
|
|
68
|
+
```
|
|
31
69
|
|
|
32
|
-
|
|
70
|
+
---
|
|
33
71
|
|
|
34
|
-
|
|
72
|
+
## Quick start
|
|
35
73
|
|
|
36
74
|
```bash
|
|
37
75
|
flecto watch config/prod.yaml
|
|
38
76
|
flecto watch .env
|
|
39
77
|
flecto watch settings.json
|
|
40
78
|
flecto watch pyproject.toml
|
|
79
|
+
flecto watch app.ini
|
|
41
80
|
```
|
|
42
81
|
|
|
43
|
-
That
|
|
82
|
+
That’s it — Flecto prints a clear summary on every meaningful change.
|
|
44
83
|
|
|
45
84
|
---
|
|
46
85
|
|
|
47
|
-
##
|
|
86
|
+
## Features at a glance
|
|
48
87
|
|
|
49
|
-
|
|
88
|
+
- **Semantic diffs** for JSON, YAML, TOML, INI, and dotenv (`.env`, `.env.*`, `*.env`)
|
|
89
|
+
- **Live watch** with optional command + webhook delivery
|
|
90
|
+
- **Policy packs** (`default`, `strict-prod`, `compose`, `node-runtime`) + custom `policies/*.json` + local ESM plugins
|
|
91
|
+
- **CI mode** with JSON / NDJSON / GitHub annotations and fail rules
|
|
92
|
+
- **Snapshots & diffs** for deploy scripts and pre-commit hooks
|
|
93
|
+
- **Profiles** via `--profile` or `FLECTO_PROFILE`
|
|
94
|
+
- **Default array identity** (`id` / `name`, or `--array-id-key`) and secret masking
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Common use cases
|
|
99
|
+
|
|
100
|
+
### Watch multiple files
|
|
50
101
|
|
|
51
102
|
```bash
|
|
52
103
|
flecto watch "config/**/*.yaml" ".env"
|
|
53
104
|
```
|
|
54
105
|
|
|
55
|
-
###
|
|
106
|
+
### Verbose before/after
|
|
56
107
|
|
|
57
108
|
```bash
|
|
58
109
|
flecto watch config/prod.yaml --mode verbose
|
|
59
110
|
```
|
|
60
111
|
|
|
61
|
-
### Ignore noisy keys
|
|
112
|
+
### Ignore noisy keys
|
|
62
113
|
|
|
63
114
|
```bash
|
|
64
115
|
flecto watch config/prod.yaml --ignore "updated_at,meta.timestamp"
|
|
65
116
|
```
|
|
66
117
|
|
|
67
|
-
You can ignore exact keys, entire subtrees, wildcards, or keys anywhere in the file:
|
|
68
|
-
|
|
69
118
|
| Pattern | What it ignores |
|
|
70
119
|
|---|---|
|
|
71
120
|
| `meta.timestamp` | That exact key |
|
|
@@ -73,21 +122,15 @@ You can ignore exact keys, entire subtrees, wildcards, or keys anywhere in the f
|
|
|
73
122
|
| `servers[*].meta.timestamp` | That key inside any array item |
|
|
74
123
|
| `**.updated_at` | Any key named `updated_at`, anywhere |
|
|
75
124
|
|
|
76
|
-
### Run a command
|
|
125
|
+
### Run a command on change
|
|
77
126
|
|
|
78
127
|
```bash
|
|
79
128
|
flecto watch .env --command "docker-compose restart app"
|
|
80
129
|
```
|
|
81
130
|
|
|
82
|
-
|
|
131
|
+
Changes are passed as JSON via `FLECTO_CHANGES` (large payloads may use `FLECTO_CHANGES_FILE`).
|
|
83
132
|
|
|
84
|
-
###
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
flecto watch config/prod.yaml --webhook https://hooks.example.com/notify
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
Add auth headers if needed:
|
|
133
|
+
### Webhooks
|
|
91
134
|
|
|
92
135
|
```bash
|
|
93
136
|
flecto watch config/prod.yaml \
|
|
@@ -95,22 +138,145 @@ flecto watch config/prod.yaml \
|
|
|
95
138
|
--webhook-header "Authorization: Bearer TOKEN"
|
|
96
139
|
```
|
|
97
140
|
|
|
98
|
-
|
|
141
|
+
Envelope shape (`schema_version: "2.0"`):
|
|
99
142
|
|
|
100
143
|
```json
|
|
101
144
|
{
|
|
102
|
-
"schema_version": "
|
|
145
|
+
"schema_version": "2.0",
|
|
103
146
|
"event_id": "uuid",
|
|
104
147
|
"event_type": "changes",
|
|
105
148
|
"emitted_at": "2026-04-14T10:42:31.000Z",
|
|
106
149
|
"file": "/absolute/path/to/config/prod.yaml",
|
|
107
150
|
"changes": [
|
|
108
151
|
{ "type": "changed", "path": "database.pool_size", "before": 5, "after": 20 }
|
|
152
|
+
],
|
|
153
|
+
"policies": [
|
|
154
|
+
{
|
|
155
|
+
"id": "pool-size-jump",
|
|
156
|
+
"severity": "warn",
|
|
157
|
+
"path": "database.pool_size",
|
|
158
|
+
"message": "Pool size increased from 5 to 20 (>=2x).",
|
|
159
|
+
"pack": "default"
|
|
160
|
+
}
|
|
109
161
|
]
|
|
110
162
|
}
|
|
111
163
|
```
|
|
112
164
|
|
|
113
|
-
|
|
165
|
+
JSON Schema: [`schemas/flecto-envelope-2.0.json`](schemas/flecto-envelope-2.0.json).
|
|
166
|
+
|
|
167
|
+
### Policy packs and profiles
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
flecto ci config/prod.yaml --profile prod --snapshot-ref HEAD~1
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"defaults": {
|
|
176
|
+
"policies": ["default"],
|
|
177
|
+
"maskSecrets": false
|
|
178
|
+
},
|
|
179
|
+
"profiles": {
|
|
180
|
+
"prod": {
|
|
181
|
+
"policies": ["default", "strict-prod"],
|
|
182
|
+
"severityRemap": { "pool-size-jump": "error" },
|
|
183
|
+
"maskSecrets": true
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Profile selection: `--profile` > `FLECTO_PROFILE` > defaults.
|
|
190
|
+
Custom packs: `policies/<id>.json`. Plugins: local ESM exporting `evaluate(changes, ctx)`.
|
|
191
|
+
|
|
192
|
+
#### Declarative rule predicates
|
|
193
|
+
|
|
194
|
+
Rules combine their top-level predicates with AND. In addition to `when`, regex
|
|
195
|
+
`match.path`, `afterEquals`, and `numericJump`, packs can use:
|
|
196
|
+
|
|
197
|
+
- `beforeEquals`, `afterIn`, and `beforeIn` for exact values or allowed value lists.
|
|
198
|
+
- `beforeTruthy: true` and `afterTruthy: true` to require a truthy before/after value.
|
|
199
|
+
- `afterMatches` to require a string after value that matches a regular expression.
|
|
200
|
+
- `numericDelta: { "min": 10 }` to match an absolute numeric change of at least 10.
|
|
201
|
+
- `match.pathEquals` and `match.pathPrefix` for exact or prefix path matching without regex.
|
|
202
|
+
- `allOf` and `anyOf` arrays of simple match clauses. Every `allOf` clause and at least
|
|
203
|
+
one `anyOf` clause must match. Clauses support the same value, truthiness, numeric, and
|
|
204
|
+
`match` predicates, but cannot nest composition.
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"id": "risky-feature-enable",
|
|
209
|
+
"severity": "error",
|
|
210
|
+
"allOf": [
|
|
211
|
+
{ "match": { "pathPrefix": "features." } },
|
|
212
|
+
{ "afterTruthy": true }
|
|
213
|
+
],
|
|
214
|
+
"anyOf": [
|
|
215
|
+
{ "afterEquals": true },
|
|
216
|
+
{ "afterIn": ["unsafe", "disabled"] }
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Pack loading fails closed for unknown rule or `match` fields, invalid regexes, and invalid
|
|
222
|
+
predicate shapes, so misspelled predicates cannot silently disable a rule.
|
|
223
|
+
|
|
224
|
+
Use `severityRemap` in defaults or a profile to change pack rule severities without forking a pack:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"profiles": {
|
|
229
|
+
"dev": {
|
|
230
|
+
"severityRemap": { "pool-size-jump": "off" }
|
|
231
|
+
},
|
|
232
|
+
"prod": {
|
|
233
|
+
"severityRemap": { "pool-size-jump": "error" }
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Each key is a rule id and each value must be `info`, `warn`, `error`, or `off`. The remap applies after all configured built-in and local packs load, before findings and CI `--fail-on` checks. When multiple packs provide the same rule id, the remap applies to every matching pack rule. Plugin findings are unchanged. Unknown rule ids print a warning instead of being ignored silently.
|
|
240
|
+
|
|
241
|
+
Authoring guides: [policy packs](docs/policy-packs.md) · [plugins](docs/plugins.md) · [plugin cookbook](docs/plugin-cookbook.md).
|
|
242
|
+
|
|
243
|
+
### Discover policy packs
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
flecto policies list
|
|
247
|
+
flecto policies list --json
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The command lists every bundled and local pack that resolves from the current
|
|
251
|
+
working directory, including its source path and rule count. For a given pack
|
|
252
|
+
id, Flecto resolves local files before bundled packs in this order:
|
|
253
|
+
`policies/<id>.json`, `policies/<id>.yaml`, `policies/<id>.yml`, then the
|
|
254
|
+
built-in pack. A local pack with the same id overrides its built-in counterpart.
|
|
255
|
+
|
|
256
|
+
### Array identity matching
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
flecto watch config/services.yaml
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Arrays of objects automatically match by a shared, unique `id` key, falling back
|
|
263
|
+
to `name` when `id` is unavailable. This avoids false changes when named items
|
|
264
|
+
are reordered. Use a custom identity field when needed:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
flecto watch config/services.yaml --array-id-key serviceKey
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
To restore index-based diffs for every array, pass `--no-array-id`:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
flecto watch config/services.yaml --no-array-id
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
In `.flectorc`, set `"arrayId": false` in `defaults` or a profile for the same
|
|
277
|
+
escape hatch.
|
|
278
|
+
|
|
279
|
+
### Command + webhook together
|
|
114
280
|
|
|
115
281
|
```bash
|
|
116
282
|
flecto watch .env \
|
|
@@ -129,37 +295,26 @@ flecto watch config/prod.yaml \
|
|
|
129
295
|
|
|
130
296
|
| Flag | Options | What it does |
|
|
131
297
|
|---|---|---|
|
|
132
|
-
| `--delivery-mode` | `best-effort` (default), `at-least-once` |
|
|
133
|
-
| `--on-alert-failure` | `warn`, `exit`, `retry` |
|
|
298
|
+
| `--delivery-mode` | `best-effort` (default), `at-least-once` | Persist and retry failed webhook events |
|
|
299
|
+
| `--on-alert-failure` | `warn`, `exit`, `retry` | Behavior when command/webhook fails |
|
|
134
300
|
|
|
135
301
|
---
|
|
136
302
|
|
|
137
|
-
## Snapshots &
|
|
138
|
-
|
|
139
|
-
Save a baseline snapshot of your file:
|
|
303
|
+
## Snapshots & diffs
|
|
140
304
|
|
|
141
305
|
```bash
|
|
142
306
|
flecto watch config/prod.yaml --snapshot
|
|
143
|
-
# Saved to .flecto-snapshots/<id>.json
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Then compare the current file against it anytime:
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
307
|
flecto watch config/prod.yaml --diff
|
|
308
|
+
flecto history config/prod.yaml --limit 10
|
|
150
309
|
```
|
|
151
310
|
|
|
152
|
-
Exit codes:
|
|
153
|
-
- `0` — no changes (file is clean)
|
|
154
|
-
- `1` — changes detected
|
|
311
|
+
Exit codes: `0` clean · `1` changes detected.
|
|
155
312
|
|
|
156
|
-
|
|
313
|
+
`flecto history` stays local: it lists recent snapshots from `.flecto-snapshots/` with their timestamps and semantic change counts from the previous snapshot. Counts use the same ignore paths, array identity, and order settings as `flecto watch --diff` (CLI flags or `.flectorc`). Omit files to view all saved snapshot history.
|
|
157
314
|
|
|
158
315
|
---
|
|
159
316
|
|
|
160
|
-
## CI
|
|
161
|
-
|
|
162
|
-
Catch risky config changes before they ship:
|
|
317
|
+
## CI mode
|
|
163
318
|
|
|
164
319
|
```bash
|
|
165
320
|
flecto ci "config/**/*.yaml" \
|
|
@@ -168,49 +323,84 @@ flecto ci "config/**/*.yaml" \
|
|
|
168
323
|
--fail-on "changed,policy,error"
|
|
169
324
|
```
|
|
170
325
|
|
|
171
|
-
**
|
|
326
|
+
**Formats:** `json`, `ndjson`, `github-annotations`
|
|
327
|
+
**Fail triggers:** `changed`, `added`, `removed`, `policy`, `error`, `warn`
|
|
328
|
+
Unresolved `--snapshot-ref` fails closed (no silent empty baseline).
|
|
329
|
+
If every target is missing or unsupported, `flecto ci` and `flecto watch --snapshot` exit non-zero (pass `--allow-empty` to opt out).
|
|
330
|
+
|
|
331
|
+
### GitHub Action
|
|
172
332
|
|
|
173
|
-
|
|
333
|
+
Use the [Flecto CI Action](.github/actions/flecto-ci/action.yml) to run `flecto ci` in a workflow with GitHub annotations enabled by default. A complete local-action workflow is available at [`examples/github-action/flecto-ci.yml`](examples/github-action/flecto-ci.yml).
|
|
334
|
+
|
|
335
|
+
```yaml
|
|
336
|
+
permissions:
|
|
337
|
+
contents: read
|
|
338
|
+
|
|
339
|
+
steps:
|
|
340
|
+
- uses: actions/checkout@v7
|
|
341
|
+
with:
|
|
342
|
+
fetch-depth: 2
|
|
343
|
+
- uses: myselfsiddharth/Flecto/.github/actions/flecto-ci@main
|
|
344
|
+
with:
|
|
345
|
+
targets: config/**/*.{yaml,yml,json,toml,ini}
|
|
346
|
+
snapshot-ref: HEAD~1
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
`contents: read` is required by `actions/checkout`. The Action emits workflow-command annotations and needs no write permissions. Keep `fetch-depth: 2` (or use `fetch-depth: 0`) when using the default `HEAD~1` baseline.
|
|
350
|
+
|
|
351
|
+
| Input | Default | Description |
|
|
352
|
+
|---|---|---|
|
|
353
|
+
| `targets` | `config/**/*.{yaml,yml,json,toml,ini}` | Whitespace-separated paths or glob patterns to check |
|
|
354
|
+
| `fail-on` | `policy,error` | Comma-separated events that fail the job |
|
|
355
|
+
| `policies` | _(empty)_ | Comma-separated policy pack IDs; omit to use `.flectorc` / Flecto defaults |
|
|
356
|
+
| `profile` | _(empty)_ | Optional `.flectorc` profile |
|
|
357
|
+
| `format` | `github-annotations` | Flecto output format |
|
|
358
|
+
| `snapshot-ref` | `HEAD~1` | Git ref or snapshot file used as the baseline |
|
|
359
|
+
| `node-version` | `20` | Node.js version used to run Flecto |
|
|
360
|
+
|
|
361
|
+
The Action runs `npx --yes flecto@2 ci`: the major version is pinned so compatible Flecto updates are received. For fully reproducible builds, pin the Action reference to a commit SHA and replace `@2` in a forked Action with an exact published Flecto version.
|
|
174
362
|
|
|
175
363
|
---
|
|
176
364
|
|
|
177
|
-
## Built-in
|
|
365
|
+
## Built-in policy checks
|
|
178
366
|
|
|
179
|
-
|
|
367
|
+
Built-in pack ids:
|
|
180
368
|
|
|
181
|
-
-
|
|
182
|
-
-
|
|
183
|
-
-
|
|
369
|
+
- `default` — secrets, dangerous toggles, and pool-size jumps.
|
|
370
|
+
- `strict-prod` — stricter severities and matching for production use.
|
|
371
|
+
- `compose` — privileged services, host networking, Docker socket mounts, and sensitive host-directory bind mounts.
|
|
372
|
+
- `node-runtime` — removed Node.js engine requirements, TLS verification bypasses, and enabled Node debugging or inspector options.
|
|
184
373
|
|
|
185
|
-
|
|
374
|
+
Fail CI with `--fail-on policy`.
|
|
186
375
|
|
|
187
376
|
---
|
|
188
377
|
|
|
189
|
-
##
|
|
378
|
+
## Migrating from envelope 1.1
|
|
190
379
|
|
|
191
|
-
|
|
380
|
+
- `schema_version` is now `"2.0"`
|
|
381
|
+
- Type name is `FlectoEnvelope` (docs/types)
|
|
382
|
+
- New `policies` array on change envelopes
|
|
383
|
+
- Webhook headers unchanged (`X-Flecto-*`)
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Tuning for network drives / odd editors
|
|
192
388
|
|
|
193
389
|
```bash
|
|
194
390
|
flecto watch config/prod.yaml --polling --interval 500
|
|
195
391
|
```
|
|
196
392
|
|
|
197
|
-
|
|
393
|
+
Polling is off by default (interval default `100ms` when enabled).
|
|
198
394
|
|
|
199
395
|
---
|
|
200
396
|
|
|
201
|
-
## Config
|
|
202
|
-
|
|
203
|
-
Set your defaults once so you don't have to repeat flags every time.
|
|
204
|
-
|
|
205
|
-
Generate a starter config:
|
|
397
|
+
## Config file (`.flectorc`)
|
|
206
398
|
|
|
207
399
|
```bash
|
|
208
400
|
flecto init
|
|
209
401
|
```
|
|
210
402
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
Example:
|
|
403
|
+
Looks for `.flectorc`, `.flectorc.json`, `.flectorc.yaml`, or `.flectorc.yml`.
|
|
214
404
|
|
|
215
405
|
```json
|
|
216
406
|
{
|
|
@@ -219,35 +409,35 @@ Example:
|
|
|
219
409
|
"interval": 100,
|
|
220
410
|
"ignore": ["**.updated_at"],
|
|
221
411
|
"deliveryMode": "best-effort",
|
|
222
|
-
"onAlertFailure": "warn"
|
|
412
|
+
"onAlertFailure": "warn",
|
|
413
|
+
"policies": ["default"],
|
|
414
|
+
"arrayId": true
|
|
223
415
|
},
|
|
224
416
|
"profiles": {
|
|
225
417
|
"dev": { "mode": "verbose" },
|
|
226
|
-
"ci": { "failOn": "policy,error" }
|
|
418
|
+
"ci": { "failOn": "policy,error" },
|
|
419
|
+
"prod": {
|
|
420
|
+
"policies": ["default", "strict-prod"],
|
|
421
|
+
"severityRemap": { "pool-size-jump": "error" },
|
|
422
|
+
"maskSecrets": true
|
|
423
|
+
}
|
|
227
424
|
},
|
|
228
|
-
"files": ["config/**/*.yaml", ".env"],
|
|
425
|
+
"files": ["config/**/*.{yaml,yml,json,toml,ini}", ".env", ".env.*", "*.env"],
|
|
229
426
|
"exclude": ["**/node_modules/**"]
|
|
230
427
|
}
|
|
231
428
|
```
|
|
232
429
|
|
|
233
|
-
Use a named profile:
|
|
234
|
-
|
|
235
430
|
```bash
|
|
236
431
|
flecto watch --profile dev
|
|
237
432
|
flecto ci --profile ci
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
CLI flags always override profile/default values.
|
|
241
|
-
|
|
242
|
-
Verify your setup:
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
433
|
flecto doctor
|
|
246
434
|
```
|
|
247
435
|
|
|
436
|
+
CLI flags override profile/default values.
|
|
437
|
+
|
|
248
438
|
---
|
|
249
439
|
|
|
250
|
-
## Output
|
|
440
|
+
## Output format reference
|
|
251
441
|
|
|
252
442
|
### Compact (default)
|
|
253
443
|
|
|
@@ -265,47 +455,45 @@ flecto doctor
|
|
|
265
455
|
~ path
|
|
266
456
|
before: old_value
|
|
267
457
|
after: new_value
|
|
268
|
-
+ path: value
|
|
269
|
-
(key added)
|
|
270
458
|
```
|
|
271
459
|
|
|
272
460
|
---
|
|
273
461
|
|
|
274
|
-
## Error
|
|
275
|
-
|
|
276
|
-
Flecto is designed to keep running even when things go wrong:
|
|
462
|
+
## Error handling
|
|
277
463
|
|
|
278
464
|
| Situation | Behavior |
|
|
279
465
|
|---|---|
|
|
280
|
-
| File not found | Error
|
|
281
|
-
| Unsupported
|
|
282
|
-
|
|
|
283
|
-
| Command fails | Warning
|
|
284
|
-
|
|
|
285
|
-
| Ctrl+C | Clean shutdown message |
|
|
466
|
+
| File not found | Error + exit 1 |
|
|
467
|
+
| Unsupported format | Lists supported extensions + exit 1 |
|
|
468
|
+
| Parse error while watching | Warning, last valid state kept |
|
|
469
|
+
| Command / webhook fails | Warning (unless `--on-alert-failure exit`) |
|
|
470
|
+
| Ctrl+C | Clean shutdown |
|
|
286
471
|
|
|
287
472
|
---
|
|
288
473
|
|
|
289
|
-
##
|
|
474
|
+
## How it works
|
|
290
475
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
476
|
+
1. **Parser** — format by extension / dotenv naming → structured values
|
|
477
|
+
2. **Watcher** — [chokidar](https://github.com/paulmillr/chokidar) + debounce
|
|
478
|
+
3. **Differ** — semantic tree diff (objects, arrays, ignore rules, automatic array ids)
|
|
479
|
+
4. **Policy engine** — packs + plugins → severity findings
|
|
480
|
+
5. **Envelope** — versioned automation payload (`2.0`)
|
|
481
|
+
6. **Alerter** — command and/or webhook with retry modes
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## Contributing
|
|
486
|
+
|
|
487
|
+
Flecto is open source. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, PR rules, and review expectations.
|
|
488
|
+
Please read the [Code of Conduct](CODE_OF_CONDUCT.md) and [Security policy](SECURITY.md).
|
|
296
489
|
|
|
297
|
-
|
|
490
|
+
Roadmap lives in [GitHub milestones](https://github.com/myselfsiddharth/Flecto/milestones).
|
|
298
491
|
|
|
299
492
|
---
|
|
300
493
|
|
|
301
|
-
##
|
|
494
|
+
## Star the project
|
|
302
495
|
|
|
303
|
-
|
|
304
|
-
2. **Watcher** — uses [chokidar](https://github.com/paulmillr/chokidar) with debouncing so rapid saves don't flood you with events.
|
|
305
|
-
3. **Differ** — computes a semantic diff (not a line diff), supporting objects, arrays, scalars, and ignore rules.
|
|
306
|
-
4. **Policy engine** — inspects the changes for patterns that look risky and adds severity findings.
|
|
307
|
-
5. **Envelope** — wraps each batch of changes in a versioned event schema ready for automation.
|
|
308
|
-
6. **Alerter** — delivers events via command execution and/or webhook, with configurable retry logic.
|
|
496
|
+
If Flecto helps your team catch a risky config change — **[star the repo](https://github.com/myselfsiddharth/Flecto)** so more people can find it.
|
|
309
497
|
|
|
310
498
|
---
|
|
311
499
|
|