@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.
- package/dist/db.d.ts +42 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +46 -0
- package/dist/db.js.map +1 -0
- package/dist/errors.d.ts +231 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +139 -0
- package/dist/errors.js.map +1 -0
- package/dist/id.d.ts +6 -0
- package/dist/id.d.ts.map +1 -0
- package/dist/id.js +21 -0
- package/dist/id.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/layer.d.ts +50 -0
- package/dist/layer.d.ts.map +1 -0
- package/dist/layer.js +155 -0
- package/dist/layer.js.map +1 -0
- package/dist/mappers/anchor.d.ts +14 -0
- package/dist/mappers/anchor.d.ts.map +1 -0
- package/dist/mappers/anchor.js +38 -0
- package/dist/mappers/anchor.js.map +1 -0
- package/dist/mappers/attempt.d.ts +15 -0
- package/dist/mappers/attempt.d.ts.map +1 -0
- package/dist/mappers/attempt.js +23 -0
- package/dist/mappers/attempt.js.map +1 -0
- package/dist/mappers/candidate.d.ts +23 -0
- package/dist/mappers/candidate.d.ts.map +1 -0
- package/dist/mappers/candidate.js +53 -0
- package/dist/mappers/candidate.js.map +1 -0
- package/dist/mappers/claim.d.ts +30 -0
- package/dist/mappers/claim.d.ts.map +1 -0
- package/dist/mappers/claim.js +32 -0
- package/dist/mappers/claim.js.map +1 -0
- package/dist/mappers/deduplication.d.ts +39 -0
- package/dist/mappers/deduplication.d.ts.map +1 -0
- package/dist/mappers/deduplication.js +53 -0
- package/dist/mappers/deduplication.js.map +1 -0
- package/dist/mappers/edge.d.ts +10 -0
- package/dist/mappers/edge.d.ts.map +1 -0
- package/dist/mappers/edge.js +19 -0
- package/dist/mappers/edge.js.map +1 -0
- package/dist/mappers/file-learning.d.ts +14 -0
- package/dist/mappers/file-learning.d.ts.map +1 -0
- package/dist/mappers/file-learning.js +75 -0
- package/dist/mappers/file-learning.js.map +1 -0
- package/dist/mappers/index.d.ts +17 -0
- package/dist/mappers/index.d.ts.map +1 -0
- package/dist/mappers/index.js +30 -0
- package/dist/mappers/index.js.map +1 -0
- package/dist/mappers/learning.d.ts +19 -0
- package/dist/mappers/learning.d.ts.map +1 -0
- package/dist/mappers/learning.js +41 -0
- package/dist/mappers/learning.js.map +1 -0
- package/dist/mappers/orchestrator-state.d.ts +33 -0
- package/dist/mappers/orchestrator-state.d.ts.map +1 -0
- package/dist/mappers/orchestrator-state.js +34 -0
- package/dist/mappers/orchestrator-state.js.map +1 -0
- package/dist/mappers/run.d.ts +32 -0
- package/dist/mappers/run.d.ts.map +1 -0
- package/dist/mappers/run.js +64 -0
- package/dist/mappers/run.js.map +1 -0
- package/dist/mappers/task.d.ts +23 -0
- package/dist/mappers/task.d.ts.map +1 -0
- package/dist/mappers/task.js +54 -0
- package/dist/mappers/task.js.map +1 -0
- package/dist/mappers/tracked-project.d.ts +15 -0
- package/dist/mappers/tracked-project.d.ts.map +1 -0
- package/dist/mappers/tracked-project.js +23 -0
- package/dist/mappers/tracked-project.js.map +1 -0
- package/dist/mappers/worker.d.ts +33 -0
- package/dist/mappers/worker.d.ts.map +1 -0
- package/dist/mappers/worker.js +35 -0
- package/dist/mappers/worker.js.map +1 -0
- package/dist/repo/anchor-repo.d.ts +52 -0
- package/dist/repo/anchor-repo.d.ts.map +1 -0
- package/dist/repo/anchor-repo.js +204 -0
- package/dist/repo/anchor-repo.js.map +1 -0
- package/dist/repo/attempt-repo.d.ts +25 -0
- package/dist/repo/attempt-repo.d.ts.map +1 -0
- package/dist/repo/attempt-repo.js +78 -0
- package/dist/repo/attempt-repo.js.map +1 -0
- package/dist/repo/candidate-repo.d.ts +16 -0
- package/dist/repo/candidate-repo.d.ts.map +1 -0
- package/dist/repo/candidate-repo.js +143 -0
- package/dist/repo/candidate-repo.js.map +1 -0
- package/dist/repo/claim-repo.d.ts +17 -0
- package/dist/repo/claim-repo.d.ts.map +1 -0
- package/dist/repo/claim-repo.js +62 -0
- package/dist/repo/claim-repo.js.map +1 -0
- package/dist/repo/deduplication-repo.d.ts +37 -0
- package/dist/repo/deduplication-repo.d.ts.map +1 -0
- package/dist/repo/deduplication-repo.js +133 -0
- package/dist/repo/deduplication-repo.js.map +1 -0
- package/dist/repo/dep-repo.d.ts +19 -0
- package/dist/repo/dep-repo.d.ts.map +1 -0
- package/dist/repo/dep-repo.js +104 -0
- package/dist/repo/dep-repo.js.map +1 -0
- package/dist/repo/edge-repo.d.ts +26 -0
- package/dist/repo/edge-repo.d.ts.map +1 -0
- package/dist/repo/edge-repo.js +227 -0
- package/dist/repo/edge-repo.js.map +1 -0
- package/dist/repo/file-learning-repo.d.ts +17 -0
- package/dist/repo/file-learning-repo.d.ts.map +1 -0
- package/dist/repo/file-learning-repo.js +60 -0
- package/dist/repo/file-learning-repo.js.map +1 -0
- package/dist/repo/index.d.ts +18 -0
- package/dist/repo/index.d.ts.map +1 -0
- package/dist/repo/index.js +18 -0
- package/dist/repo/index.js.map +1 -0
- package/dist/repo/learning-repo.d.ts +31 -0
- package/dist/repo/learning-repo.d.ts.map +1 -0
- package/dist/repo/learning-repo.js +165 -0
- package/dist/repo/learning-repo.js.map +1 -0
- package/dist/repo/orchestrator-state-repo.d.ts +27 -0
- package/dist/repo/orchestrator-state-repo.d.ts.map +1 -0
- package/dist/repo/orchestrator-state-repo.js +96 -0
- package/dist/repo/orchestrator-state-repo.js.map +1 -0
- package/dist/repo/run-repo.d.ts +31 -0
- package/dist/repo/run-repo.d.ts.map +1 -0
- package/dist/repo/run-repo.js +132 -0
- package/dist/repo/run-repo.js.map +1 -0
- package/dist/repo/task-repo.d.ts +21 -0
- package/dist/repo/task-repo.d.ts.map +1 -0
- package/dist/repo/task-repo.js +169 -0
- package/dist/repo/task-repo.js.map +1 -0
- package/dist/repo/tracked-project-repo.d.ts +16 -0
- package/dist/repo/tracked-project-repo.d.ts.map +1 -0
- package/dist/repo/tracked-project-repo.js +54 -0
- package/dist/repo/tracked-project-repo.js.map +1 -0
- package/dist/repo/worker-repo.d.ts +19 -0
- package/dist/repo/worker-repo.d.ts.map +1 -0
- package/dist/repo/worker-repo.js +72 -0
- package/dist/repo/worker-repo.js.map +1 -0
- package/dist/schemas/index.d.ts +8 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +7 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/sync.d.ts +296 -0
- package/dist/schemas/sync.d.ts.map +1 -0
- package/dist/schemas/sync.js +146 -0
- package/dist/schemas/sync.js.map +1 -0
- package/dist/schemas/worker.d.ts +77 -0
- package/dist/schemas/worker.d.ts.map +1 -0
- package/dist/schemas/worker.js +80 -0
- package/dist/schemas/worker.js.map +1 -0
- package/dist/services/anchor-service.d.ts +147 -0
- package/dist/services/anchor-service.d.ts.map +1 -0
- package/dist/services/anchor-service.js +540 -0
- package/dist/services/anchor-service.js.map +1 -0
- package/dist/services/anchor-verification.d.ts +94 -0
- package/dist/services/anchor-verification.d.ts.map +1 -0
- package/dist/services/anchor-verification.js +617 -0
- package/dist/services/anchor-verification.js.map +1 -0
- package/dist/services/ast-grep-service.d.ts +58 -0
- package/dist/services/ast-grep-service.d.ts.map +1 -0
- package/dist/services/ast-grep-service.js +356 -0
- package/dist/services/ast-grep-service.js.map +1 -0
- package/dist/services/attempt-service.d.ts +24 -0
- package/dist/services/attempt-service.d.ts.map +1 -0
- package/dist/services/attempt-service.js +55 -0
- package/dist/services/attempt-service.js.map +1 -0
- package/dist/services/auto-sync-service.d.ts +56 -0
- package/dist/services/auto-sync-service.d.ts.map +1 -0
- package/dist/services/auto-sync-service.js +66 -0
- package/dist/services/auto-sync-service.js.map +1 -0
- package/dist/services/candidate-extractor-service.d.ts +56 -0
- package/dist/services/candidate-extractor-service.d.ts.map +1 -0
- package/dist/services/candidate-extractor-service.js +365 -0
- package/dist/services/candidate-extractor-service.js.map +1 -0
- package/dist/services/claim-service.d.ts +52 -0
- package/dist/services/claim-service.d.ts.map +1 -0
- package/dist/services/claim-service.js +134 -0
- package/dist/services/claim-service.js.map +1 -0
- package/dist/services/daemon-service.d.ts +214 -0
- package/dist/services/daemon-service.d.ts.map +1 -0
- package/dist/services/daemon-service.js +522 -0
- package/dist/services/daemon-service.js.map +1 -0
- package/dist/services/deduplication-service.d.ts +67 -0
- package/dist/services/deduplication-service.d.ts.map +1 -0
- package/dist/services/deduplication-service.js +145 -0
- package/dist/services/deduplication-service.js.map +1 -0
- package/dist/services/dep-service.d.ts +14 -0
- package/dist/services/dep-service.d.ts.map +1 -0
- package/dist/services/dep-service.js +34 -0
- package/dist/services/dep-service.js.map +1 -0
- package/dist/services/diversifier-service.d.ts +46 -0
- package/dist/services/diversifier-service.d.ts.map +1 -0
- package/dist/services/diversifier-service.js +197 -0
- package/dist/services/diversifier-service.js.map +1 -0
- package/dist/services/edge-service.d.ts +78 -0
- package/dist/services/edge-service.d.ts.map +1 -0
- package/dist/services/edge-service.js +158 -0
- package/dist/services/edge-service.js.map +1 -0
- package/dist/services/embedding-service.d.ts +138 -0
- package/dist/services/embedding-service.d.ts.map +1 -0
- package/dist/services/embedding-service.js +318 -0
- package/dist/services/embedding-service.js.map +1 -0
- package/dist/services/feedback-tracker.d.ts +64 -0
- package/dist/services/feedback-tracker.d.ts.map +1 -0
- package/dist/services/feedback-tracker.js +110 -0
- package/dist/services/feedback-tracker.js.map +1 -0
- package/dist/services/file-learning-service.d.ts +17 -0
- package/dist/services/file-learning-service.d.ts.map +1 -0
- package/dist/services/file-learning-service.js +41 -0
- package/dist/services/file-learning-service.js.map +1 -0
- package/dist/services/file-watcher-service.d.ts +141 -0
- package/dist/services/file-watcher-service.d.ts.map +1 -0
- package/dist/services/file-watcher-service.js +278 -0
- package/dist/services/file-watcher-service.js.map +1 -0
- package/dist/services/graph-expansion.d.ts +155 -0
- package/dist/services/graph-expansion.d.ts.map +1 -0
- package/dist/services/graph-expansion.js +466 -0
- package/dist/services/graph-expansion.js.map +1 -0
- package/dist/services/hierarchy-service.d.ts +16 -0
- package/dist/services/hierarchy-service.d.ts.map +1 -0
- package/dist/services/hierarchy-service.js +66 -0
- package/dist/services/hierarchy-service.js.map +1 -0
- package/dist/services/index.d.ts +36 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +36 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/learning-service.d.ts +39 -0
- package/dist/services/learning-service.d.ts.map +1 -0
- package/dist/services/learning-service.js +151 -0
- package/dist/services/learning-service.js.map +1 -0
- package/dist/services/migration-service.d.ts +67 -0
- package/dist/services/migration-service.d.ts.map +1 -0
- package/dist/services/migration-service.js +144 -0
- package/dist/services/migration-service.js.map +1 -0
- package/dist/services/orchestrator-service.d.ts +52 -0
- package/dist/services/orchestrator-service.d.ts.map +1 -0
- package/dist/services/orchestrator-service.js +203 -0
- package/dist/services/orchestrator-service.js.map +1 -0
- package/dist/services/promotion-service.d.ts +67 -0
- package/dist/services/promotion-service.d.ts.map +1 -0
- package/dist/services/promotion-service.js +151 -0
- package/dist/services/promotion-service.js.map +1 -0
- package/dist/services/query-expansion-service.d.ts +55 -0
- package/dist/services/query-expansion-service.d.ts.map +1 -0
- package/dist/services/query-expansion-service.js +174 -0
- package/dist/services/query-expansion-service.js.map +1 -0
- package/dist/services/ready-service.d.ts +16 -0
- package/dist/services/ready-service.d.ts.map +1 -0
- package/dist/services/ready-service.js +70 -0
- package/dist/services/ready-service.js.map +1 -0
- package/dist/services/reranker-service.d.ts +51 -0
- package/dist/services/reranker-service.d.ts.map +1 -0
- package/dist/services/reranker-service.js +128 -0
- package/dist/services/reranker-service.js.map +1 -0
- package/dist/services/retriever-service.d.ts +49 -0
- package/dist/services/retriever-service.d.ts.map +1 -0
- package/dist/services/retriever-service.js +419 -0
- package/dist/services/retriever-service.js.map +1 -0
- package/dist/services/score-service.d.ts +43 -0
- package/dist/services/score-service.d.ts.map +1 -0
- package/dist/services/score-service.js +82 -0
- package/dist/services/score-service.js.map +1 -0
- package/dist/services/swarm-verification.d.ts +104 -0
- package/dist/services/swarm-verification.d.ts.map +1 -0
- package/dist/services/swarm-verification.js +400 -0
- package/dist/services/swarm-verification.js.map +1 -0
- package/dist/services/sync-service.d.ts +115 -0
- package/dist/services/sync-service.d.ts.map +1 -0
- package/dist/services/sync-service.js +350 -0
- package/dist/services/sync-service.js.map +1 -0
- package/dist/services/task-service.d.ts +22 -0
- package/dist/services/task-service.d.ts.map +1 -0
- package/dist/services/task-service.js +221 -0
- package/dist/services/task-service.js.map +1 -0
- package/dist/services/worker-process.d.ts +41 -0
- package/dist/services/worker-process.d.ts.map +1 -0
- package/dist/services/worker-process.js +280 -0
- package/dist/services/worker-process.js.map +1 -0
- package/dist/services/worker-service.d.ts +74 -0
- package/dist/services/worker-service.d.ts.map +1 -0
- package/dist/services/worker-service.js +148 -0
- package/dist/services/worker-service.js.map +1 -0
- package/dist/utils/glob.d.ts +15 -0
- package/dist/utils/glob.d.ts.map +1 -0
- package/dist/utils/glob.js +27 -0
- package/dist/utils/glob.js.map +1 -0
- package/dist/utils/math.d.ts +6 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +21 -0
- package/dist/utils/math.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { DatabaseError } from "../errors.js";
|
|
3
|
+
import { EdgeService } from "./edge-service.js";
|
|
4
|
+
/**
|
|
5
|
+
* Input for recording which learnings were used in a run.
|
|
6
|
+
*/
|
|
7
|
+
export interface LearningUsageFeedback {
|
|
8
|
+
readonly id: number;
|
|
9
|
+
readonly helpful: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const FeedbackTrackerService_base: Context.TagClass<FeedbackTrackerService, "FeedbackTrackerService", {
|
|
12
|
+
/**
|
|
13
|
+
* Record which learnings were shown to an agent and whether they were helpful.
|
|
14
|
+
* Creates USED_IN_RUN edges in the graph for each learning.
|
|
15
|
+
*
|
|
16
|
+
* @param runId - Unique identifier for the agent run
|
|
17
|
+
* @param learnings - Array of learnings with their helpfulness feedback
|
|
18
|
+
*/
|
|
19
|
+
readonly recordUsage: (runId: string, learnings: readonly LearningUsageFeedback[]) => Effect.Effect<void, DatabaseError>;
|
|
20
|
+
/**
|
|
21
|
+
* Get the feedback score for a learning based on historical usage.
|
|
22
|
+
* Uses Bayesian averaging: (successes + prior) / (total + 2*prior)
|
|
23
|
+
*
|
|
24
|
+
* @param learningId - The learning ID to get feedback score for
|
|
25
|
+
* @returns Score between 0 and 1, with 0.5 being neutral (no feedback)
|
|
26
|
+
*/
|
|
27
|
+
readonly getFeedbackScore: (learningId: number) => Effect.Effect<number, DatabaseError>;
|
|
28
|
+
/**
|
|
29
|
+
* Get feedback scores for multiple learnings in a single batch query.
|
|
30
|
+
* Uses EdgeService.findFromMultipleSources() to avoid N+1 queries.
|
|
31
|
+
*
|
|
32
|
+
* @param learningIds - Array of learning IDs to get feedback scores for
|
|
33
|
+
* @returns Map from learningId to score (0-1, 0.5 is neutral)
|
|
34
|
+
*/
|
|
35
|
+
readonly getFeedbackScores: (learningIds: readonly number[]) => Effect.Effect<ReadonlyMap<number, number>, DatabaseError>;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* FeedbackTrackerService tracks which learnings were helpful in agent runs
|
|
39
|
+
* via USED_IN_RUN edges. Uses Bayesian scoring to weight future retrievals.
|
|
40
|
+
*
|
|
41
|
+
* Design: DD-016 specifies feedback tracking as part of the graph-expanded
|
|
42
|
+
* retrieval pipeline. Learnings that are marked helpful receive score boosts.
|
|
43
|
+
*/
|
|
44
|
+
export declare class FeedbackTrackerService extends FeedbackTrackerService_base {
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Noop implementation - returns neutral scores and does nothing on record.
|
|
48
|
+
* Used when feedback tracking is disabled or for testing.
|
|
49
|
+
*/
|
|
50
|
+
export declare const FeedbackTrackerServiceNoop: Layer.Layer<FeedbackTrackerService, never, never>;
|
|
51
|
+
/**
|
|
52
|
+
* Live implementation that stores feedback as USED_IN_RUN edges.
|
|
53
|
+
*
|
|
54
|
+
* recordUsage: Creates USED_IN_RUN edges from learning to run.
|
|
55
|
+
* - Weight: 1.0 if helpful, 0.0 if not helpful
|
|
56
|
+
* - Metadata: { position, recordedAt }
|
|
57
|
+
*
|
|
58
|
+
* getFeedbackScore: Calculates Bayesian average from historical edges.
|
|
59
|
+
* - Formula: (helpfulCount + prior * priorWeight) / (totalCount + priorWeight)
|
|
60
|
+
* - Returns 0.5 (neutral) for learnings with no feedback.
|
|
61
|
+
*/
|
|
62
|
+
export declare const FeedbackTrackerServiceLive: Layer.Layer<FeedbackTrackerService, never, EdgeService>;
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=feedback-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback-tracker.d.ts","sourceRoot":"","sources":["../../src/services/feedback-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;;IAYG;;;;;;OAMG;0BACmB,CACpB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,SAAS,qBAAqB,EAAE,KACxC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC;IAEvC;;;;;;OAMG;+BACwB,CACzB,UAAU,EAAE,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAEzC;;;;;;OAMG;gCACyB,CAC1B,WAAW,EAAE,SAAS,MAAM,EAAE,KAC3B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,CAAC;;AA1ClE;;;;;;GAMG;AACH,qBAAa,sBAAuB,SAAQ,2BAqCzC;CAAG;AAUN;;;GAGG;AACH,eAAO,MAAM,0BAA0B,mDAUtC,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B,yDA0FtC,CAAA"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { DatabaseError } from "../errors.js";
|
|
3
|
+
import { EdgeService } from "./edge-service.js";
|
|
4
|
+
/**
|
|
5
|
+
* FeedbackTrackerService tracks which learnings were helpful in agent runs
|
|
6
|
+
* via USED_IN_RUN edges. Uses Bayesian scoring to weight future retrievals.
|
|
7
|
+
*
|
|
8
|
+
* Design: DD-016 specifies feedback tracking as part of the graph-expanded
|
|
9
|
+
* retrieval pipeline. Learnings that are marked helpful receive score boosts.
|
|
10
|
+
*/
|
|
11
|
+
export class FeedbackTrackerService extends Context.Tag("FeedbackTrackerService")() {
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Bayesian scoring constants.
|
|
15
|
+
* Prior of 0.5 means neutral (neither helpful nor unhelpful).
|
|
16
|
+
* Prior weight of 2 provides moderate regularization toward the prior.
|
|
17
|
+
*/
|
|
18
|
+
const BAYESIAN_PRIOR = 0.5;
|
|
19
|
+
const BAYESIAN_PRIOR_WEIGHT = 2;
|
|
20
|
+
/**
|
|
21
|
+
* Noop implementation - returns neutral scores and does nothing on record.
|
|
22
|
+
* Used when feedback tracking is disabled or for testing.
|
|
23
|
+
*/
|
|
24
|
+
export const FeedbackTrackerServiceNoop = Layer.succeed(FeedbackTrackerService, {
|
|
25
|
+
recordUsage: (_runId, _learnings) => Effect.void,
|
|
26
|
+
getFeedbackScore: (_learningId) => Effect.succeed(0.5),
|
|
27
|
+
getFeedbackScores: (learningIds) => Effect.succeed(new Map(learningIds.map((id) => [id, 0.5])))
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Live implementation that stores feedback as USED_IN_RUN edges.
|
|
31
|
+
*
|
|
32
|
+
* recordUsage: Creates USED_IN_RUN edges from learning to run.
|
|
33
|
+
* - Weight: 1.0 if helpful, 0.0 if not helpful
|
|
34
|
+
* - Metadata: { position, recordedAt }
|
|
35
|
+
*
|
|
36
|
+
* getFeedbackScore: Calculates Bayesian average from historical edges.
|
|
37
|
+
* - Formula: (helpfulCount + prior * priorWeight) / (totalCount + priorWeight)
|
|
38
|
+
* - Returns 0.5 (neutral) for learnings with no feedback.
|
|
39
|
+
*/
|
|
40
|
+
export const FeedbackTrackerServiceLive = Layer.effect(FeedbackTrackerService, Effect.gen(function* () {
|
|
41
|
+
const edgeService = yield* EdgeService;
|
|
42
|
+
return {
|
|
43
|
+
recordUsage: (runId, learnings) => Effect.gen(function* () {
|
|
44
|
+
const recordedAt = new Date().toISOString();
|
|
45
|
+
for (let i = 0; i < learnings.length; i++) {
|
|
46
|
+
const learning = learnings[i];
|
|
47
|
+
yield* edgeService.createEdge({
|
|
48
|
+
edgeType: "USED_IN_RUN",
|
|
49
|
+
sourceType: "learning",
|
|
50
|
+
sourceId: learning.id.toString(),
|
|
51
|
+
targetType: "run",
|
|
52
|
+
targetId: runId,
|
|
53
|
+
weight: learning.helpful ? 1.0 : 0.0,
|
|
54
|
+
metadata: {
|
|
55
|
+
position: i,
|
|
56
|
+
recordedAt
|
|
57
|
+
}
|
|
58
|
+
}).pipe(
|
|
59
|
+
// Map ValidationError to DatabaseError - validation errors here would be internal issues
|
|
60
|
+
Effect.mapError(e => e._tag === "ValidationError"
|
|
61
|
+
? new DatabaseError({ cause: e.reason })
|
|
62
|
+
: e));
|
|
63
|
+
}
|
|
64
|
+
}),
|
|
65
|
+
getFeedbackScore: (learningId) => Effect.gen(function* () {
|
|
66
|
+
// Find all USED_IN_RUN edges from this learning
|
|
67
|
+
const edges = yield* edgeService.findFromSource("learning", learningId.toString());
|
|
68
|
+
const usedInRunEdges = edges.filter(e => e.edgeType === "USED_IN_RUN");
|
|
69
|
+
// No feedback = neutral score
|
|
70
|
+
if (usedInRunEdges.length === 0) {
|
|
71
|
+
return BAYESIAN_PRIOR;
|
|
72
|
+
}
|
|
73
|
+
// Count helpful (weight > 0) edges
|
|
74
|
+
const totalCount = usedInRunEdges.length;
|
|
75
|
+
const helpfulCount = usedInRunEdges.filter(e => e.weight > 0).length;
|
|
76
|
+
// Bayesian average: (successes + prior * priorWeight) / (total + priorWeight)
|
|
77
|
+
// = (helpfulCount + 0.5 * 2) / (totalCount + 2)
|
|
78
|
+
// = (helpfulCount + 1) / (totalCount + 2)
|
|
79
|
+
return (helpfulCount + BAYESIAN_PRIOR * BAYESIAN_PRIOR_WEIGHT) / (totalCount + BAYESIAN_PRIOR_WEIGHT);
|
|
80
|
+
}),
|
|
81
|
+
getFeedbackScores: (learningIds) => Effect.gen(function* () {
|
|
82
|
+
// Handle empty input
|
|
83
|
+
if (learningIds.length === 0) {
|
|
84
|
+
return new Map();
|
|
85
|
+
}
|
|
86
|
+
// Batch fetch all edges from all learnings
|
|
87
|
+
const sourceIds = learningIds.map(id => id.toString());
|
|
88
|
+
const edgesBySource = yield* edgeService.findFromMultipleSources("learning", sourceIds);
|
|
89
|
+
// Compute Bayesian score for each learning
|
|
90
|
+
const result = new Map();
|
|
91
|
+
for (const learningId of learningIds) {
|
|
92
|
+
const edges = edgesBySource.get(learningId.toString()) ?? [];
|
|
93
|
+
const usedInRunEdges = edges.filter(e => e.edgeType === "USED_IN_RUN");
|
|
94
|
+
// No feedback = neutral score
|
|
95
|
+
if (usedInRunEdges.length === 0) {
|
|
96
|
+
result.set(learningId, BAYESIAN_PRIOR);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
// Count helpful (weight > 0) edges
|
|
100
|
+
const totalCount = usedInRunEdges.length;
|
|
101
|
+
const helpfulCount = usedInRunEdges.filter(e => e.weight > 0).length;
|
|
102
|
+
// Bayesian average
|
|
103
|
+
const score = (helpfulCount + BAYESIAN_PRIOR * BAYESIAN_PRIOR_WEIGHT) / (totalCount + BAYESIAN_PRIOR_WEIGHT);
|
|
104
|
+
result.set(learningId, score);
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
})
|
|
108
|
+
};
|
|
109
|
+
}));
|
|
110
|
+
//# sourceMappingURL=feedback-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback-tracker.js","sourceRoot":"","sources":["../../src/services/feedback-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { FileLearningRepository } from "../repo/file-learning-repo.js";
|
|
3
|
+
import { FileLearningNotFoundError, ValidationError, DatabaseError } from "../errors.js";
|
|
4
|
+
import type { FileLearning, CreateFileLearningInput } from "@jamesaphoenix/tx-types";
|
|
5
|
+
declare const FileLearningService_base: Context.TagClass<FileLearningService, "FileLearningService", {
|
|
6
|
+
readonly create: (input: CreateFileLearningInput) => Effect.Effect<FileLearning, ValidationError | DatabaseError>;
|
|
7
|
+
readonly get: (id: number) => Effect.Effect<FileLearning, FileLearningNotFoundError | DatabaseError>;
|
|
8
|
+
readonly remove: (id: number) => Effect.Effect<void, FileLearningNotFoundError | DatabaseError>;
|
|
9
|
+
readonly getAll: () => Effect.Effect<readonly FileLearning[], DatabaseError>;
|
|
10
|
+
readonly recall: (path: string) => Effect.Effect<readonly FileLearning[], DatabaseError>;
|
|
11
|
+
readonly count: () => Effect.Effect<number, DatabaseError>;
|
|
12
|
+
}>;
|
|
13
|
+
export declare class FileLearningService extends FileLearningService_base {
|
|
14
|
+
}
|
|
15
|
+
export declare const FileLearningServiceLive: Layer.Layer<FileLearningService, never, FileLearningRepository>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=file-learning-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-learning-service.d.ts","sourceRoot":"","sources":["../../src/services/file-learning-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;;qBAK/D,CAAC,KAAK,EAAE,uBAAuB,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,eAAe,GAAG,aAAa,CAAC;kBACnG,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,yBAAyB,GAAG,aAAa,CAAC;qBACnF,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,yBAAyB,GAAG,aAAa,CAAC;qBAC9E,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,YAAY,EAAE,EAAE,aAAa,CAAC;qBAC3D,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,YAAY,EAAE,EAAE,aAAa,CAAC;oBACxE,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;;AAR9D,qBAAa,mBAAoB,SAAQ,wBAUtC;CAAG;AAEN,eAAO,MAAM,uBAAuB,iEA8CnC,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { FileLearningRepository } from "../repo/file-learning-repo.js";
|
|
3
|
+
import { FileLearningNotFoundError, ValidationError } from "../errors.js";
|
|
4
|
+
export class FileLearningService extends Context.Tag("FileLearningService")() {
|
|
5
|
+
}
|
|
6
|
+
export const FileLearningServiceLive = Layer.effect(FileLearningService, Effect.gen(function* () {
|
|
7
|
+
const repo = yield* FileLearningRepository;
|
|
8
|
+
return {
|
|
9
|
+
create: (input) => Effect.gen(function* () {
|
|
10
|
+
if (!input.filePattern || input.filePattern.trim().length === 0) {
|
|
11
|
+
return yield* Effect.fail(new ValidationError({ reason: "File pattern is required" }));
|
|
12
|
+
}
|
|
13
|
+
if (!input.note || input.note.trim().length === 0) {
|
|
14
|
+
return yield* Effect.fail(new ValidationError({ reason: "Note is required" }));
|
|
15
|
+
}
|
|
16
|
+
return yield* repo.insert({
|
|
17
|
+
...input,
|
|
18
|
+
filePattern: input.filePattern.trim(),
|
|
19
|
+
note: input.note.trim()
|
|
20
|
+
});
|
|
21
|
+
}),
|
|
22
|
+
get: (id) => Effect.gen(function* () {
|
|
23
|
+
const learning = yield* repo.findById(id);
|
|
24
|
+
if (!learning) {
|
|
25
|
+
return yield* Effect.fail(new FileLearningNotFoundError({ id }));
|
|
26
|
+
}
|
|
27
|
+
return learning;
|
|
28
|
+
}),
|
|
29
|
+
remove: (id) => Effect.gen(function* () {
|
|
30
|
+
const learning = yield* repo.findById(id);
|
|
31
|
+
if (!learning) {
|
|
32
|
+
return yield* Effect.fail(new FileLearningNotFoundError({ id }));
|
|
33
|
+
}
|
|
34
|
+
yield* repo.remove(id);
|
|
35
|
+
}),
|
|
36
|
+
getAll: () => repo.findAll(),
|
|
37
|
+
recall: (path) => repo.findByPath(path),
|
|
38
|
+
count: () => repo.count()
|
|
39
|
+
};
|
|
40
|
+
}));
|
|
41
|
+
//# sourceMappingURL=file-learning-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-learning-service.js","sourceRoot":"","sources":["../../src/services/file-learning-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAiB,MAAM,cAAc,CAAA;AAGxF,MAAM,OAAO,mBAAoB,SAAQ,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAUxE;CAAG;AAEN,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC,MAAM,CACjD,mBAAmB,EACnB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,sBAAsB,CAAA;IAE1C,OAAO;QACL,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAChB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChE,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAC,CAAC,CAAA;YACxF,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAA;YAChF,CAAC;YACD,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;gBACxB,GAAG,KAAK;gBACR,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE;gBACrC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;aACxB,CAAC,CAAA;QACJ,CAAC,CAAC;QAEJ,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CACV,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,yBAAyB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAClE,CAAC;YACD,OAAO,QAAQ,CAAA;QACjB,CAAC,CAAC;QAEJ,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CACb,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,yBAAyB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAClE,CAAC;YACD,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACxB,CAAC,CAAC;QAEJ,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE;QAE5B,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAEvC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE;KAC1B,CAAA;AACH,CAAC,CAAC,CACH,CAAA"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Queue } from "effect";
|
|
2
|
+
import { FileWatcherError, WatcherAlreadyRunningError, WatcherNotRunningError } from "../errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Type of file event detected by the watcher.
|
|
5
|
+
*/
|
|
6
|
+
export type FileEventType = "add" | "change" | "delete";
|
|
7
|
+
/**
|
|
8
|
+
* Represents a file system event detected by the watcher.
|
|
9
|
+
*/
|
|
10
|
+
export interface FileEvent {
|
|
11
|
+
/** Type of the event */
|
|
12
|
+
readonly type: FileEventType;
|
|
13
|
+
/** Absolute path to the file */
|
|
14
|
+
readonly path: string;
|
|
15
|
+
/** Timestamp when the event was detected */
|
|
16
|
+
readonly timestamp: Date;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Configuration options for the file watcher.
|
|
20
|
+
*/
|
|
21
|
+
export interface FileWatcherConfig {
|
|
22
|
+
/** Glob patterns to watch (e.g., "~/.claude/projects/** /*.jsonl") */
|
|
23
|
+
readonly patterns: readonly string[];
|
|
24
|
+
/** Debounce delay in milliseconds for rapid file changes */
|
|
25
|
+
readonly debounceMs?: number;
|
|
26
|
+
/** Whether to emit events for existing files on start (default: false) */
|
|
27
|
+
readonly ignoreInitial?: boolean;
|
|
28
|
+
/** Polling interval in milliseconds (for network drives, etc.) */
|
|
29
|
+
readonly pollInterval?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Status information for the file watcher.
|
|
33
|
+
*/
|
|
34
|
+
export interface FileWatcherStatus {
|
|
35
|
+
/** Whether the watcher is currently running */
|
|
36
|
+
readonly running: boolean;
|
|
37
|
+
/** Paths/patterns currently being watched */
|
|
38
|
+
readonly watchedPaths: readonly string[];
|
|
39
|
+
/** Timestamp when the watcher was started (null if not running) */
|
|
40
|
+
readonly startedAt: Date | null;
|
|
41
|
+
/** Number of events processed since start */
|
|
42
|
+
readonly eventsProcessed: number;
|
|
43
|
+
}
|
|
44
|
+
declare const FileWatcherService_base: Context.TagClass<FileWatcherService, "FileWatcherService", {
|
|
45
|
+
/**
|
|
46
|
+
* Start watching files matching the configured patterns.
|
|
47
|
+
* Emits FileEvent objects to the event queue.
|
|
48
|
+
*
|
|
49
|
+
* @param config - Configuration options for the watcher
|
|
50
|
+
* @returns Effect that resolves when the watcher is started
|
|
51
|
+
* @throws WatcherAlreadyRunningError if the watcher is already running
|
|
52
|
+
* @throws FileWatcherError if the watcher fails to start
|
|
53
|
+
*/
|
|
54
|
+
readonly start: (config: FileWatcherConfig) => Effect.Effect<void, WatcherAlreadyRunningError | FileWatcherError>;
|
|
55
|
+
/**
|
|
56
|
+
* Stop watching files and clean up resources.
|
|
57
|
+
*
|
|
58
|
+
* @returns Effect that resolves when the watcher is stopped
|
|
59
|
+
* @throws WatcherNotRunningError if the watcher is not running
|
|
60
|
+
* @throws FileWatcherError if the watcher fails to stop cleanly
|
|
61
|
+
*/
|
|
62
|
+
readonly stop: () => Effect.Effect<void, WatcherNotRunningError | FileWatcherError>;
|
|
63
|
+
/**
|
|
64
|
+
* Check if the watcher is currently running.
|
|
65
|
+
*
|
|
66
|
+
* @returns Effect that resolves to true if running, false otherwise
|
|
67
|
+
*/
|
|
68
|
+
readonly isRunning: () => Effect.Effect<boolean>;
|
|
69
|
+
/**
|
|
70
|
+
* Get the paths/patterns currently being watched.
|
|
71
|
+
* Returns an empty array if the watcher is not running.
|
|
72
|
+
*
|
|
73
|
+
* @returns Effect that resolves to the list of watched paths
|
|
74
|
+
*/
|
|
75
|
+
readonly getWatchedPaths: () => Effect.Effect<readonly string[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Get the event queue for receiving file events.
|
|
78
|
+
* Consumers should take events from this queue to process file changes.
|
|
79
|
+
* The queue is unbounded to avoid blocking the watcher.
|
|
80
|
+
*
|
|
81
|
+
* @returns Effect that resolves to the file event queue
|
|
82
|
+
*/
|
|
83
|
+
readonly getEventQueue: () => Effect.Effect<Queue.Queue<FileEvent>>;
|
|
84
|
+
/**
|
|
85
|
+
* Get the current status of the file watcher.
|
|
86
|
+
*
|
|
87
|
+
* @returns Effect that resolves to the watcher status
|
|
88
|
+
*/
|
|
89
|
+
readonly status: () => Effect.Effect<FileWatcherStatus>;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* FileWatcherService watches file system paths and emits events when files are
|
|
93
|
+
* added, changed, or deleted. Events are delivered via an Effect Queue for
|
|
94
|
+
* decoupled, backpressure-aware processing.
|
|
95
|
+
*
|
|
96
|
+
* Used by the telemetry daemon to watch Claude Code transcript files
|
|
97
|
+
* (~/.claude/projects/** /*.jsonl) and trigger the learning extraction pipeline.
|
|
98
|
+
*
|
|
99
|
+
* See DD-015 for the full architecture.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const program = Effect.gen(function* () {
|
|
104
|
+
* const watcher = yield* FileWatcherService
|
|
105
|
+
* const eventQueue = yield* watcher.getEventQueue()
|
|
106
|
+
*
|
|
107
|
+
* // Start watching
|
|
108
|
+
* yield* watcher.start({
|
|
109
|
+
* patterns: ["~/.claude/projects/** /*.jsonl"],
|
|
110
|
+
* debounceMs: 2000
|
|
111
|
+
* })
|
|
112
|
+
*
|
|
113
|
+
* // Process events
|
|
114
|
+
* while (true) {
|
|
115
|
+
* const event = yield* Queue.take(eventQueue)
|
|
116
|
+
* yield* Effect.log(`File ${event.type}: ${event.path}`)
|
|
117
|
+
* }
|
|
118
|
+
* })
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export declare class FileWatcherService extends FileWatcherService_base {
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* No-op implementation for testing or when file watching is disabled.
|
|
125
|
+
* All operations succeed but no actual watching occurs.
|
|
126
|
+
*/
|
|
127
|
+
export declare const FileWatcherServiceNoop: Layer.Layer<FileWatcherService, never, never>;
|
|
128
|
+
/**
|
|
129
|
+
* Live implementation of FileWatcherService using chokidar.
|
|
130
|
+
*
|
|
131
|
+
* Features:
|
|
132
|
+
* - Uses chokidar for cross-platform file watching
|
|
133
|
+
* - awaitWriteFinish with 2000ms debounce for chunked writes
|
|
134
|
+
* - persistent mode to keep process running
|
|
135
|
+
* - ignoreInitial: false to emit events for existing files
|
|
136
|
+
* - Effect Queue for backpressure-aware event buffering
|
|
137
|
+
* - Supports glob patterns (expands ~ and extracts base directories)
|
|
138
|
+
*/
|
|
139
|
+
export declare const FileWatcherServiceLive: Layer.Layer<FileWatcherService, FileWatcherError, never>;
|
|
140
|
+
export {};
|
|
141
|
+
//# sourceMappingURL=file-watcher-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-watcher-service.d.ts","sourceRoot":"","sources":["../../src/services/file-watcher-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtD,OAAO,EACL,gBAAgB,EAChB,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,cAAc,CAAA;AAErB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEvD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,wBAAwB;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAA;IAChC,kEAAkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,IAAI,CAAA;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CACjC;;IAmCG;;;;;;;;OAQG;oBACa,CACd,MAAM,EAAE,iBAAiB,KACtB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,0BAA0B,GAAG,gBAAgB,CAAC;IAEvE;;;;;;OAMG;mBACY,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,sBAAsB,GAAG,gBAAgB,CAAC;IAEnF;;;;OAIG;wBACiB,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IAEhD;;;;;OAKG;8BACuB,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,MAAM,EAAE,CAAC;IAEhE;;;;;;OAMG;4BACqB,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEnE;;;;OAIG;qBACc,MAAM,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC;;AApF3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,kBAAmB,SAAQ,uBAwDrC;CAAG;AAEN;;;GAGG;AACH,eAAO,MAAM,sBAAsB,+CAqBlC,CAAA;AAsED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,0DAmOlC,CAAA"}
|