@jamesaphoenix/tx-core 0.4.1

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 (289) hide show
  1. package/dist/db.d.ts +42 -0
  2. package/dist/db.d.ts.map +1 -0
  3. package/dist/db.js +46 -0
  4. package/dist/db.js.map +1 -0
  5. package/dist/errors.d.ts +231 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/errors.js +139 -0
  8. package/dist/errors.js.map +1 -0
  9. package/dist/id.d.ts +6 -0
  10. package/dist/id.d.ts.map +1 -0
  11. package/dist/id.js +21 -0
  12. package/dist/id.js.map +1 -0
  13. package/dist/index.d.ts +25 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +56 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/layer.d.ts +50 -0
  18. package/dist/layer.d.ts.map +1 -0
  19. package/dist/layer.js +155 -0
  20. package/dist/layer.js.map +1 -0
  21. package/dist/mappers/anchor.d.ts +14 -0
  22. package/dist/mappers/anchor.d.ts.map +1 -0
  23. package/dist/mappers/anchor.js +38 -0
  24. package/dist/mappers/anchor.js.map +1 -0
  25. package/dist/mappers/attempt.d.ts +15 -0
  26. package/dist/mappers/attempt.d.ts.map +1 -0
  27. package/dist/mappers/attempt.js +23 -0
  28. package/dist/mappers/attempt.js.map +1 -0
  29. package/dist/mappers/candidate.d.ts +23 -0
  30. package/dist/mappers/candidate.d.ts.map +1 -0
  31. package/dist/mappers/candidate.js +53 -0
  32. package/dist/mappers/candidate.js.map +1 -0
  33. package/dist/mappers/claim.d.ts +30 -0
  34. package/dist/mappers/claim.d.ts.map +1 -0
  35. package/dist/mappers/claim.js +32 -0
  36. package/dist/mappers/claim.js.map +1 -0
  37. package/dist/mappers/deduplication.d.ts +39 -0
  38. package/dist/mappers/deduplication.d.ts.map +1 -0
  39. package/dist/mappers/deduplication.js +53 -0
  40. package/dist/mappers/deduplication.js.map +1 -0
  41. package/dist/mappers/edge.d.ts +10 -0
  42. package/dist/mappers/edge.d.ts.map +1 -0
  43. package/dist/mappers/edge.js +19 -0
  44. package/dist/mappers/edge.js.map +1 -0
  45. package/dist/mappers/file-learning.d.ts +14 -0
  46. package/dist/mappers/file-learning.d.ts.map +1 -0
  47. package/dist/mappers/file-learning.js +75 -0
  48. package/dist/mappers/file-learning.js.map +1 -0
  49. package/dist/mappers/index.d.ts +17 -0
  50. package/dist/mappers/index.d.ts.map +1 -0
  51. package/dist/mappers/index.js +30 -0
  52. package/dist/mappers/index.js.map +1 -0
  53. package/dist/mappers/learning.d.ts +19 -0
  54. package/dist/mappers/learning.d.ts.map +1 -0
  55. package/dist/mappers/learning.js +41 -0
  56. package/dist/mappers/learning.js.map +1 -0
  57. package/dist/mappers/orchestrator-state.d.ts +33 -0
  58. package/dist/mappers/orchestrator-state.d.ts.map +1 -0
  59. package/dist/mappers/orchestrator-state.js +34 -0
  60. package/dist/mappers/orchestrator-state.js.map +1 -0
  61. package/dist/mappers/run.d.ts +32 -0
  62. package/dist/mappers/run.d.ts.map +1 -0
  63. package/dist/mappers/run.js +64 -0
  64. package/dist/mappers/run.js.map +1 -0
  65. package/dist/mappers/task.d.ts +23 -0
  66. package/dist/mappers/task.d.ts.map +1 -0
  67. package/dist/mappers/task.js +54 -0
  68. package/dist/mappers/task.js.map +1 -0
  69. package/dist/mappers/tracked-project.d.ts +15 -0
  70. package/dist/mappers/tracked-project.d.ts.map +1 -0
  71. package/dist/mappers/tracked-project.js +23 -0
  72. package/dist/mappers/tracked-project.js.map +1 -0
  73. package/dist/mappers/worker.d.ts +33 -0
  74. package/dist/mappers/worker.d.ts.map +1 -0
  75. package/dist/mappers/worker.js +35 -0
  76. package/dist/mappers/worker.js.map +1 -0
  77. package/dist/repo/anchor-repo.d.ts +52 -0
  78. package/dist/repo/anchor-repo.d.ts.map +1 -0
  79. package/dist/repo/anchor-repo.js +204 -0
  80. package/dist/repo/anchor-repo.js.map +1 -0
  81. package/dist/repo/attempt-repo.d.ts +25 -0
  82. package/dist/repo/attempt-repo.d.ts.map +1 -0
  83. package/dist/repo/attempt-repo.js +78 -0
  84. package/dist/repo/attempt-repo.js.map +1 -0
  85. package/dist/repo/candidate-repo.d.ts +16 -0
  86. package/dist/repo/candidate-repo.d.ts.map +1 -0
  87. package/dist/repo/candidate-repo.js +143 -0
  88. package/dist/repo/candidate-repo.js.map +1 -0
  89. package/dist/repo/claim-repo.d.ts +17 -0
  90. package/dist/repo/claim-repo.d.ts.map +1 -0
  91. package/dist/repo/claim-repo.js +62 -0
  92. package/dist/repo/claim-repo.js.map +1 -0
  93. package/dist/repo/deduplication-repo.d.ts +37 -0
  94. package/dist/repo/deduplication-repo.d.ts.map +1 -0
  95. package/dist/repo/deduplication-repo.js +133 -0
  96. package/dist/repo/deduplication-repo.js.map +1 -0
  97. package/dist/repo/dep-repo.d.ts +19 -0
  98. package/dist/repo/dep-repo.d.ts.map +1 -0
  99. package/dist/repo/dep-repo.js +104 -0
  100. package/dist/repo/dep-repo.js.map +1 -0
  101. package/dist/repo/edge-repo.d.ts +26 -0
  102. package/dist/repo/edge-repo.d.ts.map +1 -0
  103. package/dist/repo/edge-repo.js +227 -0
  104. package/dist/repo/edge-repo.js.map +1 -0
  105. package/dist/repo/file-learning-repo.d.ts +17 -0
  106. package/dist/repo/file-learning-repo.d.ts.map +1 -0
  107. package/dist/repo/file-learning-repo.js +60 -0
  108. package/dist/repo/file-learning-repo.js.map +1 -0
  109. package/dist/repo/index.d.ts +18 -0
  110. package/dist/repo/index.d.ts.map +1 -0
  111. package/dist/repo/index.js +18 -0
  112. package/dist/repo/index.js.map +1 -0
  113. package/dist/repo/learning-repo.d.ts +31 -0
  114. package/dist/repo/learning-repo.d.ts.map +1 -0
  115. package/dist/repo/learning-repo.js +165 -0
  116. package/dist/repo/learning-repo.js.map +1 -0
  117. package/dist/repo/orchestrator-state-repo.d.ts +27 -0
  118. package/dist/repo/orchestrator-state-repo.d.ts.map +1 -0
  119. package/dist/repo/orchestrator-state-repo.js +96 -0
  120. package/dist/repo/orchestrator-state-repo.js.map +1 -0
  121. package/dist/repo/run-repo.d.ts +31 -0
  122. package/dist/repo/run-repo.d.ts.map +1 -0
  123. package/dist/repo/run-repo.js +132 -0
  124. package/dist/repo/run-repo.js.map +1 -0
  125. package/dist/repo/task-repo.d.ts +21 -0
  126. package/dist/repo/task-repo.d.ts.map +1 -0
  127. package/dist/repo/task-repo.js +169 -0
  128. package/dist/repo/task-repo.js.map +1 -0
  129. package/dist/repo/tracked-project-repo.d.ts +16 -0
  130. package/dist/repo/tracked-project-repo.d.ts.map +1 -0
  131. package/dist/repo/tracked-project-repo.js +54 -0
  132. package/dist/repo/tracked-project-repo.js.map +1 -0
  133. package/dist/repo/worker-repo.d.ts +19 -0
  134. package/dist/repo/worker-repo.d.ts.map +1 -0
  135. package/dist/repo/worker-repo.js +72 -0
  136. package/dist/repo/worker-repo.js.map +1 -0
  137. package/dist/schemas/index.d.ts +8 -0
  138. package/dist/schemas/index.d.ts.map +1 -0
  139. package/dist/schemas/index.js +7 -0
  140. package/dist/schemas/index.js.map +1 -0
  141. package/dist/schemas/sync.d.ts +296 -0
  142. package/dist/schemas/sync.d.ts.map +1 -0
  143. package/dist/schemas/sync.js +146 -0
  144. package/dist/schemas/sync.js.map +1 -0
  145. package/dist/schemas/worker.d.ts +77 -0
  146. package/dist/schemas/worker.d.ts.map +1 -0
  147. package/dist/schemas/worker.js +80 -0
  148. package/dist/schemas/worker.js.map +1 -0
  149. package/dist/services/anchor-service.d.ts +147 -0
  150. package/dist/services/anchor-service.d.ts.map +1 -0
  151. package/dist/services/anchor-service.js +540 -0
  152. package/dist/services/anchor-service.js.map +1 -0
  153. package/dist/services/anchor-verification.d.ts +94 -0
  154. package/dist/services/anchor-verification.d.ts.map +1 -0
  155. package/dist/services/anchor-verification.js +617 -0
  156. package/dist/services/anchor-verification.js.map +1 -0
  157. package/dist/services/ast-grep-service.d.ts +58 -0
  158. package/dist/services/ast-grep-service.d.ts.map +1 -0
  159. package/dist/services/ast-grep-service.js +356 -0
  160. package/dist/services/ast-grep-service.js.map +1 -0
  161. package/dist/services/attempt-service.d.ts +24 -0
  162. package/dist/services/attempt-service.d.ts.map +1 -0
  163. package/dist/services/attempt-service.js +55 -0
  164. package/dist/services/attempt-service.js.map +1 -0
  165. package/dist/services/auto-sync-service.d.ts +56 -0
  166. package/dist/services/auto-sync-service.d.ts.map +1 -0
  167. package/dist/services/auto-sync-service.js +66 -0
  168. package/dist/services/auto-sync-service.js.map +1 -0
  169. package/dist/services/candidate-extractor-service.d.ts +56 -0
  170. package/dist/services/candidate-extractor-service.d.ts.map +1 -0
  171. package/dist/services/candidate-extractor-service.js +365 -0
  172. package/dist/services/candidate-extractor-service.js.map +1 -0
  173. package/dist/services/claim-service.d.ts +52 -0
  174. package/dist/services/claim-service.d.ts.map +1 -0
  175. package/dist/services/claim-service.js +134 -0
  176. package/dist/services/claim-service.js.map +1 -0
  177. package/dist/services/daemon-service.d.ts +214 -0
  178. package/dist/services/daemon-service.d.ts.map +1 -0
  179. package/dist/services/daemon-service.js +522 -0
  180. package/dist/services/daemon-service.js.map +1 -0
  181. package/dist/services/deduplication-service.d.ts +67 -0
  182. package/dist/services/deduplication-service.d.ts.map +1 -0
  183. package/dist/services/deduplication-service.js +145 -0
  184. package/dist/services/deduplication-service.js.map +1 -0
  185. package/dist/services/dep-service.d.ts +14 -0
  186. package/dist/services/dep-service.d.ts.map +1 -0
  187. package/dist/services/dep-service.js +34 -0
  188. package/dist/services/dep-service.js.map +1 -0
  189. package/dist/services/diversifier-service.d.ts +46 -0
  190. package/dist/services/diversifier-service.d.ts.map +1 -0
  191. package/dist/services/diversifier-service.js +197 -0
  192. package/dist/services/diversifier-service.js.map +1 -0
  193. package/dist/services/edge-service.d.ts +78 -0
  194. package/dist/services/edge-service.d.ts.map +1 -0
  195. package/dist/services/edge-service.js +158 -0
  196. package/dist/services/edge-service.js.map +1 -0
  197. package/dist/services/embedding-service.d.ts +138 -0
  198. package/dist/services/embedding-service.d.ts.map +1 -0
  199. package/dist/services/embedding-service.js +318 -0
  200. package/dist/services/embedding-service.js.map +1 -0
  201. package/dist/services/feedback-tracker.d.ts +64 -0
  202. package/dist/services/feedback-tracker.d.ts.map +1 -0
  203. package/dist/services/feedback-tracker.js +110 -0
  204. package/dist/services/feedback-tracker.js.map +1 -0
  205. package/dist/services/file-learning-service.d.ts +17 -0
  206. package/dist/services/file-learning-service.d.ts.map +1 -0
  207. package/dist/services/file-learning-service.js +41 -0
  208. package/dist/services/file-learning-service.js.map +1 -0
  209. package/dist/services/file-watcher-service.d.ts +141 -0
  210. package/dist/services/file-watcher-service.d.ts.map +1 -0
  211. package/dist/services/file-watcher-service.js +278 -0
  212. package/dist/services/file-watcher-service.js.map +1 -0
  213. package/dist/services/graph-expansion.d.ts +155 -0
  214. package/dist/services/graph-expansion.d.ts.map +1 -0
  215. package/dist/services/graph-expansion.js +466 -0
  216. package/dist/services/graph-expansion.js.map +1 -0
  217. package/dist/services/hierarchy-service.d.ts +16 -0
  218. package/dist/services/hierarchy-service.d.ts.map +1 -0
  219. package/dist/services/hierarchy-service.js +66 -0
  220. package/dist/services/hierarchy-service.js.map +1 -0
  221. package/dist/services/index.d.ts +36 -0
  222. package/dist/services/index.d.ts.map +1 -0
  223. package/dist/services/index.js +36 -0
  224. package/dist/services/index.js.map +1 -0
  225. package/dist/services/learning-service.d.ts +39 -0
  226. package/dist/services/learning-service.d.ts.map +1 -0
  227. package/dist/services/learning-service.js +151 -0
  228. package/dist/services/learning-service.js.map +1 -0
  229. package/dist/services/migration-service.d.ts +67 -0
  230. package/dist/services/migration-service.d.ts.map +1 -0
  231. package/dist/services/migration-service.js +144 -0
  232. package/dist/services/migration-service.js.map +1 -0
  233. package/dist/services/orchestrator-service.d.ts +52 -0
  234. package/dist/services/orchestrator-service.d.ts.map +1 -0
  235. package/dist/services/orchestrator-service.js +203 -0
  236. package/dist/services/orchestrator-service.js.map +1 -0
  237. package/dist/services/promotion-service.d.ts +67 -0
  238. package/dist/services/promotion-service.d.ts.map +1 -0
  239. package/dist/services/promotion-service.js +151 -0
  240. package/dist/services/promotion-service.js.map +1 -0
  241. package/dist/services/query-expansion-service.d.ts +55 -0
  242. package/dist/services/query-expansion-service.d.ts.map +1 -0
  243. package/dist/services/query-expansion-service.js +174 -0
  244. package/dist/services/query-expansion-service.js.map +1 -0
  245. package/dist/services/ready-service.d.ts +16 -0
  246. package/dist/services/ready-service.d.ts.map +1 -0
  247. package/dist/services/ready-service.js +70 -0
  248. package/dist/services/ready-service.js.map +1 -0
  249. package/dist/services/reranker-service.d.ts +51 -0
  250. package/dist/services/reranker-service.d.ts.map +1 -0
  251. package/dist/services/reranker-service.js +128 -0
  252. package/dist/services/reranker-service.js.map +1 -0
  253. package/dist/services/retriever-service.d.ts +49 -0
  254. package/dist/services/retriever-service.d.ts.map +1 -0
  255. package/dist/services/retriever-service.js +419 -0
  256. package/dist/services/retriever-service.js.map +1 -0
  257. package/dist/services/score-service.d.ts +43 -0
  258. package/dist/services/score-service.d.ts.map +1 -0
  259. package/dist/services/score-service.js +82 -0
  260. package/dist/services/score-service.js.map +1 -0
  261. package/dist/services/swarm-verification.d.ts +104 -0
  262. package/dist/services/swarm-verification.d.ts.map +1 -0
  263. package/dist/services/swarm-verification.js +400 -0
  264. package/dist/services/swarm-verification.js.map +1 -0
  265. package/dist/services/sync-service.d.ts +115 -0
  266. package/dist/services/sync-service.d.ts.map +1 -0
  267. package/dist/services/sync-service.js +350 -0
  268. package/dist/services/sync-service.js.map +1 -0
  269. package/dist/services/task-service.d.ts +22 -0
  270. package/dist/services/task-service.d.ts.map +1 -0
  271. package/dist/services/task-service.js +221 -0
  272. package/dist/services/task-service.js.map +1 -0
  273. package/dist/services/worker-process.d.ts +41 -0
  274. package/dist/services/worker-process.d.ts.map +1 -0
  275. package/dist/services/worker-process.js +280 -0
  276. package/dist/services/worker-process.js.map +1 -0
  277. package/dist/services/worker-service.d.ts +74 -0
  278. package/dist/services/worker-service.d.ts.map +1 -0
  279. package/dist/services/worker-service.js +148 -0
  280. package/dist/services/worker-service.js.map +1 -0
  281. package/dist/utils/glob.d.ts +15 -0
  282. package/dist/utils/glob.d.ts.map +1 -0
  283. package/dist/utils/glob.js +27 -0
  284. package/dist/utils/glob.js.map +1 -0
  285. package/dist/utils/math.d.ts +6 -0
  286. package/dist/utils/math.d.ts.map +1 -0
  287. package/dist/utils/math.js +21 -0
  288. package/dist/utils/math.js.map +1 -0
  289. package/package.json +72 -0
