fix(context): fall back to path basename for unnamed bootstrap files#48021
fix(context): fall back to path basename for unnamed bootstrap files#48021jnMetaCode wants to merge 1 commit into
Conversation
Greptile SummaryThis PR fixes a display bug where
Confidence Score: 4/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/agents/bootstrap-budget.ts
Line: 153
Comment:
**`path.basename` vs `path.posix.basename` inconsistency**
The injection-map building logic (lines 138–141) normalizes backslashes before calling `path.posix.basename`:
```ts
const normalizedPath = pathValue.replace(/\\/g, "/");
const baseName = path.posix.basename(normalizedPath);
```
The new `name` derivation uses `path.basename(pathValue)` without the same normalization. On a POSIX host this is harmless because both calls treat `/` as the only separator, but if a Windows-style path (`C:\foo\bar.md`) ever reaches `buildBootstrapInjectionStats`, `path.posix.basename` (used to key the map) would return the full string while `path.basename` (on a POSIX host) would also return the full string, so no match would be found. Aligning the two usages makes the intent clearer and more robust:
```suggestion
const name = file.name || path.posix.basename(pathValue.replace(/\\/g, "/")) || "(virtual file)";
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: src/agents/bootstrap-budget.test.ts
Line: 68-75
Comment:
**Test doesn't assert injection tracking for unnamed files**
The new test verifies that the derived `name` is correct, but it doesn't assert that `injectedChars` and `truncated` are also computed correctly for the unnamed files. The content matches 1:1 in both cases, so a complete assertion would confirm injection tracking still works end-to-end:
```suggestion
const stats = buildBootstrapInjectionStats({ bootstrapFiles, injectedFiles });
expect(stats[0]?.name).toBe("SELF_IMPROVEMENT_REMINDER.md");
expect(stats[0]?.injectedChars).toBe("reminder text".length);
expect(stats[0]?.truncated).toBe(false);
expect(stats[1]?.name).toBe("NOTES.md");
expect(stats[1]?.injectedChars).toBe("notes".length);
expect(stats[1]?.truncated).toBe(false);
```
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: 9ca1f67 |
| @@ -150,9 +150,10 @@ export function buildBootstrapInjectionStats(params: { | |||
| injectedByBaseName.get(file.name); | |||
| const injectedChars = injected ? injected.length : 0; | |||
| const truncated = !file.missing && injectedChars < rawChars; | |||
| const name = file.name || path.basename(pathValue) || "(virtual file)"; | |||
There was a problem hiding this comment.
path.basename vs path.posix.basename inconsistency
The injection-map building logic (lines 138–141) normalizes backslashes before calling path.posix.basename:
const normalizedPath = pathValue.replace(/\\/g, "/");
const baseName = path.posix.basename(normalizedPath);The new name derivation uses path.basename(pathValue) without the same normalization. On a POSIX host this is harmless because both calls treat / as the only separator, but if a Windows-style path (C:\foo\bar.md) ever reaches buildBootstrapInjectionStats, path.posix.basename (used to key the map) would return the full string while path.basename (on a POSIX host) would also return the full string, so no match would be found. Aligning the two usages makes the intent clearer and more robust:
| const name = file.name || path.basename(pathValue) || "(virtual file)"; | |
| const name = file.name || path.posix.basename(pathValue.replace(/\\/g, "/")) || "(virtual file)"; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/bootstrap-budget.ts
Line: 153
Comment:
**`path.basename` vs `path.posix.basename` inconsistency**
The injection-map building logic (lines 138–141) normalizes backslashes before calling `path.posix.basename`:
```ts
const normalizedPath = pathValue.replace(/\\/g, "/");
const baseName = path.posix.basename(normalizedPath);
```
The new `name` derivation uses `path.basename(pathValue)` without the same normalization. On a POSIX host this is harmless because both calls treat `/` as the only separator, but if a Windows-style path (`C:\foo\bar.md`) ever reaches `buildBootstrapInjectionStats`, `path.posix.basename` (used to key the map) would return the full string while `path.basename` (on a POSIX host) would also return the full string, so no match would be found. Aligning the two usages makes the intent clearer and more robust:
```suggestion
const name = file.name || path.posix.basename(pathValue.replace(/\\/g, "/")) || "(virtual file)";
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Fixed in 08bd7b7 — switched to path.posix.basename with backslash normalization to match the injection-map building logic at line 139.
| const injectedFiles = [ | ||
| { path: "/workspace/SELF_IMPROVEMENT_REMINDER.md", content: "reminder text" }, | ||
| { path: "/workspace/NOTES.md", content: "notes" }, | ||
| ]; | ||
|
|
||
| const stats = buildBootstrapInjectionStats({ bootstrapFiles, injectedFiles }); | ||
| expect(stats[0]?.name).toBe("SELF_IMPROVEMENT_REMINDER.md"); | ||
| expect(stats[1]?.name).toBe("NOTES.md"); |
There was a problem hiding this comment.
Test doesn't assert injection tracking for unnamed files
The new test verifies that the derived name is correct, but it doesn't assert that injectedChars and truncated are also computed correctly for the unnamed files. The content matches 1:1 in both cases, so a complete assertion would confirm injection tracking still works end-to-end:
| const injectedFiles = [ | |
| { path: "/workspace/SELF_IMPROVEMENT_REMINDER.md", content: "reminder text" }, | |
| { path: "/workspace/NOTES.md", content: "notes" }, | |
| ]; | |
| const stats = buildBootstrapInjectionStats({ bootstrapFiles, injectedFiles }); | |
| expect(stats[0]?.name).toBe("SELF_IMPROVEMENT_REMINDER.md"); | |
| expect(stats[1]?.name).toBe("NOTES.md"); | |
| const stats = buildBootstrapInjectionStats({ bootstrapFiles, injectedFiles }); | |
| expect(stats[0]?.name).toBe("SELF_IMPROVEMENT_REMINDER.md"); | |
| expect(stats[0]?.injectedChars).toBe("reminder text".length); | |
| expect(stats[0]?.truncated).toBe(false); | |
| expect(stats[1]?.name).toBe("NOTES.md"); | |
| expect(stats[1]?.injectedChars).toBe("notes".length); | |
| expect(stats[1]?.truncated).toBe(false); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/bootstrap-budget.test.ts
Line: 68-75
Comment:
**Test doesn't assert injection tracking for unnamed files**
The new test verifies that the derived `name` is correct, but it doesn't assert that `injectedChars` and `truncated` are also computed correctly for the unnamed files. The content matches 1:1 in both cases, so a complete assertion would confirm injection tracking still works end-to-end:
```suggestion
const stats = buildBootstrapInjectionStats({ bootstrapFiles, injectedFiles });
expect(stats[0]?.name).toBe("SELF_IMPROVEMENT_REMINDER.md");
expect(stats[0]?.injectedChars).toBe("reminder text".length);
expect(stats[0]?.truncated).toBe(false);
expect(stats[1]?.name).toBe("NOTES.md");
expect(stats[1]?.injectedChars).toBe("notes".length);
expect(stats[1]?.truncated).toBe(false);
```
How can I resolve this? If you propose a fix, please make it concise.…missing Hook-injected virtual bootstrap files may omit the name field. buildBootstrapInjectionStats now falls back to basename(path) so the context breakdown never renders a literal "undefined" label. Closes openclaw#47941
9ca1f67 to
08bd7b7
Compare
|
Friendly ping — reduced my open PRs from 9 to 4 to make review easier. This fixes unnamed bootstrap files showing as |
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Keep open: current Canonical path: Close this PR as superseded by #84736. So I’m closing this here and keeping the remaining discussion on #84736. Review detailsBest possible solution: Close this PR as superseded by #84736. Do we have a high-confidence way to reproduce the issue? Yes, at source level: path-only hook entries can survive sanitization, Is this the best way to solve the issue? Yes. Normalizing the bootstrap report label in the stat builder is the narrowest maintainable generic fix; the merged Codex-specific fix does not replace this path. Security review: Security review cleared: The diff only changes context report label derivation and a colocated unit test, with no dependency, CI, install, release, secret, or package-execution surface touched. What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 25e489395ab0. |
|
ClawSweeper PR egg 🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat. Where did the egg go?
|
|
ClawSweeper applied the proposed close for this PR.
|
Fixes #47941
Hook-injected virtual bootstrap files may omit the
namefield.buildBootstrapInjectionStatsnow falls back topath.basename(file.path)(then a"(virtual file)"placeholder) so/context breakdownnever renders a literalundefinedlabel.Changes
bootstrap-budget.ts: derivenamefromfile.name || basename(path) || "(virtual file)"bootstrap-budget.test.ts: add test covering missing/emptynamewith a validpath