graph-indexer 2.1.1 → 3.0.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 (131) hide show
  1. package/CHANGELOG.md +312 -1
  2. package/README.md +236 -312
  3. package/SECURITY.md +53 -58
  4. package/bin/graph-indexer.mjs +251 -0
  5. package/integrations/claude-code/.claude-plugin/plugin.json +9 -0
  6. package/integrations/claude-code/.mcp.json +8 -0
  7. package/integrations/claude-code/agents/code-structure.md +22 -0
  8. package/integrations/claude-code/hooks/gi-hook.mjs +103 -0
  9. package/integrations/claude-code/hooks/hooks.json +16 -0
  10. package/integrations/opencode/graph-indexer.js +129 -0
  11. package/package.json +32 -109
  12. package/src/cli/helper.mjs +67 -0
  13. package/src/cli/hook.mjs +366 -0
  14. package/src/cli/init.mjs +272 -0
  15. package/src/cli/resident.mjs +185 -0
  16. package/src/index/discover.mjs +128 -0
  17. package/src/index/fingerprint.mjs +30 -0
  18. package/src/index/graph.mjs +61 -0
  19. package/src/index/indexer.mjs +476 -0
  20. package/src/index/modules.mjs +332 -0
  21. package/src/index/resolver.mjs +961 -0
  22. package/src/mcp/render.mjs +60 -0
  23. package/src/mcp/server.mjs +147 -0
  24. package/src/mcp/tools.mjs +974 -0
  25. package/src/parse/arity.mjs +153 -0
  26. package/src/parse/extract.mjs +1038 -0
  27. package/src/parse/lang/csharp.mjs +106 -0
  28. package/src/parse/lang/ecma.mjs +438 -0
  29. package/src/parse/lang/go.mjs +194 -0
  30. package/src/parse/lang/jvm.mjs +118 -0
  31. package/src/parse/lang/kotlin.mjs +97 -0
  32. package/src/parse/lang/misc.mjs +115 -0
  33. package/src/parse/lang/native.mjs +126 -0
  34. package/src/parse/lang/python.mjs +153 -0
  35. package/src/parse/lang/rust.mjs +157 -0
  36. package/src/parse/lang/scripting.mjs +219 -0
  37. package/src/parse/languages.mjs +48 -0
  38. package/src/parse/runtime.mjs +56 -0
  39. package/src/query/check.mjs +345 -0
  40. package/src/query/facts.mjs +323 -0
  41. package/src/query/intel.mjs +683 -0
  42. package/src/query/read.mjs +81 -0
  43. package/src/query/testcmd.mjs +130 -0
  44. package/src/query/textsearch.mjs +178 -0
  45. package/src/search/search.mjs +210 -0
  46. package/src/search/tokenize.mjs +188 -0
  47. package/src/store/db.mjs +169 -0
  48. package/src/util/git.mjs +30 -0
  49. package/src/util/paths.mjs +63 -0
  50. package/src/util/regex.mjs +2 -0
  51. package/vendor/grammars/bash.wasm.gz +0 -0
  52. package/vendor/grammars/c.wasm.gz +0 -0
  53. package/vendor/grammars/c_sharp.wasm.gz +0 -0
  54. package/vendor/grammars/cpp.wasm.gz +0 -0
  55. package/vendor/grammars/css.wasm.gz +0 -0
  56. package/vendor/grammars/go.wasm.gz +0 -0
  57. package/vendor/grammars/java.wasm.gz +0 -0
  58. package/vendor/grammars/javascript.wasm.gz +0 -0
  59. package/vendor/grammars/kotlin.wasm.gz +0 -0
  60. package/vendor/grammars/manifest.json +148 -0
  61. package/vendor/grammars/php.wasm.gz +0 -0
  62. package/vendor/grammars/python.wasm.gz +0 -0
  63. package/vendor/grammars/ruby.wasm.gz +0 -0
  64. package/vendor/grammars/rust.wasm.gz +0 -0
  65. package/vendor/grammars/scala.wasm.gz +0 -0
  66. package/vendor/grammars/tsx.wasm.gz +0 -0
  67. package/vendor/grammars/typescript.wasm.gz +0 -0
  68. package/vendor/web-tree-sitter/web-tree-sitter.js +3980 -0
  69. package/vendor/web-tree-sitter/web-tree-sitter.wasm +0 -0
  70. package/cli-ui.mjs +0 -78
  71. package/colbert.mjs +0 -168
  72. package/config.mjs +0 -494
  73. package/daemon-ctl.mjs +0 -175
  74. package/daemon-lock.mjs +0 -69
  75. package/embedders/python/mlx_embed_server.py +0 -61
  76. package/embedders/python/requirements-mlx.txt +0 -5
  77. package/embedders/setup-mlx.mjs +0 -110
  78. package/embeddings.mjs +0 -571
  79. package/engine/binary.mjs +0 -437
  80. package/engine/memory.mjs +0 -1003
  81. package/engine/sqlite.mjs +0 -1136
  82. package/enrichment.mjs +0 -521
  83. package/git-signals.mjs +0 -248
  84. package/indexer.mjs +0 -546
  85. package/init.mjs +0 -1809
  86. package/layout.mjs +0 -123
  87. package/mcp/centrality.mjs +0 -117
  88. package/mcp/format.mjs +0 -61
  89. package/mcp/resolver.mjs +0 -116
  90. package/mcp/symbolgraph.mjs +0 -137
  91. package/mcp/taint.mjs +0 -225
  92. package/mcp/tools.mjs +0 -1582
  93. package/mcp/topology.mjs +0 -676
  94. package/mcp-server.mjs +0 -197
  95. package/parse/extractor.mjs +0 -628
  96. package/parse/imports.mjs +0 -365
  97. package/parse/interprocedural.mjs +0 -134
  98. package/parse/languages.mjs +0 -253
  99. package/parse/metadata.mjs +0 -701
  100. package/parse/routes.mjs +0 -327
  101. package/parse/scip.mjs +0 -391
  102. package/parse/taint-patterns.mjs +0 -119
  103. package/prompts/CORE.md +0 -91
  104. package/prompts/DOMAIN_TEMPLATE.md +0 -46
  105. package/prompts/INTEGRATION.md +0 -123
  106. package/prompts/frameworks/ANDROID.md +0 -17
  107. package/prompts/frameworks/ASPNET_CORE.md +0 -19
  108. package/prompts/frameworks/FASTAPI_DJANGO.md +0 -20
  109. package/prompts/frameworks/LARAVEL_SYMFONY.md +0 -22
  110. package/prompts/frameworks/NODE_EXPRESS_NESTJS.md +0 -19
  111. package/prompts/frameworks/RAILS.md +0 -20
  112. package/prompts/frameworks/REACT.md +0 -20
  113. package/prompts/frameworks/SPRING_BOOT.md +0 -20
  114. package/prompts/languages/BASH.md +0 -22
  115. package/prompts/languages/C.md +0 -21
  116. package/prompts/languages/CSHARP.md +0 -24
  117. package/prompts/languages/CSS_SCSS.md +0 -22
  118. package/prompts/languages/GO.md +0 -24
  119. package/prompts/languages/JAVA.md +0 -23
  120. package/prompts/languages/JAVASCRIPT_TYPESCRIPT.md +0 -24
  121. package/prompts/languages/KOTLIN.md +0 -24
  122. package/prompts/languages/PHP.md +0 -23
  123. package/prompts/languages/PYTHON.md +0 -23
  124. package/prompts/languages/RUBY.md +0 -23
  125. package/prompts/languages/RUST.md +0 -21
  126. package/prompts/languages/SWIFT.md +0 -21
  127. package/seal.mjs +0 -400
  128. package/search-core.mjs +0 -777
  129. package/search-sparse.mjs +0 -183
  130. package/storage.mjs +0 -73
  131. package/watch-daemon.mjs +0 -289
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Parameter and argument counting across languages, from tree-sitter nodes: how many arguments a
3
+ * definition accepts ({ min, max }, max = Infinity for variadics) and how many a call passes
4
+ * ({ n, open }, open = a spread/splat makes n a lower bound). Used by the edit checker to spot
5
+ * call sites that no longer match a changed signature, without compiling anything.
6
+ */
7
+ import { escapeRegExp } from '../util/regex.mjs';
8
+
9
+ const PARAM_LIST_TYPES = new Set(['formal_parameters', 'parameters', 'parameter_list', 'function_value_parameters', 'method_parameters',
10
+ 'lambda_parameters', 'block_parameters', 'parameter_clause']);
11
+ const SKIP_PARAM = /^(comment|line_comment|block_comment|self_parameter|this|attribute_item|attribute|annotation|marker_annotation|decorator|keyword_separator|positional_separator|type_parameters|block_parameter)$/;
12
+ const VARIADIC = /(rest_pattern|rest_parameter|spread|variadic|splat|list_splat_pattern|dictionary_splat_pattern|varargs)/;
13
+ const OPTIONAL = /(optional_parameter|default_parameter|typed_default_parameter|optional_parameter_declaration|keyword_parameter)/;
14
+ const CALL_TYPES = new Set(['call_expression', 'call', 'method_invocation', 'invocation_expression', 'new_expression', 'object_creation_expression',
15
+ 'function_call_expression', 'member_call_expression', 'scoped_call_expression', 'nullsafe_member_call_expression', 'method_call_expression', 'macro_invocation']);
16
+ const ARG_LIST_TYPES = new Set(['arguments', 'argument_list', 'value_arguments', 'actual_parameters']);
17
+ const SPREAD_ARG = /^(spread_element|list_splat|dictionary_splat|splat_argument|hash_splat_argument|variadic_argument)$/;
18
+
19
+ function paramsNodeOf(def) {
20
+ const direct = def.childForFieldName('parameters');
21
+ if (direct) return direct;
22
+ const value = def.childForFieldName('value');
23
+ const vp = value?.childForFieldName?.('parameters');
24
+ if (vp) return vp;
25
+ if (value && (value.type === 'arrow_function') && value.childForFieldName('parameter')) return value.childForFieldName('parameter');
26
+ for (const c of def.namedChildren) {
27
+ if (PARAM_LIST_TYPES.has(c.type)) return c;
28
+ // C/C++: declarator → function_declarator → parameters
29
+ if (/declarator$/.test(c.type)) { const p = c.childForFieldName('parameters') ?? c.namedChildren.find(x => PARAM_LIST_TYPES.has(x.type)); if (p) return p; }
30
+ }
31
+ return null;
32
+ }
33
+
34
+ /**
35
+ * Python decorators that turn a def into something other than a plain function: properties, and
36
+ * classes (CapWords by convention, e.g. a caching descriptor). How the result is called is up to
37
+ * that object, so the def's parameters say nothing about its call sites.
38
+ */
39
+ function isDescriptorDecorator(d) {
40
+ const last = d.split('.').pop();
41
+ return /(property|setter|getter|deleter)$/i.test(last) || /^_*[A-Z]/.test(last);
42
+ }
43
+
44
+ /**
45
+ * Accepted argument count of a function/method definition node.
46
+ * @param {object} def tree-sitter node of the definition
47
+ * @param {{ method?: boolean, lang?: string, isStatic?: boolean, decorators?: string[] }} ctx
48
+ * @returns {{ min: number, max: number } | null}
49
+ */
50
+ export function paramArity(def, { method = false, lang = '', isStatic = false, decorators = [] } = {}) {
51
+ const params = paramsNodeOf(def);
52
+ if (!params) return null;
53
+ if (params.type === 'identifier') return { min: 1, max: 1 }; // `x => …`
54
+ let min = 0, max = 0, first = true, keywordOnly = false;
55
+ const py = lang === 'python';
56
+ if (py && decorators.some(isDescriptorDecorator)) return null;
57
+ for (const p of params.namedChildren) {
58
+ const t = p.type;
59
+ if (t === 'keyword_separator') { keywordOnly = true; continue; }
60
+ if (SKIP_PARAM.test(t)) continue;
61
+ const text = p.text;
62
+ // the receiver: Python self/cls (not for staticmethods), TS `this: T`
63
+ if (first && py && method && !isStatic && !decorators.some(d => /staticmethod/.test(d)) && /^(self|cls)\b/.test(text)) { first = false; continue; }
64
+ first = false;
65
+ if (/^this\s*[:?]/.test(text)) continue;
66
+ if (VARIADIC.test(t) || /^(\.\.\.|\*\*?)/.test(text) || /^params\s/.test(text) || /\bvararg\b/.test(text) || /\.\.\.\s*\w*$/.test(text) && lang === 'go') { max = Infinity; continue; }
67
+ // Go: `a, b int` declares two parameters
68
+ const names = t === 'parameter_declaration' && lang === 'go' ? p.namedChildren.filter(c => c.type === 'identifier').length || 1 : 1;
69
+ const optional = OPTIONAL.test(t) || !!p.childForFieldName('value') || !!p.childForFieldName('default_value')
70
+ || p.namedChildren.some(c => c.type === 'equals_value_clause')
71
+ || (['kotlin', 'scala', 'swift'].includes(lang) && /[^=]=[^=>]/.test(text));
72
+ max += names;
73
+ if (!optional && !(keywordOnly && py && /=/.test(text))) min += names;
74
+ }
75
+ return { min, max };
76
+ }
77
+
78
+ /** Node of the call whose callee name sits at (row, column), with its argument list. */
79
+ export function callAt(tree, row, column) {
80
+ let n = tree.rootNode.descendantForPosition({ row, column });
81
+ for (let g = 0; n && g < 6; g++, n = n.parent) {
82
+ if (CALL_TYPES.has(n.type)) return n;
83
+ }
84
+ return null;
85
+ }
86
+
87
+ /** Arguments passed by a call node: { n, open } or null when they cannot be counted. */
88
+ export function callArgc(call) {
89
+ let args = call.childForFieldName('arguments');
90
+ if (!args) args = call.namedChildren.find(c => ARG_LIST_TYPES.has(c.type)) ?? null;
91
+ if (!args) {
92
+ // Kotlin: call_suffix → value_arguments (+ trailing lambda)
93
+ const suffix = call.namedChildren.find(c => c.type === 'call_suffix');
94
+ if (suffix) {
95
+ const va = suffix.namedChildren.find(c => c.type === 'value_arguments');
96
+ const lam = suffix.namedChildren.some(c => c.type === 'annotated_lambda') ? 1 : 0;
97
+ if (!va && !lam) return null;
98
+ const n = (va ? va.namedChildren.filter(c => c.type === 'value_argument').length : 0) + lam;
99
+ return { n, open: va ? va.namedChildren.some(c => /\*/.test(c.text.slice(0, 1))) : false };
100
+ }
101
+ return null;
102
+ }
103
+ let n = 0, open = false;
104
+ for (const c of args.namedChildren) {
105
+ if (/comment/.test(c.type)) continue;
106
+ if (SPREAD_ARG.test(c.type) || /^\.\.\./.test(c.text) || /\.\.\.$/.test(c.text)) { open = true; continue; }
107
+ if (c.type === 'block' || c.type === 'do_block') continue; // Ruby block argument
108
+ n++;
109
+ }
110
+ return { n, open };
111
+ }
112
+
113
+ /**
114
+ * Accepted argument count read from a stored signature (`public List<T> find(String q, T... xs)`):
115
+ * for languages whose overloads are separate methods, to bind a call to the one it can reach.
116
+ * Parameters with a default value are optional; `...`, `vararg` and `params` make it open-ended.
117
+ * @returns {{ min: number, max: number } | null}
118
+ */
119
+ export function sigArity(sig, name) {
120
+ if (!sig) return null;
121
+ const m = new RegExp(`(?:^|[^\\w$])${escapeRegExp(name)}\\s*(?:<[^()]*>)?\\s*\\(`).exec(sig);
122
+ if (!m) return null;
123
+ let depth = 0, cur = '', min = 0, max = 0, done = false;
124
+ const param = (p) => {
125
+ p = p.trim();
126
+ if (!p) return;
127
+ if (/\.\.\.|^vararg\s|^params\s/.test(p)) { max = Infinity; return; }
128
+ max++;
129
+ if (!/[^=!<>]=[^=]/.test(p)) min++;
130
+ };
131
+ for (let i = m.index + m[0].length; i < sig.length; i++) {
132
+ const ch = sig[i];
133
+ if (ch === ')' && depth === 0) { param(cur); done = true; break; }
134
+ if ('([{<'.includes(ch)) depth++;
135
+ else if (')]}>'.includes(ch)) depth--;
136
+ if (ch === ',' && depth === 0) { param(cur); cur = ''; } else cur += ch;
137
+ }
138
+ return done ? { min, max } : null;
139
+ }
140
+
141
+ /** Does a call passing `a` arguments fit a definition accepting `r`? */
142
+ export function fits(a, r) {
143
+ if (!a || !r) return true;
144
+ if (a.n > r.max) return false;
145
+ if (!a.open && a.n < r.min) return false;
146
+ return true;
147
+ }
148
+
149
+ export function describeArity(r) {
150
+ if (!r) return '?';
151
+ if (r.max === Infinity) return `${r.min}+`;
152
+ return r.min === r.max ? String(r.min) : `${r.min}–${r.max}`;
153
+ }