@hyperfrontend/project-scope 0.1.0 → 0.2.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 (177) hide show
  1. package/CHANGELOG.md +15 -3
  2. package/README.md +2 -0
  3. package/analyze.d.ts.map +1 -1
  4. package/cli/commands/analyze.d.ts +8 -0
  5. package/cli/commands/analyze.d.ts.map +1 -1
  6. package/cli/commands/config.d.ts +7 -0
  7. package/cli/commands/config.d.ts.map +1 -1
  8. package/cli/commands/deps.d.ts +6 -0
  9. package/cli/commands/deps.d.ts.map +1 -1
  10. package/cli/commands/tree.d.ts +12 -0
  11. package/cli/commands/tree.d.ts.map +1 -1
  12. package/cli/index.cjs.js +73 -206
  13. package/cli/index.cjs.js.map +1 -1
  14. package/cli/index.esm.js +73 -206
  15. package/cli/index.esm.js.map +1 -1
  16. package/cli/run.d.ts.map +1 -1
  17. package/core/cache.d.ts +1 -0
  18. package/core/cache.d.ts.map +1 -1
  19. package/core/encoding/convert.d.ts.map +1 -1
  20. package/core/encoding/detect.d.ts +5 -0
  21. package/core/encoding/detect.d.ts.map +1 -1
  22. package/core/encoding/index.cjs.js +2 -23
  23. package/core/encoding/index.cjs.js.map +1 -1
  24. package/core/encoding/index.esm.js +2 -23
  25. package/core/encoding/index.esm.js.map +1 -1
  26. package/core/errors/structured-errors.d.ts +2 -0
  27. package/core/errors/structured-errors.d.ts.map +1 -1
  28. package/core/fs/directory.d.ts +3 -0
  29. package/core/fs/directory.d.ts.map +1 -1
  30. package/core/fs/index.cjs.js +0 -14
  31. package/core/fs/index.cjs.js.map +1 -1
  32. package/core/fs/index.esm.js +0 -14
  33. package/core/fs/index.esm.js.map +1 -1
  34. package/core/fs/read.d.ts +11 -3
  35. package/core/fs/read.d.ts.map +1 -1
  36. package/core/fs/traversal.d.ts.map +1 -1
  37. package/core/index.cjs.js +11 -63
  38. package/core/index.cjs.js.map +1 -1
  39. package/core/index.esm.js +11 -63
  40. package/core/index.esm.js.map +1 -1
  41. package/core/logger.d.ts.map +1 -1
  42. package/core/path/index.cjs.js +5 -2
  43. package/core/path/index.cjs.js.map +1 -1
  44. package/core/path/index.esm.js +5 -2
  45. package/core/path/index.esm.js.map +1 -1
  46. package/core/path/normalize.d.ts.map +1 -1
  47. package/core/patterns/glob.d.ts +0 -4
  48. package/core/patterns/glob.d.ts.map +1 -1
  49. package/core/platform/detect.d.ts.map +1 -1
  50. package/core/platform/index.cjs.js +0 -10
  51. package/core/platform/index.cjs.js.map +1 -1
  52. package/core/platform/index.esm.js +0 -10
  53. package/core/platform/index.esm.js.map +1 -1
  54. package/core/platform/line-endings.d.ts.map +1 -1
  55. package/heuristics/dependencies/analyze.d.ts.map +1 -1
  56. package/heuristics/dependencies/index.cjs.js +0 -17
  57. package/heuristics/dependencies/index.cjs.js.map +1 -1
  58. package/heuristics/dependencies/index.esm.js +0 -17
  59. package/heuristics/dependencies/index.esm.js.map +1 -1
  60. package/heuristics/entry-points/discover.d.ts +34 -7
  61. package/heuristics/entry-points/discover.d.ts.map +1 -1
  62. package/heuristics/entry-points/index.cjs.js +6 -34
  63. package/heuristics/entry-points/index.cjs.js.map +1 -1
  64. package/heuristics/entry-points/index.esm.js +6 -34
  65. package/heuristics/entry-points/index.esm.js.map +1 -1
  66. package/heuristics/framework/index.cjs.js +1 -63
  67. package/heuristics/framework/index.cjs.js.map +1 -1
  68. package/heuristics/framework/index.esm.js +1 -63
  69. package/heuristics/framework/index.esm.js.map +1 -1
  70. package/heuristics/index.cjs.js +7 -88
  71. package/heuristics/index.cjs.js.map +1 -1
  72. package/heuristics/index.esm.js +7 -88
  73. package/heuristics/index.esm.js.map +1 -1
  74. package/heuristics/project-type/index.cjs.js +1 -63
  75. package/heuristics/project-type/index.cjs.js.map +1 -1
  76. package/heuristics/project-type/index.esm.js +1 -63
  77. package/heuristics/project-type/index.esm.js.map +1 -1
  78. package/index.cjs.js +86 -294
  79. package/index.cjs.js.map +1 -1
  80. package/index.esm.js +86 -294
  81. package/index.esm.js.map +1 -1
  82. package/nx/detect.d.ts.map +1 -1
  83. package/nx/devkit-loader.d.ts.map +1 -1
  84. package/nx/index.cjs.js +0 -29
  85. package/nx/index.cjs.js.map +1 -1
  86. package/nx/index.esm.js +0 -29
  87. package/nx/index.esm.js.map +1 -1
  88. package/nx/project-config.d.ts +2 -0
  89. package/nx/project-config.d.ts.map +1 -1
  90. package/package.json +9 -9
  91. package/project/config/index.cjs.js +4 -46
  92. package/project/config/index.cjs.js.map +1 -1
  93. package/project/config/index.esm.js +4 -46
  94. package/project/config/index.esm.js.map +1 -1
  95. package/project/config/patterns.d.ts.map +1 -1
  96. package/project/index.cjs.js +4 -47
  97. package/project/index.cjs.js.map +1 -1
  98. package/project/index.esm.js +4 -47
  99. package/project/index.esm.js.map +1 -1
  100. package/project/package/index.cjs.js +0 -11
  101. package/project/package/index.cjs.js.map +1 -1
  102. package/project/package/index.esm.js +0 -11
  103. package/project/package/index.esm.js.map +1 -1
  104. package/project/package/read.d.ts +1 -0
  105. package/project/package/read.d.ts.map +1 -1
  106. package/project/root/index.cjs.js +0 -11
  107. package/project/root/index.cjs.js.map +1 -1
  108. package/project/root/index.esm.js +0 -11
  109. package/project/root/index.esm.js.map +1 -1
  110. package/project/traversal/index.cjs.js +4 -28
  111. package/project/traversal/index.cjs.js.map +1 -1
  112. package/project/traversal/index.esm.js +4 -28
  113. package/project/traversal/index.esm.js.map +1 -1
  114. package/tech/backend/express.d.ts.map +1 -1
  115. package/tech/backend/fastify.d.ts.map +1 -1
  116. package/tech/backend/index.cjs.js +0 -17
  117. package/tech/backend/index.cjs.js.map +1 -1
  118. package/tech/backend/index.esm.js +0 -17
  119. package/tech/backend/index.esm.js.map +1 -1
  120. package/tech/backend/koa.d.ts.map +1 -1
  121. package/tech/backend/nestjs.d.ts.map +1 -1
  122. package/tech/build/index.cjs.js +0 -12
  123. package/tech/build/index.cjs.js.map +1 -1
  124. package/tech/build/index.esm.js +0 -12
  125. package/tech/build/index.esm.js.map +1 -1
  126. package/tech/frontend/index.cjs.js +0 -16
  127. package/tech/frontend/index.cjs.js.map +1 -1
  128. package/tech/frontend/index.esm.js +0 -16
  129. package/tech/frontend/index.esm.js.map +1 -1
  130. package/tech/frontend/qwik.d.ts.map +1 -1
  131. package/tech/frontend/remix.d.ts.map +1 -1
  132. package/tech/frontend/sveltekit.d.ts.map +1 -1
  133. package/tech/index.cjs.js +1 -63
  134. package/tech/index.cjs.js.map +1 -1
  135. package/tech/index.d.ts.map +1 -1
  136. package/tech/index.esm.js +1 -63
  137. package/tech/index.esm.js.map +1 -1
  138. package/tech/legacy/angularjs.d.ts.map +1 -1
  139. package/tech/legacy/backbone.d.ts.map +1 -1
  140. package/tech/legacy/ember.d.ts.map +1 -1
  141. package/tech/legacy/index.cjs.js +0 -26
  142. package/tech/legacy/index.cjs.js.map +1 -1
  143. package/tech/legacy/index.esm.js +0 -26
  144. package/tech/legacy/index.esm.js.map +1 -1
  145. package/tech/legacy/jquery.d.ts.map +1 -1
  146. package/tech/linting/biome.d.ts.map +1 -1
  147. package/tech/linting/index.cjs.js +0 -14
  148. package/tech/linting/index.cjs.js.map +1 -1
  149. package/tech/linting/index.esm.js +0 -14
  150. package/tech/linting/index.esm.js.map +1 -1
  151. package/tech/linting/prettier.d.ts.map +1 -1
  152. package/tech/monorepo/index.cjs.js +1 -13
  153. package/tech/monorepo/index.cjs.js.map +1 -1
  154. package/tech/monorepo/index.esm.js +1 -13
  155. package/tech/monorepo/index.esm.js.map +1 -1
  156. package/tech/monorepo/types.d.ts +1 -1
  157. package/tech/monorepo/types.d.ts.map +1 -1
  158. package/tech/shared-utils/detector-helpers.d.ts.map +1 -1
  159. package/tech/testing/index.cjs.js +0 -12
  160. package/tech/testing/index.cjs.js.map +1 -1
  161. package/tech/testing/index.esm.js +0 -12
  162. package/tech/testing/index.esm.js.map +1 -1
  163. package/tech/types/detectors.d.ts.map +1 -1
  164. package/tech/types/index.cjs.js +0 -27
  165. package/tech/types/index.cjs.js.map +1 -1
  166. package/tech/types/index.esm.js +0 -27
  167. package/tech/types/index.esm.js.map +1 -1
  168. package/vfs/commit.d.ts.map +1 -1
  169. package/vfs/diff.d.ts.map +1 -1
  170. package/vfs/factory.d.ts.map +1 -1
  171. package/vfs/fs-tree.d.ts.map +1 -1
  172. package/vfs/index.cjs.js +5 -46
  173. package/vfs/index.cjs.js.map +1 -1
  174. package/vfs/index.esm.js +5 -46
  175. package/vfs/index.esm.js.map +1 -1
  176. package/vfs/types.d.ts +1 -0
  177. package/vfs/types.d.ts.map +1 -1
