@wrongstack/tools 0.313.0 → 0.313.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 (134) hide show
  1. package/dist/audit.js +10 -4055
  2. package/dist/bash.js +9 -2308
  3. package/dist/batch-tool-use.js +2 -187
  4. package/dist/browser/index.js +25 -1339
  5. package/dist/builtin.js +69 -33949
  6. package/dist/chunk-2CTB3UK5.js +197 -0
  7. package/dist/chunk-2ME7ZWDD.js +1272 -0
  8. package/dist/chunk-2TFQDEPU.js +113 -0
  9. package/dist/chunk-2ZCJNKFE.js +315 -0
  10. package/dist/chunk-3PVYQFRQ.js +472 -0
  11. package/dist/chunk-3QMQBO5Z.js +89 -0
  12. package/dist/chunk-42AKKX7O.js +385 -0
  13. package/dist/chunk-42SKEETB.js +113 -0
  14. package/dist/chunk-4BHUSMNL.js +104 -0
  15. package/dist/chunk-4I4LWFOO.js +431 -0
  16. package/dist/chunk-553IQUMO.js +478 -0
  17. package/dist/chunk-55KF77OK.js +1944 -0
  18. package/dist/chunk-6HLZK37X.js +359 -0
  19. package/dist/chunk-6RNIFLG4.js +305 -0
  20. package/dist/chunk-A6BRWIXN.js +317 -0
  21. package/dist/chunk-AHHDWNXC.js +200 -0
  22. package/dist/chunk-B2CIOKWP.js +899 -0
  23. package/dist/chunk-BTSFTGIL.js +7 -0
  24. package/dist/chunk-D33S4RQG.js +222 -0
  25. package/dist/chunk-DIJKHSUO.js +134 -0
  26. package/dist/chunk-DPL47QGS.js +3515 -0
  27. package/dist/chunk-EMRGN4KM.js +170 -0
  28. package/dist/chunk-FGOABE4Z.js +955 -0
  29. package/dist/chunk-FW65TP4G.js +520 -0
  30. package/dist/chunk-GOIZNNOA.js +221 -0
  31. package/dist/chunk-H5MJUAA6.js +295 -0
  32. package/dist/chunk-H5OHH6F4.js +223 -0
  33. package/dist/chunk-HC5RM4WY.js +199 -0
  34. package/dist/chunk-HEQFMLZ7.js +190 -0
  35. package/dist/chunk-HFXSNKCV.js +196 -0
  36. package/dist/chunk-HXSBQ2SE.js +1723 -0
  37. package/dist/chunk-ILESNGNM.js +163 -0
  38. package/dist/chunk-INF5CGAO.js +137 -0
  39. package/dist/chunk-IWDFZ6XR.js +337 -0
  40. package/dist/chunk-IXMNTNW5.js +238 -0
  41. package/dist/chunk-J4SRJKBW.js +428 -0
  42. package/dist/chunk-J5SKD6LN.js +235 -0
  43. package/dist/chunk-JRJJX3L5.js +424 -0
  44. package/dist/chunk-KXNDHMUB.js +366 -0
  45. package/dist/chunk-LIJQMYYX.js +59 -0
  46. package/dist/chunk-MAN26PZ5.js +260 -0
  47. package/dist/chunk-MKRQMLZA.js +474 -0
  48. package/dist/chunk-NBDZMMG2.js +169 -0
  49. package/dist/chunk-NHA6BEIH.js +101 -0
  50. package/dist/chunk-OA6YJIWL.js +4412 -0
  51. package/dist/chunk-OZC255IC.js +2830 -0
  52. package/dist/chunk-PUR6WU2B.js +154 -0
  53. package/dist/chunk-Q5JPPCZC.js +12 -0
  54. package/dist/chunk-QBV725YG.js +128 -0
  55. package/dist/chunk-QHVW4AAM.js +892 -0
  56. package/dist/chunk-QNJ7AQ4B.js +1000 -0
  57. package/dist/chunk-RGISBZBD.js +231 -0
  58. package/dist/chunk-RJZQWEMS.js +84 -0
  59. package/dist/chunk-RP2ZA47V.js +15 -0
  60. package/dist/chunk-RXISBFR5.js +315 -0
  61. package/dist/chunk-S5CCLZL3.js +99 -0
  62. package/dist/chunk-TVTCSBJF.js +122 -0
  63. package/dist/chunk-U4D5S3VQ.js +21 -0
  64. package/dist/chunk-U4VAATKP.js +193 -0
  65. package/dist/chunk-UKU2ZX4C.js +203 -0
  66. package/dist/chunk-UNSKG6DC.js +159 -0
  67. package/dist/chunk-URFKEIHM.js +1091 -0
  68. package/dist/chunk-UTV7YAW7.js +178 -0
  69. package/dist/chunk-V43EQ6VR.js +68 -0
  70. package/dist/chunk-VB3MJGCV.js +610 -0
  71. package/dist/chunk-WHIIIREL.js +223 -0
  72. package/dist/chunk-XMIFYKUT.js +1371 -0
  73. package/dist/chunk-YF2RSV34.js +54 -0
  74. package/dist/chunk-Z6DAKQ3U.js +1 -0
  75. package/dist/chunk-ZIGAZFWE.js +522 -0
  76. package/dist/circuit-breaker.js +3 -191
  77. package/dist/codebase-index/index.js +84 -13688
  78. package/dist/codebase-index/parser-worker-script.js +8 -3995
  79. package/dist/codebase-index/project-server.js +60 -8548
  80. package/dist/codebase-index/worker.js +20 -8416
  81. package/dist/design.js +2 -299
  82. package/dist/diff.js +4 -256
  83. package/dist/document.js +4 -222
  84. package/dist/e2e.js +5 -476
  85. package/dist/edit.js +14 -10200
  86. package/dist/exec.js +16 -3131
  87. package/dist/fetch.js +8 -398
  88. package/dist/format.js +10 -3750
  89. package/dist/generic-parser-VUXDIAOZ.js +13 -0
  90. package/dist/git.js +4 -380
  91. package/dist/glob.js +6 -280
  92. package/dist/go-parser-6CA77WZ4.js +469 -0
  93. package/dist/grep.js +7 -604
  94. package/dist/index.js +318 -35387
  95. package/dist/install.js +10 -4091
  96. package/dist/json-parser-7YMDJSBJ.js +213 -0
  97. package/dist/json.js +4 -665
  98. package/dist/kanban.js +3 -2096
  99. package/dist/languages/index.js +23 -4664
  100. package/dist/legacy-bridge-7UKZT46G.js +18 -0
  101. package/dist/lint.js +10 -3706
  102. package/dist/logs.js +4 -287
  103. package/dist/memory.js +6 -215
  104. package/dist/mode.js +3 -99
  105. package/dist/outdated.js +4 -5170
  106. package/dist/pack.js +65 -33897
  107. package/dist/parser-dispatch-VPOFDO2U.js +14 -0
  108. package/dist/patch.js +13 -9935
  109. package/dist/plan.js +5 -3286
  110. package/dist/process-registry.js +8 -651
  111. package/dist/ps-slash.js +12 -1439
  112. package/dist/py-parser-GPM5VYRG.js +16 -0
  113. package/dist/read.js +13 -9816
  114. package/dist/replace.js +15 -10014
  115. package/dist/rs-parser-WVQ4KYCX.js +81 -0
  116. package/dist/scaffold.js +4 -253
  117. package/dist/search.js +5 -585
  118. package/dist/session-kanban.js +30 -972
  119. package/dist/skill.js +2 -215
  120. package/dist/task.js +5 -3410
  121. package/dist/test.js +10 -3773
  122. package/dist/todo.js +4 -2891
  123. package/dist/tool-help.js +3 -123
  124. package/dist/tool-search.js +3 -79
  125. package/dist/tool-tier.js +68 -33984
  126. package/dist/tool-use.js +2 -93
  127. package/dist/tree-sitter-parser-YCILHGZD.js +17 -0
  128. package/dist/tree.js +4 -288
  129. package/dist/ts-parser-YH4ZMWMH.js +232 -0
  130. package/dist/typecheck.js +10 -3753
  131. package/dist/win32.js +6 -60
  132. package/dist/write.js +14 -9882
  133. package/dist/yaml-parser-GFAOKV53.js +157 -0
  134. package/package.json +5 -5
