@su-record/vibe 2.6.26 → 2.6.28

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 (287) hide show
  1. package/CLAUDE.md +202 -153
  2. package/LICENSE +21 -21
  3. package/README.md +267 -236
  4. package/agents/architect-low.md +41 -41
  5. package/agents/architect-medium.md +59 -59
  6. package/agents/architect.md +80 -80
  7. package/agents/build-error-resolver.md +115 -115
  8. package/agents/compounder.md +261 -261
  9. package/agents/diagrammer.md +178 -178
  10. package/agents/docs/api-documenter.md +99 -99
  11. package/agents/docs/changelog-writer.md +93 -93
  12. package/agents/e2e-tester.md +266 -266
  13. package/agents/explorer-low.md +42 -42
  14. package/agents/explorer-medium.md +59 -59
  15. package/agents/explorer.md +48 -48
  16. package/agents/implementer-low.md +43 -43
  17. package/agents/implementer-medium.md +52 -52
  18. package/agents/implementer.md +54 -54
  19. package/agents/planning/requirements-analyst.md +84 -84
  20. package/agents/planning/ux-advisor.md +83 -83
  21. package/agents/qa/acceptance-tester.md +86 -86
  22. package/agents/qa/edge-case-finder.md +93 -93
  23. package/agents/refactor-cleaner.md +143 -143
  24. package/agents/research/best-practices-agent.md +199 -199
  25. package/agents/research/codebase-patterns-agent.md +157 -157
  26. package/agents/research/framework-docs-agent.md +188 -188
  27. package/agents/research/security-advisory-agent.md +213 -213
  28. package/agents/review/architecture-reviewer.md +107 -107
  29. package/agents/review/complexity-reviewer.md +116 -116
  30. package/agents/review/data-integrity-reviewer.md +88 -88
  31. package/agents/review/git-history-reviewer.md +103 -103
  32. package/agents/review/performance-reviewer.md +86 -86
  33. package/agents/review/python-reviewer.md +150 -150
  34. package/agents/review/rails-reviewer.md +139 -139
  35. package/agents/review/react-reviewer.md +144 -144
  36. package/agents/review/security-reviewer.md +80 -80
  37. package/agents/review/simplicity-reviewer.md +140 -140
  38. package/agents/review/test-coverage-reviewer.md +116 -116
  39. package/agents/review/typescript-reviewer.md +127 -127
  40. package/agents/searcher.md +54 -54
  41. package/agents/simplifier.md +120 -120
  42. package/agents/tester.md +49 -49
  43. package/agents/ui-previewer.md +268 -268
  44. package/commands/vibe.analyze.md +356 -356
  45. package/commands/vibe.reason.md +329 -329
  46. package/commands/vibe.review.md +423 -423
  47. package/commands/vibe.run.md +1313 -1313
  48. package/commands/vibe.spec.md +1054 -1054
  49. package/commands/vibe.spec.review.md +412 -412
  50. package/commands/vibe.trace.md +161 -161
  51. package/commands/vibe.utils.md +376 -376
  52. package/commands/vibe.verify.md +375 -375
  53. package/dist/cli/collaborator.js +52 -52
  54. package/dist/cli/detect.js +32 -32
  55. package/dist/cli/hud.js +20 -20
  56. package/dist/cli/index.js +112 -112
  57. package/dist/cli/llm.js +144 -144
  58. package/dist/cli/mcp.d.ts +49 -0
  59. package/dist/cli/mcp.d.ts.map +1 -0
  60. package/dist/cli/mcp.js +169 -0
  61. package/dist/cli/mcp.js.map +1 -0
  62. package/dist/cli/postinstall.d.ts.map +1 -1
  63. package/dist/cli/postinstall.js +886 -858
  64. package/dist/cli/postinstall.js.map +1 -1
  65. package/dist/cli/setup/GlobalInstaller.d.ts +6 -0
  66. package/dist/cli/setup/GlobalInstaller.d.ts.map +1 -1
  67. package/dist/cli/setup/GlobalInstaller.js +26 -0
  68. package/dist/cli/setup/GlobalInstaller.js.map +1 -1
  69. package/dist/lib/DeepInit.js +24 -24
  70. package/dist/lib/IterationTracker.js +11 -11
  71. package/dist/lib/MemoryManager.d.ts +30 -0
  72. package/dist/lib/MemoryManager.d.ts.map +1 -1
  73. package/dist/lib/MemoryManager.js +74 -0
  74. package/dist/lib/MemoryManager.js.map +1 -1
  75. package/dist/lib/PythonParser.js +108 -108
  76. package/dist/lib/ReviewRace.js +96 -96
  77. package/dist/lib/SkillFrontmatter.js +28 -28
  78. package/dist/lib/SkillQualityGate.js +9 -9
  79. package/dist/lib/SkillRepository.js +159 -159
  80. package/dist/lib/UltraQA.js +77 -77
  81. package/dist/lib/gemini-api.js +5 -5
  82. package/dist/lib/gemini-mcp.d.ts +10 -0
  83. package/dist/lib/gemini-mcp.d.ts.map +1 -0
  84. package/dist/lib/gemini-mcp.js +353 -0
  85. package/dist/lib/gemini-mcp.js.map +1 -0
  86. package/dist/lib/gpt-api.js +4 -4
  87. package/dist/lib/gpt-mcp.d.ts +10 -0
  88. package/dist/lib/gpt-mcp.d.ts.map +1 -0
  89. package/dist/lib/gpt-mcp.js +352 -0
  90. package/dist/lib/gpt-mcp.js.map +1 -0
  91. package/dist/lib/memory/KnowledgeGraph.js +4 -4
  92. package/dist/lib/memory/MemorySearch.js +43 -43
  93. package/dist/lib/memory/MemoryStorage.js +130 -130
  94. package/dist/lib/memory/ObservationStore.js +28 -28
  95. package/dist/lib/memory/SessionRAGRetriever.d.ts +66 -0
  96. package/dist/lib/memory/SessionRAGRetriever.d.ts.map +1 -0
  97. package/dist/lib/memory/SessionRAGRetriever.js +196 -0
  98. package/dist/lib/memory/SessionRAGRetriever.js.map +1 -0
  99. package/dist/lib/memory/SessionRAGRetriever.test.d.ts +2 -0
  100. package/dist/lib/memory/SessionRAGRetriever.test.d.ts.map +1 -0
  101. package/dist/lib/memory/SessionRAGRetriever.test.js +180 -0
  102. package/dist/lib/memory/SessionRAGRetriever.test.js.map +1 -0
  103. package/dist/lib/memory/SessionRAGStore.d.ts +153 -0
  104. package/dist/lib/memory/SessionRAGStore.d.ts.map +1 -0
  105. package/dist/lib/memory/SessionRAGStore.js +673 -0
  106. package/dist/lib/memory/SessionRAGStore.js.map +1 -0
  107. package/dist/lib/memory/SessionRAGStore.test.d.ts +2 -0
  108. package/dist/lib/memory/SessionRAGStore.test.d.ts.map +1 -0
  109. package/dist/lib/memory/SessionRAGStore.test.js +326 -0
  110. package/dist/lib/memory/SessionRAGStore.test.js.map +1 -0
  111. package/dist/lib/memory/SessionSummarizer.js +9 -9
  112. package/dist/orchestrator/AgentManager.js +12 -12
  113. package/dist/orchestrator/MultiLlmResearch.js +8 -8
  114. package/dist/orchestrator/SmartRouter.js +11 -11
  115. package/dist/orchestrator/SwarmOrchestrator.test.js +16 -16
  116. package/dist/orchestrator/parallelResearch.js +24 -24
  117. package/dist/tools/analytics/getUsageAnalytics.d.ts +10 -0
  118. package/dist/tools/analytics/getUsageAnalytics.d.ts.map +1 -0
  119. package/dist/tools/analytics/getUsageAnalytics.js +246 -0
  120. package/dist/tools/analytics/getUsageAnalytics.js.map +1 -0
  121. package/dist/tools/analytics/index.d.ts +5 -0
  122. package/dist/tools/analytics/index.d.ts.map +1 -0
  123. package/dist/tools/analytics/index.js +5 -0
  124. package/dist/tools/analytics/index.js.map +1 -0
  125. package/dist/tools/convention/analyzeComplexity.test.js +115 -115
  126. package/dist/tools/convention/getCodingGuide.d.ts +7 -0
  127. package/dist/tools/convention/getCodingGuide.d.ts.map +1 -0
  128. package/dist/tools/convention/getCodingGuide.js +69 -0
  129. package/dist/tools/convention/getCodingGuide.js.map +1 -0
  130. package/dist/tools/convention/validateCodeQuality.test.js +104 -104
  131. package/dist/tools/index.d.ts +5 -0
  132. package/dist/tools/index.d.ts.map +1 -1
  133. package/dist/tools/index.js +4 -0
  134. package/dist/tools/index.js.map +1 -1
  135. package/dist/tools/memory/index.d.ts +3 -0
  136. package/dist/tools/memory/index.d.ts.map +1 -1
  137. package/dist/tools/memory/index.js +4 -0
  138. package/dist/tools/memory/index.js.map +1 -1
  139. package/dist/tools/memory/manageGoals.d.ts +11 -0
  140. package/dist/tools/memory/manageGoals.d.ts.map +1 -0
  141. package/dist/tools/memory/manageGoals.js +152 -0
  142. package/dist/tools/memory/manageGoals.js.map +1 -0
  143. package/dist/tools/memory/retrieveSessionContext.d.ts +9 -0
  144. package/dist/tools/memory/retrieveSessionContext.d.ts.map +1 -0
  145. package/dist/tools/memory/retrieveSessionContext.js +140 -0
  146. package/dist/tools/memory/retrieveSessionContext.js.map +1 -0
  147. package/dist/tools/memory/saveSessionItem.d.ts +26 -0
  148. package/dist/tools/memory/saveSessionItem.d.ts.map +1 -0
  149. package/dist/tools/memory/saveSessionItem.js +218 -0
  150. package/dist/tools/memory/saveSessionItem.js.map +1 -0
  151. package/dist/tools/memory/startSession.d.ts.map +1 -1
  152. package/dist/tools/memory/startSession.js +29 -0
  153. package/dist/tools/memory/startSession.js.map +1 -1
  154. package/dist/tools/planning/analyzeRequirements.d.ts +9 -0
  155. package/dist/tools/planning/analyzeRequirements.d.ts.map +1 -0
  156. package/dist/tools/planning/analyzeRequirements.js +171 -0
  157. package/dist/tools/planning/analyzeRequirements.js.map +1 -0
  158. package/dist/tools/planning/createUserStories.d.ts +9 -0
  159. package/dist/tools/planning/createUserStories.d.ts.map +1 -0
  160. package/dist/tools/planning/createUserStories.js +124 -0
  161. package/dist/tools/planning/createUserStories.js.map +1 -0
  162. package/dist/tools/planning/featureRoadmap.d.ts +10 -0
  163. package/dist/tools/planning/featureRoadmap.d.ts.map +1 -0
  164. package/dist/tools/planning/featureRoadmap.js +207 -0
  165. package/dist/tools/planning/featureRoadmap.js.map +1 -0
  166. package/dist/tools/planning/generatePrd.d.ts +11 -0
  167. package/dist/tools/planning/generatePrd.d.ts.map +1 -0
  168. package/dist/tools/planning/generatePrd.js +161 -0
  169. package/dist/tools/planning/generatePrd.js.map +1 -0
  170. package/dist/tools/planning/index.d.ts +8 -0
  171. package/dist/tools/planning/index.d.ts.map +1 -0
  172. package/dist/tools/planning/index.js +8 -0
  173. package/dist/tools/planning/index.js.map +1 -0
  174. package/dist/tools/prompt/analyzePrompt.d.ts +7 -0
  175. package/dist/tools/prompt/analyzePrompt.d.ts.map +1 -0
  176. package/dist/tools/prompt/analyzePrompt.js +150 -0
  177. package/dist/tools/prompt/analyzePrompt.js.map +1 -0
  178. package/dist/tools/prompt/enhancePrompt.d.ts +8 -0
  179. package/dist/tools/prompt/enhancePrompt.d.ts.map +1 -0
  180. package/dist/tools/prompt/enhancePrompt.js +110 -0
  181. package/dist/tools/prompt/enhancePrompt.js.map +1 -0
  182. package/dist/tools/prompt/enhancePromptGemini.d.ts +8 -0
  183. package/dist/tools/prompt/enhancePromptGemini.d.ts.map +1 -0
  184. package/dist/tools/prompt/enhancePromptGemini.js +332 -0
  185. package/dist/tools/prompt/enhancePromptGemini.js.map +1 -0
  186. package/dist/tools/prompt/index.d.ts +7 -0
  187. package/dist/tools/prompt/index.d.ts.map +1 -0
  188. package/dist/tools/prompt/index.js +7 -0
  189. package/dist/tools/prompt/index.js.map +1 -0
  190. package/dist/tools/reasoning/applyReasoningFramework.d.ts +8 -0
  191. package/dist/tools/reasoning/applyReasoningFramework.d.ts.map +1 -0
  192. package/dist/tools/reasoning/applyReasoningFramework.js +266 -0
  193. package/dist/tools/reasoning/applyReasoningFramework.js.map +1 -0
  194. package/dist/tools/reasoning/index.d.ts +5 -0
  195. package/dist/tools/reasoning/index.d.ts.map +1 -0
  196. package/dist/tools/reasoning/index.js +5 -0
  197. package/dist/tools/reasoning/index.js.map +1 -0
  198. package/dist/tools/spec/prdParser.test.js +171 -171
  199. package/dist/tools/spec/specGenerator.js +169 -169
  200. package/dist/tools/spec/traceabilityMatrix.js +64 -64
  201. package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
  202. package/dist/tools/thinking/analyzeProblem.d.ts +7 -0
  203. package/dist/tools/thinking/analyzeProblem.d.ts.map +1 -0
  204. package/dist/tools/thinking/analyzeProblem.js +55 -0
  205. package/dist/tools/thinking/analyzeProblem.js.map +1 -0
  206. package/dist/tools/thinking/breakDownProblem.d.ts +8 -0
  207. package/dist/tools/thinking/breakDownProblem.d.ts.map +1 -0
  208. package/dist/tools/thinking/breakDownProblem.js +145 -0
  209. package/dist/tools/thinking/breakDownProblem.js.map +1 -0
  210. package/dist/tools/thinking/createThinkingChain.d.ts +7 -0
  211. package/dist/tools/thinking/createThinkingChain.d.ts.map +1 -0
  212. package/dist/tools/thinking/createThinkingChain.js +44 -0
  213. package/dist/tools/thinking/createThinkingChain.js.map +1 -0
  214. package/dist/tools/thinking/formatAsPlan.d.ts +9 -0
  215. package/dist/tools/thinking/formatAsPlan.d.ts.map +1 -0
  216. package/dist/tools/thinking/formatAsPlan.js +78 -0
  217. package/dist/tools/thinking/formatAsPlan.js.map +1 -0
  218. package/dist/tools/thinking/index.d.ts +10 -0
  219. package/dist/tools/thinking/index.d.ts.map +1 -0
  220. package/dist/tools/thinking/index.js +10 -0
  221. package/dist/tools/thinking/index.js.map +1 -0
  222. package/dist/tools/thinking/stepByStepAnalysis.d.ts +8 -0
  223. package/dist/tools/thinking/stepByStepAnalysis.d.ts.map +1 -0
  224. package/dist/tools/thinking/stepByStepAnalysis.js +63 -0
  225. package/dist/tools/thinking/stepByStepAnalysis.js.map +1 -0
  226. package/dist/tools/thinking/thinkAloudProcess.d.ts +8 -0
  227. package/dist/tools/thinking/thinkAloudProcess.d.ts.map +1 -0
  228. package/dist/tools/thinking/thinkAloudProcess.js +80 -0
  229. package/dist/tools/thinking/thinkAloudProcess.js.map +1 -0
  230. package/hooks/hooks.json +115 -115
  231. package/hooks/scripts/code-check.js +70 -70
  232. package/hooks/scripts/code-review.js +22 -22
  233. package/hooks/scripts/complexity.js +22 -22
  234. package/hooks/scripts/compound.js +23 -23
  235. package/hooks/scripts/context-save.js +53 -53
  236. package/hooks/scripts/gemini-ui-gen.js +281 -281
  237. package/hooks/scripts/generate-brand-assets.js +474 -474
  238. package/hooks/scripts/hud-multiline.js +262 -262
  239. package/hooks/scripts/hud-status.js +291 -291
  240. package/hooks/scripts/keyword-detector.js +214 -214
  241. package/hooks/scripts/llm-orchestrate.js +171 -171
  242. package/hooks/scripts/post-edit.js +97 -97
  243. package/hooks/scripts/post-tool-verify.js +210 -210
  244. package/hooks/scripts/pre-tool-guard.js +125 -125
  245. package/hooks/scripts/prompt-dispatcher.js +161 -161
  246. package/hooks/scripts/recall.js +22 -22
  247. package/hooks/scripts/session-start.js +30 -30
  248. package/hooks/scripts/skill-injector.js +191 -191
  249. package/hooks/scripts/utils.js +97 -97
  250. package/languages/csharp-unity.md +515 -515
  251. package/languages/gdscript-godot.md +470 -470
  252. package/languages/ruby-rails.md +489 -489
  253. package/languages/typescript-angular.md +433 -433
  254. package/languages/typescript-astro.md +416 -416
  255. package/languages/typescript-electron.md +406 -406
  256. package/languages/typescript-nestjs.md +524 -524
  257. package/languages/typescript-svelte.md +407 -407
  258. package/languages/typescript-tauri.md +365 -365
  259. package/package.json +84 -84
  260. package/skills/brand-assets.md +141 -141
  261. package/skills/commerce-patterns.md +361 -361
  262. package/skills/context7-usage.md +102 -102
  263. package/skills/e2e-commerce.md +304 -304
  264. package/skills/frontend-design.md +92 -92
  265. package/skills/git-worktree.md +181 -181
  266. package/skills/parallel-research.md +77 -77
  267. package/skills/priority-todos.md +239 -239
  268. package/skills/seo-checklist.md +244 -244
  269. package/skills/tool-fallback.md +190 -190
  270. package/skills/vibe-capabilities.md +161 -161
  271. package/vibe/constitution.md +227 -227
  272. package/vibe/rules/core/communication-guide.md +98 -98
  273. package/vibe/rules/core/development-philosophy.md +52 -52
  274. package/vibe/rules/core/quick-start.md +102 -102
  275. package/vibe/rules/quality/bdd-contract-testing.md +393 -393
  276. package/vibe/rules/quality/checklist.md +276 -276
  277. package/vibe/rules/quality/testing-strategy.md +440 -440
  278. package/vibe/rules/standards/anti-patterns.md +541 -541
  279. package/vibe/rules/standards/code-structure.md +291 -291
  280. package/vibe/rules/standards/complexity-metrics.md +313 -313
  281. package/vibe/rules/standards/naming-conventions.md +198 -198
  282. package/vibe/setup.sh +31 -31
  283. package/vibe/templates/constitution-template.md +252 -252
  284. package/vibe/templates/contract-backend-template.md +526 -526
  285. package/vibe/templates/contract-frontend-template.md +599 -599
  286. package/vibe/templates/feature-template.md +96 -96
  287. package/vibe/templates/spec-template.md +221 -221
