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,143 @@
1
+ /**
2
+ * Thread Vitality Scoring (Phase 2) + Lifecycle State Machine (Phase 6)
3
+ *
4
+ * Computes vitality from recency + frequency (two of four eventual components).
5
+ * Importance and relevance deferred to Phases 3-4 (knowledge graph + per-session embeddings).
6
+ *
7
+ * Formula: vitality = W_recency * recency + W_frequency * frequency
8
+ *
9
+ * Phase 2 weights (renormalized from 4-component to 2-component):
10
+ * recency: 0.55 (original 0.30 / 0.55 total)
11
+ * frequency: 0.45 (original 0.25 / 0.55 total)
12
+ *
13
+ * Recency: exponential decay based on thread_class half-life
14
+ * operational: 3-day half-life (short-lived tasks)
15
+ * backlog: 21-day half-life (long-running concerns)
16
+ *
17
+ * Frequency: log-scaled touch count normalized against thread age
18
+ * log(touch_count + 1) / log(max(days_alive, 0.01) + 1)
19
+ *
20
+ * Status thresholds:
21
+ * vitality > 0.5 → "active"
22
+ * 0.2 <= v <= 0.5 → "cooling"
23
+ * vitality < 0.2 → "dormant"
24
+ *
25
+ * Phase 6 Lifecycle:
26
+ * EMERGING (< 24h old) → ACTIVE → COOLING → DORMANT → ARCHIVED (30+ days dormant)
27
+ * Any state → RESOLVED (explicit resolve)
28
+ */
29
+ // ---------- Constants ----------
30
+ const WEIGHTS = {
31
+ recency: 0.55,
32
+ frequency: 0.45,
33
+ };
34
+ const HALF_LIVES = {
35
+ operational: 3,
36
+ backlog: 21,
37
+ };
38
+ const STATUS_THRESHOLDS = {
39
+ active: 0.5,
40
+ cooling: 0.2,
41
+ };
42
+ // Phase 6 lifecycle constants
43
+ export const EMERGING_WINDOW_HOURS = 24;
44
+ export const ARCHIVAL_DORMANT_DAYS = 30;
45
+ const OPERATIONAL_KEYWORDS = [
46
+ "deploy", "fix", "debug", "hotfix", "urgent", "broken",
47
+ "failing", "revert", "rollback", "incident", "outage",
48
+ "blocker", "unblock", "investigate",
49
+ ];
50
+ // ---------- Core Computation ----------
51
+ export function computeVitality(input, now) {
52
+ const currentTime = now || new Date();
53
+ const recency = computeRecency(input.last_touched_at, input.thread_class, currentTime);
54
+ const frequency = computeFrequency(input.touch_count, input.created_at, currentTime);
55
+ const vitality_score = clamp(WEIGHTS.recency * recency + WEIGHTS.frequency * frequency, 0, 1);
56
+ const status = vitalityToStatus(vitality_score);
57
+ return {
58
+ vitality_score: round(vitality_score, 4),
59
+ status,
60
+ recency_component: round(recency, 4),
61
+ frequency_component: round(frequency, 4),
62
+ };
63
+ }
64
+ // ---------- Lifecycle State Machine (Phase 6) ----------
65
+ /**
66
+ * Compute the full lifecycle status for a thread.
67
+ * Wraps vitality scoring with age-based emerging window and archival logic.
68
+ *
69
+ * State machine:
70
+ * EMERGING (< 24h) → ACTIVE → COOLING → DORMANT → ARCHIVED (30+ days dormant)
71
+ * Any state → RESOLVED (handled externally by resolve_thread)
72
+ */
73
+ export function computeLifecycleStatus(input, now) {
74
+ const currentTime = now || new Date();
75
+ // Terminal states: archived and resolved stay as-is
76
+ if (input.current_status === "archived" || input.current_status === "resolved") {
77
+ const vitality = computeVitality(input, currentTime);
78
+ return {
79
+ lifecycle_status: input.current_status,
80
+ vitality,
81
+ };
82
+ }
83
+ // Emerging window: threads < 24h old
84
+ const created = new Date(input.created_at);
85
+ const hoursAlive = (currentTime.getTime() - created.getTime()) / (1000 * 60 * 60);
86
+ if (hoursAlive < EMERGING_WINDOW_HOURS) {
87
+ const vitality = computeVitality(input, currentTime);
88
+ return { lifecycle_status: "emerging", vitality };
89
+ }
90
+ // Compute vitality for normal lifecycle
91
+ const vitality = computeVitality(input, currentTime);
92
+ // Archival: dormant for 30+ days
93
+ if (input.current_status === "dormant" &&
94
+ input.dormant_since) {
95
+ const dormantStart = new Date(input.dormant_since);
96
+ const daysDormant = (currentTime.getTime() - dormantStart.getTime()) / (1000 * 60 * 60 * 24);
97
+ if (daysDormant >= ARCHIVAL_DORMANT_DAYS) {
98
+ return { lifecycle_status: "archived", vitality };
99
+ }
100
+ }
101
+ // Normal vitality-derived status (active/cooling/dormant)
102
+ return { lifecycle_status: vitality.status, vitality };
103
+ }
104
+ // ---------- Components ----------
105
+ function computeRecency(lastTouchedAt, threadClass, now) {
106
+ const lastTouched = new Date(lastTouchedAt);
107
+ const daysSinceTouch = Math.max((now.getTime() - lastTouched.getTime()) / (1000 * 60 * 60 * 24), 0);
108
+ const halfLife = HALF_LIVES[threadClass] || HALF_LIVES.backlog;
109
+ // Exponential decay: e^(-ln(2) * t / halfLife)
110
+ return Math.exp(-Math.LN2 * daysSinceTouch / halfLife);
111
+ }
112
+ function computeFrequency(touchCount, createdAt, now) {
113
+ const created = new Date(createdAt);
114
+ const daysAlive = Math.max((now.getTime() - created.getTime()) / (1000 * 60 * 60 * 24), 0.01);
115
+ // log(touchCount + 1) / log(daysAlive + 1), capped at 1.0
116
+ return Math.min(Math.log(touchCount + 1) / Math.log(daysAlive + 1), 1.0);
117
+ }
118
+ // ---------- Status Mapping ----------
119
+ export function vitalityToStatus(score) {
120
+ if (score > STATUS_THRESHOLDS.active)
121
+ return "active";
122
+ if (score >= STATUS_THRESHOLDS.cooling)
123
+ return "cooling";
124
+ return "dormant";
125
+ }
126
+ // ---------- Thread Class Detection ----------
127
+ export function detectThreadClass(text) {
128
+ const lower = text.toLowerCase();
129
+ for (const keyword of OPERATIONAL_KEYWORDS) {
130
+ if (lower.includes(keyword))
131
+ return "operational";
132
+ }
133
+ return "backlog";
134
+ }
135
+ // ---------- Helpers ----------
136
+ function clamp(value, min, max) {
137
+ return Math.min(Math.max(value, min), max);
138
+ }
139
+ function round(value, decimals) {
140
+ const factor = 10 ** decimals;
141
+ return Math.round(value * factor) / factor;
142
+ }
143
+ //# sourceMappingURL=thread-vitality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-vitality.js","sourceRoot":"","sources":["../../src/services/thread-vitality.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * GitMem Tier Detection and Feature Flags
3
+ *
4
+ * Three tiers:
5
+ * free — Local JSON storage, keyword search, zero config
6
+ * pro — Supabase + embeddings, semantic search, cloud persistence, variants
7
+ * dev — Everything in pro + compliance, transcripts, metrics
8
+ *
9
+ * Detection:
10
+ * GITMEM_TIER=free|pro|dev (explicit override)
11
+ * Auto-detect: no SUPABASE_URL → free, GITMEM_DEV=1 → dev, else → pro
12
+ */
13
+ export type GitMemTier = "free" | "pro" | "dev";
14
+ /**
15
+ * Get the current tier (cached after first call)
16
+ */
17
+ export declare function getTier(): GitMemTier;
18
+ /**
19
+ * Reset tier detection (for testing)
20
+ */
21
+ export declare function resetTier(): void;
22
+ /** Whether Supabase is available for storage (pro, dev) */
23
+ export declare function hasSupabase(): boolean;
24
+ /** Whether embedding generation is available (pro, dev) */
25
+ export declare function hasEmbeddings(): boolean;
26
+ /** Whether session close compliance validation is active (dev only) */
27
+ export declare function hasCompliance(): boolean;
28
+ /** Whether scar variant A/B testing is active (pro, dev — needs Supabase for assignment storage) */
29
+ export declare function hasVariants(): boolean;
30
+ /** Whether transcript storage/retrieval is available (dev only) */
31
+ export declare function hasTranscripts(): boolean;
32
+ /** Whether batch scar usage recording is available (dev only) */
33
+ export declare function hasBatchOperations(): boolean;
34
+ /** Whether cache management tools are available (pro, dev) */
35
+ export declare function hasCacheManagement(): boolean;
36
+ /** Whether detailed performance metrics recording is active (pro, dev — aligned with hasVariants) */
37
+ export declare function hasMetrics(): boolean;
38
+ /** Whether advanced agent detection (5-agent matrix) is active (dev only) */
39
+ export declare function hasAdvancedAgentDetection(): boolean;
40
+ /** Whether multi-project support is active (dev only) */
41
+ export declare function hasMultiProject(): boolean;
42
+ /** Whether LLM-cooperative enforcement fields are generated (dev only) */
43
+ export declare function hasEnforcementFields(): boolean;
44
+ /**
45
+ * Get the table prefix for the current tier
46
+ */
47
+ export declare function getTablePrefix(): string;
48
+ /**
49
+ * Get the fully-qualified table name for a base table name
50
+ */
51
+ export declare function getTableName(baseName: string): string;
52
+ //# sourceMappingURL=tier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier.d.ts","sourceRoot":"","sources":["../../src/services/tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAwBhD;;GAEG;AACH,wBAAgB,OAAO,IAAI,UAAU,CAMpC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAEhC;AAMD,2DAA2D;AAC3D,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,2DAA2D;AAC3D,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,uEAAuE;AACvE,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,oGAAoG;AACpG,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,mEAAmE;AACnE,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED,qGAAqG;AACrG,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,6EAA6E;AAC7E,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAED,yDAAyD;AACzD,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAKvC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErD"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * GitMem Tier Detection and Feature Flags
3
+ *
4
+ * Three tiers:
5
+ * free — Local JSON storage, keyword search, zero config
6
+ * pro — Supabase + embeddings, semantic search, cloud persistence, variants
7
+ * dev — Everything in pro + compliance, transcripts, metrics
8
+ *
9
+ * Detection:
10
+ * GITMEM_TIER=free|pro|dev (explicit override)
11
+ * Auto-detect: no SUPABASE_URL → free, GITMEM_DEV=1 → dev, else → pro
12
+ */
13
+ let _tier = null;
14
+ /**
15
+ * Detect tier from environment variables
16
+ */
17
+ function detectTier() {
18
+ const explicit = process.env.GITMEM_TIER?.toLowerCase();
19
+ if (explicit === "free" || explicit === "pro" || explicit === "dev") {
20
+ return explicit;
21
+ }
22
+ const supabaseUrl = process.env.SUPABASE_URL;
23
+ if (!supabaseUrl)
24
+ return "free";
25
+ // Dev tier markers
26
+ if (process.env.GITMEM_DEV === "true" || process.env.GITMEM_DEV === "1") {
27
+ return "dev";
28
+ }
29
+ return "pro";
30
+ }
31
+ /**
32
+ * Get the current tier (cached after first call)
33
+ */
34
+ export function getTier() {
35
+ if (!_tier) {
36
+ _tier = detectTier();
37
+ console.error(`[gitmem] Tier: ${_tier}`);
38
+ }
39
+ return _tier;
40
+ }
41
+ /**
42
+ * Reset tier detection (for testing)
43
+ */
44
+ export function resetTier() {
45
+ _tier = null;
46
+ }
47
+ // ============================================================================
48
+ // Feature flags
49
+ // ============================================================================
50
+ /** Whether Supabase is available for storage (pro, dev) */
51
+ export function hasSupabase() {
52
+ return getTier() !== "free";
53
+ }
54
+ /** Whether embedding generation is available (pro, dev) */
55
+ export function hasEmbeddings() {
56
+ return getTier() !== "free";
57
+ }
58
+ /** Whether session close compliance validation is active (dev only) */
59
+ export function hasCompliance() {
60
+ return getTier() === "dev";
61
+ }
62
+ /** Whether scar variant A/B testing is active (pro, dev — needs Supabase for assignment storage) */
63
+ export function hasVariants() {
64
+ return getTier() !== "free";
65
+ }
66
+ /** Whether transcript storage/retrieval is available (dev only) */
67
+ export function hasTranscripts() {
68
+ return getTier() === "dev";
69
+ }
70
+ /** Whether batch scar usage recording is available (dev only) */
71
+ export function hasBatchOperations() {
72
+ return getTier() === "dev";
73
+ }
74
+ /** Whether cache management tools are available (pro, dev) */
75
+ export function hasCacheManagement() {
76
+ return getTier() !== "free";
77
+ }
78
+ /** Whether detailed performance metrics recording is active (pro, dev — aligned with hasVariants) */
79
+ export function hasMetrics() {
80
+ return getTier() !== "free";
81
+ }
82
+ /** Whether advanced agent detection (5-agent matrix) is active (dev only) */
83
+ export function hasAdvancedAgentDetection() {
84
+ return getTier() === "dev";
85
+ }
86
+ /** Whether multi-project support is active (dev only) */
87
+ export function hasMultiProject() {
88
+ return getTier() === "dev";
89
+ }
90
+ /** Whether LLM-cooperative enforcement fields are generated (dev only) */
91
+ export function hasEnforcementFields() {
92
+ return getTier() === "dev";
93
+ }
94
+ /**
95
+ * Get the table prefix for the current tier
96
+ */
97
+ export function getTablePrefix() {
98
+ if (getTier() === "dev") {
99
+ return process.env.GITMEM_TABLE_PREFIX || "orchestra_";
100
+ }
101
+ return process.env.GITMEM_TABLE_PREFIX || "gitmem_";
102
+ }
103
+ /**
104
+ * Get the fully-qualified table name for a base table name
105
+ */
106
+ export function getTableName(baseName) {
107
+ return `${getTablePrefix()}${baseName}`;
108
+ }
109
+ //# sourceMappingURL=tier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier.js","sourceRoot":"","sources":["../../src/services/tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,IAAI,KAAK,GAAsB,IAAI,CAAC;AAEpC;;GAEG;AACH,SAAS,UAAU;IACjB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC;IACxD,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACpE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC7C,IAAI,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IAEhC,mBAAmB;IACnB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;QACxE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO;IACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,UAAU,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,KAAK,GAAG,IAAI,CAAC;AACf,CAAC;AAED,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,2DAA2D;AAC3D,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,EAAE,KAAK,MAAM,CAAC;AAC9B,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,EAAE,KAAK,MAAM,CAAC;AAC9B,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,EAAE,KAAK,KAAK,CAAC;AAC7B,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,EAAE,KAAK,MAAM,CAAC;AAC9B,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,cAAc;IAC5B,OAAO,OAAO,EAAE,KAAK,KAAK,CAAC;AAC7B,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,EAAE,KAAK,KAAK,CAAC;AAC7B,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,EAAE,KAAK,MAAM,CAAC;AAC9B,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,EAAE,KAAK,MAAM,CAAC;AAC9B,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,yBAAyB;IACvC,OAAO,OAAO,EAAE,KAAK,KAAK,CAAC;AAC7B,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,eAAe;IAC7B,OAAO,OAAO,EAAE,KAAK,KAAK,CAAC;AAC7B,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,oBAAoB;IAClC,OAAO,OAAO,EAAE,KAAK,KAAK,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,IAAI,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,YAAY,CAAC;IACzD,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,SAAS,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,OAAO,GAAG,cAAc,EAAE,GAAG,QAAQ,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Timezone Display Formatting Service
3
+ *
4
+ * Converts UTC timestamps to user's local timezone for display.
5
+ * Storage timestamps remain UTC — this is display-layer only.
6
+ *
7
+ * Config chain: .gitmem/config.json → TZ env var → UTC (default)
8
+ */
9
+ import type { ThreadObject } from "../types/index.js";
10
+ /** Get the configured timezone. Loads once from config chain. */
11
+ export declare function getTimezone(): string;
12
+ /**
13
+ * Format a date-only string (YYYY-MM-DD) for display.
14
+ *
15
+ * When timezone is UTC (default): returns original string unchanged.
16
+ * When timezone configured: returns "Feb 9, 2026" format.
17
+ *
18
+ * Does NOT shift the date to another timezone — the input is
19
+ * treated as a calendar date, not a UTC midnight timestamp.
20
+ */
21
+ export declare function formatDate(dateStr: string): string;
22
+ /**
23
+ * Format a full ISO timestamp for display.
24
+ *
25
+ * When timezone is UTC (default): returns original string unchanged.
26
+ * When timezone configured: returns "Feb 9, 2026, 1:45 PM EST" format.
27
+ */
28
+ export declare function formatTimestamp(isoStr: string): string;
29
+ /**
30
+ * Format a ThreadObject's timestamps for display.
31
+ * Returns original reference when UTC (no allocation).
32
+ * Returns a shallow copy with formatted dates when timezone configured.
33
+ */
34
+ export declare function formatThreadForDisplay(thread: ThreadObject): ThreadObject;
35
+ /** Reset cached timezone (for testing). */
36
+ export declare function resetTimezone(): void;
37
+ //# sourceMappingURL=timezone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timezone.d.ts","sourceRoot":"","sources":["../../src/services/timezone.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAwDtD,iEAAiE;AACjE,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAMD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAiBlD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoBtD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAOzE;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,IAAI,IAAI,CAGpC"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Timezone Display Formatting Service
3
+ *
4
+ * Converts UTC timestamps to user's local timezone for display.
5
+ * Storage timestamps remain UTC — this is display-layer only.
6
+ *
7
+ * Config chain: .gitmem/config.json → TZ env var → UTC (default)
8
+ */
9
+ import * as fs from "fs";
10
+ import { getGitmemPath } from "./gitmem-dir.js";
11
+ let _timezone = null;
12
+ let _loaded = false;
13
+ /**
14
+ * Load timezone from config chain:
15
+ * 1. .gitmem/config.json "timezone" field
16
+ * 2. TZ environment variable
17
+ * 3. "UTC" (default, preserves current behavior)
18
+ */
19
+ function loadTimezone() {
20
+ if (_loaded)
21
+ return _timezone || "UTC";
22
+ // 1. Try .gitmem/config.json
23
+ try {
24
+ const configPath = getGitmemPath("config.json");
25
+ if (fs.existsSync(configPath)) {
26
+ const raw = JSON.parse(fs.readFileSync(configPath, "utf-8"));
27
+ if (raw.timezone && typeof raw.timezone === "string") {
28
+ const tz = raw.timezone;
29
+ try {
30
+ Intl.DateTimeFormat(undefined, { timeZone: tz });
31
+ _timezone = tz;
32
+ _loaded = true;
33
+ console.error(`[timezone] Loaded from config.json: ${tz}`);
34
+ return tz;
35
+ }
36
+ catch {
37
+ console.warn(`[timezone] Invalid timezone in config.json: ${tz}, falling back`);
38
+ }
39
+ }
40
+ }
41
+ }
42
+ catch {
43
+ // File doesn't exist or is invalid — fall through
44
+ }
45
+ // 2. Try TZ env var
46
+ const tzEnv = process.env.TZ;
47
+ if (tzEnv) {
48
+ try {
49
+ Intl.DateTimeFormat(undefined, { timeZone: tzEnv });
50
+ _timezone = tzEnv;
51
+ _loaded = true;
52
+ console.error(`[timezone] Loaded from TZ env: ${tzEnv}`);
53
+ return tzEnv;
54
+ }
55
+ catch {
56
+ console.warn(`[timezone] Invalid TZ env var: ${tzEnv}, falling back to UTC`);
57
+ }
58
+ }
59
+ // 3. Default to UTC
60
+ _timezone = "UTC";
61
+ _loaded = true;
62
+ return _timezone;
63
+ }
64
+ /** Get the configured timezone. Loads once from config chain. */
65
+ export function getTimezone() {
66
+ return loadTimezone();
67
+ }
68
+ function isTimezoneConfigured() {
69
+ return getTimezone() !== "UTC";
70
+ }
71
+ /**
72
+ * Format a date-only string (YYYY-MM-DD) for display.
73
+ *
74
+ * When timezone is UTC (default): returns original string unchanged.
75
+ * When timezone configured: returns "Feb 9, 2026" format.
76
+ *
77
+ * Does NOT shift the date to another timezone — the input is
78
+ * treated as a calendar date, not a UTC midnight timestamp.
79
+ */
80
+ export function formatDate(dateStr) {
81
+ if (!isTimezoneConfigured())
82
+ return dateStr;
83
+ if (!dateStr || dateStr.length < 10)
84
+ return dateStr;
85
+ try {
86
+ const [year, month, day] = dateStr.split("-").map(Number);
87
+ const date = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
88
+ return new Intl.DateTimeFormat("en-US", {
89
+ month: "short",
90
+ day: "numeric",
91
+ year: "numeric",
92
+ timeZone: "UTC", // Calendar date — don't shift across timezones
93
+ }).format(date);
94
+ }
95
+ catch {
96
+ return dateStr;
97
+ }
98
+ }
99
+ /**
100
+ * Format a full ISO timestamp for display.
101
+ *
102
+ * When timezone is UTC (default): returns original string unchanged.
103
+ * When timezone configured: returns "Feb 9, 2026, 1:45 PM EST" format.
104
+ */
105
+ export function formatTimestamp(isoStr) {
106
+ if (!isTimezoneConfigured())
107
+ return isoStr;
108
+ if (!isoStr)
109
+ return isoStr;
110
+ try {
111
+ const date = new Date(isoStr);
112
+ if (isNaN(date.getTime()))
113
+ return isoStr;
114
+ return new Intl.DateTimeFormat("en-US", {
115
+ month: "short",
116
+ day: "numeric",
117
+ year: "numeric",
118
+ hour: "numeric",
119
+ minute: "2-digit",
120
+ timeZoneName: "short",
121
+ timeZone: getTimezone(),
122
+ }).format(date);
123
+ }
124
+ catch {
125
+ return isoStr;
126
+ }
127
+ }
128
+ /**
129
+ * Format a ThreadObject's timestamps for display.
130
+ * Returns original reference when UTC (no allocation).
131
+ * Returns a shallow copy with formatted dates when timezone configured.
132
+ */
133
+ export function formatThreadForDisplay(thread) {
134
+ if (!isTimezoneConfigured())
135
+ return thread;
136
+ return {
137
+ ...thread,
138
+ created_at: formatTimestamp(thread.created_at),
139
+ ...(thread.resolved_at && { resolved_at: formatTimestamp(thread.resolved_at) }),
140
+ };
141
+ }
142
+ /** Reset cached timezone (for testing). */
143
+ export function resetTimezone() {
144
+ _timezone = null;
145
+ _loaded = false;
146
+ }
147
+ //# sourceMappingURL=timezone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timezone.js","sourceRoot":"","sources":["../../src/services/timezone.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Transcript Chunking Service
3
+ *
4
+ * Parses JSONL session transcripts, chunks them intelligently,
5
+ * generates embeddings, and stores in orchestra_transcript_chunks.
6
+ *
7
+ * Issue: OD-540
8
+ */
9
+ import type { Project } from "../types/index.js";
10
+ /**
11
+ * Process a transcript: parse, chunk, embed, and store
12
+ */
13
+ export declare function processTranscript(sessionId: string, transcriptContent: string, project?: Project): Promise<{
14
+ success: boolean;
15
+ chunksCreated: number;
16
+ error?: string;
17
+ }>;
18
+ //# sourceMappingURL=transcript-chunker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-chunker.d.ts","sourceRoot":"","sources":["../../src/services/transcript-chunker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AA2MjD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,OAAO,GAAE,OAAyB,GACjC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwFtE"}