Phase 14: filter deferred pending on before_agent_start — registry + disk fallback
filterPendingReinjectForConsume applies fresh registered check at consume time; loose skills pass when requireRegistered is false and tracked SKILL.md exists. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+50
-1
@@ -26,6 +26,13 @@ function notifyWarning(ctx: ExtensionContext | undefined, message: string): void
|
||||
ctx.ui.notify(message, "warning");
|
||||
}
|
||||
|
||||
function notifyInfo(ctx: ExtensionContext | undefined, message: string): void {
|
||||
if (!ctx?.hasUI) {
|
||||
return;
|
||||
}
|
||||
ctx.ui.notify(message, "info");
|
||||
}
|
||||
|
||||
function notifySkippedSkill(ctx: ExtensionContext | undefined, skillName: string, reason: string): void {
|
||||
notifyWarning(ctx, `skill-reinject: skipped "${skillName}" — ${reason}`);
|
||||
}
|
||||
@@ -278,6 +285,42 @@ export function clearPendingReinjectOnUserPrompt(
|
||||
return hadPending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer consume stage: fresh registry filter on before_agent_start (SPEC §6.5.1, Phase 14 / B-002).
|
||||
* Loose fallback when requireRegistered is false and tracked SKILL.md still exists on disk.
|
||||
*/
|
||||
export function filterPendingReinjectForConsume(
|
||||
pendingNames: readonly string[],
|
||||
state: ExtensionState,
|
||||
settings: SkillReinjectSettings,
|
||||
registeredSkills: readonly Pick<Skill, "name">[],
|
||||
ctx?: ExtensionContext,
|
||||
): string[] {
|
||||
const registered = registeredSkillNames(registeredSkills);
|
||||
const resolved: string[] = [];
|
||||
for (const name of pendingNames) {
|
||||
const tracked = state.skills.find((skill) => skill.name === name);
|
||||
if (!tracked) {
|
||||
continue;
|
||||
}
|
||||
if (registered.has(name)) {
|
||||
resolved.push(name);
|
||||
continue;
|
||||
}
|
||||
if (settings.requireRegistered) {
|
||||
notifySkippedSkill(ctx, name, "no longer registered");
|
||||
continue;
|
||||
}
|
||||
if (existsSync(tracked.filePath)) {
|
||||
notifyInfo(ctx, `skill-reinject: re-injected "${name}" from disk`);
|
||||
resolved.push(name);
|
||||
continue;
|
||||
}
|
||||
notifySkippedSkill(ctx, name, "SKILL.md not found on disk");
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer path on before_agent_start: inject one combined message, then clear queue (SPEC §6.5.1).
|
||||
* Returns undefined when pendingReinject is empty or manual compaction scheduled a clear (SPEC §16.5).
|
||||
@@ -295,7 +338,13 @@ export function tryConsumeDeferredReinject(
|
||||
if (state.pendingReinject.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const pendingNames = [...state.pendingReinject];
|
||||
const pendingNames = filterPendingReinjectForConsume(
|
||||
state.pendingReinject,
|
||||
state,
|
||||
settings,
|
||||
registeredSkills,
|
||||
ctx,
|
||||
);
|
||||
const content = buildDeferredReinjectContent(pendingNames, state, settings, registeredSkills, ctx);
|
||||
if (!content) {
|
||||
state.pendingReinject = [];
|
||||
|
||||
Reference in New Issue
Block a user