@@ -0,0 +1,899 @@
1
+ // src/codebase-index/tree-sitter-parser.ts
2
+ import * as path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ // src/codebase-index/tree-sitter/queries.ts
6
+ function parseGroupedUse(text) {
7
+ const open = text.indexOf("{");
8
+ const close = text.lastIndexOf("}");
9
+ if (open < 0 || close <= open) return null;
10
+ const prefix = text.slice(0, open).replace(/[\\/]+$/, "");
11
+ const out = [];
12
+ for (const rawMember of text.slice(open + 1, close).split(",")) {
13
+ let member = rawMember.trim();
14
+ if (!member) continue;
15
+ member = member.replace(
16
+ /^(static|final|type|class|struct|enum|protocol|var|func|let|typealias|function|const)\s+/i,
17
+ ""
18
+ ).trim();
19
+ if (!member) continue;
20
+ const aliasMatch = /\s+as\s+([A-Za-z_]\w*)\s*$/i.exec(member);
21
+ if (aliasMatch) member = member.slice(0, aliasMatch.index).trim();
22
+ if (!member) continue;
23
+ const module = prefix ? `${prefix}\\${member}` : member;
24
+ const toName = member.split(/[\\/]/).filter(Boolean).pop();
25
+ if (toName) out.push({ toName, callType: "import", module });
26
+ }
27
+ return out.length ? out : null;
28
+ }
29
+ function importFromText(prefixes) {
30
+ return (node) => {
31
+ let text = node.text.replace(/\s+/g, " ").trim();
32
+ for (const prefix of prefixes) {
33
+ if (text.startsWith(prefix)) text = text.slice(prefix.length).trim();
34
+ }
35
+ text = text.replace(
36
+ /^(static|final|type|class|struct|enum|protocol|var|func|let|typealias|function|const)\s+/i,
37
+ ""
38
+ ).trim();
39
+ if (text.includes("{")) return parseGroupedUse(text);
40
+ if (text.includes(",") && !text.includes("<") && !text.includes("=")) {
41
+ const out = [];
42
+ for (const clause of text.split(",")) {
43
+ const one = oneImportClause(clause.trim());
44
+ if (one) out.push(one);
45
+ }
46
+ return out.length ? out : null;
47
+ }
48
+ const single = oneImportClause(text);
49
+ return single ? [single] : null;
50
+ };
51
+ }
52
+ function oneImportClause(rawClause) {
53
+ let text = rawClause;
54
+ text = text.replace(
55
+ /^(static|final|type|class|struct|enum|protocol|var|func|let|typealias|function|const)\s+/i,
56
+ ""
57
+ ).trim();
58
+ text = text.replace(/[;}]+$/g, "").trim();
59
+ const aliasMatch = /\s+as\s+([A-Za-z_]\w*)\s*$/i.exec(text);
60
+ if (aliasMatch) text = text.slice(0, aliasMatch.index).trim();
61
+ const eqMatch = /^([A-Za-z_]\w*)\s*=\s*(.+)$/.exec(text);
62
+ if (eqMatch) text = eqMatch[2].trim();
63
+ if (!text) return null;
64
+ if (text.endsWith("*")) text = text.slice(0, -1).replace(/[.]$/, "");
65
+ if (!text) return null;
66
+ const module = text;
67
+ const toName = module.split(/[.\\/]/).filter(Boolean).pop()?.replace(/<.*>$/s, "");
68
+ if (!toName) return null;
69
+ return { toName, callType: "import", module };
70
+ }
71
+ var heritageExtractor = (node) => {
72
+ const out = [];
73
+ const SKIP_SUBTREES = /* @__PURE__ */ new Set([
74
+ "type_arguments",
75
+ "type_argument_list",
76
+ // tree-sitter-cpp names its argument subtree template_argument_list —
77
+ // verified AST: (base_class_clause (template_type name:
78
+ // (type_identifier) arguments: (template_argument_list
79
+ // (type_descriptor type: (type_identifier))))). Without this entry
80
+ // `class D : Base<Foo>` recurses into the descriptor and emits Foo as a
81
+ // phantom inherit ref.
82
+ "template_argument_list",
83
+ "type_parameter_list",
84
+ "type_projection",
85
+ "value_arguments"
86
+ ]);
87
+ const collect = (current, depth) => {
88
+ if (depth > 4) return;
89
+ for (let i = 0; i < current.namedChildCount; i++) {
90
+ const child = current.namedChild(i);
91
+ if (!child) continue;
92
+ if (SKIP_SUBTREES.has(child.type)) continue;
93
+ if (child.type === "type_identifier" || child.type === "identifier" || child.type === "named_type" || child.type === "type" || // PHP heritage carries `name`; Ruby a `constant`.
94
+ child.type === "constant" || child.type === "name") {
95
+ const name = child.type === "named_type" ? leafSegment(child.text) : child.text;
96
+ if (name) out.push({ toName: name });
97
+ continue;
98
+ }
99
+ if (child.type === "generic_type" || child.type === "generic_name") {
100
+ for (let j = 0; j < child.namedChildCount; j++) {
101
+ const inner = child.namedChild(j);
102
+ if (inner && !SKIP_SUBTREES.has(inner.type) && (inner.type === "type_identifier" || inner.type === "identifier" || inner.type === "name")) {
103
+ out.push({ toName: inner.text });
104
+ break;
105
+ }
106
+ }
107
+ continue;
108
+ }
109
+ if (child.type === "qualified_name" || child.type === "scoped_type_identifier" || child.type === "user_type" || child.type === "scope_resolution") {
110
+ const leaf = heritageLeaf(child, 0);
111
+ if (leaf) out.push({ toName: leaf });
112
+ continue;
113
+ }
114
+ collect(child, depth + 1);
115
+ }
116
+ };
117
+ collect(node, 0);
118
+ return out;
119
+ };
120
+ function heritageLeaf(node, depth) {
121
+ if (depth > 6) return null;
122
+ const named = node.childForFieldName("name");
123
+ if (named) {
124
+ if (named.type === "scoped_type_identifier" || named.type === "qualified_name" || named.type === "scope_resolution" || named.type === "user_type") {
125
+ return heritageLeaf(named, depth + 1);
126
+ }
127
+ return named.text;
128
+ }
129
+ const children = [];
130
+ for (let i = 0; i < node.namedChildCount; i++) {
131
+ const c = node.namedChild(i);
132
+ if (c) children.push(c);
133
+ }
134
+ for (let i = children.length - 1; i >= 0; i--) {
135
+ const c = children[i];
136
+ if (c.type === "type_arguments" || c.type === "type_argument_list" || // cpp: (template_type arguments: (template_argument_list …)) — the
137
+ // descriptor's type_identifier inside it is never the declared base.
138
+ c.type === "template_argument_list" || c.type === "type_parameter_list" || c.type === "type_projection" || c.type === "value_arguments") {
139
+ continue;
140
+ }
141
+ if (c.type === "type_identifier" || c.type === "identifier" || c.type === "constant" || c.type === "name") {
142
+ return c.text;
143
+ }
144
+ if (c.type === "scoped_type_identifier" || c.type === "qualified_name" || c.type === "scope_resolution" || c.type === "user_type") {
145
+ return heritageLeaf(c, depth + 1);
146
+ }
147
+ }
148
+ return leafSegment(
149
+ node.text.replace(/\\/g, ".").replace(/::/g, ".").replace(/<[^<>]*>$/, "")
150
+ );
151
+ }
152
+ function leafSegment(text) {
153
+ return text.split(".").filter(Boolean).pop() ?? text;
154
+ }
155
+ var cCallExtractor = (node) => {
156
+ const fn = node.childForFieldName("function");
157
+ if (!fn) return null;
158
+ if (fn.type === "field_expression") {
159
+ const field = fn.childForFieldName("field");
160
+ if (field) return [{ toName: field.text, callType: "call" }];
161
+ const seg = fn.text.split("->").filter(Boolean).pop();
162
+ if (seg) return [{ toName: leafSegment(seg.split(".")[0] ?? seg), callType: "call" }];
163
+ return null;
164
+ }
165
+ if (fn.type === "qualified_identifier") {
166
+ const name = fn.childForFieldName("name");
167
+ if (name) return [{ toName: name.text, callType: "call" }];
168
+ const seg = fn.text.split("::").filter(Boolean).pop();
169
+ if (seg) return [{ toName: seg.split(/[<(]/)[0].trim(), callType: "call" }];
170
+ return null;
171
+ }
172
+ return [{ toName: fn.text.split(/[<(]/)[0].trim(), callType: "call" }];
173
+ };
174
+ var rubyCallExtractor = (node) => {
175
+ const emissions = [];
176
+ const method = node.childForFieldName("method");
177
+ if (method) {
178
+ const name = method.text;
179
+ if (name && !name.includes(" ")) emissions.push({ toName: name, callType: "call" });
180
+ if (name === "require" || name === "require_relative") {
181
+ const args = node.childForFieldName("arguments");
182
+ const first = args?.namedChild(0);
183
+ if (first) {
184
+ const raw = first.text.replace(/^['"]|['"]$/g, "");
185
+ const toName = raw.split("/").filter(Boolean).pop();
186
+ if (toName) emissions.push({ toName, callType: "import", module: raw });
187
+ }
188
+ }
189
+ }
190
+ return emissions;
191
+ };
192
+ var firstIdentifierCallExtractor = (node) => {
193
+ for (let i = 0; i < node.namedChildCount; i++) {
194
+ const child = node.namedChild(i);
195
+ if (child && (child.type === "simple_identifier" || child.type === "identifier")) {
196
+ return [{ toName: child.text, callType: "call" }];
197
+ }
198
+ }
199
+ const first = node.namedChild(0);
200
+ if (!first) return null;
201
+ const leaf = leafSegment(first.text.split(/[<(]/)[0] ?? first.text);
202
+ if (!leaf) return null;
203
+ return [{ toName: leaf, callType: "call" }];
204
+ };
205
+ var cIncludeExtractor = (node) => {
206
+ const raw = node.text.replace(/^#\s*include\s*/i, "").trim();
207
+ const module = raw.replace(/^["'<]|["'>]$/g, "");
208
+ if (!module) return null;
209
+ const toName = module.split("/").pop()?.replace(/\.h$/, "");
210
+ if (!toName) return null;
211
+ return [{ toName, callType: "import", module }];
212
+ };
213
+ var phpConstructorExtractor = (node) => {
214
+ for (let i = 0; i < node.namedChildCount; i++) {
215
+ const child = node.namedChild(i);
216
+ if (child && (child.type === "qualified_name" || child.type === "name")) {
217
+ const leaf = child.text.split(/[\\]/).filter(Boolean).pop();
218
+ if (leaf) return [{ toName: leaf, callType: "call" }];
219
+ }
220
+ }
221
+ return null;
222
+ };
223
+ var DEFAULT_QUERIES = {
224
+ declKinds: {}
225
+ };
226
+ var LANG_QUERIES = {
227
+ // ─── C family ──────────────────────────────────────────────────────────────
228
+ c: {
229
+ declKinds: {
230
+ function_definition: "function",
231
+ declaration: "function",
232
+ // K&R-style `int foo(...)` ambiguous w/ local var; the visitor prefers the function branch when the declarator field is present
233
+ struct_specifier: "struct",
234
+ union_specifier: "struct",
235
+ enum_specifier: "enum",
236
+ type_definition: "type",
237
+ // `typedef … X;`
238
+ preproc_def: "const"
239
+ // `#define NAME …`
240
+ },
241
+ nameField: {
242
+ function_definition: "declarator",
243
+ declaration: "declarator",
244
+ struct_specifier: "name",
245
+ enum_specifier: "name",
246
+ type_definition: "declarator",
247
+ preproc_def: "name"
248
+ },
249
+ scopeNodes: /* @__PURE__ */ new Set([
250
+ "translation_unit",
251
+ "function_definition",
252
+ "struct_specifier",
253
+ "union_specifier",
254
+ "enum_specifier"
255
+ ]),
256
+ refRules: {
257
+ // `obj->run()` and `Cls::stat()` carry structured function fields —
258
+ // cCallExtractor handles all three AST shapes.
259
+ call_expression: { callType: "call", nameExtractor: cCallExtractor },
260
+ preproc_include: { callType: "import", nameExtractor: cIncludeExtractor }
261
+ }
262
+ },
263
+ cpp: {
264
+ declKinds: {
265
+ function_definition: "function",
266
+ template_declaration: "function",
267
+ // `template<typename T> …`
268
+ class_specifier: "class",
269
+ struct_specifier: "struct",
270
+ union_specifier: "struct",
271
+ enum_specifier: "enum",
272
+ namespace_definition: "namespace",
273
+ type_definition: "type"
274
+ },
275
+ nameField: {
276
+ function_definition: "declarator",
277
+ template_declaration: "name",
278
+ class_specifier: "name",
279
+ struct_specifier: "name",
280
+ enum_specifier: "name",
281
+ namespace_definition: "name",
282
+ type_definition: "declarator"
283
+ },
284
+ scopeNodes: /* @__PURE__ */ new Set([
285
+ "translation_unit",
286
+ "function_definition",
287
+ "class_specifier",
288
+ "struct_specifier",
289
+ "union_specifier",
290
+ "enum_specifier",
291
+ "namespace_definition"
292
+ ]),
293
+ refRules: {
294
+ call_expression: { callType: "call", nameExtractor: cCallExtractor },
295
+ preproc_include: { callType: "import", nameExtractor: cIncludeExtractor },
296
+ // `class Foo : public Bar, private Baz` — the base-class clause.
297
+ base_class_clause: { callType: "inherit", nameExtractor: heritageExtractor }
298
+ }
299
+ },
300
+ java: {
301
+ declKinds: {
302
+ class_declaration: "class",
303
+ interface_declaration: "interface",
304
+ enum_declaration: "enum",
305
+ record_declaration: "class",
306
+ annotation_type_declaration: "interface",
307
+ method_declaration: "method",
308
+ constructor_declaration: "method",
309
+ field_declaration: "property"
310
+ },
311
+ nameField: {
312
+ class_declaration: "name",
313
+ interface_declaration: "name",
314
+ enum_declaration: "name",
315
+ record_declaration: "name",
316
+ annotation_type_declaration: "name",
317
+ method_declaration: "name",
318
+ constructor_declaration: "name"
319
+ },
320
+ // `field_declaration` has no single `name` field — it carries a list of
321
+ // variable declarators. We emit one Symbol per node using the first
322
+ // identifier-shaped named child (see `extractName` fallback in
323
+ // `visitor.ts`). `int a, b, c;` therefore indexes only `a` — splitting
324
+ // multi-declarator fields into separate Symbols is a separate refactor
325
+ // that needs the visitor to know it has multiple names per node, and no
326
+ // current test relies on it.
327
+ scopeNodes: /* @__PURE__ */ new Set([
328
+ "program",
329
+ "class_declaration",
330
+ "interface_declaration",
331
+ "enum_declaration",
332
+ "record_declaration"
333
+ ]),
334
+ refRules: {
335
+ method_invocation: { callType: "call", field: "name" },
336
+ object_creation_expression: { callType: "call", field: "type" },
337
+ // Verified AST: `superclass: (superclass (type_identifier))` and
338
+ // `interfaces: (super_interfaces (type_list ...))` — no underscores.
339
+ superclass: { callType: "inherit", nameExtractor: heritageExtractor },
340
+ super_interfaces: {
341
+ callType: "implement",
342
+ nameExtractor: heritageExtractor
343
+ },
344
+ import_declaration: {
345
+ callType: "import",
346
+ nameExtractor: importFromText(["import "])
347
+ }
348
+ }
349
+ },
350
+ csharp: {
351
+ // C# 10+ `namespace Foo.Bar;` produces this node type. The legacy block
352
+ // form `namespace Foo.Bar { ... }` produces `namespace_declaration`. Both
353
+ // carry a `qualified_name` child whose text already includes the dots.
354
+ // `using_directive` is intentionally not a declaration. Imports are
355
+ // extracted separately; indexing a using directive as a namespace makes
356
+ // the resolver bind it to its own source file before the real declaration.
357
+ declKinds: {
358
+ file_scoped_namespace_declaration: "namespace",
359
+ class_declaration: "class",
360
+ interface_declaration: "interface",
361
+ struct_declaration: "struct",
362
+ enum_declaration: "enum",
363
+ record_declaration: "class",
364
+ method_declaration: "method",
365
+ constructor_declaration: "method",
366
+ property_declaration: "property",
367
+ field_declaration: "property",
368
+ namespace_declaration: "namespace"
369
+ },
370
+ // Custom name extractor: take the full dotted name verbatim.
371
+ nameExtractor: (node) => {
372
+ const inner = node.namedChild(0);
373
+ if (inner && (inner.type === "qualified_name" || inner.type === "name")) {
374
+ return inner.text;
375
+ }
376
+ return null;
377
+ },
378
+ scopeNodes: /* @__PURE__ */ new Set([
379
+ "compilation_unit",
380
+ "namespace_declaration",
381
+ "class_declaration",
382
+ "interface_declaration",
383
+ "struct_declaration",
384
+ "enum_declaration",
385
+ "record_declaration"
386
+ ]),
387
+ refRules: {
388
+ // Verified AST: `invocation_expression function: (identifier)` — the
389
+ // callee field is `function` (C-style), not `name`.
390
+ invocation_expression: { callType: "call", field: "function" },
391
+ object_creation_expression: { callType: "call", field: "type" },
392
+ base_list: { callType: "inherit", nameExtractor: heritageExtractor },
393
+ using_directive: {
394
+ callType: "import",
395
+ nameExtractor: importFromText(["using "])
396
+ }
397
+ }
398
+ },
399
+ php: {
400
+ declKinds: {
401
+ function_definition: "function",
402
+ method_declaration: "method",
403
+ class_declaration: "class",
404
+ interface_declaration: "interface",
405
+ trait_declaration: "class",
406
+ enum_declaration: "enum",
407
+ namespace_definition: "namespace"
408
+ },
409
+ nameField: {
410
+ function_definition: "name",
411
+ method_declaration: "name",
412
+ class_declaration: "name",
413
+ interface_declaration: "name",
414
+ trait_declaration: "name",
415
+ enum_declaration: "name",
416
+ namespace_definition: "name"
417
+ },
418
+ scopeNodes: /* @__PURE__ */ new Set([
419
+ "program",
420
+ "namespace_definition",
421
+ "class_declaration",
422
+ "interface_declaration",
423
+ "trait_declaration",
424
+ "enum_declaration"
425
+ ]),
426
+ refRules: {
427
+ function_call_expression: { callType: "call", field: "function" },
428
+ // Verified AST: `new App\Model\User()` carries a BARE qualified_name
429
+ // child (no `name:` field), so the field default never fires.
430
+ object_creation_expression: { callType: "call", nameExtractor: phpConstructorExtractor },
431
+ base_clause: { callType: "inherit", nameExtractor: heritageExtractor },
432
+ class_interface_clause: {
433
+ callType: "implement",
434
+ nameExtractor: heritageExtractor
435
+ },
436
+ // Verified AST: `namespace_use_declaration (namespace_use_clause
437
+ // (qualified_name ...))` — not `use_declaration`.
438
+ namespace_use_declaration: {
439
+ callType: "import",
440
+ nameExtractor: importFromText(["use "])
441
+ }
442
+ }
443
+ },
444
+ // ─── Scripting / mobile ────────────────────────────────────────────────────
445
+ ruby: {
446
+ declKinds: {
447
+ method: "function",
448
+ singleton_method: "method",
449
+ class: "class",
450
+ module: "namespace",
451
+ constant: "const"
452
+ },
453
+ nameField: {
454
+ method: "name",
455
+ singleton_method: "name",
456
+ class: "name",
457
+ module: "name",
458
+ constant: "name"
459
+ },
460
+ scopeNodes: /* @__PURE__ */ new Set(["program", "class", "module", "singleton_method", "method"]),
461
+ refRules: {
462
+ // `call` covers both `foo(...)` and `obj.foo(...)` — the extractor
463
+ // records the method leaf, plus `require`/`require_relative` imports.
464
+ call: { callType: "call", nameExtractor: rubyCallExtractor },
465
+ superclass: { callType: "inherit", nameExtractor: heritageExtractor }
466
+ }
467
+ },
468
+ swift: {
469
+ declKinds: {
470
+ function_declaration: "function",
471
+ class_declaration: "class",
472
+ struct_declaration: "struct",
473
+ enum_declaration: "enum",
474
+ protocol_declaration: "interface",
475
+ actor_declaration: "class",
476
+ extension_declaration: "class",
477
+ initializer: "method",
478
+ property_declaration: "property"
479
+ },
480
+ nameField: {
481
+ function_declaration: "name",
482
+ class_declaration: "name",
483
+ struct_declaration: "name",
484
+ enum_declaration: "name",
485
+ protocol_declaration: "name",
486
+ actor_declaration: "name",
487
+ extension_declaration: "name",
488
+ initializer: "name",
489
+ property_declaration: "name"
490
+ },
491
+ scopeNodes: /* @__PURE__ */ new Set([
492
+ "source_file",
493
+ "class_declaration",
494
+ "struct_declaration",
495
+ "enum_declaration",
496
+ "protocol_declaration",
497
+ "actor_declaration",
498
+ "extension_declaration"
499
+ ]),
500
+ refRules: {
501
+ // Verified AST: `call_expression (simple_identifier) (call_suffix …)` —
502
+ // the callee is a bare first child, no field name.
503
+ call_expression: { callType: "call", nameExtractor: firstIdentifierCallExtractor },
504
+ // Verified AST: `inheritance_specifier inherits_from: (user_type …)`.
505
+ inheritance_specifier: { callType: "inherit", nameExtractor: heritageExtractor },
506
+ import_declaration: {
507
+ callType: "import",
508
+ nameExtractor: importFromText(["import ", "import type ", "@testable import "])
509
+ }
510
+ }
511
+ },
512
+ kotlin: {
513
+ declKinds: {
514
+ class_declaration: "class",
515
+ object_declaration: "class",
516
+ interface_declaration: "interface",
517
+ function_declaration: "function",
518
+ property_declaration: "property",
519
+ type_alias: "type"
520
+ },
521
+ nameField: {
522
+ class_declaration: "name",
523
+ object_declaration: "name",
524
+ interface_declaration: "name",
525
+ function_declaration: "name",
526
+ property_declaration: "name",
527
+ type_alias: "name"
528
+ },
529
+ scopeNodes: /* @__PURE__ */ new Set([
530
+ "source_file",
531
+ "class_declaration",
532
+ "object_declaration",
533
+ "interface_declaration",
534
+ "function_declaration"
535
+ ]),
536
+ refRules: {
537
+ call_expression: { callType: "call", nameExtractor: firstIdentifierCallExtractor },
538
+ // Verified AST: `delegation_specifier (user_type (type_identifier))` —
539
+ // the `: Handler` / `: Base()` clause.
540
+ delegation_specifier: { callType: "inherit", nameExtractor: heritageExtractor },
541
+ import_header: {
542
+ callType: "import",
543
+ nameExtractor: importFromText(["import "])
544
+ }
545
+ }
546
+ },
547
+ elixir: {
548
+ declKinds: {
549
+ // `def foo`, `defp foo`, `defmacro foo`, `macrop foo` all surface as
550
+ // `call` nodes in the tree-sitter grammar — there is no
551
+ // `function_definition`. The `nameExtractor` walks the call's
552
+ // children to pick the right sibling identifier.
553
+ call: "function",
554
+ module: "namespace"
555
+ },
556
+ nameExtractor: (node) => {
557
+ if (node.type === "module") {
558
+ const aliasNode = node.childForFieldName("alias");
559
+ return readFirstString(aliasNode) ?? null;
560
+ }
561
+ if (node.type !== "call") return null;
562
+ const first = node.namedChild(0);
563
+ if (!first) return null;
564
+ const target = first.text;
565
+ if (target !== "def" && target !== "defp" && target !== "defmacro" && target !== "defp_macro" && target !== "macrop" && target !== "defprotocol" && target !== "defguard" && target !== "defguardp") {
566
+ return null;
567
+ }
568
+ const nameNode = node.namedChild(1);
569
+ return nameNode?.text ?? null;
570
+ },
571
+ scopeNodes: /* @__PURE__ */ new Set(["source", "module"])
572
+ },
573
+ shell: {
574
+ declKinds: {
575
+ function_definition: "function"
576
+ },
577
+ nameField: { function_definition: "name" },
578
+ scopeNodes: /* @__PURE__ */ new Set(["program", "function_definition"])
579
+ }
580
+ };
581
+ function getQueries(lang) {
582
+ return LANG_QUERIES[lang] ?? DEFAULT_QUERIES;
583
+ }
584
+ function readFirstString(node) {
585
+ if (!node) return null;
586
+ if (node.type === "string_literal" || node.type === "alias") {
587
+ return node.text.replace(/^"|"$/g, "");
588
+ }
589
+ const child = node.namedChild(0);
590
+ return child ? readFirstString(child) : null;
591
+ }
592
+
593
+ // src/codebase-index/tree-sitter/util.ts
594
+ function lineColAt(offsets, index) {
595
+ let low = 0;
596
+ let high = offsets.length;
597
+ while (low < high) {
598
+ const mid = low + high >>> 1;
599
+ if ((offsets[mid] ?? 0) < index) low = mid + 1;
600
+ else high = mid;
601
+ }
602
+ const lastNl = low > 0 ? offsets[low - 1] ?? -1 : -1;
603
+ return { line: low + 1, col: index - lastNl };
604
+ }
605
+ function newlineOffsets(content) {
606
+ const offsets = [];
607
+ for (let i = 0; i < content.length; i++) {
608
+ if (content.charCodeAt(i) === 10) offsets.push(i);
609
+ }
610
+ return offsets;
611
+ }
612
+ var TREE_SITTER_MAX_FILE_CHARS = 512 * 1024;
613
+ var TREE_SITTER_MAX_SYMBOLS = 500;
614
+
615
+ // src/codebase-index/tree-sitter/visitor.ts
616
+ function visitTree(tree, content, file, lang, queries) {
617
+ const boundedContent = content.length > TREE_SITTER_MAX_FILE_CHARS ? content.slice(0, TREE_SITTER_MAX_FILE_CHARS) : content;
618
+ const nlOffsets = newlineOffsets(boundedContent);
619
+ const symbols = [];
620
+ const refs = [];
621
+ const seenRefs = /* @__PURE__ */ new Set();
622
+ const scopeStack = [];
623
+ function emitRefsForNode(node, rule) {
624
+ const emissions = rule.nameExtractor?.(node) ?? defaultRefTarget(node, rule);
625
+ if (!emissions) return;
626
+ const { line } = lineColAt(nlOffsets, node.startIndex);
627
+ for (const emission of emissions) {
628
+ if (!emission.toName) continue;
629
+ const callType = emission.callType ?? rule.callType;
630
+ const key = `${emission.toName}:${callType}:${line}:${emission.module ?? ""}:${node.startIndex}`;
631
+ if (seenRefs.has(key)) continue;
632
+ seenRefs.add(key);
633
+ refs.push({
634
+ fromId: 0,
635
+ // assignRefsToSymbols attaches owners after insertion
636
+ toName: emission.toName.slice(0, 200),
637
+ callType,
638
+ line,
639
+ lang,
640
+ module: emission.module
641
+ });
642
+ }
643
+ }
644
+ function defaultRefTarget(node, rule) {
645
+ if (!rule.field) return null;
646
+ const field = node.childForFieldName(rule.field);
647
+ if (!field) return null;
648
+ const leaf = field.text.split(/[.:\\]/).filter(Boolean).pop()?.split(/[<(]/)[0];
649
+ if (!leaf) return null;
650
+ return [{ toName: leaf.trim() }];
651
+ }
652
+ function visit(node, depth) {
653
+ if (symbols.length >= TREE_SITTER_MAX_SYMBOLS) return;
654
+ if (node.isMissing || node.isError) {
655
+ } else {
656
+ const kind = queries.declKinds[node.type];
657
+ if (kind) {
658
+ const emitted = emitSymbol(
659
+ node,
660
+ kind,
661
+ file,
662
+ lang,
663
+ scopeStack,
664
+ boundedContent,
665
+ nlOffsets,
666
+ queries
667
+ );
668
+ if (emitted) symbols.push(emitted);
669
+ }
670
+ const refRule = queries.refRules?.[node.type];
671
+ if (refRule) emitRefsForNode(node, refRule);
672
+ }
673
+ const pushesScope = queries.scopeNodes?.has(node.type) ?? false;
674
+ const pushIdx = pushesScope ? pushScope(scopeStack, node, queries) : -1;
675
+ if (queries.skipNamedChildren) {
676
+ if (pushIdx !== -1) scopeStack.pop();
677
+ return;
678
+ }
679
+ for (const child of node.namedChildren) {
680
+ visit(child, depth + 1);
681
+ if (symbols.length >= TREE_SITTER_MAX_SYMBOLS) {
682
+ if (pushIdx !== -1) scopeStack.pop();
683
+ return;
684
+ }
685
+ }
686
+ if (pushIdx !== -1) scopeStack.pop();
687
+ }
688
+ visit(tree.rootNode, 0);
689
+ return { symbols, refs };
690
+ }
691
+ function pushScope(scopeStack, node, queries) {
692
+ const name = extractName(node, queries);
693
+ if (!name) return -1;
694
+ scopeStack.push(name);
695
+ return scopeStack.length - 1;
696
+ }
697
+ var IDENTIFIER_NODE_TYPES = /* @__PURE__ */ new Set([
698
+ "identifier",
699
+ "simple_identifier",
700
+ "type_identifier",
701
+ "field_identifier",
702
+ "property_identifier",
703
+ "name",
704
+ "word",
705
+ "variable_name",
706
+ "constant",
707
+ "sym"
708
+ ]);
709
+ function extractName(node, queries) {
710
+ if (queries.nameExtractor) {
711
+ const extracted = queries.nameExtractor(node);
712
+ if (extracted) return extracted;
713
+ }
714
+ const fieldName = queries.nameField?.[node.type] ?? "name";
715
+ const field = node.childForFieldName(fieldName);
716
+ if (field) {
717
+ if (IDENTIFIER_NODE_TYPES.has(field.type)) {
718
+ return field.text;
719
+ }
720
+ const inner = field.childForFieldName("name") ?? field.namedChild(0);
721
+ if (inner && IDENTIFIER_NODE_TYPES.has(inner.type)) {
722
+ return inner.text;
723
+ }
724
+ }
725
+ for (let i = 0; i < node.namedChildCount; i++) {
726
+ const child = node.namedChild(i);
727
+ if (child && IDENTIFIER_NODE_TYPES.has(child.type)) {
728
+ return child.text;
729
+ }
730
+ }
731
+ return null;
732
+ }
733
+ function emitSymbol(node, kind, file, lang, scopeStack, content, nlOffsets, queries) {
734
+ const name = extractName(node, queries);
735
+ if (!name) return null;
736
+ const pos = node.startIndex;
737
+ const { line, col } = lineColAt(nlOffsets, pos);
738
+ const end = Math.min(node.endIndex, content.length);
739
+ const signature = content.slice(pos, end).replace(/\s+/g, " ").trim().slice(0, 500);
740
+ const scope = scopeStack.join(".");
741
+ const text = [name, signature].filter(Boolean).join(" | ").trim().slice(0, 1e3);
742
+ return {
743
+ id: 0,
744
+ // caller assigns during bulk insertion
745
+ lang,
746
+ kind,
747
+ name: name.slice(0, 200),
748
+ file,
749
+ line,
750
+ col,
751
+ signature,
752
+ docComment: "",
753
+ // doc-comment extraction lands with ref emission on Day 4
754
+ scope,
755
+ text
756
+ };
757
+ }
758
+
759
+ // src/codebase-index/tree-sitter-parser.ts
760
+ var WASM_DIR = fileURLToPath(new URL("./wasm/", import.meta.url));
761
+ var RUNTIME_WASM = path.join(WASM_DIR, "tree-sitter-runtime.wasm");
762
+ var LANG_TO_GRAMMAR = {
763
+ c: "c",
764
+ cpp: "cpp",
765
+ java: "java",
766
+ csharp: "c_sharp",
767
+ // tree-sitter directory uses underscore
768
+ php: "php",
769
+ ruby: "ruby",
770
+ swift: "swift",
771
+ kotlin: "kotlin",
772
+ shell: "bash",
773
+ // we treat `.sh` / `.bash` / `.zsh` via the bash grammar
774
+ // Go/Python/Rust are opt-in only (see goOptIn / pyOptIn / rsOptIn below)
775
+ elixir: "elixir"
776
+ };
777
+ var GO_OPT_IN = "WRONGSTACK_USE_TS_GO";
778
+ var PY_OPT_IN = "WRONGSTACK_USE_TS_PY";
779
+ var RS_OPT_IN = "WRONGSTACK_USE_TS_RS";
780
+ function optInEnabled(env) {
781
+ return process.env[env] === "1" || process.env[env] === "true";
782
+ }
783
+ var runtimePromise = null;
784
+ var languageCache = /* @__PURE__ */ new Map();
785
+ function getRuntime() {
786
+ if (!runtimePromise) {
787
+ runtimePromise = (async () => {
788
+ const mod = await import("web-tree-sitter");
789
+ const init = () => mod.Parser.init({ locateFile: () => RUNTIME_WASM });
790
+ return { Parser: mod.Parser, Language: mod.Language, init };
791
+ })();
792
+ }
793
+ return runtimePromise;
794
+ }
795
+ async function loadLanguage(lang) {
796
+ const existing = languageCache.get(lang);
797
+ if (existing) return existing;
798
+ const promise = (async () => {
799
+ const grammarName = resolveGrammarName(lang);
800
+ if (!grammarName) {
801
+ throw new Error(`tree-sitter: no grammar registered for lang "${lang}"`);
802
+ }
803
+ const wasmPath = path.join(WASM_DIR, grammarName, `tree-sitter-${grammarName}.wasm`);
804
+ const { Language, init } = await getRuntime();
805
+ await init();
806
+ const languageObj = await Language.load(wasmPath);
807
+ return { lang, Language: languageObj };
808
+ })();
809
+ languageCache.set(lang, promise);
810
+ return promise;
811
+ }
812
+ function resolveGrammarName(lang) {
813
+ if (lang === "go" && optInEnabled(GO_OPT_IN)) return "go";
814
+ if (lang === "py" && optInEnabled(PY_OPT_IN)) return "python";
815
+ if (lang === "rs" && optInEnabled(RS_OPT_IN)) return "rust";
816
+ return LANG_TO_GRAMMAR[lang];
817
+ }
818
+ function isTreeSitterSupported(lang) {
819
+ return resolveGrammarName(lang) !== void 0;
820
+ }
821
+ function getGrammarWasmPath(lang) {
822
+ const name = resolveGrammarName(lang);
823
+ if (!name) return void 0;
824
+ return path.join(WASM_DIR, name, `tree-sitter-${name}.wasm`);
825
+ }
826
+ async function parseSymbols(opts) {
827
+ const { file, content, lang } = opts;
828
+ if (!isTreeSitterSupported(lang)) {
829
+ return { file, lang, symbols: [], mtimeMs: Date.now() };
830
+ }
831
+ try {
832
+ const { Parser } = await getRuntime();
833
+ const cached = await loadLanguage(lang);
834
+ const parser = new Parser();
835
+ parser.setLanguage(cached.Language);
836
+ const tree = parser.parse(content);
837
+ if (!tree) {
838
+ return { file, lang, symbols: [], mtimeMs: Date.now() };
839
+ }
840
+ const { symbols, refs } = visitTree(tree, content, file, lang, getQueries(lang));
841
+ parser.delete();
842
+ tree.delete();
843
+ return { file, lang, symbols, refs, mtimeMs: Date.now() };
844
+ } catch {
845
+ return { file, lang, symbols: [], mtimeMs: Date.now() };
846
+ }
847
+ }
848
+ async function loadTreeSitterLanguage(lang) {
849
+ const cached = await loadLanguage(lang);
850
+ return cached.Language;
851
+ }
852
+ async function __smokeRootType(opts) {
853
+ if (!isTreeSitterSupported(opts.lang)) {
854
+ throw new Error(`tree-sitter: no grammar registered for lang "${opts.lang}"`);
855
+ }
856
+ const { Parser } = await getRuntime();
857
+ const cached = await loadLanguage(opts.lang);
858
+ const parser = new Parser();
859
+ parser.setLanguage(cached.Language);
860
+ let tree = null;
861
+ try {
862
+ tree = parser.parse(opts.content);
863
+ if (!tree) throw new Error("tree-sitter: parser.parse returned null");
864
+ return tree.rootNode.type;
865
+ } finally {
866
+ tree?.delete();
867
+ parser.delete();
868
+ }
869
+ }
870
+ async function parseTreeSitterAst(opts) {
871
+ const grammar = resolveGrammarName(opts.lang) ?? (opts.lang === "go" ? "go" : opts.lang === "py" ? "python" : opts.lang === "rs" ? "rust" : void 0);
872
+ if (!grammar) return null;
873
+ try {
874
+ const { Parser, Language, init } = await getRuntime();
875
+ await init();
876
+ const wasmPath = path.join(WASM_DIR, grammar, `tree-sitter-${grammar}.wasm`);
877
+ const languageObj = await Language.load(wasmPath);
878
+ const parser = new Parser();
879
+ parser.setLanguage(languageObj);
880
+ const tree = parser.parse(opts.content);
881
+ if (!tree) {
882
+ parser.delete();
883
+ return null;
884
+ }
885
+ return { tree, parser };
886
+ } catch {
887
+ return null;
888
+ }
889
+ }
890
+
891
+ export {
892
+ isTreeSitterSupported,
893
+ getGrammarWasmPath,
894
+ parseSymbols,
895
+ loadTreeSitterLanguage,
896
+ __smokeRootType,
897
+ parseTreeSitterAst
898
+ };
899
+ //# sourceMappingURL=chunk-B2CIOKWP.js.map