@@ -0,0 +1,673 @@
1
+ // Session RAG Store - Structured session context storage
2
+ // Manages Decisions, Constraints, Goals, Evidence with FTS5 search
3
+ // ============================================================================
4
+ // SessionRAGStore
5
+ // ============================================================================
6
+ export class SessionRAGStore {
7
+ db;
8
+ fts5Available = false;
9
+ constructor(storage) {
10
+ this.db = storage.getDatabase();
11
+ this.fts5Available = storage.isFTS5Available();
12
+ this.initializeTables();
13
+ }
14
+ // ==========================================================================
15
+ // Schema Initialization
16
+ // ==========================================================================
17
+ initializeTables() {
18
+ this.db.exec(`
19
+ CREATE TABLE IF NOT EXISTS session_decisions (
20
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
21
+ sessionId TEXT,
22
+ title TEXT NOT NULL,
23
+ description TEXT,
24
+ rationale TEXT,
25
+ alternatives TEXT,
26
+ impact TEXT,
27
+ status TEXT DEFAULT 'active' CHECK(status IN ('active','superseded','cancelled')),
28
+ priority INTEGER DEFAULT 1,
29
+ relatedFiles TEXT,
30
+ tags TEXT,
31
+ timestamp TEXT NOT NULL
32
+ );
33
+
34
+ CREATE INDEX IF NOT EXISTS idx_sdec_session ON session_decisions(sessionId);
35
+ CREATE INDEX IF NOT EXISTS idx_sdec_status ON session_decisions(status);
36
+ CREATE INDEX IF NOT EXISTS idx_sdec_priority ON session_decisions(priority);
37
+ CREATE INDEX IF NOT EXISTS idx_sdec_timestamp ON session_decisions(timestamp);
38
+ `);
39
+ this.db.exec(`
40
+ CREATE TABLE IF NOT EXISTS session_constraints (
41
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
42
+ sessionId TEXT,
43
+ title TEXT NOT NULL,
44
+ description TEXT,
45
+ type TEXT NOT NULL CHECK(type IN ('technical','business','resource','quality')),
46
+ severity TEXT DEFAULT 'medium' CHECK(severity IN ('low','medium','high','critical')),
47
+ scope TEXT,
48
+ timestamp TEXT NOT NULL
49
+ );
50
+
51
+ CREATE INDEX IF NOT EXISTS idx_scon_session ON session_constraints(sessionId);
52
+ CREATE INDEX IF NOT EXISTS idx_scon_type ON session_constraints(type);
53
+ CREATE INDEX IF NOT EXISTS idx_scon_severity ON session_constraints(severity);
54
+ `);
55
+ this.db.exec(`
56
+ CREATE TABLE IF NOT EXISTS session_goals (
57
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
58
+ sessionId TEXT,
59
+ parentId INTEGER,
60
+ title TEXT NOT NULL,
61
+ description TEXT,
62
+ status TEXT DEFAULT 'active' CHECK(status IN ('active','completed','blocked','cancelled')),
63
+ priority INTEGER DEFAULT 1,
64
+ progressPercent INTEGER DEFAULT 0 CHECK(progressPercent >= 0 AND progressPercent <= 100),
65
+ successCriteria TEXT,
66
+ timestamp TEXT NOT NULL,
67
+ completedAt TEXT,
68
+ FOREIGN KEY(parentId) REFERENCES session_goals(id)
69
+ );
70
+
71
+ CREATE INDEX IF NOT EXISTS idx_sgoal_session ON session_goals(sessionId);
72
+ CREATE INDEX IF NOT EXISTS idx_sgoal_status ON session_goals(status);
73
+ CREATE INDEX IF NOT EXISTS idx_sgoal_priority ON session_goals(priority);
74
+ CREATE INDEX IF NOT EXISTS idx_sgoal_parent ON session_goals(parentId);
75
+ `);
76
+ this.db.exec(`
77
+ CREATE TABLE IF NOT EXISTS session_evidence (
78
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
79
+ sessionId TEXT,
80
+ type TEXT NOT NULL CHECK(type IN ('test','build','lint','coverage','hud','review')),
81
+ title TEXT NOT NULL,
82
+ status TEXT NOT NULL CHECK(status IN ('pass','fail','warning','info')),
83
+ details TEXT,
84
+ metrics TEXT,
85
+ relatedGoals TEXT,
86
+ timestamp TEXT NOT NULL
87
+ );
88
+
89
+ CREATE INDEX IF NOT EXISTS idx_sevi_session ON session_evidence(sessionId);
90
+ CREATE INDEX IF NOT EXISTS idx_sevi_type ON session_evidence(type);
91
+ CREATE INDEX IF NOT EXISTS idx_sevi_status ON session_evidence(status);
92
+ CREATE INDEX IF NOT EXISTS idx_sevi_timestamp ON session_evidence(timestamp);
93
+ `);
94
+ this.initializeFTS5();
95
+ }
96
+ initializeFTS5() {
97
+ if (!this.fts5Available)
98
+ return;
99
+ try {
100
+ // Decisions FTS
101
+ this.db.exec(`
102
+ CREATE VIRTUAL TABLE IF NOT EXISTS session_decisions_fts
103
+ USING fts5(title, description, rationale, content=session_decisions, content_rowid=id);
104
+
105
+ CREATE TRIGGER IF NOT EXISTS sdec_fts_ai AFTER INSERT ON session_decisions BEGIN
106
+ INSERT INTO session_decisions_fts(rowid, title, description, rationale)
107
+ VALUES (new.id, new.title, new.description, new.rationale);
108
+ END;
109
+ CREATE TRIGGER IF NOT EXISTS sdec_fts_ad AFTER DELETE ON session_decisions BEGIN
110
+ INSERT INTO session_decisions_fts(session_decisions_fts, rowid, title, description, rationale)
111
+ VALUES('delete', old.id, old.title, old.description, old.rationale);
112
+ END;
113
+ CREATE TRIGGER IF NOT EXISTS sdec_fts_au AFTER UPDATE ON session_decisions BEGIN
114
+ INSERT INTO session_decisions_fts(session_decisions_fts, rowid, title, description, rationale)
115
+ VALUES('delete', old.id, old.title, old.description, old.rationale);
116
+ INSERT INTO session_decisions_fts(rowid, title, description, rationale)
117
+ VALUES (new.id, new.title, new.description, new.rationale);
118
+ END;
119
+ `);
120
+ // Constraints FTS
121
+ this.db.exec(`
122
+ CREATE VIRTUAL TABLE IF NOT EXISTS session_constraints_fts
123
+ USING fts5(title, description, content=session_constraints, content_rowid=id);
124
+
125
+ CREATE TRIGGER IF NOT EXISTS scon_fts_ai AFTER INSERT ON session_constraints BEGIN
126
+ INSERT INTO session_constraints_fts(rowid, title, description)
127
+ VALUES (new.id, new.title, new.description);
128
+ END;
129
+ CREATE TRIGGER IF NOT EXISTS scon_fts_ad AFTER DELETE ON session_constraints BEGIN
130
+ INSERT INTO session_constraints_fts(session_constraints_fts, rowid, title, description)
131
+ VALUES('delete', old.id, old.title, old.description);
132
+ END;
133
+ CREATE TRIGGER IF NOT EXISTS scon_fts_au AFTER UPDATE ON session_constraints BEGIN
134
+ INSERT INTO session_constraints_fts(session_constraints_fts, rowid, title, description)
135
+ VALUES('delete', old.id, old.title, old.description);
136
+ INSERT INTO session_constraints_fts(rowid, title, description)
137
+ VALUES (new.id, new.title, new.description);
138
+ END;
139
+ `);
140
+ // Goals FTS
141
+ this.db.exec(`
142
+ CREATE VIRTUAL TABLE IF NOT EXISTS session_goals_fts
143
+ USING fts5(title, description, content=session_goals, content_rowid=id);
144
+
145
+ CREATE TRIGGER IF NOT EXISTS sgoal_fts_ai AFTER INSERT ON session_goals BEGIN
146
+ INSERT INTO session_goals_fts(rowid, title, description)
147
+ VALUES (new.id, new.title, new.description);
148
+ END;
149
+ CREATE TRIGGER IF NOT EXISTS sgoal_fts_ad AFTER DELETE ON session_goals BEGIN
150
+ INSERT INTO session_goals_fts(session_goals_fts, rowid, title, description)
151
+ VALUES('delete', old.id, old.title, old.description);
152
+ END;
153
+ CREATE TRIGGER IF NOT EXISTS sgoal_fts_au AFTER UPDATE ON session_goals BEGIN
154
+ INSERT INTO session_goals_fts(session_goals_fts, rowid, title, description)
155
+ VALUES('delete', old.id, old.title, old.description);
156
+ INSERT INTO session_goals_fts(rowid, title, description)
157
+ VALUES (new.id, new.title, new.description);
158
+ END;
159
+ `);
160
+ // Evidence FTS
161
+ this.db.exec(`
162
+ CREATE VIRTUAL TABLE IF NOT EXISTS session_evidence_fts
163
+ USING fts5(title, details, content=session_evidence, content_rowid=id);
164
+
165
+ CREATE TRIGGER IF NOT EXISTS sevi_fts_ai AFTER INSERT ON session_evidence BEGIN
166
+ INSERT INTO session_evidence_fts(rowid, title, details)
167
+ VALUES (new.id, new.title, new.details);
168
+ END;
169
+ CREATE TRIGGER IF NOT EXISTS sevi_fts_ad AFTER DELETE ON session_evidence BEGIN
170
+ INSERT INTO session_evidence_fts(session_evidence_fts, rowid, title, details)
171
+ VALUES('delete', old.id, old.title, old.details);
172
+ END;
173
+ CREATE TRIGGER IF NOT EXISTS sevi_fts_au AFTER UPDATE ON session_evidence BEGIN
174
+ INSERT INTO session_evidence_fts(session_evidence_fts, rowid, title, details)
175
+ VALUES('delete', old.id, old.title, old.details);
176
+ INSERT INTO session_evidence_fts(rowid, title, details)
177
+ VALUES (new.id, new.title, new.details);
178
+ END;
179
+ `);
180
+ }
181
+ catch {
182
+ // FTS5 initialization failed for session RAG tables - non-critical
183
+ }
184
+ }
185
+ // ==========================================================================
186
+ // Decisions
187
+ // ==========================================================================
188
+ addDecision(input) {
189
+ const timestamp = new Date().toISOString();
190
+ const stmt = this.db.prepare(`
191
+ INSERT INTO session_decisions (sessionId, title, description, rationale, alternatives, impact, status, priority, relatedFiles, tags, timestamp)
192
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
193
+ `);
194
+ const result = stmt.run(input.sessionId || null, input.title, input.description || null, input.rationale || null, input.alternatives ? JSON.stringify(input.alternatives) : null, input.impact || null, input.status || 'active', input.priority ?? 1, input.relatedFiles ? JSON.stringify(input.relatedFiles) : null, input.tags ? JSON.stringify(input.tags) : null, timestamp);
195
+ return result.lastInsertRowid;
196
+ }
197
+ getDecision(id) {
198
+ const row = this.db.prepare(`SELECT * FROM session_decisions WHERE id = ?`).get(id);
199
+ return row ? this.rowToDecision(row) : null;
200
+ }
201
+ updateDecision(id, updates) {
202
+ const fields = [];
203
+ const values = [];
204
+ if (updates.title !== undefined) {
205
+ fields.push('title = ?');
206
+ values.push(updates.title);
207
+ }
208
+ if (updates.description !== undefined) {
209
+ fields.push('description = ?');
210
+ values.push(updates.description);
211
+ }
212
+ if (updates.rationale !== undefined) {
213
+ fields.push('rationale = ?');
214
+ values.push(updates.rationale);
215
+ }
216
+ if (updates.alternatives !== undefined) {
217
+ fields.push('alternatives = ?');
218
+ values.push(JSON.stringify(updates.alternatives));
219
+ }
220
+ if (updates.impact !== undefined) {
221
+ fields.push('impact = ?');
222
+ values.push(updates.impact);
223
+ }
224
+ if (updates.status !== undefined) {
225
+ fields.push('status = ?');
226
+ values.push(updates.status);
227
+ }
228
+ if (updates.priority !== undefined) {
229
+ fields.push('priority = ?');
230
+ values.push(updates.priority);
231
+ }
232
+ if (updates.relatedFiles !== undefined) {
233
+ fields.push('relatedFiles = ?');
234
+ values.push(JSON.stringify(updates.relatedFiles));
235
+ }
236
+ if (updates.tags !== undefined) {
237
+ fields.push('tags = ?');
238
+ values.push(JSON.stringify(updates.tags));
239
+ }
240
+ if (fields.length === 0)
241
+ return false;
242
+ values.push(id);
243
+ const result = this.db.prepare(`UPDATE session_decisions SET ${fields.join(', ')} WHERE id = ?`).run(...values);
244
+ return result.changes > 0;
245
+ }
246
+ listDecisions(sessionId, status, limit = 50) {
247
+ let sql = 'SELECT * FROM session_decisions WHERE 1=1';
248
+ const params = [];
249
+ if (sessionId) {
250
+ sql += ' AND sessionId = ?';
251
+ params.push(sessionId);
252
+ }
253
+ if (status) {
254
+ sql += ' AND status = ?';
255
+ params.push(status);
256
+ }
257
+ sql += ' ORDER BY priority DESC, timestamp DESC LIMIT ?';
258
+ params.push(limit);
259
+ const rows = this.db.prepare(sql).all(...params);
260
+ return rows.map(this.rowToDecision);
261
+ }
262
+ searchDecisions(query, limit = 20) {
263
+ if (this.fts5Available) {
264
+ try {
265
+ const rows = this.db.prepare(`
266
+ SELECT d.*, bm25(session_decisions_fts) as rank
267
+ FROM session_decisions_fts fts
268
+ JOIN session_decisions d ON d.id = fts.rowid
269
+ WHERE session_decisions_fts MATCH ?
270
+ ORDER BY rank
271
+ LIMIT ?
272
+ `).all(query, limit);
273
+ return rows.map(this.rowToDecision);
274
+ }
275
+ catch {
276
+ // FTS5 query failed, fall through to LIKE
277
+ }
278
+ }
279
+ const pattern = `%${query}%`;
280
+ const rows = this.db.prepare(`
281
+ SELECT * FROM session_decisions
282
+ WHERE title LIKE ? OR description LIKE ? OR rationale LIKE ?
283
+ ORDER BY priority DESC, timestamp DESC LIMIT ?
284
+ `).all(pattern, pattern, pattern, limit);
285
+ return rows.map(this.rowToDecision);
286
+ }
287
+ deleteDecision(id) {
288
+ const result = this.db.prepare('DELETE FROM session_decisions WHERE id = ?').run(id);
289
+ return result.changes > 0;
290
+ }
291
+ rowToDecision(row) {
292
+ return {
293
+ id: row.id,
294
+ sessionId: row.sessionId,
295
+ title: row.title,
296
+ description: row.description,
297
+ rationale: row.rationale,
298
+ alternatives: row.alternatives ? JSON.parse(row.alternatives) : [],
299
+ impact: row.impact,
300
+ status: row.status,
301
+ priority: row.priority,
302
+ relatedFiles: row.relatedFiles ? JSON.parse(row.relatedFiles) : [],
303
+ tags: row.tags ? JSON.parse(row.tags) : [],
304
+ timestamp: row.timestamp,
305
+ };
306
+ }
307
+ // ==========================================================================
308
+ // Constraints
309
+ // ==========================================================================
310
+ addConstraint(input) {
311
+ const timestamp = new Date().toISOString();
312
+ const stmt = this.db.prepare(`
313
+ INSERT INTO session_constraints (sessionId, title, description, type, severity, scope, timestamp)
314
+ VALUES (?, ?, ?, ?, ?, ?, ?)
315
+ `);
316
+ const result = stmt.run(input.sessionId || null, input.title, input.description || null, input.type, input.severity || 'medium', input.scope || null, timestamp);
317
+ return result.lastInsertRowid;
318
+ }
319
+ getConstraint(id) {
320
+ const row = this.db.prepare('SELECT * FROM session_constraints WHERE id = ?').get(id);
321
+ return row ? this.rowToConstraint(row) : null;
322
+ }
323
+ updateConstraint(id, updates) {
324
+ const fields = [];
325
+ const values = [];
326
+ if (updates.title !== undefined) {
327
+ fields.push('title = ?');
328
+ values.push(updates.title);
329
+ }
330
+ if (updates.description !== undefined) {
331
+ fields.push('description = ?');
332
+ values.push(updates.description);
333
+ }
334
+ if (updates.type !== undefined) {
335
+ fields.push('type = ?');
336
+ values.push(updates.type);
337
+ }
338
+ if (updates.severity !== undefined) {
339
+ fields.push('severity = ?');
340
+ values.push(updates.severity);
341
+ }
342
+ if (updates.scope !== undefined) {
343
+ fields.push('scope = ?');
344
+ values.push(updates.scope);
345
+ }
346
+ if (fields.length === 0)
347
+ return false;
348
+ values.push(id);
349
+ const result = this.db.prepare(`UPDATE session_constraints SET ${fields.join(', ')} WHERE id = ?`).run(...values);
350
+ return result.changes > 0;
351
+ }
352
+ listConstraints(sessionId, type, severity, limit = 50) {
353
+ let sql = 'SELECT * FROM session_constraints WHERE 1=1';
354
+ const params = [];
355
+ if (sessionId) {
356
+ sql += ' AND sessionId = ?';
357
+ params.push(sessionId);
358
+ }
359
+ if (type) {
360
+ sql += ' AND type = ?';
361
+ params.push(type);
362
+ }
363
+ if (severity) {
364
+ sql += ' AND severity = ?';
365
+ params.push(severity);
366
+ }
367
+ sql += ' ORDER BY CASE severity WHEN \'critical\' THEN 0 WHEN \'high\' THEN 1 WHEN \'medium\' THEN 2 WHEN \'low\' THEN 3 END, timestamp DESC LIMIT ?';
368
+ params.push(limit);
369
+ const rows = this.db.prepare(sql).all(...params);
370
+ return rows.map(this.rowToConstraint);
371
+ }
372
+ searchConstraints(query, limit = 20) {
373
+ if (this.fts5Available) {
374
+ try {
375
+ const rows = this.db.prepare(`
376
+ SELECT c.*, bm25(session_constraints_fts) as rank
377
+ FROM session_constraints_fts fts
378
+ JOIN session_constraints c ON c.id = fts.rowid
379
+ WHERE session_constraints_fts MATCH ?
380
+ ORDER BY rank
381
+ LIMIT ?
382
+ `).all(query, limit);
383
+ return rows.map(this.rowToConstraint);
384
+ }
385
+ catch {
386
+ // Fall through to LIKE
387
+ }
388
+ }
389
+ const pattern = `%${query}%`;
390
+ const rows = this.db.prepare(`
391
+ SELECT * FROM session_constraints
392
+ WHERE title LIKE ? OR description LIKE ?
393
+ ORDER BY timestamp DESC LIMIT ?
394
+ `).all(pattern, pattern, limit);
395
+ return rows.map(this.rowToConstraint);
396
+ }
397
+ deleteConstraint(id) {
398
+ const result = this.db.prepare('DELETE FROM session_constraints WHERE id = ?').run(id);
399
+ return result.changes > 0;
400
+ }
401
+ rowToConstraint(row) {
402
+ return {
403
+ id: row.id,
404
+ sessionId: row.sessionId,
405
+ title: row.title,
406
+ description: row.description,
407
+ type: row.type,
408
+ severity: row.severity,
409
+ scope: row.scope,
410
+ timestamp: row.timestamp,
411
+ };
412
+ }
413
+ // ==========================================================================
414
+ // Goals
415
+ // ==========================================================================
416
+ addGoal(input) {
417
+ const timestamp = new Date().toISOString();
418
+ const stmt = this.db.prepare(`
419
+ INSERT INTO session_goals (sessionId, parentId, title, description, status, priority, progressPercent, successCriteria, timestamp, completedAt)
420
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
421
+ `);
422
+ const result = stmt.run(input.sessionId || null, input.parentId || null, input.title, input.description || null, input.status || 'active', input.priority ?? 1, input.progressPercent ?? 0, input.successCriteria ? JSON.stringify(input.successCriteria) : null, timestamp, null);
423
+ return result.lastInsertRowid;
424
+ }
425
+ getGoal(id) {
426
+ const row = this.db.prepare('SELECT * FROM session_goals WHERE id = ?').get(id);
427
+ return row ? this.rowToGoal(row) : null;
428
+ }
429
+ updateGoal(id, updates) {
430
+ const fields = [];
431
+ const values = [];
432
+ if (updates.title !== undefined) {
433
+ fields.push('title = ?');
434
+ values.push(updates.title);
435
+ }
436
+ if (updates.description !== undefined) {
437
+ fields.push('description = ?');
438
+ values.push(updates.description);
439
+ }
440
+ if (updates.status !== undefined) {
441
+ fields.push('status = ?');
442
+ values.push(updates.status);
443
+ if (updates.status === 'completed') {
444
+ fields.push('completedAt = ?');
445
+ values.push(new Date().toISOString());
446
+ }
447
+ }
448
+ if (updates.priority !== undefined) {
449
+ fields.push('priority = ?');
450
+ values.push(updates.priority);
451
+ }
452
+ if (updates.progressPercent !== undefined) {
453
+ fields.push('progressPercent = ?');
454
+ values.push(updates.progressPercent);
455
+ }
456
+ if (updates.successCriteria !== undefined) {
457
+ fields.push('successCriteria = ?');
458
+ values.push(JSON.stringify(updates.successCriteria));
459
+ }
460
+ if (updates.parentId !== undefined) {
461
+ fields.push('parentId = ?');
462
+ values.push(updates.parentId);
463
+ }
464
+ if (fields.length === 0)
465
+ return false;
466
+ values.push(id);
467
+ const result = this.db.prepare(`UPDATE session_goals SET ${fields.join(', ')} WHERE id = ?`).run(...values);
468
+ return result.changes > 0;
469
+ }
470
+ listGoals(sessionId, status, limit = 50) {
471
+ let sql = 'SELECT * FROM session_goals WHERE 1=1';
472
+ const params = [];
473
+ if (sessionId) {
474
+ sql += ' AND sessionId = ?';
475
+ params.push(sessionId);
476
+ }
477
+ if (status) {
478
+ sql += ' AND status = ?';
479
+ params.push(status);
480
+ }
481
+ sql += ' ORDER BY priority DESC, timestamp DESC LIMIT ?';
482
+ params.push(limit);
483
+ const rows = this.db.prepare(sql).all(...params);
484
+ return rows.map(this.rowToGoal);
485
+ }
486
+ getActiveGoals(limit = 10) {
487
+ const rows = this.db.prepare(`
488
+ SELECT * FROM session_goals
489
+ WHERE status = 'active'
490
+ ORDER BY priority DESC, timestamp DESC
491
+ LIMIT ?
492
+ `).all(limit);
493
+ return rows.map(this.rowToGoal);
494
+ }
495
+ getGoalHierarchy(rootId) {
496
+ if (rootId) {
497
+ // Get root + all descendants (max 3 levels)
498
+ const rows = this.db.prepare(`
499
+ SELECT * FROM session_goals
500
+ WHERE id = ? OR parentId = ?
501
+ ORDER BY parentId NULLS FIRST, priority DESC
502
+ `).all(rootId, rootId);
503
+ return rows.map(this.rowToGoal);
504
+ }
505
+ // Get all top-level goals with children
506
+ const rows = this.db.prepare(`
507
+ SELECT * FROM session_goals
508
+ ORDER BY parentId NULLS FIRST, priority DESC, timestamp DESC
509
+ `).all();
510
+ return rows.map(this.rowToGoal);
511
+ }
512
+ searchGoals(query, limit = 20) {
513
+ if (this.fts5Available) {
514
+ try {
515
+ const rows = this.db.prepare(`
516
+ SELECT g.*, bm25(session_goals_fts) as rank
517
+ FROM session_goals_fts fts
518
+ JOIN session_goals g ON g.id = fts.rowid
519
+ WHERE session_goals_fts MATCH ?
520
+ ORDER BY rank
521
+ LIMIT ?
522
+ `).all(query, limit);
523
+ return rows.map(this.rowToGoal);
524
+ }
525
+ catch {
526
+ // Fall through to LIKE
527
+ }
528
+ }
529
+ const pattern = `%${query}%`;
530
+ const rows = this.db.prepare(`
531
+ SELECT * FROM session_goals
532
+ WHERE title LIKE ? OR description LIKE ?
533
+ ORDER BY priority DESC, timestamp DESC LIMIT ?
534
+ `).all(pattern, pattern, limit);
535
+ return rows.map(this.rowToGoal);
536
+ }
537
+ deleteGoal(id) {
538
+ const result = this.db.prepare('DELETE FROM session_goals WHERE id = ?').run(id);
539
+ return result.changes > 0;
540
+ }
541
+ rowToGoal(row) {
542
+ return {
543
+ id: row.id,
544
+ sessionId: row.sessionId,
545
+ parentId: row.parentId,
546
+ title: row.title,
547
+ description: row.description,
548
+ status: row.status,
549
+ priority: row.priority,
550
+ progressPercent: row.progressPercent,
551
+ successCriteria: row.successCriteria ? JSON.parse(row.successCriteria) : [],
552
+ timestamp: row.timestamp,
553
+ completedAt: row.completedAt,
554
+ };
555
+ }
556
+ // ==========================================================================
557
+ // Evidence
558
+ // ==========================================================================
559
+ addEvidence(input) {
560
+ const timestamp = new Date().toISOString();
561
+ const stmt = this.db.prepare(`
562
+ INSERT INTO session_evidence (sessionId, type, title, status, details, metrics, relatedGoals, timestamp)
563
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
564
+ `);
565
+ const result = stmt.run(input.sessionId || null, input.type, input.title, input.status, input.details ? JSON.stringify(input.details) : null, input.metrics ? JSON.stringify(input.metrics) : null, input.relatedGoals ? JSON.stringify(input.relatedGoals) : null, timestamp);
566
+ return result.lastInsertRowid;
567
+ }
568
+ getEvidence(id) {
569
+ const row = this.db.prepare('SELECT * FROM session_evidence WHERE id = ?').get(id);
570
+ return row ? this.rowToEvidence(row) : null;
571
+ }
572
+ listEvidence(sessionId, type, status, limit = 50) {
573
+ let sql = 'SELECT * FROM session_evidence WHERE 1=1';
574
+ const params = [];
575
+ if (sessionId) {
576
+ sql += ' AND sessionId = ?';
577
+ params.push(sessionId);
578
+ }
579
+ if (type) {
580
+ sql += ' AND type = ?';
581
+ params.push(type);
582
+ }
583
+ if (status) {
584
+ sql += ' AND status = ?';
585
+ params.push(status);
586
+ }
587
+ sql += ' ORDER BY timestamp DESC LIMIT ?';
588
+ params.push(limit);
589
+ const rows = this.db.prepare(sql).all(...params);
590
+ return rows.map(this.rowToEvidence);
591
+ }
592
+ getRecentEvidence(limit = 10) {
593
+ const rows = this.db.prepare(`
594
+ SELECT * FROM session_evidence
595
+ ORDER BY timestamp DESC
596
+ LIMIT ?
597
+ `).all(limit);
598
+ return rows.map(this.rowToEvidence);
599
+ }
600
+ searchEvidence(query, limit = 20) {
601
+ if (this.fts5Available) {
602
+ try {
603
+ const rows = this.db.prepare(`
604
+ SELECT e.*, bm25(session_evidence_fts) as rank
605
+ FROM session_evidence_fts fts
606
+ JOIN session_evidence e ON e.id = fts.rowid
607
+ WHERE session_evidence_fts MATCH ?
608
+ ORDER BY rank
609
+ LIMIT ?
610
+ `).all(query, limit);
611
+ return rows.map(this.rowToEvidence);
612
+ }
613
+ catch {
614
+ // Fall through to LIKE
615
+ }
616
+ }
617
+ const pattern = `%${query}%`;
618
+ const rows = this.db.prepare(`
619
+ SELECT * FROM session_evidence
620
+ WHERE title LIKE ? OR details LIKE ?
621
+ ORDER BY timestamp DESC LIMIT ?
622
+ `).all(pattern, pattern, limit);
623
+ return rows.map(this.rowToEvidence);
624
+ }
625
+ deleteEvidence(id) {
626
+ const result = this.db.prepare('DELETE FROM session_evidence WHERE id = ?').run(id);
627
+ return result.changes > 0;
628
+ }
629
+ rowToEvidence(row) {
630
+ return {
631
+ id: row.id,
632
+ sessionId: row.sessionId,
633
+ type: row.type,
634
+ title: row.title,
635
+ status: row.status,
636
+ details: row.details ? JSON.parse(row.details) : null,
637
+ metrics: row.metrics ? JSON.parse(row.metrics) : null,
638
+ relatedGoals: row.relatedGoals ? JSON.parse(row.relatedGoals) : [],
639
+ timestamp: row.timestamp,
640
+ };
641
+ }
642
+ // ==========================================================================
643
+ // Stats
644
+ // ==========================================================================
645
+ getStats() {
646
+ const decStatuses = this.db.prepare('SELECT status, COUNT(*) as count FROM session_decisions GROUP BY status').all();
647
+ const conTypes = this.db.prepare('SELECT type, COUNT(*) as count FROM session_constraints GROUP BY type').all();
648
+ const goalStatuses = this.db.prepare('SELECT status, COUNT(*) as count FROM session_goals GROUP BY status').all();
649
+ const eviTypes = this.db.prepare('SELECT type, COUNT(*) as count FROM session_evidence GROUP BY type').all();
650
+ const toRecord = (rows, keyField) => {
651
+ const record = {};
652
+ let total = 0;
653
+ for (const row of rows) {
654
+ const key = row[keyField];
655
+ const count = row.count;
656
+ record[key] = count;
657
+ total += count;
658
+ }
659
+ return { total, record };
660
+ };
661
+ const dec = toRecord(decStatuses, 'status');
662
+ const con = toRecord(conTypes, 'type');
663
+ const goal = toRecord(goalStatuses, 'status');
664
+ const evi = toRecord(eviTypes, 'type');
665
+ return {
666
+ decisions: { total: dec.total, byStatus: dec.record },
667
+ constraints: { total: con.total, byType: con.record },
668
+ goals: { total: goal.total, byStatus: goal.record },
669
+ evidence: { total: evi.total, byType: evi.record },
670
+ };
671
+ }
672
+ }
673
+ //# sourceMappingURL=SessionRAGStore.js.map