fix(bun): use modulePath for jitiFilename in bundled plugin loader (#69783)#70080
fix(bun): use modulePath for jitiFilename in bundled plugin loader (#69783)#70080EronFan wants to merge 9 commits into
Conversation
Root cause: tool runners capture startedAt = Date.now() before calling createTaskRecord. By the time the registry sets createdAt = Date.now(), a few ms may have passed, making startedAt < createdAt architecturally. Fix: in createTaskRecord, clamp createdAt to be at least startedAt when startedAt is provided and already in the past. This ensures the invariant createdAt >= startedAt is always true for new records, eliminating the false positive from the inconsistent_timestamps audit check. Tests: new regression tests in task-registry.audit.test.ts covering: - startedAt captured before registration (pre-clamp legacy input) - terminal task with pre-createdAt startedAt (genuine ordering bug still caught) - non-consecutive duplicate suppression in system-events (bundled fix) Fixes openclaw#69229
Greptile SummaryThis PR bundles several independent fixes: the stated Bun fix (switching
Confidence Score: 4/5Safe to merge after fixing the missing nth field in the aria snapshot node mapping. One P1 bug: the nth field is dropped when storing aria snapshot nodes, causing refLocator to return the wrong element for duplicate-role/name nodes. All other changes (core Bun fix, timestamp clamping, dedup, self-message guard, bind mounts) look correct. The misleading test name is P2 only. extensions/browser/src/browser/pw-tools-core.snapshot.ts (missing nth in node mapping), src/tasks/task-registry.audit.test.ts (misleading test name) Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/browser/src/browser/pw-tools-core.snapshot.ts
Line: 65
Comment:
**`nth` dropped when storing aria snapshot nodes**
The `nth` field from each `AriaSnapshotNode` is not included in the mapping, so it is never stored in `state.ariaSnapshotNodes`. When `refLocator` resolves an `ax<number>` ref whose original node had `nth` set (used to disambiguate multiple elements sharing the same role+name), it falls through to the plain `getByRole(role, { name, exact: true })` call without calling `.nth(...)`, silently returning the wrong (first) element.
```suggestion
nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined, nth: n.nth })),
```
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/tasks/task-registry.audit.test.ts
Line: 129-153
Comment:
**Misleading test name — says "does not flag" but asserts the opposite**
The test is named `"does not flag inconsistent_timestamps when startedAt is captured before task registration"`, yet the assertion expects the `inconsistent_timestamps` finding to be present. The comment clarifies the intent (testing legacy pre-clamp data), but the name contradicts the assertion and will confuse future readers. Consider renaming to something like `"flags inconsistent_timestamps for legacy data with startedAt earlier than createdAt (pre-clamp)"`.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(bun): use modulePath for jitiFilenam..." | Re-trigger Greptile |
| page, | ||
| cdpUrl: opts.cdpUrl, | ||
| targetId: opts.targetId, | ||
| nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined })), |
There was a problem hiding this comment.
nth dropped when storing aria snapshot nodes
The nth field from each AriaSnapshotNode is not included in the mapping, so it is never stored in state.ariaSnapshotNodes. When refLocator resolves an ax<number> ref whose original node had nth set (used to disambiguate multiple elements sharing the same role+name), it falls through to the plain getByRole(role, { name, exact: true }) call without calling .nth(...), silently returning the wrong (first) element.
| nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined })), | |
| nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined, nth: n.nth })), |
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/browser/src/browser/pw-tools-core.snapshot.ts
Line: 65
Comment:
**`nth` dropped when storing aria snapshot nodes**
The `nth` field from each `AriaSnapshotNode` is not included in the mapping, so it is never stored in `state.ariaSnapshotNodes`. When `refLocator` resolves an `ax<number>` ref whose original node had `nth` set (used to disambiguate multiple elements sharing the same role+name), it falls through to the plain `getByRole(role, { name, exact: true })` call without calling `.nth(...)`, silently returning the wrong (first) element.
```suggestion
nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined, nth: n.nth })),
```
How can I resolve this? If you propose a fix, please make it concise.| it("does not flag inconsistent_timestamps when startedAt is captured before task registration", () => { | ||
| // Regression: tool runners capture startedAt = Date.now() before calling | ||
| // createTaskRecord. By the time the registry records createdAt = Date.now(), | ||
| // a few ms may have passed, making startedAt < createdAt architecturally. | ||
| // createTaskRecord clamps createdAt >= startedAt, so this state never | ||
| // persists — but we test the audit still handles the invariant correctly | ||
| // for pre-clamped record inputs (e.g. restored legacy data). | ||
| const startedAt = Date.parse("2026-03-30T00:00:00.000Z"); // older than createdAt | ||
| const createdAt = startedAt + 10; // 10 ms later | ||
| const findings = listTaskAuditFindings({ | ||
| now: createdAt + 60_000, | ||
| tasks: [ | ||
| createTask({ | ||
| taskId: "ts-clock-skew", | ||
| status: "running", | ||
| createdAt, | ||
| startedAt, // intentionally earlier than createdAt (pre-clamp legacy state) | ||
| }), | ||
| ], | ||
| }); | ||
|
|
||
| expect(findings.map((f) => [f.code, f.detail])).toEqual([ | ||
| ["inconsistent_timestamps", "startedAt is earlier than createdAt"], | ||
| ]); | ||
| }); |
There was a problem hiding this comment.
Misleading test name — says "does not flag" but asserts the opposite
The test is named "does not flag inconsistent_timestamps when startedAt is captured before task registration", yet the assertion expects the inconsistent_timestamps finding to be present. The comment clarifies the intent (testing legacy pre-clamp data), but the name contradicts the assertion and will confuse future readers. Consider renaming to something like "flags inconsistent_timestamps for legacy data with startedAt earlier than createdAt (pre-clamp)".
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/tasks/task-registry.audit.test.ts
Line: 129-153
Comment:
**Misleading test name — says "does not flag" but asserts the opposite**
The test is named `"does not flag inconsistent_timestamps when startedAt is captured before task registration"`, yet the assertion expects the `inconsistent_timestamps` finding to be present. The comment clarifies the intent (testing legacy pre-clamp data), but the name contradicts the assertion and will confuse future readers. Consider renaming to something like `"flags inconsistent_timestamps for legacy data with startedAt earlier than createdAt (pre-clamp)"`.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6a6740a79f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const scope = state.roleRefsFrameSelector | ||
| ? page.frameLocator(state.roleRefsFrameSelector) | ||
| : page; |
There was a problem hiding this comment.
Ignore stale frame selector for ax refs
This new ax<number> branch scopes lookups through state.roleRefsFrameSelector, but storeAriaSnapshotNodes never clears that field. If a user takes a frame-scoped role snapshot first (which sets roleRefsFrameSelector) and then takes an aria snapshot, later refLocator("ax...") calls are forced into the old frame and fail to find elements that are in the top document. That makes valid aria refs intermittently unusable depending on prior tool calls.
Useful? React with 👍 / 👎.
| page, | ||
| cdpUrl: opts.cdpUrl, | ||
| targetId: opts.targetId, | ||
| nodes: formatted.map((n) => ({ ref: n.ref, role: n.role, name: n.name || undefined })), |
There was a problem hiding this comment.
Preserve disambiguation when caching ax snapshot refs
The cached aria node metadata now keeps only {ref, role, name}. For pages with repeated accessible names (for example multiple button elements named "Submit"), different ax refs collapse to the same getByRole query, so click/fill paths can hit Playwright strict-mode ambiguity instead of the exact node the snapshot ref pointed to. refLocator already supports node.nth, but this mapper never populates it, so the disambiguation path is unreachable for real aria snapshots.
Useful? React with 👍 / 👎.
|
Closing this in favor of the focused Bun/Jiti fix in #70073. This branch contains the same |
|
Related work from PRtags group Title: Open PR candidate: bundled plugin jitiFilename should use modulePath for #69783
|
Fixes #69783 — In Bun global install, import.meta.url in bundled plugins points to a cached path instead of the actual module path, causing jiti loader to hang. Changed to use modulePath parameter instead.