fix(agents): tolerate path-only bootstrap hook files (#115395)

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
This commit is contained in:
Vito Cappello
2026-07-28 20:53:49 -04:00
committed by GitHub
parent 6b324386b5
commit 1f6f8f9535
2 changed files with 44 additions and 4 deletions
+33
View File
@@ -46,6 +46,39 @@ describe("buildBootstrapInjectionStats", () => {
expect(stats[1]?.injectedChars).toBe(20);
expect(stats[1]?.truncated).toBe(true);
});
it("derives names for path-only files supplied by bootstrap hooks", () => {
const pathOnlyFile = {
path: "/tmp/SELF_IMPROVEMENT_REMINDER.md",
content: "remember",
missing: false,
} as unknown as WorkspaceBootstrapFile;
const injectedFiles = [
{
path: "/tmp/SELF_IMPROVEMENT_REMINDER.md",
content: "remember",
},
];
const stats = buildBootstrapInjectionStats({
bootstrapFiles: [pathOnlyFile],
injectedFiles,
});
const analysis = analyzeBootstrapBudget({
files: stats,
bootstrapMaxChars: 20_000,
bootstrapTotalMaxChars: 60_000,
});
expect(analysis.files).toEqual([
expect.objectContaining({
name: "SELF_IMPROVEMENT_REMINDER.md",
path: "/tmp/SELF_IMPROVEMENT_REMINDER.md",
injectedChars: 8,
truncated: false,
}),
]);
});
});
describe("analyzeBootstrapBudget", () => {
+11 -4
View File
@@ -166,16 +166,23 @@ export function buildBootstrapInjectionStats(params: {
}
return params.bootstrapFiles.map((file) => {
const pathValue = normalizeOptionalString(file.path) ?? "";
const normalizedPath = pathValue.replace(/\\/g, "/");
// Bootstrap hooks are extension-facing and may provide path/content only.
// Derive the display name before budget classification so those entries
// keep working and cannot crash the turn when filename-specific caps run.
const name =
normalizeOptionalString(file.name) ??
(normalizedPath ? path.posix.basename(normalizedPath) : "bootstrap");
const rawChars = file.missing ? 0 : (file.content ?? "").trimEnd().length;
const injected =
(pathValue ? injectedByPath.get(pathValue) : undefined) ??
injectedByPath.get(file.name) ??
injectedByBaseName.get(file.name);
injectedByPath.get(name) ??
injectedByBaseName.get(name);
const injectedChars = injected ? injected.length : 0;
const truncated = !file.missing && injectedChars < rawChars;
return {
name: file.name,
path: pathValue || file.name,
name,
path: pathValue || name,
missing: file.missing,
rawChars,
injectedChars,