@gitwand/core 2.0.1 → 2.3.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 (200) hide show
  1. package/README.md +58 -0
  2. package/dist/__tests__/bench.bench.js +39 -0
  3. package/dist/__tests__/bench.bench.js.map +1 -1
  4. package/dist/__tests__/corpus.d.ts.map +1 -1
  5. package/dist/__tests__/corpus.js +363 -0
  6. package/dist/__tests__/corpus.js.map +1 -1
  7. package/dist/__tests__/diff/block-move.test.d.ts +5 -0
  8. package/dist/__tests__/diff/block-move.test.d.ts.map +1 -0
  9. package/dist/__tests__/diff/block-move.test.js +132 -0
  10. package/dist/__tests__/diff/block-move.test.js.map +1 -0
  11. package/dist/__tests__/diff/histogram.test.d.ts +8 -0
  12. package/dist/__tests__/diff/histogram.test.d.ts.map +1 -0
  13. package/dist/__tests__/diff/histogram.test.js +150 -0
  14. package/dist/__tests__/diff/histogram.test.js.map +1 -0
  15. package/dist/__tests__/diff/parity.test.d.ts +17 -0
  16. package/dist/__tests__/diff/parity.test.d.ts.map +1 -0
  17. package/dist/__tests__/diff/parity.test.js +149 -0
  18. package/dist/__tests__/diff/parity.test.js.map +1 -0
  19. package/dist/__tests__/diff.test.js +6 -2
  20. package/dist/__tests__/diff.test.js.map +1 -1
  21. package/dist/__tests__/format-profiles/integration.test.d.ts +7 -0
  22. package/dist/__tests__/format-profiles/integration.test.d.ts.map +1 -0
  23. package/dist/__tests__/format-profiles/integration.test.js +193 -0
  24. package/dist/__tests__/format-profiles/integration.test.js.map +1 -0
  25. package/dist/__tests__/format-profiles/json-patch.test.d.ts +12 -0
  26. package/dist/__tests__/format-profiles/json-patch.test.d.ts.map +1 -0
  27. package/dist/__tests__/format-profiles/json-patch.test.js +222 -0
  28. package/dist/__tests__/format-profiles/json-patch.test.js.map +1 -0
  29. package/dist/__tests__/format-profiles/registry.test.d.ts +5 -0
  30. package/dist/__tests__/format-profiles/registry.test.d.ts.map +1 -0
  31. package/dist/__tests__/format-profiles/registry.test.js +124 -0
  32. package/dist/__tests__/format-profiles/registry.test.js.map +1 -0
  33. package/dist/__tests__/patterns/make-score.test.d.ts +9 -0
  34. package/dist/__tests__/patterns/make-score.test.d.ts.map +1 -0
  35. package/dist/__tests__/patterns/make-score.test.js +49 -0
  36. package/dist/__tests__/patterns/make-score.test.js.map +1 -0
  37. package/dist/__tests__/structural/grandeur-nature.test.d.ts +31 -0
  38. package/dist/__tests__/structural/grandeur-nature.test.d.ts.map +1 -0
  39. package/dist/__tests__/structural/grandeur-nature.test.js +264 -0
  40. package/dist/__tests__/structural/grandeur-nature.test.js.map +1 -0
  41. package/dist/__tests__/structural/languages.test.d.ts +5 -0
  42. package/dist/__tests__/structural/languages.test.d.ts.map +1 -0
  43. package/dist/__tests__/structural/languages.test.js +74 -0
  44. package/dist/__tests__/structural/languages.test.js.map +1 -0
  45. package/dist/__tests__/structural/matching.test.d.ts +6 -0
  46. package/dist/__tests__/structural/matching.test.d.ts.map +1 -0
  47. package/dist/__tests__/structural/matching.test.js +113 -0
  48. package/dist/__tests__/structural/matching.test.js.map +1 -0
  49. package/dist/__tests__/structural/merge.test.d.ts +6 -0
  50. package/dist/__tests__/structural/merge.test.d.ts.map +1 -0
  51. package/dist/__tests__/structural/merge.test.js +117 -0
  52. package/dist/__tests__/structural/merge.test.js.map +1 -0
  53. package/dist/__tests__/structural/reconstruct.test.d.ts +6 -0
  54. package/dist/__tests__/structural/reconstruct.test.d.ts.map +1 -0
  55. package/dist/__tests__/structural/reconstruct.test.js +104 -0
  56. package/dist/__tests__/structural/reconstruct.test.js.map +1 -0
  57. package/dist/__tests__/structural/structural-index.test.d.ts +14 -0
  58. package/dist/__tests__/structural/structural-index.test.d.ts.map +1 -0
  59. package/dist/__tests__/structural/structural-index.test.js +108 -0
  60. package/dist/__tests__/structural/structural-index.test.js.map +1 -0
  61. package/dist/diff/block-move.d.ts +53 -0
  62. package/dist/diff/block-move.d.ts.map +1 -0
  63. package/dist/diff/block-move.js +192 -0
  64. package/dist/diff/block-move.js.map +1 -0
  65. package/dist/diff/histogram.d.ts +45 -0
  66. package/dist/diff/histogram.d.ts.map +1 -0
  67. package/dist/diff/histogram.js +172 -0
  68. package/dist/diff/histogram.js.map +1 -0
  69. package/dist/diff/index.d.ts +30 -0
  70. package/dist/diff/index.d.ts.map +1 -0
  71. package/dist/diff/index.js +47 -0
  72. package/dist/diff/index.js.map +1 -0
  73. package/dist/diff/lcs.d.ts +34 -0
  74. package/dist/diff/lcs.d.ts.map +1 -0
  75. package/dist/diff/lcs.js +184 -0
  76. package/dist/diff/lcs.js.map +1 -0
  77. package/dist/diff/shared.d.ts +54 -0
  78. package/dist/diff/shared.d.ts.map +1 -0
  79. package/dist/diff/shared.js +164 -0
  80. package/dist/diff/shared.js.map +1 -0
  81. package/dist/diff.d.ts +6 -65
  82. package/dist/diff.d.ts.map +1 -1
  83. package/dist/diff.js +6 -324
  84. package/dist/diff.js.map +1 -1
  85. package/dist/format-profiles/index.d.ts +34 -0
  86. package/dist/format-profiles/index.d.ts.map +1 -0
  87. package/dist/format-profiles/index.js +86 -0
  88. package/dist/format-profiles/index.js.map +1 -0
  89. package/dist/format-profiles/json-patch.d.ts +61 -0
  90. package/dist/format-profiles/json-patch.d.ts.map +1 -0
  91. package/dist/format-profiles/json-patch.js +269 -0
  92. package/dist/format-profiles/json-patch.js.map +1 -0
  93. package/dist/format-profiles/merge-strategies.d.ts +54 -0
  94. package/dist/format-profiles/merge-strategies.d.ts.map +1 -0
  95. package/dist/format-profiles/merge-strategies.js +156 -0
  96. package/dist/format-profiles/merge-strategies.js.map +1 -0
  97. package/dist/format-profiles/profiles/composer.d.ts +18 -0
  98. package/dist/format-profiles/profiles/composer.d.ts.map +1 -0
  99. package/dist/format-profiles/profiles/composer.js +45 -0
  100. package/dist/format-profiles/profiles/composer.js.map +1 -0
  101. package/dist/format-profiles/profiles/helm-values.d.ts +21 -0
  102. package/dist/format-profiles/profiles/helm-values.d.ts.map +1 -0
  103. package/dist/format-profiles/profiles/helm-values.js +40 -0
  104. package/dist/format-profiles/profiles/helm-values.js.map +1 -0
  105. package/dist/format-profiles/profiles/kubernetes.d.ts +22 -0
  106. package/dist/format-profiles/profiles/kubernetes.d.ts.map +1 -0
  107. package/dist/format-profiles/profiles/kubernetes.js +60 -0
  108. package/dist/format-profiles/profiles/kubernetes.js.map +1 -0
  109. package/dist/format-profiles/profiles/package-json.d.ts +18 -0
  110. package/dist/format-profiles/profiles/package-json.d.ts.map +1 -0
  111. package/dist/format-profiles/profiles/package-json.js +36 -0
  112. package/dist/format-profiles/profiles/package-json.js.map +1 -0
  113. package/dist/format-profiles/profiles/tsconfig.d.ts +21 -0
  114. package/dist/format-profiles/profiles/tsconfig.d.ts.map +1 -0
  115. package/dist/format-profiles/profiles/tsconfig.js +47 -0
  116. package/dist/format-profiles/profiles/tsconfig.js.map +1 -0
  117. package/dist/format-profiles/types.d.ts +67 -0
  118. package/dist/format-profiles/types.d.ts.map +1 -0
  119. package/dist/format-profiles/types.js +9 -0
  120. package/dist/format-profiles/types.js.map +1 -0
  121. package/dist/index.d.ts +9 -1
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +10 -1
  124. package/dist/index.js.map +1 -1
  125. package/dist/patterns/insertion-at-boundary.d.ts.map +1 -1
  126. package/dist/patterns/insertion-at-boundary.js +15 -33
  127. package/dist/patterns/insertion-at-boundary.js.map +1 -1
  128. package/dist/patterns/utils.d.ts +11 -8
  129. package/dist/patterns/utils.d.ts.map +1 -1
  130. package/dist/patterns/utils.js +28 -10
  131. package/dist/patterns/utils.js.map +1 -1
  132. package/dist/resolver/format-dispatch.d.ts.map +1 -1
  133. package/dist/resolver/format-dispatch.js +3 -1
  134. package/dist/resolver/format-dispatch.js.map +1 -1
  135. package/dist/resolver/index.d.ts +14 -0
  136. package/dist/resolver/index.d.ts.map +1 -1
  137. package/dist/resolver/index.js +29 -0
  138. package/dist/resolver/index.js.map +1 -1
  139. package/dist/resolver/policy.d.ts.map +1 -1
  140. package/dist/resolver/policy.js +2 -0
  141. package/dist/resolver/policy.js.map +1 -1
  142. package/dist/resolvers/dispatcher.d.ts +22 -2
  143. package/dist/resolvers/dispatcher.d.ts.map +1 -1
  144. package/dist/resolvers/dispatcher.js +8 -3
  145. package/dist/resolvers/dispatcher.js.map +1 -1
  146. package/dist/resolvers/json.d.ts +11 -2
  147. package/dist/resolvers/json.d.ts.map +1 -1
  148. package/dist/resolvers/json.js +55 -7
  149. package/dist/resolvers/json.js.map +1 -1
  150. package/dist/resolvers/yaml.d.ts +8 -2
  151. package/dist/resolvers/yaml.d.ts.map +1 -1
  152. package/dist/resolvers/yaml.js +156 -2
  153. package/dist/resolvers/yaml.js.map +1 -1
  154. package/dist/structural/entities.d.ts +44 -0
  155. package/dist/structural/entities.d.ts.map +1 -0
  156. package/dist/structural/entities.js +315 -0
  157. package/dist/structural/entities.js.map +1 -0
  158. package/dist/structural/index.d.ts +48 -0
  159. package/dist/structural/index.d.ts.map +1 -0
  160. package/dist/structural/index.js +177 -0
  161. package/dist/structural/index.js.map +1 -0
  162. package/dist/structural/matching.d.ts +46 -0
  163. package/dist/structural/matching.d.ts.map +1 -0
  164. package/dist/structural/matching.js +83 -0
  165. package/dist/structural/matching.js.map +1 -0
  166. package/dist/structural/merge.d.ts +45 -0
  167. package/dist/structural/merge.d.ts.map +1 -0
  168. package/dist/structural/merge.js +127 -0
  169. package/dist/structural/merge.js.map +1 -0
  170. package/dist/structural/parsers/adapters/browser.d.ts +22 -0
  171. package/dist/structural/parsers/adapters/browser.d.ts.map +1 -0
  172. package/dist/structural/parsers/adapters/browser.js +27 -0
  173. package/dist/structural/parsers/adapters/browser.js.map +1 -0
  174. package/dist/structural/parsers/adapters/node.d.ts +18 -0
  175. package/dist/structural/parsers/adapters/node.d.ts.map +1 -0
  176. package/dist/structural/parsers/adapters/node.js +42 -0
  177. package/dist/structural/parsers/adapters/node.js.map +1 -0
  178. package/dist/structural/parsers/adapters/tauri.d.ts +26 -0
  179. package/dist/structural/parsers/adapters/tauri.d.ts.map +1 -0
  180. package/dist/structural/parsers/adapters/tauri.js +34 -0
  181. package/dist/structural/parsers/adapters/tauri.js.map +1 -0
  182. package/dist/structural/parsers/grammars/languages.d.ts +32 -0
  183. package/dist/structural/parsers/grammars/languages.d.ts.map +1 -0
  184. package/dist/structural/parsers/grammars/languages.js +73 -0
  185. package/dist/structural/parsers/grammars/languages.js.map +1 -0
  186. package/dist/structural/parsers/grammars/ts.d.ts +26 -0
  187. package/dist/structural/parsers/grammars/ts.d.ts.map +1 -0
  188. package/dist/structural/parsers/grammars/ts.js +46 -0
  189. package/dist/structural/parsers/grammars/ts.js.map +1 -0
  190. package/dist/structural/parsers/loader.d.ts +74 -0
  191. package/dist/structural/parsers/loader.d.ts.map +1 -0
  192. package/dist/structural/parsers/loader.js +181 -0
  193. package/dist/structural/parsers/loader.js.map +1 -0
  194. package/dist/structural/reconstruct.d.ts +28 -0
  195. package/dist/structural/reconstruct.d.ts.map +1 -0
  196. package/dist/structural/reconstruct.js +63 -0
  197. package/dist/structural/reconstruct.js.map +1 -0
  198. package/dist/types.d.ts +25 -0
  199. package/dist/types.d.ts.map +1 -1
  200. package/package.json +16 -2
