@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,162 @@
1
+ // Module: visualize-live — CLI command to start interactive browser visualizer
2
+
3
+ import { spawn } from "node:child_process";
4
+ import { mkdirSync, writeFileSync } from "node:fs";
5
+ import { join, resolve } from "node:path";
6
+ import type { SiaDb } from "@/graph/db-interface";
7
+ import { type ExtractOpts, extractSubgraph } from "@/visualization/subgraph-extract";
8
+ import {
9
+ type CommunityData,
10
+ generateCommunityClusterHtml,
11
+ } from "@/visualization/views/community-clusters";
12
+ import { generateDependencyMapHtml } from "@/visualization/views/dependency-map";
13
+ import { generateGraphExplorerHtml } from "@/visualization/views/graph-explorer";
14
+ import { generateTimelineHtml } from "@/visualization/views/timeline";
15
+
16
+ export type ViewType = "graph" | "timeline" | "deps" | "communities";
17
+
18
+ export interface VisualizeLiveOpts {
19
+ view?: ViewType;
20
+ port?: number;
21
+ scope?: string;
22
+ maxNodes?: number;
23
+ }
24
+
25
+ /**
26
+ * Parse CLI args into VisualizeLiveOpts.
27
+ */
28
+ export function parseVisualizeLiveArgs(args: string[]): VisualizeLiveOpts {
29
+ const opts: VisualizeLiveOpts = {};
30
+ for (let i = 0; i < args.length; i++) {
31
+ if (args[i] === "--view" && args[i + 1]) {
32
+ opts.view = args[++i] as ViewType;
33
+ } else if (args[i] === "--port" && args[i + 1]) {
34
+ opts.port = parseInt(args[++i], 10);
35
+ } else if (args[i] === "--scope" && args[i + 1]) {
36
+ opts.scope = args[++i];
37
+ } else if (args[i] === "--max-nodes" && args[i + 1]) {
38
+ opts.maxNodes = parseInt(args[++i], 10);
39
+ }
40
+ }
41
+ return opts;
42
+ }
43
+
44
+ /**
45
+ * Generate the appropriate view HTML based on the selected view type.
46
+ */
47
+ export async function generateViewHtml(
48
+ db: SiaDb,
49
+ view: ViewType,
50
+ extractOpts: ExtractOpts,
51
+ ): Promise<string> {
52
+ switch (view) {
53
+ case "graph": {
54
+ const data = await extractSubgraph(db, extractOpts);
55
+ return generateGraphExplorerHtml(data);
56
+ }
57
+ case "timeline": {
58
+ const data = await extractSubgraph(db, extractOpts);
59
+ const events = data.nodes.map((n) => ({
60
+ id: n.id,
61
+ type: n.type,
62
+ name: n.name,
63
+ created_at: Date.now() - Math.random() * 86400_000 * 30, // placeholder
64
+ kind: n.type,
65
+ }));
66
+ return generateTimelineHtml(events);
67
+ }
68
+ case "deps": {
69
+ const data = await extractSubgraph(db, {
70
+ ...extractOpts,
71
+ nodeType: extractOpts.nodeType ?? "FileNode",
72
+ });
73
+ return generateDependencyMapHtml(data, { rootFile: extractOpts.scope });
74
+ }
75
+ case "communities": {
76
+ // Fetch community data from the graph
77
+ const { rows: commRows } = await db.execute(
78
+ `SELECT id, name, level, summary, member_count FROM communities
79
+ WHERE t_valid_until IS NULL
80
+ ORDER BY level ASC, member_count DESC
81
+ LIMIT 50`,
82
+ );
83
+ const { rows: memberRows } = await db.execute(
84
+ `SELECT entity_id, community_id, entity_name, entity_type FROM community_members
85
+ WHERE t_valid_until IS NULL
86
+ LIMIT 500`,
87
+ );
88
+ const communityData: CommunityData = {
89
+ communities: commRows.map((r) => ({
90
+ id: r.id as string,
91
+ name: r.name as string,
92
+ level: (r.level as number) ?? 1,
93
+ summary: (r.summary as string) ?? "",
94
+ memberCount: (r.member_count as number) ?? 0,
95
+ })),
96
+ members: memberRows.map((r) => ({
97
+ entityId: r.entity_id as string,
98
+ communityId: r.community_id as string,
99
+ entityName: r.entity_name as string,
100
+ entityType: r.entity_type as string,
101
+ })),
102
+ };
103
+ return generateCommunityClusterHtml(communityData);
104
+ }
105
+ default:
106
+ throw new Error(`Unknown view type: ${view}`);
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Run the visualize-live command: start server, generate view, output URL.
112
+ */
113
+ export async function runVisualizeLive(db: SiaDb, args: string[]): Promise<void> {
114
+ const opts = parseVisualizeLiveArgs(args);
115
+ const view = opts.view ?? "graph";
116
+ const port = opts.port ?? 52742;
117
+
118
+ // Create screen directory
119
+ const screenDir = resolve(".sia-graph/viz");
120
+ mkdirSync(screenDir, { recursive: true });
121
+
122
+ // Generate HTML view
123
+ const extractOpts: ExtractOpts = {
124
+ scope: opts.scope,
125
+ maxNodes: opts.maxNodes,
126
+ };
127
+ const html = await generateViewHtml(db, view, extractOpts);
128
+
129
+ // Write to screen dir with timestamp
130
+ const filename = `${view}-${Date.now()}.html`;
131
+ writeFileSync(join(screenDir, filename), html, "utf-8");
132
+
133
+ // Start the viz server
134
+ const serverScript = resolve(__dirname, "../../scripts/viz-server.ts");
135
+ const child = spawn(
136
+ "bun",
137
+ ["run", serverScript, "--screen-dir", screenDir, "--port", String(port)],
138
+ {
139
+ stdio: "pipe",
140
+ detached: true,
141
+ },
142
+ );
143
+
144
+ child.stdout?.on("data", (data: Buffer) => {
145
+ const msg = data.toString().trim();
146
+ try {
147
+ const info = JSON.parse(msg);
148
+ if (info.type === "server-started") {
149
+ console.log(`SIA Graph Visualizer running at: ${info.url}`);
150
+ console.log(`View: ${view} | Screen dir: ${screenDir}`);
151
+ }
152
+ } catch {
153
+ console.log(msg);
154
+ }
155
+ });
156
+
157
+ child.stderr?.on("data", (data: Buffer) => {
158
+ console.error(data.toString().trim());
159
+ });
160
+
161
+ child.unref();
162
+ }
@@ -0,0 +1,117 @@
1
+ // Module: workspace — Workspace CLI subcommands (create, list, add, remove, show)
2
+ import { createHash } from "node:crypto";
3
+ import { resolve } from "node:path";
4
+ import type { SiaDb } from "@/graph/db-interface";
5
+ import {
6
+ addRepoToWorkspace,
7
+ createWorkspace,
8
+ getWorkspaceContractCount,
9
+ getWorkspaceRepos,
10
+ listWorkspaces,
11
+ registerRepo,
12
+ removeRepoFromWorkspace,
13
+ resolveWorkspaceName,
14
+ type WorkspaceListItem,
15
+ } from "@/graph/meta-db";
16
+ import { detectApiContracts, writeDetectedContracts } from "@/workspace/api-contracts";
17
+
18
+ /**
19
+ * Create a workspace.
20
+ */
21
+ export async function workspaceCreate(db: SiaDb, name: string): Promise<string> {
22
+ return createWorkspace(db, name);
23
+ }
24
+
25
+ /**
26
+ * List all workspaces with member counts.
27
+ */
28
+ export async function workspaceList(db: SiaDb): Promise<WorkspaceListItem[]> {
29
+ return listWorkspaces(db);
30
+ }
31
+
32
+ /**
33
+ * Add a repo to a workspace. Triggers API contract auto-detection.
34
+ */
35
+ export async function workspaceAdd(
36
+ db: SiaDb,
37
+ workspaceName: string,
38
+ repoPath: string,
39
+ ): Promise<void> {
40
+ const wsId = await resolveWorkspaceName(db, workspaceName);
41
+ if (!wsId) throw new Error(`Workspace '${workspaceName}' not found`);
42
+
43
+ const repoId = await registerRepo(db, repoPath);
44
+ await addRepoToWorkspace(db, wsId, repoId);
45
+
46
+ // Auto-detect API contracts
47
+ const contracts = await detectApiContracts(resolve(repoPath));
48
+ if (contracts.length > 0) {
49
+ await writeDetectedContracts(db, repoId, contracts);
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Remove a repo from a workspace.
55
+ */
56
+ export async function workspaceRemove(
57
+ db: SiaDb,
58
+ workspaceName: string,
59
+ repoPath: string,
60
+ ): Promise<void> {
61
+ const wsId = await resolveWorkspaceName(db, workspaceName);
62
+ if (!wsId) throw new Error(`Workspace '${workspaceName}' not found`);
63
+
64
+ const resolved = resolve(repoPath);
65
+ const repoId = createHash("sha256").update(resolved).digest("hex");
66
+ await removeRepoFromWorkspace(db, wsId, repoId);
67
+ }
68
+
69
+ /** Shape returned by workspaceShow. */
70
+ export interface WorkspaceShowInfo {
71
+ name: string;
72
+ id: string;
73
+ members: Array<{ id: string; path: string; name: string | null }>;
74
+ contractCount: number;
75
+ crossRepoEdgeCount: number;
76
+ }
77
+
78
+ /**
79
+ * Show workspace details: members, contracts, cross-repo edge count.
80
+ */
81
+ export async function workspaceShow(
82
+ metaDb: SiaDb,
83
+ bridgeDb: SiaDb,
84
+ workspaceName: string,
85
+ ): Promise<WorkspaceShowInfo> {
86
+ const wsId = await resolveWorkspaceName(metaDb, workspaceName);
87
+ if (!wsId) throw new Error(`Workspace '${workspaceName}' not found`);
88
+
89
+ const repos = await getWorkspaceRepos(metaDb, wsId);
90
+ const contractCount = await getWorkspaceContractCount(metaDb, wsId);
91
+
92
+ // Count cross-repo edges for workspace repos
93
+ let crossRepoEdgeCount = 0;
94
+ if (repos.length > 0) {
95
+ const repoIds = repos.map((r) => r.id as string);
96
+ const placeholders = repoIds.map(() => "?").join(", ");
97
+ const edgeResult = await bridgeDb.execute(
98
+ `SELECT COUNT(*) as cnt FROM cross_repo_edges
99
+ WHERE (source_repo_id IN (${placeholders}) OR target_repo_id IN (${placeholders}))
100
+ AND t_valid_until IS NULL`,
101
+ [...repoIds, ...repoIds],
102
+ );
103
+ crossRepoEdgeCount = (edgeResult.rows[0]?.cnt as number) ?? 0;
104
+ }
105
+
106
+ return {
107
+ name: workspaceName,
108
+ id: wsId,
109
+ members: repos.map((r) => ({
110
+ id: r.id as string,
111
+ path: r.path as string,
112
+ name: (r.name as string | null) ?? null,
113
+ })),
114
+ contractCount,
115
+ crossRepoEdgeCount,
116
+ };
117
+ }
@@ -0,0 +1,424 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { runCommunityCommand } from "@/cli/commands/community";
4
+
5
+ const VERSION = "1.0.0";
6
+
7
+ function printHelp(): void {
8
+ console.log(`sia v${VERSION} — Persistent graph memory for AI coding agents
9
+
10
+ Usage:
11
+ sia <command> [options]
12
+
13
+ Commands:
14
+ install Install Sia in the current project
15
+ workspace Manage workspaces (create, list, add, remove, show)
16
+ team Team sync (join, leave, status)
17
+ sync Manual push/pull (sync push, sync pull)
18
+ search Search the knowledge graph
19
+ stats Show graph statistics
20
+ status Show knowledge graph health dashboard
21
+ reindex Re-index the repository
22
+ learn Build the complete knowledge graph (code + docs + communities)
23
+ community Show community structure
24
+ doctor Run diagnostic checks
25
+ digest Generate session digest
26
+ graph Visualize the knowledge graph
27
+ visualize-live Launch interactive browser graph visualizer
28
+ prune Remove archived entities
29
+ export Export graph to JSON
30
+ export-knowledge Generate human-readable KNOWLEDGE.md
31
+ import Import graph from JSON
32
+ rollback Restore graph from snapshot
33
+ conflicts List or resolve entity conflicts
34
+ freshness Generate freshness report
35
+ share Share an entity
36
+ history Show temporal knowledge history
37
+ compare Compare graph state between time points
38
+ download-model Download ONNX embedding model
39
+ enable-flagging Enable mid-session flagging
40
+ disable-flagging Disable mid-session flagging
41
+ tour Guided walkthrough of the knowledge graph
42
+ qa-report Generate QA testing intelligence report
43
+ pm-report Generate PM reports (sprint, decisions, risks)
44
+ lead-report Tech lead reports (drift, knowledge-map, compliance)
45
+ server Manage MCP server (start, stop, status)
46
+
47
+ Options:
48
+ --version, -v Show version
49
+ --help, -h Show this help
50
+ `);
51
+ }
52
+
53
+ /**
54
+ * Open the graph database for the current working directory.
55
+ * Shared by commands that need SiaDb access.
56
+ */
57
+ async function openDb() {
58
+ const { resolveRepoHash } = await import("@/capture/hook");
59
+ const { openGraphDb } = await import("@/graph/semantic-db");
60
+ const repoHash = resolveRepoHash(process.cwd());
61
+ return openGraphDb(repoHash);
62
+ }
63
+
64
+ async function main(): Promise<void> {
65
+ const args = process.argv.slice(2);
66
+
67
+ if (args.includes("--version") || args.includes("-v")) {
68
+ console.log(`sia v${VERSION}`);
69
+ return;
70
+ }
71
+
72
+ if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
73
+ printHelp();
74
+ return;
75
+ }
76
+
77
+ const command = args[0];
78
+ const rest = args.slice(1);
79
+
80
+ switch (command) {
81
+ // --- Self-contained commands (no DB needed) ---
82
+ case "install": {
83
+ const { siaInstall } = await import("@/cli/commands/install");
84
+ const result = await siaInstall();
85
+ console.log(JSON.stringify(result, null, 2));
86
+ return;
87
+ }
88
+ case "reindex": {
89
+ const { siaReindex } = await import("@/cli/commands/reindex");
90
+ const result = await siaReindex();
91
+ console.log(JSON.stringify(result, null, 2));
92
+ return;
93
+ }
94
+ case "learn": {
95
+ const { siaLearn } = await import("@/cli/commands/learn");
96
+ const options: Record<string, unknown> = {};
97
+ if (rest.includes("--incremental")) options.incremental = true;
98
+ if (rest.includes("--force")) options.force = true;
99
+ if (rest.includes("--quiet")) options.verbosity = "quiet";
100
+ if (rest.includes("--interactive")) options.verbosity = "interactive";
101
+ if (rest.includes("--verbose")) options.verbosity = "verbose";
102
+ await siaLearn(options as any);
103
+ return;
104
+ }
105
+ case "download-model": {
106
+ const { downloadModel } = await import("@/cli/commands/download-model");
107
+ const path = await downloadModel();
108
+ console.log(`Model downloaded to: ${path}`);
109
+ return;
110
+ }
111
+ case "enable-flagging": {
112
+ const { enableFlagging } = await import("@/cli/commands/enable-flagging");
113
+ await enableFlagging();
114
+ console.log("Flagging enabled.");
115
+ return;
116
+ }
117
+ case "disable-flagging": {
118
+ const { disableFlagging } = await import("@/cli/commands/disable-flagging");
119
+ await disableFlagging();
120
+ console.log("Flagging disabled.");
121
+ return;
122
+ }
123
+
124
+ // --- Commands with their own CLI dispatchers ---
125
+ case "community":
126
+ await runCommunityCommand(rest);
127
+ return;
128
+ case "sync": {
129
+ const { runSync } = await import("@/cli/commands/sync");
130
+ await runSync(rest);
131
+ return;
132
+ }
133
+ case "team": {
134
+ const { teamJoin, teamLeave, teamStatus } = await import("@/cli/commands/team");
135
+ const sub = rest[0];
136
+ if (sub === "join" && rest.length >= 3) {
137
+ await teamJoin(rest[1], rest[2]);
138
+ } else if (sub === "leave") {
139
+ await teamLeave();
140
+ } else if (sub === "status") {
141
+ const status = await teamStatus();
142
+ console.log(JSON.stringify(status, null, 2));
143
+ } else {
144
+ console.error("Usage: sia team <join|leave|status>");
145
+ }
146
+ return;
147
+ }
148
+
149
+ // --- Commands that need DB ---
150
+ case "search": {
151
+ const { searchGraph } = await import("@/cli/commands/search");
152
+ const query = rest.join(" ");
153
+ if (!query) {
154
+ console.error("Usage: sia search <query>");
155
+ return;
156
+ }
157
+ const db = await openDb();
158
+ try {
159
+ const results = await searchGraph(db, query);
160
+ console.log(JSON.stringify(results, null, 2));
161
+ } finally {
162
+ await db.close();
163
+ }
164
+ return;
165
+ }
166
+ case "status": {
167
+ const { runStatus } = await import("@/cli/commands/status");
168
+ const db = await openDb();
169
+ try {
170
+ await runStatus(db);
171
+ } finally {
172
+ await db.close();
173
+ }
174
+ return;
175
+ }
176
+ case "stats": {
177
+ const { getStats } = await import("@/cli/commands/stats");
178
+ const db = await openDb();
179
+ try {
180
+ const result = await getStats(db);
181
+ console.log(JSON.stringify(result, null, 2));
182
+ } finally {
183
+ await db.close();
184
+ }
185
+ return;
186
+ }
187
+ case "doctor": {
188
+ const { runDoctor } = await import("@/cli/commands/doctor");
189
+ const db = await openDb();
190
+ try {
191
+ const report = await runDoctor(db, process.cwd());
192
+ console.log(JSON.stringify(report, null, 2));
193
+ } finally {
194
+ await db.close();
195
+ }
196
+ return;
197
+ }
198
+ case "digest": {
199
+ const { generateDigest } = await import("@/cli/commands/digest");
200
+ const db = await openDb();
201
+ try {
202
+ const result = await generateDigest(db);
203
+ console.log(JSON.stringify(result, null, 2));
204
+ } finally {
205
+ await db.close();
206
+ }
207
+ return;
208
+ }
209
+ case "graph": {
210
+ const { generateGraphVisualization } = await import("@/cli/commands/graph");
211
+ const db = await openDb();
212
+ try {
213
+ const output = await generateGraphVisualization(db);
214
+ console.log(output);
215
+ } finally {
216
+ await db.close();
217
+ }
218
+ return;
219
+ }
220
+ case "visualize-live": {
221
+ const { runVisualizeLive } = await import("@/cli/commands/visualize-live");
222
+ const db = await openDb();
223
+ try {
224
+ await runVisualizeLive(db, rest);
225
+ } finally {
226
+ await db.close();
227
+ }
228
+ return;
229
+ }
230
+ case "prune": {
231
+ const { pruneDryRun, pruneConfirm } = await import("@/cli/commands/prune");
232
+ const db = await openDb();
233
+ try {
234
+ if (rest.includes("--confirm")) {
235
+ const removed = await pruneConfirm(db);
236
+ console.log(`Pruned ${removed} entities.`);
237
+ } else {
238
+ const candidates = await pruneDryRun(db);
239
+ console.log(JSON.stringify(candidates, null, 2));
240
+ if (candidates.length > 0) {
241
+ console.log(`\nRun 'sia prune --confirm' to remove ${candidates.length} entities.`);
242
+ }
243
+ }
244
+ } finally {
245
+ await db.close();
246
+ }
247
+ return;
248
+ }
249
+ case "export-knowledge": {
250
+ const { runExportKnowledge } = await import("@/cli/commands/export-knowledge");
251
+ await runExportKnowledge(rest);
252
+ return;
253
+ }
254
+ case "export": {
255
+ const { exportToFile, exportGraph } = await import("@/cli/commands/export");
256
+ const db = await openDb();
257
+ try {
258
+ const outputPath = rest[0];
259
+ if (outputPath) {
260
+ const path = await exportToFile(db, outputPath);
261
+ console.log(`Exported to: ${path}`);
262
+ } else {
263
+ const data = await exportGraph(db);
264
+ console.log(JSON.stringify(data, null, 2));
265
+ }
266
+ } finally {
267
+ await db.close();
268
+ }
269
+ return;
270
+ }
271
+ case "import": {
272
+ const { importFromFile } = await import("@/cli/commands/import");
273
+ const filePath = rest[0];
274
+ const mode = rest.includes("--replace") ? ("replace" as const) : ("merge" as const);
275
+ if (!filePath) {
276
+ console.error("Usage: sia import <file> [--replace]");
277
+ return;
278
+ }
279
+ const db = await openDb();
280
+ try {
281
+ const result = await importFromFile(db, filePath, mode);
282
+ console.log(JSON.stringify(result, null, 2));
283
+ } finally {
284
+ await db.close();
285
+ }
286
+ return;
287
+ }
288
+ case "rollback": {
289
+ const { rollbackGraph } = await import("@/cli/commands/rollback");
290
+ const { resolveRepoHash } = await import("@/capture/hook");
291
+ const repoHash = resolveRepoHash(process.cwd());
292
+ const db = await openDb();
293
+ try {
294
+ const result = await rollbackGraph(db, repoHash);
295
+ console.log(JSON.stringify(result, null, 2));
296
+ } finally {
297
+ await db.close();
298
+ }
299
+ return;
300
+ }
301
+ case "conflicts": {
302
+ const { listConflicts, resolveConflict } = await import("@/cli/commands/conflicts");
303
+ const db = await openDb();
304
+ try {
305
+ if (rest[0] === "resolve" && rest[1] && rest[2]) {
306
+ await resolveConflict(db, rest[1], rest[2]);
307
+ console.log("Conflict resolved.");
308
+ } else {
309
+ const conflicts = await listConflicts(db);
310
+ console.log(JSON.stringify(conflicts, null, 2));
311
+ }
312
+ } finally {
313
+ await db.close();
314
+ }
315
+ return;
316
+ }
317
+ case "freshness": {
318
+ const { generateFreshnessReport } = await import("@/cli/commands/freshness");
319
+ const db = await openDb();
320
+ try {
321
+ const report = await generateFreshnessReport(db);
322
+ console.log(JSON.stringify(report, null, 2));
323
+ } finally {
324
+ await db.close();
325
+ }
326
+ return;
327
+ }
328
+ case "share": {
329
+ const { shareEntity } = await import("@/cli/commands/share");
330
+ const entityId = rest[0];
331
+ if (!entityId) {
332
+ console.error("Usage: sia share <entity-id>");
333
+ return;
334
+ }
335
+ const db = await openDb();
336
+ try {
337
+ await shareEntity(db, entityId);
338
+ console.log(`Entity ${entityId} shared.`);
339
+ } finally {
340
+ await db.close();
341
+ }
342
+ return;
343
+ }
344
+ case "workspace": {
345
+ const mod = await import("@/cli/commands/workspace");
346
+ const db = await openDb();
347
+ try {
348
+ const sub = rest[0];
349
+ if (sub === "create" && rest[1]) {
350
+ const id = await mod.workspaceCreate(db, rest[1]);
351
+ console.log(`Workspace created: ${id}`);
352
+ } else if (sub === "list") {
353
+ const items = await mod.workspaceList(db);
354
+ console.log(JSON.stringify(items, null, 2));
355
+ } else if (sub === "add" && rest[1] && rest[2]) {
356
+ await mod.workspaceAdd(db, rest[1], rest[2]);
357
+ console.log("Repository added to workspace.");
358
+ } else if (sub === "remove" && rest[1] && rest[2]) {
359
+ await mod.workspaceRemove(db, rest[1], rest[2]);
360
+ console.log("Repository removed from workspace.");
361
+ } else {
362
+ console.error("Usage: sia workspace <create|list|add|remove> [args]");
363
+ }
364
+ } finally {
365
+ await db.close();
366
+ }
367
+ return;
368
+ }
369
+ case "history": {
370
+ const { runHistory } = await import("@/cli/commands/history");
371
+ await runHistory(rest);
372
+ return;
373
+ }
374
+ case "compare": {
375
+ const { runCompare } = await import("@/cli/commands/compare");
376
+ await runCompare(rest);
377
+ return;
378
+ }
379
+ case "tour": {
380
+ const { runTour } = await import("@/cli/commands/tour");
381
+ await runTour(rest);
382
+ return;
383
+ }
384
+ case "qa-report": {
385
+ const { runQaReport } = await import("@/cli/commands/qa-report");
386
+ await runQaReport(rest);
387
+ return;
388
+ }
389
+ case "pm-report": {
390
+ const { runPmReport } = await import("@/cli/commands/pm-report");
391
+ await runPmReport(rest);
392
+ return;
393
+ }
394
+ case "lead-report": {
395
+ const { runLeadReport } = await import("@/cli/commands/lead-report");
396
+ await runLeadReport(rest);
397
+ return;
398
+ }
399
+ case "server": {
400
+ const { serverStart, serverStop, serverStatus } = await import("@/cli/commands/server");
401
+ const sub = rest[0];
402
+ if (sub === "start") {
403
+ const config = serverStart();
404
+ console.log(JSON.stringify(config, null, 2));
405
+ } else if (sub === "stop") {
406
+ const config = serverStop();
407
+ console.log(JSON.stringify(config, null, 2));
408
+ } else if (sub === "status") {
409
+ const config = serverStatus();
410
+ console.log(JSON.stringify(config, null, 2));
411
+ } else {
412
+ console.error("Usage: sia server <start|stop|status>");
413
+ }
414
+ return;
415
+ }
416
+ default:
417
+ console.error(`Unknown command: ${command}. Run 'sia --help' for usage.`);
418
+ }
419
+ }
420
+
421
+ main().catch((err) => {
422
+ console.error(err);
423
+ process.exit(1);
424
+ });