@codeledger/aggregations 0.8.9
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/LICENSE +27 -0
- package/dist/engine.d.ts +4 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +184 -0
- package/dist/engine.js.map +1 -0
- package/dist/hotspots.d.ts +7 -0
- package/dist/hotspots.d.ts.map +1 -0
- package/dist/hotspots.js +107 -0
- package/dist/hotspots.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/insights.d.ts +6 -0
- package/dist/insights.d.ts.map +1 -0
- package/dist/insights.js +89 -0
- package/dist/insights.js.map +1 -0
- package/dist/job.d.ts +9 -0
- package/dist/job.d.ts.map +1 -0
- package/dist/job.js +360 -0
- package/dist/job.js.map +1 -0
- package/dist/ownership.d.ts +4 -0
- package/dist/ownership.d.ts.map +1 -0
- package/dist/ownership.js +52 -0
- package/dist/ownership.js.map +1 -0
- package/dist/patterns.d.ts +3 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +55 -0
- package/dist/patterns.js.map +1 -0
- package/dist/recommendations.d.ts +3 -0
- package/dist/recommendations.d.ts.map +1 -0
- package/dist/recommendations.js +33 -0
- package/dist/recommendations.js.map +1 -0
- package/dist/scheduler.d.ts +9 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +19 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/store.d.ts +6 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +125 -0
- package/dist/store.js.map +1 -0
- package/dist/team-attribution.d.ts +9 -0
- package/dist/team-attribution.d.ts.map +1 -0
- package/dist/team-attribution.js +73 -0
- package/dist/team-attribution.js.map +1 -0
- package/dist/value.d.ts +11 -0
- package/dist/value.d.ts.map +1 -0
- package/dist/value.js +113 -0
- package/dist/value.js.map +1 -0
- package/package.json +39 -0
package/dist/job.js
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { computeMetrics, filterEvents } from './engine.js';
|
|
4
|
+
import { computePatternSpread } from './patterns.js';
|
|
5
|
+
import { computeRecommendations } from './recommendations.js';
|
|
6
|
+
import { computeValue } from './value.js';
|
|
7
|
+
import { persistSnapshot, readEvents, readLatestSnapshot } from './store.js';
|
|
8
|
+
import { resolveTeamAttribution } from './team-attribution.js';
|
|
9
|
+
import { generateSystemInsights } from './insights.js';
|
|
10
|
+
import { computeQualityHotspots, computeIntegrityHotspots, computeKnowledgePatterns, computeShadowHotspots, computeValueTrend, } from './hotspots.js';
|
|
11
|
+
export function writeInsightSnapshot(cwd, snapshot) {
|
|
12
|
+
const insightDir = join(cwd, '.codeledger', 'insight');
|
|
13
|
+
mkdirSync(insightDir, { recursive: true });
|
|
14
|
+
const path = join(insightDir, 'metrics.json');
|
|
15
|
+
writeFileSync(path, JSON.stringify(snapshot, null, 2) + '\n', 'utf-8');
|
|
16
|
+
return path;
|
|
17
|
+
}
|
|
18
|
+
export function runInsightAggregationJob(options) {
|
|
19
|
+
const events = readEvents(options.cwd);
|
|
20
|
+
const filters = options.filters ?? {};
|
|
21
|
+
validateInsightFilters(filters);
|
|
22
|
+
const annotatedEvents = annotateEventsWithAttribution(options.cwd, events);
|
|
23
|
+
const scopeContext = buildScopeContext(filters, annotatedEvents);
|
|
24
|
+
const scopedEvents = filterEvents(annotatedEvents, scopeContext.filters);
|
|
25
|
+
const previousSnapshot = readLatestSnapshot(options.cwd);
|
|
26
|
+
const orgTimeFilters = buildTimeFilters(filters);
|
|
27
|
+
const orgEvents = filterEvents(annotatedEvents, orgTimeFilters);
|
|
28
|
+
const metrics = computeMetrics(scopedEvents);
|
|
29
|
+
const value = computeValue(metrics, options.assumptions);
|
|
30
|
+
const syntheticRatio = scopedEvents.length > 0
|
|
31
|
+
? scopedEvents.filter((e) => e.isSynthetic).length / scopedEvents.length
|
|
32
|
+
: 0;
|
|
33
|
+
if (syntheticRatio > 0.5) {
|
|
34
|
+
value.confidence = syntheticRatio >= 1 ? 'low' : 'medium';
|
|
35
|
+
}
|
|
36
|
+
const recommendations = computeRecommendations(metrics);
|
|
37
|
+
const qualityHotspots = computeQualityHotspots(scopedEvents);
|
|
38
|
+
const integrityHotspots = computeIntegrityHotspots(scopedEvents);
|
|
39
|
+
const knowledgePatterns = computeKnowledgePatterns(scopedEvents);
|
|
40
|
+
const shadowHotspots = computeShadowHotspots(scopedEvents);
|
|
41
|
+
const valueTrend = computeValueTrend(value.estimatedSavings, previousSnapshot?.value.estimatedSavings ?? value.estimatedSavings);
|
|
42
|
+
const snapshotBaseline = buildBaseline(metrics, previousSnapshot, value);
|
|
43
|
+
const generatedAt = new Date().toISOString();
|
|
44
|
+
const orgMetrics = computeMetrics(orgEvents);
|
|
45
|
+
const scopeAttributionStatus = buildAttributionStatus(scopedEvents);
|
|
46
|
+
const scopeComparisons = buildScopeComparisons(scopeContext, metrics, orgMetrics, orgEvents.length, scopedEvents.length);
|
|
47
|
+
const scopeSummary = buildScopeSummary(scopeContext, scopedEvents, scopeAttributionStatus, scopeComparisons);
|
|
48
|
+
const hotspotSummaries = buildHotspotSummaries(scopedEvents, scopeContext);
|
|
49
|
+
const patternSpread = computePatternSpread(orgEvents, generatedAt);
|
|
50
|
+
const syntheticScenario = buildSyntheticScenarioSummary(scopedEvents);
|
|
51
|
+
const snapshot = {
|
|
52
|
+
generatedAt,
|
|
53
|
+
eventCount: scopedEvents.length,
|
|
54
|
+
filters,
|
|
55
|
+
metrics,
|
|
56
|
+
value,
|
|
57
|
+
recommendations,
|
|
58
|
+
team: determineTeamForSnapshot(options.cwd, scopedEvents, metrics.overview.teams, scopeContext),
|
|
59
|
+
insights: generateSystemInsights(metrics, value, { valueTrend, baseline: snapshotBaseline }),
|
|
60
|
+
qualityHotspots,
|
|
61
|
+
integrityHotspots,
|
|
62
|
+
knowledgePatterns,
|
|
63
|
+
shadowHotspots,
|
|
64
|
+
valueTrend,
|
|
65
|
+
baseline: snapshotBaseline,
|
|
66
|
+
scopeSummary,
|
|
67
|
+
scopeComparisons,
|
|
68
|
+
hotspotSummaries,
|
|
69
|
+
patternSpread,
|
|
70
|
+
syntheticScenario,
|
|
71
|
+
attributionStatus: scopeAttributionStatus,
|
|
72
|
+
};
|
|
73
|
+
writeInsightSnapshot(options.cwd, snapshot);
|
|
74
|
+
persistSnapshot(options.cwd, snapshot);
|
|
75
|
+
return snapshot;
|
|
76
|
+
}
|
|
77
|
+
function determineTeamForSnapshot(repoRoot, events, teams, scopeContext) {
|
|
78
|
+
const teamOverride = scopeContext.filters.team;
|
|
79
|
+
if (teamOverride)
|
|
80
|
+
return teamOverride;
|
|
81
|
+
if (scopeContext.scopeType === 'team')
|
|
82
|
+
return scopeContext.scopeId;
|
|
83
|
+
if (teams.length > 0) {
|
|
84
|
+
const teamCandidate = teams[0];
|
|
85
|
+
if (teamCandidate)
|
|
86
|
+
return teamCandidate;
|
|
87
|
+
}
|
|
88
|
+
for (const event of events) {
|
|
89
|
+
const attribution = resolveTeamAttribution(repoRoot, event);
|
|
90
|
+
if (attribution.team)
|
|
91
|
+
return attribution.team;
|
|
92
|
+
}
|
|
93
|
+
return 'unattributed';
|
|
94
|
+
}
|
|
95
|
+
function annotateEventsWithAttribution(repoRoot, events) {
|
|
96
|
+
return events.map((event) => {
|
|
97
|
+
const attribution = resolveTeamAttribution(repoRoot, event);
|
|
98
|
+
const assignedTeam = attribution.team ?? event.team;
|
|
99
|
+
return {
|
|
100
|
+
...event,
|
|
101
|
+
team: assignedTeam,
|
|
102
|
+
attributionSource: attribution.source,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function buildScopeContext(filters, events) {
|
|
107
|
+
const baseFilters = { ...filters };
|
|
108
|
+
const preferredScope = baseFilters.scopeType ??
|
|
109
|
+
(baseFilters.team
|
|
110
|
+
? 'team'
|
|
111
|
+
: baseFilters.repo
|
|
112
|
+
? 'repo'
|
|
113
|
+
: 'repo');
|
|
114
|
+
let scopeId = baseFilters.scopeId;
|
|
115
|
+
if (preferredScope === 'org') {
|
|
116
|
+
scopeId = scopeId ?? 'org';
|
|
117
|
+
}
|
|
118
|
+
else if (preferredScope === 'team') {
|
|
119
|
+
scopeId = scopeId ?? baseFilters.team ?? 'unattributed';
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const fallbackRepo = events.find((event) => event.repo)?.repo ?? 'workspace';
|
|
123
|
+
scopeId = scopeId ?? baseFilters.repo ?? fallbackRepo;
|
|
124
|
+
}
|
|
125
|
+
const effectiveFilters = { ...baseFilters };
|
|
126
|
+
delete effectiveFilters.scopeType;
|
|
127
|
+
delete effectiveFilters.scopeId;
|
|
128
|
+
if (preferredScope === 'repo') {
|
|
129
|
+
effectiveFilters.repo = scopeId;
|
|
130
|
+
delete effectiveFilters.team;
|
|
131
|
+
}
|
|
132
|
+
else if (preferredScope === 'team') {
|
|
133
|
+
effectiveFilters.team = scopeId;
|
|
134
|
+
delete effectiveFilters.repo;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
delete effectiveFilters.repo;
|
|
138
|
+
delete effectiveFilters.team;
|
|
139
|
+
}
|
|
140
|
+
const scopeLabel = preferredScope === 'org'
|
|
141
|
+
? 'Organization'
|
|
142
|
+
: scopeId === 'unattributed'
|
|
143
|
+
? 'Unattributed'
|
|
144
|
+
: scopeId ?? 'Workspace';
|
|
145
|
+
return {
|
|
146
|
+
scopeType: preferredScope,
|
|
147
|
+
scopeId,
|
|
148
|
+
scopeLabel,
|
|
149
|
+
filters: effectiveFilters,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function buildTimeFilters(filters) {
|
|
153
|
+
const timeFilters = {};
|
|
154
|
+
if (filters.dateFrom)
|
|
155
|
+
timeFilters.dateFrom = filters.dateFrom;
|
|
156
|
+
if (filters.dateTo)
|
|
157
|
+
timeFilters.dateTo = filters.dateTo;
|
|
158
|
+
return timeFilters;
|
|
159
|
+
}
|
|
160
|
+
function buildScopeComparisons(context, scopeMetrics, orgMetrics, orgEventCount, scopeEventCount) {
|
|
161
|
+
const configs = [
|
|
162
|
+
{
|
|
163
|
+
metric: 'executionReliability',
|
|
164
|
+
getter: (metrics) => metrics.quality.executionReliability.value,
|
|
165
|
+
higherBetter: true,
|
|
166
|
+
threshold: 0.85,
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
metric: 'reworkRatio',
|
|
170
|
+
getter: (metrics) => metrics.quality.reworkRatio.value,
|
|
171
|
+
higherBetter: false,
|
|
172
|
+
threshold: 0.2,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
metric: 'integrityDrift',
|
|
176
|
+
getter: (metrics) => metrics.integrity.integrityDrift.value,
|
|
177
|
+
higherBetter: false,
|
|
178
|
+
threshold: 0.1,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
metric: 'patternReuseRate',
|
|
182
|
+
getter: (metrics) => metrics.knowledge.patternReuseRate.value,
|
|
183
|
+
higherBetter: true,
|
|
184
|
+
threshold: 0.5,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
metric: 'goldenPathAdherence',
|
|
188
|
+
getter: (metrics) => metrics.patterns.goldenPathAdherence.value,
|
|
189
|
+
higherBetter: true,
|
|
190
|
+
threshold: 0.7,
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
const comparisons = [];
|
|
194
|
+
const confidence = determineConfidence(orgEventCount, scopeEventCount);
|
|
195
|
+
for (const config of configs) {
|
|
196
|
+
const scopeValue = config.getter(scopeMetrics);
|
|
197
|
+
let baselineValue;
|
|
198
|
+
let baselineScope = context.scopeType === 'org' ? 'threshold' : 'org';
|
|
199
|
+
if (context.scopeType === 'org') {
|
|
200
|
+
baselineValue = config.threshold;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
baselineValue = config.getter(orgMetrics);
|
|
204
|
+
}
|
|
205
|
+
if (baselineValue !== undefined) {
|
|
206
|
+
comparisons.push({
|
|
207
|
+
metric: config.metric,
|
|
208
|
+
scopeValue,
|
|
209
|
+
baselineValue,
|
|
210
|
+
baselineScope,
|
|
211
|
+
direction: determineDirection(scopeValue, baselineValue, config.higherBetter),
|
|
212
|
+
confidence,
|
|
213
|
+
detail: buildComparisonDetail(context.scopeLabel, config.metric, scopeValue, baselineScope, baselineValue),
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (context.scopeType !== 'org' && config.threshold !== undefined) {
|
|
217
|
+
comparisons.push({
|
|
218
|
+
metric: config.metric,
|
|
219
|
+
scopeValue,
|
|
220
|
+
baselineValue: config.threshold,
|
|
221
|
+
baselineScope: 'threshold',
|
|
222
|
+
direction: determineDirection(scopeValue, config.threshold, config.higherBetter),
|
|
223
|
+
confidence,
|
|
224
|
+
detail: `${context.scopeLabel} ${formatPercent(scopeValue)} vs recommended threshold ${formatPercent(config.threshold)}.`,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return comparisons;
|
|
229
|
+
}
|
|
230
|
+
function buildScopeSummary(context, events, attribution, comparisons) {
|
|
231
|
+
const repoSet = new Set(events.map((event) => event.repo));
|
|
232
|
+
const teamSet = new Set(events
|
|
233
|
+
.map((event) => event.team)
|
|
234
|
+
.filter((team) => Boolean(team) && team !== 'unattributed'));
|
|
235
|
+
return {
|
|
236
|
+
scopeType: context.scopeType,
|
|
237
|
+
scopeId: context.scopeId,
|
|
238
|
+
scopeLabel: context.scopeLabel,
|
|
239
|
+
filters: context.filters,
|
|
240
|
+
eventCount: events.length,
|
|
241
|
+
repoCount: repoSet.size,
|
|
242
|
+
teamCount: teamSet.size,
|
|
243
|
+
attribution,
|
|
244
|
+
comparisons,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function buildSyntheticScenarioSummary(events) {
|
|
248
|
+
const syntheticEvents = events.filter((event) => event.isSynthetic);
|
|
249
|
+
if (syntheticEvents.length === 0)
|
|
250
|
+
return null;
|
|
251
|
+
const scenarioIds = Array.from(new Set(syntheticEvents
|
|
252
|
+
.map((event) => event.scenarioId)
|
|
253
|
+
.filter((id) => Boolean(id))));
|
|
254
|
+
return {
|
|
255
|
+
scenarioIds: scenarioIds.length > 0 ? scenarioIds : ['synthetic'],
|
|
256
|
+
syntheticEventCount: syntheticEvents.length,
|
|
257
|
+
totalEventCount: events.length,
|
|
258
|
+
ratio: events.length === 0 ? 0 : syntheticEvents.length / events.length,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function buildHotspotSummaries(events, context) {
|
|
262
|
+
return [
|
|
263
|
+
{
|
|
264
|
+
type: 'quality',
|
|
265
|
+
scopeType: context.scopeType,
|
|
266
|
+
scopeId: context.scopeId,
|
|
267
|
+
entries: computeQualityHotspots(events),
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
type: 'integrity',
|
|
271
|
+
scopeType: context.scopeType,
|
|
272
|
+
scopeId: context.scopeId,
|
|
273
|
+
entries: computeIntegrityHotspots(events),
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
type: 'knowledge',
|
|
277
|
+
scopeType: context.scopeType,
|
|
278
|
+
scopeId: context.scopeId,
|
|
279
|
+
entries: computeKnowledgePatterns(events),
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
type: 'shadow',
|
|
283
|
+
scopeType: context.scopeType,
|
|
284
|
+
scopeId: context.scopeId,
|
|
285
|
+
entries: computeShadowHotspots(events),
|
|
286
|
+
},
|
|
287
|
+
];
|
|
288
|
+
}
|
|
289
|
+
function buildAttributionStatus(events) {
|
|
290
|
+
const totalEvents = events.length;
|
|
291
|
+
const sources = {};
|
|
292
|
+
let attributedEvents = 0;
|
|
293
|
+
for (const event of events) {
|
|
294
|
+
sources[event.attributionSource] = (sources[event.attributionSource] ?? 0) + 1;
|
|
295
|
+
if (event.attributionSource !== 'fallback') {
|
|
296
|
+
attributedEvents += 1;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const quality = totalEvents === 0
|
|
300
|
+
? 'low'
|
|
301
|
+
: attributedEvents === totalEvents
|
|
302
|
+
? 'high'
|
|
303
|
+
: attributedEvents / totalEvents >= 0.75
|
|
304
|
+
? 'moderate'
|
|
305
|
+
: 'low';
|
|
306
|
+
return {
|
|
307
|
+
totalEvents,
|
|
308
|
+
attributedEvents,
|
|
309
|
+
unattributedEvents: totalEvents - attributedEvents,
|
|
310
|
+
sources,
|
|
311
|
+
quality,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function buildComparisonDetail(scopeLabel, metric, scopeValue, baselineScope, baselineValue) {
|
|
315
|
+
const baselineLabel = baselineScope === 'threshold' ? 'threshold' : baselineScope === 'org' ? 'org average' : baselineScope;
|
|
316
|
+
return `${scopeLabel} ${metric} ${formatPercent(scopeValue)} vs ${baselineLabel} ${formatPercent(baselineValue)}.`;
|
|
317
|
+
}
|
|
318
|
+
function determineDirection(scopeValue, baselineValue, higherBetter) {
|
|
319
|
+
const delta = scopeValue - baselineValue;
|
|
320
|
+
if (Math.abs(delta) < 0.005)
|
|
321
|
+
return 'flat';
|
|
322
|
+
const better = higherBetter ? delta > 0 : delta < 0;
|
|
323
|
+
return better ? 'above' : 'below';
|
|
324
|
+
}
|
|
325
|
+
function formatPercent(value) {
|
|
326
|
+
return `${Math.round(value * 100)}%`;
|
|
327
|
+
}
|
|
328
|
+
function determineConfidence(orgCount, scopeCount) {
|
|
329
|
+
if (orgCount < 20 || scopeCount < 5)
|
|
330
|
+
return 'low';
|
|
331
|
+
if (orgCount < 50)
|
|
332
|
+
return 'medium';
|
|
333
|
+
return 'high';
|
|
334
|
+
}
|
|
335
|
+
function buildBaseline(metrics, previous, value) {
|
|
336
|
+
const range = metrics.overview.trend.slice(-7);
|
|
337
|
+
const average = (values, fallback) => {
|
|
338
|
+
if (values.length === 0)
|
|
339
|
+
return fallback;
|
|
340
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
341
|
+
};
|
|
342
|
+
return {
|
|
343
|
+
qualityScore: average(range.map((point) => point.quality), metrics.quality.executionReliability.value),
|
|
344
|
+
integrityScore: average(range.map((point) => point.integrity), metrics.integrity.writeSafetySuccessRate.value),
|
|
345
|
+
knowledgeScore: average(range.map((point) => point.knowledge), 1 - metrics.knowledge.shadowKnowledgeIndex.value),
|
|
346
|
+
valueSavings: previous?.value.estimatedSavings ?? value.estimatedSavings,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function validateInsightFilters(filters) {
|
|
350
|
+
const view = filters.view ?? 'your-team';
|
|
351
|
+
if (view === 'what-this-becomes') {
|
|
352
|
+
if (!filters.syntheticOnly || !filters.scenarioId) {
|
|
353
|
+
throw new Error('Projected view requires scenario-driven synthetic events.');
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else if (filters.syntheticOnly) {
|
|
357
|
+
throw new Error('Your Team view cannot include synthetic events.');
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=job.js.map
|
package/dist/job.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.js","sourceRoot":"","sources":["../src/job.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TeamAttributionConfig } from '@codeledger/types';
|
|
2
|
+
export declare function loadOwnershipMap(repoRoot: string, config: TeamAttributionConfig): Record<string, string>;
|
|
3
|
+
export declare function matchOwnershipTeam(paths: string[], mapping: Record<string, string>): string | undefined;
|
|
4
|
+
//# sourceMappingURL=ownership.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownership.d.ts","sourceRoot":"","sources":["../src/ownership.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAkB/D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBxG;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAWvG"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
const OWNERSHIP_CACHE = new Map();
|
|
4
|
+
function expandEntries(entries) {
|
|
5
|
+
const map = {};
|
|
6
|
+
for (const [team, paths] of Object.entries(entries)) {
|
|
7
|
+
if (typeof paths === 'string') {
|
|
8
|
+
map[paths] = team;
|
|
9
|
+
}
|
|
10
|
+
else if (Array.isArray(paths)) {
|
|
11
|
+
for (const pathItem of paths) {
|
|
12
|
+
map[pathItem] = team;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return map;
|
|
17
|
+
}
|
|
18
|
+
export function loadOwnershipMap(repoRoot, config) {
|
|
19
|
+
const key = `${repoRoot}:${config?.ownership_file ?? ''}`;
|
|
20
|
+
if (OWNERSHIP_CACHE.has(key)) {
|
|
21
|
+
return OWNERSHIP_CACHE.get(key);
|
|
22
|
+
}
|
|
23
|
+
const filePath = config?.ownership_file
|
|
24
|
+
? join(repoRoot, config.ownership_file)
|
|
25
|
+
: join(repoRoot, '.codeledger', 'team-ownership.json');
|
|
26
|
+
const map = {};
|
|
27
|
+
if (existsSync(filePath)) {
|
|
28
|
+
try {
|
|
29
|
+
const raw = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
30
|
+
Object.assign(map, expandEntries(raw));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// ignore malformed ownership files
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
OWNERSHIP_CACHE.set(key, map);
|
|
37
|
+
return map;
|
|
38
|
+
}
|
|
39
|
+
export function matchOwnershipTeam(paths, mapping) {
|
|
40
|
+
if (!paths.length)
|
|
41
|
+
return undefined;
|
|
42
|
+
const prefixes = Object.keys(mapping).sort((a, b) => b.length - a.length);
|
|
43
|
+
for (const path of paths) {
|
|
44
|
+
for (const prefix of prefixes) {
|
|
45
|
+
if (path.startsWith(prefix)) {
|
|
46
|
+
return mapping[prefix];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownership.js","sourceRoot":"","sources":["../src/ownership.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkC,CAAC;AAElE,SAAS,aAAa,CAAC,OAA0C;IAC/D,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QACpB,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;gBAC7B,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,MAA6B;IAC9E,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,MAAM,EAAE,cAAc,IAAI,EAAE,EAAE,CAAC;IAC1D,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,eAAe,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;IACnC,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,EAAE,cAAc;QACrC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC;QACvC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;IACzD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAsC,CAAC;YAC7F,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;IACD,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAe,EAAE,OAA+B;IACjF,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,YAAY,EACZ,oBAAoB,EAErB,MAAM,mBAAmB,CAAC;AAE3B,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,oBAAoB,CAgDtG"}
|
package/dist/patterns.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export function computePatternSpread(events, generatedAt) {
|
|
2
|
+
const patternMap = new Map();
|
|
3
|
+
for (const event of events) {
|
|
4
|
+
if (event.type !== 'PATTERN_REUSE')
|
|
5
|
+
continue;
|
|
6
|
+
const entry = patternMap.get(event.pattern) ?? {
|
|
7
|
+
occurrences: 0,
|
|
8
|
+
reused: 0,
|
|
9
|
+
repos: new Set(),
|
|
10
|
+
teams: new Set(),
|
|
11
|
+
};
|
|
12
|
+
entry.occurrences += 1;
|
|
13
|
+
if (event.reused)
|
|
14
|
+
entry.reused += 1;
|
|
15
|
+
entry.repos.add(event.repo);
|
|
16
|
+
if (event.team && event.team !== 'unattributed') {
|
|
17
|
+
entry.teams.add(event.team);
|
|
18
|
+
}
|
|
19
|
+
patternMap.set(event.pattern, entry);
|
|
20
|
+
}
|
|
21
|
+
const crossRepoPatterns = Array.from(patternMap.entries())
|
|
22
|
+
.map(([pattern, entry]) => {
|
|
23
|
+
const reuseRate = entry.occurrences === 0 ? 0 : entry.reused / entry.occurrences;
|
|
24
|
+
const crossRepoReuseRate = entry.repos.size === 0 ? 0 : entry.reused / entry.repos.size;
|
|
25
|
+
return {
|
|
26
|
+
pattern,
|
|
27
|
+
occurrenceCount: entry.occurrences,
|
|
28
|
+
reusedCount: entry.reused,
|
|
29
|
+
reuseRate,
|
|
30
|
+
distinctRepos: entry.repos.size,
|
|
31
|
+
distinctTeams: entry.teams.size,
|
|
32
|
+
crossRepoReuseRate,
|
|
33
|
+
repos: Array.from(entry.repos),
|
|
34
|
+
teams: Array.from(entry.teams),
|
|
35
|
+
successLink: buildPatternSuccessLink(pattern, reuseRate, entry.occurrences),
|
|
36
|
+
};
|
|
37
|
+
})
|
|
38
|
+
.sort((a, b) => b.occurrenceCount - a.occurrenceCount)
|
|
39
|
+
.slice(0, 5);
|
|
40
|
+
return {
|
|
41
|
+
generatedAt,
|
|
42
|
+
totalPatterns: patternMap.size,
|
|
43
|
+
crossRepoPatterns,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function buildPatternSuccessLink(pattern, reuseRate, total) {
|
|
47
|
+
if (total === 0)
|
|
48
|
+
return undefined;
|
|
49
|
+
return {
|
|
50
|
+
metric: 'patternReuseRate',
|
|
51
|
+
value: reuseRate,
|
|
52
|
+
detail: `${pattern} was reused ${Math.round(reuseRate * 100)}% of the time over ${total} signal(s).`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,oBAAoB,CAAC,MAAsB,EAAE,WAAmB;IAC9E,MAAM,UAAU,GAAG,IAAI,GAAG,EAGvB,CAAC;IAEJ,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe;YAAE,SAAS;QAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI;YAC7C,WAAW,EAAE,CAAC;YACd,MAAM,EAAE,CAAC;YACT,KAAK,EAAE,IAAI,GAAG,EAAU;YACxB,KAAK,EAAE,IAAI,GAAG,EAAU;SACzB,CAAC;QACF,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC;QACvB,IAAI,KAAK,CAAC,MAAM;YAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QACpC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAChD,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;SACvD,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE;QACxB,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;QACjF,MAAM,kBAAkB,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;QACxF,OAAO;YACL,OAAO;YACP,eAAe,EAAE,KAAK,CAAC,WAAW;YAClC,WAAW,EAAE,KAAK,CAAC,MAAM;YACzB,SAAS;YACT,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;YAC/B,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;YAC/B,kBAAkB;YAClB,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAC9B,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAC9B,WAAW,EAAE,uBAAuB,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC;SACpD,CAAC;IAC5B,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,eAAe,CAAC;SACrD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEf,OAAO;QACL,WAAW;QACX,aAAa,EAAE,UAAU,CAAC,IAAI;QAC9B,iBAAiB;KAClB,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,OAAe,EAAE,SAAiB,EAAE,KAAa;IAChF,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClC,OAAO;QACL,MAAM,EAAE,kBAAkB;QAC1B,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,GAAG,OAAO,eAAe,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,sBAAsB,KAAK,aAAa;KACrG,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations.d.ts","sourceRoot":"","sources":["../src/recommendations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE/E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,qBAAqB,EAAE,CAoCvF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function computeRecommendations(metrics) {
|
|
2
|
+
const recommendations = [];
|
|
3
|
+
if (metrics.quality.reworkRatio.value > 0.35 && metrics.knowledge.patternReuseRate.value < 0.4) {
|
|
4
|
+
recommendations.push({
|
|
5
|
+
title: 'Clarify architecture seams',
|
|
6
|
+
description: 'High rework with low reuse suggests unstable boundaries or missing canonical implementation paths.',
|
|
7
|
+
severity: 'high',
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
if (metrics.integrity.integrityDrift.value > 0.25 || metrics.integrity.rejectRate.value > 0.1) {
|
|
11
|
+
recommendations.push({
|
|
12
|
+
title: 'Review abstraction boundaries',
|
|
13
|
+
description: 'Policy violations and rejected writes indicate interfaces are being crossed without durable guardrails.',
|
|
14
|
+
severity: 'high',
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
if (metrics.knowledge.shadowKnowledgeIndex.value > 0.45) {
|
|
18
|
+
recommendations.push({
|
|
19
|
+
title: 'Add documentation for hidden context',
|
|
20
|
+
description: 'Shadow knowledge signals imply critical implementation knowledge is still implicit and concentrated.',
|
|
21
|
+
severity: 'medium',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (metrics.patterns.goldenPathAdherence.value < 0.5) {
|
|
25
|
+
recommendations.push({
|
|
26
|
+
title: 'Harden the golden path',
|
|
27
|
+
description: 'Low adherence means teams are improvising around intended workflows instead of compounding on a stable path.',
|
|
28
|
+
severity: 'medium',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return recommendations;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=recommendations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations.js","sourceRoot":"","sources":["../src/recommendations.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,sBAAsB,CAAC,OAAuB;IAC5D,MAAM,eAAe,GAA4B,EAAE,CAAC;IAEpD,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,GAAG,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC;QAC/F,eAAe,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,4BAA4B;YACnC,WAAW,EAAE,oGAAoG;YACjH,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,GAAG,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC;QAC9F,eAAe,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,+BAA+B;YACtC,WAAW,EAAE,yGAAyG;YACtH,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,CAAC,oBAAoB,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC;QACxD,eAAe,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,sCAAsC;YAC7C,WAAW,EAAE,sGAAsG;YACnH,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC;QACrD,eAAe,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,wBAAwB;YAC/B,WAAW,EAAE,8GAA8G;YAC3H,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAEA,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,GAAG;IAAE,IAAI,IAAI,IAAI,CAAA;CAAE,CAiBrF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { runInsightAggregationJob } from './job.js';
|
|
2
|
+
export function startAggregationScheduler(options) {
|
|
3
|
+
const interval = Math.max(5, options.intervalSeconds ?? 30) * 1000;
|
|
4
|
+
const timer = setInterval(async () => {
|
|
5
|
+
try {
|
|
6
|
+
await runInsightAggregationJob({ cwd: options.cwd });
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
// swallow errors to keep scheduler alive
|
|
10
|
+
}
|
|
11
|
+
}, interval);
|
|
12
|
+
void runInsightAggregationJob({ cwd: options.cwd });
|
|
13
|
+
return {
|
|
14
|
+
stop() {
|
|
15
|
+
clearInterval(timer);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAOpD,MAAM,UAAU,yBAAyB,CAAC,OAAyB;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACnE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,wBAAwB,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,yCAAyC;QAC3C,CAAC;IACH,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEb,KAAK,wBAAwB,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAEpD,OAAO;QACL,IAAI;YACF,aAAa,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { InsightEvent, InsightSnapshot } from '@codeledger/types';
|
|
2
|
+
export declare function persistEvent(repoRoot: string, event: InsightEvent): void;
|
|
3
|
+
export declare function readEvents(repoRoot: string): InsightEvent[];
|
|
4
|
+
export declare function persistSnapshot(repoRoot: string, snapshot: InsightSnapshot): void;
|
|
5
|
+
export declare function readLatestSnapshot(repoRoot: string): InsightSnapshot | null;
|
|
6
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAiDvE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAkBxE;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAoB3D;AAgBD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAoBjF;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAoB3E"}
|