@iowarp/clio-coder 0.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 (226) hide show
  1. package/CHANGELOG.md +407 -0
  2. package/CODE_OF_CONDUCT.md +21 -0
  3. package/CONTRIBUTING.md +224 -0
  4. package/LICENSE +202 -0
  5. package/NOTICE +9 -0
  6. package/README.md +798 -0
  7. package/SECURITY.md +72 -0
  8. package/assets/clio-coder-logo-128.webp +0 -0
  9. package/damage-control-rules.yaml +419 -0
  10. package/dist/acp-UMLFVA3F.js +92 -0
  11. package/dist/agents-Q4MYPMUW.js +91 -0
  12. package/dist/auth-O6HYIJ6J.js +521 -0
  13. package/dist/chunk-262G75JS.js +35 -0
  14. package/dist/chunk-26BZQOAD.js +1281 -0
  15. package/dist/chunk-2J63S4SF.js +508 -0
  16. package/dist/chunk-3DANZDGR.js +717 -0
  17. package/dist/chunk-4UQA7NCT.js +29 -0
  18. package/dist/chunk-527KG6XR.js +497 -0
  19. package/dist/chunk-5LDRNKX2.js +1063 -0
  20. package/dist/chunk-5N2FG33Q.js +25 -0
  21. package/dist/chunk-67MTHP2E.js +135 -0
  22. package/dist/chunk-6CWDTGUC.js +20 -0
  23. package/dist/chunk-7BHLZB3A.js +2115 -0
  24. package/dist/chunk-7RBKDI66.js +348 -0
  25. package/dist/chunk-AMFR5YA3.js +541 -0
  26. package/dist/chunk-BBUH4VAA.js +1224 -0
  27. package/dist/chunk-BYEU76JP.js +899 -0
  28. package/dist/chunk-CLJ5HLUD.js +458 -0
  29. package/dist/chunk-D5YD55AR.js +116 -0
  30. package/dist/chunk-DXQNI4PC.js +61 -0
  31. package/dist/chunk-E3NYWENM.js +1004 -0
  32. package/dist/chunk-GNGDQYDU.js +34688 -0
  33. package/dist/chunk-GOTUR54M.js +9 -0
  34. package/dist/chunk-HBU5MTAM.js +41 -0
  35. package/dist/chunk-HMYNFFY4.js +28 -0
  36. package/dist/chunk-JPOWPFCU.js +1010 -0
  37. package/dist/chunk-JWHCJDCI.js +1215 -0
  38. package/dist/chunk-KBR4MZZR.js +41 -0
  39. package/dist/chunk-KKKPTZLM.js +93 -0
  40. package/dist/chunk-ME6DNWIU.js +66 -0
  41. package/dist/chunk-NI4DEJMC.js +88 -0
  42. package/dist/chunk-O4EJEDHO.js +659 -0
  43. package/dist/chunk-PIDUD6M2.js +31 -0
  44. package/dist/chunk-PS4PFJQP.js +29459 -0
  45. package/dist/chunk-QV47YRF4.js +48 -0
  46. package/dist/chunk-RQDWMVRB.js +279 -0
  47. package/dist/chunk-TFSSEXL6.js +136 -0
  48. package/dist/chunk-TKHQ4DGZ.js +8290 -0
  49. package/dist/chunk-TPOCL34A.js +2876 -0
  50. package/dist/chunk-UGYAX5YI.js +565 -0
  51. package/dist/chunk-UHTSULZS.js +461 -0
  52. package/dist/chunk-UU3R62TT.js +128 -0
  53. package/dist/chunk-UWIJNAOB.js +3906 -0
  54. package/dist/chunk-VOO7NYPP.js +914 -0
  55. package/dist/chunk-VPAWTYLY.js +117 -0
  56. package/dist/chunk-WD6AJM35.js +1216 -0
  57. package/dist/chunk-X3BR7HWV.js +115 -0
  58. package/dist/chunk-X3NE4WVW.js +120 -0
  59. package/dist/chunk-XNISANGE.js +1395 -0
  60. package/dist/chunk-XV4ZJ6ZM.js +3177 -0
  61. package/dist/cli/index.js +236 -0
  62. package/dist/clio-KIQ5SNDS.js +53 -0
  63. package/dist/components-JVHMUBEB.js +653 -0
  64. package/dist/config-ZFCDBMDC.js +372 -0
  65. package/dist/configure-G4E3A2PG.js +27 -0
  66. package/dist/context-CDXTP2MP.js +293 -0
  67. package/dist/context-E3KIFVXI.js +185 -0
  68. package/dist/context-clear-3F4PLXOS.js +102 -0
  69. package/dist/context-index-Q7YSYTR3.js +106 -0
  70. package/dist/docs-YIETIWZI.js +280 -0
  71. package/dist/doctor-M5HJJZOL.js +61 -0
  72. package/dist/domains/agents/builtins/architect.md +33 -0
  73. package/dist/domains/agents/builtins/coder.md +31 -0
  74. package/dist/domains/agents/builtins/context-bootstrap.md +38 -0
  75. package/dist/domains/agents/builtins/debugger.md +30 -0
  76. package/dist/domains/agents/builtins/documenter.md +31 -0
  77. package/dist/domains/agents/builtins/git-master.md +30 -0
  78. package/dist/domains/agents/builtins/provenance.md +30 -0
  79. package/dist/domains/agents/builtins/researcher.md +71 -0
  80. package/dist/domains/agents/builtins/scout.md +42 -0
  81. package/dist/domains/agents/builtins/tester.md +31 -0
  82. package/dist/domains/agents/builtins/verifier.md +30 -0
  83. package/dist/domains/agents/builtins/wiki-writer.md +41 -0
  84. package/dist/eval-B3KZZESM.js +2674 -0
  85. package/dist/evidence-V67CHM35.js +233 -0
  86. package/dist/evolve-YDZSUQYA.js +518 -0
  87. package/dist/extensions-SRG7XCAH.js +207 -0
  88. package/dist/fleet-CA2CRTVG.js +760 -0
  89. package/dist/fleet-preflight-CLIAX7YR.js +21 -0
  90. package/dist/init-2OZDJE2D.js +227 -0
  91. package/dist/memory-3PIQQAKX.js +207 -0
  92. package/dist/models-DY35XI7Y.js +237 -0
  93. package/dist/paths-5OMXW7Z4.js +57 -0
  94. package/dist/preload-KZVHET2B.js +11 -0
  95. package/dist/reset-PIFYNOS3.js +216 -0
  96. package/dist/run-3VSPP24F.js +735 -0
  97. package/dist/share-D36RQCXM.js +241 -0
  98. package/dist/skills-F2MRLELY.js +445 -0
  99. package/dist/skills-eval-E2ZTW4PL.js +932 -0
  100. package/dist/targets-DZMEZAH4.js +977 -0
  101. package/dist/trace-7NYCUI2J.js +250 -0
  102. package/dist/uninstall-AD3JWHBB.js +322 -0
  103. package/dist/upgrade-WYYBKGDY.js +301 -0
  104. package/dist/usage-ULIDAGFF.js +755 -0
  105. package/dist/version-ROZ6CZKH.js +16 -0
  106. package/dist/wiki-generate-PKFIX6OB.js +377 -0
  107. package/dist/worker/entry.js +1739 -0
  108. package/docs/README.md +93 -0
  109. package/docs/acp.md +120 -0
  110. package/docs/alcf-provider.md +72 -0
  111. package/docs/architecture.md +172 -0
  112. package/docs/artifact-versions.md +54 -0
  113. package/docs/built-in-agents.md +265 -0
  114. package/docs/capacity-and-scheduling.md +97 -0
  115. package/docs/commands-and-modes.md +554 -0
  116. package/docs/config-knobs-audit.md +115 -0
  117. package/docs/configuration-and-targets.md +812 -0
  118. package/docs/context-engine.md +236 -0
  119. package/docs/dispatch-architecture-rationale.md +126 -0
  120. package/docs/documentation-coverage.md +46 -0
  121. package/docs/documentation-guide.md +166 -0
  122. package/docs/environment-variables.md +105 -0
  123. package/docs/eval-runner.md +205 -0
  124. package/docs/evals-internal.md +298 -0
  125. package/docs/evidence-and-memory.md +243 -0
  126. package/docs/evolution.md +143 -0
  127. package/docs/exit-codes-and-output.md +74 -0
  128. package/docs/extensions-and-sharing.md +306 -0
  129. package/docs/fleet-demo-runbook.md +179 -0
  130. package/docs/fleet-dispatch.md +591 -0
  131. package/docs/glossary.md +75 -0
  132. package/docs/html/agents_blueprint.html +936 -0
  133. package/docs/html/alcf_blueprint.html +324 -0
  134. package/docs/html/architecture_blueprint.html +850 -0
  135. package/docs/html/commands_blueprint.html +794 -0
  136. package/docs/html/config_knobs_audit_blueprint.html +178 -0
  137. package/docs/html/configuration_blueprint.html +1080 -0
  138. package/docs/html/context_blueprint.html +603 -0
  139. package/docs/html/documentation_blueprint.html +832 -0
  140. package/docs/html/environment_blueprint.html +404 -0
  141. package/docs/html/eval_blueprint.html +743 -0
  142. package/docs/html/evals_internal_blueprint.html +190 -0
  143. package/docs/html/evolution_blueprint.html +674 -0
  144. package/docs/html/extensions_blueprint.html +2065 -0
  145. package/docs/html/fleet_dispatch_blueprint.html +286 -0
  146. package/docs/html/index.html +919 -0
  147. package/docs/html/lifecycle_blueprint.html +723 -0
  148. package/docs/html/memory_blueprint.html +699 -0
  149. package/docs/html/middleware_blueprint.html +664 -0
  150. package/docs/html/models_blueprint.html +2366 -0
  151. package/docs/html/observability_blueprint.html +683 -0
  152. package/docs/html/provider_adapter_blueprint.html +245 -0
  153. package/docs/html/safety_blueprint.html +1386 -0
  154. package/docs/html/shared.css +571 -0
  155. package/docs/html/shared.js +143 -0
  156. package/docs/html/skills_blueprint.html +671 -0
  157. package/docs/html/soak_blueprint.html +182 -0
  158. package/docs/html/tool_usage_blueprint.html +350 -0
  159. package/docs/html/tools_blueprint.html +2249 -0
  160. package/docs/html/trace_blueprint.html +235 -0
  161. package/docs/html/tui_design_blueprint.html +314 -0
  162. package/docs/html/validation_blueprint.html +961 -0
  163. package/docs/html/worker_dispatch_blueprint.html +231 -0
  164. package/docs/installation-and-lifecycle.md +308 -0
  165. package/docs/middleware-and-components.md +148 -0
  166. package/docs/model-catalog.md +189 -0
  167. package/docs/observability.md +233 -0
  168. package/docs/proactive-memory.md +452 -0
  169. package/docs/prompt-envelope-and-tools.md +142 -0
  170. package/docs/provider-adapter-cookbook.md +148 -0
  171. package/docs/release-cut-checklist.md +138 -0
  172. package/docs/safety-model.md +357 -0
  173. package/docs/scientific-validation.md +105 -0
  174. package/docs/session-lifecycle.md +156 -0
  175. package/docs/skills-marketplace.md +46 -0
  176. package/docs/tool-usage.md +527 -0
  177. package/docs/trace-store.md +132 -0
  178. package/docs/troubleshooting.md +33 -0
  179. package/docs/tui-design.md +239 -0
  180. package/docs/worker-dispatch-mechanics.md +242 -0
  181. package/package.json +132 -0
  182. package/skills/README.md +408 -0
  183. package/skills/git/commit-crafting/SKILL.md +79 -0
  184. package/skills/git/commit-crafting/evals.md +92 -0
  185. package/skills/git/create-pr/SKILL.md +116 -0
  186. package/skills/git/create-pr/evals.md +114 -0
  187. package/skills/git/investigate-issue/SKILL.md +139 -0
  188. package/skills/git/investigate-issue/evals.md +94 -0
  189. package/skills/git/resolve-merge-conflicts/SKILL.md +96 -0
  190. package/skills/git/resolve-merge-conflicts/evals.md +58 -0
  191. package/skills/git/review-changes/SKILL.md +103 -0
  192. package/skills/git/review-changes/evals.md +85 -0
  193. package/skills/git/worktree-create/SKILL.md +92 -0
  194. package/skills/git/worktree-create/evals.md +97 -0
  195. package/skills/git/worktree-create/references/worktree-setup.md +66 -0
  196. package/skills/git/worktree-merge/SKILL.md +95 -0
  197. package/skills/git/worktree-merge/evals.md +114 -0
  198. package/skills/skill-marketplace.json +261 -0
  199. package/skills/workflow/cut-it/SKILL.md +86 -0
  200. package/skills/workflow/cut-it/evals.md +42 -0
  201. package/src/domains/agents/builtins/architect.md +33 -0
  202. package/src/domains/agents/builtins/coder.md +31 -0
  203. package/src/domains/agents/builtins/context-bootstrap.md +38 -0
  204. package/src/domains/agents/builtins/debugger.md +30 -0
  205. package/src/domains/agents/builtins/documenter.md +31 -0
  206. package/src/domains/agents/builtins/git-master.md +30 -0
  207. package/src/domains/agents/builtins/provenance.md +30 -0
  208. package/src/domains/agents/builtins/researcher.md +71 -0
  209. package/src/domains/agents/builtins/scout.md +42 -0
  210. package/src/domains/agents/builtins/tester.md +31 -0
  211. package/src/domains/agents/builtins/verifier.md +30 -0
  212. package/src/domains/agents/builtins/wiki-writer.md +41 -0
  213. package/src/domains/agents/fleets/build-review.md +34 -0
  214. package/src/domains/agents/fleets/build-test.md +35 -0
  215. package/src/domains/agents/fleets/sdlc.md +86 -0
  216. package/src/domains/prompts/fragments/identity/clio-worker.md +11 -0
  217. package/src/domains/prompts/fragments/identity/clio.md +26 -0
  218. package/src/domains/prompts/fragments/operating/contract.md +64 -0
  219. package/src/domains/prompts/fragments/safety/auto-edit.md +14 -0
  220. package/src/domains/prompts/fragments/safety/full-auto.md +14 -0
  221. package/src/domains/prompts/fragments/safety/read-only.md +13 -0
  222. package/src/domains/prompts/fragments/safety/suggest.md +13 -0
  223. package/src/domains/prompts/fragments/wiki/page.md +75 -0
  224. package/src/domains/prompts/fragments/wiki/plan.md +48 -0
  225. package/src/domains/providers/models/cloud-models/alcf.yaml +40 -0
  226. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +993 -0
