fix manifest glob expansion and add regression test (#3350)

This commit is contained in:
Neon
2026-04-18 13:16:39 +02:00
committed by GitHub
parent 00887125c0
commit 182d4ceea3
2 changed files with 51 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, wri
import { homedir, tmpdir } from "node:os";
import { basename, dirname, join, relative, resolve, sep } from "node:path";
import type { Readable } from "node:stream";
import { globSync } from "glob";
import ignore from "ignore";
import { minimatch } from "minimatch";
import { CONFIG_DIR_NAME } from "../config.js";
@@ -215,6 +216,14 @@ function isPattern(s: string): boolean {
return s.startsWith("!") || s.startsWith("+") || s.startsWith("-") || s.includes("*") || s.includes("?");
}
function isOverridePattern(s: string): boolean {
return s.startsWith("!") || s.startsWith("+") || s.startsWith("-");
}
function hasGlobPattern(s: string): boolean {
return s.includes("*") || s.includes("?");
}
function splitPatterns(entries: string[]): { plain: string[]; patterns: string[] } {
const plain: string[] = [];
const patterns: string[] = [];
@@ -1897,7 +1906,7 @@ export class DefaultPackageManager implements PackageManager {
const entries = manifest?.[resourceType as keyof PiManifest];
if (entries && entries.length > 0) {
const allFiles = this.collectFilesFromManifestEntries(entries, packageRoot, resourceType);
const manifestPatterns = entries.filter(isPattern);
const manifestPatterns = entries.filter(isOverridePattern);
const enabledByManifest =
manifestPatterns.length > 0 ? applyPatterns(allFiles, manifestPatterns, packageRoot) : new Set(allFiles);
return { allFiles: Array.from(enabledByManifest), enabledByManifest };
@@ -1936,7 +1945,7 @@ export class DefaultPackageManager implements PackageManager {
if (!entries) return;
const allFiles = this.collectFilesFromManifestEntries(entries, root, resourceType);
const patterns = entries.filter(isPattern);
const patterns = entries.filter(isOverridePattern);
const enabledPaths = applyPatterns(allFiles, patterns, root);
for (const f of allFiles) {
@@ -1947,8 +1956,19 @@ export class DefaultPackageManager implements PackageManager {
}
private collectFilesFromManifestEntries(entries: string[], root: string, resourceType: ResourceType): string[] {
const plain = entries.filter((entry) => !isPattern(entry));
const resolved = plain.map((entry) => resolve(root, entry));
const sourceEntries = entries.filter((entry) => !isOverridePattern(entry));
const resolved = sourceEntries.flatMap((entry) => {
if (!hasGlobPattern(entry)) {
return [resolve(root, entry)];
}
return globSync(entry, {
cwd: root,
absolute: true,
dot: false,
nodir: false,
}).map((match) => resolve(match));
});
return this.collectFilesFromPaths(resolved, resourceType);
}

View File

@@ -884,6 +884,33 @@ Content`,
expect(result.skills.some((r) => isEnabled(r, "good-skill", "includes"))).toBe(true);
expect(result.skills.some((r) => r.path.includes("bad-skill"))).toBe(false);
});
it("should expand positive glob manifest entries before collecting skills", async () => {
const pkgDir = join(tempDir, "skill-manifest-glob-pkg");
mkdirSync(join(pkgDir, "plugins/pdf-to-markdown/skills/pdf-to-markdown"), { recursive: true });
mkdirSync(join(pkgDir, "plugins/nutrient-dws/skills/document-processor-api"), { recursive: true });
writeFileSync(
join(pkgDir, "plugins/pdf-to-markdown/skills/pdf-to-markdown", "SKILL.md"),
"---\nname: pdf-to-markdown\ndescription: PDF to Markdown\n---\nContent",
);
writeFileSync(
join(pkgDir, "plugins/nutrient-dws/skills/document-processor-api", "SKILL.md"),
"---\nname: document-processor-api\ndescription: DWS\n---\nContent",
);
writeFileSync(
join(pkgDir, "package.json"),
JSON.stringify({
name: "skill-manifest-glob-pkg",
pi: {
skills: ["./plugins/*/skills"],
},
}),
);
const result = await packageManager.resolveExtensionSources([pkgDir]);
expect(result.skills.some((r) => isEnabled(r, "pdf-to-markdown", "includes"))).toBe(true);
expect(result.skills.some((r) => isEnabled(r, "document-processor-api", "includes"))).toBe(true);
});
});
describe("pattern filtering in package filters", () => {