@rkarim08/sia 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/.claude-plugin/marketplace.json +35 -0
  2. package/.claude-plugin/plugin.json +27 -0
  3. package/.mcp.json +13 -0
  4. package/CLAUDE.md +226 -0
  5. package/LICENSE +202 -0
  6. package/PLUGIN_README.md +253 -0
  7. package/README.md +1013 -0
  8. package/agents/sia-changelog-writer.md +89 -0
  9. package/agents/sia-code-reviewer.md +86 -0
  10. package/agents/sia-conflict-resolver.md +100 -0
  11. package/agents/sia-convention-enforcer.md +69 -0
  12. package/agents/sia-debug.md +106 -0
  13. package/agents/sia-decision-reviewer.md +101 -0
  14. package/agents/sia-dependency-tracker.md +80 -0
  15. package/agents/sia-explain.md +126 -0
  16. package/agents/sia-feature.md +116 -0
  17. package/agents/sia-knowledge-capture.md +117 -0
  18. package/agents/sia-lead-architecture-advisor.md +93 -0
  19. package/agents/sia-lead-team-health.md +107 -0
  20. package/agents/sia-migration.md +100 -0
  21. package/agents/sia-onboarding.md +115 -0
  22. package/agents/sia-orientation.md +99 -0
  23. package/agents/sia-pm-briefing.md +106 -0
  24. package/agents/sia-pm-risk-advisor.md +82 -0
  25. package/agents/sia-qa-analyst.md +116 -0
  26. package/agents/sia-qa-regression-map.md +94 -0
  27. package/agents/sia-refactor.md +115 -0
  28. package/agents/sia-regression.md +112 -0
  29. package/agents/sia-security-audit.md +125 -0
  30. package/agents/sia-test-advisor.md +91 -0
  31. package/hooks/hooks.json +98 -0
  32. package/migrations/bridge/001_initial.sql +34 -0
  33. package/migrations/episodic/001_initial.sql +35 -0
  34. package/migrations/meta/001_initial.sql +68 -0
  35. package/migrations/semantic/001_initial.sql +292 -0
  36. package/migrations/semantic/002_ontology.sql +89 -0
  37. package/migrations/semantic/003_freshness.sql +63 -0
  38. package/migrations/semantic/004_v5_unified_schema.sql +194 -0
  39. package/migrations/semantic/005_backfill_event_kinds.sql +8 -0
  40. package/migrations/semantic/006_tree_sitter.sql +6 -0
  41. package/migrations/semantic/007_branch_snapshots.sql +22 -0
  42. package/package.json +110 -0
  43. package/scripts/branch-switch.sh +13 -0
  44. package/scripts/build-wasm-grammars.sh +81 -0
  45. package/scripts/post-compact.sh +8 -0
  46. package/scripts/post-tool-use.sh +10 -0
  47. package/scripts/pre-compact.sh +8 -0
  48. package/scripts/session-end.sh +8 -0
  49. package/scripts/session-start.sh +8 -0
  50. package/scripts/start-mcp.ts +45 -0
  51. package/scripts/stop-hook.sh +8 -0
  52. package/scripts/user-prompt-submit.sh +8 -0
  53. package/scripts/viz-server.ts +152 -0
  54. package/skills/sia-brainstorm/SKILL.md +156 -0
  55. package/skills/sia-brainstorm/scripts/frame-template.html +214 -0
  56. package/skills/sia-brainstorm/scripts/helper.js +95 -0
  57. package/skills/sia-brainstorm/scripts/server.cjs +338 -0
  58. package/skills/sia-brainstorm/scripts/start-server.sh +153 -0
  59. package/skills/sia-brainstorm/scripts/stop-server.sh +55 -0
  60. package/skills/sia-brainstorm/spec-document-reviewer-prompt.md +49 -0
  61. package/skills/sia-brainstorm/visual-companion.md +286 -0
  62. package/skills/sia-capture/SKILL.md +64 -0
  63. package/skills/sia-compare/SKILL.md +33 -0
  64. package/skills/sia-conflicts/SKILL.md +38 -0
  65. package/skills/sia-debug-workflow/SKILL.md +120 -0
  66. package/skills/sia-debug-workflow/root-cause-tracing.md +70 -0
  67. package/skills/sia-debug-workflow/scripts/find-polluter.sh +64 -0
  68. package/skills/sia-debug-workflow/temporal-investigation.md +72 -0
  69. package/skills/sia-digest/SKILL.md +23 -0
  70. package/skills/sia-dispatch/SKILL.md +69 -0
  71. package/skills/sia-dispatch/agent-task-template.md +99 -0
  72. package/skills/sia-doctor/SKILL.md +39 -0
  73. package/skills/sia-execute/SKILL.md +70 -0
  74. package/skills/sia-execute-plan/SKILL.md +85 -0
  75. package/skills/sia-export-import/SKILL.md +49 -0
  76. package/skills/sia-export-knowledge/SKILL.md +46 -0
  77. package/skills/sia-finish/SKILL.md +100 -0
  78. package/skills/sia-finish/pr-summary-template.md +54 -0
  79. package/skills/sia-freshness/SKILL.md +38 -0
  80. package/skills/sia-history/SKILL.md +42 -0
  81. package/skills/sia-impact/SKILL.md +70 -0
  82. package/skills/sia-index/SKILL.md +54 -0
  83. package/skills/sia-install/SKILL.md +39 -0
  84. package/skills/sia-lead-compliance/SKILL.md +16 -0
  85. package/skills/sia-lead-drift-report/SKILL.md +16 -0
  86. package/skills/sia-lead-knowledge-map/SKILL.md +16 -0
  87. package/skills/sia-learn/SKILL.md +58 -0
  88. package/skills/sia-plan/SKILL.md +68 -0
  89. package/skills/sia-plan/plan-reviewer-prompt.md +63 -0
  90. package/skills/sia-playbooks/SKILL.md +29 -0
  91. package/skills/sia-playbooks/reference-feature.md +100 -0
  92. package/skills/sia-playbooks/reference-flagging.md +50 -0
  93. package/skills/sia-playbooks/reference-orientation.md +92 -0
  94. package/skills/sia-playbooks/reference-regression.md +115 -0
  95. package/skills/sia-playbooks/reference-review.md +64 -0
  96. package/skills/sia-playbooks/reference-tools.md +239 -0
  97. package/skills/sia-pm-decision-log/SKILL.md +28 -0
  98. package/skills/sia-pm-risk-dashboard/SKILL.md +24 -0
  99. package/skills/sia-pm-sprint-summary/SKILL.md +27 -0
  100. package/skills/sia-prune/SKILL.md +45 -0
  101. package/skills/sia-qa-coverage/SKILL.md +28 -0
  102. package/skills/sia-qa-flaky/SKILL.md +20 -0
  103. package/skills/sia-qa-report/SKILL.md +26 -0
  104. package/skills/sia-reindex/SKILL.md +30 -0
  105. package/skills/sia-review-respond/SKILL.md +88 -0
  106. package/skills/sia-review-respond/pushback-patterns.md +90 -0
  107. package/skills/sia-search/SKILL.md +47 -0
  108. package/skills/sia-setup/SKILL.md +82 -0
  109. package/skills/sia-setup/setup-checklist.md +97 -0
  110. package/skills/sia-stats/SKILL.md +36 -0
  111. package/skills/sia-status/SKILL.md +44 -0
  112. package/skills/sia-sync/SKILL.md +46 -0
  113. package/skills/sia-team/SKILL.md +64 -0
  114. package/skills/sia-test/SKILL.md +92 -0
  115. package/skills/sia-test/testing-anti-patterns.md +104 -0
  116. package/skills/sia-tour/SKILL.md +29 -0
  117. package/skills/sia-upgrade/SKILL.md +43 -0
  118. package/skills/sia-verify/SKILL.md +81 -0
  119. package/skills/sia-visualize/SKILL.md +28 -0
  120. package/skills/sia-visualize-live/SKILL.md +55 -0
  121. package/skills/sia-visualize-live/scripts/graph-template.html +389 -0
  122. package/skills/sia-visualize-live/scripts/start-visualizer.sh +161 -0
  123. package/skills/sia-visualize-live/scripts/stop-visualizer.sh +55 -0
  124. package/skills/sia-visualize-live/scripts/visualizer-server.cjs +264 -0
  125. package/skills/sia-workspace/SKILL.md +57 -0
  126. package/src/agent/claude-md-template-flagging.md +219 -0
  127. package/src/agent/claude-md-template.md +213 -0
  128. package/src/agent/modules/sia-feature.md +100 -0
  129. package/src/agent/modules/sia-flagging.md +50 -0
  130. package/src/agent/modules/sia-orientation.md +92 -0
  131. package/src/agent/modules/sia-regression.md +115 -0
  132. package/src/agent/modules/sia-review.md +64 -0
  133. package/src/agent/modules/sia-tools.md +239 -0
  134. package/src/ast/extractors/c-include.ts +189 -0
  135. package/src/ast/extractors/csharp-project.ts +260 -0
  136. package/src/ast/extractors/prisma-schema.ts +44 -0
  137. package/src/ast/extractors/project-manifest.ts +111 -0
  138. package/src/ast/extractors/sql-schema.ts +67 -0
  139. package/src/ast/extractors/tier-a.ts +423 -0
  140. package/src/ast/extractors/tier-b.ts +289 -0
  141. package/src/ast/extractors/tier-dispatch.ts +247 -0
  142. package/src/ast/index-worker.ts +108 -0
  143. package/src/ast/indexer.ts +484 -0
  144. package/src/ast/languages.ts +408 -0
  145. package/src/ast/pagerank-builder.ts +125 -0
  146. package/src/ast/path-utils.ts +137 -0
  147. package/src/ast/tree-sitter/backends/native.ts +57 -0
  148. package/src/ast/tree-sitter/backends/wasm.ts +39 -0
  149. package/src/ast/tree-sitter/call-walker.ts +44 -0
  150. package/src/ast/tree-sitter/edit-computer.ts +55 -0
  151. package/src/ast/tree-sitter/query-runner.ts +46 -0
  152. package/src/ast/tree-sitter/service.ts +174 -0
  153. package/src/ast/tree-sitter/tree-cache.ts +39 -0
  154. package/src/ast/tree-sitter/types.ts +79 -0
  155. package/src/ast/watcher.ts +322 -0
  156. package/src/capture/chunker.ts +169 -0
  157. package/src/capture/consolidate.ts +127 -0
  158. package/src/capture/edge-inferrer.ts +161 -0
  159. package/src/capture/embedder.ts +166 -0
  160. package/src/capture/embedding-cache.ts +73 -0
  161. package/src/capture/flag-processor.ts +64 -0
  162. package/src/capture/hook.ts +67 -0
  163. package/src/capture/pipeline.ts +450 -0
  164. package/src/capture/prompts/consolidate.ts +25 -0
  165. package/src/capture/prompts/edge-infer.ts +29 -0
  166. package/src/capture/prompts/extract-flagged.ts +36 -0
  167. package/src/capture/prompts/extract.ts +42 -0
  168. package/src/capture/tokenizer.ts +147 -0
  169. package/src/capture/track-a-ast.ts +93 -0
  170. package/src/capture/track-b-llm.ts +149 -0
  171. package/src/capture/types.ts +64 -0
  172. package/src/cli/commands/community.ts +137 -0
  173. package/src/cli/commands/compare.ts +123 -0
  174. package/src/cli/commands/conflicts.ts +41 -0
  175. package/src/cli/commands/digest.ts +197 -0
  176. package/src/cli/commands/disable-flagging.ts +34 -0
  177. package/src/cli/commands/doctor.ts +240 -0
  178. package/src/cli/commands/download-model.ts +161 -0
  179. package/src/cli/commands/enable-flagging.ts +34 -0
  180. package/src/cli/commands/export-knowledge.ts +208 -0
  181. package/src/cli/commands/export.ts +85 -0
  182. package/src/cli/commands/freshness.ts +164 -0
  183. package/src/cli/commands/graph.ts +51 -0
  184. package/src/cli/commands/history.ts +139 -0
  185. package/src/cli/commands/import.ts +335 -0
  186. package/src/cli/commands/install.ts +156 -0
  187. package/src/cli/commands/lead-report.ts +241 -0
  188. package/src/cli/commands/learn.ts +321 -0
  189. package/src/cli/commands/pm-report.ts +413 -0
  190. package/src/cli/commands/prune.ts +75 -0
  191. package/src/cli/commands/qa-report.ts +278 -0
  192. package/src/cli/commands/reindex.ts +104 -0
  193. package/src/cli/commands/rollback.ts +70 -0
  194. package/src/cli/commands/search.ts +103 -0
  195. package/src/cli/commands/server.ts +91 -0
  196. package/src/cli/commands/share.ts +33 -0
  197. package/src/cli/commands/stats.ts +79 -0
  198. package/src/cli/commands/status.ts +176 -0
  199. package/src/cli/commands/sync.ts +96 -0
  200. package/src/cli/commands/team.ts +118 -0
  201. package/src/cli/commands/tour.ts +157 -0
  202. package/src/cli/commands/visualize-live.ts +162 -0
  203. package/src/cli/commands/workspace.ts +117 -0
  204. package/src/cli/index.ts +424 -0
  205. package/src/cli/learn-progress.ts +87 -0
  206. package/src/community/detection-bridge.ts +344 -0
  207. package/src/community/leiden.ts +462 -0
  208. package/src/community/raptor.ts +210 -0
  209. package/src/community/scheduler.ts +74 -0
  210. package/src/community/summarize.ts +115 -0
  211. package/src/decay/archiver.ts +73 -0
  212. package/src/decay/bridge-orphan-cleanup.ts +212 -0
  213. package/src/decay/consolidation-sweep.ts +112 -0
  214. package/src/decay/decay.ts +116 -0
  215. package/src/decay/deep-validator.ts +62 -0
  216. package/src/decay/episodic-promoter.ts +132 -0
  217. package/src/decay/maintenance-scheduler.ts +326 -0
  218. package/src/decay/scheduler.ts +6 -0
  219. package/src/decay/session-sweeper.ts +79 -0
  220. package/src/decay/types.ts +17 -0
  221. package/src/freshness/confidence-decay.ts +122 -0
  222. package/src/freshness/cuckoo-filter.ts +176 -0
  223. package/src/freshness/deep-validation.ts +345 -0
  224. package/src/freshness/dirty-tracker.ts +237 -0
  225. package/src/freshness/file-watcher-layer.ts +119 -0
  226. package/src/freshness/firewall.ts +64 -0
  227. package/src/freshness/git-reconcile-layer.ts +161 -0
  228. package/src/freshness/inverted-index.ts +158 -0
  229. package/src/freshness/stale-read-layer.ts +222 -0
  230. package/src/graph/audit.ts +69 -0
  231. package/src/graph/bridge-db.ts +141 -0
  232. package/src/graph/communities.ts +195 -0
  233. package/src/graph/db-interface.ts +259 -0
  234. package/src/graph/edges.ts +163 -0
  235. package/src/graph/entities.ts +327 -0
  236. package/src/graph/episodic-db.ts +113 -0
  237. package/src/graph/flags.ts +31 -0
  238. package/src/graph/meta-db.ts +200 -0
  239. package/src/graph/semantic-db.ts +101 -0
  240. package/src/graph/session-resume.ts +56 -0
  241. package/src/graph/snapshots.ts +342 -0
  242. package/src/graph/staging.ts +151 -0
  243. package/src/graph/types.ts +128 -0
  244. package/src/hooks/adapters/claude-code.ts +21 -0
  245. package/src/hooks/adapters/cline.ts +43 -0
  246. package/src/hooks/adapters/cursor.ts +65 -0
  247. package/src/hooks/adapters/generic.ts +12 -0
  248. package/src/hooks/agent-detect.ts +34 -0
  249. package/src/hooks/claude-md-directives.ts +32 -0
  250. package/src/hooks/event-router.ts +182 -0
  251. package/src/hooks/extractors/pattern-detector.ts +111 -0
  252. package/src/hooks/handlers/post-compact.ts +30 -0
  253. package/src/hooks/handlers/post-tool-use.ts +403 -0
  254. package/src/hooks/handlers/pre-compact.ts +100 -0
  255. package/src/hooks/handlers/session-end.ts +47 -0
  256. package/src/hooks/handlers/session-start.ts +154 -0
  257. package/src/hooks/handlers/stop.ts +128 -0
  258. package/src/hooks/handlers/user-prompt-submit.ts +68 -0
  259. package/src/hooks/plugin-branch-switch.ts +68 -0
  260. package/src/hooks/plugin-common.ts +47 -0
  261. package/src/hooks/plugin-post-compact.ts +28 -0
  262. package/src/hooks/plugin-post-tool-use.ts +38 -0
  263. package/src/hooks/plugin-pre-compact.ts +37 -0
  264. package/src/hooks/plugin-session-end.ts +37 -0
  265. package/src/hooks/plugin-session-start.ts +75 -0
  266. package/src/hooks/plugin-stop.ts +61 -0
  267. package/src/hooks/plugin-user-prompt-submit.ts +47 -0
  268. package/src/hooks/types.ts +43 -0
  269. package/src/knowledge/discovery.ts +238 -0
  270. package/src/knowledge/external-refs.ts +98 -0
  271. package/src/knowledge/freshness.ts +221 -0
  272. package/src/knowledge/ingest.ts +330 -0
  273. package/src/knowledge/markdown-export.ts +229 -0
  274. package/src/knowledge/markdown-import.ts +359 -0
  275. package/src/knowledge/patterns.ts +74 -0
  276. package/src/knowledge/templates.ts +307 -0
  277. package/src/llm/ai-sdk-adapter.ts +46 -0
  278. package/src/llm/config.ts +88 -0
  279. package/src/llm/cost-tracker.ts +110 -0
  280. package/src/llm/prompts/extraction.ts +55 -0
  281. package/src/llm/prompts/summarization.ts +36 -0
  282. package/src/llm/prompts/validation.ts +37 -0
  283. package/src/llm/provider-registry.ts +68 -0
  284. package/src/llm/reliability.ts +179 -0
  285. package/src/llm/schemas.ts +52 -0
  286. package/src/mcp/freshness-annotator.ts +69 -0
  287. package/src/mcp/server.ts +949 -0
  288. package/src/mcp/tools/sia-ast-query.ts +225 -0
  289. package/src/mcp/tools/sia-at-time.ts +151 -0
  290. package/src/mcp/tools/sia-backlinks.ts +87 -0
  291. package/src/mcp/tools/sia-batch-execute.ts +169 -0
  292. package/src/mcp/tools/sia-by-file.ts +89 -0
  293. package/src/mcp/tools/sia-community.ts +113 -0
  294. package/src/mcp/tools/sia-doctor.ts +73 -0
  295. package/src/mcp/tools/sia-execute-file.ts +122 -0
  296. package/src/mcp/tools/sia-execute.ts +104 -0
  297. package/src/mcp/tools/sia-expand.ts +158 -0
  298. package/src/mcp/tools/sia-fetch-and-index.ts +241 -0
  299. package/src/mcp/tools/sia-flag.ts +65 -0
  300. package/src/mcp/tools/sia-index.ts +111 -0
  301. package/src/mcp/tools/sia-note.ts +134 -0
  302. package/src/mcp/tools/sia-search.ts +105 -0
  303. package/src/mcp/tools/sia-stats.ts +63 -0
  304. package/src/mcp/tools/sia-sync-status.ts +44 -0
  305. package/src/mcp/tools/sia-upgrade.ts +247 -0
  306. package/src/mcp/truncate.ts +231 -0
  307. package/src/native/bridge.ts +167 -0
  308. package/src/native/fallback-ast-diff.ts +144 -0
  309. package/src/native/fallback-graph.ts +325 -0
  310. package/src/ontology/constraints.ts +56 -0
  311. package/src/ontology/errors.ts +8 -0
  312. package/src/ontology/middleware.ts +266 -0
  313. package/src/retrieval/bm25-search.ts +151 -0
  314. package/src/retrieval/context-assembly.ts +76 -0
  315. package/src/retrieval/graph-traversal.ts +168 -0
  316. package/src/retrieval/pagerank.ts +40 -0
  317. package/src/retrieval/query-classifier.ts +106 -0
  318. package/src/retrieval/reranker.ts +156 -0
  319. package/src/retrieval/search.ts +236 -0
  320. package/src/retrieval/throttle.ts +102 -0
  321. package/src/retrieval/vector-search.ts +203 -0
  322. package/src/retrieval/workspace-search.ts +130 -0
  323. package/src/sandbox/context-mode.ts +285 -0
  324. package/src/sandbox/credential-pass.ts +55 -0
  325. package/src/sandbox/executor.ts +235 -0
  326. package/src/security/pattern-detector.ts +127 -0
  327. package/src/security/rule-of-two.ts +50 -0
  328. package/src/security/sanitize.ts +46 -0
  329. package/src/security/semantic-consistency.ts +93 -0
  330. package/src/security/staging-promoter.ts +154 -0
  331. package/src/shared/config.ts +302 -0
  332. package/src/shared/diagnostics.ts +210 -0
  333. package/src/shared/errors.ts +48 -0
  334. package/src/shared/git-utils.ts +143 -0
  335. package/src/shared/llm-client.ts +120 -0
  336. package/src/shared/logger.ts +99 -0
  337. package/src/shared/types.ts +79 -0
  338. package/src/sync/client.ts +43 -0
  339. package/src/sync/conflict.ts +106 -0
  340. package/src/sync/dedup.ts +183 -0
  341. package/src/sync/hlc.ts +117 -0
  342. package/src/sync/keychain.ts +144 -0
  343. package/src/sync/pull.ts +232 -0
  344. package/src/sync/push.ts +131 -0
  345. package/src/types/chokidar.d.ts +23 -0
  346. package/src/visualization/graph-renderer.ts +312 -0
  347. package/src/visualization/subgraph-extract.ts +208 -0
  348. package/src/visualization/views/community-clusters.ts +246 -0
  349. package/src/visualization/views/dependency-map.ts +189 -0
  350. package/src/visualization/views/graph-explorer.ts +364 -0
  351. package/src/visualization/views/timeline.ts +247 -0
  352. package/src/workspace/api-contracts.ts +226 -0
  353. package/src/workspace/cross-repo.ts +61 -0
  354. package/src/workspace/detector.ts +190 -0
  355. package/src/workspace/manifest.ts +141 -0
