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,510 @@
1
+ /**
2
+ * Supabase MCP Client
3
+ *
4
+ * HTTP client for ww-mcp Edge Function following the pattern from
5
+ * agents/coda/src/services/supabase-mcp.js
6
+ *
7
+ * Uses JSON-RPC 2.0 protocol over HTTPS.
8
+ * Integrates with CacheService for performance (OD-473).
9
+ */
10
+ import { getCache } from "./cache.js";
11
+ // Configuration from environment
12
+ const SUPABASE_URL = process.env.SUPABASE_URL || "";
13
+ const SUPABASE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_KEY || "";
14
+ // Direct REST API base URL
15
+ const SUPABASE_REST_URL = SUPABASE_URL ? `${SUPABASE_URL}/rest/v1` : "";
16
+ /**
17
+ * Check if Supabase is configured
18
+ */
19
+ export function isConfigured() {
20
+ return !!(SUPABASE_URL && SUPABASE_KEY);
21
+ }
22
+ /**
23
+ * Get the ww-mcp Edge Function URL
24
+ */
25
+ function getMcpUrl() {
26
+ return `${SUPABASE_URL}/functions/v1/ww-mcp`;
27
+ }
28
+ /**
29
+ * Call the ww-mcp Edge Function
30
+ */
31
+ async function callMcp(toolName, args) {
32
+ if (!isConfigured()) {
33
+ throw new Error("Supabase not configured - check SUPABASE_URL and SUPABASE_KEY/SUPABASE_SERVICE_ROLE_KEY");
34
+ }
35
+ const mcpUrl = getMcpUrl();
36
+ const response = await fetch(mcpUrl, {
37
+ method: "POST",
38
+ headers: {
39
+ "Content-Type": "application/json",
40
+ Authorization: `Bearer ${SUPABASE_KEY}`,
41
+ },
42
+ body: JSON.stringify({
43
+ jsonrpc: "2.0",
44
+ id: `${toolName}-${Date.now()}`,
45
+ method: "tools/call",
46
+ params: {
47
+ name: toolName,
48
+ arguments: args,
49
+ },
50
+ }),
51
+ });
52
+ if (!response.ok) {
53
+ const text = await response.text();
54
+ throw new Error(`MCP HTTP error: ${response.status} - ${text.slice(0, 200)}`);
55
+ }
56
+ const result = await response.json();
57
+ if (result.error) {
58
+ throw new Error(`MCP error: ${JSON.stringify(result.error)}`);
59
+ }
60
+ // Parse the result content
61
+ if (result.result?.content?.[0]?.text) {
62
+ return JSON.parse(result.result.content[0].text);
63
+ }
64
+ return result.result;
65
+ }
66
+ /**
67
+ * List records from a table with optional filters
68
+ */
69
+ export async function listRecords(options) {
70
+ const { table, columns, filters, limit = 50, orderBy } = options;
71
+ const args = {
72
+ table,
73
+ limit,
74
+ };
75
+ if (columns) {
76
+ args.columns = columns;
77
+ }
78
+ if (filters) {
79
+ args.filters = filters;
80
+ }
81
+ if (orderBy) {
82
+ args.orderBy = orderBy;
83
+ }
84
+ const result = await callMcp("list_records", args);
85
+ return result.data || [];
86
+ }
87
+ /**
88
+ * Get a single record by ID
89
+ */
90
+ export async function getRecord(table, id) {
91
+ const result = await callMcp("get_record", { table, id });
92
+ return result.data || null;
93
+ }
94
+ /**
95
+ * Upsert (insert or update) a record
96
+ */
97
+ export async function upsertRecord(table, data) {
98
+ const result = await callMcp("upsert_record", {
99
+ table,
100
+ data,
101
+ });
102
+ // ww-mcp returns { data: record, operation: 'insert'|'update', embedding_generated: bool }
103
+ return result.data || result;
104
+ }
105
+ /**
106
+ * Semantic search across tables
107
+ */
108
+ export async function semanticSearch(options) {
109
+ const { query, tables, match_count = 10, project } = options;
110
+ const args = {
111
+ query,
112
+ match_count,
113
+ };
114
+ if (tables && tables.length > 0) {
115
+ args.tables = tables;
116
+ }
117
+ if (project) {
118
+ args.project = project;
119
+ }
120
+ const result = await callMcp("semantic_search", args);
121
+ return result.results || [];
122
+ }
123
+ // ============================================================================
124
+ // DIRECT SUPABASE QUERIES (bypass ww-mcp for bulk operations)
125
+ // ============================================================================
126
+ /**
127
+ * Query Supabase REST API directly (bypasses ww-mcp)
128
+ *
129
+ * Used for bulk operations like loading all scars with embeddings.
130
+ * ww-mcp doesn't return embeddings by default to avoid bloated responses,
131
+ * but for local vector search we need them.
132
+ */
133
+ export async function directQuery(table, options = {}) {
134
+ if (!isConfigured()) {
135
+ throw new Error("Supabase not configured");
136
+ }
137
+ const { select = "*", filters = {}, order, limit } = options;
138
+ // Build query URL
139
+ const url = new URL(`${SUPABASE_REST_URL}/${table}`);
140
+ url.searchParams.set("select", select);
141
+ // Add filters (PostgREST syntax)
142
+ // If value already contains an operator (e.g., "in.(...)"), use as-is
143
+ // Otherwise, prefix with "eq." for equality
144
+ for (const [key, value] of Object.entries(filters)) {
145
+ const filterValue = value.includes('.') ? value : `eq.${value}`;
146
+ url.searchParams.set(key, filterValue);
147
+ }
148
+ // Add ordering
149
+ if (order) {
150
+ url.searchParams.set("order", order);
151
+ }
152
+ // Add limit
153
+ if (limit) {
154
+ url.searchParams.set("limit", String(limit));
155
+ }
156
+ const response = await fetch(url.toString(), {
157
+ method: "GET",
158
+ headers: {
159
+ "apikey": SUPABASE_KEY,
160
+ "Authorization": `Bearer ${SUPABASE_KEY}`,
161
+ "Content-Type": "application/json",
162
+ "Prefer": "return=representation",
163
+ "Accept-Profile": "public", // Required: explicitly use public schema
164
+ },
165
+ });
166
+ if (!response.ok) {
167
+ const text = await response.text();
168
+ throw new Error(`Supabase REST error: ${response.status} - ${text.slice(0, 200)}`);
169
+ }
170
+ return response.json();
171
+ }
172
+ /**
173
+ * Paginated fetch — retrieves ALL matching rows using PostgREST Range headers.
174
+ * Use instead of directQuery when the result set may exceed a single page.
175
+ *
176
+ * @param pageSize Rows per request (default 1000)
177
+ * @param maxRows Safety cap to prevent runaway queries (default 10000)
178
+ */
179
+ export async function directQueryAll(table, options = {}, pageSize = 1000, maxRows = 10000) {
180
+ if (!isConfigured()) {
181
+ throw new Error("Supabase not configured");
182
+ }
183
+ const { select = "*", filters = {}, order } = options;
184
+ const allRows = [];
185
+ let offset = 0;
186
+ while (offset < maxRows) {
187
+ const url = new URL(`${SUPABASE_REST_URL}/${table}`);
188
+ url.searchParams.set("select", select);
189
+ for (const [key, value] of Object.entries(filters)) {
190
+ const filterValue = value.includes('.') ? value : `eq.${value}`;
191
+ url.searchParams.set(key, filterValue);
192
+ }
193
+ if (order) {
194
+ url.searchParams.set("order", order);
195
+ }
196
+ const rangeEnd = offset + pageSize - 1;
197
+ const response = await fetch(url.toString(), {
198
+ method: "GET",
199
+ headers: {
200
+ "apikey": SUPABASE_KEY,
201
+ "Authorization": `Bearer ${SUPABASE_KEY}`,
202
+ "Content-Type": "application/json",
203
+ "Range": `${offset}-${rangeEnd}`,
204
+ "Range-Unit": "items",
205
+ "Prefer": "count=exact",
206
+ "Accept-Profile": "public",
207
+ },
208
+ });
209
+ if (!response.ok) {
210
+ const text = await response.text();
211
+ throw new Error(`Supabase REST error: ${response.status} - ${text.slice(0, 200)}`);
212
+ }
213
+ const rows = await response.json();
214
+ allRows.push(...rows);
215
+ // Check Content-Range header: "0-999/1234" or "*/0" for empty
216
+ const contentRange = response.headers.get("content-range");
217
+ if (!contentRange || rows.length < pageSize) {
218
+ break; // No more rows or last page
219
+ }
220
+ const match = contentRange.match(/\/(\d+)/);
221
+ if (match) {
222
+ const total = parseInt(match[1]);
223
+ if (offset + pageSize >= total)
224
+ break;
225
+ }
226
+ offset += pageSize;
227
+ }
228
+ return allRows;
229
+ }
230
+ /**
231
+ * Fetch related knowledge triples for a set of scar IDs (OD-466)
232
+ *
233
+ * Queries knowledge_triples table where source_id matches any of the provided scar IDs.
234
+ * Returns triples grouped by source_id for easy attachment to scars.
235
+ */
236
+ export async function fetchRelatedTriples(scarIds) {
237
+ const result = new Map();
238
+ if (scarIds.length === 0 || !isConfigured()) {
239
+ return result;
240
+ }
241
+ try {
242
+ const triples = await directQuery("knowledge_triples", {
243
+ select: "subject,predicate,object,event_time,decay_weight,half_life_days,decay_floor,source_id",
244
+ filters: {
245
+ source_id: `in.(${scarIds.join(",")})`,
246
+ },
247
+ });
248
+ for (const triple of triples) {
249
+ const existing = result.get(triple.source_id) || [];
250
+ existing.push(triple);
251
+ result.set(triple.source_id, existing);
252
+ }
253
+ }
254
+ catch (error) {
255
+ console.error("[fetchRelatedTriples] Failed:", error instanceof Error ? error.message : error);
256
+ }
257
+ return result;
258
+ }
259
+ /**
260
+ * Upsert a record directly to Supabase REST API (bypasses ww-mcp)
261
+ *
262
+ * Used for tests where ww-mcp authentication is problematic.
263
+ * Uses Supabase REST API's upsert capability with Prefer: resolution=merge-duplicates.
264
+ */
265
+ export async function directUpsert(table, data) {
266
+ if (!isConfigured()) {
267
+ throw new Error("Supabase not configured");
268
+ }
269
+ const url = `${SUPABASE_REST_URL}/${table}`;
270
+ const response = await fetch(url, {
271
+ method: "POST",
272
+ headers: {
273
+ "apikey": SUPABASE_KEY,
274
+ "Authorization": `Bearer ${SUPABASE_KEY}`,
275
+ "Content-Type": "application/json",
276
+ "Prefer": "return=representation,resolution=merge-duplicates",
277
+ "Content-Profile": "public", // Schema for write operations
278
+ },
279
+ body: JSON.stringify(data),
280
+ });
281
+ if (!response.ok) {
282
+ const text = await response.text();
283
+ throw new Error(`Supabase upsert error: ${response.status} - ${text.slice(0, 200)}`);
284
+ }
285
+ const result = await response.json();
286
+ // OD-539: Validate that write actually happened
287
+ // Supabase can return 200 OK with empty array [] when:
288
+ // - RLS policy blocks the write
289
+ // - Constraint violation handled gracefully
290
+ // - Database trigger cancels the insert
291
+ // - Schema mismatch
292
+ if (!result || result.length === 0) {
293
+ throw new Error(`Supabase upsert returned empty result for table '${table}'. ` +
294
+ `This usually means the write was silently blocked. ` +
295
+ `Check: (1) RLS policies on ${table}, (2) NOT NULL constraints, (3) database triggers, (4) correct schema`);
296
+ }
297
+ return result[0];
298
+ }
299
+ /**
300
+ * Patch (partial update) existing records in Supabase REST API.
301
+ *
302
+ * Uses HTTP PATCH for true partial updates — only the provided fields are
303
+ * modified. Unlike directUpsert (POST + merge-duplicates), this does NOT
304
+ * try to INSERT first, so NOT NULL columns that aren't changing can be
305
+ * omitted from `data`.
306
+ *
307
+ * @param table Target table name
308
+ * @param filters PostgREST filter to identify the row(s) to update
309
+ * @param data Fields to update (partial — omitted columns stay unchanged)
310
+ */
311
+ export async function directPatch(table, filters, data) {
312
+ if (!isConfigured()) {
313
+ throw new Error("Supabase not configured");
314
+ }
315
+ const url = new URL(`${SUPABASE_REST_URL}/${table}`);
316
+ // Apply filters (same logic as directQuery)
317
+ for (const [key, value] of Object.entries(filters)) {
318
+ const filterValue = value.includes(".") ? value : `eq.${value}`;
319
+ url.searchParams.set(key, filterValue);
320
+ }
321
+ const response = await fetch(url.toString(), {
322
+ method: "PATCH",
323
+ headers: {
324
+ "apikey": SUPABASE_KEY,
325
+ "Authorization": `Bearer ${SUPABASE_KEY}`,
326
+ "Content-Type": "application/json",
327
+ "Prefer": "return=representation",
328
+ "Content-Profile": "public",
329
+ },
330
+ body: JSON.stringify(data),
331
+ });
332
+ if (!response.ok) {
333
+ const text = await response.text();
334
+ throw new Error(`Supabase patch error: ${response.status} - ${text.slice(0, 200)}`);
335
+ }
336
+ return response.json();
337
+ }
338
+ /**
339
+ * Load all learnings with embeddings directly from Supabase
340
+ *
341
+ * This bypasses ww-mcp because we need the embedding vectors for local search.
342
+ * Returns learnings (scars, patterns, wins, anti-patterns) with full embedding data.
343
+ *
344
+ * NOTE: Changed from "scars only" to "all learning types" (OD-542 related fix)
345
+ */
346
+ export async function loadScarsWithEmbeddings(project, limit = 500) {
347
+ console.error(`[supabase-direct] Loading learnings with embeddings for project: ${project}`);
348
+ const startTime = Date.now();
349
+ try {
350
+ const learnings = await directQuery("orchestra_learnings", {
351
+ select: "id,title,description,severity,counter_arguments,applies_when,source_linear_issue,project,embedding,updated_at,learning_type",
352
+ filters: {
353
+ project,
354
+ learning_type: "in.(scar,pattern,win,anti_pattern)",
355
+ },
356
+ order: "updated_at.desc",
357
+ limit,
358
+ });
359
+ const elapsed = Date.now() - startTime;
360
+ console.error(`[supabase-direct] Loaded ${learnings.length} learnings in ${elapsed}ms`);
361
+ return learnings;
362
+ }
363
+ catch (error) {
364
+ console.error("[supabase-direct] Failed to load learnings:", error);
365
+ throw error;
366
+ }
367
+ }
368
+ /**
369
+ * Scar search with severity weighting
370
+ */
371
+ export async function scarSearch(query, matchCount = 5, project) {
372
+ const args = {
373
+ query,
374
+ match_count: matchCount,
375
+ };
376
+ if (project) {
377
+ args.project = project;
378
+ }
379
+ const result = await callMcp("scar_search", args);
380
+ return result.results || [];
381
+ }
382
+ /**
383
+ * Scar search with caching (OD-473)
384
+ *
385
+ * Returns cached results if available, otherwise fetches and caches.
386
+ */
387
+ export async function cachedScarSearch(query, matchCount = 5, project = "orchestra_dev") {
388
+ const cache = getCache();
389
+ const { data, cache_hit, cache_age_ms } = await cache.getOrFetchScarSearch(query, project, matchCount, async () => scarSearch(query, matchCount, project));
390
+ return { results: data, cache_hit, cache_age_ms };
391
+ }
392
+ /**
393
+ * List records with caching for decisions (OD-473)
394
+ */
395
+ export async function cachedListDecisions(project = "orchestra_dev", limit = 5) {
396
+ const cache = getCache();
397
+ const { data, cache_hit, cache_age_ms } = await cache.getOrFetchDecisions(project, limit, async () => listRecords({
398
+ table: "orchestra_decisions_lite",
399
+ limit,
400
+ orderBy: { column: "created_at", ascending: false },
401
+ }));
402
+ return { data, cache_hit, cache_age_ms };
403
+ }
404
+ /**
405
+ * List records with caching for wins
406
+ */
407
+ export async function cachedListWins(project = "orchestra_dev", limit = 8, columns) {
408
+ const cache = getCache();
409
+ const { data, cache_hit, cache_age_ms } = await cache.getOrFetchWins(project, limit, async () => listRecords({
410
+ table: "orchestra_learnings_lite",
411
+ columns,
412
+ filters: {
413
+ learning_type: "win",
414
+ project,
415
+ },
416
+ limit,
417
+ orderBy: { column: "created_at", ascending: false },
418
+ }));
419
+ return { data, cache_hit, cache_age_ms };
420
+ }
421
+ // ============================================================================
422
+ // STORAGE API (for transcript persistence - OD-467)
423
+ // ============================================================================
424
+ const TRANSCRIPT_BUCKET = "session-transcripts";
425
+ /**
426
+ * Upload a file to Supabase Storage
427
+ */
428
+ export async function uploadFile(bucket, path, content, contentType = "application/json") {
429
+ if (!isConfigured()) {
430
+ throw new Error("Supabase not configured");
431
+ }
432
+ const storageUrl = `${SUPABASE_URL}/storage/v1/object/${bucket}/${path}`;
433
+ const response = await fetch(storageUrl, {
434
+ method: "POST",
435
+ headers: {
436
+ "Content-Type": contentType,
437
+ Authorization: `Bearer ${SUPABASE_KEY}`,
438
+ },
439
+ body: content,
440
+ });
441
+ if (!response.ok) {
442
+ const text = await response.text();
443
+ throw new Error(`Storage upload error: ${response.status} - ${text.slice(0, 200)}`);
444
+ }
445
+ return { path: `${bucket}/${path}` };
446
+ }
447
+ /**
448
+ * Download a file from Supabase Storage
449
+ */
450
+ export async function downloadFile(bucket, path) {
451
+ if (!isConfigured()) {
452
+ throw new Error("Supabase not configured");
453
+ }
454
+ const storageUrl = `${SUPABASE_URL}/storage/v1/object/${bucket}/${path}`;
455
+ const response = await fetch(storageUrl, {
456
+ method: "GET",
457
+ headers: {
458
+ Authorization: `Bearer ${SUPABASE_KEY}`,
459
+ },
460
+ });
461
+ if (!response.ok) {
462
+ const text = await response.text();
463
+ throw new Error(`Storage download error: ${response.status} - ${text.slice(0, 200)}`);
464
+ }
465
+ return response.text();
466
+ }
467
+ /**
468
+ * Save a session transcript to storage
469
+ */
470
+ export async function saveTranscript(sessionId, transcript, metadata = {}) {
471
+ const { project = "orchestra_dev", agent = "unknown", format = "json" } = metadata;
472
+ const date = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
473
+ const extension = format === "markdown" ? "md" : "json";
474
+ const path = `${project}/${agent}/${date}/${sessionId}.${extension}`;
475
+ const contentType = format === "markdown" ? "text/markdown" : "application/json";
476
+ const content = format === "json" ? transcript : transcript;
477
+ await uploadFile(TRANSCRIPT_BUCKET, path, content, contentType);
478
+ // Update the session record with transcript_path (direct REST API)
479
+ try {
480
+ await directUpsert("orchestra_sessions", {
481
+ id: sessionId,
482
+ transcript_path: path,
483
+ });
484
+ }
485
+ catch (error) {
486
+ // Log but don't fail - transcript is saved even if session update fails
487
+ console.error("Failed to update session with transcript_path:", error);
488
+ }
489
+ return {
490
+ transcript_path: path,
491
+ size_bytes: Buffer.byteLength(content, "utf8"),
492
+ };
493
+ }
494
+ /**
495
+ * Retrieve a session transcript from storage
496
+ */
497
+ export async function getTranscript(sessionId) {
498
+ // First, get the session to find transcript_path
499
+ const session = await getRecord("orchestra_sessions", sessionId);
500
+ if (!session?.transcript_path) {
501
+ return null;
502
+ }
503
+ // Download the transcript
504
+ const transcript = await downloadFile(TRANSCRIPT_BUCKET, session.transcript_path);
505
+ return {
506
+ transcript,
507
+ path: session.transcript_path,
508
+ };
509
+ }
510
+ //# sourceMappingURL=supabase-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-client.js","sourceRoot":"","sources":["../../src/services/supabase-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Thread Deduplication Service (Phase 3)
3
+ *
4
+ * Pure functions for detecting duplicate threads by embedding similarity
5
+ * or normalized text equality. Zero I/O — all Supabase and embedding
6
+ * calls live in the caller (create-thread.ts).
7
+ *
8
+ * Strategy:
9
+ * 1. If embedding available: cosine similarity > 0.85 → duplicate
10
+ * 2. If embedding unavailable: normalized text equality → duplicate
11
+ * 3. If no existing threads: skip check
12
+ */
13
+ export interface ThreadWithEmbedding {
14
+ thread_id: string;
15
+ text: string;
16
+ embedding: number[] | null;
17
+ }
18
+ export interface DedupResult {
19
+ is_duplicate: boolean;
20
+ matched_thread_id: string | null;
21
+ matched_text: string | null;
22
+ similarity: number | null;
23
+ method: "embedding" | "text_normalization" | "skipped";
24
+ }
25
+ export declare const DEDUP_SIMILARITY_THRESHOLD = 0.85;
26
+ /**
27
+ * Check if new thread text is a semantic duplicate of any existing open thread.
28
+ *
29
+ * @param newText - Trimmed thread text
30
+ * @param newEmbedding - Normalized embedding vector, or null if unavailable
31
+ * @param existingThreads - Open threads with optional embeddings
32
+ */
33
+ export declare function checkDuplicate(newText: string, newEmbedding: number[] | null, existingThreads: ThreadWithEmbedding[]): DedupResult;
34
+ /**
35
+ * Cosine similarity between two normalized vectors.
36
+ * Assumes vectors are already L2-normalized (dot product = cosine similarity).
37
+ */
38
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
39
+ /**
40
+ * Normalize text for conservative text-only comparison.
41
+ * Lowercase, collapse whitespace, trim, strip trailing punctuation.
42
+ */
43
+ export declare function normalizeText(text: string): string;
44
+ //# sourceMappingURL=thread-dedup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-dedup.d.ts","sourceRoot":"","sources":["../../src/services/thread-dedup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,WAAW,GAAG,oBAAoB,GAAG,SAAS,CAAC;CACxD;AAID,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAI/C;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,EAC7B,eAAe,EAAE,mBAAmB,EAAE,GACrC,WAAW,CAmEb;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAQjE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD"}