@hiveai/core 0.20.1 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +58 -1
- package/dist/index.js +73 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -593,6 +593,19 @@ interface PreventionEvent {
|
|
|
593
593
|
declare function preventionLogPath(paths: HaivePaths): string;
|
|
594
594
|
/** Append one catch to the log. Best-effort, creates the dir on demand. */
|
|
595
595
|
declare function appendPreventionEvent(paths: HaivePaths, event: PreventionEvent): Promise<void>;
|
|
596
|
+
/**
|
|
597
|
+
* THE single recorder for "a documented lesson intercepted a real mistake". Every gate path —
|
|
598
|
+
* the installed git-hook gate (`enforce check`), the standalone `haive sensors check`, and the
|
|
599
|
+
* `anti_patterns_check` MCP tool — funnels its fired memory ids through here so prevention is
|
|
600
|
+
* recorded once and identically, not bolted onto each entry point (it used to leak: the git-hook
|
|
601
|
+
* gate blocked but never recorded — see the harness-positioning gotcha).
|
|
602
|
+
*
|
|
603
|
+
* Bumps `prevented_count` in usage.json (debounced per memory via {@link recordPrevention}) AND
|
|
604
|
+
* appends one timestamped event per NEW catch to the prevention log. Best-effort: a telemetry
|
|
605
|
+
* write must never break a commit, so failures are swallowed. Returns the ids actually recorded
|
|
606
|
+
* (i.e. not debounced), so callers can report "caught for you" without re-counting.
|
|
607
|
+
*/
|
|
608
|
+
declare function recordPreventionHits(paths: HaivePaths, firedIds: string[], source: PreventionSource, now?: Date): Promise<string[]>;
|
|
596
609
|
/** Read all catch events (skips malformed lines). */
|
|
597
610
|
declare function loadPreventionEvents(paths: HaivePaths): Promise<PreventionEvent[]>;
|
|
598
611
|
interface PreventionTrend {
|
|
@@ -1217,6 +1230,13 @@ interface HaiveConfig {
|
|
|
1217
1230
|
* Default: "anchored" — makes "known bad approaches are blocked" true for the precise case.
|
|
1218
1231
|
*/
|
|
1219
1232
|
antiPatternGate?: "off" | "review" | "anchored" | "strict";
|
|
1233
|
+
/**
|
|
1234
|
+
* Pre-commit/pre-push decision-coverage behaviour. When true (default), the gate SURFACES the
|
|
1235
|
+
* relevant anchored decisions/policies itself and records them in the session marker at commit
|
|
1236
|
+
* time — no separate `haive briefing` step required. Set false for the strict legacy behaviour
|
|
1237
|
+
* where the commit is blocked until a prior briefing covered those decisions.
|
|
1238
|
+
*/
|
|
1239
|
+
autoBrief?: boolean;
|
|
1220
1240
|
/**
|
|
1221
1241
|
* Execute `kind: "shell" | "test"` memory sensors during `haive sensors check`.
|
|
1222
1242
|
* These run arbitrary repo-authored commands, so they are OFF by default; turn on per repo
|
|
@@ -2014,14 +2034,20 @@ declare function findUncapturedFailures(failures: FailureObservation[], captureT
|
|
|
2014
2034
|
* Pure: the caller supplies hot files (from git history / briefing-radar) and the loaded corpus.
|
|
2015
2035
|
*/
|
|
2016
2036
|
|
|
2037
|
+
/** Where a file's "heat" came from: committed git churn, agent edits this/recent sessions, or both. */
|
|
2038
|
+
type HotFileSource = "git" | "agent" | "both";
|
|
2017
2039
|
interface HotFile {
|
|
2018
2040
|
path: string;
|
|
2019
2041
|
/** Number of times the file changed in the lookback window (the "heat"). */
|
|
2020
2042
|
changes: number;
|
|
2043
|
+
/** Provenance of the heat. Optional for back-compat with git-only callers. */
|
|
2044
|
+
source?: HotFileSource;
|
|
2021
2045
|
}
|
|
2022
2046
|
interface CoverageGap {
|
|
2023
2047
|
path: string;
|
|
2024
2048
|
changes: number;
|
|
2049
|
+
/** Provenance of the heat that made this file a blind spot. */
|
|
2050
|
+
source?: HotFileSource;
|
|
2025
2051
|
}
|
|
2026
2052
|
interface CoverageOptions {
|
|
2027
2053
|
/** Only flag files with at least this many changes. Default 3. */
|
|
@@ -2043,6 +2069,17 @@ declare function isCovered(file: string, coverage: Set<string>): boolean;
|
|
|
2043
2069
|
* Highest heat first. These are the highest-value places to add a memory or sensor.
|
|
2044
2070
|
*/
|
|
2045
2071
|
declare function findCoverageGaps(hotFiles: HotFile[], memories: LoadedMemory[], options?: CoverageOptions): CoverageGap[];
|
|
2072
|
+
/**
|
|
2073
|
+
* Tally a flat list of edited file paths into HotFiles — the agent-edit heat signal from the
|
|
2074
|
+
* PostToolUse observation log (files agents actually touch), complementary to committed git churn.
|
|
2075
|
+
* Pure: the caller reads/normalizes the observation paths.
|
|
2076
|
+
*/
|
|
2077
|
+
declare function tallyHotFiles(paths: string[], source?: HotFileSource): HotFile[];
|
|
2078
|
+
/**
|
|
2079
|
+
* Merge two HotFile lists, summing heat per path. A file hot in both lists is tagged `both` so the
|
|
2080
|
+
* report can show that agents AND git churn both point at the same uncovered file (the strongest gap).
|
|
2081
|
+
*/
|
|
2082
|
+
declare function mergeHotFiles(a: HotFile[], b: HotFile[]): HotFile[];
|
|
2046
2083
|
|
|
2047
2084
|
interface EvalHistoryEntry {
|
|
2048
2085
|
/** ISO timestamp of the eval run. */
|
|
@@ -2107,6 +2144,26 @@ interface ConflictResolution {
|
|
|
2107
2144
|
}
|
|
2108
2145
|
/** Compare two memories; returns the one that should WIN plus the reason. Pure. */
|
|
2109
2146
|
declare function planConflictResolution(a: LoadedMemory, b: LoadedMemory): ConflictResolution;
|
|
2147
|
+
interface AppliedConflictResolution {
|
|
2148
|
+
/** Updated frontmatter for the memory to keep (promoted). */
|
|
2149
|
+
winner: MemoryFrontmatter;
|
|
2150
|
+
/** Updated frontmatter for the memory to supersede (deprecated). */
|
|
2151
|
+
loser: MemoryFrontmatter;
|
|
2152
|
+
/** Topic the winner now carries — the consolidation target for future `mem_save` upserts. Null when neither carried one. */
|
|
2153
|
+
topic: string | null;
|
|
2154
|
+
/** True when the winner adopted the loser's topic because it had none. */
|
|
2155
|
+
topic_adopted: boolean;
|
|
2156
|
+
}
|
|
2157
|
+
/**
|
|
2158
|
+
* Turn a {@link ConflictResolution} plan into the two concrete frontmatter updates — the guided
|
|
2159
|
+
* supersede the backlog called for, wired into topic-upsert/revision_count:
|
|
2160
|
+
* - loser → deprecated, stamped with stale_reason + a related_ids link to the winner.
|
|
2161
|
+
* - winner → revision_count++ (it absorbed a contradiction), verified now, linked to the loser,
|
|
2162
|
+
* and it ADOPTS the loser's topic when it had none — so the next `mem_save` on this subject
|
|
2163
|
+
* upserts into the winner instead of spawning a third conflicting memory. An existing winner
|
|
2164
|
+
* topic is never overwritten. Pure: the caller persists both.
|
|
2165
|
+
*/
|
|
2166
|
+
declare function applyConflictResolution(winner: LoadedMemory, loser: LoadedMemory, plan: ConflictResolution, now?: Date): AppliedConflictResolution;
|
|
2110
2167
|
|
|
2111
2168
|
/**
|
|
2112
2169
|
* Cold-start seeding from git history — the harness has value only once the corpus is populated,
|
|
@@ -2336,4 +2393,4 @@ declare function prepareBridgeData(memories: Memory[], sensors: BridgeSensor[],
|
|
|
2336
2393
|
*/
|
|
2337
2394
|
declare function generateBridges(memories: Memory[], sensors: BridgeSensor[], opts?: GenerateBridgesOptions): BridgeFileOutput[];
|
|
2338
2395
|
|
|
2339
|
-
export { AUTOPILOT_DEFAULTS, type Activation, type ActivationContext, ActivationSchema, type Anchor, AnchorSchema, type AntiPatternGate, type AutoPromoteRule, BRIDGE_MARKERS, BRIDGE_TARGETS, BRIDGE_TARGET_PATH, BRIEFING_MARKER_TTL_MS, BRIEFING_PRESET_DEFAULTS, type BreakingChange, type BridgeFileOutput, type BridgeMemoryEntry, type BridgeSensor, type BridgeTarget, type BriefingBudgetNumbers, type BriefingBudgetPreset, type BriefingMarker, type BriefingProofLineOptions, type BudgetPart, type BudgetSlice, type BuildCodeMapOptions, CHARS_PER_TOKEN, CODE_MAP_FILE, CODE_STOPWORDS, CONFIG_FILE, type CaughtForYouOptions, type CaughtForYouRow, type CaughtForYouSummary, type CodeExport, type CodeExportKind, type CodeFileEntry, type CodeMap, type CodeMapQueryOptions, type CollectTimelineOpts, type CommandSensorSpec, type ConfidenceLevel, type ConfidenceThresholds, type ConflictCandidatePair, type ConflictCandidatesOpts, type ConflictResolution, type ContractDiffResult, type ContractFile, type ContractSnapshot, type CoverageGap, type CoverageOptions, CrossRepoProvenanceSchema, type CrossRepoReport, type CrossRepoSource, DECAY_DAYS, DEFAULT_AUTO_PROMOTE_RULE, DEFAULT_CONFIDENCE_THRESHOLDS, DEFAULT_CONFIG, DEFAULT_DORMANT_DAYS, DEFAULT_PRIORITY_SIGNALS, type DashboardOptions, type DashboardReport, type DepChange, type DepTrackResult, type DependencySnapshot, type DetectStacksInput, type DetectableStack, type DocFrequency, type DormantRow, type DraftOptions, type DraftsOptions, ENV_WORKAROUND_TAGS, type EvalDelta, type EvalHistoryEntry, type EvalReport, type EvalSpec, type EvalTrend, type FailureCoverageOptions, type FailureObservation, type FeedbackAdjustment, type FeedbackAdjustmentAction, type FeedbackAdjustmentOptions, type Finding, type FindingFormat, type FindingSeverity, GUESSABLE_THRESHOLD, type GatePrecision, type GatePrecisionDelta, type GatePrecisionMetricDelta, type GateTuningSuggestion, type GenerateBridgesOptions, type GitCommit, HAIVE_DIR, type HaiveConfig, type HaivePaths, type HotFile, type ImpactOptions, type ImpactRow, type ImpactScore, type ImpactSummary, type ImpactTier, type LexicalRankResult, type LoadedMemory, MEMORIES_DIR, MIN_WORD_LEN, type Memory, type MemoryDraft, type MemoryFrontmatter, MemoryFrontmatterSchema, type MemoryPriority, type MemoryScope, MemoryScopeSchema, type MemoryStatus, MemoryStatusSchema, type MemoryType, MemoryTypeSchema, type MemoryUsage, type MergeResult, type MetricDelta, PREVENTION_DEBOUNCE_MS, PROJECT_CONTEXT_FILE, PROJECT_CONTEXT_THROTTLE_MS, type PreventionEvent, type PreventionRow, type PreventionSource, type PreventionTrend, type PrioritySignals, RUNTIME_JOURNAL_FILENAME, type RecurrenceReport, type RecurrenceRow, type ResolveProjectInfo, type RetirementSignal, type RetrievalAggregate, type RetrievalCase, type RetrievalCaseResult, type RuntimeJournalEntry, SESSION_RECAP_TTL_MS, STACK_PACK_TAG, type SeedProposal, type SelfEvalOptions, type Sensor, type SensorAggregate, type SensorCase, type SensorCaseResult, type SensorHit, type SensorRow, SensorSchema, type SensorSuggestionOptions, type SensorTarget, type SkillActivation, type TimelineEntry, type TopicStatusPair, type TruncateOptions, type TruncateResult, USAGE_FILE, USAGE_LOG_DIR, USAGE_LOG_FILE, type UncapturedFailure, type UsageAggregate, type UsageEvent, type UsageIndex, type VerifyOptions, type VerifyResult, addedLinesFromDiff, aggregateRetrieval, aggregateSensors, aggregateUsage, allocateBudget, antiPatternGateParams, appendEvalHistory, appendPreventionEvent, appendRuntimeJournalEntry, appendUsageEvent, applyFeedbackAdjustment, bridgeMemorySummary, briefingMarkerPath, briefingMarkersDir, briefingProofLine, buildCodeMap, buildCoverageIndex, buildDashboard, buildDocFrequency, buildFrontmatter, buildReport, bumpRead, classifyMemoryPriority, codeMapPath, collectTimelineEntries, compactAutoRecapBody, compareEvalReports, compareGatePrecision, compareImpact, compileRegexSensor, computeEvalTrend, computeGatePrecision, computeImpact, computePreventionTrend, computeRecurrence, configPath, contractLockPath, deriveConfidence, detectStacksFromManifests, diffContract, diffHasDistinctiveOverlap, distinctiveCap, draftsFromFindings, emptyUsage, emptyUsageIndex, enforcementDir, estimateTokens, evalHistoryPath, evaluateSkillActivation, extractActionsBriefBody, extractSnippet, filterNewDrafts, findCoverageGaps, findLexicalConflictPairs, findProjectRoot, findTopicStatusConflictPairs, findUncapturedFailures, findingBody, findingToDraft, firstMemoryOneLine, generateBridges, getUsage, globToRegExp, hasRecentBriefingMarker, hashProjectContext, inferModulesFromPaths, isAutoPromoteEligible, isAutoRecap, isCovered, isDecaying, isDistinctiveToken, isEnvWorkaroundMemory, isFreshIsoDate, isGlobPath, isLikelyGuessable, isRetiredMemory, isSkill, isSkillSuppressed, isStackPackSeed, listMarkdownFilesRecursive, literalMatchesAllTokens, literalMatchesAnyToken, loadCodeMap, loadConfig, loadConfigSync, loadEvalHistory, loadMemoriesFromDir, loadMemory, loadPreventionEvents, loadUsageIndex, looksLikeGenericAdvice, memoryFilePath, memoryMatchesAnchorPaths, mergeMemoryVersions, newMemoryId, normalizeFindingSeverity, normalizeSessionId, overallScore, parseEslintJson, parseFindings, parseMemory, parseNpmAudit, parseSarif, parseSince, parseSonar, pathsOverlap, pickSnippetNeedle, planConflictResolution, prepareBridgeData, preventionLogPath, priorityRank, prioritySignals, projectContextRecentlyEmitted, proposeSeedsFromCommits, pullCrossRepoSources, queryCodeMap, rankMemoriesLexical, readRecentBriefingMarker, readRuntimeJournalTail, readUsageEvents, recommendFeedbackAdjustment, recordApplied, recordPrevention, recordProjectContextEmission, recordRejection, relPathFrom, renderCaughtForYou, resolveBriefingBudget, resolveHaivePaths, resolveManifestFiles, resolveProjectInfo, retirementSignal, runRegexSensor, runSensors, runtimeJournalPath, saveCodeMap, saveConfig, saveUsageIndex, scoreRetrievalCase, scoreSensorCase, selectCommandSensors, sensorAppliesToPath, sensorTargetsFromDiff, serializeMemory, snapshotContract, specificityScore, stripPrivate, suggestGate, suggestSensorFromMemory, suggestTopicKey, summarizeCaughtForYou, summarizeImpact, synthesizeSelfEvalCases, titleFromBody, tokenizeQuery, tokenizeWords, trackDependencies, trackReads, truncateToTokens, usageLogPath, usageLogSize, usagePath, verifyAnchor, watchContracts, writeBriefingMarker };
|
|
2396
|
+
export { AUTOPILOT_DEFAULTS, type Activation, type ActivationContext, ActivationSchema, type Anchor, AnchorSchema, type AntiPatternGate, type AppliedConflictResolution, type AutoPromoteRule, BRIDGE_MARKERS, BRIDGE_TARGETS, BRIDGE_TARGET_PATH, BRIEFING_MARKER_TTL_MS, BRIEFING_PRESET_DEFAULTS, type BreakingChange, type BridgeFileOutput, type BridgeMemoryEntry, type BridgeSensor, type BridgeTarget, type BriefingBudgetNumbers, type BriefingBudgetPreset, type BriefingMarker, type BriefingProofLineOptions, type BudgetPart, type BudgetSlice, type BuildCodeMapOptions, CHARS_PER_TOKEN, CODE_MAP_FILE, CODE_STOPWORDS, CONFIG_FILE, type CaughtForYouOptions, type CaughtForYouRow, type CaughtForYouSummary, type CodeExport, type CodeExportKind, type CodeFileEntry, type CodeMap, type CodeMapQueryOptions, type CollectTimelineOpts, type CommandSensorSpec, type ConfidenceLevel, type ConfidenceThresholds, type ConflictCandidatePair, type ConflictCandidatesOpts, type ConflictResolution, type ContractDiffResult, type ContractFile, type ContractSnapshot, type CoverageGap, type CoverageOptions, CrossRepoProvenanceSchema, type CrossRepoReport, type CrossRepoSource, DECAY_DAYS, DEFAULT_AUTO_PROMOTE_RULE, DEFAULT_CONFIDENCE_THRESHOLDS, DEFAULT_CONFIG, DEFAULT_DORMANT_DAYS, DEFAULT_PRIORITY_SIGNALS, type DashboardOptions, type DashboardReport, type DepChange, type DepTrackResult, type DependencySnapshot, type DetectStacksInput, type DetectableStack, type DocFrequency, type DormantRow, type DraftOptions, type DraftsOptions, ENV_WORKAROUND_TAGS, type EvalDelta, type EvalHistoryEntry, type EvalReport, type EvalSpec, type EvalTrend, type FailureCoverageOptions, type FailureObservation, type FeedbackAdjustment, type FeedbackAdjustmentAction, type FeedbackAdjustmentOptions, type Finding, type FindingFormat, type FindingSeverity, GUESSABLE_THRESHOLD, type GatePrecision, type GatePrecisionDelta, type GatePrecisionMetricDelta, type GateTuningSuggestion, type GenerateBridgesOptions, type GitCommit, HAIVE_DIR, type HaiveConfig, type HaivePaths, type HotFile, type HotFileSource, type ImpactOptions, type ImpactRow, type ImpactScore, type ImpactSummary, type ImpactTier, type LexicalRankResult, type LoadedMemory, MEMORIES_DIR, MIN_WORD_LEN, type Memory, type MemoryDraft, type MemoryFrontmatter, MemoryFrontmatterSchema, type MemoryPriority, type MemoryScope, MemoryScopeSchema, type MemoryStatus, MemoryStatusSchema, type MemoryType, MemoryTypeSchema, type MemoryUsage, type MergeResult, type MetricDelta, PREVENTION_DEBOUNCE_MS, PROJECT_CONTEXT_FILE, PROJECT_CONTEXT_THROTTLE_MS, type PreventionEvent, type PreventionRow, type PreventionSource, type PreventionTrend, type PrioritySignals, RUNTIME_JOURNAL_FILENAME, type RecurrenceReport, type RecurrenceRow, type ResolveProjectInfo, type RetirementSignal, type RetrievalAggregate, type RetrievalCase, type RetrievalCaseResult, type RuntimeJournalEntry, SESSION_RECAP_TTL_MS, STACK_PACK_TAG, type SeedProposal, type SelfEvalOptions, type Sensor, type SensorAggregate, type SensorCase, type SensorCaseResult, type SensorHit, type SensorRow, SensorSchema, type SensorSuggestionOptions, type SensorTarget, type SkillActivation, type TimelineEntry, type TopicStatusPair, type TruncateOptions, type TruncateResult, USAGE_FILE, USAGE_LOG_DIR, USAGE_LOG_FILE, type UncapturedFailure, type UsageAggregate, type UsageEvent, type UsageIndex, type VerifyOptions, type VerifyResult, addedLinesFromDiff, aggregateRetrieval, aggregateSensors, aggregateUsage, allocateBudget, antiPatternGateParams, appendEvalHistory, appendPreventionEvent, appendRuntimeJournalEntry, appendUsageEvent, applyConflictResolution, applyFeedbackAdjustment, bridgeMemorySummary, briefingMarkerPath, briefingMarkersDir, briefingProofLine, buildCodeMap, buildCoverageIndex, buildDashboard, buildDocFrequency, buildFrontmatter, buildReport, bumpRead, classifyMemoryPriority, codeMapPath, collectTimelineEntries, compactAutoRecapBody, compareEvalReports, compareGatePrecision, compareImpact, compileRegexSensor, computeEvalTrend, computeGatePrecision, computeImpact, computePreventionTrend, computeRecurrence, configPath, contractLockPath, deriveConfidence, detectStacksFromManifests, diffContract, diffHasDistinctiveOverlap, distinctiveCap, draftsFromFindings, emptyUsage, emptyUsageIndex, enforcementDir, estimateTokens, evalHistoryPath, evaluateSkillActivation, extractActionsBriefBody, extractSnippet, filterNewDrafts, findCoverageGaps, findLexicalConflictPairs, findProjectRoot, findTopicStatusConflictPairs, findUncapturedFailures, findingBody, findingToDraft, firstMemoryOneLine, generateBridges, getUsage, globToRegExp, hasRecentBriefingMarker, hashProjectContext, inferModulesFromPaths, isAutoPromoteEligible, isAutoRecap, isCovered, isDecaying, isDistinctiveToken, isEnvWorkaroundMemory, isFreshIsoDate, isGlobPath, isLikelyGuessable, isRetiredMemory, isSkill, isSkillSuppressed, isStackPackSeed, listMarkdownFilesRecursive, literalMatchesAllTokens, literalMatchesAnyToken, loadCodeMap, loadConfig, loadConfigSync, loadEvalHistory, loadMemoriesFromDir, loadMemory, loadPreventionEvents, loadUsageIndex, looksLikeGenericAdvice, memoryFilePath, memoryMatchesAnchorPaths, mergeHotFiles, mergeMemoryVersions, newMemoryId, normalizeFindingSeverity, normalizeSessionId, overallScore, parseEslintJson, parseFindings, parseMemory, parseNpmAudit, parseSarif, parseSince, parseSonar, pathsOverlap, pickSnippetNeedle, planConflictResolution, prepareBridgeData, preventionLogPath, priorityRank, prioritySignals, projectContextRecentlyEmitted, proposeSeedsFromCommits, pullCrossRepoSources, queryCodeMap, rankMemoriesLexical, readRecentBriefingMarker, readRuntimeJournalTail, readUsageEvents, recommendFeedbackAdjustment, recordApplied, recordPrevention, recordPreventionHits, recordProjectContextEmission, recordRejection, relPathFrom, renderCaughtForYou, resolveBriefingBudget, resolveHaivePaths, resolveManifestFiles, resolveProjectInfo, retirementSignal, runRegexSensor, runSensors, runtimeJournalPath, saveCodeMap, saveConfig, saveUsageIndex, scoreRetrievalCase, scoreSensorCase, selectCommandSensors, sensorAppliesToPath, sensorTargetsFromDiff, serializeMemory, snapshotContract, specificityScore, stripPrivate, suggestGate, suggestSensorFromMemory, suggestTopicKey, summarizeCaughtForYou, summarizeImpact, synthesizeSelfEvalCases, tallyHotFiles, titleFromBody, tokenizeQuery, tokenizeWords, trackDependencies, trackReads, truncateToTokens, usageLogPath, usageLogSize, usagePath, verifyAnchor, watchContracts, writeBriefingMarker };
|
package/dist/index.js
CHANGED
|
@@ -852,6 +852,25 @@ async function appendPreventionEvent(paths, event) {
|
|
|
852
852
|
await mkdir2(path6.dirname(file), { recursive: true });
|
|
853
853
|
await appendFile(file, JSON.stringify(event) + "\n", "utf8");
|
|
854
854
|
}
|
|
855
|
+
async function recordPreventionHits(paths, firedIds, source, now = /* @__PURE__ */ new Date()) {
|
|
856
|
+
const unique = [...new Set(firedIds)].filter(Boolean);
|
|
857
|
+
if (unique.length === 0) return [];
|
|
858
|
+
const usage = await loadUsageIndex(paths).catch(() => null);
|
|
859
|
+
if (!usage) return [];
|
|
860
|
+
const recordedIds = [];
|
|
861
|
+
for (const id of unique) {
|
|
862
|
+
if (recordPrevention(usage, id, now.getTime())) recordedIds.push(id);
|
|
863
|
+
}
|
|
864
|
+
if (recordedIds.length === 0) return [];
|
|
865
|
+
await saveUsageIndex(paths, usage).catch(() => {
|
|
866
|
+
});
|
|
867
|
+
const at = now.toISOString();
|
|
868
|
+
for (const id of recordedIds) {
|
|
869
|
+
await appendPreventionEvent(paths, { at, id, source }).catch(() => {
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
return recordedIds;
|
|
873
|
+
}
|
|
855
874
|
async function loadPreventionEvents(paths) {
|
|
856
875
|
const file = preventionLogPath(paths);
|
|
857
876
|
if (!existsSync4(file)) return [];
|
|
@@ -3906,11 +3925,36 @@ function findCoverageGaps(hotFiles, memories, options = {}) {
|
|
|
3906
3925
|
for (const hot of hotFiles) {
|
|
3907
3926
|
if (hot.changes < minChanges) continue;
|
|
3908
3927
|
if (isCovered(hot.path, coverage)) continue;
|
|
3909
|
-
gaps.push({ path: normalizePath(hot.path), changes: hot.changes });
|
|
3928
|
+
gaps.push({ path: normalizePath(hot.path), changes: hot.changes, ...hot.source ? { source: hot.source } : {} });
|
|
3910
3929
|
}
|
|
3911
3930
|
gaps.sort((a, b) => b.changes - a.changes);
|
|
3912
3931
|
return gaps.slice(0, limit);
|
|
3913
3932
|
}
|
|
3933
|
+
function tallyHotFiles(paths, source = "agent") {
|
|
3934
|
+
const counts = /* @__PURE__ */ new Map();
|
|
3935
|
+
for (const raw of paths) {
|
|
3936
|
+
const norm = normalizePath(raw);
|
|
3937
|
+
if (!norm) continue;
|
|
3938
|
+
counts.set(norm, (counts.get(norm) ?? 0) + 1);
|
|
3939
|
+
}
|
|
3940
|
+
return [...counts.entries()].map(([path18, changes]) => ({ path: path18, changes, source })).sort((a, b) => b.changes - a.changes);
|
|
3941
|
+
}
|
|
3942
|
+
function mergeHotFiles(a, b) {
|
|
3943
|
+
const merged = /* @__PURE__ */ new Map();
|
|
3944
|
+
for (const hot of [...a, ...b]) {
|
|
3945
|
+
const norm = normalizePath(hot.path);
|
|
3946
|
+
if (!norm) continue;
|
|
3947
|
+
const existing = merged.get(norm);
|
|
3948
|
+
if (!existing) {
|
|
3949
|
+
merged.set(norm, { path: norm, changes: hot.changes, ...hot.source ? { source: hot.source } : {} });
|
|
3950
|
+
continue;
|
|
3951
|
+
}
|
|
3952
|
+
existing.changes += hot.changes;
|
|
3953
|
+
if (hot.source && existing.source && hot.source !== existing.source) existing.source = "both";
|
|
3954
|
+
else existing.source = existing.source ?? hot.source;
|
|
3955
|
+
}
|
|
3956
|
+
return [...merged.values()].sort((x, y) => y.changes - x.changes);
|
|
3957
|
+
}
|
|
3914
3958
|
|
|
3915
3959
|
// src/eval-history.ts
|
|
3916
3960
|
import { appendFile as appendFile4, mkdir as mkdir11, readFile as readFile14 } from "fs/promises";
|
|
@@ -3998,6 +4042,30 @@ function planConflictResolution(a, b) {
|
|
|
3998
4042
|
stale_reason: `Superseded by ${keepId} (conflict resolved on ${reason}).`
|
|
3999
4043
|
};
|
|
4000
4044
|
}
|
|
4045
|
+
function applyConflictResolution(winner, loser, plan, now = /* @__PURE__ */ new Date()) {
|
|
4046
|
+
const ts = now.toISOString();
|
|
4047
|
+
const wf = winner.memory.frontmatter;
|
|
4048
|
+
const lf = loser.memory.frontmatter;
|
|
4049
|
+
const winnerHasTopic = Boolean(wf.topic && wf.topic.trim() !== "");
|
|
4050
|
+
const loserHasTopic = Boolean(lf.topic && lf.topic.trim() !== "");
|
|
4051
|
+
const topicAdopted = !winnerHasTopic && loserHasTopic;
|
|
4052
|
+
const topic = winnerHasTopic ? wf.topic : topicAdopted ? lf.topic : null;
|
|
4053
|
+
const winnerFm = {
|
|
4054
|
+
...wf,
|
|
4055
|
+
revision_count: wf.revision_count + 1,
|
|
4056
|
+
verified_at: ts,
|
|
4057
|
+
related_ids: [.../* @__PURE__ */ new Set([...wf.related_ids, plan.supersede_id])],
|
|
4058
|
+
...topic ? { topic } : {}
|
|
4059
|
+
};
|
|
4060
|
+
const loserFm = {
|
|
4061
|
+
...lf,
|
|
4062
|
+
status: "deprecated",
|
|
4063
|
+
stale_reason: plan.stale_reason,
|
|
4064
|
+
verified_at: ts,
|
|
4065
|
+
related_ids: [.../* @__PURE__ */ new Set([...lf.related_ids, plan.keep_id])]
|
|
4066
|
+
};
|
|
4067
|
+
return { winner: winnerFm, loser: loserFm, topic, topic_adopted: topicAdopted };
|
|
4068
|
+
}
|
|
4001
4069
|
|
|
4002
4070
|
// src/seed-git.ts
|
|
4003
4071
|
var REVERT_RE = /^Revert\s+"(.+)"\s*$/i;
|
|
@@ -4383,6 +4451,7 @@ export {
|
|
|
4383
4451
|
appendPreventionEvent,
|
|
4384
4452
|
appendRuntimeJournalEntry,
|
|
4385
4453
|
appendUsageEvent,
|
|
4454
|
+
applyConflictResolution,
|
|
4386
4455
|
applyFeedbackAdjustment,
|
|
4387
4456
|
bridgeMemorySummary,
|
|
4388
4457
|
briefingMarkerPath,
|
|
@@ -4466,6 +4535,7 @@ export {
|
|
|
4466
4535
|
looksLikeGenericAdvice,
|
|
4467
4536
|
memoryFilePath,
|
|
4468
4537
|
memoryMatchesAnchorPaths,
|
|
4538
|
+
mergeHotFiles,
|
|
4469
4539
|
mergeMemoryVersions,
|
|
4470
4540
|
newMemoryId,
|
|
4471
4541
|
normalizeFindingSeverity,
|
|
@@ -4496,6 +4566,7 @@ export {
|
|
|
4496
4566
|
recommendFeedbackAdjustment,
|
|
4497
4567
|
recordApplied,
|
|
4498
4568
|
recordPrevention,
|
|
4569
|
+
recordPreventionHits,
|
|
4499
4570
|
recordProjectContextEmission,
|
|
4500
4571
|
recordRejection,
|
|
4501
4572
|
relPathFrom,
|
|
@@ -4526,6 +4597,7 @@ export {
|
|
|
4526
4597
|
summarizeCaughtForYou,
|
|
4527
4598
|
summarizeImpact,
|
|
4528
4599
|
synthesizeSelfEvalCases,
|
|
4600
|
+
tallyHotFiles,
|
|
4529
4601
|
titleFromBody,
|
|
4530
4602
|
tokenizeQuery,
|
|
4531
4603
|
tokenizeWords,
|