@@ -9,7 +9,6 @@ import { existsSync, readFileSync, statSync, lstatSync, readdirSync } from 'node
9
9
  *
10
10
  * @module @hyperfrontend/immutable-api-utils/built-in-copy/json
11
11
  */
12
- // Capture references at module initialization time
13
12
  const _JSON = globalThis.JSON;
14
13
  /**
15
14
  * (Safe copy) Converts a JavaScript Object Notation (JSON) string into an object.
@@ -28,7 +27,6 @@ const stringify = _JSON.stringify;
28
27
  *
29
28
  * @module @hyperfrontend/immutable-api-utils/built-in-copy/math
30
29
  */
31
- // Capture references at module initialization time
32
30
  const _Math = globalThis.Math;
33
31
  /**
34
32
  * (Safe copy) Returns the value of a number rounded to the nearest integer.
@@ -47,7 +45,6 @@ const min = _Math.min;
47
45
  *
48
46
  * @module @hyperfrontend/immutable-api-utils/built-in-copy/object
49
47
  */
50
- // Capture references at module initialization time
51
48
  const _Object = globalThis.Object;
52
49
  /**
53
50
  * (Safe copy) Prevents modification of existing property attributes and values,
@@ -82,7 +79,6 @@ const defineProperties = _Object.defineProperties;
82
79
  *
83
80
  * @module @hyperfrontend/immutable-api-utils/built-in-copy/error
84
81
  */
