gitmem-mcp 0.2.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 (316) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/CLAUDE.md.template +65 -0
  3. package/LICENSE +21 -0
  4. package/README.md +221 -0
  5. package/bin/gitmem.js +383 -0
  6. package/dist/commands/check.d.ts +33 -0
  7. package/dist/commands/check.d.ts.map +1 -0
  8. package/dist/commands/check.js +492 -0
  9. package/dist/commands/check.js.map +1 -0
  10. package/dist/constants/closing-questions.d.ts +40 -0
  11. package/dist/constants/closing-questions.d.ts.map +1 -0
  12. package/dist/constants/closing-questions.js +107 -0
  13. package/dist/constants/closing-questions.js.map +1 -0
  14. package/dist/diagnostics/anonymizer.d.ts +55 -0
  15. package/dist/diagnostics/anonymizer.d.ts.map +1 -0
  16. package/dist/diagnostics/anonymizer.js +191 -0
  17. package/dist/diagnostics/anonymizer.js.map +1 -0
  18. package/dist/diagnostics/channels.d.ts +132 -0
  19. package/dist/diagnostics/channels.d.ts.map +1 -0
  20. package/dist/diagnostics/channels.js +150 -0
  21. package/dist/diagnostics/channels.js.map +1 -0
  22. package/dist/diagnostics/collector.d.ts +183 -0
  23. package/dist/diagnostics/collector.d.ts.map +1 -0
  24. package/dist/diagnostics/collector.js +227 -0
  25. package/dist/diagnostics/collector.js.map +1 -0
  26. package/dist/diagnostics/index.d.ts +28 -0
  27. package/dist/diagnostics/index.d.ts.map +1 -0
  28. package/dist/diagnostics/index.js +31 -0
  29. package/dist/diagnostics/index.js.map +1 -0
  30. package/dist/index.d.ts +13 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +18 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/schemas/absorb-observations.d.ts +63 -0
  35. package/dist/schemas/absorb-observations.d.ts.map +1 -0
  36. package/dist/schemas/absorb-observations.js +25 -0
  37. package/dist/schemas/absorb-observations.js.map +1 -0
  38. package/dist/schemas/active-sessions.d.ts +71 -0
  39. package/dist/schemas/active-sessions.d.ts.map +1 -0
  40. package/dist/schemas/active-sessions.js +19 -0
  41. package/dist/schemas/active-sessions.js.map +1 -0
  42. package/dist/schemas/analyze.d.ts +38 -0
  43. package/dist/schemas/analyze.d.ts.map +1 -0
  44. package/dist/schemas/analyze.js +30 -0
  45. package/dist/schemas/analyze.js.map +1 -0
  46. package/dist/schemas/common.d.ts +55 -0
  47. package/dist/schemas/common.d.ts.map +1 -0
  48. package/dist/schemas/common.js +65 -0
  49. package/dist/schemas/common.js.map +1 -0
  50. package/dist/schemas/create-decision.d.ts +48 -0
  51. package/dist/schemas/create-decision.d.ts.map +1 -0
  52. package/dist/schemas/create-decision.js +31 -0
  53. package/dist/schemas/create-decision.js.map +1 -0
  54. package/dist/schemas/create-learning.d.ts +107 -0
  55. package/dist/schemas/create-learning.d.ts.map +1 -0
  56. package/dist/schemas/create-learning.js +64 -0
  57. package/dist/schemas/create-learning.js.map +1 -0
  58. package/dist/schemas/get-transcript.d.ts +24 -0
  59. package/dist/schemas/get-transcript.d.ts.map +1 -0
  60. package/dist/schemas/get-transcript.js +22 -0
  61. package/dist/schemas/get-transcript.js.map +1 -0
  62. package/dist/schemas/index.d.ts +23 -0
  63. package/dist/schemas/index.d.ts.map +1 -0
  64. package/dist/schemas/index.js +23 -0
  65. package/dist/schemas/index.js.map +1 -0
  66. package/dist/schemas/log.d.ts +36 -0
  67. package/dist/schemas/log.d.ts.map +1 -0
  68. package/dist/schemas/log.js +27 -0
  69. package/dist/schemas/log.js.map +1 -0
  70. package/dist/schemas/prepare-context.d.ts +41 -0
  71. package/dist/schemas/prepare-context.d.ts.map +1 -0
  72. package/dist/schemas/prepare-context.js +31 -0
  73. package/dist/schemas/prepare-context.js.map +1 -0
  74. package/dist/schemas/recall.d.ts +41 -0
  75. package/dist/schemas/recall.d.ts.map +1 -0
  76. package/dist/schemas/recall.js +47 -0
  77. package/dist/schemas/recall.js.map +1 -0
  78. package/dist/schemas/record-scar-usage-batch.d.ts +82 -0
  79. package/dist/schemas/record-scar-usage-batch.d.ts.map +1 -0
  80. package/dist/schemas/record-scar-usage-batch.js +25 -0
  81. package/dist/schemas/record-scar-usage-batch.js.map +1 -0
  82. package/dist/schemas/record-scar-usage.d.ts +51 -0
  83. package/dist/schemas/record-scar-usage.d.ts.map +1 -0
  84. package/dist/schemas/record-scar-usage.js +32 -0
  85. package/dist/schemas/record-scar-usage.js.map +1 -0
  86. package/dist/schemas/save-transcript.d.ts +38 -0
  87. package/dist/schemas/save-transcript.d.ts.map +1 -0
  88. package/dist/schemas/save-transcript.js +30 -0
  89. package/dist/schemas/save-transcript.js.map +1 -0
  90. package/dist/schemas/search.d.ts +36 -0
  91. package/dist/schemas/search.d.ts.map +1 -0
  92. package/dist/schemas/search.js +27 -0
  93. package/dist/schemas/search.js.map +1 -0
  94. package/dist/schemas/session-close.d.ts +371 -0
  95. package/dist/schemas/session-close.d.ts.map +1 -0
  96. package/dist/schemas/session-close.js +95 -0
  97. package/dist/schemas/session-close.js.map +1 -0
  98. package/dist/schemas/session-start.d.ts +46 -0
  99. package/dist/schemas/session-start.d.ts.map +1 -0
  100. package/dist/schemas/session-start.js +33 -0
  101. package/dist/schemas/session-start.js.map +1 -0
  102. package/dist/schemas/thread.d.ts +72 -0
  103. package/dist/schemas/thread.d.ts.map +1 -0
  104. package/dist/schemas/thread.js +39 -0
  105. package/dist/schemas/thread.js.map +1 -0
  106. package/dist/server.d.ts +22 -0
  107. package/dist/server.d.ts.map +1 -0
  108. package/dist/server.js +313 -0
  109. package/dist/server.js.map +1 -0
  110. package/dist/services/active-sessions.d.ts +66 -0
  111. package/dist/services/active-sessions.d.ts.map +1 -0
  112. package/dist/services/active-sessions.js +311 -0
  113. package/dist/services/active-sessions.js.map +1 -0
  114. package/dist/services/agent-detection.d.ts +25 -0
  115. package/dist/services/agent-detection.d.ts.map +1 -0
  116. package/dist/services/agent-detection.js +93 -0
  117. package/dist/services/agent-detection.js.map +1 -0
  118. package/dist/services/analytics.d.ts +201 -0
  119. package/dist/services/analytics.d.ts.map +1 -0
  120. package/dist/services/analytics.js +483 -0
  121. package/dist/services/analytics.js.map +1 -0
  122. package/dist/services/cache.d.ts +148 -0
  123. package/dist/services/cache.d.ts.map +1 -0
  124. package/dist/services/cache.js +384 -0
  125. package/dist/services/cache.js.map +1 -0
  126. package/dist/services/cache.test.d.ts +8 -0
  127. package/dist/services/cache.test.d.ts.map +1 -0
  128. package/dist/services/cache.test.js +267 -0
  129. package/dist/services/cache.test.js.map +1 -0
  130. package/dist/services/compliance-validator.d.ts +30 -0
  131. package/dist/services/compliance-validator.d.ts.map +1 -0
  132. package/dist/services/compliance-validator.js +257 -0
  133. package/dist/services/compliance-validator.js.map +1 -0
  134. package/dist/services/config.d.ts +48 -0
  135. package/dist/services/config.d.ts.map +1 -0
  136. package/dist/services/config.js +128 -0
  137. package/dist/services/config.js.map +1 -0
  138. package/dist/services/embedding.d.ts +58 -0
  139. package/dist/services/embedding.d.ts.map +1 -0
  140. package/dist/services/embedding.js +243 -0
  141. package/dist/services/embedding.js.map +1 -0
  142. package/dist/services/gitmem-dir.d.ts +38 -0
  143. package/dist/services/gitmem-dir.d.ts.map +1 -0
  144. package/dist/services/gitmem-dir.js +84 -0
  145. package/dist/services/gitmem-dir.js.map +1 -0
  146. package/dist/services/local-file-storage.d.ts +56 -0
  147. package/dist/services/local-file-storage.d.ts.map +1 -0
  148. package/dist/services/local-file-storage.js +213 -0
  149. package/dist/services/local-file-storage.js.map +1 -0
  150. package/dist/services/local-vector-search.d.ts +137 -0
  151. package/dist/services/local-vector-search.d.ts.map +1 -0
  152. package/dist/services/local-vector-search.js +311 -0
  153. package/dist/services/local-vector-search.js.map +1 -0
  154. package/dist/services/metrics.d.ts +104 -0
  155. package/dist/services/metrics.d.ts.map +1 -0
  156. package/dist/services/metrics.js +264 -0
  157. package/dist/services/metrics.js.map +1 -0
  158. package/dist/services/session-state.d.ts +113 -0
  159. package/dist/services/session-state.d.ts.map +1 -0
  160. package/dist/services/session-state.js +203 -0
  161. package/dist/services/session-state.js.map +1 -0
  162. package/dist/services/startup.d.ts +112 -0
  163. package/dist/services/startup.d.ts.map +1 -0
  164. package/dist/services/startup.js +436 -0
  165. package/dist/services/startup.js.map +1 -0
  166. package/dist/services/storage.d.ts +43 -0
  167. package/dist/services/storage.d.ts.map +1 -0
  168. package/dist/services/storage.js +92 -0
  169. package/dist/services/storage.js.map +1 -0
  170. package/dist/services/supabase-client.d.ts +163 -0
  171. package/dist/services/supabase-client.d.ts.map +1 -0
  172. package/dist/services/supabase-client.js +510 -0
  173. package/dist/services/supabase-client.js.map +1 -0
  174. package/dist/services/thread-dedup.d.ts +44 -0
  175. package/dist/services/thread-dedup.d.ts.map +1 -0
  176. package/dist/services/thread-dedup.js +113 -0
  177. package/dist/services/thread-dedup.js.map +1 -0
  178. package/dist/services/thread-manager.d.ts +77 -0
  179. package/dist/services/thread-manager.d.ts.map +1 -0
  180. package/dist/services/thread-manager.js +250 -0
  181. package/dist/services/thread-manager.js.map +1 -0
  182. package/dist/services/thread-suggestions.d.ts +66 -0
  183. package/dist/services/thread-suggestions.d.ts.map +1 -0
  184. package/dist/services/thread-suggestions.js +243 -0
  185. package/dist/services/thread-suggestions.js.map +1 -0
  186. package/dist/services/thread-supabase.d.ts +111 -0
  187. package/dist/services/thread-supabase.d.ts.map +1 -0
  188. package/dist/services/thread-supabase.js +459 -0
  189. package/dist/services/thread-supabase.js.map +1 -0
  190. package/dist/services/thread-vitality.d.ts +65 -0
  191. package/dist/services/thread-vitality.d.ts.map +1 -0
  192. package/dist/services/thread-vitality.js +143 -0
  193. package/dist/services/thread-vitality.js.map +1 -0
  194. package/dist/services/tier.d.ts +52 -0
  195. package/dist/services/tier.d.ts.map +1 -0
  196. package/dist/services/tier.js +109 -0
  197. package/dist/services/tier.js.map +1 -0
  198. package/dist/services/timezone.d.ts +37 -0
  199. package/dist/services/timezone.d.ts.map +1 -0
  200. package/dist/services/timezone.js +147 -0
  201. package/dist/services/timezone.js.map +1 -0
  202. package/dist/services/transcript-chunker.d.ts +18 -0
  203. package/dist/services/transcript-chunker.d.ts.map +1 -0
  204. package/dist/services/transcript-chunker.js +237 -0
  205. package/dist/services/transcript-chunker.js.map +1 -0
  206. package/dist/services/triple-writer.d.ts +128 -0
  207. package/dist/services/triple-writer.d.ts.map +1 -0
  208. package/dist/services/triple-writer.js +338 -0
  209. package/dist/services/triple-writer.js.map +1 -0
  210. package/dist/services/variant-assignment.d.ts +92 -0
  211. package/dist/services/variant-assignment.d.ts.map +1 -0
  212. package/dist/services/variant-assignment.js +196 -0
  213. package/dist/services/variant-assignment.js.map +1 -0
  214. package/dist/tools/absorb-observations.d.ts +16 -0
  215. package/dist/tools/absorb-observations.d.ts.map +1 -0
  216. package/dist/tools/absorb-observations.js +82 -0
  217. package/dist/tools/absorb-observations.js.map +1 -0
  218. package/dist/tools/analyze.d.ts +55 -0
  219. package/dist/tools/analyze.d.ts.map +1 -0
  220. package/dist/tools/analyze.js +139 -0
  221. package/dist/tools/analyze.js.map +1 -0
  222. package/dist/tools/cleanup-threads.d.ts +47 -0
  223. package/dist/tools/cleanup-threads.d.ts.map +1 -0
  224. package/dist/tools/cleanup-threads.js +127 -0
  225. package/dist/tools/cleanup-threads.js.map +1 -0
  226. package/dist/tools/confirm-scars.d.ts +23 -0
  227. package/dist/tools/confirm-scars.d.ts.map +1 -0
  228. package/dist/tools/confirm-scars.js +209 -0
  229. package/dist/tools/confirm-scars.js.map +1 -0
  230. package/dist/tools/create-decision.d.ts +15 -0
  231. package/dist/tools/create-decision.d.ts.map +1 -0
  232. package/dist/tools/create-decision.js +138 -0
  233. package/dist/tools/create-decision.js.map +1 -0
  234. package/dist/tools/create-learning.d.ts +15 -0
  235. package/dist/tools/create-learning.d.ts.map +1 -0
  236. package/dist/tools/create-learning.js +226 -0
  237. package/dist/tools/create-learning.js.map +1 -0
  238. package/dist/tools/create-thread.d.ts +42 -0
  239. package/dist/tools/create-thread.d.ts.map +1 -0
  240. package/dist/tools/create-thread.js +180 -0
  241. package/dist/tools/create-thread.js.map +1 -0
  242. package/dist/tools/definitions.d.ts +5013 -0
  243. package/dist/tools/definitions.d.ts.map +1 -0
  244. package/dist/tools/definitions.js +2017 -0
  245. package/dist/tools/definitions.js.map +1 -0
  246. package/dist/tools/dismiss-suggestion.d.ts +20 -0
  247. package/dist/tools/dismiss-suggestion.d.ts.map +1 -0
  248. package/dist/tools/dismiss-suggestion.js +40 -0
  249. package/dist/tools/dismiss-suggestion.js.map +1 -0
  250. package/dist/tools/get-transcript.d.ts +24 -0
  251. package/dist/tools/get-transcript.d.ts.map +1 -0
  252. package/dist/tools/get-transcript.js +52 -0
  253. package/dist/tools/get-transcript.js.map +1 -0
  254. package/dist/tools/graph-traverse.d.ts +83 -0
  255. package/dist/tools/graph-traverse.d.ts.map +1 -0
  256. package/dist/tools/graph-traverse.js +394 -0
  257. package/dist/tools/graph-traverse.js.map +1 -0
  258. package/dist/tools/list-threads.d.ts +15 -0
  259. package/dist/tools/list-threads.d.ts.map +1 -0
  260. package/dist/tools/list-threads.js +114 -0
  261. package/dist/tools/list-threads.js.map +1 -0
  262. package/dist/tools/log.d.ts +43 -0
  263. package/dist/tools/log.d.ts.map +1 -0
  264. package/dist/tools/log.js +157 -0
  265. package/dist/tools/log.js.map +1 -0
  266. package/dist/tools/prepare-context.d.ts +36 -0
  267. package/dist/tools/prepare-context.d.ts.map +1 -0
  268. package/dist/tools/prepare-context.js +353 -0
  269. package/dist/tools/prepare-context.js.map +1 -0
  270. package/dist/tools/promote-suggestion.d.ts +25 -0
  271. package/dist/tools/promote-suggestion.d.ts.map +1 -0
  272. package/dist/tools/promote-suggestion.js +60 -0
  273. package/dist/tools/promote-suggestion.js.map +1 -0
  274. package/dist/tools/recall.d.ts +77 -0
  275. package/dist/tools/recall.d.ts.map +1 -0
  276. package/dist/tools/recall.js +423 -0
  277. package/dist/tools/recall.js.map +1 -0
  278. package/dist/tools/recall.test.d.ts +5 -0
  279. package/dist/tools/recall.test.d.ts.map +1 -0
  280. package/dist/tools/recall.test.js +155 -0
  281. package/dist/tools/recall.test.js.map +1 -0
  282. package/dist/tools/record-scar-usage-batch.d.ts +10 -0
  283. package/dist/tools/record-scar-usage-batch.d.ts.map +1 -0
  284. package/dist/tools/record-scar-usage-batch.js +153 -0
  285. package/dist/tools/record-scar-usage-batch.js.map +1 -0
  286. package/dist/tools/record-scar-usage.d.ts +14 -0
  287. package/dist/tools/record-scar-usage.d.ts.map +1 -0
  288. package/dist/tools/record-scar-usage.js +94 -0
  289. package/dist/tools/record-scar-usage.js.map +1 -0
  290. package/dist/tools/resolve-thread.d.ts +16 -0
  291. package/dist/tools/resolve-thread.d.ts.map +1 -0
  292. package/dist/tools/resolve-thread.js +102 -0
  293. package/dist/tools/resolve-thread.js.map +1 -0
  294. package/dist/tools/save-transcript.d.ts +29 -0
  295. package/dist/tools/save-transcript.d.ts.map +1 -0
  296. package/dist/tools/save-transcript.js +97 -0
  297. package/dist/tools/save-transcript.js.map +1 -0
  298. package/dist/tools/search.d.ts +46 -0
  299. package/dist/tools/search.d.ts.map +1 -0
  300. package/dist/tools/search.js +186 -0
  301. package/dist/tools/search.js.map +1 -0
  302. package/dist/tools/session-close.d.ts +14 -0
  303. package/dist/tools/session-close.d.ts.map +1 -0
  304. package/dist/tools/session-close.js +881 -0
  305. package/dist/tools/session-close.js.map +1 -0
  306. package/dist/tools/session-start.d.ts +38 -0
  307. package/dist/tools/session-start.d.ts.map +1 -0
  308. package/dist/tools/session-start.js +1104 -0
  309. package/dist/tools/session-start.js.map +1 -0
  310. package/dist/types/index.d.ts +456 -0
  311. package/dist/types/index.d.ts.map +1 -0
  312. package/dist/types/index.js +5 -0
  313. package/dist/types/index.js.map +1 -0
  314. package/package.json +76 -0
  315. package/schema/setup.sql +193 -0
  316. package/schema/starter-scars.json +206 -0