@@ -0,0 +1,2876 @@
1
+ import {
2
+ safeResourceWrite
3
+ } from "./chunk-VPAWTYLY.js";
4
+
5
+ // src/domains/session/workspace/project-type.ts
6
+ import { readFileSync } from "node:fs";
7
+ import { join as join2 } from "node:path";
8
+
9
+ // src/core/c-header-language.ts
10
+ function isAmbiguousHeaderPath(path) {
11
+ return path.endsWith(".h");
12
+ }
13
+ var CPP_ONLY_STD_INCLUDES = /* @__PURE__ */ new Set([
14
+ "algorithm",
15
+ "any",
16
+ "array",
17
+ "atomic",
18
+ "barrier",
19
+ "bit",
20
+ "bitset",
21
+ "cassert",
22
+ "cctype",
23
+ "cerrno",
24
+ "cfenv",
25
+ "cfloat",
26
+ "charconv",
27
+ "chrono",
28
+ "cinttypes",
29
+ "climits",
30
+ "clocale",
31
+ "cmath",
32
+ "codecvt",
33
+ "compare",
34
+ "complex",
35
+ "concepts",
36
+ "condition_variable",
37
+ "coroutine",
38
+ "csetjmp",
39
+ "csignal",
40
+ "cstdarg",
41
+ "cstddef",
42
+ "cstdint",
43
+ "cstdio",
44
+ "cstdlib",
45
+ "cstring",
46
+ "ctime",
47
+ "cuchar",
48
+ "cwchar",
49
+ "cwctype",
50
+ "deque",
51
+ "exception",
52
+ "execution",
53
+ "expected",
54
+ "filesystem",
55
+ "flat_map",
56
+ "flat_set",
57
+ "format",
58
+ "forward_list",
59
+ "fstream",
60
+ "functional",
61
+ "future",
62
+ "generator",
63
+ "initializer_list",
64
+ "iomanip",
65
+ "ios",
66
+ "iosfwd",
67
+ "iostream",
68
+ "istream",
69
+ "iterator",
70
+ "latch",
71
+ "limits",
72
+ "list",
73
+ "locale",
74
+ "map",
75
+ "mdspan",
76
+ "memory",
77
+ "memory_resource",
78
+ "mutex",
79
+ "new",
80
+ "numbers",
81
+ "numeric",
82
+ "optional",
83
+ "ostream",
84
+ "print",
85
+ "queue",
86
+ "random",
87
+ "ranges",
88
+ "ratio",
89
+ "regex",
90
+ "scoped_allocator",
91
+ "semaphore",
92
+ "set",
93
+ "shared_mutex",
94
+ "source_location",
95
+ "span",
96
+ "spanstream",
97
+ "sstream",
98
+ "stack",
99
+ "stacktrace",
100
+ "stdexcept",
101
+ "stop_token",
102
+ "streambuf",
103
+ "string",
104
+ "string_view",
105
+ "syncstream",
106
+ "system_error",
107
+ "thread",
108
+ "tuple",
109
+ "type_traits",
110
+ "typeindex",
111
+ "typeinfo",
112
+ "unordered_map",
113
+ "unordered_set",
114
+ "utility",
115
+ "valarray",
116
+ "variant",
117
+ "vector",
118
+ "version"
119
+ ]);
120
+ var CPP_SYNTAX_PATTERNS = [
121
+ /\bnamespace\s+[A-Za-z_{:]/,
122
+ /\btemplate\s*</,
123
+ /\btypename\b/,
124
+ /\bclass\s+[A-Za-z_]/,
125
+ /\benum\s+(?:class|struct)\b/,
126
+ /\w::~?[A-Za-z_~]/,
127
+ /::/,
128
+ /^\s*(?:public|private|protected)\s*:(?!:)/m,
129
+ /\b(?:static_cast|dynamic_cast|reinterpret_cast|const_cast)\s*</,
130
+ /\busing\s+[A-Za-z_]\w*\s*=/,
131
+ /\busing\s+namespace\b/,
132
+ /\boperator\s*(?:[+\-*/%^&|~!=<>]|\(\)|\[\])/,
133
+ /\b(?:constexpr|consteval|constinit|noexcept|nullptr|decltype|thread_local)\b/,
134
+ /\b(?:virtual|override|friend|mutable)\b/,
135
+ /\)\s*(?:const|noexcept|override|final)\b/,
136
+ /^[ \t]*[A-Za-z_]\w*(?:::\w+)*(?:\s*<[^;{}()]+>)?\s*&&?\s*[A-Za-z_]\w*\s*\([^;{}]*\)\s*;/m,
137
+ /\bauto\s+[A-Za-z_]\w*\s*\([^;{}]*\)\s*->/
138
+ ];
139
+ function blank(ch) {
140
+ return ch === "\n" ? "\n" : " ";
141
+ }
142
+ function stripForScan(text) {
143
+ let withStrings = "";
144
+ let code = "";
145
+ let state = "code";
146
+ for (let index = 0; index < text.length; index += 1) {
147
+ const ch = text[index];
148
+ const next = text[index + 1];
149
+ if (state === "code") {
150
+ if (ch === "/" && next === "/") {
151
+ state = "line-comment";
152
+ withStrings += " ";
153
+ code += " ";
154
+ continue;
155
+ }
156
+ if (ch === "/" && next === "*") {
157
+ state = "block-comment";
158
+ withStrings += " ";
159
+ code += " ";
160
+ continue;
161
+ }
162
+ if (ch === '"') state = "string";
163
+ else if (ch === "'") state = "char";
164
+ withStrings += ch;
165
+ code += state === "code" ? ch : " ";
166
+ continue;
167
+ }
168
+ if (state === "line-comment") {
169
+ if (ch === "\n") state = "code";
170
+ withStrings += blank(ch);
171
+ code += blank(ch);
172
+ continue;
173
+ }
174
+ if (state === "block-comment") {
175
+ if (ch === "*" && next === "/") {
176
+ state = "code";
177
+ index += 1;
178
+ withStrings += " ";
179
+ code += " ";
180
+ continue;
181
+ }
182
+ withStrings += blank(ch);
183
+ code += blank(ch);
184
+ continue;
185
+ }
186
+ if (ch === "\\" && next !== void 0) {
187
+ withStrings += ch + next;
188
+ code += blank(ch) + blank(next);
189
+ index += 1;
190
+ continue;
191
+ }
192
+ if (state === "string" && ch === '"' || state === "char" && ch === "'" || ch === "\n") {
193
+ state = "code";
194
+ withStrings += ch;
195
+ code += blank(ch);
196
+ continue;
197
+ }
198
+ withStrings += ch;
199
+ code += blank(ch);
200
+ }
201
+ return { withStrings, code };
202
+ }
203
+ function hasCppInclude(withStrings) {
204
+ for (const match of withStrings.matchAll(/^[ \t]*#[ \t]*include[ \t]*([<"])([^>"\n]+)[>"]/gm)) {
205
+ const delimiter = match[1];
206
+ const target = match[2]?.trim() ?? "";
207
+ if (/\.(?:hpp|hh|hxx|cuh)$/.test(target)) return true;
208
+ if (delimiter === "<" && CPP_ONLY_STD_INCLUDES.has(target)) return true;
209
+ }
210
+ return false;
211
+ }
212
+ function hasCppMemberDeclaration(code) {
213
+ for (const match of code.matchAll(/\b(?:class|struct)\s+[A-Za-z_]\w*[^;{]*\{([\s\S]*?)\}/g)) {
214
+ const body = match[1] ?? "";
215
+ for (const rawStatement of body.split(";")) {
216
+ const statement = rawStatement.trim();
217
+ if (statement.length === 0 || /\(\s*[*&]/.test(statement)) continue;
218
+ const member = /(?:^|\s)(operator\s*[^\s(]+|~?[A-Za-z_]\w*)\s*\([^{};]*\)\s*(?:const\b|noexcept\b|override\b|final\b|=\s*0\s*)*$/.exec(
219
+ statement
220
+ );
221
+ if (!member) continue;
222
+ const name = member[1] ?? "";
223
+ const prefix = statement.slice(0, member.index);
224
+ if (prefix.includes("[") || /^[_A-Z][_A-Z0-9]*$/.test(name)) continue;
225
+ return true;
226
+ }
227
+ }
228
+ return false;
229
+ }
230
+ function classifyCHeaderLanguage(text) {
231
+ const { withStrings, code } = stripForScan(text);
232
+ if (hasCppInclude(withStrings)) return "c++";
233
+ if (hasCppMemberDeclaration(code)) return "c++";
234
+ for (const pattern of CPP_SYNTAX_PATTERNS) {
235
+ if (pattern.test(code)) return "c++";
236
+ }
237
+ return "c";
238
+ }
239
+
240
+ // src/core/workspace-files.ts
241
+ import { execFile, execFileSync } from "node:child_process";
242
+ import fs from "node:fs";
243
+ import { join, sep } from "node:path";
244
+ import { performance as performance2 } from "node:perf_hooks";
245
+ var DEFAULT_YIELD_BUDGET_MS = 8;
246
+ function createDefaultTick(budgetMs = DEFAULT_YIELD_BUDGET_MS) {
247
+ let sliceStart = performance2.now();
248
+ return {
249
+ async tick() {
250
+ if (performance2.now() - sliceStart < budgetMs) return;
251
+ await new Promise((resolve2) => {
252
+ setImmediate(resolve2);
253
+ });
254
+ sliceStart = performance2.now();
255
+ }
256
+ };
257
+ }
258
+ var GIT_OUTPUT_LIMIT_BYTES = 128 * 1024 * 1024;
259
+ var MAX_ENUMERATION_DIAGNOSTIC_PATH_CHARS = 200;
260
+ var DEFAULT_WORKSPACE_FALLBACK_LIMITS = Object.freeze({
261
+ maxVisitedEntries: 1e5,
262
+ maxDepth: 64,
263
+ maxPathBytes: 64 * 1024 * 1024,
264
+ maxDurationMs: 5e3
265
+ });
266
+ var WorkspaceEnumerationLimitError = class extends Error {
267
+ constructor(kind, limit) {
268
+ super(`non-Git workspace enumeration exceeded ${kind} limit (${limit})`);
269
+ this.kind = kind;
270
+ this.limit = limit;
271
+ this.name = "WorkspaceEnumerationLimitError";
272
+ }
273
+ kind;
274
+ limit;
275
+ code = "WORKSPACE_ENUMERATION_LIMIT";
276
+ };
277
+ function boundedDiagnosticPath(path) {
278
+ const printable = Array.from(path.length > 0 ? path : ".", (character) => {
279
+ const codePoint = character.codePointAt(0) ?? 0;
280
+ return codePoint <= 31 || codePoint >= 127 && codePoint <= 159 ? "?" : character;
281
+ });
282
+ if (printable.length <= MAX_ENUMERATION_DIAGNOSTIC_PATH_CHARS) return printable.join("");
283
+ const side = Math.floor((MAX_ENUMERATION_DIAGNOSTIC_PATH_CHARS - 1) / 2);
284
+ return `${printable.slice(0, side).join("")}\u2026${printable.slice(-side).join("")}`;
285
+ }
286
+ function boundedSystemErrorCode(cause) {
287
+ if (typeof cause !== "object" || cause === null || !("code" in cause)) return "UNKNOWN";
288
+ const code = cause.code;
289
+ return typeof code === "string" && /^[A-Z][A-Z0-9_]{0,31}$/.test(code) ? code : "UNKNOWN";
290
+ }
291
+ var ENUMERATION_OPERATION_LABELS = Object.freeze({
292
+ "open-root": "open the workspace root",
293
+ "read-directory": "read a workspace directory",
294
+ "open-directory": "open a workspace directory",
295
+ "inspect-entry": "inspect a workspace entry"
296
+ });
297
+ var WorkspaceEnumerationIncompleteError = class extends Error {
298
+ code = "WORKSPACE_ENUMERATION_INCOMPLETE";
299
+ operation;
300
+ path;
301
+ causeCode;
302
+ constructor(operation, path, cause) {
303
+ const diagnosticPath = boundedDiagnosticPath(path);
304
+ const causeCode = boundedSystemErrorCode(cause);
305
+ super(
306
+ `non-Git workspace enumeration could not ${ENUMERATION_OPERATION_LABELS[operation]} at '${diagnosticPath}' (${causeCode})`
307
+ );
308
+ this.name = "WorkspaceEnumerationIncompleteError";
309
+ this.operation = operation;
310
+ this.path = diagnosticPath;
311
+ this.causeCode = causeCode;
312
+ }
313
+ };
314
+ var WORKSPACE_EXCLUDED_DIRS = /* @__PURE__ */ new Set([
315
+ ".git",
316
+ ".hg",
317
+ ".svn",
318
+ ".clio-coder",
319
+ "node_modules",
320
+ "dist",
321
+ "build",
322
+ "coverage",
323
+ ".venv",
324
+ "venv",
325
+ "__pycache__",
326
+ "target",
327
+ "vendor",
328
+ ".superpowers",
329
+ ".codex",
330
+ ".claude",
331
+ ".clio-coder-benchmark"
332
+ ]);
333
+ function comparePaths(a, b) {
334
+ return a === b ? 0 : a < b ? -1 : 1;
335
+ }
336
+ function normalizeRelativePath(path) {
337
+ const posixPath = sep === "\\" ? path.replaceAll("\\", "/") : path;
338
+ const normalized = posixPath.replace(/^\.\//, "");
339
+ if (normalized.length === 0 || normalized.includes("\0") || normalized.startsWith("/")) return null;
340
+ if (/^[A-Za-z]:\//.test(normalized)) return null;
341
+ const segments = normalized.split("/");
342
+ if (segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) return null;
343
+ return segments.join("/");
344
+ }
345
+ function isWorkspacePathExcluded(relPath, excludedDirs = WORKSPACE_EXCLUDED_DIRS) {
346
+ return relPath.split("/").some((segment) => excludedDirs.has(segment));
347
+ }
348
+ function isDisappearedWorkspaceEntry(cause) {
349
+ if (typeof cause !== "object" || cause === null || !("code" in cause)) return false;
350
+ const code = cause.code;
351
+ return code === "ENOENT" || code === "ENOTDIR";
352
+ }
353
+ function isRegularWorkspaceFile(cwd, relPath, requireCompleteSnapshot) {
354
+ try {
355
+ const stat = fs.lstatSync(join(cwd, relPath));
356
+ if (stat.isFile()) return true;
357
+ if (requireCompleteSnapshot && stat.isDirectory()) {
358
+ throw new WorkspaceEnumerationIncompleteError("inspect-entry", relPath, { code: "ENTRY_TYPE_CHANGED" });
359
+ }
360
+ return false;
361
+ } catch (cause) {
362
+ if (cause instanceof WorkspaceEnumerationIncompleteError) throw cause;
363
+ if (requireCompleteSnapshot) {
364
+ if (isDisappearedWorkspaceEntry(cause)) return false;
365
+ throw new WorkspaceEnumerationIncompleteError("inspect-entry", relPath, cause);
366
+ }
367
+ return false;
368
+ }
369
+ }
370
+ function gitVisibleFilesArgs(candidates) {
371
+ const args = ["--literal-pathspecs", "ls-files", "-z", "--cached", "--others", "--exclude-standard"];
372
+ if (candidates) args.push("--", ...candidates);
373
+ return args;
374
+ }
375
+ function splitGitPathOutput(output) {
376
+ return output.split("\0").filter((path) => path.length > 0);
377
+ }
378
+ function gitVisibleFiles(cwd, candidates) {
379
+ let output;
380
+ try {
381
+ output = execFileSync("git", gitVisibleFilesArgs(candidates), {
382
+ cwd,
383
+ maxBuffer: GIT_OUTPUT_LIMIT_BYTES,
384
+ stdio: ["ignore", "pipe", "ignore"]
385
+ });
386
+ } catch {
387
+ return null;
388
+ }
389
+ return splitGitPathOutput(output.toString("utf8"));
390
+ }
391
+ function gitVisibleFilesAsync(cwd, candidates) {
392
+ return new Promise((resolve2) => {
393
+ execFile("git", gitVisibleFilesArgs(candidates), { cwd, maxBuffer: GIT_OUTPUT_LIMIT_BYTES }, (error, stdout) => {
394
+ resolve2(error ? null : splitGitPathOutput(stdout));
395
+ });
396
+ });
397
+ }
398
+ function resolveFallbackLimits(overrides) {
399
+ const limits = { ...DEFAULT_WORKSPACE_FALLBACK_LIMITS, ...overrides };
400
+ for (const [name, value] of Object.entries(limits)) {
401
+ if (!Number.isFinite(value) || value < 0 || !Number.isInteger(value)) {
402
+ throw new RangeError(`workspace fallback ${name} must be a non-negative integer`);
403
+ }
404
+ }
405
+ return limits;
406
+ }
407
+ function fallbackEntryKind(absPath, relPath, entry) {
408
+ if (!entry) return "disappeared";
409
+ if (entry.isDirectory()) return "directory";
410
+ if (entry.isFile()) return "file";
411
+ try {
412
+ const stat = fs.lstatSync(absPath);
413
+ if (stat.isDirectory()) return "directory";
414
+ if (stat.isFile()) return "file";
415
+ return "other";
416
+ } catch (cause) {
417
+ if (isDisappearedWorkspaceEntry(cause)) return "disappeared";
418
+ throw new WorkspaceEnumerationIncompleteError("inspect-entry", relPath, cause);
419
+ }
420
+ }
421
+ function closeFrame(frame) {
422
+ try {
423
+ frame.dir.closeSync();
424
+ } catch {
425
+ }
426
+ }
427
+ function* fallbackFilesWalk(cwd, excludedDirs, limits, elapsedMs) {
428
+ let visitedEntries = 0;
429
+ let pathBytes = 0;
430
+ let root;
431
+ try {
432
+ root = fs.opendirSync(cwd);
433
+ } catch (cause) {
434
+ throw new WorkspaceEnumerationIncompleteError("open-root", ".", cause);
435
+ }
436
+ const stack = [{ dir: root, absPath: cwd, prefix: "", depth: 0 }];
437
+ const files = [];
438
+ try {
439
+ while (stack.length > 0) {
440
+ yield;
441
+ if (elapsedMs() >= limits.maxDurationMs) {
442
+ throw new WorkspaceEnumerationLimitError("time", limits.maxDurationMs);
443
+ }
444
+ const frame = stack.at(-1);
445
+ if (!frame) break;
446
+ let entry;
447
+ try {
448
+ entry = frame.dir.readSync();
449
+ } catch (cause) {
450
+ throw new WorkspaceEnumerationIncompleteError("read-directory", frame.prefix || ".", cause);
451
+ }
452
+ if (!entry) {
453
+ closeFrame(frame);
454
+ stack.pop();
455
+ continue;
456
+ }
457
+ visitedEntries += 1;
458
+ if (visitedEntries > limits.maxVisitedEntries) {
459
+ throw new WorkspaceEnumerationLimitError("entries", limits.maxVisitedEntries);
460
+ }
461
+ const depth = frame.depth + 1;
462
+ if (depth > limits.maxDepth) {
463
+ throw new WorkspaceEnumerationLimitError("depth", limits.maxDepth);
464
+ }
465
+ const relPath = frame.prefix.length > 0 ? `${frame.prefix}/${entry.name}` : entry.name;
466
+ pathBytes += Buffer.byteLength(relPath, "utf8");
467
+ if (pathBytes > limits.maxPathBytes) {
468
+ throw new WorkspaceEnumerationLimitError("path-bytes", limits.maxPathBytes);
469
+ }
470
+ const absPath = join(frame.absPath, entry.name);
471
+ const kind = fallbackEntryKind(absPath, relPath, entry);
472
+ if (kind === "disappeared" || kind === "other") continue;
473
+ if (kind === "directory") {
474
+ if (excludedDirs.has(entry.name)) continue;
475
+ let child;
476
+ try {
477
+ child = fs.opendirSync(absPath);
478
+ } catch (cause) {
479
+ if (isDisappearedWorkspaceEntry(cause)) continue;
480
+ throw new WorkspaceEnumerationIncompleteError("open-directory", relPath, cause);
481
+ }
482
+ stack.push({ dir: child, absPath, prefix: relPath, depth });
483
+ continue;
484
+ }
485
+ files.push(relPath);
486
+ }
487
+ return files;
488
+ } finally {
489
+ for (const frame of stack) closeFrame(frame);
490
+ }
491
+ }
492
+ function fallbackFiles(cwd, excludedDirs, overrides) {
493
+ const limits = resolveFallbackLimits(overrides);
494
+ const startedAt = performance2.now();
495
+ const walk = fallbackFilesWalk(cwd, excludedDirs, limits, () => performance2.now() - startedAt);
496
+ let step = walk.next();
497
+ while (!step.done) step = walk.next();
498
+ return step.value;
499
+ }
500
+ async function fallbackFilesAsync(cwd, excludedDirs, overrides, cooperate) {
501
+ const limits = resolveFallbackLimits(overrides);
502
+ let activeMs = 0;
503
+ let resumedAt = performance2.now();
504
+ const walk = fallbackFilesWalk(cwd, excludedDirs, limits, () => activeMs + (performance2.now() - resumedAt));
505
+ let step = walk.next();
506
+ while (!step.done) {
507
+ activeMs += performance2.now() - resumedAt;
508
+ await cooperate.tick();
509
+ resumedAt = performance2.now();
510
+ step = walk.next();
511
+ }
512
+ return step.value;
513
+ }
514
+ function* normalizeVisibleFilesSteps(cwd, paths, excludedDirs, requireCompleteSnapshot) {
515
+ const visible = /* @__PURE__ */ new Set();
516
+ for (const path of paths) {
517
+ yield;
518
+ const normalized = normalizeRelativePath(path);
519
+ if (!normalized) {
520
+ if (requireCompleteSnapshot) {
521
+ throw new WorkspaceEnumerationIncompleteError("inspect-entry", path, { code: "INVALID_RELATIVE_PATH" });
522
+ }
523
+ continue;
524
+ }
525
+ if (isWorkspacePathExcluded(normalized, excludedDirs)) continue;
526
+ if (isRegularWorkspaceFile(cwd, normalized, requireCompleteSnapshot)) visible.add(normalized);
527
+ }
528
+ return [...visible].sort(comparePaths);
529
+ }
530
+ function normalizeVisibleFiles(cwd, paths, excludedDirs, requireCompleteSnapshot = false) {
531
+ const steps = normalizeVisibleFilesSteps(cwd, paths, excludedDirs, requireCompleteSnapshot);
532
+ let step = steps.next();
533
+ while (!step.done) step = steps.next();
534
+ return step.value;
535
+ }
536
+ async function normalizeVisibleFilesAsync(cwd, paths, excludedDirs, requireCompleteSnapshot, cooperate) {
537
+ const steps = normalizeVisibleFilesSteps(cwd, paths, excludedDirs, requireCompleteSnapshot);
538
+ let step = steps.next();
539
+ while (!step.done) {
540
+ await cooperate.tick();
541
+ step = steps.next();
542
+ }
543
+ return step.value;
544
+ }
545
+ function enumerateWorkspaceFiles(cwd, excludedDirs = WORKSPACE_EXCLUDED_DIRS, fallbackLimits) {
546
+ const gitFiles = gitVisibleFiles(cwd);
547
+ if (gitFiles) return normalizeVisibleFiles(cwd, gitFiles, excludedDirs);
548
+ return normalizeVisibleFiles(cwd, fallbackFiles(cwd, excludedDirs, fallbackLimits), excludedDirs, true);
549
+ }
550
+ async function enumerateWorkspaceFilesAsync(cwd, excludedDirs = WORKSPACE_EXCLUDED_DIRS, fallbackLimits, cooperate = createDefaultTick()) {
551
+ const gitFiles = await gitVisibleFilesAsync(cwd);
552
+ if (gitFiles) return normalizeVisibleFilesAsync(cwd, gitFiles, excludedDirs, false, cooperate);
553
+ const walked = await fallbackFilesAsync(cwd, excludedDirs, fallbackLimits, cooperate);
554
+ return normalizeVisibleFilesAsync(cwd, walked, excludedDirs, true, cooperate);
555
+ }
556
+ function filterWorkspaceFileCandidates(cwd, paths, excludedDirs = WORKSPACE_EXCLUDED_DIRS, fallbackLimits) {
557
+ const candidates = paths.map(normalizeRelativePath).filter((path) => path !== null && !isWorkspacePathExcluded(path, excludedDirs));
558
+ if (candidates.length === 0) return [];
559
+ const gitFiles = gitVisibleFiles(cwd, candidates);
560
+ if (gitFiles) return normalizeVisibleFiles(cwd, gitFiles, excludedDirs);
561
+ const fallbackVisible = new Set(
562
+ normalizeVisibleFiles(cwd, fallbackFiles(cwd, excludedDirs, fallbackLimits), excludedDirs, true)
563
+ );
564
+ return candidates.filter((path) => fallbackVisible.has(path)).sort(comparePaths);
565
+ }
566
+
567
+ // src/domains/session/workspace/project-type.ts
568
+ var SOURCE_LANGUAGES = [
569
+ "typescript",
570
+ "javascript",
571
+ "python",
572
+ "rust",
573
+ "go",
574
+ "c",
575
+ "c++",
576
+ "java",
577
+ "ruby",
578
+ "c#"
579
+ ];
580
+ var EXTENSION_LANGUAGES = /* @__PURE__ */ new Map([
581
+ [".ts", "typescript"],
582
+ [".tsx", "typescript"],
583
+ [".mts", "typescript"],
584
+ [".cts", "typescript"],
585
+ [".js", "javascript"],
586
+ [".jsx", "javascript"],
587
+ [".mjs", "javascript"],
588
+ [".cjs", "javascript"],
589
+ [".py", "python"],
590
+ [".pyw", "python"],
591
+ [".rs", "rust"],
592
+ [".go", "go"],
593
+ [".c", "c"],
594
+ [".h", "c"],
595
+ [".cc", "c++"],
596
+ [".cpp", "c++"],
597
+ [".cxx", "c++"],
598
+ [".hpp", "c++"],
599
+ [".hh", "c++"],
600
+ [".hxx", "c++"],
601
+ [".cu", "c++"],
602
+ [".cuh", "c++"],
603
+ [".java", "java"],
604
+ [".rb", "ruby"],
605
+ [".cs", "c#"]
606
+ ]);
607
+ var MANIFEST_LANGUAGES = [
608
+ { name: "package.json", type: "typescript" },
609
+ { name: "pyproject.toml", type: "python" },
610
+ { name: "setup.py", type: "python" },
611
+ { name: "Cargo.toml", type: "rust" },
612
+ { name: "go.mod", type: "go" },
613
+ { name: "pom.xml", type: "java" },
614
+ { name: "CMakeLists.txt", type: "c++" },
615
+ { name: "compile_commands.json", type: "c++" },
616
+ { name: "Gemfile", type: "ruby" },
617
+ { name: "*.csproj", type: "c#" }
618
+ ];
619
+ function emptyLanguageCounts() {
620
+ return {
621
+ typescript: 0,
622
+ javascript: 0,
623
+ python: 0,
624
+ rust: 0,
625
+ go: 0,
626
+ c: 0,
627
+ "c++": 0,
628
+ java: 0,
629
+ ruby: 0,
630
+ "c#": 0
631
+ };
632
+ }
633
+ function extensionOf(name) {
634
+ const index = name.lastIndexOf(".");
635
+ return index === -1 ? "" : name.slice(index);
636
+ }
637
+ function countManifest(name, manifestCounts) {
638
+ for (const marker of MANIFEST_LANGUAGES) {
639
+ if (marker.name.startsWith("*.")) {
640
+ const ext = marker.name.slice(1);
641
+ if (name.endsWith(ext)) {
642
+ manifestCounts[marker.type] = (manifestCounts[marker.type] ?? 0) + 1;
643
+ }
644
+ } else {
645
+ if (name !== marker.name) continue;
646
+ manifestCounts[marker.type] = (manifestCounts[marker.type] ?? 0) + 1;
647
+ }
648
+ }
649
+ }
650
+ function scanFiles(cwd, files, languageCounts, manifestCounts) {
651
+ for (const path of files) {
652
+ const name = path.split("/").pop() ?? path;
653
+ countManifest(name, manifestCounts);
654
+ if (name.endsWith(".d.ts")) continue;
655
+ const extension = extensionOf(name);
656
+ let language = EXTENSION_LANGUAGES.get(extension);
657
+ if (extension === ".h") {
658
+ try {
659
+ language = classifyCHeaderLanguage(readFileSync(join2(cwd, path), "utf8"));
660
+ } catch {
661
+ language = "c";
662
+ }
663
+ }
664
+ if (language) languageCounts[language] += 1;
665
+ }
666
+ }
667
+ function looksLikeDotfiles(files) {
668
+ const dotDirs = /* @__PURE__ */ new Set();
669
+ for (const path of files) {
670
+ const [root, child] = path.split("/", 2);
671
+ if (child && root?.startsWith("dot-")) dotDirs.add(root);
672
+ }
673
+ return dotDirs.size >= 2;
674
+ }
675
+ function dominantFromCounts(counts) {
676
+ let best;
677
+ let bestCount = 0;
678
+ for (const language of SOURCE_LANGUAGES) {
679
+ const count = counts[language] ?? 0;
680
+ if (count > bestCount) {
681
+ best = language;
682
+ bestCount = count;
683
+ } else if (count === bestCount && count > 0) {
684
+ best = void 0;
685
+ }
686
+ }
687
+ return best;
688
+ }
689
+ function detectProjectProfile(cwd) {
690
+ const languageCounts = emptyLanguageCounts();
691
+ const manifestCounts = {};
692
+ const files = enumerateWorkspaceFiles(cwd);
693
+ scanFiles(cwd, files, languageCounts, manifestCounts);
694
+ const sourceFiles = SOURCE_LANGUAGES.reduce((sum, language) => sum + languageCounts[language], 0);
695
+ const dominantSource = dominantFromCounts(languageCounts);
696
+ const dominantCount = dominantSource ? languageCounts[dominantSource] : 0;
697
+ const polyglot = sourceFiles > 0 && dominantCount / sourceFiles <= 0.7;
698
+ if (sourceFiles > 0) {
699
+ return {
700
+ projectType: polyglot ? "polyglot" : dominantSource ?? "polyglot",
701
+ sourceFiles,
702
+ languageCounts,
703
+ manifestCounts,
704
+ ...dominantSource ? { dominantLanguage: dominantSource } : {},
705
+ polyglot
706
+ };
707
+ }
708
+ const manifestDominant = dominantFromCounts(manifestCounts);
709
+ if (manifestDominant) {
710
+ return {
711
+ projectType: manifestDominant,
712
+ sourceFiles,
713
+ languageCounts,
714
+ manifestCounts,
715
+ dominantLanguage: manifestDominant,
716
+ polyglot: false
717
+ };
718
+ }
719
+ const manifestTotal = SOURCE_LANGUAGES.reduce((sum, language) => sum + (manifestCounts[language] ?? 0), 0);
720
+ if (manifestTotal > 0) {
721
+ return {
722
+ projectType: "polyglot",
723
+ sourceFiles,
724
+ languageCounts,
725
+ manifestCounts,
726
+ polyglot: true
727
+ };
728
+ }
729
+ return {
730
+ projectType: looksLikeDotfiles(files) ? "dotfiles" : "unknown",
731
+ sourceFiles,
732
+ languageCounts,
733
+ manifestCounts,
734
+ polyglot: false
735
+ };
736
+ }
737
+ function detectProjectType(cwd) {
738
+ return detectProjectProfile(cwd).projectType;
739
+ }
740
+
741
+ // src/domains/context/codewiki/cooperative.ts
742
+ import { setImmediate as yieldToEventLoop } from "node:timers/promises";
743
+ var INDEX_SLICE_MS = 8;
744
+ var settled = Promise.resolve();
745
+ function createSlicer(sliceMs = INDEX_SLICE_MS) {
746
+ let deadline = performance.now() + sliceMs;
747
+ let yields = 0;
748
+ return {
749
+ tick() {
750
+ if (performance.now() < deadline) return settled;
751
+ yields += 1;
752
+ return yieldToEventLoop().then(() => {
753
+ deadline = performance.now() + sliceMs;
754
+ });
755
+ },
756
+ get yields() {
757
+ return yields;
758
+ }
759
+ };
760
+ }
761
+
762
+ // src/domains/context/codewiki/indexer.ts
763
+ import { createHash } from "node:crypto";
764
+ import { existsSync, readFileSync as readFileSync2, statSync } from "node:fs";
765
+ import { readFile as readFileAsync } from "node:fs/promises";
766
+ import { dirname as dirname2, join as join4, relative, resolve } from "node:path";
767
+
768
+ // src/domains/context/codewiki/cmake.ts
769
+ var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
770
+ ".c",
771
+ ".cc",
772
+ ".cpp",
773
+ ".cxx",
774
+ ".cu",
775
+ ".cuh",
776
+ ".h",
777
+ ".hh",
778
+ ".hpp",
779
+ ".hxx",
780
+ ".java",
781
+ ".js",
782
+ ".jsx",
783
+ ".mjs",
784
+ ".cjs",
785
+ ".mts",
786
+ ".cts",
787
+ ".py",
788
+ ".pyw",
789
+ ".rb",
790
+ ".rs",
791
+ ".cs",
792
+ ".ts",
793
+ ".tsx"
794
+ ]);
795
+ var TARGET_SOURCE_KEYWORDS = /* @__PURE__ */ new Set([
796
+ "PUBLIC",
797
+ "PRIVATE",
798
+ "INTERFACE",
799
+ "BEFORE",
800
+ "FILE_SET",
801
+ "TYPE",
802
+ "BASE_DIRS",
803
+ "FILES"
804
+ ]);
805
+ function compareStrings(a, b) {
806
+ return a.localeCompare(b);
807
+ }
808
+ function uniqueSorted(values) {
809
+ return [...new Set(values)].sort(compareStrings);
810
+ }
811
+ function lineStarts(text) {
812
+ const starts = [0];
813
+ for (let index = 0; index < text.length; index += 1) {
814
+ if (text[index] === "\n") starts.push(index + 1);
815
+ }
816
+ return starts;
817
+ }
818
+ function lineAt(starts, offset) {
819
+ let low = 0;
820
+ let high = starts.length;
821
+ while (low < high) {
822
+ const middle = Math.floor((low + high) / 2);
823
+ if ((starts[middle] ?? 0) <= offset) low = middle + 1;
824
+ else high = middle;
825
+ }
826
+ return Math.max(1, low);
827
+ }
828
+ function readBracketBlock(text, index) {
829
+ if (text[index] !== "[") return null;
830
+ let delimiterEnd = index + 1;
831
+ while (text[delimiterEnd] === "=") delimiterEnd += 1;
832
+ if (text[delimiterEnd] !== "[") return null;
833
+ const equals = text.slice(index + 1, delimiterEnd);
834
+ const close = `]${equals}]`;
835
+ const contentStart = delimiterEnd + 1;
836
+ const closeStart = text.indexOf(close, contentStart);
837
+ if (closeStart === -1) return null;
838
+ return {
839
+ content: text.slice(contentStart, closeStart),
840
+ end: closeStart + close.length
841
+ };
842
+ }
843
+ function skipComment(text, index) {
844
+ const bracket = readBracketBlock(text, index + 1);
845
+ if (bracket) return bracket.end;
846
+ const newline = text.indexOf("\n", index + 1);
847
+ return newline === -1 ? text.length : newline + 1;
848
+ }
849
+ function skipTrivia(text, start) {
850
+ let index = start;
851
+ while (index < text.length) {
852
+ if (/\s/.test(text[index] ?? "")) {
853
+ index += 1;
854
+ continue;
855
+ }
856
+ if (text[index] === "#") {
857
+ index = skipComment(text, index);
858
+ continue;
859
+ }
860
+ break;
861
+ }
862
+ return index;
863
+ }
864
+ function readQuotedArgument(text, start) {
865
+ let content = "";
866
+ for (let index = start + 1; index < text.length; index += 1) {
867
+ const current = text[index] ?? "";
868
+ if (current === '"') return { content, end: index + 1 };
869
+ if (current === "\\") {
870
+ const next = text[index + 1];
871
+ if (next === void 0) return null;
872
+ if (next === "\n") {
873
+ index += 1;
874
+ continue;
875
+ }
876
+ content += next;
877
+ index += 1;
878
+ continue;
879
+ }
880
+ content += current;
881
+ }
882
+ return null;
883
+ }
884
+ function parseInvocation(text, name, line2, openParen) {
885
+ const args = [];
886
+ let current = "";
887
+ let depth = 1;
888
+ let index = openParen + 1;
889
+ const flush = () => {
890
+ if (current.length > 0) args.push(current);
891
+ current = "";
892
+ };
893
+ while (index < text.length) {
894
+ const char = text[index] ?? "";
895
+ if (/\s/.test(char)) {
896
+ flush();
897
+ index += 1;
898
+ continue;
899
+ }
900
+ if (char === "#") {
901
+ flush();
902
+ index = skipComment(text, index);
903
+ continue;
904
+ }
905
+ if (char === '"') {
906
+ const quoted = readQuotedArgument(text, index);
907
+ if (!quoted) return null;
908
+ current += quoted.content;
909
+ index = quoted.end;
910
+ continue;
911
+ }
912
+ if (char === "[") {
913
+ const bracket = readBracketBlock(text, index);
914
+ if (bracket) {
915
+ current += bracket.content;
916
+ index = bracket.end;
917
+ continue;
918
+ }
919
+ }
920
+ if (char === "\\") {
921
+ const next = text[index + 1];
922
+ if (next === void 0) return null;
923
+ if (next === "\n") {
924
+ index += 2;
925
+ continue;
926
+ }
927
+ current += next;
928
+ index += 2;
929
+ continue;
930
+ }
931
+ if (char === ";" && depth === 1) {
932
+ flush();
933
+ index += 1;
934
+ continue;
935
+ }
936
+ if (char === "(") {
937
+ depth += 1;
938
+ current += char;
939
+ index += 1;
940
+ continue;
941
+ }
942
+ if (char === ")") {
943
+ depth -= 1;
944
+ if (depth === 0) {
945
+ flush();
946
+ return {
947
+ invocation: { name, line: line2, args },
948
+ end: index + 1
949
+ };
950
+ }
951
+ current += char;
952
+ index += 1;
953
+ continue;
954
+ }
955
+ current += char;
956
+ index += 1;
957
+ }
958
+ return null;
959
+ }
960
+ function scanInvocations(text) {
961
+ const invocations = [];
962
+ const starts = lineStarts(text);
963
+ let index = 0;
964
+ while (index < text.length) {
965
+ index = skipTrivia(text, index);
966
+ if (index >= text.length) break;
967
+ if (text[index] === '"') {
968
+ const quoted = readQuotedArgument(text, index);
969
+ index = quoted?.end ?? text.length;
970
+ continue;
971
+ }
972
+ if (text[index] === "[") {
973
+ const bracket = readBracketBlock(text, index);
974
+ if (bracket) {
975
+ index = bracket.end;
976
+ continue;
977
+ }
978
+ }
979
+ const name = /^[A-Za-z_][A-Za-z_0-9]*/.exec(text.slice(index))?.[0];
980
+ if (!name) {
981
+ index += 1;
982
+ continue;
983
+ }
984
+ const nameStart = index;
985
+ const openParen = skipTrivia(text, index + name.length);
986
+ if (text[openParen] !== "(") {
987
+ index += name.length;
988
+ continue;
989
+ }
990
+ const parsed = parseInvocation(text, name.toLowerCase(), lineAt(starts, nameStart), openParen);
991
+ if (!parsed) {
992
+ index = openParen + 1;
993
+ continue;
994
+ }
995
+ invocations.push(parsed.invocation);
996
+ index = parsed.end;
997
+ }
998
+ return invocations;
999
+ }
1000
+ function literal(value) {
1001
+ if (!value) return null;
1002
+ const trimmed = value.trim();
1003
+ if (trimmed.length === 0 || trimmed.includes("$")) return null;
1004
+ return trimmed.replace(/\\/g, "/");
1005
+ }
1006
+ function literalTarget(value) {
1007
+ const target = literal(value);
1008
+ return target && /^[A-Za-z0-9_.:+-]+$/.test(target) ? target : null;
1009
+ }
1010
+ function relativeSpecifier(value) {
1011
+ if (value.startsWith("/") || /^[A-Za-z]:\//.test(value)) return null;
1012
+ const normalized = value.replace(/^\.\//, "").replace(/\/+$/g, "");
1013
+ if (normalized.length === 0) return null;
1014
+ return normalized.startsWith(".") ? normalized : `./${normalized}`;
1015
+ }
1016
+ function sourceSpecifier(value) {
1017
+ const path = literal(value);
1018
+ if (!path || path.includes(";") || path.startsWith("-") || TARGET_SOURCE_KEYWORDS.has(path.toUpperCase())) return null;
1019
+ const withoutQuery = path.split(/[?#]/, 1)[0] ?? path;
1020
+ const dot = withoutQuery.lastIndexOf(".");
1021
+ if (dot === -1 || !SOURCE_EXTENSIONS.has(withoutQuery.slice(dot).toLowerCase())) return null;
1022
+ return relativeSpecifier(path);
1023
+ }
1024
+ function childCMakeSpecifier(value) {
1025
+ const directory = literal(value);
1026
+ if (!directory) return null;
1027
+ const relative2 = relativeSpecifier(directory);
1028
+ if (!relative2) return null;
1029
+ return `${relative2}/CMakeLists.txt`.replace(/\/\//g, "/");
1030
+ }
1031
+ function isCMakePath(path) {
1032
+ const name = path.split("/").at(-1) ?? path;
1033
+ return name === "CMakeLists.txt" || name.toLowerCase().endsWith(".cmake");
1034
+ }
1035
+ function extractCMake(text) {
1036
+ const symbols = [];
1037
+ const imports = [];
1038
+ for (const invocation of scanInvocations(text)) {
1039
+ if (invocation.name === "add_subdirectory") {
1040
+ const child = childCMakeSpecifier(invocation.args[0]);
1041
+ if (child) imports.push(child);
1042
+ continue;
1043
+ }
1044
+ if (invocation.name === "add_library" || invocation.name === "add_executable") {
1045
+ const target = literalTarget(invocation.args[0]);
1046
+ if (!target) continue;
1047
+ symbols.push({ name: target, kind: "const", line: invocation.line });
1048
+ if (invocation.args[1]?.toUpperCase() === "ALIAS") continue;
1049
+ for (const arg of invocation.args.slice(1)) {
1050
+ const source = sourceSpecifier(arg);
1051
+ if (source) imports.push(source);
1052
+ }
1053
+ continue;
1054
+ }
1055
+ if (invocation.name === "target_sources") {
1056
+ if (!literalTarget(invocation.args[0])) continue;
1057
+ for (const arg of invocation.args.slice(1)) {
1058
+ const source = sourceSpecifier(arg);
1059
+ if (source) imports.push(source);
1060
+ }
1061
+ }
1062
+ }
1063
+ return {
1064
+ symbols: symbols.sort((a, b) => a.line - b.line || a.name.localeCompare(b.name)),
1065
+ imports: uniqueSorted(imports)
1066
+ };
1067
+ }
1068
+
1069
+ // src/domains/context/codewiki/tree-sitter.ts
1070
+ import { createRequire } from "node:module";
1071
+ import { dirname, join as join3 } from "node:path";
1072
+ import TreeSitter from "@vscode/tree-sitter-wasm";
1073
+ var require2 = createRequire(import.meta.url);
1074
+ var { Language, Parser } = TreeSitter;
1075
+ var VSCODE_WASM_DIR = dirname(require2.resolve("@vscode/tree-sitter-wasm"));
1076
+ var WASM_BY_GRAMMAR = {
1077
+ typescript: join3(VSCODE_WASM_DIR, "tree-sitter-typescript.wasm"),
1078
+ tsx: join3(VSCODE_WASM_DIR, "tree-sitter-tsx.wasm"),
1079
+ javascript: join3(VSCODE_WASM_DIR, "tree-sitter-javascript.wasm"),
1080
+ python: join3(VSCODE_WASM_DIR, "tree-sitter-python.wasm"),
1081
+ go: join3(VSCODE_WASM_DIR, "tree-sitter-go.wasm"),
1082
+ rust: join3(VSCODE_WASM_DIR, "tree-sitter-rust.wasm"),
1083
+ // VS Code does not currently ship a C grammar; its runtime accepts this
1084
+ // ABI-compatible compact C side module from tree-sitter-wasms.
1085
+ c: require2.resolve("tree-sitter-wasms/out/tree-sitter-c.wasm"),
1086
+ cpp: join3(VSCODE_WASM_DIR, "tree-sitter-cpp.wasm"),
1087
+ java: join3(VSCODE_WASM_DIR, "tree-sitter-java.wasm"),
1088
+ ruby: join3(VSCODE_WASM_DIR, "tree-sitter-ruby.wasm"),
1089
+ c_sharp: join3(VSCODE_WASM_DIR, "tree-sitter-c-sharp.wasm")
1090
+ };
1091
+ var NAME_NODE_TYPES = /* @__PURE__ */ new Set([
1092
+ "identifier",
1093
+ "type_identifier",
1094
+ "property_identifier",
1095
+ "field_identifier",
1096
+ "constant",
1097
+ "constant_identifier"
1098
+ ]);
1099
+ var FUNCTION_LIKE_NODE_TYPES = /* @__PURE__ */ new Set([
1100
+ "function_declaration",
1101
+ "function_expression",
1102
+ "generator_function",
1103
+ "generator_function_declaration",
1104
+ "generator_function_expression",
1105
+ "arrow_function",
1106
+ "method_definition",
1107
+ "function_definition",
1108
+ "function_item",
1109
+ "lambda",
1110
+ "lambda_expression",
1111
+ "func_literal",
1112
+ "method",
1113
+ "singleton_method",
1114
+ "do_block",
1115
+ "method_declaration",
1116
+ "constructor_declaration",
1117
+ "local_function_statement"
1118
+ ]);
1119
+ var PY_SCOPE_NODE_TYPES = /* @__PURE__ */ new Set(["function_definition", "class_definition"]);
1120
+ var parserInit = null;
1121
+ function ensureParserInit() {
1122
+ parserInit ??= Parser.init({
1123
+ locateFile() {
1124
+ return join3(VSCODE_WASM_DIR, "tree-sitter.wasm");
1125
+ }
1126
+ });
1127
+ return parserInit;
1128
+ }
1129
+ function grammarForPath(path, lang) {
1130
+ if (lang === "typescript") return path.endsWith(".tsx") ? "tsx" : "typescript";
1131
+ if (lang === "javascript") return "javascript";
1132
+ if (lang === "python") return "python";
1133
+ if (lang === "go") return "go";
1134
+ if (lang === "rust") return "rust";
1135
+ if (lang === "c") return "c";
1136
+ if (lang === "c++") return "cpp";
1137
+ if (lang === "java") return "java";
1138
+ if (lang === "ruby") return "ruby";
1139
+ if (lang === "c#") return "c_sharp";
1140
+ return null;
1141
+ }
1142
+ function line(node) {
1143
+ return node.startPosition.row + 1;
1144
+ }
1145
+ function sig(node) {
1146
+ return node.text.split(/\r?\n/, 1)[0]?.trim().slice(0, 240) ?? "";
1147
+ }
1148
+ function namedChildren(node) {
1149
+ return node.namedChildren.filter((child) => child !== null);
1150
+ }
1151
+ function firstNamedDescendant(node, types = NAME_NODE_TYPES) {
1152
+ if (types.has(node.type)) return node;
1153
+ for (const child of namedChildren(node)) {
1154
+ const found = firstNamedDescendant(child, types);
1155
+ if (found) return found;
1156
+ }
1157
+ return null;
1158
+ }
1159
+ function nameFromNode(node) {
1160
+ const direct = node.childForFieldName("name");
1161
+ if (direct) return firstNamedDescendant(direct)?.text ?? direct.text;
1162
+ for (const child of namedChildren(node)) {
1163
+ if (NAME_NODE_TYPES.has(child.type)) return child.text;
1164
+ }
1165
+ return firstNamedDescendant(node)?.text ?? null;
1166
+ }
1167
+ function hasAncestor(node, type) {
1168
+ let current = node.parent;
1169
+ while (current) {
1170
+ if (current.type === type) return true;
1171
+ current = current.parent;
1172
+ }
1173
+ return false;
1174
+ }
1175
+ function hasFunctionLikeAncestor(node) {
1176
+ let current = node.parent;
1177
+ while (current) {
1178
+ if (FUNCTION_LIKE_NODE_TYPES.has(current.type)) return true;
1179
+ current = current.parent;
1180
+ }
1181
+ return false;
1182
+ }
1183
+ function nearestAncestorType(node, types) {
1184
+ let current = node.parent;
1185
+ while (current) {
1186
+ if (types.has(current.type)) return current.type;
1187
+ current = current.parent;
1188
+ }
1189
+ return null;
1190
+ }
1191
+ function addSymbol(target, node, kind, name = nameFromNode(node)) {
1192
+ if (!name) return;
1193
+ const clean = name.trim();
1194
+ if (clean.length === 0) return;
1195
+ target.push({ name: clean, kind, line: line(node), sig: sig(node) });
1196
+ }
1197
+ function descendants(root, types) {
1198
+ return root.descendantsOfType(types).filter((node) => node !== null);
1199
+ }
1200
+ function compareStrings2(a, b) {
1201
+ return a.localeCompare(b);
1202
+ }
1203
+ function uniqueSorted2(values) {
1204
+ return [...new Set([...values].filter((value) => value.trim().length > 0))].sort(compareStrings2);
1205
+ }
1206
+ function cleanStringLiteral(value) {
1207
+ const trimmed = value.trim();
1208
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'") || trimmed.startsWith("`") && trimmed.endsWith("`") || trimmed.startsWith("<") && trimmed.endsWith(">")) {
1209
+ return trimmed.slice(1, -1);
1210
+ }
1211
+ return trimmed;
1212
+ }
1213
+ function stringValue(node) {
1214
+ if (!node) return null;
1215
+ const value = cleanStringLiteral(node.text);
1216
+ return value.length > 0 ? value : null;
1217
+ }
1218
+ function firstStringDescendant(node) {
1219
+ if (!node) return null;
1220
+ if (node.type === "string" || node.type === "string_literal" || node.type === "interpreted_string_literal" || node.type === "raw_string_literal" || node.type === "system_lib_string") {
1221
+ return node;
1222
+ }
1223
+ for (const child of namedChildren(node)) {
1224
+ const found = firstStringDescendant(child);
1225
+ if (found) return found;
1226
+ }
1227
+ return null;
1228
+ }
1229
+ function firstStringValue(node) {
1230
+ return stringValue(firstStringDescendant(node));
1231
+ }
1232
+ function extractTsJs(root) {
1233
+ const symbols = [];
1234
+ for (const node of descendants(root, ["function_declaration", "generator_function_declaration"])) {
1235
+ if (hasFunctionLikeAncestor(node)) continue;
1236
+ addSymbol(symbols, node, "func");
1237
+ }
1238
+ for (const node of descendants(root, "class_declaration")) {
1239
+ if (hasFunctionLikeAncestor(node)) continue;
1240
+ addSymbol(symbols, node, "class");
1241
+ }
1242
+ for (const node of descendants(root, "interface_declaration")) {
1243
+ if (hasFunctionLikeAncestor(node)) continue;
1244
+ addSymbol(symbols, node, "iface");
1245
+ }
1246
+ for (const node of descendants(root, ["type_alias_declaration", "enum_declaration"])) {
1247
+ if (hasFunctionLikeAncestor(node)) continue;
1248
+ addSymbol(symbols, node, "type");
1249
+ }
1250
+ for (const node of descendants(root, "method_definition")) {
1251
+ if (node.parent?.type !== "class_body") continue;
1252
+ if (hasFunctionLikeAncestor(node)) continue;
1253
+ addSymbol(symbols, node, "method");
1254
+ }
1255
+ for (const node of descendants(root, "variable_declarator")) {
1256
+ if (hasFunctionLikeAncestor(node)) continue;
1257
+ const parentText = node.parent?.text ?? "";
1258
+ addSymbol(symbols, node, parentText.trimStart().startsWith("const") ? "const" : "var");
1259
+ }
1260
+ return symbols;
1261
+ }
1262
+ function extractPython(root) {
1263
+ const symbols = [];
1264
+ for (const node of descendants(root, "function_definition")) {
1265
+ const scope = nearestAncestorType(node, PY_SCOPE_NODE_TYPES);
1266
+ if (scope === "function_definition") continue;
1267
+ addSymbol(symbols, node, scope === "class_definition" ? "method" : "func");
1268
+ }
1269
+ for (const node of descendants(root, "class_definition")) {
1270
+ if (hasFunctionLikeAncestor(node)) continue;
1271
+ addSymbol(symbols, node, "class");
1272
+ }
1273
+ for (const node of descendants(root, "assignment")) {
1274
+ if (hasFunctionLikeAncestor(node)) continue;
1275
+ const left = node.childForFieldName("left") ?? node.namedChild(0);
1276
+ if (!left) continue;
1277
+ const name = firstNamedDescendant(left)?.text;
1278
+ if (name) addSymbol(symbols, node, /^[A-Z][A-Z0-9_]*$/.test(name) ? "const" : "var", name);
1279
+ }
1280
+ return symbols;
1281
+ }
1282
+ function extractGo(root) {
1283
+ const symbols = [];
1284
+ for (const node of descendants(root, "function_declaration")) addSymbol(symbols, node, "func");
1285
+ for (const node of descendants(root, "method_declaration")) addSymbol(symbols, node, "method");
1286
+ for (const node of descendants(root, "type_spec")) {
1287
+ addSymbol(symbols, node, node.text.includes("interface") ? "iface" : "type");
1288
+ }
1289
+ for (const node of descendants(root, "const_spec")) {
1290
+ if (hasFunctionLikeAncestor(node)) continue;
1291
+ addSymbol(symbols, node, "const");
1292
+ }
1293
+ for (const node of descendants(root, "var_spec")) {
1294
+ if (hasFunctionLikeAncestor(node)) continue;
1295
+ addSymbol(symbols, node, "var");
1296
+ }
1297
+ return symbols;
1298
+ }
1299
+ function extractRust(root) {
1300
+ const symbols = [];
1301
+ for (const node of descendants(root, "function_item")) {
1302
+ if (hasFunctionLikeAncestor(node)) continue;
1303
+ const isMethod = hasAncestor(node, "impl_item") || hasAncestor(node, "trait_item");
1304
+ addSymbol(symbols, node, isMethod ? "method" : "func");
1305
+ }
1306
+ for (const node of descendants(root, ["struct_item", "enum_item", "type_item"])) addSymbol(symbols, node, "type");
1307
+ for (const node of descendants(root, "trait_item")) addSymbol(symbols, node, "trait");
1308
+ for (const node of descendants(root, "const_item")) addSymbol(symbols, node, "const");
1309
+ for (const node of descendants(root, "static_item")) addSymbol(symbols, node, "var");
1310
+ return symbols;
1311
+ }
1312
+ var C_FAMILY_CLASS_SCOPES = /* @__PURE__ */ new Set(["class_specifier", "struct_specifier", "union_specifier"]);
1313
+ function cFamilyDeclaredTypeName(node) {
1314
+ const name = node.childForFieldName("name");
1315
+ return name ? name.text.trim() || null : null;
1316
+ }
1317
+ function cFamilyDeclaratorName(node) {
1318
+ if (NAME_NODE_TYPES.has(node.type)) return node.text.trim() || null;
1319
+ const declarator = node.childForFieldName("declarator") ?? node.childForFieldName("name");
1320
+ if (declarator) return cFamilyDeclaratorName(declarator);
1321
+ if (node.type === "parenthesized_declarator" || node.type === "abstract_parenthesized_declarator" || node.type === "attributed_declarator") {
1322
+ for (const child of namedChildren(node)) {
1323
+ const name = cFamilyDeclaratorName(child);
1324
+ if (name) return name;
1325
+ }
1326
+ }
1327
+ return null;
1328
+ }
1329
+ function cFamilyDeclarators(node) {
1330
+ return node.childrenForFieldName("declarator").filter((child) => child !== null);
1331
+ }
1332
+ function uniqueCFamilySymbols(symbols) {
1333
+ const unique = /* @__PURE__ */ new Map();
1334
+ for (const symbol of symbols) {
1335
+ const key = `${symbol.name}\0${symbol.kind}\0${symbol.line}`;
1336
+ if (!unique.has(key)) unique.set(key, symbol);
1337
+ }
1338
+ return [...unique.values()];
1339
+ }
1340
+ function cFamilyFunctionDeclarator(node) {
1341
+ const declarator = node.childForFieldName("declarator");
1342
+ if (!declarator) return null;
1343
+ const candidates = [
1344
+ ...declarator.type === "function_declarator" ? [declarator] : [],
1345
+ ...declarator.descendantsOfType("function_declarator")
1346
+ ];
1347
+ for (let index = candidates.length - 1; index >= 0; index -= 1) {
1348
+ const candidate = candidates[index];
1349
+ const inner = candidate?.childForFieldName("declarator");
1350
+ if (inner && inner.type !== "parenthesized_declarator") return candidate ?? null;
1351
+ }
1352
+ return null;
1353
+ }
1354
+ function cFamilyFunctionName(node) {
1355
+ const fnDeclarator = cFamilyFunctionDeclarator(node);
1356
+ const inner = fnDeclarator?.childForFieldName("declarator");
1357
+ if (!inner) return null;
1358
+ let name = inner;
1359
+ while (name.type === "qualified_identifier") {
1360
+ const unqualified = name.childForFieldName("name");
1361
+ if (!unqualified) break;
1362
+ name = unqualified;
1363
+ }
1364
+ if (name.type === "template_function") name = name.childForFieldName("name") ?? name;
1365
+ return name.text;
1366
+ }
1367
+ function cFamilyFunctionQualifier(node) {
1368
+ const inner = cFamilyFunctionDeclarator(node)?.childForFieldName("declarator");
1369
+ if (inner?.type !== "qualified_identifier") return null;
1370
+ const parts = inner.text.split("::");
1371
+ parts.pop();
1372
+ return parts.join("::") || null;
1373
+ }
1374
+ function cFamilyQualifiedMethod(node, classNames, namespaceNames) {
1375
+ const qualifier = cFamilyFunctionQualifier(node);
1376
+ if (!qualifier) return false;
1377
+ const last = qualifier.split("::").at(-1) ?? qualifier;
1378
+ if (classNames.has(last)) return true;
1379
+ if (namespaceNames.has(last) || namespaceNames.has(qualifier)) return false;
1380
+ return /^[A-Z_]/.test(last);
1381
+ }
1382
+ function extractCFamily(root) {
1383
+ const symbols = [];
1384
+ const classNames = new Set(
1385
+ descendants(root, ["class_specifier", "struct_specifier", "union_specifier"]).map((node) => cFamilyDeclaredTypeName(node)).filter((name) => name !== null)
1386
+ );
1387
+ const namespaceNames = new Set(
1388
+ descendants(root, "namespace_definition").map((node) => nameFromNode(node)).filter((name) => name !== null)
1389
+ );
1390
+ for (const node of descendants(root, "function_definition")) {
1391
+ const kind = nearestAncestorType(node, C_FAMILY_CLASS_SCOPES) || cFamilyQualifiedMethod(node, classNames, namespaceNames) ? "method" : "func";
1392
+ addSymbol(symbols, node, kind, cFamilyFunctionName(node) ?? nameFromNode(node));
1393
+ }
1394
+ for (const node of descendants(root, ["declaration", "field_declaration"])) {
1395
+ if (hasFunctionLikeAncestor(node)) continue;
1396
+ const name = cFamilyFunctionName(node);
1397
+ if (!name) continue;
1398
+ const isTypedef = namedChildren(node).some(
1399
+ (child) => child.type === "storage_class_specifier" && child.text === "typedef"
1400
+ );
1401
+ const kind = isTypedef ? "type" : nearestAncestorType(node, C_FAMILY_CLASS_SCOPES) || cFamilyQualifiedMethod(node, classNames, namespaceNames) ? "method" : "func";
1402
+ addSymbol(symbols, node, kind, name);
1403
+ }
1404
+ for (const node of descendants(root, ["class_specifier", "struct_specifier", "union_specifier", "enum_specifier"])) {
1405
+ const name = cFamilyDeclaredTypeName(node);
1406
+ if (name) addSymbol(symbols, node, node.type === "class_specifier" ? "class" : "type", name);
1407
+ }
1408
+ for (const node of descendants(root, "type_definition")) {
1409
+ if (hasFunctionLikeAncestor(node)) continue;
1410
+ for (const declarator of cFamilyDeclarators(node)) {
1411
+ const name = cFamilyDeclaratorName(declarator);
1412
+ if (name) addSymbol(symbols, node, "type", name);
1413
+ }
1414
+ }
1415
+ for (const node of descendants(root, "alias_declaration")) {
1416
+ if (hasFunctionLikeAncestor(node)) continue;
1417
+ const name = node.childForFieldName("name")?.text.trim();
1418
+ if (name) addSymbol(symbols, node, "type", name);
1419
+ }
1420
+ return uniqueCFamilySymbols(symbols);
1421
+ }
1422
+ function extractJava(root) {
1423
+ const symbols = [];
1424
+ for (const node of descendants(root, "class_declaration")) addSymbol(symbols, node, "class");
1425
+ for (const node of descendants(root, "interface_declaration")) addSymbol(symbols, node, "iface");
1426
+ for (const node of descendants(root, "enum_declaration")) addSymbol(symbols, node, "type");
1427
+ for (const node of descendants(root, "method_declaration")) addSymbol(symbols, node, "method");
1428
+ for (const node of descendants(root, "field_declaration")) {
1429
+ const modifiers = namedChildren(node).find((child) => child.type === "modifiers")?.text ?? "";
1430
+ const staticFinal = /\bstatic\b/.test(modifiers) && /\bfinal\b/.test(modifiers);
1431
+ for (const declarator of namedChildren(node)) {
1432
+ if (declarator.type !== "variable_declarator") continue;
1433
+ const name = declarator.childForFieldName("name")?.text ?? namedChildren(declarator).find((child) => child.type === "identifier")?.text;
1434
+ if (!name) continue;
1435
+ const isConst = staticFinal || /^[A-Z][A-Z0-9_]*$/.test(name);
1436
+ addSymbol(symbols, declarator, isConst ? "const" : "var", name);
1437
+ }
1438
+ }
1439
+ return symbols;
1440
+ }
1441
+ function extractRuby(root) {
1442
+ const symbols = [];
1443
+ for (const node of descendants(root, ["method", "singleton_method"])) addSymbol(symbols, node, "func");
1444
+ for (const node of descendants(root, "class")) addSymbol(symbols, node, "class");
1445
+ for (const node of descendants(root, "module")) addSymbol(symbols, node, "type");
1446
+ for (const node of descendants(root, "assignment")) {
1447
+ if (hasFunctionLikeAncestor(node)) continue;
1448
+ const name = nameFromNode(node);
1449
+ if (name) addSymbol(symbols, node, /^[A-Z]/.test(name) ? "const" : "var", name);
1450
+ }
1451
+ return symbols;
1452
+ }
1453
+ function extractCSharp(root) {
1454
+ const symbols = [];
1455
+ for (const node of descendants(root, "class_declaration")) {
1456
+ if (!hasFunctionLikeAncestor(node)) addSymbol(symbols, node, "class");
1457
+ }
1458
+ for (const node of descendants(root, "interface_declaration")) {
1459
+ if (!hasFunctionLikeAncestor(node)) addSymbol(symbols, node, "iface");
1460
+ }
1461
+ for (const node of descendants(root, ["enum_declaration", "struct_declaration", "record_declaration"])) {
1462
+ if (!hasFunctionLikeAncestor(node)) addSymbol(symbols, node, "type");
1463
+ }
1464
+ for (const node of descendants(root, ["method_declaration", "constructor_declaration"]))
1465
+ addSymbol(symbols, node, "method");
1466
+ for (const node of descendants(root, "property_declaration")) {
1467
+ if (hasFunctionLikeAncestor(node)) continue;
1468
+ addSymbol(symbols, node, "var");
1469
+ }
1470
+ for (const node of descendants(root, "field_declaration")) {
1471
+ if (hasFunctionLikeAncestor(node)) continue;
1472
+ const text = node.text;
1473
+ const isConst = /\bconst\b/.test(text) || /\bstatic\b/.test(text) && /\breadonly\b/.test(text);
1474
+ addSymbol(symbols, node, isConst ? "const" : "var");
1475
+ }
1476
+ return symbols;
1477
+ }
1478
+ function extractSymbolsByGrammar(grammar, root) {
1479
+ if (grammar === "typescript" || grammar === "tsx" || grammar === "javascript") return extractTsJs(root);
1480
+ if (grammar === "python") return extractPython(root);
1481
+ if (grammar === "go") return extractGo(root);
1482
+ if (grammar === "rust") return extractRust(root);
1483
+ if (grammar === "c" || grammar === "cpp") return extractCFamily(root);
1484
+ if (grammar === "java") return extractJava(root);
1485
+ if (grammar === "ruby") return extractRuby(root);
1486
+ if (grammar === "c_sharp") return extractCSharp(root);
1487
+ return [];
1488
+ }
1489
+ function extractTsJsImports(root) {
1490
+ const imports = [];
1491
+ for (const node of descendants(root, "import_statement")) {
1492
+ const source = stringValue(node.childForFieldName("source")) ?? firstStringValue(node);
1493
+ if (source) imports.push(source);
1494
+ }
1495
+ for (const node of descendants(root, "export_statement")) {
1496
+ const source = stringValue(node.childForFieldName("source"));
1497
+ if (source) imports.push(source);
1498
+ }
1499
+ for (const node of descendants(root, "call_expression")) {
1500
+ const callee = node.childForFieldName("function");
1501
+ if (!callee || callee.text !== "require" && callee.text !== "import" && callee.type !== "import") continue;
1502
+ const source = firstStringValue(node.childForFieldName("arguments"));
1503
+ if (source) imports.push(source);
1504
+ }
1505
+ return uniqueSorted2(imports);
1506
+ }
1507
+ function extractPythonImports(root) {
1508
+ const imports = [];
1509
+ for (const node of descendants(root, "import_statement")) {
1510
+ for (const child of namedChildren(node)) {
1511
+ if (child.type === "dotted_name") imports.push(child.text);
1512
+ if (child.type === "aliased_import") {
1513
+ const name = child.childForFieldName("name") ?? child.namedChild(0);
1514
+ if (name) imports.push(name.text);
1515
+ }
1516
+ }
1517
+ }
1518
+ for (const node of descendants(root, "import_from_statement")) {
1519
+ const moduleName = node.childForFieldName("module_name") ?? namedChildren(node).find((child) => child.type === "relative_import" || child.type === "dotted_name");
1520
+ if (moduleName) imports.push(moduleName.text);
1521
+ }
1522
+ return uniqueSorted2(imports);
1523
+ }
1524
+ function extractGoImports(root) {
1525
+ const imports = [];
1526
+ for (const node of descendants(root, "import_spec")) {
1527
+ const source = stringValue(node.childForFieldName("path"));
1528
+ if (source) imports.push(source);
1529
+ }
1530
+ return uniqueSorted2(imports);
1531
+ }
1532
+ function extractRustImports(root) {
1533
+ const imports = [];
1534
+ for (const node of descendants(root, "use_declaration")) {
1535
+ const argument = node.childForFieldName("argument") ?? node.namedChild(0);
1536
+ if (argument) imports.push(argument.text.trim());
1537
+ }
1538
+ for (const node of descendants(root, "extern_crate_declaration")) {
1539
+ const name = node.childForFieldName("name") ?? namedChildren(node).find((child) => child.type === "identifier");
1540
+ if (name) imports.push(name.text.trim());
1541
+ }
1542
+ return uniqueSorted2(imports);
1543
+ }
1544
+ function extractCFamilyImports(root) {
1545
+ const imports = [];
1546
+ for (const node of descendants(root, "preproc_include")) {
1547
+ const sourceNode = node.childForFieldName("path") ?? firstStringDescendant(node);
1548
+ const source = stringValue(sourceNode);
1549
+ if (!source) continue;
1550
+ const quoted = sourceNode?.text.trim().startsWith('"') === true;
1551
+ imports.push(quoted && !source.startsWith(".") && !source.startsWith("/") ? `./${source}` : source);
1552
+ }
1553
+ return uniqueSorted2(imports);
1554
+ }
1555
+ function extractJavaImports(root) {
1556
+ const imports = [];
1557
+ for (const node of descendants(root, "import_declaration")) {
1558
+ const source = node.text.replace(/^import\s+/, "").replace(/^static\s+/, "").replace(/;$/, "").trim();
1559
+ if (source) imports.push(source);
1560
+ }
1561
+ return uniqueSorted2(imports);
1562
+ }
1563
+ function extractRubyImports(root) {
1564
+ return uniqueSorted2([
1565
+ ...Array.from(root.text.matchAll(/^\s*require\s+["']([^"']+)["']/gm), (match) => match[1] ?? ""),
1566
+ ...Array.from(root.text.matchAll(/^\s*require_relative\s+["']([^"']+)["']/gm), (match) => `./${match[1] ?? ""}`)
1567
+ ]);
1568
+ }
1569
+ function extractCSharpImports(root) {
1570
+ const imports = [];
1571
+ for (const node of descendants(root, "using_directive")) {
1572
+ let source = node.text.replace(/^using\s+/, "").replace(/;$/, "").trim();
1573
+ if (source.startsWith("static ")) source = source.slice("static ".length).trim();
1574
+ const aliasIndex = source.indexOf("=");
1575
+ if (aliasIndex !== -1) source = source.slice(aliasIndex + 1).trim();
1576
+ if (source) imports.push(source);
1577
+ }
1578
+ return uniqueSorted2(imports);
1579
+ }
1580
+ function extractImportsByGrammar(grammar, root) {
1581
+ if (grammar === "typescript" || grammar === "tsx" || grammar === "javascript") return extractTsJsImports(root);
1582
+ if (grammar === "python") return extractPythonImports(root);
1583
+ if (grammar === "go") return extractGoImports(root);
1584
+ if (grammar === "rust") return extractRustImports(root);
1585
+ if (grammar === "c" || grammar === "cpp") return extractCFamilyImports(root);
1586
+ if (grammar === "java") return extractJavaImports(root);
1587
+ if (grammar === "ruby") return extractRubyImports(root);
1588
+ if (grammar === "c_sharp") return extractCSharpImports(root);
1589
+ return [];
1590
+ }
1591
+ function sortSymbols(symbols) {
1592
+ return symbols.sort((a, b) => a.line - b.line || a.name.localeCompare(b.name) || a.kind.localeCompare(b.kind));
1593
+ }
1594
+ function grammarForSourceFile(path, text) {
1595
+ if (isAmbiguousHeaderPath(path)) return classifyCHeaderLanguage(text) === "c++" ? "cpp" : "c";
1596
+ return grammarForPath(path, languageFromPath(path));
1597
+ }
1598
+ function grammarCandidatesForSourceFile(path) {
1599
+ if (isAmbiguousHeaderPath(path)) return ["c", "cpp"];
1600
+ const grammar = grammarForPath(path, languageFromPath(path));
1601
+ return grammar ? [grammar] : [];
1602
+ }
1603
+ async function createTreeSitterExtractor() {
1604
+ await ensureParserInit();
1605
+ const parsers = /* @__PURE__ */ new Map();
1606
+ const loading = /* @__PURE__ */ new Map();
1607
+ const loadGrammar = (grammar) => {
1608
+ if (parsers.has(grammar)) return Promise.resolve();
1609
+ let pending = loading.get(grammar);
1610
+ if (!pending) {
1611
+ pending = Language.load(WASM_BY_GRAMMAR[grammar]).then((language) => {
1612
+ const parser = new Parser();
1613
+ parser.setLanguage(language);
1614
+ parsers.set(grammar, parser);
1615
+ }).finally(() => {
1616
+ loading.delete(grammar);
1617
+ });
1618
+ loading.set(grammar, pending);
1619
+ }
1620
+ return pending;
1621
+ };
1622
+ return {
1623
+ langs: ["typescript", "javascript", "python", "go", "rust", "c", "c++", "java", "ruby", "c#"],
1624
+ async ensureGrammarsForPaths(paths) {
1625
+ const needed = /* @__PURE__ */ new Set();
1626
+ for (const path of paths) {
1627
+ for (const grammar of grammarCandidatesForSourceFile(path)) needed.add(grammar);
1628
+ }
1629
+ await Promise.all([...needed].map(loadGrammar));
1630
+ },
1631
+ extract(path, text) {
1632
+ const grammar = grammarForSourceFile(path, text);
1633
+ if (!grammar || text.trim().length === 0) return { symbols: [], imports: [] };
1634
+ const parser = parsers.get(grammar);
1635
+ if (!parser) throw new Error(`tree-sitter grammar not loaded for ${path}`);
1636
+ let tree = null;
1637
+ try {
1638
+ const parsed = parser.parse(text);
1639
+ if (!parsed) throw new Error(`tree-sitter returned no tree for ${path}`);
1640
+ tree = parsed;
1641
+ const symbols = sortSymbols(extractSymbolsByGrammar(grammar, parsed.rootNode));
1642
+ return {
1643
+ symbols,
1644
+ imports: extractImportsByGrammar(grammar, parsed.rootNode)
1645
+ };
1646
+ } catch {
1647
+ throw new Error(`tree-sitter parse failed for ${path}`);
1648
+ } finally {
1649
+ tree?.delete();
1650
+ }
1651
+ }
1652
+ };
1653
+ }
1654
+ function languageFromPath(path) {
1655
+ if (/\.[cm]?tsx?$/.test(path)) return "typescript";
1656
+ if (/\.[cm]?jsx?$/.test(path)) return "javascript";
1657
+ if (path.endsWith(".py") || path.endsWith(".pyw")) return "python";
1658
+ if (path.endsWith(".go")) return "go";
1659
+ if (path.endsWith(".rs")) return "rust";
1660
+ if (/\.(cc|cpp|cxx|hpp|hh|hxx|cu|cuh)$/.test(path)) return "c++";
1661
+ if (/\.(c|h)$/.test(path)) return "c";
1662
+ if (path.endsWith(".java")) return "java";
1663
+ if (path.endsWith(".rb")) return "ruby";
1664
+ if (path.endsWith(".cs")) return "c#";
1665
+ return "config";
1666
+ }
1667
+
1668
+ // src/domains/context/codewiki/indexer.ts
1669
+ var CODEWIKI_SYMBOL_KINDS_WITH_SIG = /* @__PURE__ */ new Set(["func", "class", "method", "type"]);
1670
+ var CODEWIKI_VERSION = 5;
1671
+ var treeSitterExtractorPromise = null;
1672
+ function loadTreeSitterExtractor() {
1673
+ treeSitterExtractorPromise ??= createTreeSitterExtractor();
1674
+ return treeSitterExtractorPromise;
1675
+ }
1676
+ var SOURCE_EXTENSIONS2 = /* @__PURE__ */ new Map([
1677
+ [".ts", "typescript"],
1678
+ [".tsx", "typescript"],
1679
+ [".mts", "typescript"],
1680
+ [".cts", "typescript"],
1681
+ [".js", "javascript"],
1682
+ [".jsx", "javascript"],
1683
+ [".mjs", "javascript"],
1684
+ [".cjs", "javascript"],
1685
+ [".py", "python"],
1686
+ [".pyw", "python"],
1687
+ [".rs", "rust"],
1688
+ [".go", "go"],
1689
+ [".c", "c"],
1690
+ [".h", "c"],
1691
+ [".cc", "c++"],
1692
+ [".cpp", "c++"],
1693
+ [".cxx", "c++"],
1694
+ [".hpp", "c++"],
1695
+ [".hh", "c++"],
1696
+ [".hxx", "c++"],
1697
+ [".cu", "c++"],
1698
+ [".cuh", "c++"],
1699
+ [".java", "java"],
1700
+ [".rb", "ruby"],
1701
+ [".cs", "c#"]
1702
+ ]);
1703
+ var CONFIG_FILE_NAMES = /* @__PURE__ */ new Set([
1704
+ "package.json",
1705
+ "pyproject.toml",
1706
+ "setup.py",
1707
+ "Cargo.toml",
1708
+ "go.mod",
1709
+ "pom.xml",
1710
+ "CMakeLists.txt",
1711
+ "compile_commands.json",
1712
+ "Gemfile"
1713
+ ]);
1714
+ var RESOLUTION_EXTENSIONS = [
1715
+ ".ts",
1716
+ ".tsx",
1717
+ ".mts",
1718
+ ".cts",
1719
+ ".js",
1720
+ ".jsx",
1721
+ ".mjs",
1722
+ ".cjs",
1723
+ ".py",
1724
+ ".go",
1725
+ ".rs",
1726
+ ".c",
1727
+ ".h",
1728
+ ".cc",
1729
+ ".cpp",
1730
+ ".cxx",
1731
+ ".hpp",
1732
+ ".hh",
1733
+ ".hxx",
1734
+ ".cu",
1735
+ ".cuh",
1736
+ ".java",
1737
+ ".rb",
1738
+ ".cs"
1739
+ ];
1740
+ function compareStrings3(a, b) {
1741
+ return a.localeCompare(b);
1742
+ }
1743
+ function stableFileId(path) {
1744
+ return `f_${createHash("sha256").update(path).digest("hex").slice(0, 16)}`;
1745
+ }
1746
+ function contentHash(text) {
1747
+ return createHash("sha256").update(text).digest("hex").slice(0, 16);
1748
+ }
1749
+ function defaultReadFile(path) {
1750
+ try {
1751
+ return readFileSync2(path, "utf8");
1752
+ } catch {
1753
+ return null;
1754
+ }
1755
+ }
1756
+ function extensionOf2(name) {
1757
+ const index = name.lastIndexOf(".");
1758
+ return index === -1 ? "" : name.slice(index);
1759
+ }
1760
+ function normalizeRel(cwd, filePath) {
1761
+ return relative(cwd, filePath).split("\\").join("/");
1762
+ }
1763
+ function normalizeInputPath(path) {
1764
+ return path.split("\\").join("/").replace(/^\.\//, "");
1765
+ }
1766
+ function sourceLanguageForPath(relPath) {
1767
+ if (relPath.endsWith(".d.ts")) return null;
1768
+ return SOURCE_EXTENSIONS2.get(extensionOf2(relPath)) ?? null;
1769
+ }
1770
+ function languageForPath(relPath) {
1771
+ const source = sourceLanguageForPath(relPath);
1772
+ if (source) return source;
1773
+ const name = relPath.split("/").pop() ?? relPath;
1774
+ return CONFIG_FILE_NAMES.has(name) || name.endsWith(".csproj") || name.toLowerCase().endsWith(".cmake") ? "config" : null;
1775
+ }
1776
+ function isIndexablePath(relPath) {
1777
+ if (relPath.split("/").some((segment) => WORKSPACE_EXCLUDED_DIRS.has(segment))) return false;
1778
+ return languageForPath(relPath) !== null;
1779
+ }
1780
+ function lineCount(text) {
1781
+ if (text.length === 0) return 0;
1782
+ return text.endsWith("\n") ? text.split("\n").length - 1 : text.split("\n").length;
1783
+ }
1784
+ function roleFor(relPath, language) {
1785
+ if (language === "config") return "config";
1786
+ const lower = relPath.toLowerCase();
1787
+ if (lower.includes("/test/") || lower.includes("/tests/") || /\.(test|spec)\.[cm]?[jt]sx?$/.test(lower) || /(^|\/)test_.*\.py$/.test(lower) || /(^|\/).*_test\.(go|rs|rb)$/.test(lower)) {
1788
+ return "test";
1789
+ }
1790
+ if (/(^|\/)(index|main|server|cli|orchestrator|bootstrap)\.[^.]+$/.test(lower) || lower.endsWith("/__main__.py")) {
1791
+ return "entry";
1792
+ }
1793
+ return "module";
1794
+ }
1795
+ function firstDocSummary(text) {
1796
+ const jsDoc = /\/\*\*([\s\S]*?)\*\//.exec(text)?.[1];
1797
+ const pythonDoc = /^\s*(?:"""([\s\S]*?)"""|'''([\s\S]*?)''')/.exec(text);
1798
+ const raw = jsDoc ?? pythonDoc?.[1] ?? pythonDoc?.[2];
1799
+ if (!raw) return null;
1800
+ const cleaned = raw.split("\n").map((line2) => line2.replace(/^\s*\*\s?/, "").trim()).filter((line2) => line2.length > 0 && !line2.startsWith("@")).join(" ").replace(/\s+/g, " ").trim();
1801
+ return cleaned.length > 0 ? cleaned.slice(0, 160) : null;
1802
+ }
1803
+ function sanitizeSymbolName(value) {
1804
+ return value.trim().replace(/^self\./, "").replace(/^this\./, "").slice(0, 160);
1805
+ }
1806
+ function addSymbol2(target, seen, name, kind, line2, sig2) {
1807
+ if (!name) return;
1808
+ const clean = sanitizeSymbolName(name);
1809
+ if (clean.length === 0) return;
1810
+ const key = `${clean}\0${kind}\0${line2}`;
1811
+ if (seen.has(key)) return;
1812
+ seen.add(key);
1813
+ target.push({
1814
+ name: clean,
1815
+ kind,
1816
+ line: line2,
1817
+ ...sig2 && sig2.trim().length > 0 ? { sig: sig2.trim().slice(0, 240) } : {}
1818
+ });
1819
+ }
1820
+ function uniqueSorted3(values) {
1821
+ return [...new Set([...values].filter((item) => item.length > 0))].sort(compareStrings3);
1822
+ }
1823
+ function extractWithLineRegex(text, patterns) {
1824
+ const symbols = [];
1825
+ const seen = /* @__PURE__ */ new Set();
1826
+ const lines = text.split(/\r?\n/);
1827
+ for (const [index, line2] of lines.entries()) {
1828
+ for (const pattern of patterns) {
1829
+ const match = pattern.regex.exec(line2);
1830
+ if (!match) continue;
1831
+ const name = match[pattern.nameIndex ?? 1];
1832
+ addSymbol2(symbols, seen, name, pattern.kind, index + 1, line2.trim());
1833
+ }
1834
+ }
1835
+ return symbols.sort(compareSymbols);
1836
+ }
1837
+ function compareSymbols(a, b) {
1838
+ return a.line - b.line || a.name.localeCompare(b.name) || a.kind.localeCompare(b.kind);
1839
+ }
1840
+ function extractMatches(text, regex, group = 1) {
1841
+ const out = [];
1842
+ for (const match of text.matchAll(regex)) {
1843
+ const value = match[group];
1844
+ if (value) out.push(value);
1845
+ }
1846
+ return out;
1847
+ }
1848
+ function maskCFamilyCommentsAndStrings(text) {
1849
+ const chars = text.split("");
1850
+ let state = "code";
1851
+ for (let index = 0; index < chars.length; index += 1) {
1852
+ const current = chars[index] ?? "";
1853
+ const next = chars[index + 1] ?? "";
1854
+ if (state === "code") {
1855
+ if (current === "/" && next === "/") {
1856
+ chars[index] = " ";
1857
+ chars[index + 1] = " ";
1858
+ state = "line-comment";
1859
+ index += 1;
1860
+ } else if (current === "/" && next === "*") {
1861
+ chars[index] = " ";
1862
+ chars[index + 1] = " ";
1863
+ state = "block-comment";
1864
+ index += 1;
1865
+ } else if (current === "'") {
1866
+ chars[index] = " ";
1867
+ state = "single-quote";
1868
+ } else if (current === '"') {
1869
+ chars[index] = " ";
1870
+ state = "double-quote";
1871
+ }
1872
+ continue;
1873
+ }
1874
+ if (current === "\n") {
1875
+ if (state === "line-comment") state = "code";
1876
+ continue;
1877
+ }
1878
+ chars[index] = " ";
1879
+ if (state === "block-comment" && current === "*" && next === "/") {
1880
+ chars[index + 1] = " ";
1881
+ state = "code";
1882
+ index += 1;
1883
+ continue;
1884
+ }
1885
+ if ((state === "single-quote" || state === "double-quote") && current === "\\") {
1886
+ if (index + 1 < chars.length && chars[index + 1] !== "\n") {
1887
+ chars[index + 1] = " ";
1888
+ index += 1;
1889
+ }
1890
+ continue;
1891
+ }
1892
+ if (state === "single-quote" && current === "'") state = "code";
1893
+ if (state === "double-quote" && current === '"') state = "code";
1894
+ }
1895
+ return chars.join("");
1896
+ }
1897
+ function cFamilyAliasStatements(text) {
1898
+ const masked = maskCFamilyCommentsAndStrings(text);
1899
+ const statements = [];
1900
+ const token = /\b(?:typedef|using)\b/g;
1901
+ for (let match = token.exec(masked); match; match = token.exec(masked)) {
1902
+ const start = match.index;
1903
+ const lineStart = masked.lastIndexOf("\n", start - 1) + 1;
1904
+ if (masked.slice(lineStart, start).trimStart().startsWith("#")) continue;
1905
+ let braces = 0;
1906
+ let parentheses = 0;
1907
+ let brackets = 0;
1908
+ let end = -1;
1909
+ for (let index = token.lastIndex; index < masked.length; index += 1) {
1910
+ const current = masked[index];
1911
+ if (current === "{") braces += 1;
1912
+ else if (current === "}") braces = Math.max(0, braces - 1);
1913
+ else if (current === "(") parentheses += 1;
1914
+ else if (current === ")") parentheses = Math.max(0, parentheses - 1);
1915
+ else if (current === "[") brackets += 1;
1916
+ else if (current === "]") brackets = Math.max(0, brackets - 1);
1917
+ else if (current === ";" && braces === 0 && parentheses === 0 && brackets === 0) {
1918
+ end = index + 1;
1919
+ break;
1920
+ }
1921
+ }
1922
+ if (end === -1) continue;
1923
+ statements.push({
1924
+ text: text.slice(start, end),
1925
+ masked: masked.slice(start, end),
1926
+ line: 1 + Array.from(masked.slice(0, start).matchAll(/\n/g)).length
1927
+ });
1928
+ token.lastIndex = end;
1929
+ }
1930
+ return statements;
1931
+ }
1932
+ function stripCFamilyBraceBodies(statement) {
1933
+ let depth = 0;
1934
+ let result = "";
1935
+ for (const current of statement) {
1936
+ if (current === "{") {
1937
+ depth += 1;
1938
+ result += " ";
1939
+ continue;
1940
+ }
1941
+ if (current === "}") {
1942
+ depth = Math.max(0, depth - 1);
1943
+ result += " ";
1944
+ continue;
1945
+ }
1946
+ result += depth === 0 || current === "\n" ? current : " ";
1947
+ }
1948
+ return result;
1949
+ }
1950
+ function splitCFamilyDeclarators(value) {
1951
+ const parts = [];
1952
+ let start = 0;
1953
+ let parentheses = 0;
1954
+ let brackets = 0;
1955
+ let angles = 0;
1956
+ for (let index = 0; index < value.length; index += 1) {
1957
+ const current = value[index];
1958
+ if (current === "(") parentheses += 1;
1959
+ else if (current === ")") parentheses = Math.max(0, parentheses - 1);
1960
+ else if (current === "[") brackets += 1;
1961
+ else if (current === "]") brackets = Math.max(0, brackets - 1);
1962
+ else if (current === "<") angles += 1;
1963
+ else if (current === ">") angles = Math.max(0, angles - 1);
1964
+ else if (current === "," && parentheses === 0 && brackets === 0 && angles === 0) {
1965
+ parts.push(value.slice(start, index));
1966
+ start = index + 1;
1967
+ }
1968
+ }
1969
+ parts.push(value.slice(start));
1970
+ return parts;
1971
+ }
1972
+ var C_FAMILY_TYPE_WORDS = /* @__PURE__ */ new Set([
1973
+ "typedef",
1974
+ "const",
1975
+ "volatile",
1976
+ "restrict",
1977
+ "signed",
1978
+ "unsigned",
1979
+ "short",
1980
+ "long",
1981
+ "void",
1982
+ "char",
1983
+ "int",
1984
+ "float",
1985
+ "double",
1986
+ "struct",
1987
+ "union",
1988
+ "enum",
1989
+ "class",
1990
+ "typename",
1991
+ "auto"
1992
+ ]);
1993
+ function stripTrailingCFamilyDeclaratorSuffixes(value) {
1994
+ let end = value.length;
1995
+ while (end > 0) {
1996
+ while (end > 0 && /\s/.test(value[end - 1] ?? "")) end -= 1;
1997
+ const close = value[end - 1];
1998
+ if (close !== ")" && close !== "]") break;
1999
+ const open = close === ")" ? "(" : "[";
2000
+ let depth = 1;
2001
+ let start = end - 1;
2002
+ for (start -= 1; start >= 0; start -= 1) {
2003
+ const current = value[start];
2004
+ if (current === close) depth += 1;
2005
+ else if (current === open) {
2006
+ depth -= 1;
2007
+ if (depth === 0) break;
2008
+ }
2009
+ }
2010
+ if (start < 0) break;
2011
+ if (start === 0 || !/[A-Za-z_0-9)\]]/.test(value[start - 1] ?? "")) break;
2012
+ end = start;
2013
+ }
2014
+ return value.slice(0, end);
2015
+ }
2016
+ function cFamilyTypedefNames(maskedStatement) {
2017
+ const withoutBodies = stripCFamilyBraceBodies(maskedStatement).replace(/^\s*typedef\b/, "").replace(/;\s*$/, "");
2018
+ const names = [];
2019
+ for (const declarator of splitCFamilyDeclarators(withoutBodies)) {
2020
+ const functionPointerNames = Array.from(
2021
+ declarator.matchAll(
2022
+ /\(\s*(?:[A-Za-z_]\w*\s+)*[*&]+\s*(?:(?:const|volatile|restrict)\s+)*([A-Za-z_]\w*)\s*(?:\[[^\]]*\]\s*)*\)(?=\s*\()/g
2023
+ ),
2024
+ (match) => match[1] ?? ""
2025
+ ).filter((name2) => name2.length > 0);
2026
+ if (functionPointerNames.length > 0) {
2027
+ names.push(...functionPointerNames);
2028
+ continue;
2029
+ }
2030
+ const declaratorWithoutSuffixes = stripTrailingCFamilyDeclaratorSuffixes(declarator);
2031
+ const identifiers = Array.from(declaratorWithoutSuffixes.matchAll(/\b[A-Za-z_]\w*\b/g), (match) => match[0]).filter(
2032
+ (name2) => !C_FAMILY_TYPE_WORDS.has(name2)
2033
+ );
2034
+ const name = identifiers.at(-1);
2035
+ if (name) names.push(name);
2036
+ }
2037
+ return uniqueSorted3(names);
2038
+ }
2039
+ function extractCFamilyAliasSymbols(text) {
2040
+ const symbols = [];
2041
+ const seen = /* @__PURE__ */ new Set();
2042
+ for (const statement of cFamilyAliasStatements(text)) {
2043
+ const usingName = /^\s*using\s+([A-Za-z_]\w*)\s*=/.exec(statement.masked)?.[1];
2044
+ const names = usingName ? [usingName] : /^\s*typedef\b/.test(statement.masked) ? cFamilyTypedefNames(statement.masked) : [];
2045
+ const signature = statement.text.replace(/\s+/g, " ").trim();
2046
+ for (const name of names) addSymbol2(symbols, seen, name, "type", statement.line, signature);
2047
+ }
2048
+ return symbols;
2049
+ }
2050
+ var tsJsExtractor = {
2051
+ langs: ["typescript", "javascript"],
2052
+ extractImports(_path, text) {
2053
+ return uniqueSorted3([
2054
+ ...extractMatches(text, /\bimport\s+(?:type\s+)?(?:[^'"]*?\s+from\s+)?["']([^"']+)["']/g),
2055
+ ...extractMatches(text, /\bexport\s+[^'"]*?\s+from\s+["']([^"']+)["']/g),
2056
+ ...extractMatches(text, /\brequire\s*\(\s*["']([^"']+)["']\s*\)/g),
2057
+ ...extractMatches(text, /\bimport\s*\(\s*["']([^"']+)["']\s*\)/g)
2058
+ ]);
2059
+ },
2060
+ extract(_path, text) {
2061
+ const symbols = extractWithLineRegex(text, [
2062
+ { regex: /^\s*export\s+default\s+(?:async\s+)?function\s+([A-Za-z_$][\w$]*)?/, kind: "func" },
2063
+ { regex: /^\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)\s*\(/, kind: "func" },
2064
+ { regex: /^\s*(?:export\s+)?class\s+([A-Za-z_$][\w$]*)\b/, kind: "class" },
2065
+ { regex: /^\s*(?:export\s+)?interface\s+([A-Za-z_$][\w$]*)\b/, kind: "iface" },
2066
+ { regex: /^\s*(?:export\s+)?type\s+([A-Za-z_$][\w$]*)\b/, kind: "type" },
2067
+ { regex: /^\s*(?:export\s+)?enum\s+([A-Za-z_$][\w$]*)\b/, kind: "type" },
2068
+ { regex: /^(?:\s*export\s+)?const\s+([A-Za-z_$][\w$]*)\b/, kind: "const" },
2069
+ { regex: /^(?:\s*export\s+)?(?:let|var)\s+([A-Za-z_$][\w$]*)\b/, kind: "var" },
2070
+ {
2071
+ regex: /^(?: {2,}|\t+)(?:public\s+|private\s+|protected\s+|static\s+|override\s+|abstract\s+|async\s+|get\s+|set\s+)*(?!(?:if|for|while|switch|catch|return|typeof|else|do|new|await|yield)\b)([A-Za-z_$][\w$]*)\s*\([^)]*\)\s*\{?$/,
2072
+ kind: "method"
2073
+ }
2074
+ ]);
2075
+ return { symbols, imports: tsJsExtractor.extractImports?.(_path, text) ?? [] };
2076
+ }
2077
+ };
2078
+ var pythonExtractor = {
2079
+ langs: ["python"],
2080
+ extractImports(_path, text) {
2081
+ return uniqueSorted3([
2082
+ ...extractMatches(text, /^\s*import\s+([A-Za-z_][\w.]*)(?:\s+as\s+\w+)?/gm),
2083
+ ...extractMatches(text, /^\s*from\s+([.\w]+)\s+import\s+/gm)
2084
+ ]);
2085
+ },
2086
+ extract(_path, text) {
2087
+ const rawSymbols = extractWithLineRegex(text, [
2088
+ { regex: /^(\s*)def\s+([A-Za-z_]\w*)\s*\(/, kind: "func", nameIndex: 2 },
2089
+ { regex: /^(\s*)async\s+def\s+([A-Za-z_]\w*)\s*\(/, kind: "func", nameIndex: 2 },
2090
+ { regex: /^\s*class\s+([A-Za-z_]\w*)\b/, kind: "class" },
2091
+ { regex: /^([A-Z][A-Z0-9_]*)\s*=/, kind: "const" },
2092
+ { regex: /^([A-Za-z_]\w*)\s*=/, kind: "var" }
2093
+ ]);
2094
+ const symbols = rawSymbols.map((symbol) => {
2095
+ if ((symbol.kind === "func" || symbol.kind === "var") && /^\s+/.test(symbol.sig ?? "")) {
2096
+ return { ...symbol, kind: symbol.kind === "func" ? "method" : symbol.kind };
2097
+ }
2098
+ return symbol;
2099
+ });
2100
+ return { symbols: symbols.sort(compareSymbols), imports: pythonExtractor.extractImports?.(_path, text) ?? [] };
2101
+ }
2102
+ };
2103
+ var goExtractor = {
2104
+ langs: ["go"],
2105
+ extractImports(_path, text) {
2106
+ return uniqueSorted3([
2107
+ ...extractMatches(text, /^\s*import\s+"([^"]+)"/gm),
2108
+ ...extractMatches(text, /^\s*"([^"]+)"\s*$/gm)
2109
+ ]);
2110
+ },
2111
+ extract(_path, text) {
2112
+ const rawSymbols = extractWithLineRegex(text, [
2113
+ { regex: /^\s*func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)\s*\(/, kind: "func" },
2114
+ { regex: /^\s*type\s+([A-Za-z_]\w*)\s+interface\b/, kind: "iface" },
2115
+ { regex: /^\s*type\s+([A-Za-z_]\w*)\s+struct\b/, kind: "type" },
2116
+ { regex: /^\s*type\s+([A-Za-z_]\w*)\b/, kind: "type" },
2117
+ { regex: /^const\s+([A-Za-z_]\w*)\b/, kind: "const" },
2118
+ { regex: /^var\s+([A-Za-z_]\w*)\b/, kind: "var" }
2119
+ ]);
2120
+ const symbols = rawSymbols.map((symbol) => {
2121
+ if (symbol.kind === "func" && /^\s*func\s+\(/.test(symbol.sig ?? "")) return { ...symbol, kind: "method" };
2122
+ return symbol;
2123
+ });
2124
+ return { symbols: symbols.sort(compareSymbols), imports: goExtractor.extractImports?.(_path, text) ?? [] };
2125
+ }
2126
+ };
2127
+ var rustExtractor = {
2128
+ langs: ["rust"],
2129
+ extractImports(_path, text) {
2130
+ return uniqueSorted3([
2131
+ ...extractMatches(text, /^\s*use\s+([^;]+);/gm).map((item) => item.trim()),
2132
+ ...extractMatches(text, /^\s*extern\s+crate\s+([A-Za-z_]\w*)/gm)
2133
+ ]);
2134
+ },
2135
+ extract(_path, text) {
2136
+ const symbols = extractWithLineRegex(text, [
2137
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?fn\s+([A-Za-z_]\w*)\s*[<(]/, kind: "func" },
2138
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?struct\s+([A-Za-z_]\w*)\b/, kind: "type" },
2139
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?enum\s+([A-Za-z_]\w*)\b/, kind: "type" },
2140
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?trait\s+([A-Za-z_]\w*)\b/, kind: "trait" },
2141
+ { regex: /^\s*(?:pub(?:\([^)]*\))?\s+)?type\s+([A-Za-z_]\w*)\b/, kind: "type" },
2142
+ { regex: /^(?:\s*pub(?:\([^)]*\))?\s+)?const\s+([A-Za-z_]\w*)\b/, kind: "const" },
2143
+ { regex: /^(?:\s*pub(?:\([^)]*\))?\s+)?static\s+([A-Za-z_]\w*)\b/, kind: "var" }
2144
+ ]);
2145
+ return { symbols, imports: rustExtractor.extractImports?.(_path, text) ?? [] };
2146
+ }
2147
+ };
2148
+ var cFamilyExtractor = {
2149
+ langs: ["c", "c++"],
2150
+ extractImports(_path, text) {
2151
+ const imports = [];
2152
+ for (const match of text.matchAll(/^\s*#\s*include\s*(?:"([^"]+)"|<([^>]+)>)/gm)) {
2153
+ const quoted = match[1];
2154
+ const system = match[2];
2155
+ if (quoted) imports.push(quoted.startsWith(".") || quoted.startsWith("/") ? quoted : `./${quoted}`);
2156
+ else if (system) imports.push(system);
2157
+ }
2158
+ return uniqueSorted3(imports);
2159
+ },
2160
+ extract(_path, text) {
2161
+ const regexSymbols = extractWithLineRegex(text, [
2162
+ { regex: /^\s*class\s+([A-Za-z_]\w*)\b/, kind: "class" },
2163
+ {
2164
+ regex: /^\s*(?:typedef\s+)?(?:struct\s+|union\s+|enum\s+(?:(?:class|struct)\s+)?)([A-Za-z_]\w*)\b/,
2165
+ kind: "type"
2166
+ },
2167
+ {
2168
+ regex: /^\s*(?!(?:typedef|using)\b)(?:template\s*<[^>]+>\s*)?(?:[A-Za-z_][\w:<>,*&\s]+\s+)+(?:(?:[A-Za-z_]\w*)::)*([~A-Za-z_]\w*)\s*\([^;]*\)\s*(?:const\s*)?(?:noexcept\s*)?(?:;|\{)?$/,
2169
+ kind: "func"
2170
+ },
2171
+ { regex: /^(?:const\s+)?[A-Za-z_][\w:<>,*&\s]+\s+([A-Z][A-Z0-9_]*)\s*=/, kind: "const" }
2172
+ ]);
2173
+ const symbolsByKey = /* @__PURE__ */ new Map();
2174
+ for (const symbol of [...regexSymbols, ...extractCFamilyAliasSymbols(text)]) {
2175
+ const key = `${symbol.name}\0${symbol.kind}\0${symbol.line}`;
2176
+ if (!symbolsByKey.has(key)) symbolsByKey.set(key, symbol);
2177
+ }
2178
+ const symbols = [...symbolsByKey.values()].sort(compareSymbols);
2179
+ return { symbols, imports: cFamilyExtractor.extractImports?.(_path, text) ?? [] };
2180
+ }
2181
+ };
2182
+ var javaExtractor = {
2183
+ langs: ["java"],
2184
+ extractImports(_path, text) {
2185
+ return uniqueSorted3(extractMatches(text, /^\s*import\s+(?:static\s+)?([A-Za-z_][\w.*]*);/gm));
2186
+ },
2187
+ extract(_path, text) {
2188
+ const symbols = extractWithLineRegex(text, [
2189
+ { regex: /^\s*(?:public\s+|private\s+|protected\s+|abstract\s+|final\s+)*class\s+([A-Za-z_]\w*)\b/, kind: "class" },
2190
+ {
2191
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|abstract\s+|final\s+)*interface\s+([A-Za-z_]\w*)\b/,
2192
+ kind: "iface"
2193
+ },
2194
+ { regex: /^\s*(?:public\s+|private\s+|protected\s+|abstract\s+|final\s+)*enum\s+([A-Za-z_]\w*)\b/, kind: "type" },
2195
+ {
2196
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|static\s+|final\s+|synchronized\s+)*[A-Za-z_][\w<>,[\]\s]*\s+([A-Za-z_]\w*)\s*\([^)]*\)\s*\{?$/,
2197
+ kind: "method"
2198
+ },
2199
+ {
2200
+ regex: /^\s*public\s+(?:static\s+|final\s+)*[A-Za-z_][\w<>,[\]\s]*\s+([A-Z][A-Z0-9_]*)\s*=/,
2201
+ kind: "const"
2202
+ }
2203
+ ]);
2204
+ return { symbols, imports: javaExtractor.extractImports?.(_path, text) ?? [] };
2205
+ }
2206
+ };
2207
+ var rubyExtractor = {
2208
+ langs: ["ruby"],
2209
+ extractImports(_path, text) {
2210
+ return uniqueSorted3([
2211
+ ...extractMatches(text, /^\s*require\s+["']([^"']+)["']/gm),
2212
+ ...extractMatches(text, /^\s*require_relative\s+["']([^"']+)["']/gm).map((item) => `./${item}`)
2213
+ ]);
2214
+ },
2215
+ extract(_path, text) {
2216
+ const symbols = extractWithLineRegex(text, [
2217
+ { regex: /^\s*class\s+([A-Z]\w*(?:::[A-Z]\w*)*)\b/, kind: "class" },
2218
+ { regex: /^\s*module\s+([A-Z]\w*(?:::[A-Z]\w*)*)\b/, kind: "type" },
2219
+ { regex: /^\s*def\s+(?:self\.)?([A-Za-z_]\w*[!?=]?)\b/, kind: "func" },
2220
+ { regex: /^([A-Z][A-Z0-9_]*)\s*=/, kind: "const" }
2221
+ ]);
2222
+ return { symbols, imports: rubyExtractor.extractImports?.(_path, text) ?? [] };
2223
+ }
2224
+ };
2225
+ var csharpExtractor = {
2226
+ langs: ["c#"],
2227
+ extractImports(_path, text) {
2228
+ return uniqueSorted3(
2229
+ extractMatches(text, /^\s*using\s+(?:static\s+)?(?:[A-Za-z_]\w*\s*=\s*)?([A-Za-z_][\w.]*)\s*;/gm)
2230
+ );
2231
+ },
2232
+ extract(_path, text) {
2233
+ const symbols = extractWithLineRegex(text, [
2234
+ {
2235
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|static\s+|sealed\s+|abstract\s+|partial\s+)*class\s+([A-Za-z_]\w*)\b/,
2236
+ kind: "class"
2237
+ },
2238
+ {
2239
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|partial\s+)*interface\s+([A-Za-z_]\w*)\b/,
2240
+ kind: "iface"
2241
+ },
2242
+ {
2243
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|readonly\s+|partial\s+)*(?:enum|struct|record)\s+([A-Za-z_]\w*)\b/,
2244
+ kind: "type"
2245
+ },
2246
+ {
2247
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|static\s+|virtual\s+|override\s+|abstract\s+|sealed\s+|async\s+|partial\s+|new\s+)*(?!(?:if|for|foreach|while|switch|catch|return|using|else|do|new|class|interface|enum|struct|record|namespace|lock|throw)\b)[A-Za-z_][\w<>,[\].?\s]*\s+([A-Za-z_]\w*)\s*\([^)]*\)\s*\{?$/,
2248
+ kind: "method"
2249
+ },
2250
+ {
2251
+ regex: /^\s*(?:public\s+|private\s+|protected\s+|internal\s+|static\s+)*const\s+[A-Za-z_][\w<>,[\]\s]*\s+([A-Za-z_]\w*)\s*=/,
2252
+ kind: "const"
2253
+ }
2254
+ ]);
2255
+ return { symbols, imports: csharpExtractor.extractImports?.(_path, text) ?? [] };
2256
+ }
2257
+ };
2258
+ var fallbackExtractors = [
2259
+ tsJsExtractor,
2260
+ pythonExtractor,
2261
+ goExtractor,
2262
+ rustExtractor,
2263
+ cFamilyExtractor,
2264
+ javaExtractor,
2265
+ rubyExtractor,
2266
+ csharpExtractor
2267
+ ];
2268
+ function extractWithExtractors(extractors, language, relPath, text) {
2269
+ const symbols = /* @__PURE__ */ new Map();
2270
+ const imports = [];
2271
+ for (const extractor of extractors) {
2272
+ if (!extractor.langs.includes(language)) continue;
2273
+ const extracted = extractor.extract(relPath, text);
2274
+ for (const symbol of extracted.symbols) {
2275
+ const key = `${symbol.name}\0${symbol.kind}\0${symbol.line}`;
2276
+ if (!symbols.has(key)) symbols.set(key, symbol);
2277
+ }
2278
+ imports.push(...extracted.imports);
2279
+ }
2280
+ return {
2281
+ symbols: [...symbols.values()].sort(compareSymbols),
2282
+ imports: uniqueSorted3(imports)
2283
+ };
2284
+ }
2285
+ function extractImportsWithExtractors(extractors, language, relPath, text) {
2286
+ const imports = [];
2287
+ for (const extractor of extractors) {
2288
+ if (!extractor.langs.includes(language) || !extractor.extractImports) continue;
2289
+ imports.push(...extractor.extractImports(relPath, text));
2290
+ }
2291
+ return uniqueSorted3(imports);
2292
+ }
2293
+ function mergeTreeSitterWithRegexImports(language, relPath, text, extracted) {
2294
+ const regexImports = extractImportsWithExtractors(fallbackExtractors, language, relPath, text);
2295
+ return {
2296
+ symbols: extracted.symbols.sort(compareSymbols),
2297
+ imports: uniqueSorted3([...extracted.imports, ...regexImports])
2298
+ };
2299
+ }
2300
+ function fallbackExtraction(language, relPath, text) {
2301
+ return extractWithExtractors(fallbackExtractors, language, relPath, text);
2302
+ }
2303
+ function extractSourceFile(language, relPath, text, treeSitterExtractor) {
2304
+ if (!treeSitterExtractor.langs.includes(language)) return fallbackExtraction(language, relPath, text);
2305
+ try {
2306
+ return mergeTreeSitterWithRegexImports(language, relPath, text, treeSitterExtractor.extract(relPath, text));
2307
+ } catch {
2308
+ return fallbackExtraction(language, relPath, text);
2309
+ }
2310
+ }
2311
+ function buildFile(cwd, relPath, treeSitterExtractor, readFile) {
2312
+ const pathLanguage = languageForPath(relPath);
2313
+ if (!pathLanguage) return null;
2314
+ let text;
2315
+ try {
2316
+ text = readFile(join4(cwd, relPath));
2317
+ } catch {
2318
+ return null;
2319
+ }
2320
+ if (text === null) return null;
2321
+ const language = pathLanguage === "c" && isAmbiguousHeaderPath(relPath) ? classifyCHeaderLanguage(text) : pathLanguage;
2322
+ const file = {
2323
+ id: stableFileId(relPath),
2324
+ path: relPath,
2325
+ lang: language,
2326
+ loc: lineCount(text),
2327
+ role: roleFor(relPath, language),
2328
+ hash: contentHash(text),
2329
+ imports: []
2330
+ };
2331
+ if (text.trim().length === 0) return { file, symbols: [] };
2332
+ const extracted = isCMakePath(relPath) ? extractCMake(text) : language !== "config" ? extractSourceFile(language, relPath, text, treeSitterExtractor) : null;
2333
+ if (!extracted) return { file, symbols: [] };
2334
+ const summary = firstDocSummary(text);
2335
+ const sourceFile = {
2336
+ ...file,
2337
+ imports: extracted.imports,
2338
+ ...summary ? { summary } : {}
2339
+ };
2340
+ const symbols = extracted.symbols.map((symbol) => ({
2341
+ name: symbol.name,
2342
+ kind: symbol.kind,
2343
+ fileId: sourceFile.id,
2344
+ line: symbol.line,
2345
+ ...symbolSigFields(symbol.kind, symbol.sig)
2346
+ }));
2347
+ return {
2348
+ file: sourceFile,
2349
+ symbols
2350
+ };
2351
+ }
2352
+ function candidatePathsForImport(cwd, fromRel, specifier) {
2353
+ const fromDir = dirname2(join4(cwd, fromRel));
2354
+ const cleaned = specifier.replace(/\\/g, "/");
2355
+ const base = cleaned.startsWith(".") || cleaned.startsWith("/") ? resolve(fromDir, cleaned) : "";
2356
+ if (!base) return [];
2357
+ const candidates = [base];
2358
+ for (const ext of RESOLUTION_EXTENSIONS) candidates.push(`${base}${ext}`);
2359
+ for (const ext of RESOLUTION_EXTENSIONS) candidates.push(join4(base, `index${ext}`));
2360
+ if (cleaned.endsWith(".js")) {
2361
+ const stripped = base.replace(/\.js$/, "");
2362
+ for (const ext of [".ts", ".tsx", ".mts", ".cts"]) candidates.push(`${stripped}${ext}`);
2363
+ }
2364
+ if (/^[.]+[A-Za-z_]/.test(cleaned)) {
2365
+ const pythonModule = cleaned.replace(/^\.+/, "").replace(/\./g, "/");
2366
+ const pythonBase = resolve(fromDir, pythonModule);
2367
+ candidates.push(`${pythonBase}.py`, join4(pythonBase, "__init__.py"));
2368
+ }
2369
+ return uniqueSorted3(
2370
+ candidates.map((candidate) => normalizeRel(cwd, candidate)).filter((candidate) => !candidate.startsWith(".."))
2371
+ );
2372
+ }
2373
+ function createImportResolver(cwd) {
2374
+ const candidatesByOrigin = /* @__PURE__ */ new Map();
2375
+ const onDisk = /* @__PURE__ */ new Map();
2376
+ const candidatesFor = (fromRel, specifier) => {
2377
+ const key = `${dirname2(fromRel)}\0${specifier}`;
2378
+ let candidates = candidatesByOrigin.get(key);
2379
+ if (!candidates) {
2380
+ candidates = candidatePathsForImport(cwd, fromRel, specifier);
2381
+ candidatesByOrigin.set(key, candidates);
2382
+ }
2383
+ return candidates;
2384
+ };
2385
+ const isFile = (candidate) => {
2386
+ const cached = onDisk.get(candidate);
2387
+ if (cached !== void 0) return cached;
2388
+ let exists;
2389
+ try {
2390
+ exists = statSync(join4(cwd, candidate)).isFile();
2391
+ } catch {
2392
+ exists = false;
2393
+ }
2394
+ onDisk.set(candidate, exists);
2395
+ return exists;
2396
+ };
2397
+ return {
2398
+ resolve(fromRel, specifier, pathToId) {
2399
+ for (const candidate of candidatesFor(fromRel, specifier)) {
2400
+ if (pathToId.has(candidate)) return pathToId.get(candidate) ?? null;
2401
+ if (isFile(candidate)) return null;
2402
+ }
2403
+ return null;
2404
+ }
2405
+ };
2406
+ }
2407
+ async function buildEdges(cwd, files, slicer) {
2408
+ const pathToId = new Map(files.map((file) => [file.path, file.id]));
2409
+ const resolver = createImportResolver(cwd);
2410
+ const edges = [];
2411
+ const seen = /* @__PURE__ */ new Set();
2412
+ for (const file of files) {
2413
+ for (const specifier of file.imports) {
2414
+ await slicer.tick();
2415
+ const target = resolver.resolve(file.path, specifier, pathToId);
2416
+ const edge = target ? { fileId: file.id, toFileId: target } : { fileId: file.id, externalModule: specifier };
2417
+ const key = "toFileId" in edge ? `${edge.fileId}\0${edge.toFileId}` : `${edge.fileId}\0${edge.externalModule}`;
2418
+ if (seen.has(key)) continue;
2419
+ seen.add(key);
2420
+ edges.push(edge);
2421
+ }
2422
+ }
2423
+ return edges.sort(compareEdges);
2424
+ }
2425
+ function compareFiles(a, b) {
2426
+ return a.path.localeCompare(b.path);
2427
+ }
2428
+ function compareCodewikiSymbols(a, b) {
2429
+ const pathCmp = a.fileId.localeCompare(b.fileId);
2430
+ return pathCmp || a.line - b.line || a.name.localeCompare(b.name) || a.kind.localeCompare(b.kind);
2431
+ }
2432
+ function compareEdges(a, b) {
2433
+ const fileCmp = a.fileId.localeCompare(b.fileId);
2434
+ if (fileCmp !== 0) return fileCmp;
2435
+ const aTarget = "toFileId" in a ? a.toFileId : `~${a.externalModule}`;
2436
+ const bTarget = "toFileId" in b ? b.toFileId : `~${b.externalModule}`;
2437
+ return aTarget.localeCompare(bTarget);
2438
+ }
2439
+ function promoteSingleSourceEntry(files) {
2440
+ const sourceFiles = files.filter((file) => file.lang !== "config");
2441
+ if (sourceFiles.length !== 1) return files;
2442
+ const only = sourceFiles[0];
2443
+ if (only?.role !== "module") return files;
2444
+ return files.map((file) => file.id === only.id ? { ...file, role: "entry" } : file);
2445
+ }
2446
+ async function codewikiFromBuiltFiles(cwd, language, builtFiles, slicer) {
2447
+ const baseBuiltFiles = builtFiles.map((item) => ({
2448
+ ...item,
2449
+ file: { ...item.file, role: roleFor(item.file.path, item.file.lang) }
2450
+ }));
2451
+ const files = promoteSingleSourceEntry(baseBuiltFiles.map((item) => item.file).sort(compareFiles));
2452
+ const roleById = new Map(files.map((file) => [file.id, file.role]));
2453
+ const normalizedBuilt = baseBuiltFiles.map((item) => {
2454
+ const role = roleById.get(item.file.id);
2455
+ return role && role !== item.file.role ? { ...item, file: { ...item.file, role } } : item;
2456
+ });
2457
+ const normalizedFiles = normalizedBuilt.map((item) => item.file).sort(compareFiles);
2458
+ return {
2459
+ version: CODEWIKI_VERSION,
2460
+ language,
2461
+ files: normalizedFiles,
2462
+ symbols: normalizedBuilt.flatMap((item) => item.symbols).sort(compareCodewikiSymbols),
2463
+ edges: await buildEdges(cwd, normalizedFiles, slicer)
2464
+ };
2465
+ }
2466
+ async function buildFromPaths(cwd, language, relPaths, options = {}) {
2467
+ const slicer = options.slicer ?? createSlicer();
2468
+ const sortedPaths = [...relPaths].sort(compareStrings3);
2469
+ const treeSitterExtractor = await loadTreeSitterExtractor();
2470
+ await treeSitterExtractor.ensureGrammarsForPaths(sortedPaths);
2471
+ const readFile = options.readFile ?? defaultReadFile;
2472
+ const builtFiles = [];
2473
+ for (const relPath of sortedPaths) {
2474
+ await slicer.tick();
2475
+ const built = buildFile(cwd, relPath, treeSitterExtractor, readFile);
2476
+ if (built) builtFiles.push(built);
2477
+ }
2478
+ return codewikiFromBuiltFiles(cwd, language, builtFiles, slicer);
2479
+ }
2480
+ async function buildCodewiki(input, options = {}) {
2481
+ const slicer = options.slicer ?? createSlicer();
2482
+ const files = (await enumerateWorkspaceFilesAsync(input.cwd, WORKSPACE_EXCLUDED_DIRS, void 0, slicer)).filter(
2483
+ isIndexablePath
2484
+ );
2485
+ return buildFromPaths(input.cwd, input.language, files, { ...options, slicer });
2486
+ }
2487
+ async function updateCodewikiPaths(cwd, codewiki, paths, options = {}) {
2488
+ const normalizedPaths = uniqueSorted3(
2489
+ paths.map(normalizeInputPath).filter((path) => path.length > 0 && !path.startsWith(".."))
2490
+ );
2491
+ if (normalizedPaths.length === 0) return codewiki;
2492
+ if (normalizedPaths.some(
2493
+ (path) => path === ".gitignore" || path.endsWith("/.gitignore") || path === ".git/info/exclude" || path === ".git/index" || path === ".gitmodules"
2494
+ )) {
2495
+ return buildCodewiki({ cwd, language: codewiki.language }, options);
2496
+ }
2497
+ const slicer = options.slicer ?? createSlicer();
2498
+ const existingPaths = new Set(codewiki.files.map((file) => file.path));
2499
+ const visiblePaths = new Set(filterWorkspaceFileCandidates(cwd, normalizedPaths, WORKSPACE_EXCLUDED_DIRS));
2500
+ const readFile = options.readFile ?? defaultReadFile;
2501
+ const changedPathSet = new Set(normalizedPaths);
2502
+ const rebuildPaths = [];
2503
+ let hasIndexChange = false;
2504
+ for (const relPath of normalizedPaths) {
2505
+ const wasIndexed = existingPaths.has(relPath);
2506
+ const isCurrentIndexableFile = isIndexablePath(relPath) && visiblePaths.has(relPath);
2507
+ if (!wasIndexed && !isCurrentIndexableFile) continue;
2508
+ hasIndexChange = true;
2509
+ if (isCurrentIndexableFile) rebuildPaths.push(relPath);
2510
+ }
2511
+ if (!hasIndexChange) return codewiki;
2512
+ const rebuiltFiles = [];
2513
+ if (rebuildPaths.length > 0) {
2514
+ const treeSitterExtractor = await loadTreeSitterExtractor();
2515
+ await treeSitterExtractor.ensureGrammarsForPaths(rebuildPaths);
2516
+ for (const relPath of rebuildPaths) {
2517
+ await slicer.tick();
2518
+ const built = buildFile(cwd, relPath, treeSitterExtractor, readFile);
2519
+ if (built) rebuiltFiles.push(built);
2520
+ }
2521
+ }
2522
+ const removedFileIds = new Set(codewiki.files.filter((file) => changedPathSet.has(file.path)).map((file) => file.id));
2523
+ const symbolsByFileId = /* @__PURE__ */ new Map();
2524
+ for (const symbol of codewiki.symbols) {
2525
+ if (removedFileIds.has(symbol.fileId)) continue;
2526
+ const symbols = symbolsByFileId.get(symbol.fileId) ?? [];
2527
+ symbols.push(symbol);
2528
+ symbolsByFileId.set(symbol.fileId, symbols);
2529
+ }
2530
+ const keptFiles = codewiki.files.filter((file) => !changedPathSet.has(file.path)).map((file) => ({ file, symbols: symbolsByFileId.get(file.id) ?? [] }));
2531
+ return codewikiFromBuiltFiles(cwd, codewiki.language, [...keptFiles, ...rebuiltFiles], slicer);
2532
+ }
2533
+ async function syncCodewiki(cwd, codewiki, options = {}) {
2534
+ const slicer = options.slicer ?? createSlicer();
2535
+ const readFile = options.readFile ?? defaultReadFile;
2536
+ const currentPaths = (await enumerateWorkspaceFilesAsync(cwd, WORKSPACE_EXCLUDED_DIRS, void 0, slicer)).filter(
2537
+ isIndexablePath
2538
+ );
2539
+ const currentFiles = /* @__PURE__ */ new Map();
2540
+ const currentTexts = /* @__PURE__ */ new Map();
2541
+ for (const relPath of currentPaths) {
2542
+ await slicer.tick();
2543
+ const text = readFile(join4(cwd, relPath));
2544
+ if (text !== null) {
2545
+ currentFiles.set(relPath, contentHash(text));
2546
+ currentTexts.set(relPath, text);
2547
+ }
2548
+ }
2549
+ const indexedFiles = new Map(codewiki.files.map((file) => [file.path, file]));
2550
+ const changedPaths = /* @__PURE__ */ new Set();
2551
+ for (const [relPath, hash] of currentFiles) {
2552
+ if (indexedFiles.get(relPath)?.hash !== hash) changedPaths.add(relPath);
2553
+ }
2554
+ for (const relPath of indexedFiles.keys()) {
2555
+ if (!currentFiles.has(relPath)) changedPaths.add(relPath);
2556
+ }
2557
+ if (changedPaths.size === 0) return codewiki;
2558
+ const syncOptions = {
2559
+ ...options,
2560
+ slicer,
2561
+ readFile: (path) => currentTexts.get(normalizeRel(cwd, path)) ?? readFile(path)
2562
+ };
2563
+ return updateCodewikiPaths(cwd, codewiki, [...changedPaths], syncOptions);
2564
+ }
2565
+ function codewikiPath(cwd) {
2566
+ return join4(cwd, ".clio-coder", "codewiki.json");
2567
+ }
2568
+ function serializeCodewiki(codewiki) {
2569
+ return `${JSON.stringify(normalizeCodewiki(codewiki))}
2570
+ `;
2571
+ }
2572
+ function writeCodewiki(cwd, codewiki) {
2573
+ const serialized = serializeCodewiki(codewiki);
2574
+ safeResourceWrite(codewikiPath(cwd), serialized, {
2575
+ encoding: "utf8"
2576
+ });
2577
+ return serialized;
2578
+ }
2579
+ function parseCodewikiRaw(raw) {
2580
+ let parsed;
2581
+ try {
2582
+ parsed = JSON.parse(raw);
2583
+ } catch {
2584
+ return null;
2585
+ }
2586
+ return upgradeCodewiki(parsed);
2587
+ }
2588
+ function readCodewikiRaw(cwd) {
2589
+ const filePath = codewikiPath(cwd);
2590
+ if (!existsSync(filePath)) return null;
2591
+ let raw;
2592
+ try {
2593
+ raw = readFileSync2(filePath, "utf8");
2594
+ } catch {
2595
+ return null;
2596
+ }
2597
+ const codewiki = parseCodewikiRaw(raw);
2598
+ return codewiki ? { raw, codewiki } : null;
2599
+ }
2600
+ function readCodewiki(cwd) {
2601
+ return readCodewikiRaw(cwd)?.codewiki ?? null;
2602
+ }
2603
+ async function readCodewikiAsync(cwd) {
2604
+ let raw;
2605
+ try {
2606
+ raw = await readFileAsync(codewikiPath(cwd), "utf8");
2607
+ } catch {
2608
+ return null;
2609
+ }
2610
+ return parseCodewikiRaw(raw);
2611
+ }
2612
+ function codewikiEntries(codewiki) {
2613
+ const fileById = new Map(codewiki.files.map((file) => [file.id, file]));
2614
+ const exportsByFile = /* @__PURE__ */ new Map();
2615
+ for (const symbol of codewiki.symbols) {
2616
+ const list = exportsByFile.get(symbol.fileId) ?? [];
2617
+ list.push(symbol.name);
2618
+ exportsByFile.set(symbol.fileId, list);
2619
+ }
2620
+ const importsByFile = /* @__PURE__ */ new Map();
2621
+ for (const edge of codewiki.edges) {
2622
+ const list = importsByFile.get(edge.fileId) ?? [];
2623
+ if ("toFileId" in edge) {
2624
+ const target = fileById.get(edge.toFileId);
2625
+ if (target) list.push(target.path);
2626
+ } else {
2627
+ list.push(edge.externalModule);
2628
+ }
2629
+ importsByFile.set(edge.fileId, list);
2630
+ }
2631
+ return codewiki.files.filter((file) => file.lang !== "config").map((file) => ({
2632
+ path: file.path,
2633
+ exports: uniqueSorted3(exportsByFile.get(file.id) ?? []),
2634
+ imports: uniqueSorted3(importsByFile.get(file.id) ?? []),
2635
+ kind: file.role === "entry" ? "entry-point" : file.role === "test" ? "test" : "module",
2636
+ ...file.summary ? { summary: file.summary } : {}
2637
+ })).sort((a, b) => a.path.localeCompare(b.path));
2638
+ }
2639
+ function codewikiNeedsBackfill(codewiki) {
2640
+ return codewiki.files.some((file) => file.lang !== "config" && file.hash.length === 0);
2641
+ }
2642
+ function structuralCodewikiHash(codewiki) {
2643
+ return createHash("sha256").update(JSON.stringify(normalizeCodewiki(codewiki))).digest("hex");
2644
+ }
2645
+ function normalizeCodewikiFile(file) {
2646
+ return {
2647
+ id: file.id,
2648
+ path: file.path,
2649
+ lang: file.lang,
2650
+ loc: file.loc,
2651
+ role: file.role,
2652
+ hash: file.hash,
2653
+ imports: uniqueSorted3(file.imports),
2654
+ ...file.summary ? { summary: file.summary } : {}
2655
+ };
2656
+ }
2657
+ function symbolSigFields(kind, sig2) {
2658
+ if (!CODEWIKI_SYMBOL_KINDS_WITH_SIG.has(kind)) return {};
2659
+ const clean = sig2?.trim().slice(0, 240);
2660
+ return clean && clean.length > 0 ? { sig: clean } : {};
2661
+ }
2662
+ function normalizeCodewikiSymbol(symbol) {
2663
+ return {
2664
+ name: symbol.name,
2665
+ kind: symbol.kind,
2666
+ fileId: symbol.fileId,
2667
+ line: symbol.line,
2668
+ ...symbolSigFields(symbol.kind, symbol.sig)
2669
+ };
2670
+ }
2671
+ function normalizeCodewiki(codewiki) {
2672
+ return {
2673
+ version: CODEWIKI_VERSION,
2674
+ language: codewiki.language,
2675
+ files: codewiki.files.map(normalizeCodewikiFile).sort(compareFiles),
2676
+ symbols: codewiki.symbols.map(normalizeCodewikiSymbol).sort(compareCodewikiSymbols),
2677
+ edges: [...codewiki.edges].sort(compareEdges)
2678
+ };
2679
+ }
2680
+ function upgradeCodewiki(value) {
2681
+ if (isCodewikiV5(value)) return normalizeCodewiki(value);
2682
+ if (isCodewikiV4(value)) return upgradeV4Codewiki(value);
2683
+ if (isCodewikiV3(value)) return upgradeV3Codewiki(value);
2684
+ if (isCodewikiV2(value)) return upgradeV2Codewiki(value);
2685
+ return null;
2686
+ }
2687
+ function upgradeV3Codewiki(value) {
2688
+ return normalizeCodewiki({
2689
+ version: CODEWIKI_VERSION,
2690
+ language: value.language,
2691
+ files: value.files.map((file) => ({
2692
+ ...file,
2693
+ hash: "",
2694
+ imports: []
2695
+ })),
2696
+ symbols: value.symbols,
2697
+ edges: value.edges
2698
+ });
2699
+ }
2700
+ function upgradeV4Codewiki(value) {
2701
+ return normalizeCodewiki({
2702
+ version: CODEWIKI_VERSION,
2703
+ language: value.language,
2704
+ // v5 changes C-family extraction and adds CUDA paths. Blank hashes force
2705
+ // one complete rebuild instead of treating a structurally obsolete v4
2706
+ // artifact as fresh.
2707
+ files: value.files.map((file) => ({ ...file, hash: "" })),
2708
+ symbols: value.symbols,
2709
+ edges: value.edges
2710
+ });
2711
+ }
2712
+ function upgradeV2Codewiki(value) {
2713
+ const files = value.entries.map((entry) => {
2714
+ const lang = languageForPath(entry.path) ?? (value.language === "unknown" || value.language === "polyglot" || value.language === "dotfiles" ? "config" : value.language);
2715
+ return {
2716
+ id: stableFileId(entry.path),
2717
+ path: entry.path,
2718
+ lang,
2719
+ loc: 0,
2720
+ role: entry.kind === "entry-point" ? "entry" : entry.kind === "test" ? "test" : "module"
2721
+ };
2722
+ });
2723
+ const pathToId = new Map(files.map((file) => [file.path, file.id]));
2724
+ const symbols = [];
2725
+ for (const entry of value.entries) {
2726
+ const fileId = pathToId.get(entry.path);
2727
+ if (!fileId) continue;
2728
+ for (const name of entry.exports) symbols.push({ name, kind: "const", fileId, line: 1 });
2729
+ }
2730
+ const edges = [];
2731
+ for (const entry of value.entries) {
2732
+ const fileId = pathToId.get(entry.path);
2733
+ if (!fileId) continue;
2734
+ for (const item of entry.imports) {
2735
+ const toFileId = pathToId.get(item);
2736
+ edges.push(toFileId ? { fileId, toFileId } : { fileId, externalModule: item });
2737
+ }
2738
+ }
2739
+ return upgradeV3Codewiki({
2740
+ version: 3,
2741
+ language: value.language,
2742
+ files,
2743
+ symbols,
2744
+ edges
2745
+ });
2746
+ }
2747
+ function isNormalizedRelativeCodewikiPath(path) {
2748
+ if (path.length === 0 || path.includes("\0") || path.includes("\\") || path.startsWith("/")) return false;
2749
+ if (/^[A-Za-z]:\//.test(path)) return false;
2750
+ const segments = path.split("/");
2751
+ return segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
2752
+ }
2753
+ function hasValidNativeV5Semantics(value) {
2754
+ const fileIds = /* @__PURE__ */ new Set();
2755
+ const filePaths = /* @__PURE__ */ new Set();
2756
+ const locByFileId = /* @__PURE__ */ new Map();
2757
+ for (const file of value.files) {
2758
+ if (fileIds.has(file.id) || filePaths.has(file.path)) return false;
2759
+ if (!isNormalizedRelativeCodewikiPath(file.path) || !/^[0-9a-f]{16}$/.test(file.hash)) return false;
2760
+ fileIds.add(file.id);
2761
+ filePaths.add(file.path);
2762
+ locByFileId.set(file.id, file.loc);
2763
+ }
2764
+ for (const symbol of value.symbols) {
2765
+ const loc = locByFileId.get(symbol.fileId);
2766
+ if (loc === void 0 || symbol.line > loc) return false;
2767
+ }
2768
+ for (const edge of value.edges) {
2769
+ if (!fileIds.has(edge.fileId)) return false;
2770
+ if ("toFileId" in edge && !fileIds.has(edge.toFileId)) return false;
2771
+ }
2772
+ return true;
2773
+ }
2774
+ function isCodewikiV5(value) {
2775
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2776
+ const obj = value;
2777
+ if (obj.version !== CODEWIKI_VERSION || typeof obj.language !== "string") return false;
2778
+ if (!Array.isArray(obj.files) || !Array.isArray(obj.symbols) || !Array.isArray(obj.edges)) return false;
2779
+ if (!obj.files.every(isCodewikiFile) || !obj.symbols.every(isCodewikiSymbol) || !obj.edges.every(isCodewikiEdge)) {
2780
+ return false;
2781
+ }
2782
+ return hasValidNativeV5Semantics(obj);
2783
+ }
2784
+ function isCodewikiV4(value) {
2785
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2786
+ const obj = value;
2787
+ if (obj.version !== 4 || typeof obj.language !== "string") return false;
2788
+ if (!Array.isArray(obj.files) || !Array.isArray(obj.symbols) || !Array.isArray(obj.edges)) return false;
2789
+ return obj.files.every(isCodewikiFile) && obj.symbols.every(isCodewikiSymbol) && obj.edges.every(isCodewikiEdge);
2790
+ }
2791
+ function isCodewikiV3(value) {
2792
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2793
+ const obj = value;
2794
+ if (obj.version !== 3 || typeof obj.language !== "string") return false;
2795
+ if (!Array.isArray(obj.files) || !Array.isArray(obj.symbols) || !Array.isArray(obj.edges)) return false;
2796
+ return obj.files.every(isCodewikiFileV3) && obj.symbols.every(isCodewikiSymbol) && obj.edges.every(isCodewikiEdge);
2797
+ }
2798
+ function isCodewikiV2(value) {
2799
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2800
+ const obj = value;
2801
+ if (obj.version !== 2 || typeof obj.generatedAt !== "string" || typeof obj.language !== "string") return false;
2802
+ if (!Array.isArray(obj.entries)) return false;
2803
+ return obj.entries.every(isCodewikiEntry);
2804
+ }
2805
+ var CODEWIKI_LANGUAGES = /* @__PURE__ */ new Set([
2806
+ "typescript",
2807
+ "javascript",
2808
+ "python",
2809
+ "rust",
2810
+ "go",
2811
+ "c",
2812
+ "c++",
2813
+ "java",
2814
+ "ruby",
2815
+ "c#",
2816
+ "config"
2817
+ ]);
2818
+ var FILE_ROLES = /* @__PURE__ */ new Set(["entry", "test", "module", "config"]);
2819
+ var SYMBOL_KINDS = /* @__PURE__ */ new Set(["func", "class", "method", "type", "const", "var", "trait", "iface"]);
2820
+ function isCodewikiFile(value) {
2821
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2822
+ const obj = value;
2823
+ return typeof obj.id === "string" && typeof obj.path === "string" && typeof obj.lang === "string" && CODEWIKI_LANGUAGES.has(obj.lang) && typeof obj.loc === "number" && Number.isInteger(obj.loc) && obj.loc >= 0 && typeof obj.role === "string" && FILE_ROLES.has(obj.role) && typeof obj.hash === "string" && Array.isArray(obj.imports) && obj.imports.every((item) => typeof item === "string") && (!("summary" in obj) || typeof obj.summary === "string");
2824
+ }
2825
+ function isCodewikiFileV3(value) {
2826
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2827
+ const obj = value;
2828
+ return typeof obj.id === "string" && typeof obj.path === "string" && typeof obj.lang === "string" && CODEWIKI_LANGUAGES.has(obj.lang) && typeof obj.loc === "number" && Number.isInteger(obj.loc) && obj.loc >= 0 && typeof obj.role === "string" && FILE_ROLES.has(obj.role);
2829
+ }
2830
+ function isCodewikiSymbol(value) {
2831
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2832
+ const obj = value;
2833
+ return typeof obj.name === "string" && typeof obj.kind === "string" && SYMBOL_KINDS.has(obj.kind) && typeof obj.fileId === "string" && typeof obj.line === "number" && Number.isInteger(obj.line) && obj.line >= 1 && (!("sig" in obj) || typeof obj.sig === "string");
2834
+ }
2835
+ function isCodewikiEdge(value) {
2836
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2837
+ const obj = value;
2838
+ if (typeof obj.fileId !== "string") return false;
2839
+ const hasToFile = typeof obj.toFileId === "string";
2840
+ const hasExternal = typeof obj.externalModule === "string";
2841
+ return hasToFile !== hasExternal;
2842
+ }
2843
+ function isCodewikiEntry(value) {
2844
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
2845
+ const obj = value;
2846
+ if (typeof obj.path !== "string") return false;
2847
+ if (!Array.isArray(obj.exports) || obj.exports.some((item) => typeof item !== "string")) return false;
2848
+ if (!Array.isArray(obj.imports) || obj.imports.some((item) => typeof item !== "string")) return false;
2849
+ if (obj.kind !== "entry-point" && obj.kind !== "test" && obj.kind !== "module") return false;
2850
+ if ("summary" in obj && typeof obj.summary !== "string") return false;
2851
+ return true;
2852
+ }
2853
+
2854
+ export {
2855
+ WORKSPACE_EXCLUDED_DIRS,
2856
+ enumerateWorkspaceFiles,
2857
+ enumerateWorkspaceFilesAsync,
2858
+ detectProjectProfile,
2859
+ detectProjectType,
2860
+ INDEX_SLICE_MS,
2861
+ createSlicer,
2862
+ CODEWIKI_VERSION,
2863
+ isIndexablePath,
2864
+ buildCodewiki,
2865
+ updateCodewikiPaths,
2866
+ syncCodewiki,
2867
+ codewikiPath,
2868
+ writeCodewiki,
2869
+ parseCodewikiRaw,
2870
+ readCodewiki,
2871
+ readCodewikiAsync,
2872
+ codewikiEntries,
2873
+ codewikiNeedsBackfill,
2874
+ structuralCodewikiHash
2875
+ };
2876
+ //# sourceMappingURL=chunk-TPOCL34A.js.map