85
- // Capture references at module initialization time
86
82
  const _Error = globalThis.Error;
87
83
  const _Reflect$2 = globalThis.Reflect;
88
84
  /**
@@ -103,7 +99,6 @@ const createError = (message, options) => _Reflect$2.construct(_Error, [message,
103
99
  *
104
100
  * @module @hyperfrontend/immutable-api-utils/built-in-copy/array
105
101
  */
106
- // Capture references at module initialization time
107
102
  const _Array = globalThis.Array;
108
103
  /**
109
104
  * (Safe copy) Determines whether the passed value is an Array.
@@ -118,7 +113,6 @@ const isArray = _Array.isArray;
118
113
  *
119
114
  * @module @hyperfrontend/immutable-api-utils/built-in-copy/console
120
115
  */
121
- // Capture references at module initialization time
122
116
  const _console = globalThis.console;
123
117
  /**
124
118
  * (Safe copy) Outputs a message to the console.
@@ -204,7 +198,6 @@ _console.timeLog.bind(_console);
204
198
  *
205
199
  * @module @hyperfrontend/immutable-api-utils/built-in-copy/set
206
200
  */
207
- // Capture references at module initialization time
208
201
  const _Set = globalThis.Set;
209
202
  const _Reflect$1 = globalThis.Reflect;
210
203
  /**
@@ -252,7 +245,6 @@ const getType = (target) => {
252
245
  *
253
246
  * @module @hyperfrontend/immutable-api-utils/built-in-copy/map
254
247
  */
255
- // Capture references at module initialization time
256
248
  const _Map = globalThis.Map;
257
249
  const _Reflect = globalThis.Reflect;
258
250
  /**
@@ -530,14 +522,11 @@ function formatMessage(namespace, message, meta) {
530
522
  */
