From 02cbe66846354bf7b28e75e45cf5f0acbd70f49a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 13 Jul 2026 00:45:41 -0700 Subject: [PATCH] refactor: use built-in glob for package manifests (#105951) * refactor: use built-in glob for package manifests * docs: note built-in glob migration * docs: defer dependency note to release process --- npm-shrinkwrap.json | 34 --------------------- package.json | 1 - pnpm-lock.yaml | 3 -- src/agents/sessions/package-manager.test.ts | 27 ++++++++++++++++ src/agents/sessions/package-manager.ts | 12 +++----- 5 files changed, 31 insertions(+), 46 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 61a8f51d966b..bfc1eb551401 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -37,7 +37,6 @@ "entities": "8.0.0", "express": "5.2.1", "file-type": "22.0.1", - "glob": "13.0.6", "grammy": "1.44.0", "highlight.js": "11.11.1", "hosted-git-info": "10.1.1", @@ -1667,23 +1666,6 @@ "node": ">= 0.4" } }, - "node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/google-auth-library": { "version": "10.9.0", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.9.0.tgz", @@ -2543,22 +2525,6 @@ "node": ">=8" } }, - "node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/path-to-regexp": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", diff --git a/package.json b/package.json index b840e2030780..e36746289862 100644 --- a/package.json +++ b/package.json @@ -2031,7 +2031,6 @@ "entities": "8.0.0", "express": "5.2.1", "file-type": "22.0.1", - "glob": "13.0.6", "grammy": "1.44.0", "highlight.js": "11.11.1", "hosted-git-info": "10.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a15876992776..74e664f7b745 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -127,9 +127,6 @@ importers: file-type: specifier: 22.0.1 version: 22.0.1 - glob: - specifier: 13.0.6 - version: 13.0.6 grammy: specifier: 1.44.0 version: 1.44.0 diff --git a/src/agents/sessions/package-manager.test.ts b/src/agents/sessions/package-manager.test.ts index 39c088386932..c3f7385eace8 100644 --- a/src/agents/sessions/package-manager.test.ts +++ b/src/agents/sessions/package-manager.test.ts @@ -60,6 +60,33 @@ describe("DefaultPackageManager", () => { expect(skillPaths).not.toContain(outsideSkill); }); + it("expands manifest resource globs without hidden paths", async () => { + const root = await makeTempDir("openclaw-package-manager-"); + const packageRoot = join(root, "package"); + const visibleSkill = join(packageRoot, "skills", "visible", "SKILL.md"); + const hiddenSkill = join(packageRoot, "skills", ".hidden", "SKILL.md"); + await mkdir(join(packageRoot, "skills", "visible"), { recursive: true }); + await mkdir(join(packageRoot, "skills", ".hidden"), { recursive: true }); + await writeFile(visibleSkill, "# Visible\n", "utf-8"); + await writeFile(hiddenSkill, "# Hidden\n", "utf-8"); + await writeFile( + join(packageRoot, "package.json"), + JSON.stringify({ openclaw: { skills: ["skills/*"] } }), + "utf-8", + ); + + const manager = new DefaultPackageManager({ + cwd: root, + agentDir: join(root, "agent"), + settingsManager: SettingsManager.inMemory({ packages: [packageRoot] }), + }); + + const skillPaths = (await manager.resolve()).skills.map((skill) => skill.path); + + expect(skillPaths).toContain(visibleSkill); + expect(skillPaths).not.toContain(hiddenSkill); + }); + it("keeps convention-discovered resource entries inside the package root", async () => { const root = await makeTempDir("openclaw-package-manager-"); const packageRoot = join(root, "package"); diff --git a/src/agents/sessions/package-manager.ts b/src/agents/sessions/package-manager.ts index 5c867d84dc46..f4b7ed379470 100644 --- a/src/agents/sessions/package-manager.ts +++ b/src/agents/sessions/package-manager.ts @@ -4,10 +4,9 @@ * Resolves extension, skill, prompt, and theme sources from npm, git, local paths, and project manifests. */ import { createHash } from "node:crypto"; -import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs"; +import { existsSync, globSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs"; import { homedir, tmpdir } from "node:os"; import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path"; -import { globSync } from "glob"; import ignore from "ignore"; import { minimatch } from "minimatch"; import { addIgnoreRules, toPosixPath, type IgnoreMatcher } from "../../shared/ignore-rules.js"; @@ -1221,12 +1220,9 @@ export class DefaultPackageManager implements PackageManager { return [resolve(root, entry)]; } - return globSync(entry, { - cwd: root, - absolute: true, - dot: false, - nodir: false, - }).map((match) => resolve(match)); + // The supported Node floor has stable fs globbing; its defaults exclude + // hidden paths and retain directories, matching package manifests. + return globSync(entry, { cwd: root }).map((match) => resolve(root, match)); }); return this.collectFilesFromPaths( this.filterManifestResourcePaths(resolved, root),