graph-indexer 2.1.0 → 3.0.0

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