@@ -0,0 +1,278 @@
1
+ import { Context, Effect, Layer, Queue } from "effect";
2
+ import { FileWatcherError, WatcherAlreadyRunningError, WatcherNotRunningError } from "../errors.js";
3
+ /**
4
+ * FileWatcherService watches file system paths and emits events when files are
5
+ * added, changed, or deleted. Events are delivered via an Effect Queue for
6
+ * decoupled, backpressure-aware processing.
7
+ *
8
+ * Used by the telemetry daemon to watch Claude Code transcript files
9
+ * (~/.claude/projects/** /*.jsonl) and trigger the learning extraction pipeline.
10
+ *
11
+ * See DD-015 for the full architecture.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const program = Effect.gen(function* () {
16
+ * const watcher = yield* FileWatcherService
17
+ * const eventQueue = yield* watcher.getEventQueue()
18
+ *
19
+ * // Start watching
20
+ * yield* watcher.start({
21
+ * patterns: ["~/.claude/projects/** /*.jsonl"],
22
+ * debounceMs: 2000
23
+ * })
24
+ *
25
+ * // Process events
26
+ * while (true) {
27
+ * const event = yield* Queue.take(eventQueue)
28
+ * yield* Effect.log(`File ${event.type}: ${event.path}`)
29
+ * }
30
+ * })
31
+ * ```
32
+ */
33
+ export class FileWatcherService extends Context.Tag("FileWatcherService")() {
34
+ }
35
+ /**
36
+ * No-op implementation for testing or when file watching is disabled.
37
+ * All operations succeed but no actual watching occurs.
38
+ */
39
+ export const FileWatcherServiceNoop = Layer.scoped(FileWatcherService, Effect.gen(function* () {
40
+ // Create a dummy queue that will never receive events
41
+ const eventQueue = yield* Queue.unbounded();
42
+ return {
43
+ start: () => Effect.void,
44
+ stop: () => Effect.void,
45
+ isRunning: () => Effect.succeed(false),
46
+ getWatchedPaths: () => Effect.succeed([]),
47
+ getEventQueue: () => Effect.succeed(eventQueue),
48
+ status: () => Effect.succeed({
49
+ running: false,
50
+ watchedPaths: [],
51
+ startedAt: null,
52
+ eventsProcessed: 0
53
+ })
54
+ };
55
+ }));
56
+ /**
57
+ * Expand tilde (~) to the user's home directory.
58
+ */
59
+ const expandTilde = (path) => {
60
+ const { homedir } = require("node:os");
61
+ return path.startsWith("~") ? path.replace(/^~/, homedir()) : path;
62
+ };
63
+ /**
64
+ * Extract the base directory from a glob pattern.
65
+ * For "~/.claude/projects/** /*.jsonl", returns the expanded "~/.claude/projects".
66
+ * For paths without globs, returns the path as-is.
67
+ */
68
+ const extractBaseDir = (pattern) => {
69
+ const expanded = expandTilde(pattern);
70
+ const firstGlobIndex = expanded.search(/[*?[\]{}]/);
71
+ if (firstGlobIndex === -1) {
72
+ return expanded;
73
+ }
74
+ // Find the last path separator before the first glob character
75
+ const beforeGlob = expanded.slice(0, firstGlobIndex);
76
+ const lastSep = Math.max(beforeGlob.lastIndexOf("/"), beforeGlob.lastIndexOf("\\"));
77
+ return lastSep > 0 ? expanded.slice(0, lastSep) : expanded;
78
+ };
79
+ /**
80
+ * Check if a file path matches a glob-like pattern.
81
+ * Simple implementation supporting:
82
+ * - ** for any directory depth
83
+ * - * for any characters in a filename
84
+ */
85
+ const matchesPattern = (filePath, pattern) => {
86
+ const expanded = expandTilde(pattern);
87
+ // If no glob characters, just check if the path starts with the pattern
88
+ if (!/[*?[\]{}]/.test(expanded)) {
89
+ return filePath.startsWith(expanded);
90
+ }
91
+ // Convert glob pattern to regex
92
+ // Escape special regex chars except * and ?
93
+ let regexStr = expanded
94
+ .replace(/[.+^${}()|[\]\\]/g, "\\$&")
95
+ .replace(/\*\*/g, "<<<GLOBSTAR>>>")
96
+ .replace(/\*/g, "[^/\\\\]*")
97
+ .replace(/<<<GLOBSTAR>>>/g, ".*")
98
+ .replace(/\?/g, ".");
99
+ const regex = new RegExp(`^${regexStr}$`);
100
+ return regex.test(filePath);
101
+ };
102
+ /**
103
+ * Live implementation of FileWatcherService using chokidar.
104
+ *
105
+ * Features:
106
+ * - Uses chokidar for cross-platform file watching
107
+ * - awaitWriteFinish with 2000ms debounce for chunked writes
108
+ * - persistent mode to keep process running
109
+ * - ignoreInitial: false to emit events for existing files
110
+ * - Effect Queue for backpressure-aware event buffering
111
+ * - Supports glob patterns (expands ~ and extracts base directories)
112
+ */
113
+ export const FileWatcherServiceLive = Layer.scoped(FileWatcherService, Effect.gen(function* () {
114
+ const chokidar = yield* Effect.tryPromise({
115
+ try: () => import("chokidar"),
116
+ catch: (error) => new FileWatcherError({
117
+ reason: "Failed to import chokidar",
118
+ cause: error
119
+ })
120
+ });
121
+ // Create the event queue for delivering file events
122
+ const eventQueue = yield* Queue.unbounded();
123
+ // Mutable state using Effect Ref
124
+ const stateRef = yield* Effect.sync(() => ({
125
+ current: {
126
+ running: false,
127
+ watcher: null,
128
+ watchedPaths: [],
129
+ startedAt: null,
130
+ eventsProcessed: 0
131
+ }
132
+ }));
133
+ const getState = () => stateRef.current;
134
+ const setState = (updater) => {
135
+ stateRef.current = updater(stateRef.current);
136
+ };
137
+ // Cleanup on scope finalization
138
+ yield* Effect.addFinalizer(() => Effect.gen(function* () {
139
+ const state = getState();
140
+ if (state.watcher) {
141
+ yield* Effect.tryPromise({
142
+ try: () => state.watcher.close(),
143
+ catch: () => new Error("cleanup") // Error will be ignored
144
+ }).pipe(Effect.ignore);
145
+ }
146
+ }));
147
+ const start = (config) => Effect.gen(function* () {
148
+ const state = getState();
149
+ if (state.running) {
150
+ return yield* Effect.fail(new WatcherAlreadyRunningError({
151
+ path: state.watchedPaths.join(", ")
152
+ }));
153
+ }
154
+ // Extract base directories from glob patterns
155
+ const expandedPaths = config.patterns.map((p) => expandTilde(p));
156
+ const baseDirs = [...new Set(config.patterns.map(extractBaseDir))];
157
+ // Store original patterns for filtering
158
+ const originalPatterns = config.patterns;
159
+ // Configure chokidar options
160
+ const debounceMs = config.debounceMs ?? 2000;
161
+ const watcherOptions = {
162
+ persistent: true,
163
+ ignoreInitial: config.ignoreInitial ?? false,
164
+ awaitWriteFinish: {
165
+ stabilityThreshold: debounceMs,
166
+ pollInterval: Math.min(100, debounceMs / 10)
167
+ },
168
+ // Use polling interval if specified
169
+ ...(config.pollInterval && {
170
+ usePolling: true,
171
+ interval: config.pollInterval
172
+ })
173
+ };
174
+ // Create the watcher
175
+ const watcher = yield* Effect.try({
176
+ try: () => chokidar.watch(baseDirs, watcherOptions),
177
+ catch: (error) => new FileWatcherError({
178
+ reason: "Failed to create chokidar watcher",
179
+ cause: error
180
+ })
181
+ });
182
+ // Set up event handlers
183
+ const handleEvent = (type, path) => {
184
+ // Check if the path matches any of our patterns
185
+ const matches = originalPatterns.some((pattern) => matchesPattern(path, pattern));
186
+ if (!matches)
187
+ return;
188
+ const event = {
189
+ type,
190
+ path,
191
+ timestamp: new Date()
192
+ };
193
+ // Offer event to queue (non-blocking)
194
+ Effect.runFork(Queue.offer(eventQueue, event).pipe(Effect.tap(() => Effect.sync(() => {
195
+ setState((s) => ({ ...s, eventsProcessed: s.eventsProcessed + 1 }));
196
+ }))));
197
+ };
198
+ watcher.on("add", (path) => handleEvent("add", path));
199
+ watcher.on("change", (path) => handleEvent("change", path));
200
+ watcher.on("unlink", (path) => handleEvent("delete", path));
201
+ watcher.on("error", (error) => {
202
+ // Log errors but don't crash - fire and forget error reporting
203
+ Effect.runFork(Effect.logWarning(`File watcher error: ${error}`));
204
+ });
205
+ // Wait for the ready event
206
+ yield* Effect.async((resume) => {
207
+ const timeout = setTimeout(() => {
208
+ resume(Effect.fail(new FileWatcherError({
209
+ reason: "Watcher did not become ready within timeout"
210
+ })));
211
+ }, 30000); // 30 second timeout
212
+ watcher.once("ready", () => {
213
+ clearTimeout(timeout);
214
+ resume(Effect.void);
215
+ });
216
+ watcher.once("error", (error) => {
217
+ clearTimeout(timeout);
218
+ resume(Effect.fail(new FileWatcherError({
219
+ reason: "Watcher failed during initialization",
220
+ cause: error
221
+ })));
222
+ });
223
+ });
224
+ // Update state
225
+ setState(() => ({
226
+ running: true,
227
+ watcher,
228
+ watchedPaths: expandedPaths,
229
+ startedAt: new Date(),
230
+ eventsProcessed: 0
231
+ }));
232
+ });
233
+ const stop = () => Effect.gen(function* () {
234
+ const state = getState();
235
+ if (!state.running || !state.watcher) {
236
+ return yield* Effect.fail(new WatcherNotRunningError({
237
+ path: "no active watcher"
238
+ }));
239
+ }
240
+ // Close the watcher
241
+ yield* Effect.tryPromise({
242
+ try: () => state.watcher.close(),
243
+ catch: (error) => new FileWatcherError({
244
+ reason: "Failed to close chokidar watcher",
245
+ cause: error
246
+ })
247
+ });
248
+ // Update state
249
+ setState(() => ({
250
+ running: false,
251
+ watcher: null,
252
+ watchedPaths: [],
253
+ startedAt: null,
254
+ eventsProcessed: 0
255
+ }));
256
+ });
257
+ const isRunning = () => Effect.sync(() => getState().running);
258
+ const getWatchedPaths = () => Effect.sync(() => getState().watchedPaths);
259
+ const getEventQueue = () => Effect.succeed(eventQueue);
260
+ const status = () => Effect.sync(() => {
261
+ const state = getState();
262
+ return {
263
+ running: state.running,
264
+ watchedPaths: state.watchedPaths,
265
+ startedAt: state.startedAt,
266
+ eventsProcessed: state.eventsProcessed
267
+ };
268
+ });
269
+ return {
270
+ start,
271
+ stop,
272
+ isRunning,
273
+ getWatchedPaths,
274
+ getEventQueue,
275
+ status
276
+ };
277
+ }));
278
+ //# sourceMappingURL=file-watcher-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-watcher-service.js","sourceRoot":"","sources":["../../src/services/file-watcher-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import { EdgeService } from "./edge-service.js";
3
+ import { LearningRepository } from "../repo/learning-repo.js";
4
+ import { AnchorRepository } from "../repo/anchor-repo.js";
5
+ import { DatabaseError, ValidationError } from "../errors.js";
6
+ import type { Learning, EdgeType, LearningId } from "@jamesaphoenix/tx-types";
7
+ /**
8
+ * Seed learning with an initial score for graph expansion.
9
+ * Typically the RRF score from hybrid search.
10
+ */
11
+ export interface SeedLearning {
12
+ readonly learning: Learning;
13
+ readonly score: number;
14
+ }
15
+ /**
16
+ * Expanded learning with graph traversal metadata.
17
+ */
18
+ export interface ExpandedLearning {
19
+ readonly learning: Learning;
20
+ /** Number of hops from the nearest seed (0 = direct seed) */
21
+ readonly hops: number;
22
+ /** Score after applying weight decay per hop */
23
+ readonly decayedScore: number;
24
+ /** Path of learning IDs from seed to this learning */
25
+ readonly path: readonly LearningId[];
26
+ /** Edge type that connected this learning (null for seeds) */
27
+ readonly sourceEdge: EdgeType | null;
28
+ /** The edge weight that led to this learning (null for seeds) */
29
+ readonly edgeWeight: number | null;
30
+ }
31
+ /**
32
+ * Filter configuration for edge types during graph traversal.
33
+ * Supports include/exclude lists and per-hop overrides.
34
+ */
35
+ export interface EdgeTypeFilter {
36
+ /** Only traverse these edge types (mutually exclusive with exclude for same types) */
37
+ readonly include?: readonly EdgeType[];
38
+ /** Traverse all edge types except these (mutually exclusive with include for same types) */
39
+ readonly exclude?: readonly EdgeType[];
40
+ /** Depth-specific filter overrides (1-indexed, matching hop number) */
41
+ readonly perHop?: Readonly<Record<number, EdgeTypeFilter>>;
42
+ }
43
+ /**
44
+ * Options for graph expansion algorithm.
45
+ */
46
+ export interface GraphExpansionOptions {
47
+ /** Maximum traversal depth (default: 2) */
48
+ readonly depth?: number;
49
+ /** Score decay factor per hop (default: 0.7) */
50
+ readonly decayFactor?: number;
51
+ /** Maximum nodes to return (default: 100) */
52
+ readonly maxNodes?: number;
53
+ /** Filter by specific edge types (default: all types).
54
+ * Accepts either a simple array for backwards compatibility or EdgeTypeFilter for advanced filtering. */
55
+ readonly edgeTypes?: EdgeTypeFilter | readonly EdgeType[];
56
+ }
57
+ /**
58
+ * Result of graph expansion operation.
59
+ */
60
+ export interface GraphExpansionResult {
61
+ /** Seeds that were provided as input */
62
+ readonly seeds: readonly ExpandedLearning[];
63
+ /** Learnings discovered through graph expansion (excludes seeds) */
64
+ readonly expanded: readonly ExpandedLearning[];
65
+ /** Total learnings (seeds + expanded) */
66
+ readonly all: readonly ExpandedLearning[];
67
+ /** Statistics about the expansion */
68
+ readonly stats: {
69
+ readonly seedCount: number;
70
+ readonly expandedCount: number;
71
+ readonly maxDepthReached: number;
72
+ readonly nodesVisited: number;
73
+ };
74
+ }
75
+ /**
76
+ * Options for file-based graph expansion.
77
+ * Expands from files via IMPORTS and CO_CHANGES_WITH edges to find related learnings.
78
+ * See PRD-016 for specification.
79
+ */
80
+ export interface FileExpansionOptions {
81
+ /** Maximum traversal depth for file relationships (default: 2) */
82
+ readonly depth?: number;
83
+ /** Score decay factor per hop (default: 0.7) */
84
+ readonly decayFactor?: number;
85
+ /** Maximum learnings to return (default: 100) */
86
+ readonly maxNodes?: number;
87
+ }
88
+ /**
89
+ * A learning discovered through file-based graph expansion.
90
+ * Contains metadata about how the learning was found via file relationships.
91
+ */
92
+ export interface FileExpandedLearning {
93
+ readonly learning: Learning;
94
+ /** The source file path that led to this learning */
95
+ readonly sourceFile: string;
96
+ /** Number of hops from the source file (0 = directly anchored to input file) */
97
+ readonly hops: number;
98
+ /** Score after applying weight decay per hop */
99
+ readonly decayedScore: number;
100
+ /** Edge type that connected this learning (ANCHORED_TO for direct, IMPORTS or CO_CHANGES_WITH for expanded) */
101
+ readonly sourceEdge: EdgeType;
102
+ /** Edge weight (null for directly anchored learnings, weight value for IMPORTS/CO_CHANGES_WITH) */
103
+ readonly edgeWeight: number | null;
104
+ }
105
+ /**
106
+ * Result of file-based graph expansion operation.
107
+ */
108
+ export interface FileExpansionResult {
109
+ /** Learnings directly anchored to the input files (hop 0) */
110
+ readonly anchored: readonly FileExpandedLearning[];
111
+ /** Learnings discovered through file expansion (hops > 0 via IMPORTS/CO_CHANGES_WITH) */
112
+ readonly expanded: readonly FileExpandedLearning[];
113
+ /** All learnings (anchored + expanded), sorted by decayedScore */
114
+ readonly all: readonly FileExpandedLearning[];
115
+ /** Statistics about the expansion */
116
+ readonly stats: {
117
+ readonly inputFileCount: number;
118
+ readonly anchoredCount: number;
119
+ readonly expandedCount: number;
120
+ readonly maxDepthReached: number;
121
+ readonly filesVisited: number;
122
+ };
123
+ }
124
+ declare const GraphExpansionService_base: Context.TagClass<GraphExpansionService, "GraphExpansionService", {
125
+ /**
126
+ * Expand from seed learnings through the knowledge graph.
127
+ * Uses BFS traversal with weight decay per hop.
128
+ * Bidirectional traversal (both incoming and outgoing edges).
129
+ *
130
+ * @param seeds - Learnings to start expansion from, with initial scores
131
+ * @param options - Expansion configuration (depth, decay, limits)
132
+ * @returns Seeds and expanded learnings with traversal metadata
133
+ */
134
+ readonly expand: (seeds: readonly SeedLearning[], options?: GraphExpansionOptions) => Effect.Effect<GraphExpansionResult, ValidationError | DatabaseError>;
135
+ /**
136
+ * Expand from file paths to find related learnings.
137
+ * First finds learnings ANCHORED_TO the input files, then expands via
138
+ * IMPORTS and CO_CHANGES_WITH edges to find learnings anchored to related files.
139
+ *
140
+ * @param files - File paths to expand from (e.g., ["src/auth.ts", "src/jwt.ts"])
141
+ * @param options - Expansion configuration (depth, decay, limits)
142
+ * @returns Anchored and expanded learnings with file relationship metadata
143
+ */
144
+ readonly expandFromFiles: (files: readonly string[], options?: FileExpansionOptions) => Effect.Effect<FileExpansionResult, ValidationError | DatabaseError>;
145
+ }>;
146
+ export declare class GraphExpansionService extends GraphExpansionService_base {
147
+ }
148
+ /**
149
+ * Noop implementation that returns seeds without expansion.
150
+ * Used when graph expansion is disabled or for testing.
151
+ */
152
+ export declare const GraphExpansionServiceNoop: Layer.Layer<GraphExpansionService, never, never>;
153
+ export declare const GraphExpansionServiceLive: Layer.Layer<GraphExpansionService, never, LearningRepository | AnchorRepository | EdgeService>;
154
+ export {};
155
+ //# sourceMappingURL=graph-expansion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-expansion.d.ts","sourceRoot":"","sources":["../../src/services/graph-expansion.ts"],"names":[],"mappings":"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"}