@flagshark/core 2.0.0 → 2.1.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.
Files changed (68) hide show
  1. package/README.md +2 -0
  2. package/dist/config/schema.d.ts +112 -0
  3. package/dist/config/schema.d.ts.map +1 -1
  4. package/dist/config/schema.js +63 -0
  5. package/dist/config/schema.js.map +1 -1
  6. package/dist/detection/detectors/typescript.d.ts.map +1 -1
  7. package/dist/detection/detectors/typescript.js +41 -0
  8. package/dist/detection/detectors/typescript.js.map +1 -1
  9. package/dist/detection/feature-flag.d.ts +28 -0
  10. package/dist/detection/feature-flag.d.ts.map +1 -1
  11. package/dist/detection/helpers.d.ts +16 -0
  12. package/dist/detection/helpers.d.ts.map +1 -1
  13. package/dist/detection/helpers.js +117 -6
  14. package/dist/detection/helpers.js.map +1 -1
  15. package/dist/detection/import-graph.d.ts +234 -0
  16. package/dist/detection/import-graph.d.ts.map +1 -0
  17. package/dist/detection/import-graph.js +641 -0
  18. package/dist/detection/import-graph.js.map +1 -0
  19. package/dist/detection/interface.d.ts +57 -0
  20. package/dist/detection/interface.d.ts.map +1 -1
  21. package/dist/detection/interface.js.map +1 -1
  22. package/dist/detection/polyglot-analyzer.d.ts +8 -0
  23. package/dist/detection/polyglot-analyzer.d.ts.map +1 -1
  24. package/dist/detection/polyglot-analyzer.js +2 -0
  25. package/dist/detection/polyglot-analyzer.js.map +1 -1
  26. package/dist/detection/tree-sitter/engine.d.ts.map +1 -1
  27. package/dist/detection/tree-sitter/engine.js +62 -15
  28. package/dist/detection/tree-sitter/engine.js.map +1 -1
  29. package/dist/detection/tree-sitter/parser-cache.d.ts +20 -0
  30. package/dist/detection/tree-sitter/parser-cache.d.ts.map +1 -1
  31. package/dist/detection/tree-sitter/parser-cache.js +32 -1
  32. package/dist/detection/tree-sitter/parser-cache.js.map +1 -1
  33. package/dist/output/json.d.ts.map +1 -1
  34. package/dist/output/json.js +28 -0
  35. package/dist/output/json.js.map +1 -1
  36. package/dist/output/markdown.d.ts.map +1 -1
  37. package/dist/output/markdown.js +47 -1
  38. package/dist/output/markdown.js.map +1 -1
  39. package/dist/output/text.d.ts.map +1 -1
  40. package/dist/output/text.js +89 -0
  41. package/dist/output/text.js.map +1 -1
  42. package/dist/providers/cross-reference.d.ts +36 -2
  43. package/dist/providers/cross-reference.d.ts.map +1 -1
  44. package/dist/providers/cross-reference.js +102 -7
  45. package/dist/providers/cross-reference.js.map +1 -1
  46. package/dist/providers/interface.d.ts +116 -2
  47. package/dist/providers/interface.d.ts.map +1 -1
  48. package/dist/providers/launchdarkly/client.d.ts +12 -0
  49. package/dist/providers/launchdarkly/client.d.ts.map +1 -1
  50. package/dist/providers/launchdarkly/client.js +243 -24
  51. package/dist/providers/launchdarkly/client.js.map +1 -1
  52. package/dist/providers/launchdarkly/types.d.ts +318 -0
  53. package/dist/providers/launchdarkly/types.d.ts.map +1 -1
  54. package/dist/providers/launchdarkly/types.js +82 -0
  55. package/dist/providers/launchdarkly/types.js.map +1 -1
  56. package/dist/providers/orchestrate.d.ts +34 -2
  57. package/dist/providers/orchestrate.d.ts.map +1 -1
  58. package/dist/providers/orchestrate.js +59 -7
  59. package/dist/providers/orchestrate.js.map +1 -1
  60. package/dist/scan-repo.d.ts +28 -0
  61. package/dist/scan-repo.d.ts.map +1 -1
  62. package/dist/scan-repo.js +290 -4
  63. package/dist/scan-repo.js.map +1 -1
  64. package/dist/staleness.d.ts +31 -1
  65. package/dist/staleness.d.ts.map +1 -1
  66. package/dist/staleness.js +66 -10
  67. package/dist/staleness.js.map +1 -1
  68. package/package.json +2 -1
