sweet-search 2.6.4 → 2.6.7

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.
@@ -1394,7 +1394,11 @@ export class GraphExtractor {
1394
1394
 
1395
1395
  const groupEnd = j - 1;
1396
1396
  const groupContent = source.slice(start, groupEnd);
1397
- const isOptional = source[groupEnd + 1] === '?';
1397
+ // A group quantified by `?` OR `*` can match zero times, so the tokens
1398
+ // AFTER it (e.g. the real keyword) may start the line. Treating a `(?:…)*`
1399
+ // modifier prefix as mandatory wrongly rejected lines like `class Foo`
1400
+ // (QL/Vala/Haxe leading-modifier patterns), dropping all their entities.
1401
+ const isOptional = source[groupEnd + 1] === '?' || source[groupEnd + 1] === '*';
1398
1402
  if (!isOptional) {
1399
1403
  const alternatives = groupContent.split('|').map((alt) => alt.trim()).filter(Boolean);
1400
1404
  const altTokens = [];
@@ -1409,7 +1413,14 @@ export class GraphExtractor {
1409
1413
  const optionalAlternatives = groupContent.split('|').map((alt) => alt.trim()).filter(Boolean);
1410
1414
  for (const alt of optionalAlternatives) {
1411
1415
  const token = this.extractLiteralPrefix(alt);
1412
- if (token) tokens.push(token);
1416
+ // A nested group / non-literal alternative (e.g. `(?:(?:public|…)\s+)*`)
1417
+ // means we cannot enumerate every literal this optional prefix could
1418
+ // start with. Adding only the literals we *can* see would
1419
+ // false-negative lines that begin with an un-enumerated one (Vala/Haxe
1420
+ // `public class Foo`). Disabling the prefilter is the only
1421
+ // correctness-preserving choice; the full regex still runs per line.
1422
+ if (!token) return [];
1423
+ tokens.push(token);
1413
1424
  }
1414
1425
  i = groupEnd + 2;
1415
1426
  while (skipLeadingWhitespace()) {}
@@ -3,6 +3,8 @@
3
3
  * Extracted to prevent drift between graph-search.js and sweet-search.js
4
4
  */
5
5
 
6
+ import { EXTENSION_MAP } from './language-patterns/maps.js';
7
+
6
8
  export const SYMBOL_KIND_WEIGHTS = {
7
9
  class: 1.0,
8
10
  interface: 0.95,
@@ -26,25 +28,43 @@ export const DEFINITION_TYPES = new Set([
26
28
  ]);
27
29
 
28
30
  /**
29
- * Canonical set of code file extensions recognized by sweet-search.
30
- * Used by both the indexer (sparse gram builder) and the search pipeline
31
- * (ripgrep type filter + code file detection). Single source of truth.
31
+ * Canonical set of code file extensions recognized by sweet-search's
32
+ * grep/pattern path the sparse-gram literal index, native-grep extension
33
+ * filter, ripgrep `--type-add code` fallback, and `isRipgrepCodePath`.
34
+ *
35
+ * DERIVED from EXTENSION_MAP (the single source of truth for which extensions
36
+ * sweet-search indexes) so ss-grep coverage can NEVER drift behind newly-added
37
+ * languages. This drift previously dropped Solidity, .cts/.mts, .cljc/.cljs/.edn,
38
+ * .mli, .rd/.rmd, shaders, build DSLs, etc. from ss-grep even though they were
39
+ * discovered + embedded (so ss-search worked but ss-grep silently returned
40
+ * nothing). Keys are stored bare + lowercase (no leading dot) to match
41
+ * `path.extname(f).slice(1).toLowerCase()` at the call sites.
42
+ *
43
+ * Pure document formats (Markdown/reStructuredText/plaintext) are intentionally
44
+ * EXCLUDED — they go through DocumentChunker and are not part of the grep
45
+ * code-path (isRipgrepCodePath('README.md') must stay false, and sparse-gram
46
+ * candidate lists drop doc files). Config/markup/style formats (json/yaml/xml/
47
+ * html/css/ini/…) stay in, matching the historical set.
48
+ *
49
+ * Plus a few historically grep-able languages that have no EXTENSION_MAP entry
50
+ * (no chunker grammar): Ada, D, V.
32
51
  */
52
+ const DOC_FORMAT_LANGUAGE_IDS = new Set(['markdown', 'rst', 'plaintext']);
53
+ const LEGACY_EXTRA_CODE_EXTENSIONS = ['ada', 'd', 'v'];
33
54
  export const CODE_FILE_EXTENSIONS = new Set([
34
- 'js', 'ts', 'jsx', 'tsx', 'py', 'rs', 'go', 'java', 'c', 'cpp', 'h', 'hpp',
35
- 'cs', 'rb', 'php', 'swift', 'kt', 'scala', 'lua', 'sh', 'zig', 'hs', 'ml',
36
- 'ex', 'exs', 'clj', 'erl', 'r', 'jl', 'dart', 'v', 'nim', 'cr', 'd', 'f90',
37
- 'ada', 'pas', 'cob', 'pl', 'pm', 'sql', 'graphql', 'proto', 'yaml', 'yml',
38
- 'json', 'toml', 'xml', 'html', 'css', 'scss', 'sass', 'less', 'svelte',
39
- 'vue', 'astro', 'mdx',
55
+ ...Object.entries(EXTENSION_MAP)
56
+ .filter(([, id]) => !DOC_FORMAT_LANGUAGE_IDS.has(id))
57
+ .map(([ext]) => ext.replace(/^\./, '').toLowerCase()),
58
+ ...LEGACY_EXTRA_CODE_EXTENSIONS,
40
59
  ]);
41
60
 
42
61
  /**
43
62
  * Ripgrep type definition glob matching CODE_FILE_EXTENSIONS.
44
- * Used with --type-add to define a custom 'code' type for ripgrep.
63
+ * Used with --type-add to define a custom 'code' type for ripgrep. Derived from
64
+ * the same set so it stays in lockstep.
45
65
  */
46
66
  export const RIPGREP_CODE_TYPE_GLOB =
47
- 'code:*.{js,ts,jsx,tsx,py,rs,go,java,c,cpp,h,hpp,cs,rb,php,swift,kt,scala,lua,sh,zig,hs,ml,ex,exs,clj,erl,r,jl,dart,v,nim,cr,d,f90,ada,pas,cob,pl,pm,sql,graphql,proto,yaml,yml,json,toml,xml,html,css,scss,sass,less,svelte,vue,astro,mdx}';
67
+ `code:*.{${Array.from(CODE_FILE_EXTENSIONS).join(',')}}`;
48
68
 
49
69
  /**
50
70
  * Sparse gram symbol type bitmasks.
@@ -235,6 +235,503 @@ export const TOOLING_LANGUAGES = {
235
235
  skipCallObjects: [],
236
236
  },
237
237
  },
238
+ // ─── Julia (graph-only spike) ────────────────────────────────────────────────
239
+ // No `chunker` key → getLanguageByExtension returns chunker:null → ast-chunker
240
+ // keeps Julia on generic windowing. The `graph` patterns alone enable
241
+ // regex-based entity extraction so ss-trace/code-graph works.
242
+ julia: {
243
+ indentBased: false,
244
+ endKeyword: null,
245
+ comment: { line: "#", block: ["#=", "=#"] },
246
+ graph: {
247
+ entities: {
248
+ function: /^\s*function\s+([A-Za-z_]\w*)/,
249
+ shortFunction: /^\s*([A-Za-z_]\w*)\((?:[^()]*)\)\s*(?:::[\w.<>{} ]+)?\s*=(?!=)/,
250
+ struct: /^\s*(?:mutable\s+)?struct\s+([A-Za-z_]\w*)/,
251
+ module: /^\s*module\s+([A-Za-z_]\w*)/,
252
+ },
253
+ relationships: {
254
+ import: /^\s*(?:using|import)\s+([\w.]+)/,
255
+ },
256
+ skipCallObjects: [],
257
+ },
258
+ },
259
+ // ════════════════════════════════════════════════════════════════════════════
260
+ // GRAPH-ONLY language entries (no `chunker` key → chunking stays generic via
261
+ // parseGenericFile; the `graph` regexes enable ss-trace / code-graph symbol
262
+ // extraction). Authored 2026-06 from each language's tree-sitter tags.scm /
263
+ // universal-ctags conventions. Entity-type keys are free-form (the regex graph
264
+ // path accepts any label, like Rust's existing const/static/type).
265
+ // ════════════════════════════════════════════════════════════════════════════
266
+ clojure: {
267
+ indentBased: false, endKeyword: null,
268
+ comment: { line: ";", block: null },
269
+ graph: {
270
+ entities: {
271
+ function: /^\s*\(def(?:n-?|multi|method)\s+(?:\^(?:\{[^}]*\}|\S+)\s+)*([A-Za-z0-9*+!?<>=.\/'-]+)/,
272
+ macro: /^\s*\(defmacro\s+(?:\^(?:\{[^}]*\}|\S+)\s+)*([A-Za-z0-9*+!?<>=.\/'-]+)/,
273
+ struct: /^\s*\(def(?:record|type)\s+(?:\^(?:\{[^}]*\}|\S+)\s+)*([A-Za-z0-9*+!?<>=.\/'-]+)/,
274
+ interface: /^\s*\(defprotocol\s+(?:\^(?:\{[^}]*\}|\S+)\s+)*([A-Za-z0-9*+!?<>=.\/'-]+)/,
275
+ constant: /^\s*\(def\s+(?:\^(?:\{[^}]*\}|\S+)\s+)*([A-Za-z0-9*+!?<>=.\/'-]+)/,
276
+ module: /^\s*\(ns\s+([A-Za-z0-9*+!?<>=.\/'-]+)/,
277
+ },
278
+ relationships: { import: /^\s*\(:?(?:require|use)\s+'?\[?([A-Za-z0-9.*_-]+)/ },
279
+ skipCallObjects: ["let", "let*", "if", "when", "do", "fn", "map", "filter", "reduce"],
280
+ },
281
+ },
282
+ elisp: {
283
+ indentBased: false, endKeyword: null,
284
+ comment: { line: ";", block: null },
285
+ graph: {
286
+ entities: {
287
+ function: /^\s*\((?:cl-)?def(?:un|subst)\s+([A-Za-z0-9*+!?<>=\/_-]+)/,
288
+ macro: /^\s*\((?:cl-)?defmacro\s+([A-Za-z0-9*+!?<>=\/_-]+)/,
289
+ variable: /^\s*\(def(?:var|custom)\s+([A-Za-z0-9*+!?<>=\/_-]+)/,
290
+ constant: /^\s*\(defconst\s+([A-Za-z0-9*+!?<>=\/_-]+)/,
291
+ module: /^\s*\(defgroup\s+([A-Za-z0-9*+!?<>=\/_-]+)/,
292
+ },
293
+ relationships: { import: /^\s*\(require\s+'([A-Za-z0-9*+!?<>=\/_-]+)/ },
294
+ skipCallObjects: ["let", "let*", "if", "when", "unless", "cond", "setq", "lambda", "progn"],
295
+ },
296
+ },
297
+ haskell: {
298
+ indentBased: false, endKeyword: null,
299
+ comment: { line: "--", block: ["{-", "-}"] },
300
+ graph: {
301
+ entities: {
302
+ function: /^\s*([a-z_][\w']*)\s*::/,
303
+ type: /^\s*(?:data|newtype|type)\s+([A-Z]\w*)/,
304
+ class: /^\s*class\s+(?:.*?=>\s*)?([A-Z]\w*)/,
305
+ instance: /^\s*instance\s+(?:.*?=>\s*)?([A-Z]\w*)/,
306
+ module: /^\s*module\s+([A-Z][\w.]*)/,
307
+ },
308
+ relationships: { import: /^\s*import\s+(?:qualified\s+)?([A-Z][\w.]*)/ },
309
+ skipCallObjects: ["map", "filter", "foldr", "foldl", "return", "pure", "print", "putStrLn", "fmap", "show"],
310
+ },
311
+ },
312
+ erlang: {
313
+ indentBased: false, endKeyword: null,
314
+ comment: { line: "%", block: null },
315
+ graph: {
316
+ entities: {
317
+ module: /^\s*-module\(\s*([a-z]\w*)/,
318
+ function: /^\s*(?!fun\b)([a-z]\w*)\s*\((?:(?!fun\b).)*\)\s*(?:when\b.*)?->/,
319
+ struct: /^\s*-record\(\s*([a-z]\w*)/,
320
+ macro: /^\s*-define\(\s*([A-Za-z_]\w*)/,
321
+ },
322
+ relationships: {
323
+ import: /^\s*-import\(\s*([a-z]\w*)/,
324
+ include: /^\s*-include(?:_lib)?\(\s*"([^"]+)"/,
325
+ inherit: /^\s*-behaviou?r\(\s*([a-z]\w*)/,
326
+ },
327
+ skipCallObjects: ["lists", "io", "erlang", "maps", "string", "proplists", "gen_server"],
328
+ },
329
+ },
330
+ elm: {
331
+ indentBased: false, endKeyword: null,
332
+ comment: { line: "--", block: ["{-", "-}"] },
333
+ graph: {
334
+ entities: {
335
+ function: /^\s*([a-z]\w*)\s*:/,
336
+ type: /^\s*type\s+alias\s+([A-Z]\w*)/,
337
+ enum: /^\s*type\s+([A-Z]\w*)/,
338
+ port: /^\s*port\s+([a-z]\w*)\s*:/,
339
+ module: /^\s*(?:port\s+|effect\s+)?module\s+([A-Z][\w.]*)/,
340
+ },
341
+ relationships: { import: /^\s*import\s+([A-Z][\w.]*)/ },
342
+ skipCallObjects: ["List", "Maybe", "Result", "Html", "String", "Debug"],
343
+ },
344
+ },
345
+ r: {
346
+ indentBased: false, endKeyword: null,
347
+ comment: { line: "#", block: null },
348
+ graph: {
349
+ entities: {
350
+ function: /^\s*([A-Za-z.][\w.]*)\s*(?:<<?-|=)\s*function\b/,
351
+ class: /^\s*set(?:Ref)?Class\s*\(\s*["']([A-Za-z.][\w.]*)["']/,
352
+ method: /^\s*setMethod\s*\(\s*["']([A-Za-z.][\w.]*)["']/,
353
+ },
354
+ relationships: {
355
+ import: /^\s*(?:library|require)\s*\(\s*["']?([A-Za-z.][\w.]*)["']?/,
356
+ source: /^\s*source\s*\(\s*["']([^"']+)["']/,
357
+ },
358
+ skipCallObjects: ["c", "list", "print", "cat", "paste", "paste0", "return", "stop", "warning"],
359
+ },
360
+ },
361
+ perl: {
362
+ indentBased: false, endKeyword: null,
363
+ comment: { line: "#", block: null },
364
+ graph: {
365
+ entities: {
366
+ function: /^\s*sub\s+([A-Za-z_]\w*)/,
367
+ module: /^\s*package\s+([\w:]+)/,
368
+ constant: /^\s*use\s+constant\s+([A-Za-z_]\w*)/,
369
+ },
370
+ relationships: {
371
+ import: /^\s*(?:use|require)\s+([A-Z][\w:]*)/,
372
+ inherit: /^\s*use\s+(?:parent|base)\s+(?:-norequire\s*,?\s*)?(?:qw[(\/{[|]\s*)?["']?([\w:]+)["']?/,
373
+ },
374
+ skipCallObjects: ["print", "say", "shift", "push", "pop", "return", "my", "scalar", "keys", "values"],
375
+ },
376
+ },
377
+ tcl: {
378
+ indentBased: false, endKeyword: null,
379
+ comment: { line: "#", block: null },
380
+ graph: {
381
+ entities: {
382
+ function: /^\s*proc\s+([^\s{]+)/,
383
+ module: /^\s*namespace\s+eval\s+([^\s{]+)/,
384
+ },
385
+ relationships: {
386
+ import: /^\s*package\s+require\s+([\w:]+)/,
387
+ source: /^\s*source\s+(\S+)/,
388
+ },
389
+ skipCallObjects: ["set", "puts", "expr", "return", "string", "list", "lappend", "incr", "if", "foreach"],
390
+ },
391
+ },
392
+ vim: {
393
+ indentBased: false, endKeyword: null,
394
+ comment: { line: '"', block: null },
395
+ graph: {
396
+ entities: {
397
+ function: /^\s*func(?:tion)?!?\s+([A-Za-z_<][\w#:.>]*)/,
398
+ command: /^\s*command!?\s+(?:-\S+\s+)*([A-Z]\w*)/,
399
+ constant: /^\s*let\s+([gsb]:[A-Za-z_]\w*)/,
400
+ },
401
+ relationships: { import: /^\s*(?:source|runtime)!?\s+(\S+)/ },
402
+ skipCallObjects: ["echo", "echom", "call", "let", "set", "execute", "normal"],
403
+ },
404
+ },
405
+ crystal: {
406
+ indentBased: false, endKeyword: "end",
407
+ comment: { line: "#", block: null },
408
+ graph: {
409
+ entities: {
410
+ method: /^\s*def\s+(?:self\.)?([A-Za-z_]\w*[!?=]?)/,
411
+ class: /^\s*(?:abstract\s+)?class\s+([A-Z]\w*)/,
412
+ module: /^\s*module\s+([A-Z]\w*)/,
413
+ struct: /^\s*(?:abstract\s+)?struct\s+([A-Z]\w*)/,
414
+ enum: /^\s*enum\s+([A-Z]\w*)/,
415
+ macro: /^\s*macro\s+([A-Za-z_]\w*)/,
416
+ },
417
+ relationships: {
418
+ import: /^\s*require\s+"([^"]+)"/,
419
+ inherit: /^\s*(?:abstract\s+)?(?:class|struct)\s+[A-Z]\w*\s*<\s*([A-Z][\w:]*)/,
420
+ include: /^\s*(?:include|extend)\s+([A-Z][\w:]*)/,
421
+ },
422
+ skipCallObjects: ["puts", "print", "p", "pp", "raise", "self"],
423
+ },
424
+ },
425
+ fortran: {
426
+ indentBased: false, endKeyword: null,
427
+ comment: { line: "!", block: null },
428
+ graph: {
429
+ entities: {
430
+ module: /^\s*(?:module(?!\s+(?:procedure|subroutine|function)\b)|program)\s+([a-z_]\w*)/i,
431
+ function: /^\s*(?!end\b)(?:[\w()*,:=.]+\s+)*?(?:subroutine|function)\s+([a-z_]\w*)/i,
432
+ struct: /^\s*type\b\s*(?:,[^:]*)?(?:::\s*)?(?!is\b)([a-z_]\w*)/i,
433
+ interface: /^\s*interface\s+([a-z_]\w*)/i,
434
+ },
435
+ relationships: { use: /^\s*use\b\s*(?:,[^:]*::\s*)?([a-z_]\w*)/i },
436
+ skipCallObjects: [],
437
+ },
438
+ },
439
+ cobol: {
440
+ indentBased: false, endKeyword: null,
441
+ comment: { line: "*>", block: null },
442
+ graph: {
443
+ entities: {
444
+ module: /^\s*program-id\s*\.\s*([a-z0-9][a-z0-9-]*)/i,
445
+ class: /^\s*([a-z0-9][a-z0-9-]*)\s+section\s*\./i,
446
+ function: /^\s*(?!(?:end-[a-z]+|exit|goback|continue|stop)\b)([a-z0-9][a-z0-9-]*)\s*\.\s*$/i,
447
+ },
448
+ relationships: {
449
+ copyFrom: /^\s*copy\s+([a-z0-9][a-z0-9-]*)/i,
450
+ // CALL "subprog" → dependency edge (`call` is not a mapped relationship
451
+ // type; `dep` is the canonical generic-dependency key).
452
+ dep: /^\s*call\s+["']([a-z0-9][a-z0-9-]*)/i,
453
+ },
454
+ skipCallObjects: [],
455
+ },
456
+ },
457
+ assembly: {
458
+ indentBased: false, endKeyword: null,
459
+ comment: { line: ";", block: ["/*", "*/"] },
460
+ graph: {
461
+ entities: {
462
+ function: /^([a-zA-Z_][\w$.]*)\s*:/,
463
+ macro: /^\s*(?:\.macro\s+|%macro\s+|%define\s+)([a-zA-Z_][\w$.]*)/i,
464
+ constant: /^\s*([a-zA-Z_][\w$.]*)\s+equ\b/i,
465
+ },
466
+ relationships: {
467
+ import: /^\s*(?:\.extern|extern)\s+([a-zA-Z_][\w$.]*)/i,
468
+ include: /^\s*(?:%include|\.include)\s+["']?([^"'\s,]+)/i,
469
+ },
470
+ skipCallObjects: [],
471
+ },
472
+ },
473
+ pascal: {
474
+ indentBased: false, endKeyword: null,
475
+ comment: { line: "//", block: ["{", "}"] },
476
+ graph: {
477
+ entities: {
478
+ module: /^\s*(?:unit|program|library)\s+([a-z_]\w*)/i,
479
+ function: /^\s*(?:procedure|function)\s+([a-z_][\w.]*)/i,
480
+ class: /^\s*([a-z_]\w*)\s*=\s*class\b/i,
481
+ struct: /^\s*([a-z_]\w*)\s*=\s*(?:packed\s+)?(?:record|object)\b/i,
482
+ interface: /^\s*([a-z_]\w*)\s*=\s*interface\b/i,
483
+ enum: /^\s*([a-z_]\w*)\s*=\s*\(\s*[a-z_]\w*(?:\s*,\s*[a-z_]\w*)*\s*\)\s*;?/i,
484
+ },
485
+ relationships: { plainImport: /^\s*uses\s+([a-z_][\w.,\s]*)/i },
486
+ skipCallObjects: [],
487
+ },
488
+ },
489
+ vala: {
490
+ indentBased: false, endKeyword: null,
491
+ comment: { line: "//", block: ["/*", "*/"] },
492
+ graph: {
493
+ entities: {
494
+ module: /^\s*(?:public\s+)?namespace\s+([A-Za-z_][\w.]*)/,
495
+ class: /^\s*(?:(?:public|private|protected|internal|abstract|sealed|static)\s+)*class\s+([A-Za-z_]\w*)/,
496
+ interface: /^\s*(?:(?:public|private|protected|internal)\s+)*interface\s+([A-Za-z_]\w*)/,
497
+ struct: /^\s*(?:(?:public|private|protected|internal)\s+)*struct\s+([A-Za-z_]\w*)/,
498
+ enum: /^\s*(?:(?:public|private|protected|internal)\s+)*enum\s+([A-Za-z_]\w*)/,
499
+ method: /^\s*(?!return\b|if\b|else\b|while\b|for\b|foreach\b|switch\b|case\b|do\b|new\b|throw\b|yield\b)(?:(?:public|private|protected|internal|static|virtual|override|abstract|async|extern|inline|sealed|weak|unowned|owned|const|signal|delegate)\s+)*[\w.<>?\[\]*]+\s+([a-z_]\w*)\s*\(/,
500
+ },
501
+ relationships: { using: /^\s*using\s+([A-Za-z_][\w.]*)/ },
502
+ skipCallObjects: [],
503
+ },
504
+ },
505
+ haxe: {
506
+ indentBased: false, endKeyword: null,
507
+ comment: { line: "//", block: ["/*", "*/"] },
508
+ graph: {
509
+ entities: {
510
+ module: /^\s*package\s+([\w.]+)/,
511
+ class: /^\s*(?:(?:public|private|extern|final)\s+)*class\s+([A-Za-z_]\w*)/,
512
+ interface: /^\s*(?:(?:public|private|extern)\s+)*interface\s+([A-Za-z_]\w*)/,
513
+ enum: /^\s*(?:(?:public|private|extern)\s+)*enum\s+(?!abstract\b)([A-Za-z_]\w*)/,
514
+ type: /^\s*(?:(?:public|private)\s+)*typedef\s+([A-Za-z_]\w*)/,
515
+ struct: /^\s*(?:(?:public|private|extern)\s+)*(?:enum\s+)?abstract\s+([A-Za-z_]\w*)/,
516
+ method: /^\s*(?:[\w@:.]+\s+)*function\s+([A-Za-z_]\w*)/,
517
+ },
518
+ relationships: {
519
+ import: /^\s*import\s+([\w.*]+)/,
520
+ using: /^\s*using\s+([\w.]+)/,
521
+ },
522
+ skipCallObjects: [],
523
+ },
524
+ },
525
+ nix: {
526
+ indentBased: false, endKeyword: null,
527
+ comment: { line: "#", block: ["/*", "*/"] },
528
+ graph: {
529
+ // Require BOTH a space before `=` (rejects shell `VAR=val` in build-script
530
+ // strings) AND a trailing `;`/`{` (real Nix attrs always terminate with
531
+ // `;`, or open a nested attrset with `{`) — this drops the actively-harmful
532
+ // false positives from spaced `key = value` config embedded in `''…''`
533
+ // string literals (INI/systemd/gitconfig content), at the cost of missing
534
+ // multi-line string attrs (`x = ''`). Conservative by design.
535
+ entities: { constant: /^\s*([\w'.-]+)\s+=\s*(?!=).*?[;{]\s*$/ },
536
+ relationships: {},
537
+ skipCallObjects: [],
538
+ },
539
+ },
540
+ glsl: {
541
+ indentBased: false, endKeyword: null,
542
+ comment: { line: "//", block: ["/*", "*/"] },
543
+ graph: {
544
+ entities: {
545
+ function: /^\s*(?!(?:if|for|while|switch|else|return|do|case|default)\b)(?:[A-Za-z_]\w*[\s*&]+){1,8}([A-Za-z_]\w*)\s*\(/,
546
+ struct: /^\s*struct\s+([A-Za-z_]\w*)/,
547
+ constant: /^\s*#\s*define\s+([A-Za-z_]\w*)/,
548
+ type: /^\s*layout\s*\([^)]*\)\s*(?:uniform|buffer)\s+([A-Za-z_]\w*)\s*\{/,
549
+ },
550
+ relationships: { import: /^\s*#\s*include\s+[<"]([^>"]+)[>"]/ },
551
+ skipCallObjects: ["gl_Position", "gl_FragCoord", "gl_FragColor", "gl_FragDepth", "gl_VertexID", "gl_InstanceID"],
552
+ },
553
+ },
554
+ hlsl: {
555
+ indentBased: false, endKeyword: null,
556
+ comment: { line: "//", block: ["/*", "*/"] },
557
+ graph: {
558
+ entities: {
559
+ function: /^\s*(?!(?:if|for|while|switch|else|return|do|case|default)\b)(?:[A-Za-z_]\w*[\s*&]+){1,8}([A-Za-z_]\w*)\s*\(/,
560
+ struct: /^\s*struct\s+([A-Za-z_]\w*)/,
561
+ constant: /^\s*#\s*define\s+([A-Za-z_]\w*)/,
562
+ type: /^\s*(?:cbuffer|tbuffer|ConstantBuffer)\s+([A-Za-z_]\w*)/,
563
+ },
564
+ relationships: { import: /^\s*#\s*include\s+[<"]([^>"]+)[>"]/ },
565
+ skipCallObjects: ["input", "output", "SV_Target", "SV_Position", "SV_Depth"],
566
+ },
567
+ },
568
+ metal: {
569
+ indentBased: false, endKeyword: null,
570
+ comment: { line: "//", block: ["/*", "*/"] },
571
+ graph: {
572
+ entities: {
573
+ function: /^\s*(?!(?:if|for|while|switch|else|return|do|case|default)\b)(?:[A-Za-z_]\w*[\s*&]+){1,8}([A-Za-z_]\w*)\s*\(/,
574
+ struct: /^\s*struct\s+([A-Za-z_]\w*)/,
575
+ constant: /^\s*#\s*define\s+([A-Za-z_]\w*)/,
576
+ },
577
+ relationships: { import: /^\s*#\s*(?:include|import)\s+[<"]([^>"]+)[>"]/ },
578
+ skipCallObjects: ["metal", "simd", "threadgroup", "device", "constant"],
579
+ },
580
+ },
581
+ wgsl: {
582
+ indentBased: false, endKeyword: null,
583
+ comment: { line: "//", block: ["/*", "*/"] },
584
+ graph: {
585
+ entities: {
586
+ function: /^\s*fn\s+([A-Za-z_]\w*)/,
587
+ struct: /^\s*struct\s+([A-Za-z_]\w*)/,
588
+ constant: /^\s*(?:@\w+\([^)]*\)\s*)*(?:const|override|var(?:<[^>]*>)?)\s+([A-Za-z_]\w*)/,
589
+ },
590
+ relationships: {},
591
+ skipCallObjects: [],
592
+ },
593
+ },
594
+ shaderlab: {
595
+ indentBased: false, endKeyword: null,
596
+ comment: { line: "//", block: ["/*", "*/"] },
597
+ graph: {
598
+ entities: {
599
+ type: /^\s*Shader\s+"([^"]+)"/,
600
+ function: /^\s*(?!(?:if|for|while|switch|else|return|do|case|default)\b)(?:[A-Za-z_]\w*[\s*&]+){1,8}([A-Za-z_]\w*)\s*\(/,
601
+ struct: /^\s*struct\s+([A-Za-z_]\w*)/,
602
+ constant: /^\s*(_[A-Za-z]\w*)\s*\(\s*"/,
603
+ },
604
+ relationships: { import: /^\s*#\s*include\s+[<"]([^>"]+)[>"]/ },
605
+ skipCallObjects: ["UNITY_MATRIX_MVP", "_Time", "_WorldSpaceCameraPos", "unity_ObjectToWorld"],
606
+ },
607
+ },
608
+ cg: {
609
+ indentBased: false, endKeyword: null,
610
+ comment: { line: "//", block: ["/*", "*/"] },
611
+ graph: {
612
+ entities: {
613
+ function: /^\s*(?!(?:if|for|while|switch|else|return|do|case|default)\b)(?:[A-Za-z_]\w*[\s*&]+){1,8}([A-Za-z_]\w*)\s*\(/,
614
+ struct: /^\s*struct\s+([A-Za-z_]\w*)/,
615
+ constant: /^\s*#\s*define\s+([A-Za-z_]\w*)/,
616
+ },
617
+ relationships: { import: /^\s*#\s*include\s+[<"]([^>"]+)[>"]/ },
618
+ skipCallObjects: ["UNITY_MATRIX_MVP", "_Time", "_WorldSpaceCameraPos"],
619
+ },
620
+ },
621
+ hcl: {
622
+ indentBased: false, endKeyword: null,
623
+ comment: { line: "#", block: ["/*", "*/"] },
624
+ graph: {
625
+ entities: {
626
+ resource: /^\s*resource\s+"[^"]+"\s+"([^"]+)"/,
627
+ data: /^\s*data\s+"[^"]+"\s+"([^"]+)"/,
628
+ variable: /^\s*variable\s+"([^"]+)"/,
629
+ module: /^\s*module\s+"([^"]+)"/,
630
+ output: /^\s*output\s+"([^"]+)"/,
631
+ provider: /^\s*provider\s+"([^"]+)"/,
632
+ },
633
+ relationships: { import: /^\s*source\s*=\s*"([^"]+)"/ },
634
+ skipCallObjects: [],
635
+ },
636
+ },
637
+ cmake: {
638
+ indentBased: false, endKeyword: null,
639
+ comment: { line: "#", block: null },
640
+ graph: {
641
+ entities: {
642
+ function: /^\s*function\s*\(\s*([A-Za-z_]\w*)/i,
643
+ macro: /^\s*macro\s*\(\s*([A-Za-z_]\w*)/i,
644
+ constant: /^\s*set\s*\(\s*([A-Za-z_]\w*)/i,
645
+ },
646
+ relationships: { import: /^\s*(?:include|add_subdirectory|find_package)\s*\(\s*([A-Za-z_0-9./${}-]+)/i },
647
+ skipCallObjects: [],
648
+ },
649
+ },
650
+ gradle: {
651
+ indentBased: false, endKeyword: null,
652
+ comment: { line: "//", block: ["/*", "*/"] },
653
+ graph: {
654
+ entities: {
655
+ task: /^\s*task\s+([A-Za-z_]\w*)/,
656
+ def: /^\s*def\s+([A-Za-z_]\w*)/,
657
+ },
658
+ relationships: { import: /^\s*import\s+([\w.]+)/ },
659
+ skipCallObjects: [],
660
+ },
661
+ },
662
+ starlark: {
663
+ indentBased: true, endKeyword: null,
664
+ comment: { line: "#", block: null },
665
+ graph: {
666
+ entities: {
667
+ function: /^\s*def\s+([A-Za-z_]\w*)/,
668
+ rule: /^\s*([A-Za-z_]\w*)\s*=\s*(?:rule|provider|aspect|repository_rule|tag_class|module_extension)\s*\(/,
669
+ },
670
+ relationships: { import: /^\s*load\s*\(\s*["']([^"']+)["']/ },
671
+ skipCallObjects: [],
672
+ },
673
+ },
674
+ ql: {
675
+ indentBased: false, endKeyword: null,
676
+ comment: { line: "//", block: ["/*", "*/"] },
677
+ graph: {
678
+ entities: {
679
+ class: /^\s*(?:abstract\s+|final\s+|private\s+|library\s+|deprecated\s+|additional\s+|external\s+|extensible\s+)*class\s+([A-Za-z_]\w*)/,
680
+ function: /^\s*(?:abstract\s+|cached\s+|private\s+|final\s+|override\s+|additional\s+|deprecated\s+|library\s+|external\s+|extensible\s+|pragma\s*\[[^\]]*\]\s+|bindingset\s*\[[^\]]*\]\s+)*(?!(?:and|or|not|if|then|else|in|exists|forall|forex|count|sum|strictsum|strictcount|any|none|select|where|from|instanceof)\b)(?:[A-Za-z_][\w.]*)\s+([a-z_]\w*)\s*\(/,
681
+ module: /^\s*(?:private\s+|library\s+)*module\s+([A-Za-z_]\w*)/,
682
+ type: /^\s*newtype\s+([A-Za-z_]\w*)/,
683
+ },
684
+ relationships: {
685
+ import: /^\s*(?:private\s+)?import\s+([\w.]+)/,
686
+ extends: /\bclass\s+\w+\s+extends\s+([\w.]+)/,
687
+ },
688
+ skipCallObjects: [],
689
+ },
690
+ },
691
+ systemrdl: {
692
+ indentBased: false, endKeyword: null,
693
+ comment: { line: "//", block: ["/*", "*/"] },
694
+ graph: {
695
+ entities: {
696
+ addrmap: /^\s*addrmap\s+([A-Za-z_]\w*)/,
697
+ regfile: /^\s*regfile\s+([A-Za-z_]\w*)/,
698
+ reg: /^\s*reg\s+([A-Za-z_]\w*)/,
699
+ field: /^\s*field\s+([A-Za-z_]\w*)/,
700
+ mem: /^\s*mem\s+([A-Za-z_]\w*)/,
701
+ signal: /^\s*signal\s+([A-Za-z_]\w*)/,
702
+ enum: /^\s*enum\s+([A-Za-z_]\w*)/,
703
+ struct: /^\s*struct\s+([A-Za-z_]\w*)/,
704
+ },
705
+ relationships: {},
706
+ skipCallObjects: [],
707
+ },
708
+ },
709
+ zeek: {
710
+ indentBased: false, endKeyword: null,
711
+ comment: { line: "#", block: null },
712
+ graph: {
713
+ entities: {
714
+ function: /^\s*function\s+([A-Za-z_][\w:]*)/,
715
+ event: /^\s*event\s+([A-Za-z_][\w:]*)/,
716
+ hook: /^\s*hook\s+([A-Za-z_][\w:]*)/,
717
+ global: /^\s*global\s+(?!function\b|event\b|hook\b)([A-Za-z_]\w*)/,
718
+ constant: /^\s*const\s+([A-Za-z_]\w*)/,
719
+ type: /^\s*type\s+([A-Za-z_]\w*)/,
720
+ module: /^\s*module\s+([A-Za-z_]\w*)/,
721
+ },
722
+ relationships: { import: /^\s*@load\s+([\w./-]+)/ },
723
+ skipCallObjects: [],
724
+ },
725
+ },
726
+ embedded_template: {
727
+ indentBased: false, endKeyword: null,
728
+ comment: { line: null, block: ["<%#", "%>"] },
729
+ graph: {
730
+ entities: {},
731
+ relationships: { include: /<%[-=]?\s*include\s*\(\s*['"`]([^'"`]+)['"`]/ },
732
+ skipCallObjects: [],
733
+ },
734
+ },
238
735
  // ─── Solidity ────────────────────────────────────────────────────────────────
239
736
  // Real chunking is done by tree-sitter-solidity (GRAMMAR_MAP); these regex
240
737
  // patterns are the fallback used only when tree-sitter is unavailable.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sweet-search",
3
- "version": "2.6.4",
3
+ "version": "2.6.7",
4
4
  "description": "Sweet Search - SOTA Hybrid Code Search Engine with WASM CatBoost Query Router, Semantic/Lexical/Structural Search, and Multilingual Support",
5
5
  "type": "module",
6
6
  "main": "core/search/sweet-search.js",
@@ -167,13 +167,13 @@
167
167
  "vitest": "^4.0.16"
168
168
  },
169
169
  "optionalDependencies": {
170
- "@sweet-search/native-darwin-arm64": "2.6.4",
171
- "@sweet-search/native-darwin-x64": "2.6.4",
172
- "@sweet-search/native-linux-arm64-gnu": "2.6.4",
173
- "@sweet-search/native-linux-arm64-gnu-cuda": "2.6.4",
174
- "@sweet-search/native-linux-x64-gnu": "2.6.4",
175
- "@sweet-search/native-linux-x64-gnu-cuda": "2.6.4",
176
- "@sweet-search/bg-priority": "2.6.4"
170
+ "@sweet-search/native-darwin-arm64": "2.6.7",
171
+ "@sweet-search/native-darwin-x64": "2.6.7",
172
+ "@sweet-search/native-linux-arm64-gnu": "2.6.7",
173
+ "@sweet-search/native-linux-arm64-gnu-cuda": "2.6.7",
174
+ "@sweet-search/native-linux-x64-gnu": "2.6.7",
175
+ "@sweet-search/native-linux-x64-gnu-cuda": "2.6.7",
176
+ "@sweet-search/bg-priority": "2.6.7"
177
177
  },
178
178
  "engines": {
179
179
  "node": ">=18.0.0"