Phase 14: build reinject blocks from tracked paths — loose skill disk fallback

buildReinjectBlocks uses tracked filePath/baseDir when resourceLoader has no entry and requireRegistered is false, completing defer-path B-002 injection.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-17 17:34:43 +07:00
parent e63041bfc5
commit ebc169c91f
2 changed files with 29 additions and 7 deletions
+13 -6
View File
@@ -179,11 +179,18 @@ export function buildReinjectBlocks(
continue;
}
const registered = registeredByName.get(name);
const filePath = registered?.filePath ?? tracked.filePath;
const baseDir = registered?.baseDir ?? tracked.baseDir;
if (!registered) {
notifySkippedSkill(ctx, name, "no longer registered");
continue;
}
if (!existsSync(registered.filePath)) {
if (settings.requireRegistered) {
notifySkippedSkill(ctx, name, "no longer registered");
continue;
}
if (!existsSync(tracked.filePath)) {
notifySkippedSkill(ctx, name, "SKILL.md not found on disk");
continue;
}
} else if (!existsSync(filePath)) {
notifySkippedSkill(ctx, name, "SKILL.md not found on disk");
continue;
}
@@ -192,8 +199,8 @@ export function buildReinjectBlocks(
expandSkill(
{
name: tracked.name,
filePath: registered.filePath,
baseDir: registered.baseDir,
filePath,
baseDir,
},
settings.suffix,
),
+16 -1
View File
@@ -2,7 +2,7 @@ import { existsSync, mkdtempSync, mkdirSync, rmSync, writeFileSync } from "fs";
import { tmpdir } from "os";
import { join } from "path";
import { afterEach, describe, expect, it, vi } from "vitest";
import { filterPendingReinjectForConsume } from "../src/reinject";
import { filterPendingReinjectForConsume, tryConsumeDeferredReinject } from "../src/reinject";
import { createDefaultSettings } from "../src/settings";
import { createInitialState, trackSkill } from "../src/state";
@@ -94,3 +94,18 @@ describe("filterPendingReinjectForConsume", () => {
);
});
});
describe("tryConsumeDeferredReinject loose path", () => {
it("injects skill block from tracked filePath when not registered", () => {
const { filePath, baseDir } = tempSkillDir("loose");
const state = createInitialState();
trackSkill(state, { name: "loose", filePath, baseDir, source: "slash" });
state.pendingReinject = ["loose"];
const result = tryConsumeDeferredReinject(state, createDefaultSettings(), [], undefined);
expect(result?.message?.content).toContain('<skill name="loose"');
expect(result?.message?.content).toContain("[skill-reinject] Re-applied after compaction.");
expect(state.pendingReinject).toEqual([]);
});
});