Phase 7: add planReinject — kept-window and registration filter for post-compaction skills.

Computes which tracked skills need re-inject after compaction by slicing the kept branch and excluding skills still present in kept user messages or unregistered on disk.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-17 11:54:01 +07:00
parent ab315d899b
commit 23d580b6d2
+39
View File
@@ -0,0 +1,39 @@
import type {
ExtensionContext,
SessionCompactEvent,
Skill,
} from "@earendil-works/pi-coding-agent";
import {
filterSkillsNeedingReinject,
getKeptEntries,
skillsPresentInKeptWindow,
} from "./kept.js";
import type { SkillReinjectSettings } from "./settings.js";
import type { ExtensionState } from "./state.js";
/** Names still registered in resourceLoader (SPEC §5.2). */
export function registeredSkillNames(skills: readonly Pick<Skill, "name">[]): ReadonlySet<string> {
return new Set(skills.map((skill) => skill.name));
}
/**
* Skill names to re-inject after compaction: tracked, absent from kept window, still registered (SPEC §5.2).
* `registeredSkills` comes from resourceLoader — ExtensionContext has no getSkills(); wired in index.ts.
*/
export function planReinject(
state: ExtensionState,
_settings: SkillReinjectSettings,
ctx: ExtensionContext,
compactionEvent: SessionCompactEvent,
registeredSkills: readonly Pick<Skill, "name">[],
): string[] {
const branch = ctx.sessionManager.getBranch();
const keptEntries = getKeptEntries(branch, compactionEvent.compactionEntry.firstKeptEntryId);
const trackedNames = state.skills.map((skill) => skill.name);
const keptPresent = skillsPresentInKeptWindow(keptEntries, trackedNames);
return filterSkillsNeedingReinject(
state.skills,
keptPresent,
registeredSkillNames(registeredSkills),
);
}