@@ -0,0 +1,338 @@
1
+ /**
2
+ * Knowledge Triple Writer Service
3
+ *
4
+ * Phase 2: Rule-based extraction of knowledge triples from
5
+ * create_learning and create_decision operations.
6
+ *
7
+ * Design principles:
8
+ * - Fire-and-forget: never blocks the main tool response
9
+ * - High-confidence only: rule-based, no guessing
10
+ * - Uses directUpsert pattern from supabase-client.ts
11
+ */
12
+ import { v4 as uuidv4 } from "uuid";
13
+ import * as supabase from "./supabase-client.js";
14
+ import { hasSupabase } from "./tier.js";
15
+ // --- Constants ---
16
+ /** Half-life profiles (days). Process = structural, never decays. */
17
+ const HALF_LIFE_PROCESS = 9999;
18
+ // --- Helpers ---
19
+ /**
20
+ * Canonical persona name map.
21
+ * Raw personas_involved values may contain full names or contextual suffixes.
22
+ * This ensures consistent node identity in the knowledge graph.
23
+ */
24
+ const CANONICAL_PERSONA_NAMES = {
25
+ "elena vos": "Elena",
26
+ "elena": "Elena",
27
+ "marcus thorne": "Marcus",
28
+ "marcus": "Marcus",
29
+ "reiko tanaka": "Reiko",
30
+ "reiko": "Reiko",
31
+ "jax": "Jax",
32
+ "jax dimitri": "Jax",
33
+ "jax reed": "Jax",
34
+ "chris crawford": "Chris Crawford",
35
+ "chris": "Chris Crawford",
36
+ };
37
+ /**
38
+ * Normalize a persona label to its canonical form.
39
+ * Strips contextual suffixes like " - UX navigation clarity" or ": Prefers non-invasive..."
40
+ * Then maps to canonical short name if known.
41
+ *
42
+ * Examples:
43
+ * "Elena Vos" → "Elena"
44
+ * "Marcus - Architectural pattern" → "Marcus"
45
+ * "Elena: Prefers non-invasive instrumentation" → "Elena"
46
+ * "Chris Crawford - Process decision" → "Chris Crawford"
47
+ */
48
+ export function normalizePersonaLabel(raw) {
49
+ // Strip contextual suffix after " - " or ": "
50
+ let name = raw.split(" - ")[0].split(": ")[0].trim();
51
+ // Strip parenthetical role descriptions like "(Integration & Deployment)"
52
+ name = name.replace(/\s*\(.*?\)\s*$/, "").trim();
53
+ // Look up canonical name (case-insensitive)
54
+ const canonical = CANONICAL_PERSONA_NAMES[name.toLowerCase()];
55
+ return canonical || name;
56
+ }
57
+ /** Set of canonical persona names (Orchestra team members + human). */
58
+ const KNOWN_PERSONAS = new Set(Object.values(CANONICAL_PERSONA_NAMES));
59
+ /**
60
+ * Determine if a name refers to an Orchestra persona vs an agent.
61
+ * Returns true for Elena, Marcus, Reiko, Jax, Chris Crawford.
62
+ */
63
+ function isPersonaName(name) {
64
+ return KNOWN_PERSONAS.has(normalizePersonaLabel(name));
65
+ }
66
+ /**
67
+ * Build a prefixed node label: "Persona: X" for known personas, "Agent: X" for agents.
68
+ * Normalizes persona names to canonical form.
69
+ */
70
+ export function buildInfluencerLabel(rawName) {
71
+ const normalized = normalizePersonaLabel(rawName);
72
+ if (isPersonaName(normalized)) {
73
+ return `Persona: ${normalized}`;
74
+ }
75
+ return `Agent: ${rawName}`;
76
+ }
77
+ /**
78
+ * Build a human-readable subject label following the existing DB convention:
79
+ * "Win: Read-side enrichment pattern for denormalization gaps"
80
+ */
81
+ function buildSubjectLabel(type, title) {
82
+ const typeLabels = {
83
+ scar: "Scar",
84
+ win: "Win",
85
+ pattern: "Pattern",
86
+ anti_pattern: "Anti-Pattern",
87
+ decision: "Decision",
88
+ thread: "Thread",
89
+ };
90
+ const label = typeLabels[type] || type.charAt(0).toUpperCase() + type.slice(1);
91
+ return `${label}: ${title}`;
92
+ }
93
+ /**
94
+ * Extract triples from a newly created learning using rule-based logic.
95
+ * Pure function — no side effects.
96
+ */
97
+ export function extractLearningTriples(params) {
98
+ const triples = [];
99
+ const subjectLabel = buildSubjectLabel(params.learning_type, params.title);
100
+ const base = {
101
+ source_type: "learning",
102
+ source_id: params.id,
103
+ source_linear_issue: params.source_linear_issue,
104
+ domain: params.domain,
105
+ project: params.project,
106
+ half_life_days: HALF_LIFE_PROCESS,
107
+ created_by: params.persona_name,
108
+ };
109
+ // RULE 1: source_linear_issue -> "created_in"
110
+ if (params.source_linear_issue) {
111
+ triples.push({
112
+ ...base,
113
+ subject: subjectLabel,
114
+ predicate: "created_in",
115
+ object: `Issue: ${params.source_linear_issue}`,
116
+ });
117
+ }
118
+ // RULE 2: persona_name -> "influenced_by"
119
+ if (params.persona_name && params.persona_name !== "Unknown") {
120
+ triples.push({
121
+ ...base,
122
+ subject: subjectLabel,
123
+ predicate: "influenced_by",
124
+ object: buildInfluencerLabel(params.persona_name),
125
+ });
126
+ }
127
+ // RULE 3: Description contains "supersedes" with a reference
128
+ const supersedesMatch = params.description.match(/supersedes?\s+(?:scar|learning|pattern|win)?\s*[:\-]?\s*["']?([^"'\n.]{10,80})["']?/i);
129
+ if (supersedesMatch) {
130
+ triples.push({
131
+ ...base,
132
+ subject: subjectLabel,
133
+ predicate: "supersedes",
134
+ object: supersedesMatch[1].trim(),
135
+ });
136
+ }
137
+ return triples;
138
+ }
139
+ /**
140
+ * Extract triples from a newly created decision using rule-based logic.
141
+ * Pure function — no side effects.
142
+ */
143
+ export function extractDecisionTriples(params) {
144
+ const triples = [];
145
+ const subjectLabel = buildSubjectLabel("decision", params.title);
146
+ const base = {
147
+ source_type: "decision",
148
+ source_id: params.id,
149
+ source_linear_issue: params.linear_issue,
150
+ project: params.project,
151
+ half_life_days: HALF_LIFE_PROCESS,
152
+ created_by: params.agent,
153
+ };
154
+ // RULE 1: linear_issue -> "created_in"
155
+ if (params.linear_issue) {
156
+ triples.push({
157
+ ...base,
158
+ subject: subjectLabel,
159
+ predicate: "created_in",
160
+ object: `Issue: ${params.linear_issue}`,
161
+ });
162
+ }
163
+ // RULE 2: Each persona -> "influenced_by"
164
+ if (params.personas_involved?.length) {
165
+ const seen = new Set();
166
+ for (const persona of params.personas_involved) {
167
+ const label = buildInfluencerLabel(persona);
168
+ if (seen.has(label))
169
+ continue; // dedup after normalization
170
+ seen.add(label);
171
+ triples.push({
172
+ ...base,
173
+ subject: subjectLabel,
174
+ predicate: "influenced_by",
175
+ object: label,
176
+ });
177
+ }
178
+ }
179
+ // RULE 3: Agent identity -> "influenced_by" (if not already covered by personas)
180
+ if (params.agent && params.agent !== "Unknown") {
181
+ const alreadyCovered = params.personas_involved?.some((p) => p.toLowerCase() === params.agent.toLowerCase());
182
+ if (!alreadyCovered) {
183
+ triples.push({
184
+ ...base,
185
+ subject: subjectLabel,
186
+ predicate: "influenced_by",
187
+ object: `Agent: ${params.agent}`,
188
+ });
189
+ }
190
+ }
191
+ // RULE 4: Each doc in docs_affected -> "affects_doc"
192
+ if (params.docs_affected?.length) {
193
+ for (const doc of params.docs_affected) {
194
+ triples.push({
195
+ ...base,
196
+ subject: subjectLabel,
197
+ predicate: "affects_doc",
198
+ object: `Doc: ${doc}`,
199
+ });
200
+ }
201
+ }
202
+ return triples;
203
+ }
204
+ // --- Write ---
205
+ /**
206
+ * Write triples to knowledge_triples table.
207
+ * Fire-and-forget: errors logged but never thrown to caller.
208
+ */
209
+ export async function writeTriples(candidates) {
210
+ if (candidates.length === 0 || !hasSupabase()) {
211
+ return 0;
212
+ }
213
+ let written = 0;
214
+ for (const candidate of candidates) {
215
+ try {
216
+ await supabase.directUpsert("knowledge_triples", {
217
+ id: uuidv4(),
218
+ subject: candidate.subject,
219
+ predicate: candidate.predicate,
220
+ object: candidate.object,
221
+ event_time: new Date().toISOString(),
222
+ decay_weight: 1.0,
223
+ half_life_days: candidate.half_life_days,
224
+ decay_floor: 0.1,
225
+ source_type: candidate.source_type,
226
+ source_id: candidate.source_id,
227
+ source_linear_issue: candidate.source_linear_issue || null,
228
+ domain: candidate.domain || [],
229
+ project: candidate.project,
230
+ created_at: new Date().toISOString(),
231
+ updated_at: new Date().toISOString(),
232
+ created_by: candidate.created_by,
233
+ });
234
+ written++;
235
+ }
236
+ catch (error) {
237
+ console.error(`[triple-writer] Failed to write triple: ${candidate.subject} ${candidate.predicate} ${candidate.object}`, error instanceof Error ? error.message : error);
238
+ }
239
+ }
240
+ if (written > 0) {
241
+ console.error(`[triple-writer] Wrote ${written}/${candidates.length} triples`);
242
+ }
243
+ return written;
244
+ }
245
+ // --- Public API ---
246
+ /**
247
+ * Generate and write triples for a newly created learning.
248
+ * Fire-and-forget — call with .catch(() => {}).
249
+ */
250
+ export function writeTriplesForLearning(params) {
251
+ const triples = extractLearningTriples(params);
252
+ return writeTriples(triples);
253
+ }
254
+ /**
255
+ * Generate and write triples for a newly created decision.
256
+ * Fire-and-forget — call with .catch(() => {}).
257
+ */
258
+ export function writeTriplesForDecision(params) {
259
+ const triples = extractDecisionTriples(params);
260
+ return writeTriples(triples);
261
+ }
262
+ /**
263
+ * Extract triples from a newly created thread.
264
+ * Pure function — no side effects.
265
+ */
266
+ export function extractThreadCreationTriples(params) {
267
+ const triples = [];
268
+ const threadLabel = buildSubjectLabel("thread", params.text);
269
+ const base = {
270
+ source_type: "thread",
271
+ source_id: params.thread_id,
272
+ source_linear_issue: params.linear_issue,
273
+ project: params.project,
274
+ half_life_days: HALF_LIFE_PROCESS,
275
+ created_by: params.agent,
276
+ };
277
+ // RULE 1: session_id -> "created_thread" (Session created this thread)
278
+ if (params.session_id) {
279
+ triples.push({
280
+ ...base,
281
+ subject: `Session: ${params.session_id}`,
282
+ predicate: "created_thread",
283
+ object: threadLabel,
284
+ });
285
+ }
286
+ // RULE 2: linear_issue -> "relates_to_thread" (Thread relates to issue)
287
+ if (params.linear_issue) {
288
+ triples.push({
289
+ ...base,
290
+ subject: threadLabel,
291
+ predicate: "relates_to_thread",
292
+ object: `Issue: ${params.linear_issue}`,
293
+ });
294
+ }
295
+ return triples;
296
+ }
297
+ /**
298
+ * Extract triples from a resolved thread.
299
+ * Pure function — no side effects.
300
+ */
301
+ export function extractThreadResolutionTriples(params) {
302
+ const triples = [];
303
+ const threadLabel = buildSubjectLabel("thread", params.text);
304
+ const base = {
305
+ source_type: "thread",
306
+ source_id: params.thread_id,
307
+ project: params.project,
308
+ half_life_days: HALF_LIFE_PROCESS,
309
+ created_by: params.agent,
310
+ };
311
+ // RULE 1: session_id -> "resolves_thread" (Session resolved this thread)
312
+ if (params.session_id) {
313
+ triples.push({
314
+ ...base,
315
+ subject: `Session: ${params.session_id}`,
316
+ predicate: "resolves_thread",
317
+ object: threadLabel,
318
+ });
319
+ }
320
+ return triples;
321
+ }
322
+ /**
323
+ * Generate and write triples for a newly created thread.
324
+ * Fire-and-forget — call with .catch(() => {}).
325
+ */
326
+ export function writeTriplesForThreadCreation(params) {
327
+ const triples = extractThreadCreationTriples(params);
328
+ return writeTriples(triples);
329
+ }
330
+ /**
331
+ * Generate and write triples for a resolved thread.
332
+ * Fire-and-forget — call with .catch(() => {}).
333
+ */
334
+ export function writeTriplesForThreadResolution(params) {
335
+ const triples = extractThreadResolutionTriples(params);
336
+ return writeTriples(triples);
337
+ }
338
+ //# sourceMappingURL=triple-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triple-writer.js","sourceRoot":"","sources":["../../src/services/triple-writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Scar Variant Assignment Service
3
+ * OD-525: Integrates variant assignment into enforcement engine
4
+ * OD-547: Switched from issue-keyed to agent-keyed assignment
5
+ *
6
+ * Handles:
7
+ * - Random variant assignment for scars with variants
8
+ * - Idempotent assignment (same agent+scar always gets same variant)
9
+ * - Legacy scar fallback (scars without variants use original description)
10
+ * - Blind testing (agent doesn't know which variant they received)
11
+ */
12
+ /**
13
+ * Variant record from database
14
+ */
15
+ export interface ScarVariant {
16
+ id: string;
17
+ variant_name: string;
18
+ variant_version: string;
19
+ description: string;
20
+ enforcement_config: {
21
+ type: "imperative" | "declarative";
22
+ show_counter_arguments?: boolean;
23
+ steps?: string[];
24
+ success_state?: string;
25
+ verification_tests?: string[];
26
+ constraints?: string[];
27
+ };
28
+ active: boolean;
29
+ }
30
+ /**
31
+ * Assignment record
32
+ * OD-547: Primary key is (agent_id, scar_id), issue_id/session_id are metadata
33
+ */
34
+ export interface VariantAssignment {
35
+ id: string;
36
+ agent_id: string;
37
+ scar_id: string;
38
+ variant_id: string;
39
+ assigned_at: string;
40
+ issue_id?: string;
41
+ session_id?: string;
42
+ }
43
+ /**
44
+ * Result of variant retrieval for a scar
45
+ */
46
+ export interface ScarWithVariant {
47
+ scar_id: string;
48
+ has_variants: boolean;
49
+ variant?: ScarVariant;
50
+ assignment?: VariantAssignment;
51
+ }
52
+ /**
53
+ * Get active variants for a scar
54
+ */
55
+ export declare function getActiveVariants(scarId: string): Promise<ScarVariant[]>;
56
+ /**
57
+ * Get existing assignment for an agent + scar pair
58
+ * OD-547: Changed from issue-keyed to agent-keyed lookup
59
+ */
60
+ export declare function getExistingAssignment(agentId: string, scarId: string): Promise<VariantAssignment | null>;
61
+ /**
62
+ * Create random variant assignment
63
+ * OD-547: Agent-keyed with optional issue/session metadata
64
+ */
65
+ export declare function createVariantAssignment(agentId: string, scarId: string, variants: ScarVariant[], metadata?: {
66
+ issueId?: string;
67
+ sessionId?: string;
68
+ }): Promise<VariantAssignment | null>;
69
+ /**
70
+ * Get or create variant assignment for a scar
71
+ * This is the main entry point for enforcement integration
72
+ *
73
+ * OD-547: Changed from issue-keyed to agent-keyed assignment.
74
+ * Agent identity is always available, so variants are always assigned.
75
+ *
76
+ * @param agentId - Agent identity (e.g., 'CLI', 'DAC', 'CODA-1')
77
+ * @param scarId - UUID of the scar
78
+ * @param metadata - Optional issue_id and session_id for triple traversals
79
+ * @returns Scar with variant info, or has_variants=false for legacy scars
80
+ */
81
+ export declare function getOrAssignVariant(agentId: string, scarId: string, metadata?: {
82
+ issueId?: string;
83
+ sessionId?: string;
84
+ }): Promise<ScarWithVariant>;
85
+ /**
86
+ * Format enforcement text based on variant type
87
+ * Returns formatted description with variant-specific structure
88
+ *
89
+ * This is BLIND - agent never sees variant name or type indicator
90
+ */
91
+ export declare function formatVariantEnforcement(variant: ScarVariant, scarTitle: string): string;
92
+ //# sourceMappingURL=variant-assignment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variant-assignment.d.ts","sourceRoot":"","sources":["../../src/services/variant-assignment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE;QAClB,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC;QACnC,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC9B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAuB9E;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAwBnC;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,WAAW,EAAE,EACvB,QAAQ,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkCnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,eAAe,CAAC,CA4C1B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmDxF"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Scar Variant Assignment Service
3
+ * OD-525: Integrates variant assignment into enforcement engine
4
+ * OD-547: Switched from issue-keyed to agent-keyed assignment
5
+ *
6
+ * Handles:
7
+ * - Random variant assignment for scars with variants
8
+ * - Idempotent assignment (same agent+scar always gets same variant)
9
+ * - Legacy scar fallback (scars without variants use original description)
10
+ * - Blind testing (agent doesn't know which variant they received)
11
+ */
12
+ import * as supabase from "./supabase-client.js";
13
+ /**
14
+ * Get active variants for a scar
15
+ */
16
+ export async function getActiveVariants(scarId) {
17
+ if (!supabase.isConfigured()) {
18
+ return [];
19
+ }
20
+ try {
21
+ // Use directQuery to bypass ww-mcp and query Supabase REST API directly
22
+ const variants = await supabase.directQuery("scar_enforcement_variants", {
23
+ select: "*",
24
+ filters: {
25
+ scar_id: scarId,
26
+ active: "true",
27
+ },
28
+ });
29
+ return variants;
30
+ }
31
+ catch (error) {
32
+ console.error(`[variant-assignment] Exception fetching variants:`, error);
33
+ return [];
34
+ }
35
+ }
36
+ /**
37
+ * Get existing assignment for an agent + scar pair
38
+ * OD-547: Changed from issue-keyed to agent-keyed lookup
39
+ */
40
+ export async function getExistingAssignment(agentId, scarId) {
41
+ if (!supabase.isConfigured()) {
42
+ return null;
43
+ }
44
+ try {
45
+ const assignments = await supabase.directQuery("variant_assignments", {
46
+ select: "*",
47
+ filters: {
48
+ agent_id: agentId,
49
+ },
50
+ limit: 10,
51
+ });
52
+ // Filter by scar_id locally
53
+ const match = assignments.find(a => a.scar_id === scarId);
54
+ return match || null;
55
+ }
56
+ catch (error) {
57
+ console.error(`[variant-assignment] Exception fetching assignment:`, error);
58
+ return null;
59
+ }
60
+ }
61
+ /**
62
+ * Create random variant assignment
63
+ * OD-547: Agent-keyed with optional issue/session metadata
64
+ */
65
+ export async function createVariantAssignment(agentId, scarId, variants, metadata) {
66
+ if (!supabase.isConfigured() || variants.length === 0) {
67
+ return null;
68
+ }
69
+ try {
70
+ // Random selection from active variants
71
+ const randomIndex = Math.floor(Math.random() * variants.length);
72
+ const selectedVariant = variants[randomIndex];
73
+ const result = await supabase.directUpsert("variant_assignments", {
74
+ agent_id: agentId,
75
+ scar_id: scarId,
76
+ variant_id: selectedVariant.id,
77
+ issue_id: metadata?.issueId || null,
78
+ session_id: metadata?.sessionId || null,
79
+ });
80
+ return result;
81
+ }
82
+ catch (error) {
83
+ const errorMessage = error instanceof Error ? error.message : String(error);
84
+ // Handle race condition: unique constraint violation
85
+ if (errorMessage.includes("23505") || errorMessage.includes("duplicate key")) {
86
+ console.error(`[variant-assignment] Assignment already exists (race condition), fetching...`);
87
+ return await getExistingAssignment(agentId, scarId);
88
+ }
89
+ console.error(`[variant-assignment] Exception creating assignment:`, error);
90
+ return null;
91
+ }
92
+ }
93
+ /**
94
+ * Get or create variant assignment for a scar
95
+ * This is the main entry point for enforcement integration
96
+ *
97
+ * OD-547: Changed from issue-keyed to agent-keyed assignment.
98
+ * Agent identity is always available, so variants are always assigned.
99
+ *
100
+ * @param agentId - Agent identity (e.g., 'CLI', 'DAC', 'CODA-1')
101
+ * @param scarId - UUID of the scar
102
+ * @param metadata - Optional issue_id and session_id for triple traversals
103
+ * @returns Scar with variant info, or has_variants=false for legacy scars
104
+ */
105
+ export async function getOrAssignVariant(agentId, scarId, metadata) {
106
+ // Step 1: Check for active variants
107
+ const variants = await getActiveVariants(scarId);
108
+ if (variants.length === 0) {
109
+ // Legacy scar - no variants available
110
+ return {
111
+ scar_id: scarId,
112
+ has_variants: false,
113
+ };
114
+ }
115
+ // Step 2: Check for existing assignment (idempotent per agent+scar)
116
+ let assignment = await getExistingAssignment(agentId, scarId);
117
+ // Step 3: Create assignment if it doesn't exist
118
+ if (!assignment) {
119
+ assignment = await createVariantAssignment(agentId, scarId, variants, metadata);
120
+ if (!assignment) {
121
+ // Assignment failed, fall back to legacy mode
122
+ return {
123
+ scar_id: scarId,
124
+ has_variants: false,
125
+ };
126
+ }
127
+ }
128
+ // Step 4: Find the assigned variant
129
+ const variant = variants.find((v) => v.id === assignment.variant_id);
130
+ if (!variant) {
131
+ console.error(`[variant-assignment] Variant ${assignment.variant_id} not found in active variants`);
132
+ return {
133
+ scar_id: scarId,
134
+ has_variants: false,
135
+ };
136
+ }
137
+ return {
138
+ scar_id: scarId,
139
+ has_variants: true,
140
+ variant,
141
+ assignment,
142
+ };
143
+ }
144
+ /**
145
+ * Format enforcement text based on variant type
146
+ * Returns formatted description with variant-specific structure
147
+ *
148
+ * This is BLIND - agent never sees variant name or type indicator
149
+ */
150
+ export function formatVariantEnforcement(variant, scarTitle) {
151
+ const config = variant.enforcement_config;
152
+ if (config.type === "imperative") {
153
+ // Traditional format: imperative steps
154
+ const lines = [];
155
+ if (config.steps && config.steps.length > 0) {
156
+ for (const step of config.steps) {
157
+ lines.push(step);
158
+ }
159
+ }
160
+ else {
161
+ // Fallback to description if no steps
162
+ lines.push(variant.description);
163
+ }
164
+ return lines.join("\n\n");
165
+ }
166
+ else if (config.type === "declarative") {
167
+ // Karpathy format: success state + verification tests + constraints
168
+ const lines = [];
169
+ if (config.success_state) {
170
+ lines.push("## Success State");
171
+ lines.push("");
172
+ lines.push(config.success_state);
173
+ lines.push("");
174
+ }
175
+ if (config.verification_tests && config.verification_tests.length > 0) {
176
+ lines.push("## Verification Tests");
177
+ lines.push("");
178
+ for (const test of config.verification_tests) {
179
+ lines.push(`- ${test}`);
180
+ }
181
+ lines.push("");
182
+ }
183
+ if (config.constraints && config.constraints.length > 0) {
184
+ lines.push("## Constraints");
185
+ lines.push("");
186
+ for (const constraint of config.constraints) {
187
+ lines.push(`- ${constraint}`);
188
+ }
189
+ lines.push("");
190
+ }
191
+ return lines.join("\n");
192
+ }
193
+ // Fallback
194
+ return variant.description;
195
+ }
196
+ //# sourceMappingURL=variant-assignment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variant-assignment.js","sourceRoot":"","sources":["../../src/services/variant-assignment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * absorb_observations Tool (GitMem v2 Phase 2)
3
+ *
4
+ * Captures observations from sub-agents and teammates.
5
+ * The lead agent parses findings from sub-agent responses,
6
+ * then calls this tool to persist and analyze them.
7
+ *
8
+ * Identifies scar candidates via explicit severity or pattern matching.
9
+ * Observations are stored in-memory (session state) and optionally
10
+ * persisted to Supabase as a fire-and-forget upsert.
11
+ *
12
+ * Performance target: <500ms (in-memory + optional upsert)
13
+ */
14
+ import type { AbsorbObservationsParams, AbsorbObservationsResult } from "../types/index.js";
15
+ export declare function absorbObservations(params: AbsorbObservationsParams): Promise<AbsorbObservationsResult>;
16
+ //# sourceMappingURL=absorb-observations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"absorb-observations.d.ts","sourceRoot":"","sources":["../../src/tools/absorb-observations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAe,MAAM,mBAAmB,CAAC;AA2BzG,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,wBAAwB,CAAC,CA+CnC"}