mirror of
https://github.com/garrytan/gbrain.git
synced 2026-08-14 00:48:18 +00:00
fix(skillpack): resolve gbrain root from module path when cwd walk fails (#3144)
Co-Authored-By: Time Attakc <89218912+time-attack@users.noreply.github.com>
This commit is contained in:
committed by
Sina Matian
co-authored by
Time Attakc
parent
64ad743d98
commit
a3000d4630
@@ -9,6 +9,7 @@
|
||||
|
||||
import { existsSync, readFileSync, statSync, readdirSync } from 'fs';
|
||||
import { join, dirname, isAbsolute, resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
import { parseMarkdown } from '../markdown.ts';
|
||||
|
||||
@@ -38,19 +39,45 @@ export class BundleError extends Error {
|
||||
/**
|
||||
* Walk up from `start` (default cwd) looking for an `openclaw.plugin.json`
|
||||
* sibling to `src/cli.ts`. That pair identifies a gbrain repo root.
|
||||
*
|
||||
* When no explicit `start` is given and the cwd walk fails (e.g. gbrain was
|
||||
* installed globally via `bun install -g` and the user is in an unrelated
|
||||
* directory, #1917), fall back to walking up from this module's own location
|
||||
* and from the running entrypoint (`process.argv[1]`). Both resolve the
|
||||
* bun-global layout (~/.bun/install/global/node_modules/gbrain/) and the
|
||||
* in-repo compiled binary (bin/gbrain).
|
||||
*/
|
||||
export function findGbrainRoot(start: string = process.cwd()): string | null {
|
||||
let dir = resolve(start);
|
||||
for (let i = 0; i < 10; i++) {
|
||||
if (
|
||||
existsSync(join(dir, 'openclaw.plugin.json')) &&
|
||||
existsSync(join(dir, 'src', 'cli.ts'))
|
||||
) {
|
||||
return dir;
|
||||
export function findGbrainRoot(start?: string): string | null {
|
||||
const walkUp = (from: string): string | null => {
|
||||
let dir = resolve(from);
|
||||
for (let i = 0; i < 10; i++) {
|
||||
if (
|
||||
existsSync(join(dir, 'openclaw.plugin.json')) &&
|
||||
existsSync(join(dir, 'src', 'cli.ts'))
|
||||
) {
|
||||
return dir;
|
||||
}
|
||||
const parent = dirname(dir);
|
||||
if (parent === dir) break;
|
||||
dir = parent;
|
||||
}
|
||||
const parent = dirname(dir);
|
||||
if (parent === dir) break;
|
||||
dir = parent;
|
||||
return null;
|
||||
};
|
||||
|
||||
const found = walkUp(start ?? process.cwd());
|
||||
if (found !== null || start !== undefined) return found;
|
||||
|
||||
const fallbacks: string[] = [];
|
||||
try {
|
||||
// Not a file:// URL inside a compiled binary; skip on error.
|
||||
fallbacks.push(dirname(fileURLToPath(import.meta.url)));
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
if (process.argv[1]) fallbacks.push(dirname(resolve(process.argv[1])));
|
||||
for (const candidate of fallbacks) {
|
||||
const root = walkUp(candidate);
|
||||
if (root !== null) return root;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,23 @@ describe('findGbrainRoot', () => {
|
||||
it('returns null when no gbrain root above', () => {
|
||||
expect(findGbrainRoot('/tmp/definitely-not-a-gbrain-repo-XYZ')).toBeNull();
|
||||
});
|
||||
it('falls back to the module location when cwd has no markers (#1917)', () => {
|
||||
// Simulate a bun-global install: cwd is an unrelated directory with no
|
||||
// gbrain markers anywhere above it. The no-arg call must still resolve
|
||||
// via bundle.ts's own location (which lives in the real repo).
|
||||
const elsewhere = mkdtempSync(join(tmpdir(), 'skillpack-elsewhere-'));
|
||||
created.push(elsewhere);
|
||||
const prevCwd = process.cwd();
|
||||
try {
|
||||
process.chdir(elsewhere);
|
||||
const root = findGbrainRoot();
|
||||
expect(root).not.toBeNull();
|
||||
expect(existsSync(join(root!, 'openclaw.plugin.json'))).toBe(true);
|
||||
expect(existsSync(join(root!, 'src', 'cli.ts'))).toBe(true);
|
||||
} finally {
|
||||
process.chdir(prevCwd);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadBundleManifest', () => {
|
||||
|
||||
Reference in New Issue
Block a user