fix: load pierre themes without json module imports#45869
fix: load pierre themes without json module imports#45869gumadeiras merged 5 commits intoopenclaw:mainfrom
Conversation
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
Greptile SummaryThis PR extracts pierre theme loading into a new
Confidence Score: 3/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/diffs/src/pierre-themes.ts
Line: 9-16
Comment:
**Missing error fallback removed from old implementation**
The previous implementation wrapped path resolution and theme loader registration in a `try/catch` with an explicit fallback comment: `// Keep upstream loaders if theme files cannot be resolved.` That guard meant a broken theme install never caused a render failure — it gracefully degraded to the upstream loaders.
In the new code, `loadPierreTheme` calls `fs.realpath()` and `fs.readFile()` without any catch. If the resolved `@pierre/diffs` symlink doesn't exist at the expected relative location (e.g., in a flat `node_modules` or a different package manager), `fs.realpath` will throw `ENOENT`. Because `loadPierreTheme` is registered as a lazy callback in `RegisteredCustomThemes`, the error won't surface during `ensurePierreThemesRegistered()` — it will surface later as an uncaught rejection inside `preloadFileDiff` / `preloadMultiFileDiff`, causing every render to fail rather than falling back.
Consider wrapping the body of `loadPierreTheme` (or the entire registration callback) in a try/catch so that on resolution failure the slot is removed from `RegisteredCustomThemes` and `@pierre/diffs` retries with its own upstream loader:
```ts
async function loadPierreTheme(themeFileName: string, themeName: string): Promise<unknown> {
try {
const diffsPackageRoot = await fs.realpath(
fileURLToPath(new URL("../node_modules/@pierre/diffs", import.meta.url)),
);
const themePath = path.join(diffsPackageRoot, "..", "theme", "themes", themeFileName);
return {
...(JSON.parse(await fs.readFile(themePath, "utf8")) as Record<string, unknown>),
name: themeName,
};
} catch {
// Fall back to upstream loaders if theme files cannot be resolved.
return undefined;
}
}
```
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: 09e2e5f |
| const diffsPackageRoot = await fs.realpath( | ||
| fileURLToPath(new URL("../node_modules/@pierre/diffs", import.meta.url)), | ||
| ); | ||
| const themePath = path.join(diffsPackageRoot, "..", "theme", "themes", themeFileName); | ||
| return { | ||
| ...(JSON.parse(await fs.readFile(themePath, "utf8")) as Record<string, unknown>), | ||
| name: themeName, | ||
| }; |
There was a problem hiding this comment.
Missing error fallback removed from old implementation
The previous implementation wrapped path resolution and theme loader registration in a try/catch with an explicit fallback comment: // Keep upstream loaders if theme files cannot be resolved. That guard meant a broken theme install never caused a render failure — it gracefully degraded to the upstream loaders.
In the new code, loadPierreTheme calls fs.realpath() and fs.readFile() without any catch. If the resolved @pierre/diffs symlink doesn't exist at the expected relative location (e.g., in a flat node_modules or a different package manager), fs.realpath will throw ENOENT. Because loadPierreTheme is registered as a lazy callback in RegisteredCustomThemes, the error won't surface during ensurePierreThemesRegistered() — it will surface later as an uncaught rejection inside preloadFileDiff / preloadMultiFileDiff, causing every render to fail rather than falling back.
Consider wrapping the body of loadPierreTheme (or the entire registration callback) in a try/catch so that on resolution failure the slot is removed from RegisteredCustomThemes and @pierre/diffs retries with its own upstream loader:
async function loadPierreTheme(themeFileName: string, themeName: string): Promise<unknown> {
try {
const diffsPackageRoot = await fs.realpath(
fileURLToPath(new URL("../node_modules/@pierre/diffs", import.meta.url)),
);
const themePath = path.join(diffsPackageRoot, "..", "theme", "themes", themeFileName);
return {
...(JSON.parse(await fs.readFile(themePath, "utf8")) as Record<string, unknown>),
name: themeName,
};
} catch {
// Fall back to upstream loaders if theme files cannot be resolved.
return undefined;
}
}Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/diffs/src/pierre-themes.ts
Line: 9-16
Comment:
**Missing error fallback removed from old implementation**
The previous implementation wrapped path resolution and theme loader registration in a `try/catch` with an explicit fallback comment: `// Keep upstream loaders if theme files cannot be resolved.` That guard meant a broken theme install never caused a render failure — it gracefully degraded to the upstream loaders.
In the new code, `loadPierreTheme` calls `fs.realpath()` and `fs.readFile()` without any catch. If the resolved `@pierre/diffs` symlink doesn't exist at the expected relative location (e.g., in a flat `node_modules` or a different package manager), `fs.realpath` will throw `ENOENT`. Because `loadPierreTheme` is registered as a lazy callback in `RegisteredCustomThemes`, the error won't surface during `ensurePierreThemesRegistered()` — it will surface later as an uncaught rejection inside `preloadFileDiff` / `preloadMultiFileDiff`, causing every render to fail rather than falling back.
Consider wrapping the body of `loadPierreTheme` (or the entire registration callback) in a try/catch so that on resolution failure the slot is removed from `RegisteredCustomThemes` and `@pierre/diffs` retries with its own upstream loader:
```ts
async function loadPierreTheme(themeFileName: string, themeName: string): Promise<unknown> {
try {
const diffsPackageRoot = await fs.realpath(
fileURLToPath(new URL("../node_modules/@pierre/diffs", import.meta.url)),
);
const themePath = path.join(diffsPackageRoot, "..", "theme", "themes", themeFileName);
return {
...(JSON.parse(await fs.readFile(themePath, "utf8")) as Record<string, unknown>),
name: themeName,
};
} catch {
// Fall back to upstream loaders if theme files cannot be resolved.
return undefined;
}
}
```
How can I resolve this? If you propose a fix, please make it concise.e60916d to
30b5968
Compare
f3904c2 to
0fa2d8e
Compare
0fa2d8e to
dd456aa
Compare
|
Merged via squash.
Thanks @NickHood1984! |
Merged via squash. Prepared head SHA: dd456aa Co-authored-by: NickHood1984 <[email protected]> Co-authored-by: gumadeiras <[email protected]> Reviewed-by: @gumadeiras
Merged via squash. Prepared head SHA: dd456aa Co-authored-by: NickHood1984 <[email protected]> Co-authored-by: gumadeiras <[email protected]> Reviewed-by: @gumadeiras
Merged via squash. Prepared head SHA: dd456aa Co-authored-by: NickHood1984 <[email protected]> Co-authored-by: gumadeiras <[email protected]> Reviewed-by: @gumadeiras
Merged via squash. Prepared head SHA: dd456aa Co-authored-by: NickHood1984 <[email protected]> Co-authored-by: gumadeiras <[email protected]> Reviewed-by: @gumadeiras
Merged via squash. Prepared head SHA: dd456aa Co-authored-by: NickHood1984 <[email protected]> Co-authored-by: gumadeiras <[email protected]> Reviewed-by: @gumadeiras
Summary
@pierre/diffsso the extension can resolve them on newer Node buildsextensions/diffsWhy
The
checks (node, extensions, pnpm test:extensions)failure inherited by #40791 includesextensions/diffstests breaking when Node requirestype: "json"for those bundled theme imports. This PR isolates that fix so it can be reviewed independently.Validation
pnpm exec vitest run --config vitest.extensions.config.ts extensions/diffs/index.test.ts extensions/diffs/src/render.test.ts extensions/diffs/src/tool.test.ts