package/README.md CHANGED
@@ -4,6 +4,8 @@ The detection engine behind [FlagShark](https://github.com/FlagShark/flagshark)
4
4
 
5
5
  This is the **library**. For a CLI or GitHub Action, install [`flagshark`](https://www.npmjs.com/package/flagshark) instead.
6
6
 
7
+ 📚 **Library documentation: [flagshark.com/docs/getting-started/library](https://flagshark.com/docs/getting-started/library/)**
8
+
7
9
  ## Install
8
10
 
9
11
  ```bash
@@ -75,6 +75,70 @@ export declare const CustomProviderSchema: z.ZodObject<{
75
75
  importPattern?: string | undefined;
76
76
  enabled?: boolean | undefined;
77
77
  }>;
78
+ /**
79
+ * Escape hatch for typed config-struct flag systems (B3).
80
+ *
81
+ * Codebases like Mattermost don't use an SDK — flags are typed fields on a
82
+ * configuration struct:
83
+ *
84
+ * if (server.Config().FeatureFlags.EnableSharedChannelsMemberSync) { ... }
85
+ *
86
+ * There's no `import 'unleash-client'`, no `client.variation(...)`, no string
87
+ * literal flag key. The standard import-gated detection model returns 0 on
88
+ * these codebases because none of its preconditions hold (see the
89
+ * design spec at docs/superpowers/specs/2026-05-24-static-config-flag-detection.md).
90
+ *
91
+ * Users opt in by declaring the access pattern in `.flagshark.yml`:
92
+ *
93
+ * custom_detectors:
94
+ * - type: struct-field-access
95
+ * language: go
96
+ * access_pattern: '\.FeatureFlags\.([A-Z]\w+)'
97
+ *
98
+ * The capture group is the flag name. Files matching this regex are added
99
+ * to detection results with `confidence: 'low'` so downstream tooling
100
+ * surfaces them for manual review — false-positive risk on heuristic
101
+ * matches is real and the user is the one who said "trust this pattern".
102
+ *
103
+ * We deliberately do NOT auto-discover the struct definition + enumerate
104
+ * its fields (the more aggressive design path from the spec). Reasons:
105
+ * each codebase invents its own pattern (Mattermost, Kubernetes, Grafana
106
+ * each have different shapes) and chasing them is N customer-engagements
107
+ * of work. The config-driven approach scales — users with bespoke
108
+ * patterns can express them; we don't have to encode every variant.
109
+ */
110
+ export declare const CustomDetectorSchema: z.ZodObject<{
111
+ /**
112
+ * Detector kind. Today only `struct-field-access` is supported; future
113
+ * kinds (e.g. `runtime-symbol`, `type-assertion`) would slot in here
114
+ * without breaking the schema.
115
+ */
116
+ type: z.ZodLiteral<"struct-field-access">;
117
+ /** Language whose file extensions this detector applies to. */
118
+ language: z.ZodEnum<["typescript", "javascript", "go", "python", "java", "kotlin", "swift", "ruby", "csharp", "php", "rust", "cpp", "objc"]>;
119
+ /**
120
+ * Regex with exactly one capture group — the captured text becomes the
121
+ * detected flag name. Run as a global regex over file content. Must be
122
+ * a string (parsed at load time) so the YAML stays plain-data.
123
+ */
124
+ access_pattern: z.ZodString;
125
+ /**
126
+ * Optional display name surfaced as the `provider` for matched flags.
127
+ * Defaults to "Custom struct-field detector" so JSON consumers can
128
+ * filter on a stable string.
129
+ */
130
+ name: z.ZodOptional<z.ZodString>;
131
+ }, "strip", z.ZodTypeAny, {
132
+ type: "struct-field-access";
133
+ language: "go" | "typescript" | "javascript" | "python" | "java" | "kotlin" | "swift" | "ruby" | "csharp" | "php" | "rust" | "cpp" | "objc";
134
+ access_pattern: string;
135
+ name?: string | undefined;
136
+ }, {
137
+ type: "struct-field-access";
138
+ language: "go" | "typescript" | "javascript" | "python" | "java" | "kotlin" | "swift" | "ruby" | "csharp" | "php" | "rust" | "cpp" | "objc";
139
+ access_pattern: string;
140
+ name?: string | undefined;
141
+ }>;
78
142
  export declare const OutputConfigSchema: z.ZodDefault<z.ZodObject<{
79
143
  format: z.ZodDefault<z.ZodEnum<["text", "json", "sarif", "markdown", "csv"]>>;
80
144
  groupBy: z.ZodDefault<z.ZodEnum<["file", "provider", "signal", "none"]>>;
@@ -188,6 +252,42 @@ export declare const FlagsharkConfigSchema: z.ZodObject<{
188
252
  importPattern?: string | undefined;
189
253
  enabled?: boolean | undefined;
190
254
  }>, "many">>;
255
+ /**
256
+ * User-defined non-SDK detectors (B3). Today only `struct-field-access`.
257
+ * See `CustomDetectorSchema` for the rationale + per-codebase examples.
258
+ */
259
+ custom_detectors: z.ZodDefault<z.ZodArray<z.ZodObject<{
260
+ /**
261
+ * Detector kind. Today only `struct-field-access` is supported; future
262
+ * kinds (e.g. `runtime-symbol`, `type-assertion`) would slot in here
263
+ * without breaking the schema.
264
+ */
265
+ type: z.ZodLiteral<"struct-field-access">;
266
+ /** Language whose file extensions this detector applies to. */
267
+ language: z.ZodEnum<["typescript", "javascript", "go", "python", "java", "kotlin", "swift", "ruby", "csharp", "php", "rust", "cpp", "objc"]>;
268
+ /**
269
+ * Regex with exactly one capture group — the captured text becomes the
270
+ * detected flag name. Run as a global regex over file content. Must be
271
+ * a string (parsed at load time) so the YAML stays plain-data.
272
+ */
273
+ access_pattern: z.ZodString;
274
+ /**
275
+ * Optional display name surfaced as the `provider` for matched flags.
276
+ * Defaults to "Custom struct-field detector" so JSON consumers can
277
+ * filter on a stable string.
278
+ */
279
+ name: z.ZodOptional<z.ZodString>;
280
+ }, "strip", z.ZodTypeAny, {
281
+ type: "struct-field-access";
282
+ language: "go" | "typescript" | "javascript" | "python" | "java" | "kotlin" | "swift" | "ruby" | "csharp" | "php" | "rust" | "cpp" | "objc";
283
+ access_pattern: string;
284
+ name?: string | undefined;
285
+ }, {
286
+ type: "struct-field-access";
287
+ language: "go" | "typescript" | "javascript" | "python" | "java" | "kotlin" | "swift" | "ruby" | "csharp" | "php" | "rust" | "cpp" | "objc";
288
+ access_pattern: string;
289
+ name?: string | undefined;
290
+ }>, "many">>;
191
291
  output: z.ZodDefault<z.ZodObject<{
192
292
  format: z.ZodDefault<z.ZodEnum<["text", "json", "sarif", "markdown", "csv"]>>;
193
293
  groupBy: z.ZodDefault<z.ZodEnum<["file", "provider", "signal", "none"]>>;
@@ -267,6 +367,12 @@ export declare const FlagsharkConfigSchema: z.ZodObject<{
267
367
  suppress: {
268
368
  flags: string[];
269
369
  };
370
+ custom_detectors: {
371
+ type: "struct-field-access";
372
+ language: "go" | "typescript" | "javascript" | "python" | "java" | "kotlin" | "swift" | "ruby" | "csharp" | "php" | "rust" | "cpp" | "objc";
373
+ access_pattern: string;
374
+ name?: string | undefined;
375
+ }[];
270
376
  output: {
271
377
  format: "json" | "text" | "sarif" | "markdown" | "csv";
272
378
  groupBy: "provider" | "file" | "signal" | "none";
@@ -309,6 +415,12 @@ export declare const FlagsharkConfigSchema: z.ZodObject<{
309
415
  suppress?: {
310
416
  flags?: string[] | undefined;
311
417
  } | undefined;
418
+ custom_detectors?: {
419
+ type: "struct-field-access";
420
+ language: "go" | "typescript" | "javascript" | "python" | "java" | "kotlin" | "swift" | "ruby" | "csharp" | "php" | "rust" | "cpp" | "objc";
421
+ access_pattern: string;
422
+ name?: string | undefined;
423
+ }[] | undefined;
312
424
  output?: {
313
425
  format?: "json" | "text" | "sarif" | "markdown" | "csv" | undefined;
314
426
  groupBy?: "provider" | "file" | "signal" | "none" | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAWvB,eAAO,MAAM,gBAAgB,wFAAuB,CAAA;AACpD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD,eAAO,MAAM,cAAc;;;;;;;;;;;;GAIb,CAAA;AAEd,eAAO,MAAM,cAAc;;;;;;GAEb,CAAA;AAEd,eAAO,MAAM,cAAc;;;;;;;;;EAGzB,CAAA;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAA;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU/B,CAAA;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;GAMjB,CAAA;AAEd,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;GAMhB,CAAA;AAEd,eAAO,MAAM,YAAY,6EAGZ,CAAA;AAEb,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAavB,CAAA;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACnE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAWvB,eAAO,MAAM,gBAAgB,wFAAuB,CAAA;AACpD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAEzD,eAAO,MAAM,cAAc;;;;;;;;;;;;GAIb,CAAA;AAEd,eAAO,MAAM,cAAc;;;;;;GAEb,CAAA;AAEd,eAAO,MAAM,cAAc;;;;;;;;;EAGzB,CAAA;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAA;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU/B,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,oBAAoB;IAC/B;;;;OAIG;;IAEH,+DAA+D;;IAM/D;;;;OAIG;;IAEH;;;;OAIG;;;;;;;;;;;;EAEH,CAAA;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;GAMjB,CAAA;AAEd,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;GAMhB,CAAA;AAEd,eAAO,MAAM,YAAY,6EAGZ,CAAA;AAEb,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMhC;;;OAGG;;QAxDH;;;;WAIG;;QAEH,+DAA+D;;QAM/D;;;;WAIG;;QAEH;;;;WAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CM,CAAA;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACnE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA"}
@@ -35,6 +35,64 @@ export const CustomProviderSchema = z.object({
35
35
  enabled: z.boolean().default(true),
36
36
  methods: z.array(MethodConfigSchema),
37
37
  });
38
+ /**
39
+ * Escape hatch for typed config-struct flag systems (B3).
40
+ *
41
+ * Codebases like Mattermost don't use an SDK — flags are typed fields on a
42
+ * configuration struct:
43
+ *
44
+ * if (server.Config().FeatureFlags.EnableSharedChannelsMemberSync) { ... }
45
+ *
46
+ * There's no `import 'unleash-client'`, no `client.variation(...)`, no string
47
+ * literal flag key. The standard import-gated detection model returns 0 on
48
+ * these codebases because none of its preconditions hold (see the
49
+ * design spec at docs/superpowers/specs/2026-05-24-static-config-flag-detection.md).
50
+ *
51
+ * Users opt in by declaring the access pattern in `.flagshark.yml`:
52
+ *
53
+ * custom_detectors:
54
+ * - type: struct-field-access
55
+ * language: go
56
+ * access_pattern: '\.FeatureFlags\.([A-Z]\w+)'
57
+ *
58
+ * The capture group is the flag name. Files matching this regex are added
59
+ * to detection results with `confidence: 'low'` so downstream tooling
60
+ * surfaces them for manual review — false-positive risk on heuristic
61
+ * matches is real and the user is the one who said "trust this pattern".
62
+ *
63
+ * We deliberately do NOT auto-discover the struct definition + enumerate
64
+ * its fields (the more aggressive design path from the spec). Reasons:
65
+ * each codebase invents its own pattern (Mattermost, Kubernetes, Grafana
66
+ * each have different shapes) and chasing them is N customer-engagements
67
+ * of work. The config-driven approach scales — users with bespoke
68
+ * patterns can express them; we don't have to encode every variant.
69
+ */
70
+ export const CustomDetectorSchema = z.object({
71
+ /**
72
+ * Detector kind. Today only `struct-field-access` is supported; future
73
+ * kinds (e.g. `runtime-symbol`, `type-assertion`) would slot in here
74
+ * without breaking the schema.
75
+ */
76
+ type: z.literal('struct-field-access'),
77
+ /** Language whose file extensions this detector applies to. */
78
+ language: z.enum([
79
+ 'typescript', 'javascript', 'go', 'python', 'java',
80
+ 'kotlin', 'swift', 'ruby', 'csharp', 'php', 'rust',
81
+ 'cpp', 'objc',
82
+ ]),
83
+ /**
84
+ * Regex with exactly one capture group — the captured text becomes the
85
+ * detected flag name. Run as a global regex over file content. Must be
86
+ * a string (parsed at load time) so the YAML stays plain-data.
87
+ */
88
+ access_pattern: z.string().min(1),
89
+ /**
90
+ * Optional display name surfaced as the `provider` for matched flags.
91
+ * Defaults to "Custom struct-field detector" so JSON consumers can
92
+ * filter on a stable string.
93
+ */
94
+ name: z.string().optional(),
95
+ });
38
96
  export const OutputConfigSchema = z.object({
39
97
  format: z.enum(['text', 'json', 'sarif', 'markdown', 'csv']).default('text'),
40
98
  groupBy: z.enum(['file', 'provider', 'signal', 'none']).default('file'),
@@ -56,6 +114,11 @@ export const FlagsharkConfigSchema = z.object({
56
114
  suppress: SuppressSchema,
57
115
  paths: z.array(PathRuleSchema).default([]),
58
116
  providers: z.array(CustomProviderSchema).default([]),
117
+ /**
118
+ * User-defined non-SDK detectors (B3). Today only `struct-field-access`.
119
+ * See `CustomDetectorSchema` for the rationale + per-codebase examples.
120
+ */
121
+ custom_detectors: z.array(CustomDetectorSchema).default([]),
59
122
  output: OutputConfigSchema,
60
123
  healthScore: HealthScoreSchema,
61
124
  engine: EngineSchema,
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,YAAY,GAAG;IACnB,YAAY;IACZ,WAAW;IACX,UAAU;IACV,SAAS;IACT,UAAU;IACV,WAAW;CACH,CAAA;AAEV,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;AAGpD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC/C,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAEd,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACvC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAEd,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAClD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;CAC/B,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC;QACf,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM;QAClD,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM;QAClD,KAAK,EAAE,MAAM;KACd,CAAC;IACF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAClC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;CACrC,CAAC,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC;IACtC,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC;QACf,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM;QAClD,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM;QAClD,KAAK,EAAE,MAAM;KACd,CAAC;IACF;;;;OAIG;IACH,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5E,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACvE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACvD,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC1D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACpD,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAEd,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;QAC1C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;QAC/C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;KACjD,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACf,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAEd,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAClC,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CACjC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAEb,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAClD,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,cAAc;IACxB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACpD;;;OAGG;IACH,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3D,MAAM,EAAE,kBAAkB;IAC1B,WAAW,EAAE,iBAAiB;IAC9B,MAAM,EAAE,YAAY;IACpB,SAAS,EAAE,CAAC,CAAC,MAAM,CACjB,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAC7D,CAAC,QAAQ,EAAE;CACb,CAAC,CAAC,MAAM,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../../src/detection/detectors/typescript.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAEtG,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACjC,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAED,qBAAa,kBAAmB,YAAW,gBAAgB;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,IAAI,GAAE,yBAA8B;IAKhD,QAAQ,IAAI,QAAQ;IAIpB,cAAc,IAAI,MAAM,EAAE;IAI1B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAQvC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAOtF,YAAY,IAAI,mBAAmB,EAAE;CAGtC;AAED,wBAAgB,0BAA0B,IAAI,mBAAmB,EAAE,CAgUlE"}
1
+ {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../../src/detection/detectors/typescript.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAEtG,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,MAAM,WAAW,yBAAyB;IACxC,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACjC,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAED,qBAAa,kBAAmB,YAAW,gBAAgB;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,IAAI,GAAE,yBAA8B;IAKhD,QAAQ,IAAI,QAAQ;IAIpB,cAAc,IAAI,MAAM,EAAE;IAI1B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAQvC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAOtF,YAAY,IAAI,mBAAmB,EAAE;CAGtC;AAED,wBAAgB,0BAA0B,IAAI,mBAAmB,EAAE,CAyWlE"}
@@ -102,9 +102,36 @@ export function defaultTypeScriptProviders() {
102
102
  {
103
103
  name: 'LaunchDarkly React SDK',
104
104
  importPattern: '@launchdarkly/react-client-sdk',
105
+ // launchdarkly-react-client-sdk is the legacy unscoped package name
106
+ // still widely used; @launchdarkly/react-client-sdk is the current
107
+ // scoped name. Both ship the same hooks (useFlag, useFlags,
108
+ // useLDClient) so they share one provider config.
109
+ importAliases: ['launchdarkly-react-client-sdk'],
105
110
  description: 'LaunchDarkly React SDK',
106
111
  enabled: true,
112
+ // The React SDK has two flag-shaped surfaces:
113
+ // 1. `useFlag('flag-key', defaultValue)` — positional flag key,
114
+ // handled by the standard pipeline (flagKeyIndex: 0).
115
+ // 2. `useFlags()` returns an object keyed by every flag; consumers
116
+ // destructure or index into it. That second shape can't be
117
+ // expressed as a positional arg, so the provider declares
118
+ // `useFlagsHook` and the helpers run a second pass that
119
+ // extracts flag keys from `const { flagX, flagY } = useFlags()`
120
+ // destructures. See detectDestructuredHookFlags in helpers.ts.
121
+ // useLDClient is documented for completeness (it returns the SDK
122
+ // client and is used to call `.variation()` on it manually); when
123
+ // present, the `.variation()` site is detected by the JS SDK
124
+ // provider above. No standalone extraction is needed here.
125
+ useFlagsHook: 'useFlags',
107
126
  methods: [
127
+ {
128
+ name: 'useFlag',
129
+ flagKeyIndex: 0,
130
+ examples: ["const enabled = useFlag('show-new-checkout', false)"],
131
+ },
132
+ // useFlags + useLDClient are documented here but produce no
133
+ // positional-arg matches (flagKeyIndex: -1 → skipped by the main
134
+ // loop). The useFlags extraction runs via useFlagsHook above.
108
135
  { name: 'useFlags', flagKeyIndex: -1, examples: ['const { flagKey } = useFlags()'] },
109
136
  { name: 'useLDClient', flagKeyIndex: -1, examples: ['const ldClient = useLDClient()'] },
110
137
  ],
@@ -299,6 +326,20 @@ export function defaultTypeScriptProviders() {
299
326
  importPattern: 'posthog-js',
300
327
  description: 'PostHog JavaScript/TypeScript SDK',
301
328
  enabled: true,
329
+ // Runtime-load symbols (B2). PostHog's canonical snippet attaches
330
+ // the SDK to `window.posthog` from a <script src=".../array.js">,
331
+ // so React/Vue/etc. consumer files never `import 'posthog-js'`
332
+ // directly. Without these symbols flagshark returns 0 on every
333
+ // PostHog frontend (n8n, PostHog's own dashboard, ...). The
334
+ // patterns are property-access shapes (with `.` separators) or
335
+ // call-shaped (with trailing `(`) so they don't match the bare
336
+ // string "posthog" in unrelated comments / docs.
337
+ runtimeSymbols: [
338
+ 'window.posthog.',
339
+ 'posthog.isFeatureEnabled(',
340
+ 'posthog.getFeatureFlag(',
341
+ 'posthog.getFeatureFlagPayload(',
342
+ ],
302
343
  methods: [
303
344
  {
304
345
  name: 'isFeatureEnabled',
@@ -1 +1 @@
1
- {"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../../src/detection/detectors/typescript.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../../src/detection/detectors/typescript.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,25 @@
1
+ /**
2
+ * How sure we are this is really a feature flag callsite.
3
+ *
4
+ * - **high**: Detected through a strict import-gated SDK match. False
5
+ * positives are very rare; the SDK package is statically imported and
6
+ * the call shape matches the provider's declared method exactly. Safe
7
+ * for auto-merge cleanup PRs.
8
+ *
9
+ * - **medium**: Detected through a weaker signal — a runtime-symbol
10
+ * gate bypass (`window.posthog` etc.), an unambiguous-method-name
11
+ * match without an import, or a user-configured custom detector.
12
+ * The flag is almost certainly real but the gate is wider. Suggested
13
+ * handling: surface to humans for review, don't auto-merge.
14
+ *
15
+ * - **low**: Reserved for the future static-config flag system
16
+ * detector (B3 auto-discovery slice — not shipped today). Heuristic
17
+ * match with weaker precision; recommend manual confirmation.
18
+ *
19
+ * Absent / undefined is equivalent to `'high'` so existing consumers
20
+ * that don't read the field keep their current behaviour.
21
+ */
22
+ export type FlagConfidence = 'high' | 'medium' | 'low';
1
23
  /**
2
24
  * Represents a detected feature flag in source code.
3
25
  */
@@ -12,5 +34,11 @@ export interface FeatureFlag {
12
34
  language: string;
13
35
  /** SDK/library provider if detected (e.g., "launchdarkly") */
14
36
  provider?: string;
37
+ /**
38
+ * Detection-quality tier. See FlagConfidence's docstring for what each
39
+ * value means. Absent = `'high'` (the historical default, preserves
40
+ * behaviour for consumers that haven't been updated yet).
41
+ */
42
+ confidence?: FlagConfidence;
15
43
  }
16
44
  //# sourceMappingURL=feature-flag.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-flag.d.ts","sourceRoot":"","sources":["../../src/detection/feature-flag.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAA;IAClB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB"}
1
+ {"version":3,"file":"feature-flag.d.ts","sourceRoot":"","sources":["../../src/detection/feature-flag.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;AAEtD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAA;IAClB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,CAAA;CAC5B"}
@@ -41,6 +41,22 @@ export declare function escapeRegExp(str: string): string;
41
41
  * This is used by all language detectors as the primary detection mechanism.
42
42
  */
43
43
  export declare function detectFlagsWithRegex(filename: string, content: string, language: Language, providers: FeatureFlagProvider[]): FeatureFlag[];
44
+ /**
45
+ * Extracts flag keys from destructured property names on a hook's return
46
+ * value. Handles the LaunchDarkly React SDK pattern (and any future hook
47
+ * with the same shape):
48
+ *
49
+ * const { showNewCheckout, oneClickPurchase } = useFlags()
50
+ * let { feature: aliased } = useFlags() // takes `feature`, not `aliased`
51
+ *
52
+ * Multi-line destructures are supported (the regex spans newlines). The
53
+ * line number reported is the line where the destructure begins.
54
+ *
55
+ * Identifiers that fail `isValidFlagKey` (numeric literals, reserved
56
+ * words) are dropped — this is the same gate the positional-arg path
57
+ * applies, kept consistent so downstream consumers see one rule.
58
+ */
59
+ export declare function detectDestructuredHookFlags(filename: string, content: string, language: Language, provider: string, hookName: string, confidence?: 'high' | 'medium'): FeatureFlag[];
44
60
  /** Checks whether a string looks like a valid feature flag key. */
45
61
  export declare function isValidFlagKey(key: string): boolean;
46
62
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/detection/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEjF,yDAAyD;AACzD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAEpE;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAKlE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAapE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiCzF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA2DxD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAQpE;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,mBAAmB,EAAE,GAC/B,WAAW,EAAE,CAqEf;AAmDD,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAanD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,MAAM,EAAE,mBAAmB,EAAE,GAC5B,mBAAmB,EAAE,CAuBvB"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/detection/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEjF,yDAAyD;AACzD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAEpE;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAKlE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAapE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiCzF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA2DxD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAQpE;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,mBAAmB,EAAE,GAC/B,WAAW,EAAE,CAsHf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAM,GAAG,QAAiB,GACrC,WAAW,EAAE,CAoCf;AAkED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAqBnD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,MAAM,EAAE,mBAAmB,EAAE,GAC5B,mBAAmB,EAAE,CAuBvB"}
@@ -155,12 +155,33 @@ export function detectFlagsWithRegex(filename, content, language, providers) {
155
155
  }
156
156
  const providerName = provider.name;
157
157
  const importPat = getImportPattern(provider);
158
- // Import check: skip this provider if file doesn't import its SDK.
159
- // Providers with no importPattern (e.g., "Custom Feature Flags") are kept as fallbacks.
158
+ // Import gate: skip this provider if the file doesn't import its SDK,
159
+ // UNLESS it carries a runtime-symbol that flags the SDK as present even
160
+ // without a static import. Providers with no importPattern (the legacy
161
+ // "Custom Feature Flags" catch-all) always run.
162
+ //
163
+ // Detected via runtimeSymbols are tagged below with `confidence: 'medium'`
164
+ // so downstream consumers can route them through review rather than
165
+ // auto-merge. See B2 design doc + the provider docstring for the
166
+ // false-positive trade-off.
167
+ let detectionConfidence = 'high';
160
168
  if (importPat) {
161
- const hasImport = content.includes(importPat) || lines.some((line) => line.includes(importPat));
169
+ // The import gate passes if EITHER the primary pattern OR any
170
+ // declared alias is present in the file. SDKs republished under a
171
+ // scoped name (e.g. `@launchdarkly/react-client-sdk`) rely on the
172
+ // alias list so the legacy unscoped form
173
+ // (`launchdarkly-react-client-sdk`) still triggers detection.
174
+ const importPatterns = [importPat, ...(provider.importAliases ?? [])];
175
+ const hasImport = importPatterns.some((pat) => content.includes(pat) || lines.some((line) => line.includes(pat)));
162
176
  if (!hasImport) {
163
- continue;
177
+ // Check whether the file matches any runtime-symbol pattern.
178
+ const runtimeHit = (provider.runtimeSymbols ?? []).some((sym) => content.includes(sym));
179
+ if (!runtimeHit) {
180
+ continue;
181
+ }
182
+ // Gate passed via runtime symbol — downgrade confidence so the
183
+ // flag's downstream treatment reflects the weaker signal.
184
+ detectionConfidence = 'medium';
164
185
  }
165
186
  }
166
187
  for (const method of provider.methods) {
@@ -189,20 +210,89 @@ export function detectFlagsWithRegex(filename, content, language, providers) {
189
210
  }
190
211
  const flagKey = extractStringArgument(restOfContent, method.flagKeyIndex);
191
212
  if (flagKey && isValidFlagKey(flagKey)) {
192
- flags.push({
213
+ const flag = {
193
214
  name: flagKey,
194
215
  filePath: filename,
195
216
  lineNumber: lineIdx + 1,
196
217
  language,
197
218
  provider: importPat || providerName,
198
- });
219
+ };
220
+ // Only emit `confidence` when it's a non-default value. The
221
+ // FeatureFlag type documents `confidence` as optional with
222
+ // "absent = high", so omitting it for the common case keeps
223
+ // existing JSON consumers + test fixtures stable.
224
+ if (detectionConfidence !== 'high')
225
+ flag.confidence = detectionConfidence;
226
+ flags.push(flag);
199
227
  }
200
228
  }
201
229
  }
202
230
  }
231
+ // useFlagsHook: providers like the LaunchDarkly React SDK don't pass
232
+ // flag keys as call-site arguments. Instead, calling `useFlags()` returns
233
+ // an object whose keys ARE the flag names; consumers either destructure
234
+ // them or index into them. The positional-arg pipeline above can't see
235
+ // this shape. When a provider declares `useFlagsHook`, run a second pass
236
+ // that extracts destructured property names from `... = <hook>()` sites
237
+ // and emits each as a detected flag.
238
+ if (provider.useFlagsHook) {
239
+ const hookFlags = detectDestructuredHookFlags(filename, content, language, importPat || providerName, provider.useFlagsHook, detectionConfidence);
240
+ flags.push(...hookFlags);
241
+ }
203
242
  }
204
243
  return deduplicateFlags(flags);
205
244
  }
245
+ /**
246
+ * Extracts flag keys from destructured property names on a hook's return
247
+ * value. Handles the LaunchDarkly React SDK pattern (and any future hook
248
+ * with the same shape):
249
+ *
250
+ * const { showNewCheckout, oneClickPurchase } = useFlags()
251
+ * let { feature: aliased } = useFlags() // takes `feature`, not `aliased`
252
+ *
253
+ * Multi-line destructures are supported (the regex spans newlines). The
254
+ * line number reported is the line where the destructure begins.
255
+ *
256
+ * Identifiers that fail `isValidFlagKey` (numeric literals, reserved
257
+ * words) are dropped — this is the same gate the positional-arg path
258
+ * applies, kept consistent so downstream consumers see one rule.
259
+ */
260
+ export function detectDestructuredHookFlags(filename, content, language, provider, hookName, confidence = 'high') {
261
+ const out = [];
262
+ const pattern = new RegExp(`(?:const|let|var)\\s*\\{\\s*([\\s\\S]*?)\\}\\s*=\\s*${escapeRegExp(hookName)}\\s*\\(\\s*\\)`, 'g');
263
+ let m;
264
+ while ((m = pattern.exec(content)) !== null) {
265
+ const lineNumber = content.slice(0, m.index).split('\n').length;
266
+ const inside = m[1];
267
+ // Strip line comments inside the destructure body before splitting on
268
+ // commas — otherwise a trailing `// note` would taint the last name.
269
+ const cleaned = inside
270
+ .split('\n')
271
+ .map((seg) => seg.replace(/\/\/.*$/, ''))
272
+ .join(' ');
273
+ for (const raw of cleaned.split(',')) {
274
+ const trimmed = raw.trim();
275
+ if (!trimmed)
276
+ continue;
277
+ // `originalName: alias` — the flag key is the SOURCE side (the
278
+ // property on the hook's return value), not the local alias.
279
+ const flagKey = trimmed.split(':')[0].trim();
280
+ if (isValidFlagKey(flagKey)) {
281
+ const flag = {
282
+ name: flagKey,
283
+ filePath: filename,
284
+ lineNumber,
285
+ language,
286
+ provider,
287
+ };
288
+ if (confidence !== 'high')
289
+ flag.confidence = confidence;
290
+ out.push(flag);
291
+ }
292
+ }
293
+ }
294
+ return out;
295
+ }
206
296
  /** Builds a regex for a single method name that matches calls. */
207
297
  function buildSingleMethodPattern(methodName) {
208
298
  const escaped = escapeRegExp(methodName);
@@ -249,6 +339,20 @@ function getCallExpression(lines, startLine, startCol) {
249
339
  /* v8 ignore next -- foundOpen is always true here: the matching regex requires '(' which startCol points to */
250
340
  return foundOpen ? result : null;
251
341
  }
342
+ /**
343
+ * Characters that legitimate feature flag keys never contain. Real keys
344
+ * across LaunchDarkly, Unleash, PostHog, Statsig, Split.io, and the
345
+ * shakedown corpus are limited to letters, digits, underscores, dashes,
346
+ * dots, and colons. The chars below appear only when we've accidentally
347
+ * latched onto a regex literal, a URL fragment, or a string with parens.
348
+ *
349
+ * Surfaced by the PostHog shakedown: a TSX file contained the regex
350
+ * fragment `([^/]+)` which slipped through `isValidFlagKey` because the
351
+ * legacy check only rejected URL prefixes. The new key now reports as a
352
+ * false positive in flagshark's output — that's the bug this set guards
353
+ * against. See A2 in the shakedown bug inventory.
354
+ */
355
+ const INVALID_FLAG_KEY_CHAR = /[()\[\]^$\\\s]/;
252
356
  /** Checks whether a string looks like a valid feature flag key. */
253
357
  export function isValidFlagKey(key) {
254
358
  if (key.length === 0 || key.length > 256) {
@@ -260,6 +364,13 @@ export function isValidFlagKey(key) {
260
364
  return false;
261
365
  }
262
366
  }
367
+ // Reject keys that look like regex literals, character classes, or contain
368
+ // whitespace — none of these are legitimate shapes for a feature flag key
369
+ // and they consistently indicate we've extracted the wrong string from a
370
+ // method call (e.g. `new RegExp('([^/]+)')` getting matched).
371
+ if (INVALID_FLAG_KEY_CHAR.test(key)) {
372
+ return false;
373
+ }
263
374
  return true;
264
375
  }
265
376
  /**