@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,167 @@
1
+ // Module: native/bridge — Single import site for the native performance module
2
+ // Three-tier fallback: native → wasm → typescript
3
+ //
4
+ // Since @sia/native and @sia/native-wasm do not exist yet, this always
5
+ // falls back to the pure TypeScript implementations.
6
+
7
+ import { fallbackAstDiff } from "./fallback-ast-diff";
8
+ import { fallbackGraphCompute } from "./fallback-graph";
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // Public types
12
+ // ---------------------------------------------------------------------------
13
+
14
+ export interface AstDiffResult {
15
+ inserts: Array<{ node_id: string; kind: string; name: string }>;
16
+ removes: Array<{ node_id: string }>;
17
+ updates: Array<{ node_id: string; old_name: string; new_name: string }>;
18
+ moves: Array<{ node_id: string; old_parent: string; new_parent: string }>;
19
+ }
20
+
21
+ export interface GraphComputeResult {
22
+ scores: Float64Array;
23
+ node_ids: string[];
24
+ }
25
+
26
+ export type GraphAlgorithm =
27
+ | { kind: "pagerank"; damping: number; iterations: number; seed_nodes?: string[] }
28
+ | { kind: "shortest_path"; source: string }
29
+ | { kind: "betweenness_centrality" }
30
+ | { kind: "connected_components" };
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // Tier detection
34
+ // ---------------------------------------------------------------------------
35
+
36
+ export type NativeModuleStatus = "native" | "wasm" | "typescript";
37
+
38
+ let _cachedStatus: NativeModuleStatus | null = null;
39
+
40
+ /**
41
+ * Probe the three tiers in order and return which one is available:
42
+ * 1. `@sia/native` — compiled Rust module
43
+ * 2. `@sia/native-wasm` — WASM build of the same Rust module
44
+ * 3. `typescript` — pure TS fallback (always available)
45
+ */
46
+ export function isNativeAvailable(): NativeModuleStatus {
47
+ return getNativeModuleStatus();
48
+ }
49
+
50
+ /**
51
+ * Detect which implementation is active:
52
+ * - "native" — native Rust module loaded successfully
53
+ * - "wasm" — WASM fallback loaded successfully
54
+ * - "typescript" — pure TypeScript fallback (no compiled module)
55
+ */
56
+ export function getNativeModuleStatus(): NativeModuleStatus {
57
+ if (_cachedStatus !== null) {
58
+ return _cachedStatus;
59
+ }
60
+
61
+ // Attempt to load the native Rust module
62
+ try {
63
+ require("@sia/native");
64
+ _cachedStatus = "native";
65
+ return _cachedStatus;
66
+ } catch {
67
+ // not installed
68
+ }
69
+
70
+ // Attempt to load the WASM build
71
+ try {
72
+ require("@sia/native-wasm");
73
+ _cachedStatus = "wasm";
74
+ return _cachedStatus;
75
+ } catch {
76
+ // not installed
77
+ }
78
+
79
+ // Pure TypeScript fallback
80
+ _cachedStatus = "typescript";
81
+ return _cachedStatus;
82
+ }
83
+
84
+ /**
85
+ * Reset the cached status (for testing).
86
+ */
87
+ export function _resetNativeStatusCache(): void {
88
+ _cachedStatus = null;
89
+ }
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // Lazy native module handle
93
+ // ---------------------------------------------------------------------------
94
+
95
+ interface NativeModule {
96
+ astDiff(
97
+ oldTreeBytes: Uint8Array,
98
+ newTreeBytes: Uint8Array,
99
+ nodeIdMap: Map<number, string>,
100
+ ): AstDiffResult;
101
+ graphCompute(edges: Int32Array, nodeIds: string[], algorithm: GraphAlgorithm): GraphComputeResult;
102
+ }
103
+
104
+ function loadNativeModule(pkg: string): NativeModule | null {
105
+ try {
106
+ return require(pkg) as NativeModule;
107
+ } catch {
108
+ return null;
109
+ }
110
+ }
111
+
112
+ // ---------------------------------------------------------------------------
113
+ // Public API — routes to the best available implementation
114
+ // ---------------------------------------------------------------------------
115
+
116
+ /**
117
+ * Diff two AST trees encoded as byte arrays.
118
+ *
119
+ * In the TypeScript fallback the bytes are JSON-encoded arrays of
120
+ * `{name, kind, parent}` objects. `nodeIdMap` maps positional indices in the
121
+ * old tree to stable node IDs.
122
+ */
123
+ export function astDiff(
124
+ oldTreeBytes: Uint8Array,
125
+ newTreeBytes: Uint8Array,
126
+ nodeIdMap: Map<number, string>,
127
+ ): AstDiffResult {
128
+ const tier = getNativeModuleStatus();
129
+
130
+ if (tier === "native") {
131
+ const mod = loadNativeModule("@sia/native");
132
+ if (mod) return mod.astDiff(oldTreeBytes, newTreeBytes, nodeIdMap);
133
+ }
134
+
135
+ if (tier === "wasm") {
136
+ const mod = loadNativeModule("@sia/native-wasm");
137
+ if (mod) return mod.astDiff(oldTreeBytes, newTreeBytes, nodeIdMap);
138
+ }
139
+
140
+ return fallbackAstDiff(oldTreeBytes, newTreeBytes, nodeIdMap);
141
+ }
142
+
143
+ /**
144
+ * Run a graph algorithm on a flat edge list.
145
+ *
146
+ * `edges` is a flat Int32Array of `[from, to, from, to, …]` pairs where
147
+ * indices refer to positions in `nodeIds`.
148
+ */
149
+ export function graphCompute(
150
+ edges: Int32Array,
151
+ nodeIds: string[],
152
+ algorithm: GraphAlgorithm,
153
+ ): GraphComputeResult {
154
+ const tier = getNativeModuleStatus();
155
+
156
+ if (tier === "native") {
157
+ const mod = loadNativeModule("@sia/native");
158
+ if (mod) return mod.graphCompute(edges, nodeIds, algorithm);
159
+ }
160
+
161
+ if (tier === "wasm") {
162
+ const mod = loadNativeModule("@sia/native-wasm");
163
+ if (mod) return mod.graphCompute(edges, nodeIds, algorithm);
164
+ }
165
+
166
+ return fallbackGraphCompute(edges, nodeIds, algorithm);
167
+ }
@@ -0,0 +1,144 @@
1
+ // Module: fallback-ast-diff — TypeScript fallback for AST diff
2
+ // Correctness over performance. For the native/wasm implementation see @sia/native.
3
+
4
+ import type { AstDiffResult } from "./bridge";
5
+
6
+ interface AstNode {
7
+ name: string;
8
+ kind: string;
9
+ parent: string | null;
10
+ }
11
+
12
+ function parseTree(bytes: Uint8Array): AstNode[] {
13
+ try {
14
+ const text = new TextDecoder().decode(bytes);
15
+ const parsed = JSON.parse(text) as unknown;
16
+ if (!Array.isArray(parsed)) return [];
17
+ return (parsed as unknown[]).map((item) => {
18
+ const obj = item as Record<string, unknown>;
19
+ return {
20
+ name: String(obj.name ?? ""),
21
+ kind: String(obj.kind ?? ""),
22
+ parent: obj.parent != null ? String(obj.parent) : null,
23
+ };
24
+ });
25
+ } catch {
26
+ return [];
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Name-based AST diff: compares two sets of extracted symbols to detect
32
+ * inserts, removes, updates, and moves.
33
+ *
34
+ * The old/new trees are encoded as JSON arrays of {name, kind, parent} objects.
35
+ * nodeIdMap maps positional indices to stable node IDs (used for removes).
36
+ */
37
+ export function fallbackAstDiff(
38
+ oldTreeBytes: Uint8Array,
39
+ newTreeBytes: Uint8Array,
40
+ nodeIdMap: Map<number, string>,
41
+ ): AstDiffResult {
42
+ const oldNodes = parseTree(oldTreeBytes);
43
+ const newNodes = parseTree(newTreeBytes);
44
+
45
+ // Index old nodes by name for O(1) lookup
46
+ const oldByName = new Map<string, { node: AstNode; index: number }[]>();
47
+ for (let i = 0; i < oldNodes.length; i++) {
48
+ const node = oldNodes[i];
49
+ if (!oldByName.has(node.name)) {
50
+ oldByName.set(node.name, []);
51
+ }
52
+ oldByName.get(node.name)?.push({ node, index: i });
53
+ }
54
+
55
+ // Index new nodes by name
56
+ const newByName = new Map<string, { node: AstNode; index: number }[]>();
57
+ for (let j = 0; j < newNodes.length; j++) {
58
+ const node = newNodes[j];
59
+ if (!newByName.has(node.name)) {
60
+ newByName.set(node.name, []);
61
+ }
62
+ newByName.get(node.name)?.push({ node, index: j });
63
+ }
64
+
65
+ const inserts: AstDiffResult["inserts"] = [];
66
+ const removes: AstDiffResult["removes"] = [];
67
+ const updates: AstDiffResult["updates"] = [];
68
+ const moves: AstDiffResult["moves"] = [];
69
+
70
+ // Track which old/new nodes have been matched
71
+ const matchedOld = new Set<number>();
72
+ const matchedNew = new Set<number>();
73
+
74
+ // Exact matches first: same name, kind, and parent
75
+ for (const [name, oldEntries] of oldByName) {
76
+ const newEntries = newByName.get(name);
77
+ if (!newEntries) continue;
78
+
79
+ for (const oldEntry of oldEntries) {
80
+ for (const newEntry of newEntries) {
81
+ if (matchedOld.has(oldEntry.index) || matchedNew.has(newEntry.index)) continue;
82
+ if (oldEntry.node.kind === newEntry.node.kind) {
83
+ matchedOld.add(oldEntry.index);
84
+ matchedNew.add(newEntry.index);
85
+ // Check for moves (same name+kind but different parent)
86
+ if (oldEntry.node.parent !== newEntry.node.parent) {
87
+ const nodeId = nodeIdMap.get(oldEntry.index) ?? `node-${oldEntry.index}`;
88
+ moves.push({
89
+ node_id: nodeId,
90
+ old_parent: oldEntry.node.parent ?? "",
91
+ new_parent: newEntry.node.parent ?? "",
92
+ });
93
+ }
94
+ break;
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ // Partial matches: same name, different kind (update)
101
+ for (const [name, oldEntries] of oldByName) {
102
+ const newEntries = newByName.get(name);
103
+ if (!newEntries) continue;
104
+
105
+ for (const oldEntry of oldEntries) {
106
+ if (matchedOld.has(oldEntry.index)) continue;
107
+ for (const newEntry of newEntries) {
108
+ if (matchedNew.has(newEntry.index)) continue;
109
+ // Different kind — treat as an update
110
+ const nodeId = nodeIdMap.get(oldEntry.index) ?? `node-${oldEntry.index}`;
111
+ updates.push({
112
+ node_id: nodeId,
113
+ old_name: oldEntry.node.name,
114
+ new_name: newEntry.node.name,
115
+ });
116
+ matchedOld.add(oldEntry.index);
117
+ matchedNew.add(newEntry.index);
118
+ break;
119
+ }
120
+ }
121
+ }
122
+
123
+ // Removes: unmatched old nodes
124
+ for (let i = 0; i < oldNodes.length; i++) {
125
+ if (!matchedOld.has(i)) {
126
+ const nodeId = nodeIdMap.get(i) ?? `node-${i}`;
127
+ removes.push({ node_id: nodeId });
128
+ }
129
+ }
130
+
131
+ // Inserts: unmatched new nodes
132
+ for (let j = 0; j < newNodes.length; j++) {
133
+ if (!matchedNew.has(j)) {
134
+ const node = newNodes[j];
135
+ inserts.push({
136
+ node_id: `new-${j}`,
137
+ kind: node.kind,
138
+ name: node.name,
139
+ });
140
+ }
141
+ }
142
+
143
+ return { inserts, removes, updates, moves };
144
+ }
@@ -0,0 +1,325 @@
1
+ // Module: fallback-graph — Pure TypeScript graph algorithm implementations
2
+ // Used when the native Rust module is unavailable.
3
+
4
+ import type { GraphAlgorithm, GraphComputeResult } from "./bridge";
5
+
6
+ // ---------------------------------------------------------------------------
7
+ // Internal helpers
8
+ // ---------------------------------------------------------------------------
9
+
10
+ /** Build adjacency list from flat Int32Array of [from, to] pairs. */
11
+ function buildAdjacency(edges: Int32Array, nodeCount: number): Map<number, number[]> {
12
+ const adj = new Map<number, number[]>();
13
+ for (let i = 0; i < nodeCount; i++) adj.set(i, []);
14
+
15
+ for (let i = 0; i < edges.length - 1; i += 2) {
16
+ const from = edges[i];
17
+ const to = edges[i + 1];
18
+ if (from >= 0 && to >= 0) {
19
+ adj.get(from)?.push(to);
20
+ }
21
+ }
22
+ return adj;
23
+ }
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // PageRank (power iteration)
27
+ // ---------------------------------------------------------------------------
28
+
29
+ function pagerank(
30
+ edges: Int32Array,
31
+ nodeIds: string[],
32
+ damping: number,
33
+ maxIterations: number,
34
+ _seedNodes?: string[],
35
+ ): Float64Array {
36
+ const n = nodeIds.length;
37
+ if (n === 0) return new Float64Array(0);
38
+
39
+ // outDegree[i] = number of out-edges from node i
40
+ const outDegree = new Int32Array(n);
41
+ for (let i = 0; i < edges.length - 1; i += 2) {
42
+ const from = edges[i];
43
+ if (from >= 0 && from < n) {
44
+ outDegree[from]++;
45
+ }
46
+ }
47
+
48
+ // Incoming edge map: to -> [from, ...]
49
+ const incoming = new Map<number, number[]>();
50
+ for (let i = 0; i < n; i++) incoming.set(i, []);
51
+ for (let i = 0; i < edges.length - 1; i += 2) {
52
+ const from = edges[i];
53
+ const to = edges[i + 1];
54
+ if (from >= 0 && to >= 0 && from < n && to < n) {
55
+ incoming.get(to)?.push(from);
56
+ }
57
+ }
58
+
59
+ let scores = new Float64Array(n).fill(1 / n);
60
+ const uniform = 1 / n;
61
+
62
+ for (let iter = 0; iter < maxIterations; iter++) {
63
+ const next = new Float64Array(n);
64
+
65
+ // Dangling node mass (nodes with no out-edges)
66
+ let dangling = 0;
67
+ for (let i = 0; i < n; i++) {
68
+ if (outDegree[i] === 0) dangling += scores[i];
69
+ }
70
+
71
+ for (let v = 0; v < n; v++) {
72
+ let rank = dangling * uniform; // spread dangling mass uniformly
73
+ for (const u of incoming.get(v) ?? []) {
74
+ rank += scores[u] / outDegree[u];
75
+ }
76
+ next[v] = (1 - damping) * uniform + damping * rank;
77
+ }
78
+
79
+ let delta = 0;
80
+ for (let i = 0; i < n; i++) {
81
+ delta += Math.abs(next[i] - scores[i]);
82
+ }
83
+ scores = next;
84
+ if (delta < 1e-8) break;
85
+ }
86
+
87
+ return scores;
88
+ }
89
+
90
+ // ---------------------------------------------------------------------------
91
+ // Dijkstra (shortest path from source)
92
+ // ---------------------------------------------------------------------------
93
+
94
+ function dijkstra(edges: Int32Array, nodeIds: string[], source: string): Float64Array {
95
+ const n = nodeIds.length;
96
+ if (n === 0) return new Float64Array(0);
97
+
98
+ const sourceIdx = nodeIds.indexOf(source);
99
+ const dist = new Float64Array(n).fill(Number.POSITIVE_INFINITY);
100
+ if (sourceIdx < 0) return dist;
101
+
102
+ dist[sourceIdx] = 0;
103
+
104
+ // Min-heap: [dist, nodeIndex]
105
+ // Simple binary min-heap implementation
106
+ const heap: Array<[number, number]> = [[0, sourceIdx]];
107
+
108
+ function heapPush(item: [number, number]): void {
109
+ heap.push(item);
110
+ let i = heap.length - 1;
111
+ while (i > 0) {
112
+ const parent = Math.floor((i - 1) / 2);
113
+ if (heap[parent][0] <= heap[i][0]) break;
114
+ [heap[parent], heap[i]] = [heap[i], heap[parent]];
115
+ i = parent;
116
+ }
117
+ }
118
+
119
+ function heapPop(): [number, number] | undefined {
120
+ if (heap.length === 0) return undefined;
121
+ const top = heap[0];
122
+ const last = heap.pop();
123
+ if (last !== undefined && heap.length > 0) {
124
+ heap[0] = last;
125
+ let i = 0;
126
+ while (true) {
127
+ const left = 2 * i + 1;
128
+ const right = 2 * i + 2;
129
+ let smallest = i;
130
+ if (left < heap.length && heap[left][0] < heap[smallest][0]) smallest = left;
131
+ if (right < heap.length && heap[right][0] < heap[smallest][0]) smallest = right;
132
+ if (smallest === i) break;
133
+ [heap[i], heap[smallest]] = [heap[smallest], heap[i]];
134
+ i = smallest;
135
+ }
136
+ }
137
+ return top;
138
+ }
139
+
140
+ // Build adjacency with unit weights (edge length = 1)
141
+ const adj = buildAdjacency(edges, n);
142
+
143
+ while (heap.length > 0) {
144
+ const top = heapPop();
145
+ if (!top) break;
146
+ const [d, u] = top;
147
+ if (d > dist[u]) continue; // stale entry
148
+ for (const v of adj.get(u) ?? []) {
149
+ const nd = dist[u] + 1;
150
+ if (nd < dist[v]) {
151
+ dist[v] = nd;
152
+ heapPush([nd, v]);
153
+ }
154
+ }
155
+ }
156
+
157
+ return dist;
158
+ }
159
+
160
+ // ---------------------------------------------------------------------------
161
+ // Union-Find (connected components)
162
+ // ---------------------------------------------------------------------------
163
+
164
+ function connectedComponents(edges: Int32Array, nodeCount: number): Float64Array {
165
+ if (nodeCount === 0) return new Float64Array(0);
166
+
167
+ const parent = new Int32Array(nodeCount);
168
+ const rank = new Int32Array(nodeCount);
169
+ for (let i = 0; i < nodeCount; i++) parent[i] = i;
170
+
171
+ function find(x: number): number {
172
+ let cur = x;
173
+ while (parent[cur] !== cur) {
174
+ parent[cur] = parent[parent[cur]]; // path halving
175
+ cur = parent[cur];
176
+ }
177
+ return cur;
178
+ }
179
+
180
+ function union(a: number, b: number): void {
181
+ const ra = find(a);
182
+ const rb = find(b);
183
+ if (ra === rb) return;
184
+ if (rank[ra] < rank[rb]) {
185
+ parent[ra] = rb;
186
+ } else if (rank[ra] > rank[rb]) {
187
+ parent[rb] = ra;
188
+ } else {
189
+ parent[rb] = ra;
190
+ rank[ra]++;
191
+ }
192
+ }
193
+
194
+ for (let i = 0; i < edges.length - 1; i += 2) {
195
+ const from = edges[i];
196
+ const to = edges[i + 1];
197
+ if (from >= 0 && to >= 0 && from < nodeCount && to < nodeCount) {
198
+ union(from, to);
199
+ }
200
+ }
201
+
202
+ // Assign compact component labels
203
+ const rootToLabel = new Map<number, number>();
204
+ let nextLabel = 0;
205
+ const result = new Float64Array(nodeCount);
206
+ for (let i = 0; i < nodeCount; i++) {
207
+ const root = find(i);
208
+ if (!rootToLabel.has(root)) {
209
+ rootToLabel.set(root, nextLabel++);
210
+ }
211
+ result[i] = rootToLabel.get(root) ?? 0;
212
+ }
213
+ return result;
214
+ }
215
+
216
+ // ---------------------------------------------------------------------------
217
+ // Brandes betweenness centrality
218
+ // ---------------------------------------------------------------------------
219
+
220
+ function betweennessCentrality(edges: Int32Array, nodeIds: string[]): Float64Array {
221
+ const n = nodeIds.length;
222
+ if (n === 0) return new Float64Array(0);
223
+
224
+ const adj = new Map<number, number[]>();
225
+ for (let i = 0; i < n; i++) adj.set(i, []);
226
+ for (let i = 0; i < edges.length - 1; i += 2) {
227
+ const from = edges[i];
228
+ const to = edges[i + 1];
229
+ if (from >= 0 && to >= 0 && from < n && to < n) {
230
+ adj.get(from)?.push(to);
231
+ adj.get(to)?.push(from); // treat as undirected for betweenness
232
+ }
233
+ }
234
+
235
+ // Deduplicate adjacency
236
+ for (const [k, v] of adj) {
237
+ adj.set(k, [...new Set(v)]);
238
+ }
239
+
240
+ const betweenness = new Float64Array(n);
241
+
242
+ for (let s = 0; s < n; s++) {
243
+ const stack: number[] = [];
244
+ const pred: number[][] = Array.from({ length: n }, () => []);
245
+ const sigma = new Float64Array(n); // number of shortest paths from s
246
+ const dist = new Float64Array(n).fill(-1);
247
+
248
+ sigma[s] = 1;
249
+ dist[s] = 0;
250
+ const queue: number[] = [s];
251
+
252
+ while (queue.length > 0) {
253
+ const v = queue.shift();
254
+ if (v === undefined) break;
255
+ stack.push(v);
256
+ for (const w of adj.get(v) ?? []) {
257
+ if (dist[w] < 0) {
258
+ queue.push(w);
259
+ dist[w] = dist[v] + 1;
260
+ }
261
+ if (dist[w] === dist[v] + 1) {
262
+ sigma[w] += sigma[v];
263
+ pred[w].push(v);
264
+ }
265
+ }
266
+ }
267
+
268
+ const delta = new Float64Array(n);
269
+ while (stack.length > 0) {
270
+ const w = stack.pop();
271
+ if (w === undefined) break;
272
+ for (const v of pred[w]) {
273
+ delta[v] += (sigma[v] / sigma[w]) * (1 + delta[w]);
274
+ }
275
+ if (w !== s) betweenness[w] += delta[w];
276
+ }
277
+ }
278
+
279
+ // Normalize (undirected: divide by 2)
280
+ for (let i = 0; i < n; i++) {
281
+ betweenness[i] /= 2;
282
+ }
283
+
284
+ return betweenness;
285
+ }
286
+
287
+ // ---------------------------------------------------------------------------
288
+ // Public entry point
289
+ // ---------------------------------------------------------------------------
290
+
291
+ export function fallbackGraphCompute(
292
+ edges: Int32Array,
293
+ nodeIds: string[],
294
+ algorithm: GraphAlgorithm,
295
+ ): GraphComputeResult {
296
+ let scores: Float64Array;
297
+
298
+ switch (algorithm.kind) {
299
+ case "pagerank":
300
+ scores = pagerank(
301
+ edges,
302
+ nodeIds,
303
+ algorithm.damping,
304
+ algorithm.iterations,
305
+ algorithm.seed_nodes,
306
+ );
307
+ break;
308
+ case "shortest_path":
309
+ scores = dijkstra(edges, nodeIds, algorithm.source);
310
+ break;
311
+ case "connected_components":
312
+ scores = connectedComponents(edges, nodeIds.length);
313
+ break;
314
+ case "betweenness_centrality":
315
+ scores = betweennessCentrality(edges, nodeIds);
316
+ break;
317
+ default: {
318
+ // Exhaustive check
319
+ const _never: never = algorithm;
320
+ throw new Error(`Unknown algorithm: ${JSON.stringify(_never)}`);
321
+ }
322
+ }
323
+
324
+ return { scores, node_ids: nodeIds };
325
+ }
@@ -0,0 +1,56 @@
1
+ // Module: constraints — Application-layer edge validation using edge_constraints table
2
+
3
+ import type { SiaDb } from "@/graph/db-interface";
4
+
5
+ /** Shape of a row in the edge_constraints table. */
6
+ export interface EdgeConstraint {
7
+ id: number;
8
+ source_type: string;
9
+ edge_type: string;
10
+ target_type: string;
11
+ description: string | null;
12
+ cardinality: string;
13
+ required: number;
14
+ }
15
+
16
+ /**
17
+ * Check whether a (source_type, edge_type, target_type) triple exists
18
+ * in the edge_constraints table.
19
+ *
20
+ * Returns true if the triple is declared valid, false otherwise.
21
+ */
22
+ export async function validateEdge(
23
+ db: SiaDb,
24
+ sourceType: string,
25
+ edgeType: string,
26
+ targetType: string,
27
+ ): Promise<boolean> {
28
+ const result = await db.execute(
29
+ `SELECT COUNT(*) AS cnt FROM edge_constraints
30
+ WHERE source_type = ? AND edge_type = ? AND target_type = ?`,
31
+ [sourceType, edgeType, targetType],
32
+ );
33
+ const row = result.rows[0] as { cnt: number } | undefined;
34
+ return (row?.cnt ?? 0) > 0;
35
+ }
36
+
37
+ /**
38
+ * Return all valid edge constraint rows for a given source entity type.
39
+ */
40
+ export async function getConstraintsForType(
41
+ db: SiaDb,
42
+ sourceType: string,
43
+ ): Promise<EdgeConstraint[]> {
44
+ const result = await db.execute("SELECT * FROM edge_constraints WHERE source_type = ?", [
45
+ sourceType,
46
+ ]);
47
+ return result.rows as unknown as EdgeConstraint[];
48
+ }
49
+
50
+ /**
51
+ * Return the entire constraint set from the edge_constraints table.
52
+ */
53
+ export async function getAllConstraints(db: SiaDb): Promise<EdgeConstraint[]> {
54
+ const result = await db.execute("SELECT * FROM edge_constraints", []);
55
+ return result.rows as unknown as EdgeConstraint[];
56
+ }
@@ -0,0 +1,8 @@
1
+ // Module: errors — Ontology-specific error types
2
+
3
+ export class OntologyError extends Error {
4
+ constructor(message: string) {
5
+ super(message);
6
+ this.name = "OntologyError";
7
+ }
8
+ }