531
523
  function createScopedLogger(namespace, options = {}) {
532
524
  const { level = 'error', sanitizeSecrets = true } = options;
533
- // Create wrapper functions that add namespace prefix and sanitization
534
525
  const createLogFn = (baseFn) => (message, meta) => {
535
526
  const processedMeta = sanitizeSecrets && meta ? sanitize(meta) : meta;
536
527
  baseFn(formatMessage(namespace, message, processedMeta));
537
528
  };
538
- // Create base logger with wrapped functions
539
529
  const baseLogger = createLogger(createLogFn(error), createLogFn(warn), createLogFn(log), createLogFn(info), createLogFn(debug));
540
- // Set initial log level (use global override if set)
541
530
  baseLogger.setLogLevel(level);
542
531
  const scopedLogger = freeze({
543
532
  error: (message, meta) => baseLogger.error(message, meta),
@@ -548,7 +537,6 @@ function createScopedLogger(namespace, options = {}) {
548
537
  setLogLevel: baseLogger.setLogLevel,
549
538
  getLogLevel: baseLogger.getLogLevel,
550
539
  });
551
- // Register logger for global level management
552
540
  loggerRegistry.add(scopedLogger);
553
541
  return scopedLogger;
554
542
  }
@@ -879,7 +867,6 @@ const cacheRegistry = createSet();
879
867
  function createCache(options) {
880
868
  const { ttl, maxSize } = options ?? {};
881
869
  const store = createMap();
882
- // Track insertion order for FIFO eviction
883
870
  const insertionOrder = [];
884
871
  /**
885
872
  * Check if an entry is expired.
@@ -930,12 +917,10 @@ function createCache(options) {
930
917
  return entry.value;
931
918
  },
932
919
  set(key, value) {
933
- // If key exists, remove from order first
934
920
  if (store.has(key)) {
935
921
  removeFromOrder(key);
936
922
  }
937
923
  else {
938
- // Evict if needed before adding new entry
939
924
  evictIfNeeded();
940
925
  }
941
926
  // eslint-disable-next-line workspace/no-unsafe-builtin-methods -- Date.now() is needed for Jest fake timers compatibility
@@ -968,7 +953,6 @@ function createCache(options) {
968
953
  return [...insertionOrder];
969
954
  },
970
955
  };
971
- // Register cache for global operations
972
956
  cacheRegistry.add(cache);
973
957
  return freeze(cache);
974
958
  }
@@ -999,7 +983,6 @@ function collectAllDependencies(packageJson) {
999
983
  function parseVersionString(versionString) {
1000
984
  if (versionString === undefined || versionString === null)
1001
985
  return undefined;
1002
- // Manual parsing instead of regex to avoid ReDoS
1003
986
  let start = 0;
1004
987
  while (start < versionString.length) {
1005
988
  const char = versionString[start];
@@ -1060,7 +1043,6 @@ function expressDetector(projectPath, packageJson) {
1060
1043
  version = parseVersionString(deps['express']);
1061
1044
  sources.push({ type: 'package.json', field: 'dependencies.express' });
1062
1045
  }
1063
- // @types/express (indicates usage)
1064
1046
  if (deps['@types/express']) {
1065
1047
  confidence += 10;
1066
1048
  sources.push({ type: 'package.json', field: 'dependencies.@types/express' });
@@ -1096,13 +1078,11 @@ function nestDetector(projectPath, packageJson) {
1096
1078
  let version;
1097
1079
  let configPath;
1098
1080
  const deps = collectAllDependencies(pkg);
1099
- // @nestjs/core package
1100
1081
  if (deps['@nestjs/core']) {
1101
1082
  confidence += 70;
1102
1083
  version = parseVersionString(deps['@nestjs/core']);
1103
1084
  sources.push({ type: 'package.json', field: 'dependencies.@nestjs/core' });
1104
1085
  }
1105
- // @nestjs/common
1106
1086
  if (deps['@nestjs/common']) {
1107
1087
  confidence += 15;
1108
1088
  sources.push({ type: 'package.json', field: 'dependencies.@nestjs/common' });
@@ -1153,7 +1133,6 @@ function fastifyDetector(projectPath, packageJson) {
1153
1133
  confidence += 15;
1154
1134
  sources.push({ type: 'package.json', field: 'dependencies (fastify plugins)' });
1155
1135
  }
1156
- // @types/fastify (older versions)
1157
1136
  if (deps['@types/fastify']) {
1158
1137
  confidence += 5;
1159
1138
  sources.push({ type: 'package.json', field: 'dependencies.@types/fastify' });
@@ -1188,7 +1167,6 @@ function koaDetector(projectPath, packageJson) {
1188
1167
  version = parseVersionString(deps['koa']);
1189
1168
  sources.push({ type: 'package.json', field: 'dependencies.koa' });
1190
1169
  }
1191
- // @types/koa
1192
1170
  if (deps['@types/koa']) {
1193
1171
  confidence += 10;
1194
1172
  sources.push({ type: 'package.json', field: 'dependencies.@types/koa' });
@@ -1731,7 +1709,6 @@ function remixDetector(projectPath, packageJson) {
1731
1709
  let confidence = 0;
1732
1710
  let version;
1733
1711
  const deps = collectAllDependencies(pkg);
1734
- // @remix-run packages
1735
1712
  if (deps['@remix-run/react']) {
1736
1713
  confidence += 70;
1737
1714
  version = parseVersionString(deps['@remix-run/react']);
@@ -2007,7 +1984,6 @@ function sveltekitDetector(projectPath, packageJson) {
2007
1984
  let confidence = 0;
2008
1985
  let version;
2009
1986
  const deps = collectAllDependencies(pkg);
2010
- // @sveltejs/kit package
2011
1987
  if (deps['@sveltejs/kit']) {
2012
1988
  confidence += 70;
2013
1989
  version = parseVersionString(deps['@sveltejs/kit']);
@@ -2086,13 +2062,11 @@ function qwikDetector(projectPath, packageJson) {
2086
2062
  let confidence = 0;
2087
2063
  let version;
2088
2064
  const deps = collectAllDependencies(pkg);
2089
- // @builder.io/qwik package
2090
2065
  if (deps['@builder.io/qwik']) {
2091
2066
  confidence += 70;
2092
2067
  version = parseVersionString(deps['@builder.io/qwik']);
2093
2068
  sources.push({ type: 'package.json', field: 'dependencies.@builder.io/qwik' });
2094
2069
  }
2095
- // @builder.io/qwik-city
2096
2070
  if (deps['@builder.io/qwik-city']) {
2097
2071
  confidence += 20;
2098
2072
  sources.push({ type: 'package.json', field: 'dependencies.@builder.io/qwik-city' });
@@ -2185,23 +2159,19 @@ function angularJSDetector(projectPath, packageJson) {
2185
2159
  let confidence = 0;
2186
2160
  let version;
2187
2161
  const deps = collectAllDependencies(pkg);
2188
- // AngularJS package (angular, not @angular/core)
2189
2162
  if (deps['angular']) {
2190
2163
  confidence += 70;
2191
2164
  version = parseVersionString(deps['angular']);
2192
2165
  sources.push({ type: 'package.json', field: 'dependencies.angular' });
2193
2166
  }
2194
- // AngularJS router
2195
2167
  if (deps['angular-route']) {
2196
2168
  confidence += 15;
2197
2169
  sources.push({ type: 'package.json', field: 'dependencies.angular-route' });
2198
2170
  }
2199
- // AngularJS resource
2200
2171
  if (deps['angular-resource']) {
2201
2172
  confidence += 10;
2202
2173
  sources.push({ type: 'package.json', field: 'dependencies.angular-resource' });
2203
2174
  }
2204
- // AngularJS animate
2205
2175
  if (deps['angular-animate']) {
2206
2176
  confidence += 5;
2207
2177
  sources.push({ type: 'package.json', field: 'dependencies.angular-animate' });
@@ -2232,23 +2202,19 @@ function backboneDetector(projectPath, packageJson) {
2232
2202
  let confidence = 0;
2233
2203
  let version;
2234
2204
  const deps = collectAllDependencies(pkg);
2235
- // Backbone package
2236
2205
  if (deps['backbone']) {
2237
2206
  confidence += 70;
2238
2207
  version = parseVersionString(deps['backbone']);
2239
2208
  sources.push({ type: 'package.json', field: 'dependencies.backbone' });
2240
- // Underscore (commonly used with Backbone)
2241
2209
  if (deps['underscore']) {
2242
2210
  confidence += 15;
2243
2211
  sources.push({ type: 'package.json', field: 'dependencies.underscore' });
2244
2212
  }
2245
- // Lodash can be used as underscore replacement
2246
2213
  if (deps['lodash']) {
2247
2214
  confidence += 5;
2248
2215
  sources.push({ type: 'package.json', field: 'dependencies.lodash' });
2249
2216
  }
2250
2217
  }
2251
- // Marionette (Backbone framework)
2252
2218
  if (deps['backbone.marionette'] || deps['marionette']) {
2253
2219
  confidence += 10;
2254
2220
  sources.push({ type: 'package.json', field: 'dependencies.backbone.marionette' });
@@ -2279,18 +2245,15 @@ function emberDetector(projectPath, packageJson) {
2279
2245
  let confidence = 0;
2280
2246
  let version;
2281
2247
  const deps = collectAllDependencies(pkg);
2282
- // Ember source package
2283
2248
  if (deps['ember-source']) {
2284
2249
  confidence += 70;
2285
2250
  version = parseVersionString(deps['ember-source']);
2286
2251
  sources.push({ type: 'package.json', field: 'dependencies.ember-source' });
2287
2252
  }
2288
- // Ember CLI
2289
2253
  if (deps['ember-cli']) {
2290
2254
  confidence += 20;
2291
2255
  sources.push({ type: 'package.json', field: 'devDependencies.ember-cli' });
2292
2256
  }
2293
- // Ember Data
2294
2257
  if (deps['ember-data']) {
2295
2258
  confidence += 10;
2296
2259
  sources.push({ type: 'package.json', field: 'dependencies.ember-data' });
@@ -2321,18 +2284,15 @@ function jqueryDetector(projectPath, packageJson) {
2321
2284
  let confidence = 0;
2322
2285
  let version;
2323
2286
  const deps = collectAllDependencies(pkg);
2324
- // jQuery package
2325
2287
  if (deps['jquery']) {
2326
2288
  confidence += 80;
2327
2289
  version = parseVersionString(deps['jquery']);
2328
2290
  sources.push({ type: 'package.json', field: 'dependencies.jquery' });
2329
2291
  }
2330
- // jQuery UI
2331
2292
  if (deps['jquery-ui']) {
2332
2293
  confidence += 10;
2333
2294
  sources.push({ type: 'package.json', field: 'dependencies.jquery-ui' });
2334
2295
  }
2335
- // jQuery plugins
2336
2296
  if (deps['jquery-validation']) {
2337
2297
  confidence += 5;
2338
2298
  sources.push({ type: 'package.json', field: 'dependencies.jquery-validation' });
@@ -2461,7 +2421,6 @@ function prettierDetector(projectPath, packageJson) {
2461
2421
  confidence += 30;
2462
2422
  sources.push({ type: 'package.json', field: 'prettier' });
2463
2423
  }
2464
- // .prettierignore file
2465
2424
  if (exists(join$1(projectPath, '.prettierignore'))) {
2466
2425
  confidence += 10;
2467
2426
  sources.push({ type: 'config-file', path: '.prettierignore' });
@@ -2556,7 +2515,6 @@ function biomeDetector(projectPath, packageJson) {
2556
2515
  let configPath;
2557
2516
  let version;
2558
2517
  const deps = collectAllDependencies(pkg);
2559
- // @biomejs/biome package
2560
2518
  if (deps['@biomejs/biome']) {
2561
2519
  confidence += 70;
2562
2520
  version = parseVersionString(deps['@biomejs/biome']);
@@ -2825,7 +2783,7 @@ function npmWorkspacesDetector(workspacePath, packageJson) {
2825
2783
  sources.push({ type: 'lockfile', path: 'package-lock.json' });
2826
2784
  }
2827
2785
  if (exists(join$1(workspacePath, 'yarn.lock'))) {
2828
- return null; // Let yarn workspace detector handle this
2786
+ return null;
2829
2787
  }
2830
2788
  if (confidence === 0) {
2831
2789
  return null;
@@ -3168,7 +3126,6 @@ function checkTsConfigStrict(projectPath) {
3168
3126
  if (!content)
3169
3127
  return undefined;
3170
3128
  try {
3171
- // Simple JSON parsing - doesn't handle comments but good enough for strict check
3172
3129
  const cleanContent = content.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '');
3173
3130
  const parsed = parse(cleanContent);
3174
3131
  return parsed?.compilerOptions?.strict === true;
@@ -3191,19 +3148,16 @@ function typescriptDetector(projectPath, packageJson) {
3191
3148
  let configPath;
3192
3149
  let version;
3193
3150
  const deps = collectAllDependencies(pkg);
3194
- // TypeScript package
3195
3151
  if (deps['typescript']) {
3196
3152
  confidence += 50;
3197
3153
  version = parseVersionString(deps['typescript']);
3198
3154
  sources.push({ type: 'package.json', field: 'dependencies.typescript' });
3199
3155
  }
3200
- // tsconfig.json
3201
3156
  if (exists(join$1(projectPath, 'tsconfig.json'))) {
3202
3157
  confidence += 40;
3203
3158
  configPath = 'tsconfig.json';
3204
3159
  sources.push({ type: 'config-file', path: 'tsconfig.json' });
3205
3160
  }
3206
- // tsconfig.*.json variants
3207
3161
  const tsconfigVariants = ['tsconfig.build.json', 'tsconfig.lib.json', 'tsconfig.spec.json', 'tsconfig.app.json'];
3208
3162
  for (const variant of tsconfigVariants) {
3209
3163
  if (exists(join$1(projectPath, variant))) {
@@ -3212,7 +3166,6 @@ function typescriptDetector(projectPath, packageJson) {
3212
3166
  break;
3213
3167
  }
3214
3168
  }
3215
- // @types packages
3216
3169
  const typePackages = keys(deps).filter((d) => d.startsWith('@types/'));
3217
3170
  if (typePackages.length > 0) {
3218
3171
  confidence += 10;
@@ -3246,24 +3199,20 @@ function flowDetector(projectPath, packageJson) {
3246
3199
  let configPath;
3247
3200
  let version;
3248
3201
  const deps = collectAllDependencies(pkg);
3249
- // flow-bin package
3250
3202
  if (deps['flow-bin']) {
3251
3203
  confidence += 60;
3252
3204
  version = parseVersionString(deps['flow-bin']);
3253
3205
  sources.push({ type: 'package.json', field: 'dependencies.flow-bin' });
3254
3206
  }
3255
- // .flowconfig
3256
3207
  if (exists(join$1(projectPath, '.flowconfig'))) {
3257
3208
  confidence += 40;
3258
3209
  configPath = '.flowconfig';
3259
3210
  sources.push({ type: 'config-file', path: '.flowconfig' });
3260
3211
  }
3261
- // flow-typed directory
3262
3212
  if (exists(join$1(projectPath, 'flow-typed'))) {
3263
3213
  confidence += 10;
3264
3214
  sources.push({ type: 'directory', path: 'flow-typed/' });
3265
3215
  }
3266
- // @babel/preset-flow
3267
3216
  if (deps['@babel/preset-flow']) {
3268
3217
  confidence += 10;
3269
3218
  sources.push({ type: 'package.json', field: 'dependencies.@babel/preset-flow' });
@@ -3287,7 +3236,6 @@ function flowDetector(projectPath, packageJson) {
3287
3236
  * @returns `true` if the content contains JSDoc type annotations.
3288
3237
  */
3289
3238
  function hasJsDocTypes(content) {
3290
- // Check for JSDoc type annotations
3291
3239
  return (content.includes('@type {') ||
3292
3240
  content.includes('@param {') ||
3293
3241
  content.includes('@returns {') ||
@@ -3306,14 +3254,11 @@ function jsdocDetector(projectPath, packageJson) {
3306
3254
  const sources = [];
3307
3255
  let confidence = 0;
3308
3256
  const deps = collectAllDependencies(pkg);
3309
- // jsdoc package
3310
3257
  if (deps['jsdoc']) {
3311
3258
  confidence += 30;
3312
3259
  sources.push({ type: 'package.json', field: 'dependencies.jsdoc' });
3313
3260
  }
3314
- // typescript with checkJs (JSDoc type checking)
3315
3261
  if (deps['typescript']) {
3316
- // Check if checkJs is enabled in tsconfig
3317
3262
  const tsconfigPath = join$1(projectPath, 'tsconfig.json');
3318
3263
  const content = readFileIfExists(tsconfigPath);
3319
3264
  if (content) {
@@ -3330,12 +3275,10 @@ function jsdocDetector(projectPath, packageJson) {
3330
3275
  }
3331
3276
  }
3332
3277
  }
3333
- // Check for jsconfig.json (VS Code JS type checking)
3334
3278
  if (exists(join$1(projectPath, 'jsconfig.json'))) {
3335
3279
  confidence += 40;
3336
3280
  sources.push({ type: 'config-file', path: 'jsconfig.json' });
3337
3281
  }
3338
- // Sample check for JSDoc annotations in source files
3339
3282
  const srcDir = join$1(projectPath, 'src');
3340
3283
  if (exists(srcDir)) {
3341
3284
  try {
@@ -3386,8 +3329,6 @@ const detectAllCache = createCache({ ttl: 60000, maxSize: 50 });
3386
3329
  function isDetectAllOptions(value) {
3387
3330
  if (typeof value !== 'object' || value === null)
3388
3331
  return false;
3389
- // DetectAllOptions has skipCache or packageJson fields specifically
3390
- // PackageJson never has skipCache field
3391
3332
  return 'skipCache' in value || 'packageJson' in value;
3392
3333
  }
3393
3334
  /**
@@ -3419,9 +3360,7 @@ function isDetectAllOptions(value) {
3419
3360
  * ```
3420
3361
  */
3421
3362
  function detectAll(projectPath, packageJsonOrOptions) {
3422
- // Handle backward-compatible arguments
3423
3363
  const options = isDetectAllOptions(packageJsonOrOptions) ? packageJsonOrOptions : { packageJson: packageJsonOrOptions };
3424
- // Check cache first (unless skipCache is true)
3425
3364
  if (!options.skipCache) {
3426
3365
  const cached = detectAllCache.get(projectPath);
3427
3366
  if (cached) {
@@ -3472,7 +3411,6 @@ function detectAll(projectPath, packageJsonOrOptions) {
3472
3411
  legacyFrameworks: result.legacyFrameworks.map((f) => f.id),
3473
3412
  testingFrameworks: result.testingFrameworks.map((f) => f.id),
3474
3413
  });
3475
- // Cache the result
3476
3414
  detectAllCache.set(projectPath, result);
3477
3415
  return result;
3478
3416
  }
@@ -3842,10 +3780,6 @@ function usesFramework(projectPath, frameworkId, minConfidence = 50) {
3842
3780
  return allFrameworks.some((f) => f.id === frameworkId && f.confidence >= minConfidence);
3843
3781
  }
3844
3782
 
3845
- /**
3846
- * Pattern matching utilities with ReDoS protection.
3847
- * Uses character-by-character matching instead of regex where possible.
3848
- */
3849
3783
  /**
3850
3784
  * Match path against glob pattern using safe character iteration.
3851
3785
  * Avoids regex to prevent ReDoS attacks.
@@ -3883,17 +3817,14 @@ function matchGlobPattern(path, pattern) {
3883
3817
  * @returns True if remaining segments match
3884
3818
  */
3885
3819
  function matchSegments(pathParts, patternParts, pathIdx, patternIdx) {
3886
- // Base cases
3887
3820
  if (pathIdx === pathParts.length && patternIdx === patternParts.length) {
3888
- return true; // Both exhausted = match
3821
+ return true;
3889
3822
  }
3890
3823
  if (patternIdx >= patternParts.length) {
3891
- return false; // Pattern exhausted but path remains
3824
+ return false;
3892
3825
  }
3893
3826
  const patternPart = patternParts[patternIdx];
3894
- // Handle ** (globstar) - matches zero or more directories
3895
3827
  if (patternPart === '**') {
3896
- // Try matching rest of pattern against current position and all future positions
3897
3828
  for (let i = pathIdx; i <= pathParts.length; i++) {
3898
3829
  if (matchSegments(pathParts, patternParts, i, patternIdx + 1)) {
3899
3830
  return true;
@@ -3902,10 +3833,9 @@ function matchSegments(pathParts, patternParts, pathIdx, patternIdx) {
3902
3833
  return false;
3903
3834
  }
3904
3835
  if (pathIdx >= pathParts.length) {
3905
- return false; // Path exhausted but pattern remains (and it's not **)
3836
+ return false;
3906
3837
  }
3907
3838
  const pathPart = pathParts[pathIdx];
3908
- // Match current segment
3909
3839
  if (matchSegment(pathPart, patternPart)) {
3910
3840
  return matchSegments(pathParts, patternParts, pathIdx + 1, patternIdx + 1);
3911
3841
  }
@@ -3925,12 +3855,10 @@ function matchSegment(text, pattern) {
3925
3855
  while (patternIdx < pattern.length) {
3926
3856
  const char = pattern[patternIdx];
3927
3857
  if (char === '*') {
3928
- // * matches zero or more characters
3929
3858
  patternIdx++;
3930
3859
  if (patternIdx === pattern.length) {
3931
- return true; // * at end matches rest of string
3860
+ return true;
3932
3861
  }
3933
- // Try matching rest of pattern at each position in text
3934
3862
  for (let i = textIdx; i <= text.length; i++) {
3935
3863
  if (matchSegmentFrom(text, i, pattern, patternIdx)) {
3936
3864
  return true;
@@ -3939,7 +3867,6 @@ function matchSegment(text, pattern) {
3939
3867
  return false;
3940
3868
  }
3941
3869
  else if (char === '?') {
3942
- // ? matches exactly one character
3943
3870
  if (textIdx >= text.length) {
3944
3871
  return false;
3945
3872
  }
@@ -3947,10 +3874,8 @@ function matchSegment(text, pattern) {
3947
3874
  patternIdx++;
3948
3875
  }
3949
3876
  else if (char === '{') {
3950
- // {a,b,c} matches any alternative
3951
3877
  const closeIdx = findClosingBrace(pattern, patternIdx);
3952
3878
  if (closeIdx === -1) {
3953
- // Unmatched brace, treat as literal
3954
3879
  if (textIdx >= text.length || text[textIdx] !== char) {
3955
3880
  return false;
3956
3881
  }
@@ -3968,7 +3893,6 @@ function matchSegment(text, pattern) {
3968
3893
  }
3969
3894
  }
3970
3895
  else {
3971
- // Literal character
3972
3896
  if (textIdx >= text.length || text[textIdx] !== char) {
3973
3897
  return false;
3974
3898
  }
@@ -4254,7 +4178,8 @@ const entryPointLogger = createScopedLogger('project-scope:heuristics:entry-poin
4254
4178
  */
4255
4179
  const entryPointCache = createCache({ ttl: 60000, maxSize: 50 });
4256
4180
  /**
4257
- * Common entry point patterns.
4181
+ * Common entry point patterns by project type.
4182
+ * Used for convention-based entry point discovery.
4258
4183
  */
4259
4184
  const ENTRY_POINT_PATTERNS = {
4260
4185
  /** Library entry patterns */
@@ -4520,29 +4445,23 @@ const depsLogger = createScopedLogger('project-scope:heuristics:deps');
4520
4445
  */
4521
4446
  function extractImports(content) {
4522
4447
  const imports = [];
4523
- // ES import with 'from': import X from 'path' or import { X } from 'path'
4524
- // Use non-greedy match and avoid nested quantifiers by matching "from" keyword directly
4525
4448
  const esImportFromRegex = /import\s+.+?\s+from\s+['"]([^'"]+)['"]/g;
4526
4449
  let match;
4527
4450
  while ((match = esImportFromRegex.exec(content)) !== null) {
4528
4451
  imports.push(match[1]);
4529
4452
  }
4530
- // Side-effect import: import 'path'
4531
4453
  const sideEffectImportRegex = /import\s+['"]([^'"]+)['"]/g;
4532
4454
  while ((match = sideEffectImportRegex.exec(content)) !== null) {
4533
4455
  imports.push(match[1]);
4534
4456
  }
4535
- // Dynamic import: import('path')
4536
4457
  const dynamicImportRegex = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
4537
4458
  while ((match = dynamicImportRegex.exec(content)) !== null) {
4538
4459
  imports.push(match[1]);
4539
4460
  }
4540
- // require: require('path')
4541
4461
  const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
4542
4462
  while ((match = requireRegex.exec(content)) !== null) {
4543
4463
  imports.push(match[1]);
4544
4464
  }
4545
- // Re-export: export * from 'path' or export { X } from 'path'
4546
4465
  const exportFromRegex = /export\s+.+?\s+from\s+['"]([^'"]+)['"]/g;
4547
4466
  while ((match = exportFromRegex.exec(content)) !== null) {
4548
4467
  imports.push(match[1]);