@@ -0,0 +1,315 @@
1
+ /**
2
+ * Top-level entity extraction from a tree-sitter AST.
3
+ *
4
+ * An "entity" is a top-level declaration in a TypeScript/TSX file:
5
+ * import, export, function, class, interface, type alias, variable declaration,
6
+ * or ambient declaration (declare …).
7
+ *
8
+ * Each entity carries:
9
+ * - `signature` — stable key for 3-way matching (based on name/kind)
10
+ * - `text` — exact source slice (used in the merged output)
11
+ * - byte offsets — for gap-preserving reconstruction
12
+ */
13
+ // ─── Internal helpers ─────────────────────────────────────────────────────────
14
+ /** Find the first named child with the given field name, or fall back to type search. */
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ function fieldOrType(node, fieldName, typeName) {
17
+ return node.childForFieldName?.(fieldName) ?? findChildByType(node, typeName);
18
+ }
19
+ /** Find the first direct child with the given type. */
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ function findChildByType(node, typeName) {
22
+ for (let i = 0; i < node.childCount; i++) {
23
+ const child = node.child(i);
24
+ if (child.type === typeName)
25
+ return child;
26
+ }
27
+ return undefined;
28
+ }
29
+ /**
30
+ * Derive a stable signature and kind for a top-level tree-sitter node.
31
+ *
32
+ * Signatures are intentionally simple (kind:name) so that a renamed entity
33
+ * is treated as delete+add rather than a mysterious match. Conservative, correct.
34
+ *
35
+ * Covers: TypeScript/TSX/JS/JSX, Python, Go, Rust.
36
+ */
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ function nodeSignature(node, source) {
39
+ const type = node.type;
40
+ // ╔══════════════════════════════════════════════════════╗
41
+ // ║ TypeScript / JavaScript (shared grammar base) ║
42
+ // ╚══════════════════════════════════════════════════════╝
43
+ // ── import_statement ─────────────────────────────────────
44
+ if (type === "import_statement") {
45
+ const sourceNode = fieldOrType(node, "source", "string");
46
+ const mod = sourceNode
47
+ ? source.slice(sourceNode.startIndex, sourceNode.endIndex)
48
+ : String(node.startIndex);
49
+ return { sig: `import:${mod}`, kind: "import" };
50
+ }
51
+ // ── export_statement ─────────────────────────────────────
52
+ if (type === "export_statement") {
53
+ const decl = node.childForFieldName?.("declaration");
54
+ if (decl) {
55
+ const inner = nodeSignature(decl, source);
56
+ return { sig: `export:${inner.sig}`, kind: "export" };
57
+ }
58
+ const preview = source
59
+ .slice(node.startIndex, Math.min(node.startIndex + 60, node.endIndex))
60
+ .replace(/\s+/g, " ")
61
+ .trim();
62
+ return { sig: `export:${preview}`, kind: "export" };
63
+ }
64
+ // ── function_declaration / generator_function_declaration ─
65
+ if (type === "function_declaration" || type === "generator_function_declaration") {
66
+ const name = fieldOrType(node, "name", "identifier");
67
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anonymous";
68
+ return { sig: `function:${nameText}`, kind: "function" };
69
+ }
70
+ // ── class_declaration / abstract_class_declaration ────────
71
+ if (type === "class_declaration" || type === "abstract_class_declaration") {
72
+ const name = fieldOrType(node, "name", "type_identifier") ?? fieldOrType(node, "name", "identifier");
73
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anonymous";
74
+ return { sig: `class:${nameText}`, kind: "class" };
75
+ }
76
+ // ── interface_declaration ─────────────────────────────────
77
+ if (type === "interface_declaration") {
78
+ const name = fieldOrType(node, "name", "type_identifier");
79
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anon";
80
+ return { sig: `interface:${nameText}`, kind: "interface" };
81
+ }
82
+ // ── type_alias_declaration ────────────────────────────────
83
+ if (type === "type_alias_declaration") {
84
+ const name = fieldOrType(node, "name", "type_identifier");
85
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anon";
86
+ return { sig: `type:${nameText}`, kind: "type" };
87
+ }
88
+ // ── lexical_declaration (const / let) ─────────────────────
89
+ // ── variable_declaration (var) ────────────────────────────
90
+ if (type === "lexical_declaration" || type === "variable_declaration") {
91
+ const names = [];
92
+ for (let i = 0; i < node.childCount; i++) {
93
+ const child = node.child(i);
94
+ if (child.type === "variable_declarator") {
95
+ const nameNode = child.childForFieldName?.("name");
96
+ if (nameNode)
97
+ names.push(source.slice(nameNode.startIndex, nameNode.endIndex));
98
+ }
99
+ }
100
+ return { sig: `var:${names.join(",")}`, kind: "variable" };
101
+ }
102
+ // ── ambient_declaration (declare …) ──────────────────────
103
+ if (type === "ambient_declaration") {
104
+ for (let i = 0; i < node.childCount; i++) {
105
+ const child = node.child(i);
106
+ if (child.type !== "declare") {
107
+ const inner = nodeSignature(child, source);
108
+ return { sig: `declare:${inner.sig}`, kind: "declare" };
109
+ }
110
+ }
111
+ return { sig: `declare:${node.startIndex}`, kind: "declare" };
112
+ }
113
+ // ── expression_statement ──────────────────────────────────
114
+ if (type === "expression_statement") {
115
+ const preview = source
116
+ .slice(node.startIndex, Math.min(node.startIndex + 50, node.endIndex))
117
+ .replace(/\s+/g, " ")
118
+ .trim();
119
+ return { sig: `expr:${preview}`, kind: "expression" };
120
+ }
121
+ // ╔══════════════════════════════════════════════════════╗
122
+ // ║ Python ║
123
+ // ╚══════════════════════════════════════════════════════╝
124
+ // ── function_definition ───────────────────────────────────
125
+ if (type === "function_definition") {
126
+ const name = fieldOrType(node, "name", "identifier");
127
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anonymous";
128
+ return { sig: `function:${nameText}`, kind: "function" };
129
+ }
130
+ // ── class_definition ──────────────────────────────────────
131
+ if (type === "class_definition") {
132
+ const name = fieldOrType(node, "name", "identifier");
133
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anonymous";
134
+ return { sig: `class:${nameText}`, kind: "class" };
135
+ }
136
+ // ── decorated_definition (wraps function_definition / class_definition) ──
137
+ if (type === "decorated_definition") {
138
+ // Find the wrapped definition
139
+ for (let i = 0; i < node.childCount; i++) {
140
+ const child = node.child(i);
141
+ if (child.type === "function_definition" || child.type === "class_definition") {
142
+ const inner = nodeSignature(child, source);
143
+ return { sig: `decorated:${inner.sig}`, kind: inner.kind };
144
+ }
145
+ }
146
+ return { sig: `decorated:${node.startIndex}`, kind: "other" };
147
+ }
148
+ // ── import_statement (Python) — already handled above (same name) ──
149
+ // ── import_from_statement (Python) ────────────────────────
150
+ if (type === "import_from_statement") {
151
+ const modNode = node.childForFieldName?.("module_name") ?? findChildByType(node, "dotted_name");
152
+ const mod = modNode ? source.slice(modNode.startIndex, modNode.endIndex) : String(node.startIndex);
153
+ return { sig: `import_from:${mod}`, kind: "import" };
154
+ }
155
+ // ╔══════════════════════════════════════════════════════╗
156
+ // ║ Go ║
157
+ // ╚══════════════════════════════════════════════════════╝
158
+ // ── function_declaration (Go) ─────────────────────────────
159
+ // Note: Go also has function_declaration but the name field is "name" with type "identifier"
160
+ // Already handled above by the JS function_declaration case.
161
+ // ── method_declaration (Go) ───────────────────────────────
162
+ if (type === "method_declaration") {
163
+ const name = fieldOrType(node, "name", "field_identifier") ?? fieldOrType(node, "name", "identifier");
164
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anonymous";
165
+ const receiver = node.childForFieldName?.("receiver");
166
+ const receiverText = receiver ? source.slice(receiver.startIndex, receiver.endIndex).replace(/\s+/g, " ").trim() : "";
167
+ return { sig: `method:${receiverText}:${nameText}`, kind: "function" };
168
+ }
169
+ // ── type_declaration (Go) ─────────────────────────────────
170
+ if (type === "type_declaration") {
171
+ // Contains type_spec children
172
+ const spec = findChildByType(node, "type_spec");
173
+ if (spec) {
174
+ const name = fieldOrType(spec, "name", "type_identifier");
175
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anon";
176
+ return { sig: `type:${nameText}`, kind: "type" };
177
+ }
178
+ return { sig: `type:${node.startIndex}`, kind: "type" };
179
+ }
180
+ // ── var_declaration (Go) ───────────────────────────────────
181
+ if (type === "var_declaration") {
182
+ const spec = findChildByType(node, "var_spec");
183
+ if (spec) {
184
+ const name = findChildByType(spec, "identifier");
185
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anon";
186
+ return { sig: `var:${nameText}`, kind: "variable" };
187
+ }
188
+ return { sig: `var:${node.startIndex}`, kind: "variable" };
189
+ }
190
+ // ── import_declaration (Go) ───────────────────────────────
191
+ if (type === "import_declaration") {
192
+ const preview = source
193
+ .slice(node.startIndex, Math.min(node.startIndex + 60, node.endIndex))
194
+ .replace(/\s+/g, " ")
195
+ .trim();
196
+ return { sig: `import:${preview}`, kind: "import" };
197
+ }
198
+ // ╔══════════════════════════════════════════════════════╗
199
+ // ║ Rust ║
200
+ // ╚══════════════════════════════════════════════════════╝
201
+ // ── function_item (Rust) ──────────────────────────────────
202
+ if (type === "function_item") {
203
+ const name = fieldOrType(node, "name", "identifier");
204
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anonymous";
205
+ return { sig: `function:${nameText}`, kind: "function" };
206
+ }
207
+ // ── struct_item (Rust) ────────────────────────────────────
208
+ if (type === "struct_item") {
209
+ const name = fieldOrType(node, "name", "type_identifier");
210
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anon";
211
+ return { sig: `struct:${nameText}`, kind: "class" };
212
+ }
213
+ // ── enum_item (Rust) ──────────────────────────────────────
214
+ if (type === "enum_item") {
215
+ const name = fieldOrType(node, "name", "type_identifier");
216
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anon";
217
+ return { sig: `enum:${nameText}`, kind: "type" };
218
+ }
219
+ // ── trait_item (Rust) ─────────────────────────────────────
220
+ if (type === "trait_item") {
221
+ const name = fieldOrType(node, "name", "type_identifier");
222
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anon";
223
+ return { sig: `trait:${nameText}`, kind: "interface" };
224
+ }
225
+ // ── impl_item (Rust) ──────────────────────────────────────
226
+ if (type === "impl_item") {
227
+ // impl Foo or impl Bar for Foo
228
+ const traitNode = node.childForFieldName?.("trait");
229
+ const typeNode = node.childForFieldName?.("type");
230
+ const typeText = typeNode
231
+ ? source.slice(typeNode.startIndex, typeNode.endIndex).replace(/\s+/g, " ").trim()
232
+ : String(node.startIndex);
233
+ const traitText = traitNode
234
+ ? source.slice(traitNode.startIndex, traitNode.endIndex).replace(/\s+/g, " ").trim()
235
+ : null;
236
+ const sig = traitText ? `impl:${traitText} for ${typeText}` : `impl:${typeText}`;
237
+ return { sig, kind: "class" };
238
+ }
239
+ // ── mod_item (Rust) ───────────────────────────────────────
240
+ if (type === "mod_item") {
241
+ const name = fieldOrType(node, "name", "identifier");
242
+ const nameText = name ? source.slice(name.startIndex, name.endIndex) : "__anon";
243
+ return { sig: `mod:${nameText}`, kind: "declare" };
244
+ }
245
+ // ── use_declaration (Rust) ────────────────────────────────
246
+ if (type === "use_declaration") {
247
+ const preview = source
248
+ .slice(node.startIndex, Math.min(node.startIndex + 60, node.endIndex))
249
+ .replace(/\s+/g, " ")
250
+ .trim();
251
+ return { sig: `use:${preview}`, kind: "import" };
252
+ }
253
+ // ── attribute_item / inner_attribute_item (Rust — top-level attributes) ──
254
+ if (type === "attribute_item" || type === "inner_attribute_item") {
255
+ const preview = source
256
+ .slice(node.startIndex, Math.min(node.startIndex + 40, node.endIndex))
257
+ .replace(/\s+/g, " ")
258
+ .trim();
259
+ return { sig: `attr:${preview}`, kind: "other" };
260
+ }
261
+ // ╔══════════════════════════════════════════════════════╗
262
+ // ║ Fallback ║
263
+ // ╚══════════════════════════════════════════════════════╝
264
+ return { sig: `${type}:${node.startIndex}`, kind: "other" };
265
+ }
266
+ // ─── Public API ───────────────────────────────────────────────────────────────
267
+ /**
268
+ * Extract top-level entities from a parsed tree-sitter tree.
269
+ *
270
+ * Skips unnamed tokens (punctuation, keywords) and ERROR nodes.
271
+ *
272
+ * @param tree - Parsed tree-sitter tree
273
+ * @param source - Source code (as passed to `parser.parse()`)
274
+ */
275
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
276
+ export function extractEntities(tree, source) {
277
+ const entities = [];
278
+ const root = tree.rootNode;
279
+ for (let i = 0; i < root.childCount; i++) {
280
+ const node = root.child(i);
281
+ // Skip unnamed tokens (semicolons, whitespace nodes) and parse errors
282
+ if (!node.isNamed || node.type === "ERROR")
283
+ continue;
284
+ const { sig, kind } = nodeSignature(node, source);
285
+ entities.push({
286
+ signature: sig,
287
+ kind,
288
+ text: source.slice(node.startIndex, node.endIndex),
289
+ startByte: node.startIndex,
290
+ endByte: node.endIndex,
291
+ startLine: node.startPosition.row,
292
+ });
293
+ }
294
+ return entities;
295
+ }
296
+ /**
297
+ * Return `true` if the tree contains at least one ERROR node.
298
+ *
299
+ * A tree with ERROR nodes has parse failures and should not be used
300
+ * for structural merge (we fall back to the hunk-based resolver).
301
+ */
302
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
303
+ export function hasParseErrors(tree) {
304
+ function walk(node) {
305
+ if (node.type === "ERROR")
306
+ return true;
307
+ for (let i = 0; i < node.childCount; i++) {
308
+ if (walk(node.child(i)))
309
+ return true;
310
+ }
311
+ return false;
312
+ }
313
+ return walk(tree.rootNode);
314
+ }
315
+ //# sourceMappingURL=entities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entities.js","sourceRoot":"","sources":["../../src/structural/entities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @gitwand/core v2.3 — Structural (AST-based) merge dispatcher
3
+ *
4
+ * Provides `tryStructuralMergeResolve()`, an async entry point that:
5
+ *
6
+ * 1. Reconstructs the three file versions (base/ours/theirs) from the
7
+ * Git conflict markers in the conflicted content.
8
+ * 2. Parses each version with tree-sitter (via `web-tree-sitter`, optional peer).
9
+ * 3. Extracts top-level entities and matches them across the three versions.
10
+ * 4. Merges entities individually — only auto-resolvable conflicts are handled.
11
+ * 5. Reconstructs the merged file following theirs entity order.
12
+ *
13
+ * Returns `null` (never throws) when:
14
+ * - `web-tree-sitter` is not installed (graceful degradation)
15
+ * - The grammar WASM file is unavailable
16
+ * - Any version has parse errors
17
+ * - Any entity has a real (both-changed-diff) conflict
18
+ *
19
+ * In all these cases the caller falls back to the standard hunk-based resolver.
20
+ */
21
+ import type { MergeResult } from "../types.js";
22
+ import { type LoaderOptions } from "./parsers/loader.js";
23
+ import { isStructuralLanguage } from "./parsers/grammars/languages.js";
24
+ export type { LoaderOptions as StructuralLoaderOptions };
25
+ export { isStructuralLanguage };
26
+ export type { SupportedLanguage } from "./parsers/grammars/languages.js";
27
+ /**
28
+ * Returns `true` for `.ts` and `.tsx` files.
29
+ * @deprecated Use `isStructuralLanguage` — now covers JS/JSX/Python/Go/Rust too.
30
+ */
31
+ export declare function isTypeScriptFile(filePath: string): boolean;
32
+ /**
33
+ * Attempt structural (AST-based) merge resolution for a TypeScript/TSX file.
34
+ *
35
+ * @param conflictedContent - File content with Git conflict markers
36
+ * @param filePath - File path (grammar selection + type detection)
37
+ * @param opts - Optional loader overrides (WASM paths, custom loaders)
38
+ * @returns Merged content string on success, `null` on any failure
39
+ */
40
+ export declare function tryStructuralMergeResolve(conflictedContent: string, filePath: string, opts?: LoaderOptions): Promise<string | null>;
41
+ /**
42
+ * Wrap a structurally merged content string in a `MergeResult` object.
43
+ *
44
+ * All hunks are marked as auto-resolved via the "structural-merge" resolver.
45
+ * This keeps the return type compatible with the synchronous `resolve()`.
46
+ */
47
+ export declare function wrapStructuralResult(conflictedContent: string, mergedContent: string, filePath: string): MergeResult;
48
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/structural/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,WAAW,EAA8D,MAAM,aAAa,CAAC;AAE3G,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAIvE,YAAY,EAAE,aAAa,IAAI,uBAAuB,EAAE,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAIzE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D;AAiDD;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,iBAAiB,EAAE,MAAM,EACzB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2CxB;AAID;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,WAAW,CAyDb"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * @gitwand/core v2.3 — Structural (AST-based) merge dispatcher
3
+ *
4
+ * Provides `tryStructuralMergeResolve()`, an async entry point that:
5
+ *
6
+ * 1. Reconstructs the three file versions (base/ours/theirs) from the
7
+ * Git conflict markers in the conflicted content.
8
+ * 2. Parses each version with tree-sitter (via `web-tree-sitter`, optional peer).
9
+ * 3. Extracts top-level entities and matches them across the three versions.
10
+ * 4. Merges entities individually — only auto-resolvable conflicts are handled.
11
+ * 5. Reconstructs the merged file following theirs entity order.
12
+ *
13
+ * Returns `null` (never throws) when:
14
+ * - `web-tree-sitter` is not installed (graceful degradation)
15
+ * - The grammar WASM file is unavailable
16
+ * - Any version has parse errors
17
+ * - Any entity has a real (both-changed-diff) conflict
18
+ *
19
+ * In all these cases the caller falls back to the standard hunk-based resolver.
20
+ */
21
+ import { parseConflictMarkers } from "../parser.js";
22
+ import { validateMergedContent } from "../resolver/validation.js";
23
+ import { loadGrammarForFile } from "./parsers/grammars/ts.js";
24
+ import { createParser } from "./parsers/loader.js";
25
+ import { extractEntities, hasParseErrors } from "./entities.js";
26
+ import { matchEntities } from "./matching.js";
27
+ import { mergeEntity, hasEntityConflict } from "./merge.js";
28
+ import { reconstructFile } from "./reconstruct.js";
29
+ import { isStructuralLanguage } from "./parsers/grammars/languages.js";
30
+ export { isStructuralLanguage };
31
+ // ─── Backward-compat alias ────────────────────────────────────────────────────
32
+ /**
33
+ * Returns `true` for `.ts` and `.tsx` files.
34
+ * @deprecated Use `isStructuralLanguage` — now covers JS/JSX/Python/Go/Rust too.
35
+ */
36
+ export function isTypeScriptFile(filePath) {
37
+ return /\.(ts|tsx)$/i.test(filePath) && !/\.d\.ts$/i.test(filePath);
38
+ }
39
+ /**
40
+ * Reconstruct the three clean file versions from a conflicted file.
41
+ *
42
+ * - `ours` = text segments + ours lines from each conflict hunk
43
+ * - `theirs` = text segments + theirs lines from each conflict hunk
44
+ * - `base` = text segments + base lines (diff3) or ours lines (diff2 fallback)
45
+ */
46
+ function reconstructVersions(conflictedContent) {
47
+ const { segments } = parseConflictMarkers(conflictedContent);
48
+ const oursLines = [];
49
+ const theirsLines = [];
50
+ const baseLines = [];
51
+ for (const seg of segments) {
52
+ if (seg.type === "text") {
53
+ oursLines.push(...seg.lines);
54
+ theirsLines.push(...seg.lines);
55
+ baseLines.push(...seg.lines);
56
+ }
57
+ else {
58
+ const { conflict } = seg;
59
+ oursLines.push(...conflict.oursLines);
60
+ theirsLines.push(...conflict.theirsLines);
61
+ // Use diff3 base if available; fall back to ours (conservative)
62
+ baseLines.push(...(conflict.baseLines.length > 0 ? conflict.baseLines : conflict.oursLines));
63
+ }
64
+ }
65
+ return {
66
+ base: baseLines.join("\n"),
67
+ ours: oursLines.join("\n"),
68
+ theirs: theirsLines.join("\n"),
69
+ };
70
+ }
71
+ // ─── Main entry point ─────────────────────────────────────────────────────────
72
+ /**
73
+ * Attempt structural (AST-based) merge resolution for a TypeScript/TSX file.
74
+ *
75
+ * @param conflictedContent - File content with Git conflict markers
76
+ * @param filePath - File path (grammar selection + type detection)
77
+ * @param opts - Optional loader overrides (WASM paths, custom loaders)
78
+ * @returns Merged content string on success, `null` on any failure
79
+ */
80
+ export async function tryStructuralMergeResolve(conflictedContent, filePath, opts = {}) {
81
+ // Only handle supported languages
82
+ if (!isStructuralLanguage(filePath))
83
+ return null;
84
+ // Load tree-sitter grammar (returns null if optional peer not installed)
85
+ const language = await loadGrammarForFile(filePath, opts);
86
+ if (!language)
87
+ return null;
88
+ // Create parser
89
+ const parser = await createParser(language, opts);
90
+ if (!parser)
91
+ return null;
92
+ // Reconstruct the three file versions
93
+ const { base, ours, theirs } = reconstructVersions(conflictedContent);
94
+ // Parse all three versions
95
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
+ const p = parser;
97
+ const [baseTree, oursTree, theirsTree] = [base, ours, theirs].map((src) => p.parse(src));
98
+ // Abort on parse errors in any version
99
+ if (hasParseErrors(baseTree) || hasParseErrors(oursTree) || hasParseErrors(theirsTree)) {
100
+ return null;
101
+ }
102
+ // Extract top-level entities
103
+ const baseEntities = extractEntities(baseTree, base);
104
+ const oursEntities = extractEntities(oursTree, ours);
105
+ const theirsEntities = extractEntities(theirsTree, theirs);
106
+ // 3-way entity matching
107
+ const matches = matchEntities(baseEntities, oursEntities, theirsEntities);
108
+ // Entity-level merge decisions
109
+ const merges = matches.map(mergeEntity);
110
+ // Abort if any entity has a real conflict
111
+ if (hasEntityConflict(merges))
112
+ return null;
113
+ // Reconstruct the merged file
114
+ const mergedContent = reconstructFile(merges, theirsEntities, oursEntities, theirs);
115
+ return mergedContent;
116
+ }
117
+ // ─── MergeResult wrapper ──────────────────────────────────────────────────────
118
+ /**
119
+ * Wrap a structurally merged content string in a `MergeResult` object.
120
+ *
121
+ * All hunks are marked as auto-resolved via the "structural-merge" resolver.
122
+ * This keeps the return type compatible with the synchronous `resolve()`.
123
+ */
124
+ export function wrapStructuralResult(conflictedContent, mergedContent, filePath) {
125
+ const { segments } = parseConflictMarkers(conflictedContent);
126
+ const hunks = segments
127
+ .filter((s) => s.type === "conflict")
128
+ .map((s) => ({
129
+ baseLines: s.conflict.baseLines,
130
+ oursLines: s.conflict.oursLines,
131
+ theirsLines: s.conflict.theirsLines,
132
+ startLine: s.conflict.startLine,
133
+ type: "complex",
134
+ confidence: {
135
+ score: 100,
136
+ label: "certain",
137
+ dimensions: {
138
+ typeClassification: 100,
139
+ dataRisk: 0,
140
+ scopeImpact: 0,
141
+ fileFrequency: 0,
142
+ baseAvailability: s.conflict.baseLines.length > 0 ? 100 : 0,
143
+ },
144
+ boosters: ["structural-merge"],
145
+ penalties: [],
146
+ },
147
+ explanation: "Résolu via merge structurel (tree-sitter AST)",
148
+ trace: {
149
+ steps: [],
150
+ selected: "complex",
151
+ summary: "Résolu via analyse structurelle AST — merge par entités TypeScript",
152
+ hasBase: s.conflict.baseLines.length > 0,
153
+ },
154
+ }));
155
+ const resolutions = hunks.map((hunk) => ({
156
+ hunk,
157
+ resolvedLines: null,
158
+ autoResolved: true,
159
+ resolutionReason: "structural-merge: résolu via analyse AST tree-sitter",
160
+ }));
161
+ const byType = hunks.length > 0 ? { complex: hunks.length } : {};
162
+ const validation = validateMergedContent(mergedContent, filePath);
163
+ return {
164
+ filePath,
165
+ mergedContent,
166
+ hunks,
167
+ resolutions,
168
+ stats: {
169
+ totalConflicts: hunks.length,
170
+ autoResolved: hunks.length,
171
+ remaining: 0,
172
+ byType,
173
+ },
174
+ validation,
175
+ };
176
+ }
177
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/structural/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 3-way entity matching for structural merge.
3
+ *
4
+ * Matches top-level entities across the three file versions (base / ours /
5
+ * theirs) using their `signature` as a stable key. Each entity triple is
6
+ * assigned a status that describes what happened to it during the merge.
7
+ */
8
+ import type { TopLevelEntity } from "./entities.js";
9
+ export type EntityMatchStatus =
10
+ /** Text identical in all three versions */
11
+ "unchanged"
12
+ /** Changed in ours, unchanged in theirs */
13
+ | "ours-only-change"
14
+ /** Changed in theirs, unchanged in ours */
15
+ | "theirs-only-change"
16
+ /** Both sides made the same change (or both deleted) */
17
+ | "both-changed-same"
18
+ /** Both sides changed differently — unresolvable at entity level */
19
+ | "both-changed-diff"
20
+ /** Added only by ours (not in base, not in theirs) */
21
+ | "ours-added"
22
+ /** Added only by theirs (not in base, not in ours) */
23
+ | "theirs-added"
24
+ /** Deleted by ours (was in base and theirs) */
25
+ | "ours-deleted"
26
+ /** Deleted by theirs (was in base and ours) */
27
+ | "theirs-deleted";
28
+ export interface EntityMatch {
29
+ signature: string;
30
+ status: EntityMatchStatus;
31
+ base: TopLevelEntity | null;
32
+ ours: TopLevelEntity | null;
33
+ theirs: TopLevelEntity | null;
34
+ }
35
+ /**
36
+ * Compute 3-way entity matches between base, ours, and theirs.
37
+ *
38
+ * The returned array covers every unique signature found across all three
39
+ * versions. Order follows: base order → ours-only → theirs-only sigs.
40
+ *
41
+ * @param base - Entities extracted from the base (ancestor) version
42
+ * @param ours - Entities extracted from our version (current branch)
43
+ * @param theirs - Entities extracted from their version (incoming branch)
44
+ */
45
+ export declare function matchEntities(base: TopLevelEntity[], ours: TopLevelEntity[], theirs: TopLevelEntity[]): EntityMatch[];
46
+ //# sourceMappingURL=matching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/structural/matching.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,MAAM,MAAM,iBAAiB;AAC3B,2CAA2C;AACzC,WAAW;AACb,2CAA2C;GACzC,kBAAkB;AACpB,2CAA2C;GACzC,oBAAoB;AACtB,wDAAwD;GACtD,mBAAmB;AACrB,oEAAoE;GAClE,mBAAmB;AACrB,sDAAsD;GACpD,YAAY;AACd,sDAAsD;GACpD,cAAc;AAChB,+CAA+C;GAC7C,cAAc;AAChB,+CAA+C;GAC7C,gBAAgB,CAAC;AAErB,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;CAC/B;AA4CD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,cAAc,EAAE,EACtB,IAAI,EAAE,cAAc,EAAE,EACtB,MAAM,EAAE,cAAc,EAAE,GACvB,WAAW,EAAE,CA8Bf"}