@@ -0,0 +1,260 @@
1
+ // Module: csharp-project — C# code entity extraction + .csproj dependency extraction
2
+
3
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
4
+ import { basename, dirname, extname, join } from "node:path";
5
+ import type { CandidateFact } from "@/capture/types";
6
+
7
+ // ─── Phase 1: C# code patterns ──────────────────────────────────────────────
8
+
9
+ /** Regex for C# methods (access modifier required). Capture group 2 = name.
10
+ * Return type allows generic forms like Task<string> or List<T>. */
11
+ const METHOD_RE =
12
+ /(public|private|protected|internal|static|async|virtual|override|abstract)\s+\w+(?:<[^>]*>)?\s+(\w+)\s*\(/gm;
13
+
14
+ /** Regex for C# class / interface / struct / enum / record declarations. Capture group 2 = name. */
15
+ const CLASS_RE = /(class|interface|struct|enum|record)\s+(\w+)/gm;
16
+
17
+ /** Regex for C# auto-properties: `modifier type Name { get; set; }` on a single line.
18
+ * [^}\n] prevents crossing into multi-line class bodies. */
19
+ const PROPERTY_RE =
20
+ /(public|private|protected|internal)\s+[\w<>[\]?]+\s+(\w+)\s*\{[^}\n]*(?:get|set)[^}\n]*\}/gm;
21
+
22
+ /** Regex for C# using statements. Capture group 1 = namespace. */
23
+ const USING_RE = /^using\s+([\w.]+)\s*;/gm;
24
+
25
+ // ─── Phase 2: .csproj patterns ───────────────────────────────────────────────
26
+
27
+ /** ProjectReference Include="..." */
28
+ const PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
29
+
30
+ /** PackageReference Include="..." with optional Version="..." */
31
+ const PACKAGE_REF_RE = /<PackageReference\s+Include="([^"]+)"(?:[^/]*?Version="([^"]+)")?/g;
32
+
33
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
34
+
35
+ /**
36
+ * Walk UP from startDir looking for a .csproj file in each directory.
37
+ * Stops at repoRoot or after maxLevels iterations.
38
+ */
39
+ function findCsprojFile(startDir: string, repoRoot: string, maxLevels = 5): string | null {
40
+ let current = startDir;
41
+
42
+ for (let level = 0; level < maxLevels; level++) {
43
+ let entries: string[] = [];
44
+ try {
45
+ entries = readdirSync(current) as string[];
46
+ } catch {
47
+ return null;
48
+ }
49
+
50
+ const csproj = entries.find((e) => e.endsWith(".csproj"));
51
+ if (csproj) {
52
+ const fullPath = join(current, csproj);
53
+ if (existsSync(fullPath)) {
54
+ return fullPath;
55
+ }
56
+ }
57
+
58
+ if (current === repoRoot) break;
59
+
60
+ const parent = dirname(current);
61
+ if (parent === current) break;
62
+ current = parent;
63
+ }
64
+
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * Extract C# code entities from .cs source and project dependencies from an
70
+ * adjacent .csproj file.
71
+ *
72
+ * Phase 1: methods, classes/interfaces/structs/enums/records, properties, usings.
73
+ * Phase 2: walks up directories to find a .csproj, then extracts ProjectReference
74
+ * and PackageReference entries.
75
+ */
76
+ export function extractCSharpProject(
77
+ content: string,
78
+ filePath: string,
79
+ repoRoot?: string,
80
+ ): CandidateFact[] {
81
+ if (extname(filePath).toLowerCase() !== ".cs") return [];
82
+ if (!content) return [];
83
+
84
+ const base = basename(filePath);
85
+ const facts: CandidateFact[] = [];
86
+ const seen = new Set<string>();
87
+
88
+ // ── Phase 1: code entity extraction ──────────────────────────────────────
89
+
90
+ // Methods
91
+ {
92
+ const re = new RegExp(METHOD_RE.source, METHOD_RE.flags);
93
+ let m = re.exec(content);
94
+ while (m !== null) {
95
+ const name = m[2];
96
+ if (name) {
97
+ const key = `method:${name}`;
98
+ if (!seen.has(key)) {
99
+ seen.add(key);
100
+ facts.push({
101
+ type: "CodeEntity",
102
+ name,
103
+ content: m[0].trim(),
104
+ summary: `method ${name} in ${base}`,
105
+ tags: ["csharp", "method"],
106
+ file_paths: [filePath],
107
+ trust_tier: 2,
108
+ confidence: 0.92,
109
+ });
110
+ }
111
+ }
112
+ m = re.exec(content);
113
+ }
114
+ }
115
+
116
+ // Classes, interfaces, structs, enums, records
117
+ {
118
+ const re = new RegExp(CLASS_RE.source, CLASS_RE.flags);
119
+ let m = re.exec(content);
120
+ while (m !== null) {
121
+ const kind = m[1];
122
+ const name = m[2];
123
+ if (name && kind) {
124
+ const key = `class:${name}`;
125
+ if (!seen.has(key)) {
126
+ seen.add(key);
127
+ facts.push({
128
+ type: "CodeEntity",
129
+ name,
130
+ content: m[0].trim(),
131
+ summary: `${kind} ${name} in ${base}`,
132
+ tags: ["csharp", "class"],
133
+ file_paths: [filePath],
134
+ trust_tier: 2,
135
+ confidence: 0.92,
136
+ });
137
+ }
138
+ }
139
+ m = re.exec(content);
140
+ }
141
+ }
142
+
143
+ // Properties
144
+ {
145
+ const re = new RegExp(PROPERTY_RE.source, PROPERTY_RE.flags);
146
+ let m = re.exec(content);
147
+ while (m !== null) {
148
+ const name = m[2];
149
+ if (name) {
150
+ const key = `property:${name}`;
151
+ if (!seen.has(key)) {
152
+ seen.add(key);
153
+ facts.push({
154
+ type: "CodeEntity",
155
+ name,
156
+ content: m[0].trim(),
157
+ summary: `property ${name} in ${base}`,
158
+ tags: ["csharp", "property"],
159
+ file_paths: [filePath],
160
+ trust_tier: 2,
161
+ confidence: 0.92,
162
+ });
163
+ }
164
+ }
165
+ m = re.exec(content);
166
+ }
167
+ }
168
+
169
+ // Using statements
170
+ {
171
+ const re = new RegExp(USING_RE.source, USING_RE.flags);
172
+ let m = re.exec(content);
173
+ while (m !== null) {
174
+ const name = m[1];
175
+ if (name) {
176
+ const key = `using:${name}`;
177
+ if (!seen.has(key)) {
178
+ seen.add(key);
179
+ facts.push({
180
+ type: "CodeEntity",
181
+ name,
182
+ content: m[0].trim(),
183
+ summary: `using ${name} in ${base}`,
184
+ tags: ["csharp", "using"],
185
+ file_paths: [filePath],
186
+ trust_tier: 2,
187
+ confidence: 0.92,
188
+ });
189
+ }
190
+ }
191
+ m = re.exec(content);
192
+ }
193
+ }
194
+
195
+ // ── Phase 2: .csproj dependency extraction ────────────────────────────────
196
+
197
+ const searchRoot = repoRoot ?? dirname(filePath);
198
+ const csprojPath = findCsprojFile(dirname(filePath), searchRoot);
199
+
200
+ if (csprojPath) {
201
+ let csprojContent: string;
202
+ try {
203
+ csprojContent = readFileSync(csprojPath, "utf8") as string;
204
+ } catch {
205
+ return facts;
206
+ }
207
+
208
+ // ProjectReference entries
209
+ {
210
+ const re = new RegExp(PROJECT_REF_RE.source, PROJECT_REF_RE.flags);
211
+ let m = re.exec(csprojContent);
212
+ while (m !== null) {
213
+ const include = m[1];
214
+ if (include) {
215
+ facts.push({
216
+ type: "Dependency",
217
+ name: include,
218
+ content: m[0].trim(),
219
+ summary: `ProjectReference ${include} in ${basename(csprojPath)}`,
220
+ tags: ["project-reference", "csharp"],
221
+ file_paths: [filePath, csprojPath],
222
+ trust_tier: 2,
223
+ confidence: 0.9,
224
+ extraction_method: "csharp-project",
225
+ });
226
+ }
227
+ m = re.exec(csprojContent);
228
+ }
229
+ }
230
+
231
+ // PackageReference entries
232
+ {
233
+ const re = new RegExp(PACKAGE_REF_RE.source, PACKAGE_REF_RE.flags);
234
+ let m = re.exec(csprojContent);
235
+ while (m !== null) {
236
+ const pkgName = m[1];
237
+ const version = m[2];
238
+ if (pkgName) {
239
+ const contentStr = version ? `${pkgName} ${version}` : pkgName;
240
+ facts.push({
241
+ type: "Dependency",
242
+ name: pkgName,
243
+ content: contentStr,
244
+ summary: version
245
+ ? `PackageReference ${pkgName} v${version} in ${basename(csprojPath)}`
246
+ : `PackageReference ${pkgName} in ${basename(csprojPath)}`,
247
+ tags: ["package-reference", "csharp", "nuget"],
248
+ file_paths: [filePath, csprojPath],
249
+ trust_tier: 2,
250
+ confidence: 0.9,
251
+ extraction_method: "csharp-project",
252
+ });
253
+ }
254
+ m = re.exec(csprojContent);
255
+ }
256
+ }
257
+ }
258
+
259
+ return facts;
260
+ }
@@ -0,0 +1,44 @@
1
+ // Module: prisma-schema — Regex-based Prisma model extraction
2
+
3
+ import type { CandidateFact } from "@/capture/types";
4
+
5
+ /**
6
+ * Extract model entities from Prisma schema files using regex patterns.
7
+ * Recognises `model <Name> { ... }` blocks.
8
+ */
9
+ export function extractPrismaSchema(content: string, filePath: string): CandidateFact[] {
10
+ const facts: CandidateFact[] = [];
11
+
12
+ const modelRe = /model\s+(\w+)\s*\{([^}]*)}/g;
13
+ let match: RegExpExecArray | null = modelRe.exec(content);
14
+ while (match !== null) {
15
+ const name = match[1];
16
+ const body = match[2].trim();
17
+
18
+ // Build a summary from the field lines
19
+ const fields = body
20
+ .split("\n")
21
+ .map((l) => l.trim())
22
+ .filter((l) => l.length > 0 && !l.startsWith("//") && !l.startsWith("@@"));
23
+
24
+ const summary =
25
+ fields.length > 0
26
+ ? `Prisma model ${name}: ${fields.slice(0, 5).join(", ")}${fields.length > 5 ? "..." : ""}`
27
+ : `Prisma model: ${name}`;
28
+
29
+ facts.push({
30
+ type: "CodeEntity",
31
+ name,
32
+ content: match[0],
33
+ summary,
34
+ tags: ["model"],
35
+ file_paths: [filePath],
36
+ trust_tier: 2,
37
+ confidence: 0.9,
38
+ extraction_method: "prisma-schema",
39
+ });
40
+ match = modelRe.exec(content);
41
+ }
42
+
43
+ return facts;
44
+ }
@@ -0,0 +1,111 @@
1
+ // Module: project-manifest — Cargo.toml/go.mod/pyproject.toml dependency extraction
2
+
3
+ import { basename } from "node:path";
4
+ import type { CandidateFact } from "@/capture/types";
5
+
6
+ /**
7
+ * Extract dependency / workspace-member facts from project manifest files.
8
+ *
9
+ * Supported formats:
10
+ * - Cargo.toml: `members = ["pkg-a", "pkg-b"]` under [workspace]
11
+ * - go.mod: `replace ... => <local-path>` directives
12
+ * - pyproject.toml: `path = "..."` dependency references
13
+ */
14
+ export function extractManifest(content: string, filePath: string): CandidateFact[] {
15
+ const file = basename(filePath).toLowerCase();
16
+
17
+ if (file === "cargo.toml") {
18
+ return extractCargoMembers(content, filePath);
19
+ }
20
+ if (file === "go.mod") {
21
+ return extractGoModReplace(content, filePath);
22
+ }
23
+ if (file === "pyproject.toml" || file === "setup.py" || file === "setup.cfg") {
24
+ return extractPyprojectPaths(content, filePath);
25
+ }
26
+
27
+ return [];
28
+ }
29
+
30
+ /** Extract workspace members from Cargo.toml */
31
+ function extractCargoMembers(content: string, filePath: string): CandidateFact[] {
32
+ const facts: CandidateFact[] = [];
33
+
34
+ // Match members = ["a", "b", "c"] -- possibly multiline
35
+ const membersRe = /members\s*=\s*\[([^\]]*)\]/gs;
36
+ let match: RegExpExecArray | null = membersRe.exec(content);
37
+ while (match !== null) {
38
+ const block = match[1];
39
+ const entryRe = /"([^"]+)"/g;
40
+ let entry: RegExpExecArray | null = entryRe.exec(block);
41
+ while (entry !== null) {
42
+ facts.push({
43
+ type: "Dependency",
44
+ name: entry[1],
45
+ content: `workspace member: ${entry[1]}`,
46
+ summary: `Cargo workspace member: ${entry[1]}`,
47
+ tags: ["workspace-member"],
48
+ file_paths: [filePath],
49
+ trust_tier: 2,
50
+ confidence: 0.85,
51
+ extraction_method: "manifest",
52
+ });
53
+ entry = entryRe.exec(block);
54
+ }
55
+ match = membersRe.exec(content);
56
+ }
57
+
58
+ return facts;
59
+ }
60
+
61
+ /** Extract replace directives from go.mod */
62
+ function extractGoModReplace(content: string, filePath: string): CandidateFact[] {
63
+ const facts: CandidateFact[] = [];
64
+
65
+ // replace <module> => <local-path>
66
+ const replaceRe = /replace\s+\S+\s+=>\s+(\S+)/gm;
67
+ let match: RegExpExecArray | null = replaceRe.exec(content);
68
+ while (match !== null) {
69
+ const localPath = match[1];
70
+ facts.push({
71
+ type: "Dependency",
72
+ name: localPath,
73
+ content: match[0],
74
+ summary: `go.mod replace: ${localPath}`,
75
+ tags: ["replace"],
76
+ file_paths: [filePath],
77
+ trust_tier: 2,
78
+ confidence: 0.85,
79
+ extraction_method: "manifest",
80
+ });
81
+ match = replaceRe.exec(content);
82
+ }
83
+
84
+ return facts;
85
+ }
86
+
87
+ /** Extract path dependencies from pyproject.toml */
88
+ function extractPyprojectPaths(content: string, filePath: string): CandidateFact[] {
89
+ const facts: CandidateFact[] = [];
90
+
91
+ // path = "some/local/path"
92
+ const pathRe = /path\s*=\s*"([^"]+)"/g;
93
+ let match: RegExpExecArray | null = pathRe.exec(content);
94
+ while (match !== null) {
95
+ const localPath = match[1];
96
+ facts.push({
97
+ type: "Dependency",
98
+ name: localPath,
99
+ content: match[0],
100
+ summary: `pyproject path dependency: ${localPath}`,
101
+ tags: ["path-dependency"],
102
+ file_paths: [filePath],
103
+ trust_tier: 2,
104
+ confidence: 0.85,
105
+ extraction_method: "manifest",
106
+ });
107
+ match = pathRe.exec(content);
108
+ }
109
+
110
+ return facts;
111
+ }
@@ -0,0 +1,67 @@
1
+ // Module: sql-schema — Regex-based SQL CREATE TABLE/INDEX extraction
2
+
3
+ import type { CandidateFact } from "@/capture/types";
4
+
5
+ /**
6
+ * Extract schema entities from SQL files using regex patterns.
7
+ * Recognises CREATE TABLE and CREATE INDEX statements.
8
+ */
9
+ export function extractSqlSchema(content: string, filePath: string): CandidateFact[] {
10
+ const facts: CandidateFact[] = [];
11
+
12
+ // CREATE TABLE
13
+ const tableRe = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(\w+)/gi;
14
+ let match: RegExpExecArray | null = tableRe.exec(content);
15
+ while (match !== null) {
16
+ const name = match[1];
17
+ facts.push({
18
+ type: "CodeEntity",
19
+ name,
20
+ content: surroundingContext(content, match.index),
21
+ summary: `SQL table: ${name}`,
22
+ tags: ["table"],
23
+ file_paths: [filePath],
24
+ trust_tier: 2,
25
+ confidence: 0.9,
26
+ extraction_method: "sql-schema",
27
+ });
28
+ match = tableRe.exec(content);
29
+ }
30
+
31
+ // CREATE INDEX
32
+ const indexRe = /CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?(\w+)/gi;
33
+ let idxMatch: RegExpExecArray | null = indexRe.exec(content);
34
+ while (idxMatch !== null) {
35
+ const name = idxMatch[1];
36
+ facts.push({
37
+ type: "CodeEntity",
38
+ name,
39
+ content: surroundingContext(content, idxMatch.index),
40
+ summary: `SQL index: ${name}`,
41
+ tags: ["index"],
42
+ file_paths: [filePath],
43
+ trust_tier: 2,
44
+ confidence: 0.9,
45
+ extraction_method: "sql-schema",
46
+ });
47
+ idxMatch = indexRe.exec(content);
48
+ }
49
+
50
+ return facts;
51
+ }
52
+
53
+ /** Return a few lines surrounding the match position for context. */
54
+ function surroundingContext(content: string, matchIndex: number): string {
55
+ const before = content.lastIndexOf("\n", matchIndex);
56
+ const lineStart = before === -1 ? 0 : before + 1;
57
+ let end = matchIndex;
58
+ for (let i = 0; i < 5; i++) {
59
+ const next = content.indexOf("\n", end + 1);
60
+ if (next === -1) {
61
+ end = content.length;
62
+ break;
63
+ }
64
+ end = next;
65
+ }
66
+ return content.slice(lineStart, end).trim();
67
+ }