flagshark 1.3.0 โ 1.3.1
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 +111 -106
- package/dist/cli.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,60 +1,82 @@
|
|
|
1
|
-
# flagshark
|
|
1
|
+
# ๐ฆ flagshark
|
|
2
2
|
|
|
3
|
-
Find stale feature flags in your codebase
|
|
3
|
+
**Find stale feature flags in your codebase.** Polyglot CLI + GitHub Action. 13 languages, 13 providers, zero config.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npx flagshark scan
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
๐ฆ FlagShark v1.
|
|
10
|
+
๐ฆ FlagShark v1.3.0 โ scanned 156 files in 2.3s
|
|
11
|
+
(47 excluded via .flagsharkignore + test-files preset)
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Found 23 feature flags, 7 stale
|
|
13
|
+
Detected providers: LaunchDarkly (Node SDK), Unleash, PostHog
|
|
14
|
+
Found 23 feature flags ยท 7 stale ยท health 70/100 โ ๏ธ
|
|
15
15
|
|
|
16
|
-
Stale flags:
|
|
17
16
|
โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
18
17
|
โ Flag โ File โ Added โ Signal โ
|
|
19
18
|
โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
|
|
20
|
-
โ CHECKOUT_V2 โ src/checkout.ts:47 โ 14 months ago โ
|
|
21
|
-
โ NEW_NAV โ src/layout.tsx:12 โ 8 months ago โ
|
|
22
|
-
โ BETA_SEARCH โ src/search.ts:91 โ 11 months ago โ
|
|
19
|
+
โ CHECKOUT_V2 โ src/checkout.ts:47 โ 14 months ago โ age โ
|
|
20
|
+
โ NEW_NAV โ src/layout.tsx:12 โ 8 months ago โ age, low-usage โ
|
|
21
|
+
โ BETA_SEARCH โ src/search.ts:91 โ 11 months ago โ low-usage โ
|
|
23
22
|
โโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
Exit code: 1 (stale flags found)
|
|
26
25
|
```
|
|
27
26
|
|
|
27
|
+
## Why FlagShark
|
|
28
|
+
|
|
29
|
+
- **Zero install, zero config.** `npx flagshark scan` works on any repo today.
|
|
30
|
+
- **Polyglot.** TypeScript, JavaScript, Go, Python, Java, Kotlin, Swift, Ruby, C#, PHP, Rust, C/C++, Objective-C.
|
|
31
|
+
- **Provider-aware.** Auto-detects 13 flag SDKs โ no custom rules to maintain.
|
|
32
|
+
- **AST-based detection** for TS/JS/Go/Python via [tree-sitter](https://tree-sitter.github.io/). Flag names inside strings, comments, and unrelated calls aren't false positives.
|
|
33
|
+
- **Two staleness signals** โ `git blame` age + single-file usage. Both run automatically.
|
|
34
|
+
- **MIT licensed.** No account, no token, no telemetry.
|
|
35
|
+
|
|
28
36
|
## Install
|
|
29
37
|
|
|
30
38
|
```bash
|
|
31
|
-
#
|
|
39
|
+
# Recommended โ run without installing
|
|
32
40
|
npx flagshark scan
|
|
33
41
|
|
|
34
|
-
# Or
|
|
42
|
+
# Or globally
|
|
35
43
|
npm install -g flagshark
|
|
36
44
|
```
|
|
37
45
|
|
|
38
|
-
|
|
46
|
+
## CLI
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
flagshark scan [options]
|
|
50
|
+
|
|
51
|
+
Scan options:
|
|
52
|
+
--diff <ref> Only scan files changed since this git ref (e.g. main, HEAD~1)
|
|
53
|
+
--threshold <months> Staleness age threshold (default: 6, or config.threshold)
|
|
54
|
+
--verbose Show all stale flags + effective exclude rules
|
|
55
|
+
|
|
56
|
+
Output:
|
|
57
|
+
--json Emit JSON to stdout (stable schema for tooling)
|
|
58
|
+
|
|
59
|
+
Configuration:
|
|
60
|
+
--config <path> Use this config file (overrides .flagshark.yml discovery)
|
|
61
|
+
--no-config Skip .flagshark.yml discovery
|
|
62
|
+
--no-ignore-file Skip .flagsharkignore discovery
|
|
63
|
+
--show-excluded List excluded files in the output
|
|
64
|
+
```
|
|
39
65
|
|
|
40
|
-
|
|
66
|
+
Example invocations:
|
|
41
67
|
|
|
42
68
|
```bash
|
|
43
|
-
# Scan current directory
|
|
69
|
+
# Scan current directory, default 6-month threshold
|
|
44
70
|
flagshark scan
|
|
45
71
|
|
|
46
|
-
#
|
|
47
|
-
flagshark scan --json
|
|
48
|
-
|
|
49
|
-
# Only scan files changed since a git ref
|
|
50
|
-
flagshark scan --diff HEAD~1
|
|
72
|
+
# Scan only files changed since main
|
|
51
73
|
flagshark scan --diff main
|
|
52
74
|
|
|
53
|
-
#
|
|
54
|
-
flagshark scan --threshold 3
|
|
75
|
+
# Stricter threshold + JSON for piping
|
|
76
|
+
flagshark scan --threshold 3 --json | jq '.staleFlags'
|
|
55
77
|
|
|
56
|
-
#
|
|
57
|
-
flagshark scan --
|
|
78
|
+
# Use a custom config file
|
|
79
|
+
flagshark scan --config ./tooling/flagshark.yml
|
|
58
80
|
```
|
|
59
81
|
|
|
60
82
|
### Exit codes
|
|
@@ -63,11 +85,64 @@ flagshark scan --verbose
|
|
|
63
85
|
|------|---------|
|
|
64
86
|
| 0 | No stale flags found |
|
|
65
87
|
| 1 | Stale flags detected |
|
|
66
|
-
| 2 | Runtime error |
|
|
88
|
+
| 2 | Runtime or configuration error |
|
|
67
89
|
|
|
68
|
-
##
|
|
90
|
+
## Configuration
|
|
91
|
+
|
|
92
|
+
FlagShark is zero-config by default. When you want more control, two files compose:
|
|
93
|
+
|
|
94
|
+
### `.flagsharkignore` โ skip files entirely
|
|
95
|
+
|
|
96
|
+
Drop a `.flagsharkignore` at your repo root. Same syntax as `.gitignore`:
|
|
97
|
+
|
|
98
|
+
```gitignore
|
|
99
|
+
examples/
|
|
100
|
+
**/*.test.ts
|
|
101
|
+
**/*_test.go
|
|
102
|
+
**/test_*.py
|
|
103
|
+
!examples/important-flag-test.ts # Re-include with `!`
|
|
104
|
+
```
|
|
69
105
|
|
|
70
|
-
|
|
106
|
+
### `.flagshark.yml` โ full config
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
threshold: 6
|
|
110
|
+
|
|
111
|
+
excludes:
|
|
112
|
+
paths:
|
|
113
|
+
- 'examples/**'
|
|
114
|
+
files:
|
|
115
|
+
- '**/*.test.ts'
|
|
116
|
+
presets:
|
|
117
|
+
- test-files # Curated bundles โ see table below
|
|
118
|
+
- snapshots
|
|
119
|
+
|
|
120
|
+
suppress:
|
|
121
|
+
flags:
|
|
122
|
+
- 'INTERNAL_DEBUG_*' # Don't report these flag names
|
|
123
|
+
- 'PERMANENT_KILLSWITCH'
|
|
124
|
+
|
|
125
|
+
paths: # Per-path threshold overrides
|
|
126
|
+
- match: 'src/critical/**'
|
|
127
|
+
threshold: 3
|
|
128
|
+
- match: 'src/experimental/**'
|
|
129
|
+
threshold: 12
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The unconditional baseline โ `node_modules`, `.git`, `dist`, `build`, `coverage`, `__pycache__`, `vendor`, `.next`, `.turbo` โ is always skipped.
|
|
133
|
+
|
|
134
|
+
### Built-in presets
|
|
135
|
+
|
|
136
|
+
| Preset | Covers |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `test-files` | `*.test.*`, `*.spec.*`, `*_test.go`, `test_*.py`, `*Test.java`, `*_spec.rb`, `__tests__/**`, etc. |
|
|
139
|
+
| `snapshots` | `*.snap`, `__snapshots__/**` |
|
|
140
|
+
| `examples` | `examples/**`, `demo/**` |
|
|
141
|
+
| `stories` | `*.stories.{ts,tsx,js,jsx}` (Storybook) |
|
|
142
|
+
| `fixtures` | `__fixtures__/**`, `fixtures/**` |
|
|
143
|
+
| `generated` | `*.generated.{ts,js}`, `*.gen.go`, `generated/**` |
|
|
144
|
+
|
|
145
|
+
## GitHub Action
|
|
71
146
|
|
|
72
147
|
```yaml
|
|
73
148
|
name: FlagShark
|
|
@@ -83,95 +158,25 @@ jobs:
|
|
|
83
158
|
steps:
|
|
84
159
|
- uses: actions/checkout@v4
|
|
85
160
|
with:
|
|
86
|
-
fetch-depth: 0
|
|
161
|
+
fetch-depth: 0
|
|
87
162
|
- uses: FlagShark/flagshark@v1
|
|
88
163
|
env:
|
|
89
164
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
90
165
|
```
|
|
91
166
|
|
|
92
|
-
|
|
167
|
+
See the [main repo README](https://github.com/FlagShark/flagshark) for action inputs and full docs.
|
|
93
168
|
|
|
94
|
-
|
|
95
|
-
|-------|---------|-------------|
|
|
96
|
-
| `scan` | `changed` | `changed` (PR files only) or `full` (entire repo) |
|
|
97
|
-
| `threshold` | `6` | Staleness threshold in months |
|
|
98
|
-
| `fail-threshold` | `0` | Health score below which the check fails (0 = never fail) |
|
|
169
|
+
## Library usage
|
|
99
170
|
|
|
100
|
-
|
|
171
|
+
Building a tool on top of the engine? Use [`@flagshark/core`](https://www.npmjs.com/package/@flagshark/core) directly:
|
|
101
172
|
|
|
102
|
-
|
|
173
|
+
```ts
|
|
174
|
+
import { scanRepo } from '@flagshark/core'
|
|
103
175
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
```yaml
|
|
107
|
-
- uses: FlagShark/flagshark@v1
|
|
108
|
-
with:
|
|
109
|
-
scan: full
|
|
110
|
-
env:
|
|
111
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
176
|
+
const result = await scanRepo({ cwd: process.cwd(), threshold: 6 })
|
|
177
|
+
console.log(`${result.staleFlags.length} stale of ${result.totalFlags}`)
|
|
112
178
|
```
|
|
113
179
|
|
|
114
|
-
### What the Action does
|
|
115
|
-
|
|
116
|
-
On every PR, FlagShark comments with a table of stale flags:
|
|
117
|
-
|
|
118
|
-
> ### ๐ฆ FlagShark found 3 stale flags
|
|
119
|
-
>
|
|
120
|
-
> | Flag | File | Added | Signal |
|
|
121
|
-
> |------|------|-------|--------|
|
|
122
|
-
> | `CHECKOUT_V2` | src/checkout.ts:47 | 14 months ago | Age > 6 months |
|
|
123
|
-
> | `NEW_NAV` | src/layout.tsx:12 | 8 months ago | Single file |
|
|
124
|
-
>
|
|
125
|
-
> **Flag Health:** 70/100
|
|
126
|
-
|
|
127
|
-
It also sets a GitHub status check that can optionally block merge if health drops below a threshold.
|
|
128
|
-
|
|
129
|
-
## Supported Languages
|
|
130
|
-
|
|
131
|
-
FlagShark detects feature flags across 13 languages:
|
|
132
|
-
|
|
133
|
-
| Language | Extensions |
|
|
134
|
-
|----------|-----------|
|
|
135
|
-
| TypeScript/JavaScript | .ts, .tsx, .js, .jsx, .mjs, .cjs |
|
|
136
|
-
| Go | .go |
|
|
137
|
-
| Python | .py |
|
|
138
|
-
| Java | .java |
|
|
139
|
-
| Kotlin | .kt |
|
|
140
|
-
| Swift | .swift |
|
|
141
|
-
| Ruby | .rb |
|
|
142
|
-
| C# | .cs |
|
|
143
|
-
| PHP | .php |
|
|
144
|
-
| Rust | .rs |
|
|
145
|
-
| C/C++ | .c, .cpp, .h, .hpp |
|
|
146
|
-
| Objective-C | .m |
|
|
147
|
-
|
|
148
|
-
## Supported Providers
|
|
149
|
-
|
|
150
|
-
Auto-detected from imports (no configuration needed):
|
|
151
|
-
|
|
152
|
-
- LaunchDarkly
|
|
153
|
-
- Unleash
|
|
154
|
-
- Flipt
|
|
155
|
-
- Split.io
|
|
156
|
-
- PostHog
|
|
157
|
-
- Flagsmith
|
|
158
|
-
- ConfigCat
|
|
159
|
-
- Statsig
|
|
160
|
-
- GrowthBook
|
|
161
|
-
- DevCycle
|
|
162
|
-
- Eppo
|
|
163
|
-
- Optimizely
|
|
164
|
-
- Custom flag implementations
|
|
165
|
-
|
|
166
|
-
## How Staleness Works
|
|
167
|
-
|
|
168
|
-
A flag is marked stale if **any** of these signals fires:
|
|
169
|
-
|
|
170
|
-
1. **Age:** `git blame` shows the flag reference was added more than 6 months ago (configurable with `--threshold`)
|
|
171
|
-
2. **Single file:** The flag name appears in only one file across the entire repo, suggesting a completed rollout
|
|
172
|
-
|
|
173
|
-
FlagShark only checks files that actually import a flag SDK. A function called `isEnabled()` in a file that doesn't import LaunchDarkly/Unleash/etc. won't be flagged. This prevents false positives.
|
|
174
|
-
|
|
175
180
|
## License
|
|
176
181
|
|
|
177
182
|
MIT
|
package/dist/cli.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flagshark",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Find stale feature flags in your codebase",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"typecheck": "tsc --noEmit"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@flagshark/core": "1.
|
|
25
|
+
"@flagshark/core": "1.3.1",
|
|
26
26
|
"yaml": "^2.4.0",
|
|
27
27
|
"zod": "^3.23.0"
|
|
28
28
|
},
|